@@ -33,10 +33,13 @@ struct Texture {
33
33
34
34
class Shader {
35
35
public:
36
+ float tmp_material_shininess=32 ;
37
+
36
38
void setup_shader (){
37
39
assert_with_info (shader==nullptr , " shader is already setup" );
38
40
shader = new shader_t (" ../shader/fragpos_normal_texcoord_lightpos.vs" , " ../shader/multiple_lights.fs" , " view" , " projection" , " model" );
39
41
}
42
+ // TODO update_lights
40
43
void bind (const std::vector<Texture>& textures, const camera_t * camera, const model_t * model){
41
44
assert_with_info (shader!=nullptr , " forget to setup shader" );
42
45
shader->use ();
@@ -60,6 +63,7 @@ class Shader{
60
63
}
61
64
// shader->set_uniform("diffuse_num", diffuse_cnt);
62
65
// shader->set_uniform("specular_num", spaiTexecular_cnt);
66
+ shader->set_uniform (" material.shininess" , tmp_material_shininess);
63
67
shader->set_uniform (" viewPos" , camera->position );
64
68
shader->update_camera (camera);
65
69
shader->update_model (model);
@@ -68,8 +72,11 @@ class Shader{
68
72
if (shader!=nullptr )
69
73
delete shader;
70
74
}
71
- shader_t * shader=nullptr ;
75
+ friend class LightDir ;
76
+ friend class LightPoint ;
77
+ friend class LightSpot ;
72
78
private:
79
+ shader_t * shader=nullptr ;
73
80
};
74
81
75
82
class Mesh {
@@ -87,9 +94,9 @@ class Mesh{
87
94
delete vert;
88
95
}
89
96
90
- void draw (Shader& shader, const camera_t * camera, const model_t * model) const {
97
+ void draw (Shader* shader, const camera_t * camera, const model_t * model) const {
91
98
assert_with_info (vert!=nullptr , " forget to setup vertices" );
92
- shader. bind (textures, camera, model);
99
+ shader-> bind (textures, camera, model);
93
100
vert->draw_element (GL_TRIANGLES);
94
101
}
95
102
private:
@@ -98,13 +105,20 @@ class Mesh{
98
105
99
106
class Model {
100
107
public:
108
+ Model ()=default ;
101
109
Model (std::string path){
110
+ setup_model (path);
111
+ }
112
+ void setup_model (std::string path){
113
+ assert_with_info (model_path.empty (), " model is already setup" );
114
+ model_path = path;
102
115
load_model (path);
103
116
for (auto & mesh: meshes){
104
117
mesh.setup_vertices ();
105
118
}
106
119
}
107
- void draw (Shader& shader, const camera_t * camera, const model_t * model){
120
+ void draw (Shader* shader, const camera_t * camera, const model_t * model){
121
+ assert_with_info (!model_path.empty (), " forget to setup model" );
108
122
for (const auto & mesh: meshes){
109
123
mesh.draw (shader, camera, model);
110
124
}
@@ -116,6 +130,7 @@ class Model{
116
130
private:
117
131
std::vector<Mesh> meshes;
118
132
std::vector<Texture> loaded_textures;
133
+ std::string model_path;
119
134
std::string directory;
120
135
void load_model (std::string path){
121
136
Assimp::Importer import ;
@@ -205,19 +220,125 @@ class Model{
205
220
}
206
221
};
207
222
223
+ class LightBase {
224
+ public:
225
+ glm::vec3 ambient=glm::vec3(0 .2f , 0 .2f , 0 .2f );
226
+ glm::vec3 diffuse=glm::vec3(0 .5f , 0 .5f , 0 .5f );
227
+ glm::vec3 specular=glm::vec3(1 .0f , 1 .0f , 1 .0f );
228
+
229
+ LightBase (glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular):ambient(ambient), diffuse(diffuse), specular(specular) {
230
+
231
+ }
232
+
233
+ virtual void apply_shader (Shader* shader) const = 0;
234
+ };
235
+
236
+ class LightDir : public LightBase {
237
+ public:
238
+ glm::vec3 direction;
239
+ LightDir (glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular, glm::vec3 direction):
240
+ LightBase (ambient, diffuse, specular), direction(direction) {
241
+
242
+ }
243
+ void apply_shader (Shader* shader) const override {
244
+ shader->shader ->use ();
245
+
246
+ shader->shader ->set_uniform (" light_dir.ambient" , ambient);
247
+ shader->shader ->set_uniform (" light_dir.diffuse" , diffuse);
248
+ shader->shader ->set_uniform (" light_dir.specular" , specular);
249
+
250
+ shader->shader ->set_uniform (" light_dir.direction" , direction);
251
+ }
252
+ };
253
+
254
+ class LightPoint : public LightBase {
255
+ public:
256
+ glm::vec3 position;
257
+
258
+ float constant = 1 .f;
259
+ float linear = 0 .0014f ;
260
+ float quadratic = 0 .000007f ;
261
+
262
+ LightPoint (glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular,
263
+ glm::vec3 position,
264
+ float constant, float linear, float quadratic):
265
+ LightBase (ambient, diffuse, specular), position(position), constant(constant), linear(linear), quadratic(quadratic) {
266
+ }
267
+ void apply_shader (Shader* shader) const override {
268
+ shader->shader ->use ();
269
+
270
+ shader->shader ->set_uniform (" light_point.ambient" , ambient);
271
+ shader->shader ->set_uniform (" light_point.diffuse" , diffuse);
272
+ shader->shader ->set_uniform (" light_point.specular" , specular);
273
+
274
+ shader->shader ->set_uniform (" light_point.position" , position);
275
+
276
+ shader->shader ->set_uniform (" light_point.constant" , constant);
277
+ shader->shader ->set_uniform (" light_point.linear" , linear);
278
+ shader->shader ->set_uniform (" light_point.quadratic" , quadratic);
279
+ }
280
+ };
281
+
282
+ class LightSpot : public LightPoint {
283
+ public:
284
+ glm::vec3 direction;
285
+ float inner_degree;
286
+ float outer_degree;
287
+
288
+ LightSpot (glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular,
289
+ glm::vec3 position, glm::vec3 direction,
290
+ float constant, float linear, float quadratic,
291
+ float inner_degree, float outer_degree):
292
+ LightPoint (ambient, diffuse, specular, position, constant, linear, quadratic),
293
+ direction (direction),
294
+ inner_degree (inner_degree), outer_degree(outer_degree) {
295
+ assert_with_info (inner_degree<outer_degree, " inner degree must be less than outer degree" );
296
+ }
297
+ void apply_shader (Shader* shader) const override {
298
+ shader->shader ->use ();
299
+
300
+ auto cutoff = glm::cos (glm::radians (inner_degree));
301
+ auto cutoff_outer = glm::cos (glm::radians (outer_degree));
302
+ shader->shader ->set_uniform (" light_spot.ambient" , ambient);
303
+ shader->shader ->set_uniform (" light_spot.diffuse" , diffuse);
304
+ shader->shader ->set_uniform (" light_spot.specular" , specular);
305
+
306
+ shader->shader ->set_uniform (" light_spot.position" , position);
307
+ shader->shader ->set_uniform (" light_spot.direction" , direction);
308
+
309
+ shader->shader ->set_uniform (" light_spot.constant" , constant);
310
+ shader->shader ->set_uniform (" light_spot.linear" , linear);
311
+ shader->shader ->set_uniform (" light_spot.quadratic" , quadratic);
312
+
313
+ shader->shader ->set_uniform (" light_spot.cutoff" , cutoff);
314
+ shader->shader ->set_uniform (" light_spot.cutoff_outer" , cutoff_outer);
315
+ }
316
+ private:
317
+
318
+ };
319
+
320
+
208
321
/* *
209
322
* @brief 光源对象,支持定向光源,点光源,聚光
210
323
*
211
324
*/
212
- class Light {
325
+ class Lights {
213
326
public:
214
-
215
- light_dir_t dir_light;
327
+ std::vector<LightDir> dir_light;
216
328
// note that the size has limited
217
- std::vector<light_point_t > point_lights;
218
- light_spot_t spot_light;
219
-
220
-
329
+ std::vector<LightPoint> point_lights;
330
+ std::vector<LightSpot> spot_light;
331
+ void apply_shader (Shader* shader) const {
332
+ for (const auto & dir : dir_light){
333
+ dir.apply_shader (shader);
334
+ }
335
+ for (const auto & point : point_lights){
336
+ point.apply_shader (shader);
337
+ }
338
+ for (const auto & spot : spot_light){
339
+ spot.apply_shader (shader);
340
+ }
341
+ }
221
342
};
222
343
223
344
}
0 commit comments