added an offscreen canvas
This commit is contained in:
parent
d7513ddf4d
commit
6f74599567
2 changed files with 45 additions and 68 deletions
30
canvas.go
30
canvas.go
|
@ -24,6 +24,10 @@ type Canvas struct {
|
|||
|
||||
state drawState
|
||||
stateStack []drawState
|
||||
|
||||
offscreen bool
|
||||
offscrBuf offscreenBuffer
|
||||
offscrImg Image
|
||||
}
|
||||
|
||||
type drawState struct {
|
||||
|
@ -118,6 +122,15 @@ func New(x, y, w, h int) *Canvas {
|
|||
return cv
|
||||
}
|
||||
|
||||
// NewOffscreen creates a new canvas with the given size. It
|
||||
// does not render directly to the screen but renders to a
|
||||
// texture instead
|
||||
func NewOffscreen(w, h int) *Canvas {
|
||||
cv := New(0, 0, w, h)
|
||||
cv.offscreen = true
|
||||
return cv
|
||||
}
|
||||
|
||||
// SetSize changes the internal size of the canvas. This would
|
||||
// usually be called for example when the window is resized
|
||||
//
|
||||
|
@ -131,9 +144,11 @@ func (cv *Canvas) SetSize(w, h int) {
|
|||
// SetBounds updates the bounds of the canvas. This would
|
||||
// usually be called for example when the window is resized
|
||||
func (cv *Canvas) SetBounds(x, y, w, h int) {
|
||||
if !cv.offscreen {
|
||||
cv.x, cv.y = x, y
|
||||
cv.w, cv.h = w, h
|
||||
cv.fx, cv.fy = float64(x), float64(y)
|
||||
}
|
||||
cv.w, cv.h = w, h
|
||||
cv.fw, cv.fh = float64(w), float64(h)
|
||||
activeCanvas = nil
|
||||
}
|
||||
|
@ -155,7 +170,16 @@ func (cv *Canvas) tf(v vec) vec {
|
|||
// Activate makes the canvas active and sets the viewport. Only needs
|
||||
// to be called if any other GL code changes the viewport
|
||||
func (cv *Canvas) Activate() {
|
||||
if cv.offscreen {
|
||||
gli.Viewport(0, 0, int32(cv.w), int32(cv.h))
|
||||
cv.enableTextureRenderTarget(&cv.offscrBuf)
|
||||
cv.offscrImg.w = cv.offscrBuf.w
|
||||
cv.offscrImg.h = cv.offscrBuf.h
|
||||
cv.offscrImg.tex = cv.offscrBuf.tex
|
||||
} else {
|
||||
gli.Viewport(int32(cv.x), int32(cv.y), int32(cv.w), int32(cv.h))
|
||||
cv.disableTextureRenderTarget()
|
||||
}
|
||||
cv.applyScissor()
|
||||
gli.Clear(gl_STENCIL_BUFFER_BIT)
|
||||
}
|
||||
|
@ -609,7 +633,11 @@ func (cv *Canvas) enableTextureRenderTarget(offscr *offscreenBuffer) {
|
|||
}
|
||||
|
||||
func (cv *Canvas) disableTextureRenderTarget() {
|
||||
if cv.offscreen {
|
||||
cv.enableTextureRenderTarget(&cv.offscrBuf)
|
||||
} else {
|
||||
gli.BindFramebuffer(gl_FRAMEBUFFER, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// SetLineWidth sets the line width for any line drawing calls
|
||||
|
|
77
images.go
77
images.go
|
@ -275,7 +275,14 @@ func (img *Image) Replace(src interface{}) {
|
|||
// Where dx/dy/dw/dh are the destination coordinates and sx/sy/sw/sh are the
|
||||
// source coordinates
|
||||
func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
||||
img := getImage(image)
|
||||
var img *Image
|
||||
var flip bool
|
||||
if cv2, ok := image.(*Canvas); ok && cv2.offscreen {
|
||||
img = &cv2.offscrImg
|
||||
flip = true
|
||||
} else {
|
||||
img = getImage(image)
|
||||
}
|
||||
|
||||
if img == nil {
|
||||
return
|
||||
|
@ -302,6 +309,11 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
|||
dw, dh = coords[6], coords[7]
|
||||
}
|
||||
|
||||
if flip {
|
||||
dy += dh
|
||||
dh = -dh
|
||||
}
|
||||
|
||||
sx /= float64(img.w)
|
||||
sy /= float64(img.h)
|
||||
sw /= float64(img.w)
|
||||
|
@ -354,66 +366,3 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
|
|||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
}
|
||||
|
||||
func (cv *Canvas) drawImageTemp(image interface{}, coords ...float64) {
|
||||
img := getImage(image)
|
||||
|
||||
if img == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if img.deleted {
|
||||
return
|
||||
}
|
||||
|
||||
cv.activate()
|
||||
|
||||
var sx, sy, sw, sh, dx, dy, dw, dh float64
|
||||
sw, sh = float64(img.w), float64(img.h)
|
||||
dw, dh = float64(img.w), float64(img.h)
|
||||
if len(coords) == 2 {
|
||||
dx, dy = coords[0], coords[1]
|
||||
} else if len(coords) == 4 {
|
||||
dx, dy = coords[0], coords[1]
|
||||
dw, dh = coords[2], coords[3]
|
||||
} else if len(coords) == 8 {
|
||||
sx, sy = coords[0], coords[1]
|
||||
sw, sh = coords[2], coords[3]
|
||||
dx, dy = coords[4], coords[5]
|
||||
dw, dh = coords[6], coords[7]
|
||||
}
|
||||
|
||||
sx /= float64(img.w)
|
||||
sy /= float64(img.h)
|
||||
sw /= float64(img.w)
|
||||
sh /= float64(img.h)
|
||||
|
||||
p0 := vec{dx, dy}
|
||||
p1 := vec{dx, dy + dh}
|
||||
p2 := vec{dx + dw, dy + dh}
|
||||
p3 := vec{dx + dw, dy}
|
||||
|
||||
gli.StencilFunc(gl_EQUAL, 0, 0xFF)
|
||||
|
||||
gli.BindBuffer(gl_ARRAY_BUFFER, shadowBuf)
|
||||
data := [16]float32{float32(p0[0]), float32(p0[1]), float32(p1[0]), float32(p1[1]), float32(p2[0]), float32(p2[1]), float32(p3[0]), float32(p3[1]),
|
||||
float32(sx), float32(sy), float32(sx), float32(sy + sh), float32(sx + sw), float32(sy + sh), float32(sx + sw), float32(sy)}
|
||||
gli.BufferData(gl_ARRAY_BUFFER, len(data)*4, unsafe.Pointer(&data[0]), gl_STREAM_DRAW)
|
||||
|
||||
gli.ActiveTexture(gl_TEXTURE0)
|
||||
gli.BindTexture(gl_TEXTURE_2D, img.tex)
|
||||
|
||||
gli.UseProgram(ir.id)
|
||||
gli.Uniform1i(ir.image, 0)
|
||||
gli.Uniform2f(ir.canvasSize, float32(cv.fw), float32(cv.fh))
|
||||
gli.Uniform1f(ir.globalAlpha, float32(cv.state.globalAlpha))
|
||||
gli.VertexAttribPointer(ir.vertex, 2, gl_FLOAT, false, 0, 0)
|
||||
gli.VertexAttribPointer(ir.texCoord, 2, gl_FLOAT, false, 0, 8*4)
|
||||
gli.EnableVertexAttribArray(ir.vertex)
|
||||
gli.EnableVertexAttribArray(ir.texCoord)
|
||||
gli.DrawArrays(gl_TRIANGLE_FAN, 0, 4)
|
||||
gli.DisableVertexAttribArray(ir.vertex)
|
||||
gli.DisableVertexAttribArray(ir.texCoord)
|
||||
|
||||
gli.StencilFunc(gl_ALWAYS, 0, 0xFF)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue