NeHe_001_创建一个OpenGL窗口
从几个星期前开始学习OpenGL,因为项目的需要。有幸刚开始就知道了NeHe,以及他的OpenGL教程。于是上他的官网,一课一课的学下去。到现在,虽然学得不多,但已经能够应付需要。仅从这一点来说,NeHe是一个伟大的人。我由衷的向他致敬。
NeHe的官网是http://nehe.gamedev.net/
到目前为止,我从来没有读过一个教程解释细致到NeHe的水平,他用简单的语言把一个小孩引入了OpenGl的殿堂。如果英语不是很差的话,建议上他的官网学习,会得到很多。
第一课讲了怎样利用windows api建立一个OpenGL编程窗口。
代码如下,所有的代码都在vs2008下调试通过。
#include<windows.h>//vs2008,windows.h has glaut.h#include<tchar.h>#include <gl\gl.h>#include <gl\glu.h>#pragma comment(lib,"opengl32.lib")#pragma comment(lib,"glu32.lib")
HGLRC hRC=NULL; // Permanent Rendering ContextHDC hDC=NULL; // Private GDI Device ContextHWND hWnd=NULL; // Holds Our Window HandleHINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routinebool active=TRUE; // Window Active Flag Set To TRUE By Defaultbool fullscreen=FALSE; // no Fullscreen Flag Set To Fullscreen Mode By Default
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window{if (height==0) // Prevent A Divide By Zero By { height=1; // Making Height Equal One } glViewport(0, 0, width, height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix}//end of ReSizeGLScene
int InitGL(GLvoid) // All Setup For OpenGL Goes Here{ glShadeModel(GL_SMOOTH); // Enables Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Really Nice Perspective Calculations
return TRUE; // Initialization Went OK}//end of InitGL
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The Current Modelview Matrix
////TODO:the code of openGL//
return TRUE; // Everything Went OK}//end of DrawGLScene
GLvoid KillGLWindow(GLvoid) // Properly Kill The Window{if (fullscreen) // Are We In Fullscreen Mode? { ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop ShowCursor(TRUE); // Show Mouse Pointer }if (hRC) // Do We Have A Rendering Context? {if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? { MessageBox(NULL,_T("Release Of DC And RC Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION); }if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? { MessageBox(NULL,_T("Release Rendering Context Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION); } hRC=NULL; // Set RC To NULL }if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC { MessageBox(NULL,_T("Release Device Context Failed."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION); hDC=NULL; // Set DC To NULL }if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window? { MessageBox(NULL,_T("Could Not Release hWnd."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION); hWnd=NULL; // Set hWnd To NULL }if (!UnregisterClass(_T("OpenGL"),hInstance)) // Are We Able To Unregister Class { MessageBox(NULL,_T("Could Not Unregister Class."),_T("SHUTDOWN ERROR"),MB_OK | MB_ICONINFORMATION); hInstance=NULL; // Set hInstance To NULL }}//end of KillGLWindow
BOOL CreateGLWindow(TCHAR * title, int width, int height, int bits, bool fullscreenflag){ GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class Structure DWORD dwExStyle; // Window Extended Style DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left=(long)0; // Set Left Value To 0 WindowRect.right=(long)width; // Set Right Value To Requested Width WindowRect.top=(long)0; // Set Top Value To 0 WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag hInstance= GetModuleHandle(NULL);// Grab An Instance For Our Window wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages wc.cbClsExtra = 0; // No Extra Window Data wc.cbWndExtra = 0; // No Extra Window Data wc.hInstance = hInstance; // Set The Instance wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);// Load The Default Icon wc.hCursor = LoadCursor(NULL, IDC_ARROW);// Load The Arrow Pointer wc.hbrBackground = NULL; // No Background Required For GL wc.lpszMenuName = NULL; // We Don't Want A Menu wc.lpszClassName = _T("OpenGL"); // Set The Class Nameif (!RegisterClass(&wc)) // Attempt To Register The Window Class { MessageBox(NULL,_T("Failed To Register The Window Class."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Exit And Return FALSE }if (fullscreen) // Attempt Fullscreen Mode? { DEVMODE dmScreenSettings; // Device Mode memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared dmScreenSettings.dmSize = sizeof(dmScreenSettings); // Size Of The Devmode Structure dmScreenSettings.dmPelsWidth = width;// Selected Screen Width dmScreenSettings.dmPelsHeight = height;// Selected Screen Height dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) {// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.if (MessageBox(NULL,_T("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),_T("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { fullscreen=FALSE; // Select Windowed Mode (Fullscreen=FALSE) }else {// Pop Up A Message Box Letting User Know The Program Is Closing. MessageBox(NULL,_T("Program Will Now Close."),_T("ERROR"),MB_OK|MB_ICONSTOP);return FALSE; // Exit And Return FALSE } } }if (fullscreen) // Are We Still In Fullscreen Mode? { dwExStyle=WS_EX_APPWINDOW; // Window Extended Style dwStyle=WS_POPUP; // Windows Style ShowCursor(FALSE); // Hide Mouse Pointer }else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// Window Extended Style dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Sizeif (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window _T("OpenGL"), // Class Name title, // Window Title WS_CLIPSIBLINGS |// Required Window Style WS_CLIPCHILDREN |// Required Window Style dwStyle, // Selected Window Style 0, 0, // Window Position WindowRect.right-WindowRect.left, // Calculate Adjusted Window Width WindowRect.bottom-WindowRect.top, // Calculate Adjusted Window Height NULL, // No Parent Window NULL, // No Menu hInstance, // Instance NULL))) // Don't Pass Anything To WM_CREATE { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Window Creation Error."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be {sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format bits, // Select Our 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, // Accumulation Bits Ignored 16, // 16Bit Z-Buffer (Depth Buffer) 0, // No Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored };if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context? { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Can't Create A GL Device Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format? { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Can't Find A Suitable PixelFormat."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format? { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Can't Set The PixelFormat."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Can't Create A GL Rendering Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Can't Activate The GL Rendering Context."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }
ShowWindow(hWnd,SW_SHOW); // Show The Window SetForegroundWindow(hWnd); // Slightly Higher Priority SetFocus(hWnd); // Sets Keyboard Focus To The Window ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window { KillGLWindow(); // Reset The Display MessageBox(NULL,_T("Initialization Failed."),_T("ERROR"),MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }return TRUE; // Success}//end of CreateGLWindow
LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window UINT uMsg, // Message For This Window WPARAM wParam, // Additional Message Information LPARAM lParam) // Additional Message Information{switch (uMsg) // Check For Windows Messages {case WM_ACTIVATE: // Watch For Window Activate Message {if (!HIWORD(wParam)) // Check Minimization State { active=TRUE; // Program Is Active }else { active=FALSE; // Program Is No Longer Active }return 0; // Return To The Message Loop }case WM_SYSCOMMAND: // Intercept System Commands {switch (wParam) // Check System Calls {case SC_SCREENSAVE: // Screensaver Trying To Start?case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?return 0; // Prevent From Happening }break; // Exit }case WM_CLOSE: // Did We Receive A Close Message? { PostQuitMessage(0); // Send A Quit Messagereturn 0; // Jump Back }case WM_KEYDOWN: // Is A Key Being Held Down? { keys[wParam] = TRUE; // If So, Mark It As TRUEreturn 0; // Jump Back }case WM_KEYUP: // Has A Key Been Released? { keys[wParam] = FALSE; // If So, Mark It As FALSEreturn 0; // Jump Back }case WM_SIZE: // Resize The OpenGL Window { ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Heightreturn 0; // Jump Back } }// Pass All Unhandled Messages To DefWindowProcreturn DefWindowProc(hWnd,uMsg,wParam,lParam);}//end of WndProc
int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parametersint nCmdShow) // Window Show State{ MSG msg; // Windows Message Structure BOOL done=FALSE; // Bool Variable To Exit Loop// Ask The User Which Screen Mode They Preferif (MessageBox(NULL,_T("Would You Like To Run In Fullscreen Mode?"),_T( "Start FullScreen?"),MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; // Windowed Mode }else { fullscreen=TRUE; }// Create Our OpenGL Windowif (!CreateGLWindow(_T("NeHe's OpenGL Framework"),640,480,16,fullscreen)) {return 0; // Quit If Window Was Not Created }while(!done) // Loop That Runs Until done=TRUE {if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))// Is There A Message Waiting? {//The first thing we have to do is check to see if any window messages are waiting. //By using PeekMessage() we can check for messages without halting our program. //A lot of programs use GetMessage(). It works fine, but with GetMessage() //your program doesn't do anything until it receives a paint message or some other window message. if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=TRUE; // If So done=TRUE }else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } }else // If There Are No Messages {// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()if (active) // Program Active? {if (keys[VK_ESCAPE]) // Was ESC Pressed? { done=TRUE; // ESC Signalled A Quit }else // Not Time To Quit, Update Screen { DrawGLScene(); // Draw The Scene SwapBuffers(hDC);// Swap Buffers (Double Buffering) } }if (keys[VK_F1]) // Is F1 Being Pressed? { keys[VK_F1]=FALSE; // If So Make Key FALSE KillGLWindow(); // Kill Our Current Window fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow(_T("NeHe's OpenGL Framework"),640,480,16,fullscreen)) {return 0; // Quit If Window Was Not Created } } }//else }//while// Shutdown KillGLWindow(); // Kill The Windowreturn (msg.wParam); // Exit The Program}//end of WinMain
转载于:https://www.cnblogs.com/afarmer/archive/2009/11/25/1610909.html
NeHe_001_创建一个OpenGL窗口相关推荐
- OpenGL创建一个GLFW窗口的实例
OpenGL创建一个GLFW窗口 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include < ...
- python生成一个窗口_PyQt5创建一个新窗口的实例
更多python教程请到友情连接: 菜鸟教程www.piaodoo.com 人人影视www.sfkyty.com 飞卢小说网www.591319.com 韩剧网www.op-kg.com 兴化论坛ww ...
- python自动关闭弹窗_python – 每隔x分钟创建一个tkinter窗口,然后在y秒后自动关闭它...
我正在尝试构建一个简单的程序来提醒我在使用计算机时休息一下.我对 python有一个合理的理解,但以前从未玩过GUI编程或线程,所以以下基本上是从stackoverflow复制/粘贴: import ...
- c#窗体程序生成错误_创建一个没有窗口的程序 (C#) | 学步园
为了创建一个主窗口不显示的应用程序,我做了若干个探索.结果绕了几个弯,回到最简朴的没有窗体的世界中. 由此发现,我已经对窗体设计器产生了严重的依赖性,而且自已已经懒得不得了了--哪怕只有几行的代码,也 ...
- 利用c语言在屏幕上画出窗口,第一课:创建一个windows窗口
跟我一起学图形编程 作者:姚明联系方式: 欢迎使用我的图形学教程.我是计算机专业的学生,对图形图像技术有浓厚的兴趣,就读期间广泛的涉及相关知 ...
- 【OpenGL从入门到精通(一)】Windows搭建OpenGL的渲染环境,并初始化一个OPenGL窗口
注意:需要在Windows 窗口程序下,而不能是控制台程序,Windows平台的VS下已经包含了OpenGL相关的API,可以直接引用 #include <windows.h> #incl ...
- 在C#中使用Ribbon界面(一)——创建一个Ribbon窗口
自Office2007开始,软件都逐渐地采用了Ribbon界面,一方面是时尚,如同许多厂商声称的那样,是 state of arts,另外,通过调查表明,Ribbon界面比传统的下拉栏菜单方式的工作效 ...
- 【C#桌面应用】第三节:创建一个按钮窗口 您好,世界!
步骤一.选择左侧菜单中的工具箱 将其拖拽到我们的窗口中 步骤二.改变按钮的文字信息,这里我们修改成,点击弹出你好,世界. 步骤三.双击按钮,进入代码编辑界面,开始写入您好世界 步骤四.您好世界的代码实 ...
- OPenGL笔记--创建一个3D场景
文章目录 一.前言 二.效果展示 三.详细流程 3.1.World.txt文件规则 3.2.加载World.txt 3.3.绘制场景 3.4.交互 四.详细代码 五.举一反三 一.前言 通过前面的学习 ...
最新文章
- java注解返回不同消息,Spring MVC Controller中的一个读入和返回都是JSON的方法如何获取javax.validation注解的异常信息...
- [转载]“java.sql.SQLException:指定了无效的 Oracle URL”
- Linux 系统调用(一)
- mysql中00933错误_ORA-00933: SQL command not properly ended
- opencv java 摄像头_使用OpenCV Java创建Windows摄像头扫码程序
- Visual Studio 2017 15.9预览版3支持ARM64 for UWP
- 基于Fragment的百度地图框架的使用
- 计算机组成原理 第二章 数据的表示与运算
- 看mysql手册中模式(SQL_MODE)学到的知识
- 水电图纸——安装配电箱,插座——3.8
- python实现误差逆传播算法
- Red Hat Linux 9.0 网络服务入门
- pyqt5标签中的字设置不同字体_PyQt5 控件字体样式等设置的实现
- HDU6078	Wavel Sequence
- 叁-拾玖|c++入门笔记
- 【愚公系列】2022年11月 uniapp专题-优购电商-商品列表
- Java 读取Word表格中的文本和图片
- 软件需求——需求规格说明书模版(三)
- 比较原始的QQ大家来找茬的原型
- 自动控制原理->一些内容的概括了解