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

anyTex - 用于 OpenGL 中非限制性纹理的类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (11投票s)

2005 年 7 月 25 日

CPOL

4分钟阅读

viewsIcon

65092

downloadIcon

2945

anyTex - 一个用于 OpenGL 中非限制性纹理的类。

Sample Image

引言

直到最近,在 OpenGL 中处理纹理意味着处理尺寸为 2 的幂次方,限制在 1024、2048 或 4096 的图像。2005 年 4 月 26 日,Mark J. Kilgard 发布了 NVIDIA OpenGL 2.0 支持说明,直接引用了“NVIDIA 的 GeForce 6 系列和基于 NV4xGL 的 Quadro FX GPU 在片段级别完全支持非 2 的幂次方纹理”(当然,有一些限制)。从程序员的角度来看,有时会希望处理任意尺寸的图像(我指的是相当大的图像),并将其隐式地视为非 2 的幂次方的大纹理,例如 8000 x 3000 像素大小,而不用担心众所周知的纹理“麻烦”。

anyTex 是一个允许您从文件加载给定颜色深度的位图,并将其视为无限制纹理(当然,受限于计算机资源,这是我们不得不接受的)的类。

使用此类

anyTex 包含两个文件:anytex.cppanytex.h,您需要将它们添加到您的项目中。请确保在项目设置的 **链接** 选项卡中有 OpenGL32.libGLu32.libGLaux.lib。然后,在主对话框类的头文件中 #include "anytex.h"。向主对话框类添加一个 AnyTex 类型的公共成员。

AnyTex m_atImage;

在您的应用程序中添加一个 CStatic 控件,它将负责渲染您的 OpenGL 场景(我为了演示方便而选择了它)。然后,使用向导添加一个 CStatic 派生类,并将该类型的变量映射到控件。我们假设 m_oglDisplay 是该变量的名称。在 OnInitDialog() 函数中,通过将控件的地址传递给 anyTex 类提供的 InitializeOpenGL() 函数来创建 OpenGL 渲染上下文。

if ( !m_atImage.InitializeOpenGL(&m_oglDisplay) ) 
{
    AfxMessageBox("Cannot initialize OpenGL");
    PostMessage(WM_QUIT);
}

在继续之前,请记住,在后台,anyTex 仍然使用 2 的幂次方经典纹理作为基本的方形单元。默认情况下,单元大小为 1024。如果您想设置另一个单元大小,您可以随时通过调用 anyTex 提供的 SetTexCellSize(int nSize) 函数来实现。您可以为 nSize 选择任何值。anyTex 会自动将其调整为 128、256、512 或 1024。加载您选择的位图图像,并创建 anyTex 纹理,为了简单起见,我们将其称为 anyTex

if ( m_atImage.LoadBmpImage("test.bmp") ) m_atImage.CreateTex();

CreateTex() 函数需要一个布尔参数,默认值为 false,这会导致创建 2D 图像纹理。通过将参数设置为 true 调用该函数,将生成 mipmap。从现在开始,您只需在 CStatic 派生类的 OnPaint() 函数中调用 PreRender() 函数(可以根据您的需求覆盖)和 anyTex 类的 Render() 函数。

幕后

anyTex 由一个 CList <UINT, UINT> m_listTex 支持,该列表存储纹理单元的 ID。位图以 DIB 的形式加载到内存中。anytex "遍历" DIB,依次提取与基本纹理单元相同大小的方形区域。每个方形区域都被绘制到一个内存设备上下文中,生成一个 DDB。DDB 被转换为具有 32 色深的 DIB,然后根据传递给 AnyText::CreateTex() 函数的布尔参数,用于生成基本纹理单元或其对应的 mipmap。纹理 ID 被添加到 m_listTex

Texture creation

anyTex 以如下方式将大小为 1 的方形纹理画布映射到 anyTex 对象上:

Texture creation

anyTex 在画布的左上角对齐。AnyTex::Render() 函数将 anytext 整体渲染出来。如果您现在对 3D 渲染感兴趣,并且需要单独使用组件纹理单元,您只需要调用

UINT AnyTex::RetrieveTexCell(double atX, double atY, 
         double &renLeft, double &renTop, double &renSize)

函数,并将逻辑画布上的 atX, atY 位置作为参数传递。该函数返回对应单元的纹理 ID,如果找不到则返回 0。非零 ID 表示一个有效 ID,并且该 ID 指向的基本单元将在 renLeft, renTop 处渲染,其大小存储在 renSize 中,这些值可用于您的后续计算。

历史

  • 创建时间:2005 年 7 月 22 日。
© . All rights reserved.