Skip to content

Commit c5aa713

Browse files
committed
feat: add Lights(mesh layer); rewrite model_t(vertices) to support quaternion
1 parent 84cc671 commit c5aa713

File tree

6 files changed

+193
-50
lines changed

6 files changed

+193
-50
lines changed

core/entity_layer.hpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
#include "core/mesh_layer.hpp"
2+
#include "core/vertices_layer.hpp"
3+
#include "utils/debug.hpp"
24

35
namespace Ez3DGL{
46

5-
class MotionObj{
7+
class DynamicObj{
68
public:
7-
float mass=1;
8-
void apply_force(glm::vec3 force){
9+
DynamicObj(glm::vec3 pos, float mass=1): position(pos), velocity(0), acceleration(0), mass(mass){}
10+
glm::vec3 update_dynamic(const glm::vec3 force, float delta_time_seconds){
911
acceleration = force / mass;
10-
}
11-
glm::vec3 update(float delta_time_seconds){
1212
position += velocity * delta_time_seconds + acceleration * delta_time_seconds * delta_time_seconds * 0.5f;
13+
velocity += acceleration * delta_time_seconds;
1314
return position;
1415
}
1516
glm::vec3 pos() const{
@@ -19,20 +20,25 @@ class MotionObj{
1920
return velocity;
2021
}
2122
private:
23+
float mass=1;
2224
glm::vec3 position;
2325
glm::vec3 velocity;
2426
glm::vec3 acceleration;
2527
};
2628

27-
class RenderObj{
28-
public:
29-
void render(){
30-
// render
31-
}
32-
private:
33-
Model* model;
34-
Shader* shader;
29+
// class RenderObj{
30+
// public:
31+
// RenderObj(Shader* shader, Model* model, model_t* mat_model):
32+
// shader(shader), model(model), mat_model(mat_model){}
33+
// void render(const Lights* lights, const camera_t* camera){
34+
// lights->apply_shader(shader);
35+
// model->draw(shader, camera, mat_model);
36+
// }
37+
// private:
38+
// model_t* mat_model;
39+
// Model* model;
40+
// Shader* shader;
3541

36-
};
42+
// };
3743

3844
}

core/mesh_layer.hpp

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ struct Texture {
3333

3434
class Shader{
3535
public:
36+
float tmp_material_shininess=32;
37+
3638
void setup_shader(){
3739
assert_with_info(shader==nullptr, "shader is already setup");
3840
shader = new shader_t("../shader/fragpos_normal_texcoord_lightpos.vs", "../shader/multiple_lights.fs", "view", "projection", "model");
3941
}
42+
// TODO update_lights
4043
void bind(const std::vector<Texture>& textures, const camera_t* camera, const model_t* model){
4144
assert_with_info(shader!=nullptr, "forget to setup shader");
4245
shader->use();
@@ -60,6 +63,7 @@ class Shader{
6063
}
6164
// shader->set_uniform("diffuse_num", diffuse_cnt);
6265
// shader->set_uniform("specular_num", spaiTexecular_cnt);
66+
shader->set_uniform("material.shininess", tmp_material_shininess);
6367
shader->set_uniform("viewPos", camera->position);
6468
shader->update_camera(camera);
6569
shader->update_model(model);
@@ -68,8 +72,11 @@ class Shader{
6872
if(shader!=nullptr)
6973
delete shader;
7074
}
71-
shader_t* shader=nullptr;
75+
friend class LightDir;
76+
friend class LightPoint;
77+
friend class LightSpot;
7278
private:
79+
shader_t* shader=nullptr;
7380
};
7481

7582
class Mesh{
@@ -87,9 +94,9 @@ class Mesh{
8794
delete vert;
8895
}
8996

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{
9198
assert_with_info(vert!=nullptr, "forget to setup vertices");
92-
shader.bind(textures, camera, model);
99+
shader->bind(textures, camera, model);
93100
vert->draw_element(GL_TRIANGLES);
94101
}
95102
private:
@@ -98,13 +105,20 @@ class Mesh{
98105

99106
class Model{
100107
public:
108+
Model()=default;
101109
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;
102115
load_model(path);
103116
for(auto& mesh: meshes){
104117
mesh.setup_vertices();
105118
}
106119
}
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");
108122
for(const auto& mesh: meshes){
109123
mesh.draw(shader, camera, model);
110124
}
@@ -116,6 +130,7 @@ class Model{
116130
private:
117131
std::vector<Mesh> meshes;
118132
std::vector<Texture> loaded_textures;
133+
std::string model_path;
119134
std::string directory;
120135
void load_model(std::string path){
121136
Assimp::Importer import;
@@ -205,19 +220,125 @@ class Model{
205220
}
206221
};
207222

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+
208321
/**
209322
* @brief 光源对象,支持定向光源,点光源,聚光
210323
*
211324
*/
212-
class Light{
325+
class Lights{
213326
public:
214-
215-
light_dir_t dir_light;
327+
std::vector<LightDir> dir_light;
216328
// 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+
}
221342
};
222343

223344
}

core/vertices_layer.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "stb_image.h"
1313
#include <cmath>
1414
#include "utils/debug.hpp"
15+
#include <glm/gtx/quaternion.hpp>
1516

1617
using namespace Ez3DGL;
1718

@@ -403,7 +404,13 @@ void camera_t::input_fov(double scroll){
403404
}
404405

405406
glm::mat4 model_t::get_model() const{
406-
return get_trans_mat(pos, scale, rotate_degree, rotate_axis);
407+
auto parent_trans = glm::mat4(1.);
408+
if(parent)
409+
parent_trans = parent->get_model();
410+
const auto transl_trans = glm::translate(glm::mat4(1.), pos);
411+
const auto rotate_trans = glm::toMat4(quaternion);
412+
const auto scala_trans = glm::scale(glm::mat4(1.), scale);
413+
return parent_trans * transl_trans * rotate_trans * scala_trans;
407414
}
408415

409416
glm::mat4 model_t::move_to(glm::vec3 x){
@@ -431,27 +438,32 @@ glm::mat4 model_t::scale_to(glm::vec3 x){
431438
return get_model();
432439
}
433440

434-
glm::mat4 model_t::rotate_to(float x, glm::vec3 axis){
435-
rotate_degree = x;
436-
rotate_axis = axis;
441+
glm::mat4 model_t::rotate_to(float degree, glm::vec3 axis){
442+
quaternion =glm::angleAxis(glm::radians(degree), axis);
443+
return get_model();
444+
}
445+
446+
glm::mat4 model_t::rotate_to(glm::vec3 pitch_yaw_roll_degree){
447+
quaternion = glm::quat(pitch_yaw_roll_degree);
437448
return get_model();
438449
}
439450

451+
glm::mat4 model_t::rotate(glm::vec3 pitch_yaw_roll_degree){
452+
const auto q = glm::quat(glm::radians(pitch_yaw_roll_degree));
453+
quaternion *= q;
454+
return get_model();
455+
}
456+
457+
glm::vec3 model_t::look_at_dir() const{
458+
return glm::normalize(quaternion * dir);
459+
}
460+
440461
void model_t::set_parent_model(struct model_t *p) {
441462
parent = p;
442463
}
443464

444-
glm::mat4 model_t::get_trans_mat(glm::vec3 pos, glm::vec3 scale, float rotate_degree, glm::vec3 rotate_axis) const{
445-
auto trans = glm::mat4(1.);
446-
if(parent)
447-
trans = parent->get_model();
448-
trans = glm::translate(trans, pos);
449-
trans = glm::rotate(trans, glm::radians(rotate_degree), rotate_axis);
450-
trans = glm::scale(trans, scale);
451-
return trans;
452-
}
453465

454-
model_t::model_t(glm::vec3 pos, glm::vec3 scale, class model_t *p):pos(pos), scale(scale), parent(p) {
466+
model_t::model_t(glm::vec3 pos, glm::vec3 scale, glm::vec3 init_dir, class model_t *p):pos(pos), scale(scale), dir(init_dir), parent(p) {
455467

456468
}
457469

core/vertices_layer.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <initializer_list>
1919
#include <memory>
2020
#include <vector>
21+
#include <glm/gtc/quaternion.hpp>
2122

2223
namespace Ez3DGL {
2324

@@ -158,11 +159,11 @@ class model_t{
158159
public:
159160
glm::vec3 pos;
160161
glm::vec3 scale=glm::vec3(1.);
161-
glm::vec3 rotate_axis=glm::vec3(0, 0, 1);
162-
float rotate_degree=0;
162+
glm::vec3 dir;
163+
glm::quat quaternion;
163164

164165
model_t()=default;
165-
model_t(glm::vec3 pos, glm::vec3 scale=glm::vec3(1.), class model_t* p=nullptr);
166+
model_t(glm::vec3 pos, glm::vec3 scale=glm::vec3(1.), glm::vec3 init_dir=glm::vec3(0, 0, 1), class model_t* p=nullptr);
166167

167168
glm::mat4 get_model() const;
168169
glm::mat4 move_to(glm::vec3 pos);
@@ -171,9 +172,10 @@ class model_t{
171172
glm::mat4 scale_to(glm::vec3 x);
172173
glm::mat4 scale_to(float x, float y, float z);
173174
glm::mat4 rotate_to(float degree, glm::vec3 axis);
175+
glm::mat4 rotate_to(glm::vec3 pitch_yaw_roll_degree);
176+
glm::mat4 rotate(glm::vec3 pitch_yaw_roll_degree);
177+
glm::vec3 look_at_dir() const;
174178
void set_parent_model(class model_t* p);
175-
176-
glm::mat4 get_trans_mat(glm::vec3 pos, glm::vec3 scale, float rotate_degree, glm::vec3 rotate_axis) const;
177179
private:
178180
class model_t* parent = nullptr;
179181
};

0 commit comments

Comments
 (0)