Mac OS X troubles

Hello,

I’m new to Mac OS and am trying to get a simple JOGL demo running. All my jogl programming so far has been in Windows.

I was able to get a simple JOGL application working (I used the code found in the JOGL wikipedia article).

Anyways, when I run this code on my Mac using Eclipse I get 15 FPS in fullscreen mode…whereas with my 2-yr old WIndows machine, I get 1000+ FPS.

Im pretty sure that Im doing something wrong because I can run the JOGL demos on the JOGL demo site (such as the gears demo) on my Mac and they work just fine.

Any tips on what I should check? I am very new to OS x and UNIX in particular, so any advice would be greatly appreciated.

Thanks

What kind of Mac do you have? What kind of graphics card?

I’m pretty sure that by default Mac OS X synchronizes the OpenGL buffer flipping with the vertical retrace, so you may see your frame rate capped to your monitor’s refresh rate (i.e., 60 Hz or 75 Hz). You can turn this off by adding a “gl.setSwapInterval(0);” to your GLEventListener.init() method. 15 FPS seems pretty low though. Maybe Eclipse is enabling debugging or profiling by default which may impact the application’s performance.

Hi Ken,

I have a MacBook Pro, it has a 256 MB ATI Mobility Radeon X1600 graphics card.

I heard that Eclipse for Mac has some issues with SWT / AWT…so I tried running the same program on NetBeans. FPS is better at around 57…but still remarkably slow. (The Windows machine mentioned earlier actually runs the program at 750 FPS, not 1000)

I’ve also set the gl.setSwapBuffers(0), no effect.

I’ve attached my code in case you’d like to try it. I took this from the Wikipedia JOGL article and modified it so that it displays FPS once the close window button (X) is clicked. The code renders a triangle base pyramid that rotates faster as the frame rate is higher.

Run JavaDia to start the program.

Anything else that I should try?

Thanks

JavaDia

import com.sun.opengl.util.Animator;
import javax.media.opengl.GLCanvas;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class JavaDia implements Runnable {
    static Thread displayT = new Thread(new JavaDia());
    static boolean bQuit = false;
    static long startTime = 0;
    
    public static void main(String[] args) {
        displayT.start();
    }

    public void run() {
        Frame frame = new Frame("Jogl 3d Shape/Rotation");
        GLCanvas canvas = new GLCanvas();
        canvas.addGLEventListener(new JavaRenderer());
        frame.add(canvas);
        frame.setSize(640, 480);
        //frame.setUndecorated(true);
        int size = frame.getExtendedState();
        size |= Frame.MAXIMIZED_BOTH;
        frame.setExtendedState(size);

        Animator animator = new Animator(canvas);
        
        startTime = System.currentTimeMillis();
        
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                bQuit = true;
                displayT.stop();
                
                long endTime = System.currentTimeMillis();
                
                double runTime = ((double) (endTime - startTime) / 1000);
                
                System.out.println("Runtime: " + runTime);
                double fps = (double) JavaRenderer.frames / runTime;
                
                System.out.println("FPS: " + fps);
                System.exit(0);
            }
        });
        frame.setVisible(true);
//      frame.show();
        canvas.requestFocus();
        animator.start();
    }
}

JavaRenderer

