I'd like to render a scene to an initially empty texture. To do so, I use a Framebuffer Object to which I attach an empty 2d texture and a depth buffer. After the set up, as for testing, I draw a simple quad into the scene. Every vertex has a different color, so I eventually expect a color-interpolated quad in the texture. I then use that texture containing the quad and map it on another quad. So evetually, I have a quad in my default Framebuffer which has a texture containing a colored quad. I hope this is not too confusing...
我想渲染一个最初空洞的纹理。为此,我使用一个Framebuffer对象,我将一个空的2d纹理和一个深度缓冲连接起来。在设置完毕后,为了测试,我在场景中画了一个简单的quad。每个顶点都有不同的颜色,所以我最终希望在纹理中有一个彩色插值的quad。然后,我使用这个纹理,包含了quad,并将它映射到另一个quad上。因此,我在默认的Framebuffer中有一个quad,它的纹理包含一个彩色的quad。我希望这不是太混乱……
Anyway, I must be missing something here, since what I get is nothing but a grey texture. I basically followed this instructions which are pretty straight forward. However, I cannot quite figure out what I am missing here. I would be grateful if somebody could give me a clue.
不管怎样,我一定是漏掉了什么,因为我得到的只是一个灰色的纹理。我基本上遵循了这个非常直接的指令。然而,我不知道这里缺少什么。如果有人能给我一个提示,我会很感激的。
Thanks Walter
由于沃尔特
This is the code I have so far: // create frame buffer object glGenFramebuffers(1, &frameBufferObject);
这是迄今为止我所拥有的代码://创建帧缓冲对象glgenframebuffer (1, &frameBufferObject);
// create depth buffer
glGenRenderbuffers(1, &depthAttachment);
// create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB;
GLuint format = GL_RGB;
unsigned char* texels = new unsigned char[width * height * numberOfChannels];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] texels;
texels = NULL;
// activate & bind empty texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
// attach empty texture to framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// define render targets (empty texture is at GL_COLOR_ATTACHMENT0)
glDrawBuffers(1, GL_COLOR_ATTACHMENT0);
// attach depth buffer
glBindRenderbuffer(GL_RENDERBUFFER, depthAttachment);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthAttachment);
// use framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
// draw the colored quad into the initially empty texture
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
// store attibutes
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// reset viewport
glViewport(0, 0, width, height);
// make background yellow
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
// draw quad into texture attached to frame buffer object
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(0.0f, 100.0f); // top left
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0.0f, 0.0f); // bottom left
glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glVertex2f(100.0f, 0.0f); // bottom right
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(100.0f, 100.0f); // top right
glEnd();
// restore attributes
glPopAttrib();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// use default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// clear default framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw the scene
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 1.0);
// begin texture mapping
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBegin(GL_QUADS);
glNormal3d(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 50.0f, -100.0f); // top left
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, -100.0f); // bottom left
glTexCoord2f(1.0f, 1.0f); glVertex3f(50.0f, 0.0f, -100.0f); // bottom right
glTexCoord2f(1.0f, 0.0f); glVertex3f(50.0f, 50.0f, -100.0f); // top right
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
// swap buffers (I forgot to mention that I use SDL)
SDL_GL_SwapBuffers();
Expected result:
预期结果:
- Texture with a colored quad on a yellow background
- 在黄色背景上有一个彩色的四轴的纹理。
- That texture is mapped on another quad
- 这个纹理映射在另一个四边形上。
Actual result:
实际结果:
- A grey texture
- 一个灰色纹理
- Texture can successfully be mapped on the other quad
- 纹理可以成功地映射到另一个quad上。
EDIT: I missed to mention the error handling. This is how I check for errors. It includes the additional cases Paul S suggested. Thanks for that.
编辑:我没有提到错误处理。这是我检查错误的方法。它包括保罗提出的附加案例。谢谢你,。
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
return;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
throw FramebufferIncompleteException("An attachment could not be bound to frame buffer object!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
throw FramebufferIncompleteException("Attachments are missing! At least one image (texture) must be bound to the frame buffer object!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
throw FramebufferIncompleteException("The dimensions of the buffers attached to the currently used frame buffer object do not match!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
throw FramebufferIncompleteException("The formats of the currently used frame buffer object are not supported or do not fit together!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
throw FramebufferIncompleteException("A Draw buffer is incomplete or undefinied. All draw buffers must specify attachment points that have images attached.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
throw FramebufferIncompleteException("A Read buffer is incomplete or undefinied. All read buffers must specify attachment points that have images attached.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
throw FramebufferIncompleteException("All images must have the same number of multisample samples.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS :
throw FramebufferIncompleteException("If a layered image is attached to one attachment, then all attachments must be layered attachments. The attached layers do not have to have the same number of layers, nor do the layers have to come from the same kind of texture.");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
throw FramebufferIncompleteException("Attempt to use an unsupported format combinaton!");
break;
default:
throw FramebufferIncompleteException("Unknown error while attempting to create frame buffer object!");
break;
}
EDIT 2: This is the method I use to check for GL-errors
编辑2:这是我用来检查错误的方法。
checkForGLErrors(string sourceFile, int line)
GLenum error = glGetError();
ostringstream o;
switch(error) {
case GL_NO_ERROR:
return;
break;
case GL_INVALID_ENUM:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid enum!"<<endl;
throw GLErrorException(o.str());
break;
case GL_INVALID_VALUE:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid value!"<<endl;
throw GLErrorException(o.str());
break;
case GL_INVALID_OPERATION:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid operation!"<<endl;
throw GLErrorException(o.str());
break;
case GL_STACK_OVERFLOW:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Stack overflow!"<<endl;
throw GLErrorException(o.str());
break;
case GL_STACK_UNDERFLOW:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Stack underflow!"<<endl;
throw GLErrorException(o.str());
break;
case GL_OUT_OF_MEMORY:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Out Of memory!"<<endl;
throw GLErrorException(o.str());
break;
case GL_TABLE_TOO_LARGE:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Table too large!"<<endl;
throw GLErrorException(o.str());
break;
default:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Unknown error!"<<endl;
throw GLErrorException(o.str());
break;
}
}
3 个解决方案
#1
5
I resolved this issue.
我解决了这个问题。
So here is what I do. Maybe there is some better / smarter way to do it, but it works perfectly fine now. Feel free to suggest adaptions...
这就是我所做的。也许有更好的/更聪明的方法来做,但是现在它工作的很好。请随意建议改编……
I don't list the error handling beneath. You can find that further up in this question.
我不列出下面的错误处理。你可以在这个问题中找到进一步的答案。
// create frame buffer object
glGenFramebuffers(1, frameBufferObject);
// create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB8;
GLuint format = GL_RGB;
unsigned char* texels = new unsigned char[width * height * numberOfChannels];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);
delete[] texels;
texels = NULL;
// draw the colored quad into the initially empty texture
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
// store attibutes
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// reset viewport
glViewport(0, 0, width, height);
// setup modelview matrix
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup projection matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// setup orthogonal projection
glOrtho(-width / 2, width / 2, -height / 2, height / 2, 0, 1000);
// bind framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
// attach empty texture to framebuffer object
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// check framebuffer status (see above)
// bind framebuffer object (IMPORTANT! bind before adding color attachments!)
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
// define render targets (empty texture is at GL_COLOR_ATTACHMENT0)
glDrawBuffers(1, GL_COLOR_ATTACHMENT0); // you can of course have more than only 1 attachment
// activate & bind empty texture
// I figured activating and binding must take place AFTER attaching texture as color attachment
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
// clear color attachments
glClear(GL_COLOR_BUFFER_BIT);
// make background yellow
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
// draw quad into texture attached to frame buffer object
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(0.0f, 100.0f); // top left
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0.0f, 0.0f); // bottom left
glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glVertex2f(100.0f, 0.0f); // bottom right
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(100.0f, 100.0f); // top right
glEnd();
// reset projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// reset modelview matrix
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore attributes
glPopAttrib();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// I guess, now it's OK to create MipMaps
// draw the scene
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 1.0);
// begin texture mapping
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// normal faces "camera"
glNormal3d(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glNormal3d(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 50.0f, -100.0f); // top left
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, -100.0f); // bottom left
glTexCoord2f(1.0f, 1.0f); glVertex3f(50.0f, 0.0f, -100.0f); // bottom right
glTexCoord2f(1.0f, 0.0f); glVertex3f(50.0f, 50.0f, -100.0f); // top right
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
// finish rendering
glFlush();
glFinish();
// swap buffers (I forgot to mention that I use SDL)
SDL_GL_SwapBuffers();
// do the clean up!
As you see, I got rid of the depth buffer attachment. I figured that I don't really need it for my task. As soon as I actually could draw things, I added the orthogonal projection. Without that, drawing to a texture results in pretty awkward images...
如您所见,我删除了深度缓冲附件。我认为我并不需要它来完成我的任务。只要我能画出一些东西,我就加入了正交投影。如果没有这一点,绘制纹理会产生一些非常尴尬的画面……
Hope this is useful for somebody out there Walter
希望这对外面的人有用。
#2
4
Weird, both glDrawBuffers and glFramebufferTexture2D don't look like the specs! The first one takes an array of GLenum, and not a GLenum (check warnings: it can be silently casted!). And the second one only take 4 arguments on the specs!
奇怪的是,gldrawbuffer和glFramebufferTexture2D都不像规范!第一个选择的是格伦姆的数组,而不是一个GLenum(检查警告:它可以被安静地casted!)而第二个则只接受4个参数的参数!
EDIT:
编辑:
void glDrawBuffers(GLsizei n, const GLenum * bufs);
#3
1
I expect what is happening either:
我希望发生的事情是:
- You're rendering from an unpopulated mip-map level. You're calling glGenerateMipmap well before you've rendered the coloured quad. Just try GL_NEAREST for now.
- 您正在从一个未填充的mip-map级别呈现。你在渲染彩色四边形之前,已经把它叫做glGenerateMipmap。试试gl_最近的。
- You're getting an error when you create your framebuffer object. If that happens your rendering will just fall down a black hole.
- 当您创建framebuffer对象时,您会得到一个错误。如果这种情况发生,你的渲染就会掉进黑洞。
Here's a snippet of code I use to check the frame buffer status. It uses the EXT version of FBOs and is in Objective-C (hence the @"" strings), but it should be obvious. It comes after I've called glBindFramebuffer, glFramebufferTexture2D & glDrawBuffers.
下面是我用来检查帧缓冲状态的代码片段。它使用了FBOs的EXT版本,在Objective-C中(也就是@“字符串”),但它应该是显而易见的。在我调用了glBindFramebuffer、glFramebufferTexture2D和gldrawbuffer之后。
GLenum framebufferStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch (framebufferStatus) {
case GL_FRAMEBUFFER_COMPLETE_EXT: break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
NSLog(@"Framebuffer Object %d Error: Attachment Point Unconnected", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
NSLog(@"Framebuffer Object %d Error: Missing Attachment", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
NSLog(@"Framebuffer Object %d Error: Dimensions do not match", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
NSLog(@"Framebuffer Object %d Error: Formats", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
NSLog(@"Framebuffer Object %d Error: Draw Buffer", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
NSLog(@"Framebuffer Object %d Error: Read Buffer", i);
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
NSLog(@"Framebuffer Object %d Error: Unsupported Framebuffer Configuration", i);
break;
default:
NSLog(@"Framebuffer Object %d Error: Unkown Framebuffer Object Failure", i);
break;
}
The problem is likely to be the depth buffer, as drivers tend to be quite picky about this. For this test you don't need depth so you could remove the render buffer stuff if it's causing issues.
这个问题很可能是深度缓冲,因为司机们往往对这个问题很挑剔。对于这个测试,您不需要深度,所以如果它引起问题,您可以删除渲染缓冲区的内容。
Another note, the texture doesn't need to be bound and active for rendering to it. You could postpone that code until you want to use it to render your final image.
另一个注意事项是,纹理不需要绑定和主动渲染。您可以延迟该代码,直到您想使用它来呈现您的最终图像。
#1
5
I resolved this issue.
我解决了这个问题。
So here is what I do. Maybe there is some better / smarter way to do it, but it works perfectly fine now. Feel free to suggest adaptions...
这就是我所做的。也许有更好的/更聪明的方法来做,但是现在它工作的很好。请随意建议改编……
I don't list the error handling beneath. You can find that further up in this question.
我不列出下面的错误处理。你可以在这个问题中找到进一步的答案。
// create frame buffer object
glGenFramebuffers(1, frameBufferObject);
// create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB8;
GLuint format = GL_RGB;
unsigned char* texels = new unsigned char[width * height * numberOfChannels];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);
delete[] texels;
texels = NULL;
// draw the colored quad into the initially empty texture
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
// store attibutes
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// reset viewport
glViewport(0, 0, width, height);
// setup modelview matrix
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// setup projection matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// setup orthogonal projection
glOrtho(-width / 2, width / 2, -height / 2, height / 2, 0, 1000);
// bind framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
// attach empty texture to framebuffer object
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// check framebuffer status (see above)
// bind framebuffer object (IMPORTANT! bind before adding color attachments!)
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
// define render targets (empty texture is at GL_COLOR_ATTACHMENT0)
glDrawBuffers(1, GL_COLOR_ATTACHMENT0); // you can of course have more than only 1 attachment
// activate & bind empty texture
// I figured activating and binding must take place AFTER attaching texture as color attachment
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
// clear color attachments
glClear(GL_COLOR_BUFFER_BIT);
// make background yellow
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
// draw quad into texture attached to frame buffer object
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(0.0f, 100.0f); // top left
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0.0f, 0.0f); // bottom left
glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glVertex2f(100.0f, 0.0f); // bottom right
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(100.0f, 100.0f); // top right
glEnd();
// reset projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// reset modelview matrix
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// restore attributes
glPopAttrib();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// I guess, now it's OK to create MipMaps
// draw the scene
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 1.0);
// begin texture mapping
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// normal faces "camera"
glNormal3d(0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glNormal3d(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 50.0f, -100.0f); // top left
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, -100.0f); // bottom left
glTexCoord2f(1.0f, 1.0f); glVertex3f(50.0f, 0.0f, -100.0f); // bottom right
glTexCoord2f(1.0f, 0.0f); glVertex3f(50.0f, 50.0f, -100.0f); // top right
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
// finish rendering
glFlush();
glFinish();
// swap buffers (I forgot to mention that I use SDL)
SDL_GL_SwapBuffers();
// do the clean up!
As you see, I got rid of the depth buffer attachment. I figured that I don't really need it for my task. As soon as I actually could draw things, I added the orthogonal projection. Without that, drawing to a texture results in pretty awkward images...
如您所见,我删除了深度缓冲附件。我认为我并不需要它来完成我的任务。只要我能画出一些东西,我就加入了正交投影。如果没有这一点,绘制纹理会产生一些非常尴尬的画面……
Hope this is useful for somebody out there Walter
希望这对外面的人有用。
#2
4
Weird, both glDrawBuffers and glFramebufferTexture2D don't look like the specs! The first one takes an array of GLenum, and not a GLenum (check warnings: it can be silently casted!). And the second one only take 4 arguments on the specs!
奇怪的是,gldrawbuffer和glFramebufferTexture2D都不像规范!第一个选择的是格伦姆的数组,而不是一个GLenum(检查警告:它可以被安静地casted!)而第二个则只接受4个参数的参数!
EDIT:
编辑:
void glDrawBuffers(GLsizei n, const GLenum * bufs);
#3
1
I expect what is happening either:
我希望发生的事情是:
- You're rendering from an unpopulated mip-map level. You're calling glGenerateMipmap well before you've rendered the coloured quad. Just try GL_NEAREST for now.
- 您正在从一个未填充的mip-map级别呈现。你在渲染彩色四边形之前,已经把它叫做glGenerateMipmap。试试gl_最近的。
- You're getting an error when you create your framebuffer object. If that happens your rendering will just fall down a black hole.
- 当您创建framebuffer对象时,您会得到一个错误。如果这种情况发生,你的渲染就会掉进黑洞。
Here's a snippet of code I use to check the frame buffer status. It uses the EXT version of FBOs and is in Objective-C (hence the @"" strings), but it should be obvious. It comes after I've called glBindFramebuffer, glFramebufferTexture2D & glDrawBuffers.
下面是我用来检查帧缓冲状态的代码片段。它使用了FBOs的EXT版本,在Objective-C中(也就是@“字符串”),但它应该是显而易见的。在我调用了glBindFramebuffer、glFramebufferTexture2D和gldrawbuffer之后。
GLenum framebufferStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch (framebufferStatus) {
case GL_FRAMEBUFFER_COMPLETE_EXT: break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
NSLog(@"Framebuffer Object %d Error: Attachment Point Unconnected", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
NSLog(@"Framebuffer Object %d Error: Missing Attachment", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
NSLog(@"Framebuffer Object %d Error: Dimensions do not match", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
NSLog(@"Framebuffer Object %d Error: Formats", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
NSLog(@"Framebuffer Object %d Error: Draw Buffer", i);
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
NSLog(@"Framebuffer Object %d Error: Read Buffer", i);
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
NSLog(@"Framebuffer Object %d Error: Unsupported Framebuffer Configuration", i);
break;
default:
NSLog(@"Framebuffer Object %d Error: Unkown Framebuffer Object Failure", i);
break;
}
The problem is likely to be the depth buffer, as drivers tend to be quite picky about this. For this test you don't need depth so you could remove the render buffer stuff if it's causing issues.
这个问题很可能是深度缓冲,因为司机们往往对这个问题很挑剔。对于这个测试,您不需要深度,所以如果它引起问题,您可以删除渲染缓冲区的内容。
Another note, the texture doesn't need to be bound and active for rendering to it. You could postpone that code until you want to use it to render your final image.
另一个注意事项是,纹理不需要绑定和主动渲染。您可以延迟该代码,直到您想使用它来呈现您的最终图像。