ebiten/graphics/opengl/render_target.go

128 lines
3.2 KiB
Go
Raw Normal View History

2014-05-01 14:42:57 +02:00
package opengl
2013-10-27 11:54:28 +01:00
// #cgo LDFLAGS: -framework OpenGL
//
// #include <OpenGL/gl.h>
import "C"
import (
2014-01-08 08:38:03 +01:00
"fmt"
2013-12-18 10:05:28 +01:00
"github.com/hajimehoshi/go-ebiten/graphics"
2014-01-11 00:59:38 +01:00
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
2014-05-02 17:06:20 +02:00
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
2014-01-11 00:20:05 +01:00
"math"
2013-10-27 11:54:28 +01:00
)
2014-05-02 17:06:20 +02:00
func glMatrix(matrix [4][4]float64) [16]float32 {
result := [16]float32{}
for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ {
result[i+j*4] = float32(matrix[i][j])
}
}
return result
}
2014-01-08 06:37:07 +01:00
type RenderTarget struct {
2014-01-08 10:47:38 +01:00
framebuffer C.GLuint
2014-01-08 10:03:21 +01:00
width int
height int
2014-01-10 13:28:50 +01:00
flipY bool
2013-10-27 11:54:28 +01:00
}
2014-05-01 14:42:57 +02:00
func newRTWithCurrentFramebuffer(width, height int) *RenderTarget {
2014-01-08 10:47:38 +01:00
framebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &framebuffer)
2014-01-11 00:20:05 +01:00
return &RenderTarget{C.GLuint(framebuffer), width, height, true}
2014-01-08 10:47:38 +01:00
}
func createFramebuffer(nativeTexture C.GLuint) C.GLuint {
framebuffer := C.GLuint(0)
C.glGenFramebuffers(1, &framebuffer)
origFramebuffer := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &origFramebuffer)
C.glBindFramebuffer(C.GL_FRAMEBUFFER, framebuffer)
defer C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(origFramebuffer))
C.glFramebufferTexture2D(C.GL_FRAMEBUFFER, C.GL_COLOR_ATTACHMENT0,
C.GL_TEXTURE_2D, nativeTexture, 0)
if C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) !=
C.GL_FRAMEBUFFER_COMPLETE {
panic("creating framebuffer failed")
2013-10-27 11:54:28 +01:00
}
2014-01-08 10:47:38 +01:00
// Set this framebuffer opaque because alpha values on a target might be
// confusing.
C.glClearColor(0, 0, 0, 1)
C.glClear(C.GL_COLOR_BUFFER_BIT)
return framebuffer
2013-10-27 11:54:28 +01:00
}
2014-01-10 13:28:50 +01:00
func (r *RenderTarget) setAsViewport() {
2014-01-11 01:03:00 +01:00
current := C.GLint(0)
C.glGetIntegerv(C.GL_FRAMEBUFFER_BINDING, &current)
if C.GLuint(current) == r.framebuffer {
return
}
2014-01-08 10:47:38 +01:00
C.glFlush()
2014-01-08 08:38:03 +01:00
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(r.framebuffer))
err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER)
if err != C.GL_FRAMEBUFFER_COMPLETE {
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err))
}
C.glBlendFuncSeparate(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA,
C.GL_ZERO, C.GL_ONE)
width := graphics.AdjustSizeForTexture(r.width)
height := graphics.AdjustSizeForTexture(r.height)
C.glViewport(0, 0, C.GLsizei(width), C.GLsizei(height))
}
2014-01-11 01:03:00 +01:00
func (r *RenderTarget) projectionMatrix() [4][4]float64 {
2014-01-08 08:38:03 +01:00
width := graphics.AdjustSizeForTexture(r.width)
height := graphics.AdjustSizeForTexture(r.height)
2014-01-10 13:28:50 +01:00
matrix := graphics.OrthoProjectionMatrix(0, width, 0, height)
if r.flipY {
matrix[1][1] *= -1
matrix[1][3] += float64(r.height) /
float64(graphics.AdjustSizeForTexture(r.height)) * 2
}
return matrix
2014-01-08 08:38:03 +01:00
}
2014-05-02 17:06:20 +02:00
func (r *RenderTarget) dispose() {
C.glDeleteFramebuffers(1, &r.framebuffer)
}
2014-01-11 00:20:05 +01:00
2014-05-02 17:06:20 +02:00
func (r *RenderTarget) fill(red, green, blue uint8) {
2014-01-11 01:03:00 +01:00
r.setAsViewport()
2014-01-11 00:20:05 +01:00
const max = float64(math.MaxUint8)
C.glClearColor(
C.GLclampf(float64(red)/max),
C.GLclampf(float64(green)/max),
C.GLclampf(float64(blue)/max),
1)
C.glClear(C.GL_COLOR_BUFFER_BIT)
}
2014-01-11 00:59:38 +01:00
2014-05-02 17:06:20 +02:00
func (r *RenderTarget) drawTexture(
texture *Texture,
2014-01-11 00:59:38 +01:00
parts []graphics.TexturePart,
2014-05-02 17:06:20 +02:00
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
2014-01-11 01:03:00 +01:00
r.setAsViewport()
projectionMatrix := r.projectionMatrix()
2014-05-02 17:06:20 +02:00
quads := graphics.TextureQuads(parts, texture.width, texture.height)
shader.DrawTexture(
shader.NativeTexture(texture.native),
glMatrix(projectionMatrix),
quads,
geometryMatrix,
colorMatrix)
2014-01-11 00:59:38 +01:00
}