PyOpenGL:渲染……嗯……任何东西都可以
我已经在一个使用 python 和 OpenGL 的项目上工作了一段时间了。我之前发布过类似的问题,但后来我做了更多研究并切换到了未弃用的函数。按照本教程(翻译显然是Python版本)我最终得到了这段代码:
import sys
import OpenGL
from OpenGL.GL import *
from OpenGL.GL.shaders import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GLUT.freeglut import *
from OpenGL.arrays import vbo
import pygame
import Image
import numpy
class AClass:
def __init__(self):
self.Splash = True #There's actually more here, but it's impertinent
def TexFromPNG(self, filename):
img = Image.open(filename) # .jpg, .bmp, etc. also work
img_data = numpy.array(list(img.getdata()), 'B')
texture = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
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_RGBA, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
return texture
def MakeBuffer(self, target, data, size):
TempBuffer = glGenBuffers(1)
glBindBuffer(target, TempBuffer)
glBufferData(target, size, data, GL_STATIC_DRAW)
return TempBuffer
def ReadFile(self, filename):
tempfile = open(filename,'r')
source = tempfile.read()
temprfile.close()
return source
def run(self):
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(256,244)
self.window = glutCreateWindow("test")
glutReshapeFunc(self.reshape)
glutDisplayFunc(self.draw)
glutKeyboardFunc(self.keypress)
self.MainTex = glGenTextures(1)
self.SplashTex = self.TexFromPNG("Resources/Splash.png")
MainVertexData = numpy.array([-1,-1,1,-1,-1,1,1,1],numpy.float32)
FullWindowVertices = numpy.array([0,1,2,3],numpy.ushort)
self.MainVertexData = self.MakeBuffer(GL_ARRAY_BUFFER,MainVertexData,len(MainVertexData))
self.FullWindowVertices = self.MakeBuffer(GL_ELEMENT_ARRAY_BUFFER,FullWindowVertices,len(FullWindowVertices))
self.BaseProgram = compileProgram(compileShader(self.ReadFile("Shaders/Mainv.glsl"),
GL_VERTEX_SHADER),
compileShader(self.ReadFile("Shaders/Mainf.glsl"),
GL_FRAGMENT_SHADER))
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)
glClearColor(0,0,0,0)
glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
if self.Splash:
glUseProgram(self.BaseProgram)
pos = glGetAttribLocation(self.BaseProgram, "position")
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.SplashTex)
glUniform1i(glGetUniformLocation(self.BaseProgram,"texture"), 0)
glBindBuffer(GL_ARRAY_BUFFER,self.MainVertexData)
glVertexAttribPointer(pos,
2,
GL_FLOAT,
GL_FALSE,
0,
numpy.array([0],numpy.uint8))
glEnableVertexAttribArray(pos)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,self.FullWindowVertices)
glDrawElements(GL_TRIANGLE_STRIP,
4,
GL_UNSIGNED_SHORT,
numpy.array([0],numpy.uint8))
glDisableVertexAttribArray(pos)
else:
glBindTexture(GL_TEXTURE_2D, self.MainTex)
glutSwapBuffers()
glutInit(sys.argv)
test = AClass()
test.run()
Shaders/Mainv.glsl和Shaders/Mainf.glsl分别包含:
#version 110
attribute vec2 position;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
和:
#version 110
uniform sampler2D texture;
varying vec2 texcoord;
void main()
{
gl_FragColor = texture2D(texture, texcoord);
}
。
这段代码为我提供了一个(清晰的颜色)GLUT 窗口,这似乎表明它由于某种原因没有渲染我的三角形,但我不知道为什么会这样,而且我真的找不到任何 PyOpenGL 的示例不使用已弃用的函数,所以我看不到他们是否做了与我不同的事情,而我错过了。
I've been working on a project using python with OpenGL for a while now. I previously posted a similar problem, but I have since done some more research and switched to non-deprecated functions. Following this tutorial (Translating it to Python versions obviously) I end up with this code:
import sys
import OpenGL
from OpenGL.GL import *
from OpenGL.GL.shaders import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGL.GLUT.freeglut import *
from OpenGL.arrays import vbo
import pygame
import Image
import numpy
class AClass:
def __init__(self):
self.Splash = True #There's actually more here, but it's impertinent
def TexFromPNG(self, filename):
img = Image.open(filename) # .jpg, .bmp, etc. also work
img_data = numpy.array(list(img.getdata()), 'B')
texture = glGenTextures(1)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
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_RGBA, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
return texture
def MakeBuffer(self, target, data, size):
TempBuffer = glGenBuffers(1)
glBindBuffer(target, TempBuffer)
glBufferData(target, size, data, GL_STATIC_DRAW)
return TempBuffer
def ReadFile(self, filename):
tempfile = open(filename,'r')
source = tempfile.read()
temprfile.close()
return source
def run(self):
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(256,244)
self.window = glutCreateWindow("test")
glutReshapeFunc(self.reshape)
glutDisplayFunc(self.draw)
glutKeyboardFunc(self.keypress)
self.MainTex = glGenTextures(1)
self.SplashTex = self.TexFromPNG("Resources/Splash.png")
MainVertexData = numpy.array([-1,-1,1,-1,-1,1,1,1],numpy.float32)
FullWindowVertices = numpy.array([0,1,2,3],numpy.ushort)
self.MainVertexData = self.MakeBuffer(GL_ARRAY_BUFFER,MainVertexData,len(MainVertexData))
self.FullWindowVertices = self.MakeBuffer(GL_ELEMENT_ARRAY_BUFFER,FullWindowVertices,len(FullWindowVertices))
self.BaseProgram = compileProgram(compileShader(self.ReadFile("Shaders/Mainv.glsl"),
GL_VERTEX_SHADER),
compileShader(self.ReadFile("Shaders/Mainf.glsl"),
GL_FRAGMENT_SHADER))
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)
glClearColor(0,0,0,0)
glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
if self.Splash:
glUseProgram(self.BaseProgram)
pos = glGetAttribLocation(self.BaseProgram, "position")
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.SplashTex)
glUniform1i(glGetUniformLocation(self.BaseProgram,"texture"), 0)
glBindBuffer(GL_ARRAY_BUFFER,self.MainVertexData)
glVertexAttribPointer(pos,
2,
GL_FLOAT,
GL_FALSE,
0,
numpy.array([0],numpy.uint8))
glEnableVertexAttribArray(pos)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,self.FullWindowVertices)
glDrawElements(GL_TRIANGLE_STRIP,
4,
GL_UNSIGNED_SHORT,
numpy.array([0],numpy.uint8))
glDisableVertexAttribArray(pos)
else:
glBindTexture(GL_TEXTURE_2D, self.MainTex)
glutSwapBuffers()
glutInit(sys.argv)
test = AClass()
test.run()
Shaders/Mainv.glsl and Shaders/Mainf.glsl contain:
#version 110
attribute vec2 position;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
texcoord = position * vec2(0.5) + vec2(0.5);
}
and:
#version 110
uniform sampler2D texture;
varying vec2 texcoord;
void main()
{
gl_FragColor = texture2D(texture, texcoord);
}
respectively.
This code nets me with a (clear color) GLUT window, which seems to suggest that it's not rendering my triangles for some reason, but I have no idea why that could be, and I can't really find any examples for PyOpenGL that don't use deprecated functions, so I can't see if they did anything different from me that I'm missing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这对于任何开始使用 PyOpenGL 和可编程管道的人来说都是一个有用的参考,因此我根据上面 Bethor 和 Josiah 的评论更正了代码,并且还对其进行了一些简化(将着色器嵌入为字符串)。这段代码对我有用。它假设您在同一目录中有 test.png。
这是输出:
I think this is a useful reference for anyone starting out with PyOpenGL and the programmable pipleline, so I've corrected the code according to comments by Bethor and Josiah above, and have also simplified it a bit (embedded the shaders as strings). This code works for me. It assumes that you have test.png in the same directory.
Here is the output:
在修复以下问题后,我设法让您的代码正常工作:
我的测试图像之后显示,尽管颜色是乱码。我没有尝试调试它,因为您用于解码 png 文件的选项可能特定于您的数据:)
I managed to get your code working after fixing the following things:
My test image displayed after that, although colors were garbled. I did not attempt to debug that as the options you use to decode your png file might be specific to your data :)