Loading main.go +3 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ import ( "repositories.muehmer.net/bsmrgo/saola/support/scene" si "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/icosahedron" //si "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/icosahedron" sd "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/gldemo" ) func init() { Loading @@ -31,6 +32,6 @@ func main() { ContextVersionMinor: 3, CenterOnPrimaryMonitor: true, } hooks := si.Hooks() hooks := sd.Hooks() scene.Manage(setup, hooks) } scenes/gldemo/gldemo.go 0 → 100644 +323 −0 Original line number Diff line number Diff line package gldemo import ( "fmt" "image" "image/draw" _ "image/png" // register PNG "log" "os" "strings" "github.com/go-gl/gl/v4.3-core/gl" "github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/mathgl/mgl32" "repositories.muehmer.net/bsmrgo/saola/support/scene" ) const ( sceneName = "GL-Demo" windowWidth = 1650 windowHeight = 1080 ) var ( angle float64 previousTime float64 err error program uint32 projection mgl32.Mat4 camera mgl32.Mat4 model mgl32.Mat4 modelUniform int32 texture uint32 vao uint32 ) // Hooks returns our hooks. func Hooks() scene.HooksType { hooks := scene.HooksType{ Initialize: initialize, Render: render, Resize: resize, Key: keyCallback, } return hooks } func initialize() { fmt.Fprintf(os.Stderr, "[%s] Initialize()\n", sceneName) // Configure the vertex and fragment shaders program, err = newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection = mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera = mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model = mgl32.Ident4() modelUniform = gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Load the texture texture, err = newTexture("/home/MUEHMER/bsmr/go/src/repositories.muehmer.net/bsmrgo/graphics-playground/scenes/gldemo/square.png") if err != nil { log.Fatalln(err) } // Configure the vertex data gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle = 0.0 previousTime = glfw.GetTime() } // Resize changes the view. func resize(width, height int) { fmt.Fprintf(os.Stderr, "[%s] Resize(%d, %d)\n", sceneName, width, height) } // Render something. func render() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) } func keyCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { fmt.Fprintf(os.Stderr, "[%s] key: %v - scancode: %d - action: %v - mode: %v\n", sceneName, key, scancode, action, mods) if key == glfw.KeyEscape && action == glfw.Press { w.SetShouldClose(true) } } func newProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to link program: %v", log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil } 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 } func newTexture(file string) (uint32, error) { imgFile, err := os.Open(file) if err != nil { return 0, fmt.Errorf("texture %q not found on disk: %v", file, err) } img, _, err := image.Decode(imgFile) if err != nil { return 0, err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return 0, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return texture, nil } var vertexShader = ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; in vec2 vertTexCoord; out vec2 fragTexCoord; void main() { fragTexCoord = vertTexCoord; gl_Position = projection * camera * model * vec4(vert, 1); } ` + "\x00" var fragmentShader = ` #version 330 uniform sampler2D tex; in vec2 fragTexCoord; out vec4 outputColor; void main() { outputColor = texture(tex, fragTexCoord); } ` + "\x00" var cubeVertices = []float32{ // X, Y, Z, U, V // Bottom -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, // Top -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // Front -1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, // Back -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // Left -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, // Right 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, } scenes/gldemo/square.png 0 → 100644 +352 KiB Loading image diff... Loading
main.go +3 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ import ( "repositories.muehmer.net/bsmrgo/saola/support/scene" si "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/icosahedron" //si "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/icosahedron" sd "repositories.muehmer.net/bsmrgo/graphics-playground/scenes/gldemo" ) func init() { Loading @@ -31,6 +32,6 @@ func main() { ContextVersionMinor: 3, CenterOnPrimaryMonitor: true, } hooks := si.Hooks() hooks := sd.Hooks() scene.Manage(setup, hooks) }
scenes/gldemo/gldemo.go 0 → 100644 +323 −0 Original line number Diff line number Diff line package gldemo import ( "fmt" "image" "image/draw" _ "image/png" // register PNG "log" "os" "strings" "github.com/go-gl/gl/v4.3-core/gl" "github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/mathgl/mgl32" "repositories.muehmer.net/bsmrgo/saola/support/scene" ) const ( sceneName = "GL-Demo" windowWidth = 1650 windowHeight = 1080 ) var ( angle float64 previousTime float64 err error program uint32 projection mgl32.Mat4 camera mgl32.Mat4 model mgl32.Mat4 modelUniform int32 texture uint32 vao uint32 ) // Hooks returns our hooks. func Hooks() scene.HooksType { hooks := scene.HooksType{ Initialize: initialize, Render: render, Resize: resize, Key: keyCallback, } return hooks } func initialize() { fmt.Fprintf(os.Stderr, "[%s] Initialize()\n", sceneName) // Configure the vertex and fragment shaders program, err = newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection = mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera = mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model = mgl32.Ident4() modelUniform = gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Load the texture texture, err = newTexture("/home/MUEHMER/bsmr/go/src/repositories.muehmer.net/bsmrgo/graphics-playground/scenes/gldemo/square.png") if err != nil { log.Fatalln(err) } // Configure the vertex data gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle = 0.0 previousTime = glfw.GetTime() } // Resize changes the view. func resize(width, height int) { fmt.Fprintf(os.Stderr, "[%s] Resize(%d, %d)\n", sceneName, width, height) } // Render something. func render() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) } func keyCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { fmt.Fprintf(os.Stderr, "[%s] key: %v - scancode: %d - action: %v - mode: %v\n", sceneName, key, scancode, action, mods) if key == glfw.KeyEscape && action == glfw.Press { w.SetShouldClose(true) } } func newProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to link program: %v", log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil } 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 } func newTexture(file string) (uint32, error) { imgFile, err := os.Open(file) if err != nil { return 0, fmt.Errorf("texture %q not found on disk: %v", file, err) } img, _, err := image.Decode(imgFile) if err != nil { return 0, err } rgba := image.NewRGBA(img.Bounds()) if rgba.Stride != rgba.Rect.Size().X*4 { return 0, fmt.Errorf("unsupported stride") } draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) var texture uint32 gl.GenTextures(1, &texture) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, int32(rgba.Rect.Size().X), int32(rgba.Rect.Size().Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(rgba.Pix)) return texture, nil } var vertexShader = ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; in vec2 vertTexCoord; out vec2 fragTexCoord; void main() { fragTexCoord = vertTexCoord; gl_Position = projection * camera * model * vec4(vert, 1); } ` + "\x00" var fragmentShader = ` #version 330 uniform sampler2D tex; in vec2 fragTexCoord; out vec4 outputColor; void main() { outputColor = texture(tex, fragTexCoord); } ` + "\x00" var cubeVertices = []float32{ // X, Y, Z, U, V // Bottom -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, // Top -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // Front -1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, // Back -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 1.0, 0.0, -1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // Left -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, // Right 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, }