예제 #1
0
파일: opengl.go 프로젝트: tanema/amore
// SetBlendMode sets the blending mode. Blending modes are different ways to do
// color blending. See BlendMode constants to see how they operate.
func SetBlendMode(mode BlendMode) {
	fn := gl.FUNC_ADD
	srcRGB := gl.ONE
	srcA := gl.ONE
	dstRGB := gl.ZERO
	dstA := gl.ZERO

	switch mode {
	case BLENDMODE_ALPHA:
		srcRGB = gl.SRC_ALPHA
		srcA = gl.ONE
		dstRGB = gl.ONE_MINUS_SRC_ALPHA
		dstA = gl.ONE_MINUS_SRC_ALPHA
	case BLENDMODE_MULTIPLICATIVE:
		srcRGB = gl.DST_COLOR
		srcA = gl.DST_COLOR
		dstRGB = gl.ZERO
		dstA = gl.ZERO
	case BLENDMODE_PREMULTIPLIED:
		srcRGB = gl.ONE
		srcA = gl.ONE
		dstRGB = gl.ONE_MINUS_SRC_ALPHA
		dstA = gl.ONE_MINUS_SRC_ALPHA
	case BLENDMODE_SUBTRACTIVE:
		fn = gl.FUNC_REVERSE_SUBTRACT
	case BLENDMODE_ADDITIVE:
		srcRGB = gl.SRC_ALPHA
		srcA = gl.SRC_ALPHA
		dstRGB = gl.ONE
		dstA = gl.ONE
	case BLENDMODE_SCREEN:
		srcRGB = gl.ONE
		srcA = gl.ONE
		dstRGB = gl.ONE_MINUS_SRC_COLOR
		dstA = gl.ONE_MINUS_SRC_COLOR
		break
	case BLENDMODE_REPLACE:
		srcRGB = gl.ONE
		srcA = gl.ONE
		dstRGB = gl.ZERO
		dstA = gl.ZERO
	}

	gl.BlendEquation(gl.Enum(fn))
	gl.BlendFuncSeparate(gl.Enum(srcRGB), gl.Enum(dstRGB), gl.Enum(srcA), gl.Enum(dstA))
	states.back().blend_mode = mode
}
예제 #2
0
파일: mesh.go 프로젝트: tanema/amore
// Draw satisfies the Drawable interface. Inputs are as follows
// x, y, r, sx, sy, ox, oy, kx, ky
// x, y are position
// r is rotation
// sx, sy is the scale, if sy is not given sy will equal sx
// ox, oy are offset
// kx, ky are the shear. If ky is not given ky will equal kx
func (mesh *Mesh) Draw(args ...float32) {
	prepareDraw(generateModelMatFromArgs(args))
	mesh.bindTexture()
	mesh.bindEnabledAttributes()
	min, max := mesh.GetDrawRange()
	if mesh.ibo != nil && mesh.elementCount > 0 {
		mesh.ibo.drawElements(uint32(mesh.mode), min, max-min+1)
	} else {
		gl.DrawArrays(gl.Enum(mesh.mode), min, max-min+1)
	}
}
예제 #3
0
파일: opengl.go 프로젝트: tanema/amore
// setTextureUnit activates a texture unit
func setTextureUnit(textureunit int) error {
	if textureunit < 0 || textureunit >= len(gl_state.boundTextures) {
		return fmt.Errorf("Invalid texture unit index (%v).", textureunit)
	}

	if textureunit != gl_state.curTextureUnit {
		gl.ActiveTexture(gl.Enum(gl.TEXTURE0 + uint32(textureunit)))
	}

	gl_state.curTextureUnit = textureunit
	return nil
}
예제 #4
0
파일: canvas.go 프로젝트: tanema/amore
// 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
}
예제 #5
0
파일: opengl.go 프로젝트: tanema/amore
// StencilExt operates like stencil but with access to change the stencil action,
// value, and keepvalues.
//
// action: How to modify any stencil values of pixels that are touched by what's
// drawn in the stencil function.
//
// value: The new stencil value to use for pixels if the "replace" stencil action
// is used. Has no effect with other stencil actions. Must be between 0 and 255.
//
// keepvalues: True to preserve old stencil values of pixels, false to re-set
// every pixel's stencil value to 0 before executing the stencil function. Clear
// will also re-set all stencil values.
func StencilExt(stencil_func func(), action StencilAction, value int32, keepvalues bool) {
	gl_state.writingToStencil = true
	if !keepvalues {
		gl.Clear(gl.STENCIL_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	}
	if gl_state.currentCanvas != nil {
		gl_state.currentCanvas.checkCreateStencil()
	}
	gl.Enable(gl.STENCIL_TEST)
	gl.ColorMask(false, false, false, false)
	gl.StencilFunc(gl.ALWAYS, int(value), 0xFF)
	gl.StencilOp(gl.KEEP, gl.KEEP, gl.Enum(action))

	stencil_func()

	gl_state.writingToStencil = false
	SetColorMask(states.back().colorMask)
	SetStencilTest(states.back().stencilCompare, states.back().stencilTestValue)
}
예제 #6
0
파일: opengl.go 프로젝트: tanema/amore
// SetStencilTest configures or disables stencil testing. When stencil testing is
// enabled, the geometry of everything that is drawn afterward will be clipped/stencilled
// out based on a comparison between the arguments of this function and the stencil
// value of each pixel that the geometry touches. The stencil values of pixels are
// affected via Stencil/StencilEXT.
func SetStencilTest(compare CompareMode, value int32) {
	if gl_state.writingToStencil {
		return
	}

	states.back().stencilCompare = compare
	states.back().stencilTestValue = value
	if compare == COMPARE_ALWAYS {
		gl.Disable(gl.STENCIL_TEST)
		return
	}

	if gl_state.currentCanvas != nil {
		gl_state.currentCanvas.checkCreateStencil()
	}

	gl.Enable(gl.STENCIL_TEST)
	gl.StencilFunc(gl.Enum(compare), int(value), 0xFF)
	gl.StencilOp(gl.KEEP, gl.KEEP, gl.REPLACE)
}
예제 #7
0
파일: opengl.go 프로젝트: tanema/amore
// InitContext will initiate the opengl context with a viewport in the size of
// w x h. This is generally called from the game loop and wont generally need to
// be called unless you are rolling your own game loop.
func InitContext(w, h int32) {
	if gl_state.initialized {
		return
	}

	// Okay, setup OpenGL.
	gl.ContextWatcher.OnMakeCurrent(nil)

	//Get system info
	opengl_version = gl.GetString(gl.VERSION)
	opengl_vendor = gl.GetString(gl.VENDOR)
	gl_state.defaultFBO = gl.GetBoundFramebuffer()
	gl.GetIntegerv(gl.VIEWPORT, gl_state.viewport)
	// And the current scissor - but we need to compensate for GL scissors
	// starting at the bottom left instead of top left.
	gl.GetIntegerv(gl.SCISSOR_BOX, states.back().scissorBox)
	states.back().scissorBox[1] = gl_state.viewport[3] - (states.back().scissorBox[1] + states.back().scissorBox[3])

	initMaxValues() //check shim code

	glcolor := []float32{1.0, 1.0, 1.0, 1.0}
	gl.VertexAttrib4fv(attrib_color, glcolor)
	gl.VertexAttrib4fv(attrib_constantcolor, glcolor)
	useVertexAttribArrays(0)

	// Enable blending
	gl.Enable(gl.BLEND)
	SetBlendMode(BLENDMODE_ALPHA)
	// Auto-generated mipmaps should be the best quality possible
	gl.Hint(gl.GENERATE_MIPMAP_HINT, gl.NICEST)
	// Make sure antialiasing works when set elsewhere
	enableMultisample() //check shim code
	// Set pixel row alignment
	gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)

	//default matricies
	gl_state.projectionStack = matstack.NewMatStack()
	gl_state.viewStack = matstack.NewMatStack() //stacks are initialized with ident matricies on top

	SetViewportSize(w, h)
	SetBackgroundColor(0, 0, 0, 255)

	gl_state.boundTextures = make([]gl.Texture, maxTextureUnits)
	curgltextureunit := gl.GetInteger(gl.ACTIVE_TEXTURE)
	gl_state.curTextureUnit = int(curgltextureunit - gl.TEXTURE0)
	// Retrieve currently bound textures for each texture unit.
	for i := 0; i < len(gl_state.boundTextures); i++ {
		gl.ActiveTexture(gl.Enum(gl.TEXTURE0 + uint32(i)))
		gl_state.boundTextures[i] = gl.Texture{Value: uint32(gl.GetInteger(gl.TEXTURE_BINDING_2D))}
	}
	gl.ActiveTexture(gl.Enum(curgltextureunit))
	createDefaultTexture()
	setTextureUnit(0)

	// We always need a default shader.
	defaultShader = NewShader()

	gl_state.initialized = true

	loadAllVolatile()

	//have to set this after loadallvolatile() so we are sure the  default shader is loaded
	SetShader(nil)
}
예제 #8
0
func (buffer *indexBuffer) drawElementsLocal(mode uint32, offset, size int) {
	gl.DrawElements(gl.Enum(mode), size, gl.UNSIGNED_INT, gl.Ptr(&buffer.data[offset]))
}
예제 #9
0
func (buffer *indexBuffer) drawElements(mode uint32, offset, size int) {
	buffer.bind()
	defer buffer.unbind()
	gl.DrawElements(gl.Enum(mode), size, gl.UNSIGNED_INT, gl.PtrOffset(offset*4))
}