当前位置: 首页 > 知识库问答 >
问题:

什么会全局影响OpenGL中的纹理坐标值?

卢知
2023-03-14

我正在为一个名为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()

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

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

自从输入了上面的内容,并且做了一些研究之后,我发现有一个GL_纹理矩阵用于这种效果。整洁的事实上,当我一开始得到这个矩阵的值时,它是一个好的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)一样绘制:

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

共有1个答案

田嘉澍
2023-03-14

啊哈!这些电话:

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

<罢工> ...必须在之后制作 GL_TEXTURE_2D已启用。

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

我想我现在明白了。

 类似资料:
  • 任何人请解释为什么framework在调用detach时需要删除这个纹理对象,因为纹理是在SurfaceTexture外部创建并提供给Constructor的。因此,我希望使用纹理,即使在分离和创建者应该能够控制它的生命周期。 我们正尝试将它与附加方法和MediaCodec结合使用。在我们的用例中,我们需要复制视频帧纹理以供将来使用。 下面是创建SurfaceTexture的示例代码: 但问题是a

  • 问题内容: 有在。根据文件我应该 如果您打算将URL连接用于输出,请将DoOutput标志设置为true,否则将其设置为false。 现在,我正好面对这个问题 -Java运行时将请求转换为一次调用,而服务器仅响应请求。我想了解如果我从代码中删除代码会发生什么。 这究竟会影响什么?假设我将其设置为-现在可以做什么,现在不能做什么?我可以执行请求吗?在此方法的上下文中,“输出”是什么? 问题答案: 如

  • 我有一个用于OpenGL中模型渲染的纹理数组。此数组包含漫反射和镜面纹理。由于某些网格没有镜面纹理,因此我在每次渲染后简单地将NULL纹理绑定到我的镜面采样器,并且只有当网格具有镜面纹理时,我才绑定一个。但是,我仍然在没有镜面纹理的网格上看到镜面纹理。 这是我的渲染代码 材质索引保存数组中纹理的索引,如果网格没有镜面纹理 索引为-1 纹理单元0用于漫反射 纹理单元2用于镜面

  • 所以最近我开始阅读OpenGL维基文章。这就是我在这里描述OpenGL纹理的方式。不过,有几点尚不清楚。 以下陈述是真的、假的还是视情况而定? 将两个纹理绑定到同一个纹理单元是不可能的。 将两个采样器绑定到同一个纹理单元是不可能的。 将一个纹理绑定到两个不同的纹理单元是不可能的。 将一个采样器绑定到两个不同的纹理单元是不可能的。 应用程序有责任明确将什么采样器类型传递给什么统一变量。 着色器程序有

  • “我在我的申请中发现了一个奇怪的行为,希望你能解释给我听。”。你看,我有两个3D纹理,它们被发送到片段着色器,渲染得非常好。但有一个问题,当我创建另一个纹理(它是1D纹理)时,一个黑屏正在被渲染,而不是正确的前一个结果。 关于这个1D纹理,我甚至没有将其发送到片段着色器。当我调用glTexImage1D(…)时,黑屏就出现了。我评论这句话,它就消失了!!这两种纹理被渲染。 我觉得纹理单位肯定有问题

  • 在andrid上的opengl es中,当我将两个纹理相邻放置时,会有一个轻微的接缝,可以看到它们后面绘制的对象。基本上看起来是一个小差距。我把范围缩小到了地图上 glTexParameteri(GL_纹理_2D、GL_纹理_最小过滤器、GL_线性_MIPMAP_线性);glTexParameteri(GL_纹理_2D、GL_纹理_MAG_过滤器、GL_线性); 如果我将它们都设置为距接缝最近的G