dungeon_crawler

view prototype/src/renderer.cc @ 17:d98240a13793

lalala
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 20 Aug 2012 06:11:58 +0300
parents 91180ee7b7d9
children 5c41e6fcb300
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <limits.h>
5 #include "opengl.h"
6 #include "renderer.h"
7 #include "sdr.h"
8 #include "datapath.h"
10 static bool create_fbo(int xsz, int ysz);
11 static bool load_shaders();
12 static int round_pow2(int x);
15 #define MRT_COUNT 4
16 static unsigned int mrt_tex[MRT_COUNT];
18 static unsigned int mrt_prog;
19 static unsigned int deferred_omni;
21 static unsigned int fbo, rbuf_depth;
22 static const char *fbstname[] = {
23 "GL_FRAMEBUFFER_COMPLETE",
24 "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
25 "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
26 "no such fbo error",
27 "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
28 "GL_FRAMEBUFFER_INCOMPLETE_FORMATS",
29 "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER",
30 "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER",
31 "GL_FRAMEBUFFER_UNSUPPORTED"
32 };
34 static int fb_xsz, fb_ysz, tex_xsz, tex_ysz;
36 bool init_renderer(int xsz, int ysz)
37 {
38 if(!create_fbo(xsz, ysz)) {
39 return false;
40 }
41 if(!load_shaders()) {
42 return false;
43 }
44 return true;
45 }
47 void destroy_renderer()
48 {
49 free_program(mrt_prog);
50 free_program(deferred_omni);
52 glDeleteTextures(MRT_COUNT, mrt_tex);
53 glDeleteFramebuffersEXT(1, &fbo);
54 }
56 void render_deferred(void (*draw_func)())
57 {
58 bind_program(mrt_prog);
59 draw_func();
60 bind_program(0);
61 }
63 static bool create_fbo(int xsz, int ysz)
64 {
65 unsigned int clamp = GL_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
67 tex_xsz = round_pow2(xsz);
68 tex_ysz = round_pow2(ysz);
69 fb_xsz = xsz;
70 fb_ysz = ysz;
72 if(!glGenFramebuffersEXT) {
73 fprintf(stderr, "FBO support missing\n");
74 return false;
75 }
76 glGenFramebuffersEXT(1, &fbo);
78 glGenRenderbuffersEXT(1, &rbuf_depth);
79 glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth);
80 glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
81 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
83 glGenTextures(MRT_COUNT, mrt_tex);
84 for(int i=0; i<MRT_COUNT; i++) {
85 glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
86 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
87 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
90 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
92 // attach to fbo
93 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
94 mrt_tex[i], 0);
95 }
97 int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
98 if(fbst != GL_FRAMEBUFFER_COMPLETE) {
99 fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]);
100 return false;
101 }
102 return true;
103 }
105 static bool load_shaders()
106 {
107 char vsfile[PATH_MAX], psfile[PATH_MAX];
108 const char *fname;
110 if((fname = datafile_path("mrt.v.glsl"))) {
111 strcpy(vsfile, fname);
112 } else {
113 vsfile[0] = 0;
114 }
115 if((fname = datafile_path("mrt.p.glsl"))) {
116 strcpy(psfile, fname);
117 } else {
118 psfile[0] = 0;
119 }
120 if(!(mrt_prog = create_program_load(vsfile, psfile))) {
121 fprintf(stderr, "failed to load MRT program\n");
122 return false;
123 }
125 if((fname = datafile_path("deferred.v.glsl"))) {
126 strcpy(vsfile, fname);
127 } else {
128 vsfile[0] = 0;
129 }
130 if((fname = datafile_path("deferred.p.glsl"))) {
131 strcpy(psfile, fname);
132 } else {
133 psfile[0] = 0;
134 }
136 if(!(deferred_omni = create_program_load(vsfile, psfile))) {
137 fprintf(stderr, "failed to load deferred shader program\n");
138 return false;
139 }
140 return true;
141 }
143 static int round_pow2(int x)
144 {
145 x--;
146 x = (x >> 1) | x;
147 x = (x >> 2) | x;
148 x = (x >> 4) | x;
149 x = (x >> 8) | x;
150 x = (x >> 16) | x;
151 return x + 1;
152 }