/
render_framebuffer.go
128 lines (107 loc) · 3.04 KB
/
render_framebuffer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package common
import (
"github.com/EngoEngine/engo"
"github.com/EngoEngine/gl"
)
type RenderBuffer struct {
rbo *gl.RenderBuffer
width, height int
}
type Framebuffer struct {
fbo *gl.FrameBuffer
oldVP [4]int32
isOpen bool
}
type RenderTexture struct {
tex *gl.Texture
width, height float32
depth bool
}
func CreateRenderBuffer(width, height int) *RenderBuffer {
rbuf := &RenderBuffer{
rbo: engo.Gl.CreateRenderBuffer(),
width: width,
height: height,
}
engo.Gl.BindRenderBuffer(rbuf.rbo)
engo.Gl.RenderBufferStorage(engo.Gl.RGBA8, width, height)
engo.Gl.BindRenderBuffer(nil)
return rbuf
}
func CreateRenderTexture(width, height int, depthBuffer bool) *RenderTexture {
texBuf := &RenderTexture{
width: float32(width),
height: float32(height),
tex: engo.Gl.CreateTexture(),
depth: depthBuffer,
}
engo.Gl.BindTexture(engo.Gl.TEXTURE_2D, texBuf.tex)
if depthBuffer {
engo.Gl.TexImage2DEmpty(engo.Gl.TEXTURE_2D, 0, engo.Gl.DEPTH_COMPONENT, width, height, engo.Gl.DEPTH_COMPONENT, engo.Gl.UNSIGNED_BYTE)
} else {
engo.Gl.TexImage2DEmpty(engo.Gl.TEXTURE_2D, 0, engo.Gl.RGBA, width, height, engo.Gl.RGBA, engo.Gl.UNSIGNED_BYTE)
}
if err := engo.Gl.GetError(); err != 0 {
panic(err)
}
engo.Gl.TexParameteri(engo.Gl.TEXTURE_2D, engo.Gl.TEXTURE_MAG_FILTER, engo.Gl.NEAREST)
engo.Gl.TexParameteri(engo.Gl.TEXTURE_2D, engo.Gl.TEXTURE_MIN_FILTER, engo.Gl.NEAREST)
return texBuf
}
func CreateFramebuffer() *Framebuffer {
return &Framebuffer{
fbo: engo.Gl.CreateFrameBuffer(),
}
}
func (t *RenderTexture) Bind() {
if t.depth {
engo.Gl.FrameBufferTexture2D(engo.Gl.FRAMEBUFFER, engo.Gl.DEPTH_ATTACHMENT, engo.Gl.TEXTURE_2D, t.tex, 0)
} else {
engo.Gl.FrameBufferTexture2D(engo.Gl.FRAMEBUFFER, engo.Gl.COLOR_ATTACHMENT0, engo.Gl.TEXTURE_2D, t.tex, 0)
}
}
func (t *RenderTexture) Close() {
engo.Gl.DeleteTexture(t.tex)
}
// Width returns the width of the texture.
func (t *RenderTexture) Width() float32 {
return t.width
}
// Height returns the height of the texture.
func (t *RenderTexture) Height() float32 {
return t.height
}
// Texture returns the OpenGL ID of the Texture.
func (t *RenderTexture) Texture() *gl.Texture {
return t.tex
}
// View returns the viewport properties of the Texture. The order is Min.X, Min.Y, Max.X, Max.Y.
func (t *RenderTexture) View() (float32, float32, float32, float32) {
return 0, 0, 1, 1
}
func (rb *RenderBuffer) Bind(attachment int) {
engo.Gl.FrameBufferRenderBuffer(engo.Gl.FRAMEBUFFER, attachment, rb.rbo)
}
func (rb *RenderBuffer) Destroy() {
engo.Gl.DeleteRenderBuffer(rb.rbo)
}
func (fb *Framebuffer) Open(width, height int) {
if fb.isOpen {
return
}
engo.Gl.BindFrameBuffer(fb.fbo)
fb.oldVP = engo.Gl.GetViewport()
engo.Gl.Viewport(0, 0, width, height)
fb.isOpen = true
}
func (fb *Framebuffer) Close() {
if !fb.isOpen {
return
}
engo.Gl.BindFrameBuffer(nil)
engo.Gl.Viewport(int(fb.oldVP[0]), int(fb.oldVP[1]), int(fb.oldVP[2]), int(fb.oldVP[3]))
fb.isOpen = false
}
func (fb *Framebuffer) Destroy() {
engo.Gl.DeleteFrameBuffer(fb.fbo)
}