2016-01-06 29 views
0

要扩展我的库中的一些东西,我需要将数据从VBO读回CPU内存。这里没有涉及转换 - 反馈。glGetBufferSubData pyopengl随机结果和段错误

当我从缓冲器读取I数据要么得到“随机数据” 中“segmentation fault” “非法硬件指令” “的malloc”。

这里有不同的错误,我得到:

的malloc

python(678,0x7fff746f7000) malloc: *** error for object 0x7fa532e1d6b8: 
incorrect checksum for freed object - object was probably modified after being freed. 
*** set a breakpoint in malloc_error_break to debug 
[1] 678 abort  python -m glib.examples.transformation_domain 

段错误

[1] 2448 segmentation fault python -m demos.read_vbo 

非法硬件指令

objc[2789]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else. 
objc[2789]: receiver 0x7fcaee1efaf0, SEL 0x7fff8314a468, isa 0x7fff72e0cf18, cache 0x7fff72e0cf28, buckets 0x7fcaee1d0a10, mask 0x1f, occupied 0x10 
objc[2789]: receiver 64 bytes, buckets 528 bytes 
objc[2789]: selector 'key' 
objc[2789]: isa '_CFXNotificationNameWildcardObjectRegistration' 
objc[2789]: Method cache corrupted. 
[1] 2789 illegal hardware instruction python -m glib.examples.transformation_domain 

因为我想知道是否可能有东西在我的应用程序,它可能会导致这个问题(也许状态不好......)我找出问题:

""" 
this code demosntrates problems with glGetBufferSubData 
@author Nicolas 'keksnicoh' Heimann 
""" 
from gllib.glfw import * 
from OpenGL.GL import * 
import numpy as np 

# spawn glfw stuff 
if not glfwInit(): raise RuntimeError('glfw.Init() error') 
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
window = glfwCreateWindow(500, 500) 
glfwMakeContextCurrent(window) 

# push data to vbo 
data = np.array([1,2,3,4,5,6], dtype=np.float32) 
vbo = glGenBuffers(1) 
glBindBuffer(GL_ARRAY_BUFFER, vbo) 
glBufferData(GL_ARRAY_BUFFER, 6*4, data, GL_STATIC_READ) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

# pullback 
recv_data = np.empty_like(data) 
glBindBuffer(GL_ARRAY_BUFFER, vbo) 
glGetBufferSubData(GL_ARRAY_BUFFER, 0, 6*4, recv_data) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 

print(recv_data) 

该代码可以产生不同的结果每个运行或结束于上述错误之一。

1 [email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo         :(
[ 0.00000000e+00 1.58456325e+29 0.00000000e+00 1.58456325e+29 
    4.02037986e-33 1.40129846e-45] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 -4.65661287e-10 0.00000000e+00 -4.65661287e-10 
    5.88545355e-44 0.00000000e+00] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 3.68934881e+19 0.00000000e+00 3.68934881e+19 
    1.89559592e+28 1.40129846e-43] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 2.52435490e-29 0.00000000e+00 2.52435490e-29 
    1.89559592e+28 1.40129846e-43] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 3.68934881e+19 0.00000000e+00 3.68934881e+19 
    2.92698291e-36 1.40129846e-45] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 -3.68934881e+19 0.00000000e+00 -3.68934881e+19 
    7.42639198e-31 1.40129846e-45] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[ 0.00000000e+00 -4.65661287e-10 0.00000000e+00 -4.65661287e-10 
    7.22223950e-33 1.40129846e-45] 
[email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo 
[1] 4263 segmentation fault python -m demos.read_vbo 
139 [email protected] ~/unih/bsc/opengl_plot_prototype (git)-[master] % python -m demos.read_vbo        :(
[1] 4335 segmentation fault python -m demos.read_vbo 

这似乎是这个glGetBufferSubData可能从错误的内存空间读取?或者,也许指针recv_data有一些问题?

这是我的OpenGL设置:

[...] init GLFW 
[...] load OPENGL_CORE_PROFILE 4.10 
[...] initialize glfw window 
    + Opengl version  410 
    + GLSL Version  410 
    + GLFW3    (3, 1, 2) 

我使用MacBook Pro的视网膜2013

Date/Time:    2015-06-22 21:30:53.795 +0200 
OS Version:   Mac OS X 10.10.2 (14C109) 
Report Version:  11 
+0

尝试检查OpenGL错误。我首先想到的glGetBufferSubData可能不会拖延管道,但根据其他SO答案它。为了以防万一,你可以尝试在写入和读取调用之间放置一个glFinish()来确认。你也可以初始化为0而不是empty_like,并将recv_data的分配移到第一个glBufferData的上面,这样你就可以确定你没有从OpenGL中获得伪造。 –

+0

我试图将recv_data初始化为一个空数组,但是后来我更频繁地得到segfaults。 – keksnicoh

回答

0

后在这个问题上我找到了解决一些调查。首先我意识到recv_data参数可能会发生什么情况。造成无效操作例外,我能看到内部跟踪到clGetBufferSubData

的C调用
OpenGL.error.GLError: GLError(
    err = 1281, 
    description = 'invalid value', 
    baseOperation = glGetBufferSubData, 
    pyArgs = (
     GL_ARRAY_BUFFER, 
     0, 
     48, 
     array([ 0., 0., 0., 0., 0., 0.], dtype=float32), 
    ), 
    cArgs = (
     GL_ARRAY_BUFFER, 
     0, 
     48, 
     array([0, 0, 0, 0, 0, 0], dtype=uint8), *** < data is now unit8 instead of float32 
    ), 
    cArguments = (
     GL_ARRAY_BUFFER, 
     0, 
     48, 
     array([0, 0, 0, 0, 0, 0], dtype=uint8), 
    ) 
) 

可以看到,这也许是论点是错误的处理,因为它不应该是一个unit8?函数glGetBufferSubData返回一个类型为unit8的numpy.ndarray。然后我通过转换。 numpy视图返回到float32并最终可以读取数据。

# pullback 
glBindBuffer(GL_ARRAY_BUFFER, vbo) 
raw_unit8_data = glGetBufferSubData(GL_ARRAY_BUFFER, 0, 6*4) 
glBindBuffer(GL_ARRAY_BUFFER, 0) 
print(raw_unit8_data.view('<f4')) 

感谢另一个stackoverflow article在短期转换

由于这种行为看起来很奇怪我,我pyopengl售票系统上创建一个bug ticket