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