Hi folks,
I’m loading a PNG texture to use as a sprite, using TextureIO and Texture class from JOGL.
Turns out that when I render the sprite, it’s a white quad! Code that renders is the following:
Sprite.java
/**
     * Draw the sprite at the specified location
     *
     * @param x The x location at which to draw this sprite
     * @param y The y location at which to draw this sprite
     */
    public void draw(int x, int y) {
        
        GL gl = Game.getRenderer().getGL();
        
        gl.glPushMatrix();
        
        texture.bind();
        
        gl.glTranslatef(x, y, 0);
        
        gl.glBegin(GL.GL_QUADS); 
        {
            gl.glTexCoord2f(0, 0);
            gl.glVertex2f(0, 0);
            gl.glTexCoord2f(0, texture.getHeight());
            gl.glVertex2f(0, height);
            gl.glTexCoord2f(texture.getWidth(), texture.getHeight());
            gl.glVertex2f(width, height);
            gl.glTexCoord2f(texture.getWidth(), 0);
            gl.glVertex2f(width, 0);
        }
        gl.glEnd();
        
        gl.glPopMatrix();
        
    }
GameRenderer.java, using active rendering:
/**
 * GameRenderer.java
 */
package com.rghartmann.game;
import com.rghartmann.game.state.GameStateManager;
import com.rghartmann.game.state.impl.MainGameState;
import java.awt.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
public final class GameRenderer extends Canvas implements Runnable {
    
    /**
     * Frame skipping control
     */
    private static final int NO_DELAYS_PER_YIELD = 16;
    private static int MAX_FRAME_SKIPS = 5;
    
    /**
     * Top level window and period
     */
    private Game game;
    private long period;
    
    /**
     * Updater and state management
     */
    private Thread updater;
    private volatile boolean running = false;
    private volatile boolean paused = false;
    
    /**
     * OpenGL stuff
     */
    private GLDrawable drawable;
    private GLContext context;
    private GL gl;
    private GLU glu;
    
    /**
     * Window sizing and resizing
     */
    private boolean resized = false;
    private int width;
    private int height;
    
    /**
     *
     */
    public GameRenderer(Game game,
            long period,
            int width,
            int height,
            GraphicsConfiguration config,
            GLCapabilities caps) {
        
        super(config);
        
        this.game = game;
        this.period = period;
        
        this.width = width;
        this.height = height;
        
        drawable = GLDrawableFactory.getFactory().getGLDrawable(this, caps, null);
        context = drawable.createContext(null);
        
    }
    
    public GL getGL() {
        return gl;
    }
    
    public void addNotify() {
        super.addNotify();
        drawable.setRealized(true);
        if (updater == null || !running) {
            updater = new Thread(this);
            updater.start();
        }
    }
    
    public void resumeGame() {  paused = false; }
    
    public void pauseGame() { paused = true; }
    
    public void stopGame() { running = false; }
    
    public void reshape(int w, int h) {
        resized = true;
        if (h == 0) h = 1;
        width = w; height = h;
    }
    
    public void run() {
        
        initRender();
        loop();
        
        context.destroy();
        System.exit(0);
    }
    
    private void makeContentCurrent() {
        try {
            while (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
                System.out.println("Context not yet current...");
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    private void initRender() {
        
        makeContentCurrent();
        
        gl = context.getGL();
        glu = new GLU();
        
        // Initialize the resource manager
        ResourceManager.getInstance().initialize(gl);
        
        // MainGameState (should be initialized somewhere else)
        GameStateManager.getInstance().addState(new MainGameState(), true);
        
        resizeView();
        
        gl.glClearColor(0.2f, 0.7f, 0.9f, 0.0f);
        
        gl.glMatrixMode(GL.GL_PROJECTION);
        
        gl.glPushMatrix();
        
        gl.glLoadIdentity();
        
        gl.glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
        
        gl.glMatrixMode(GL.GL_MODELVIEW);
        
        gl.glPushMatrix();
        
        gl.glLoadIdentity();
        
        gl.glDisable(GL.GL_DEPTH_TEST);
        
        gl.glEnable(GL.GL_BLEND);
        
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
        
        context.release();
    }
    
    private void resizeView() {
        
        gl.glMatrixMode(GL.GL_PROJECTION);
        
        gl.glLoadIdentity();
        
        gl.glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
    }
    
    private void loop() {
        
        long before, after, delta, sleep;
        long overSleep = 0L;
        long excess = 0L;
        int noDelays = 0;
        
        before = System.nanoTime();
        running = true;
        while ( running ) {
            
            after = System.nanoTime();
            delta = after - before;
            sleep = (period - delta) - overSleep;
            
            makeContentCurrent();
            
            update(delta);
            render(delta);
            
            drawable.swapBuffers();
            
            if (sleep > 0) {
                try {
                    Thread.sleep(sleep/1000000L);
                } catch(InterruptedException ex){}
                overSleep = (System.nanoTime() - after) - sleep;
            } else {
                excess -= sleep;
                overSleep = 0L;
                if (++noDelays >= NO_DELAYS_PER_YIELD) {
                    Thread.yield();
                    noDelays = 0;
                }
            }
            
            before = System.nanoTime();
            
            // Frame skipping
            int skips = 0;
            while((excess > period) && (skips < MAX_FRAME_SKIPS)) {
                excess -= period;
                update(delta);
                skips++;
            }
            
            context.release();
        }
        
    }
    
    private void update(long delta) {
        
        // update current game state
        if ( !paused ) {
            GameStateManager.getInstance().getCurrent().update(delta);
        }
    }
    
    private void render(long delta) {
        
        if (context.getCurrent() == null) {
            System.out.println("Current context is null");
            System.exit(0);
        }
        
        if (resized) {
            resizeView();
            resized = false;
        }
        
        // clear colour and depth buffers
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
        
        // render current game state
        GameStateManager.getInstance().getCurrent().render(delta);
        
        gl.glFlush();
    }
    
}
The update() and render() methods are in my GameState class. They are empty methods, and all render() does is calling draw(0, 0) on a Sprite instance in that class.
Thanks in advance for any help or critic. References to readings that might help me out are also appreciated =D
Son Of Cain
