Exemplo n.º 1
0
// newFBO will generate a new Frame Buffer Object for use with the canvas
func newFBO(texture gl.Texture) (gl.Framebuffer, uint32) {
	// get currently bound fbo to reset to it later
	current_fbo := gl.GetBoundFramebuffer()

	framebuffer := gl.CreateFramebuffer()
	gl.BindFramebuffer(gl.FRAMEBUFFER, framebuffer)
	if texture.Valid() {
		gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0)
		// Initialize the texture to transparent black.
		gl.ClearColor(0.0, 0.0, 0.0, 0.0)
		gl.Clear(gl.COLOR_BUFFER_BIT)
	}
	status := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)

	// unbind framebuffer
	gl.BindFramebuffer(gl.FRAMEBUFFER, current_fbo)

	return framebuffer, uint32(status)
}
Exemplo n.º 2
0
// checkCreateStencil if a stencil is set on a canvas then we need to create
// some buffers to handle this.
func (canvas *Canvas) checkCreateStencil() bool {
	// Do nothing if we've already created the stencil buffer.
	if canvas.depth_stencil.Valid() {
		return true
	}

	if gl_state.currentCanvas != canvas {
		gl.BindFramebuffer(gl.FRAMEBUFFER, canvas.fbo)
	}

	format := gl.STENCIL_INDEX8
	attachment := gl.STENCIL_ATTACHMENT

	canvas.depth_stencil = gl.CreateRenderbuffer()
	gl.BindRenderbuffer(gl.RENDERBUFFER, canvas.depth_stencil)
	gl.RenderbufferStorage(gl.RENDERBUFFER, gl.Enum(format), int(canvas.width), int(canvas.height))

	// Attach the stencil buffer to the framebuffer object.
	gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.Enum(attachment), gl.RENDERBUFFER, canvas.depth_stencil)
	gl.BindRenderbuffer(gl.RENDERBUFFER, gl.Renderbuffer{})

	success := (gl.CheckFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE)

	// We don't want the stencil buffer filled with garbage.
	if success {
		gl.Clear(gl.STENCIL_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	} else {
		gl.DeleteRenderbuffer(canvas.depth_stencil)
		canvas.depth_stencil = gl.Renderbuffer{}
	}

	if gl_state.currentCanvas != nil && gl_state.currentCanvas != canvas {
		gl.BindFramebuffer(gl.FRAMEBUFFER, gl_state.currentCanvas.fbo)
	} else if gl_state.currentCanvas == nil {
		gl.BindFramebuffer(gl.FRAMEBUFFER, getDefaultFBO())
	}

	return success
}
Exemplo n.º 3
0
// stopGrab will bind the context back to the default framebuffer and set back
// all the settings
func (canvas *Canvas) stopGrab(switchingToOtherCanvas bool) error {
	// i am not grabbing. leave me alone
	if gl_state.currentCanvas != canvas {
		return nil
	}
	gl_state.projectionStack.Pop()
	if !switchingToOtherCanvas {
		// bind system framebuffer.
		gl_state.currentCanvas = nil
		gl.BindFramebuffer(gl.FRAMEBUFFER, getDefaultFBO())
		SetViewport(canvas.systemViewport[0], canvas.systemViewport[1], canvas.systemViewport[2], canvas.systemViewport[3])
	}
	return nil
}
Exemplo n.º 4
0
// startGrab will bind this canvas to grab all drawing operations
// multiple canvases can only be passed in on non mobile platforms
func (canvas *Canvas) startGrab(canvases ...*Canvas) error {
	if gl_state.currentCanvas == canvas {
		return nil // already grabbing
	}

	if canvases != nil && len(canvases) > 0 {
		// Whether the new canvas list is different from the old one.
		// A more thorough check is done below.
		if maxRenderTargets < 4 {
			return fmt.Errorf("Multi-canvas rendering is not supported on this system.")
		}

		if int32(len(canvases)+1) > maxRenderTargets {
			return fmt.Errorf("This system can't simultaneously render to %v canvases.", len(canvases)+1)
		}

		for i := 0; i < len(canvases); i++ {
			if canvases[i].width != canvas.width || canvases[i].height != canvas.height {
				return fmt.Errorf("All canvases must have the same dimensions.")
			}
		}
	}

	// cleanup after previous Canvas
	if gl_state.currentCanvas != nil {
		canvas.systemViewport = gl_state.currentCanvas.systemViewport
		gl_state.currentCanvas.stopGrab(true)
	} else {
		canvas.systemViewport = GetViewport()
	}

	// indicate we are using this Canvas.
	gl_state.currentCanvas = canvas
	// bind the framebuffer object.
	gl.BindFramebuffer(gl.FRAMEBUFFER, canvas.fbo)
	SetViewport(0, 0, canvas.width, canvas.height)
	// Set up the projection matrix
	gl_state.projectionStack.Push()
	gl_state.projectionStack.Load(mgl32.Ortho(0.0, float32(screen_width), 0.0, float32(screen_height), -1, 1))

	canvas.attacheExtra(canvases)
	canvas.attachedCanvases = canvases

	return nil
}