文号
828313
阅读
7271
回复
1
收藏
1
Windows中的OpenGL 1.1编程
2016/12/12
IP:四川

OpenGL 1.1是Windows支持的最高软件加速版本,虽然不如Direct3D好用,但是也是可以用的,并且兼容性很好,支持除Windows 95 OSR2和Windows NT 4.0以上的操作系统,并且不需要硬件支持。

Windows 98/2000的屏保就是用它编写的,Windows XP用DirectX 8重写了一遍,Windows 7屏保则是用的DirectX 9。

比较烦人的地方是DirectX和OpenGL计算上的差异,DirectX用弧度,OpenGL用角度,DirectX用左手系,OpenGL用右手系。。。

OpenGL.png

源代码如下:

// main.c

#include <stdint.h>
#undef UNICODE
#define UNICODE
#include <windows.h>

#include <gl gl.h>
#include <gl glu.h>
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

HINSTANCE hInstExe;
HWND hMainWnd;

intptr_t __stdcall WndProc(HWND hWnd, unsigned int msg, uintptr_t wParam, intptr_t lParam)
{
	if (msg == WM_CREATE)
	{
		return 0;
	}
	if (msg == WM_PAINT)
	{
		PAINTSTRUCT ps = { 0 };
		HDC hdc = NULL;

		hdc = BeginPaint(hWnd, &ps);

		EndPaint(hWnd, &ps);
		return 0;
	}
	if (msg == WM_DESTROY)
	{
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInstReserved, char *szCmdLine, int nShowCmd)
{
	WNDCLASSEX wcex = {
		sizeof wcex,											// cbSize
		CS_VREDRAW|CS_HREDRAW, (WNDPROC)WndProc, 0, 0, hInst,	// style lpfnWndProc cbClsExtra cbWndExtra
		NULL, NULL, NULL,										// hIcon hCursor hbrBackground
		NULL, L"MainWndClass",									// lpszMenuName lpszClassName
		NULL,													// hIconSm
	};
	RECT rc = { 0, 0, 640, 480 };
	MSG msg = { 0 };

	hInstExe = hInst;

	// 注册窗口类
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.hIconSm = wcex.hIcon;
	if (!RegisterClassEx(&wcex))
	{
		return 0;
	}

	// 创建窗口
	AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0);
	hMainWnd = CreateWindowEx(
		0, L"MainWndClass", L"Main Window", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
		NULL, NULL, hInst, NULL);
	if (hMainWnd == NULL)
	{
		return 0;
	}

	// 显示窗口,立即重绘窗口
	ShowWindow(hMainWnd, nShowCmd);
	UpdateWindow(hMainWnd);

	// 消息循环
	while (TRUE)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			// GDI - 声明
			HDC hdc = NULL;
			RECT rc = { 0 };
			wchar_t hellomsg[] = L"欢迎使用Microsoft Windows";

			// OpenGL - 声明
			HGLRC hglrc = NULL;
			PIXELFORMATDESCRIPTOR pfd =
			{
				sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
				1,                              // version number
				PFD_DRAW_TO_WINDOW|             // support window
				PFD_SUPPORT_OPENGL|             // support OpenGL
				PFD_DOUBLEBUFFER,               // double buffered
				PFD_TYPE_RGBA,                  // RGBA type
				24,                             // 24-bit color depth
				0, 0, 0, 0, 0, 0,               // color bits ignored
				0,                              // no alpha buffer
				0,                              // shift bit ignored
				0,                              // no accumulation buffer
				0, 0, 0, 0,                     // accum bits ignored
				32,                             // 32-bit z-buffer
				0,                              // no stencil buffer
				0,                              // no auxiliary buffer
				PFD_MAIN_PLANE,                 // main layer
				0,                              // reserved
				0, 0, 0                         // layer masks ignored
			};
			int pixelformat = 0;

			// GDI - 初始化
			hdc = GetDC(hMainWnd);

			// OpenGL - 初始化
			pixelformat = ChoosePixelFormat(hdc, &pfd);
			SetPixelFormat(hdc, pixelformat, &pfd);
			hglrc = wglCreateContext(hdc);
			wglMakeCurrent(hdc, hglrc);

			// OpenGL - 打开深度测试
			glEnable(GL_DEPTH_TEST);

			// OpenGL - 清屏
			glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
			glClearDepth(1.0f);
			glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

			// OpenGL - 设置投影和观察矩阵
			glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			gluPerspective(180.0f / 4.0f, 640.0f / 480.0f, 1.0f, 100.0f);
			glMatrixMode(GL_MODELVIEW); // 观察矩阵和世界矩阵都用GL_MODELVIEW
			glLoadIdentity();
			gluLookAt(0, 1.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

			// OpenGL - 设置世界矩阵并绘制三角形
			glPushMatrix();
			glRotatef(GetTickCount() / 4 % 360, 0.0f, 1.0f, 0.0f);
			glBegin(GL_TRIANGLES);
			glColor3f(1.0f, 0.0f, 0.0f);
			glVertex3f(0.0f, 0.5f, 0.0f);
			glColor3f(0.0f, 1.0f, 0.0f);
			glVertex3f(-0.5f, -0.5f, 0.0f);
			glColor3f(0.0f, 0.0f, 1.0f);
			glVertex3f(0.5f, -0.5f, 0.0f);
			glEnd();
			glPopMatrix();

			// OpenGL - 上屏
			glFinish();
			SwapBuffers(wglGetCurrentDC());

			// OpenGL - 清理
			wglMakeCurrent(NULL, NULL);
			wglDeleteContext(hglrc);

			// GDI - 绘制文字
			SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
			GetClientRect(hMainWnd, &rc);
			DrawText(hdc, hellomsg, lstrlen(hellomsg), &rc, DT_SINGLELINE|DT_CENTER|DT_VCENTER); 

			// GDI - 清理
			ReleaseDC(hMainWnd, hdc);
		}
	}

	return (int)msg.wParam;
}
</gl></gl></windows.h></stdint.h>
[ 修改于10年0个月前 - 2016/12/20 00:00:49 ]
acmilan作者
10年0个月前修改于 10年0个月前IP:四川
828445
1楼
OGL是完全的状态机模型,目的是减少参数数量,因此学习起来超级简单,但是造成了API随意性很强,用起来要麻烦很多,必须按照固定的逻辑来用
DX8/DX9是半状态机半对象模型,简单性可以和OGL相比,并且使用起来也比较方便
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的