Documentation ¶
Overview ¶
Package gl provides simple abstractions over a modern subset of OpenGL.
Example (FirstCube) ¶
package main import ( "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/input" "github.com/cozely/cozely/space" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" "github.com/cozely/cozely/x/math32" ) // Declarations //////////////////////////////////////////////////////////////// // Input Bindings var ( quit = input.Button("Quit") rotate = input.Button("Rotate") move = input.Button("Move") zoom = input.Button("Zoom") delta = input.Delta("Delta") ) type loop04 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer // Transformation matrices screenFromView space.Matrix // projection matrix viewFromWorld space.Matrix // view matrix worldFromObject space.Matrix // model matrix // Cube state position coord.XYZ yaw, pitch float32 } // Uniform buffer type perObject struct { screenFromObject space.Matrix } // Vertex buffer type mesh []struct { position coord.XYZ `layout:"0"` color color.LRGB `layout:"1"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() cozely.Configure(cozely.Multisample(8)) l := loop04{} window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) r := float32(s.X) / float32(s.Y) l.screenFromView = space.Perspective(math32.Pi/4, r, 0.001, 1000.0) } err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop04) Enter() { // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader04.vert"), gl.Shader(cozely.Path()+"shader04.frag"), gl.VertexFormat(0, mesh{}), gl.Topology(gl.Triangles), gl.CullFace(false, true), gl.DepthTest(true), gl.DepthWrite(true), gl.DepthComparison(gl.LessOrEqual), ) gl.Enable(gl.FramebufferSRGB) // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perObject{}, gl.DynamicStorage) // Create and fill the vertex buffer vbo := gl.NewVertexBuffer(coloredcube(), 0) // Initialize worldFromObject and viewFromWorld matrices l.position = coord.XYZ{0, 0, 0} l.yaw = -0.6 l.pitch = 0.3 l.computeWorldFromObject() l.computeViewFromWorld() // Bind the vertex buffer to the pipeline l.pipeline.Bind() vbo.Bind(0, 0) l.pipeline.Unbind() } func (loop04) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (l *loop04) React() { m := delta.XY() s := window.Size().Coord() if rotate.Pressed() || move.Pressed() || zoom.Pressed() { input.GrabMouse(true) } if rotate.Released() || move.Released() || zoom.Released() { input.GrabMouse(false) } if rotate.Ongoing() { l.yaw += 4 * m.X / s.X l.pitch += 4 * m.Y / s.Y switch { case l.pitch < -math32.Pi/2: l.pitch = -math32.Pi / 2 case l.pitch > +math32.Pi/2: l.pitch = +math32.Pi / 2 } l.computeWorldFromObject() } if move.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Y -= d.Y l.computeWorldFromObject() } if zoom.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Z += d.Y l.computeWorldFromObject() } if quit.Pressed() { cozely.Stop(nil) } } func (l *loop04) computeWorldFromObject() { rot := space.EulerZXY(l.pitch, l.yaw, 0) l.worldFromObject = space.Translation(l.position).Times(rot) } func (l *loop04) computeViewFromWorld() { l.viewFromWorld = space.LookAt( coord.XYZ{0, 0, 3}, coord.XYZ{0, 0, 0}, coord.XYZ{0, 1, 0}, ) } func (loop04) Update() { } func (l *loop04) Render() { l.pipeline.Bind() gl.ClearDepthBuffer(1.0) gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) u := perObject{ screenFromObject: l.screenFromView. Times(l.viewFromWorld). Times(l.worldFromObject), } l.perFrameUBO.SubData(&u, 0) l.perFrameUBO.Bind(0) gl.Draw(0, 6*2*3) l.pipeline.Unbind() } //////////////////////////////////////////////////////////////////////////////// var ( purple = color.LRGB{0.2, 0, 0.6} orange = color.LRGB{0.8, 0.3, 0} green = color.LRGB{0, 0.3, 0.1} ) func coloredcube() mesh { return mesh{ // Front Face {coord.XYZ{-0.5, -0.5, +0.5}, purple}, {coord.XYZ{+0.5, +0.5, +0.5}, purple}, {coord.XYZ{-0.5, +0.5, +0.5}, purple}, {coord.XYZ{-0.5, -0.5, +0.5}, purple}, {coord.XYZ{+0.5, -0.5, +0.5}, purple}, {coord.XYZ{+0.5, +0.5, +0.5}, purple}, // Back Face {coord.XYZ{-0.5, -0.5, -0.5}, purple}, {coord.XYZ{-0.5, +0.5, -0.5}, purple}, {coord.XYZ{+0.5, +0.5, -0.5}, purple}, {coord.XYZ{-0.5, -0.5, -0.5}, purple}, {coord.XYZ{+0.5, +0.5, -0.5}, purple}, {coord.XYZ{+0.5, -0.5, -0.5}, purple}, // Right Face {coord.XYZ{+0.5, -0.5, +0.5}, green}, {coord.XYZ{+0.5, +0.5, -0.5}, green}, {coord.XYZ{+0.5, +0.5, +0.5}, green}, {coord.XYZ{+0.5, -0.5, +0.5}, green}, {coord.XYZ{+0.5, -0.5, -0.5}, green}, {coord.XYZ{+0.5, +0.5, -0.5}, green}, // Left Face {coord.XYZ{-0.5, -0.5, +0.5}, green}, {coord.XYZ{-0.5, +0.5, +0.5}, green}, {coord.XYZ{-0.5, +0.5, -0.5}, green}, {coord.XYZ{-0.5, -0.5, +0.5}, green}, {coord.XYZ{-0.5, +0.5, -0.5}, green}, {coord.XYZ{-0.5, -0.5, -0.5}, green}, // Bottom Face {coord.XYZ{-0.5, -0.5, +0.5}, orange}, {coord.XYZ{-0.5, -0.5, -0.5}, orange}, {coord.XYZ{+0.5, -0.5, +0.5}, orange}, {coord.XYZ{-0.5, -0.5, -0.5}, orange}, {coord.XYZ{+0.5, -0.5, -0.5}, orange}, {coord.XYZ{+0.5, -0.5, +0.5}, orange}, // Top Face {coord.XYZ{-0.5, +0.5, +0.5}, orange}, {coord.XYZ{+0.5, +0.5, +0.5}, orange}, {coord.XYZ{-0.5, +0.5, -0.5}, orange}, {coord.XYZ{-0.5, +0.5, -0.5}, orange}, {coord.XYZ{+0.5, +0.5, +0.5}, orange}, {coord.XYZ{+0.5, +0.5, -0.5}, orange}, } }
Output:
Example (FirstTriangle) ¶
package main import ( "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" ) // Declarations //////////////////////////////////////////////////////////////// type loop01 struct { // OpenGL Object pipeline *gl.Pipeline } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) } l := loop01{} err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop01) Enter() { // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader01.vert"), gl.Shader(cozely.Path()+"shader01.frag"), gl.Topology(gl.Triangles), ) } func (loop01) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (loop01) React() { // if input.Default.Back.Pushed() { // cozely.Stop(nil) // } } func (loop01) Update() { } func (l *loop01) Render() { l.pipeline.Bind() gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) gl.Draw(0, 3) l.pipeline.Unbind() }
Output:
Example (IndirectDraw) ¶
package main import ( "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/input" "github.com/cozely/cozely/space" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" "github.com/cozely/cozely/x/math32" ) // Declarations //////////////////////////////////////////////////////////////// // Input Bindings // (same as in FirstCube example) type loop07 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer // Tranformation matrices screenFromView space.Matrix // projection matrix viewFromWorld space.Matrix // view matrix worldFromObject space.Matrix // model matirx // Cube state position coord.XYZ yaw, pitch float32 } // Uniform buffer // (same as in FirstCube example) // type perObject struct { // screenFromObject space.Matrix // } // Indirect Command Buffer var commands = []gl.DrawIndirectCommand{ { VertexCount: 6, InstanceCount: 1, FirstVertex: 0, BaseInstance: 1, }, { VertexCount: 6, InstanceCount: 1, FirstVertex: 6, BaseInstance: 1, }, { VertexCount: 6, InstanceCount: 1, FirstVertex: 12, BaseInstance: 2, }, { VertexCount: 6, InstanceCount: 1, FirstVertex: 18, BaseInstance: 3, }, { VertexCount: 6, InstanceCount: 1, FirstVertex: 24, BaseInstance: 4, }, { VertexCount: 6, InstanceCount: 1, FirstVertex: 30, BaseInstance: 5, }, } // Instance Buffer var draws = []struct { color color.LRGB `layout:"1" divisor:"1"` }{ {color.LRGB{R: 0.2, G: 0, B: 0.6}}, {color.LRGB{R: 0.2, G: 0, B: 0.6}}, {color.LRGB{R: 0, G: 0.3, B: 0.1}}, {color.LRGB{R: 0, G: 0.3, B: 0.1}}, {color.LRGB{R: 0.8, G: 0.3, B: 0}}, {color.LRGB{R: 0.8, G: 0.3, B: 0}}, } // Vertex buffer type simplemesh []struct { position coord.XYZ `layout:"0"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() cozely.Configure(cozely.Multisample(8)) l := loop07{} window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) r := float32(s.X) / float32(s.Y) l.screenFromView = space.Perspective(math32.Pi/4, r, 0.001, 1000.0) } err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop07) Enter() { // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader07.vert"), gl.Shader(cozely.Path()+"shader07.frag"), gl.VertexFormat(0, simplemesh{}), gl.VertexFormat(1, draws), gl.Topology(gl.Triangles), gl.CullFace(false, true), gl.DepthTest(true), ) gl.Enable(gl.FramebufferSRGB) //TODO: bug related to depth or face culling when run in test sequence // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perObject{}, gl.DynamicStorage) // Create the Indirect Command Buffer icbo := gl.NewIndirectBuffer(commands, gl.DynamicStorage) ibo := gl.NewVertexBuffer(draws, gl.DynamicStorage) // Create and fill the vertex buffer vbo := gl.NewVertexBuffer(simplecube(), 0) // Initialize worldFromObject and viewFromWorld matrices l.position = coord.XYZ{0, 0, 0} l.yaw = -0.6 l.pitch = 0.3 l.computeWorldFromObject() l.computeViewFromWorld() // Bind the vertex buffer to the pipeline l.pipeline.Bind() vbo.Bind(0, 0) icbo.Bind() ibo.Bind(1, 0) l.pipeline.Unbind() } func (loop07) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (loop07) Update() { } func (l *loop07) React() { m := delta.XY() s := window.Size().Coord() if rotate.Pressed() || move.Pressed() || zoom.Pressed() { input.GrabMouse(true) } if rotate.Released() || move.Released() || zoom.Released() { input.GrabMouse(false) } if rotate.Ongoing() { l.yaw += 4 * m.X / s.X l.pitch += 4 * m.Y / s.Y switch { case l.pitch < -math32.Pi/2: l.pitch = -math32.Pi / 2 case l.pitch > +math32.Pi/2: l.pitch = +math32.Pi / 2 } l.computeWorldFromObject() } if move.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Y -= d.Y l.computeWorldFromObject() } if zoom.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Z += d.Y l.computeWorldFromObject() } if quit.Pressed() { cozely.Stop(nil) } } func (l *loop07) Render() { l.pipeline.Bind() gl.ClearDepthBuffer(1.0) gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) u := perObject{ screenFromObject: l.screenFromView. Times(l.viewFromWorld). Times(l.worldFromObject), } l.perFrameUBO.SubData(&u, 0) l.perFrameUBO.Bind(0) gl.DrawIndirect(0, 6) l.pipeline.Unbind() } func (l *loop07) computeWorldFromObject() { rot := space.EulerZXY(l.pitch, l.yaw, 0) l.worldFromObject = space.Translation(l.position).Times(rot) } func (l *loop07) computeViewFromWorld() { l.viewFromWorld = space.LookAt( coord.XYZ{0, 0, 3}, coord.XYZ{0, 0, 0}, coord.XYZ{0, 1, 0}, ) } //////////////////////////////////////////////////////////////////////////////// func simplecube() simplemesh { return simplemesh{ // Front Face {coord.XYZ{-0.5, -0.5, +0.5}}, {coord.XYZ{+0.5, +0.5, +0.5}}, {coord.XYZ{-0.5, +0.5, +0.5}}, {coord.XYZ{-0.5, -0.5, +0.5}}, {coord.XYZ{+0.5, -0.5, +0.5}}, {coord.XYZ{+0.5, +0.5, +0.5}}, // Back Face {coord.XYZ{-0.5, -0.5, -0.5}}, {coord.XYZ{-0.5, +0.5, -0.5}}, {coord.XYZ{+0.5, +0.5, -0.5}}, {coord.XYZ{-0.5, -0.5, -0.5}}, {coord.XYZ{+0.5, +0.5, -0.5}}, {coord.XYZ{+0.5, -0.5, -0.5}}, // Right Face {coord.XYZ{+0.5, -0.5, +0.5}}, {coord.XYZ{+0.5, +0.5, -0.5}}, {coord.XYZ{+0.5, +0.5, +0.5}}, {coord.XYZ{+0.5, -0.5, +0.5}}, {coord.XYZ{+0.5, -0.5, -0.5}}, {coord.XYZ{+0.5, +0.5, -0.5}}, // Left Face {coord.XYZ{-0.5, -0.5, +0.5}}, {coord.XYZ{-0.5, +0.5, +0.5}}, {coord.XYZ{-0.5, +0.5, -0.5}}, {coord.XYZ{-0.5, -0.5, +0.5}}, {coord.XYZ{-0.5, +0.5, -0.5}}, {coord.XYZ{-0.5, -0.5, -0.5}}, // Bottom Face {coord.XYZ{-0.5, -0.5, +0.5}}, {coord.XYZ{-0.5, -0.5, -0.5}}, {coord.XYZ{+0.5, -0.5, +0.5}}, {coord.XYZ{-0.5, -0.5, -0.5}}, {coord.XYZ{+0.5, -0.5, -0.5}}, {coord.XYZ{+0.5, -0.5, +0.5}}, // Top Face {coord.XYZ{-0.5, +0.5, +0.5}}, {coord.XYZ{+0.5, +0.5, +0.5}}, {coord.XYZ{-0.5, +0.5, -0.5}}, {coord.XYZ{-0.5, +0.5, -0.5}}, {coord.XYZ{+0.5, +0.5, +0.5}}, {coord.XYZ{+0.5, +0.5, -0.5}}, } }
Output:
Example (InstancedDraw) ¶
package main import ( "math/rand" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/input" "github.com/cozely/cozely/window" "github.com/cozely/cozely" "github.com/cozely/cozely/x/gl" ) // Declarations //////////////////////////////////////////////////////////////// type loop06 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer rosesINBO gl.VertexBuffer perFrame perFrame06 } // Instance Buffer var roses [64]struct { position coord.XY `layout:"0" divisor:"1"` size float32 `layout:"1"` numerator int32 `layout:"2"` denominator int32 `layout:"3"` offset float32 `layout:"4"` speed float32 `layout:"5"` } const nbPoints int32 = 512 // Uniform buffer type perFrame06 struct { ratio float32 time float32 } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() cozely.Configure(cozely.Multisample(8)) l := loop06{} window.Events.Resize = func() { s := window.Size() l.perFrame.ratio = float32(s.X) / float32(s.Y) gl.Viewport(0, 0, int32(s.X), int32(s.Y)) } err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop06) Enter() { // Setup the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader06.vert"), gl.Shader(cozely.Path()+"shader06.frag"), gl.VertexFormat(1, roses[:]), gl.Topology(gl.LineStrip), ) gl.Enable(gl.FramebufferSRGB) // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perFrame{}, gl.DynamicStorage) // Create the instance buffer l.randomizeRosesData() l.rosesINBO = gl.NewVertexBuffer(roses[:], gl.DynamicStorage) // Bind the instance buffer to the pipeline l.pipeline.Bind() l.rosesINBO.Bind(1, 0) l.pipeline.Unbind() } func (loop06) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (l *loop06) React() { if input.Select.Pressed() || input.Click.Pressed() { l.randomizeRosesData() l.rosesINBO.SubData(roses[:], 0) } if quit.Pressed() { cozely.Stop(nil) } } func (loop06) Update() { } func (l *loop06) Render() { l.perFrame.time += float32(cozely.RenderDelta()) l.pipeline.Bind() gl.ClearDepthBuffer(1.0) gl.ClearColorBuffer(color.LRGBA{0.9, 0.85, 0.80, 1.0}) gl.Enable(gl.LineSmooth) gl.Enable(gl.Blend) gl.Blending(gl.SrcAlpha, gl.OneMinusSrcAlpha) u := l.perFrame l.perFrameUBO.Bind(0) l.perFrameUBO.SubData(&u, 0) gl.DrawInstanced(0, nbPoints, int32(len(roses))) l.pipeline.Unbind() } func (l *loop06) randomizeRosesData() { for i := 0; i < len(roses); i++ { roses[i].position.X = rand.Float32()*2.0 - 1.0 roses[i].position.Y = rand.Float32()*2.0 - 1.0 roses[i].size = rand.Float32()*0.20 + 0.1 roses[i].numerator = rand.Int31n(16) + 1 roses[i].denominator = rand.Int31n(16) + 1 roses[i].offset = rand.Float32()*2.8 + 0.2 roses[i].speed = 0.5 + 1.5*rand.Float32() if rand.Int31n(2) > 0 { roses[i].speed = -roses[i].speed } } } //////////////////////////////////////////////////////////////////////////////// // func rose(nbPoints int, num int, den int, offset float32) []perVertex { // var m = []perVertex{} // for i := den * nbPoints; i >= 0; i-- { // var k = float32(num) / float32(den) // var theta = float32(i) * 2 * math32.Pi / float32(nbPoints) // var r = (math.Cos(k*theta) + offset) / (1.0 + offset) // var p = plane.Polar{r, theta} // m = append(m, perVertex{p.Coord()}) // } // return m // }
Output:
Example (Streaming) ¶
package main import ( "math/rand" "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/input" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" "github.com/cozely/cozely/x/math32" ) // Declarations //////////////////////////////////////////////////////////////// // Input Bindings // (same as in InstancedDraw example) type loop08 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer pointsVBO gl.VertexBuffer perFrame perFrame08 // Application State bgColor color.LRGBA rotSpeed float32 jitter float32 angles []float32 speeds []float32 cleared, updated bool } // Uniform buffer type perFrame08 struct { ratio coord.XY Rotation float32 } // Vertex buffer var points [512]struct { Position coord.XY `layout:"0"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() l := loop08{ bgColor: color.LRGBA{0.9, 0.87, 0.85, 1.0}, rotSpeed: float32(0.003), jitter: float32(0.002), angles: make([]float32, len(points)), speeds: make([]float32, len(points)), } cozely.Configure(cozely.Multisample(8), gl.NoClear()) window.Events.Resize = l.resize err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop08) Enter() { // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader08.vert"), gl.Shader(cozely.Path()+"shader08.frag"), gl.Topology(gl.Points), gl.VertexFormat(0, points[:]), gl.DepthTest(false), gl.DepthWrite(false), ) // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perFrame08{}, gl.DynamicStorage) l.perFrame.Rotation = 0.0 // Create and fill the vertex buffer // points = make(mesh, len(points)) l.setupPoints() l.pointsVBO = gl.NewVertexBuffer(points[:], gl.DynamicStorage) // Bind the vertex buffer to the pipeline l.pipeline.Bind() l.pointsVBO.Bind(0, 0) l.pipeline.Unbind() } func (loop08) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (l *loop08) React() { if input.Select.Pressed() { l.setupPoints() } if quit.Pressed() { cozely.Stop(nil) } } func (l *loop08) Update() { for i, pt := range points { points[i].Position = coord.XY{ pt.Position.X + l.speeds[i]*math32.Cos(l.angles[i]) + l.jitter*(rand.Float32()-0.5), pt.Position.Y + l.speeds[i]*math32.Sin(l.angles[i]) + l.jitter*(rand.Float32()-0.5), } if points[i].Position.Length() > 0.75 { l.angles[i] += math32.Pi / 4.0 } } l.pointsVBO.SubData(points[:], 0) l.perFrame.Rotation += l.rotSpeed l.updated = true } func (l *loop08) Render() { if !l.cleared { gl.ClearColorBuffer(l.bgColor) l.cleared = true } if l.updated { l.pipeline.Bind() gl.Enable(gl.FramebufferSRGB) gl.Enable(gl.Blend) gl.Blending(gl.SrcAlpha, gl.OneMinusSrcAlpha) gl.PointSize(3.0) u := l.perFrame l.perFrameUBO.Bind(0) l.perFrameUBO.SubData(&u, 0) gl.Draw(0, int32(len(points))) l.pipeline.Unbind() l.updated = false } } func (l *loop08) setupPoints() { n := float32(3 + rand.Intn(13)) for i := range points { points[i].Position = coord.XY{rand.Float32(), rand.Float32()} a := math32.Floor(rand.Float32() * n) a = a * (2.0 * math32.Pi) / n points[i].Position = coord.XY{0.75 * math32.Cos(a), 0.75 * math32.Sin(a)} l.angles[i] = a + float32(i)*math32.Pi/float32(len(points)) + math32.Pi/2.0 l.speeds[i] = 0.004 * rand.Float32() } l.rotSpeed = 0.01 * (rand.Float32() - 0.5) l.jitter = 0.014 * rand.Float32() l.cleared = false } func (l *loop08) resize() { l.setupPoints() s := window.Size().Coord() // Compute ratio if s.X > s.Y { l.perFrame.ratio = coord.XY{s.Y / s.X, 1.0} } else { l.perFrame.ratio = coord.XY{1.0, s.X / s.Y} } gl.Viewport(0, 0, int32(s.X), int32(s.Y)) }
Output:
Example (Texture) ¶
package main import ( "image" _ "image/png" "os" "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/input" "github.com/cozely/cozely/space" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" "github.com/cozely/cozely/x/math32" ) // Declarations //////////////////////////////////////////////////////////////// // Input Bindings // (same as in example 04) // OpenGL Objects type loop05 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer sampler gl.Sampler diffuse gl.Texture2D // Transformation matrices screenFromView space.Matrix // projection matrix viewFromWorld space.Matrix // view matrix worldFromObject space.Matrix // model matrix // Cube state position coord.XYZ yaw, pitch float32 } // Uniform buffer // (same as in example 04) // type perObject struct { // screenFromObject space.Matrix // } // Vertex buffer type uvmesh []struct { position coord.XYZ `layout:"0"` uv coord.XY `layout:"1"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() cozely.Configure(cozely.Multisample(8)) l := loop05{} window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) r := float32(s.X) / float32(s.Y) l.screenFromView = space.Perspective(math32.Pi/4, r, 0.001, 1000.0) } err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop05) Enter() { // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader05.vert"), gl.Shader(cozely.Path()+"shader05.frag"), gl.VertexFormat(0, uvmesh{}), gl.Topology(gl.Triangles), gl.CullFace(false, true), gl.DepthTest(true), gl.DepthWrite(true), gl.DepthComparison(gl.LessOrEqual), ) gl.Enable(gl.FramebufferSRGB) // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perObject{}, gl.DynamicStorage) // Create and fill the vertex buffer vbo := gl.NewVertexBuffer(uvcube(), gl.StaticStorage) // Create and bind the sampler l.sampler = gl.NewSampler( gl.Minification(gl.LinearMipmapLinear), gl.Anisotropy(16.0), ) // Create and load the textures l.diffuse = gl.NewTexture2D(8, gl.SRGBA8, 512, 512) r, err := os.Open(cozely.Path() + "testpattern.png") if err != nil { panic(cozely.Wrap("opening texture", err)) } defer r.Close() img, _, err := image.Decode(r) if err != nil { panic(cozely.Wrap("decoding texture", err)) } l.diffuse.SubImage(0, 0, 0, img) l.diffuse.GenerateMipmap() // Initialize worldFromObject and viewFromWorld matrices l.position = coord.XYZ{0, 0, 0} l.yaw = -0.6 l.pitch = 0.3 l.computeWorldFromObject() l.computeViewFromWorld() // Bind the vertex buffer to the pipeline l.pipeline.Bind() vbo.Bind(0, 0) l.pipeline.Unbind() } func (loop05) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (l *loop05) React() { m := delta.XY() s := window.Size().Coord() if rotate.Pressed() || move.Pressed() || zoom.Pressed() { input.GrabMouse(true) } if rotate.Released() || move.Released() || zoom.Released() { input.GrabMouse(false) } if rotate.Ongoing() { l.yaw += 4 * m.X / s.X l.pitch += 4 * m.Y / s.Y switch { case l.pitch < -math32.Pi/2: l.pitch = -math32.Pi / 2 case l.pitch > +math32.Pi/2: l.pitch = +math32.Pi / 2 } l.computeWorldFromObject() } if move.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Y -= d.Y l.computeWorldFromObject() } if zoom.Ongoing() { d := m.Times(2).Slashxy(s) l.position.X += d.X l.position.Z += d.Y l.computeWorldFromObject() } if quit.Pressed() { cozely.Stop(nil) } } func (l *loop05) computeWorldFromObject() { rot := space.EulerZXY(l.pitch, l.yaw, 0) l.worldFromObject = space.Translation(l.position).Times(rot) } func (l *loop05) computeViewFromWorld() { l.viewFromWorld = space.LookAt( coord.XYZ{0, 0, 3}, coord.XYZ{0, 0, 0}, coord.XYZ{0, 1, 0}, ) } func (loop05) Update() { } func (l *loop05) Render() { l.pipeline.Bind() gl.ClearDepthBuffer(1.0) gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) u := perObject{ screenFromObject: l.screenFromView. Times(l.viewFromWorld). Times(l.worldFromObject), } l.perFrameUBO.SubData(&u, 0) l.perFrameUBO.Bind(0) l.diffuse.Bind(0) l.sampler.Bind(0) gl.Draw(0, 6*2*3) l.pipeline.Unbind() } //////////////////////////////////////////////////////////////////////////////// func uvcube() uvmesh { return uvmesh{ // Front Face {coord.XYZ{-0.5, -0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, -0.5, +0.5}, coord.XY{1, 1}}, {coord.XYZ{+0.5, +0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, -0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, +0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, +0.5, +0.5}, coord.XY{0, 0}}, // Back Face {coord.XYZ{+0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{-0.5, -0.5, -0.5}, coord.XY{1, 1}}, {coord.XYZ{-0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{+0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{-0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{+0.5, +0.5, -0.5}, coord.XY{0, 0}}, // Right Face {coord.XYZ{+0.5, -0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, -0.5, -0.5}, coord.XY{1, 1}}, {coord.XYZ{+0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{+0.5, -0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{+0.5, +0.5, +0.5}, coord.XY{0, 0}}, // Left Face {coord.XYZ{-0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{-0.5, -0.5, +0.5}, coord.XY{1, 1}}, {coord.XYZ{-0.5, +0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{-0.5, +0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, +0.5, -0.5}, coord.XY{0, 0}}, // Bottom Face {coord.XYZ{-0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, -0.5, -0.5}, coord.XY{1, 1}}, {coord.XYZ{+0.5, -0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, -0.5, -0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, -0.5, +0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, -0.5, +0.5}, coord.XY{0, 0}}, // Top Face {coord.XYZ{-0.5, +0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, +0.5, +0.5}, coord.XY{1, 1}}, {coord.XYZ{+0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, +0.5, +0.5}, coord.XY{0, 1}}, {coord.XYZ{+0.5, +0.5, -0.5}, coord.XY{1, 0}}, {coord.XYZ{-0.5, +0.5, -0.5}, coord.XY{0, 0}}, } }
Output:
Example (UniformBuffer) ¶
package main import ( "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/plane" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" ) // Declarations //////////////////////////////////////////////////////////////// type loop03 struct { // OpenGL objects pipeline *gl.Pipeline perFrameUBO gl.UniformBuffer // Animation state angle float64 } // Uniform buffer type perFrame struct { transform plane.GPUMatrix } // Vertex buffer type coloredmesh2d []struct { position coord.XY `layout:"0"` color color.LRGB `layout:"1"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) } l := loop03{} err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop03) Enter() { var triangle coloredmesh2d // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader03.vert"), gl.Shader(cozely.Path()+"shader03.frag"), gl.VertexFormat(0, triangle), gl.Topology(gl.Triangles), ) gl.Enable(gl.FramebufferSRGB) // Create the uniform buffer l.perFrameUBO = gl.NewUniformBuffer(&perFrame{}, gl.DynamicStorage) // Fill and create the vertex buffer triangle = coloredmesh2d{ {coord.XY{0, 0.75}, color.LRGB{0.3, 0, 0.8}}, {coord.XY{-0.65, -0.465}, color.LRGB{0.8, 0.3, 0}}, {coord.XY{0.65, -0.465}, color.LRGB{0, 0.6, 0.2}}, } vbo := gl.NewVertexBuffer(triangle, gl.StaticStorage) // Bind the vertex buffer to the pipeline l.pipeline.Bind() vbo.Bind(0, 0) l.pipeline.Unbind() } func (loop03) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (loop03) React() { } func (loop03) Update() { } func (l *loop03) Render() { l.angle -= 1.0 * cozely.RenderDelta() l.pipeline.Bind() gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) u := perFrame{ transform: plane.Rotation(float32(l.angle)).GPU(), } l.perFrameUBO.SubData(&u, 0) l.perFrameUBO.Bind(0) gl.Draw(0, 3) l.pipeline.Unbind() }
Output:
Example (VertexBuffer) ¶
package main import ( "github.com/cozely/cozely" "github.com/cozely/cozely/color" "github.com/cozely/cozely/coord" "github.com/cozely/cozely/window" "github.com/cozely/cozely/x/gl" ) // Declarations //////////////////////////////////////////////////////////////// type loop02 struct { pipeline *gl.Pipeline } // Vertex buffer type mesh2d []struct { position coord.XY `layout:"0"` color color.LRGB `layout:"1"` } // Initialization ////////////////////////////////////////////////////////////// func main() { defer cozely.Recover() window.Events.Resize = func() { s := window.Size() gl.Viewport(0, 0, int32(s.X), int32(s.Y)) } l := loop02{} err := cozely.Run(&l) if err != nil { panic(err) } } func (l *loop02) Enter() { var triangle mesh2d // Create and configure the pipeline l.pipeline = gl.NewPipeline( gl.Shader(cozely.Path()+"shader02.vert"), gl.Shader(cozely.Path()+"shader02.frag"), gl.VertexFormat(0, triangle), gl.Topology(gl.Triangles), ) gl.Enable(gl.FramebufferSRGB) // Create and fill the vertex buffer triangle = mesh2d{ {coord.XY{0, 0.65}, color.LRGB{R: 0.3, G: 0, B: 0.8}}, {coord.XY{-0.65, -0.475}, color.LRGB{R: 0.8, G: 0.3, B: 0}}, {coord.XY{0.65, -0.475}, color.LRGB{R: 0, G: 0.6, B: 0.2}}, } vbo := gl.NewVertexBuffer(triangle, gl.StaticStorage) // Bind the vertex buffer to the pipeline l.pipeline.Bind() vbo.Bind(0, 0) l.pipeline.Unbind() } func (loop02) Leave() { } // Game Loop /////////////////////////////////////////////////////////////////// func (loop02) React() { } func (loop02) Update() { } func (l *loop02) Render() { l.pipeline.Bind() gl.ClearColorBuffer(color.LRGBA{0.9, 0.9, 0.9, 1.0}) gl.Draw(0, 3) l.pipeline.Unbind() }
Output:
Index ¶
- Variables
- func BindComputeSubroutines(s []uint32)
- func BindFragmentSubroutines(s []uint32)
- func BindGeometrySubroutines(s []uint32)
- func BindTessControlSubroutines(s []uint32)
- func BindTessEvaluationSubroutines(s []uint32)
- func BindVertexSubroutines(s []uint32)
- func Blending(src, dst BlendFactor)
- func ClearColorBuffer(c struct{ ... })
- func ClearDepthBuffer(d float32)
- func ClearStencilBuffer(m int32)
- func DepthRange(near, far float64)
- func Disable(c Capability)
- func Draw(first int32, count int32)
- func DrawIndexed(first int32, count int32)
- func DrawIndirect(firstdraw uintptr, drawcount int32)
- func DrawInstanced(first int32, count int32, instances int32)
- func Enable(c Capability)
- func Err() error
- func MemoryBarrier()
- func PointSize(s float32)
- func Viewport(ox, oy, width, height int32)
- type Access
- type BlendFactor
- type BufferFlags
- type BufferMask
- type BufferTexture
- type Capability
- type ComparisonOp
- type CounterBuffer
- type DrawIndirectCommand
- type FilterMode
- type Framebuffer
- func (fb Framebuffer) Bind(t FramebufferTarget)
- func (fb Framebuffer) Blit(dst Framebuffer, srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2 int32, ...)
- func (fb Framebuffer) CheckStatus(t FramebufferTarget) FramebufferStatus
- func (fb Framebuffer) ClearColor(drawbuffer int32, r, g, b, a float32)
- func (fb Framebuffer) ClearColorUint(r, g, b, a uint32)
- func (fb Framebuffer) ClearDepth(d float32)
- func (fb Framebuffer) Delete()
- func (fb Framebuffer) DrawBuffer(a FramebufferAttachment)
- func (fb Framebuffer) DrawBuffers(a []FramebufferAttachment)
- func (fb Framebuffer) ReadBuffer(a FramebufferAttachment)
- func (fb Framebuffer) Renderbuffer(a FramebufferAttachment, r Renderbuffer)
- func (fb Framebuffer) SetEmptySize(w, h int16)
- func (fb Framebuffer) Texture(a FramebufferAttachment, t Texture2D, level int32)
- type FramebufferAttachment
- type FramebufferStatus
- type FramebufferTarget
- type IndexBuffer
- type IndirectBuffer
- type Option
- type Pipeline
- type PipelineConfig
- func ComputeShader(r io.Reader) PipelineConfig
- func CullFace(front, back bool) PipelineConfig
- func DepthClamp(enable bool) PipelineConfig
- func DepthComparison(op ComparisonOp) PipelineConfig
- func DepthTest(enable bool) PipelineConfig
- func DepthWrite(enable bool) PipelineConfig
- func FragmentShader(r io.Reader) PipelineConfig
- func FrontFace(d WindingDirection) PipelineConfig
- func GeometryShader(r io.Reader) PipelineConfig
- func PrimitiveRestart(enable bool) PipelineConfig
- func RasterizerDiscard(enable bool) PipelineConfig
- func Shader(path string) PipelineConfig
- func ShareShadersWith(other *Pipeline) PipelineConfig
- func ShareVertexFormatsWith(other *Pipeline) PipelineConfig
- func StencilTest(enable bool) PipelineConfig
- func TessControlShader(r io.Reader) PipelineConfig
- func TessEvaluationShader(r io.Reader) PipelineConfig
- func Topology(m Primitive) PipelineConfig
- func VertexFormat(binding uint32, format interface{}) PipelineConfig
- func VertexShader(r io.Reader) PipelineConfig
- type Primitive
- type Renderbuffer
- type Sampler
- type SamplerOption
- func Anisotropy(max float32) SamplerOption
- func BorderColor(color struct{ ... }) SamplerOption
- func Comparison(op ComparisonOp) SamplerOption
- func LevelOfDetail(min, max float32) SamplerOption
- func Magnification(fm FilterMode) SamplerOption
- func Minification(fm FilterMode) SamplerOption
- func Wrapping(s, t, p WrapMode) SamplerOption
- type StorageBuffer
- type Texture1D
- type Texture2D
- func (t *Texture2D) Bind(index uint32)
- func (t *Texture2D) BindImage(index uint32, level int32, a Access, f TextureFormat)
- func (t *Texture2D) ClearByte(level int32, r uint8)
- func (t *Texture2D) Delete()
- func (t *Texture2D) GenerateMipmap()
- func (t *Texture2D) SubImage(level int32, ox, oy int32, img image.Image)
- type Texture3D
- type TextureArray1D
- type TextureArray2D
- type TextureFormat
- type UniformBuffer
- type VertexBuffer
- type WindingDirection
- type WrapMode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultFramebuffer = Framebuffer{ // contains filtered or unexported fields }
Functions ¶
func BindComputeSubroutines ¶
func BindComputeSubroutines(s []uint32)
BindComputeSubroutines binds the compute shader subroutines to indices in s.
func BindFragmentSubroutines ¶
func BindFragmentSubroutines(s []uint32)
BindFragmentSubroutines binds the fragment shader subroutines to indices in s.
func BindGeometrySubroutines ¶
func BindGeometrySubroutines(s []uint32)
BindGeometrySubroutines binds the geometry shader subroutines to indices in s.
func BindTessControlSubroutines ¶
func BindTessControlSubroutines(s []uint32)
BindTessControlSubroutines binds the tesselation control shader subroutines to indices in s.
func BindTessEvaluationSubroutines ¶
func BindTessEvaluationSubroutines(s []uint32)
BindTessEvaluationSubroutines binds the tesselation evaluation shader subroutines to indices in s.
func BindVertexSubroutines ¶
func BindVertexSubroutines(s []uint32)
BindVertexSubroutines binds the vertex shader subroutines to indices in s.
func Blending ¶
func Blending(src, dst BlendFactor)
Blending specifies the formula used for blending pixels.
Note that you must also `Enable(Blend)`. The default values are `One` and `Zero`. For alpha-blending and antialiasing, the most useful choice is `Blending(SrcAlpha, OneMinusSrcAlpha)`.
func ClearColorBuffer ¶
func ClearColorBuffer(c struct{ R, G, B, A float32 })
ClearColorBuffer clears the color buffer with c.
func ClearDepthBuffer ¶
func ClearDepthBuffer(d float32)
ClearDepthBuffer clears the depth buffer with d.
func ClearStencilBuffer ¶
func ClearStencilBuffer(m int32)
ClearStencilBuffer clears the stencil buffer with m.
func DepthRange ¶
func DepthRange(near, far float64)
DepthRange specifies the mapping of depth values from normalized device coordinates to window coordinates.
func DrawIndexed ¶
DrawIndexed asks the GPU to draw a sequence of primitives with indexed vertices.
func DrawIndirect ¶
DrawIndirect asks the GPU to read the Indirect Buffer starting at firstdraw, and make drawcount draw calls.
func DrawInstanced ¶
DrawInstanced asks the GPU to draw several instances of a sequence of primitives.
func Err ¶
func Err() error
Err returns the first unchecked error of the package since last call to the function. The error is then considered checked, and further calls to Err will return nil until the next error occurs.
Note: errors occuring while there already is an unchecked error will not be recorded. However, if the debug mode is active, all errors will be logged.
func MemoryBarrier ¶
func MemoryBarrier()
Types ¶
type Access ¶
A Access specifies...
const ( ReadOnly Access = C.GL_READ_ONLY WriteOnly Access = C.GL_WRITE_ONLY ReadWrite Access = C.GL_READ_WRITE )
Used in ...
type BlendFactor ¶
A BlendFactor is a formula used when blending pixels.
const ( Zero BlendFactor = C.GL_ZERO One BlendFactor = C.GL_ONE SrcColor BlendFactor = C.GL_SRC_COLOR OneMinusSrcColor BlendFactor = C.GL_ONE_MINUS_SRC_COLOR DstColor BlendFactor = C.GL_DST_COLOR OneMinusDstColor BlendFactor = C.GL_ONE_MINUS_DST_COLOR SrcAlpha BlendFactor = C.GL_SRC_ALPHA OneMinusSrcAlpha BlendFactor = C.GL_ONE_MINUS_SRC_ALPHA DstAlpha BlendFactor = C.GL_DST_ALPHA OneMinusDstAlpha BlendFactor = C.GL_ONE_MINUS_DST_ALPHA ConstantColor BlendFactor = C.GL_CONSTANT_COLOR OneMinusConstantColor BlendFactor = C.GL_ONE_MINUS_CONSTANT_COLOR ConstantAlpha BlendFactor = C.GL_CONSTANT_ALPHA OneMinusConstantAlpha BlendFactor = C.GL_ONE_MINUS_CONSTANT_ALPHA AlphaSaturate BlendFactor = C.GL_SRC_ALPHA_SATURATE Src1Color BlendFactor = C.GL_SRC1_COLOR OneMinusSrc1Color BlendFactor = C.GL_ONE_MINUS_SRC1_COLOR Src1Alpha BlendFactor = C.GL_SRC1_ALPHA OneMinuxSrc1Alpha BlendFactor = C.GL_ONE_MINUS_SRC1_ALPHA )
Used in `Blending`.
type BufferFlags ¶
type BufferFlags C.GLbitfield
BufferFlags specify which settings to use when creating a new buffer. Values can be ORed together.
const ( StaticStorage BufferFlags = C.GL_NONE // Content will not be updated MapRead BufferFlags = C.GL_MAP_READ_BIT // Data store will be mapped for reading MapWrite BufferFlags = C.GL_MAP_WRITE_BIT // Data store will be mapped for writing MapPersistent BufferFlags = C.GL_MAP_PERSISTENT_BIT // Data store will be accessed by both application and GPU while mapped MapCoherent BufferFlags = C.GL_MAP_COHERENT_BIT // No synchronization needed when persistently mapped DynamicStorage BufferFlags = C.GL_DYNAMIC_STORAGE_BIT // Content will be updated ClientStorage BufferFlags = C.GL_CLIENT_STORAGE_BIT // Prefer storage on application side )
Used in `NewUniformBuffer` and `NewVertexBuffer`.
type BufferMask ¶
type BufferMask C.GLbitfield
const ( ColorBufferBit BufferMask = C.GL_COLOR_BUFFER_BIT DepthBufferBit BufferMask = C.GL_DEPTH_BUFFER_BIT StencilBufferBit BufferMask = C.GL_STENCIL_BUFFER_BIT )
type BufferTexture ¶
type BufferTexture struct {
// contains filtered or unexported fields
}
BufferTexture is a block of memory own by the GPU.
func NewBufferTexture ¶
func NewBufferTexture(data interface{}, fmt TextureFormat, f BufferFlags) BufferTexture
NewBufferTexture asks the GPU to allocate a new block of memory.
func (*BufferTexture) SubData ¶
func (bt *BufferTexture) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type Capability ¶
A Capability is an OpenGL functionality that can be enabled or disabled.
const ( Blend Capability = C.GL_BLEND ColorLogicOp Capability = C.GL_COLOR_LOGIC_OP DebugOutput Capability = C.GL_DEBUG_OUTPUT DebugOutputSynchronous Capability = C.GL_DEBUG_OUTPUT_SYNCHRONOUS Dither Capability = C.GL_DITHER FramebufferSRGB Capability = C.GL_FRAMEBUFFER_SRGB LineSmooth Capability = C.GL_LINE_SMOOTH Multisample Capability = C.GL_MULTISAMPLE SampleAlphaToCoverage Capability = C.GL_SAMPLE_ALPHA_TO_COVERAGE SampleAlphaToOne Capability = C.GL_SAMPLE_ALPHA_TO_ONE SampleCoverage Capability = C.GL_SAMPLE_COVERAGE SampleShading Capability = C.GL_SAMPLE_SHADING SampleMask Capability = C.GL_SAMPLE_MASK ScissorTest Capability = C.GL_SCISSOR_TEST TextureCubeMapSeamless Capability = C.GL_TEXTURE_CUBE_MAP_SEAMLESS )
Used in `Enable` and `Disable`.
type ComparisonOp ¶
A ComparisonOp specifies an operator for depth texture comparison.
const ( LessOrEqual ComparisonOp = C.GL_LEQUAL GreaterOrEqual ComparisonOp = C.GL_GEQUAL Less ComparisonOp = C.GL_LESS Greater ComparisonOp = C.GL_GREATER Equal ComparisonOp = C.GL_EQUAL NotEqual ComparisonOp = C.GL_NOTEQUAL Always ComparisonOp = C.GL_ALWAYS Never ComparisonOp = C.GL_NEVER )
Used in `Sampler.Comparison` and `DepthComparison`.
type CounterBuffer ¶
type CounterBuffer struct {
// contains filtered or unexported fields
}
A CounterBuffer is a block of memory owned by the GPU.
func NewCounterBuffer ¶
func NewCounterBuffer(nb int, f BufferFlags) CounterBuffer
NewCounterBuffer asks the GPU to allocate a new block of memory.
func (*CounterBuffer) Bind ¶
func (sb *CounterBuffer) Bind(binding uint32)
Bind to a storage binding index.
This index should correspond to one indicated by a layout qualifier in the shaders.
func (*CounterBuffer) SubData ¶
func (sb *CounterBuffer) SubData(data []uint32, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type DrawIndirectCommand ¶
type DrawIndirectCommand struct { VertexCount uint32 InstanceCount uint32 FirstVertex uint32 BaseInstance uint32 }
A DrawIndirectCommand describes a single draw call. A slice of these is used to fill indirect buffers.
type FilterMode ¶
A FilterMode specifies how to filter textures when minifying or magnifying.
const ( Nearest FilterMode = C.GL_NEAREST Linear FilterMode = C.GL_LINEAR NearestMimapNearest FilterMode = C.GL_NEAREST_MIPMAP_NEAREST LinearMipmapNearest FilterMode = C.GL_LINEAR_MIPMAP_NEAREST NearestMipmapLinear FilterMode = C.GL_NEAREST_MIPMAP_LINEAR LinearMipmapLinear FilterMode = C.GL_LINEAR_MIPMAP_LINEAR )
Used in `Sampler.Minification` and `Sampler.Magnification` (only `Nearest` and `Linear` are valid for magnification).
type Framebuffer ¶
type Framebuffer struct {
// contains filtered or unexported fields
}
func NewFramebuffer ¶
func NewFramebuffer() Framebuffer
func (Framebuffer) Bind ¶
func (fb Framebuffer) Bind(t FramebufferTarget)
func (Framebuffer) Blit ¶
func (fb Framebuffer) Blit(dst Framebuffer, srcX1, srcY1, srcX2, srcY2, dstX1, dstY1, dstX2, dstY2 int32, m BufferMask, f FilterMode)
func (Framebuffer) CheckStatus ¶
func (fb Framebuffer) CheckStatus(t FramebufferTarget) FramebufferStatus
func (Framebuffer) ClearColor ¶
func (fb Framebuffer) ClearColor(drawbuffer int32, r, g, b, a float32)
func (Framebuffer) ClearColorUint ¶
func (fb Framebuffer) ClearColorUint(r, g, b, a uint32)
func (Framebuffer) ClearDepth ¶
func (fb Framebuffer) ClearDepth(d float32)
func (Framebuffer) Delete ¶
func (fb Framebuffer) Delete()
func (Framebuffer) DrawBuffer ¶
func (fb Framebuffer) DrawBuffer(a FramebufferAttachment)
func (Framebuffer) DrawBuffers ¶
func (fb Framebuffer) DrawBuffers(a []FramebufferAttachment)
func (Framebuffer) ReadBuffer ¶
func (fb Framebuffer) ReadBuffer(a FramebufferAttachment)
func (Framebuffer) Renderbuffer ¶
func (fb Framebuffer) Renderbuffer(a FramebufferAttachment, r Renderbuffer)
func (Framebuffer) SetEmptySize ¶
func (fb Framebuffer) SetEmptySize(w, h int16)
func (Framebuffer) Texture ¶
func (fb Framebuffer) Texture(a FramebufferAttachment, t Texture2D, level int32)
type FramebufferAttachment ¶
const ( ColorAttachment0 FramebufferAttachment = C.GL_COLOR_ATTACHMENT0 ColorAttachment1 FramebufferAttachment = C.GL_COLOR_ATTACHMENT1 ColorAttachment2 FramebufferAttachment = C.GL_COLOR_ATTACHMENT2 ColorAttachment3 FramebufferAttachment = C.GL_COLOR_ATTACHMENT3 DepthAttachment FramebufferAttachment = C.GL_DEPTH_ATTACHMENT StencilAttachment FramebufferAttachment = C.GL_STENCIL_ATTACHMENT DepthStencilAttachment FramebufferAttachment = C.GL_DEPTH_STENCIL_ATTACHMENT NoAttachment FramebufferAttachment = C.GL_NONE )
type FramebufferStatus ¶
const ( FramebufferComplete FramebufferStatus = C.GL_FRAMEBUFFER_COMPLETE FramebufferUndefined FramebufferStatus = C.GL_FRAMEBUFFER_UNDEFINED FramebufferIncompleteAttachment FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT FramebufferIncompleteMissingAttachment FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT FramebufferIncompleteDrawBuffer FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER FramebufferIncompleteReadBuffer FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER FramebufferUnsupported FramebufferStatus = C.GL_FRAMEBUFFER_UNSUPPORTED FramebufferIncompleteMultisample FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE FramebufferIncompleteLayerTargets FramebufferStatus = C.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS )
func (FramebufferStatus) String ¶
func (fbs FramebufferStatus) String() string
type FramebufferTarget ¶
const ( DrawFramebuffer FramebufferTarget = C.GL_DRAW_FRAMEBUFFER ReadFramebuffer FramebufferTarget = C.GL_READ_FRAMEBUFFER DrawReadFramebuffer FramebufferTarget = C.GL_FRAMEBUFFER )
type IndexBuffer ¶
type IndexBuffer struct {
// contains filtered or unexported fields
}
An IndexBuffer is a block of memory owned by the GPU, used to store vertex indices.
func NewIndexBuffer ¶
func NewIndexBuffer(data interface{}, f BufferFlags) IndexBuffer
NewIndexBuffer asks the GPU to allocate a new block of memory.
If data is a uinptr, it is interpreted as the desired size for the buffer (in bytes), and the content is not initialized. Otherwise data must be a slice of uint8, uint16 or uin32. In all cases the size of the buffer is fixed at creation.
func (*IndexBuffer) SubData ¶
func (eb *IndexBuffer) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type IndirectBuffer ¶
type IndirectBuffer struct {
// contains filtered or unexported fields
}
An IndirectBuffer is a block of memory owned by the GPU.
func NewIndirectBuffer ¶
func NewIndirectBuffer(data interface{}, f BufferFlags) IndirectBuffer
NewIndirectBuffer asks the GPU to allocate a new block of memory.
If data is a ¶
In all cases the size of the buffer is fixed at creation.
func (*IndirectBuffer) Bind ¶
func (ib *IndirectBuffer) Bind()
Bind the indirect buffer.
The buffer should use the same struct type than the one used in the corresponding call to Pipeline.IndirectFormat.
func (*IndirectBuffer) SubData ¶
func (ib *IndirectBuffer) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type Option ¶
type Option = func() error
An Option represents a configuration option used to change some parameters of the framework: see cozely.Configure.
type Pipeline ¶
type Pipeline struct {
// contains filtered or unexported fields
}
A Pipeline consists of shaders and state for the GPU.
func NewPipeline ¶
func NewPipeline(o ...PipelineConfig) *Pipeline
NewPipeline returns a pipeline with created from a specific set of shaders.
type PipelineConfig ¶
type PipelineConfig func(*Pipeline)
A PipelineConfig represents a configuration option used when creating a new pipeline.
func ComputeShader ¶
func ComputeShader(r io.Reader) PipelineConfig
ComputeShader compiles a comput shader.
func CullFace ¶
func CullFace(front, back bool) PipelineConfig
CullFace specifies if front and/or back faces are culled.
See also `FrontFace`.
func DepthClamp ¶
func DepthClamp(enable bool) PipelineConfig
func DepthComparison ¶
func DepthComparison(op ComparisonOp) PipelineConfig
DepthComparison specifies the function used to compare pixel depth.
Note that you must also `Enable(DepthTest)`. The default value is `Less`.
func DepthTest ¶
func DepthTest(enable bool) PipelineConfig
func DepthWrite ¶
func DepthWrite(enable bool) PipelineConfig
func FragmentShader ¶
func FragmentShader(r io.Reader) PipelineConfig
FragmentShader compiles a fragment shader.
func FrontFace ¶
func FrontFace(d WindingDirection) PipelineConfig
FrontFace specifies which winding direction is considered front.
See also `CullFace`.
func GeometryShader ¶
func GeometryShader(r io.Reader) PipelineConfig
GeometryShader compiles a geometry shader.
func PrimitiveRestart ¶
func PrimitiveRestart(enable bool) PipelineConfig
func RasterizerDiscard ¶
func RasterizerDiscard(enable bool) PipelineConfig
func Shader ¶
func Shader(path string) PipelineConfig
Shader compiles a shader. The path is slash-separated, and the file extension determine the type of shader:
- ".vert" for a vertex shader - ".frag" for a fragment shader - ".comp" for a compute shader - ".geom" for a geometry shader - ".tesc" for a tesselation control shader - ".tese" for a tesselation evaluation shader
func ShareShadersWith ¶
func ShareShadersWith(other *Pipeline) PipelineConfig
func ShareVertexFormatsWith ¶
func ShareVertexFormatsWith(other *Pipeline) PipelineConfig
func StencilTest ¶
func StencilTest(enable bool) PipelineConfig
func TessControlShader ¶
func TessControlShader(r io.Reader) PipelineConfig
TessControlShader compiles a tesselation control shader.
func TessEvaluationShader ¶
func TessEvaluationShader(r io.Reader) PipelineConfig
TessEvaluationShader compiles a tesselation evaluation shader.
func Topology ¶
func Topology(m Primitive) PipelineConfig
func VertexFormat ¶
func VertexFormat(binding uint32, format interface{}) PipelineConfig
VertexFormat prepares everything the pipeline needs to use a vertex buffer of a specific format, and assign a binding index to it.
The format must be a slice of struct, and the struct must have with layout tags.
func VertexShader ¶
func VertexShader(r io.Reader) PipelineConfig
VertexShader compiles a vertex shader.
type Primitive ¶
A Primitive specifies what kind of object to draw.
const ( Points Primitive = C.GL_POINTS Lines Primitive = C.GL_LINES LineLoop Primitive = C.GL_LINE_LOOP LineStrip Primitive = C.GL_LINE_STRIP Triangles Primitive = C.GL_TRIANGLES TriangleStrip Primitive = C.GL_TRIANGLE_STRIP TriangleFan Primitive = C.GL_TRIANGLE_FAN LinesAdjency Primitive = C.GL_LINES_ADJACENCY LineStripAdjency Primitive = C.GL_LINE_STRIP_ADJACENCY TrianglesAdjency Primitive = C.GL_TRIANGLES_ADJACENCY TriangleStripAdjency Primitive = C.GL_TRIANGLE_STRIP_ADJACENCY Patches Primitive = C.GL_PATCHES )
Used in `Topology`.
type Renderbuffer ¶
type Renderbuffer struct {
// contains filtered or unexported fields
}
A Renderbuffer is a two-dimensional texture that can only be used for rendering (attached a Framebuffer)
func NewRenderbuffer ¶
func NewRenderbuffer(f TextureFormat, width, height int32) Renderbuffer
NewRenderbuffer returns a new render buffer.
type Sampler ¶
type Sampler struct {
// contains filtered or unexported fields
}
A Sampler describes a way to sample textures inside shaders.
type SamplerOption ¶
type SamplerOption func(sa *Sampler)
A SamplerOption is a setting used when creating a new `Sampler`.
func Anisotropy ¶
func Anisotropy(max float32) SamplerOption
Anisotropy specifies the maximum anisotropy level.
func BorderColor ¶
func BorderColor(color struct{ R, G, B, A float32 }) SamplerOption
BorderColor sets the color used for texture filtering when ClampToborder wrapping mode is used.
func Comparison ¶
func Comparison(op ComparisonOp) SamplerOption
Comparison specifies the mode and operator used when comparing depth textures.
func LevelOfDetail ¶
func LevelOfDetail(min, max float32) SamplerOption
LevelOfDetail specifies the minimum and maximum LOD to use.
The default values are -1000 and 1000.
func Magnification ¶
func Magnification(fm FilterMode) SamplerOption
Magnification specifies which filter is used when minifying the texture.
The default value is `Linear`.
func Minification ¶
func Minification(fm FilterMode) SamplerOption
Minification specifies which filter is used when minifying the texture.
The default value is `NearestMipmapLinear`.
func Wrapping ¶
func Wrapping(s, t, p WrapMode) SamplerOption
Wrapping sets the wrapping modes for texture coordinates.
The default value is `Repeat` for all coordinates.
type StorageBuffer ¶
type StorageBuffer struct {
// contains filtered or unexported fields
}
A StorageBuffer is a block of memory owned by the GPU.
func NewStorageBuffer ¶
func NewStorageBuffer(data interface{}, f BufferFlags) StorageBuffer
NewStorageBuffer asks the GPU to allocate a new block of memory.
If data is a uinptr, it is interpreted as the desired size for the buffer (in bytes), and the content is not initialized. Otherwise data must be a pointer to a struct of pure values (no nested references). In all cases the size of the buffer is fixed at creation.
func (*StorageBuffer) Bind ¶
func (sb *StorageBuffer) Bind(binding uint32)
Bind to a storage binding index.
This index should correspond to one indicated by a layout qualifier in the shaders.
func (*StorageBuffer) ClearUint32 ¶
func (sb *StorageBuffer) ClearUint32(data uint32)
func (*StorageBuffer) SubData ¶
func (sb *StorageBuffer) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type Texture1D ¶
type Texture1D struct {
// contains filtered or unexported fields
}
A Texture1D is a one-dimensional texture.
func NewTexture1D ¶
func NewTexture1D(levels int32, f TextureFormat, width int32) Texture1D
NewTexture1D returns a new one-dimensional texture.
func (*Texture1D) GenerateMipmap ¶
func (t *Texture1D) GenerateMipmap()
GenerateMipmap generates mipmaps for the texture.
type Texture2D ¶
type Texture2D struct {
// contains filtered or unexported fields
}
A Texture2D is a two-dimensional texture.
func NewTexture2D ¶
func NewTexture2D(levels int32, f TextureFormat, width, height int32) Texture2D
NewTexture2D returns a new two-dimensional texture.
func (*Texture2D) BindImage ¶
func (t *Texture2D) BindImage(index uint32, level int32, a Access, f TextureFormat)
BindImage to an image unit.
func (*Texture2D) GenerateMipmap ¶
func (t *Texture2D) GenerateMipmap()
GenerateMipmap generates mipmaps for the texture.
type Texture3D ¶
type Texture3D struct {
// contains filtered or unexported fields
}
A Texture3D is a three-dimensional texture.
func NewTexture3D ¶
func NewTexture3D(levels int32, f TextureFormat, width, height, depth int32) Texture3D
NewTexture3D returns a new three-dimensional texture.
func (*Texture3D) GenerateMipmap ¶
func (t *Texture3D) GenerateMipmap()
GenerateMipmap generates mipmaps for the texture.
type TextureArray1D ¶
type TextureArray1D struct {
// contains filtered or unexported fields
}
A TextureArray1D is an array of one-dimensional textures.
func NewTextureArray1D ¶
func NewTextureArray1D(levels int32, f TextureFormat, width int32, count int32) TextureArray1D
NewTextureArray1D returns a new array of one-dimensional textures.
func (*TextureArray1D) GenerateMipmap ¶
func (t *TextureArray1D) GenerateMipmap()
GenerateMipmap generates mipmaps for the texture.
type TextureArray2D ¶
type TextureArray2D struct {
// contains filtered or unexported fields
}
A TextureArray2D is an array of two-dimensional textures.
func NewTextureArray2D ¶
func NewTextureArray2D(levels int32, f TextureFormat, width, height int32, count int32) TextureArray2D
NewTextureArray2D returns a new array of two-dimensional textures.
func (*TextureArray2D) GenerateMipmap ¶
func (t *TextureArray2D) GenerateMipmap()
GenerateMipmap generates mipmaps for the texture.
type TextureFormat ¶
A TextureFormat specifies the format used to store textures in memory.
const ( R8 TextureFormat = C.GL_R8 R16 TextureFormat = C.GL_R16 R16F TextureFormat = C.GL_R16F R32F TextureFormat = C.GL_R32F R8I TextureFormat = C.GL_R8I R16I TextureFormat = C.GL_R16I R32I TextureFormat = C.GL_R32I R8UI TextureFormat = C.GL_R8UI R16UI TextureFormat = C.GL_R16UI R32UI TextureFormat = C.GL_R32UI RG8 TextureFormat = C.GL_RG8 RG16 TextureFormat = C.GL_RG16 RG16F TextureFormat = C.GL_RG16F RG32F TextureFormat = C.GL_RG32F RG8I TextureFormat = C.GL_RG8I RG16I TextureFormat = C.GL_RG16I RG32I TextureFormat = C.GL_RG32I RG8UI TextureFormat = C.GL_RG8UI RG16UI TextureFormat = C.GL_RG16UI RG32UI TextureFormat = C.GL_RG32UI RGB32F TextureFormat = C.GL_RGB32F RGB32I TextureFormat = C.GL_RGB32I RGB32UI TextureFormat = C.GL_RGB32UI RGB8 TextureFormat = C.GL_RGB8 RGBA8 TextureFormat = C.GL_RGBA8 RGBA16 TextureFormat = C.GL_RGBA16 RGBA16F TextureFormat = C.GL_RGBA16F RGBA32F TextureFormat = C.GL_RGBA32F RGBA8I TextureFormat = C.GL_RGBA8I RGBA16I TextureFormat = C.GL_RGBA16I RGBA32I TextureFormat = C.GL_RGBA32I RGBA8UI TextureFormat = C.GL_RGBA8UI RGBA16UI TextureFormat = C.GL_RGBA16UI RGBA32UI TextureFormat = C.GL_RGBA32UI SRGBA8 TextureFormat = C.GL_SRGB8_ALPHA8 SRGB8 TextureFormat = C.GL_SRGB8 Depth16 TextureFormat = C.GL_DEPTH_COMPONENT16 Depth24 TextureFormat = C.GL_DEPTH_COMPONENT24 Depth32F TextureFormat = C.GL_DEPTH_COMPONENT32F )
Used in NewTexture1D, NewTexture2D...
type UniformBuffer ¶
type UniformBuffer struct {
// contains filtered or unexported fields
}
A UniformBuffer is a block of memory owned by the GPU.
func NewUniformBuffer ¶
func NewUniformBuffer(data interface{}, f BufferFlags) UniformBuffer
NewUniformBuffer asks the GPU to allocate a new block of memory.
If data is a uinptr, it is interpreted as the desired size for the buffer (in bytes), and the content is not initialized. Otherwise data must be a pointer to a struct of pure values (no nested references). In all cases the size of the buffer is fixed at creation.
func (*UniformBuffer) Bind ¶
func (ub *UniformBuffer) Bind(binding uint32)
Bind to a uniform binding index.
This index should correspond to one indicated by a layout qualifier in the shaders.
func (*UniformBuffer) SubData ¶
func (ub *UniformBuffer) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type VertexBuffer ¶
type VertexBuffer struct {
// contains filtered or unexported fields
}
A VertexBuffer is a block of memory owned by the GPU.
func NewVertexBuffer ¶
func NewVertexBuffer(data interface{}, f BufferFlags) VertexBuffer
NewVertexBuffer asks the GPU to allocate a new block of memory.
If data is a uinptr, it is interpreted as the desired size for the buffer (in bytes), and the content is not initialized. Otherwise data must be a slice of pure values (no nested references). In all cases the size of the buffer is fixed at creation.
func (*VertexBuffer) Bind ¶
func (vb *VertexBuffer) Bind(binding uint32, offset uintptr)
Bind to a vertex buffer binding index.
The buffer should use the same struct type than the one used in the corresponding call to Pipeline.VertexFormat.
func (*VertexBuffer) SubData ¶
func (vb *VertexBuffer) SubData(data interface{}, atOffset uintptr)
SubData updates the buffer with data, starting at a specified offset.
It is your responsibility to ensure that the size of data plus the offset does not exceed the buffer size.
type WindingDirection ¶
A WindingDirection specifies a rotation direction.
const ( Clockwise WindingDirection = C.GL_CW CounterClockwise WindingDirection = C.GL_CCW )
Used in `FrontFace`.
type WrapMode ¶
A WrapMode specifies the way a texture wraps.
const ( ClampToBorder WrapMode = C.GL_CLAMP_TO_BORDER ClampToEdge WrapMode = C.GL_CLAMP_TO_EDGE MirrorClampToEdge WrapMode = C.GL_MIRROR_CLAMP_TO_EDGE Repeat WrapMode = C.GL_REPEAT MirroredRepeat WrapMode = C.GL_MIRRORED_REPEAT )
Used in `Sampler.Wrap`.