您尚未登录。

楼主 #1 2021-01-18 17:06:35

拉轰的脚踏车
会员
注册时间: 2020-03-20
已发帖子: 288
积分: 222

试一试 直接用 win32 api 运行 OpenGL 程序

/* An example of an OpenGL animation loop using the Win32 API. Also
   demonstrates palette management for RGB and color index modes and
   general strategies for message handling. */


#include <windows.h>			/* must include this before GL/gl.h */
#include <windowsx.h>
#include <GL/gl.h>			/* OpenGL header file */
#include <stdio.h>

#pragma comment(lib, "opengl32.lib")

HDC hDC;				/* device context */
HPALETTE hPalette = 0;			/* custom palette (if needed) */
GLboolean animate = GL_TRUE;		/* animation flag */
#define IDT_TIMER1 1000
float fZoom = 1.0f;
POINT m_lastPos = {0, 0};
float m_xMove;
float m_yMove;
bool in_drag = false;//是否处于拖动模式

void display()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	glClearColor(1, 1, 1, 1);

	glScalef(fZoom, fZoom, 0);
	glTranslatef(m_xMove, m_yMove, -10.0);
/*
	glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
	glColor3f(0.2, 0.2, 0.5);
	glVertex3f(0.0f, 1.0f, 0.0f);              // Top
	glVertex3f(-1.0f, -1.0f, 0.0f);              // Bottom Left
	glVertex3f(1.0f, -1.0f, 0.0f);              // Bottom Right
	glEnd();
*/
	glBegin(GL_TRIANGLES);                      // Drawing Using Triangles
	glColor3f(0.2f, 0.2f, 0.5f);
	glVertex3f(-0.0f, 1.0f, 0.0f);              // Top
	glVertex3f(-1.0f, -1.0f, 0.0f);              // Bottom Left
	glVertex3f(1.0f, -1.0f, 0.0f);              // Bottom Right
	glEnd();
	glFlush();
	SwapBuffers(hDC);			/* nop if singlebuffered */
}


LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static PAINTSTRUCT ps;
	int delta = 0;
	char strLog[64];

	switch (uMsg) {
	case WM_CREATE:
		//SetTimer(hWnd, IDT_TIMER1, 1, NULL);
		break;
	case WM_PAINT:				
		BeginPaint(hWnd, &ps);		
		display();
		EndPaint(hWnd, &ps);
		return 0;
	case WM_TIMER:
		switch (wParam)
		{
		case IDT_TIMER1:
			PostMessage(hWnd, WM_PAINT, 0, 0);
			return 0;
		}
		break;
	case WM_MOUSEWHEEL:
		if ((wParam & MK_CONTROL) == MK_CONTROL)
		{
			delta += (short)HIWORD(wParam);     // 120 or -120
			if (delta >= 120)
			{
				fZoom += 0.03f;
			}
			else if (delta <= -120)
			{
				fZoom -= 0.03f;
			}

			if (fZoom < 0.00001f)
				fZoom = 0.01f;
		}

		if (HIBYTE(GetKeyState(VK_MENU)) & 0x80)
		{
			OutputDebugString("alt is press\n");
		}
//		PostMessage(hWnd, WM_PAINT, 0, 0);
		SendMessage(hWnd, WM_PAINT, 0, 0);
		snprintf(strLog, sizeof(strLog), "%f\n", fZoom);
		OutputDebugString(strLog);
		break;
	case WM_MBUTTONUP:
		break;
	case WM_LBUTTONDOWN:
		if ((wParam & MK_CONTROL) == MK_CONTROL)
		{
			POINT pt;
			pt.x = GET_X_LPARAM(lParam);
			pt.y = GET_Y_LPARAM(lParam);
			snprintf(strLog, sizeof(strLog), "press: %d,%d\n", pt.x, pt.y);
			OutputDebugString(strLog);
			m_lastPos = pt;

			in_drag = true;
		}
		break;
	case WM_LBUTTONUP:	
		POINT pt2;
		pt2.x = GET_X_LPARAM(lParam);
		pt2.y = GET_Y_LPARAM(lParam);
		snprintf(strLog, sizeof(strLog), "release: %d,%d\n", pt2.x, pt2.y);
		OutputDebugString(strLog);
		in_drag = false;
		break;
	case WM_MOUSEMOVE:
		if (((wParam & MK_CONTROL) == MK_CONTROL) && in_drag)
		{
			POINT pt3;
			int dx, dy;
			float dx_scale, dy_scale;
			pt3.x = GET_X_LPARAM(lParam);
			pt3.y = GET_Y_LPARAM(lParam);
			snprintf(strLog, sizeof(strLog), "move: %d,%d\n", pt3.x, pt3.y);
			OutputDebugString(strLog);

			dx = pt3.x - m_lastPos.x;
			dy = pt3.y - m_lastPos.y;
			dx_scale = dx * (1 / (float)800);
			dy_scale = -dy * (1 / (float)640);

			m_xMove = m_xMove + dx_scale;
			m_yMove = m_yMove + dy_scale;

			m_lastPos = pt3;

			SendMessage(hWnd, WM_PAINT, 0, 0);
		}
		break;
	case WM_SIZE:
		glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
		PostMessage(hWnd, WM_PAINT, 0, 0);
		return 0;

	case WM_CHAR:
		switch (wParam) {
		case 27:			/* ESC key */
			PostQuitMessage(0);
			break;
		case ' ':
			animate = !animate;
			break;
		}
		return 0;
#if 0
	case WM_ACTIVATE:
		if (IsIconic(hWnd))
			animate = GL_FALSE;
		else
			animate = GL_TRUE;
		return 0;
#endif
	case WM_PALETTECHANGED:
		if (hWnd == (HWND)wParam)
			break;
		/* fall through to WM_QUERYNEWPALETTE */

	case WM_QUERYNEWPALETTE:
		if (hPalette) {
			UnrealizeObject(hPalette);
			SelectPalette(hDC, hPalette, FALSE);
			RealizePalette(hDC);
			return TRUE;
		}
		return FALSE;

	case WM_CLOSE:
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HWND CreateOpenGLWindow(char* title, int x, int y, int width, int height,
	BYTE type, DWORD flags)
{
	int         n, pf;
	HWND        hWnd;
	WNDCLASS    wc;
	LOGPALETTE* lpPal;
	PIXELFORMATDESCRIPTOR pfd;
	static HINSTANCE hInstance = 0;

	/* only register the window class once - use hInstance as a flag. */
	if (!hInstance) {
		hInstance = GetModuleHandle(NULL);
		wc.style = CS_OWNDC;
		wc.lpfnWndProc = (WNDPROC)WindowProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = hInstance;
		wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		wc.hbrBackground = NULL;
		wc.lpszMenuName = NULL;
		wc.lpszClassName = "OpenGL";

		if (!RegisterClass(&wc)) {
			MessageBox(NULL, "RegisterClass() failed:  "
				"Cannot register window class.", "Error", MB_OK);
			return NULL;
		}
	}

	hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
		WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
		x, y, width, height, NULL, NULL, hInstance, NULL);

	if (hWnd == NULL) {
		MessageBox(NULL, "CreateWindow() failed:  Cannot create a window.",
			"Error", MB_OK);
		return NULL;
	}

	hDC = GetDC(hWnd);

	/* there is no guarantee that the contents of the stack that become
	   the pfd are zeroed, therefore _make sure_ to clear these bits. */
	memset(&pfd, 0, sizeof(pfd));
	pfd.nSize = sizeof(pfd);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
	pfd.iPixelType = type;
	pfd.cColorBits = 32;

	pf = ChoosePixelFormat(hDC, &pfd);
	if (pf == 0) {
		MessageBox(NULL, "ChoosePixelFormat() failed:  "
			"Cannot find a suitable pixel format.", "Error", MB_OK);
		return 0;
	}

	if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
		MessageBox(NULL, "SetPixelFormat() failed:  "
			"Cannot set format specified.", "Error", MB_OK);
		return 0;
	}

	DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

	if (pfd.dwFlags & PFD_NEED_PALETTE ||
		pfd.iPixelType == PFD_TYPE_COLORINDEX) {

		n = 1 << pfd.cColorBits;
		if (n > 256) n = 256;

		lpPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
			sizeof(PALETTEENTRY) * n);
		memset(lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
		lpPal->palVersion = 0x300;
		lpPal->palNumEntries = n;

		GetSystemPaletteEntries(hDC, 0, n, &lpPal->palPalEntry[0]);

		/* if the pixel type is RGBA, then we want to make an RGB ramp,
		   otherwise (color index) set individual colors. */
		if (pfd.iPixelType == PFD_TYPE_RGBA) {
			int redMask = (1 << pfd.cRedBits) - 1;
			int greenMask = (1 << pfd.cGreenBits) - 1;
			int blueMask = (1 << pfd.cBlueBits) - 1;
			int i;

			/* fill in the entries with an RGB color ramp. */
			for (i = 0; i < n; ++i) {
				lpPal->palPalEntry[i].peRed =
					(((i >> pfd.cRedShift)   & redMask) * 255) / redMask;
				lpPal->palPalEntry[i].peGreen =
					(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
				lpPal->palPalEntry[i].peBlue =
					(((i >> pfd.cBlueShift)  & blueMask) * 255) / blueMask;
				lpPal->palPalEntry[i].peFlags = 0;
			}
		}
		else {
			lpPal->palPalEntry[0].peRed = 0;
			lpPal->palPalEntry[0].peGreen = 0;
			lpPal->palPalEntry[0].peBlue = 0;
			lpPal->palPalEntry[0].peFlags = PC_NOCOLLAPSE;
			lpPal->palPalEntry[1].peRed = 255;
			lpPal->palPalEntry[1].peGreen = 0;
			lpPal->palPalEntry[1].peBlue = 0;
			lpPal->palPalEntry[1].peFlags = PC_NOCOLLAPSE;
			lpPal->palPalEntry[2].peRed = 0;
			lpPal->palPalEntry[2].peGreen = 255;
			lpPal->palPalEntry[2].peBlue = 0;
			lpPal->palPalEntry[2].peFlags = PC_NOCOLLAPSE;
			lpPal->palPalEntry[3].peRed = 0;
			lpPal->palPalEntry[3].peGreen = 0;
			lpPal->palPalEntry[3].peBlue = 255;
			lpPal->palPalEntry[3].peFlags = PC_NOCOLLAPSE;
		}

		hPalette = CreatePalette(lpPal);
		if (hPalette) {
			SelectPalette(hDC, hPalette, FALSE);
			RealizePalette(hDC);
		}

		free(lpPal);
	}

	ReleaseDC(hWnd, hDC);

	return hWnd;
}

