pyOpenGLのglBufferData
の仕様がよくわからん。
undocumentedなのである。
調べていたら自分の過去記事が出てきて、2年前も同じところではまってたよ・・・
思い出したのでちょっとまとめておきます。
実験
#vbo
def set_vertex_attribute(self, component_count: int, bytelength: int,
data: any) -> None:
''' float2, 3, 4'''
self.component_count = component_count
stride = 4 * self.component_count
self.vertex_count = bytelength // stride
self.bind()
glBufferData(GL_ARRAY_BUFFER, bytelength, data, GL_STATIC_DRAW)
#ibo
def set_indices(self, stride: int, bytelength: int, data: Any) -> None:
self.index_count = bytelength // stride
self.bind()
if stride == 1:
raise Exception("not implemented")
elif stride == 2:
self.index_type = GL_UNSIGNED_SHORT
elif stride == 4:
self.index_type = GL_UNSIGNED_INT
glBufferData(GL_ELEMENT_ARRAY_BUFFER, bytelength, data, GL_STATIC_DRAW)
self.positions = (-1.0, -1.0, 1.0, -1.0, 0.0, 1.0) # vec2 x 3
self.indices = (0, 1, 2)
ctypesで配列を作って渡す
動く
float6 = (ctypes.c_float * 6) # float[6] 型
values = float6(*self.positions)
self.vbo.set_vertex_attribute(2, 4 * 2 * 3, vallues)
self.ibo.set_indices(4, 12, (ctypes.c_uint * 3)(*self.indices))
bytes 作って渡す
動く
structでpackして、bytesを作る。
self.vbo.set_vertex_attribute(2, 4 * 2 * 3, struct.pack("6f", *self.positions))
self.ibo.set_indices(4, 12, struct.pack("3I", *self.indices))
array.array に入れて渡す
意外にも動かなかった。
対応するハンドラが無いというエラーになる。
self.vbo.set_vertex_attribute(2, 4 * 2 * 3, array.array('f', self.positions))
self.ibo.set_indices(4, 12, array.array('I', self.indices))
memoryview
エラーにならないが動かない。
self.vbo.set_vertex_attribute(2, 4 * 2 * 3, memoryview(struct.pack("6f", *self.positions)))
self.ibo.set_indices(4, 12, memoryview(struct.pack("3I", *self.indices)))
ctypes か bytes が動く
もしくは numpy
まとめ
久しぶりに PyOpenGL やったら、過渡期のOpenGLのコードとか出てきたのでついでに整理しなければと思った。
DirectXの方は、11 か 12 かしか無くてバージョンの問題は無いのだけど、OpenGLの方はいろいろあるが OpenGL4が d3d11 相当くらい?。ベースラインを最低でも WebGL2.0
あたりに揃える必要があると思った。学習用でも、それより古い OpenGL を使うのはあまりよろしくないなと。
なので、
WebGL2.0 - OpenGLES3.0 - OpenGL3.3(Core profile)
が最低ラインになるか。
動くコード