1
\$\begingroup\$

On the main menu of my game there is (obviously) several buttons. 2 of which, in different positions on different screens, render a different colour to the rest.

As you can see below, "New game" renders black, while the others render grey and on the options screen "Back" does the same thing (this one has literally only just started doing it but I don't know what would cause it).

Main menu broken button Options menu broken button

The code for both buttons is basically exactly the same:

public class ButtonNewGame extends Button
{
    public ButtonNewGame(int height, String text) 
    {
        super(height, text);
    }

    @Override
    protected void click() 
    {   
        //Begin drawing the correct components and stop the unneeded ones
        Main.instanceManager.menuInstance.draw = false;
        Main.instanceManager.introInstance.draw = true;
    }
}

The only difference between the two are the draw booleans they change, and their names. V.s one of the other buttons the code is again pretty much exactly the same.

The main button class:

public abstract class Button extends Component //TODO Fix strange render issues with new game and options back buttons
{
    private UnicodeFont font;
    private String text;
    /**
     * True if user just clicked. Used to stop button spamming on toggle buttons.
     */
    protected static boolean clicked;

    /**
     * Create a new button
     * @param height the text size
     * @param text the text to display
     */
    public Button(int height, String text)
    {
        createFont(height, true, false); //Create font to draw with
        this.text = text;
    }

    /**
     * Render the button
     * @param x start x position
     * @param y start y position
     * @param width the button width
     * @param height the button height
     */
    public void draw(double x, double y, int width, int height)
    {   
        Color.white.bind();
        glPushMatrix();
            glTranslated(x, y, 0); //Make sure to draw the button at the specified coordinates

            //Get mouse coordinates
            int mouseX = Mouse.getX();
            int mouseY = Main.WINDOW_HEIGHT-Mouse.getY(); //Compensates for mouse being calculated from bottom up

            //Check for mouse status and call correct draw method accordingly
            if((mouseX > x && mouseX < x + width) && (mouseY > y && mouseY < y + height))
            {
                if(Mouse.isButtonDown(0) && !clicked) //If the button has been clicked
                {
                    drawClick(x, y, width, height); //This will very rarely, if at all, be seen.
                    click(); //Actual click event
                    clicked = true;
                }
                else
                {
                    drawHover(x, y, width, height); //When the mouse is within the button area
                }
            }
            else 
            {
                drawNormal(x, y, width, height); //When the mouse is not within the button area
            }

            if(!Mouse.isButtonDown(0)) clicked = false; //Only reset clicked once the mouse button is released

            drawFont(0, 0, this.text, Color.white); //Draw the button text
        glPopMatrix();
    }

    /**
     * Draw the button when nothing is happening to it
     * @param x start x position
     * @param y start y position
     * @param width the width of the button
     * @param height the height of the button
     */
    protected void drawNormal(double x, double y, int width, int height)
    {
        glBegin(GL_QUADS);
            glColor4d(0.6, 0.6, 0.6, 0.8);
            glVertex2d(0, 0);
            glVertex2d(width, 0);
            glVertex2d(width, height);
            glVertex2d(0, height);
        glEnd();
    }

    /**
     * Draw the button when the mouse is hovering over it
     * @param x start x position
     * @param y start y position
     * @param width the width of the button
     * @param height the height of the button
     */
    protected void drawHover(double x, double y, int width, int height)
    {
        glBegin(GL_QUADS);
            glColor3d(0.7, 0.7, 0.7);
            glVertex2d(0, 0);
            glVertex2d(width, 0);
            glVertex2d(width, height);
            glVertex2d(0, height);
        glEnd();
    }

    /**
     * Draw the button when the mouse is hovering over it and held down
     * @param x start x position
     * @param y start y position
     * @param width the width of the button
     * @param height the height of the button
     */
    protected void drawClick(double x, double y, int width, int height)
    {
        glBegin(GL_QUADS);
            glColor3d(0.75, 0.75, 0.75);
            glVertex2d(0, 0);
            glVertex2d(width, 0);
            glVertex2d(width, height);
            glVertex2d(0, height);
        glEnd();
    }

    /**
     * Font setup
     * @return UnicodeFont for drawing
     */
    @SuppressWarnings("unchecked")
    private UnicodeFont createFont(int size, boolean isBold, boolean isItalic)
    {
        //Try to load the font from file
        try
        {
            InputStream inputStream = ResourceLoader.getResourceAsStream("assets/fonts/handwriting_draft.ttf");

            Font awtFont = Font.createFont(Font.TRUETYPE_FONT, inputStream);
            font = new UnicodeFont(awtFont, size, isBold, isItalic);

        }
        catch (Exception e) 
        {
            e.printStackTrace();
        } 

        //Load the font effects and set to white as backup
        font.addAsciiGlyphs();
        ColorEffect colour = new ColorEffect();
        colour.setColor(java.awt.Color.white);
        font.getEffects().add(colour);
        try 
        {
            font.loadGlyphs();
        } 
        catch (SlickException e1)
        {
            e1.printStackTrace();
        }
        return font;
    }

    /**
     * Draws the pre-setup font
     * @param x x-offset inside the button
     * @param y y-offset inside the button
     * @param text the text to render
     * @param colour the text's colour
     */
    private void drawFont(int x, int y, String text, Color colour)
    {
        glEnable(GL_TEXTURE_2D);
            font.drawString(x, y, text, colour);
        glDisable(GL_TEXTURE_2D);
    }

    protected abstract void click();
}

I think this class is probably responsible, however I also believe it could be down to my OpenGL setup method which is called every frame (is that a bad thing to do?):

private void setCamera()
    {
        glClear(GL_COLOR_BUFFER_BIT); //Clear screen

        //Modify projection matrix
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);

        //Enable transparency, so the text doesn't have a black background
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_TEXTURE_2D); //For loading textures

        //Modify modelview matrix
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }

If however I am completely wrong all of the code can be found here: https://github.com/Roboguy99/World-Map-Game

I have no idea what is causing this, and my knowledge on OpenGL is very limited. I appreciate any help I can get, thanks.

\$\endgroup\$
0
\$\begingroup\$

You need to disable textures before drawing the quads. Here's basically what's going on:

  1. You enable textures (in setCamera).
  2. You draw a button which:
  3. Draws a quad (which is textured, not just a solid color, but texcoords aren't set so...weirdness happens, and it might not be entirely predictable)
  4. Then you draw text (correctly) by:
  5. Enabling textures.
  6. Drawing the font with textures.
  7. Disabling textures <-------
  8. Back to step 2, to draw the next button -- but it starts with DISABLED textures this time, so things happen as you expect.

If you'll note, on the 'options' screen, you are drawing the 'back' button first (even though it's the 'last' button).

As an entire sidenote... Almost everything you're doing is deprecated in OpenGL -- fixed pipelines are not the way it's done anymore. With that said, it IS probably the easiest way to start grasping the concepts of 3D programming as everything is done step-by-step. On the other hand, when you start trying to do more complex things, you're going to run into some problems, not the least of which is finding any tutorials that aren't many years old. If you're looking for resources on 'the new way', do searches for 'OpenGL 3.3', or 'OpenGL Core Profile'.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks a lot, that makes a lot of sense now. In terms of the sidenote, I'm using OpenGL only because I learnt Java, but I'll be moving from it when I've grasped how game development plays out. \$\endgroup\$ – Jake Stanger Jun 30 '15 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.