(Python OpenGL)现在开始我们使用着色器来进行渲染。着色器是目前做3D图形最流行的方式。

OpenGL的渲染管线流程:

数据传输到OpenGL—>顶点处理器—>细分着色—>几何处理器—>图元装配—>裁剪器—>光栅器(片段处理器)

详细信息可以参考《OpenGL编程指南》 原书第8版  王锐译   中的P8 -P10

一些Shader的注意:

Shader着色器的使用跟C/C++程序的创建过程类似。

1、写一个shader着色器文本并使其在你的程序中有效可用

2、Shader着色器文本全为字符串类型          例如     S = “ coding部分” 代码部分为字符串

3、将字符串编译为Shader对象

4、使用GLSL编译器(编译器的语法见《OpenGL编程指南》 原书第8版  王锐译)

对于每一个着色器程序需要进行下面的步骤设置:

对于着色器对象:

1、创建Shader对象

2、编译

3、验证编译成功?

然后将上述的着色器对象链接为一个着色器程序:

1、创建程序

2、将Shader对象关联到着色器程序

3、链接程序

4、判断链接是否成功

5、使用着色器处理数据

 Shader程序:

 __author__ = "WSX"

 import numpy as np
from OpenGL.GLUT import *
from OpenGL.GL import *
import ctypes
#顶点着色器部分
VERTEX_SHADER = """
#version 330 layout (location = 0) in vec3 Position; void main()
{
gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
}
"""
#片段着色器部分,字符串类型
FRAGMENT_SHADER = """
#version 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
"""
def Create_Shader( ShaderProgram, Shader_Type , Source): #创建并且添加着色器(相当于AddShader)Shader_Type为类型
ShaderObj = glCreateShader( Shader_Type ) #创建Shader对象
glShaderSource(ShaderObj , Source)
glCompileShader(ShaderObj) #进行编译
glAttachShader(ShaderProgram, ShaderObj) #将着色器对象关联到程序上 def Compile_Shader(): #编译着色器
Shader_Program = glCreateProgram() #创建空的着色器程序
Create_Shader(Shader_Program , GL_VERTEX_SHADER , VERTEX_SHADER)
Create_Shader(Shader_Program , GL_FRAGMENT_SHADER , FRAGMENT_SHADER)
glLinkProgram(Shader_Program)
glUseProgram(Shader_Program) def Draw():
glClear(GL_COLOR_BUFFER_BIT)
glEnableVertexAttribArray(0)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) #这里的None不能写为0
glDrawArrays(GL_TRIANGLES, 0, 3)
glDisableVertexAttribArray(0) #解析数据 例如一个矩阵里含有 位置 、颜色、多种信息
glutSwapBuffers() def CreateBuffer(): #创建顶点缓存器
global VBO #设置为全局变量
vertex = np.array([[-1.0,-1.0,0.0],
[1.0,-1.0,0.0],
[0.0,1.0,0.0]],dtype="float32") #创建顶点数组
VBO = glGenBuffers(1) #创建缓存
glBindBuffer(GL_ARRAY_BUFFER , VBO) #绑定
glBufferData(GL_ARRAY_BUFFER , vertex.nbytes , vertex , GL_STATIC_DRAW) #输入数据 def main():
glutInit([])
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA) # 显示模式 双缓存
glutInitWindowPosition(100, 100) # 窗口位置
glutInitWindowSize(500, 500) # 窗口大小
glutCreateWindow("sanjiao") # 创建窗口
glutInitContextVersion(4,3) #为了兼容
glutInitContextProfile(GLUT_CORE_PROFILE) #为了兼容
glutDisplayFunc(Draw) # 回调函数
glClearColor(0.0, 0.0, 0.0, 0.0)
CreateBuffer()
Compile_Shader()
glutMainLoop() main()

结果:

关于着色器代码部分(字符串)的解释:

#version 330

这告诉编译器我们的目标是3.3版的GLSL。如果编译器不支持它,它会发出错误。

layout (location = 0) in vec3 Position;

该语句出现在顶点着色器中。它声明了一个顶点特定属性,它是3个浮点数的向量,在着色器中将被称为'位置'。“特定于顶点”表示对于GPU中每个对着色器的调用,将提供缓冲区中新顶点的值。

layout (location = 0)创建缓冲区中属性名称和属性之间的绑定。

您可以通过将多个着色器对象链接在一起来创建着色器。但是,每个着色器阶段(VS,GS,FS)只能有一个主要函数,用作着色器的入口点。例如,您可以创建一个具有多个函数的光照库,并将其与着色器链接,前提是这些函数中没有任何一个函数名为“main”。

gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);

这里我们对输入的顶点位置进行硬编码转换。我们将X和Y值减半,并保持Z不变。'gl_Position'是一个特殊的内置变量,它应该包含齐次(包含X,Y,Z和W分量)顶点位置。光栅化器将查找该变量并将其用作屏幕空间中的位置(在进行了几次转换之后)。将X和Y值减半意味着我们将看到一个三角形,它是前一教程中三角形大小的四分之一。请注意,我们将W设置为1.0。这对于正确显示三角形非常重要。从3D到2D的投影实际上分两个阶段完成。首先,您需要将所有顶点乘以投影矩阵(我们将在一些教程中开发),然后GPU在位置属性到达光栅化器之前自动执行所谓的“透视分割”。这意味着它将W组件的所有组件分割成W组件。在本教程中,我们尚未在顶点着色器中进行任何投影,但透视分割阶段是我们无法禁用的。无论我们从顶点着色器输出的gl_Position值是用HW分量还是HW分量。我们需要记住,否则我们不会得到我们期望的结果。为了规避视角分割的影响,我们将W设置为1.0。由1除。

如果一切工作正常,则具有值(-0.5,-0.5),(0.5,-0.5)和(0.0,0.5)的三个顶点到达光栅器。裁剪器不需要做任何事情,因为所有的顶点都在标准化的框内。这些值被映射到屏幕空间坐标,并且光栅化器开始运行三角形内的所有点。对于每个点,执行片段着色器。以下着色器代码是从片段着色器中获取的。

out vec4 FragColor;

通常片段着色器的工作是确定片段(像素)的颜色。此外,片段着色器可以完全丢弃像素或更改其Z值(这会影响后续Z测试的结果)。通过声明上述变量来输出颜色。四个分量表示R,G,B和A(对于alpha)。您设置到该变量中的值将由光栅化器接收并写入帧缓冲区。

FragColor = vec4(1.0, 0.0, 0.0, 1.0);

在之前的几个教程中,没有片段着色器,因此所有内容都以白色的默认颜色绘制。在这里,我们将FragColor设置为红色。

更多关于着色器部分的解释:http://ogldev.atspace.co.uk/www/tutorial04/tutorial04.html

(Python OpenGL)【3】着色器 PyOpenGL的更多相关文章

  1. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  2. OpenGL ES着色器语言之操作数(官方文档第五章)

    OpenGL ES着色器语言之操作数(官方文档第五章) 5.1操作数 OpenGL ES着色器语言包含如下操作符. 5.2数组下标 数组元素通过数组下标操作符([ ])进行访问.这是操作数组的唯一操作 ...

  3. OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)

    OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,unifo ...

  4. OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围

    OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)   所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符. ...

  5. OpenGL ES着色器语言之静态使用(static use)和预处理

    OpenGL ES着色器语言之静态使用(static use) 在OpenGL ES中有一个术语叫静态使用(static use),什么叫静态使用呢? 在写代码中,对于一个变量可能具有以下三种情况: ...

  6. OpenGL ES着色器语言之着色概览(官方文档)

    OpenGL ES着色器语言之着色概览(官方文档第二章) 事实上,OpenGL ES着色语言是两种紧密关联的语言.这些语言用来在OpenGL ES处理管线的可编程处理器创建着色器. 在本文档中,除非另 ...

  7. Android OpenGL ES 开发(八): OpenGL ES 着色器语言GLSL

    前面的文章主要是整理的Android 官方文档对OpenGL ES支持的介绍.通过之前的文章,我们基本上可以完成的基本的形状的绘制. 这是本人做的整理笔记: https://github.com/re ...

  8. openGL之着色器程序的使用

    #define GLEW_STATIC #include <GL\glew.h> #include <GLFW\glfw3.h> #include<iostream> ...

  9. OpenGL中着色器,渲染管线,光栅化

    https://www.zhihu.com/question/29163054   光栅(shan一声)化(Rasterize/rasteriztion).这个词儿Adobe官方翻译成栅格化或者像素化 ...

随机推荐

  1. python第二十三天-----Tornado

    Tornado是一个轻量级完整的web框架,在Linux系统下它会使用epoll,是一个异步非阻塞的web服务器框架,对于实时应用来说很理想,想想同是异步非阻塞的nginx的残暴程度就知道了 1.路由 ...

  2. 分布式代码管理github

    Git是世界上最先进的分布式版本的控制系统,特点是:简单大气上档次. Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了.

  3. 下拉列表---demo---bai

    select.jsp <%@ page language="java" import="java.util.*" pageEncoding="U ...

  4. SEO中常用HTML代码大全,及权重排序

    做SEO必须要懂HTML,说的是一点都没错,不过其实是不需要全部都懂,最重点的你懂了会用,基本上都是事半功倍了.可以这么说一个不懂代码的优化人员不算是一个合格的好优化.下面就总结一下做优化,必须要懂得 ...

  5. springmvc 在页面跳转之后 引入文件的路径前面加上了 controller 的映射名

    转自:https://zhidao.baidu.com/question/2140453086362943788.html 应该是没有前面的/user的 前端用的是jsp吗,如果是在路径前加${pag ...

  6. kvm iptables 3306端口

    # iptables -t nat -A PREROUTING -p TCP --dport 3306 -j DNAT --to-destination 192.168.122.102:3306# i ...

  7. python中的整数、浮点数和布尔值

    整数和浮点数有那个四则运算: 两种类型的数可以直接进行加减,当整数和浮点数进行加减的时候,结果会自动的变为浮点数,其中除法运算是“/”来表示的, 而余数的算术符号是“%”来表示的. 在布尔值的判断中我 ...

  8. Android远程服务(AIDL)实现步骤

    AIDL是安卓接口定义语言的缩写 由于笔者使用的是android studio所以建立AIDL文件的位置也需要注意,要在APPNAME->main->aidl->packagenam ...

  9. Android中无标题样式和全屏样式学习

    在进行UI设计时,我们经常需要将屏幕设置成无标题栏或者全屏.要实现起来也非常简单,主要有两种方法:配置xml文件和编写代码设置. 1.在xml文件中进行配置 在项目的清单文件AndroidManife ...

  10. Ajax02 什么是json、json语法、json的使用、利用jQuery实现ajax

    目录 1什么是json 2json语法 3json的使用 4利用jQuery实现ajax编程 1 什么是json JavaScript Object Notation(JavaScript 对象表示法 ...