0

我正在为一个名为 Autodesk MotionBuilder 的应用程序编写一个插件,该应用程序有一个 OpenGL 渲染器,并且我正在尝试将纹理几何体渲染到场景中。我有一个嵌入了 3D 视图的窗口,每次渲染我的窗口时,这就是(简而言之)发生的情况:

  1. 我告诉渲染器我将要绘制到一个给定大小的区域
  2. 我告诉渲染器在该区域绘制 MotionBuilder 场景
  3. 我在场景中和/或顶部画了一些额外的东西

这里的挑战是我从 MotionBuilder 的渲染器继承了一些任意的 OpenGL 状态,这取决于它正在绘制什么以及场景中存在什么。到目前为止,我一直在处理这个问题,但有一件事我无法弄清楚。OpenGL 解释我的 UV 坐标的方式似乎会根据 MotionBuilder 在我背后所做的事情而改变。

这是我的渲染代码。如果场景中没有纹理几何体,这意味着 MotionBuilder 尚未处理任何与纹理相关的属性,它会按预期工作。

// Tell MotionBuilder's renderer to draw the scene
RenderScene();

// Clear whatever arbitrary state MotionBuilder left for us
InitializeAttributes(); // includes glPushAttrib(GL_ALL_ATTRIB_BITS)
InitializePerspective(); // projects into the scene / loads matrices

// Enable texturing, bind to our texture, and draw a triangle into the scene
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mTexture);

glBegin(GL_TRIANGLES);
glColor4f(1.0, 1.0, 1.0, 0.5f);
    glTexCoord2f(1.0, 0.0); glVertex3f(128.0,   0.0, 0.0);
    glTexCoord2f(0.0, 1.0); glVertex3f(  0.0, 128.0, 0.0);
    glTexCoord2f(0.0, 0.0); glVertex3f(  0.0,   0.0, 0.0);
glEnd();

// Clean up so we don't confound MotionBuilder's initial expectations
RestoreState(); // includes glPopAttrib()

现在,如果我引入一些带有纹理的网格,就会发生一些奇怪的事情。我的纹理坐标被放大了。这是之前和之后:

mbtexture.jpg
(来源:awforsythe.com

从右侧的特写可以看出,当 MotionBuilder 被要求渲染其文件找不到的纹理时,它会加载这个小问号纹理并将其平铺在几何体上。我唯一的假设是 MotionBuilder 正在更改一些全局纹理坐标标量,例如,glTexCoord2f(0.5, 1.0) 将被解释为 (50.0, 100.0)。OpenGL中有这样的功能吗?知道我需要修改什么以保留我输入的纹理坐标吗?


自从输入上述内容并进行了一些研究后,我发现有一个用于此效果的 GL_TEXTURE 矩阵。整洁的!事实上,当我最初得到这个矩阵的值时,它是好的 ol' 单位矩阵:

 1  0  0  0
 0  1  0  0
 0  0  1  0
 0  0  0  1

当我在 MotionBuilder 捏造我的纹理坐标后再次检查它时:

16  0  0  0
 0 16  0  0
 0  0  1  0
 0  0  0  1

多有话说!但这里有一个小问题:如果我在自己绘制之前尝试显式设置纹理矩阵,无论 MotionBuilder 在做什么,似乎我的纹理坐标都没有效果,它只是对纹理的左下角进行采样( 0.0, 0.0) 对于每个顶点。

这是尝试的修复,位于RenderScene上面发布的代码之后:

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

我可以验证 GL_TEXTURE_MATRIX 的值现在是单位矩阵,但无论我在 glTexCoord2f 中指定什么坐标,它总是像每个顶点的坐标是 (0.0, 0.0) 一样绘制:

mbtexturematrix.jpg
(来源:awforsythe.com

知道还有什么会影响 OpenGL 如何解释我的纹理坐标吗?

4

1 回答 1

2

啊哈!这些电话:

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

...必须在GL_TEXTURE_2D启用后进行。

...应该通过将矩阵模式设置回GL_MODELVIEW. 显然,我在重置纹理矩阵(glViewport和/或gluPerspective?)后立即调用的某些函数会影响当前的矩阵堆栈。所以这些调用影响了纹理矩阵,导致我的纹理坐标以意想不到的方式被转换。

我想我现在明白了。

于 2012-08-16T22:57:01.950 回答