vc+win32+opengl框架代码

重拾OpenGL,起步艰难。我发现自己也同胡老师一样了,学得快(当初花了一个国庆假就把基础都看完了)也忘得快。废话少说,进入正题。  

新建一个win32控制台程序。选择“空项目“以及在上面的“应用程序类型”里选择“Windows应用程序”。建立项目后再工程属性里设置“常规”下设置字符集为“多字节……”。然后再新建一个cpp文件,把以下代码拷贝进去运行就OK了。  

至于代码里的Windows窗口注册、消息循环机制等等,以及OpenGL里的窗口设置、初始化代码就自己理解吧。呵呵,欢迎一起交流,哎,自己忘得太快了。这次再次接触恐怕是30岁前都会记得了。  写下这篇文章的时候想着明天弟弟就要高考。只希望一切都好,考完那晚别太疯狂了。也别学他这没用的哥哥就是了。呵呵。

 

#include <windows.h>        //视窗头文件 #include <GL/gl.h> #include <GL/glu.h> #include <gl/glaux.h>

//定义程序中计划使用的所有变量 HWND   hWnd=NULL;            //得到窗口的句柄 HDC    hDC=NULL;             //私有的GDI设备环境 HGLRC hRC=NULL;             //定义渲染环境 HINSTANCE hInstance;        //建立一个程序的例子Instance(事件)

//设置窗口大小,斜率及全屏标志变量

RECT   rect; int   sw = 640; int   sh = 480; bool   fullscreen   = 1; GLfloat aspect;

#pragma comment( lib, "opengl32.lib" )    #pragma comment( lib, "glu32.lib" )     #pragma comment( lib, "glaux.lib" ) 

//OpenGL初始化开始 void SceneInit(int w,int h) {   glShadeModel(GL_SMOOTH);                             //允许平滑着色   glClearColor( 1.0, 1.0, 1.0, 0.5 );                  //设置屏幕清屏的颜色   glClearDepth(1.0f);                                  //设置深度缓冲区   glEnable(GL_DEPTH_TEST);                             //允许深度测试   glDepthFunc(GL_LEQUAL);                              //深度测试的类型   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //透视校正,会使透视效果显得更好一些 }

//窗口尺寸改变时OpenGL场景的尺寸 void SceneResizeViewport(GLsizei w, GLsizei h) {   if(h==0)   {     h=1;   }   aspect = (GLfloat)w/(GLfloat)h;

  //设置透视场景,透视的作用是景物距离越远其尺寸越小   glViewport(0, 0, w, h);   glMatrixMode(GL_PROJECTION);                     //选择投影矩阵   glLoadIdentity();

  gluPerspective( 45.0f, aspect, 0.1f, 100.0f );   //基于窗口的高和宽并以45度视角进行计算。0.1f和                                                    //100f是绘制在屏幕上相对于屏幕距离的开始点和结束点   glMatrixMode(GL_MODELVIEW);                      //确定任何新的变换都会影响模型视点矩阵ModelView   glLoadIdentity();                                //把被选择的矩阵还原到初始状态 }

void SceneShow(GLvoid)          //这里进行所有的绘图工作 {   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清屏和清除深度缓冲区   glLoadIdentity();                  //重置当前Modelview矩阵   //此处添加绘图命令 }    

//激活创建OpenGL窗口 void EnableOpenGL() {   PIXELFORMATDESCRIPTOR pfd;   int iFormat;

  hDC = GetDC( hWnd );

  ZeroMemory( &pfd, sizeof( pfd ) );   pfd.nSize = sizeof( pfd );   pfd.nVersion = 1;   pfd.dwFlags =    PFD_DRAW_TO_WINDOW |     PFD_SUPPORT_OPENGL |     PFD_DOUBLEBUFFER;   pfd.iPixelType = PFD_TYPE_RGBA;   pfd.cColorBits = 16;   pfd.cDepthBits = 16;   pfd.iLayerType = PFD_MAIN_PLANE;

  iFormat = ChoosePixelFormat( hDC, &pfd );

  SetPixelFormat( hDC, iFormat, &pfd );

  hRC = wglCreateContext( hDC );   wglMakeCurrent( hDC, hRC ); }

// 取消 OpenGL ,在程序结束前调用,释放渲染环境,设备环境以及最终窗口句柄。 void DisableOpenGL() {   wglMakeCurrent( NULL, NULL );   wglDeleteContext( hRC );   ReleaseDC( hWnd, hDC ); }

//改变屏幕的分辨率 bool ChangeResolution(int w, int h, int bitdepth) {   DEVMODE devMode;   int    modeSwitch;   int    closeMode = 0;

  EnumDisplaySettings(NULL, closeMode, &devMode);

  devMode.dmBitsPerPel = bitdepth;   devMode.dmPelsWidth   = w;   devMode.dmPelsHeight = h;   devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

  modeSwitch = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);

  if(modeSwitch == DISP_CHANGE_SUCCESSFUL)   {     return true;   }   else   {     ChangeDisplaySettings(NULL, 0);     return false;   } }

//处理窗口信息 LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {   switch ( message )                             //将message设置为所有事件声明比较的     //值,message将得到要处理的消息的名字   {   case WM_CREATE:                                    //监视窗口激活的信息     GetWindowRect(hWnd, &rect);     sw = rect.right - rect.left;     sh = rect.bottom - rect.top;     SceneResizeViewport(sw, sh);     return 0;

  case WM_SIZE:                                      //改变OpenGL窗口的尺寸。

    if(!fullscreen)     {       GetWindowRect(hWnd, &rect);       sw = rect.right - rect.left;       sh = rect.bottom - rect.top;       if(sw>0 && sh>0)         SceneResizeViewport(sw, sh);     }     else     {       SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),         GetSystemMetrics( SM_CYSCREEN ));     }

    return 0;

  case WM_CLOSE:                                                 //是否收到一个关闭信息?     ShowWindow (hWnd, SW_HIDE);     PostQuitMessage( 0 );     return 0;

  case WM_DESTROY:     return 0;

  case WM_KEYDOWN:                                                //是否有一个键被按下?     switch( wParam )     {     case VK_ESCAPE:       PostMessage(hWnd, WM_CLOSE, 0, 0);       break;     }     return 0;   default:     return DefWindowProc( hWnd,message, wParam, lParam );        //一些无须在意的信息视窗自己处理   } }

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {   WNDCLASS wc;               //窗口类   MSG msg;                   //检测是否有信息在等待处理   bool bQuit = false;        //bQuit为FLASE,程序当前在运行;为TRUE程序将退出

  //询问选择那种屏幕模式   if (MessageBox(NULL,"是否选择全屏显示模式?", "全屏模式运行?",MB_YESNO|MB_ICONQUESTION)==IDNO)   {     fullscreen=0;        //窗口模式   }   //创建OpenGL窗口,设置标题、宽高及颜色数   wc.style = CS_OWNDC;   wc.lpfnWndProc = WndProc;   wc.cbClsExtra = 0;   wc.cbWndExtra = 0;   wc.hInstance = hInstance;   wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );   wc.hCursor = LoadCursor( NULL, IDC_ARROW );   wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );   wc.lpszMenuName = NULL;   wc.lpszClassName = "Name";   RegisterClass( &wc );

  if(fullscreen)   {     ChangeResolution(640, 480, 16);     hWnd = CreateWindow(       "Name",       "Sink",       WS_POPUP |   WS_CLIPSIBLINGS | WS_VISIBLE,       0, 0,       GetSystemMetrics( SM_CXSCREEN ),       GetSystemMetrics( SM_CYSCREEN ),       NULL, NULL,       hInstance,       NULL );   }   else   {     hWnd = CreateWindow(       "Name",       "Sink",       WS_TILEDWINDOW | WS_VISIBLE,       GetSystemMetrics( SM_CXSCREEN )/2-sw/2,       GetSystemMetrics( SM_CYSCREEN )/2-sh/2,       sw,       sh,       NULL, NULL,       hInstance,       NULL );     ChangeDisplaySettings(NULL, 0);   }   ShowWindow(hWnd, SW_SHOW);   UpdateWindow(hWnd);

  //初始化   EnableOpenGL();   SceneInit(sw, sh);

  if(!fullscreen)   {     GetWindowRect(hWnd, &rect);     sw = rect.right - rect.left;     sh = rect.bottom - rect.top;     if(sw>0 && sh>0)       SceneResizeViewport(sw, sh);   }   else   {     SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),       GetSystemMetrics( SM_CYSCREEN ));   }

  //下面开始循环,如果bQuit的值一直是FLASE,循环将一直重复下去   while ( !bQuit )   {     if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )     //通过PeekMessage(),检测是否有消息       //在等待,又不会使程序挂起       if ( msg.message == WM_QUIT )                        //检测是否有退出消息发出                        bQuit = true;       else       {         TranslateMessage( &msg );//如果消息不是退出,使得WndProc()或窗口能处理它         DispatchMessage( &msg );       }     else     {

      // OpenGL 动画,如果程序被激活并且ESC没有被按下,可以渲染场景及交换缓冲区(通过使用       //双缓冲区可获得平滑运动的动画)       //通过使用双缓存,先在不可见的隐藏屏幕上绘制,当交换缓冲区时,隐藏屏幕变为可见屏幕,       //原先可见的屏幕变为隐藏,这样       //就看不到屏幕被绘制的过程,画面会马上出现,这样看上去会更真实。

      SceneShow();       SwapBuffers(hDC);

    }   }

  //关闭,退出程序。清除OpenGL窗口,以便释放所有资源,然后退出程序。   DisableOpenGL();

  ShowWindow (hWnd, SW_HIDE);   DestroyWindow( hWnd );

  ChangeDisplaySettings(NULL, 0);

  return msg.wParam;

  return 0; }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值