OpenGL ES 2.0 多个着色器程序 - 纹理渲染不再工作
我的应用程序绘制了点精灵和标准四边形纹理的混合。直到最近,我还为此使用单个着色器程序 - 然而片段着色器中的一个分支(决定是否使用点精灵坐标/颜色)严重限制了我的渲染性能。我的片段着色器最初看起来是这样的:
precision highp float;
uniform sampler2D u_textureSprite;
uniform bool u_isSprite;
varying vec4 v_color;
varying vec2 v_textureCoord;
void main()
{
vec4 textureColor = texture2D(u_textureSprite, u_isSprite ? gl_PointCoord : v_textureCoord);
if (u_isSprite) {
gl_FragColor = v_color * textureColor;
}
else {
gl_FragColor = textureColor;
}
}
阅读 Apple 在 OpenGL ES 编程指南中的建议,听起来使用多个着色器程序是一件容易的事...只需像平常一样创建另一个着色器程序并在相关绘制代码之前调用 glUseProgram() 即可。然而,由于这样做我无法让纹理渲染工作。两个新的片段着色器是:
pointSprite.fsh:
precision highp float;
uniform sampler2D s_textureSprite;
varying vec4 v_color;
void main()
{
vec4 textureColor = texture2D(s_textureSprite, gl_PointCoord);
gl_FragColor = v_color * textureColor;
}
texture.fsh:
precision highp float;
uniform sampler2D s_texture;
varying vec2 v_textureCoord;
void main()
{
gl_FragColor = texture2D(s_texture, v_textureCoord);
}
我认为非常简单。如果我忽略所有绘制纹理的调用,我可以看到点精灵渲染得很好。然而,纹理四边形只是渲染为纯灰色 - 顺便说一句,这种灰色与任何 glClearColor() 颜色都不匹配,我相信它是来自它尝试渲染的纹理的某个点的颜色。
纹理渲染的一些示例代码如下:
- (void)drawTexture:(GLuint)texture {
glUseProgram(programs[PROGRAM_TEXTURE]);
glBindTexture(GL_TEXTURE_2D, texture);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_VERTICES]);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, vertex));
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, textureCoord));
glEnableVertexAttribArray(ATTRIB_TEXTURE_COORD);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_INDICIES]);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
该代码在不处理多个着色器时有效。或者我不小心,纹理片段着色器代码是错误的?
谢谢
编辑:
嗯,这是一段漫长而痛苦的时间,真正令人恼火的是,这不是代码问题,而是与项目目录的名称有关。
我的 Xcode 项目目录的命名如下:“ProjectName (current)”。这是我遇到麻烦的项目。我后来发现,将此文件夹名称更改为任何不同的名称可以使应用程序正常工作,并正确渲染背景纹理。只是为了澄清 - 该应用程序以前工作正常,除了在 OpenGL 中渲染背景纹理之外,并且在重命名项目文件夹后,一切工作正常。
有什么想法可能是为什么吗?
My app draws a mixture of point sprites and standard quad textures. Until recently, I was using a single shader program for this - however a branch in the fragment shader (to decide whether to use point sprite coords/colors) was seriously throttling the performance of my rendering. My fragment shader originally looked like this:
precision highp float;
uniform sampler2D u_textureSprite;
uniform bool u_isSprite;
varying vec4 v_color;
varying vec2 v_textureCoord;
void main()
{
vec4 textureColor = texture2D(u_textureSprite, u_isSprite ? gl_PointCoord : v_textureCoord);
if (u_isSprite) {
gl_FragColor = v_color * textureColor;
}
else {
gl_FragColor = textureColor;
}
}
Reading Apple's recommendations in the OpenGL ES Programming guide makes it sound like an easy job to use multiple shader programs... just create another one as normal and call glUseProgram() before the relevant draw code. However, since doing this I cannot get the texture rendering to work. The two new fragment shaders are:
pointSprite.fsh:
precision highp float;
uniform sampler2D s_textureSprite;
varying vec4 v_color;
void main()
{
vec4 textureColor = texture2D(s_textureSprite, gl_PointCoord);
gl_FragColor = v_color * textureColor;
}
texture.fsh:
precision highp float;
uniform sampler2D s_texture;
varying vec2 v_textureCoord;
void main()
{
gl_FragColor = texture2D(s_texture, v_textureCoord);
}
Pretty trivial, I think. If I ignore all calls to draw the texture, I can see that point sprites are being rendered just fine. Texture quads, however, just render to a solid grey color - incidentally this grey color does not match any of the glClearColor() colors, I believe it is a color from some point of the texture that it is trying to render.
A little sample code for a texture render is as follows:
- (void)drawTexture:(GLuint)texture {
glUseProgram(programs[PROGRAM_TEXTURE]);
glBindTexture(GL_TEXTURE_2D, texture);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_VERTICES]);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, vertex));
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTURE_COORD, 2, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ISTextureData), (void*)offsetof(ISTextureData, textureCoord));
glEnableVertexAttribArray(ATTRIB_TEXTURE_COORD);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObjects[VBO_TEXTURE_INDICIES]);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
This code works when not dealing with multiple shaders. Or am I being careless, and the texture fragment shader code is wrong?
Thanks
EDIT:
Well it's been a number of long and painful hours, and what's really irritating is that it's somehow not a code issue, but something to do with the name of the project directory.
My Xcode project directory is named as such: "ProjectName (current)". This is the project I was having trouble with. I have since discovered that changing this folder name to anything different makes the app work, and properly render the background texture. Just to clarify - the app previously worked normally with the exception of the rendering of a background texture in OpenGL, and after renaming the project folder everything works fine.
Any ideas why this might be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在哪里为着色器设置纹理统一?您需要使用如下代码指定用于纹理统一的适当纹理单元的编号:
glUniform1i() 中的第二个参数是用于拉动纹理的纹理单元的编号从。
默认情况下,该统一值为 0,对应于 GL_TEXTURE0,这就是为什么它一开始可能有效,但如果您将活动纹理单元切换为其他单元,您将无法再读取着色器中的纹理。
Where do you set up the texture uniform for your shaders? You need to assign the number of the appropriate texture unit to use for the texture uniform, using code like the following:
The second argument in
glUniform1i()
here is the number of the texture unit to pull the texture from.By default, this uniform would be 0, corresponding to GL_TEXTURE0, which is why it might have worked in the first place, but if you switched the active texture unit to something else you no longer would be able to read the texture in your shader.
奇怪的是,这与项目目录的名称有某种关系。我的 Xcode 项目目录被命名为:“ProjectName (current)”。这是我遇到麻烦的项目。将此文件夹名称更改为任何不同的名称可以使应用程序正常工作,并正确渲染背景纹理。很奇怪。
This, strangely, turned out to be somehow related to the name of the project directory. My Xcode project directory was named as such: "ProjectName (current)". This is the project I was having trouble with. Changing this folder name to anything different made the app work, and properly render the background texture. Very strange.