姑且不谈论OpenGL的名贵背景和光明前途,单凭其实用性和有效性就足以使其成为我们图形输出编程的首选。但是在实际工程应用中程序员没必要仔细地深究OpenGL的运作机制,也往往不需要掌握各种高级的效果制作,真正需要的是最简捷地利用这个得力的工具实现输出数据的可视化,如波形、谱图、立体统计图表等的显示。有鉴于此,本文总结出了在C++Builder中OpenGL编程的实用框架。笔者经过实践,对于一般的图形输出的应用,此框架足以应付。对于复杂些的程序可以在本框架的基础上进行扩充。
在Windows环境下用OpenGL编程至少要了解如下预备知识:
OpenGL本身:对于一般的应用,我们可以认为OpenGL就是一套与窗口系统和操作系统无关的三维图形函数库。
DC和RC:每个Win32应用程序都有一个设备描述表(Device Context)简称DC,在这个设备描述表中包含了图形怎样显示在窗口的设置( GDI)信息。调用OpenGL函数必须使用设备描述表才能正确地在窗口输出。图形操作描述表(Rendering Context)简称RC,是一种设备描述表的形式,在图形操作描述表中存放一些OpenGL和操作系统相联系的信息。图形操作描述表是传递所有OpenGL命令的端口。
像素格式:像素格式定义了OpenGL绘图的属性,创建图形操作描述表首先要定义象素格式。它由这样一个数据结构实现
typedef struct tagPIXELFORMATDESCRIPTOR
{
WORD nSize; //结构大小
WORD nVersion; //版本
DWORD dwFlags; //象素缓冲的位标志
BYTE iPixelType; //RGBA模式或颜色索引模式
BYTE cColorBits; //颜色位数
BYTE cRedBits; //RGBA模式下R所占位数
BYTE cRedShift; //RGBA模式下R位数偏移
BYTE cGreenBits; //RGBA模式下G所占位数
BYTE cGreenShift; //RGBA模式下G位数偏移
BYTE cBlueBits; //RGBA模式下B所占位数
BYTE cBlueShift; //RGBA模式下B位数偏移
BYTE cAlphaBits; //RGBA模式下Alpha所占位数
BYTE cAlphaShift; //RGBA模式下Alpha位数偏移
BYTE cAccumBits; //累计缓冲区位面总数
BYTE cAccumRedBits; //累计缓冲区R位面总数
BYTE cAccumGreenBits; //累计缓冲区G位面总数
BYTE cAccumBlueBits; //累计缓冲区B位面总数
BYTE cAccumAlphaBits; //累计缓冲区Alpaha位面总数
BYTE cDepthBits; //深度缓冲位数
BYTE cStencilBits; //模板缓冲位数
BYTE cAuxBuffers; //Win32 下不支持
BYTE iLayerType; //不再使用
BYTE bReserved; //0
DWORD dwLayerMask; //不再使用
DWORD dwVisibleMask; //0
DWORD dwDamageMask; //不再使用
} PIXELFORMATDESCRIPTOR;
双缓冲技术:OpenGL支持一个显示缓冲和一个非显示缓冲。缺省的情况是所有的OpenGL绘制命令在非显示缓冲中绘制,绘制完成后再将其内容拷贝到显示缓冲区中(使用SwapBuffers函数)。双缓冲使图象转换更平滑,这就是在快速动画(如波形等的实时输出)时没有屏幕闪烁的奥妙所在。
反走样技术:实际中需要画出的往往是曲线,由于计算机以离散点生成图形,曲线上会有锯齿,这就是一种走样现象。在用一般语言画图时,这一现象是难以避免的。OpenGL中利用混合技术,把原来边界的锯齿部分用低饱和度的点补上从而实现反走样,达到平滑的边界效果。
好,我们现在可以启用下面的程序框架了。
在*.h文件的类声明中添加private成员:
private:
HGLRC hRC;
HDC hDC;
以下是相应*.cpp文件
首先加上两个包含文件:
#include <gl\gl.h> //程序使用OpenGL的核心函数
#include <gl\glu.h> //程序使用实用库中的函数