Bug 115

Summary: GLDrawable.swapBuffers(); behaviour
Product: [JogAmp] Jogl Reporter: Sven Gothel <sgothel>
Component: coreAssignee: Sven Gothel <sgothel>
Status: VERIFIED WORKSFORME    
Severity: normal    
Priority: P1    
Version: 1   
Hardware: All   
OS: windows   
Type: DEFECT SCM Refs:
Workaround: ---

Description Sven Gothel 2010-03-24 07:47:00 CET


---- Reported by skippy 2004-10-22 04:48:03 ----

windowed + automatic-swap = only dark-green box (as expected) 
fullscreen + automatic-swap = only dark-green box (as expected) 
 
forced-swap + canvas.setAutoSwapBufferMode(true); combo 
   (which is wrong, but shows the unpredicted behaviour) 
windowed + forced-swap = dark/bright green boxes flicking (hm...) 
fullscreen + forced-swap = only dark-green box (hm...) 
^^^^^^^^^^ both should result in the same gfx, but are different. 
 
What happens: 
in fullscreen-mode the swapBuffers() is ignored (correct) 
in windowed-mode the swapBuffer() is processed (wrong, as: canvas.
setAutoSwapBufferMode(true)) 
 
forced-swap + canvas.setAutoSwapBufferMode(false); combo works just fine.

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.JOptionPane; 
import javax.swing.UIManager; 
 
import net.java.games.jogl.*; 
 
public class Run 
{ 
   public static void main(String[] args) throws Exception 
   { 
      new Run(); 
   } 
 
 
 
   private Run() 
   { 
      try 
      { 
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
      } 
      catch (Exception exc) 
      { 
         // 
      } 
 
      // Settings 
 
      final boolean fullscreen = JOptionPane.OK_OPTION == JOptionPane.
showConfirmDialog(new Frame(), "Do you want to enter fullscreen-mode?", 
"Fullscreen?", JOptionPane.YES_NO_OPTION); 
 
      try 
      { 
         Thread.sleep(500); 
      } 
      catch (Exception exc) 
      { 
         // 
      } 
 
      final boolean forcedSwap = JOptionPane.OK_OPTION == JOptionPane.
showConfirmDialog(new Frame(), "Do you want to forcibly swap buffers?", 
"ForcedSwap?", JOptionPane.YES_NO_OPTION); 
 
      // GUI 
 
      final GLCapabilities caps = new GLCapabilities(); 
      caps.setHardwareAccelerated(true); 
 
      final GLCanvas canvas = GLDrawableFactory.getFactory().
createGLCanvas(caps); 
 
      /* 
       * If this mode is set to true, whatever the "forcedSwap" value might be, 
       * behaviour changes in fullscreen/windowed-mode. 
       */ 
      canvas.setAutoSwapBufferMode(true); 
      // Should be: [!forcedSwap] in perfect code 
 
      canvas.setNoAutoRedrawMode(true); 
      canvas.addGLEventListener(new Renderer(forcedSwap)); 
      canvas.addKeyListener(new KeyboardShutdown()); 
 
      final Frame frame = new Frame(); 
      frame.setTitle("Bouncing box"); 
      frame.setResizable(false); 
      frame.add(canvas, BorderLayout.CENTER); 
 
      if (fullscreen) 
      { 
         frame.setUndecorated(true); 
 
         GraphicsEnvironment env = GraphicsEnvironment.
getLocalGraphicsEnvironment(); 
         GraphicsDevice device = env.getDefaultScreenDevice(); 
         device.setFullScreenWindow(frame); 
      } 
      else 
      { 
         frame.setSize(640, 480); 
         frame.setLocationRelativeTo(null); 
         frame.setVisible(true); 
      } 
 
      frame.addWindowListener(new FrameShutdown()); 
 
      canvas.requestFocus(); 
 
      running = true; 
      n00bL00p(frame, canvas); 
   } 
 
   /** 
    * LOOP 
    */ 
 
   private boolean running; 
 
 
 
   private void n00bL00p(Frame frame, GLCanvas canvas) 
   { 
      while (running) 
      { 
         logic(); 
         canvas.display(); 
      } 
 
      // Close 
      frame.setVisible(false); 
      frame.dispose(); 
      System.exit(0); 
   } 
 
   /** 
    * LOGIC 
    */ 
 
   private int w, h; 
 
   private int rectX, rectY, rectR, rectSpeedX, rectSpeedY; 
 
 
 
   private void logic() 
   { 
      rectX += rectSpeedX; 
      rectY += rectSpeedY; 
 
      if (rectX < 0 || rectX > w) 
      { 
         rectSpeedX *= -1; 
      } 
 
      if (rectY < 0 || rectY > h) 
      { 
         rectSpeedY *= -1; 
      } 
   } 
 
   /** 
    * RENDERER 
    */ 
 
   private class Renderer implements GLEventListener 
   { 
      private final boolean forcedSwap; 
 
 
 
      public Renderer(boolean forcedSwap) 
      { 
         this.forcedSwap = forcedSwap; 
      } 
 
 
 
      public void init(GLDrawable d) 
      { 
         GL gl = d.getGL(); 
         gl.glShadeModel(GL.GL_SMOOTH); 
         gl.glClearColor(0.0F, 0.0F, 0.0F, 1.0F); 
 
         rectR = 32; 
         rectSpeedX = 4; 
         rectSpeedY = 4; 
      } 
 
 
 
      public void display(GLDrawable d) 
      { 
         GL gl = d.getGL(); 
 
         // Bright green box 
         this.renderBox(gl, rectX - rectR, rectY, rectR, new float[] { 0.0F, 1.
0F, 0.0F }); 
 
         if (forcedSwap) 
         { 
            // Swap in-between 
            d.swapBuffers(); 
         } 
 
         // Dark green box 
         this.renderBox(gl, rectX + rectR, rectY, rectR, new float[] { 0.0F, 0.
5F, 0.0F }); 
 
         if (forcedSwap) 
         { 
            // Swap finally 
            d.swapBuffers(); 
         } 
      } 
 
 
 
      private void renderBox(GL gl, int x, int y, int r, float[] color) 
      { 
         gl.glClear(GL.GL_COLOR_BUFFER_BIT); 
 
         this.enable2D(gl); 
 
         gl.glColor3fv(color); 
         gl.glBegin(GL.GL_QUADS); 
         gl.glVertex2f(x - r, y - r); 
         gl.glVertex2f(x + r, y - r); 
         gl.glVertex2f(x + r, y + r); 
         gl.glVertex2f(x - r, y + r); 
         gl.glEnd(); 
 
         this.disable2D(gl); 
 
         try 
         { 
            Thread.sleep(10L); 
         } 
         catch (Exception exc) 
         { 
            // Terrible I know, just for testing. 
         } 
      } 
 
 
 
      public void displayChanged(GLDrawable arg0, boolean arg1, boolean arg2) 
      { 
         // 
      } 
 
 
 
      public void reshape(GLDrawable arg0, int arg1, int arg2, int arg3, int 
arg4) 
      { 
         w = arg3; 
         h = arg4; 
      } 
 
 
 
      private final void enable2D(GL gl) 
      { 
         // Java2D coord-system 
         gl.glMatrixMode(GL.GL_PROJECTION); 
         gl.glPushMatrix(); 
         gl.glLoadIdentity(); 
 
         gl.glScalef(1.0F / (w / 2), 1.0F / (h / 2), 1); 
         gl.glTranslatef(-w / 2, h / 2, 0); 
         gl.glScalef(1, -1, 1); 
 
         gl.glMatrixMode(GL.GL_MODELVIEW); 
         gl.glPushMatrix(); 
         gl.glLoadIdentity(); 
      } 
 
 
 
      private final void disable2D(GL gl) 
      { 
         gl.glMatrixMode(GL.GL_PROJECTION); 
         gl.glPopMatrix(); 
         gl.glMatrixMode(GL.GL_MODELVIEW); 
         gl.glPopMatrix(); 
      } 
   } 
 
   /** 
    * SHUT DOWN 
    */ 
 
   private class FrameShutdown extends WindowAdapter 
   { 
      public void windowClosing(WindowEvent event) 
      { 
         running = false; 
      } 
   } 
 
   private class KeyboardShutdown extends KeyAdapter 
   { 
      public void keyPressed(KeyEvent event) 
      { 
         if (event.getKeyCode() == KeyEvent.VK_ESCAPE) 
         { 
            running = false; 
         } 
      } 
   } 
}



---- Additional Comments From kbr 2005-01-31 01:26:58 ----

I can't reproduce this behavior. Fullscreen and windowed mode work identically
on my machine (Windows XP, NVidia Quadro FX Go700). The code should be
specifying canvas.setAutoSwapBufferMode(!forcedSwap) as far as I can tell in
order for it to exhibit the intended behavior. Regardless, as long as
sync-to-vertical-refresh is enabled, both boxes are shown.




--- Bug imported by sgothel@jausoft.com 2010-03-24 07:47 EDT  ---

This bug was previously known as _bug_ 115 at https://jogl.dev.java.net/bugs/show_bug.cgi?id=115