summaryrefslogtreecommitdiff
path: root/source/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/main.cpp')
-rw-r--r--source/main.cpp1134
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