0

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.

Community
  • 1
  • 1
Ilya Lapan
  • 1,103
  • 2
  • 12
  • 31
  • Possible duplicate of [OpenGl read and write to the same texture](http://stackoverflow.com/questions/11410292/opengl-read-and-write-to-the-same-texture) – vallentin Apr 22 '17 at 18:17
  • @Vallentin I don't think that this is a duplicate of that thread. First of all, in that thread the only answer provided is 'This can not be done'. Actually, the question asked in that thread has an answer: glCopyTexImage2D. glCopyTexImage2D is not mentioned there at all. Here is am specifically asking about using glCopyTexImage2D with a frame buffer. – Ilya Lapan Apr 22 '17 at 18:21
  • @Vallentin the issue is that I know how to use `glTexImage2D()` when rendering to the screen. But I want to use it when rendering offscreen. If I render to texture, that texture can not be used as input at the same time. But there is can not find any documentation on offscreen rendering and `glTexImage2D()`. `glTexImage2D()` copies from back buffer by default, if I am not mistaken. – Ilya Lapan Apr 22 '17 at 18:30
  • 1
    `glCopyTexImage` will work no matter if the default framebuffer or a custom FBO is used as the source. When you say it "doesn't work", it is unclear what is actually going on, but there is most likely some error in your code. – derhass Apr 22 '17 at 18:58
  • @derhass thank you. I was not sure whether or not that was my mistake or whether it was not supposed to work in this way. I will try again then and will try to see whether my code is working properly. – Ilya Lapan Apr 22 '17 at 20:32
  • @derhass I've edited the post showing how I am using glCopyTexImage2D here to copy from frame buffer. I am using it correctly? It is not working for me – Ilya Lapan Apr 23 '17 at 10:56
  • I don't see anything wrong with the code. Make sure `glReadBuffer` is set to `GL_COLOR_ATTACHMENT0`, though (but that should be default for a FBO). Apart from that, `glCopyTexSubImage2D` should be more efficient, as it does not recreate the texture objects' storage completely, but both should work. – derhass Apr 23 '17 at 21:41

0 Answers0