dungeon_crawler

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