summaryrefslogtreecommitdiff
path: root/tests/fbo.cc
blob: 403a32e81de2c290030300764b45e9169e571365 (plain)
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
#include "fbo.h"
#include <stdio.h>
#include <iostream>

fbo_t *fbo_new()
{
  fbo_t *fbo = new fbo_t;
  fbo->fbo_id = 0;
  fbo->old_fbo_id = 0;
  fbo->renderbuf_id = 0;
  fbo->depthbuf_id = 0;

  return fbo;
}

#define REPORTGLERROR(task) { GLenum tGLErr = glGetError(); if (tGLErr != GL_NO_ERROR) { std::cout << "OpenGL error " << tGLErr << " while " << task << "\n"; } }

bool fbo_init(fbo_t *fbo, size_t width, size_t height)
{
  if (!glewIsSupported("GL_ARB_framebuffer_object")) {
    fprintf(stderr, "Framebuffer extension not found\n");
    return false;
  }

  // Generate and bind FBO
  glGenFramebuffers(1, &fbo->fbo_id);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo_id);
  REPORTGLERROR("binding framebuffer");

  // Generate depth and render buffers
  glGenRenderbuffers(1, &fbo->depthbuf_id);
  glGenRenderbuffers(1, &fbo->renderbuf_id);

  // Create buffers with correct size
  if (!fbo_resize(fbo, width, height)) return false;

  // Attach render and depth buffers
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
                               GL_RENDERBUFFER, fbo->renderbuf_id);
  REPORTGLERROR("specifying color render buffer");

  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    fprintf(stderr, "Problem with OpenGL framebuffer after specifying color render buffer.\n");
    return false;
  }

  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
                               GL_RENDERBUFFER, fbo->depthbuf_id);
  REPORTGLERROR("specifying depth render buffer");

  if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    fprintf(stderr, "Problem with OpenGL framebuffer after specifying depth render buffer.\n");
    return false;
  }

  return true;
}

bool fbo_resize(fbo_t *fbo, size_t width, size_t height)
{
  glBindRenderbuffer(GL_RENDERBUFFER, fbo->depthbuf_id);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
  REPORTGLERROR("creating depth render buffer");

  glBindRenderbuffer(GL_RENDERBUFFER, fbo->renderbuf_id);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
  REPORTGLERROR("creating color render buffer");

  return true;
}

void fbo_delete(fbo_t *fbo)
{
  delete fbo;
}

GLuint fbo_bind(fbo_t *fbo)
{
  glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&fbo->old_fbo_id);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo->fbo_id);
  return fbo->old_fbo_id;
}

void fbo_unbind(fbo_t *fbo)
{
  glBindFramebuffer(GL_FRAMEBUFFER, fbo->old_fbo_id);
}
contact: Jan Huwald // Impressum