解除绑定 Open GL ES 纹理的正确方法?
Correct way to unbind an Open GL ES texture?
我的绘图代码首先绘制没有纹理的背景,然后在其上叠加纹理。我目前正在使用 glBindTexture(GL_TEXTURE_2D, 0)
以便在执行第二批绘图后取消绑定纹理。
但是,当我在 Xcode 中分析 GPU 性能时,会生成以下警告:
当我删除取消绑定纹理的代码时,警告消失了,但绘制不正确。我正在绘制的纹理没有启用 mipmapping,所以它不是来自那里。
绘图代码:
glClear(GL_COLOR_BUFFER_BIT);
{ // Drawing
glViewport(0, 0, frameWidth, frameHeight);
GLuint vertexCount = animBuffer.vertexCounts[animIndex];
glBindBuffer(GL_ARRAY_BUFFER, animBuffer.vertexBuffers[animIndex]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, animBuffer.indexBuffers[animIndex]);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*3));
glVertexAttribPointer(textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*7));
glDrawElements(GL_TRIANGLE_STRIP, vertexCount, GL_UNSIGNED_SHORT, 0);
// glEnable(GL_TEXTURE_2D) (tried this, gives another warning)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, textureColorBuffer); // Transparent color buffer to allow texture to be overlayed.
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(float)*3));
glDrawElements(GL_TRIANGLE_STRIP, vertexCount, GL_UNSIGNED_SHORT, 0);
// Unbind texture.... this line is causing the error.
glBindTexture(GL_TEXTURE_2D, 0);
// glDisable(GL_TEXTURE_2D) (tried this, gives another warning)
}
[context presentRenderbuffer:GL_RENDERBUFFER];
纹理加载代码:
CGImageRef textureImage = image.CGImage;
size_t width = CGImageGetWidth(textureImage);
size_t height = CGImageGetHeight(textureImage);
GLubyte* spriteData = malloc(width*height*4);
CGColorSpaceRef cs = CGImageGetColorSpace(textureImage);
CGContextRef c = CGBitmapContextCreate(spriteData, width, height, 8, width*4, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(cs);
CGContextScaleCTM(c, 1, -1);
CGContextTranslateCTM(c, 0, -CGContextGetClipBoundingBox(c).size.height);
CGContextDrawImage(c, (CGRect){CGPointZero, {width, height}}, textureImage);
CGContextRelease(c);
GLuint glTex;
glGenTextures(1, &glTex);
glBindTexture(GL_TEXTURE_2D, glTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
glBindTexture(GL_TEXTURE_2D, 0);
free(spriteData);
return glTex;
我应该如何解除绑定纹理以消除此警告?
编辑:
我曾尝试在纹理绘图前后使用 glEnable(GL_TEXTURE_2D)
& glDisable(GL_TEXTURE_2D)
,尽管这现在给了我以下警告:
我认为避免此警告的最简单方法是保持纹理绑定,但只需向片段着色器发送一个 uniform
指示是否混合纹理。
所以,在绘制之前添加:
glUniform1i(drawTexInput, GL_FALSE); // Or GL_TRUE to draw.
在片段着色器中:
varying lowp vec4 destinationColor;
uniform bool drawTex;
varying lowp vec2 texCoordOut;
uniform sampler2D tex;
void main() {
lowp vec4 result;
if (drawTex) {
lowp vec4 tex2D = texture2D(tex, texCoordOut);
result = tex2D + vec4(1.0 - tex2D.a) * destinationColor; // Alpha blending
} else {
result = destinationColor;
}
gl_FragColor = result;
}
我的绘图代码首先绘制没有纹理的背景,然后在其上叠加纹理。我目前正在使用 glBindTexture(GL_TEXTURE_2D, 0)
以便在执行第二批绘图后取消绑定纹理。
但是,当我在 Xcode 中分析 GPU 性能时,会生成以下警告:
当我删除取消绑定纹理的代码时,警告消失了,但绘制不正确。我正在绘制的纹理没有启用 mipmapping,所以它不是来自那里。
绘图代码:
glClear(GL_COLOR_BUFFER_BIT);
{ // Drawing
glViewport(0, 0, frameWidth, frameHeight);
GLuint vertexCount = animBuffer.vertexCounts[animIndex];
glBindBuffer(GL_ARRAY_BUFFER, animBuffer.vertexBuffers[animIndex]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, animBuffer.indexBuffers[animIndex]);
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), 0);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*3));
glVertexAttribPointer(textureCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)(sizeof(float)*7));
glDrawElements(GL_TRIANGLE_STRIP, vertexCount, GL_UNSIGNED_SHORT, 0);
// glEnable(GL_TEXTURE_2D) (tried this, gives another warning)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(textureUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, textureColorBuffer); // Transparent color buffer to allow texture to be overlayed.
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(float)*3));
glDrawElements(GL_TRIANGLE_STRIP, vertexCount, GL_UNSIGNED_SHORT, 0);
// Unbind texture.... this line is causing the error.
glBindTexture(GL_TEXTURE_2D, 0);
// glDisable(GL_TEXTURE_2D) (tried this, gives another warning)
}
[context presentRenderbuffer:GL_RENDERBUFFER];
纹理加载代码:
CGImageRef textureImage = image.CGImage;
size_t width = CGImageGetWidth(textureImage);
size_t height = CGImageGetHeight(textureImage);
GLubyte* spriteData = malloc(width*height*4);
CGColorSpaceRef cs = CGImageGetColorSpace(textureImage);
CGContextRef c = CGBitmapContextCreate(spriteData, width, height, 8, width*4, cs, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(cs);
CGContextScaleCTM(c, 1, -1);
CGContextTranslateCTM(c, 0, -CGContextGetClipBoundingBox(c).size.height);
CGContextDrawImage(c, (CGRect){CGPointZero, {width, height}}, textureImage);
CGContextRelease(c);
GLuint glTex;
glGenTextures(1, &glTex);
glBindTexture(GL_TEXTURE_2D, glTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
glBindTexture(GL_TEXTURE_2D, 0);
free(spriteData);
return glTex;
我应该如何解除绑定纹理以消除此警告?
编辑:
我曾尝试在纹理绘图前后使用 glEnable(GL_TEXTURE_2D)
& glDisable(GL_TEXTURE_2D)
,尽管这现在给了我以下警告:
我认为避免此警告的最简单方法是保持纹理绑定,但只需向片段着色器发送一个 uniform
指示是否混合纹理。
所以,在绘制之前添加:
glUniform1i(drawTexInput, GL_FALSE); // Or GL_TRUE to draw.
在片段着色器中:
varying lowp vec4 destinationColor;
uniform bool drawTex;
varying lowp vec2 texCoordOut;
uniform sampler2D tex;
void main() {
lowp vec4 result;
if (drawTex) {
lowp vec4 tex2D = texture2D(tex, texCoordOut);
result = tex2D + vec4(1.0 - tex2D.a) * destinationColor; // Alpha blending
} else {
result = destinationColor;
}
gl_FragColor = result;
}