Skip to content

Instantly share code, notes, and snippets.

@morcmarc
Created June 3, 2015 19:08
Show Gist options
  • Save morcmarc/31a02dbbd9aad2955f47 to your computer and use it in GitHub Desktop.
Save morcmarc/31a02dbbd9aad2955f47 to your computer and use it in GitHub Desktop.
framebuffer post processing
type Square struct {
program uint32
vbo uint32
vao uint32
vertices []float32
vrtx uint32
}
const (
squareVS = `#version 330
in vec2 vrtx;
void main()
{
float x = vrtx[0];
float y = vrtx[1];
gl_Position = vec4(x, y, 0.0, 1.0);
}` + "\x00"
squareFS = `#version 330
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}` + "\x00"
)
func NewSquare() *Square {
s := &Square{}
s.vertices = []float32{
0.0, 0.05,
0.025, -0.05,
0.0, -0.025,
0.0, -0.025,
-0.025, -0.05,
0.0, 0.05,
}
p, _ := CreateProgram(squareVS, squareFS)
s.program = p
gl.UseProgram(p)
gl.BindFragDataLocation(p, 0, gl.Str("outColor\x00"))
gl.GenVertexArrays(1, &s.vao)
gl.BindVertexArray(s.vao)
gl.GenBuffers(1, &s.vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, s.vbo)
gl.BufferData(gl.ARRAY_BUFFER, len(s.vertices)*4, gl.Ptr(s.vertices), gl.STATIC_DRAW)
s.vrtx = uint32(gl.GetAttribLocation(p, gl.Str("vrtx\x00")))
gl.EnableVertexAttribArray(s.vrtx)
gl.VertexAttribPointer(s.vrtx, 2, gl.FLOAT, false, 0, gl.PtrOffset(0))
gl.UseProgram(0)
return s
}
func (this *Square) Draw() {
gl.UseProgram(this.program)
gl.BindVertexArray(this.vao)
gl.BindBuffer(gl.ARRAY_BUFFER, this.vbo)
gl.DrawArrays(gl.TRIANGLES, 0, int32(len(this.vertices)))
gl.UseProgram(0)
}
func (this *Square) Destroy() {
gl.DeleteBuffers(1, &this.vbo)
gl.DeleteVertexArrays(1, &this.vao)
gl.DeleteProgram(this.program)
}
type PostProcessor struct {
fbo uint32
fboTex uint32
rboDepth uint32
program uint32
vbo uint32
fboVertices []float32
vCoord uint32
fTex uint32
}
func NewPostProcessor() *PostProcessor {
v, err := ioutil.ReadFile("shaders/vignette.vertex.glsl")
if err != nil {
panic(err)
}
f, err := ioutil.ReadFile("shaders/vignette.frag.glsl")
if err != nil {
panic(err)
}
p, err := CreateProgram(string(v)+"\x00", string(f)+"\x00")
if err != nil {
panic(err)
}
return &PostProcessor{
program: p,
fboVertices: []float32{
-1, -1,
1, -1,
-1, 1,
1, 1,
},
}
}
func (this *PostProcessor) Init(w, h int) {
gl.UseProgram(this.program)
gl.ActiveTexture(gl.TEXTURE0)
gl.GenTextures(1, &this.fboTex)
gl.BindTexture(gl.TEXTURE_2D, this.fboTex)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(w), int32(h), 0, gl.RGBA, gl.UNSIGNED_BYTE, nil)
gl.BindTexture(gl.TEXTURE_2D, 0)
gl.GenRenderbuffers(1, &this.rboDepth)
gl.BindRenderbuffer(gl.RENDERBUFFER, this.rboDepth)
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT24, int32(w), int32(h))
gl.BindRenderbuffer(gl.RENDERBUFFER, 0)
gl.GenFramebuffers(1, &this.fbo)
gl.BindFramebuffer(gl.FRAMEBUFFER, this.fbo)
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.fboTex, 0)
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.rboDepth)
status := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
switch status {
case gl.FRAMEBUFFER_COMPLETE:
log.Println("Framebuffer check complete!")
break
case gl.FRAMEBUFFER_UNSUPPORTED:
log.Println("Framebuffer not supported")
break
default:
panic("Framebuffer error")
break
}
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
gl.GenBuffers(1, &this.vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, this.vbo)
gl.BufferData(gl.ARRAY_BUFFER, len(this.fboVertices)*4, gl.Ptr(this.fboVertices), gl.STATIC_DRAW)
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
this.vCoord = uint32(gl.GetAttribLocation(this.program, gl.Str("v_coord\x00")))
this.fTex = uint32(gl.GetUniformLocation(this.program, gl.Str("fbo_texture\x00")))
gl.BindFragDataLocation(this.program, 0, gl.Str("outColor\x00"))
gl.UseProgram(0)
}
func (this *PostProcessor) Bind() {
gl.BindTexture(gl.TEXTURE_2D, 0)
gl.BindFramebuffer(gl.FRAMEBUFFER, this.fbo)
// Clear buffer
gl.ClearColor(1.0, 0.0, 0.0, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
}
func (this *PostProcessor) Unbind() {
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
}
func (this *PostProcessor) Render() {
gl.Enable(gl.TEXTURE_2D)
gl.UseProgram(this.program)
gl.BindTexture(gl.TEXTURE_2D, this.fboTex)
gl.Uniform1i(int32(this.fTex), 0)
gl.EnableVertexAttribArray(this.vCoord)
gl.BindBuffer(gl.ARRAY_BUFFER, this.vbo)
gl.VertexAttribPointer(
this.vCoord,
2,
gl.FLOAT,
false,
0,
gl.PtrOffset(0),
)
gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
gl.DisableVertexAttribArray(this.vCoord)
gl.UseProgram(0)
gl.Disable(gl.TEXTURE_2D)
}
func (this *PostProcessor) Destroy() {
gl.DeleteTextures(1, &this.fboTex)
gl.DeleteRenderbuffers(1, &this.rboDepth)
gl.DeleteFramebuffers(1, &this.fbo)
gl.DeleteBuffers(1, &this.vbo)
gl.DeleteProgram(this.program)
}
func (this *GLFW3OpenGlCtx) Draw() error {
// Bind frame buffer and render our scene
this.pp.Bind()
this.square.Draw()
this.pp.Unbind()
// Clear screen
gl.ClearColor(0.0, 1.0, 0.0, 1.0)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
// Render frame buffer
this.pp.Render()
// Refresh window
this.window.SwapBuffers()
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment