win32编程教程:Win32 OpenGL 编程(1)Win32下的OpenGL编程必须步骤

  、   前言

  人生在于折腾继续折腾吧OpenGL编程红宝书OpenGL Programming Guide在举例子时候为了平台无关使用都是GLUT来管理窗口个人感觉不爽-_-! 要是针对Windows平台个人倾向使用Win32(MFC也行)要是跨平台我还会Qt嘛Qt对OpenGL也有很好支持为啥还折腾个新窗口管理组件?虽然说GLUT比较简单但是还是不喜欢扭曲适应的何况我去看了下GLUT这个东西最新版本都是2001年发布什么古董级家伙啊更加不想用了还是在Windows平台上学习OpenGL吧刚开始这样想就这样做了结果比我想象稍微复杂原来不光是熟悉Win32 API就能随便搞掂当时还看到有人专门为此写了篇论文-_-!(不知道学历)吓到我了没有那么高学术研究价值吧?后来又看到3个研究生都开始为此写论文了(这还真是研究院中人写)感叹不已

   2、   提要

  本文主要介绍Win32下OpenGL编程需要些操作以Andre LaMothe T3D Game Console为Win32框架实现个Win32下OpenGL游戏编程框架以参考资料2为蓝本实现些OpenGL举例以后讲解围绕此框架展开本文假设读者已经具备基本Win32编程知识不讲解Win32编程中固有要素需要了解Win32编程建议学习Charles PetzoldProgramming Windows

   3、   Win32下OpenGL编程需要操作步骤

  全部源代码见我放在Google Code上blog-sample-code中2009-9-27\Win32OpenGLTemplate目录取回方式见本文最后介绍说明

  下面会用到全局变量:

// GLOBALS ////////////////////////////////////////////////
HWND      ghWnd; // 窗口句柄
HINSTANCE ghInstance; // 例子句柄
HDC ghDC;                             // GDI设备环境句柄
HGLRC ghRC;           // 渲染环境句柄


  1.      头文件

# <windows.h>
// OpenGL需要头文件
# <GL/gl.h>
# <GL/glu.h>


  需要注意就是必须先包含Windows.h然后才能包含gl.h和glu.hgl.h和glu.h中可能包含Windows.h中定义

  2.      链接库

  此步完全可以通过功能配置来完成需要包含库为opengl32.lib何glu32.lib事实上为了方便可以通过如下语句来完成(VC特有特性)但是我们讨论是Win32下OpenGL这样也能接受了

//定义链接时所需要OpenGL库,简化工程配置
#pragma comment( lib, "opengl32.lib" )
#pragma comment( lib, "glu32.lib" ) 


  3.      像素格式(Pixel Format)设置

  需要用到原型:

 ChoosePixelFormat(
  HDC  hdc,  // device context to search for a best pixel format 
             // match
  CONST PIXELFORMATDESCRIPTOR *  ppfd 
             // pixel format for which a best match is sought
);
 
BOOL SetPixelFormat(
  HDC  hdc,  // device context whose pixel format the function 
             // attempts to 
    iPixelFormat,
             // pixel format index (one-based)
  CONST PIXELFORMATDESCRIPTOR *  ppfd 
             // poer to logical pixel format specication
);


  这是Win32下OpenGL编程必做事情的为DC设置像素格式

//设置像素格式
       PIXELFORMATDESCRIPTOR pfd;
        iFormat;
 
       ghDC = GetDC( ghWnd );
 
       ZeroMemory( &pfd, ( pfd ) );
       pfd.nSize = ( pfd ); 
       pfd.nVersion = 1;      //版本般设为
       pfd.dwFlags =   PFD_DRAW_TO_WINDOW | //组表明象素缓冲特性标志位
              PFD_SUPPORT_OPENGL;
       pfd.iPixelType = PFD_TYPE_RGBA;   //明象素数据类型是RGBA还是颜色索引;
       pfd.cColorBits = 32;     //每个颜色缓冲区中颜色位平面数目对颜色索引方式是缓冲区大小
       pfd.iLayerType = PFD_MAIN_PLANE; //被忽略为了致性而包含
 
       iFormat = ChoosePixelFormat( ghDC, &pfd );//选择个像素格式
 
       SetPixelFormat( ghDC, iFormat, &pfd ); //设置到DC中


  这样完成了像素格式设置事实上还可以进行更多操作比如设置缓冲区等下面代码就是个设置双重缓冲区代码

PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, ( pfd ) );
pfd.nSize = ( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
              PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
 iFormat = ChoosePixelFormat( hDC, &pfd );
SetPixelFormat( hDC, iFormat, &pfd );


  具体每个参数意义最好还是去查查MSDN啦查看PIXELFORMATDESCRIPTOR结构解释就行

  4.      渲染器环境(Render Context)创建

  wglCreateContext和wglMakeCurrent这两个都是Windows下为了兼容OpenGL而特别提供接口以wgl开头

  原型:

HGLRC wglCreateContext(
  HDC  hdc   // device context of device that the rendering context 
             // will be suitable for
);
 
BOOL wglMakeCurrent(
  HDC  hdc,      // device context of device that OpenGL calls are 
                 // to be drawn on
  HGLRC  hglrc   // OpenGL rendering context to be made the calling 
                 // thread's current rendering context
);


  方式如下:

       ghRC = wglCreateContext( ghDC );    //创建渲染环境
       wglMakeCurrent( ghDC, ghRC );     //使的成为当前渲染环境


  5.      实际绘制

  这个部分就和OpenGL在后面慢慢展开讲述

  6.      释放资源

  首先取消当前渲染环境选中然后依次删除渲染环境和设备环境

  需要原型:

BOOL wglDeleteContext(
  HGLRC  hglrc   // handle to the OpenGL rendering context to delete
);
 
// 取消OpenGL 结束前释放渲染环境设备环境以及最终窗口句柄
void DisableOpenGL
{
       wglMakeCurrent( NULL, NULL );
       wglDeleteContext( ghRC );
       ReleaseDC( ghWnd, ghDC );
}


  上述流程基本就是个完整Win32 OpenGL所需要实际上在参考5中有较为详细论述但是事实上你也可以作为论文发表见参考3.

   4、   真正OpenGL相关内容

  1.      静态图形显示演示:个矩形

  见参考2中(即所谓OpenGL红宝书The Red Book)中例子

  基本流程分两部分化和实际绘制:

//OpenGL化开始
void SceneInit( w, h)
{
       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);      // 黑色背景
 
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity;
       glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
 
 //这里进行所有绘图工作
void SceneShow(GLvoid)       
{
       glClear(GL_COLOR_BUFFER_BIT);
 
       glColor3f(1.0, 1.0, 1.0);
       glBegin(GL_POLYGON);
       glVertex3f(0.25, 0.25, 0.0);
       glVertex3f(0.75, 0.25, 0.0);
       glVertex3f(0.75, 0.75, 0.0);
       glVertex3f(0.25, 0.75, 0.0);
       glEnd;
       glFlush;
}


  显示效果非常简陋就是黑色背景窗口中个白色矩形OpenGLGL每个意义不在此文中描述本文主要目是讲述win32中OpenGL编程需要操作

  然后就是将所有部分串起来了上述都是代码片段全部源代码见我放在Google Code上blog-sample-code中2009-9-27\Win32OpenGLTemplate目录取回方式见本文最后介绍说明

  2.      动画演示:个旋转矩形

  整体框架使用了Andre LaMothe T3D Game Console所以显示动画非常简单只不过需要注意这里为了显示效果更好利用了双缓冲那么上面设置像素格式步需要用第 2种设置方式

  全部改动如下:

//激活创建OpenGL窗口
void EnableOpenGL
{
       PIXELFORMATDESCRIPTOR pfd;
        iFormat;
 
       ghDC = GetDC( ghWnd );
 
       ZeroMemory( &pfd, ( pfd ) );
       pfd.nSize = ( pfd ); 
       pfd.nVersion = 1;      //版本般设为
 
       //组表明象素缓冲特性标志位
       pfd.dwFlags =   PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
       pfd.iPixelType = PFD_TYPE_RGBA;   //明象素数据类型是RGBA还是颜色索引;
       pfd.cColorBits = 32;     //每个颜色缓冲区中颜色位平面数目对颜色索引方式是缓冲区大小
       pfd.cDepthBits = 16;
       pfd.iLayerType = PFD_MAIN_PLANE; //被忽略为了致性而包含
 
       iFormat = ChoosePixelFormat( ghDC, &pfd );//选择个像素格式
 
       SetPixelFormat( ghDC, iFormat, &pfd ); //设置到DC中
 
       ghRC = wglCreateContext( ghDC );    //创建绘图描述表
       wglMakeCurrent( ghDC, ghRC );     //使的成为当前绘图描述表
}
 
//OpenGL化开始
void SceneInit( w, h)
{
       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);      // 黑色背景
       glColor3f(1.0f, 1.0f, 1.0f);
 
       glShadeModel(GL_FLAT);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity;
       glOrtho(-50.0f, 50.0f, -50.0f, 50.0f, -1.0f, 1.0f);
}
 
 //这里进行所有绘图工作
void SceneShow(GLvoid)       
{
       // 旋转角度
        float fSpin = 0.0f;
       fSpin  2.0f;
       (fSpin > 360.0f)
       {
              fSpin -= 360.0f;
       }
 
       glClear(GL_COLOR_BUFFER_BIT);
 
       glPushMatrix;
       // 旋转矩形主要
       glRotatef(fSpin, 0.0f, 0.0f, 1.0f);
       glRectf(-25.0, -25.0, 25.0, 25.0);
       glPopMatrix;
 
       // 交换缓冲区
       SwapBuffers(ghDC);
} 




  全部源代码见我放在Google Code上blog-sample-code中2009-9-28\RotateRect\目录取回方式见本文最后介绍说明

   5、   最后介绍说明

  本文中所有代码(如果有话)都能用Mercurial在Google Code中下载

  文章以博文发表日期分目录存放下载地址为:

  http://code.google.com/p/jtianling/source/checkout?repo=blog-sample-code



Tags:  win32编程教程

延伸阅读

最新评论

发表评论