backup
[demo] / src / renderer.cc
1 #include <GL/glew.h>
2
3 #include "global.h"
4 #include "gfxapi.h"
5
6 #include "camera.h"
7 #include "mesh.h"
8 #include "meshgen.h"
9 #include "object.h"
10 #include "renderer.h"
11 #include "scene.h"
12 #include "shader.h"
13 #include "shader_manager.h"
14 #include "texture.h"
15 #include "uniforms.h"
16
17 #undef DRAW_NORMALS
18
19 /* skybox */
20
21 static Mesh *skymesh; /* it will be used by many renderers => no destroy */
22 static ShaderProgram *skyprog;
23
24 Renderer::Renderer()
25 {
26         scene = 0;
27         camera = 0;
28         sprog = 0;
29
30         skytex = 0;
31         dskytex = 0;
32
33         fog_density = 0;
34
35         vbuf = fbuf = svbuf = 0;
36 }
37
38 Renderer::~Renderer()
39 {
40         delete vbuf;
41         delete fbuf;
42         delete svbuf;
43 }
44
45 bool Renderer::create()
46 {
47         //debug
48         // if(!(nprog = sdr_man->create_shader_program("debug.v.glsl", "debug.f.glsl"))) {
49         //      fprin
50         //      tf(stderr, "Failed to load debug shaders.\n");
51         // }
52
53         vbuf = gfx_create_uniform_buffer();
54         if(!vbuf->create(sizeof vu)) {
55                 fprintf(stderr, "Failed to create uniform buffer.\n");
56                 return false;
57         }
58
59         fbuf = gfx_create_uniform_buffer();
60         if(!fbuf->create(sizeof fu)) {
61                 fprintf(stderr, "Failed to create uniform buffer.\n");
62                 return false;
63         }
64
65         svbuf = gfx_create_uniform_buffer();
66         if(!svbuf->create(sizeof svu)) {
67                 fprintf(stderr, "Failed to create uniform buffer.\n");
68                 return false;
69         }
70
71         if(!(sprog = sdr_man->create_shader_program("default.v.glsl", "default.f.glsl"))) {
72                 return false;
73         }
74
75         return true;
76 }
77
78 void Renderer::draw()
79 {
80         if(!camera || !scene)
81                 return;
82
83         if(skytex) {
84                 draw_skybox();
85
86                 if(dskytex) {
87                         dskytex->bind(1);
88                 }
89         }
90
91         if(!sprog->link())
92                 return;
93
94         sprog->use();
95
96         for(size_t i=0; i<scene->objects.size(); i++) {
97                 draw_object(scene->objects[i]);
98         }
99 }
100
101 void Renderer::draw_object(Object *object)
102 {
103         Material *m = object->material;
104
105         /* setting uniforms for material */
106
107         fu.diffuse = Vec4(m->diffuse.x, m->diffuse.y, m->diffuse.z, 1.0);
108         fu.specular = Vec4(m->specular.x, m->specular.y, m->specular.z, 1.0);
109         fu.shininess = m->shininess;
110         fu.fog_density = fog_density;
111
112         fbuf->update(&fu);
113         fbuf->bind(SHADING_UNIFORMS);
114
115         /* texture */
116
117         if(m->dtex)
118                 m->dtex->bind(0);
119
120         /* setting uniforms for matrices */
121
122         vu.mview = object->transform * camera->get_view_matrix();
123         vu.mmviewproj = object->transform * camera->get_view_matrix() * mprojection;
124         vu.mmod = object->transform.upper3x3();
125
126         vbuf->update(&vu);
127         vbuf->bind(MATRIX_UNIFORMS);
128
129         object->mesh->draw();
130
131         // debug
132 #ifdef DRAW_NORMALS
133         if(nprog) {
134                 vu.mmviewproj = mmviewproj;
135                 vbuf->update(&vu);
136                 vbuf->bind(MATRIX_UNIFORMS);
137
138                 nprog->use();
139                 object->mesh->draw_normals(1.0);
140         }
141 #endif
142 }
143
144 void Renderer::set_sky_tex(Texture *stex)
145 {
146         if(!skymesh) {
147                 skymesh = gfx_create_mesh();
148                 gen_geosphere(skymesh, 1, 0);
149         }
150         if(!skyprog) {
151                 if(!(skyprog = sdr_man->create_shader_program("sky.v.glsl", "sky.f.glsl")))
152                         return;
153         }
154         skytex = stex;
155 }
156
157 void Renderer::set_diffuse_sky_tex(Texture *dstex)
158 {
159         dskytex = dstex;
160 }
161
162 void Renderer::draw_skybox()
163 {
164         if(!skymesh || !skytex)
165                 return;
166
167         gfx_zbuffer(false);
168         gfx_cull_face(GFX_CULL_NONE);
169
170         skytex->bind();
171         skyprog->use();
172
173         svu.mviewproj = camera->get_view_matrix().upper3x3() * mprojection;
174         svbuf->update(&svu);
175         svbuf->bind(SKY_MATRIX_UNIFORMS);
176
177         skymesh->draw();
178
179         gfx_cull_face(GFX_CULL_BACK);
180         gfx_zbuffer(true);
181 }