Example #1
0
func New() (*Renderer, error) {
	r := &Renderer{
		RenderExec:     make(chan func() bool, 1024),
		LoaderExec:     make(chan func(), 1024),
		renderComplete: make(chan struct{}, 8),
		wantFree:       make(chan struct{}, 1),
		clock:          clock.New(),
	}

	// MSAA is enabled by default.
	r.msaa.enabled = true

	// Initialize r.render now.
	r.render = gl.New()
	r.render.SetBatching(false)
	if !r.render.AtLeastVersion(2, 0) {
		return nil, ErrInvalidVersion
	}

	// Initialize r.loader now.
	r.loader = gl.New()
	r.loader.SetBatching(false)

	// Note: we don't need r.ctx.Lock() here because no other goroutines
	// can be using r.ctx yet since we haven't returned from New().

	// Find the renderer's precision.
	var redBits, greenBits, blueBits, alphaBits, depthBits, stencilBits int32
	r.render.GetIntegerv(gl.RED_BITS, &redBits)
	r.render.GetIntegerv(gl.GREEN_BITS, &greenBits)
	r.render.GetIntegerv(gl.BLUE_BITS, &blueBits)
	r.render.GetIntegerv(gl.ALPHA_BITS, &alphaBits)
	r.render.GetIntegerv(gl.DEPTH_BITS, &depthBits)
	r.render.GetIntegerv(gl.STENCIL_BITS, &stencilBits)
	r.render.Execute()

	r.precision.RedBits = uint8(redBits)
	r.precision.GreenBits = uint8(greenBits)
	r.precision.BlueBits = uint8(blueBits)
	r.precision.AlphaBits = uint8(alphaBits)
	r.precision.DepthBits = uint8(depthBits)
	r.precision.StencilBits = uint8(stencilBits)

	// Query whether we have the GL_ARB_framebuffer_object.
	r.glArbFramebufferObject = r.render.Extension("GL_ARB_framebuffer_object")

	// Query whether we have the GL_ARB_occlusion_query.
	r.glArbOcclusionQuery = r.render.Extension("GL_ARB_occlusion_query")

	// Query whether we have the GL_ARB_multisample extension.
	r.glArbMultisample = r.render.Extension("GL_ARB_multisample")
	if r.glArbMultisample {
		// Query the number of samples and sample buffers we have, if any.
		r.render.GetIntegerv(gl.SAMPLES, &r.samples)
		r.render.GetIntegerv(gl.SAMPLE_BUFFERS, &r.sampleBuffers)
		r.render.Execute() // Needed because glGetIntegerv must execute now.
		r.precision.Samples = int(r.samples)
	}

	// Store GPU info.
	var maxTextureSize, maxVaryingFloats, maxVertexInputs, maxFragmentInputs, occlusionQueryBits int32
	r.render.GetIntegerv(gl.MAX_TEXTURE_SIZE, &maxTextureSize)
	r.render.GetIntegerv(gl.MAX_VARYING_FLOATS, &maxVaryingFloats)
	r.render.GetIntegerv(gl.MAX_VERTEX_UNIFORM_COMPONENTS, &maxVertexInputs)
	r.render.GetIntegerv(gl.MAX_FRAGMENT_UNIFORM_COMPONENTS, &maxFragmentInputs)
	if r.glArbOcclusionQuery {
		r.render.GetQueryiv(gl.SAMPLES_PASSED, gl.QUERY_COUNTER_BITS, &occlusionQueryBits)
	}
	r.render.Execute()

	r.gpuInfo.MaxTextureSize = int(maxTextureSize)
	r.gpuInfo.GLSLMaxVaryingFloats = int(maxVaryingFloats)
	r.gpuInfo.GLSLMaxVertexInputs = int(maxVertexInputs)
	r.gpuInfo.GLSLMaxFragmentInputs = int(maxFragmentInputs)
	r.gpuInfo.GLExtensions = r.render.Extensions()
	r.gpuInfo.AlphaToCoverage = r.glArbMultisample && r.samples > 0 && r.sampleBuffers > 0
	r.gpuInfo.Name = gl.String(r.render.GetString(gl.RENDERER))
	r.gpuInfo.Vendor = gl.String(r.render.GetString(gl.VENDOR))
	r.gpuInfo.GLMajor, r.gpuInfo.GLMinor, _ = r.render.Version()
	r.gpuInfo.GLSLMajor, r.gpuInfo.GLSLMinor, _ = r.render.ShaderVersion()
	r.gpuInfo.OcclusionQuery = r.glArbOcclusionQuery && occlusionQueryBits > 0
	r.gpuInfo.OcclusionQueryBits = int(occlusionQueryBits)

	// Grab the current renderer bounds (opengl viewport).
	var viewport [4]int32
	r.render.GetIntegerv(gl.VIEWPORT, &viewport[0])
	r.render.Execute()
	r.bounds.rect = image.Rect(0, 0, int(viewport[2]), int(viewport[3]))

	// Update scissor rectangle.
	r.stateScissor(r.bounds.rect)

	// Grab the number of texture compression formats.
	var numFormats int32
	r.render.GetIntegerv(gl.NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats)
	r.render.Execute() // Needed because glGetIntegerv must execute now.

	// Store the slice of texture compression formats.
	if numFormats > 0 {
		r.compressedTextureFormats = make([]int32, numFormats)
		r.render.GetIntegerv(gl.COMPRESSED_TEXTURE_FORMATS, &r.compressedTextureFormats[0])
		r.render.Execute() // Needed because glGetIntegerv must execute now.
	}
	return r, nil
}
Example #2
0
// Nil returns a renderer that does not actually render anything.
func Nil() Renderer {
	r := new(nilRenderer)
	r.msaa.enabled = true
	r.clock = clock.New()
	return r
}