ebiten/graphics/opengl/offscreen/offscreen.go

92 lines
2.7 KiB
Go
Raw Normal View History

2013-11-26 17:46:07 +01:00
package offscreen
// #cgo LDFLAGS: -framework OpenGL
//
// #include <stdlib.h>
// #include <OpenGL/gl.h>
import "C"
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
)
type Offscreen struct {
screenHeight int
screenScale int
2014-01-08 08:38:03 +01:00
currentRenderTarget *rendertarget.RenderTarget
2014-01-08 06:37:07 +01:00
mainFramebufferTexture *rendertarget.RenderTarget
2013-11-26 17:46:07 +01:00
}
func New(screenWidth, screenHeight, screenScale int) *Offscreen {
offscreen := &Offscreen{
screenHeight: screenHeight,
screenScale: screenScale,
}
mainFramebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &mainFramebuffer)
var err error
2013-11-28 18:38:18 +01:00
offscreen.mainFramebufferTexture, err = rendertarget.CreateWithFramebuffer(
2013-11-26 17:46:07 +01:00
screenWidth*screenScale,
screenHeight*screenScale,
rendertarget.Framebuffer(mainFramebuffer))
if err != nil {
panic("creating main framebuffer failed: " + err.Error())
}
2014-01-08 08:38:03 +01:00
offscreen.currentRenderTarget = offscreen.mainFramebufferTexture
2013-11-26 17:46:07 +01:00
return offscreen
}
2014-01-08 06:37:07 +01:00
func (o *Offscreen) Set(rt *rendertarget.RenderTarget) {
2013-11-26 17:46:07 +01:00
C.glFlush()
2014-01-08 08:38:03 +01:00
o.currentRenderTarget = rt
rt.SetAsViewport()
2013-11-26 17:46:07 +01:00
}
func (o *Offscreen) SetMainFramebuffer() {
o.Set(o.mainFramebufferTexture)
}
2014-01-08 06:37:07 +01:00
func (o *Offscreen) DrawTexture(texture *texture.Texture,
2013-11-26 17:46:07 +01:00
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
2014-01-08 08:38:03 +01:00
projectionMatrix := o.projectionMatrix()
2014-01-08 06:37:07 +01:00
quad := graphics.TextureQuadForTexture(texture.Width, texture.Height)
shader.DrawTexture(texture.Native,
2014-01-08 08:38:03 +01:00
projectionMatrix, []graphics.TextureQuad{quad},
2014-01-08 06:37:07 +01:00
geometryMatrix, colorMatrix)
2013-11-26 17:46:07 +01:00
}
2014-01-08 06:37:07 +01:00
func (o *Offscreen) DrawTextureParts(texture *texture.Texture,
2013-11-26 17:46:07 +01:00
parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
2014-01-08 08:38:03 +01:00
projectionMatrix := o.projectionMatrix()
2014-01-08 06:37:07 +01:00
quads := graphics.TextureQuadsForTextureParts(parts, texture.Width, texture.Height)
shader.DrawTexture(texture.Native,
2014-01-08 08:38:03 +01:00
projectionMatrix, quads,
2014-01-08 06:37:07 +01:00
geometryMatrix, colorMatrix)
2013-11-26 17:46:07 +01:00
}
2014-01-08 08:38:03 +01:00
func (o *Offscreen) projectionMatrix() [16]float32 {
matrix := o.currentRenderTarget.ProjectionMatrix()
if o.currentRenderTarget == o.mainFramebufferTexture {
2014-01-08 06:37:07 +01:00
actualScreenHeight := o.screenHeight * o.screenScale
2013-11-26 17:46:07 +01:00
// Flip Y and move to fit with the top of the window.
matrix[1][1] *= -1
2014-01-08 08:38:03 +01:00
matrix[1][3] += float64(actualScreenHeight) /
float64(graphics.AdjustSizeForTexture(actualScreenHeight)) * 2
2013-11-26 17:46:07 +01:00
}
2014-01-08 08:38:03 +01:00
projectionMatrix := [16]float32{}
2013-11-26 17:46:07 +01:00
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
2014-01-08 08:38:03 +01:00
projectionMatrix[i+j*4] = float32(matrix[i][j])
2013-11-26 17:46:07 +01:00
}
}
2014-01-08 08:38:03 +01:00
return projectionMatrix
2013-11-26 17:46:07 +01:00
}