Python开放式语言:无法在使用Python的opengl中使用VBO绘制三角形

nlejzf6q  于 2022-11-04  发布在  Python
关注(0)|答案(1)|浏览(163)

我是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()
7cwmlq89

7cwmlq891#

GL_FLOAT向GL指示您在VBO中提供的是单精度浮点数,但传递的是双精度浮点数(float64). GL_DOUBLE确实是一种有效的类型,但是双精度浮点通常对于存储顶点数据来说有些多余,并且可能会带来相当大的性能代价,因此我建议将VBO数据转换为单精度浮点数,使其与现有的属性配置保持一致,这在其他方面似乎是正确的。

相关问题