heres the 2D setup and gui stuff…
I use GLOrtho as a setup projection, and the dimensions are the same as my window dimensions. This has pros and cons.
pros:
really easy gui management. The coordinates passed in by awt as the mouseclick coordinates are the same as the glOrtho ‘surface’ so no translation or scaling is required.
Much much easier to get fonts and gui elements to look good without any dodgy aliasing and filtering
cons:
GUI elements are fixed in size, so a large dialog on 640x480 will look like a smalllll dialog on 1280x1024. Frankly i’m willing to live with this.
heres the ortho setup for each draw call in my GluiManager class.
gl.glPushAttrib(GL.GL_ALL_ATTRIB_BITS);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glBindTexture(GL.GL_TEXTURE_2D, lafTexture.getTextureID());
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
gl.glDisable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glColor4fv(DEFAULT_COLOR);
gl.glMatrixMode(GL.GL_PROJECTION);
// Select Projection
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
gl.glOrtho( 0,width,height, 0, -1, 1 ); // Select Ortho Mode
gl.glMatrixMode(GL.GL_MODELVIEW); // Select Modelview Matrix
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity();
all this does is setup the correct state and projection matrix for the gui drawing. The GLOrtho call is the important bit. The width and height are set by the containing class (normally the one that implements GLEventListener) at startup and whenever it gets a reshape event. The rest of the stuff is just gumph, sets up the blend functions, color, and whatever Look&Feel texture i’m using to draw the windows.
GluiWidget gluiw;
Object[] drawArray = children.toArray();
for(int c1 = drawArray.length-1;c1 >= 0;c1 --)
{
gluiw = (GluiWidget)drawArray[c1];
if(gluiw.isVisible() && gluiw.isActive() ) gluiw.draw(gl,glu);
}
gl.glPopMatrix();
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
gl.glPopAttrib();
this draws all the top level component objects in the gluimanager component list in reverse order then pops all the matrices and reverts to the previous state with regards to blending/color etc etc.
this next bit is the initial dispatch on the mouse events:
public boolean dispatchMouseEvent(GluiMouseEvent e)
{
if(mouseFocus == null)
{
Iterator it = children.iterator();
while(it.hasNext())
{
((GluiWidget)it.next()).processGluiMouseEvent(e);
if (e.isConsumed()) return false;
}
return true;
}
else
{
e.toLocalCoordinates(mouseFocus.getParent());
mouseFocus.processGluiMouseEvent(e);
e.toGlobalCoordinates();
return(!e.isConsumed());
}
this passes the GluiMouseEvents got from the AWT component on to the children. One important thing to note is the mouse Focus stuff. A left click on a component gives it mouse focus, so it grabs the mouse events directly as opposed to recieving them through the normal chain of parents. The mouse events are transformed in the local frame of reference of that components parent. This ensures that theres no actual discernable difference between getting them through the component stack or having them passed directly to the component.
MouseMove events are handled simialarly, and also fire off MouseExit and MouseEntry events to the components to handle things like rollovers.
Then in GluiFrame which is my top level ‘window’ type component, theres added functionality in the MouseMotion listener to handle being dragged.
if(hasMouseFocus)
{
position.x += e.getX() - oldMouseX;
position.y += e.getY() - oldMouseY;
oldMouseX = e.getX();
oldMouseY = e.getY();
}
The oldMouseX and Y are stored from frame to frame.
D.