rev |
line source |
nuclear@60
|
1 #include <stdio.h>
|
nuclear@60
|
2 #include <stdlib.h>
|
nuclear@60
|
3 #include <string.h>
|
nuclear@60
|
4 #include "opengl.h"
|
nuclear@60
|
5 #include "renderer_multipass.h"
|
nuclear@60
|
6 #include "level.h"
|
nuclear@60
|
7 #include "sdr.h"
|
nuclear@60
|
8 #include "datapath.h"
|
nuclear@60
|
9
|
nuclear@60
|
10 static unsigned int load_sdr(const char *vfname, const char *pfname);
|
nuclear@60
|
11
|
nuclear@60
|
12
|
nuclear@60
|
13 MultipassRenderer::MultipassRenderer()
|
nuclear@60
|
14 {
|
nuclear@60
|
15 for(int i=0; i<MRT_COUNT; i++) {
|
nuclear@60
|
16 rt_prog[i] = 0;
|
nuclear@60
|
17 }
|
nuclear@60
|
18 }
|
nuclear@60
|
19
|
nuclear@60
|
20 MultipassRenderer::~MultipassRenderer()
|
nuclear@60
|
21 {
|
nuclear@60
|
22 for(int i=0; i<MRT_COUNT; i++) {
|
nuclear@60
|
23 if(rt_prog[i]) {
|
nuclear@60
|
24 free_program(rt_prog[i]);
|
nuclear@60
|
25 }
|
nuclear@60
|
26 }
|
nuclear@60
|
27 }
|
nuclear@60
|
28
|
nuclear@60
|
29 bool MultipassRenderer::init(int xsz, int ysz)
|
nuclear@60
|
30 {
|
nuclear@60
|
31 width = xsz;
|
nuclear@60
|
32 height = ysz;
|
nuclear@60
|
33
|
nuclear@60
|
34 if(!GLEW_ARB_texture_float) {
|
nuclear@60
|
35 fprintf(stderr, "%s: error: no floating point texture support\n", __func__);
|
nuclear@60
|
36 return false;
|
nuclear@60
|
37 }
|
nuclear@60
|
38
|
nuclear@60
|
39 if(!create_fbo()) {
|
nuclear@60
|
40 return false;
|
nuclear@60
|
41 }
|
nuclear@60
|
42
|
nuclear@60
|
43 for(int i=0; i<MRT_COUNT; i++) {
|
nuclear@60
|
44 char fname[128];
|
nuclear@60
|
45 sprintf(fname, "multi%d.p.glsl", i);
|
nuclear@60
|
46
|
nuclear@60
|
47 if(!(rt_prog[i] = load_sdr("mrt.v.glsl", fname))) {
|
nuclear@60
|
48 return false;
|
nuclear@60
|
49 }
|
nuclear@60
|
50 set_uniform_int(rt_prog[i], "tex_dif", 0);
|
nuclear@60
|
51 set_uniform_int(rt_prog[i], "tex_norm", 1);
|
nuclear@60
|
52 }
|
nuclear@60
|
53
|
nuclear@60
|
54 if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) {
|
nuclear@60
|
55 return false;
|
nuclear@60
|
56 }
|
nuclear@60
|
57 for(int i=0; i<MRT_COUNT; i++) {
|
nuclear@60
|
58 char uname[32];
|
nuclear@60
|
59 sprintf(uname, "mrt%d", i);
|
nuclear@60
|
60 set_uniform_int(deferred_omni, uname, i);
|
nuclear@60
|
61 }
|
nuclear@60
|
62
|
nuclear@60
|
63 rend = this;
|
nuclear@60
|
64 return true;
|
nuclear@60
|
65 }
|
nuclear@60
|
66
|
nuclear@60
|
67 int MultipassRenderer::get_tangent_location() const
|
nuclear@60
|
68 {
|
nuclear@60
|
69 if(!curr_prog) {
|
nuclear@60
|
70 return -1;
|
nuclear@60
|
71 }
|
nuclear@60
|
72 return get_attrib_loc(curr_prog, "attr_tangent");
|
nuclear@60
|
73 }
|
nuclear@60
|
74
|
nuclear@60
|
75 void MultipassRenderer::render(const Level *level) const
|
nuclear@60
|
76 {
|
nuclear@62
|
77 render_pre(level);
|
nuclear@62
|
78
|
nuclear@60
|
79 // render into the MRT buffers
|
nuclear@60
|
80 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
|
nuclear@60
|
81
|
nuclear@60
|
82 for(int i=0; i<MRT_COUNT; i++) {
|
nuclear@60
|
83 glUseProgram(rt_prog[i]);
|
nuclear@60
|
84 curr_prog = rt_prog[i];
|
nuclear@60
|
85
|
nuclear@60
|
86 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
nuclear@60
|
87 mrt_tex[i], 0);
|
nuclear@60
|
88
|
nuclear@60
|
89 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
nuclear@60
|
90 level->draw();
|
nuclear@60
|
91 }
|
nuclear@60
|
92 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
|
nuclear@60
|
93
|
nuclear@60
|
94 // post-process lighting
|
nuclear@60
|
95 light_pass(level);
|
nuclear@60
|
96
|
nuclear@60
|
97 glUseProgram(0);
|
nuclear@60
|
98 curr_prog = 0;
|
nuclear@62
|
99
|
nuclear@62
|
100 render_post(level);
|
nuclear@60
|
101 }
|
nuclear@60
|
102
|
nuclear@60
|
103 static unsigned int load_sdr(const char *vfname, const char *pfname)
|
nuclear@60
|
104 {
|
nuclear@60
|
105 char vsfile[PATH_MAX], psfile[PATH_MAX];
|
nuclear@60
|
106 const char *fname;
|
nuclear@60
|
107 unsigned int prog;
|
nuclear@60
|
108
|
nuclear@60
|
109 if((fname = datafile_path(vfname))) {
|
nuclear@60
|
110 strcpy(vsfile, fname);
|
nuclear@60
|
111 } else {
|
nuclear@60
|
112 vsfile[0] = 0;
|
nuclear@60
|
113 }
|
nuclear@60
|
114 if((fname = datafile_path(pfname))) {
|
nuclear@60
|
115 strcpy(psfile, fname);
|
nuclear@60
|
116 } else {
|
nuclear@60
|
117 psfile[0] = 0;
|
nuclear@60
|
118 }
|
nuclear@60
|
119 if(!(prog = create_program_load(vsfile, psfile))) {
|
nuclear@60
|
120 fprintf(stderr, "failed to load shader program (%s, %s)\n", vsfile, psfile);
|
nuclear@60
|
121 return 0;
|
nuclear@60
|
122 }
|
nuclear@60
|
123 return prog;
|
nuclear@60
|
124 }
|