一片云雾

写博客挺浪费时间的……
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用Windows窗口句柄建立OpenGL环境

Posted on 2011-11-17 14:38  一片云雾  阅读(4758)  评论(0编辑  收藏  举报

在Windows中,OpenGL命令是通过OpenGL Render Context(以下简称RC)来执行的。这个RC是OpenGL和Windows之间的纽带。

每个RC创建时,必须指定一个DC(Windows Device Context 也就是那个通常用于GDI的设备环境DC)。RC的绘制目标,就是这个DC所对应的窗口。

每次RC创建时,应该设置一下DC的像素格式

同一个时刻,一个窗口可能对应多个RC,但一个线程只能有一个被激活的RC

每个RC都有一个对应的DC,该DC不一定必须是当初创建的RC时的DC,但这个DC必须与创建RC时的那个DC,对应于同样的Windows对象,并且像素格式相同。

每个线程有且只能拥有一个RC

Windows提供了一组用于RC管理的函数:

WGL Function

Description

wglCreateContext

创建一个RC

WglMakeCurrent

为线程指定当前RC

WglGetCurrentContext

获取一个线程的当前RC

WglGetCurrentDC

获取当前线程RC所对应的DC

WglDeleteContext

删除一个RC

根据以上内容,可以确定使用Windows窗口句柄建立OpenGL环境的步骤如下:

各个过程的示例代码如下:

1、在合适的地方,定义RC和DC句柄;

#include <GL\gl.h>                        //必要的头文件
#pragma comment(lib, "opengl32.lib")      //加入必要的lib文件

HGLRC    m_hRC;    //OpenGL渲染上下文环境句柄
HDC      m_hDC;    //Windows设备环境句柄

 

2、初始化RC的示例代码;

//根据hWnd创建RC
void Init(HWND hWnd)

{
    //获取DC
    m_hDC = GetDC(hWnd);

    //初始化像素格式
    static    PIXELFORMATDESCRIPTOR pfd =    
    {
        sizeof(PIXELFORMATDESCRIPTOR),    //上述格式描述符的大小
        1,                                //版本号
        PFD_DRAW_TO_WINDOW |              //格式支持窗口
        PFD_SUPPORT_OPENGL |              //格式必须支持OpenGL
        PFD_DOUBLEBUFFER,                 //必须支持双缓冲
        PFD_TYPE_RGBA,                    //申请RGBA 格式
        24,                               //选定色彩深度
        0, 0, 0, 0, 0, 0, 0, 0,           //忽略RGBA
        0,                                //无累加缓存
        0, 0, 0, 0,                       //忽略聚集位
        32,                               //32位Z-缓存(深度缓存)
        0,                                //无蒙板缓存
        0,                                //无辅助缓存
        PFD_MAIN_PLANE,                   //主绘图层
        0,                                //Reserved
        0, 0, 0                           //忽略层遮罩
    };

    //选择一个最适合pfd描述的像素格式索引值
    int nPixelFormat = ChoosePixelFormat(m_hDC, &pfd);

    //为DC设置像素格式
    SetPixelFormat(m_hDC, nPixelFormat, &pfd);

    //创建RC
    m_hRC = wglCreateContext(m_hDC);
}

 

3、渲染示例代码:

void Render()
{
    //选择RC作为当前线程的RC
    wglMakeCurrent(m_hDC, m_hRC);

    //
    //在此使用OpenGL进行绘制
    //

    //交换当前缓冲区和后台缓冲区
    SwapBuffers(m_hDC);

    //取消当前线程选中的RC
    wglMakeCurrent(NULL, NULL);
}

 

4、退出时的示范代码:

void DeInit(HWND hWnd)
{
    wglDeleteContext(m_hRC);
    ReleaseDC(hWnd, m_hDC);
}