int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
	LPSTR lpszCmdLine, int nCmdShow)
{
	HGLRC hRC;				/* opengl context */
	HWND  hWnd;				/* window */
	MSG   msg;				/* message */
	DWORD buffer = PFD_DOUBLEBUFFER;	/* buffering type */
	BYTE  color = PFD_TYPE_RGBA;	/* color type */

	if (strstr(lpszCmdLine, "-sb")) {
		buffer = 0;
	}
	if (strstr(lpszCmdLine, "-ci")) {
		color = PFD_TYPE_COLORINDEX;
	}
	if (strstr(lpszCmdLine, "-h")) {
		MessageBox(NULL, "animate [-ci] [-sb]\n"
			"  -sb   single buffered\n"
			"  -ci   color index\n",
			"Usage help", MB_ICONINFORMATION);
		exit(0);
	}

	hWnd = CreateOpenGLWindow((char*)"opengl test    ---- https://whycan.com", 0, 0, 800, 640, color, buffer);
	if (hWnd == NULL)
		exit(1);

	hDC = GetDC(hWnd);
	hRC = wglCreateContext(hDC);
	wglMakeCurrent(hDC, hRC);

	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	wglMakeCurrent(NULL, NULL);
	ReleaseDC(hWnd, hDC);
	wglDeleteContext(hRC);
	DestroyWindow(hWnd);
	if (hPalette)
		DeleteObject(hPalette);

	return 0;
}

不依赖任何第三方库, 可执行文件下载: win32_opengl_test_1.7z

离线

楼主 #2 2021-01-18 17:08:09

拉轰的脚踏车
会员
注册时间: 2020-03-20
已发帖子: 288
积分: 222

Re: 试一试 直接用 win32 api 运行 OpenGL 程序

2021-01-18_170659.png

按住 CTRL 键, 可以平移和缩放。

离线

#3 2021-01-18 18:53:48

armstrong
会员
注册时间: 2019-04-10
已发帖子: 255
积分: 169.5

Re: 试一试 直接用 win32 api 运行 OpenGL 程序

搬出我多年前的收藏给楼主助威吧,NEHE OpenGL 教学例程,例程个个精美:
nehegl.zip

最近编辑记录 armstrong (2021-01-18 18:55:44)

离线

楼主 #4 2021-01-18 20:25:26

拉轰的脚踏车
会员
注册时间: 2020-03-20
已发帖子: 288
积分: 222

Re: 试一试 直接用 win32 api 运行 OpenGL 程序

armstrong 说:

搬出我多年前的收藏给楼主助威吧,NEHE OpenGL 教学例程,例程个个精美:
nehegl.zip

大哥! 太强大了!

整整48个例程啊, 我直接用VC2017编译了最后一个例程, 改了两三行就编译运行了, 真不依赖任何第三方库.

顺便请教一个问题, 现在我们公司的软件有点变态, 里面最多可能有一百万条线段的连接, OpenGL渲染可能要好几十微秒,

这种情况下鼠标还要能继续画线, 如果一起渲染的画感觉有点卡了,

请问OpenGL有没有增量渲染呢?或者说局部渲染? 这样感觉可以提高流畅度.

离线

#5 2021-01-18 23:47:18

落日余晖
会员
注册时间: 2019-11-23
已发帖子: 34
积分: 26.5

Re: 试一试 直接用 win32 api 运行 OpenGL 程序

armstrong 说:

搬出我多年前的收藏给楼主助威吧,NEHE OpenGL 教学例程,例程个个精美:
nehegl.zip

不错, 找到官网了, 就是这个

https://github.com/gamedev-net/nehe-opengl/tree/master/vc

http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/

欢迎来到我的OpenGL教程。我是一个对OpenGL充满热情的普通人!当3Dfx为Voodoo 1卡发布他们的硬件加速OpenGL驱动程序时,我第一次听说OpenGL。我立刻知道OpenGL是我必须学习的东西。不幸的是,很难在书籍或网上找到有关OpenGL的任何信息。我花了数小时试图使代码正常工作,甚至花更多时间恳求人们在电子邮件和IRC上寻求帮助。我发现那些了解OpenGL的人认为自己是精英,对共享知识没有兴趣。非常令人沮丧!

看到这里, 感觉作者就像天使一样.

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn