OGL是完全的状态机模型,目的是减少参数数量,因此学习起来超级简单,但是造成了API随意性很强,用起来要麻烦很多,必须按照固定的逻辑来用
DX8/DX9是半状态机半对象模型,简单性可以和OGL相比,并且使用起来也比较方便
DX8/DX9是半状态机半对象模型,简单性可以和OGL相比,并且使用起来也比较方便
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用右手系。。。
源代码如下:
// 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>