func (a AABB) RotateY(an, ox, oy, oz float32) AABB { mat := mgl32.Rotate3DY(an) o := mgl32.Vec3{ox, oy, oz} a.Max = mat.Mul3x1(a.Max.Sub(o)).Add(o) a.Min = mat.Mul3x1(a.Min.Sub(o)).Add(o) a.fixBounds() return a }
func (this *Transform) GetUpdatedModel() mathgl.Mat4 { Model := this.model Model = Model.Mul4(mathgl.Translate3D(float32(this.X), float32(this.Y), float32(this.Z))) // Model = Model.Mul4(mathgl.HomogRotate3DZ(float32(s.rot))) // Model = Model.Mul4(mathgl.HomogRotate3D(s.Rot, mathgl.Vec3{s.XR, s.YR, s.ZR})) // Euler rotation is easy.. no quaternions yet.. what a pain. Model = Model.Mul4(mathgl.Rotate3DX(this.XR * this.Rot).Mat4()) Model = Model.Mul4(mathgl.Rotate3DY(this.YR * this.Rot).Mat4()) Model = Model.Mul4(mathgl.Rotate3DZ(this.ZR * this.Rot).Mat4()) Model = Model.Mul4(mathgl.Scale3D(float32(this.XS), float32(this.YS), float32(this.ZS))) return Model }
func programLoop(window *win.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/phong.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/phong.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() lightFragShader, err := gfx.NewShaderFromFile("shaders/light.frag", gl.FRAGMENT_SHADER) if err != nil { return err } // special shader program so that lights themselves are not affected by lighting lightProgram, err := gfx.NewProgram(vertShader, lightFragShader) if err != nil { return err } VAO := createVAO(cubeVertices, nil) lightVAO := createVAO(cubeVertices, nil) // ensure that triangles that are "behind" others do not draw over top of them gl.Enable(gl.DEPTH_TEST) camera := cam.NewFpsCamera(mgl32.Vec3{0, 0, 3}, mgl32.Vec3{0, 1, 0}, -90, 0, window.InputManager()) for !window.ShouldClose() { // swaps in last buffer, polls for window events, and generally sets up for a new render frame window.StartFrame() // update camera position and direction from input evevnts camera.Update(window.SinceLastFrame()) // background color gl.ClearColor(0, 0, 0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // depth buffer needed for DEPTH_TEST // cube rotation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-45 * float32(glfw.GetTime())))) // creates perspective fov := float32(60.0) projectTransform := mgl32.Perspective(mgl32.DegToRad(fov), float32(window.Width())/float32(window.Height()), 0.1, 100.0) camTransform := camera.GetTransform() lightPos := mgl32.Vec3{0.6, 1, 0.1} lightTransform := mgl32.Translate3D(lightPos.X(), lightPos.Y(), lightPos.Z()).Mul4( mgl32.Scale3D(0.2, 0.2, 0.2)) program.Use() gl.UniformMatrix4fv(program.GetUniformLocation("view"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.BindVertexArray(VAO) // draw each cube after all coordinate system transforms are bound // obj is colored, light is white gl.Uniform3f(program.GetUniformLocation("material.ambient"), 1.0, 0.5, 0.31) gl.Uniform3f(program.GetUniformLocation("material.diffuse"), 1.0, 0.5, 0.31) gl.Uniform3f(program.GetUniformLocation("material.specular"), 0.5, 0.5, 0.5) gl.Uniform1f(program.GetUniformLocation("material.shininess"), 32.0) lightColor := mgl32.Vec3{ float32(math.Sin(glfw.GetTime() * 1)), float32(math.Sin(glfw.GetTime() * 0.35)), float32(math.Sin(glfw.GetTime() * 0.65)), } diffuseColor := mgl32.Vec3{ 0.5 * lightColor[0], 0.5 * lightColor[1], 0.5 * lightColor[2], } ambientColor := mgl32.Vec3{ 0.2 * lightColor[0], 0.2 * lightColor[1], 0.2 * lightColor[2], } gl.Uniform3f(program.GetUniformLocation("light.ambient"), ambientColor[0], ambientColor[1], ambientColor[2]) gl.Uniform3f(program.GetUniformLocation("light.diffuse"), diffuseColor[0], diffuseColor[1], diffuseColor[2]) gl.Uniform3f(program.GetUniformLocation("light.specular"), 1.0, 1.0, 1.0) gl.Uniform3f(program.GetUniformLocation("light.position"), lightPos.X(), lightPos.Y(), lightPos.Z()) for _, pos := range cubePositions { // turn the cubes into rectangular prisms for more fun worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := worldTranslate.Mul4( rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4(), ) gl.UniformMatrix4fv(program.GetUniformLocation("model"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } gl.BindVertexArray(0) // Draw the light obj after the other boxes using its separate shader program // this means that we must re-bind any uniforms lightProgram.Use() gl.BindVertexArray(lightVAO) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("model"), 1, false, &lightTransform[0]) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("view"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(lightProgram.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) gl.BindVertexArray(0) // end of draw loop } return nil }
func programLoop(window *glfw.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/basic.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/basic.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() vertices := []float32{ // position // texture position -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5, 0.0, 1.0, } indices := []uint32{} VAO := createVAO(vertices, indices) texture0, err := gfx.NewTextureFromFile("../images/RTS_Crate.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } texture1, err := gfx.NewTextureFromFile("../images/trollface-transparent.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } cubePositions := [][]float32{ []float32{0.0, 0.0, -3.0}, []float32{2.0, 5.0, -15.0}, []float32{-1.5, -2.2, -2.5}, []float32{-3.8, -2.0, -12.3}, []float32{2.4, -0.4, -3.5}, []float32{-1.7, 3.0, -7.5}, []float32{1.3, -2.0, -2.5}, []float32{1.5, 2.0, -2.5}, []float32{1.5, 0.2, -1.5}, []float32{-1.3, 1.0, -1.5}, } gl.Enable(gl.DEPTH_TEST) for !window.ShouldClose() { // poll events and call their registered callbacks glfw.PollEvents() // background color gl.ClearColor(0.2, 0.5, 0.5, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // draw vertices program.Use() // set texture0 to uniform0 in the fragment shader texture0.Bind(gl.TEXTURE0) texture0.SetUniform(program.GetUniformLocation("ourTexture0")) // set texture1 to uniform1 in the fragment shader texture1.Bind(gl.TEXTURE1) texture1.SetUniform(program.GetUniformLocation("ourTexture1")) // update shader transform matrices // Create transformation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) viewTransform := mgl32.Translate3D(0, 0, -3) projectTransform := mgl32.Perspective(mgl32.DegToRad(60), windowWidth/windowHeight, 0.1, 100.0) gl.UniformMatrix4fv(program.GetUniformLocation("view"), 1, false, &viewTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateX"), 1, false, &rotateX[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateY"), 1, false, &rotateY[0]) gl.UniformMatrix4fv(program.GetUniformLocation("worldRotateZ"), 1, false, &rotateZ[0]) gl.BindVertexArray(VAO) for _, pos := range cubePositions { worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := (worldTranslate.Mul4(rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4())) gl.UniformMatrix4fv(program.GetUniformLocation("world"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } // gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, unsafe.Pointer(nil)) gl.BindVertexArray(0) texture0.UnBind() texture1.UnBind() // end of draw loop // swap in the rendered buffer window.SwapBuffers() } return nil }
func esPlayerModelTick(p *playerModelComponent, pos PositionComponent, t *targetPositionComponent, r RotationComponent) { x, y, z := pos.Position() model := p.model model.X, model.Y, model.Z = -float32(x), -float32(y), float32(z) if p.heldModel != nil { p.heldModel.X, p.heldModel.Y, p.heldModel.Z = -float32(x), -float32(y), float32(z) p.heldModel.BlockLight, p.heldModel.SkyLight = p.model.BlockLight, p.model.SkyLight } offMat := mgl32.Translate3D(float32(x), -float32(y), float32(z)). Mul4(mgl32.Rotate3DY(math.Pi - float32(r.Yaw())).Mat4()) if p.cape != "" { if t.stillTime < 5.0 { if p.capeTime < 30 { p.capeTime += Client.delta } else { p.capeTime = 30 } } else { if p.capeTime > 0 { p.capeTime -= Client.delta } else { p.capeTime = 0 } } p.model.Matrix[playerModelCape] = offMat.Mul4(mgl32.Translate3D(0, -24/16.0, 2/16.0)). Mul4(mgl32.Rotate3DX(float32(p.capeTime)/60.0 + 0.05).Mat4()) } // TODO This isn't the most optimal way of doing this if p.hasNameTag { val := math.Atan2(x-render.Camera.X, z-render.Camera.Z) model.Matrix[playerModelNameTag] = mgl32.Translate3D(float32(x), -float32(y), float32(z)). Mul4(mgl32.Translate3D(0, -12/16.0-12/16.0-0.6, 0)). Mul4(mgl32.Rotate3DY(float32(val)).Mat4()) } model.Matrix[playerModelHead] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-12/16.0, 0)). Mul4(mgl32.Rotate3DX(float32(r.Pitch())).Mat4()) model.Matrix[playerModelBody] = offMat.Mul4(mgl32.Translate3D(0, -12/16.0-6/16.0, 0)) time := p.time dir := p.dir if dir == 0 { dir = 1 time = 15 } ang := ((time / 15) - 1) * (math.Pi / 4) model.Matrix[playerModelLegRight] = offMat.Mul4(mgl32.Translate3D(2/16.0, -12/16.0, 0)). Mul4(mgl32.Rotate3DX(float32(ang)).Mat4()) model.Matrix[playerModelLegLeft] = offMat.Mul4(mgl32.Translate3D(-2/16.0, -12/16.0, 0)). Mul4(mgl32.Rotate3DX(-float32(ang)).Mat4()) iTime := p.idleTime iTime += Client.delta * 0.02 if iTime > math.Pi*2 { iTime -= math.Pi * 2 } p.idleTime = iTime if p.armTime <= 0 { p.armTime = 0 } else { p.armTime -= Client.delta } model.Matrix[playerModelArmRight] = offMat.Mul4(mgl32.Translate3D(6/16.0, -12/16.0-12/16.0, 0)) model.Matrix[playerModelArmRight] = model.Matrix[playerModelArmRight]. Mul4(mgl32.Rotate3DX(-float32(ang * 0.75)).Mat4()). Mul4(mgl32.Rotate3DZ(float32(math.Cos(iTime)*0.06) - 0.06).Mat4()). Mul4(mgl32.Rotate3DX(float32(math.Sin(iTime)*0.06) - float32((7.5-math.Abs(p.armTime-7.5))/7.5)).Mat4()) if p.heldModel != nil { p.heldModel.Matrix[0] = offMat.Mul4(mgl32.Translate3D(6/16.0, -12/16.0-12/16.0, 0.0)). Mul4(mgl32.Rotate3DX(-float32(ang * 0.75)).Mat4()). Mul4(mgl32.Rotate3DZ(float32(math.Cos(iTime)*0.06) - 0.06).Mat4()). Mul4(mgl32.Rotate3DX(float32(math.Sin(iTime)*0.06) - float32((7.5-math.Abs(p.armTime-7.5))/7.5)).Mat4()). Mul4(mgl32.Translate3D(0, 11/16.0, -5/16.0)). Mul4(mgl32.Rotate3DX(math.Pi).Mat4()). Mul4(p.heldMat) } model.Matrix[playerModelArmLeft] = offMat.Mul4(mgl32.Translate3D(-6/16.0, -12/16.0-12/16.0, 0)). Mul4(mgl32.Rotate3DX(float32(ang * 0.75)).Mat4()). Mul4(mgl32.Rotate3DZ(-float32(math.Cos(iTime)*0.06) + 0.06).Mat4()). Mul4(mgl32.Rotate3DX(-float32(math.Sin(iTime) * 0.06)).Mat4()) update := true if (!p.manualMove && t.X == t.sX && t.Y == t.sY && t.Z == t.sZ) || (p.manualMove && !p.walking) { if t.stillTime > 5.0 { if math.Abs(time-15) <= 1.5*Client.delta { time = 15 update = false } dir = math.Copysign(1, 15-time) } else { t.stillTime += Client.delta } } else { t.stillTime = 0 } if update { time += Client.delta * 1.5 * dir if time > 30 { time = 30 dir = -1 } else if time < 0 { time = 0 dir = 1 } } p.dir = dir p.time = time }
func (s *signComponent) create() { const yS = (6.0 / 16.0) / 4.0 const xS = yS / 16.0 var verts []*render.StaticVertex for i, line := range s.lines { if line.Value == nil { continue } format.ConvertLegacy(line) // Hijack ui.Formatted's component parsing to split // up components into ui.Text elements. // TODO(Think) Move this into some common place for // easier reuse in other places? wrap := &format.TextComponent{} wrap.Color = format.Black wrap.Extra = []format.AnyComponent{line} f := ui.NewFormatted(format.Wrap(wrap), 0, 0) offset := 0.0 for _, txt := range f.Text { str := txt.Value() for _, r := range str { tex := render.CharacterTexture(r) if tex == nil { continue } s := render.SizeOfCharacter(r) if r == ' ' { offset += (s + 2) * xS continue } for _, v := range faceVertices[direction.North].verts { vert := &render.StaticVertex{ X: float32(v.X)*float32(s*xS) - float32(offset+s*xS) + float32(f.Width*xS*0.5), Y: float32(v.Y)*yS - yS*float32(i-1), Z: -.6 / 16.0, Texture: tex, TextureX: float64(v.TOffsetX), TextureY: float64(v.TOffsetY), R: byte(txt.R()), G: byte(txt.G()), B: byte(txt.B()), A: 255, } verts = append(verts, vert) } offset += (s + 2) * xS } } } wood := render.GetTexture("blocks/planks_oak") // The backboard verts = appendBoxExtra(verts, -0.5, -4/16.0, -0.5/16.0, 1.0, 8/16.0, 1/16.0, [6]render.TextureInfo{ direction.Up: wood.Sub(0, 0, 16, 2), direction.Down: wood.Sub(0, 0, 16, 2), direction.East: wood.Sub(0, 0, 2, 12), direction.West: wood.Sub(0, 0, 2, 12), direction.North: wood.Sub(0, 4, 16, 12), direction.South: wood.Sub(0, 4, 16, 12), }, [6][2]float64{ direction.Up: {1.5, 1.0}, direction.Down: {1.5, 1.0}, direction.East: {1.0, 1.0}, direction.West: {1.0, 1.0}, direction.North: {1.5, 1.0}, direction.South: {1.5, 1.0}, }) if s.hasStand { // Stand log := render.GetTexture("blocks/log_oak") verts = appendBox(verts, -0.5/16.0, -0.25-9/16.0, -0.5/16.0, 1/16.0, 9/16.0, 1/16.0, [6]render.TextureInfo{ direction.Up: log.Sub(0, 0, 2, 2), direction.Down: log.Sub(0, 0, 2, 2), direction.East: log.Sub(0, 0, 2, 12), direction.West: log.Sub(0, 0, 2, 12), direction.North: log.Sub(0, 0, 2, 12), direction.South: log.Sub(0, 0, 2, 12), }) } s.model = render.NewStaticModel([][]*render.StaticVertex{ verts, }) s.model.Radius = 2 x, y, z := s.position.X, s.position.Y, s.position.Z s.model.X, s.model.Y, s.model.Z = -float32(x)-0.5, -float32(y)-0.5, float32(z)+0.5 s.model.Matrix[0] = mgl32.Translate3D( float32(x)+0.5, -float32(y)-0.5, float32(z)+0.5, ).Mul4(mgl32.Rotate3DY(float32(s.rotation)).Mat4()). Mul4(mgl32.Translate3D(float32(s.ox), float32(-s.oy), float32(s.oz))) }
func modelToUI(mdl *model, block Block) *ui.Model { mat := mgl32.Ident4() if gui, ok := mdl.display["gui"]; ok { if gui.Scale != nil { mat = mat.Mul4(mgl32.Scale3D( float32(gui.Scale[0]), float32(gui.Scale[1]), float32(gui.Scale[2]), )) } if gui.Translation != nil { mat = mat.Mul4(mgl32.Translate3D( float32(gui.Translation[0]/16), float32(gui.Translation[1]/16), float32(gui.Translation[2]/16), )) } if gui.Rotation != nil { mat = mat.Mul4(mgl32.Rotate3DX(float32(gui.Rotation[0]/180) * math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DZ(float32(gui.Rotation[2]/180) * math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DY(float32(gui.Rotation[1]/180) * math.Pi).Mat4()) } } var verts []*ui.ModelVertex p := precomputeModel(mdl) for _, f := range p.faces { var cr, cg, cb byte cr = 255 cg = 255 cb = 255 if block != nil && block.TintImage() != nil { switch f.tintIndex { case 0: bi := biome.Plains ix := bi.ColorIndex & 0xFF iy := bi.ColorIndex >> 8 col := block.TintImage().NRGBAAt(ix, iy) cr = byte(col.R) cg = byte(col.G) cb = byte(col.B) } } if f.facing == direction.East || f.facing == direction.West { cr = byte(float64(cr) * 0.8) cg = byte(float64(cg) * 0.8) cb = byte(float64(cb) * 0.8) } if f.facing == direction.North || f.facing == direction.South { cr = byte(float64(cr) * 0.6) cg = byte(float64(cg) * 0.6) cb = byte(float64(cb) * 0.6) } for _, vert := range f.vertices { vert := &ui.ModelVertex{ X: vert.X, Y: vert.Y, Z: vert.Z, TOffsetX: vert.TOffsetX, TOffsetY: vert.TOffsetY, R: cr, G: cg, B: cb, A: 255, TX: vert.TX, TY: vert.TY, TW: vert.TW, TH: vert.TH, TAtlas: vert.TAtlas, } verts = append(verts, vert) } } return ui.NewModel(0, 0, verts, mat) }
func staticModelFromItem(mdl *model, block Block, mode string) (out []*render.StaticVertex, mat mgl32.Mat4) { mat = mgl32.Ident4() if gui, ok := mdl.display[mode]; ok { if gui.Scale != nil { mat = mat.Mul4(mgl32.Scale3D( float32(gui.Scale[0]), float32(gui.Scale[1]), float32(gui.Scale[2]), )) } if gui.Translation != nil { mat = mat.Mul4(mgl32.Translate3D( float32(gui.Translation[0]/32), float32(gui.Translation[1]/32), float32(gui.Translation[2]/32), )) } if gui.Rotation != nil { mat = mat.Mul4(mgl32.Rotate3DX(float32(gui.Rotation[0]/180) * math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DZ(float32(gui.Rotation[2]/180) * math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DY(float32(gui.Rotation[1]/180) * math.Pi).Mat4()) } } mat = mat.Mul4(mgl32.Rotate3DZ(-math.Pi / 4).Mat4()) mat = mat.Mul4(mgl32.Rotate3DX(-math.Pi / 4).Mat4()) p := precomputeModel(mdl) for fi := range p.faces { f := p.faces[len(p.faces)-1-fi] var cr, cg, cb byte cr = 255 cg = 255 cb = 255 if block != nil && block.TintImage() != nil { switch f.tintIndex { case 0: bi := biome.Plains ix := bi.ColorIndex & 0xFF iy := bi.ColorIndex >> 8 col := block.TintImage().NRGBAAt(ix, iy) cr = byte(col.R) cg = byte(col.G) cb = byte(col.B) } } if f.facing == direction.East || f.facing == direction.West { cr = byte(float64(cr) * 0.8) cg = byte(float64(cg) * 0.8) cb = byte(float64(cb) * 0.8) } if f.facing == direction.North || f.facing == direction.South { cr = byte(float64(cr) * 0.6) cg = byte(float64(cg) * 0.6) cb = byte(float64(cb) * 0.6) } for i, vert := range f.vertices { vX, vY, vZ := vert.X, vert.Y, vert.Z tex := f.verticesTexture[i] rect := tex.Rect() vert := &render.StaticVertex{ X: vX - 0.5, Y: vY - 0.5, Z: vZ - 0.5, Texture: tex, TextureX: float64(vert.TOffsetX) / float64(16*rect.Width), TextureY: float64(vert.TOffsetY) / float64(16*rect.Height), R: cr, G: cg, B: cb, A: 255, } out = append(out, vert) } } return }
func genStaticModelFromItem(mdl *model, block Block, mode string) (out []*render.StaticVertex, mat mgl32.Mat4) { mat = mgl32.Rotate3DZ(math.Pi).Mat4(). Mul4(mgl32.Rotate3DY(math.Pi / 2).Mat4()). Mul4(mgl32.Rotate3DZ(-math.Pi / 2).Mat4()) if gui, ok := mdl.display[mode]; ok { if gui.Scale != nil { mat = mat.Mul4(mgl32.Scale3D( float32(gui.Scale[0]), float32(gui.Scale[1]), float32(gui.Scale[2]), )) } if gui.Translation != nil { mat = mat.Mul4(mgl32.Translate3D( float32(gui.Translation[0]/32), float32(gui.Translation[1]/32), float32(gui.Translation[2]/32), )) } if gui.Rotation != nil { mat = mat.Mul4(mgl32.Rotate3DX(math.Pi + float32(gui.Rotation[0]/180)*math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DZ(math.Pi + float32(gui.Rotation[2]/180)*math.Pi).Mat4()) mat = mat.Mul4(mgl32.Rotate3DY(float32(gui.Rotation[1]/180) * math.Pi).Mat4()) } } mat = mat.Mul4(mgl32.Rotate3DY(math.Pi / 2).Mat4()) mat = mat.Mul4(mgl32.Translate3D(-1/16.0, 0, 0)) tex := render.GetTexture("solid") rect := tex.Rect() tName, plugin := mdl.textureVars["layer0"], "minecraft" if pos := strings.IndexRune(tName, ':'); pos != -1 { plugin = tName[:pos] tName = tName[pos:] } f, err := resource.Open(plugin, "textures/"+tName+".png") if err != nil { return } defer f.Close() img, err := png.Decode(f) if err != nil { panic(err) } w, h := img.Bounds().Dx(), img.Bounds().Dy() sx := 1 / float32(w) sy := 1 / float32(h) isSolid := func(x, y int) bool { col := img.At(x, y) _, _, _, aa := col.RGBA() if aa == 0 { return false } return true } for x := 0; x < w; x++ { for y := 0; y < h; y++ { col := img.At(x, y) rr, gg, bb, aa := col.RGBA() if aa == 0 { continue } for i, f := range faceVertices { facing := direction.Type(i) if facing != direction.North && facing != direction.South { xx, yy, _ := facing.Offset() if isSolid(x+xx, y+yy) { continue } } var cr, cg, cb byte cr = byte(rr >> 8) cg = byte(gg >> 8) cb = byte(bb >> 8) if facing == direction.East || facing == direction.West { cr = byte(float64(cr) * 0.8) cg = byte(float64(cg) * 0.8) cb = byte(float64(cb) * 0.8) } if facing == direction.North || facing == direction.South { cr = byte(float64(cr) * 0.6) cg = byte(float64(cg) * 0.6) cb = byte(float64(cb) * 0.6) } for _, vert := range f.verts { vX, vY, vZ := float32(vert.X), float32(vert.Y), float32(vert.Z) vert := &render.StaticVertex{ Y: vY*sy - 0.5 + sy*float32(y), X: vX*sx - 0.5 + sx*float32(x), Z: (vZ - 0.5) * (1.0 / 16.0), Texture: tex, TextureX: float64(vert.TOffsetX) / float64(16*rect.Width), TextureY: float64(vert.TOffsetY) / float64(16*rect.Height), R: cr, G: cg, B: cb, A: byte(aa >> 8), } out = append(out, vert) } } } } return }
func (s *skullComponent) create() { var skin render.TextureInfo if s.SkullType == skullPlayer && s.OwnerSkin != nil { skin = s.OwnerSkin } else { switch s.SkullType { case skullPlayer: skin = render.RelativeTexture(render.GetTexture("entity/steve"), 64, 64) case skullZombie: skin = render.RelativeTexture(render.GetTexture("entity/zombie/zombie"), 64, 64) case skullSkeleton: skin = render.RelativeTexture(render.GetTexture("entity/skeleton/skeleton"), 64, 32) case skullWitherSkeleton: skin = render.RelativeTexture(render.GetTexture("entity/skeleton/wither_skeleton"), 64, 32) case skullCreeper: skin = render.RelativeTexture(render.GetTexture("entity/creeper/creeper"), 64, 32) } } var hverts []*render.ModelVertex // Base layer hverts = appendBox(hverts, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(8, 8, 8, 8), direction.South: skin.Sub(24, 8, 8, 8), direction.East: skin.Sub(0, 8, 8, 8), direction.West: skin.Sub(16, 8, 8, 8), direction.Up: skin.Sub(8, 0, 8, 8), direction.Down: skin.Sub(16, 0, 8, 8), }) // Hat layer hverts = appendBox(hverts, -4.2/16.0, -.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(8+32, 8, 8, 8), direction.South: skin.Sub(24+32, 8, 8, 8), direction.East: skin.Sub(0+32, 8, 8, 8), direction.West: skin.Sub(16+32, 8, 8, 8), direction.Up: skin.Sub(8+32, 0, 8, 8), direction.Down: skin.Sub(16+32, 0, 8, 8), }) s.model = render.NewModel([][]*render.ModelVertex{ hverts, }) model := s.model model.Radius = 2 x, y, z := s.position.X, s.position.Y, s.position.Z model.X, model.Y, model.Z = -float32(x)-0.5, -float32(y), float32(z)+0.5 mat := mgl32.Translate3D(float32(x)+0.5, -float32(y), float32(z)+0.5) if s.Facing == direction.Up { mat = mat.Mul4(mgl32.Rotate3DY(-(math.Pi / 8) * float32(s.Rotation)).Mat4()) } else { ang := float32(0) switch s.Facing { case direction.South: ang = math.Pi case direction.East: ang = math.Pi / 2 case direction.West: ang = -math.Pi / 2 } mat = mat.Mul4(mgl32.Rotate3DY(ang).Mat4()) mat = mat.Mul4(mgl32.Translate3D(0, -4/16.0, 4/16.0)) } model.Matrix[0] = mat }
func programLoop(window *win.Window) error { // the linked shader program determines how the data will be rendered vertShader, err := gfx.NewShaderFromFile("shaders/basic.vert", gl.VERTEX_SHADER) if err != nil { return err } fragShader, err := gfx.NewShaderFromFile("shaders/basic.frag", gl.FRAGMENT_SHADER) if err != nil { return err } program, err := gfx.NewProgram(vertShader, fragShader) if err != nil { return err } defer program.Delete() VAO := createVAO(cubeVertices, nil) texture0, err := gfx.NewTextureFromFile("../images/RTS_Crate.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } texture1, err := gfx.NewTextureFromFile("../images/trollface-transparent.png", gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE) if err != nil { panic(err.Error()) } // ensure that triangles that are "behind" others do not draw over top of them gl.Enable(gl.DEPTH_TEST) camera := cam.NewFpsCamera(mgl32.Vec3{0, 0, 3}, mgl32.Vec3{0, 1, 0}, -90, 0, window.InputManager()) for !window.ShouldClose() { // swaps in last buffer, polls for window events, and generally sets up for a new render frame window.StartFrame() // update camera position and direction from input evevnts camera.Update(window.SinceLastFrame()) // background color gl.ClearColor(0.2, 0.5, 0.5, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // depth buffer needed for DEPTH_TEST program.Use() // bind textures texture0.Bind(gl.TEXTURE0) texture0.SetUniform(program.GetUniformLocation("ourTexture0")) texture1.Bind(gl.TEXTURE1) texture1.SetUniform(program.GetUniformLocation("ourTexture1")) // cube rotation matrices rotateX := (mgl32.Rotate3DX(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateY := (mgl32.Rotate3DY(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) rotateZ := (mgl32.Rotate3DZ(mgl32.DegToRad(-60 * float32(glfw.GetTime())))) // creates perspective fov := float32(60.0) projectTransform := mgl32.Perspective(mgl32.DegToRad(fov), float32(window.Width())/float32(window.Height()), 0.1, 100.0) camTransform := camera.GetTransform() gl.UniformMatrix4fv(program.GetUniformLocation("camera"), 1, false, &camTransform[0]) gl.UniformMatrix4fv(program.GetUniformLocation("project"), 1, false, &projectTransform[0]) gl.BindVertexArray(VAO) // draw each cube after all coordinate system transforms are bound for _, pos := range cubePositions { worldTranslate := mgl32.Translate3D(pos[0], pos[1], pos[2]) worldTransform := (worldTranslate.Mul4(rotateX.Mul3(rotateY).Mul3(rotateZ).Mat4())) gl.UniformMatrix4fv(program.GetUniformLocation("world"), 1, false, &worldTransform[0]) gl.DrawArrays(gl.TRIANGLES, 0, 36) } gl.BindVertexArray(0) texture0.UnBind() texture1.UnBind() // end of draw loop } return nil }