OPENGL2_基本框架

来源:互联网 发布:js foreach 跳出循环 编辑:程序博客网 时间:2024/06/05 02:03

一些概念

HDC:设备描述句柄(窗口着色描述表句柄),是WINDOWS的一种数据类型,HDC定义的变量指向一块内存,这块内存用来描述一个设备的相关的内容(设备描述表).

HGLRC:OpenGL渲染环境句柄(OpenGL渲染描述表句柄).所有OpenGL命令要通过HRC执行,每个使用OpenGL调用的线程必须有且只有一个当前渲染环境HRC,OpenGL通过渲染环境HRC与Windows窗口系统连接。单个窗口可以使用多个RC,但单一线程只能有一个当前RC.使一个RC成为当前RC需要3步:1设置窗口像素格式,2产生RC,3设置为当前RC.

GDI:Graphics Deveice Interface,图形设备接口.用GDI编程,可以不考虑硬件的具体特性,GDI函数都要求有一个HDC类型的句柄,可直接调用Windows API中的图形处理函数


GDI就是Windows自身api绘制函数,需要HDC,跟OpenGL无关。

而使用OpenGL API需要HRC,而HRC又需要和HDC绑定来连接OpenGL与Windows


框架概述

跟opengl和游戏相关的用蓝字

创建窗口

1定义windows类
2注册windows类
3设置全屏参数
4创建窗口
5设置当前HRC
   5.1设置窗口像素格式
                1定义窗口像素格式
                2从窗口获取HDC
                3使用HDC和之前定义的像素格式,在Windows中寻找匹配像素格式,并保存
                4设置像素格式
   5.2使用HDC创建HRC
   5.3激活渲染环境HRC(绑定HRC到HDC)
6显示窗口
7OpenGL初始化(设定Opengl视口等信息ReSizeGLScene(),设定Opengl初始环境InitGL())


主循环

1 事件消息处理
2 OpenGL渲染(在主循环中渲染而不在windows事件中渲染,更加灵活,适合游戏开发)


事件回调

按键按下获取按键值,窗口大小调整时调整opengl视口大小等


框架代码

以下使用的是nehe的opengl框架代码

引自http://www.yakergong.net/nehe/

#include "stdafx.h"#include "Nehe_Base.h"#include "GL.H"// Header File For The OpenGL32 Library#include "GLU.H"// Header File For The GLu32 Library#include "GLAUX.H"// Header File For The Glaux LibraryHDChDC=NULL;// Private GDI Device ContextHGLRChRC=NULL;// Permanent Rendering ContextHWNDhWnd=NULL;// Holds Our Window HandleHINSTANCEhInstance;// Holds The Instance Of The Applicationboolkeys[256];// Array Used For The Keyboard Routineboolactive=TRUE;// Window Active Flag Set To TRUE By Defaultboolfullscreen=TRUE;// Fullscreen Flag Set To Fullscreen Mode By DefaultLRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Declaration For WndProcGLvoid 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 ViewportglMatrixMode(GL_PROJECTION);// Select The Projection MatrixglLoadIdentity();// Reset The Projection Matrix<span style="white-space:pre"></span>//指定了观察的视景体// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);// Select The Modelview MatrixglLoadIdentity();// Reset The Modelview Matrix}int InitGL(GLvoid)// All Setup For OpenGL Goes Here{glShadeModel(GL_SMOOTH);// Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f);// Black BackgroundglClearDepth(1.0f);// Depth Buffer SetupglEnable(GL_DEPTH_TEST);// Enables Depth TestingglDepthFunc(GL_LEQUAL);// The Type Of Depth Testing To DoglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Really Nice Perspective Calculationsreturn TRUE;// Initialization Went OK}int DrawGLScene(GLvoid)// Here's Where We Do All The Drawing{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Clear Screen And Depth BufferglLoadIdentity();// Reset The Current Modelview Matrix// move back 5 units and rotate about all 3 axesglTranslatef(0.0, 0.0, -5.0f);glRotatef(0.0f, 1.0f, 0.0f, 0.0f);glRotatef(0.0f, 0.0f, 1.0f, 0.0f);glRotatef(0.0f, 0.0f, 0.0f, 1.0f);// lime greenish colorglColor3f(0.7f, 1.0f, 0.3f);// draw the triangle such that the rotation point is in the centerglBegin(GL_TRIANGLES);glVertex3f(1.0f, -1.0f, 0.0f);glVertex3f(-1.0f, -1.0f, 0.0f);glVertex3f(0.0f, 1.0f, 0.0f);glEnd();return TRUE;// Everything Went OK}GLvoid KillGLWindow(GLvoid)// Properly Kill The Window{if (fullscreen)// Are We In Fullscreen Mode?{ChangeDisplaySettings(NULL,0);// If So Switch Back To The DesktopShowCursor(TRUE);// Show Mouse Pointer}if (hRC)// Do We Have A Rendering Context?{if (!wglMakeCurrent(NULL,NULL))//2参数空则1参数被忽略,作用是尝试分离HRC与HDC// Are We Able To Release The DC And RC Contexts?{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC))// Are We Able To Delete The RC?{MessageBox(NULL,"Release Rendering Context Failed.","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,"Release Device Context Failed.","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,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hWnd=NULL;// Set hWnd To NULL}if (!UnregisterClass("OpenGL",hInstance))// Are We Able To Unregister Class{MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hInstance=NULL;// Set hInstance To NULL}}/*This Code Creates Our OpenGL Window.  Parameters Are:* *title- Title To Appear At The Top Of The Window* *width- Width Of The GL Window Or Fullscreen Mode* *height- Height Of The GL Window Or Fullscreen Mode* *bits- Number Of Bits To Use For Color (8/16/24/32)* *fullscreenflag- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)*/ BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){//当我们要求Windows为我们寻找相匹配的象素格式时,Windows寻找结束后将模式值保存在变量PixelFormat中。GLuintPixelFormat;// Holds The Results After Searching For A MatchWNDCLASSwc;// Windows Class StructureDWORDdwExStyle;// Window Extended StyleDWORDdwStyle;// Window StyleRECTWindowRect;// Grabs Rectangle Upper Left / Lower Right ValuesWindowRect.left=(long)0;// Set Left Value To 0WindowRect.right=(long)width;// Set Right Value To Requested WidthWindowRect.top=(long)0;// Set Top Value To 0WindowRect.bottom=(long)height;// Set Bottom Value To Requested Heightfullscreen=fullscreenflag;// Set The Global Fullscreen FlaghInstance= GetModuleHandle(NULL);// Grab An Instance For Our Windowwc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;// Redraw On Size, And Own DC For Window.wc.lpfnWndProc= (WNDPROC) WndProc;// WndProc Handles Messageswc.cbClsExtra= 0;// No Extra Window Datawc.cbWndExtra= 0;// No Extra Window Datawc.hInstance= hInstance;// Set The Instancewc.hIcon= LoadIcon(NULL, IDI_WINLOGO);// Load The Default Iconwc.hCursor= LoadCursor(NULL, IDC_ARROW);// Load The Arrow Pointerwc.hbrBackground= NULL;// No Background Required For GLwc.lpszMenuName= NULL;// We Don't Want A Menuwc.lpszClassName= "OpenGL";// Set The Class Nameif (!RegisterClass(&wc))// Attempt To Register The Window Class{MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (fullscreen)// Attempt Fullscreen Mode?{DEVMODE dmScreenSettings;// Device Modememset(&dmScreenSettings,0,sizeof(dmScreenSettings));// Makes Sure Memory's CleareddmScreenSettings.dmSize=sizeof(dmScreenSettings);// Size Of The Devmode StructuredmScreenSettings.dmPelsWidth= width;// Selected Screen WidthdmScreenSettings.dmPelsHeight= height;// Selected Screen HeightdmScreenSettings.dmBitsPerPel= bits;// Selected Bits Per PixeldmScreenSettings.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 Use Windowed Mode.if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){fullscreen=FALSE;// Windowed Mode Selected.  Fullscreen = FALSE}else{// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);return FALSE;// Return FALSE}}}if (fullscreen)// Are We Still In Fullscreen Mode?{dwExStyle=WS_EX_APPWINDOW;// Window Extended StyledwStyle=WS_POPUP;// Windows StyleShowCursor(FALSE);// Hide Mouse Pointer}else{dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// Window Extended StyledwStyle=WS_OVERLAPPEDWINDOW;// Windows Style}AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);// Adjust Window To True Requested Size// Create The Windowif (!(hWnd=CreateWindowEx(dwExStyle,// Extended Style For The Window"OpenGL",// Class Nametitle,// Window TitledwStyle |// Defined Window StyleWS_CLIPSIBLINGS |// Required Window StyleWS_CLIPCHILDREN,// Required Window Style0, 0,// Window PositionWindowRect.right-WindowRect.left,// Calculate Window WidthWindowRect.bottom-WindowRect.top,// Calculate Window HeightNULL,// No Parent WindowNULL,// No MenuhInstance,// InstanceNULL)))// Dont Pass Anything To WM_CREATE{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}//像素格式明确了OpenGL绘制平面的特性,如象素缓冲区是单缓冲还是双缓冲,数据是 RGBA方式还是Color Index方式等。//每个OpenGL显示设备一般用名为PIXELFORMATDESCRIPTOR的结构来表示某个的像素格式staticPIXELFORMATDESCRIPTOR pfd=// pfd Tells Windows How We Want Things To Be{sizeof(PIXELFORMATDESCRIPTOR),// Size Of This Pixel Format Descriptor1,// Version NumberPFD_DRAW_TO_WINDOW |// Format Must Support WindowPFD_SUPPORT_OPENGL |// Format Must Support OpenGLPFD_DOUBLEBUFFER,// Must Support Double BufferingPFD_TYPE_RGBA,// Request An RGBA Formatbits,// Select Our Color Depth0, 0, 0, 0, 0, 0,// Color Bits Ignored0,// No Alpha Buffer0,// Shift Bit Ignored0,// No Accumulation Buffer0, 0, 0, 0,// Accumulation Bits Ignored16,// 16Bit Z-Buffer (Depth Buffer)  0,// No Stencil Buffer0,// No Auxiliary BufferPFD_MAIN_PLANE,// Main Drawing Layer0,// Reserved0, 0, 0// Layer Masks Ignored};if (!(hDC=GetDC(hWnd)))// Did We Get A Device Context?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))// Did Windows Find A Matching Pixel Format?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Find A Suitable PixelFormat.","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 DisplayMessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(hRC=wglCreateContext(hDC)))// Are We Able To Get A Rendering Context?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if(!wglMakeCurrent(hDC,hRC))// Try To Activate The Rendering Context{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}ShowWindow(hWnd,SW_SHOW);// Show The WindowSetForegroundWindow(hWnd);// Slightly Higher PrioritySetFocus(hWnd);// Sets Keyboard Focus To The WindowReSizeGLScene(width, height);// Set Up Our Perspective GL Screenif (!InitGL())// Initialize Our Newly Created GL Window{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}return TRUE;// Success}LRESULT CALLBACK WndProc(HWNDhWnd,// Handle For This WindowUINTuMsg,// Message For This WindowWPARAMwParam,// Additional Message InformationLPARAMlParam)// 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);}int WINAPI WinMain(HINSTANCEhInstance,// InstanceHINSTANCEhPrevInstance,// Previous InstanceLPSTRlpCmdLine,// Command Line ParametersintnCmdShow)// Window Show State{MSGmsg;// Windows Message StructureBOOLdone = FALSE;// Bool Variable To Exit Loop// Ask The User Which Screen Mode They Preferif (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen = FALSE;// Windowed Mode}// Create Our OpenGL Windowif (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)){return 0;// Quit If Window Was Not Created}while(!done)// Loop That Runs While done=FALSE{if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))// Is There A Message Waiting?{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 MessageDispatchMessage(&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 SceneSwapBuffers(hDC);// Swap Buffers (Double Buffering)}}if (keys[VK_F1])// Is F1 Being Pressed?{keys[VK_F1]=FALSE;// If So Make Key FALSEKillGLWindow();// Kill Our Current Windowfullscreen=!fullscreen;// Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen)){return 0;// Quit If Window Was Not Created}}}}// ShutdownKillGLWindow();// Kill The Windowreturn (msg.wParam);// Exit The Program}


0 0
原创粉丝点击