现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

windows下opengl(一):使用微软的OpenGL库

2014-10-27 21:28 工业·编程 ⁄ 共 5519字 ⁄ 字号 暂无评论

1.1 windows平台OpenGL介绍

         OpenGL是一个强大的2D/3D图形库。作为初学者,在查看各类网络文章或书籍时,往往一开始就被里面提到的各种各样的OpenGL开发库搞糊涂了,为什么开发OpenGL程序要这么多库呢?

        OpenGL本身是一个图形开发系统,且OpenGL是利用硬件加速的,这就决定了它需要直接操作显示设备,而在各种现代操作系统中,应用程序及应用程序库都不能直接操作硬件设备,而只能通过操作系统提供的接口层实现对硬件的访问。

       微软与SGI有过一段非常短暂的合作开发OpenGL的阶段,所以从windows95(winnt 3.5)开始,windows操作系统提供了对OpenGL的内在支持,除windows Mobile版本之外,都可以在其系统目录中找到opengl32.dll这个动态链接库,在安装了VC6或VisualStudio任何一个版本之后,都能找到gl/gl.h和gl/glu.h这两个头文件,在微软的MSDN上也能找到OpenGL相关的文档。不过,在这段合作中,微软只是想学点技术发展自己的DirectX,所以很快合作失败了,但windows对OpenGL的内在支持却延续至今。

       想想我们调用C语言的标准库函数printf,其实printf也需要在某个时候操作显示设备,从而显示出字符串,它利用的是操作系统提供的接口。从这个意义上讲,在windows上使用OpenGL函数与使用printf并无任何区别。

       下面介绍一下在windows平台上完成最简单的OpenGL程序需要完成的最基础工作:创建环境。

1.2 创建OpenGL环境

        正如在windows上使用Socket要首先调用WSAStartup(…)函数创建好Socket环境,使用OpenGL函数之前也需要创建好环境。VC6或VisualStudio安装好后自带的库中,及下载的windows各版本SDK库中,都提供了对OpenGL的支持。我没有去细究所有细节,只查找了几个主要的数据类型和函数:

1.2.1数据类型及结构

  1)  PIXELFORMATDESCRIPTOR结构

该结构体的定义位于:wingdi.h

2) HGLRC结构

该结构的定义位于:windef.h,以如下形式声明,其中DECLARE_HANDLE是一个宏

DECLARE_HANDLE(HGLRC);         // OpenGL

   3)DECLARE_HANDLE宏

该宏位于winnt.h中,定义如下:

#defineDECLARE_HANDLE(name)struct name##__{int unused;};typedefstruct name##__ *name

将2)3)结合在一起得到:

struct HGLRC__{int unused;};

typedef struct HGLRC__ * HGLRC

1.2.2 函数

在wingdi.h中有如下一组函数声明:

// OpenGL wglprototypes

WINGDIAPIBOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT); 

WINGDIAPIHGLRCWINAPI wglCreateContext(HDC); 

WINGDIAPIHGLRCWINAPIwglCreateLayerContext(HDC,int); 

WINGDIAPIBOOL WINAPI wglDeleteContext(HGLRC); 

WINGDIAPIHGLRCWINAPIwglGetCurrentContext(VOID); 

WINGDIAPIHDC  WINAPI wglGetCurrentDC(VOID); 

WINGDIAPIPROC WINAPI wglGetProcAddress(LPCSTR); 

WINGDIAPIBOOL WINAPI wglMakeCurrent(HDC,HGLRC); 

WINGDIAPIBOOL WINAPI wglShareLists(HGLRC,HGLRC); 

WINGDIAPIBOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD); 

WINGDIAPIBOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD); 

用于创建OpenGL环境的函数就在其中。

1)HGLRC wglCreateContext(HDC)

用于创建OpenGL的RenderingContext句柄,需要一个有效地HDC参数。

2)BOOL wglMakeCurrent(HDC,HGLRC)

     将HGLRC设置与指定HDC绑定。

       以上就是所有Windows平台上OpenGL相关的创建类型与函数。使用这些函数可以创建OpenGL运行环境,且不需要使用微软提供的库之外的任何第三方库。

1.2.3 环境创建步骤

       这小节介绍具体如何创建最简单的创建OpenGL环境。首先强调一遍,创建OpenGL环境,并不需要使用任何第三方库。当然如果愿意,我们也可以选择使用freeglut库的glutInit\glutCreateWindow函数来完成环境创建工作。

       创建环境的核心函数是wglCreateContext(HDC),这里可以看到参数是HDC类型,熟悉Windows窗口程序就明白,HDC需要从一个窗体获得,这表明为了使用wglCreateContext函数,首先需要创建一个窗口,而创建窗口需要一个程序句柄 HINSTANCE。这就是全部,非常简单,下面整理成5点:

        1) 获取一个合法的HINSTANCE

        2) 创建一个窗口,并获得HWND

        3) 通过HWND获取窗口的HDC

        4) 利用HDC创建HGLRC

        5) 将HGLRC与HDC绑定

        6)     利用glGetString函数获取OpenGL相关信息

