1

I have a problem with what seems to be binding the textures to a shape. When I do so, I get a white shape of the correct dimensions, the color given to it by Color.white.bind().

GraphicsManager.java

package com.jackwilsdon.spectrun;

import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class GraphicsManager {

    final static int WIDTH = 800;
    final static int HEIGHT = 600;

    private static Texture cloudTexture = null;

    public static void initDisplay() throws LWJGLException
    {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.create();
    }

    public static void initOpenGL()
    {     
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public static void loadTextures()
    {
        Texture currentObject = null;
        try {
            currentObject = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("./resources/cloud.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Texture loaded: "+currentObject);
        System.out.println(">> Image width: "+currentObject.getImageWidth());
        System.out.println(">> Image height: "+currentObject.getImageHeight());
        System.out.println(">> Texture width: "+currentObject.getTextureWidth());
        System.out.println(">> Texture height: "+currentObject.getTextureHeight());
        System.out.println(">> Texture ID: "+currentObject.getTextureID());
        cloudTexture = currentObject;
    }

    public static void DrawRectangle(int x, int y, int width, int height)
    {
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
    }

    public static void DrawRectangle(int x, int y, int width, int height, int red, int green, int blue)
    {
        GL11.glColor3ub((byte)red, (byte)green, (byte)blue);
        DrawRectangle(x, y, width, height);
    }

    public static Vector2f DrawCloud(int x, int y)
    {
        cloudTexture.bind();
        int width = cloudTexture.getImageWidth();
        int height = cloudTexture.getImageHeight();
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
        return new Vector2f(cloudTexture.getImageWidth(), cloudTexture.getImageHeight());
    }
}

I suspect it has something to do with my initOpenGL() method, as in an example I have looked at (http://ninjacave.com/slickutil1), theirs is very different. Just copying theirs into mine gives unexpected results (black screen). Is something missing from my initOpenGL() method?

EDIT: The loadTextures() method outputs the correct image dimensions, but the texture's dimensions are different, what does this mean?

EDIT 2: The PNG is not the problem, I've tried 2 others to find the same result.


A new problem has arisen after fixing my code, by setting the texture coordinates. I now get a weird effect, like this; i.imgur.com/5lr79.png. The image is no longer full size, and has a black box to the bottom left of it.

GraphicsManager.java

package com.jackwilsdon.spectrun;

import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class GraphicsManager {

    final static int WIDTH = 800;
    final static int HEIGHT = 600;

    private static Texture cloudTexture = null;

    public static void initDisplay() throws LWJGLException
    {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.create();
    }

    public static void initOpenGL()
    {    
        GL11.glEnable(GL11.GL_TEXTURE);  
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public static void loadTextures()
    {
        Texture currentObject = null;
        try {
            currentObject = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("./resources/cloud.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Texture loaded: "+currentObject);
        System.out.println(">> Image width: "+currentObject.getImageWidth());
        System.out.println(">> Image height: "+currentObject.getImageHeight());
        System.out.println(">> Texture width: "+currentObject.getTextureWidth());
        System.out.println(">> Texture height: "+currentObject.getTextureHeight());
        System.out.println(">> Texture ID: "+currentObject.getTextureID());
        cloudTexture = currentObject;
    }

    public static void DrawRectangle(int x, int y, int width, int height)
    {
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
    }

    public static void DrawRectangle(int x, int y, int width, int height, int red, int green, int blue)
    {
        GL11.glColor3ub((byte)red, (byte)green, (byte)blue);
        DrawRectangle(x, y, width, height);
    }

    public static Vector2f DrawCloud(int x, int y)
    {
        cloudTexture.bind();
        int width = cloudTexture.getImageWidth();
        int height = cloudTexture.getImageHeight();
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(1,1);
            GL11.glVertex2f(x,y);
            GL11.glTexCoord2f(0,1);
            GL11.glVertex2f(x+width,y);
            GL11.glTexCoord2f(0,0);
            GL11.glVertex2f(x+width,y+height);
            GL11.glTexCoord2f(1,0);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
        return new Vector2f(cloudTexture.getImageWidth(), cloudTexture.getImageHeight());
    }
}
Jack Wilsdon
  • 6,706
  • 11
  • 44
  • 87

4 Answers4

2

It doesn't help that you aren't calling GL11.glEnable( GL11.GL_TEXTURE ) and you also aren't setting any texture coordinates.

Both of these will rather mess up your ability to see a texture on the quad ...

Goz
  • 61,365
  • 24
  • 124
  • 204
  • After setting texture coordinates, I now get a weird effect, like this; http://i.imgur.com/5lr79.png. The image is no longer full size, and has a black box to the bottom left of it. – Jack Wilsdon Jan 02 '13 at 14:23
  • @jackwilsdon: Well it looks like lwjgl is re-sizing the image to a power of 2. You are best off using a texture with power of 2 on the axis or setting your max tex-coord to (actualWidth/pow2Width) instead of 1. – Goz Jan 03 '13 at 09:13
1

I do believe the call to bind() needs to be between your glBegin() and glEnd() call to make it stick. The dimension problem is somewhat more odd - perhaps your texture dimensions are not a power of 2 and it is being translated by the driver?

Gimby
  • 5,095
  • 2
  • 35
  • 47
  • Sorry, but that doesn't work. I've also added `GL11.glEnable(GL11.GL_TEXTURE_2D);` in attempt to fix it, but that doesn't work either. – Jack Wilsdon Jan 02 '13 at 14:09
  • 1
    Yep, my OpenGL knowledge is really rusty or I'd have spotted the missing texcoord calls in a second... I'm spoiled by LibGDX. It might benefit you to study up on OpenGL in a native programming context and not from a Java perspective. LWJGL is only a thin layer between Java and the (native) OpenGL API, you really need to dig into the API itself. There are tons of books on using OpenGL in C/C++; perhaps you should consider reading one. – Gimby Jan 02 '13 at 15:28
  • Thanks, I'll try that :) Any ideas on the new problem that has arisen? – Jack Wilsdon Jan 02 '13 at 15:29
1

You didnt enable gl_TEXTURE_2D first of all. Second, you need to call .bind() inside glBegin() and your glEnd(). Third, you need texture coordinates. So, for the top left edge it would be 'glTexCoord(0, 0)', the next would be '(1, 0)' and then '(1, 1)' and lastly '(0, 1)'

  • After looking at your draw cloud method, i realized your texture coordinates are wrong. Look at my answer for the correct ones, it should solve your problem. –  Jan 02 '13 at 14:42
  • I made my texture coordinates that way, as otherwise the image appears flipped vertically. Here is my current code for the coordinates (the ones that appear flipped): https://gist.github.com/a3ef7d9bce9f0dfaa02a – Jack Wilsdon Jan 02 '13 at 14:51
1

Don't forget to call TextureImpl.unbind when needed.

RobotRock
  • 4,211
  • 6
  • 46
  • 86