Can I render a texture to a framebuffer and then copy it with glCopyTexImage2D
? A more obvious way of doing this would be to use:
glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, renderedTexture, 0);
However, this is not going to work in my case, because I want to read and write the same texture and when I use glFramebufferTexture
, I can not use the same texture as the input of the shader at the same time. I've asked about this issue not long ago on Stackoverflow: Writing and reading from the same texture for an iterative DE solver on OpenGL
glCopyTexImage2D
eliminates this issue: I render first and then copy whatever got rendered to the texture. I tried it out and it works when I render to the screen. But what if I want to do some offscreen rendering and copy that? I am not sure if glCopyTexImage2D
work when I am trying to use a FrameBuffer. I tried it, and it didn't seem to be working. Can this be done? Is there a different way to do this that applies in my case? If it is possible, can someone show me a quick snippet of how to use both a frame buffer and glCopyTexImage2D
?
This question is not the duplicate. I am not trying to read and write to the same texture at the same time. I need to write to a texture first, and then read it, consecutively. I fully understand that operation of doing those things at the same time is not well defined. In my case it is an issue of reading first, then copying and then using it again.
EDIT:
So here is how I am trying to use glCopyTexImage2D and how it fails for me with a frame buffer:
// Set "renderTargetTexture" as our colour attachement #0
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderTargetTexture, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, renderTargetTexture);
// Give an empty image to OpenGL ( the last "0" means "empty" )
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, windowWidth, windowHeight, 0,GL_RGB, GL_UNSIGNED_BYTE, 0);
// Poor filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
do{
// Set to render to our framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glViewport(0,0,windowWidth,windowHeight); // Render on the whole framebuffer, complete from the lower left corner to the upper right
// attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
//
// Processing
//
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(advectShaderID);
// Bind velocity texture to advection uniform in the shader
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, velocityTexture);
glUniform1i(advectionTextureID, 0);
// Draw the triangles
glDrawArrays(GL_TRIANGLES, 0, 6);
//Copy from framebuffer
glBindTexture(GL_TEXTURE_2D, velocityTexture);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, windowWidth, windowHeight, 0);
//
// Render to screen
//
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Render on the whole framebuffer, complete from the lower left corner to the upper right
glViewport(0,0,windowWidth,windowHeight);
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(quad_programID);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, velocityTexture);
// Set our "renderedTexture" sampler to user Texture Unit 0
glUniform1i(texID, 0);
// Draw the triangles
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
}
And this gives me just a black screen. However, when I replace glBindTexture(GL_TEXTURE_2D, velocityTexture);
with glBindTexture(GL_TEXTURE_2D, renderTargetTexture);
i.e when I render the output of the frame buffer, it gives me what I expect. Also, if I get rid of glCopyTexImage2D
and just render velocityTexture
, it produces the original texture. But, as soon as I use glCopyTexImage2D
, it copies a black screen into velocityTexture.