Beispiel #1
0
func renderBoard(g *game.Game, fudge float32) bool {
	if g.Board == nil {
		return false
	}

	b := g.Board

	metrics := newMetrics(g, fudge)

	gl.UniformMatrix4fv(projectionViewMatrixUniform, 1, false, &perspectiveProjectionViewMatrix[0])
	gl.Uniform3fv(mixColorUniform, 1, &blackColor[0])

	globalGrayscale := float32(1)
	globalDarkness := float32(0.8)
	var boardDarkness float32

	gameEase := func(start, change float32) float32 {
		return easeOutCubic(g.StateProgress(fudge), start, change)
	}
	boardEase := func(start, change float32) float32 {
		return easeOutCubic(b.StateProgress(fudge), start, change)
	}

	switch g.State {
	case game.GamePlaying:
		globalGrayscale = gameEase(1, -1)
		globalDarkness = gameEase(0.8, -0.8)

	case game.GamePaused:
		globalGrayscale = gameEase(0, 1)
		globalDarkness = gameEase(0, 0.8)

	case game.GameExiting:
		globalGrayscale = 1
		globalDarkness = gameEase(0.8, 1)
	}

	switch b.State {
	case game.BoardEntering:
		boardDarkness = boardEase(1, -1)

	case game.BoardExiting:
		boardDarkness = boardEase(0, 1)
	}

	finalDarkness := globalDarkness
	if finalDarkness < boardDarkness {
		finalDarkness = boardDarkness
	}
	gl.Uniform1f(mixAmountUniform, finalDarkness)

	gl.Uniform1i(textureUniform, int32(boardTexture)-1)

	for i := 0; i <= 2; i++ {
		gl.Uniform1f(grayscaleUniform, globalGrayscale)
		gl.Uniform1f(brightnessUniform, 0)
		gl.Uniform1f(alphaUniform, 1)

		if i == 0 {
			renderSelector(metrics)
		}

		for y, r := range b.Rings {
			for x, c := range r.Cells {
				switch i {
				case 0: // draw opaque objects
					switch c.Block.State {
					case game.BlockStatic,
						game.BlockSwappingFromLeft,
						game.BlockSwappingFromRight,
						game.BlockDroppingFromAbove,
						game.BlockFlashing:
						renderCellBlock(metrics, c, x, y)

					case game.BlockCracking, game.BlockCracked:
						renderCellFragments(metrics, c, x, y)
					}

				case 1: // draw transparent objects
					switch c.Block.State {
					case game.BlockExploding:
						renderCellFragments(metrics, c, x, y)
					}
					renderMarker(metrics, c.Marker, x, y)
				}
			}
		}
	}

	// Render the spare rings.

	// Set brightness to zero for all spare rings.
	gl.Uniform1f(brightnessUniform, 0)

	for y, r := range b.SpareRings {
		// Set grayscale value. First spare rings becomes colored. Rest are gray.
		grayscale := float32(1)
		if y == 0 {
			grayscale = easeInExpo(b.RiseProgress(fudge), 1, -1)
		}
		if grayscale < globalGrayscale {
			grayscale = globalGrayscale
		}
		gl.Uniform1f(grayscaleUniform, grayscale)

		// Set alpha value. Last spare ring fades in. Rest are opaque.
		alpha := float32(1)
		if y == len(b.SpareRings)-1 {
			alpha = easeInExpo(b.RiseProgress(fudge), 0, 1)
		}
		gl.Uniform1f(alphaUniform, alpha)

		// Render the spare rings below the normal rings.
		for x, c := range r.Cells {
			renderCellBlock(metrics, c, x, y+b.RingCount)
		}
	}

	return true
}
Beispiel #2
0
func Init() error {
	if err := gl.Init(); err != nil {
		return err
	}

	log.Printf("OpenGL version: %s", gl.GoStr(gl.GetString(gl.VERSION)))

	vs, err := asset.String("shader.vert")
	if err != nil {
		return err
	}

	fs, err := asset.String("shader.frag")
	if err != nil {
		return err
	}

	program, err := createProgram(vs, fs)
	if err != nil {
		return err
	}
	gl.UseProgram(program)

	var shaderErr error
	uniform := func(name string) int32 {
		var loc int32
		loc, shaderErr = getUniformLocation(program, name)
		return loc
	}

	projectionViewMatrixUniform = uniform("u_projectionViewMatrix")
	modelMatrixUniform = uniform("u_modelMatrix")
	normalMatrixUniform = uniform("u_normalMatrix")
	ambientLightColorUniform = uniform("u_ambientLightColor")
	directionalLightColorUniform = uniform("u_directionalLightColor")
	directionalVectorUniform = uniform("u_directionalVector")
	textureUniform = uniform("u_texture")
	grayscaleUniform = uniform("u_grayscale")
	brightnessUniform = uniform("u_brightness")
	alphaUniform = uniform("u_alpha")
	mixColorUniform = uniform("u_mixColor")
	mixAmountUniform = uniform("u_mixAmount")

	if shaderErr != nil {
		return shaderErr
	}

	vm := newViewMatrix(cameraPosition, targetPosition, up)
	nm := vm.inverse().transpose()
	gl.UniformMatrix4fv(normalMatrixUniform, 1, false, &nm[0])

	gl.Uniform3fv(ambientLightColorUniform, 1, &ambientLightColor[0])
	gl.Uniform3fv(directionalLightColorUniform, 1, &directionalLightColor[0])
	gl.Uniform3fv(directionalVectorUniform, 1, &directionalVector[0])

	SizeCallback = func(width, height int) {
		if winWidth == width && winHeight == height {
			return
		}

		log.Printf("window size changed (%dx%d -> %dx%d)", int(winWidth), int(winHeight), width, height)
		gl.Viewport(0, 0, int32(width), int32(height))

		// Calculate new perspective projection view matrix.
		winWidth, winHeight = width, height
		fw, fh := float32(width), float32(height)
		aspect := fw / fh
		fovRadians := float32(math.Pi) / 3
		perspectiveProjectionViewMatrix = vm.mult(newPerspectiveMatrix(fovRadians, aspect, 1, 2000))

		// Calculate new ortho projection view matrix.
		orthoProjectionViewMatrix = newOrthoMatrix(fw, fh, fw /* use width as depth */)
	}

	if err := initMeshes(); err != nil {
		return err
	}

	if err := initTextures(); err != nil {
		return err
	}

	gl.Enable(gl.CULL_FACE)
	gl.CullFace(gl.BACK)

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.ClearColor(0, 0, 0, 0)

	return nil
}