我正在使用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");
它不会返回负数,因此这里可能没有错误。
我正在将此库用于Mat4类
https://github.com/jroyalty/jglm
Bellow是我的代码的一个“可行的”示例,我所能获得的规模很小。
//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要求传递给它的所有NIO缓冲区都是直接缓冲区。直接缓冲区实际上包装了一个指向堆外内存的地址,即本机指针。这是LWJGL可以安全地将数据从Java代码传递到本机代码,反之亦然的唯一方法,而不会影响性能。它不支持堆上Java数组(或包装它们的普通NIO缓冲区),因为当本机代码访问它们时,JVM的垃圾收集器可能会在内存中四处移动数组。另外,Java数组具有未指定的布局,即它们不一定在内存中是连续的。
您可以像使用顶点一样使用BufferUtils类:
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();
关于java - lwjgl 3,glUniformMatrix4导致jre崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61727093/