尝试使用帧缓冲区渲染纹理总是会导致白色纹理
使用 StackOverflow 中的几篇文章,我使用帧缓冲区创建了一个简单的渲染到纹理的内容。
这里的问题是它不起作用。混合中有些东西被破坏了,因为我的最终纹理只是一个白色方块。我没有收到任何 gl 错误。这是我的代码。
声明实例变量。
GLuint texture;
GLuint textureFrameBuffer;
生成纹理和帧缓冲区。
glGetError();
//Generate the texture that we will draw to (saves us a lot of processor).
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Use OpenGL ES to generate a name for the texture.
// Pass by reference so that our texture variable gets set.
glGenTextures(1, &texture);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, texture);
// Specify a 2D texture image, providing a pointer to the image data in memory.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
//Create a frame buffer to draw to. This will allow us to directly edit the texture.
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on framebuffer init. glError: 0x%04X", err);
}
将一个大字符串绘制到帧缓冲区中。
glGetError();
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
//Bind our frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
//Clear out the texture.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Draw the letters to the frame buffer. (calls glDrawArrays a bunch of times, binds various textures, etc.) Does everything in 2D.
[self renderDialog:displayString withSprite:displaySprite withName:displaySpriteName];
//Unbind the frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on string creation. glError: 0x%04X", err);
}
画出来吧
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glGetError();
//Draw the text.
[EAGLView enable2D];
//Push the matrix so we can keep it as it was previously.
glPushMatrix();
//Store the coordinates/dimensions from the rectangle.
float x = 0;
float y = [Globals getPlayableHeight] - dialogRect.size.height;
float w = [Globals getPlayableWidth];
float h = dialogRect.size.height;
// Set up an array of values to use as the sprite vertices.
GLfloat vertices[] =
{
x, y,
x, y+h,
x+w, y+h,
x+w, y
};
// Set up an array of values for the texture coordinates.
GLfloat texcoords[] =
{
0, 0,
0, h / 128,
w / 512, h / 128,
w / 512, 0
};
//Render the vertices by pointing to the arrays.
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
// Set the texture parameters to use a linear filter when minifying.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
//Allow transparency and blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enable 2D textures.
glEnable(GL_TEXTURE_2D);
//Bind this texture.
[EAGLView bindTexture:texture];
//Finally draw the arrays.
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Restore the model view matrix to prevent contamination.
glPopMatrix();
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on draw. glError: 0x%04X", err);
}
我所说的任何外部事物在其他情况下都可以正常工作。有什么想法吗?我对帧缓冲区几乎一无所知,因此任何故障排除帮助都会很棒。
Using a couple of posts here in StackOverflow, I created what is supposed to be a simple render-to-texture using a framebuffer.
The problem here is that it's not working. Something is broken in the mix, as my final texture is just a white square. I am not getting any gl errors whatsoever. Here is my code.
Declare instance variables.
GLuint texture;
GLuint textureFrameBuffer;
Generate the texture and framebuffer.
glGetError();
//Generate the texture that we will draw to (saves us a lot of processor).
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Use OpenGL ES to generate a name for the texture.
// Pass by reference so that our texture variable gets set.
glGenTextures(1, &texture);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, texture);
// Specify a 2D texture image, providing a pointer to the image data in memory.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
//Create a frame buffer to draw to. This will allow us to directly edit the texture.
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on framebuffer init. glError: 0x%04X", err);
}
Draw a big string into the framebuffer.
glGetError();
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
//Bind our frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
//Clear out the texture.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Draw the letters to the frame buffer. (calls glDrawArrays a bunch of times, binds various textures, etc.) Does everything in 2D.
[self renderDialog:displayString withSprite:displaySprite withName:displaySpriteName];
//Unbind the frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on string creation. glError: 0x%04X", err);
}
Draw it.
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glGetError();
//Draw the text.
[EAGLView enable2D];
//Push the matrix so we can keep it as it was previously.
glPushMatrix();
//Store the coordinates/dimensions from the rectangle.
float x = 0;
float y = [Globals getPlayableHeight] - dialogRect.size.height;
float w = [Globals getPlayableWidth];
float h = dialogRect.size.height;
// Set up an array of values to use as the sprite vertices.
GLfloat vertices[] =
{
x, y,
x, y+h,
x+w, y+h,
x+w, y
};
// Set up an array of values for the texture coordinates.
GLfloat texcoords[] =
{
0, 0,
0, h / 128,
w / 512, h / 128,
w / 512, 0
};
//Render the vertices by pointing to the arrays.
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
// Set the texture parameters to use a linear filter when minifying.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
//Allow transparency and blending.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Enable 2D textures.
glEnable(GL_TEXTURE_2D);
//Bind this texture.
[EAGLView bindTexture:texture];
//Finally draw the arrays.
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//Restore the model view matrix to prevent contamination.
glPopMatrix();
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
NSLog(@"Error on draw. glError: 0x%04X", err);
}
Any external things I called work just fine in other contexts. Any ideas? I know almost nothing about framebuffers, so any help troubleshooting would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
纹理参数是基于每个纹理设置的。您发布的代码似乎是在创建或绑定要渲染的纹理之前设置
GL_TEXTURE_MIN_FILTER
。如果您没有在其他地方设置过滤器,并且没有为其余级别指定纹理图像,则您的纹理可能不完整,这就是您变白的原因。为了将来参考,帧缓冲区设置后没有 GL 错误并不意味着帧缓冲区可用于渲染。您还应该通过调用
glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)
并验证是否返回GL_FRAMEBUFFER_COMPLETE_OES
来检查帧缓冲区是否完整。Texture parameters are set on a per-texture basis. The code you posted appears to be setting
GL_TEXTURE_MIN_FILTER
before the texture you’re rendering to has been created or bound. If you’re not setting the filter anywhere else, and you haven’t specified texture images for the remaining levels, your texture is likely incomplete, which is why you’re getting white.For future reference, the absence of GL errors after framebuffer setup does not mean that the framebuffer is usable for rendering. You should also check that the framebuffer is complete by calling
glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)
and verifying thatGL_FRAMEBUFFER_COMPLETE_OES
is returned.