现在的位置: 首页 > 综合 > 正文

OpenGL系统设计-2 第一个OpenGL程序

2013年09月09日 ⁄ 综合 ⁄ 共 4100字 ⁄ 字号 评论关闭

 

1         第一个OpenGL程序

 

俗话说,“工欲善其事,必先利其器”,一个好的开发工具能够使你将注意力其中在程序设计本身,做到事半功倍,反之,可能经常需要解决开发工具的问题。我们建议使用微软公司的Visual C++ 6.0,如果使用Visual C++ .NET也可以,当然使用Borland C++C++ Builder或者Watcom C++也完全可以,这也要看个人的爱好。

之所以把一个“Hello World”程序单独算作一章,是因为在这一章很重要,我们要先奠定OpenGL应用程序的框架,以后的程序将使用这一框架。

 

1.1        环境设置

Windows系统中,opengl32.dllglu32.dll提供对OpenGL的支持,所以应该在编译OpenGL程序时链接相应的库文件。

    通常可以在程序的开头加入以下代码来达到链接库文件的目的,如果用到了辅助函数,还需要链接辅助函数库glaux.lib:

    #pragma comment(lib, "opengl32.lib")

    #pragma comment(lib, "glu32.lib")

    #pragma comment(lib, "glaux.lib")

 

    另一种办法是在VC中设置好工程的参数如图1-7所示通过菜单Project->Settings...->Linkopengl32.libglu32.libglaux.lib如果需要的话三个文件加入工程中。

   

 

    1-7   VC++静态库设置

 

1.2        OpenGL应用框架

    开发环境设置完毕后,我们开始第一个OpenGL程序“Hello World”。因为三维图形通常对性能和速度要求比较高,我们就使用Win32 API来写代码,而不使用MFC。实际上,真正的大型高性能三维图形软件和游戏软件是很少会使用MFC来写的。

    首先使用VC的Win32 Application Wizard创建一个Hello World的Win32程序,该工程一共包含9个文件,Hello.cpp、Hello.rc、StdAfx.cpp、Hello.h、resource.h、StdAfx.h、Hello.ico、small.ico和Readme.txt。

    把StdAfx.cpp、StdAfx.h两个文件删除,再通过菜单Project->Settings...->C/C++将Project Options编译开关中的 /Yu"stdafx.h" 去掉,然后将Hello.cpp按照以下方式进行修改。

 

#include "windows.h"           //Windows标准API的头文件

#include "resource.h"     //本程序资源定义文件

 

//增加opengl的头文件

#include "gl/gl.h"           //OpenGL32库的头文件

#include "gl/glu.h"         //glu32库的头文件

#include "gl/glaux.h"      //辅助库的头文件

 

#define WIN32_LEAN_AND_MEAN          //表示不使用MFC

#define WIDTH            640                //窗口的宽度

#define HEIGHT           480                //窗口的高度

#define BITS                16                  //程序的像素格式

 

    然后定义几个全局变量

 

HGLRC hRC=NULL;         //渲染描述表句柄

HDC hDC=NULL;           //设备描述表句柄

HWND hWnd=NULL;         //当前窗口句柄

HINSTANCE hInst;        //当前程序实例句柄

 

    其中hDChWndhInst三个变量很容易理解重要的是第一个变量hRC它是OpenGL程序的特色表示渲染描述表Rendering Context。它将所有的OpenGL调用全部连接到对应的设备描述表hDC上,hDC通过图形设备接口GDI将窗口联结为一体,通过Windows系统完成显示。

 

    然后再定义一个表示应用是否激活的标志bActive:

 

BOOL bActive;           //当前应用程序是否处于激活状态

 

    下面几行在原来的文件中有,不用修改。

 

TCHAR szTitle[MAX_LOADSTRING];      // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];    // The title bar text

 

// Foward declarations of functions included in this code module:

ATOM                MyRegisterClass(HINSTANCE hInstance);

BOOL                InitInstance(int Width, int Height, int Bits);//这里有变化

                    //原来的函数有两个参数HINSTANCEnCmdShow,这里改成更加有用的

                    //窗口大小和像素格式

 

LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

 

    接下来是我们自定义的函数原型说明,用于处理OpenGL的初始化,主流程和OpenGL的关闭。

 

void glMain(){};

void glShutdown(){};

void glInit(){};

   

然后进入我们程序的入口WinMain做一些改动。

int APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     int       nCmdShow)

{

    // TODO: Place code here.

    MSG msg;

    //HACCEL hAccelTable;

 

    // Initialize global strings

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

    LoadString(hInstance, IDC_HELLO, szWindowClass, MAX_LOADSTRING);

    MyRegisterClass(hInstance);

    hInst = hInstance;

 

    // Perform application initialization:

    if (!InitInstance (WIDTH, HEIGHT, BITS))

    {

        return FALSE;

    }

 

    //hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_HELLO); 

 

    // 下面的消息主循环有变化

 

    //初始化OpenGL

    glInit();

 

    while(TRUE)

    {

        //检查队列是否有消息,若有就取出。这里使用PM_REMOVE表示取出后从队列中删除。

    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{

       //如果是WM_QUIT消息就停止

       if (msg.message == WM_QUIT)

           break;

   

       TranslateMessage(&msg);

 

       //将消息发送到窗口函数WndProc

       DispatchMessage(&msg);

    } // end if

   

   

//只有程序处于激活状态时才进入OpenGL的主程序进行绘制

    if(bActive)

    {

       glMain();

    }

      

    } // end while

 

    //程序结束前关闭OpenGL

    glShutdown();

 

    return msg.wParam;

 

} // end WinMain

 

    WinMain函数中我们看到了增加两个函数glMain()glShutdown()。其中对OpenGl的各种变换、处理、显示都在glMain()中,它是我们的OpenGL应用真正的主函数。当程序收到退出消息时,先关闭OpenGL,这些在glShutdown()中实现。

   

    接下来我们看MyRegusterClass函数,该函数仅仅是注册窗口函数,几乎不用改变。

ATOM MyRegisterClass(HINSTANCE hInstance)

{

    WNDCLASSEX wcex;

 

    wcex.cbSize = sizeof(WNDCLASSEX);

 

    wcex.style          = CS_HREDRAW | CS_VREDRAW;

    wcex.lpfnWndProc    = (WNDPROC)WndProc;

    wcex.cbClsExtra     = 0;

    wcex.cbWndExtra     = 0;

    wcex.hInstance      = hInstance;

    wcex.hIcon          = LoadIcon(hInstance, (LPCTSTR)IDI_HELLO1);

    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);

    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);

    w

抱歉!评论已关闭.