summaryrefslogtreecommitdiff
path: root/source/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/main.cpp')
-rw-r--r--source/main.cpp704
1 files changed, 167 insertions, 537 deletions
diff --git a/source/main.cpp b/source/main.cpp
index a9e5c81..7deb893 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -2,14 +2,14 @@
#include <stdlib.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"
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
/* @lookup:
* - understand kernals, how they work and how they affect post processing
* - Check to see why it is necessary to do glBindTexture()
@@ -50,6 +50,31 @@ typedef u8 b8;
// =========== Shader Loading =============
+enum Texture_Filtering { TF_NEAREST, TF_LINEAR };
+
+struct GlTexturedQuad {
+ u32 vao;
+ u32 vbo;
+ u32 texture_id;
+};
+
+struct GlShader {
+ u32 id;
+ s32 model_loc;
+ s32 view_loc;
+ s32 proj_loc;
+};
+
+void gl_shader_load_locations(GlShader *shader)
+{
+ glUseProgram(shader->id);
+ shader->model_loc = glGetUniformLocation(shader->id, "Model");
+ shader->view_loc = glGetUniformLocation(shader->id, "View");
+ shader->proj_loc = glGetUniformLocation(shader->id, "Projection");
+
+ return;
+}
+
unsigned int gl_create_vertex_shader(char* vertex_shader_source)
{
unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
@@ -121,36 +146,25 @@ unsigned int gl_shader_program(char* vertex_shader_source, char* fragment_shader
return shader_program;
}
-Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up)
+u32 gl_shader_program_from_path(char* vs_path, char* fs_path)
{
- // @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;
-}
+ // @todo: add failure handling here
+ // what to do if we fail to read the shaders
+ size_t read_count;
+ char* vs = (char*)SDL_LoadFile(vs_path, &read_count);
+ char* fs = (char*)SDL_LoadFile(fs_path, &read_count);
-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);
-
- return camera_look;
+ u32 shader_program = gl_shader_program(vs, fs);
+
+ return shader_program;
}
-s32 gl_load_texture(u32 texture_id, const char* path)
+s32 gl_load_texture(u32 texture_id, char *path, enum Texture_Filtering filter)
{
s32 width, height, nrChannels;
+ stbi_set_flip_vertically_on_load(1);
unsigned char *data = stbi_load(path, &width, &height, &nrChannels, 0);
+ stbi_set_flip_vertically_on_load(0);
if (data)
{
GLenum format;
@@ -167,431 +181,137 @@ s32 gl_load_texture(u32 texture_id, const char* path)
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
- {
- printf("failed to load image texture at path: %s", path);
- stbi_image_free(data);
- }
-
- return texture_id;
-}
-
-// =================== 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
-
-s32 TextureFromFile(const char* filepath, std::string directory)
-{
- // @note: this function is stupid as it already became outdated as I needed to tweak the parameters
- // for wrapping. Either those become function parameters (Which makes sense I guess) or I look at
- // exactly what steps I am reusing and just make that a function so the function is called fewer times.
- //
- // I am guessing this won't look good from a design point of view for all those jobs and postings, even if
- // this may be the simpler and faster thing to do, albeit at the cost of typing.
- 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)
- {
- 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
- {
- printf("failed to load image texture at path: %s", filepath);
- stbi_image_free(data);
- }
-
- return texid;
-}
-
-enum TextureType { TextureDiffuse=0, TextureSpecular };
-struct Vertex {
- Vec3 position;
- Vec3 normal;
- Vec2 texture;
-};
-
-struct Texture {
- u32 id;
- enum TextureType type;
- std::string fname;
-};
-
-class Mesh {
- public:
- std::vector<Vertex> vertices;
- std::vector<u32> indices;
- std::vector<Texture> textures;
-
- u32 vao;
- u32 vbo;
- u32 ebo;
-
- 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));
-
- glBindVertexArray(0);
- }
-
- void draw(u32 shader_program)
- {
- glUseProgram(shader_program);
+ u32 min_filter;
+ u32 max_filter;
- 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);
-
- for (u32 i=0; i<textures.size(); i++)
+ if (filter == TF_LINEAR)
{
- 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);
+ min_filter = GL_LINEAR_MIPMAP_LINEAR;
+ max_filter = GL_LINEAR;
}
- glActiveTexture(GL_TEXTURE0);
-
- glBindVertexArray(vao);
- glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
- glBindVertexArray(0);
- }
-
- void draw_instanced(u32 shader_program, u32 instance_count)
- {
- glUseProgram(shader_program);
-
- 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);
-
- for (u32 i=0; i<textures.size(); i++)
+ else if (filter == TF_NEAREST)
{
- 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);
+ min_filter = GL_NEAREST_MIPMAP_LINEAR;
+ max_filter = GL_NEAREST;
}
- glActiveTexture(GL_TEXTURE0);
- glBindVertexArray(vao);
- glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0, instance_count);
- glBindVertexArray(0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
+ stbi_image_free(data);
}
-};
-
-class Model
-{
- public:
- std::vector<Texture> loaded_textures;
- std::vector<Mesh> meshes;
- std::string directory;
-
- Model(std::string path)
- {
- load_model(path);
- }
- void instance_mesh();
- void draw(u32 shader_program);
- void draw_instanced(u32 shader_program, u32 instance_count);
- private:
- 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);
-};
-
-void Model::instance_mesh()
-{
- for (u32 i=0; i < meshes.size(); i++)
+ else
{
- Mesh curr_mesh = meshes[i];
- glBindVertexArray(curr_mesh.vao);
- glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(u32), (void*)0);
- glEnableVertexAttribArray(3);
-
- glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(u32), (void*)(4*sizeof(u32)));
- glEnableVertexAttribArray(4);
-
- glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(u32), (void*)(8*sizeof(u32)));
- glEnableVertexAttribArray(5);
-
- glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 16 * sizeof(u32), (void*)(12*sizeof(u32)));
- glEnableVertexAttribArray(6);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glVertexAttribDivisor(3, 1);
- glVertexAttribDivisor(4, 1);
- glVertexAttribDivisor(5, 1);
- glVertexAttribDivisor(6, 1);
-
- glBindVertexArray(0);
+ // @todo: logging
+ printf("failed to load image texture at path: %s", path);
+ stbi_image_free(data);
+ return -1;
}
+
+ return 0;
}
-void Model::draw(u32 shader_program)
+GlTexturedQuad gl_setup_textured_quad(char* texture_path, enum Texture_Filtering filter)
{
- for (int i=0; i < meshes.size(); i++)
- {
- meshes[i].draw(shader_program);
- }
+ // rendering is clock-wise
+ r32 quad_vertices[] = {
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-left
+ 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
+ 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
+ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top-left
+ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-left
+ };
+ u32 vao, vbo, tex_id;
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &vbo);
+
+ glBindVertexArray(vao);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), &quad_vertices, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(r32), (void*)0);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(r32), (void*)(3*sizeof(r32)));
+ glBindVertexArray(0);
+
+ glGenTextures(1, &tex_id);
+ glActiveTexture(GL_TEXTURE0);
+ gl_load_texture(tex_id, texture_path, filter);
+
+ GlTexturedQuad tex_quad;
+ tex_quad.vao = vao;
+ tex_quad.vbo = vbo;
+ tex_quad.texture_id = tex_id;
+
+ return tex_quad;
}
-void Model::draw_instanced(u32 shader_program, u32 instance_count)
+void gl_draw_tex_quad(u32 shader_program, GlTexturedQuad tex_quad)
{
- for (int i=0; i < meshes.size(); i++)
- {
- meshes[i].draw_instanced(shader_program, instance_count);
- }
+ glUseProgram(shader_program);
+ s32 tex_id_loc = glGetUniformLocation(shader_program, "Texture");
+ glUniform1i(tex_id_loc, 0);
+ glBindVertexArray(tex_quad.vao);
+ glBindTexture(GL_TEXTURE_2D, tex_quad.texture_id);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
}
-void Model::load_model(std::string path)
+// =============== CAMERA STUFF =================
+// @note: Be sure to update and refactor the camera
+Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up)
{
- Assimp::Importer import;
- const aiScene *scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
-
- if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
- {
- printf("error loading model :%s\n", import.GetErrorString());
- return;
- }
-
- directory = path.substr(0, path.find_last_of('/'));
- process_node(scene->mRootNode, scene);
+ // @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;
}
-void Model::process_node(aiNode *node, const aiScene *scene)
+Vec3 camera_look_around(r32 angle_pitch, r32 angle_yaw)
{
- for (int i=0; i < node->mNumMeshes; i++)
- {
- aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
- meshes.push_back(process_mesh(mesh, scene));
- }
-
- for (int i=0; i<node->mNumChildren; i++)
- {
- process_node(node->mChildren[i], scene);
- }
+ 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;
}
-Mesh Model::process_mesh(aiMesh *mesh, const aiScene *scene)
+int main(int argc, char* argv[])
{
- std::vector<Vertex> vertices;
- std::vector<u32> indices;
- std::vector<Texture> textures;
-
- 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;
- }
- struct Vertex vertex;
- vertex.position = position;
- vertex.normal = normal;
- vertex.texture = texture;
+ // Load freetype
+ FT_Library library;
+ FT_Face face;
- vertices.push_back(vertex);
- }
- // process indices
- for (u32 i = 0; i < mesh->mNumFaces; i++)
+ if (FT_Init_FreeType(&library))
{
- aiFace face = mesh->mFaces[i];
- for(u32 j = 0; j < face.mNumIndices; j++)
- {
- indices.push_back(face.mIndices[j]);
- }
+ printf("Error: Could not init freetype library\n");
+ return -1;
}
- // process material
- if (mesh->mMaterialIndex >= 0)
+
+ FT_Error error = FT_New_Face(library, "assets/fonts/Arial.ttf", 0, &face);
+ if (error == FT_Err_Unknown_File_Format)
{
- 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());
+ printf("Error: Font Loading Failed. The font format is unsupported.\n");
+ return -1;
}
-
- return Mesh(vertices, indices, textures);
-}
-
-std::vector<Texture> Model::load_material_textures(aiMaterial *mat, aiTextureType type, TextureType tex_type)
-{
- std::vector<Texture> textures;
- for(u32 i=0; i<mat->GetTextureCount(type); i++)
+ else if (error)
{
- bool load_texture = true;
- aiString str;
- mat->GetTexture(type, i, &str);
- const char* fname = str.C_Str();
-
- 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);
- }
+ printf("Error: Font Loading Failed. Unknown error code: %d\n", error);
+ return -1;
}
- return textures;
-}
-
-class Shader {
- // @note: this is a draft, I think frankly, it's a stupid idea to be making this at this point
- // but my goal is to look at my code at this stage (which is in the second half of (or so I think)
- // learnopengl and identify repeated code that I think I can yank out and can make convenient to write.
- // The precondition for all of this is that I do not remodel the program based off of some vague idea of
- // cleanliness in my head. This is all still very procedural, I just want to minimize the amount I type
- // and at the same time see how well I can identify good abstractions
- //
- //
- // I much prefer to have things be not a class, especially if I look at how I did my lovely
- // math functions, which are so simple and straightforward
- public:
- u32 id;
-
- // @note: all well and good until you get compute shaders
- // then the entire thing shits the bed
- Shader(char* vertex_shader_source, char* fragment_shader_source) {
- id = gl_shader_program(vertex_shader_source, fragment_shader_source);
- }
+ FT_Set_Pixel_Sizes(face, 0, 48);
- void use() {
- glUseProgram(id);
- }
-
- void draw_triangles(u32 vao, u32 count) {
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 0, count);
- }
-
- void set_1i(char* variable, s32 value) {
- s32 loc = glGetUniformLocation(id, variable);
- glUniform1i(loc, value);
- }
-
- void set_matrix4fv(char* variable, Mat4 value, int count) {
- s32 loc = glGetUniformLocation(id, variable);
- glUniformMatrix4fv(loc, count, GL_TRUE, value.buffer);
- };
-
- ~Shader() {
- // @note: this can literally be replaced by another function that goes over the entire list
- // of shader_programs near the program exit and deletes them, if I even need to do that.
- glDeleteProgram(id);
- }
-};
-
-int main(int argc, char* argv[])
-{
-
- // ============ END ============
int width = 1024;
int height = 768;
@@ -615,7 +335,7 @@ int main(int argc, char* argv[])
height,
SDL_WINDOW_OPENGL);
- SDL_SetRelativeMouseMode(SDL_TRUE);
+ SDL_SetRelativeMouseMode(SDL_TRUE);
// create an opengl context
SDL_GLContext context = SDL_GL_CreateContext(window);
@@ -637,91 +357,13 @@ int main(int argc, char* argv[])
// filesystem playground stuff
size_t read_count;
- char* vertex_source = (char*)SDL_LoadFile("./source/shaders/model.vs.glsl", &read_count);
- char* inst_vertex_source = (char*)SDL_LoadFile("./source/shaders/instanced_model.vs.glsl", &read_count);
- char* fragment_source = (char*)SDL_LoadFile("./source/shaders/model.fs.glsl", &read_count);
-
- u32 shader_program = gl_shader_program(vertex_source, fragment_source);
- u32 inst_shader_program = gl_shader_program(inst_vertex_source, fragment_source);
-
- stbi_set_flip_vertically_on_load(1);
+ GlShader tex_quad_shader;
+ tex_quad_shader.id = gl_shader_program_from_path("./source/shaders/textured_quad.vs.glsl", "./source/shaders/textured_quad.fs.glsl");
+ gl_shader_load_locations(&tex_quad_shader);
- Model planet_model = Model(std::string("./assets/planet/planet.obj"));
- Model rock_model = Model(std::string("assets/rock/rock.obj"));
+ GlTexturedQuad tex_quad1 = gl_setup_textured_quad("./assets/smiling.png", TF_LINEAR);
+ GlTexturedQuad tex_quad2 = gl_setup_textured_quad("./assets/container.jpg", TF_LINEAR);
- float inst_vertices[] = {
- // positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)
- // BottomFace
- -0.5f, -1.0f, -0.5f, // top-right
- 0.5f, -1.0f, -0.5f, // top-left
- 0.5f, -1.0f, 0.5f, // bottom-left
- 0.5f, -1.0f, 0.5f, // bottom-left
- -0.5f, -1.0f, 0.5f, // bottom-right
- -0.5f, -1.0f, -0.5f, // top-right
- // Top face
- -0.5f, -0.9f, -0.5f, // top-left
- 0.5f, -0.9f, 0.5f, // bottom-right
- 0.5f, -0.9f, -0.5f, // top-right
- 0.5f, -0.9f, 0.5f, // bottom-right
- -0.5f, -0.9f, -0.5f, // top-left
- -0.5f, -0.9f, 0.5f // bottom-left
- };
- const u32 instance_count = 100000;
- Mat4 *offsets = (Mat4 *)calloc(instance_count, sizeof(Mat4));
- u32 amount = instance_count;
- r32 offset = 7.0f;
- r32 radius = 50.0f;
- srand(SDL_GetTicks64());
- for (u32 i = 0; i < amount; i++)
- {
- Mat4 model = init_value4m(1.0f);
-
- // 1. translation
- u32 angle = (i*360)/amount;
- r32 displacement = (rand()%(u32)(2 * offset * 100)) / 100.0f - offset;
- r32 x = sin(angle) * radius + displacement;
- displacement = (rand()%(u32)(2 * offset * 100)) / 100.0f - offset;
- r32 y = displacement * 1.5f;
- displacement = (rand()%(u32)(2 * offset * 100)) / 100.0f - offset;
- r32 z = cos(angle) * radius + displacement;
- Mat4 translation = translation_matrix4m(x, y, z);
-
- // 2. scale
- r32 rnd_scale = (rand()%20) / 100.0f + 0.05;
- Mat4 scale = scaling_matrix4m(rnd_scale, rnd_scale, rnd_scale);
-
- // 3. rotation
- r32 rot_angle = To_Radian(rand()%360);
- Mat4 rotation = rotation_matrix4m(rot_angle, Vec3{0.4f, 0.6f, 0.8f});
-
- model = multiply4m(rotation, model);
- model = multiply4m(scale, model);
- model = multiply4m(translation, model);
-
- offsets[i] = to_col_major4m(model);
- }
-
- u32 instance_vbo;
- glGenBuffers(1, &instance_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, instance_vbo);
-
-#if 0
- u32 offset_sz = offsets.size();
- Mat4 *offset_ptr = offsets.data();
-#endif
- u32 offset_sz = instance_count * sizeof(Mat4);
- Mat4 *offset_ptr = &offsets[0];
- glBufferData(GL_ARRAY_BUFFER, offset_sz, offset_ptr, GL_STATIC_DRAW);
-
- rock_model.instance_mesh();
-
- // uniform buffer objects
- u32 ubo_camera_block;
- glGenBuffers(1, &ubo_camera_block);
- glBindBuffer(GL_UNIFORM_BUFFER, ubo_camera_block);
- glBufferData(GL_UNIFORM_BUFFER, 128, NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-
// objects
Vec3 model_translations[] = {
Vec3{ 0.5, 0.0, 0.0}, // 0: origin square
@@ -755,20 +397,9 @@ int main(int argc, char* argv[])
Mat4 proj = perspective4m((r32)To_Radian(90.0), (r32)width / (r32)height, 0.1f, 1000.0f);
- u32 block_binding = 0;
- u32 matrices_ind;
- matrices_ind = glGetUniformBlockIndex(shader_program, "Matrices");
- glUniformBlockBinding(shader_program, matrices_ind, block_binding);
- matrices_ind = glGetUniformBlockIndex(inst_shader_program, "Matrices");
- glUniformBlockBinding(inst_shader_program, matrices_ind, block_binding);
- // or glBindBufferBase();
- glBindBufferRange(GL_UNIFORM_BUFFER, block_binding, ubo_camera_block, 0, 128);
-
- Mat4 col_major_proj = to_col_major4m(proj);
- glBindBuffer(GL_UNIFORM_BUFFER, ubo_camera_block);
- glBufferSubData(GL_UNIFORM_BUFFER, 64, 64, col_major_proj.buffer);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-
+ s32 proj_loc;
+ glUniformMatrix4fv(tex_quad_shader.proj_loc, 1, GL_TRUE, proj.buffer);
+
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
@@ -892,40 +523,39 @@ int main(int argc, char* argv[])
view = camera_create4m(camera_pos, add3v(camera_pos, camera_look), preset_up_dir);
// object shader program stuff
- Mat4 col_major_view = to_col_major4m(view);
- glBindBuffer(GL_UNIFORM_BUFFER, ubo_camera_block);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, 64, col_major_view.buffer);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-
time_prev = time_curr;
+ glUniformMatrix4fv(tex_quad_shader.view_loc, 1, GL_TRUE, view.buffer);
// OUTPUT
glClearColor(1.0f, 0.6f, .6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- {
- glUseProgram(shader_program);
- Vec3 translation_iter = model_translations[0];
- Mat4 model = init_value4m(1.0);
- Mat4 model_scale = scaling_matrix4m(5.0f, 5.0f, 5.0f);
- model = multiply4m(model_scale, model);
- Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z);
- model = multiply4m(model_translation, model);
- u32 model_loc = glGetUniformLocation(shader_program, "Model");
- glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer);
- planet_model.draw(shader_program);
- }
- {
- rock_model.draw_instanced(inst_shader_program, instance_count);
- }
+ {
+ glUseProgram(tex_quad_shader.id);
+ Vec3 pos = model_translations[0];
+ Mat4 translation = translation_matrix4m(pos.x, pos.y, pos.z);
+ glUniformMatrix4fv(tex_quad_shader.model_loc, 1, GL_TRUE, translation.buffer);
+ gl_draw_tex_quad(tex_quad_shader.id, tex_quad1);
+ }
+
+ {
+ glUseProgram(tex_quad_shader.id);
+ Vec3 pos = model_translations[1];
+ Mat4 translation = translation_matrix4m(pos.x, pos.y, pos.z);
+ glUniformMatrix4fv(tex_quad_shader.model_loc, 1, GL_TRUE, translation.buffer);
+ gl_draw_tex_quad(tex_quad_shader.id, tex_quad2);
+ }
SDL_GL_SwapWindow(window);
}
// opengl free calls
- //glDeleteVertexArrays(1, &vao);
- //glDeleteBuffers(1, &vbo);
- glDeleteProgram(shader_program);
+ // it is up to the renderer to free everything here
+ // of course I have not bothered to set that up so it does not matter
+ glDeleteVertexArrays(1, &tex_quad1.vao);
+ glDeleteVertexArrays(1, &tex_quad2.vao);
+ glDeleteBuffers(1, &tex_quad1.vao);
+ glDeleteBuffers(1, &tex_quad2.vao);
// sdl free calls
SDL_GL_DeleteContext(context);