func (c SpritesheetFrameConfig) ToSpritesheetFrame() *SpritesheetFrame { var ( texX = c.textureX / c.textureOriginalW texY = c.textureY / c.textureOriginalH texW = c.textureW / c.textureOriginalW texH = c.textureH / c.textureOriginalH ) var ( texMove = mgl32.Translate3D(texX, -texH-texY, 0.0) texScale = mgl32.Scale3D(texW, texH, 1.0) texRotate = mgl32.HomogRotate3DZ(mgl32.DegToRad(0)) texAdj = texMove.Mul4(texScale).Mul4(texRotate).Transpose() ) var ( ptScale = mgl32.Scale3D(c.sourceW/c.pxPerUnit, c.sourceH/c.pxPerUnit, 1.0) ptAdj = ptScale.Transpose() ) return &SpritesheetFrame{ Frame: FrameConfig{ PointAdjustment: ptAdj, TextureAdjustment: texAdj, }, Width: c.sourceW / c.pxPerUnit, Height: c.sourceH / c.pxPerUnit, } }
func init() { uvRotations = make(map[int]*mgl32.Mat4) for i := 0; i < 4; i++ { matrix := mgl32.Translate3D(0.5, 0.5, 0.0). Mul4(mgl32.HomogRotate3DZ(float32(math.Pi * float32(i) / 2.0))). Mul4(mgl32.Translate3D(-0.5, -0.5, 0.0)) uvRotations[i] = &matrix } }
func (r *BatchRenderer) Draw(batch *Batch, x, y, rot float32) error { batch.Texture.Bind() gl.BindBuffer(gl.ARRAY_BUFFER, batch.Buffer) gl.EnableVertexAttribArray(r.PositionLoc) gl.VertexAttribPointer(r.PositionLoc, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(r.TextureLoc) gl.VertexAttribPointer(r.TextureLoc, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) m := mgl32.Translate3D(x, y, 0.0).Mul4(mgl32.HomogRotate3DZ(rot)) gl.UniformMatrix4fv(r.ModelViewLoc, 1, false, &m[0]) gl.Uniform2f(r.TexOffsetLoc, batch.textureOffset.X(), batch.textureOffset.Y()) gl.DrawArrays(gl.TRIANGLES, 0, int32(batch.Count)) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return nil }
func (i *Instance) GetModel() mgl32.Mat4 { if i.dirty { var model mgl32.Mat4 model = mgl32.Translate3D( i.position.X(), i.position.Y(), i.position.Z(), ) model = model.Mul4(mgl32.HomogRotate3DZ(mgl32.DegToRad(i.rotation))) model = model.Mul4(mgl32.Scale3D(i.scale.X(), i.scale.Y(), i.scale.Z())) i.model = model i.dirty = false } return i.model }
func main() { vertices, normals := obj.Parse(os.Args[1]) // initialize GLFW if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() // set opengl core profile 3.3 glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(640, 480, "GOpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // initialise OpenGL library if err := gl.Init(); err != nil { panic(err) } // link program from shaders program, err := newProgram("vertex.glsl", "fragment.glsl") if err != nil { panic(err) } gl.UseProgram(program) // vertex attribute object holds links between attributes and vbo var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) // vertex buffer with per-vertex data var vbo [2]uint32 gl.GenBuffers(2, &vbo[0]) // position data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[0]) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) // set up position attribute with layout of vertices posAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00"))) gl.VertexAttribPointer(posAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(posAttrib) // normal data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[1]) gl.BufferData(gl.ARRAY_BUFFER, len(normals)*4, gl.Ptr(normals), gl.STATIC_DRAW) normAttrib := uint32(gl.GetAttribLocation(program, gl.Str("normal\x00"))) gl.VertexAttribPointer(normAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(normAttrib) uniModel := gl.GetUniformLocation(program, gl.Str("model\x00")) uniView := gl.GetUniformLocation(program, gl.Str("view\x00")) uniProj := gl.GetUniformLocation(program, gl.Str("proj\x00")) matView := mgl32.LookAt(2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0) gl.UniformMatrix4fv(uniView, 1, false, &matView[0]) matProj := mgl32.Perspective(mgl32.DegToRad(45.0), 640.0/480.0, 1.0, 10.0) gl.UniformMatrix4fv(uniProj, 1, false, &matProj[0]) uniLightDir := gl.GetUniformLocation(program, gl.Str("lightDir\x00")) uniLightCol := gl.GetUniformLocation(program, gl.Str("lightCol\x00")) gl.Uniform3f(uniLightDir, -0.5, 0.0, -1.0) gl.Uniform3f(uniLightCol, 0.0, 0.5, 0.5) startTime := glfw.GetTime() gl.Enable(gl.DEPTH_TEST) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { // clear buffer gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) matRot := mgl32.HomogRotate3DZ(float32(glfw.GetTime() - startTime)) gl.UniformMatrix4fv(uniModel, 1, false, &matRot[0]) gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices))) window.SwapBuffers() glfw.PollEvents() } }
func main() { glfw.SetErrorCallback(errorCallback) // lock glfw/gl calls to a single thread runtime.LockOSThread() runtime.GOMAXPROCS(8) // Render, read commands, send input, extra for file loading, etc if !glfw.Init() { panic("Could not init glfw!") } defer glfw.Terminate() glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True) glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile) window, err := glfw.CreateWindow(800, 600, "Example", nil, nil) if err != nil { panic(err) } window.SetFramebufferSizeCallback(func(w *glfw.Window, width, height int) { fmt.Printf("Framebuffer size is now %vx%v\n", width, height) // Keep aspect ratio from camwidth/camheight camRatio := camWidth / camHeight bufRatio := float32(width) / float32(height) var newWidth, newHeight float32 switch { case camRatio > bufRatio: newHeight = float32(width) / camRatio newWidth = float32(width) case bufRatio > camRatio: newWidth = float32(height) * camRatio newHeight = float32(height) } fmt.Printf("Viewport size is now %vx%v; cam ratio is %v; viewport ratio is %v;\n", newWidth, newHeight, camRatio, newWidth/newHeight) gl.Viewport((width-int(newWidth))/2, (height-int(newHeight))/2, int(newWidth), int(newHeight)) }) defer window.Destroy() window.MakeContextCurrent() glfw.SwapInterval(1) gl.Init() // Enable blending gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) vao := gl.GenVertexArray() vao.Bind() vbo := gl.GenBuffer() vbo.Bind(gl.ARRAY_BUFFER) verticies := []float32{-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5} gl.BufferData(gl.ARRAY_BUFFER, len(verticies)*4, verticies, gl.STATIC_DRAW) vertex_shader := gl.CreateShader(gl.VERTEX_SHADER) vertex_shader.Source(vertex) vertex_shader.Compile() fmt.Println(vertex_shader.GetInfoLog()) defer vertex_shader.Delete() fragment_shader := gl.CreateShader(gl.FRAGMENT_SHADER) fragment_shader.Source(fragment) fragment_shader.Compile() fmt.Println(fragment_shader.GetInfoLog()) defer fragment_shader.Delete() program := gl.CreateProgram() program.AttachShader(vertex_shader) program.AttachShader(fragment_shader) program.BindFragDataLocation(0, "outColor") program.Link() program.Use() defer program.Delete() positionAttrib := program.GetAttribLocation("position") positionAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil) positionAttrib.EnableArray() defer positionAttrib.DisableArray() modelMat := program.GetUniformLocation("modelView") projMat := program.GetUniformLocation("projection") spriteSize := program.GetUniformLocation("size") cmd := exec.Command(os.Args[1], os.Args[2:]...) stdoutReader, stdoutWriter := io.Pipe() cmd.Stdout = stdoutWriter input := bufio.NewReader(stdoutReader) stdinReader, stdinWriter := io.Pipe() cmd.Stdin = stdinReader stderr, err := cmd.StderrPipe() chkErr(err) go io.Copy(os.Stderr, stderr) err = cmd.Start() chkErr(err) window.SetKeyCallback(handleKey) go func() { runtime.LockOSThread() for !window.ShouldClose() { sendInput(stdinWriter) //fmt.Fprintf(stdinWriter, "T %v\n", time.Now()) <-ticks readCommands(input) } }() frameCnt := 0 queueDepth := 0 then := time.Now() for !window.ShouldClose() { frameCnt++ queueDepth += len(commandBus) if frameCnt%120 == 0 { fmt.Printf("Queue depth: %v. Render time: %v. Decode time: %v.\n", queueDepth/120, time.Since(then)/120, decodeTime/time.Duration(decodes)) queueDepth = 0 then = time.Now() decodeTime = time.Duration(0) decodes = 0 } for len(commandBus) > 0 { (<-commandBus)() } halfwidth := camWidth / 2.0 halfheight := camHeight / 2.0 projection := mathgl.Ortho2D(camera.x-halfwidth, camera.x+halfwidth, camera.y+halfheight, camera.y-halfheight) projection = mathgl.Scale3D(camera.sx, camera.sy, 1).Mul4(projection) projection = mathgl.HomogRotate3DZ(camera.rot).Mul4(projection) projMat.UniformMatrix4f(false, (*[16]float32)(&projection)) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) for _, sprite := range sprites { sMat := mathgl.Scale3D(sprite.sx, sprite.sy, 1) sMat = mathgl.HomogRotate3DZ(sprite.rot).Mul4(sMat) sMat = mathgl.Translate3D(sprite.x, sprite.y, sprite.z).Mul4(sMat) // temp hack bank in sprite.bank = 1 sMap := findSMap(sprite.smap) spriteSize.Uniform2f(float32(sMap.getWidth()*sprite.cellwidth), float32(sMap.getHeight()*sprite.cellheight)) modelMat.UniformMatrix4f(false, (*[16]float32)(&sMat)) gl.DrawArrays(gl.TRIANGLE_FAN, 0, 4) } window.SwapBuffers() glfw.PollEvents() if window.GetKey(glfw.KeyEscape) == glfw.Press { window.SetShouldClose(true) } } }
// Rotate rotates the coordinate system in two dimensions. Calling this function // affects all future drawing operations by rotating the coordinate system around // the origin by the given amount of radians. This change lasts until drawing completes func Rotate(angle float32) { gl_state.viewStack.LeftMul(mgl32.HomogRotate3DZ(angle)) }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Transform", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader 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]) gl.BindFragDataLocation(program, 0, gl.Str("vert\x00")) points := []float32{ -0.9, -0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, 0.9, 0.9, -0.9, 0.9, 0.9, 0.9, -0.9, 0.9, 0.9, } vertices := []uint32{ 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(0.0, 0.0, 0.0, 1.0) angleX := 0.0 angleY := 0.0 angleZ := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) time := glfw.GetTime() elapsed := time - previousTime previousTime = time angleX += math.Sin((elapsed / period) * math.Pi * 2.0) angleY += math.Sin((elapsed / period) / 6.0 * math.Pi * 2.0) angleZ += math.Sin((elapsed / period) / 3.0 * math.Pi * 2.0) model = mgl32.HomogRotate3DY(float32(angleY)).Mul4(mgl32.HomogRotate3DX(float32(angleX))).Mul4(mgl32.HomogRotate3DZ(float32(angleZ))) gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.DrawElements(gl.LINES, int32(len(vertices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }