用PyOpenGL渲染带纹理的矩形
我正在做一个使用PyOpenGL的项目,现在想要让OpenGL显示一个启动画面。我决定的解决办法是画一个带纹理的2D矩形。不过,不管我怎么做,屏幕上总是黑乎乎的(我想应该是有东西被画出来了,要不然窗口应该是透明的,但这显然不是我想要的效果)。以下是我这个类的相关代码:
class ClassThing:
def __init__(self):
self.Splash = True
glutInit(sys.argv)
def TexFromPNG(self, filename):
img = Image.open(filename)
img_data = numpy.array(list(img.getdata()), numpy.uint8)
texture = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
return texture
def run(self):
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(256,224)
self.window = glutCreateWindow("GL")
glutDisplayFunc(self.draw)
glClearColor(0,0,0,0)
glEnable(GL_TEXTURE_2D)
glEnable(GL_VERTEX_ARRAY)
self.MainTex = glGenTextures(1)
self.SplashTex = self.TexFromPNG("Resources/Splash.png")
glutMainLoop()
def draw(self):
glClear(GL_COLOR_BUFFER_BIT)
glLoadIdentity()
if self.Splash:
glBindTexture(GL_TEXTURE_2D, self.SplashTex)
else:
glBindTexture(GL_TEXTURE_2D, self.MainTex)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
Varray = numpy.array([[0,0],[0,256],[224,256],[224,0]],numpy.uint16)
glVertexPointer(2,GL_SHORT,0,Varray)
indices = [0,1,2,3]
glDrawElements(GL_QUADS,1,GL_UNSIGNED_SHORT,indices)
glFlush()
thing = ClassThing()
thing.run()
正如我所说,这段代码让我看到的只是一个完全黑的屏幕。我感觉可能是我漏掉了某些初始化或开启的步骤,但我不知道还需要开启什么。
另外,听说glVertexPointer这个函数已经过时了,那我该怎么在不使用它的情况下运行glDrawElements呢?有没有类似于纹理生成的顶点生成方法?
2 个回答
0
你还需要提供纹理坐标,不然OpenGL就不知道怎么把纹理贴到你的四边形上。虽然你可以使用自动生成纹理坐标的方法,但在你的情况下,直接指定坐标会更简单。此外,你还需要设置视口和投影。
class ClassThing:
def __init__(self):
self.Splash = True
def TexFromPNG(self, filename):
img = Image.open(filename)
img_data = numpy.array(list(img.getdata()), numpy.uint8)
texture = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, texture)
# Texture parameters are part of the texture object, so you need to
# specify them only once for a given texture object.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
return texture
def run(self):
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(256,224)
self.window = glutCreateWindow("GL")
glutReshapeFunc(self.reshape)
glutDisplayFunc(self.draw)
self.MainTex = glGenTextures(1)
self.SplashTex = self.TexFromPNG("Resources/Splash.png")
glutMainLoop()
def reshape(self, width, height):
self.width = width
self.height = height
glutPostRedisplay();
def draw(self):
glViewport(0, 0, self.width, self.height)
glClearDepth(1) # just for completeness
glClearColor(0,0,0,0)
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, 1, 0, 1, -1, 1)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity()
if self.Splash:
glBindTexture(GL_TEXTURE_2D, self.SplashTex)
else:
glBindTexture(GL_TEXTURE_2D, self.MainTex)
# it's a good idea to enable state right before you need it
# there's no such thing like global state intialization in
# OpenGL
glEnable(GL_TEXTURE_2D)
# vertex arrays must be enabled using glEnableClientState
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
Varray = numpy.array([[0,0],[0,1],[1,1],[1,0]],numpy.float)
glVertexPointer(2,GL_FLOAT,0,Varray)
glTexCoordPointer(2,GL_FLOAT,0,Varray)
indices = [0,1,2,3]
glDrawElements(GL_QUADS,1,GL_UNSIGNED_SHORT,indices)
# This implies a glFinish, which includes a glFlush
glutSwapBuffers()
# GLUT initialization in program global, so initialize it on
# the process level. It might be
glutInit(sys.argv)
thing = ClassThing()
thing.run()
4
这可能是因为你调用了 glGenTextures(1)
两次吧?你在 TexFromPNG 里把它赋值给了 texture,然后又在 run 里把它赋值给了 self.MainTex。