欢迎您来到GIS动力

加入收藏 免费注册 用户登陆 帮助中心
首页 新闻动态 技术专栏 银杏树下 学习考研 软件下载 求职招聘 许愿瓶 节日祝福 用户中心 精彩推荐 资源搜索 地图
专栏导航: AO开发 | SO开发 | ArcGIS桌面 | 超图桌面 | 开发语言 | 数据库 | WebGIS | 银杏文学 | 研究生考题 | FreeMap 谈天说地
   您现在位于: 首页技术专栏开发语言 → 正文
OpenGL起步1
07-12-27 00:00:00 作者:浩淼的天空 出处:浩淼的天空
u        OpenGL OS 的窗口系统进行关联
我们早说过,这是很重要的一步,也是一个SDI OpenGL 程序在初始化的过程中必须做的工作,因此下面需要介绍一些相关概念:
图形操作描述
  在Windows 窗口程序必须首先处理设备描述表(Device Contexts DC ),DC 包括许多如何在窗口上显示图形的信息,如指定画笔和刷子的颜色,设置绘图模式、调色板、映射模式以及其它图形属性。同样,OpenGL 的程序也必须使用DC ,这与其它Windows 程序类似。但是,OpenGL 必须处理 特殊的 DC 渲染描述表 ,这是DC 中专为OpenGL 使用的一种 “渲染描述表 (RC) 。一个OpenGL 渲染描述表内有OpenGL Windows 窗口系统相关的各种信息。 一个 OpenGL 应用首先必须创建一个渲染描述表,然后再启动它,最后在所定义的窗口内按常规方式调用 OpenGL 函数绘制图形。
一个渲染描述表RC 不同于其它DC ,后者调用每个GDI 函数都需要一个句柄,而RC 方式下只需一个句柄就可以任意调用OpenGL 函数。也就是说,只要当前启用了某个渲染描述表,那么在未删除渲染描述表之前可以调用任何OpenGL 函数,进行各种操作。在程序中也可以看到,除了在初始化和卸载过程中使用RC 外,其余的代码我们几乎没有再遇到过RC
像素格式
  在创建一个图形操作表之前,首先必须设置像素格式。像素格式含有设备绘图界面的属性,这些属性包括绘图界面是用RGBA 模式还是颜色表模式,像素缓存是用单缓存还是双缓存,以及颜色位数、深度缓存和模板缓存所用的位数,还有其它一些属性信息。
像素格式结构
  每个OpenGL 显示设备都支持一种指定的像素格式。一般用一个名为PIXELFORMATDESCRIPTOR 的结构来表示某个特殊的像素格式,这个结构包含26 个属性信息。Win32 定义PIXELFORMATDESCRIPTOR 如下所示:
typedef struct tagPIXELFORMATDESCRIPTOR
  {
    WORD nSize;
    WORD nVersion;
    DWORD dwFlags;
    BYTE iPixelType;
    BYTE cColorBits;
    BYTE cRedBits;
    BYTE cRedShift;
    BYTE cGreenBits;
    BYTE cGreenShift;
    BYTE cBlueBits;
    BYTE cBlueShift;
    BYTE cAlphaBits;
    BYTE cAlphaShift;
    BYTE cAccumBits;
    BYTE cAccumRedBits;
    BYTE cAccumGreenBits;
    BYTE cAccumBlueBits;
    BYTE cAccumAlphaBits;
    BYTE cDepthBits;
    BYTE cStencilBits;
    BYTE cAuxBuffers;
    BYTE iLayerType;
    BYTE bReserved;
    DWORD dwLayerMask;
    DWORD dwVisibleMask;
    DWORD dwDamageMask;
  } PIXELFORMATDESCRIPTOR;
 
好,了解了这些,我们开始写MFC 代码,首先产生一个SDI MFC 程序,然后必须引入OpenGL 的库,方法与前例相同(这些都不难),然后在StdAfx.h 中键入下列的代码:
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
这样我们就可以在程序的任何地方都使用OpenGL 的函数了。
我新建的SDI 项目名为COpenGLDemo ,在CCOpenGLDemoView 类中添加如下方法和变量:
public:
      BOOL InitOpenGL(CDC* pDC);
      void SetLogicalPalette();
      BOOL SetupPixelFormat();
      BOOL RenderScene();
private:
      HPALETTE m_hPalette;
      CDC* m_pDC;
      HGLRC m_hRC;
 
