PyOpenGL 奇怪的随机彩色三角形
PyOpenGL weird random colored triangles
我使用 PyOpenGL 编写了一个简单的程序,用于加载模型然后显示它。但是当我看到模型时,我还看到它周围有很多随机彩色三角形
我不知道,它们为什么会出现,但我不想要它们。代码:
prim.py(原始模型和模型class)
# -*- coding: utf-8 -*-
from OpenGL.GL import *
from array import array
class Primitive():
def __init__(self,vert,colors,colors2,drawMode,ind,x=0,y=0,z=0,s=0,rX=0,rY=0,rZ=0):
#Csúcstömbadatok tárolása/Storing vertex-data
self.vert=array('f',list(vert))
#Színtömbadatok/Storing color-data
self.colors=array('f',list(colors))
#Indexadatok/Incidies
self.ind=array('B',list(ind))
#X-y eltolás/X-Y translation
self.x,self.y,self.z=x,y,z
#Elforgatás/Rotation
self.rX,self.rY,self.rZ=rX,rY,rZ
#Másodlagos színtömbadatok(Inaktív 3szög esetén)/Secondary coloring, when triangle is inactive
self.colors2=array('f',list(colors2))
#Aktív-inaktív/Active-inactive
self.selected=s
self.drawM=drawMode
def draw(self):
#Ideiglenes projekciós mártix létrehozása/Creating a temporary projection matrix
glPushMatrix()
#Döntés elsődlege-másodlagos szinezés között/Chosing betveen primary and secondary coloring
if self.selected: glColorPointer( 3, GL_FLOAT, 0, self.colors.tostring( ) );cl=len(self.colors)/3
else: glColorPointer( 3, GL_FLOAT, 0, self.colors2.tostring( ) );cl=len(self.colors2)/3
#Csúcstömbadatok feltöltése/Uploading vertexarray
glVertexPointer( 3, GL_FLOAT, 0, self.vert.tostring( ) )
#Eltolás/translation
glTranslate(self.x, self.y, self.z)
#Elforgatás/Rotation
glRotate(self.rX,1,0,0)
glRotate(self.rY,0,1,0)
glRotate(self.rZ,0,0,1)
#Kirajzolás/Drawing
glDrawElements( self.drawM, len(self.vert)+cl, GL_UNSIGNED_BYTE, self.ind.tostring( ) )
#Eredeti projekciós mátrix visszaállítása/Restoring original projection matrix
glPopMatrix()
#Osztály tárolásra/A Class for storing
class ElementsList():
def __init__(self,elements):
#Elemeket egy listában tároljuk/We store the elements in a list
self.el=list(elements)
def __len__(self):
#Elemszám/lenght
return len(self.el)
def __setitem__(self,key,value):
#Elemek elérése/Access elements
self.el[key]=value
def __getitem__(self,key):
#Elemek elérése/Access elements
return self.el[key]
def append(self,value):
#Elemek elérése/Access elements
self.el.append(value)
def select(self,i):
#Adott elem kiválasztása/Select an element
for item in self.el: item.selected=0 #Összes elem kiválasztásának törlése/Deselect all elements
self.el[i].selected=1 #Adott elem kiválasztása/Select element
def draw(self): #Kirayzolás/Drawing
for i in self.el: i.draw()
def aCoords(self,x,y,z=0): #Aktív elem eltolása
for i in self.el: #\
if i.selected==1: # > Aktív elem kiválasztása/Select active element
i.x+=x #Eltolás
i.y+=y #Translation
i.z+=z
def Coords(self,x,y,z=0): #Összes elem eltolása/Translate all elements
for i in self.el: #Minden elemre/For all elements
i.x+=x
i.y+=y
i.z+=z
def aRotate(self,rX,rY,rZ): #Aktív elem elforgatása/Rotate active element
for i in self.el:
if i.selected==1:
i.rX+=rX
i.rY+=rY
i.rZ+=rZ
def Rotate(self,rX,rY,rZ): #Összes elem elforgatása/Rotate all elements
for i in self.el:
i.rX+=rX
i.rY+=rY
i.rZ+=rZ
cVertices = [ -1,-1,1,
-1,1,1,
1,1,1,
1,-1,1,
-1,-1,-1,
-1,1,-1,
1,1,-1,
1,-1,-1 ]
cColors = [ 0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
0, 0, 1,
1, 0, 1,
1, 1, 1,
0, 1, 1]
cFaces = [0, 3, 2, 1,
2, 3, 7, 6,
0, 4, 7, 3,
1, 2, 6, 5,
4, 5, 6, 7,
0, 1, 5, 4 ]
model.py(一个简单的坡度模型)
from prim import *
from OpenGL.GL import *
vert=[1,1,1,
2,1,1,
1,1,2,
2,1,2,
1,2,1,
2,2,1]
colors=[1,1,1,
1,0,1,
0,1,1,
1,1,0,
1,0,0,
0,0,1
]
faces=[0,1,5,4,
0,1,3,2,
3,2,4,5]
faces2=[0,2,4,
1,5,3]
m1=Primitive(vert,colors,colors,GL_TRIANGLE_FAN,faces)
m2=Primitive(vert,colors,colors,GL_TRIANGLES,faces2)
model=ElementsList([m1,m2])
modelview.py(主程序)
# -*- coding: utf-8 -*-
#Importálások/Importing
import pygame # a pygame "játékmodul"/pygame "gamemodule"
from OpenGL.GL import * #OpenGL grafika/OpenGL graphics
from ctypes import * #C-kompatibilis elemek(pl. c_int)/C-compat. elements(for ex. c_int)
from array import array #powerful array class
from prim import *
from model import model
print("Modules imported")
#Inicializáció/initializing
pygame.init ()
#Ablak létrehozása/Creating a window
screen = pygame.display.set_mode ((1000,1200), pygame.OPENGL|pygame.DOUBLEBUF, 24)
#OpenGL nézetport beállítása/Set OpenGL's viewport
glViewport (0, 0, 1000, 1200)
glOrtho( -8, 8, -8, 8, -8, 8 )
#Törlőszín/Clear Color
glClearColor (0.0, 0.5, 0.5, 1.0)
#Csúcs-és színtömbök engedélyezése
glEnableClientState (GL_VERTEX_ARRAY)
glEnableClientState( GL_COLOR_ARRAY )
#Mélységtesz engedélyezése/Enable Depth Test
glEnable(GL_DEPTH_TEST)
#Simítás/Smoothing
glShadeModel( GL_SMOOTH )
#Rotáció/Rotation
rX,rY,rZ=0,0,0
#'Futási indikátor'/Flag for running
done=0
#Eseménykezelő fügvények/Event handling functions
def rightFunction(): global model; model.Rotate(10,0,0)
def leftFunction(): global model; model.Rotate(-10,0,0)
def upFunction(): global model; model.Rotate(0,10,0)
def downFunction(): global model; model.Rotate(0,-10,0)
def plusFunction(): global model; model.Rotate(0,0,10)
def minusFunction(): global model; model.Rotate(0,0,-10)
def qFunction(): global done; done=1 #Kilépési 'zászló'/Exiting 'flag'
print("Functions created")
#Eseménykezelő szótár, nagyjából a C++-s switch utasítás/Event handling dictionary, like the switch in C++
eventHandler={
pygame.K_UP:upFunction, #K_xx egy konstans, egy szám
pygame.K_DOWN:downFunction, #K_xx is a constant value(a number)
pygame.K_LEFT:leftFunction,
pygame.K_RIGHT:rightFunction,
pygame.K_q:qFunction,
pygame.K_KP_PLUS:plusFunction,
pygame.K_KP_MINUS:minusFunction
}
print("Events bound")
#Örökciklus/Infinite loop
while not done:
#For-each ciklus az eseményeken
#For-each loop in the events
for event in pygame.event.get():
#Ha kilép, akkor a ciklusból is
#If clicked the X, exit from the loop
if event.type == pygame.QUIT:
done=1
#Hívás az eseménykezelő szótárra
#Calling the event handler dictionary
elif event.type==pygame.KEYDOWN:
#try:
eventHandler[event.key]()
#except: print("Unbound key")
#Törlés/Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
#Kirajzolófügvények/Drawing functions
model.draw()
#Kép frissítése/Updating
pygame.display.flip()
#Cikluson kívül/Outside of the loop
print("Program finished!")
#Kilépés/quit
pygame.quit()
你可以看到上面的结果。
我该如何解决这个错误?
编辑:
如果我用这个替换 **model.py* 文件:
from prim import *
from OpenGL.GL import *
model=Primitive(cVertices,cColors,cColors,GL_QUADS,cFaces) #To draw a cube
然后它工作正常。我认为问题出在 VBO 的数据上。
编辑:
如果我用这个替换 model.py 文件:
from prim import Primitive
from OpenGL.GL import *
vert=[0,0,0,
1,0,0,
0,1,0,
1,1,0]
face=[0,1,3,2]
colors=[1,1,1, #That isn't changed
1,0,1,
0,1,1,
1,1,0,
1,0,0,
0,0,1
]
model=Primitive(vert,colors,colors,GL_QUADS,face)
那就没有什么奇怪的原语了。但是当我尝试使用 "old" vert 列表时,会出现一些四边形。
我写了一个简单的程序来测试 Primitive class,它在 2D 和 3D(使用立方体)中工作正常
我认为错误出在我的顶点数据中,因为当我重写我的顶点数据时,问题就消失了。
我使用 PyOpenGL 编写了一个简单的程序,用于加载模型然后显示它。但是当我看到模型时,我还看到它周围有很多随机彩色三角形
# -*- coding: utf-8 -*-
from OpenGL.GL import *
from array import array
class Primitive():
def __init__(self,vert,colors,colors2,drawMode,ind,x=0,y=0,z=0,s=0,rX=0,rY=0,rZ=0):
#Csúcstömbadatok tárolása/Storing vertex-data
self.vert=array('f',list(vert))
#Színtömbadatok/Storing color-data
self.colors=array('f',list(colors))
#Indexadatok/Incidies
self.ind=array('B',list(ind))
#X-y eltolás/X-Y translation
self.x,self.y,self.z=x,y,z
#Elforgatás/Rotation
self.rX,self.rY,self.rZ=rX,rY,rZ
#Másodlagos színtömbadatok(Inaktív 3szög esetén)/Secondary coloring, when triangle is inactive
self.colors2=array('f',list(colors2))
#Aktív-inaktív/Active-inactive
self.selected=s
self.drawM=drawMode
def draw(self):
#Ideiglenes projekciós mártix létrehozása/Creating a temporary projection matrix
glPushMatrix()
#Döntés elsődlege-másodlagos szinezés között/Chosing betveen primary and secondary coloring
if self.selected: glColorPointer( 3, GL_FLOAT, 0, self.colors.tostring( ) );cl=len(self.colors)/3
else: glColorPointer( 3, GL_FLOAT, 0, self.colors2.tostring( ) );cl=len(self.colors2)/3
#Csúcstömbadatok feltöltése/Uploading vertexarray
glVertexPointer( 3, GL_FLOAT, 0, self.vert.tostring( ) )
#Eltolás/translation
glTranslate(self.x, self.y, self.z)
#Elforgatás/Rotation
glRotate(self.rX,1,0,0)
glRotate(self.rY,0,1,0)
glRotate(self.rZ,0,0,1)
#Kirajzolás/Drawing
glDrawElements( self.drawM, len(self.vert)+cl, GL_UNSIGNED_BYTE, self.ind.tostring( ) )
#Eredeti projekciós mátrix visszaállítása/Restoring original projection matrix
glPopMatrix()
#Osztály tárolásra/A Class for storing
class ElementsList():
def __init__(self,elements):
#Elemeket egy listában tároljuk/We store the elements in a list
self.el=list(elements)
def __len__(self):
#Elemszám/lenght
return len(self.el)
def __setitem__(self,key,value):
#Elemek elérése/Access elements
self.el[key]=value
def __getitem__(self,key):
#Elemek elérése/Access elements
return self.el[key]
def append(self,value):
#Elemek elérése/Access elements
self.el.append(value)
def select(self,i):
#Adott elem kiválasztása/Select an element
for item in self.el: item.selected=0 #Összes elem kiválasztásának törlése/Deselect all elements
self.el[i].selected=1 #Adott elem kiválasztása/Select element
def draw(self): #Kirayzolás/Drawing
for i in self.el: i.draw()
def aCoords(self,x,y,z=0): #Aktív elem eltolása
for i in self.el: #\
if i.selected==1: # > Aktív elem kiválasztása/Select active element
i.x+=x #Eltolás
i.y+=y #Translation
i.z+=z
def Coords(self,x,y,z=0): #Összes elem eltolása/Translate all elements
for i in self.el: #Minden elemre/For all elements
i.x+=x
i.y+=y
i.z+=z
def aRotate(self,rX,rY,rZ): #Aktív elem elforgatása/Rotate active element
for i in self.el:
if i.selected==1:
i.rX+=rX
i.rY+=rY
i.rZ+=rZ
def Rotate(self,rX,rY,rZ): #Összes elem elforgatása/Rotate all elements
for i in self.el:
i.rX+=rX
i.rY+=rY
i.rZ+=rZ
cVertices = [ -1,-1,1,
-1,1,1,
1,1,1,
1,-1,1,
-1,-1,-1,
-1,1,-1,
1,1,-1,
1,-1,-1 ]
cColors = [ 0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
0, 0, 1,
1, 0, 1,
1, 1, 1,
0, 1, 1]
cFaces = [0, 3, 2, 1,
2, 3, 7, 6,
0, 4, 7, 3,
1, 2, 6, 5,
4, 5, 6, 7,
0, 1, 5, 4 ]
model.py(一个简单的坡度模型)
from prim import *
from OpenGL.GL import *
vert=[1,1,1,
2,1,1,
1,1,2,
2,1,2,
1,2,1,
2,2,1]
colors=[1,1,1,
1,0,1,
0,1,1,
1,1,0,
1,0,0,
0,0,1
]
faces=[0,1,5,4,
0,1,3,2,
3,2,4,5]
faces2=[0,2,4,
1,5,3]
m1=Primitive(vert,colors,colors,GL_TRIANGLE_FAN,faces)
m2=Primitive(vert,colors,colors,GL_TRIANGLES,faces2)
model=ElementsList([m1,m2])
modelview.py(主程序)
# -*- coding: utf-8 -*-
#Importálások/Importing
import pygame # a pygame "játékmodul"/pygame "gamemodule"
from OpenGL.GL import * #OpenGL grafika/OpenGL graphics
from ctypes import * #C-kompatibilis elemek(pl. c_int)/C-compat. elements(for ex. c_int)
from array import array #powerful array class
from prim import *
from model import model
print("Modules imported")
#Inicializáció/initializing
pygame.init ()
#Ablak létrehozása/Creating a window
screen = pygame.display.set_mode ((1000,1200), pygame.OPENGL|pygame.DOUBLEBUF, 24)
#OpenGL nézetport beállítása/Set OpenGL's viewport
glViewport (0, 0, 1000, 1200)
glOrtho( -8, 8, -8, 8, -8, 8 )
#Törlőszín/Clear Color
glClearColor (0.0, 0.5, 0.5, 1.0)
#Csúcs-és színtömbök engedélyezése
glEnableClientState (GL_VERTEX_ARRAY)
glEnableClientState( GL_COLOR_ARRAY )
#Mélységtesz engedélyezése/Enable Depth Test
glEnable(GL_DEPTH_TEST)
#Simítás/Smoothing
glShadeModel( GL_SMOOTH )
#Rotáció/Rotation
rX,rY,rZ=0,0,0
#'Futási indikátor'/Flag for running
done=0
#Eseménykezelő fügvények/Event handling functions
def rightFunction(): global model; model.Rotate(10,0,0)
def leftFunction(): global model; model.Rotate(-10,0,0)
def upFunction(): global model; model.Rotate(0,10,0)
def downFunction(): global model; model.Rotate(0,-10,0)
def plusFunction(): global model; model.Rotate(0,0,10)
def minusFunction(): global model; model.Rotate(0,0,-10)
def qFunction(): global done; done=1 #Kilépési 'zászló'/Exiting 'flag'
print("Functions created")
#Eseménykezelő szótár, nagyjából a C++-s switch utasítás/Event handling dictionary, like the switch in C++
eventHandler={
pygame.K_UP:upFunction, #K_xx egy konstans, egy szám
pygame.K_DOWN:downFunction, #K_xx is a constant value(a number)
pygame.K_LEFT:leftFunction,
pygame.K_RIGHT:rightFunction,
pygame.K_q:qFunction,
pygame.K_KP_PLUS:plusFunction,
pygame.K_KP_MINUS:minusFunction
}
print("Events bound")
#Örökciklus/Infinite loop
while not done:
#For-each ciklus az eseményeken
#For-each loop in the events
for event in pygame.event.get():
#Ha kilép, akkor a ciklusból is
#If clicked the X, exit from the loop
if event.type == pygame.QUIT:
done=1
#Hívás az eseménykezelő szótárra
#Calling the event handler dictionary
elif event.type==pygame.KEYDOWN:
#try:
eventHandler[event.key]()
#except: print("Unbound key")
#Törlés/Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
#Kirajzolófügvények/Drawing functions
model.draw()
#Kép frissítése/Updating
pygame.display.flip()
#Cikluson kívül/Outside of the loop
print("Program finished!")
#Kilépés/quit
pygame.quit()
你可以看到上面的结果。 我该如何解决这个错误?
编辑: 如果我用这个替换 **model.py* 文件:
from prim import *
from OpenGL.GL import *
model=Primitive(cVertices,cColors,cColors,GL_QUADS,cFaces) #To draw a cube
然后它工作正常。我认为问题出在 VBO 的数据上。
编辑: 如果我用这个替换 model.py 文件:
from prim import Primitive
from OpenGL.GL import *
vert=[0,0,0,
1,0,0,
0,1,0,
1,1,0]
face=[0,1,3,2]
colors=[1,1,1, #That isn't changed
1,0,1,
0,1,1,
1,1,0,
1,0,0,
0,0,1
]
model=Primitive(vert,colors,colors,GL_QUADS,face)
那就没有什么奇怪的原语了。但是当我尝试使用 "old" vert 列表时,会出现一些四边形。 我写了一个简单的程序来测试 Primitive class,它在 2D 和 3D(使用立方体)中工作正常
我认为错误出在我的顶点数据中,因为当我重写我的顶点数据时,问题就消失了。