Exemple #1
0
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,
	}
}
Exemple #2
0
/* Update transform matrix and right/up/forward vectors */
func (t *Transform) Update(dt float32) {
	// todo: avoid recalculating unless something has changed

	/* Update transform */
	rad := t.Rotation.Mul(math.Pi / 180.0) // translate rotaiton to radians
	rotation := mgl.AnglesToQuat(rad[0], rad[1], rad[2], mgl.XYZ).Mat4()
	scaling := mgl.Scale3D(t.Scale[0], t.Scale[1], t.Scale[2])
	translation := mgl.Translate3D(t.Position[0], t.Position[1], t.Position[2])

	/* New transform matrix: S * R * T */
	//m := scaling.Mul4(rotation.Mul4(translation))
	m := translation.Mul4(rotation.Mul4(scaling))

	/* Grab axis vectors from transformation matrix */
	t.Right[0] = m[4*0+0] // first column
	t.Right[1] = m[4*1+0]
	t.Right[2] = m[4*2+0]
	t.Up[0] = m[4*0+1] // second column
	t.Up[1] = m[4*1+1]
	t.Up[2] = m[4*2+1]
	t.Forward[0] = -m[4*0+2] // third column
	t.Forward[1] = -m[4*1+2]
	t.Forward[2] = -m[4*2+2]

	/* Update transformation matrix */
	t.Matrix = m
}
func TestStackMultiPush(t *testing.T) {
	stack := NewTransformStack()

	scale := mgl32.Scale3D(2, 2, 2)
	rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90))
	trans := mgl32.Translate3D(4, 5, 6)

	stack.Push(trans)
	stack.Push(rot)

	if !stack.Peek().ApproxEqualThreshold(trans.Mul4(rot), 1e-4) {
		t.Errorf("Stack does not multiply first two pushes correctly")
	}

	stack.Push(scale)

	if !stack.Peek().ApproxEqualThreshold(trans.Mul4(rot).Mul4(scale), 1e-4) {
		t.Errorf("Stack does not multiple third push correctly")
	}

	stack.Unwind(2)
	stack.Push(scale)

	if !stack.Peek().ApproxEqualThreshold(trans.Mul4(scale), 1e-4) {
		t.Errorf("Unwinding and multiplying does not work correctly")
	}
}
func ExampleRebase() {
	parent1 := NewTransformStack()

	scale := mgl32.Scale3D(2, 2, 2)
	rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90))
	trans := mgl32.Translate3D(5, 5, 5)

	parent1.Push(trans)
	parent1.Push(rot)
	parent1.Push(scale)

	parent2 := parent1.Copy()

	trans2 := mgl32.Translate3D(1, 1, 1)
	rot2 := mgl32.HomogRotate3DX(mgl32.DegToRad(45))
	parent1.Push(trans2)
	parent1.Push(rot2)

	// Replay the pushes the changes from parent1 after the copy onto parent2, as if
	// they had been done on parent2 instead
	parent2, err := Rebase(parent1, 4, parent2)

	if err != nil {
		panic(err)
	}

	// Now parent2 and parent 1 should be the same!
	fmt.Println(parent2.Peek().ApproxEqualThreshold(parent1.Peek(), 1e-4))
	// Output: true
}
Exemple #5
0
func onPaint(glctx gl.Context, sz size.Event) {

	glctx.Viewport(0, 0, sz.WidthPx, sz.HeightPx)
	glctx.ClearColor(0.5, 0.5, 0.5, 1)
	glctx.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

	glctx.UseProgram(program)

	projectionMtx = mgl32.Perspective(45, float32(width)/float32(height), 0.1, 100)

	arcBallMtx := arcball.getMtx()

	glctx.UniformMatrix4fv(projection, projectionMtx[:])

	glctx.UniformMatrix4fv(view, arcBallMtx[:])

	glctx.BindBuffer(gl.ARRAY_BUFFER, triBuf)
	glctx.EnableVertexAttribArray(position)
	glctx.EnableVertexAttribArray(color)
	glctx.EnableVertexAttribArray(normals)

	vertSize := 4 * (coordsPerVertex + colorPerVertex + normalsPerVertex)

	glctx.VertexAttribPointer(position, coordsPerVertex, gl.FLOAT, false, vertSize, 0)
	glctx.VertexAttribPointer(color, colorPerVertex, gl.FLOAT, false, vertSize, 4*coordsPerVertex)
	glctx.VertexAttribPointer(normals, normalsPerVertex, gl.FLOAT, false, vertSize, 4*(coordsPerVertex+colorPerVertex))

	glctx.DepthMask(true)

	glctx.Uniform3fv(lightPos, light.Pos[:])
	glctx.Uniform3fv(lightIntensity, light.Intensities[:])

	for _, k := range piano.Keys {
		glctx.Uniform4fv(tint, k.Color[:])

		mtx := k.GetMtx()
		normMat := mtx.Mat3().Inv().Transpose()
		glctx.UniformMatrix3fv(normalMatrix, normMat[:])
		glctx.UniformMatrix4fv(model, mtx[:])
		glctx.DrawArrays(gl.TRIANGLES, 0, len(triangleData)/vertSize)
	}

	modelMtx := mgl32.Ident4()
	modelMtx = modelMtx.Mul4(mgl32.Translate3D(worldPos.X(), worldPos.Y(), worldPos.Z()))
	modelMtx = modelMtx.Mul4(mgl32.Scale3D(0.5, 0.5, 0.5))

	/*
		glctx.Uniform4fv(tint, red[:])
		// Disable depthmask so we dont get the pixel depth of the cursor cube
		glctx.DepthMask(false)
		glctx.UniformMatrix4fv(model, modelMtx[:])
		glctx.DepthMask(true)
	*/

	glctx.DisableVertexAttribArray(position)
	glctx.DisableVertexAttribArray(color)
	glctx.DisableVertexAttribArray(normals)

	fps.Draw(sz)
}
Exemple #6
0
// GetTransformMat4 creates a transform matrix: scale * transform
func (r *Renderable) GetTransformMat4() mgl.Mat4 {
	scaleMat := mgl.Scale3D(r.Scale[0], r.Scale[1], r.Scale[2])
	transMat := mgl.Translate3D(r.Location[0], r.Location[1], r.Location[2])
	localRotMat := r.LocalRotation.Mat4()
	rotMat := r.Rotation.Mat4()
	modelTransform := rotMat.Mul4(transMat).Mul4(localRotMat).Mul4(scaleMat)
	return modelTransform
}
Exemple #7
0
func (t *Text) SetScale(s float32) (changed bool) {
	if s > t.ScaleMax || s < t.ScaleMin {
		return
	}
	changed = true
	t.Scale = s
	t.scaleMatrix = mgl32.Scale3D(s, s, s)
	return
}
Exemple #8
0
func (this *TextRenderer) TextTransform(vertex mathgl.Vec4) mathgl.Vec4 {
	// apply font transforms
	scale := float32(this.size) / 100.0
	t := mathgl.Translate3D(curTotWidth, 0, 0).Mul4x1(vertex)

	t = mathgl.Scale3D(scale, scale, 1).Mul4x1(t)

	return t
}
Exemple #9
0
func (t *Transform2D) Update(dt float32) {
	/* Update transform */
	rad := t.Rotation * math.Pi / 180.0
	rotation := mgl.AnglesToQuat(0, 0, rad, mgl.XYZ).Mat4()
	scaling := mgl.Scale3D(t.Scale[0], t.Scale[1], 1)
	translation := mgl.Translate3D(t.Position[0], t.Position[1], t.Position[2])

	/* New transform matrix: S * R * T */
	t.Matrix = scaling.Mul4(rotation.Mul4(translation))
}
Exemple #10
0
func (t *Text) AddScale(s float32) (changed bool) {
	if s < 0 && t.Scale <= t.ScaleMin {
		return
	}
	if s > 0 && t.Scale >= t.ScaleMax {
		return
	}
	changed = true
	t.Scale += s
	t.scaleMatrix = mgl32.Scale3D(t.Scale, t.Scale, t.Scale)
	return
}
Exemple #11
0
func (c Context) DrawRectangle(x, y, w, h float32, color Color) {

	gl.UseProgram(c.program)
	model := mgl32.Translate3D(x, y, 0).Mul4(mgl32.Scale3D(w, h, 0))
	modelUniform := gl.GetUniformLocation(c.program, gl.Str("model\x00"))
	gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])

	colorArray := []float32{color.B, color.G, color.R}

	colorUniform := gl.GetUniformLocation(c.program, gl.Str("color\x00"))
	gl.Uniform4fv(colorUniform, 1, &colorArray[0])

	gl.DrawArrays(gl.TRIANGLES, 0, 6)
}
Exemple #12
0
func (k PianoKey) GetMtx() mgl32.Mat4 {
	axis := mgl32.Vec3{1, 0, 0}
	keyLen := float32(2.0)
	if !k.white {
		keyLen = 1.0
	}
	modelMtx := mgl32.Ident4()
	modelMtx = modelMtx.Mul4(mgl32.Translate3D(k.Pos[0], k.Pos[1], k.Pos[2]-2))
	modelMtx = modelMtx.Mul4(mgl32.HomogRotate3D(k.Angle, axis))
	modelMtx = modelMtx.Mul4(mgl32.Translate3D(0, 0, keyLen))
	modelMtx = modelMtx.Mul4(mgl32.Scale3D(0.5, 0.5, keyLen))

	return modelMtx
}
// Render renders the bitmap with the center at given position
func (renderable *SimpleBitmapRenderable) Render(context *RenderContext, icons []PlacedIcon) {
	gl := renderable.gl

	renderable.withShader(func() {
		renderable.setMatrix(renderable.viewMatrixUniform, context.ViewMatrix())
		renderable.setMatrix(renderable.projectionMatrixUniform, context.ProjectionMatrix())

		gl.EnableVertexAttribArray(uint32(renderable.vertexPositionAttrib))
		gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.vertexPositionBuffer)
		gl.VertexAttribOffset(uint32(renderable.vertexPositionAttrib), 3, opengl.FLOAT, false, 0, 0)
		gl.EnableVertexAttribArray(uint32(renderable.uvPositionAttrib))
		gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.uvPositionBuffer)
		gl.VertexAttribOffset(uint32(renderable.uvPositionAttrib), 3, opengl.FLOAT, false, 0, 0)

		textureUnit := int32(0)
		gl.ActiveTexture(opengl.TEXTURE0 + uint32(textureUnit))
		gl.BindTexture(opengl.TEXTURE_2D, renderable.paletteTexture.Handle())
		gl.Uniform1i(renderable.paletteUniform, textureUnit)

		textureUnit = 1
		gl.ActiveTexture(opengl.TEXTURE0 + uint32(textureUnit))
		gl.Uniform1i(renderable.bitmapUniform, textureUnit)
		for _, icon := range icons {
			x, y := icon.Center()
			u, v := icon.Icon().UV()
			width, height := renderable.limitedSize(icon)
			modelMatrix := mgl.Ident4().
				Mul4(mgl.Translate3D(x, y, 0.0)).
				Mul4(mgl.Scale3D(width, height, 1.0))

			renderable.setMatrix(renderable.modelMatrixUniform, &modelMatrix)

			var uv = []float32{
				0.0, 0.0, 0.0,
				u, 0.0, 0.0,
				u, v, 0.0,

				u, v, 0.0,
				0.0, v, 0.0,
				0.0, 0.0, 0.0}
			gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.uvPositionBuffer)
			gl.BufferData(opengl.ARRAY_BUFFER, len(uv)*4, uv, opengl.STATIC_DRAW)

			gl.BindTexture(opengl.TEXTURE_2D, icon.Icon().Handle())
			gl.DrawArrays(opengl.TRIANGLES, 0, 6)
		}
		gl.BindTexture(opengl.TEXTURE_2D, 0)
	})
}
// NewTextureRenderable returns a new instance of a texture renderable
func NewTextureRenderable(gl opengl.OpenGl, positionX, positionY float32, displaySize float32,
	paletteTexture graphics.Texture, bitmapTexture graphics.Texture) *TextureRenderable {
	vertexShader, err1 := opengl.CompileNewShader(gl, opengl.VERTEX_SHADER, textureVertexShaderSource)
	defer gl.DeleteShader(vertexShader)
	fragmentShader, err2 := opengl.CompileNewShader(gl, opengl.FRAGMENT_SHADER, textureFragmentShaderSource)
	defer gl.DeleteShader(fragmentShader)
	program, _ := opengl.LinkNewProgram(gl, vertexShader, fragmentShader)

	if err1 != nil {
		fmt.Fprintf(os.Stderr, "Failed to compile shader 1:\n", err1)
	}
	if err2 != nil {
		fmt.Fprintf(os.Stderr, "Failed to compile shader 2:\n", err2)
	}

	renderable := &TextureRenderable{
		gl:      gl,
		program: program,
		modelMatrix: mgl.Ident4().
			Mul4(mgl.Translate3D(positionX, positionY, 0.0)).
			Mul4(mgl.Scale3D(displaySize, displaySize, 1.0)),

		vertexArrayObject:       gl.GenVertexArrays(1)[0],
		vertexPositionBuffer:    gl.GenBuffers(1)[0],
		vertexPositionAttrib:    gl.GetAttribLocation(program, "vertexPosition"),
		modelMatrixUniform:      gl.GetUniformLocation(program, "modelMatrix"),
		viewMatrixUniform:       gl.GetUniformLocation(program, "viewMatrix"),
		projectionMatrixUniform: gl.GetUniformLocation(program, "projectionMatrix"),
		paletteTexture:          paletteTexture,
		paletteUniform:          gl.GetUniformLocation(program, "palette"),
		bitmapTexture:           bitmapTexture,
		bitmapUniform:           gl.GetUniformLocation(program, "bitmap")}

	renderable.withShader(func() {
		gl.BindBuffer(opengl.ARRAY_BUFFER, renderable.vertexPositionBuffer)
		limit := float32(1.0)
		var vertices = []float32{
			0.0, 0.0, 0.0,
			limit, 0.0, 0.0,
			limit, limit, 0.0,

			limit, limit, 0.0,
			0.0, limit, 0.0,
			0.0, 0.0, 0.0}
		gl.BufferData(opengl.ARRAY_BUFFER, len(vertices)*4, vertices, opengl.STATIC_DRAW)
	})

	return renderable
}
Exemple #15
0
func NewFloor(shader Shader, reflected ...Drawable) Drawable {
	floor := NewStaticShape()
	floor.vertices = floorVertices
	floor.normals = floorNormals
	floor.Buffer()
	flipped := mgl.Scale3D(1, -1, 1)
	return &Floor{
		Node: Node{
			Shape:     floor,
			transform: &flipped,
			shader:    shader,
		},
		reflected: reflected,
	}
}
Exemple #16
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
}
Exemple #17
0
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
}
Exemple #18
0
// DrawFrame will draw the sprite in the x,y and z with the specified frame from a spritesheet
func (sprite *Sprite) DrawFrame(x float32, y float32, z float32, scale float32, frame int) {

	model := mgl32.Translate3D(x, y, z)
	model = model.Mul4(mgl32.Scale3D(scale, scale, 1))
	// remember this is in radians!
	// model = model.Mul4(mgl32.HomogRotate3D(mgl32.DegToRad(90), mgl32.Vec3{0, 0, 1}))
	if shader := shader.GetActive(); shader != nil {
		gl.UniformMatrix4fv(shader.Model, 1, false, &model[0])
	}

	gl.BindVertexArray(sprite.vao)

	sprite.image.Bind()

	gl.DrawArrays(gl.TRIANGLES, int32(frame*6), 6)
}
Exemple #19
0
// Scale scales the coordinate system in two dimensions. By default the coordinate system
/// in amore corresponds to the display pixels in horizontal and vertical directions
// one-to-one, and the x-axis increases towards the right while the y-axis increases
// downwards. Scaling the coordinate system changes this relation. After scaling by
// sx and sy, all coordinates are treated as if they were multiplied by sx and sy.
// Every result of a drawing operation is also correspondingly scaled, so scaling by
// (2, 2) for example would mean making everything twice as large in both x- and y-directions. Scaling by a negative value flips the coordinate system in the corresponding direction, which also means everything will be drawn flipped or upside down, or both. Scaling by zero is not a useful operation.
// Scale and translate are not commutative operations, therefore, calling them
// in different orders will change the outcome. Scaling lasts until drawing completes
func Scale(args ...float32) {
	if args == nil || len(args) == 0 {
		panic("not enough params passed to scale call")
	}
	var sx, sy float32
	sx = args[0]
	if len(args) > 1 {
		sy = args[1]
	} else {
		sy = sx
	}

	gl_state.viewStack.LeftMul(mgl32.Scale3D(sx, sy, 1))

	states.back().pixelSize *= (2.0 / (mgl32.Abs(sx) + mgl32.Abs(sy)))
}
func TestReseed(t *testing.T) {
	stack := NewTransformStack()

	scale := mgl32.Scale3D(2, 2, 2)
	rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90))
	trans := mgl32.Translate3D(4, 5, 6)

	stack.Push(trans)
	stack.Push(rot)
	stack.Push(scale)

	trans2 := mgl32.Translate3D(1, 2, 3)
	err := stack.Reseed(1, trans2)

	if err != nil {
		t.Fatalf("Rebase returned error when it should not %v", err)
	}

	if !stack.Peek().ApproxEqualThreshold(trans2.Mul4(rot).Mul4(scale), 1e-4) {
		t.Fatalf("Rebase does not remultiply correctly. Got\n %v expected\n %v. (Previous state:\n %v)", stack.Peek(), trans2.Mul4(rot).Mul4(scale), trans.Mul4(rot).Mul4(scale))
	}
}
func TestRebase(t *testing.T) {
	stack := NewTransformStack()
	stack2 := NewTransformStack()

	scale := mgl32.Scale3D(2, 2, 2)
	rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90))
	trans := mgl32.Translate3D(4, 5, 6)
	trans2 := mgl32.Translate3D(1, 2, 3)

	stack.Push(trans)
	stack.Push(rot)

	stack2.Push(trans2)
	stack2.Push(scale)

	out, _ := Rebase(stack2, 1, stack)

	if !out.Peek().ApproxEqualThreshold(trans.Mul4(rot).Mul4(trans2).Mul4(scale), 1e-4) {
		t.Log("\n", out)
		t.Errorf("Rebase unsuccessful. Got\n %v, expected\n %v", out.Peek(), trans.Mul4(rot).Mul4(trans2).Mul4(scale))
	}
}
// Render renders the highlight.
func (highlighter *BasicHighlighter) Render(context *RenderContext, areas []Area) {
	gl := highlighter.gl

	highlighter.withShader(func() {
		highlighter.setMatrix(highlighter.viewMatrixUniform, context.ViewMatrix())
		highlighter.setMatrix(highlighter.projectionMatrixUniform, context.ProjectionMatrix())

		gl.BindBuffer(opengl.ARRAY_BUFFER, highlighter.vertexPositionBuffer)
		gl.VertexAttribOffset(uint32(highlighter.vertexPositionAttrib), 3, opengl.FLOAT, false, 0, 0)

		for _, area := range areas {
			x, y := area.Center()
			width, height := area.Size()
			modelMatrix := mgl.Ident4().
				Mul4(mgl.Translate3D(x, y, 0.0)).
				Mul4(mgl.Scale3D(width, height, 1.0))

			highlighter.setMatrix(highlighter.modelMatrixUniform, &modelMatrix)
			gl.DrawArrays(opengl.TRIANGLES, 0, 6)
		}
	})
}
func ExampleReseed() {
	stack := NewTransformStack()

	scale := mgl32.Scale3D(2, 2, 2)
	rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90))
	trans := mgl32.Translate3D(4, 5, 6)

	stack.Push(trans)
	stack.Push(rot)
	stack.Push(scale)

	fmt.Println("Initial state:\n", stack.Peek())

	trans2 := mgl32.Translate3D(1, 2, 3)

	err := stack.Reseed(1, trans2)
	if err == nil {
		panic("Rebase failed")
	}

	fmt.Println("After rebase:\n", stack.Peek())
	fmt.Println("Should be:\n", trans2.Mul4(rot).Mul4(scale))
}
// NewTextRenderable returns a new instance of a text renderable
func NewTextRenderable(gl opengl.OpenGl, positionX, positionY float32, displaySize float32,
	paletteTexture graphics.Texture) *TextRenderable {
	vertexShader, err1 := opengl.CompileNewShader(gl, opengl.VERTEX_SHADER, textVertexShaderSource)
	defer gl.DeleteShader(vertexShader)
	fragmentShader, err2 := opengl.CompileNewShader(gl, opengl.FRAGMENT_SHADER, textFragmentShaderSource)
	defer gl.DeleteShader(fragmentShader)
	program, _ := opengl.LinkNewProgram(gl, vertexShader, fragmentShader)

	if err1 != nil {
		fmt.Fprintf(os.Stderr, "Failed to compile shader 1:\n", err1)
	}
	if err2 != nil {
		fmt.Fprintf(os.Stderr, "Failed to compile shader 2:\n", err2)
	}

	renderable := &TextRenderable{
		gl:      gl,
		program: program,
		modelMatrix: mgl.Ident4().
			Mul4(mgl.Translate3D(positionX, positionY, 0.0)).
			Mul4(mgl.Scale3D(displaySize, displaySize, 1.0)),

		vertexArrayObject:       gl.GenVertexArrays(1)[0],
		vertexPositionBuffer:    gl.GenBuffers(1)[0],
		vertexPositionAttrib:    gl.GetAttribLocation(program, "vertexPosition"),
		uvPositionBuffer:        gl.GenBuffers(1)[0],
		uvPositionAttrib:        gl.GetAttribLocation(program, "uvPosition"),
		modelMatrixUniform:      gl.GetUniformLocation(program, "modelMatrix"),
		viewMatrixUniform:       gl.GetUniformLocation(program, "viewMatrix"),
		projectionMatrixUniform: gl.GetUniformLocation(program, "projectionMatrix"),
		paletteTexture:          paletteTexture,
		paletteUniform:          gl.GetUniformLocation(program, "palette"),
		bitmapUniform:           gl.GetUniformLocation(program, "bitmap"),
		text:                    ""}

	return renderable
}
func (cam *LimitedCamera) updateViewMatrix() {
	scaleFactor := cam.scaleFactor()
	cam.viewMatrix = mgl.Ident4().
		Mul4(mgl.Scale3D(scaleFactor, scaleFactor, 1.0)).
		Mul4(mgl.Translate3D(cam.viewOffsetX, cam.viewOffsetY, 0))
}
Exemple #26
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
}
Exemple #27
0
func (cube *Cube) Scale(scaleX, scaleY, scaleZ float32) {
	cube.Model = cube.Model.Mul4(mgl32.Scale3D(scaleX, scaleY, scaleZ))
}
Exemple #28
0
// Draw draws a single frame
func Draw(width, height int, delta float64) {
	tickAnimatedTextures(delta)
	frameID++
sync:
	for {
		select {
		case f := <-syncChan:
			f()
		default:
			break sync
		}
	}

	// Only update the viewport if the window was resized
	if lastHeight != height || lastWidth != width || lastFOV != FOV.Value() {
		lastWidth = width
		lastHeight = height
		lastFOV = FOV.Value()

		perspectiveMatrix = mgl32.Perspective(
			(math.Pi/180)*float32(lastFOV),
			float32(width)/float32(height),
			0.1,
			500.0,
		)
		gl.Viewport(0, 0, width, height)
		frustum.SetPerspective(
			(math.Pi/180)*float32(lastFOV),
			float32(width)/float32(height),
			0.1,
			500.0,
		)
		initTrans()
	}

	mainFramebuffer.Bind()
	gl.Enable(gl.Multisample)

	gl.ActiveTexture(0)
	glTexture.Bind(gl.Texture2DArray)

	gl.ClearColor(ClearColour.R, ClearColour.G, ClearColour.B, 1.0)
	gl.Clear(gl.ColorBufferBit | gl.DepthBufferBit)

	chunkProgram.Use()

	viewVector = mgl32.Vec3{
		float32(math.Cos(Camera.Yaw-math.Pi/2) * -math.Cos(Camera.Pitch)),
		float32(-math.Sin(Camera.Pitch)),
		float32(-math.Sin(Camera.Yaw-math.Pi/2) * -math.Cos(Camera.Pitch)),
	}
	cam := mgl32.Vec3{-float32(Camera.X), -float32(Camera.Y), float32(Camera.Z)}
	cameraMatrix = mgl32.LookAtV(
		cam,
		cam.Add(mgl32.Vec3{-viewVector.X(), -viewVector.Y(), viewVector.Z()}),
		mgl32.Vec3{0, -1, 0},
	)
	cameraMatrix = cameraMatrix.Mul4(mgl32.Scale3D(-1.0, 1.0, 1.0))

	frustum.SetCamera(
		cam,
		cam.Add(mgl32.Vec3{-viewVector.X(), -viewVector.Y(), viewVector.Z()}),
		mgl32.Vec3{0, -1, 0},
	)

	shaderChunk.PerspectiveMatrix.Matrix4(&perspectiveMatrix)
	shaderChunk.CameraMatrix.Matrix4(&cameraMatrix)
	shaderChunk.Texture.Int(0)
	shaderChunk.LightLevel.Float(LightLevel)
	shaderChunk.SkyOffset.Float(SkyOffset)

	chunkPos := position{
		X: int(Camera.X) >> 4,
		Y: int(Camera.Y) >> 4,
		Z: int(Camera.Z) >> 4,
	}
	nearestBuffer = buffers[chunkPos]

	for _, dir := range direction.Values {
		validDirs[dir] = viewVector.Dot(dir.AsVec()) > -0.8
	}

	renderOrder = renderOrder[:0]
	renderBuffer(nearestBuffer, chunkPos, direction.Invalid, delta)

	drawLines()
	drawModels()
	clouds.tick(delta)

	chunkProgramT.Use()
	shaderChunkT.PerspectiveMatrix.Matrix4(&perspectiveMatrix)
	shaderChunkT.CameraMatrix.Matrix4(&cameraMatrix)
	shaderChunkT.Texture.Int(0)
	shaderChunkT.LightLevel.Float(LightLevel)
	shaderChunkT.SkyOffset.Float(SkyOffset)

	// Copy the depth buffer
	mainFramebuffer.BindRead()
	transFramebuffer.BindDraw()
	gl.BlitFramebuffer(
		0, 0, lastWidth, lastHeight,
		0, 0, lastWidth, lastHeight,
		gl.DepthBufferBit, gl.Nearest,
	)

	gl.Enable(gl.Blend)
	gl.DepthMask(false)
	transFramebuffer.Bind()
	gl.ClearColor(0, 0, 0, 1)
	gl.Clear(gl.ColorBufferBit)
	gl.ClearBuffer(gl.Color, 0, []float32{0, 0, 0, 1})
	gl.ClearBuffer(gl.Color, 1, []float32{0, 0, 0, 0})
	gl.BlendFuncSeparate(gl.OneFactor, gl.OneFactor, gl.ZeroFactor, gl.OneMinusSrcAlpha)
	for _, chunk := range renderOrder {
		if chunk.countT > 0 && chunk.bufferT.IsValid() {
			shaderChunkT.Offset.Int3(chunk.X, chunk.Y*4096-chunk.Y*int(4096*(1-chunk.progress)), chunk.Z)

			chunk.arrayT.Bind()
			gl.DrawElements(gl.Triangles, chunk.countT, elementBufferType, 0)
		}
	}

	gl.UnbindFramebuffer()
	gl.Disable(gl.DepthTest)
	gl.Clear(gl.ColorBufferBit)
	gl.Disable(gl.Blend)

	transDraw()

	gl.Enable(gl.DepthTest)
	gl.DepthMask(true)
	gl.BlendFunc(gl.SrcAlpha, gl.OneMinusSrcAlpha)
	gl.Disable(gl.Multisample)

	drawUI()

	if debugFramebuffers.Value() {
		gl.Enable(gl.Multisample)
		blitBuffers()
		gl.Disable(gl.Multisample)
	}
}
Exemple #29
0
//SetScale reset this transform to represent only the scaling transform of `amount`
//I do not allow non-uniform scaling to prevent ending up with matrices without an inverse.
func (t *Transform) SetScale(amount float32) {
	t.LocalToWorld = glm.Scale3D(amount, amount, amount)
}
Exemple #30
0
//Scale add a scaling operation to the currently stored transform.
//I do not allow non-uniform scaling to prevent ending up with matrices without an inverse.
func (t *Transform) Scale(amount float32) {
	t.LocalToWorld = t.LocalToWorld.Mul4(glm.Scale3D(amount, amount, amount))
}