我正在尝试为基于2D瓦片的项目制作简单的纹理管理器。简单的Java OpenGL纹理管理器
我所拥有的是一个具有字符串(纹理名称)和纹理的散列图的类。如果该名称不存在于散列映射中,它将使用TextureIO.newTexture(..)来创建它并将其存储到散列映射中。
这是我得到的错误,当我尝试加载纹理:
Exception in thread "Timer-0" javax.media.opengl.GLException: java.lang.IllegalArgumentException: Illegally formatted version identifier: "null"
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(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: Illegally formatted version identifier: "null"
at com.sun.opengl.impl.FunctionAvailabilityCache$Version.<init>(FunctionAvailabilityCache.java:354)
at com.sun.opengl.impl.FunctionAvailabilityCache.initAvailableExtensions(FunctionAvailabilityCache.java:133)
at com.sun.opengl.impl.FunctionAvailabilityCache.isExtensionAvailable(FunctionAvailabilityCache.java:104)
at com.sun.opengl.impl.GLContextImpl.isExtensionAvailable(GLContextImpl.java:351)
at com.sun.opengl.impl.GLImpl.isExtensionAvailable(GLImpl.java:30493)
at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:416)
at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:381)
at com.sun.opengl.util.texture.Texture.<init>(Texture.java:182)
at com.sun.opengl.util.texture.TextureIO.newTexture(TextureIO.java:445)
at com.sun.opengl.util.texture.TextureIO.newTexture(TextureIO.java:465)
at dqs.manager.TextureManager.loadTexture(TextureManager.java:31)
at dqs.world.World.draw(World.java:59)
at dqs.scene.GameScene.display(GameScene.java:58)
at com.sun.opengl.impl.GLDrawableHelper.display(GLDrawableHelper.java:78)
at javax.media.opengl.GLCanvas$DisplayAction.run(GLCanvas.java:435)
at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:194)
at javax.media.opengl.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:452)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.sun.opengl.impl.FunctionAvailabilityCache$Version.<init>(FunctionAvailabilityCache.java:309)
... 30 more
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.opengl.impl.mipmap.Mipmap.closestFit(Mipmap.java:252)
at com.sun.opengl.impl.mipmap.Mipmap.gluBuild2DMipmaps(Mipmap.java:726)
at javax.media.opengl.glu.GLU.gluBuild2DMipmapsJava(GLU.java:1525)
at javax.media.opengl.glu.GLU.gluBuild2DMipmaps(GLU.java:1581)
at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:523)
at com.sun.opengl.util.texture.Texture.updateImage(Texture.java:381)
at com.sun.opengl.util.texture.Texture.<init>(Texture.java:182)
at com.sun.opengl.util.texture.TextureIO.newTexture(TextureIO.java:445)
at com.sun.opengl.util.texture.TextureIO.newTexture(TextureIO.java:465)
at dqs.manager.TextureManager.loadTexture(TextureManager.java:31)
at dqs.world.World.draw(World.java:59)
at dqs.scene.GameScene.display(GameScene.java:58)
at com.sun.opengl.impl.GLDrawableHelper.display(GLDrawableHelper.java:78)
at javax.media.opengl.GLCanvas$DisplayAction.run(GLCanvas.java:435)
at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:194)
at javax.media.opengl.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:412)
at javax.media.opengl.GLCanvas.display(GLCanvas.java:244)
at javax.media.opengl.GLCanvas.paint(GLCanvas.java:277)
at sun.awt.RepaintArea.paintComponent(Unknown Source)
at sun.awt.RepaintArea.paint(Unknown Source)
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
错误发生的那一刻我打电话loadTexture从我TextureManager内。
这里是TextureManager代码:
public class TextureManager {
private static HashMap<String, Texture> textureMap;
public TextureManager() {
textureMap = new HashMap<String, Texture>();
}
public static void loadTexture(String name) {
if(textureMap.containsKey(name)) return;
try {
textureMap.put(name, TextureIO.newTexture(new File("textures/" + name + ".png"), true));
}
catch (GLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void bindTexture(String name) {
textureMap.get(name).bind();
}
}
一个TextureManager对象已经通过前面的代码创建:
new TextureManager();
这就是我把它叫做使用的代码:
TextureManager.loadTexture("tree");
path textures/tree.png也存在。
我在一个较旧的项目中做过类似的工作,但是我没有使用散列表,而是在TextureManager中为我使用的每个纹理(不是很多)硬编码了一个变量。我怀疑这是因为线程缺少GL上下文,因为我的旧的TextureManager通过构造函数传入了GL,但从未在代码中使用它。调用loadTexture函数的绘图函数也传递给GL变量。