-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathframebuffer.go
91 lines (71 loc) · 2.22 KB
/
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
// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package glh
import (
"image"
"log"
"github.com/go-gl/gl"
)
// Mapping from texture dimensions onto ready made framebuffer/renderbuffer
// therefore we only construct one per image dimensions
// This number should be less than O(1000) otherwise opengl throws OUT_OF_MEMORY
// on some cards
var framebuffers map[image.Point]*fborbo = make(map[image.Point]*fborbo)
type fborbo struct {
fbo gl.Framebuffer
rbo gl.Renderbuffer
}
// Internal function to generate a framebuffer/renderbuffer of the correct
// dimensions exactly once per execution
func getFBORBO(t *Texture) *fborbo {
p := image.Point{t.W, t.H}
result, ok := framebuffers[p]
if ok {
return result
}
result = &fborbo{}
result.rbo = gl.GenRenderbuffer()
OpenGLSentinel()
result.fbo = gl.GenFramebuffer()
OpenGLSentinel()
result.fbo.Bind()
result.rbo.Bind()
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT, t.W, t.H)
result.rbo.Unbind()
result.rbo.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER)
result.fbo.Unbind()
framebuffers[image.Point{t.W, t.H}] = result
return result
}
// During this context, OpenGL drawing operations will instead render to `*Texture`.
// Example usage:
// With(Framebuffer{my_texture}, func() { .. operations to render to texture .. })
//
// Internally this will permanently allocate a framebuffer with the appropriate
// dimensions. Beware that using a large number of textures with differing sizes
// will therefore cause some graphics cards to run out of memory.
type Framebuffer struct {
*Texture
*fborbo
Level int
}
func (b *Framebuffer) Enter() {
if b.fborbo == nil {
b.fborbo = getFBORBO(b.Texture)
}
b.fbo.Bind()
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
b.Texture.Texture, b.Level)
s := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
if s != gl.FRAMEBUFFER_COMPLETE {
log.Panicf("Incomplete framebuffer, reason: %x (level %d)", s, b.Level)
}
}
func (b *Framebuffer) Exit() {
b.fbo.Unbind()
}
func (b *Framebuffer) BindFramebuffer(target gl.GLenum) {
b.fborbo.fbo.BindTarget(target)
}