我一直在研究使用Java,OpenGL / LWJGL和Slick-Utils的3D游戏引擎,我无法在程序中找到这个错误(Null Pointer Exception)。
错误:
Exception in thread "main" java.lang.ExceptionInInitializerError
at engineTester.Main.main(Main.java:22)
Caused by: java.lang.NullPointerException
at com.hybridia.engine3D.shaders.StaticShader.<clinit>(StaticShader.java:13)
... 1 more
engineTester.Main.main的第22行是初始化StaticShader的地方。
代码来自的文件(错误行旁边有注释):
package com.hybridia.engine3D.shaders;
import java.net.URL;
import org.lwjgl.util.vector.Matrix4f;
public class StaticShader extends ShaderProgram {
private int location_transformationLocaiton;
private static final String VERTEX_FILE = URL.class.getClass().getClassLoader()
.getResource("/resc/shaders/vertexShader.txt").toString(); //Error Here
private static final String FRAGMENT_FILE = URL.class.getClass().getClassLoader()
.getResource("/resc/shaders/fragmentShader.txt").toString();
public StaticShader() {
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes() {
super.bindAttribute(0, "position");
super.bindAttribute(1, "textureCoords");
}
@Override
protected void getAllUniformLocations() {
location_transformationLocaiton = super.getUniformLocation("transformationMatrix");
}
public void loadTransformation(Matrix4f matrix) {
super.loadMatrix(location_transformationLocaiton, matrix);
}
}
(下一行(FRAGMENT_FILE)也有错误,但修复第一行会修复第二行。)
我正在尝试做什么:
我将此项目导出为JAR,以便将来可用于我的3D项目。但是,当我在我的测试项目中运行它时,我得到上面的错误。我尝试了几种方法(如下所示),但我得到的是Null Pointer exception
或File Not Found exception
。 StaticShader
类继承自ShaderProgam
和VERTEX_FILE
的{{1}}类,并使用GLSL代码与VAO和VBO一起完成。
我知道问题出在第13行(带有FRAGMENT_FILE
注释的行)。出于某种原因,无论我试图做什么都失败了。我知道文件存在100%,因为在测试项目的Referenced Libraries中我看到了“vertexShader.txt”和“fragmentShader.txt”。我(在字面上)确实把这两个文件放在程序的各处,希望它能被StaticShader / ShaderProgram读取。我为这两个文本文件创建了一个文件夹,该文件夹是构建路径的一部分。
我会发布一个层次结构的图像,这样它看起来很漂亮,更容易理解,但我没有这样做的声誉。这是没有图片的层次结构的最佳表示:
//Error Here
方法我试图解决这个问题:(只是一点证明我试图自己修复bug)
SpaghettiEngineMKIII
|
|
|
|com.hybridia.engine3D.shaders
| |ShaderProgram
| |StaticShader
|
|
|resc
|shaders
|vertexShader.txt
|fragmentShader.txt
传递字符串而不使用URL / InputStream 重复/ TL; DR:
我已导出此项目并将其设为JAR文件。我已将JAR添加到测试项目的Build Path中以测试渲染限制。但是,尽管在StaticShader类中不断修改搜索代码,但在启动测试项目时无法找到/访问着色器文件。这可能是一个错误/非相对或绝对路径的问题,还是我有不同的方法从我所做的事情中获取文本文件?
快速的小历史:当StaticShader在测试项目中而不是游戏引擎项目时,项目工作正常。我移动了它,因为在我编写代码时,我需要在引擎本身的其他类中引用StaticShader。
我很抱歉,如果有什么事情发生,那就是“活泼”,我不打算这样做。
修改
ShaderProgram实际上读取文件,StaticShader查找文件并完成创建VBO的所有有趣内容。我之前忘记提及。
答案 0 :(得分:0)
NPE似乎来自资源。似乎URL的类加载器与包含jar文件的类加载器不同。 您是否尝试将错误行更改为?:
private static final String VERTEX_FILE = StaticShader.class.getClass().getClassLoader()
.getResource("/resc/shaders/vertexShader.txt").toString();
StaticShader.class包含在与txt文件相同的jar文件中,所以我希望这可以工作......
答案 1 :(得分:0)
你的问题在这里
URL.class.getClass() ...
您要求系统提供 URL.class 的类,它返回 java.lang.Class.class 类。然后发生的事情是 java.lang.Class.class 的类加载器无法找到相对于 java.lang.Class.class 已加载。
使用h3f3st0中的建议,您希望使用jar文件中的类,因此请将您的调用更改为
private static final String VERTEX_FILE = StaticShader.class.getClassLoader()
.getResource("/resc/shaders/vertexShader.txt").toString();
并查看是否有帮助。
编辑:
对我有用的选项如评论中所列,使用 getResourceAsStream()而不是 getResource()。