Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>By default OpenGL maintains two buffers: a front buffer and a back buffer. The front buffer is what is displayed while the back buffer is what you draw on. This is called double buffering and prevents partially rendered scenes from being shown to the user. Whenever you call Display.update(), lwjgl tells opengl to move the content of the back buffer to the front buffer for display. This is either done by copying the data, or by marking the old front buffer as new back buffer and the old back buffer as new front buffer (the buffers are swaped).</p> <p>This is geared towards the normal situation e.g. in games where you want to draw something new like 60 times a second. Now if you don't actually draw anything, but still call Display.update() (e.g. to get Input), the buffers are still moved. Now depending on how this is implemented, either you still see your old image (if the data is simply copied, because your back buffer then still contains the data you rendered), or you alternate with each Display.update() between the buffer you have drawn on and the buffer that was the front buffer at the time that you rendered (which is likely just black). This leads to the flickering you are seeing, as the image is only shown every second frame (original back buffer), and every other frame the black original front buffer is seen.</p> <p>With some driver implementations (e.g. from Nvidia), it seems that Windows can even draw on the active front buffer, so dialog boxes can show up and be displayed even after are closed if you don't redraw the scene.</p> <p>The cleanest solution to this is to simply render to a texture (works since OpenGL 1.1) or a renderbuffer (introduced in OpenGL 3.0) in your init, and then render this texture each frame. This is really the solution that the OpenGL designers had in mind for this type of thing.</p> <p><strong>Edit</strong>: Either you uncomment the draw method in the above code, or in case that is no option because of render time, you have to render to a texture. Using OpenGL 3 or above you would need to put something like this in your init:</p> <pre><code>fbo = GL30.glGenFramebuffers(); GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo); rbo = GL30.glGenRenderbuffers(); GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, rbo); GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_RGBA8, 640, 480); GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL30.GL_RENDERBUFFER, rbo); assert(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE); GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, fbo); GL20.glDrawBuffers(GL30.GL_COLOR_ATTACHMENT0); GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); drawScene(); //draw here </code></pre> <p>your draw method to call every frame would then be simplified to a simple and fast copy from the framebuffer fbo:</p> <pre><code>GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, fbo); GL11.glReadBuffer(GL30.GL_COLOR_ATTACHMENT0); GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, 0); GL20.glDrawBuffers(GL11.GL_BACK_LEFT); GL30.glBlitFramebuffer(0, 0, 640, 480, 0, 0, 640, 480, GL11.GL_COLOR_BUFFER_BIT, GL11.GL_NEAREST); GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload