added a function to switch to an offscreen framebuffer
This commit is contained in:
parent
aabe03b003
commit
0cb030619e
3 changed files with 106 additions and 14 deletions
80
canvas.go
80
canvas.go
|
@ -177,20 +177,25 @@ loop:
|
||||||
const alphaTexSize = 2048
|
const alphaTexSize = 2048
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gli GL
|
gli GL
|
||||||
buf uint32
|
buf uint32
|
||||||
shadowBuf uint32
|
shadowBuf uint32
|
||||||
alphaTex uint32
|
alphaTex uint32
|
||||||
sr *solidShader
|
sr *solidShader
|
||||||
lgr *linearGradientShader
|
lgr *linearGradientShader
|
||||||
rgr *radialGradientShader
|
rgr *radialGradientShader
|
||||||
ipr *imagePatternShader
|
ipr *imagePatternShader
|
||||||
sar *solidAlphaShader
|
sar *solidAlphaShader
|
||||||
rgar *radialGradientAlphaShader
|
rgar *radialGradientAlphaShader
|
||||||
lgar *linearGradientAlphaShader
|
lgar *linearGradientAlphaShader
|
||||||
ipar *imagePatternAlphaShader
|
ipar *imagePatternAlphaShader
|
||||||
ir *imageShader
|
ir *imageShader
|
||||||
glChan = make(chan func())
|
offScrTex uint32
|
||||||
|
offScrW int
|
||||||
|
offScrH int
|
||||||
|
renderStencilBuf uint32
|
||||||
|
frameBuf uint32
|
||||||
|
glChan = make(chan func())
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadGL needs to be called once per GL context to load the GL assets
|
// LoadGL needs to be called once per GL context to load the GL assets
|
||||||
|
@ -509,6 +514,53 @@ func (cv *Canvas) useAlphaShader(style *drawStyle, alphaTexSlot int32) (vertexLo
|
||||||
return sar.vertex, sar.alphaTexCoord
|
return sar.vertex, sar.alphaTexCoord
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) enableTextureRenderTarget() {
|
||||||
|
if offScrW != cv.w || offScrH != cv.h {
|
||||||
|
if offScrW != 0 && offScrH != 0 {
|
||||||
|
gli.DeleteTextures(1, &offScrTex)
|
||||||
|
gli.DeleteFramebuffers(1, &frameBuf)
|
||||||
|
gli.DeleteRenderbuffers(1, &renderStencilBuf)
|
||||||
|
}
|
||||||
|
offScrW = cv.w
|
||||||
|
offScrH = cv.h
|
||||||
|
|
||||||
|
gli.GenTextures(1, &offScrTex)
|
||||||
|
gli.BindTexture(gl_TEXTURE_2D, offScrTex)
|
||||||
|
// todo do non-power-of-two textures work everywhere?
|
||||||
|
gli.TexImage2D(gl_TEXTURE_2D, 0, gl_RGB, int32(cv.w), int32(cv.h), 0, gl_RGB, gl_UNSIGNED_BYTE, nil)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_NEAREST)
|
||||||
|
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_NEAREST)
|
||||||
|
|
||||||
|
gli.GenFramebuffers(1, &frameBuf)
|
||||||
|
gli.BindFramebuffer(gl_FRAMEBUFFER, frameBuf)
|
||||||
|
|
||||||
|
gli.GenRenderbuffers(1, &renderStencilBuf)
|
||||||
|
gli.BindRenderbuffer(gl_RENDERBUFFER, renderStencilBuf)
|
||||||
|
gli.RenderbufferStorage(gl_RENDERBUFFER, gl_DEPTH_STENCIL, int32(cv.w), int32(cv.h))
|
||||||
|
gli.FramebufferRenderbuffer(gl_FRAMEBUFFER, gl_DEPTH_STENCIL_ATTACHMENT, gl_RENDERBUFFER, renderStencilBuf)
|
||||||
|
|
||||||
|
gli.FramebufferTexture(gl_FRAMEBUFFER, gl_COLOR_ATTACHMENT0, offScrTex, 0)
|
||||||
|
|
||||||
|
if gli.CheckFramebufferStatus(gl_FRAMEBUFFER) != gl_FRAMEBUFFER_COMPLETE {
|
||||||
|
// todo this should maybe not panic
|
||||||
|
panic("Failed to set up framebuffer for offscreen texture")
|
||||||
|
}
|
||||||
|
|
||||||
|
gli.Clear(gl_COLOR_BUFFER_BIT | gl_STENCIL_BUFFER_BIT)
|
||||||
|
} else {
|
||||||
|
gli.BindFramebuffer(gl_FRAMEBUFFER, frameBuf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) disableTextureRenderTarget() {
|
||||||
|
gli.BindFramebuffer(gl_FRAMEBUFFER, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cv *Canvas) renderOffscreenTexture() {
|
||||||
|
img := Image{w: cv.w, h: cv.h, tex: offScrTex}
|
||||||
|
cv.DrawImage(&img, 0, 0, cv.fw, cv.fh)
|
||||||
|
}
|
||||||
|
|
||||||
// SetLineWidth sets the line width for any line drawing calls
|
// SetLineWidth sets the line width for any line drawing calls
|
||||||
func (cv *Canvas) SetLineWidth(width float64) {
|
func (cv *Canvas) SetLineWidth(width float64) {
|
||||||
if width < 0 {
|
if width < 0 {
|
||||||
|
|
|
@ -24,6 +24,12 @@ func (_ GLImpl) AttachShader(program uint32, shader uint32) {
|
||||||
func (_ GLImpl) BindBuffer(target uint32, buffer uint32) {
|
func (_ GLImpl) BindBuffer(target uint32, buffer uint32) {
|
||||||
gl.BindBuffer(target, buffer)
|
gl.BindBuffer(target, buffer)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) BindFramebuffer(target uint32, framebuffer uint32) {
|
||||||
|
gl.BindFramebuffer(target, framebuffer)
|
||||||
|
}
|
||||||
|
func (_ GLImpl) BindRenderbuffer(target uint32, renderbuffer uint32) {
|
||||||
|
gl.BindRenderbuffer(target, renderbuffer)
|
||||||
|
}
|
||||||
func (_ GLImpl) BindTexture(target uint32, texture uint32) {
|
func (_ GLImpl) BindTexture(target uint32, texture uint32) {
|
||||||
gl.BindTexture(target, texture)
|
gl.BindTexture(target, texture)
|
||||||
}
|
}
|
||||||
|
@ -33,6 +39,9 @@ func (_ GLImpl) BlendFunc(sfactor uint32, dfactor uint32) {
|
||||||
func (_ GLImpl) BufferData(target uint32, size int, data unsafe.Pointer, usage uint32) {
|
func (_ GLImpl) BufferData(target uint32, size int, data unsafe.Pointer, usage uint32) {
|
||||||
gl.BufferData(target, size, data, usage)
|
gl.BufferData(target, size, data, usage)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) CheckFramebufferStatus(target uint32) uint32 {
|
||||||
|
return gl.CheckFramebufferStatus(target)
|
||||||
|
}
|
||||||
func (_ GLImpl) Clear(mask uint32) {
|
func (_ GLImpl) Clear(mask uint32) {
|
||||||
gl.Clear(mask)
|
gl.Clear(mask)
|
||||||
}
|
}
|
||||||
|
@ -54,6 +63,12 @@ func (_ GLImpl) CreateShader(xtype uint32) uint32 {
|
||||||
func (_ GLImpl) DeleteShader(shader uint32) {
|
func (_ GLImpl) DeleteShader(shader uint32) {
|
||||||
gl.DeleteShader(shader)
|
gl.DeleteShader(shader)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) DeleteFramebuffers(n int32, framebuffers *uint32) {
|
||||||
|
gl.DeleteFramebuffers(n, framebuffers)
|
||||||
|
}
|
||||||
|
func (_ GLImpl) DeleteRenderbuffers(n int32, renderbuffers *uint32) {
|
||||||
|
gl.DeleteRenderbuffers(n, renderbuffers)
|
||||||
|
}
|
||||||
func (_ GLImpl) DeleteTextures(n int32, textures *uint32) {
|
func (_ GLImpl) DeleteTextures(n int32, textures *uint32) {
|
||||||
gl.DeleteTextures(n, textures)
|
gl.DeleteTextures(n, textures)
|
||||||
}
|
}
|
||||||
|
@ -72,9 +87,21 @@ func (_ GLImpl) Enable(cap uint32) {
|
||||||
func (_ GLImpl) EnableVertexAttribArray(index uint32) {
|
func (_ GLImpl) EnableVertexAttribArray(index uint32) {
|
||||||
gl.EnableVertexAttribArray(index)
|
gl.EnableVertexAttribArray(index)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) {
|
||||||
|
gl.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)
|
||||||
|
}
|
||||||
|
func (_ GLImpl) FramebufferTexture(target uint32, attachment uint32, texture uint32, level int32) {
|
||||||
|
gl.FramebufferTexture(target, attachment, texture, level)
|
||||||
|
}
|
||||||
func (_ GLImpl) GenBuffers(n int32, buffers *uint32) {
|
func (_ GLImpl) GenBuffers(n int32, buffers *uint32) {
|
||||||
gl.GenBuffers(n, buffers)
|
gl.GenBuffers(n, buffers)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) GenFramebuffers(n int32, framebuffers *uint32) {
|
||||||
|
gl.GenFramebuffers(n, framebuffers)
|
||||||
|
}
|
||||||
|
func (_ GLImpl) GenRenderbuffers(n int32, renderbuffers *uint32) {
|
||||||
|
gl.GenRenderbuffers(n, renderbuffers)
|
||||||
|
}
|
||||||
func (_ GLImpl) GenTextures(n int32, textures *uint32) {
|
func (_ GLImpl) GenTextures(n int32, textures *uint32) {
|
||||||
gl.GenTextures(n, textures)
|
gl.GenTextures(n, textures)
|
||||||
}
|
}
|
||||||
|
@ -119,6 +146,9 @@ func (_ GLImpl) GetUniformLocation(program uint32, name string) int32 {
|
||||||
func (_ GLImpl) LinkProgram(program uint32) {
|
func (_ GLImpl) LinkProgram(program uint32) {
|
||||||
gl.LinkProgram(program)
|
gl.LinkProgram(program)
|
||||||
}
|
}
|
||||||
|
func (_ GLImpl) RenderbufferStorage(target uint32, internalformat uint32, width int32, height int32) {
|
||||||
|
gl.RenderbufferStorage(target, internalformat, width, height)
|
||||||
|
}
|
||||||
func (_ GLImpl) ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) {
|
func (_ GLImpl) ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer) {
|
||||||
gl.ReadPixels(x, y, width, height, format, xtype, pixels)
|
gl.ReadPixels(x, y, width, height, format, xtype, pixels)
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,9 +797,12 @@ type GL interface {
|
||||||
ActiveTexture(texture uint32)
|
ActiveTexture(texture uint32)
|
||||||
AttachShader(program uint32, shader uint32)
|
AttachShader(program uint32, shader uint32)
|
||||||
BindBuffer(target uint32, buffer uint32)
|
BindBuffer(target uint32, buffer uint32)
|
||||||
|
BindFramebuffer(target uint32, framebuffer uint32)
|
||||||
|
BindRenderbuffer(target uint32, renderbuffer uint32)
|
||||||
BindTexture(target uint32, texture uint32)
|
BindTexture(target uint32, texture uint32)
|
||||||
BlendFunc(sfactor uint32, dfactor uint32)
|
BlendFunc(sfactor uint32, dfactor uint32)
|
||||||
BufferData(target uint32, size int, data unsafe.Pointer, usage uint32)
|
BufferData(target uint32, size int, data unsafe.Pointer, usage uint32)
|
||||||
|
CheckFramebufferStatus(target uint32) uint32
|
||||||
Clear(mask uint32)
|
Clear(mask uint32)
|
||||||
ClearColor(red float32, green float32, blue float32, alpha float32)
|
ClearColor(red float32, green float32, blue float32, alpha float32)
|
||||||
ColorMask(red bool, green bool, blue bool, alpha bool)
|
ColorMask(red bool, green bool, blue bool, alpha bool)
|
||||||
|
@ -807,13 +810,19 @@ type GL interface {
|
||||||
CreateProgram() uint32
|
CreateProgram() uint32
|
||||||
CreateShader(xtype uint32) uint32
|
CreateShader(xtype uint32) uint32
|
||||||
DeleteShader(shader uint32)
|
DeleteShader(shader uint32)
|
||||||
|
DeleteFramebuffers(n int32, framebuffers *uint32)
|
||||||
|
DeleteRenderbuffers(n int32, renderbuffers *uint32)
|
||||||
DeleteTextures(n int32, textures *uint32)
|
DeleteTextures(n int32, textures *uint32)
|
||||||
Disable(cap uint32)
|
Disable(cap uint32)
|
||||||
DisableVertexAttribArray(index uint32)
|
DisableVertexAttribArray(index uint32)
|
||||||
DrawArrays(mode uint32, first int32, count int32)
|
DrawArrays(mode uint32, first int32, count int32)
|
||||||
Enable(cap uint32)
|
Enable(cap uint32)
|
||||||
EnableVertexAttribArray(index uint32)
|
EnableVertexAttribArray(index uint32)
|
||||||
|
FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32)
|
||||||
|
FramebufferTexture(target uint32, attachment uint32, texture uint32, level int32)
|
||||||
GenBuffers(n int32, buffers *uint32)
|
GenBuffers(n int32, buffers *uint32)
|
||||||
|
GenFramebuffers(n int32, framebuffers *uint32)
|
||||||
|
GenRenderbuffers(n int32, renderbuffers *uint32)
|
||||||
GenTextures(n int32, textures *uint32)
|
GenTextures(n int32, textures *uint32)
|
||||||
GenerateMipmap(target uint32)
|
GenerateMipmap(target uint32)
|
||||||
GetAttribLocation(program uint32, name string) int32
|
GetAttribLocation(program uint32, name string) int32
|
||||||
|
@ -825,6 +834,7 @@ type GL interface {
|
||||||
GetUniformLocation(program uint32, name string) int32
|
GetUniformLocation(program uint32, name string) int32
|
||||||
LinkProgram(program uint32)
|
LinkProgram(program uint32)
|
||||||
ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer)
|
ReadPixels(x int32, y int32, width int32, height int32, format uint32, xtype uint32, pixels unsafe.Pointer)
|
||||||
|
RenderbufferStorage(target uint32, internalformat uint32, width int32, height int32)
|
||||||
Scissor(x int32, y int32, width int32, height int32)
|
Scissor(x int32, y int32, width int32, height int32)
|
||||||
ShaderSource(shader uint32, source string)
|
ShaderSource(shader uint32, source string)
|
||||||
StencilFunc(xfunc uint32, ref int32, mask uint32)
|
StencilFunc(xfunc uint32, ref int32, mask uint32)
|
||||||
|
|
Loading…
Reference in a new issue