Refactor to create Mesh and Model structs
This commit is contained in:
parent
9dd778289c
commit
560619ae5b
163
src/main.cc
163
src/main.cc
@ -52,13 +52,23 @@ struct Camera {
|
||||
|
||||
// pitch, yaw
|
||||
glm::vec2 rotation;
|
||||
|
||||
// View matrix to be sent as uniform to the vertex shader
|
||||
glm::mat4 view_mat;
|
||||
GLint u_view_idx;
|
||||
|
||||
// Projection matrix to be sent as uniform to the vertex shader
|
||||
glm::mat4 projection_mat;
|
||||
GLint u_projection_idx;
|
||||
};
|
||||
|
||||
struct App {
|
||||
SDL_Window *window;
|
||||
SDL_GLContext context;
|
||||
SDL_Event event;
|
||||
struct Transform {
|
||||
glm::mat4 translation;
|
||||
glm::mat4 rotation;
|
||||
glm::mat4 scale;
|
||||
};
|
||||
|
||||
struct Mesh {
|
||||
// VAO is an object that stores the state needed to supply the GPU with the vertex data.
|
||||
// Think of it as a specification or a C struct that defines the types of data stored for the
|
||||
// vertex array including the attributes for each vertex as well the indices buffer if it exists.
|
||||
@ -76,34 +86,31 @@ struct App {
|
||||
GLuint ebo;
|
||||
|
||||
GLuint shader_program;
|
||||
};
|
||||
|
||||
Camera camera;
|
||||
|
||||
float speed;
|
||||
glm::mat4 translation;
|
||||
glm::mat4 rotation;
|
||||
glm::mat4 scale;
|
||||
struct Model {
|
||||
Transform transform;
|
||||
Mesh mesh;
|
||||
|
||||
// Model matrix to be sent as uniform to the vertex shader
|
||||
glm::mat4 model_mat;
|
||||
GLint u_model_idx;
|
||||
|
||||
// View matrix to be sent as uniform to the vertex shader
|
||||
glm::mat4 view_mat;
|
||||
GLint u_view_idx;
|
||||
|
||||
// Projection matrix to be sent as uniform to the vertex shader
|
||||
glm::mat4 projection_mat;
|
||||
GLint u_projection_idx;
|
||||
glm::mat4 model_mat;
|
||||
GLint u_model_idx;
|
||||
};
|
||||
|
||||
struct App {
|
||||
SDL_Window *window;
|
||||
SDL_GLContext context;
|
||||
SDL_Event event;
|
||||
Model model;
|
||||
Camera camera;
|
||||
float speed;
|
||||
glm::vec2 prev_mouse;
|
||||
|
||||
bool running;
|
||||
};
|
||||
|
||||
int init (App &app);
|
||||
void create_vertex_spec (App &app);
|
||||
void create_graphics_pipeline (App &app);
|
||||
void create_vertex_spec (Model &model);
|
||||
void create_graphics_pipeline (Model &model, Camera &camera);
|
||||
void run_main_loop (App &app);
|
||||
void cleanup (App &app);
|
||||
GLuint create_shader_program (const std::string &vertex_shader_source, const std::string &fragment_shader_source);
|
||||
@ -121,10 +128,10 @@ int main() {
|
||||
}
|
||||
|
||||
// Setup the geometry
|
||||
create_vertex_spec(app);
|
||||
create_vertex_spec(app.model);
|
||||
|
||||
// Setup graphics pipeline. At the very minimum creating vertex and fragment shaders
|
||||
create_graphics_pipeline(app);
|
||||
create_graphics_pipeline(app.model, app.camera);
|
||||
|
||||
run_main_loop(app);
|
||||
|
||||
@ -175,27 +182,27 @@ int init(App &app) {
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION)
|
||||
);
|
||||
|
||||
app.speed = 0.04f;
|
||||
app.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f));
|
||||
app.rotation = glm::mat4(1.0f);
|
||||
app.scale = glm::mat4(1.0f);
|
||||
app.camera.rotation = glm::vec2(0.0f, -90.0f);
|
||||
app.camera.position = glm::vec3(0.0f, 0.0f, 3.0f);
|
||||
app.camera.view_direction = rotation_to_view_direction(app.camera);
|
||||
app.camera.up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
app.model_mat = app.translation * app.rotation * app.scale;
|
||||
app.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
||||
app.projection_mat = glm::perspective(glm::radians(60.0f),
|
||||
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
||||
0.1f,
|
||||
20.0f
|
||||
);
|
||||
app.prev_mouse = glm::vec2(WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
|
||||
app.speed = 0.04f;
|
||||
app.model.transform.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f));
|
||||
app.model.transform.rotation = glm::mat4(1.0f);
|
||||
app.model.transform.scale = glm::mat4(1.0f);
|
||||
app.camera.rotation = glm::vec2(0.0f, -90.0f);
|
||||
app.camera.position = glm::vec3(0.0f, 0.0f, 3.0f);
|
||||
app.camera.view_direction = rotation_to_view_direction(app.camera);
|
||||
app.camera.up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
app.model.model_mat = app.model.transform.translation *
|
||||
app.model.transform.rotation * app.model.transform.scale;
|
||||
app.camera.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
||||
app.camera.projection_mat = glm::perspective(glm::radians(60.0f),
|
||||
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
||||
0.1f,
|
||||
20.0f);
|
||||
app.prev_mouse = glm::vec2(WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
|
||||
|
||||
return EXIT_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void create_vertex_spec(App &app) {
|
||||
void create_vertex_spec(Model &model) {
|
||||
const std::vector<GLfloat> vertices = {
|
||||
// vert0
|
||||
-0.5f, -0.5f, 0.0f, // position
|
||||
@ -219,12 +226,12 @@ void create_vertex_spec(App &app) {
|
||||
};
|
||||
|
||||
// Create and activate the VAO
|
||||
glGenVertexArrays(1, &app.vao);
|
||||
glBindVertexArray(app.vao);
|
||||
glGenVertexArrays(1, &model.mesh.vao);
|
||||
glBindVertexArray(model.mesh.vao);
|
||||
|
||||
// Create and set up the VBO
|
||||
glGenBuffers(1, &app.vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, app.vbo);
|
||||
glGenBuffers(1, &model.mesh.vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
vertices.size() * sizeof(GLfloat),
|
||||
(void *)vertices.data(),
|
||||
@ -232,8 +239,8 @@ void create_vertex_spec(App &app) {
|
||||
);
|
||||
|
||||
// Create and set up the EBO
|
||||
glGenBuffers(1, &app.ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, app.ebo);
|
||||
glGenBuffers(1, &model.mesh.ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.mesh.ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
indices.size() * sizeof(GLuint),
|
||||
(void *)indices.data(),
|
||||
@ -265,27 +272,28 @@ void create_vertex_spec(App &app) {
|
||||
glDisableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
void create_graphics_pipeline(App &app) {
|
||||
void create_graphics_pipeline(Model &model, Camera &camera) {
|
||||
const std::string vs_source = load_shader("shaders/vert.glsl");
|
||||
const std::string fs_source = load_shader("shaders/frag.glsl");
|
||||
|
||||
app.shader_program = create_shader_program(vs_source, fs_source);
|
||||
model.mesh.shader_program = create_shader_program(vs_source, fs_source);
|
||||
|
||||
const char *u_model = "u_model";
|
||||
app.u_model_idx = glGetUniformLocation(app.shader_program, u_model);
|
||||
if (app.u_model_idx < 0) {
|
||||
model.u_model_idx = glGetUniformLocation(model.mesh.shader_program, u_model);
|
||||
if (model.u_model_idx < 0) {
|
||||
printf("Failed to find uniform %s\n", u_model);
|
||||
}
|
||||
|
||||
// TODO (Abdelrahman): Finding the camera matrices uniforms shouldn't be handled here
|
||||
const char *u_view = "u_view";
|
||||
app.u_view_idx = glGetUniformLocation(app.shader_program, u_view);
|
||||
if (app.u_view_idx < 0) {
|
||||
camera.u_view_idx = glGetUniformLocation(model.mesh.shader_program, u_view);
|
||||
if (camera.u_view_idx < 0) {
|
||||
printf("Failed to find uniform %s\n", u_view);
|
||||
}
|
||||
|
||||
const char *u_projection = "u_projection";
|
||||
app.u_projection_idx = glGetUniformLocation(app.shader_program, u_projection);
|
||||
if (app.u_projection_idx < 0) {
|
||||
camera.u_projection_idx = glGetUniformLocation(model.mesh.shader_program, u_projection);
|
||||
if (camera.u_projection_idx < 0) {
|
||||
printf("Failed to find uniform %s\n", u_projection);
|
||||
}
|
||||
}
|
||||
@ -321,20 +329,20 @@ void run_main_loop(App &app) {
|
||||
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
||||
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(app.shader_program);
|
||||
if (app.u_model_idx >= 0) {
|
||||
glUniformMatrix4fv(app.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model_mat));
|
||||
glUseProgram(app.model.mesh.shader_program);
|
||||
if (app.model.u_model_idx >= 0) {
|
||||
glUniformMatrix4fv(app.model.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model.model_mat));
|
||||
}
|
||||
if (app.u_view_idx >= 0) {
|
||||
glUniformMatrix4fv(app.u_view_idx, 1, GL_FALSE, glm::value_ptr(app.view_mat));
|
||||
if (app.camera.u_view_idx >= 0) {
|
||||
glUniformMatrix4fv(app.camera.u_view_idx, 1, GL_FALSE, glm::value_ptr(app.camera.view_mat));
|
||||
}
|
||||
if (app.u_projection_idx >= 0) {
|
||||
glUniformMatrix4fv(app.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.projection_mat));
|
||||
if (app.camera.u_projection_idx >= 0) {
|
||||
glUniformMatrix4fv(app.camera.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.camera.projection_mat));
|
||||
}
|
||||
// End pre draw setup
|
||||
|
||||
// Draw call
|
||||
glBindVertexArray(app.vao);
|
||||
glBindVertexArray(app.model.mesh.vao);
|
||||
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)0);
|
||||
// End draw call
|
||||
|
||||
@ -418,37 +426,44 @@ std::string load_shader(const std::string &filepath) {
|
||||
return output;
|
||||
}
|
||||
|
||||
// Example of moving an object
|
||||
void handle_object_movement(App &app) {
|
||||
switch (app.event.key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, app.speed));
|
||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
||||
glm::vec3(0.0f, 0.0f, app.speed));
|
||||
break;
|
||||
case SDLK_s:
|
||||
app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, -app.speed));
|
||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
||||
glm::vec3(0.0f, 0.0f, -app.speed));
|
||||
break;
|
||||
case SDLK_d:
|
||||
app.translation = glm::translate(app.translation, glm::vec3(app.speed, 0.0f, 0.0f));
|
||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
||||
glm::vec3(app.speed, 0.0f, 0.0f));
|
||||
break;
|
||||
case SDLK_a:
|
||||
app.translation = glm::translate(app.translation, glm::vec3(-app.speed, 0.0f, 0.0f));
|
||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
||||
glm::vec3(-app.speed, 0.0f, 0.0f));
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
app.rotation = glm::rotate(app.rotation, glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
app.model.transform.rotation = glm::rotate(app.model.transform.rotation,
|
||||
glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
app.rotation = glm::rotate(app.rotation, glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
app.model.transform.rotation = glm::rotate(app.model.transform.rotation,
|
||||
glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
break;
|
||||
case SDLK_r:
|
||||
app.scale = glm::scale(app.scale, glm::vec3(1.2f));
|
||||
app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(1.2f));
|
||||
break;
|
||||
case SDLK_e:
|
||||
app.scale = glm::scale(app.scale, glm::vec3(0.8f));
|
||||
app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(0.8f));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
app.model_mat = app.translation * app.rotation * app.scale;
|
||||
app.model.model_mat = app.model.transform.translation * app.model.transform.rotation * app.model.transform.scale;
|
||||
}
|
||||
|
||||
void handle_camera_movement(App &app) {
|
||||
@ -477,7 +492,7 @@ void handle_camera_movement(App &app) {
|
||||
}
|
||||
}
|
||||
|
||||
app.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
||||
app.camera.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
||||
}
|
||||
|
||||
glm::vec3 rotation_to_view_direction(const Camera &camera) {
|
||||
|
Loading…
Reference in New Issue
Block a user