将纹理绑定到Objective-C中的GLSL着色器

将纹理绑定到Objective-C中的GLSL着色器,objective-c,opengl,glsl,shader,texture-mapping,Objective C,Opengl,Glsl,Shader,Texture Mapping,我在MacOSX下工作,试图通过GLSL着色器在立方体上映射图像 我显示立方体(以及未通过着色器时的图像)的方法是: 正如您所看到的,在这个测试中,我正在检查是否有一个着色器应用到我的对象上(这是一个运行非常好的包装) 如果没有着色器,我只启用GL_纹理_坐标_数组,如果有,我尝试将图像绑定到着色器中的sampler2D均匀 我使用的着色器非常简单:它只显示纹理。我在Quartz Composer下测试了它,效果很好 但是,在这里,它只显示黑色 编辑 这是着色器 顶点 varying vec2

我在MacOSX下工作,试图通过GLSL着色器在立方体上映射图像

我显示立方体(以及未通过着色器时的图像)的方法是:

正如您所看到的,在这个测试中,我正在检查是否有一个着色器应用到我的对象上(这是一个运行非常好的包装)

如果没有着色器,我只启用GL_纹理_坐标_数组,如果有,我尝试将图像绑定到着色器中的sampler2D均匀

我使用的着色器非常简单:它只显示纹理。我在Quartz Composer下测试了它,效果很好

但是,在这里,它只显示黑色

编辑 这是着色器

顶点

varying vec2 texture_coordinate;

void main() {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
texture_coordinate = vec2(gl_MultiTexCoord0);
}
碎片

varying vec2 texture_coordinate;
uniform sampler2D tex0;

void main()
{
gl_FragColor = gl_Color * texture2D(tex0, gl_TexCoord[0].xy);
}

将仅在着色器为NULL时应用纹理坐标指针的错误逻辑替换为:

if(shader != nil) {
  glUseProgramObjectARB([shader programObject]);
  glUniform1iARB([shader getUniformLocation:"tex0"], 0);
}

// You need texture coordinates in shaders too!
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, sizeof(btVector3), &textureCoords[0].getX());
稍后,您还需要更正清理代码:

if (shader != nil) {
  glUseProgramObjectARB(NULL);
}

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
然后,当需要纹理坐标时,在顶点着色器中,使用
gl\u MultiTexCoord0
。。。使用不同的方法将其传递给片段着色器


进行此操作时,不要在每次绘制时设置
tex0
采样器的值。GLSL程序持续保持统一状态,当您设置采样器时,采样器在整个程序生命周期的大部分时间都引用相同的纹理单元。因此,在链接程序后立即设置采样器制服的值更为合理,并且在该点之后再也不要设置它们。

您能实际向我们展示着色器吗?首先,
GL_纹理_坐标_数组
不推荐使用,您应该使用顶点属性。如果未使用顶点属性,则需要使用适当的固定函数GLSL保留字(例如,
gl\u MultiTexCoord0
)。想想看,即使你在着色器中使用保留字来获取纹理坐标,因为当着色器为非NULL时你没有设置纹理坐标指针,这无论如何都不会起作用。谢谢,我已经完成了着色器代码。即使有你的答案,它也不起作用。。。是的,问题是您使用的是
gl\u TexCoord[0].xy
。我建议您在片段着色器中将其替换为
纹理\u坐标
,这样您就可以开始了
gl_TexCoord[n]
可用于存储顶点和片段着色器阶段之间的纹理坐标,但如果您想要迁移到现代OpenGL(其中不存在特定保留字),最好避免使用它。或者,您可以设置
gl_TexCoord[0]=gl_MultiTexCoord0在顶点着色器中,但我再次尝试为您设置一条路径,以帮助您过渡到现代GLSL。抱歉,但没有。。。它不起作用。但是,多亏了你,我开始明白了。我想当我能够显示这个纹理时,我的生活会像一个梦:)顺便问一下,你真的有3D纹理坐标吗?如果它们存储为数组中的二维坐标,则表示您向OpenGL传递了错误的指针信息。我通常希望看到:
glTexCoordPointer(2,GL_FLOAT,sizeof(btVector2),&textureCoords[0].getX())除非您正在进行纹理投影或3D纹理处理。
if (shader != nil) {
  glUseProgramObjectARB(NULL);
}

glDisableClientState(GL_TEXTURE_COORD_ARRAY);