DGL
https://delphigl.com/forum/

Backbuffer corruption
https://delphigl.com/forum/viewtopic.php?f=19&t=10994
Seite 1 von 1

Autor:  GL123 [ Di Okt 08, 2013 22:27 ]
Betreff des Beitrags:  Backbuffer corruption

Hi guys,

I hope someone can help this annoying issue I am having. I have gotten GLSL working using your dglopengl libraries and can successfully get most of the shaders here http://glsl.heroku.com/ working as on the website.

My problem is when I try and duplicate the ones that use a backbuffer texture to render to (so as to blend with it on the next frame).

For example this one http://glsl.heroku.com/e#11440.0 smoothly blends with the backbuffer, but when I try the same I get a diagonal split and many small squares like this that break up the image.
Bild
One thing to note is those "lines" stay in the same place. Every frame the diagonal and square shapes remain in the same positions.

Here is another sample. The diagonal line and squares (in this case they are more horizontal lines) are more obvious here. The grey blur should be smooth.
Bild

Any ideas as to why? It really ruins any smaooth backbuffer effects.

I have used both glReadPixels and glGetTexImage to get the results each frame and both show the same artifacts.
glReadPixels(0,0,imwidth,imheight,GL_BGRA,GL_UNSIGNED_BYTE,tbm.bits);
//glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_UNSIGNED_BYTE,tbm.bits);
I thought it may have been the imwidth and imheight, but if I change these even a single pixel the output is truly corrupted.

I activate and bind the backbuffer each frame
glActiveTexture(backbuffer);
glBindTexture(GL_TEXTURE_2D,backbuffer);

I setup the texture as follows
glGenTextures(1,@backbuffer);
glBindTexture(GL_TEXTURE_2D,backbuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,pixdata);

and bind it to my FBO as follows
glGenFramebuffers(1,@fbo);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, backbuffer, 0);

So please, any other ideas would be very helpful.

Autor:  end [ Mi Okt 09, 2013 08:06 ]
Betreff des Beitrags:  Re: Backbuffer corruption

I had a problem like this on NVIDIA-cards, too. I found no solution - but on my NVIDIA the browser-sample works...

Autor:  Lord Horazont [ Mi Okt 09, 2013 11:16 ]
Betreff des Beitrags:  Re: Backbuffer corruption

This is strange. The artifacts look like a mix of incorrect texture coordinates and compression artifacts. Some of the effects could also be related to scaling happening in GL_NEAREST mode. Try to switch to GL_LINEAR.

Are you aware that you cannot use the framebuffer texture and the framebuffer at the same time? That is, you first have to render into the front FBO using the back FBO texture as input and then flip FBOs. The code on glsl.heroku.com does that too.

regards,
Horazont

Autor:  GL123 [ Do Okt 10, 2013 03:09 ]
Betreff des Beitrags:  Re: Backbuffer corruption

Thanks for the ideas.

I tried GL_LINEAR and the same sharp artifacts are still there. Also I am sure the heroku samples use GL_NEAREST as GL_LINEAR smooths them out too much.

FBOs are new to me and I cobbled together my code from various samples until it worked. I don't do any swapping from front to back.

My basic structure for rendering is...

The RC is for an offscreen bitmap, not directly on screen

RC := CreateRenderingContext(DC, [opDoubleBuffered,opGDI], 32, 24, 0, 0, 0, 0);

Setup the backbuffer texture and FBO before main loop

glGenTextures(1,@backbuffer);
glBindTexture(GL_TEXTURE_2D,backbuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,nil);

glGenFramebuffers(1,@fbo);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, backbuffer, 0);

Then within the main loop, pass all the uniforms and then render a fullscreen quad

glviewport(0,0,imwidth,imheight);
glBegin(GL_QUADS);
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -1, -1);
glTexCoord2f( 1.0, 0.0 ); glVertex2f( 1, -1);
glTexCoord2f( 1.0, 1.0 ); glVertex2f( 1, 1);
glTexCoord2f( 0.0, 1.0 ); glVertex2f( -1, 1);
glEnd;

And then read the frame into a graphics32 bitmap.

glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA,GL_UNSIGNED_BYTE,tbm.bits);

And then show the bitmap on the main display form

That's it. Then the loop repeats. I don't do anything with flipping fbos or putting data back into the backbuffer texture.

Any other of the shaders that do not use backbuffer all render perfect without artifacts so I don't think it is due to the card getting overheated.

Bild

Bild

I don't know what else it could be.

Autor:  Shaijan [ Do Okt 10, 2013 07:55 ]
Betreff des Beitrags:  Re: Backbuffer corruption

Hi …

