OpenGL/lwjgl 纹理创建 sigsegv
OpenGL/lwjgl texture creation sigsegv
我正在尝试使用 lwjgl 创建一个简单的 OpenGL 程序,但我目前正忙于创建要渲染的纹理。
我遇到的错误是分段错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fff6c894ab6, pid=18463, tid=775
#
# JRE version: OpenJDK Runtime Environment (14.0.1+7) (build 14.0.1+7)
# Java VM: OpenJDK 64-Bit Server VM (14.0.1+7, mixed mode, sharing, tiered, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# C [libGLImage.dylib+0x11ab6] _Z15glgConvertTo_32I23GLGConverter_RGB8_ARGB8L9GLGMemory1EEvPK15GLGOperationRecPK15GLDPixelModeRec+0x59
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# https://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.
#
机器信息:
Host: iMac16,2 x86_64 2800 MHz, 4 cores, 8G, Darwin 20.2.0
Time: Wed Jun 2 23:49:46 2021 CEST elapsed time: 178 seconds (0d 0h 2m 58s)
有问题的 JVM 线程堆栈:
Stack: [0x00007ffee5272000,0x00007ffee5a72000], sp=0x00007ffee5a6de10, free space=8175k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libGLImage.dylib+0x11ab6] _Z15glgConvertTo_32I23GLGConverter_RGB8_ARGB8L9GLGMemory1EEvPK15GLGOperationRecPK15GLDPixelModeRec+0x59
C [libGLImage.dylib+0x6227] glgProcessPixelsWithProcessor+0xdf4
C [AppleIntelBDWGraphicsGLDriver+0x13500] glrWriteTextureData+0x1438
C [GLEngine+0x189f7] glTexImage2D_Exec+0x52b
C [libGL.dylib+0x3195] glTexImage2D+0x37
C [liblwjgl_opengl.dylib+0xb22e]
j org.lwjgl.opengl.GL11C.nglTexImage2D(IIIIIIIIJ)V+0
j org.lwjgl.opengl.GL11C.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+17
j org.lwjgl.opengl.GL11.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+14
j rendering.Window.render()V+420
j rendering.Window.loop()V+8
j rendering.Window.main([Ljava/lang/String;)V+25
v ~StubRoutines::call_stub
V [libjvm.dylib+0x34bbbe] _ZN9JavaCalls11call_helperEP9JavaValueRK12methodHandleP17JavaCallArgumentsP6Thread+0x256
V [libjvm.dylib+0x39032d] _ZL17jni_invoke_staticP7JNIEnv_P9JavaValueP8_jobject11JNICallTypeP10_jmethodIDP18JNI_ArgumentPusherP6Thread+0x11c
V [libjvm.dylib+0x393c10] jni_CallStaticVoidMethod+0x1b3
C [libjli.dylib+0x4a42] JavaMain+0xab4
C [libjli.dylib+0x6fb3] __JVMInit_block_invoke+0x4b
C [Foundation+0x4201c] __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__+0x7
C [Foundation+0x41f14] -[NSBlockOperation main]+0x62
C [Foundation+0x41ea5] __NSOPERATION_IS_INVOKING_MAIN__+0x11
C [Foundation+0x41156] -[NSOperation start]+0x311
C [Foundation+0x804d9] __NSThreadPerformPerform+0xcc
C [CoreFoundation+0x81a0c] __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11
C [CoreFoundation+0x81974] __CFRunLoopDoSource0+0xb4
C [CoreFoundation+0x816ef] __CFRunLoopDoSources0+0xf8
C [CoreFoundation+0x80121] __CFRunLoopRun+0x37a
C [CoreFoundation+0x7f6ce] CFRunLoopRunSpecific+0x233
C [libjli.dylib+0x65c1] CreateExecutionEnvironment+0x18f
C [libjli.dylib+0x2752] JLI_Launch+0x54a
C [java+0xca1] main+0x177
C [libdyld.dylib+0x15621] start+0x1
最后是我处理纹理创建的代码:
// texture stuff
int texture = glGenTextures();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
// load and generate the texture
glTexImage2D(
GL_TEXTURE_2D, // target
0, // highest level of detail
GL_RGB, // source image bytes per pixel rgb = 3
image.getWidth(), // width
image.getHeight(), // height
0, // ??? must be zero
GL_RGB, // shader texel layout
GL_UNSIGNED_BYTE, // size of each color channel
image.getBuffer() // the data itself, a ByteBuffer wrapping byte[12]
);
glGenerateMipmap(GL_TEXTURE_2D);
// set the texture wrapping/filtering options (on the currently bound texture object)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// toggle on to use lines
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// use our nice shader
glUseProgram(shaderProgram.id);
// set uniforms after activation
shaderProgram.setInt("tex", 0); // why zero? idk
我创建的图像 class 工作得非常好,我使用的示例图像是 2 x 2 像素并且有一个 12 字节长度的内部缓冲区,所以 segvault 不应该由缓冲区太短。
您的图片尺寸为 2x2,图片格式为 RGB。因此,一行的长度是 6 个字节。默认情况下,OpenGL 假设图像的每一行的开始对齐到 4 个字节。
这是因为GL_UNPACK_ALIGNMENT
参数默认为4。由于图像有3个颜色通道(GL_RGB
),并且是紧凑的,所以一行图像的大小可能不是对齐到 4 个字节。
当具有 3 个颜色通道的 RGB 图像被加载到纹理对象并且 3*width 不能被 4 整除时,GL_UNPACK_ALIGNMENT
必须设置为 1,然后用 glTexImage2D
指定纹理图像:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getWidth(), image.getHeight(),
0, GL_RGB, GL_UNSIGNED_BYTE, image.getBuffer());
感谢 Rabbid76 的回答和 Kai Burjack 的评论,我让程序运行起来了!
我必须明确告诉 OpenGL 使用单字节对齐并且必须避免 ByteBuffer.wrap
和 ByteBuffer.allocate
(并使用 ByteBuffer.allocateDirect
)
如果没有您的帮助,我可能仍会遭受调试抑郁症的困扰;)再次感谢您的帮助。
我正在尝试使用 lwjgl 创建一个简单的 OpenGL 程序,但我目前正忙于创建要渲染的纹理。
我遇到的错误是分段错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fff6c894ab6, pid=18463, tid=775
#
# JRE version: OpenJDK Runtime Environment (14.0.1+7) (build 14.0.1+7)
# Java VM: OpenJDK 64-Bit Server VM (14.0.1+7, mixed mode, sharing, tiered, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# C [libGLImage.dylib+0x11ab6] _Z15glgConvertTo_32I23GLGConverter_RGB8_ARGB8L9GLGMemory1EEvPK15GLGOperationRecPK15GLDPixelModeRec+0x59
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
# https://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.
#
机器信息:
Host: iMac16,2 x86_64 2800 MHz, 4 cores, 8G, Darwin 20.2.0
Time: Wed Jun 2 23:49:46 2021 CEST elapsed time: 178 seconds (0d 0h 2m 58s)
有问题的 JVM 线程堆栈:
Stack: [0x00007ffee5272000,0x00007ffee5a72000], sp=0x00007ffee5a6de10, free space=8175k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libGLImage.dylib+0x11ab6] _Z15glgConvertTo_32I23GLGConverter_RGB8_ARGB8L9GLGMemory1EEvPK15GLGOperationRecPK15GLDPixelModeRec+0x59
C [libGLImage.dylib+0x6227] glgProcessPixelsWithProcessor+0xdf4
C [AppleIntelBDWGraphicsGLDriver+0x13500] glrWriteTextureData+0x1438
C [GLEngine+0x189f7] glTexImage2D_Exec+0x52b
C [libGL.dylib+0x3195] glTexImage2D+0x37
C [liblwjgl_opengl.dylib+0xb22e]
j org.lwjgl.opengl.GL11C.nglTexImage2D(IIIIIIIIJ)V+0
j org.lwjgl.opengl.GL11C.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+17
j org.lwjgl.opengl.GL11.glTexImage2D(IIIIIIIILjava/nio/ByteBuffer;)V+14
j rendering.Window.render()V+420
j rendering.Window.loop()V+8
j rendering.Window.main([Ljava/lang/String;)V+25
v ~StubRoutines::call_stub
V [libjvm.dylib+0x34bbbe] _ZN9JavaCalls11call_helperEP9JavaValueRK12methodHandleP17JavaCallArgumentsP6Thread+0x256
V [libjvm.dylib+0x39032d] _ZL17jni_invoke_staticP7JNIEnv_P9JavaValueP8_jobject11JNICallTypeP10_jmethodIDP18JNI_ArgumentPusherP6Thread+0x11c
V [libjvm.dylib+0x393c10] jni_CallStaticVoidMethod+0x1b3
C [libjli.dylib+0x4a42] JavaMain+0xab4
C [libjli.dylib+0x6fb3] __JVMInit_block_invoke+0x4b
C [Foundation+0x4201c] __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__+0x7
C [Foundation+0x41f14] -[NSBlockOperation main]+0x62
C [Foundation+0x41ea5] __NSOPERATION_IS_INVOKING_MAIN__+0x11
C [Foundation+0x41156] -[NSOperation start]+0x311
C [Foundation+0x804d9] __NSThreadPerformPerform+0xcc
C [CoreFoundation+0x81a0c] __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x11
C [CoreFoundation+0x81974] __CFRunLoopDoSource0+0xb4
C [CoreFoundation+0x816ef] __CFRunLoopDoSources0+0xf8
C [CoreFoundation+0x80121] __CFRunLoopRun+0x37a
C [CoreFoundation+0x7f6ce] CFRunLoopRunSpecific+0x233
C [libjli.dylib+0x65c1] CreateExecutionEnvironment+0x18f
C [libjli.dylib+0x2752] JLI_Launch+0x54a
C [java+0xca1] main+0x177
C [libdyld.dylib+0x15621] start+0x1
最后是我处理纹理创建的代码:
// texture stuff
int texture = glGenTextures();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
// load and generate the texture
glTexImage2D(
GL_TEXTURE_2D, // target
0, // highest level of detail
GL_RGB, // source image bytes per pixel rgb = 3
image.getWidth(), // width
image.getHeight(), // height
0, // ??? must be zero
GL_RGB, // shader texel layout
GL_UNSIGNED_BYTE, // size of each color channel
image.getBuffer() // the data itself, a ByteBuffer wrapping byte[12]
);
glGenerateMipmap(GL_TEXTURE_2D);
// set the texture wrapping/filtering options (on the currently bound texture object)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// toggle on to use lines
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// use our nice shader
glUseProgram(shaderProgram.id);
// set uniforms after activation
shaderProgram.setInt("tex", 0); // why zero? idk
我创建的图像 class 工作得非常好,我使用的示例图像是 2 x 2 像素并且有一个 12 字节长度的内部缓冲区,所以 segvault 不应该由缓冲区太短。
您的图片尺寸为 2x2,图片格式为 RGB。因此,一行的长度是 6 个字节。默认情况下,OpenGL 假设图像的每一行的开始对齐到 4 个字节。
这是因为GL_UNPACK_ALIGNMENT
参数默认为4。由于图像有3个颜色通道(GL_RGB
),并且是紧凑的,所以一行图像的大小可能不是对齐到 4 个字节。
当具有 3 个颜色通道的 RGB 图像被加载到纹理对象并且 3*width 不能被 4 整除时,GL_UNPACK_ALIGNMENT
必须设置为 1,然后用 glTexImage2D
指定纹理图像:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getWidth(), image.getHeight(),
0, GL_RGB, GL_UNSIGNED_BYTE, image.getBuffer());
感谢 Rabbid76 的回答和 Kai Burjack 的评论,我让程序运行起来了!
我必须明确告诉 OpenGL 使用单字节对齐并且必须避免 ByteBuffer.wrap
和 ByteBuffer.allocate
(并使用 ByteBuffer.allocateDirect
)
如果没有您的帮助,我可能仍会遭受调试抑郁症的困扰;)再次感谢您的帮助。