如何解决PyOpenGL 如何通过 VBO 为元素着色
我正在编写 gcode 发送器。我想按线可视化机器工作的路径(并用其他颜色分隔 G00 移动线)。为了渲染元素,我使用了 VBO 并且它工作正常,但我不知道如何为边缘设置单独的颜色。我尝试在一个单独的 rgb 颜色列表中用 G00 移动“标记”一个顶点(你很容易猜到,它不能正常工作)。在互联网上找到的所有解决方案都不适用于我的代码。我真的是 OpenGL 的新手,我的想法已经用完了。也许有人可以向我展示一个我看不到的解决方案。非常感谢您的帮助。
def get_edges(self):
for x in range(0,len(self.points) - 2):
self.edges.append(x)
self.edges.append(x+1)
self.edges.append(x+1)
self.edges.append(x)
def get_points_from_buffer(self):
is_first_zminmax = True
is_first_fminmax = True
last_motion_mode = None
for command in self.buffer:
if command.find("G") != -1:
last_motion_mode = command[command.find("G"):command.find("G") + 3]
if command.find("F") != -1:
start = command.find("F") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
f = int(command[start])
else:
if stop == len(command) - 1:
f = int(command[start:stop+1])
else:
f = int(command[start:stop])
if is_first_fminmax is True:
is_first_fminmax = False
self.FMinMax[0] = f
self.FMinMax[1] = f
elif f < self.FMinMax[0]:
self.FMinMax[0] = f
elif f > self.FMinMax[1]:
self.FMinMax[1] = f
if command.find("X") != -1 or command.find("Y") != -1 or command.find("Z") != -1:
if last_motion_mode == "G00":
self.colors.append((0.25,1.0,0.0))
elif last_motion_mode != "G00":
self.colors.append((1.0,1.0))
if command.find("X") != -1:
start = command.find("X") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
x = float(command[start])
else:
if stop == len(command) - 1:
x = float(command[start:stop + 1])
else:
x = float(command[start:stop])
elif len(self.points) == 0:
x = 0
else:
x = self.points[len(self.points) - 1][0]
if command.find("Y") != -1:
start = command.find("Y") + 1
stop = start
while command[stop].isalpha() is False and stop < len(command) - 1 and command[stop] != ";":
stop += 1
if start == stop:
y = float(command[start])
else:
if stop == len(command) - 1:
y = float(command[start:stop + 1])
else:
y = float(command[start:stop])
elif len(self.points) == 0:
y = 0
else:
y = self.points[len(self.points) - 1][1]
if command.find("Z") != -1:
z = self.get_z(command)
if last_motion_mode != "G00" and is_first_zminmax is True:
is_first_zminmax = False
self.ZMinMax[0] = z
self.ZMinMax[1] = z
elif last_motion_mode != "G00":
if z < self.ZMinMax[0]:
self.ZMinMax[0] = z
elif z > self.ZMinMax[1]:
self.ZMinMax[1] = z
elif len(self.points) == 0:
z = 0
else:
z = self.points[len(self.points) - 1][2]
p = (x,y,z)
self.points.append(p)
self.is_motion_line.append(True)
else:
self.is_motion_line.append(False)
self.difZ = self.ZMinMax[1] - self.ZMinMax[0]
我的 OpenGL 代码:
from OpenGL.GL import *
from OpenGL.glu import *
from OpenGL.arrays import vbo
import numpy as np
from PyQt5 import QtOpenGL
class MyOpenGlWidget(QtOpenGL.QGLWidget):
def __init__(self,parent=None):
QtOpenGL.QGLWidget.__init__(self,parent)
def initGeometry(self,points=None,edges=None,colors=None):
if points is not None and edges is not None and colors is not None:
self.points = np.array(points)
self.vertVBO = vbo.VBO(np.reshape(self.points,(1,-1)).astype(np.float32))
self.vertVBO.bind()
# self.colors = np.array(colors)
# self.clrVBO = vbo.VBO(np.reshape(self.colors,-1)).astype(np.float32))
# self.clrVBO.bind()
self.edges = np.array(edges)
else:
self.points = np.array([])
self.vertVBO = vbo.VBO(np.reshape(self.points,-1)).astype(np.float32))
self.vertVBO.bind()
self.colors = np.array([])
self.clrVBO = vbo.VBO(np.reshape(self.colors,-1)).astype(np.float32))
self.clrVBO.bind()
self.edges = np.array([])
def initializeGL(self):
glClearColor(0.0,0.0,0.0)
glEnable(GL_DEPTH_TEST)
self.initGeometry()
self.rotX = 0.0
self.rotY = 0.0
self.rotZ = 0.0
def resizeGL(self,w,h):
glViewport(0,h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
aspect = w / float(h)
gluPerspective(45.0,aspect,100.0)
glMatrixMode(GL_MODELVIEW)
glpolygonMode(GL_FRONT_AND_BACK,GL_LINE)
def paintGL(self,coordinates=None):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glPushmatrix()
glTranslate(0.0,-50.0)
glScale(0.1,0.1,0.1)
glrotate(self.rotX,0.0)
glrotate(self.rotY,0.0)
glrotate(self.rotZ,1.0)
glTranslate(-0.5,-0.5,-0.5)
glEnableClientState(GL_VERTEX_ARRAY)
# glEnableClientState(GL_COLOR_ARRAY)
glVertexPointer(3,GL_FLOAT,self.vertVBO)
# glColorPointer(3,self.clrVBO)
glDrawElements(GL_QUADS,len(self.edges),GL_UNSIGNED_INT,self.edges)
gldisableClientState(GL_VERTEX_ARRAY)
# gldisableClientState(GL_COLOR_ARRAY)
glPopMatrix()
我已经拥有的:
我想要的:
解决方法
来自 glVertexPointer 的 OpenGL 规范
如果在指定顶点数组时将非零命名缓冲区对象绑定到 GL_ARRAY_BUFFER 目标(请参阅 glBindBuffer),则指针将被视为缓冲区对象数据存储中的字节偏移量。
本质上这意味着 glVertexPointer
的最后一个参数指定了最后一个绑定缓冲区的偏移量,而不是实际缓冲区本身。
因此,为了解决这个问题,您需要绑定 vertVBO
并指定 glVertexPointer
,然后绑定 clrVBO
并指定 glColorPointer
。这让 OpenGL 知道有两个缓冲区具有不同的数据。
示例:
self.vertVBO.bind()
glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3,G_FLOAT,None)
self.clrVBO.bind()
glEnableClientState(GL_COLOR_ARRAY)
glColorPointer(3,GL_FLOAT,None)
,
glVertexPointer
和 glColorPointer
的最后一个参数不是缓冲区对象,而是缓冲区对象数据存储中的偏移量。
当您调用 glVertexPointer
或 glColorPointer
时,当前绑定到目标 GL_ARRAY_BUFFER
的缓冲区与固定函数属性相关联。您需要在调用 glVertexPointer
或 glColorPointer
之前绑定正确的缓冲区:
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
self.vertVBO.bind()
glVertexPointer(3,None)
self.clrVBO.bind()
glColorPointer(3,None)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。