import javax.media.opengl.GL;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class JavaRenderer implements GLEventListener, KeyListener {
   private float rotateT = 0.0f;
   private static final GLU glu = new GLU();
   public static long frames = 0;
   
   public void display(GLAutoDrawable gLDrawable) {
       final GL gl = gLDrawable.getGL();
       gl.glClear(GL.GL_COLOR_BUFFER_BIT);
       gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
       gl.glLoadIdentity();
       gl.glTranslatef(0.0f, 0.0f, -5.0f);

       gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
       gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
       gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
       gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);

       gl.glBegin(GL.GL_TRIANGLES);

       // Front
       gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
       gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
       gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f);

       // Right Side Facing Front
       gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
       gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
       gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f);

       // Left Side Facing Front
       gl.glColor3f(0.0f, 1.0f, 1.0f); gl.glVertex3f(0.0f, 1.0f, 0.0f);
       gl.glColor3f(0.0f, 0.0f, 1.0f); gl.glVertex3f(0.0f, -1.0f, -1.0f);
       gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);

       // Bottom
       gl.glColor3f(0.0f, 0.0f, 0.0f); gl.glVertex3f(-1.0f, -1.0f, 1.0f);
       gl.glColor3f(0.1f, 0.1f, 0.1f); gl.glVertex3f(1.0f, -1.0f, 1.0f);
       gl.glColor3f(0.2f, 0.2f, 0.2f); gl.glVertex3f(0.0f, -1.0f, -1.0f);

       gl.glEnd();

       rotateT += 0.2f;
       frames++;
   }

   public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
   }

   public void init(GLAutoDrawable gLDrawable) {
       final GL gl = gLDrawable.getGL();
       gl.glShadeModel(GL.GL_SMOOTH);
       gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
       gl.glClearDepth(1.0f);
       gl.glEnable(GL.GL_DEPTH_TEST);
       gl.glDepthFunc(GL.GL_LEQUAL);
       gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
       gl.setSwapInterval(0);
       gLDrawable.addKeyListener(this);
   }

   public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
       final GL gl = gLDrawable.getGL();
       if(height <= 0) {
           height = 1;
       }
       final float h = (float)width / (float)height;
       gl.glMatrixMode(GL.GL_PROJECTION);
       gl.glLoadIdentity();
       glu.gluPerspective(50.0f, h, 1.0, 1000.0);
       gl.glMatrixMode(GL.GL_MODELVIEW);
       gl.glLoadIdentity();
   }

   public void keyPressed(KeyEvent e) {
       if(e.getKeyCode() == KeyEvent.VK_ESCAPE) {
           JavaDia.bQuit = true;
           JavaDia.displayT.stop();
           System.exit(0);
       }
   }

   public void keyReleased(KeyEvent e) {
   }

   public void keyTyped(KeyEvent e) {
   }
}

On my Mac Mini with Intel integrated graphics, I get 30 FPS when the app is maximized and much higher framerates (> 1000 FPS) when the window is smaller. This is to be expected since this graphics chipset is severely fill limited.

I think you shouldn’t worry about this too much. Your graphics card is more than capable of maintaining the exact same framerate as the scene complexity increases.

I was trying a bunch of different ideas to see if I could get the FPS to increase.

  • Running same program in NetBeans on a Windows XP VM on my Mac
  • Moving the JOGL libraries to /Libraries/Java/Extensions, to the desktop, to my user directory
  • Trying different JOGL versions
  • Removing the gl.setSwapInterval(0) call

I was able to get the program to run at ~525 FPS fullscreen on my Mac…the only problem is I don’t know how I did it.

I tried to reset my configuration to “break” my program (just so that I would know what fixed it)…none of the changes that I recall making seem to make the program run at 50 FPS.

I’ll try to mess around with my configuration and see if I can find the exact cause of the frame rate discrepancy.

Edit: Its also worth mentioning that the program runs at ~525 FPS fullscreen on either Eclipse and NetBeans. It ran at ~150 FPS on my Windows XP VM w/ NetBeans (but the VM only had 512 MB RAM allocated)

Hey dmiranda,

have you, by any chance, managed to find what caused the performance loss? I’m having an analogue problem with a program that displays a terrain mesh. When I render the mesh on a MAC with standard GL-calls (glVertex, etc.) I get a framerate of around 400 fps. When I render the whole thing with vertex and fragment shaders, the framerate drops to 40fps. On my Windows PC I get much higher framerates and, as expected, the shader-version is much faster than the standard-renderer.

Cheers,

Sebastian