10dd7667308c500fab73e3e099c0f5c16f128571
[demo] / src / renderer.cc
1 #include <GL/glew.h>
2 #include <gmath/gmath.h>
3
4 #include "global.h"
5 #include "gfxapi.h"
6
7 #include "camera.h"
8 #include "mesh.h"
9 #include "meshgen.h"
10 #include "object.h"
11 #include "renderer.h"
12 #include "scene.h"
13 #include "shader.h"
14 #include "shader_manager.h"
15 #include "texture.h"
16
17 /* skybox */
18
19 static Mesh *skymesh; /* it will be used by many renderers => no destroy */
20 static ShaderProgram *skyprog;
21 static int viewproj_loc;
22
23 Renderer::Renderer()
24 {
25         scene = 0;
26         camera = 0;
27         sprog = 0;
28
29         skytex = 0;
30         dskytex = 0;
31 }
32
33 Renderer::~Renderer()
34 {
35 }
36
37 bool Renderer::create()
38 {
39         if(!(sprog = sdr_man->create_shader_program("default.v.glsl", "default.f.glsl"))) {
40                 return false;
41         }
42
43         /* getting material uniform locations: diffuse, specular, specular exponent (strength) */
44
45         if((diff_loc = sprog->get_uniform_location("diffuse")) == -1) {
46                 fprintf(stderr, "Invalid uniform location: can't find \"diffuse\".\n");
47                 return false;
48         }
49
50         if((spec_loc = sprog->get_uniform_location("specular")) == -1) {
51                 fprintf(stderr, "Invalid uniform location: can't find \"specular\".\n");
52                 return false;
53         }
54
55         if((shin_loc = sprog->get_uniform_location("shininess")) == -1) {
56                 fprintf(stderr, "Invalid uniform location: can't find \"shininess\".\n");
57                 return false;
58         }
59
60         /* uniform locations for matrices */
61
62         if((mmviewproj_loc = sprog->get_uniform_location("mmviewproj")) == -1) {
63                 fprintf(stderr, "Invalid uniform location: can't find \"mmviewproj\".\n");
64                 return false;
65         }
66
67         if((mview_loc = sprog->get_uniform_location("mview")) == -1) {
68                 fprintf(stderr, "Invalid uniform location: can't find \"mview\".\n");
69                 return false;
70         }
71
72         return true;
73 }
74
75 void Renderer::draw() const
76 {
77         if(!camera || !scene)
78                 return;
79
80         if(!sprog->link())
81                 return;
82
83         sprog->use();
84
85         for(size_t i=0; i<scene->objects.size(); i++) {
86                 draw_object(scene->objects[i]);
87         }
88 }
89
90 void Renderer::draw_object(Object *object) const
91 {
92         Material *m = object->material;
93
94         /* setting uniforms for material */
95
96         sprog->set_uniformf(diff_loc, m->diffuse.x, m->diffuse.y, m->diffuse.z, 1);
97         sprog->set_uniformf(spec_loc, m->specular.x, m->specular.y, m->specular.z, 1);
98         sprog->set_uniformf(shin_loc, m->shininess);
99
100         /* texture */
101
102         if(m->dtex)
103                 m->dtex->bind();
104
105         /* setting uniforms for matrices */
106
107         Mat4 mmviewproj = object->transform * camera->get_view_matrix() * mprojection;
108         sprog->set_uniform_matrix(mmviewproj_loc, mmviewproj);
109
110         Mat4 mview = object->transform * camera->get_view_matrix();
111         sprog->set_uniform_matrix(mview_loc, mview);
112
113         object->mesh->update_vertex_data();
114         object->mesh->draw();
115 }
116
117 void Renderer::set_sky_tex(Texture *stex)
118 {
119         if(!skymesh) {
120                 skymesh = gfx_create_mesh();
121                 gen_geosphere(skymesh, 1, 0);
122         }
123         if(!skyprog) {
124                 if(!(skyprog = sdr_man->create_shader_program("sky.v.glsl", "sky.f.glsl")))
125                         return;
126                 if((viewproj_loc = skyprog->get_uniform_location("viewproj") == -1))
127                         return;
128         }
129         skytex = stex;
130 }
131
132 void Renderer::set_diffuse_sky_tex(Texture *dstex)
133 {
134         dskytex = dstex;
135 }
136
137 void Renderer::draw_skybox()
138 {
139         if(!skymesh || !skytex)
140                 return;
141
142         skytex->bind();
143         skyprog->use();
144
145         Mat4 mviewproj;
146         mviewproj = camera->get_view_matrix().upper3x3() * mprojection;
147         skyprog->set_uniform_matrix(viewproj_loc, mviewproj);
148
149         skymesh->draw();
150 }