65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的 OpenGL 测试框架

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (13投票s)

2009年3月4日

CPOL

5分钟阅读

viewsIcon

107891

downloadIcon

6620

一个简单的 OpenGL 框架, 用于快速原型化 OpenGL 和游戏应用程序

GLDemoApp

引言

这是一个用于原型化 OpenGL 和游戏应用程序的简单框架。它提供了一种快速启动并使用所有最常用工具的方法,这些工具已内置其中。

框架中包含以下功能

  • Collada 加载器
  • OpenGL 渲染器
  • FreeType 字体渲染
  • TGA 纹理加载
  • 帧率计数
  • 全屏/窗口模式支持

Zip 文件中包含以下已编译的第三方库。

  • Collada DOM
  • GLEW
  • FreeType

Using the Code

要使用该框架,只需解压 GLDemoApp_demo.zip。使用 Visual Studio 2005 打开项目。在使用 Visual Studio 2008 时存在已知问题,您需要使用 Visual Studio 2008 重新编译 Collada DOM 库。

在使用框架之前,请花点时间观察目录结构。在顶层,应该有三个目录

  • "3rdParty" - 包含框架中使用的所有第三方库和头文件
  • "bin" - 所有可执行文件构建后都将在此处;此目录内包含子目录:releaseresources
  • "GLDemoApp" - 包含所有源文件和 *.sln 文件

代码中最主要的部分包含在 demo.cpp 中。在此文件中,有三个函数

void InitDemo()
{
    RenderInit();
    CColladaLoader loader;
    g_pTestColladaMesh = loader.LoadColladaFile(BuildResourcePath("test.dae"));
    g_uiTextureId = RenderLoadTexture(BuildResourcePath("test.tga"));
}

bool RunDemo()
{
    static float32 fRotation = 0.0f;
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix();

    gluLookAt(0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    
    RenderGroundGrid(-4.0f);
    
    glPushMatrix();
        glRotatef(fRotation, 1.0f, 1.0f, 1.0f);
        RenderMesh(*g_pTestColladaMesh);
    glPopMatrix();

    glPushMatrix();
    glPointSize(10.0f);
    glBegin(GL_POINTS);
    glColor3f(1.0f, 1.0f, 1.0f);
    glVertex3f(0.0f, 0.0f, 0.0f);
    glEnd();
    glPopMatrix();

    glPopMatrix();
    
    RenderText(&g_defaultFont, "F1 : Fullscreen", Vector2f(0.0f, 20.0f));
    RenderText(&g_defaultFont, "F2 : Windowed", Vector2f(0.0f, 40.0f));


    RenderBegin2dMode();
        
    RenderTexture(Vector2f(RenderGetOrthoWidth() * .5f, 50.0f), g_uiTextureId, 0.0f);

    RenderEnd2dMode();

    if(GetAsyncKeyState(VK_F1))
    {
        sRenderResolution sRes;
        sRes.nWidth = RenderGetDesiredWidth();
        sRes.nHeight = RenderGetDesiredHeight();
        sRes.nBitDepth = RenderGetBitDepth();

        RenderSetResolution(sRes, true);
    }else if(GetAsyncKeyState(VK_F2))
    {
        sRenderResolution sRes;
        sRes.nWidth = RenderGetDesiredWidth();
        sRes.nHeight = RenderGetDesiredHeight();
        sRes.nBitDepth = RenderGetBitDepth();

        RenderSetResolution(sRes, false);
    }

    fRotation += .1f;
    if(fRotation > 360.0f)
        fRotation = 0.0f;

    RenderStats();
    RenderSwapBuffers();

    return (GetAsyncKeyState(VK_ESCAPE) & 0xFFFF) ? false : true;
}

void EndDemo()
{
    RenderReleaseTexture(g_uiTextureId);
    RenderReleaseMesh(&g_pTestColladaMesh);
    RenderDestroy();
}

这里发生的事情很容易看懂。InitDemo()winmain 函数的 gldemoapp.cpp 中被调用,就在主应用程序循环开始之前。在 InitDemo() 函数中,您应该添加应用程序所需的任何初始化代码。请记住,此函数在应用程序的整个生命周期中仅被调用一次。默认情况下,在 InitDemo() 函数中,有一些代码用于加载 Collada 文件和纹理文件。您可以简单地删除大部分代码,只保留 RenderInit(),它执行所有的 OpenGL 初始化工作。BuildResourcePath() 函数会构建一个相对于应用程序运行的当前目录的路径,该路径向上移一级,并在一个名为“resources”的文件夹内。查看目录结构,您会发现 BuildResourcePath() 始终提供一个路径,该路径为“ACTUALPATH\\bin\\resources\\yourfilename.ext”。

接下来是 RunDemo() 函数。在其中,您应该放入大部分代码。此函数在应用程序执行期间被反复调用。重要的是要注意,此函数返回一个 bool。这表示应用程序是应继续运行还是立即退出。正如您所见,此函数中已包含几个绘图调用。这些只是为了演示,可以安全地删除。但是,您应该保留 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)RenderSwapBuffers()

