新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → Win32 下的 OpenGL 编程必须步骤 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3930 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: Win32 下的 OpenGL 编程必须步骤 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     葛靖青001 美女呀,离线,快来找我吧!水瓶座1984-2-14
      
      
      等级:大三(研究MFC有点眉目了!)
      文章:168
      积分:595
      门派:XML.ORG.CN
      注册:2010/11/2

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给葛靖青001发送一个短消息 把葛靖青001加入好友 查看葛靖青001的个人资料 搜索葛靖青001在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给葛靖青001 引用回复这个贴子 回复这个贴子 查看葛靖青001的博客楼主
    发贴心情 Win32 下的 OpenGL 编程必须步骤

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

      

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

      

    三、    Win32 下 OpenGL 编程需要的操作步骤
    全部源代码见我的放在 Google Code 上的 blog-sample-code 中 2009-9-27\Win32OpenGLTemplate 目录。取回方式见本文最后的说明。

      

    下面会用到的全局变量:

    // GLOBALS ////////////////////////////////////////////////

    HWND       ghWnd ; // 窗口句柄

    HINSTANCE ghInstance ; // 程序实例句柄

    HDC ghDC ;                             // GDI 设备环境句柄

    HGLRC ghRC ;           // 渲染环境句柄

      

      

    1.       头文件
    #include <windows.h>

    // OpenGL 需要的头文件

    #include <GL/gl.h>

    #include <GL/glu.h>

    需要注意的就是,必须先包含 Windows.h ,然后才能包含 gl.h 和 glu.h 。因为 gl.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) 设置
    需要用到的函数的原型:

    int 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 set


      
    int

    iPixelFormat

    ,


                 
    // pixel format index (one-based)


      
    CONST PIXELFORMATDESCRIPTOR *

    ppfd


                 
    // pointer to logical pixel format specification


    );


      

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

    // 设置像素格式

           PIXELFORMATDESCRIPTOR pfd ;

           int iFormat ;

      

           ghDC = GetDC ( ghWnd );

      

           ZeroMemory ( & pfd , sizeof ( pfd ) );

           pfd . nSize = sizeof ( 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, 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 = 32;

    pfd.cDepthBits = 32;

    pfd.iLayerType = PFD_MAIN_PLANE;

    int 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.

      

    四、    真正的 OpenGL 相关内容
    1.       静态图形显示演示:一个矩形
    见参考 2 中(即所谓的 OpenGL 红宝书 The Red Book )中的例子

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

    //OpenGL 初始化开始

    void SceneInit ( int w , int 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 ,所以显示动画非常简单。只不过需要注意的是,这里为了显示效果更好利用了双缓冲,那么上面的设置像素格式一步需要用第二种设置方式。

      

    全部的改动如下:

    // 激活创建OpenGL 窗口

    void EnableOpenGL ()

    {

           PIXELFORMATDESCRIPTOR pfd ;

           int iFormat ;

      

           ghDC = GetDC ( ghWnd );

      

           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 ;   // 明象素数据类型是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 ( int w , int 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 )        

    {

           // 旋转角度

           static float fSpin = 0.0f;

           fSpin += 2.0f;

           if ( 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 \ 目录。取回方式见本文最后的说明。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vagrxie/archive/2009/09/28/4602961.aspx


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    ---人之所以能,是相信能!!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/11/7 11:51:00
     
     GoogleAdSense水瓶座1984-2-14
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给Google AdSense 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/25 16:33:03

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    78.125ms