Beispiel #1
0
func (a AABB) RotateX(an, ox, oy, oz float32) AABB {
	mat := mgl32.Rotate3DX(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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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)
}
Beispiel #7
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}