some meshgen and map rendering updates
[voxelands-alt.git] / src / graphics / framebuffer.c
blobec13e66d3cc2604af9c00df033657396024e3824
1 /************************************************************************
2 * framebuffer.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #include "graphics.h"
22 #include "list.h"
24 static struct {
25 framebuffer_t *buffers;
26 int ids;
27 } fbo_data = {
28 NULL,
32 /* create a texture attachment for a fbo */
33 static int fbo_create_texture(int w, int h, fbo_buffer_t *b, uint8_t d)
35 texture_t *t;
37 t = tex_create();
39 glGenTextures(1,&t->glid);
40 glBindTexture(GL_TEXTURE_2D, t->glid);
41 if (d) {
42 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
43 }else{
44 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
47 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
48 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
50 if (d) {
51 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, t->glid, 0);
52 }else{
53 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, t->glid, 0);
56 t->state = 1;
58 b->texture = t;
60 return 0;
63 /* create a buffer attachment for a fbo */
64 static int fbo_create_buffer(int w, int h, fbo_buffer_t *b)
66 glGenRenderbuffers(1,&b->glid);
68 glBindRenderbuffer(GL_RENDERBUFFER, b->glid);
69 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
70 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, b->glid);
72 return 0;
75 /* create a frame buffer object of width and height, with colour and depth buffers optionally bound to textures */
76 framebuffer_t *fbo_create(int w, int h, uint8_t c_texture, uint8_t d_texture)
78 framebuffer_t *f;
80 f = malloc(sizeof(framebuffer_t));
81 if (!f)
82 return NULL;
84 f->depth.glid = 0;
85 f->colour.glid = 0;
86 f->id = ++fbo_data.ids;
87 f->w = w;
88 f->h = h;
90 glGenFramebuffers(1,&f->glid);
92 glBindFramebuffer(GL_FRAMEBUFFER, f->glid);
94 if (c_texture) {
95 glDrawBuffer(GL_COLOR_ATTACHMENT0);
96 fbo_create_texture(w,h,&f->colour,0);
97 }else{
98 glDrawBuffer(GL_NONE);
101 if (d_texture) {
102 fbo_create_texture(w,h,&f->depth,1);
103 }else{
104 fbo_create_buffer(w,h,&f->depth);
107 glBindFramebuffer(GL_FRAMEBUFFER, 0);
109 fbo_data.buffers = list_append(&fbo_data.buffers,f);
111 return f;
114 /* free a framebuffer */
115 void fbo_free(framebuffer_t *f)
117 /* TODO: this */
120 /* get a framebuffer by id */
121 framebuffer_t *fbo_get(int id)
123 framebuffer_t *f = fbo_data.buffers;
125 while (f) {
126 if (f->id == id)
127 return f;
128 f = f->next;
131 return NULL;
134 /* use/bind a framebuffer */
135 void fbo_use(framebuffer_t *f)
137 glBindTexture(GL_TEXTURE_2D, 0);
138 glBindFramebuffer(GL_FRAMEBUFFER, f->glid);
139 glViewport(0, 0, f->w, f->h);
140 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
141 glEnable(GL_DEPTH_TEST);
144 /* unbind framebuffers */
145 void fbo_unbind_all()
147 glBindFramebuffer(GL_FRAMEBUFFER, 0);
148 glViewport(0, 0, wm_data.size.width, wm_data.size.height);