问题
I'm using lwjgl 3 and learning modern opengl (3). I want to send a uniform matrix to the vertex shader so i can apply transformations. I tried that and the program crashes with this error
#
# 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.
#
Clearly I'm doing something wrong.
The problem seems to be in this line of code
glUniformMatrix4(uniformMatrixLocation, false, mvp.getBuffer());
The program executes without error if i remove this line of code.
I tried passing a diagonal matrix to check if the problem was with the matrix itself and still i got the same result
mvp is the diagonal matrix i am passing to the shader.
uniformMatrixLocation hold the position i found with this line of code
glGetUniformLocation(shaderProgram.programId, "MVP");
which doesn't return a negative number, so probably there are no error here.
I am using this library for the Mat4 class
https://github.com/jroyalty/jglm
Bellow is a "working" example of my code as small as i can get it.
//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
Vertex shader
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 MVP;
void main(){
gl_Position = MVP*vec4(position,1);
}
Fragment shader
#version 330 core
out vec4 color;
void main()
{
color = vec4(1,1,1,1);
}
Excuse me if this has been asked before, i search the web and didn't find anything useful. Thank you in advance.
回答1:
The crash is most likely happening because you are passing LWJGL an on-heap float buffer returned from 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.
You can use the BufferUtils class like you are already using for your vertices:
FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16).put(mvp.getBuffer()).flip();
...
glUniformMatrix4(uniformMatrixLocation, false, matrixBuffer);
If that doesn't work, try this instead:
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();
来源:https://stackoverflow.com/questions/29187765/lwjgl-3-gluniformmatrix4-causes-jre-to-crash