diff options
author | talha <talha@talhaamir.xyz> | 2024-03-31 18:22:14 +0500 |
---|---|---|
committer | talha <talha@talhaamir.xyz> | 2024-03-31 18:22:14 +0500 |
commit | 02077305a5b63fcf7242ac909d8caed5cc3cf18f (patch) | |
tree | 9940db9786f9496e3a3a872955591c21b433632f /source/main.cpp | |
parent | 82de1ef9f3d7fd9268af7de92bfc929f48f5b3bb (diff) |
Completed lighting, Model loading
Diffstat (limited to 'source/main.cpp')
-rw-r--r-- | source/main.cpp | 1134 |
1 files changed, 353 insertions, 781 deletions
diff --git a/source/main.cpp b/source/main.cpp index 1562ed1..18a816b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,6 +1,10 @@ #include <stdio.h> #include <SDL2/SDL.h> #include <glad/glad.h> +#include <assimp/Importer.hpp> +#include <assimp/scene.h> +#include <assimp/postprocess.h> +#include <vector> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" @@ -17,10 +21,6 @@ * that ofcourse everything is actually happening from the cameras' perspective. I would still love to figure this out. */ -/* @todo: - * - Switch to using clang on windows (for simplicity) -*/ - typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; @@ -36,6 +36,9 @@ typedef double r64; typedef u8 b8; + +#include "math.h" + // =========== Shader Loading ============= unsigned int gl_create_vertex_shader(char* vertex_shader_source) @@ -43,7 +46,7 @@ unsigned int gl_create_vertex_shader(char* vertex_shader_source) unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL); glCompileShader(vertex_shader); - + int success; char info_log[512]; glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success); @@ -53,7 +56,7 @@ unsigned int gl_create_vertex_shader(char* vertex_shader_source) printf("================================\n"); printf("vertex shader compilation failed:\n%s\n", info_log); } - + return vertex_shader; } @@ -62,7 +65,7 @@ unsigned int gl_create_fragment_shader(char* fragment_shader_source) unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL); glCompileShader(fragment_shader); - + int success; char info_log[512]; glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success); @@ -72,18 +75,18 @@ unsigned int gl_create_fragment_shader(char* fragment_shader_source) printf("================================\n"); printf("fragment shader compilation failed:\n%s\n", info_log); } - + return fragment_shader; } unsigned int gl_create_shader_program(unsigned int vertex_shader, unsigned int fragment_shader) { unsigned int shader_program = glCreateProgram(); - + glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); - + int success; char info_log[512]; glGetProgramiv(shader_program, GL_LINK_STATUS, &success); @@ -93,459 +96,350 @@ unsigned int gl_create_shader_program(unsigned int vertex_shader, unsigned int f printf("================================\n"); printf("shader program linking failed:\n%s\n", info_log); } - + glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); - + return shader_program; } -int platform_read_file() +Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) { - return 0; + // @note: We do this because this allows the camera to have the axis it looks at + // inwards be the +z axis. + // If we did not do this, then the inward axis the camera looks at would be negative. + // I am still learning from learnopengl.com but I imagine that this was done for conveniences' sake. + Vec3 camera_forward_dir = normalize3v(subtract3v(camera_pos, camera_look)); + Vec3 camera_right_dir = normalize3v(cross_multiply3v(camera_up, camera_forward_dir)); + Vec3 camera_up_dir = normalize3v(cross_multiply3v(camera_forward_dir, camera_right_dir)); + + Mat4 res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos); + + return res; } -int platform_write_file() +Vec3 camera_look_around(r32 angle_pitch, r32 angle_yaw) { - return 0; + Vec3 camera_look = {0.0}; + camera_look.x = cosf(angle_yaw) * cosf(angle_pitch); + camera_look.y = sinf(angle_pitch); + camera_look.z = sinf(angle_yaw) * cosf(angle_pitch); + camera_look = normalize3v(camera_look); + + return camera_look; } -// =========================================================== MATH ================================================== -#define PI 3.14159265358979323846264338327950288f -#define Square(x) ((x)*(x)) -#define To_Radian(x) ((x) * PI / 180.0f) -#define To_Degree(x) ((x) * 180.0f / PI) +// =================== Model Loading ======================== +// This section contains a whole host of things: +// 1. classes +// 2. std::vectors +// 3. std::strings +// that I have only used as a glue for I did not know if I had the model loading setup properly. +// @todo: replace these things eventually. For now the goal is to complete learnopengl -r32 clampf(r32 x, r32 bottom, r32 top) +s32 TextureFromFile(const char* filepath, std::string directory) { - if (x < bottom) + std::string filename = std::string(filepath); + filename = directory + '/' + filename; + + u32 texid; + glGenTextures(1, &texid); + + s32 width, height, nrChannels; + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0); + if (data) { - x = bottom; - } - else if (x > top) + GLenum format; + if (nrChannels == 1) + format = GL_RED; + else if (nrChannels == 3) + format = GL_RGB; + else if (nrChannels == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, texid); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else { - x = top; + printf("failed to load image texture at path: %s", filepath); + stbi_image_free(data); } - return x; + return texid; } -// ==== Vector Math ==== +enum TextureType { TextureDiffuse=0, TextureSpecular }; -union Vec3 { - struct { - r32 x; - r32 y; - r32 z; - }; - r32 data[3]; +struct Vertex { + Vec3 position; + Vec3 normal; + Vec2 texture; }; -union Vec4 { - struct { - r32 x; - r32 y; - r32 z; - r32 w; - }; - r32 data[4]; +struct Texture { + u32 id; + enum TextureType type; + std::string fname; }; -union Mat4 { - Vec4 xyzw[4]; - r32 data[4][4]; - r32 buffer[16]; -}; - -// ========================================================== Vec3 ========================================================== - -Vec3 init3v(r32 x, r32 y, r32 z) -{ - Vec3 res; - res.x = x; - res.y = y; - res.z = z; - - return res; -} - -Vec3 scaler_add3v(Vec3 vec, r32 scaler) -{ - Vec3 res; - res.x = vec.x + scaler; - res.y = vec.y + scaler; - res.z = vec.z + scaler; - - return res; -} - -Vec3 scaler_multiply3v(Vec3 vec, r32 scaler) -{ - Vec3 res; - res.x = vec.x * scaler; - res.y = vec.y * scaler; - res.z = vec.z * scaler; - - return res; -} - -Vec3 scaler_divide3v(Vec3 vec, r32 scaler) -{ - Vec3 res; - res.x = vec.x / scaler; - res.y = vec.y / scaler; - res.z = vec.z / scaler; - - return res; -} - - -Vec3 add3v(Vec3 a, Vec3 b) -{ - Vec3 res; - res.x = a.x + b.x; - res.y = a.y + b.y; - res.z = a.z + b.z; - - return res; -} - -Vec3 subtract3v(Vec3 a, Vec3 b) -{ - Vec3 res; - res.x = a.x - b.x; - res.y = a.y - b.y; - res.z = a.z - b.z; - - return res; -} - -r32 dot_multiply3v(Vec3 a, Vec3 b) -{ - r32 x = a.x * b.x; - r32 y = a.y * b.y; - r32 z = a.z * b.z; - - r32 res = x + y + z; - - return res; -} - -r32 magnitude3v(Vec3 vec) -{ - r32 res = sqrtf(Square(vec.x) + Square(vec.y) + Square(vec.z)); - return res; -} - -Vec3 normalize3v(Vec3 vec) -{ - r32 magnitude = magnitude3v(vec); - Vec3 res = scaler_divide3v(vec, magnitude); - return res; -} - -#ifndef FUN_CALCS -r32 angle3v(Vec3 a, Vec3 b) -{ - Vec3 a_norm = normalize3v(a); - Vec3 b_norm = normalize3v(b); - - r32 dot_product = dot_multiply3v(a_norm, b_norm); - r32 res = acosf(dot_product); - - return res; -} -#endif - -Vec3 cross_multiply3v(Vec3 a, Vec3 b) -{ - Vec3 res; - res.x = (a.y * b.z) - (a.z * b.y); - res.y = (a.z * b.x) - (a.x * b.z); - res.z = (a.x * b.y) - (a.y * b.x); - - return res; -} - -// ============================================== Vec4, Mat4 ============================================== +class Mesh { + public: + std::vector<Vertex> vertices; + std::vector<u32> indices; + std::vector<Texture> textures; -Vec4 init4v(r32 x, r32 y, r32 z, r32 w) -{ - Vec4 res; - res.x = x; - res.y = y; - res.z = z; - res.w = w; - - return res; -} - -Mat4 init_value4m(r32 value) -{ - Mat4 res = {0}; - res.data[0][0] = value; - res.data[1][1] = value; - res.data[2][2] = value; - res.data[3][3] = value; - - return res; -} + u32 vao; + u32 vbo; + u32 ebo; -// @note: These operations are just defined and not expressed. They are kept here for completeness sake BUT -// since I have not had to do anything related to these, I have not created them. -Vec4 scaler_add4v(Vec4 vec, r32 scaler); -Vec4 scaler_subtract4v(Vec4 vec, r32 scaler); -Vec4 scaler_multiply4v(Vec4 vec, r32 scaler); -Vec4 scaler_divide4v(Vec4 vec, r32 scaler); -Vec4 add4v(Vec4 a, Vec4 b); -Vec4 subtract4v(Vec4 a, Vec4 b); -Vec4 dot_multiply4v(Vec4 a, Vec4 b); - -Mat4 add4m(Mat4 a, Mat4 b) -{ - Mat4 res; - // row 0 - res.data[0][0] = a.data[0][0] + b.data[0][0]; - res.data[0][1] = a.data[0][1] + b.data[0][1]; - res.data[0][2] = a.data[0][2] + b.data[0][2]; - res.data[0][3] = a.data[0][3] + b.data[0][3]; - // row 1 - res.data[1][0] = a.data[1][0] + b.data[1][0]; - res.data[1][1] = a.data[1][1] + b.data[1][1]; - res.data[1][2] = a.data[1][2] + b.data[1][2]; - res.data[1][3] = a.data[1][3] + b.data[1][3]; - // row 2 - res.data[2][0] = a.data[2][0] + b.data[2][0]; - res.data[2][1] = a.data[2][1] + b.data[2][1]; - res.data[2][2] = a.data[2][2] + b.data[2][2]; - res.data[2][3] = a.data[2][3] + b.data[2][3]; - // row 3 - res.data[3][0] = a.data[3][0] + b.data[3][0]; - res.data[3][1] = a.data[3][1] + b.data[3][1]; - res.data[3][2] = a.data[3][2] + b.data[3][2]; - res.data[3][3] = a.data[3][3] + b.data[3][3]; - - return res; -} - -Mat4 subtract4m(Mat4 a, Mat4 b) -{ - Mat4 res; - // row 0 - res.data[0][0] = a.data[0][0] - b.data[0][0]; - res.data[0][1] = a.data[0][1] - b.data[0][1]; - res.data[0][2] = a.data[0][2] - b.data[0][2]; - res.data[0][3] = a.data[0][3] - b.data[0][3]; - // row 1 - res.data[1][0] = a.data[1][0] - b.data[1][0]; - res.data[1][1] = a.data[1][1] - b.data[1][1]; - res.data[1][2] = a.data[1][2] - b.data[1][2]; - res.data[1][3] = a.data[1][3] - b.data[1][3]; - // row 2 - res.data[2][0] = a.data[2][0] - b.data[2][0]; - res.data[2][1] = a.data[2][1] - b.data[2][1]; - res.data[2][2] = a.data[2][2] - b.data[2][2]; - res.data[2][3] = a.data[2][3] - b.data[2][3]; - // row 3 - res.data[3][0] = a.data[3][0] - b.data[3][0]; - res.data[3][1] = a.data[3][1] - b.data[3][1]; - res.data[3][2] = a.data[3][2] - b.data[3][2]; - res.data[3][3] = a.data[3][3] - b.data[3][3]; + Mesh(std::vector<Vertex> vertices, std::vector<u32> indices, std::vector<Texture> textures) + { + this->vertices = vertices; + this->indices = indices; + this->textures = textures; + + // setup mesh shader stuff + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + + glBindVertexArray(vao); + + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(struct Vertex), &(this->vertices[0]), GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(u32), &(this->indices[0]), GL_STATIC_DRAW); + + // position + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + // normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal)); + // texture + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texture)); - return res; -} + glBindVertexArray(0); + } -Vec4 multiply4vm(Vec4 vec, Mat4 mat) -{ - /* - * @note: Incase I get confused about this in the future. - * - * Everything is row-order, which means that things in memory are laid out row first. So with a sample matrix - * we have this order in memory: r1c1 r1c2 r1c3 r1c4 r2c1 ... (r = row, c = column). The same holds true for - * vectors. (maybe move this explanation to the top) - * - * Now, multiply4vm will multiply a vector with a matrix. Conventionally that does not make any sense as - * a vector is usually 4x1 and a matrix ix 4x4. - * What this function considers a vector, while it is a vector, it is infact a row from a matrix, which - * means that the vector is 1x4 and the matrix is 4x4. - * - * The function is meant to supplement the matrix multiplication process to alleviate the multiple lines of code - * we have to write when multiplying the row of a left matrix to each column of the right matrix - */ - Vec4 res = { 0 }; - res.x = (mat.data[0][0] * vec.x) + (mat.data[0][1] * vec.y) + (mat.data[0][2] * vec.z) + (mat.data[0][3] * vec.w); - res.y = (mat.data[1][0] * vec.x) + (mat.data[1][1] * vec.y) + (mat.data[1][2] * vec.z) + (mat.data[1][3] * vec.w); - res.z = (mat.data[2][0] * vec.x) + (mat.data[2][1] * vec.y) + (mat.data[2][2] * vec.z) + (mat.data[2][3] * vec.w); - res.w = (mat.data[3][0] * vec.x) + (mat.data[3][1] * vec.y) + (mat.data[3][2] * vec.z) + (mat.data[3][3] * vec.w); - - return res; -} + void draw(u32 shader_program) + { + glUseProgram(shader_program); -Mat4 multiply4m(Mat4 a, Mat4 b) -{ - Mat4 res = { 0 }; - - res.xyzw[0] = multiply4vm(a.xyzw[0], b); - res.xyzw[1] = multiply4vm(a.xyzw[1], b); - res.xyzw[2] = multiply4vm(a.xyzw[2], b); - res.xyzw[3] = multiply4vm(a.xyzw[3], b); + u32 diffuse_num = 1; + u32 specular_num = 1; + char tex_unit_name[64]; + // set shininess + s32 mat_shine_loc = glGetUniformLocation(shader_program, "material.shininess"); + glUniform1f(mat_shine_loc, 32.0f); - return res; -} + for (u32 i=0; i<textures.size(); i++) + { + struct Texture curr_tex = textures[i]; + if (curr_tex.type == TextureDiffuse) + { + sprintf(tex_unit_name, "material.diffuse[%i]", diffuse_num); + } + else if (curr_tex.type == TextureSpecular) + { + sprintf(tex_unit_name, "material.diffuse[%i]", specular_num); + } + + glActiveTexture(GL_TEXTURE0 + i); + s32 tex_unit_loc = glGetUniformLocation(shader_program, tex_unit_name); + glUniform1i(tex_unit_loc, i); + glBindTexture(GL_TEXTURE_2D, curr_tex.id); + } + glActiveTexture(GL_TEXTURE0); -// ==== Matrix Transformation ==== + glBindVertexArray(vao); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); + glBindVertexArray(0); + } +}; -Mat4 scaling_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 scaling matrix for scaling each of the x,y,z axis +class Model { - Mat4 res = init_value4m(1.0f); - res.data[0][0] = x; - res.data[1][1] = y; - res.data[2][2] = z; - - return res; -} + public: + Model(std::string path) + { + load_model(path); + } + void draw(u32 shader_program); + private: + std::vector<Texture> loaded_textures; + std::vector<Mesh> meshes; + std::string directory; + + void load_model(std::string path); + void process_node(aiNode *node, const aiScene *scene); + Mesh process_mesh(aiMesh *mesh, const aiScene *scene); + std::vector<Texture> load_material_textures(aiMaterial *mat, aiTextureType type, TextureType type_name); +}; -Mat4 translation_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 translation matrix for translation along each of the x,y,z axis +void Model::draw(u32 shader_program) { - Mat4 res = init_value4m(1.0f); - res.data[0][3] = x; - res.data[1][3] = y; - res.data[2][3] = z; - - return res; + for (int i=0; i < meshes.size(); i++) + { + meshes[i].draw(shader_program); + } } -Mat4 rotation_matrix4m(r32 angle_radians, Vec3 axis) // generates a 4x4 rotation matrix for rotation along each of the x,y,z axis +void Model::load_model(std::string path) { - Mat4 res = init_value4m(1.0f); - axis = normalize3v(axis); - - r32 cos_theta = cosf(angle_radians); - r32 sin_theta = sinf(angle_radians); - r32 cos_value = 1.0f - cos_theta; - - res.data[0][0] = (axis.x * axis.x * cos_value) + cos_theta; - res.data[0][1] = (axis.x * axis.y * cos_value) + (axis.z * sin_theta); - res.data[0][2] = (axis.x * axis.z * cos_value) - (axis.y * sin_theta); - - res.data[1][0] = (axis.x * axis.y * cos_value) - (axis.z * sin_theta); - res.data[1][1] = (axis.y * axis.y * cos_value) + cos_theta; - res.data[1][2] = (axis.y * axis.z * cos_value) + (axis.x * sin_theta); + Assimp::Importer import; + const aiScene *scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); - res.data[2][0] = (axis.x * axis.z * cos_value) + (axis.y * sin_theta); - res.data[2][1] = (axis.z * axis.y * cos_value) - (axis.x * sin_theta); - res.data[2][2] = (axis.z * axis.z * cos_value) + cos_theta; + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + printf("error loading model :%s\n", import.GetErrorString()); + return; + } - return res; + directory = path.substr(0, path.find_last_of('/')); + process_node(scene->mRootNode, scene); } -Mat4 perspective_projection_matrix4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) +void Model::process_node(aiNode *node, const aiScene *scene) { - Mat4 res = { 0 }; - - res.data[0][0] = (2.0 * near)/(right - left); - res.data[0][2] = (right + left)/(right - left); - - res.data[1][1] = (2.0 * near)/(top - bottom); - res.data[1][2] = (top + bottom)/(top - bottom); - - res.data[2][2] = -(far + near)/(far - near); - res.data[2][3] = -2.0*far*near/(far - near); - - res.data[3][2] = -1.0; + for (int i=0; i < node->mNumMeshes; i++) + { + aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(process_mesh(mesh, scene)); + } - return res; + for (int i=0; i<node->mNumChildren; i++) + { + process_node(node->mChildren[i], scene); + } } -Mat4 perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far) +Mesh Model::process_mesh(aiMesh *mesh, const aiScene *scene) { - r32 cotangent = 1.0f / tanf(fov / 2.0f); - - Mat4 res = { 0 }; + std::vector<Vertex> vertices; + std::vector<u32> indices; + std::vector<Texture> textures; - res.data[0][0] = cotangent / aspect_ratio; - - res.data[1][1] = cotangent; - - res.data[2][2] = -(far + near) / (far - near); - res.data[2][3] = -2.0f * far * near / (far - near); - - res.data[3][2] = -1.0f; + for (u32 i=0; i < mesh->mNumVertices; i++) + { + Vec3 position; + position.x = mesh->mVertices[i].x; + position.y = mesh->mVertices[i].y; + position.z = mesh->mVertices[i].z; + + Vec3 normal; + normal.x = mesh->mNormals[i].x; + normal.y = mesh->mNormals[i].y; + normal.z = mesh->mNormals[i].z; + + Vec2 texture = {0, 0}; + if (mesh->mTextureCoords[0]) + { + texture.x = mesh->mTextureCoords[0][i].x; + texture.y = mesh->mTextureCoords[0][i].y; + } - return res; -} + struct Vertex vertex; + vertex.position = position; + vertex.normal = normal; + vertex.texture = texture; -Mat4 lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position) -{ - /* - * @note: The construction of the lookat matrix is not obvious. For that reason here is the supplemental matrial I have used to understand - * things while I maintain my elementary understanding of linear algebra. - * 1. This youtube video (https://www.youtube.com/watch?v=3ZmqJb7J5wE) helped me understand why we invert matrices. - * It is because, we are moving from the position matrix which is a global to the view matrix which - * is a local. It won't be very clear from this illustration alone, so you would be best served watching the video and recollecting and understanding from there. - * 2. This article (https://twodee.org/blog/17560) derives (or rather shows), in a very shallow way how we get to the look at matrix. - */ - Mat4 res = init_value4m(1.0); - res.xyzw[0] = Vec4{ right.x, right.y, right.z, -dot_multiply3v(right, position) }; - res.xyzw[1] = Vec4{ up.x, up.y, up.z, -dot_multiply3v(up, position) }; - res.xyzw[2] = Vec4{ forward.x, forward.y, forward.z, -dot_multiply3v(forward, position) }; - res.xyzw[3] = Vec4{ 0.0f, 0.0f, 0.0f, 1.0f }; + vertices.push_back(vertex); + } + // process indices + for (u32 i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + for(u32 j = 0; j < face.mNumIndices; j++) + { + indices.push_back(face.mIndices[j]); + } + } + // process material + if (mesh->mMaterialIndex >= 0) + { + aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; + std::vector<Texture> diffuse_maps = load_material_textures(material, aiTextureType_DIFFUSE, TextureDiffuse); + textures.insert(textures.end(), diffuse_maps.begin(), diffuse_maps.end()); + std::vector<Texture> specular_maps = load_material_textures(material, aiTextureType_SPECULAR, TextureSpecular); + textures.insert(textures.end(), specular_maps.begin(), specular_maps.end()); + } - return res; + return Mesh(vertices, indices, textures); } -Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) +std::vector<Texture> Model::load_material_textures(aiMaterial *mat, aiTextureType type, TextureType tex_type) { - // @note: We do this because this allows the camera to have the axis it looks at - // inwards be the +z axis. - // If we did not do this, then the inward axis the camera looks at would be negative. - // I am still learning from learnopengl.com but I imagine that this was done for conveniences' sake. - Vec3 camera_forward_dir = normalize3v(subtract3v(camera_pos, camera_look)); - Vec3 camera_right_dir = normalize3v(cross_multiply3v(camera_up, camera_forward_dir)); - Vec3 camera_up_dir = normalize3v(cross_multiply3v(camera_forward_dir, camera_right_dir)); - - Mat4 res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos); - - return res; -} + std::vector<Texture> textures; + for(u32 i=0; i<mat->GetTextureCount(type); i++) + { + bool load_texture = true; + aiString str; + mat->GetTexture(type, i, &str); + const char* fname = str.C_Str(); -Vec3 camera_look_around(r32 angle_pitch, r32 angle_yaw) -{ - Vec3 camera_look = {0.0}; - camera_look.x = cosf(angle_yaw) * cosf(angle_pitch); - camera_look.y = sinf(angle_pitch); - camera_look.z = sinf(angle_yaw) * cosf(angle_pitch); - camera_look = normalize3v(camera_look); + for (s32 j=0; j<loaded_textures.size(); j++) + { + if (std::strcmp(loaded_textures[j].fname.data(), fname) == 0) + { + load_texture = false; + textures.push_back(loaded_textures[j]); + break; + } + } + if (load_texture) + { + Texture texture; + texture.id = TextureFromFile(fname, directory); + texture.type = tex_type; + texture.fname = std::string(fname); + textures.push_back(texture); + loaded_textures.push_back(texture); + } + } - return camera_look; + return textures; } int main(int argc, char* argv[]) { + + // ============ END ============ int width = 1024; int height = 768; - + if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("Error initialising SDL2: %s\n", SDL_GetError()); return 0; }; - + // set opengl version and profile SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - + // initialise window with opengl flag SDL_Window* window = SDL_CreateWindow("SDL Test", - 50, - 50, - width, - height, - SDL_WINDOW_OPENGL); - - SDL_SetRelativeMouseMode(SDL_TRUE); - + 50, + 50, + width, + height, + SDL_WINDOW_OPENGL); + + SDL_SetRelativeMouseMode(SDL_TRUE); + // create an opengl context SDL_GLContext context = SDL_GL_CreateContext(window); if (!context) @@ -553,236 +447,34 @@ int main(int argc, char* argv[]) printf("OpenGL context creation failed: %s\n", SDL_GetError()); return -1; } - - + + // load glad if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { printf("Failed to initialize Glad\n"); return 1; } - + // filesystem playground stuff size_t read_count; - char* vertex_source = (char*)SDL_LoadFile("./source/shaders/light_subject.vs.glsl", &read_count); - char* fragment_source = (char*)SDL_LoadFile("./source/shaders/light_subject.fs.glsl", &read_count); - char* light_vertex_source = (char*)SDL_LoadFile("./source/shaders/light_source.vs.glsl", &read_count); - char* light_fragment_source = (char*)SDL_LoadFile("./source/shaders/light_source.fs.glsl", &read_count); - + char* vertex_source = (char*)SDL_LoadFile("./source/shaders/model/model.vs.glsl", &read_count); + char* fragment_source = (char*)SDL_LoadFile("./source/shaders/model/model.fs.glsl", &read_count); + GLuint vertex_shader = gl_create_vertex_shader(vertex_source); GLuint fragment_shader = gl_create_fragment_shader(fragment_source); GLuint shader_program = gl_create_shader_program(vertex_shader, fragment_shader); - GLuint light_vs = gl_create_vertex_shader(light_vertex_source); - GLuint light_fs = gl_create_fragment_shader(light_fragment_source); - GLuint light_sp = gl_create_shader_program(light_vs, light_fs); printf("Successfully compiled shaders.\n"); - - r32 cube_normal_vertices[] = { - // positions // normals // texture coords - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f - }; - - r32 cube_vertices[] = { - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f - }; - - GLuint light_VBO, light_VAO; - { - glGenVertexArrays(1, &light_VAO); - glGenBuffers(1, &light_VBO); - - glBindVertexArray(light_VAO); - - glBindBuffer(GL_ARRAY_BUFFER, light_VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - - GLuint VBO, VAO, EBO, steel_wood_container, steel_wood_specular; - { - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - - glBindVertexArray(VAO); - - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normal_vertices), cube_normal_vertices, GL_STATIC_DRAW); - - // Position Attribute - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - - // normal attribute - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); - glEnableVertexAttribArray(1); - - // Texture Attributes - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); - glEnableVertexAttribArray(2); - - int img_width, img_height, img_nrChannels; - - // ==== Texture 1 ==== - glGenTextures(1, &steel_wood_container); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, steel_wood_container); - - const char* steel_wood_path = "assets/steel_wood_container.png"; - stbi_set_flip_vertically_on_load(1); - unsigned char* steel_wood_data = stbi_load(steel_wood_path, &img_width, &img_height, &img_nrChannels, 0); - - // Texture Properties - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - - // Texture Data - if (steel_wood_data) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, steel_wood_data); - glGenerateMipmap(GL_TEXTURE_2D); - } - else - { - printf("Error! Failed to load image from `%s`\n", steel_wood_path); - } - stbi_image_free(steel_wood_data); - - // ==== Texture 2 ==== - glGenTextures(1, &steel_wood_specular); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, steel_wood_specular); - const char* steel_wood_specular_path = "assets/steel_wood_specular.png"; - unsigned char* steel_wood_specular_data = stbi_load(steel_wood_specular_path, &img_width, &img_height, &img_nrChannels, 0); - - // Texture Properties - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - - // Texture Data - if (steel_wood_specular_data) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, steel_wood_specular_data); - glGenerateMipmap(GL_TEXTURE_2D); - } - else - { - printf("Error! Failed to load image from `%s`\n", steel_wood_specular_path); - } - stbi_image_free(steel_wood_specular_data); - - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - //glBindTexture(GL_TEXTURE_2D, 0); - } - + glUseProgram(shader_program); - Vec3 ambient_color = Vec3{ 0.0f, 0.1f, 0.6f }; - Vec3 diffuse_color = Vec3{ 0.0f, 0.50980392f, 0.50980392f}; - Vec3 specular_color = Vec3{ 0.50196078f, 0.50196078f, 0.50196078f}; - Vec3 light_color = Vec3{ 1.0f, 1.0f, 1.0f}; - r32 specular_shine_factor = 128.0f * 0.25f; - - // material uniforms - int mat_diffuse_loc = glGetUniformLocation(shader_program, "material.diffuse"); - glUniform1i(mat_diffuse_loc, 0); - int mat_specular_loc = glGetUniformLocation(shader_program, "material.specular"); - glUniform1i(mat_specular_loc, 1); - - int shine_factor_loc = glGetUniformLocation(shader_program, "material.shininess"); - glUniform1f(shine_factor_loc, specular_shine_factor); + stbi_set_flip_vertically_on_load(1); + // ============ Start Model handling using Assimp ============ + // loading a 3d model using assimp + Model test_model = Model(std::string("assets/Survival_Backpack/backpack.obj")); // directional light things // - directional light params - Vec3 DL_direction = Vec3{ 0.0f, -1.0f, 0.0f }; + Vec3 DL_direction = Vec3{ 0.0f, -0.5f, -1.0f }; Vec3 DL_ambient = Vec3{ 0.2f, 0.2f, 0.2f }; Vec3 DL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f }; Vec3 DL_specular = Vec3{ 1.0f, 1.0f, 1.0f }; @@ -796,96 +488,29 @@ int main(int argc, char* argv[]) glUniform3fv(DL_ambient_loc, 1, DL_ambient.data); glUniform3fv(DL_diffuse_loc, 1, DL_diffuse.data); glUniform3fv(DL_specular_loc, 1, DL_specular.data); - - // pointlight things - // - point light params - Vec3 MPL_position[4] = { - Vec3{ 0.0f, 0.0f, 5.0f }, - Vec3{ 0.0f, 0.0f, -8.0f }, - Vec3{ -5.0f, 0.0f, -5.0f }, - Vec3{ 5.0f, 0.0f, -5.0f }, - }; - Vec3 MPL_ambient[4] = { - Vec3{ 0.2f, 0.2f, 0.2f }, - Vec3{ 0.2f, 0.2f, 0.2f }, - Vec3{ 0.2f, 0.2f, 0.2f }, - Vec3{ 0.2f, 0.2f, 0.2f } - }; - Vec3 MPL_diffuse[4] = { - Vec3{ 0.5f, 0.5f, 0.5f }, - Vec3{ 0.5f, 0.5f, 0.5f }, - Vec3{ 0.5f, 0.5f, 0.5f }, - Vec3{ 0.5f, 0.5f, 0.5f } - }; - Vec3 MPL_specular[4] = { - Vec3{ 1.0f, 1.0f, 1.0f }, - Vec3{ 1.0f, 1.0f, 1.0f }, - Vec3{ 1.0f, 1.0f, 1.0f }, - Vec3{ 1.0f, 1.0f, 1.0f } - }; - - for (int i=0; i < 4; i++) - { - char buffer[64]; - sprintf(buffer, "multiPointLight[%i].ambient", i); - int MPL_ambient_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].diffuse", i); - int MPL_diffuse_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].specular", i); - int MPL_specular_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].position", i); - int MPL_pos_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].kC", i); - int MPL_kc_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].kL", i); - int MPL_kl_loc = glGetUniformLocation(shader_program, buffer); - sprintf(buffer, "multiPointLight[%i].kQ", i); - int MPL_kq_loc = glGetUniformLocation(shader_program, buffer); - - glUniform3fv(MPL_pos_loc, 1, MPL_position[i].data); - glUniform3fv(MPL_ambient_loc, 1, MPL_ambient[i].data); - glUniform3fv(MPL_diffuse_loc, 1, MPL_diffuse[i].data); - glUniform3fv(MPL_specular_loc, 1, MPL_specular[i].data); - // attenuation factors - glUniform1f(MPL_kc_loc, 1.0f); - glUniform1f(MPL_kl_loc, 0.09f); - glUniform1f(MPL_kq_loc, 0.032f); - } - - - - // spotlight things - // - spot light params - Vec3 SL_ambient = Vec3{ 0.2f, 0.2f, 0.2f }; - Vec3 SL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f }; - Vec3 SL_specular = Vec3{ 1.0f, 1.0f, 1.0f }; - - int SL_ambient_loc = glGetUniformLocation(shader_program, "spotLight.ambient"); - int SL_diffuse_loc = glGetUniformLocation(shader_program, "spotLight.diffuse"); - int SL_specular_loc = glGetUniformLocation(shader_program, "spotLight.specular"); - int SL_pos_loc = glGetUniformLocation(shader_program, "spotLight.position"); - int SL_kc_loc = glGetUniformLocation(shader_program, "spotLight.kC"); - int SL_kl_loc = glGetUniformLocation(shader_program, "spotLight.kL"); - int SL_kq_loc = glGetUniformLocation(shader_program, "spotLight.kQ"); - int SL_radius_inner = glGetUniformLocation(shader_program, "spotLight.radius_inner"); - int SL_radius_outer = glGetUniformLocation(shader_program, "spotLight.radius_outer"); - int SL_front_loc = glGetUniformLocation(shader_program, "spotLight.front"); - - glUniform3fv(SL_ambient_loc, 1, SL_ambient.data); - glUniform3fv(SL_diffuse_loc, 1, SL_diffuse.data); - glUniform3fv(SL_specular_loc, 1, SL_specular.data); + + // load point light + Vec3 PL_position = Vec3{ 0.0f, 0.0f, 3.0f }; + Vec3 PL_ambient = Vec3{ 0.2f, 0.2f, 0.2f }; + Vec3 PL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f }; + Vec3 PL_specular = Vec3{ 1.0f, 1.0f, 1.0f }; + + s32 PL_pos_loc = glGetUniformLocation(shader_program, "pointLight.position"); + s32 PL_ambient_loc = glGetUniformLocation(shader_program, "pointLight.ambient"); + s32 PL_diffuse_loc = glGetUniformLocation(shader_program, "pointLight.diffuse"); + s32 PL_specular_loc = glGetUniformLocation(shader_program, "pointLight.specular"); + s32 PL_kc_loc = glGetUniformLocation(shader_program, "pointLight.kC"); + s32 PL_kl_loc = glGetUniformLocation(shader_program, "pointLight.kL"); + s32 PL_kq_loc = glGetUniformLocation(shader_program, "pointLight.kQ"); + + glUniform3fv(PL_pos_loc, 1, PL_position.data); + glUniform3fv(PL_ambient_loc, 1, PL_ambient.data); + glUniform3fv(PL_diffuse_loc, 1, PL_diffuse.data); + glUniform3fv(PL_specular_loc, 1, PL_specular.data); // attenuation factors - glUniform1f(SL_kc_loc, 1.0f); - glUniform1f(SL_kl_loc, 0.09f); - glUniform1f(SL_kq_loc, 0.032f); - // radius - glUniform1f(SL_radius_inner, cosf(To_Radian(10.0f))); - glUniform1f(SL_radius_outer, cosf(To_Radian(15.00f))); - // end spotlight things - - int light_uniform_loc = glGetUniformLocation(shader_program, "lightColor"); - glUniform3fv(light_uniform_loc, 1, light_color.data); - + glUniform1f(PL_kc_loc, 1.0f); + glUniform1f(PL_kl_loc, 0.09f); + glUniform1f(PL_kq_loc, 0.032f); int camera_pos_loc = glGetUniformLocation(shader_program, "cameraPosition"); @@ -897,51 +522,45 @@ int main(int argc, char* argv[]) Vec3{ -3.0, 5.0, -6.0}, Vec3{ 3.0, -7.0, -6.0}, }; - + r32 FOV = 90.0; r32 time_curr; r32 time_prev = SDL_GetTicks64() / 100.0; uint32_t model_loc = glGetUniformLocation(shader_program, "Model"); - + // camera stuff Vec3 camera_pos = Vec3{ 0.0, 5.0, 10.0f}; Vec3 preset_up_dir = Vec3{ 0.0, 1.0, 0.0 }; - + r32 angle_yaw, angle_pitch, angle_roll; angle_pitch = (r32)To_Radian(0.0f); angle_yaw = (r32)-To_Radian(90.0f); - + Vec3 camera_look = camera_look_around(angle_pitch, angle_yaw); // @todo: remove this, I dont like this and think that this is unnecessary Vec3 camera_look_increment; r32 camera_speed = 0.5f; - + Mat4 view = camera_create4m(camera_pos, camera_look, preset_up_dir); uint32_t view_loc = glGetUniformLocation(shader_program, "View"); glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); - + Mat4 proj = perspective4m((r32)To_Radian(90.0), (r32)width / (r32)height, 0.1f, 100.0f); uint32_t proj_loc = glGetUniformLocation(shader_program, "Projection"); glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); - glUseProgram(light_sp); - uint32_t light_view_loc = glGetUniformLocation(light_sp, "View"); - glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer); - uint32_t light_proj_loc = glGetUniformLocation(light_sp, "Projection"); - glUniformMatrix4fv(light_proj_loc, 1, GL_TRUE, proj.buffer); - glEnable(GL_DEPTH_TEST); - + u8 game_running = true; - + u8 hold_lshift = false; u8 move_w = false; u8 move_a = false; u8 move_s = false; u8 move_d = false; - + while(game_running) { @@ -951,11 +570,11 @@ int main(int argc, char* argv[]) r32 camera_speed_adjusted = time_delta * camera_speed; camera_look_increment = scaler_multiply3v(camera_look, camera_speed_adjusted); - + SDL_Event ev; while(SDL_PollEvent(&ev)) { - + // INPUT switch (ev.type) { @@ -967,22 +586,8 @@ int main(int argc, char* argv[]) { if (ev.key.keysym.sym == SDLK_LSHIFT) { - hold_lshift = true; + hold_lshift = true; } - if (ev.key.keysym.sym == SDLK_SPACE) - {} - if (ev.key.keysym.sym == SDLK_UP) - { - { - specular_shine_factor = specular_shine_factor*2.0; - } - } - if (ev.key.keysym.sym == SDLK_DOWN) - { - { - specular_shine_factor = specular_shine_factor/2.0; - } - } if (ev.key.keysym.sym == SDLK_w) { move_w = true; @@ -1002,10 +607,10 @@ int main(int argc, char* argv[]) } break; case (SDL_KEYUP): { - if (ev.key.keysym.sym == SDLK_LSHIFT) - { - hold_lshift = false; - } + if (ev.key.keysym.sym == SDLK_LSHIFT) + { + hold_lshift = false; + } if (ev.key.keysym.sym == SDLK_w) { move_w = false; @@ -1023,11 +628,11 @@ int main(int argc, char* argv[]) move_d = false; } } break; - case (SDL_MOUSEMOTION): - { - SDL_MouseMotionEvent mouse_event = ev.motion; - r32 x_motion = (r32)mouse_event.xrel; - r32 y_motion = (r32)mouse_event.yrel; + case (SDL_MOUSEMOTION): + { + SDL_MouseMotionEvent mouse_event = ev.motion; + r32 x_motion = (r32)mouse_event.xrel; + r32 y_motion = (r32)mouse_event.yrel; if (x_motion != 0.0 || y_motion != 0.0) { angle_yaw = angle_yaw + To_Radian(x_motion * 0.1f); @@ -1035,14 +640,14 @@ int main(int argc, char* argv[]) camera_look = camera_look_around(angle_pitch, angle_yaw); } - } break; + } break; default: { break; } } } - + // PROCESS if (move_w) { @@ -1064,70 +669,37 @@ int main(int argc, char* argv[]) Vec3 camera_right_scaled = scaler_multiply3v(camera_right, camera_speed_adjusted); camera_pos = subtract3v(camera_pos, camera_right_scaled); } - // light_location.z = 10.00 * sinf(time_curr/10.0); - view = camera_create4m(camera_pos, add3v(camera_pos, camera_look), preset_up_dir); - + view = camera_create4m(camera_pos, add3v(camera_pos, camera_look), preset_up_dir); + // object shader program stuff glUseProgram(shader_program); - - // Update spot light params - glUniform3fv(SL_pos_loc, 1, camera_pos.data); - glUniform3fv(SL_front_loc, 1, camera_look.data); - + glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); - glUniform3fv(camera_pos_loc, 1, camera_pos.data); - - // light/lamp shader program stuff - //glUseProgram(light_sp); - //glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer); + glUniform3fv(camera_pos_loc, 1, camera_pos.data); time_prev = time_curr; - // OUTPUT - //glClearColor(1.0f, 0.6f, .6f, 1.0f); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClearColor(1.0f, 0.6f, .6f, 1.0f); + //glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //glActiveTexture(GL_TEXTURE1); - //glBindTexture(GL_TEXTURE_2D, container_texture); - - glUseProgram(light_sp); - glBindVertexArray(light_VAO); - for (int i = 0; i < 4; i++) - { - Mat4 light_model = translation_matrix4m(MPL_position[i].x, MPL_position[i].y, MPL_position[i].z); - uint32_t light_model_loc = glGetUniformLocation(light_sp, "Model"); - glUniformMatrix4fv(light_model_loc, 1, GL_TRUE, light_model.buffer); - - glUniformMatrix4fv(light_view_loc, 1, GL_TRUE, view.buffer); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - glBindVertexArray(0); - glUseProgram(0); - - glUseProgram(shader_program); - glBindVertexArray(VAO); - - for (int i = 0; i < 5; i++) + + for (int i = 0; i < 1; i++) { Vec3 translation_iter = model_translations[i]; Mat4 model = init_value4m(1.0); Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z); model = multiply4m(model_translation, model); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); - glDrawArrays(GL_TRIANGLES, 0, 36); + test_model.draw(shader_program); } - - glBindVertexArray(0); - - + SDL_GL_SwapWindow(window); } // opengl free calls - glDeleteVertexArrays(1, &VAO); - glDeleteBuffers(1, &VBO); + //glDeleteVertexArrays(1, &VAO); + //glDeleteBuffers(1, &VBO); glDeleteProgram(shader_program); // sdl free calls |