-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathObject.hpp
258 lines (202 loc) · 8.01 KB
/
Object.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#pragma once
#define GL_SILENCE_DEPRECATION // silences warnings on macOS 10.14 related to deprecated OpenGL functions
#include "cs488-framework/ShaderProgram.hpp"
#include "cs488-framework/GlErrorCheck.hpp"
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/io.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <string>
#include <vector>
#include <unordered_map>
#include <iostream>
#include "Renderable.hpp"
class Scene;
class Model;
/***********************************************************
Abstract Base Class
***********************************************************/
class Object : public Renderable {
protected:
// Pointer to the scene in order to access the camera, light source, terrain, etc
Scene* m_scene;
ShaderProgram* m_shader;
GLuint m_vao;
GLuint m_vbo;
GLuint m_ebo;
std::vector <GLuint> m_textureIDs;
glm::vec3 m_position;
float m_size;
glm::vec3 m_rotation; // in degrees, angle per axis
// Helpers for binding data to buffers
GLuint storeToVBO(GLfloat* vertices, int size);
GLuint storeToVBO(GLfloat* positions, int sizeP, GLfloat* normals, int sizeN, GLfloat* texCoords, int sizeT);
GLuint storeToEBO(GLuint* indices, int size);
GLuint storeTex(std::string path, GLenum wrapping = GL_REPEAT);
GLuint storeCubeMap(std::vector<std::string>& faces);
// Template method pattern: the following helper functions can be overridden
// by derived classes to customize the rendering of the objects
virtual void uploadLightingUniforms();
virtual void uploadMaterialUniforms(glm::vec3 kd, glm::vec3 ks, float shininess);
virtual void uploadModelUniform();
virtual void uploadViewUniform();
virtual void uploadProjectionUniform();
virtual void uploadClippingUniforms(Mode m);
virtual void uploadCustomUniforms(Mode m);
virtual void bindData();
virtual void drawElements();
virtual void releaseData();
public:
Object(ShaderProgram* shader, Scene* scene);
virtual ~Object();
void render(Mode m) final;
virtual void renderToShadowMap() {};
virtual glm::vec3 position() { return m_position; }; // virtual bc Sun overrides it
virtual glm::mat4 modelMatrix(); // public bc Character accesses it
void setPosition(glm::vec3 p) { m_position = p; };
void setSize(float s) { m_size = s; };
void setRotation(glm::vec3 r) { m_rotation = r; };
void rotate(glm::vec3 rotation) { m_rotation += rotation; };
};
/***********************************************************
Derived Classes
***********************************************************/
class Skybox : public Object {
float m_rotationSpeed; // degrees per second
bool m_isDay;
// Overridden template methods
void uploadLightingUniforms() override;
void uploadModelUniform() override;
void uploadViewUniform() override;
void uploadClippingUniforms(Mode m) override;
void uploadCustomUniforms(Mode m) override;
void bindData() override;
void drawElements() override;
void releaseData() override;
public:
Skybox(ShaderProgram* shader, Scene* scene, float rotateSpeed);
void setRotationSpeed(float r) { m_rotationSpeed = r; };
bool isDay() { return m_isDay; };
float time() { return m_rotation.y / -360.0f; }; // Returns a value from 0-1 indicating how far
// though the current time (day or night) we are
};
// ------------------------------
class Water : public Object {
float m_distortion;
bool m_bumpMapping;
Mode m_renderingMode;
// Overridden template methods
void uploadLightingUniforms() override;
void uploadClippingUniforms(Mode m) override;
void uploadCustomUniforms(Mode m) override;
void bindData() override;
void drawElements() override;
void releaseData() override;
public:
Water(ShaderProgram* shader, Scene* scene);
void setDistortion(float d) { m_distortion = d; };
void setBumpMapping(bool b) { m_bumpMapping = b; };
void setMode(Mode m) { m_renderingMode = m; };
};
// ------------------------------
class Terrain : public Object {
float m_size; // size of one side of the terrain square
float m_maxHeight; // height of the peaks
int m_texture;
int m_numIndices;
unsigned m_heightMapSize;
// Calculate these at initialization
std::vector< std::vector<float> > m_heights;
std::vector< std::vector<glm::vec3> > m_normals;
void calculateHeightsAndNormals(unsigned char* heightMap);
float baryCentric(glm::vec3 p1, glm::vec3 p2, glm::vec3 p3, glm::vec2 pos);
// Overridden template methods
void uploadCustomUniforms(Mode m) override;
void bindData() override;
void drawElements() override;
void releaseData() override;
public:
Terrain(ShaderProgram* shader, Scene* scene, float size, float maxHeight);
float getHeightAt(float x, float z);
float getSize() { return m_size; };
};
// ------------------------------
// The sun is a 2D texture which is rendered in front of the skybox
// It also acts as the light source for the scene
class Sun : public Object {
glm::vec3 m_color;
glm::vec3 m_directionToSun;
float m_dist;
// Shadow map clipping planes
float m_left;
float m_right;
float m_top;
float m_bottom;
float m_near;
float m_far;
void updateDirectionToSun();
void updateClippingPlanes();
glm::vec3 clippingBoxCenter();
// Overridden template methods
void uploadLightingUniforms() override;
void uploadClippingUniforms(Mode m) override;
void uploadCustomUniforms(Mode m) override;
void bindData() override;
void drawElements() override;
void releaseData() override;
public:
Sun(ShaderProgram* shader, Scene* scene);
glm::vec3 color() { return m_color; };
glm::vec3 position() override { return m_dist * m_directionToSun; };
glm::mat4 modelMatrix() override;
// View & projection matrix from the Sun's perspective are for shadow mappings
glm::mat4 viewMatrix();
glm::mat4 orthographicProjMatrix();
};
// ------------------------------
// An Image2D is a 2D GUI image which is rendered directly to the screen (2D space, not 3D space)
class Image2D : public Object {
glm::vec2 m_size2D;
float m_transparency;
// Overridden template methods
void uploadLightingUniforms() override;
void uploadViewUniform() override;
void uploadProjectionUniform() override;
void uploadClippingUniforms(Mode m) override;
void uploadCustomUniforms(Mode m) override;
void bindData() override;
void drawElements() override;
void releaseData() override;
public:
Image2D(ShaderProgram* shader, Scene* scene, std::string path, glm::vec2 size);
glm::mat4 modelMatrix() override;
void setImage(std::string path);
void setTransparency(float t) { m_transparency = t; };
};
// ------------------------------
class Mesh : public Object {
friend class Model; // a container of Meshes
int m_numIndices;
// Overridden template methods
void bindData() override;
void drawElements() override;
void releaseData() override;
void uploadCustomUniforms(Mode m) override;
// Bounding box information (for collision detection)
glm::vec3 m_minBounds;
glm::vec3 m_maxBounds;
GLuint bb_vao;
GLuint bb_vbo;
ShaderProgram bb_shader;
void initBoundingBoxData();
void renderBoundingBox(Mode m);
public:
Mesh(ShaderProgram* shader, Scene* scene, aiMesh* mesh, const aiScene* aiscene, std::string texturePrefix);
~Mesh();
void renderToShadowMap() final;
bool collision(Mesh* m); // checks if the bounding boxes of these meshes collide
glm::vec3 minBounds() { return m_minBounds; };
glm::vec3 maxBounds() { return m_maxBounds; };
};