我是opengl的新手,我已经写了一个简单的程序,用opengl中的VBO画一个三角形。我看到窗口出现了,但我没有看到任何三角形在屏幕上。我也没有看到任何错误。有人能帮助确定我到底哪里出错了吗?
开放式语言版本:3.1.0
Code:
import numpy as np
from OpenGL import GL, GLU, GLUT
from OpenGL.arrays import ArrayDatatype
import sys
vertex = """
# version 130
in vec3 vin_position;
in vec3 vin_color;
out vec3 vout_color;
void main(void)
{
vout_color = vin_color;
gl_Position = vec4(vin_position, 1.0);
}
"""
fragment = """
# version 130
in vec3 vout_color;
out vec4 fout_color;
void main(void)
{
fout_color = vec4(vout_color, 1.0);
}
"""
vertex_data = np.array([0.75, 0.75, 0.0,
0.75, -0.75, 0.0,
-0.75, -0.75, 0.0],
dtype=np.float64)
color_data = np.array([1, 0, 0,
0 ,1, 0,
0, 0, 1],
dtype=np.float64)
ESCAPE = '\033'
class ShaderProgram(object):
""" Helper class for using GLSL shader programs
"""
def __init__(self, vertex, fragment):
"""
Parameters
----------
vertex : str
String containing shader source code for the vertex
shader
fragment : str
String containing shader source code for the fragment
shader
"""
self.program_id = GL.glCreateProgram()
vs_id = self.add_shader(vertex, GL.GL_VERTEX_SHADER)
frag_id = self.add_shader(fragment, GL.GL_FRAGMENT_SHADER)
GL.glAttachShader(self.program_id, vs_id)
GL.glAttachShader(self.program_id, frag_id)
GL.glLinkProgram(self.program_id)
if (GL.glGetProgramiv(self.program_id, GL.GL_LINK_STATUS) !=
GL.GL_TRUE):
info = GL.glGetProgramInfoLog(self.program_id)
GL.glDeleteProgram(self.program_id)
GL.glDeleteShader(vs_id)
GL.glDeleteShader(frag_id)
raise RuntimeError('Error linking program: %s' % (info))
GL.glDeleteShader(vs_id)
GL.glDeleteShader(frag_id)
def add_shader(self, source, shader_type):
""" Helper function for compiling a GLSL shader
Parameters
----------
source : str
String containing shader source code
shader_type : valid OpenGL shader type
Type of shader to compile
Returns
-------
value : int
Identifier for shader if compilation is successful
"""
try:
shader_id = GL.glCreateShader(shader_type)
GL.glShaderSource(shader_id, source)
GL.glCompileShader(shader_id)
if GL.glGetShaderiv(shader_id, GL.GL_COMPILE_STATUS) != GL.GL_TRUE:
info = GL.glGetShaderInfoLog(shader_id)
raise RuntimeError('Shader compilation failed: %s' % (info))
return shader_id
except:
GL.glDeleteShader(shader_id)
raise
def uniform_location(self, name):
""" Helper function to get location of an OpenGL uniform variable
Parameters
----------
name : str
Name of the variable for which location is to be returned
Returns
-------
value : int
Integer describing location
"""
return GL.glGetUniformLocation(self.program_id, name)
def attribute_location(self, name):
""" Helper function to get location of an OpenGL attribute variable
Parameters
----------
name : str
Name of the variable for which location is to be returned
Returns
-------
value : int
Integer describing location
"""
return GL.glGetAttribLocation(self.program_id, name)
class Triangle(object):
def __init__(self, window):
self.glut_window = window
self.program = None
self.vao_id = None
self.vbo_id = None
def init(self):
GL.glClearColor(0.95, 1.0, 0.95, 0)
self.program = ShaderProgram(fragment=fragment, vertex=vertex)
self.vao_id = GL.glGenVertexArrays(1)
GL.glBindVertexArray(self.vao_id)
print self.vao_id
self.vbo_id = GL.glGenBuffers(2)
print self.vbo_id
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo_id[0])
GL.glBufferData(GL.GL_ARRAY_BUFFER,
ArrayDatatype.arrayByteCount(vertex_data),
vertex_data,
GL.GL_STATIC_DRAW)
GL.glVertexAttribPointer(self.program.attribute_location('vin_position'),
3, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
GL.glEnableVertexAttribArray(0)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo_id[1])
GL.glBufferData(GL.GL_ARRAY_BUFFER,
ArrayDatatype.arrayByteCount(color_data),
color_data,
GL.GL_STATIC_DRAW)
GL.glVertexAttribPointer(self.program.attribute_location('vin_color'),
3, GL.GL_FLOAT,
GL.GL_FALSE, 0, None)
GL.glEnableVertexAttribArray(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
GL.glBindVertexArray(0)
def display(self):
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
GL.glUseProgram(self.program.program_id)
GL.glBindVertexArray(self.vao_id)
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
GL.glUseProgram(0)
GL.glBindVertexArray(0)
GLUT.glutSwapBuffers()
def resize(self, width, height):
if not height:
height = 1
# Reset the view port and
GL.glViewport(0, 0, width, height)
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GLU.gluPerspective(45.0, float(width)/float(height), 0.1, 100.0)
GL.glMatrixMode(GL.GL_MODELVIEW)
def keyboard_activity(self, *args):
if args[0] == ESCAPE:
GLUT.glutDestroyWindow(self.glut_window)
sys.exit()
if __name__ =='__main__':
# GLUT init
GLUT.glutInit()
GLUT.glutInitDisplayMode(GLUT.GLUT_DOUBLE | GLUT.GLUT_RGBA)
GLUT.glutInitWindowSize(640, 480)
win = GLUT.glutCreateWindow('Triangle using VBO')
GLUT.glutFullScreen()
triangle_obj = Triangle(win)
GLUT.glutDisplayFunc(triangle_obj.display)
GLUT.glutIdleFunc(triangle_obj.display)
GLUT.glutReshapeFunc(triangle_obj.resize)
GLUT.glutKeyboardFunc(triangle_obj.keyboard_activity)
triangle_obj.init()
GLUT.glutMainLoop()
1条答案
按热度按时间7cwmlq891#
GL_FLOAT
向GL指示您在VBO中提供的是单精度浮点数,但传递的是双精度浮点数(float64
).GL_DOUBLE
确实是一种有效的类型,但是双精度浮点通常对于存储顶点数据来说有些多余,并且可能会带来相当大的性能代价,因此我建议将VBO数据转换为单精度浮点数,使其与现有的属性配置保持一致,这在其他方面似乎是正确的。