私はこのcolor_cube_actor.pyファイルを使用していて、HTC Viveを使用中にhello_qt_controllers.pyの例を実行することができます。色付きのキューブが表示され、私はルームスケールを使用して歩くことができます。OpenVRのcolor_cube_actor.pyのgl_PointSizeを変更すると、Pythonがクラッシュしますか?
私は、Pythonからリアルタイムでバッファデータを変更する方法を学習を開始したいと思います。
開始するにはGLSLプログラムの不要な部分をたくさん削除して、顔のない頂点を10pxの白い点としてレンダリングしました。
私はthis exampleで実験された頂点のドットサイズの変更を持っているPythonのループからの値を供給しようとすると、私はdrawWithoutVBOs()
スタイルに合わせて自分のプロジェクトを変更しました。
単純な静的で変化しない変数(layout(location = 8) uniform float Size = 10;
)を使用すると、私のプログラムは動作し、上記の画像を生成します。
しかし、私が "変化する"変数(layout(location = 8) in float Size;
)を使用すると、Pythonは完全にエラーなく終了します。
ソースコードプロジェクト
#!/bin/env python
# file color_cube_actor.py
from textwrap import dedent
import numpy as np
from OpenGL.arrays import vbo
from OpenGL.GL import * # @UnusedWildImport # this comment squelches an IDE warning
from OpenGL.GL.shaders import compileShader, compileProgram
from pyqtgraph.opengl.shaders import getShaderProgram
class ColorCubeActor(object):
"""
Draws a cube
2________ 3
/| /|
6/_|____7/ |
| |_____|_|
| /0 | /1
|/______|/
4 5
"""
def __init__(self):
self.shader = 0
def init_gl(self):
vertex_shader = compileShader(dedent(
"""
#version 450 core
layout(location = 0) uniform mat4 Projection = mat4(1);
layout(location = 4) uniform mat4 ModelView = mat4(1);
//layout(location = 8) in float Size; //This causes Python to crash!
layout(location = 8) uniform float Size = 10;
vec3 UNIT_CUBE[8] = vec3[8](
vec3(-1.0, -0.0, -1.0), // 0: lower left rear
vec3(+1.0, -0.0, -1.0), // 1: lower right rear
vec3(-1.0, +2.0, -1.0), // 2: upper left rear
vec3(+1.0, +2.0, -1.0), // 3: upper right rear
vec3(-1.0, -0.0, +1.0), // 4: lower left front
vec3(+1.0, -0.0, +1.0), // 5: lower right front
vec3(-1.0, +2.0, +1.0), // 6: upper left front
vec3(+1.0, +2.0, +1.0) // 7: upper right front
);
out vec3 _color;
void main() {
_color = vec3(1.0, 1.0, 1.0);
gl_Position = Projection * ModelView * vec4(UNIT_CUBE[gl_VertexID] * 0.3, 1.0);
gl_PointSize = Size;
}
"""),
GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent(
"""
#version 450 core
in vec3 _color;
out vec4 FragColor;
void main() {
FragColor = vec4(_color, 1.0);
}
"""),
GL_FRAGMENT_SHADER)
self.shader = compileProgram(vertex_shader, fragment_shader)
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBindAttribLocation(self.shader, 8, "Size")
glLinkProgram(self.shader)
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
glEnable(GL_DEPTH_TEST)
def setPointSize(self):
size = [10.0,10.0,10.0,10.0,10.0,10.0,10.0,10.0]
glEnableVertexAttribArray(8)
glVertexAttribPointer(8, 1, GL_FLOAT, GL_FALSE, 0, size)
def display_gl(self, modelview, projection):
glUseProgram(self.shader)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glBindVertexArray(self.vao)
glClear(GL_COLOR_BUFFER_BIT) #| GL_DEPTH_BUFFER_BIT)
glUniformMatrix4fv(0, 1, False, projection)
glUniformMatrix4fv(4, 1, False, modelview)
self.setPointSize()
glDrawArrays(GL_POINTS, 0, 8)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
def dispose_gl(self):
glDeleteProgram(self.shader)
self.shader = 0
glDeleteVertexArrays(1, (self.vao,))
self.vao = 0
のために、私はpygameのダウンロードとは対照的に、私はQTバックエンドを使用して私のプロジェクトで、おそらく何かを逃した場合、またはしているかはわからないが、その後、私の環境と他の間の微妙な違いがあります問題の原因となっている例??
ここで誰かがgl_PointSizeに値を与えることでPythonがクラッシュする原因を突き止めることができたらと思っていました。また、PyOpenVRライブラリを使用してリアルタイムでバッファデータ(位置、ポイントサイズなど)を変更する方法にも興味がありますか?
ありがとうございました!
[UPDATE]
これは私がGLSL Tutorial – Attribute Variablesからコピーして修正私の最新のプロジェクトです。これで、pyGameとpySide QTの両方で空白の画面しか表示されなくなりました。
#!/bin/env python
# file color_cube_actor.py
import time
from textwrap import dedent
import numpy as np
from OpenGL.GL import * # @UnusedWildImport # this comment squelches an IDE warning
from OpenGL.GL.shaders import compileShader, compileProgram
import pygame
from pygame.locals import *
class ColorCubeActor(object):
array_size = 100
def __init__(self):
self.program = 0
self.scale = 0
self.indices = np.ascontiguousarray(np.arange(self.array_size), dtype=np.int)
self.colors = np.ascontiguousarray(np.tile(np.array([0.0,1.0,0.0]), (self.array_size,1)), dtype=np.float) #a bunch of green vertices
self.sizes = np.ascontiguousarray(np.ones(self.array_size)*10, dtype=np.float)
def init_gl(self):
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
vertex_shader = compileShader(dedent("""
#version 450 core
layout(location = 0) uniform mat4 Projection = mat4(1);
layout(location = 4) uniform mat4 ModelView = mat4(1);
in vec3 ptPosition;
in float ptSize;
in vec3 ptColor;
out vec3 _color;
void main()
{
_color = ptColor; //vec3(0.2, 0.5, 1.0); //light blue
gl_Position = Projection * ModelView * vec4(ptPosition, 1.0);
//use normalized device coordinates to calculate the PointSize of a vertex based on it's distance from the perspective camera.
//https://www.gamedev.net/topic/574695-gl_points-distance-attenuation/#
vec3 ndc = gl_Position.xyz/gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = ptSize*zDist ; // between 0 and 50 now.
}
"""), GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent("""
#version 450 core
in vec3 _color;
out vec4 FragColor;
void main() {
FragColor = vec4(_color, 1.0); //just pass a color to the vertex (results in a rectangle pixel)
}
"""), GL_FRAGMENT_SHADER)
self.program = compileProgram(vertex_shader, fragment_shader)
#setup the vao and bind buffers (example: http://www.lighthouse3d.com/tutorials/glsl-tutorial/attribute-variables/)
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
self.ptSize = glGenBuffers(1) #bind buffer for point sizes
glBindBuffer(GL_ARRAY_BUFFER, self.ptSize) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
ptSize_pointer = glGetAttribLocation(self.program, "ptSize") #get the location of attribute "ptSize" from self.program
glBufferData(GL_ARRAY_BUFFER, self.sizes.nbytes, self.sizes, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
glEnableVertexAttribArray(ptSize_pointer) #Enable the attribute at that location
glVertexAttribPointer(ptSize_pointer, 1, GL_FLOAT, GL_FALSE, 0, 0) #Tell OpenGL what the array contains:
self.ptColor = glGenBuffers(1) #bind buffer for point colors
glBindBuffer(GL_ARRAY_BUFFER, self.ptColor) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
ptColor_pointer = glGetAttribLocation(self.program, "ptColor") #get the location of attribute "ptSize" from self.program
glBufferData(GL_ARRAY_BUFFER, self.colors.nbytes, self.colors, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
glEnableVertexAttribArray(ptColor_pointer) #Enable the attribute at that location
glVertexAttribPointer(ptColor_pointer, 3, GL_FLOAT, GL_FALSE, 0, 0) #Tell OpenGL what the array contains:
def setPoints(self, modelview, projection):
self.scale += 0.0005
#create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
theta = np.linspace(-4 * np.pi, 4 * np.pi, self.array_size)
z = np.linspace(-2, 2, self.array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
plot = np.ascontiguousarray(np.dstack((x,y,z)) * self.scale, dtype=np.float)
self.ptPosition = glGenBuffers(1) #bind buffer for positions and copy data into buffer
glBindBuffer(GL_ARRAY_BUFFER, self.ptPosition) #GL_ARRAY_BUFFER is the buffer type we use to feed attributes
ptPosition_pointer = glGetAttribLocation(self.program, "ptPosition") #get the location of attribute "ptSize" from self.program
glBufferData(GL_ARRAY_BUFFER, plot.nbytes, plot, GL_STREAM_DRAW) #feed the buffer, and let OpenGL know that we don't plan to
glEnableVertexAttribArray(ptPosition_pointer) #Enable the attribute at that location
glVertexAttribPointer(ptPosition_pointer, 3, GL_FLOAT, GL_FALSE, 0, 0)#Tell OpenGL what the array contains:
glUniformMatrix4fv(0, 1, False, projection)
glUniformMatrix4fv(4, 1, False, modelview)
glDrawElements(GL_POINTS, self.array_size, GL_UNSIGNED_INT, self.indices)
def display_gl(self, modelview, projection):
glClear(GL_COLOR_BUFFER_BIT) #| GL_DEPTH_BUFFER_BIT)
glUseProgram(self.program)
self.setPoints(modelview, projection)
def dispose_gl(self):
glDeleteProgram(self.program)
self.program = 0
def main(self):
pygame.init()
pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
self.init_gl()
projection = np.array([#the matrix generated captured while using HTC Vive
[ 0.75752085, 0. , 0. , 0.],
[ 0. , 0.68160856, 0. , 0.],
[ 0.05516453, -0.00299519, -1.00040019, -1.],
[ 0. , 0. , -0.20008004, 0.]
])
modelview = np.array([#the matrix generated captured while using HTC Vive
[ 0.99030989, 0.04490654, 0.13141415, 0.],
[-0.01430531, 0.9742285 , -0.22510922, 0.],
[-0.13813627, 0.22104797, 0.9654305 , 0.],
[-0.12975544, -0.9294402 , -1.06236947, 1.]
])
start_time = time.time()
while time.time() - start_time < 5: #5 second animation
self.display_gl(modelview, projection)
pygame.display.flip()
if __name__ == '__main__':
t = ColorCubeActor()
t.main()
また、助けと患者の皆さんに感謝します!私はOpenGLについて非常に経験が不十分であり、本当にすべての提案に感謝しています。
[UPDATE]
ラーニングOpenGLは、おそらく私は非常に長い時間で行うことを試みてきた最も難しいものの一つとなっています。私は今、OpenGL 4.5でバッファーを設定しようとしているだけで4日間過ごしました。私はほとんど進歩を遂げておらず、ちょっとしたことに悩まされています。
私が書いたコードの例です(バージョン4.5は指定していません)。Derhassの提案によると、私はこのファイルをVBOsで使用しようとしましたが、#version 450 core
を指定するまで機能しているようですが、そこでは償却エラーと1282がたくさんあります。再びOpenGL 4.5をターゲットにしていないので、OpenVRで使用することはできません。
#!/bin/env python
# coding: utf-8
import time
import numpy as np
from textwrap import dedent
from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram
import pygame
from pygame.locals import *
##############################################################################
# OpenGL funcs
##############################################################################
buffers=None
shader = None
def init_gl():
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
global shader, buffers
vertex_shader = compileShader(dedent('''
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
varying out vec3 _color;
void main() {
_color = gl_Color;
gl_Position = Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 ndc = gl_Position.xyz/gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 25*zDist ; // between 0 and 50 now.
}
'''), GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent('''
in vec3 _color;
void main() {
gl_FragColor = vec4(_color, 1.0); //gl_Color;
}
'''), GL_FRAGMENT_SHADER)
shader = compileProgram(vertex_shader, fragment_shader)
buffers=create_vbo()
yaw=0
pitch=0
def draw():
global yaw, pitch
glClear(GL_COLOR_BUFFER_BIT)# | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
yaw+=0.39
pitch+=0.27
glTranslatef(0.0, 0.0, 0.0)
glRotatef(yaw, 0, 1, 0)
glRotatef(pitch, 1, 0, 0)
setPoints()
glFlush()
##############################################################################
# vertices
##############################################################################
array_size = 100
scale = 0.15
#create dataset https://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html
theta = np.linspace(-4 * np.pi, 4 * np.pi, array_size)
z = np.linspace(-2, 2, array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
vertices = np.dstack((x,y,z)) * scale
colors = np.tile(np.array([0.0, 1.0, 0.0]), (array_size,1)) #a bunch of green vertices
indices=np.arange(array_size)
def create_vbo():
buffers = glGenBuffers(3)
glBindBuffer(GL_ARRAY_BUFFER, buffers[0])
glBufferData(GL_ARRAY_BUFFER,
vertices.nbytes, # byte size
(ctypes.c_float*len(vertices.flat))(*vertices.flat),
GL_STREAM_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, buffers[1])
glBufferData(GL_ARRAY_BUFFER,
colors.nbytes, # byte size
(ctypes.c_float*len(colors.flat))(*colors.flat),
GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2])
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices.nbytes, # byte size
(ctypes.c_uint*len(indices.flat))(*indices.flat),
GL_STATIC_DRAW)
return buffers
def draw_vbo():
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glVertexPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glColorPointer(3, GL_FLOAT, 0, None);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
glDrawElements(GL_POINTS, indices.size, GL_UNSIGNED_INT, None);
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY);
def setPoints():
global shader
glUseProgram(shader)
draw_vbo()
projection = np.array([#the matrix generated captured while using HTC Vive
[ 0.75752085, 0. , 0. , 0.],
[ 0. , 0.68160856, 0. , 0.],
[ 0.05516453, -0.00299519, -1.00040019, -1.],
[ 0. , 0. , -0.20008004, 0.]
])
modelview = np.array([#the matrix generated captured while using HTC Vive
[ 0.99030989, 0.04490654, 0.13141415, 0.],
[-0.01430531, 0.9742285 , -0.22510922, 0.],
[-0.13813627, 0.22104797, 0.9654305 , 0.],
[-0.12975544, -0.9294402 , -1.06236947, 1.]
])
glUniformMatrix4fv(glGetUniformLocation(shader, "Projection"), 1, False, projection)
glUniformMatrix4fv(glGetUniformLocation(shader, "ModelView"), 1, False, modelview)
glUseProgram(0)
##############################################################################
if __name__ == '__main__':
pygame.init()
pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
init_gl()
start_time = time.time()
while time.time() - start_time < 5: #5 second animation
draw()
pygame.display.flip()
だから私はそれが同じに見えるにもかかわらず、何らかの理由で、私は唯一動き回る一つの頂点を参照し、残りの場所を知っている人ですが)Pythonのクラス(にそれを書き換えてみました
#!/bin/env python
# coding: utf-8
import time
import numpy as np
from textwrap import dedent
from OpenGL.GL import *
from OpenGL.GL.shaders import compileShader, compileProgram
import pygame
from pygame.locals import *
class ObjectActor(object):
array_size = 100
def __init__(self):
self.buffers=None
self.shader=None
self.vertices = self.get_vertices()
self.colors = np.tile(np.array([0.0, 1.0, 0.0]), (self.array_size,1)) #a bunch of green vertices
self.indices = np.arange(self.array_size)
def init_gl(self):
##############################################################################
# OpenGL funcs
##############################################################################
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) #allow the program to specify the point size
vertex_shader = compileShader(dedent('''
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
varying out vec3 _color;
void main() {
_color = gl_Color;
gl_Position = Projection * ModelView * gl_ModelViewProjectionMatrix * gl_Vertex;
vec3 ndc = gl_Position.xyz/gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 25*zDist ; // between 0 and 50 now.
}
'''), GL_VERTEX_SHADER)
fragment_shader = compileShader(dedent('''
in vec3 _color;
void main() {
gl_FragColor = vec4(_color, 1.0); //gl_Color;
}
'''), GL_FRAGMENT_SHADER)
self.shader = compileProgram(vertex_shader, fragment_shader)
self.create_vbo()
def display_gl(self, modelview, projection):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.setPoints(modelview, projection)
glFlush()
def get_vertices(self):
##############################################################################
# vertices
##############################################################################
scale = 0.15
theta = np.linspace(-4 * np.pi, 4 * np.pi, self.array_size)
z = np.linspace(-2, 2, self.array_size)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
return np.dstack((x,y,z)) * scale
def create_vbo(self):
self.buffers = glGenBuffers(3)
glBindBuffer(GL_ARRAY_BUFFER, self.buffers[0])
glBufferData(GL_ARRAY_BUFFER,
self.vertices.nbytes, # byte size
(ctypes.c_float*len(self.vertices.flat))(*self.vertices.flat),
GL_STREAM_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, self.buffers[1])
glBufferData(GL_ARRAY_BUFFER,
self.colors.nbytes, # byte size
(ctypes.c_float*len(self.colors.flat))(*self.colors.flat),
GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.buffers[2])
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
self.indices.nbytes, # byte size
(ctypes.c_float*len(self.indices.flat))(*self.indices.flat),
GL_STATIC_DRAW)
def draw_vbo(self):
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
glBindBuffer(GL_ARRAY_BUFFER, self.buffers[0])
glVertexPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.buffers[1])
glColorPointer(3, GL_FLOAT, 0, None)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.buffers[2])
glDrawElements(GL_POINTS, self.indices.size, GL_UNSIGNED_INT, None)
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY)
def setPoints(self, modelview, projection):
glUseProgram(self.shader)
self.draw_vbo()
glUniformMatrix4fv(glGetUniformLocation(self.shader, "Projection"), 1, False, projection)
glUniformMatrix4fv(glGetUniformLocation(self.shader, "ModelView"), 1, False, modelview)
glUseProgram(0)
def main(self):
pygame.init()
pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
self.init_gl()
projection = np.array([#the matrix generated captured while using HTC Vive
[ 0.75752085, 0. , 0. , 0.],
[ 0. , 0.68160856, 0. , 0.],
[ 0.05516453, -0.00299519, -1.00040019, -1.],
[ 0. , 0. , -0.20008004, 0.]
])
modelview = np.array([#the matrix generated captured while using HTC Vive
[ 0.99030989, 0.04490654, 0.13141415, 0.],
[-0.01430531, 0.9742285 , -0.22510922, 0.],
[-0.13813627, 0.22104797, 0.9654305 , 0.],
[-0.12975544, -0.9294402 , -1.06236947, 1.]
])
yaw=0
pitch=0
start_time = time.time()
while time.time() - start_time < 5: #5 second animation
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
yaw+=0.39
pitch+=0.27
glTranslatef(0.0, 0.0, 0.0)
glRotatef(yaw, 0, 1, 0)
glRotatef(pitch, 1, 0, 0)
self.display_gl(modelview, projection)
pygame.display.flip()
##############################################################################
if __name__ == '__main__':
t = ObjectActor()
t.main()
この時点では、PyOpenGLが動作する方法で何かが非常に壊れているか、それを使用する方法を理解できない可能性があります。いずれかの方法は、実際のバマー..
あなたは間違いを確認しますか?私はあなたがプログラムをコンパイル&リンクしているのを見ますが、それが成功したかどうかを確認することは決してありません。確かに、PythonのGLラッパーがそれを行うかもしれません。 –