我正在尝试渲染2D正方形,但是我的程序崩溃了。我认为我的方法顺序不正确。我正在使用LWJGL3,以及jars Lwjgl,GLFW和OpenGL。 stacktrace显示错误是EXCEPTION_ACCESS_VIOLATION,并且错误是在第一个openGL函数上(取决于哪个是第一个)(在当前代码中是GL20.glGetAttribLocation()(在此处的指导https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Rendering之后) 我也没有使用legacyGL
如果您遇到此问题: 添加行GLFW.makeContextCurrent(window)和Gl.createCapabilities()
主要:
public class DungeonRunners {
private double lastTick;
private float timeCount;
private int fps;
private int fpsCount;
private int ups;
private int upsCount;
public static void main(String[] args) {
System.out.println("LWJGL Version: " + Version.getVersion());
int width = 1240;
int height = 720;
boolean legacyGL = false;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if(arg.equals("width:")) {
try {
width = Integer.parseInt(args[i+1]);
i++;
} catch (NumberFormatException ignored) { }
} else if(arg.equals("height:")) {
try {
height = Integer.parseInt(args[i+1]);
} catch (NumberFormatException ignored) { }
} else if(arg.equals("-useLegacyGL")) {
legacyGL = true;
}
}
DungeonRunners dungeonRunners = new DungeonRunners();
dungeonRunners.start(width, height, legacyGL);
}
private void start(int width, int height, Boolean legacyGL) {
long window;
GLFW.glfwInit();
if(!legacyGL) {
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
} else {
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 1);
window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
}
RenderEngine engine = new RenderEngine(legacyGL);
while(!GLFW.glfwWindowShouldClose(window)) {
update();
engine.frame();
}
}
private void update() {
if (timeCount > 1f) {
fps = fpsCount;
fpsCount = 0;
ups = upsCount;
upsCount = 0;
timeCount -= 1f;
}
}
private float getDelta() {
double time = getTime();
float delta = (float) (time - lastTick);
lastTick = time;
timeCount += delta;
return delta;
}
public double getTime() {
return System.nanoTime() / 1000000000.0;
}
private void updateFPS() {
fpsCount++;
}
private void updateUPS() {
upsCount++;
}
}
代码很容易解释,这是我的RenderEngine类:
public class RenderEngine {
private int shaderProgram;
public RenderEngine(Boolean legacyGL) {
setVertexAttribs();
bindImage();
int vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
setupShaders(legacyGL);
GL20.glUseProgram(shaderProgram);
setUniformVars();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
}
private void bindImage() {
try (MemoryStack stack = MemoryStack.stackPush()) {
FloatBuffer vertices = stack.mallocFloat(3 * 6);
vertices.put(-0.6f).put(-0.4f).put(0f).put(1f).put(0f).put(0f);
vertices.put(0.6f).put(-0.4f).put(0f).put(0f).put(1f).put(0f);
vertices.put(0f).put(0.6f).put(0f).put(0f).put(0f).put(1f);
vertices.flip();
int vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
MemoryStack.stackPop();
}
}
public void frame() {
}
private void setUniformVars() {
int uniModel = GL20.glGetUniformLocation(shaderProgram, "model");
UtilMatrix4f model = new UtilMatrix4f();
GL20.glUniformMatrix4fv(uniModel, false, model.getBuffer());
int uniView = GL20.glGetUniformLocation(shaderProgram, "view");
UtilMatrix4f view = new UtilMatrix4f();
GL20.glUniformMatrix4fv(uniView, false, view.getBuffer());
int uniProjection = GL20.glGetUniformLocation(shaderProgram, "projection");
float ratio = 640f / 480f;
UtilMatrix4f projection = UtilMatrix4f.orthographic(-ratio, ratio, -1f, 1f, -1f, 1f);
GL20.glUniformMatrix4fv(uniProjection, false, projection.getBuffer());
}
private void setVertexAttribs() {
int floatSize = 4;
int posAttrib = GL20.glGetAttribLocation(shaderProgram, "position");
GL20.glEnableVertexAttribArray(posAttrib);
GL20.glVertexAttribPointer(posAttrib, 3, GL11.GL_FLOAT, false, 6 * floatSize, 0);
int colAttrib = GL20.glGetAttribLocation(shaderProgram, "color");
GL20.glEnableVertexAttribArray(colAttrib);
GL20.glVertexAttribPointer(colAttrib, 3, GL11.GL_FLOAT, false, 6 * floatSize, 3 * floatSize);
}
private void setupShaders(boolean legacyGL) {
int vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
if(legacyGL)
GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\legacyVertexShader.txt");
else
GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\vertexShader.txt");
GL20.glCompileShader(vertexShader);
int status = GL20.glGetShaderi(vertexShader, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(vertexShader));
}
int fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
if(legacyGL)
GL20.glShaderSource(vertexShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\legacyFragmentShader.txt");
else
GL20.glShaderSource(fragmentShader, "src\\main\\java\\bigbade\\dungeonrunners\\renderer\\shaders\\fragmentShader.txt");
GL20.glCompileShader(fragmentShader);
status = GL20.glGetShaderi(fragmentShader, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(fragmentShader));
}
shaderProgram = GL20.glCreateProgram();
GL20.glAttachShader(shaderProgram, vertexShader);
GL20.glAttachShader(shaderProgram, fragmentShader);
GL30.glBindFragDataLocation(shaderProgram, 0, "fragColor");
GL20.glLinkProgram(shaderProgram);
status = GL20.glGetProgrami(shaderProgram, GL20.GL_LINK_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetProgramInfoLog(shaderProgram));
}
}
}