开篇有益
先提供了测试用的"开发包",用Visual Studio 2008打开,点此下载,,,
最近又开始学习OpenGl了,不知道能坚持多久,希望能坚持下去吧,
OpenGL是"输出"型的API,就是说,如具体的windows消息接受,窗口创建,消息循环,键盘输入,鼠标输入等功能,在OpenGl看来,它无能为力;
它只是输出内容,就这么简单,它只负责跟自己有关的内容;这保证了它的可移植性等特点,更详细的信息还是自己多在网上搜索下吧,这不是重点.
基础中的基础 - windows SDK开发模式简单介绍
windows SDK的"开发模式",执行顺序大概如下:
1,定义WinMain方法,这是入口函数,在WinMain函数中:
- 定义窗口类
- 注册窗口类
- 创建窗口类实例
- 运行该实例
- 更新该实例
2,定义窗口回调函数
- 在回调函数中接受窗口消息
- 分别为不同的消息做不同的处理,如在创建消息中进行OpenGl的初始化,在退出消息中释放OpenGl的资源
大体上就是这个样子,在WinMain函数中的五步是"一气呵成"顺序编写就成,在窗口回调函数中进行实际的渲染工作,
到这里为止,OpenGl可以粉墨登场了,在参考代码中game->RenderWindow(); 这一行是OpenGl调用的"入口函数",
Game类是我们自定义的一个类,它负责OpenGl的初始化工作,好了,在此之前都是windows SDK的内容,
内容不多,但非常重要;
参考代码

头文件
#include <windows.h> // Windows的头文件
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <gl\gl.h> // OpenGL32库的头文件
#include <gl\glu.h> // GLu32库的头文件
//#include <gl\glaux.h> // GLaux库的头文件
#pragma comment( lib, "winmm.lib")
#pragma comment( lib, "opengl32.lib") // OpenGL32连接库
#pragma comment( lib, "glu32.lib") // GLu32连接库
//#pragma comment( lib, "glaux.lib") // GLaux连接库
#define KEY_DOWN(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0);

cpp内容
#include <windows.h>
#include "inc.h"
#include "game.h"
HDC hDc; // GDI设备句柄,将窗口连接到 GDI( 图形设备接口)
HGLRC hRC=NULL; // 渲染描述句柄,将OpenGL调用连接到设备描述表
HWND hWnd=NULL; // 保存 Windows 分配给程序的窗口句柄
INT gWidth = 200;
INT gHeight = 200;
Game *game = new Game();
//声明回调函数
LRESULT CALLBACK WindowProcedure(HWND hwnd , UINT message, WPARAM wParam, LPARAM lParam);
/* Make the class name into a global variable */
char szClassName[ ] = "kkun";
int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) {
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
//注册窗口类
WNDCLASSEX wc;
wc.hInstance = hThisInstance;
wc.lpszClassName = szClassName;
wc.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wc.style = CS_DBLCLKS; /* Catch double-clicks */
wc.cbSize = sizeof (WNDCLASSEX);
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.lpszMenuName = NULL; /* No menu */
wc.cbClsExtra = 0; /* No extra bytes after the window class */
wc.cbWndExtra = 0; /* structure or the window instance */
wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wc))
return 0;
//创建窗口
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"OpenGl", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
gWidth, /* The programs width */
gHeight, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */ );
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
UpdateWindow(hwnd);
//消息循环
MSG msg;
BOOL fMessage;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
while(msg.message != WM_QUIT){
fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
if(fMessage){
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{
//渲染窗口
game->RenderWindow();
}
}
return msg.wParam;
}
//消息回调函数
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) /* handle the messages */
{
case WM_CREATE:
hDc = GetDC(hwnd);
game->SetupFixelFormat(hDc);
break;
case WM_CLOSE:
game->Remove();
PostQuitMessage (0);
break;
case WM_SIZE:
game->InitWindow(gWidth,gHeight);
break;
case WM_KEYUP:
switch(wParam){
case VK_ESCAPE:
game->Remove();
PostQuitMessage(0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架