PyOpenGL编程-02.三色三角形绘制

“本系列教程主要讲解利用Python和OpenGL开发三维图形程序。这里主要用到的工具库是glfw开源图形库。本系列内容较难。要求学生对几何和编程有一定的了解。建议初三以上同学学习。”


>>三维图形生成原理

三维图形每个顶点都具有X,Y,Z三个数值的三维空间坐标,要把这些空间顶点投影到屏幕上。投影到屏幕上就形成了只有(X,Y)二维屏幕坐标。

每三个空间顶点构成一个平面三角形,这个三角形就是组成复杂几何图形的基础。不管是简单的几何图形,还是复杂的人物花草,都是由N个三角形组成的。

>>OpenGL渲染架构

OpenGL渲染架构

OpenGL现在已经发展到4.6版本了,从1.2版本起,就由最初的管道渲染模型升级为着色器渲染模式。渲染着色器主要由顶点着色器(Vertex)和片元着色器(Fragment)组成,一个负责顶点计算,一个负责颜色的填充。

现在的OpenGL着色器,已经增加了细分着色器、几何着色器等在不同渲染阶段工作的着色器了。功能更强大。要使用这些着色器,我们就要使用GLSL语言。这是一种专门为着色器设计的类C语言。它专门跟GPU打交道。顶点着色器的GLSL用VS作后缀名,片元着器用FS作后缀名。

>>三色三角形的着色文件

顶点着色文件(triangle.vs)

#version 330

layout (location = 0) in vec2 in_Pos;
layout (location = 1) in vec3 in_Color;

out vec3 out_Color;

void main()
{
     gl_Position = vec4(in_Pos.x, in_Pos.y, 0, 1.0);
     out_Color = in_Color;
}

片元着色文件(triangle.fx)

#version 330

out vec4 FragColor;
in vec3  out_Color;

void main()
{
     FragColor = vec4(out_Color,1);
}

主程序(main.py)

import glfw
import numpy as np
from OpenGL.GLUT import *
from OpenGL.GL import *

#获取文件内容
def get_file(fname):
    tmp = open(fname,"r")
    ret = tmp.read()
    tmp.close()
    return ret
    
#=======================================
#创建着色器
def Create_Shader( ShaderProgram, Shader_Type , Source):
    #创建并且添加着色器
    ShaderObj = glCreateShader( Shader_Type )  #创建Shader对象
    glShaderSource(ShaderObj , Source)
    glCompileShader(ShaderObj)  #进行编译
    glAttachShader(ShaderProgram, ShaderObj)  #将着色器对象关联到程序上

#=======================================
#编译着色器
def Compile_Shader():  
    vs_file = get_file("triangle.vs")
    fs_file = get_file("triangle.fs")
    
    Shader_Program = glCreateProgram()  #创建空的着色器程序
    Create_Shader(Shader_Program , GL_VERTEX_SHADER , vs_file)
    Create_Shader(Shader_Program , GL_FRAGMENT_SHADER , fs_file)
    glLinkProgram(Shader_Program)
    glUseProgram(Shader_Program)

#=======================================
def CreateBuffer():  #创建顶点缓存器

    global VBO   #设置为全局变量
    
    #创建顶点数组
    vertex = np.array([[-1.0,-1.0],
                       [1.0,-1.0],
                       [0.0,1.0],],dtype="float32")
    #创建顶点颜色                   
    color = np.array([[1,0,0],
                      [0,1,0],
                      [0,0,1],],dtype="float32")
       

    #创建缓存
    VBO = glGenBuffers(2)  
    
    #绑定缓冲区
    glBindBuffer(GL_ARRAY_BUFFER , VBO[0])
    #输入数据
    glBufferData(GL_ARRAY_BUFFER , vertex.nbytes , vertex , GL_STATIC_DRAW)   
    
    #绑定缓冲区
    glBindBuffer(GL_ARRAY_BUFFER , VBO[1])
    #输入数据
    glBufferData(GL_ARRAY_BUFFER , color.nbytes , color , GL_STATIC_DRAW)   
  
    

#=======================================
if __name__ == '__main__':

    # 初始化GLFW
    glfw.init()        
        
    # 创建窗口
    window = glfw.create_window(640, 480, "三角三角形", None, None)
    
    if not window:
        glfw.terminate()
        

    #生成窗口上下文设备
    glfw.make_context_current(window)
    
    CreateBuffer()
    Compile_Shader()
    

    # 窗口事件循环
    while not glfw.window_should_close(window):
    
        glClear(GL_COLOR_BUFFER_BIT)
        glClearColor(0,0,0,1)
        
        #绑定顶点缓冲区
        glBindBuffer(GL_ARRAY_BUFFER, VBO[0])        
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None) #这里的None不能写为0
        glEnableVertexAttribArray(0)
        
        #绑定颜色缓冲区
        glBindBuffer(GL_ARRAY_BUFFER, VBO[1])
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None) #这里的None不能写为0
        glEnableVertexAttribArray(1)
        
        #绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3)
        
        #恢复禁止通道
        glDisableVertexAttribArray(0)  
        glDisableVertexAttribArray(1)  

        # 交换缓冲区,提交渲染内容
        glfw.swap_buffers(window)

        # 窗口事件轮询
        glfw.poll_events()

    glfw.terminate()
运行结果

PyOpenGL编程-02.三色三角形绘制
滚动到顶部