OpenGL编程-OpenGL框架-win32项目

时间:2024-04-28 11:37:42

在win32项目中开发的程序

小知识: 控制台应用程序运行就是dos的界面 项目一般采用了可视化开发 开发出来的东西就像QQ之类的 是有窗口界面的

程序运行结果是这样的

OpenGL编程-OpenGL框架-win32项目

源代码:对第45行进行覆盖

 #include <windows.h>     //Windows的头文件
#include <gl\gl.h> //包含OpenGL基本库
#include <gl\glu.h> //包含OpenGL实用库
#include <gl\glaux.h> //包含OpenGL辅助库
#include <gl\glut.h> //包含OpenGL工具库
//设置程序中使用的所有变量
HGLRC hRC = NULL; //OpenGL着色描述表句柄
HDC hDC = NULL; //设备描述表句柄
HWND hWnd = NULL; //保存窗口句柄
HINSTANCE hInstance; //保存程序的实例
//增加两个全局变量来控制这两个对象的旋转。
GLfloat rtri; //用于三角形的角度
GLfloat rquad; //用于四边形的角度 bool keys[]; //保存键盘按键的数组
bool active = TRUE; //口的活动标志,缺省为TRUE
bool fullscreen = TRUE; //全屏标志缺省,缺省设定成全屏模式
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //WndProc定义
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) //重置OpenGL窗口大小
{
if (height == ) //防止被零除
{
height = ;
} //将Height设为
glViewport(, , width, height); //重置当前的视口
glMatrixMode(GL_PROJECTION); //选择投影矩阵
glLoadIdentity(); //重置投影矩阵
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f); //设置视景体
glMatrixMode(GL_MODELVIEW); //选择模型观察矩阵
glLoadIdentity(); //重置模型观察矩阵
}
int InitGL(GLvoid) //开始对OpenGL进行所有设置
{
glShadeModel(GL_SMOOTH); //启用阴影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //黑色背景
glClearDepth(1.0f); //设置深度缓存
glEnable(GL_DEPTH_TEST); //启用深度测试
glDepthFunc(GL_LEQUAL);//所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //告诉系统对透视进行修正
return TRUE; //初始化OK
} //将这段代码覆盖之后,往里面添加东西。就能进行OpenGL int DrawGLScene(GLvoid) //开始进行所有的绘制
{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
glLoadIdentity(); //重置当前的模型观察矩阵
return TRUE; } // 一切OK GLvoid KillGLWindow(GLvoid) //正常销毁窗口
{
if (fullscreen) { //处于全屏模式吗?
ChangeDisplaySettings(NULL, ); //切回桌面
ShowCursor(TRUE);
} //显示鼠标指针
if (hRC) { //拥有OpenGL着色描述表吗?
if (!wglMakeCurrent(NULL, NULL)) {
//能否释放DC和RC描述表?
MessageBox(NULL, "释放DC和RC失 败。", "关闭错误", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)){ //能否删除RC?
MessageBox(NULL, "释放RC失 败。", "关闭错误", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;
} //将RC设为NULL
if (hDC && !ReleaseDC(hWnd, hDC)) {
//能否释放DC?
MessageBox(NULL, "释放DC失败。", "关闭错误", MB_OK | MB_ICONINFORMATION);
hDC = NULL;
} //将DC设为NULL
if (hWnd && !DestroyWindow(hWnd)) {
//能否销毁窗口?
MessageBox(NULL, "释放窗口句柄失 败。", "关闭错误", MB_OK | MB_ICONINFORMATION);
hWnd = NULL;
} //将hWnd设为NULL
if (!UnregisterClass("OpenGL", hInstance)) {
//能否注销类?
MessageBox(NULL, "不能注销窗口类 。", " 关闭错误", MB_OK | MB_ICONINFORMATION);
hInstance = NULL;
}
} //hInstance为NULL
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; //保存查找匹配的结果
WNDCLASS wc; //窗口类结构
DWORD dwExStyle; //扩展窗口风格
DWORD dwStyle; //窗口风格
RECT WindowRect; //取得矩形的左上角和右下角的坐标值
WindowRect.left = (long); //将Left 设为
WindowRect.right = (long)width; //将Right设为要求的宽度
WindowRect.top = (long); //将Top设为0
WindowRect.bottom = (long)height; //将Bottom设为要求的高度
fullscreen = fullscreenflag; //设置全局全屏标志
hInstance = GetModuleHandle(NULL); //取得窗口实例
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //移动时重画,为窗口取得DC
wc.lpfnWndProc = (WNDPROC)WndProc; //WndProc处理消息
wc.cbClsExtra = ; //窗口类额外字节数
wc.cbWndExtra = ; //窗口实例额外字节数
wc.hInstance = hInstance; //设置实例
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); //装入缺省图标
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //装入鼠标指针
wc.hbrBackground = NULL; //GL不需要背景
wc.lpszMenuName = NULL; //不需要菜单
wc.lpszClassName = "OpenGL"; //设定类名字
if (!RegisterClass(&wc)) //尝试注册窗口类
{
MessageBox(NULL, "注册窗口失败。", " 错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; //退出并返回FALSE
}
if (fullscreen) //要尝试全屏模式吗?
{
DEVMODE dmScreenSettings; //设备模式
memset(&dmScreenSettings, , sizeof(dmScreenSettings)); //确保内存为零
dmScreenSettings.dmSize = sizeof(dmScreenSettings); //Devmode结构大小
dmScreenSettings.dmPelsWidth = width; //所选屏幕宽度
dmScreenSettings.dmPelsHeight = height; //所选屏幕高度
dmScreenSettings.dmBitsPerPel = bits; //每像素所选的色彩深度 dmScreenSettings.dmFields= DM_BITSPERPEL|DM_PELSWIDTH| DM_PELSHEIGHT;
//尝试设置显示模式并返回结果。
//注: CDS_FULLSCREEN 移去了状态条。
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
//若模式失败,退出或在窗口内运行
if (MessageBox(NULL, "全屏模式在当前 显卡上设置失败!使用窗口模式? ", "OpenGL程序", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
{
fullscreen = FALSE; //选择窗口模式
}
else {
//弹出对话框告诉用户程序结束
MessageBox(NULL, "程序将被关 闭。", "错误", MB_OK | MB_ICONSTOP);
return FALSE; // 退出并返回FALSE
}
}
}
if (fullscreen) //仍处于全屏模式吗?
{
dwExStyle = WS_EX_APPWINDOW; //扩展窗体风格
dwStyle = WS_POPUP; //窗体风格
ShowCursor(FALSE); //隐藏鼠标指针
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; //扩展窗体风格
dwStyle = WS_OVERLAPPEDWINDOW; // 窗体风格
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); //调整窗口到要求大小
if (!(hWnd = CreateWindowEx(dwExStyle, //扩展窗体风格
"OpenGL", //类名字
title, //窗口标题
WS_CLIPSIBLINGS | //必须窗体风格属性
WS_CLIPCHILDREN |//必须窗体风格属性
dwStyle, //选择的窗体属性
, , //窗口位置
WindowRect.right - WindowRect.left, //计算调整好的窗口宽度
WindowRect.bottom - WindowRect.top, //计算调整好的窗口高度
NULL, //无父窗口
NULL, //无菜单
hInstance, //实例
NULL))) //不向WM_CREATE传任何东西
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "创建窗口失败。", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
} //返回FALSE
static PIXELFORMATDESCRIPTOR pfd = //pfd 告诉窗口使用的像素格式
{
sizeof(PIXELFORMATDESCRIPTOR), //上述格式描述符的大小
, //版本号
PFD_DRAW_TO_WINDOW | //格式支持窗口
PFD_SUPPORT_OPENGL | //格式必须支持OpenGL
PFD_DOUBLEBUFFER, //必须支持双缓冲
PFD_TYPE_RGBA, //申请RGBA 格式
bits, //选定色彩深度
, , , , , , //忽略的色彩位
, //无Alpha缓存
, //忽略Shift Bit
, //无累加缓存
, , , , //忽略聚集位
, //16位Z-缓存(深度缓存)
, //无模板缓存
, //无辅助缓存
PFD_MAIN_PLANE, //主绘图层
, //Reserved
, , //忽略层遮罩
};
if (!(hDC = GetDC(hWnd))) //获取设备描述表?
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "不能创建GL设备描 述表。", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
} //返回FALSE
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) //Windows找到相应像素格式了吗?
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "不能创建一种相匹配 的像素格式。", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
} //返回FALSE
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) //能够设置象素格式么?
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "不能设置像素格式。 ", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; //返回FALSE
}
if (!(hRC = wglCreateContext(hDC))) //能否取得着色描述表?
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "不能创建着色描述 表。", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
} //返回FALSE
if (!wglMakeCurrent(hDC, hRC)) //尝试激活着色描述表
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "不能激活当前的 OpenGL着色描述表。", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
} //返回FALSE
ShowWindow(hWnd, SW_SHOW);//显示窗口
SetForegroundWindow(hWnd); //稍微提高优先级
SetFocus(hWnd); //设置键盘的焦点至此窗口
ReSizeGLScene(width, height); //设置透视GL 屏幕
if (!InitGL()) //初始化新建的GL窗口
{
KillGLWindow(); //重置显示区
MessageBox(NULL, "初始化失败。", "错误 ", MB_OK | MB_ICONEXCLAMATION);
return FALSE; //返回FALSE
}
return TRUE; //成功
}
LRESULT CALLBACK WndProc(
HWND hWnd, //窗口的句柄
UINT uMsg, //窗口的消息
WPARAM wParam, //附加的消息内容
LPARAM lParam) //附加的消息内容
{
switch (uMsg) { //检查Windows消息
case WM_ACTIVATE: //监视窗口激活消息
{
if (!HIWORD(wParam)) //检查最小化状态
{
active = TRUE;
} //程序处于激活状态
else
{
active = FALSE;
} //程序不再激活
return ; //返回消息循环
}
case WM_SYSCOMMAND: //系统中断命令
{
switch (wParam) { //检查系统调用
case SC_SCREENSAVE: //屏保要运行?
case SC_MONITORPOWER: //显示器要进入节电模式?
return ;
} //阻止发生
break; //退出
}
case WM_CLOSE: //收到Close消息?
{
PostQuitMessage(); //发出退出消息
return ; //返回
}
case WM_KEYDOWN: //有键按下么?
{
keys[wParam] = TRUE; //若是设为TRUE
return ; //返回
}
case WM_KEYUP: //有键放开么?
{
keys[wParam] = FALSE;//是则设为FALSE
return ; //返回
}
case WM_SIZE: //调整OpenGL窗口大小
{
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
//LoWord=Width,HiWord=Height
return ; //返回
}
}
//向DefWindowProc传递所有未处理的消息。
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(
HINSTANCE hInstance, //当前窗口实例
HINSTANCE hPrevInstance, //前一个窗口实例
LPSTR lpCmdLine, //命令行参数
int nCmdShow) //窗口显示状态
{
MSG msg; //Windowsx消息结构
BOOL done = FALSE; //退出循环的Bool变量
//提示用户选择运行模式
if (MessageBox(NULL, "你想在全屏模式下运 行吗?", "设置全屏模式?", MB_YESNO | MB_ICONQUESTION) == IDNO)
{
fullscreen = FALSE; //FALSE为窗口模式
}
//创建OpenGL窗口
if (!CreateGLWindow("OpenGL程序框架", , , , fullscreen))
{
return ; //失败退出
}
while (!done) //保持循环直到done=TRUE
{
if (PeekMessage(&msg, NULL, , , PM_REMOVE)) //有消息在等待吗?
{
if (msg.message == WM_QUIT)
//收到退出消息?
{
done = TRUE; //是则done=TRUE
}
else //不是,处理窗口消息
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg); //发送消息
}
}
else //如果没有消息
{
//绘制场景。监视ESC键和来自 //的退出消息,然后调用DrawGLScene()
if (active) //程序激活的么?
{
if (keys[VK_ESCAPE])//ESC按下么?
{
done = TRUE; //ESC发退出信号
}
else //不是退出的时候,刷新屏幕
{
DrawGLScene(); //绘制场景
SwapBuffers(hDC); //交换缓存(双缓存)
}
}
if (keys[VK_F1]) //F1键按下了么?
{
keys[VK_F1] = FALSE; //若是,使对应的Key数组中的值为FALSE
KillGLWindow(); //销毁当前窗口
fullscreen = !fullscreen; //切换全屏/窗口模式
//重建OpenGL 窗口
// if (!CreateGLWindow("OpenGL程 序框架",640,480,16,fullscreen))
// {
// return 0; //如果窗口未能创建,程序退出
// }
// }
if (!CreateGLWindow("绘制基本图元", , , , fullscreen))
{
return ; //若窗口未能创建程序退出
}
} }
}
//关闭程序
KillGLWindow(); //销毁窗口
return (msg.wParam); //退出程序
}