Hello everyone, I have a problem with jogl’s TextureLoader. I don’t even remember where I found the TextureLoader class, but it is using jogls texture-utilities to load a texture given a filename as a string.
I am using it with a relative path, and it works when I run it inside netbeans. However, when deploying the jar file and running it, it can’t reach the sprite file (a .png picture).
So, it works inside netbeans, but running my jar gives me this error:
felix@felix-laptop:~/NetBeansProjects/GameEngine/dist$ ./run_linux
New Device: ALSA Software on default
New Device: ALSA Software on HDA Intel
New Device: OSS Software
New Device: Wave File Writer
file:/home/felix/NetBeansProjects/GameEngine/dist/GameEngine.jar!/com/gameengine/res/sprites/particle.png (No such file or directory)
Error loading texture file:/home/felix/NetBeansProjects/GameEngine/dist/GameEngine.jar!/com/gameengine/res/sprites/particle.png
Exception in thread "Timer-0" javax.media.opengl.GLException: java.lang.NullPointerException
at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:271)
at javax.media.opengl.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:410)
at javax.media.opengl.GLCanvas.display(GLCanvas.java:244)
at com.sun.opengl.util.Animator.display(Animator.java:144)
at com.sun.opengl.util.FPSAnimator$1.run(FPSAnimator.java:95)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
Caused by: java.lang.NullPointerException
at com.gameengine.gutils.SpriteBuffer.<init>(SpriteBuffer.java:30)
at com.gameengine.actors.TestPlayer.<init>(TestPlayer.java:19)
at com.gameengine.env.GLListener.init(GLListener.java:50)
at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:72)
at javax.media.opengl.GLCanvas$InitAction.run(GLCanvas.java:418)
at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:189)
at javax.media.opengl.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:452)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
The peculiar thing is, the code for getting the relative path is identical to the code I use for getting relative paths for my sound/music files. And it works perfectly with my sound files in the jar file…
I encourage you to have a look at my gameengine if you are interested in helping me, here is the entire thing with source and compiled classes: http://www.sendspace.com/file/i9ck2w
here are the classes using the path-method, the sound-class is working, the texture one isnt:
package com.gameengine.gutils;
import com.sun.opengl.util.texture.*;
import javax.media.opengl.GL;
public class SpriteBuffer {
private Texture spriteSheet;
private int dimX,dimY;
private int dimension;
private double memory;
private double frameWidth,frameHeight;
public int rows,cols;
private int[][] frames;
private DisplaylistManager dm;
private double pixelX,pixelY;
/*
* Her tager vi dimensionerne ind, og går ud fra at vi har en kvadratisk tekstur.
* Det viser sig at være nødvendigt på ældre og dårligere grafik-chipset.
*/
public SpriteBuffer(String filename, int rows, int cols, int dimension)
{
ClassLoader cl = this.getClass().getClassLoader();
String fname = cl.getResource("com/gameengine/res/sprites/"+filename).getFile();
// System.out.println(fname);
spriteSheet = TextureLoader.load(fname);
dimX = spriteSheet.getImageWidth();
dimY = spriteSheet.getImageHeight();
memory = spriteSheet.getEstimatedMemorySize();
this.rows = rows;
this.cols = cols;
this.frameHeight = (double)dimension/dimY;
this.frameWidth = (double)dimension/dimX;
this.dimension = dimension/2;
this.dm = DisplaylistManager.getInstance();
frames = dm.getSpriteList(this);
}
public void dump(String filename){
System.out.println("Filename: "+filename);
System.out.println("pixelX: "+pixelX+" pixelY: "+pixelY);
System.out.println("Framewidth: "+frameWidth+ " Frameheight: "+frameHeight);
System.out.println("rows: "+rows+" cols: "+cols);
System.out.println("dimX: "+dimX+" dimY: "+dimY);
System.out.println("1/cols: "+frameWidth);
}
public int[][] getFrames(){
return frames;
}
public void drawFrameNoBind(GL gl,int x, int y)
{
gl.glScaled(dimension, dimension, 1);
gl.glCallList(frames[x][y]);
}
public void drawFrameWithBind(GL gl,int x, int y)
{
spriteSheet.bind();
drawFrameNoBind(gl,x,y);
spriteSheet.disable();
}
public void drawWithoutDisplaylist(GL gl,int x, int y)
{
spriteSheet.bind();
dm.drawQuad(this, x, y, dimension);
}
public double getFrameHeight(){ return frameHeight;}
public double getFrameWidth(){ return frameWidth;}
}
package com.gameengine.gutils;
import javax.media.opengl.*;
import com.sun.opengl.util.texture.*;
import com.sun.opengl.util.*;
import java.io.*;
public class TextureLoader{
/**
* Texture loader utilizes JOGL's provided utilities to produce a texture.
*
* @param fileName relative filename from execution point
* @return a texture binded to the OpenGL context
*/
public static Texture load(String fileName){
Texture text = null;
try{
// TextureIO.setTexRectEnabled(true);
text = TextureIO.newTexture(new File(fileName), true);
text.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
text.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
}catch(Exception e){
System.out.println(e.getMessage());
System.out.println("Error loading texture " + fileName);
}
return text;
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.gameengine.sound.facade;
/**
*
* @author felix
*/
public class Sound
{
private String filename;
private boolean SFX; //true if SFX, false if BGM
private SoundBuffer buffer;
private int bufferNumber = -1;
private int sourceNumber = -1;
public Sound(String filename, boolean SFX)
{
ClassLoader cl = this.getClass().getClassLoader();
if(SFX)
this.filename = cl.getResource("com/gameengine/res/sound/sfx/"+filename).getFile();
else
this.filename = cl.getResource("com/gameengine/res/sound/bgm/"+filename).getFile();
this.SFX = SFX;
buffer = SoundBuffer.getInstance();
bufferNumber = buffer.cacheFile(this);
if(!isSFX())
sourceNumber = buffer.getNextSource();
}
public void play()
{
buffer.playFile(this, 1.0f, 1.0f, false);
}
public void play(float pitch)
{
buffer.playFile(this, pitch, 1.0f, false);
}
public void play(float pitch, float volume)
{
buffer.playFile(this, pitch, volume, false);
}
public void play(float pitch, float volume, boolean looping)
{
buffer.playFile(this, pitch, volume, looping);
}
public void playAsMusic(float volume, boolean looping){
buffer.playFile(this, 1.0f, volume, looping);
}
public void changeVolume(float volume)
{
if(!isSFX())
buffer.changeVolume(this, volume);
}
public int getSource(){
return sourceNumber;
}
// Lav overloads
public String getFilename()
{
return filename;
}
public boolean isSFX()
{
return SFX;
}
public boolean hasBufferNumber()
{
return (bufferNumber > -1);
}
public int getBufferNumber()
{
return bufferNumber;
}
}