添加完以后,我们必须修改SDI 的窗口类型,使之与OpenGL 相匹配,这个更改是在窗口产生以前,代码如下(灰色部分):
BOOL CCOpenGLDemoView::PreCreateWindow(CREATESTRUCT& cs)
{
      // TODO: Modify the Window class or styles here by modifying
      // the CREATESTRUCT cs
      cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;
 
      return CView::PreCreateWindow(cs);
}
然后该在OnCreate 里面进行初始化了,其实这个初始化在OnInitialUpdate 中实现也可以,我们就选择前者。添加一个WM_Create 的响应函数(这个要是不会的话,您该先看看MFC 再来),然后键入代码:
int CCOpenGLDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
      if (CView::OnCreate(lpCreateStruct) == -1)
             return -1;
      // TODO: Add your specialized creation code here
      // 产生一个 DC
      m_pDC=new CClientDC(this);
      // 使用窗口 DC 来设置 RC
      InitOpenGL(m_pDC);            
      // 产生一个 Timer 进程,程序每 20ms 就产生一个 WM_TIMER 事件,作用后面讲
      SetTimer(0,20,NULL);    
 
      return 0;
}
上面的代码中我们使用了InitOpenGL 函数来对OpenGL 进行初始化,其函数具体实现如下:
BOOL CCOpenGLDemoView::InitOpenGL(CDC *pDC)
{
      m_pDC=pDC;
      // 设置像素格式
      SetupPixelFormat();
      // 产生一个 RC
      m_hRC::wglCreateContext(m_pDC->GetSafeHdc());
      // 设置该 RC 为当前使用的 RC
      ::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
      return TRUE;
}
注意上面使用了SetupPixelFormat 函数来设置OS 的像素格式,该函数详细为:
BOOL CCOpenGLDemoView::SetupPixelFormat()
{
      PIXELFORMATDESCRIPTOR *pfd=new PIXELFORMATDESCRIPTOR();
      pfd->nSize=sizeof(PIXELFORMATDESCRIPTOR);
      pfd->nVersion=1;
      pfd->dwFlags=PFD_DRAW_TO_WINDOW|
             PFD_SUPPORT_OPENGL|
             PFD_DOUBLEBUFFER|
             PFD_STEREO_DONTCARE;
      pfd->iPixelType=PFD_TYPE_RGBA;
      pfd->cColorBits=32;
      pfd->cRedBits=8;
      pfd->cRedShift=16;
      pfd->cGreenBits=8;
      pfd->cGreenShift=8;
      pfd->cBlueBits=8;
      pfd->cBlueShift=0;
      pfd->cAlphaBits=0;
      pfd->cAlphaShift=0;
      pfd->cAccumBits=64;
      pfd->cAccumRedBits=16;
      pfd->cAccumGreenBits=16;
      pfd->cAccumBlueBits=16;
      pfd->cAccumAlphaBits=0;
      pfd->cDepthBits=32;
      pfd->cStencilBits=8;
      pfd->cAuxBuffers=0;
      pfd->iLayerType=PFD_MAIN_PLANE;
      pfd->bReserved=0;
      pfd->dwLayerMask=0;
      pfd->dwVisibleMask=0;
      pfd->dwDamageMask=0;
// 选择一个像素索引
      int m_GLPixelIndex=::ChoosePixelFormat(m_pDC->GetSafeHdc(),pfd);
// 设置像素索引
      ::SetPixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,pfd);
 
      if (pfd->dwFlags&PFD_NEED_PALETTE)
      {
             SetLogicalPalette();       // 有必要的话设置逻辑调色板
      }
      return TRUE;
}
好长一个函数啊,不过主要是一个结构体的设置,关于这个结构体的具体属性,请大家自己去查阅,在设置了一个结构体后,我们选择了一个像素索引并设置为当前像素结构。至于逻辑调色板,其代码如下:
void CCOpenGLDemoView::SetLogicalPalette()
{
      struct 
      {
             WORD Version;
             WORD NumberOfEntries;
             PALETTEENTRY aEntries[256];
      } logicalPalette={0x300,256};
9 7 3 1 2 4 8 :

(本文已被浏览 次)
发布人:admin
推荐给好友:发送给好友
上篇新闻:
下篇新闻:
相关评论
发表我的评论
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  •   相关文章  
    OpenGL起步4
    OpenGL起步3
    OpenGL起步2

    关于我们 友情链接 ┋ 与我在线 ┋ 管理 ┋ TOP
    网站当前版本:GisPower CMS V3.0
    『GIS 动力』- http://www.gispower.org/
    联系我们:webmaster#gispower.org
    Copyright (c) 2003-2007 GisPOwer.Org. All Rights Reserved.

                   滇ICP备05006901号