lwjgl 3 , glUniformMatrix4 导致 jre 崩溃
lwjgl 3 , glUniformMatrix4 causes jre to crash
我正在使用 lwjgl 3 并学习现代 opengl (3)。我想将统一矩阵发送到顶点着色器,以便我可以应用变换。我试过了,程序因这个错误而崩溃
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000073a9820d, pid=8644, tid=2760
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [nvoglv64.DLL+0xd5820d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Copy\Code\Personal\atei-graphics\GraphicsProject\hs_err_pid8644.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
显然我做错了什么。
问题好像出在这行代码
glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());
如果我删除这行代码,程序将无误地执行。
我尝试传递一个对角矩阵来检查问题是否与矩阵本身有关,但我仍然得到相同的结果
mvp 是我传递给着色器的对角矩阵。
uniformMatrixLocation 保持我用这行代码找到的位置
glGetUniformLocation(shaderProgram.programId, "MVP");
这不是 return 负数,所以这里可能没有错误。
我正在为 Mat4 使用这个库 class
https://github.com/jroyalty/jglm
Bellow 是我的代码的一个 "working" 示例,它尽可能小。
//glfw create windows and etc
int programId = glCreateProgram();
int vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, FileUtils.readFile("shaders/vertex.glsl"));
glCompileShader(vertexShaderId);
if (glGetShaderi(vertexShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(vertexShaderId, glGetShaderi(vertexShaderId, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programId, vertexShaderId);
int fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, FileUtils.readFile("shaders/fragment.glsl"));
glCompileShader(fragmentShaderId);
if (glGetShaderi(fragmentShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(fragmentShaderId, glGetShaderi(fragmentShaderId, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId);
if (glGetProgrami(programId, GL_LINK_STATUS) == GL_FALSE) {
throw new RuntimeException("Unable to link shader program:");
}
/*
Hold the location of the matrix in the shader
*/
int uniformMatrixLocation = glGetUniformLocation(programId, "MVP");
float[] vertices = {
+0.0f, +0.8f, 0,
-0.8f, -0.8f, 0,
+0.8f, -0.8f, 0
};
int vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices).flip();
int vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer ,GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindVertexArray(0);
glClearColor(0,0,0,1);
while (glfwWindowShouldClose(window) == GL_FALSE) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glUseProgram(programId);
Mat4 mvp = new Mat4(1.0f);//diagonal matrix , should just show a triangle on the screen
/*
Crashes here
*/
//glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glUseProgram(0);
glfwPollEvents();
glfwSwapBuffers(window); // swap the color buffers
}
//dispose stuff no point showing them here
顶点着色器
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 MVP;
void main(){
gl_Position = MVP*vec4(position,1);
}
片段着色器
#version 330 core
out vec4 color;
void main()
{
color = vec4(1,1,1,1);
}
对不起,如果以前有人问过这个问题,我在网上搜索了一下,没有找到任何有用的信息。提前谢谢你。
崩溃很可能发生,因为您正在向 LWJGL 传递从 Mat4.getBuffer()
返回的堆上浮点缓冲区。 JWJGL requires that you pass it direct buffers:
LWJGL requires that all NIO buffers passed to it are direct buffers. Direct buffers essentially wrap an address that points to off-heap memory, i.e. a native pointer. This is the only way LWJGL can safely pass data from Java code to native code, and vice-versa, without a performance penalty. It does not support on-heap Java arrays (or plain NIO buffers, which wrap them) because arrays may be moved around in memory by the JVM's garbage collector while native code is accessing them. In addition, Java arrays have an unspecified layout, i.e. they are not necessarily contiguous in memory.
您可以像您已经为顶点使用的那样使用 BufferUtils class:
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(mvp.getBuffer()).flip();
...
glUniformMatrix4(uniformMatrixLocation, false, matrixBuffer);
如果这不起作用,请试试这个:
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(new float[] {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f}).flip();
我正在使用 lwjgl 3 并学习现代 opengl (3)。我想将统一矩阵发送到顶点着色器,以便我可以应用变换。我试过了,程序因这个错误而崩溃
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000073a9820d, pid=8644, tid=2760
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [nvoglv64.DLL+0xd5820d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Copy\Code\Personal\atei-graphics\GraphicsProject\hs_err_pid8644.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
显然我做错了什么。
问题好像出在这行代码
glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());
如果我删除这行代码,程序将无误地执行。
我尝试传递一个对角矩阵来检查问题是否与矩阵本身有关,但我仍然得到相同的结果
mvp 是我传递给着色器的对角矩阵。
uniformMatrixLocation 保持我用这行代码找到的位置
glGetUniformLocation(shaderProgram.programId, "MVP");
这不是 return 负数,所以这里可能没有错误。
我正在为 Mat4 使用这个库 class
https://github.com/jroyalty/jglm
Bellow 是我的代码的一个 "working" 示例,它尽可能小。
//glfw create windows and etc
int programId = glCreateProgram();
int vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, FileUtils.readFile("shaders/vertex.glsl"));
glCompileShader(vertexShaderId);
if (glGetShaderi(vertexShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(vertexShaderId, glGetShaderi(vertexShaderId, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programId, vertexShaderId);
int fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, FileUtils.readFile("shaders/fragment.glsl"));
glCompileShader(fragmentShaderId);
if (glGetShaderi(fragmentShaderId, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(fragmentShaderId, glGetShaderi(fragmentShaderId, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId);
if (glGetProgrami(programId, GL_LINK_STATUS) == GL_FALSE) {
throw new RuntimeException("Unable to link shader program:");
}
/*
Hold the location of the matrix in the shader
*/
int uniformMatrixLocation = glGetUniformLocation(programId, "MVP");
float[] vertices = {
+0.0f, +0.8f, 0,
-0.8f, -0.8f, 0,
+0.8f, -0.8f, 0
};
int vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices).flip();
int vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer ,GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindVertexArray(0);
glClearColor(0,0,0,1);
while (glfwWindowShouldClose(window) == GL_FALSE) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glUseProgram(programId);
Mat4 mvp = new Mat4(1.0f);//diagonal matrix , should just show a triangle on the screen
/*
Crashes here
*/
//glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glUseProgram(0);
glfwPollEvents();
glfwSwapBuffers(window); // swap the color buffers
}
//dispose stuff no point showing them here
顶点着色器
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 MVP;
void main(){
gl_Position = MVP*vec4(position,1);
}
片段着色器
#version 330 core
out vec4 color;
void main()
{
color = vec4(1,1,1,1);
}
对不起,如果以前有人问过这个问题,我在网上搜索了一下,没有找到任何有用的信息。提前谢谢你。
崩溃很可能发生,因为您正在向 LWJGL 传递从 Mat4.getBuffer()
返回的堆上浮点缓冲区。 JWJGL requires that you pass it direct buffers:
LWJGL requires that all NIO buffers passed to it are direct buffers. Direct buffers essentially wrap an address that points to off-heap memory, i.e. a native pointer. This is the only way LWJGL can safely pass data from Java code to native code, and vice-versa, without a performance penalty. It does not support on-heap Java arrays (or plain NIO buffers, which wrap them) because arrays may be moved around in memory by the JVM's garbage collector while native code is accessing them. In addition, Java arrays have an unspecified layout, i.e. they are not necessarily contiguous in memory.
您可以像您已经为顶点使用的那样使用 BufferUtils class:
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(mvp.getBuffer()).flip();
...
glUniformMatrix4(uniformMatrixLocation, false, matrixBuffer);
如果这不起作用,请试试这个:
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(new float[] {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f}).flip();