使用Opengl绘制两个三角形-Python注释版

环境搭建可参考https://www.jianshu.com/p/9527c0435e9c------之前在anaconda下搭建环境一直报错,后来使用pycharm并将解释器路径设置到anaconda下就好了

代码来源于https://www.jianshu.com/p/f1d326bce955

阅读了C++板的《OpenGL编程指南(原书第9版).pdf》后,根据理解写了一些代码注释,有错误请指正,谢谢


"""
glfw_Triangle02.py
Author: dalong10
Description: Draw a Triagle, 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

'''做渲染的话,现代OpenGL需要我们至少设置一个顶点和一个片段着色器'''
#Vertex Shader顶点着色器,数据流入顶点着色器,将输入的顶点位置复制到顶点着色器的输出位置gl_Position
#vec4(position.x, position.y, position.z, 1.0);------XYZW,坐标及缩放比例
strVS = """
#version 330 core
layout(location = 0) in vec3 position;
void main(){
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
    }
"""
#Fragment Shader片段着色器,片段着色器会输出color数据
#vec4(1.0, 0.0, 0.0, 1.0);------RGBA红绿蓝及透明度
strFS1 = """
#version 330 core
out vec4 color;
void main(){
    color = vec4(1.0, 0.0, 0.0, 1.0);
    }
"""

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

class FirstTriangle:
    def __init__(self, side1, side2, side3):
        self.side1 = side1
        self.side2 = side2
        self.side3 = side3

        # load shaders
        if side3>0:
            strFS=strFS1
        else:
            strFS=strFS2
        #读取链接顶点着色器和片元着色器的源程序字串的函数,为着色器进入GPU的操作专门实现的函数
        self.program = glutils.loadShaders(strVS, strFS)
        glUseProgram(self.program)

        s1 = side1/1.0
        s2 = side2/1.0
        s3 = side3/1.0
        #三角形的三个点
        vertices = [
             s1, -0.5, 0,#xyzz
             s2, -0.5, 0,#xyzz
             s3, 0.5, 0  #xyzz
             ]
        '''着色管线装配:将应用程序的数据和着色器程序的变量关联起来'''
        # set up vertex array object (VAO)建立1个顶点数组对象,并将对象名返回,类似CC语言的指针变量
        self.vao = glGenVertexArrays(1)
        #绑定一个顶点数组对象,opengl内部会将其作为当前对象,后面的所有操作都作用于这个对象
        glBindVertexArray(self.vao)
        # set up VBOs
        vertexData = numpy.array(vertices, numpy.float32)
        #创建1个顶点缓存对象,并将对象名称返回 与顶点对象类似。缓存对象就是opengl服务端分配和管理的一块内存区域
        self.vertexBuffer = glGenBuffers(1)
        #绑定到opengl环境中,opengl有多种类型,因此绑定时需要指定缓存对象的类型GL_ARRAY_BUFFER
        glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)
        #分配缓存对象空间,大小为4*len(vertexData)字节,并将vertexData数据拷贝到opengl的缓存中
        glBufferData(GL_ARRAY_BUFFER, 4*len(vertexData), vertexData,
                     GL_STATIC_DRAW)
        '''着色管线装配:将应用程序与着色器之间,以及不同着色阶段之间的数据通道连接起来'''
        #enable arrays启用索引为0的顶点属性数组
        self.vertIndex = 0
        glEnableVertexAttribArray(self.vertIndex)
        # set buffers
        glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)
        #0:设置顶点着色器中变量position对应的值 3:每个顶点有xyz3个值
        # GL_FLOAT:每个元素的数据类型 GL_FALSE:不需要进行归一化
        #0:每两个数据之间的偏移量为0
        #将着色器中的变量position与vertexBuffer关联起来
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
        # unbind VAO opengl不在使用之前绑定的顶点数组
        glBindVertexArray(0)
    '''执行渲染工作'''
    def render(self):
        # 指定program作为opengl的当前着色器程序
        glUseProgram(self.program)
        # bind VAO指定vao作为opengl的当前顶点对象
        glBindVertexArray(self.vao)
        # draw
        glDrawArrays(GL_TRIANGLES, 0, 3)
        # 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初始化GLFW库
    if not glfw.init():
        sys.exit()

    # Create a windowed mode window and its OpenGL context设置程序所使用的窗口类型及窗口大小,也可以先查询显示器的尺寸再设置
    window = glfw.create_window(640, 480, "glfw_Triangle02", None, None)
    if not window:
        glfw.terminate()
        sys.exit()

    # Make the window's context current把创建的window窗口作为OPENGL显示的窗口
    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,0.0,0.0)
        firstTriangle0 = FirstTriangle(-0.9,-0.0,-0.45)
        firstTriangle1 = FirstTriangle(0,0.9,0.45)
        # render
        firstTriangle0.render()
        firstTriangle1.render()

        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

    glfw.terminate()

 

你可能感兴趣的:(OpenGl)