我正在为一个名为Autodesk MotionBuilder的应用程序编写一个插件,它有一个OpenGL渲染器,我正在尝试将纹理几何体渲染到场景中。我有一个嵌入3D视图的窗口,每次渲染窗口时,都会(简而言之)会发生什么:
这里的挑战是我从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 http://awforsythe.com/i/mbtexture.jpg
从右边的特写中可以看出,当要求MotionBuilder渲染其文件无法找到的纹理时,它会加载这个小问号纹理并将其平铺在几何体上。我唯一的假设是MotionBuilder正在改变一些全局纹理坐标标量,以便例如将glTexCoord2f(0.5,1.0)解释为(50.0,100.0)。 OpenGL中有这样的功能吗?知道我需要修改什么来保存我输入的纹理坐标吗?
自从键入上述内容并进行一些研究后,我发现有一个GL_TEXTURE矩阵用于此效果。整齐!事实上,当我最初得到这个矩阵的值时,它就是好的身份矩阵:
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 http://awforsythe.com/i/mbtexturematrix.jpg
知道还有什么可能会影响OpenGL如何解释我的纹理坐标?
答案 0 :(得分:2)
啊哈!这些电话:
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
...必须在 GL_TEXTURE_2D
启用后进行。
...应该通过将矩阵模式设置回GL_MODELVIEW
来跟进。事实证明,重置纹理矩阵(glViewport
和/或gluPerspective
?)后我立即调用的一些函数会影响当前的矩阵堆栈。所以那些调用正在影响纹理矩阵,导致我的纹理坐标以意想不到的方式转换。
我想我现在已经知道了。