Python之OpenGL笔记(6):使用EBO绘制矩形

一、目的

1、使用EBO绘制两个三角形,组成矩形图形。

二、程序运行结果

Python之OpenGL笔记(6):使用EBO绘制矩形_第1张图片

三、索引缓冲对象(Element Buffer Object,EBO)

  索引缓冲对象EBO相当于OpenGL中的顶点数组的概念,是为了解决同一个顶点多次重复调用的问题,可以减少内存空间浪费,提高执行效率。当需要使用重复的顶点时,通过顶点的位置索引来调用顶点,而不是对重复的顶点信息重复记录,重复调用。
  EBO中存储的内容就是顶点位置的索引indices,EBO跟VBO类似,也是在显存中的一块内存缓冲器,只不过EBO保存的是顶点的索引。

四、EBO的创建并绑定

  创建EBO并绑定,用glBufferData(以GL_ELEMENT_ARRAY_BUFFER为参数)把索引存储到EBO中:

       vertexData = numpy.array(vertices, numpy.float32)
        self.vboID = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER,self.vboID)
        glBufferData(GL_ARRAY_BUFFER, 4 *len(vertexData), vertexData, GL_STATIC_DRAW)

五、绘制模型

  当用EBO绑定顶点索引的方式绘制模型时,需要使用glDrawElements而不是glDrawArrays:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
第一个参数指定了要绘制的模式;
第二个参数指定要绘制的顶点个数;
第三个参数是索引的数据类型;
第四个参数是可选的EBO中偏移量设定。
在Python中语句是glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

六、源代码

"""
glfw_Triangle04.py
Author: dalong10
Description: use EBO and Draw a TRIANGLE_FAN, learning OPENGL 
"""
import glutils    #Common OpenGL utilities,see glutils.py
import sys, random, math
import OpenGL
from OpenGL.GL import *
from OpenGL.GL.shaders import *
import numpy 
import numpy as np
import glfw

strVS = """
#version 330 core
layout(location = 0) in vec3 position;
void main(){
	gl_Position = vec4(position.x, position.y, position.z, 1.0);
	}
"""

strFS = """
#version 330 core
out vec4 color;
void main(){
	color = vec4(1.0, 0.0, 0.0, 1.0);
	}
"""

class FourthTriangle:
    def __init__(self, side):
        self.side = side

        # load shaders
        self.program = glutils.loadShaders(strVS, strFS)
        glUseProgram(self.program)
        
        vertices = [
             #// Positions          
             0.5, 0.5, 0,  1.0,      #// Top Right
             0.5, -0.5, 0, 0.0,   #// Bottom Right
             -0.5, -0.5, 0, 0.0,    #// Bottom Left
             -0.5, 0.5, 0, 1.0     #// Top Left 
             ]
      
        indices =  [
             0,1,3,
             1,2,3
             ]                 
        # set up vertex array object (VAO)
        self.vao = glGenVertexArrays(1)     
        glBindVertexArray(self.vao)
        
        # set up VBOs
        vertexData = numpy.array(vertices, numpy.float32)
        self.vboID = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER,self.vboID)
        glBufferData(GL_ARRAY_BUFFER, 4 *len(vertexData), vertexData, GL_STATIC_DRAW)
        
        # set up EBOs
        indiceData = numpy.array(indices, numpy.int32)
        self.eboID = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,self.eboID)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 *len(indiceData), indiceData, GL_STATIC_DRAW)
        
        # Position attribute
        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0,None)
        glEnableVertexAttribArray(0)

        # unbind VAO
        glBindVertexArray(0)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)    

    def render(self):
        # use shader
        glUseProgram(self.program)       
        offset = 0.5
        glUniform1f(glGetUniformLocation(self.program, "xOffset"), offset);
        # bind VAO
        glBindVertexArray(self.vao)
        # draw
        #glDrawArrays(GL_TRIANGLE_FAN, 0, 4)
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
        # unbind VAO
        glBindVertexArray(0)

if __name__ == '__main__':
    import sys
    import glfw
    import OpenGL.GL as gl
    def on_key(window, key, scancode, action, mods):
        if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
            glfw.set_window_should_close(window,1)

    # Initialize the library
    if not glfw.init():
        sys.exit()

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(640, 480, "glfw_Triangle04", None, None)
    if not window:
        glfw.terminate()
        sys.exit()

    # Make the window's context current
    glfw.make_context_current(window)

    # Install a key handler
    glfw.set_key_callback(window, on_key)

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here
        width, height = glfw.get_framebuffer_size(window)
        ratio = width / float(height)
        gl.glViewport(0, 0, width, height)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)
        gl.glClearColor(0.0,0.0,4.0,0.0)
        firstTriangle0 = FourthTriangle(1.0)
        # render
        firstTriangle0.render()
        # Swap front and back buffers
        glfw.swap_buffers(window)
        # Poll for and process events
        glfw.poll_events()

    glfw.terminate()

你可能感兴趣的:(OpenGL)