我写文章做教程看博客找慕课什么的都喜欢短而多的,基本一篇就一两个知识点
代码详解(只是打上些注释)
库和常量
- gl_4.1 的版本只是用于实验室的老显卡 ( Opengl 4.0.0 )
package main
import (
"log"
"runtime"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/go-gl/glfw/v3.3/glfw"
)
const (
width = 800
height = 600
)
main函数
-
这里我们使用了 runtime 包的 LockOSThread(),这能确保我们总是在操作系统的同一个线程中运行代码,这对 GLFW 来说很重要,GLFW 需要在其被初始化之后的线程里被调用。
- 获得 glfw生成的窗口, 并推迟关闭 defer
- 从 Opengl获取一个 program
- for监听 window的关闭事件,不断调用 draw函数,draw 使用 program在 window上画图
func main() {
runtime.LockOSThread()
window := initGlfw()
defer glfw.Terminate()
program := initOpenGL()
for !window.ShouldClose() {
draw(window, program)
}
}
initGLFW 初始化gl运行环境
- 返回一个窗口
- 分别传递参数 WindowHint
- 不可缩放
- OpenGL版本号 - 主版本 & 小数点后副版本
- 其他
- 最后是将窗口绑定在线程上
func initGlfw() *glfw.Window {
if err := glfw.Init(); err != nil {
panic(err)
}
glfw.WindowHint(glfw.Resizable, glfw.False)
glfw.WindowHint(glfw.ContextVersionMajor, 4) // OR 2
glfw.WindowHint(glfw.ContextVersionMinor, 0)
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
window, err := glfw.CreateWindow(width, height, "Conway's Game of Life", nil, nil)
if err != nil {
panic(err)
}
window.MakeContextCurrent()
return window
}
initOpenGL
- get到 gl的版本信息,log打印
- 创建、链接、返回一个 program
// initOpenGL 初始化 OpenGL 并且返回一个初始化了的程序。
func initOpenGL() uint32 {
if err := gl.Init(); err != nil {
panic(err)
}
version := gl.GoStr(gl.GetString(gl.VERSION))
log.Println("OpenGL version", version)
prog := gl.CreateProgram()
gl.LinkProgram(prog)
return prog
}
draw 使用 program在 window上画图
- 设置 clear的属性:color buffer 和 depth buffer 同时清除
- 通知 OpenGL使用程序 (并没有x)
- glfw 看作一个回调函数,处理 Windows的事件池 / 鼠标键盘等响应事件
- swap buffers将 OpenGL的双缓冲的两帧交换 (双缓冲是 OpenGL的重要概念)
func draw(window *glfw.Window, program uint32) {
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.UseProgram(program)
glfw.PollEvents()
window.SwapBuffers()
}
之后的画图操作大多添加到 draw函数中
To be continued…