今天涉及硬核的 shader编写,具体请参阅:
- OpenGL 渲染流水线
- GLSL语法格式
Shader
稍微接触点游戏编程 / 渲染的估计都知道它的大名
- OpenGL Shader Language
- GLSL
- 是 OpenGL专用的 shader语言
- 顶点着色器 vertex shader
- 片元着色器 fragment shader
import 中添加两个库
import (
"strings"
"fmt"
)
添加编译着色器的函数
- 直接复制来的,大多在进行错误处理…
- 返回的还是 Opengl对该 shader的一个编号(uint32)
func compileShader(source string, shaderType uint32) (uint32, error) {
shader := gl.CreateShader(shaderType)
csources, free := gl.Strs(source)
gl.ShaderSource(shader, 1, csources, nil)
free()
gl.CompileShader(shader)
var status int32
gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
if status == gl.FALSE {
var logLength int32
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
log := strings.Repeat("\x00", int(logLength+1))
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
return 0, fmt.Errorf("failed to compile %v: %v", source, log)
}
return shader, nil
}
在const ( width height)下添加 shader源码
-
唯一比较特殊的地方是它们都要在末尾加上一个空终止字符,\x00 —— OpenGL 需要它才能编译着色器。
- 注意两个 shader开头的 version
- vshader 简单地将原三维坐标升维
-
- 后面的 1.0 是缩放比/归一值,相当于将坐标除以该值.
- fshader 输出黑色 RGBA:(1, 1, 1, 1)
const vertexShaderSource = `
#version 410
in vec3 vp;
void main() {
gl_Position = vec4(vp, 1.0);
}
` + "\x00"
const fragmentShaderSource = `
#version 410
out vec4 frag_colour;
void main() {
frag_colour = vec4(1, 1, 1, 1);
}
` + "\x00"
修改 initOpenGL
- 编译 shader
- 将两个 shader与 program链接
func initOpenGL() uint32 {
if err := gl.Init(); err != nil {
panic(err)
}
version := gl.GoStr(gl.GetString(gl.VERSION))
log.Println("OpenGL version", version)
// 修改了后半部
vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER)
if err != nil {
panic(err)
}
fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
if err != nil {
panic(err)
}
prog := gl.CreateProgram()
gl.AttachShader(prog, vertexShader)
gl.AttachShader(prog, fragmentShader)
gl.LinkProgram(prog)
return prog
}
Go!
go (run)
- 不出意外还是之前那个黑底白色的三角形
- 不过使用的是自定义的 shader (vshader $ fshader)
改变一下效果
const vertexShaderSource = `
#version 410
in vec3 vp;
void main() {
gl_Position = vec4(vp- vec3(0.25, 0.25, 0),
1.0);
}
` + "\x00"
const fragmentShaderSource = `
#version 410
out vec4 frag_colour;
void main() {
frag_colour = vec4(0.66, 0.22, 0.22, 1);
}
` + "\x00"
Go!
简单地向左下平移了 0.25个单位
修改了一下三角形的颜色 (大约是 #A83838)
- 这只是一个开始…
To be continued…