2016-01-06 110 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