JOGL Overlays

Is there any tutorials/samples of producing overlays in OpenGL / JOGL that someone can point me too?

Regards,

Zak Nixon

Do you mean drawing 2D on top of your 3D scene?

Yes.
Like a dashboard, or scene information…

Something simple, just 2D text. No 3D.

Zak

Ahh yes. First you need to turn 2D on/off like so:


     /**
         * Begin 2D mode.
         */
        public void begin2D()
        {
            gl.glMatrixMode(GL.GL_PROJECTION); 
            gl.glPushMatrix();
            gl.glLoadIdentity();
            gl.glOrtho(0.0f,viewPortWidth, viewPortHeight, 0.0f, -1.0f, 1.0f);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glPushMatrix();
            gl.glLoadIdentity();    
            gl.glDisable(GL.GL_DEPTH_TEST);
        }
        
        /**
         * End 2D mode.
         */
        public void end2D()
        {
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glPopMatrix();
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glPopMatrix();   
        }
        

Using GLUT for simple text you could do like this:


/** 
     * Draw text.
     * @param x X position of text
     * @param y Y position of text
     * @param text Text string to print
     */
    public void drawText(int x, int y, String text)
    {
        gl.glRasterPos2i(x, y);
        glut.glutBitmapString(gl, glut.BITMAP_HELVETICA_12, text);
    }

Drawing a 2D box could be done like this:


/**
     * Draw 2D box.
     */
    public void draw2DBox(int x, int y, int width, int height)
    {
        // Do some calcs
        float fPosX = x;
        float fPosY = y;
        float fPosX2 = x + width;
        float fPosY2 = y + height;
        
        // Draw it
      gl.glBegin(GL.GL_TRIANGLES);
           
            gl.glVertex3f(fPosX, fPosY2, 0);
            
            gl.glVertex3f(fPosX2, fPosY, 0);
                
            gl.glVertex3f(fPosX, fPosY, 0);
            
            gl.glVertex3f(fPosX, fPosY2, 0);
           
            gl.glVertex3f(fPosX2, fPosY2, 0);
           
            gl.glVertex3f(fPosX2, fPosY, 0);
      gl.glEnd();
    }

If you want to use the active texture as a sprite, you could exchange the contents of the previous function like this:


// Do some calcs
        float fPosX = x;
        float fPosY = y;
        float fPosX2 = x + width;
        float fPosY2 = y + height;
        
        // Draw it
      gl.glBegin(GL.GL_TRIANGLES);
            gl.glTexCoord2f(uvs[0], uvs[1]);
            gl.glVertex3f(fPosX, fPosY2, 0);
    
            gl.glTexCoord2f(uvs[2], uvs[3]);
            gl.glVertex3f(fPosX2, fPosY, 0);
    
            gl.glTexCoord2f(uvs[0], uvs[3]);
            gl.glVertex3f(fPosX, fPosY, 0);

            gl.glTexCoord2f(uvs[0], uvs[1]);
            gl.glVertex3f(fPosX, fPosY2, 0);

            gl.glTexCoord2f(uvs[2], uvs[1]);
            gl.glVertex3f(fPosX2, fPosY2, 0);

            gl.glTexCoord2f(uvs[2], uvs[3]);
            gl.glVertex3f(fPosX2, fPosY, 0);
      gl.glEnd();


The uv list is defined as a float array:


// Setup standard UVs
        uvs[0] = 0.0f;
      uvs[1] = 0.0f;
        uvs[2] = 1.0f;
      uvs[3] = 1.0f;

You can adjust these for clipping, UV scroll etc.

Thanks for the code, works beautifully.

Quick question. Once I draw a 2D box, and I put 3D objects in the scene, the 2D should always be “on top” of the 3D objects in the depth buffer. For some reason, this effect is not doing it.
Is there anyway to acheive this effect?

Thanks

Zak

Theres a couple of different ways you can do this. The way I do it is to use glOrtho with the near/far values set to 0/1 and then just draw everything at z=0. Another way you could do it is draw your 3D scene, clear the z-buffer then draw your 2D components.

D.

Draw your 3D as usual.
Call
begin2D()

Do 2D

end2D()

And it will always stay on top.
My code just disables the z-buffer, but any of the above suggestions would do the trick too… Anyhow. The order is 3D then 2D (my code above) and it will work. Does for me that is :slight_smile:

Thanks, I figured out my problem. I was setting the
alpha value of my overlays, which produced the illusion of the 3D being placed on top of my 2D lines (only where they intersected).

Thanks for all the help. ::slight_smile: ;D

Zak

Another question:
Using 2D, you have specified the 2D box in 3D space. If I perform transformations upon that geometry, how would you specify it, in 2D or 3D? I have tried rotations and scales on the box, yet I get very strange results.

Thanks

Zak

There is no 2D in OpenGL, only 3D. glOrtho sets your projection matrix to a special case of perspective projection called “orthographic projection” where parallel lines remain parallel once projected. So your “2d box” is in fact a quad facing the camera in a 3d space. Now if you can think of your “2d box” as a quad, you should understand why rotating it along x or z axis appears to scale it and why translating it along the y axis has no effect.

About drawing something on the top of your scene, you can call glDepthRange( 1f, 1f ); before drawing and restore it to glDepthRange( 0f, 1f ). I’ve never tried that but it may work.