How to draw GUI

I almost ashamed to ask :wink:
Usually I’m doing all in 3D (and all looks like FPS shooter) but now I want to draw GUI and in fact I don’t know how, how to again drawing in 2D.
Mostly my class looks like this one


public class MainCanvas extends Canvas {
	private static MainCanvas canvas;
	private Thread gameThread;
	boolean running = false;
	
	private GameState gameState;
	
	public static MainCanvas get(){
		if(canvas == null) {
			canvas = new MainCanvas();
		}
		return canvas;
	}
	
	public final void addNotify(){
		super.addNotify();
		startLWJGL();
	}
	
	public final void removeNotify(){
		stopLWJGL();
		super.removeNotify();
	}
	
	public void startLWJGL(){
		gameThread = new Thread (){
			
			public void run(){
				running = true;
				try {
					Display.setParent(canvas);
					Display.create();
					Display.setVSyncEnabled(true);
					initGL();
					gameState = GameState.prepare();
				} catch (LWJGLException e) {
					e.printStackTrace();
				}
				gameLoop();
			}

		};
		gameThread.start();
	}
	
	public void stopLWJGL(){
		running = false;
		try {
			gameThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void initGL() {
		glViewport(0, 0,  Conf.W,Conf.H); // Reset The Current Viewport
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45.0f, ((float)Conf.W / (float)Conf.H) , 0.1f, 100f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
		glShadeModel(GL11.GL_SMOOTH); // Enables Smooth Shading
		GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Black Background
		glClearDepth(1.0f); // Depth Buffer Setup
		glEnable(GL_DEPTH_TEST); // Enables Depth Testing
		glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
		GL11.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations
	}
	
	public void gameLoop(){
		
		while(running) {
			gameState.update();
			gameState.render();
			Display.update();
		}
		Display.destroy();
	}
	
}

Turn off depth testing, turn on ortho mode, and then just draw using screen coordinates. You can easily switch modes and depth testing in between draw calls.

An alternative is to use something like TWL ( http://twl.l33tlabs.org/ ) and allow it to do some of the work.

It looks like it’s working but until I’m not trying to load texture after this my GUI square turns black (should be blue) and loaded texture gets more blue.
I’m using SLICK TextureLoader.
Can you help me with this?


public class TexturedCubeVA extends JApplet {
	
	private Canvas canvas;
	private Thread gameThread;
	boolean running = false;
	
	private Texture texture;
	
	public void startLWJGL(){
		gameThread = new Thread (){
			public void run(){
				running = true;
				try {
					Display.setParent(canvas);
					Display.create();
					Display.setVSyncEnabled(true);
					initGL();
				} catch (LWJGLException e) {
					e.printStackTrace();
				}
				gameLoop();
			}
		};
		gameThread.start();
	}
	
	public void stopLWJGL(){
		running = false;
		try {
			gameThread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void destroy(){
		remove(canvas);
		super.destroy();
	}
	
	public void init(){
		setLayout(new BorderLayout());
		canvas = new Canvas(){
			public final void addNotify(){
				super.addNotify();
				startLWJGL();
			}
			public final void removeNotify(){
				stopLWJGL();
				super.removeNotify();
			}
		};
		canvas.setSize(Conf.W, Conf.H);
		setSize(Conf.W, Conf.H);
		canvas.setBackground(Color.BLACK);
		canvas.setFocusable(true);
		canvas.requestFocus();
		canvas.setIgnoreRepaint(false);
		add(canvas);
	}
	
	private void initGL() {
		glViewport(0, 0,  Conf.W,Conf.H); // Reset The Current Viewport
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45.0f, ((float)Conf.W / (float)Conf.H) , 0.1f, 100f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
		glShadeModel(GL11.GL_SMOOTH); // Enables Smooth Shading
		GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Black Background
		glClearDepth(1.0f); // Depth Buffer Setup
		glEnable(GL_DEPTH_TEST); // Enables Depth Testing
		glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
		GL11.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations
		
		try {
			texture = TextureLoader.getTexture("png", ResourceLoader.getResourceAsStream("res/caution.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	float rquad; // Angle For The Quad
	public void gameLoop(){
		final int amountOfVertices = 24;
        final int vertexSize = 3;
        final int textureVertexSize = 2;
		
        FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
        vertexData.put(CubeUtil.getCube(1f, 1f, 1f));
        vertexData.flip();
        
        FloatBuffer textureData = BufferUtils.createFloatBuffer(amountOfVertices * textureVertexSize);
        textureData.put(CubeUtil.getCubeTexture(1.0f,1.0f));
        textureData.flip();
        
		while(running) {
			update();
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
			texture.bind();
			
			glLoadIdentity();//Matrix reseting.
			GL11.glTranslatef(-1.0f, 0.0f, -8.0f); // Move Right And Into The Screen
			GL11.glRotatef(rquad, 1.0f, 1.0f, 1.0f); // Rotate The Cube On X, Y & Z
			
			glEnableClientState(GL_VERTEX_ARRAY);// Enable vertex
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			
            glVertexPointer(vertexSize, 0, vertexData);//First cube
            glTexCoordPointer(textureVertexSize, 0, textureData);
            glDrawArrays(GL_QUADS, 0, amountOfVertices);//Draw cube
            
            glDisableClientState(GL_VERTEX_ARRAY);//Disable Vertex
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);//Disable Vertex
			
            drawGUI();
			Display.sync(60);
			Display.update();
		}
		
		Display.destroy();
	}
	
	private void update(){
		rquad -= 0.80f; // Decrease The Rotation Variable For The Quad
	}

	/**
	 * Draw the overlay for score and lifes
	 * 
	 * @param window The window in which the GUI is displayed 
	 */
	private void drawGUI() {
		enterOrtho();
		guiRenderer();
		leaveOrtho();
	}
	
	/**
	 * Drawing square on screen
	 */
	private void guiRenderer() {
		GL11.glColor3f(0.5f, 0.5f, 1.0f);
		GL11.glBegin(GL11.GL_QUADS);
		GL11.glVertex2f(10, 410);
		GL11.glVertex2f(70, 410);
		GL11.glVertex2f(70, 470);
		GL11.glVertex2f(10, 470);
		GL11.glEnd();
	}
	
	/**
	 * Enter the orthographic mode by first recording the current state, 
	 * next changing us into orthographic projection.
	 */
	public void enterOrtho() {
		// store the current state of the renderer
		GL11.glPushAttrib(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_ENABLE_BIT);
		GL11.glPushMatrix();
		GL11.glLoadIdentity();
		GL11.glMatrixMode(GL11.GL_PROJECTION); 
		GL11.glPushMatrix();	
		
		// now enter orthographic projection
		GL11.glLoadIdentity();		
		GL11.glOrtho(0, Conf.W, Conf.H, 0, 1, -1);
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		GL11.glDisable(GL11.GL_LIGHTING);  
	}
	
	/**
	 * Leave the orthographic mode by restoring the state we store
	 * in enterOrtho()
	 * 
	 * @see enterOrtho()
	 */
	public void leaveOrtho() {
		// restore the state of the renderer
		GL11.glPopMatrix();
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glPopMatrix();
		GL11.glPopAttrib();
	}
}

I don’t know Slick’s texture loader, unfortunately.

Correct me if I am wrong, but couldn’t you just draw a 2D gui via the normal awt Graphics, directing its output to an image of some kind (BufferedImage perhaps) and simply paint it to the canvas after each render…?

Yup, but this is not asking about Java2D :wink:

Well what I meant was do the gl rendering as normal, but simply create the gui this way… just to clarify.