1.3 测试程序

        理论说得再多不如看一个实例,当然实例要越简单越好,太过复杂的示例程序将显著增加学习的难度。

        这里我设计了一个示例:

            1)一个控制台程序

            2)创建OpenGL环境

            3)调用glGetString函数获取系统支持的OpenGL版本等信息并输出

            4)撤消环境再次调用glGetString返回空值,表明环境确实在发挥作用

程序设置:创建一个空的windows控制台项目,添加如下程序,编译前需要在VisualStudio项目设置的“链接器-->输入”中添加opengl32.lib,其它均不需要变动。

程序代码及注释如下:

#include<iostream>

#include<Windows.h>

#include<gl/gl.h>

LRESULTCALLBACK WndProc(HWNDhWnd,//定义窗口回调函数,没啥解释的

                        UINTuMsg, 

                        WPARAMwParam, 

                        LPARAMlParam) 

        Return 1; //没有任何作用,只是为了能成功创建窗口

}   

int main(intargc,char **argv) 

HWND        hWnd; 

    HGLRC       hRC; 

HDC         hDC; 

HINSTANCE   hInstance; 

//第 1)步:获取HINSTANCE

    hInstance =GetModuleHandle(NULL); 

    WNDCLASS    windClass; 

TCHAR szWindowName[50] = TEXT("OpenGL_Window");//随便设

TCHAR szClassName[50] = TEXT("OpenGL_Class"); //随便设

//初始化窗口结构体

    windClass.lpszClassName = szClassName; 

    windClass.lpfnWndProc   = (WNDPROC)WndProc; 

    windClass.hInstance     = hInstance; 

    windClass.hCursor       =LoadCursor(NULL,IDC_ARROW); 

    windClass.hIcon         =LoadIcon(NULL,IDI_WINLOGO); 

    windClass.hbrBackground =NULL;  

    windClass.lpszMenuName  =NULL;    

    windClass.style         =0;//随便设

    windClass.cbClsExtra    = 0;   

    windClass.cbWndExtra    = 0; 

//注册窗口类

if(!RegisterClass( &windClass )) return 1; 

//第 2)步:创建窗口

    hWnd = CreateWindowEx(0,     // Extended style

        szClassName,   // class name

        szWindowName,  // window name

        0, 

        0,      //window position, x

        0,      //window position, y

        0,  //height

        0, //width

        NULL,          // Parent window

        NULL,          // menu

        hInstance,     // instance

        NULL);         // pass this toWM_CREATE

//第 3)步:获取HDC,并随意设置一个空像素格式

    hDC = GetDC(hWnd); 

    PIXELFORMATDESCRIPTOR pfd; 

    SetPixelFormat( hDC, 1,&pfd); 

//第 4)步:创建OpenGL环境

    hRC = wglCreateContext( hDC ); 

//第 5)步:绑定HDC与HRC

    wglMakeCurrent( hDC, hRC ); 

    constGLubyte * pb = glGetString(GL_VERSION);//获取OpenGL版本字符串

if(pb) 

        std::cout <<"OpenGL versionis "<< pb << std::endl; 

    pb = glGetString(GL_VENDOR); //获取OpenGL显卡厂家信息字符串

if(pb) 

        std::cout <<"OpenGL vendoris "<< pb << std::endl; 

    pb = (glGetString(GL_RENDERER)); //获取OpenGL显卡型号信息字符串

if(pb) 

        std::cout <<"OpenGLrenderer is "<< pb << std::endl; 

    pb = glGetString(GL_EXTENSIONS); //获取OpenGL扩展函数名称字符串

if(pb) 

        std::cout <<"OpenGLextensions is "<< pb << std::endl; 

//一旦释放环境,glGetString函数将总是返回空值

    wglMakeCurrent(NULL,NULL); 

    wglDeleteContext(hRC); 

    ReleaseDC(hWnd, hDC); 

    DestroyWindow(hWnd); 

//释放后再执行,则pb每次均返回空值,表明OpenGL环境已经被释放

    pb = glGetString(GL_VERSION); 

if(pb) 

        std::cout <<"OpenGL versionis "<< pb << std::endl; 

    pb = glGetString(GL_VENDOR); 

if(pb) 

        std::cout <<"OpenGL vendoris "<< pb << std::endl; 

    pb = (glGetString(GL_RENDERER)); 

if(pb) 

        std::cout <<"OpenGLrenderer is "<< pb << std::endl; 

    pb = glGetString(GL_EXTENSIONS); 

if(pb) 

        std::cout <<"OpenGLextensions is "<< pb << std::endl; 

return 0; 

1.4 运行结果

上面示例的运行结果如下:

图中结果表明,运行本程序的系统支持的OpenGL版本为4.3.0,显卡生产厂家是NVIDIA Corporation,显卡型号是GeForce 605,支持的扩展函数名很多,这里只截图了一段。

1.5参考文献

       OpenGL SuperBible 5/e

      OpenGLprogramming guide 8/e

www.msdn.com

给我留言

留言无头像?