i havn't checked out the site and codes but you won't get far without swapping Textures (Buffers).

Here is a basic lineout of how i would expect such an algorithm to work:
Code:
  1.  
  2. 1. Generate FBO with Texture1 and Texture2.
  3.  
  4. 2. Frame1:
  5.   3. Bind Texture1 for writing
  6.   4. Bind Texture2 for reading
  7.   5. Draw fullscreen quad and do your shader-magic
  8.   6. Blit Texture1 to screen
  9. 7. Frame2:
  10.   8. Bind Texture2 for writing
  11.   9. Bind Texture1 for reading
  12.   10. Draw fullscreen quad and do your shader-magic
  13.   11. Blit Texture2 to screen
  14. 12. goto 2
  15.  


Texture1 and Texture2 can be seen as your Screen-Buffers (Front-/Backbuffer). You read from TextureX, do some stuff with the data and render a final result into TextureY. In the next frame you parctically swap them so you have the data from the last frame to read from.
If you really do no swapping, your artifacts could be the result of reading and writing to/from the same Texture at the same time.

Autor:  Lord Horazont [ Do Okt 10, 2013 10:49 ]
Betreff des Beitrags:  Re: Backbuffer corruption

Yes. If you have the Texture the Framebuffer is using bound in a texture unit and you are using the framebuffer as the target, you are triggering undefined behaviour. In fact, glCheckFramebufferStatus (english reference) should show you an error about that, but that may be implementation defined, I'm not sure.

The technical reasoning behind this is most likely that graphic cards are highly parallel. If you're reading and writing to a buffer in such a parallel system, most of the time would have to be spent with synchronizing the access, making it not parallel anymore, if it can be solved at all without copying.

regards,
Horazont

Autor:  GL123 [ Do Okt 10, 2013 22:55 ]
Betreff des Beitrags:  Re: Backbuffer corruption

OK, now that makes perfect sense, and shows why this corruption only shows up when I read and write to the same texture using backbuffer.

So now I setup two textures and bind them to one FBO...

Code:
  1.  
  2.      glGenTextures(1,@backbuffer);
  3.      glBindTexture(GL_TEXTURE_2D,backbuffer);
  4.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  5.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  6.      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  7.      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  8.      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,nil);
  9.  
  10.      glGenTextures(1,@backbuffer2);
  11.      glBindTexture(GL_TEXTURE_2D,backbuffer2);
  12.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  13.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  14.      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  15.      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  16.      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,nil);
  17.  
  18.      glGenFramebuffers(1,@fbo);
  19.      glBindFramebuffer(GL_FRAMEBUFFER,fbo);
  20.      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, backbuffer, 0);
  21.      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,GL_TEXTURE_2D, backbuffer2, 0);
  22.  


What GL commands do I use to bind the 2 textures each frame?

Attempts like the following don't work.

Code:
  1.  
  2.           case frames mod 2 of
  3.                0:begin
  4.                       glDrawBuffer(GL_COLOR_ATTACHMENT0);
  5.                       glReadBuffer(GL_COLOR_ATTACHMENT1);
  6.                end;
  7.                1:begin
  8.                       glDrawBuffer(GL_COLOR_ATTACHMENT1);
  9.                       glReadBuffer(GL_COLOR_ATTACHMENT0);
  10.                end;
  11.           end;
  12.  


How do I set the read and write texture each frame?

I was able to get it working with 2 FBOs each with its own texture as shown here http://www.comp.nus.edu/~ashwinna/docs/PingPong_FBO.pdf but I read that a single FBO with 2 textures is faster, so any tips on that will be appreciated.

At least for the time being I am finally artifact free when using the backbuffer.

Bild

Autor:  Shaijan [ Fr Okt 11, 2013 07:26 ]
Betreff des Beitrags:  Re: Backbuffer corruption

You need to use glDrawBuffer to set the buffer to draw to. But as your buffers are simple textures you have to use glBindTexture to bind them for reading.

Code:
  1.  
  2. Gen-FBO with Texture0 + Texture1
  3. Bind-FBO
  4.  
  5. Frame1:
  6.   glDrawBuffer(GL_COLOR_ATTACHMENT0);
  7.   glBindTexture(GL_TEXTURE_2D, Texture1);
  8. Frame2:
  9.   glDrawBuffer(GL_COLOR_ATTACHMENT1);
  10.   glBindTexture(GL_TEXTURE_2D, Texture0);
  11.  

Autor:  GL123 [ Sa Okt 12, 2013 02:41 ]
Betreff des Beitrags:  Re: Backbuffer corruption

Thank you, that worked too. I was told that that should be faster, but on my nvidia they both are almost identical in speed.

Thanks again for your help guys.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/