最后,当应用程序即将终止执行时,会调用 EndDemo() 函数。这是应该放置大多数清理代码的地方。

渲染函数

该框架提供了许多应该使 OpenGL 使用更容易的实用程序。这里列出了一些您可能会发现有用的渲染和实用函数

  • RenderLoadTexture(const std::string& strFilePath)

    从磁盘加载 TGA 纹理并返回 OpenGL 纹理对象 ID。此 ID 可用于调用 glBindTexture

  • RenderGroundGrid(float32 fYPos)

    此函数将在给定 Y 坐标位置的地面上绘制一个网格。

  • RenderText(CFTFont* pFont, const char* strText, Vector2f& vtPosition, float32 fScale, const sRGBColor& rgbColor)

    此函数使用提供的字体作为第一个参数来显示文本。默认情况下,在 RenderInit() 中加载了一个字体,可以通过全局变量 g_defaultFont 访问。例如,如果要显示一些文本,可以这样做...

    RenderText(&g_defaultFont, "Your cool text here", Vector2f(0.0f, 20.0f));
  • RenderQueryResolutions(std::list& lstResolution)

    检索当前显示器上可用分辨率的列表。

  • RenderSetResolution(sRenderResolution& rRes, bool bFullScreen)

    设置 OpenGL 窗口的当前分辨率。此外,通过将“true”传递给第二个参数,可以切换到全屏模式。例如,要设置分辨率并切换到全屏,可以执行以下操作...

    sRenderResolution rRes;
    rRes.nWidth = 640;
    rRes.nHeight = 480;
    rRes.nBitDepth = 32;
    RenderSetResolution(rRes, true);
  • RenderBegin2dMode()

    使用此函数会将当前投影矩阵切换为正交投影。重要的是要注意,正交分辨率独立于透视分辨率。

  • RenderEnd2dMode()

    使用此函数是在正交模式下完成绘制时。以下代码段将在 50,50 处绘制一个加载的纹理

    RenderBegin2dMode();
    RenderTexture(50.0f, 50.0f), g_uiTextureId, 0.0f);
    RenderEnd2dMode();
  • std::string ReadTextFileToBuffer(const std::string& strFileName)

    此函数将从磁盘加载一个文件并将其内容放入返回的缓冲区中。这对于加载着色器很有用。

辅助类

除了上述函数外,还有几个类在使用此框架时您会发现很有用

  • CFTFont - 此类是 FreeType 库的包装器。它将加载指定的 FreeType 字体并创建适当的显示列表用于渲染。您可以将此类的一个实例用作 RenderText 的参数。
  • CFTFont coolFont;
    coolFont.Init(BuildResourcePath("MyAwesomeFont.TTF"), 18);
    RenderText(&coolFont, "Loaded the font!", Vector2f(0.0f, 20.0f));
  • CColladaLoader - 这是 Collada DOM 库的包装类。它将加载 Collada 网格文件并将其常量存储到 sMesh 的实例中。文件加载和处理后,可以从加载函数返回的实例调用 void RenderMesh(const sMesh& pMesh)。加载器会加载 TGA 格式的纹理。请记住,一旦加载,Collada 提供的许多额外数据将被丢弃。
  • CColladaLoader loader;
    sMesh* pMyMesh = loader.LoadColladaFile(BuildResourcePath("colladaTest.dae"));
    
    RenderMesh(*pMyMesh);
    
    //Once you are done with the mesh call
    //
    RenderReleaseMesh(&pMyMesh);

其他说明

请随意查看提供的源文件。有许多助手函数可供您使用,它们应该能让您的生活更轻松。如果您在运行已编译的可执行文件时遇到任何问题,请务必仔细检查您的“工作目录”设置(对于调试版本应为“..\\bin\\debug”,对于发布版本应为“..\\bin\\release”)。此选项可以在“调试”下的“解决方案属性”窗口中找到。

如果您对代码有任何疑问或评论,请随时通过 rebelcoder at gmail.com 与我联系。

历史

  • 2009 年 3 月 4 日:初始发布
  • 2009年4月4日:文章更改
© . All rights reserved.