diff --git a/data/default.fs b/data/default.fs new file mode 100644 index 0000000..39afb28 --- /dev/null +++ b/data/default.fs @@ -0,0 +1,11 @@ +#version 330 core + +in vec3 fragmentColor; + +out vec3 color; + +void main() +{ + color = fragmentColor; +} + diff --git a/data/default.vs b/data/default.vs new file mode 100644 index 0000000..b30ca0e --- /dev/null +++ b/data/default.vs @@ -0,0 +1,17 @@ +#version 330 core + +in vec3 vertexPosition_modelspace; +in vec3 vertexColor; + +out vec3 fragmentColor; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * view * model * vec4(vertexPosition_modelspace, 1); + fragmentColor = vertexColor; +} + diff --git a/src/hexgame.cpp b/src/hexgame.cpp index 3bbbe8f..92f57a4 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -5,7 +5,10 @@ // - pathfinding // - assimp animation // - update imgui to v1.62 -- requires changes to example api +// - replace aixlog with custom logging iostream +// - fix vector normalization in renderer.cpp when moving in 2 directions // - add prefix to interface function names for eg) gooey.h, renderer.h +// - test build on windows / update vs project files //----------------------------------------------------------------------------- // Some defaults for the game layout diff --git a/src/mesh.cpp b/src/mesh.cpp index 48d59f2..fe23038 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -27,6 +27,15 @@ meInitAssimp() return true; } +inline glm::vec3 +copyVector(aiVector3D v_in, glm::vec3& v_out) +{ + v_out.x = v_in.x; + v_out.y = v_in.y; + v_out.z = v_in.z; + return v_out; +} + meMeshInfo* meLoadFromFile(const char* filename) { @@ -50,19 +59,10 @@ meLoadFromFile(const char* filename) // copy vertices and normals for (uint i = 0; i < mesh->num_vertices; i++) { - aiVector3D v_in = scene->mMeshes[0]->mVertices[i]; - glm::vec3& v_out = mesh->vertices[i]; - v_out.x = v_in.x; - v_out.y = v_in.y; - v_out.z = v_in.z; - - if (scene->mMeshes[0]->HasNormals()) { - aiVector3D n_in = scene->mMeshes[0]->mNormals[i]; - glm::vec3& n_out = mesh->normals[i]; - n_out.x = n_in.x; - n_out.y = n_in.y; - n_out.z = n_in.z; - } + copyVector(scene->mMeshes[0]->mVertices[i], mesh->vertices[i]); + + if (scene->mMeshes[0]->HasNormals()) + copyVector(scene->mMeshes[0]->mNormals[i], mesh->normals[i]); } // copy indices diff --git a/src/render_group.cpp b/src/render_group.cpp index d08cef6..93d6937 100644 --- a/src/render_group.cpp +++ b/src/render_group.cpp @@ -71,14 +71,14 @@ rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * } void -rgInitGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLenum target, GLfloat data[]) +rgInitGLBufferObject(gl_buffer* buf_obj, uint len, GLenum usage, GLenum target, GLfloat data[]) { - buf_obj->buffer_len = (size_t) len; + buf_obj->buffer_len = len; buf_obj->buffer = (GLfloat*) std::calloc(len, sizeof(GLfloat)); if (data) { - for (int i = 0; i < len; i++) + for (uint i = 0; i < len; i++) buf_obj->buffer[i] = data[i]; } @@ -239,7 +239,6 @@ rgDraw(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, glDisableVertexAttribArray(1); } -// TODO: testing indexed drawing void rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix, bool update_vertex_data) @@ -269,10 +268,8 @@ rgDrawIndexed(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); } - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rg->index_buffer.buffer_id); - // draw - //glDrawArrays(draw_mode, 0, rg->vertex_buffer.buffer_len / 3); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rg->index_buffer.buffer_id); glDrawElements(draw_mode, rg->index_buffer.buffer_len, GL_UNSIGNED_INT, 0); // cleanup diff --git a/src/render_group.h b/src/render_group.h index a91562f..c66eead 100644 --- a/src/render_group.h +++ b/src/render_group.h @@ -43,7 +43,7 @@ gl_render_group* rgCreateGroup(); bool rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * frag_code, const char* model_name, const char* view_name, const char* projection_name); -void rgInitGLBufferObject(gl_buffer* buf_obj, int len, GLenum usage, GLenum target, GLfloat data[]); +void rgInitGLBufferObject(gl_buffer* buf_obj, uint len, GLenum usage, GLenum target, GLfloat data[]); bool rgInitEntity(gl_render_group* rg, Entity* e); diff --git a/src/renderer.cpp b/src/renderer.cpp index 2718fff..4e198d8 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -20,7 +20,6 @@ #include "aixlog.hpp" #include "hexlib.h" -#include "util.h" #include "hexgame.h" #include "renderer.h" #include "render_group.h" @@ -31,29 +30,6 @@ //#define PROJ_TYPE ORTHOGRAPHIC #define PROJ_TYPE PERSPECTIVE -const char * VERTEX_SHADER_CODE = - "#version 330 core\n" - "in vec3 vertexPosition_modelspace;\n" - "in vec3 vertexColor;\n" - "out vec3 fragmentColor;\n" - "uniform mat4 model;\n" - "uniform mat4 view;\n" - "uniform mat4 projection;\n" - "void main()\n" - "{\n" - " gl_Position = projection * view * model * vec4(vertexPosition_modelspace, 1);\n" - " fragmentColor = vertexColor;\n" - "}"; - -const char * FRAGMENT_SHADER_CODE = - "#version 330 core\n" - "in vec3 fragmentColor;\n" - "out vec3 color;\n" - "void main()\n" - "{\n" - " color = fragmentColor;\n" - "}"; - const char * LINE_FRAGMENT_SHADER_CODE = "#version 330 core\n" "out vec3 color;\n" @@ -193,11 +169,13 @@ initMatrices(projection_type p) glm::cos(v) * glm::cos(h), glm::sin(v) ); + + glm::normalize(c.forward); ////// g_camera.up = glm::vec3(0,1,0); g_camera.left = glm::normalize(glm::cross(g_camera.up, g_camera.forward)); - g_camera.up = glm::cross(g_camera.forward, g_camera.left); + g_camera.up = glm::normalize(glm::cross(g_camera.forward, g_camera.left)); g_scene_matrices.view = glm::lookAt( g_camera.position, // camera position @@ -296,17 +274,20 @@ initRenderer(SDL_Handles &handles, v2i vpDims) // hide VRAM debug messages glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); + const char* vs_code = utilDumpTextFile("../data/default.vs"); + const char* fs_code = utilDumpTextFile("../data/default.fs"); + if (!rgInitShaderProgram( - g_filled_hex_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, + g_filled_hex_render_group, vs_code, fs_code, "model", "view", "projection") || !rgInitShaderProgram( - g_hex_line_render_group, VERTEX_SHADER_CODE, LINE_FRAGMENT_SHADER_CODE, + g_hex_line_render_group, vs_code, LINE_FRAGMENT_SHADER_CODE, "model", "view", "projection") || !rgInitShaderProgram( - g_debug_render_group, VERTEX_SHADER_CODE, DEBUG_FRAGMENT_SHADER_CODE, + g_debug_render_group, vs_code, DEBUG_FRAGMENT_SHADER_CODE, "model", "view", "projection") || !rgInitShaderProgram( - g_entity_render_group, VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE, + g_entity_render_group, vs_code, fs_code, "model", "view", "projection")) { return false; @@ -424,6 +405,8 @@ createScene(std::vector* hexes, Entity* entities, uint32 entity_count) fillHexLineBuffer(line_buf, line_buf_len, hexes); rgInitGLBufferObject(&g_hex_line_render_group->vertex_buffer, line_buf_len, GL_STATIC_DRAW, GL_ARRAY_BUFFER, line_buf); + // TODO: add a color buffer to hex_line and debug render groups to re-use + // fragment shaders and simplify draw rgDraw() // free temporary buffers std::free(vbuf); @@ -456,24 +439,23 @@ moveCamera(bool up, bool left, bool down, bool right, bool forward, bool backwar glm::vec3 &p = g_camera.position; glm::vec3 v(0.f); // normalized direction - if (forward) v += f; + // TODO: still seems like we're adding magnitude when moving in 2 directions +#if 0 + if (forward) v = glm::normalize(v + f); + if (backward) v = glm::normalize(v - f); + if (up) v = glm::normalize(v + u); + if (down) v = glm::normalize(v - u); + if (left) v -= glm::normalize(glm::cross(f, u)); + if (right) v -= glm::normalize(glm::cross(u, f)); +#else + if (forward) v += f; if (backward) v -= f; if (up) v += u; if (down) v -= u; - if (left) - { - glm::vec3 l = glm::cross(f, u); - v -= l; - } - if (right) - { - glm::vec3 r = glm::cross(u, f); - v -= r; - } + if (left) v -= glm::cross(f, u); + if (right) v -= glm::cross(u, f); +#endif - // TODO: this still doesn't fix side to side movement magnitude when vAngle is - // close to +- 90 degrees - glm::normalize(v); p += (v * MOVE_SPEED); glm::vec3 diff = old - p; g_scene_matrices.view = glm::translate(g_scene_matrices.view, diff); @@ -500,8 +482,10 @@ rotateCamera(int32 xrel, int32 yrel) glm::sin(v) ); + glm::normalize(c.forward); c.up = glm::vec3(0,0,1); - c.left = glm::cross(c.forward, c.up); + c.left = glm::normalize(glm::cross(c.forward, c.up)); + c.up = glm::normalize(glm::cross(c.left, c.forward)); g_scene_matrices.view = glm::lookAt(c.position, c.position + c.forward, c.up); g_scene_matrices.MVP = g_scene_matrices.projection * g_scene_matrices.view * g_scene_matrices.model; @@ -553,7 +537,8 @@ renderFrame(std::vector *hexes, Entity* entities, uint32 entity_count) for (uint i = 0; i < entity_count; i++) { rgDrawIndexed( g_entity_render_group, GL_TRIANGLES, - entities[i].mesh->model_transform, m_view, m_projection); + entities[i].mesh->model_transform, m_view, m_projection + ); } } diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..2a848d5 --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,40 @@ + +#include +#include + +#include "util.h" + +const uint MAX_FILESIZE = 2 * 1024 * 1024; // 2MB + +char * +utilDumpTextFile(const char* filename) +{ + // log('info: loading filename, blablabla); + // TODO: log errors + std::FILE* fp = std::fopen(filename, "rb"); + assert(fp); + + std::fseek(fp, 0, SEEK_END); + uint length = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); + assert(length < MAX_FILESIZE); + // TODO: check error codes for fseek and ftell + + char* buf = (char *) std::calloc(length, sizeof(char)); + assert(buf); + + std::fread(buf, sizeof(char), length, fp); + // TODO: check fp w/ ferror() here + + return buf; +} + +// TODO: search/replace other calls to stdd::free with this +void +utilSafeFree(void* mem) +{ + assert(mem != nullptr); + std::free(mem); + mem = nullptr; +} + diff --git a/src/util.h b/src/util.h index 69c5fb4..c106e3c 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,7 @@ #pragma once +#include #include @@ -11,6 +12,7 @@ typedef int32_t int32; typedef int64_t int64; typedef uint8_t uint8; typedef uint32_t uint32; +typedef uint32_t uint; struct v2f { @@ -49,7 +51,8 @@ inline real32 SafeRatio(real32 dividend, real32 divisor) { if (divisor == 0) - return dividend; + // TODO: log warning (don't require aixlog) + return 0; else return dividend / divisor; } @@ -61,3 +64,20 @@ SafeTruncateToInt32(int64 val) return (int32) val; } +// TODO: can't implement this before removing aixlog because of global name clashes +#if 0 +enum utilLogLevel { + DEBUG, + INFO, + WARNING, + ERROR, + ENUM_COUNT +}; + +void utilLog(utilLogError lvl, char* message); +#endif + +char * utilDumpTextFile(const char* filename); + +void utilSafeFree(void* mem); +