Browse Source

staging entity changes to renderer

master
cinnaboot 8 years ago
parent
commit
096f3b16e7
  1. 2
      .gitignore
  2. 1
      data/default.fs
  3. 17
      src/entity.h
  4. 91
      src/hexgame.cpp
  5. 19
      src/hexgame.h
  6. 80
      src/mesh.cpp
  7. 12
      src/mesh.h
  8. 294
      src/render_group.cpp
  9. 42
      src/render_group.h
  10. 118
      src/renderer.cpp
  11. 23
      src/util.cpp
  12. 6
      src/util.h

2
.gitignore vendored

@ -5,4 +5,4 @@ tags
msvc/.vs/ msvc/.vs/
msvc/x64/ msvc/x64/
imgui.ini imgui.ini
doc/

1
data/default.fs

@ -22,5 +22,6 @@ void main()
brightness = clamp(brightness, 0, 1); brightness = clamp(brightness, 0, 1);
color = brightness * fragmentColor; color = brightness * fragmentColor;
//color = vec3(255, 255, 255);
} }

17
src/entity.h

@ -0,0 +1,17 @@
#pragma once
#include "mesh.h"
#include "render_group.h"
struct render_group;
struct Entity
{
meMeshGroup mesh_group;
render_group* ren_group;
//TODO: more entity properties: sound, gameplay info
};

91
src/hexgame.cpp

@ -1,18 +1,27 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// TODO: // TODO:
// - add a color buffer to hex_line and debug render groups to re-use
// fragment shaders and simplify draw rgDraw()
// - need to add normal buffer too
// - lighting // - lighting
// - add light struct // - add light struct
// - pass all lights to render groups/shaders every frame // - pass all lights to render groups/shaders every frame
// - need to give hexagons vertex normals (can then get rid of rgDraw())
// - maybe use more than one model in a scene // - maybe use more than one model in a scene
// - map generation // - map generation
// - pathfinding // - pathfinding
// - assimp animation // - assimp animation
// - update imgui to v1.62 -- requires changes to example api
// - replace aixlog with custom logging iostream? // - replace aixlog with custom logging iostream?
// - fix vector normalization in renderer.cpp when moving in 2 directions // - fix vector normalization in renderer.cpp when moving in 2 directions
// - add prefix to interface function names for eg) gooey.h, renderer.h // - add prefix to interface function names for eg) gooey.h, renderer.h
// - test build on windows / update vs project files // - move hex logic to new file to leave only init glue in a main.cpp
// - move SDL input callbacks somewhere too?
// - think about combining mesh data and render_group data to save some memory
// - actually don't need to save the vertex/normal buffers after passing
// to opengl
// - replace calls to malloc/free with safe(r) function in util.h
// - also need to make a macro that works with malloc void * and c++
// - add cpu perforcmace counters in render loop
// - check for memory leaks w/ valgrind
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Some defaults for the game layout // Some defaults for the game layout
@ -47,19 +56,19 @@
#endif #endif
#include "aixlog.hpp" #include "aixlog.hpp"
#include "util.h" #include "gooey.h"
#include "hexgame.h" #include "hexgame.h"
#include "hexlib.h" #include "hexlib.h"
#include "renderer.h"
#include "gooey.h"
#include "mesh.h" #include "mesh.h"
#include "platform_wait_for_vblank.h" #include "platform_wait_for_vblank.h"
#include "renderer.h"
#include "util.h"
using std::vector; using std::vector;
game_state* g_game_state; static game_state* g_game_state;
render_state* g_render_state; static render_state* g_render_state;
vector<Point> g_polygon_select_vertices = {Point(), Point(), Point(), Point()}; static vector<Point> g_polygon_select_vertices = {Point(), Point(), Point(), Point()};
void void
createHexes(vector<hex_info> *hxi_array, const Layout &layout, uint32 color) createHexes(vector<hex_info> *hxi_array, const Layout &layout, uint32 color)
@ -454,26 +463,20 @@ cleanUp(SDL_Handles &handles)
SDL_DestroyWindow(handles.window); SDL_DestroyWindow(handles.window);
SDL_Quit(); SDL_Quit();
if (g_game_state) game_state* g = g_game_state;
{
if (g_game_state->hex_array) if (g_game_state->hex_array)
delete g_game_state->hex_array; delete g_game_state->hex_array;
delete g_game_state;
}
// TODO: C-style memory management for entities for (uint i = 0; i < g->entity_count; i++) {
render_state* r = g_render_state; meFreeMeshGroup(g->entities[i].mesh_group);
if (r) { rgFree(g->entities[i].ren_group);
for (uint i = 0; i < r->entity_count; i++) {
meFreeMesh(r->entities[i].mesh);
} }
std::free(r->entities); utilSafeFree(g->entities);
r->entities = nullptr;
delete r;
r = nullptr;
}
delete g_render_state;
delete g_game_state;
return true; return true;
} }
@ -541,19 +544,32 @@ int main(int argc, char* argv[])
} }
} }
if (meInitAssimp()) {
// TODO: better entity memory management // TODO: better entity memory management
if (meInitAssimp()) {
// TODO: hard coded limit of 1000 entities here // TODO: hard coded limit of 1000 entities here
Entity* e = (Entity*) std::calloc(1000, sizeof(Entity)); game_state* g = g_game_state;
render_state* r = g_render_state; g->entities = (Entity*) std::calloc(1000, sizeof(Entity));
r->entities = e;
//const char* test_file = "../data/animated.block.dae"; const char* test_file1 = "../data/animated.block.dae";
const char* test_file = "../data/catepillar.dae"; const char* test_file2 = "../data/catepillar.dae";
meMeshInfo* mesh = meLoadFromFile(test_file); meMeshGroup mg1, mg2;
if (mesh != nullptr) { if (meLoadFromFile(test_file1, mg1)) {
r->entities[r->entity_count].mesh = mesh; g->entities[g->entity_count].mesh_group = mg1;
r->entity_count++; g->entity_count++;
}
else {
LOG(ERROR) << "Error loading file, exiting\n";
return 1;
}
if (meLoadFromFile(test_file2, mg2)) {
g->entities[g->entity_count].mesh_group = mg2;
g->entity_count++;
}
else {
LOG(ERROR) << "Error loading file, exiting\n";
return 1;
} }
} else { } else {
@ -561,7 +577,7 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
if (!createScene(g_game_state->hex_array, g_render_state->entities, g_render_state->entity_count)) { if (!createScene(g_game_state->hex_array, g_game_state->entities, g_game_state->entity_count)) {
LOG(ERROR) << "Error in vertex data, exiting\n"; LOG(ERROR) << "Error in vertex data, exiting\n";
return 1; return 1;
} }
@ -571,17 +587,20 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
#if defined(_WIN32)
if (!platform_init(handles.window)) { if (!platform_init(handles.window)) {
LOG(ERROR) << "Couldn't get SDL platform info, exiting\n"; LOG(ERROR) << "Couldn't get SDL platform info, exiting\n";
return 1; return 1;
} }
#else
LOG(DEBUG) << "TODO: Implement better frame timer on linux\n"; // should notice this
#endif
// main loop // main loop
while (processSDLEvents()) { while (processSDLEvents()) {
#if defined(_WIN32) #if defined(_WIN32)
// sort-of fixed in windows with platform_wait_for_vblank() // sort-of fixed in windows with platform_wait_for_vblank()
#else #else
LOG(DEBUG) << "TODO: Implement better frame timer on linux\n"; // should notice this
SDL_Delay(16); // ~60hz SDL_Delay(16); // ~60hz
#endif #endif
game_state* g = g_game_state; game_state* g = g_game_state;
@ -590,7 +609,7 @@ int main(int argc, char* argv[])
moveCamera(g->is_moveup, g->is_moveleft, g->is_movedown, g->is_moveright, moveCamera(g->is_moveup, g->is_moveleft, g->is_movedown, g->is_moveright,
g->is_moveforward, g->is_movebackward); g->is_moveforward, g->is_movebackward);
renderFrame(g->hex_array, g_render_state->entities, g_render_state->entity_count); renderFrame(g->hex_array, g->entities, g->entity_count);
if (r->is_debug_draw && g->draw_mode == CONE_FILL) if (r->is_debug_draw && g->draw_mode == CONE_FILL)
renderDebug(g_polygon_select_vertices); renderDebug(g_polygon_select_vertices);

19
src/hexgame.h

@ -11,9 +11,10 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "entity.h"
#include "hexlib.h" #include "hexlib.h"
#include "util.h"
#include "mesh.h" #include "mesh.h"
#include "util.h"
// TODO: should move this to renderer.h // TODO: should move this to renderer.h
@ -46,22 +47,12 @@ enum HexDrawMode
PATHFINDING PATHFINDING
}; };
struct Entity
{
meMeshInfo* mesh;
//TODO: more entity properties: sound, gameplay info
};
struct render_state struct render_state
{ {
v2i viewport_dims; v2i viewport_dims;
bool is_debug_draw; bool is_debug_draw;
uint32 fill_color; uint32 fill_color;
uint32 selected_fill_color; uint32 selected_fill_color;
// TODO: should move this to game_state
uint32 entity_count = 0;
Entity* entities = nullptr;
}; };
struct game_state struct game_state
@ -73,7 +64,11 @@ struct game_state
HexDrawMode draw_mode; HexDrawMode draw_mode;
const Layout hex_layout; const Layout hex_layout;
// movement controls // TODO: WiP
uint32 entity_count = 0;
Entity* entities = nullptr;
// camera movement controls
bool is_selecting = false; bool is_selecting = false;
bool is_camera_rotate = false; bool is_camera_rotate = false;
bool is_moveforward = false; bool is_moveforward = false;

80
src/mesh.cpp

@ -14,6 +14,10 @@
#include "mesh.h" #include "mesh.h"
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out);
meMeshInfo* copyMeshInfo(const aiScene* scene, aiMesh* mesh);
void freeMesh(meMeshInfo* mesh);
bool bool
meInitAssimp() meInitAssimp()
{ {
@ -27,6 +31,43 @@ meInitAssimp()
return true; return true;
} }
bool
meLoadFromFile(const char* filename, meMeshGroup& mesh_group)
{
LOG(INFO) << "Loading file: " << filename << "\n";
const aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality);
if (scene->mNumMeshes < 1) {
LOG(ERROR) << "Scene contains no meshes\n";
return false;
}
mesh_group.num_meshes = scene->mNumMeshes;
mesh_group.meshes = (meMeshInfo**) std::calloc(mesh_group.num_meshes, sizeof(meMeshInfo*));
mesh_group.use_normals = scene->mMeshes[0]->HasNormals();
for (uint i = 0; i < scene->mNumMeshes; i++) {
mesh_group.meshes[i] = copyMeshInfo(scene, scene->mMeshes[i]);
}
// free memeory from assimp
aiReleaseImport(scene);
return true;
}
void
meFreeMeshGroup(meMeshGroup& mesh_group)
{
for (uint i = 0; i < mesh_group.num_meshes; i++)
freeMesh(mesh_group.meshes[i]);
}
void
meShutdownAssimp()
{
aiDetachAllLogStreams();
}
inline glm::vec3 inline glm::vec3
copyVector(aiVector3D v_in, glm::vec3& v_out) copyVector(aiVector3D v_in, glm::vec3& v_out)
{ {
@ -37,26 +78,13 @@ copyVector(aiVector3D v_in, glm::vec3& v_out)
} }
meMeshInfo* meMeshInfo*
meLoadFromFile(const char* filename) copyMeshInfo(const aiScene* scene, aiMesh* mesh)
{ {
const aiScene* scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_MaxQuality);
if (scene->mNumMeshes != 1) {
LOG(ERROR) << "We Can only handle 1 mesh per entity atm\n";
#if 0
return nullptr;
#else
LOG(DEBUG) << "num meshes: " << scene->mNumMeshes << "\n";
LOG(DEBUG) << "num materials: " << scene->mNumMaterials << "\n";
#endif
}
meMeshInfo* mi = (meMeshInfo*) std::calloc(1, sizeof(meMeshInfo)); meMeshInfo* mi = (meMeshInfo*) std::calloc(1, sizeof(meMeshInfo));
// TODO: using hard coded model transform for now // TODO: using hard coded model transform for now
mi->model_transform = glm::scale(glm::mat4(1), glm::vec3(100, 100, 100)); mi->model_transform = glm::scale(glm::mat4(1), glm::vec3(100, 100, 100));
// allocate buffers for vertex and index data from mesh // allocate buffers for vertex and index data from mesh
aiMesh* mesh = scene->mMeshes[2];
mi->num_vertices = mesh->mNumVertices; mi->num_vertices = mesh->mNumVertices;
mi->vertices = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3)); mi->vertices = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3));
mi->normals = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3)); mi->normals = (glm::vec3 *) std::calloc(mi->num_vertices, sizeof(glm::vec3));
@ -77,7 +105,7 @@ meLoadFromFile(const char* filename)
mi->indices[i * 3 + j] = mesh->mFaces[i].mIndices[j]; mi->indices[i * 3 + j] = mesh->mFaces[i].mIndices[j];
// material // material
aiMaterial* mat = scene->mMaterials[1]; aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
aiColor3D color(0.f, 0.f, 0.f); aiColor3D color(0.f, 0.f, 0.f);
if (AI_SUCCESS != mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) { if (AI_SUCCESS != mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) {
LOG(ERROR) << "Some Assimp-type-error\n"; LOG(ERROR) << "Some Assimp-type-error\n";
@ -87,27 +115,15 @@ meLoadFromFile(const char* filename)
mi->diffuse_color.b = color.b; mi->diffuse_color.b = color.b;
} }
// free memeory from assimp
aiReleaseImport(scene);
return mi; return mi;
} }
void void
meFreeMesh(meMeshInfo* mesh) freeMesh(meMeshInfo* mesh)
{ {
std::free(mesh->vertices); utilSafeFree(mesh->vertices);
mesh->vertices = nullptr; utilSafeFree(mesh->normals);
std::free(mesh->normals); utilSafeFree(mesh->indices);
mesh->normals = nullptr; utilSafeFree(mesh);
std::free(mesh->indices);
mesh->indices = nullptr;
std::free(mesh);
mesh = nullptr;
}
void
meShutdownAssimp()
{
aiDetachAllLogStreams();
} }

12
src/mesh.h

@ -20,12 +20,20 @@ struct meMeshInfo
glm::vec3 diffuse_color; glm::vec3 diffuse_color;
}; };
struct meMeshGroup
{
bool use_normals = false;
uint num_meshes = 0;
meMeshInfo** meshes = nullptr;
// animation/bonemapping info here...
};
bool meInitAssimp(); bool meInitAssimp();
meMeshInfo* meLoadFromFile(const char* filename); bool meLoadFromFile(const char* filename, meMeshGroup& mesh_group);
void meFreeMesh(meMeshInfo* mesh); void meFreeMeshGroup(meMeshGroup& mesh_group);
void meShutdownAssimp(); void meShutdownAssimp();

294
src/render_group.cpp

@ -2,9 +2,6 @@
#include <cassert> #include <cassert>
#include <cstdlib> // calloc #include <cstdlib> // calloc
// TODO: decide on extension library
//#include <GL/glew.h>
#include <GL/gl3w.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/geometric.hpp> #include <glm/geometric.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
@ -13,14 +10,30 @@
#include "render_group.h" #include "render_group.h"
#include "mesh.h" #include "mesh.h"
#include "util.h"
#define INFO_LOG_MAX_LENGTH 312; #define INFO_LOG_MAX_LENGTH 312;
// forward declarations
render_object * allocateRenderObject(uint buffer_len, uint index_len = 0);
void freeRenderObject(render_object* ro);
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals);
void sendBufferToGL(gl_buffer* buffer, GLenum usage, GLenum target);
void sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target);
void drawRenderObject(render_group* rg, render_object* ro,
glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix,
glm::vec3 light_position, GLuint light_id, bool update_vertex_data);
// interface
bool bool
rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * frag_code) rgInitShaderProgram(rg_shader_program& sp, const char * vertex_code, const char * frag_code)
{ {
glGenVertexArrays(1, &rg->vertex_array_id); glGenVertexArrays(1, &sp.vertex_array_id);
glBindVertexArray(rg->vertex_array_id); glBindVertexArray(sp.vertex_array_id);
GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER); GLuint vertex_shader_id = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER); GLuint fragment_shader_id = glCreateShader(GL_FRAGMENT_SHADER);
@ -29,18 +42,18 @@ rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char *
glCompileShader(vertex_shader_id); glCompileShader(vertex_shader_id);
glCompileShader(fragment_shader_id); glCompileShader(fragment_shader_id);
rg->program_id = glCreateProgram(); sp.program_id = glCreateProgram();
glAttachShader(rg->program_id, vertex_shader_id); glAttachShader(sp.program_id, vertex_shader_id);
glAttachShader(rg->program_id, fragment_shader_id); glAttachShader(sp.program_id, fragment_shader_id);
glLinkProgram(rg->program_id); glLinkProgram(sp.program_id);
rg->model_matrix_id = glGetUniformLocation(rg->program_id, "model"); sp.model_matrix_id = glGetUniformLocation(sp.program_id, "model");
rg->view_matrix_id = glGetUniformLocation(rg->program_id, "view"); sp.view_matrix_id = glGetUniformLocation(sp.program_id, "view");
rg->projection_matrix_id = glGetUniformLocation(rg->program_id, "projection"); sp.projection_matrix_id = glGetUniformLocation(sp.program_id, "projection");
rg->normal_matrix_id = glGetUniformLocation(rg->program_id, "normal_matrix"); sp.normal_matrix_id = glGetUniformLocation(sp.program_id, "normal_matrix");
glDetachShader(rg->program_id, vertex_shader_id); glDetachShader(sp.program_id, vertex_shader_id);
glDetachShader(rg->program_id, fragment_shader_id); glDetachShader(sp.program_id, fragment_shader_id);
glDeleteShader(vertex_shader_id); glDeleteShader(vertex_shader_id);
glDeleteShader(fragment_shader_id); glDeleteShader(fragment_shader_id);
@ -48,18 +61,18 @@ rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char *
// also remove INFO_LOG_MAX_LENGTH define // also remove INFO_LOG_MAX_LENGTH define
#if 1 #if 1
GLint isLinked = 0; GLint isLinked = 0;
glGetProgramiv(rg->program_id, GL_LINK_STATUS, &isLinked); glGetProgramiv(sp.program_id, GL_LINK_STATUS, &isLinked);
if (isLinked == GL_FALSE) { if (isLinked == GL_FALSE) {
GLint maxLength = INFO_LOG_MAX_LENGTH; GLint maxLength = INFO_LOG_MAX_LENGTH;
glGetProgramiv(rg->program_id, GL_INFO_LOG_LENGTH, &maxLength); glGetProgramiv(sp.program_id, GL_INFO_LOG_LENGTH, &maxLength);
#ifdef _WIN32 #ifdef _WIN32
GLchar infoLog[312] = { 0 }; GLchar infoLog[312] = { 0 };
#else #else
GLchar infoLog[maxLength] = { 0 }; GLchar infoLog[maxLength] = { 0 };
#endif #endif
glGetProgramInfoLog(rg->program_id, maxLength, &maxLength, &infoLog[0]); glGetProgramInfoLog(sp.program_id, maxLength, &maxLength, &infoLog[0]);
LOG(ERROR) << infoLog << "\n"; LOG(ERROR) << infoLog << "\n";
glDeleteProgram(rg->program_id); glDeleteProgram(sp.program_id);
return false; return false;
} }
@ -68,32 +81,130 @@ rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char *
return true; return true;
} }
gl_buffer * // TODO: should pass in a buffer of colors here instead of hexes, move to renderer.cpp
rgInitGLBuffer(gl_buffer* buffer, uint buffer_len) // we don't need to know about hexes here
#if 0
void
rgFillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes)
{
int buf_idx;
int buf_len_per_hex = 54; // NOTE: 3 * 3 * 6
GLfloat color_buf[3];
for (int i = 0; i < (int) hexes->size(); i++)
{
buf_idx = i * buf_len_per_hex;
hex_info hxi = (*hexes)[i];
utilConvertColor(color_buf, hxi.current_color);
for (int j = 0; j < buf_len_per_hex; j+=3)
{
buf[buf_idx + j] = color_buf[0];
buf[buf_idx + j + 1] = color_buf[1];
buf[buf_idx + j + 2] = color_buf[2];
}
}
}
#endif
bool
rgInitEntity(Entity* e)
{ {
buffer->buffer_len = buffer_len; render_group* rg = UTIL_ALLOC(1, render_group);
buffer->buffer = (GLfloat*) std::calloc(buffer_len, sizeof(GLfloat)); e->ren_group = rg;
rg->draw_indexed = true;
rg->use_normals = e->mesh_group.use_normals;
uint num_meshes = rg->num_objects = e->mesh_group.num_meshes;
if (!buffer->buffer) rg->render_objects = (render_object**) std::calloc(num_meshes, sizeof(render_object*));
LOG(ERROR) << "Error allocating memory\n";
return buffer; for (uint i = 0; i < num_meshes; i++)
{
uint buffer_len = e->mesh_group.meshes[i]->num_vertices * 3;
uint index_len = e->mesh_group.meshes[i]->num_indices;
rg->render_objects[i] = allocateRenderObject(buffer_len, index_len);
if (rg->render_objects[i] == nullptr)
return false;
// TODO: safely free memory here when convertMeshInfo returns false
if (!convertMeshInfo(e->mesh_group.meshes[i], rg->render_objects[i], rg->use_normals))
return false;
}
return true;
} }
gl_index_buffer * void
initGLIndexBuffer(gl_index_buffer* index_buffer, uint buffer_len) rgDraw(render_group* rg, glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix,
glm::vec3 light_position, GLuint light_id, bool update_vertex_data)
{
for (uint i = 0; i < rg->num_objects; i++) {
drawRenderObject(rg, rg->render_objects[i], model_matrix, view_matrix, projection_matrix,
light_position, light_id, false);
}
}
void
rgFree(render_group* rg)
{ {
index_buffer->buffer_len = buffer_len; if (rg == nullptr) {
index_buffer->buffer = (uint*) std::calloc(buffer_len, sizeof(uint)); LOG(ERROR) << "tried to free nullptr\n";
return;
}
if (!index_buffer->buffer) for (uint i = 0; i < rg->num_objects; i++)
LOG(ERROR) << "Error allocating memory\n"; freeRenderObject(rg->render_objects[i]);
return index_buffer; utilSafeFree(rg);
}
// internal
render_object *
allocateRenderObject(uint buffer_len, uint index_len)
{
render_object* ro = UTIL_ALLOC(1, render_object);
if (ro == nullptr)
return nullptr;
ro->vertex_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat);
ro->vertex_buffer.buffer_len = buffer_len;
ro->normal_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat);
ro->normal_buffer.buffer_len = buffer_len;
ro->color_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat);
ro->color_buffer.buffer_len = buffer_len;
if (index_len > 0) {
ro->index_buffer.buffer = UTIL_ALLOC(index_len, uint);
ro->index_buffer.buffer_len = index_len;
}
if (ro->vertex_buffer.buffer == nullptr ||
ro->normal_buffer.buffer == nullptr ||
ro->color_buffer.buffer == nullptr ||
((index_len > 0) && (ro->vertex_buffer.buffer == nullptr)))
{
freeRenderObject(ro);
return nullptr;
}
return ro;
} }
void void
rgSendBufferToGL(gl_buffer* buffer, GLenum usage, GLenum target) freeRenderObject(render_object* ro)
{
utilSafeFree(ro->vertex_buffer.buffer);
utilSafeFree(ro->normal_buffer.buffer);
utilSafeFree(ro->color_buffer.buffer);
utilSafeFree(ro->index_buffer.buffer);
utilSafeFree(ro);
}
void
sendBufferToGL(gl_buffer* buffer, GLenum usage, GLenum target)
{ {
glGenBuffers(1, &buffer->buffer_id); glGenBuffers(1, &buffer->buffer_id);
glBindBuffer(target, buffer->buffer_id); glBindBuffer(target, buffer->buffer_id);
@ -108,39 +219,14 @@ sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target)
glBufferData(target, index_buffer->buffer_len * sizeof(uint), index_buffer->buffer, usage); glBufferData(target, index_buffer->buffer_len * sizeof(uint), index_buffer->buffer, usage);
} }
void
rgFillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes)
{
int buf_idx;
int buf_len_per_hex = 54; // NOTE: 3 * 3 * 6
GLfloat color_buf[3];
for (int i = 0; i < (int) hexes->size(); i++)
{
buf_idx = i * buf_len_per_hex;
hex_info hxi = (*hexes)[i];
utilConvertColor(color_buf, hxi.current_color);
for (int j = 0; j < buf_len_per_hex; j+=3)
{
buf[buf_idx + j] = color_buf[0];
buf[buf_idx + j + 1] = color_buf[1];
buf[buf_idx + j + 2] = color_buf[2];
}
}
}
// NOTE: Copy assimp data to our structures for openGL
bool bool
rgInitEntity(gl_render_group* rg, Entity* e) convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals)
{ {
rg->draw_indexed = true; uint vertex_buf_len = mesh->num_vertices * 3;
rg->use_normals = (e->mesh->normals != nullptr); GLfloat* vertex_buf = ro->vertex_buffer.buffer;
uint vertex_buf_len = e->mesh->num_vertices * 3; GLfloat* color_buf = ro->color_buffer.buffer;
GLfloat* normal_buf = ro->normal_buffer.buffer;
GLfloat* vertex_buf = rgInitGLBuffer(&rg->vertex_buffer, vertex_buf_len)->buffer; uint* index_buf = ro->index_buffer.buffer;
GLfloat* color_buf = rgInitGLBuffer(&rg->color_buffer, vertex_buf_len)->buffer;
GLfloat* normal_buf = rgInitGLBuffer(&rg->normal_buffer, vertex_buf_len)->buffer;
uint* index_buf = initGLIndexBuffer(&rg->index_buffer, e->mesh->num_indices)->buffer;
if (!vertex_buf || !color_buf || !normal_buf || !index_buf) if (!vertex_buf || !color_buf || !normal_buf || !index_buf)
return false; return false;
@ -150,8 +236,8 @@ rgInitEntity(gl_render_group* rg, Entity* e)
uint vertex_prop_index = 0; uint vertex_prop_index = 0;
for (uint i = 0; i < vertex_buf_len; i++) { for (uint i = 0; i < vertex_buf_len; i++) {
const glm::vec3& vertex = e->mesh->vertices[vertex_index]; const glm::vec3& vertex = mesh->vertices[vertex_index];
const glm::vec3& normal = e->mesh->normals[vertex_index]; const glm::vec3& normal = mesh->normals[vertex_index];
switch (vertex_prop_index) { switch (vertex_prop_index) {
case 0: vertex_buf[i] = vertex.x; break; case 0: vertex_buf[i] = vertex.x; break;
@ -159,7 +245,7 @@ rgInitEntity(gl_render_group* rg, Entity* e)
case 2: vertex_buf[i] = vertex.z; break; case 2: vertex_buf[i] = vertex.z; break;
} }
if (rg->use_normals) { if (use_normals) {
switch (vertex_prop_index) { switch (vertex_prop_index) {
case 0: normal_buf[i] = normal.x; break; case 0: normal_buf[i] = normal.x; break;
case 1: normal_buf[i] = normal.y; break; case 1: normal_buf[i] = normal.y; break;
@ -167,7 +253,7 @@ rgInitEntity(gl_render_group* rg, Entity* e)
} }
} }
color_buf[i] = e->mesh->diffuse_color[vertex_prop_index]; color_buf[i] = mesh->diffuse_color[vertex_prop_index];
vertex_prop_index++; vertex_prop_index++;
if (vertex_prop_index == 3) { if (vertex_prop_index == 3) {
@ -177,89 +263,77 @@ rgInitEntity(gl_render_group* rg, Entity* e)
} }
// dump indices // dump indices
for (uint i = 0; i < e->mesh->num_indices; i++) for (uint i = 0; i < mesh->num_indices; i++)
index_buf[i] = e->mesh->indices[i]; index_buf[i] = mesh->indices[i];
rgSendBufferToGL(&rg->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); sendBufferToGL(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgSendBufferToGL(&rg->color_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER); sendBufferToGL(&ro->color_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
if (rg->use_normals) if (use_normals)
rgSendBufferToGL(&rg->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER); sendBufferToGL(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
sendIndexBufferToGL(&rg->index_buffer, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER); sendIndexBufferToGL(&ro->index_buffer, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
return true; return true;
} }
void void
rgDraw(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, drawRenderObject(render_group* rg, render_object* ro,
glm::mat4 view_matrix, glm::mat4 projection_matrix, glm::mat4 model_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix,
glm::vec3 light_position, GLuint light_id, bool update_vertex_data) glm::vec3 light_position, GLuint light_id, bool update_vertex_data)
{ {
glUseProgram(rg->program_id); glUseProgram(rg->shader.program_id);
glUniformMatrix4fv(rg->model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]); glUniformMatrix4fv(rg->shader.model_matrix_id, 1, GL_FALSE, &model_matrix[0][0]);
glUniformMatrix4fv(rg->view_matrix_id, 1, GL_FALSE, &view_matrix[0][0]); glUniformMatrix4fv(rg->shader.view_matrix_id, 1, GL_FALSE, &view_matrix[0][0]);
glUniformMatrix4fv(rg->projection_matrix_id, 1, GL_FALSE, &projection_matrix[0][0]); glUniformMatrix4fv(rg->shader.projection_matrix_id, 1, GL_FALSE, &projection_matrix[0][0]);
// 1st attribute buffer : vertices // 1st attribute buffer : vertices
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, rg->vertex_buffer.buffer_id); glBindBuffer(GL_ARRAY_BUFFER, ro->vertex_buffer.buffer_id);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
if (update_vertex_data) if (update_vertex_data)
{ {
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->vertex_buffer.buffer_len * sizeof(GLfloat), glBufferSubData(GL_ARRAY_BUFFER, 0, ro->vertex_buffer.buffer_len * sizeof(GLfloat),
rg->vertex_buffer.buffer); ro->vertex_buffer.buffer);
} }
// 2nd attribute buffer : colors // 2nd attribute buffer : colors
if (rg->color_buffer.buffer) if (ro->color_buffer.buffer)
{ {
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, rg->color_buffer.buffer_id); glBindBuffer(GL_ARRAY_BUFFER, ro->color_buffer.buffer_id);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// TODO: maybe add an option to not send color data every frame? // TODO: maybe add an option to not send color data every frame?
glBufferSubData(GL_ARRAY_BUFFER, 0, rg->color_buffer.buffer_len * sizeof(GLfloat), glBufferSubData(GL_ARRAY_BUFFER, 0, ro->color_buffer.buffer_len * sizeof(GLfloat),
rg->color_buffer.buffer); ro->color_buffer.buffer);
} }
// 3rd attribute buffer: normals // 3rd attribute buffer: normals
#if 1
if (rg->use_normals) { if (rg->use_normals) {
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, rg->normal_buffer.buffer_id); glBindBuffer(GL_ARRAY_BUFFER, ro->normal_buffer.buffer_id);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
// TODO: testing lighting // TODO: testing lighting
glUniform3f(light_id, light_position.x, light_position.y, light_position.z); glUniform3f(light_id, light_position.x, light_position.y, light_position.z);
glm::mat3 normal_matrix = glm::transpose(glm::inverse(glm::mat3(model_matrix))); glm::mat3 normal_matrix = glm::transpose(glm::inverse(glm::mat3(model_matrix)));
glUniformMatrix3fv(rg->normal_matrix_id, 1, GL_FALSE, &normal_matrix[0][0]); glUniformMatrix3fv(rg->shader.normal_matrix_id, 1, GL_FALSE, &normal_matrix[0][0]);
} }
#endif
// draw // draw
if (rg->draw_indexed) { if (rg->draw_indexed) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rg->index_buffer.buffer_id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ro->index_buffer.buffer_id);
glDrawElements(draw_mode, rg->index_buffer.buffer_len, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, ro->index_buffer.buffer_len, GL_UNSIGNED_INT, 0);
} else { } else {
glDrawArrays(draw_mode, 0, rg->vertex_buffer.buffer_len / 3); glDrawArrays(rg->draw_mode, 0, ro->vertex_buffer.buffer_len / 3);
} }
// cleanup // cleanup
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
if (rg->color_buffer.buffer) if (ro->color_buffer.buffer)
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
if (rg->use_normals) if (rg->use_normals)
glDisableVertexAttribArray(2); glDisableVertexAttribArray(2);
} }
void
rgFree(gl_render_group* rg)
{
if (rg == nullptr)
return;
utilSafeFree(rg->vertex_buffer.buffer);
utilSafeFree(rg->normal_buffer.buffer);
utilSafeFree(rg->index_buffer.buffer);
utilSafeFree(rg->color_buffer.buffer);
utilSafeFree(rg);
}

42
src/render_group.h

@ -1,6 +1,13 @@
#pragma once
#include <GL/gl3w.h>
#include "entity.h"
//#include "hexgame.h"
#include "util.h" #include "util.h"
#include "hexgame.h"
struct Entity;
// TODO: can these structs be used as opaque pointers? // TODO: can these structs be used as opaque pointers?
@ -18,39 +25,44 @@ struct gl_index_buffer
uint* buffer = nullptr; uint* buffer = nullptr;
}; };
struct gl_render_group struct render_object
{ {
gl_buffer vertex_buffer; gl_buffer vertex_buffer;
gl_buffer normal_buffer; gl_buffer normal_buffer;
gl_buffer color_buffer; gl_buffer color_buffer;
gl_index_buffer index_buffer; gl_index_buffer index_buffer;
};
struct rg_shader_program
{
GLuint program_id = 0; GLuint program_id = 0;
GLuint model_matrix_id = 0; GLuint model_matrix_id = 0;
GLuint view_matrix_id = 0; GLuint view_matrix_id = 0;
GLuint projection_matrix_id = 0; GLuint projection_matrix_id = 0;
GLuint normal_matrix_id = 0; GLuint normal_matrix_id = 0;
GLuint vertex_array_id = 0; GLuint vertex_array_id = 0;
};
struct render_group
{
uint num_objects = 0;
render_object** render_objects = nullptr;
rg_shader_program shader;
bool use_normals = false; bool use_normals = false;
bool draw_indexed = false; bool draw_indexed = false;
GLenum draw_mode = GL_TRIANGLES;
}; };
typedef struct gl_buffer gl_buffer; bool rgInitShaderProgram(rg_shader_program& sp, const char * vertex_code, const char * frag_code);
typedef struct gl_index_buffer gl_index_buffer;
typedef struct gl_render_group gl_render_group;
bool rgInitShaderProgram(gl_render_group* rg, const char * vertex_code, const char * frag_code);
gl_buffer * rgInitGLBuffer(gl_buffer* buffer, uint buffer_len);
void rgSendBufferToGL(gl_buffer* buffer, GLenum usage, GLenum target);
bool rgInitEntity(gl_render_group* rg, Entity* e); bool rgInitEntity(Entity* e);
void rgFillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes); // TODO: fix this function to use just buffers instead of hexes
//void rgFillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes);
void rgDraw(gl_render_group* rg, GLenum draw_mode, glm::mat4 model_matrix, void rgDraw(render_group* rg, glm::mat4 model_matrix,
glm::mat4 view_matrix, glm::mat4 projection_matrix, glm::mat4 view_matrix, glm::mat4 projection_matrix,
glm::vec3 light_position, GLuint light_id, bool update_vertex_data = false); glm::vec3 light_position, GLuint light_id, bool update_vertex_data = false);
void rgFree(gl_render_group* rg); void rgFree(render_group* rg);

118
src/renderer.cpp

@ -83,16 +83,16 @@ struct camera
}; };
gl_matrix_info g_scene_matrices; // globals
gl_render_group* g_filled_hex_render_group; static gl_matrix_info g_scene_matrices;
gl_render_group* g_hex_line_render_group; static render_group g_filled_hex_render_group;
gl_render_group* g_debug_render_group; static render_group g_hex_line_render_group;
gl_render_group* g_entity_render_group; static render_group g_debug_render_group;
camera g_camera; // NOTE: entity render_group references are kept in the entity struct
static camera g_camera;
// TODO: testing lighting // TODO: testing lighting
renPointLight g_test_light; static renPointLight g_test_light;
bool bool
@ -158,6 +158,7 @@ initMatrices(projection_type p)
g_camera.position = glm::vec3(640,0,100); g_camera.position = glm::vec3(640,0,100);
g_camera.target = glm::vec3(640,500,0); g_camera.target = glm::vec3(640,500,0);
//g_camera.target = glm::vec3(0,0,0);
// inital rotation should match target direction // inital rotation should match target direction
glm::vec3 &p = g_camera.position; glm::vec3 &p = g_camera.position;
glm::vec3 &t = g_camera.target; glm::vec3 &t = g_camera.target;
@ -274,29 +275,26 @@ initRenderer(SDL_Handles &handles, v2i vpDims)
// hide VRAM debug messages // hide VRAM debug messages
glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE); glDebugMessageControl(GL_DONT_CARE, 33361, GL_DONT_CARE, 0, 0, GL_FALSE);
g_filled_hex_render_group = (gl_render_group *) std::calloc(1, sizeof(gl_render_group)); #if 0
g_hex_line_render_group = (gl_render_group *) std::calloc(1, sizeof(gl_render_group));
g_debug_render_group = (gl_render_group *) std::calloc(1, sizeof(gl_render_group));
g_entity_render_group = (gl_render_group *) std::calloc(1, sizeof(gl_render_group));
if (!g_filled_hex_render_group || !g_hex_line_render_group
|| !g_debug_render_group || !g_entity_render_group)
{
return false;
}
const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE); const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE);
const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE); const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE);
if (!rgInitShaderProgram(g_filled_hex_render_group, vs_code, fs_code) bool shader_error = (!rgInitShaderProgram(&g_filled_hex_render_group, vs_code, fs_code)
|| !rgInitShaderProgram(g_hex_line_render_group, vs_code, LINE_FRAGMENT_SHADER_CODE) || !rgInitShaderProgram(&g_hex_line_render_group, vs_code, LINE_FRAGMENT_SHADER_CODE)
|| !rgInitShaderProgram(g_debug_render_group, vs_code, DEBUG_FRAGMENT_SHADER_CODE) || !rgInitShaderProgram(&g_debug_render_group, vs_code, DEBUG_FRAGMENT_SHADER_CODE));
|| !rgInitShaderProgram(g_entity_render_group, vs_code, fs_code))
{ utilSafeFree(vs_code);
utilSafeFree(fs_code);
if (shader_error) {
LOG(ERROR) << "Error initializing shader program\n";
return false; return false;
} else {
return true;
} }
#else
return true; return true;
#endif
} }
void void
@ -370,16 +368,17 @@ fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes)
bool bool
initHexGridBuffers(std::vector<hex_info>* hexes) initHexGridBuffers(std::vector<hex_info>* hexes)
{ {
#if 0
// TODO: index duplicate vertices // TODO: index duplicate vertices
// 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54 // 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54
uint vbuf_len = hexes->size() * 6 * 3 * 3; uint vbuf_len = hexes->size() * 6 * 3 * 3;
uint line_vertices_per_hex = 6 * 2; // 12 vertices since we're using line segments atm uint line_vertices_per_hex = 6 * 2; // 12 vertices since we're using line segments atm
uint line_buf_len = hexes->size() * line_vertices_per_hex * 3; // 3 floats per vertex uint line_buf_len = hexes->size() * line_vertices_per_hex * 3; // 3 floats per vertex
gl_buffer& vbuf = * rgInitGLBuffer(&g_filled_hex_render_group->vertex_buffer, vbuf_len); gl_buffer& vbuf = * rgInitGLBuffer(&g_filled_hex_render_group.vertex_buffer, vbuf_len);
gl_buffer& cbuf = * rgInitGLBuffer(&g_filled_hex_render_group->color_buffer, vbuf_len); gl_buffer& cbuf = * rgInitGLBuffer(&g_filled_hex_render_group.color_buffer, vbuf_len);
gl_buffer& normal_buf = * rgInitGLBuffer(&g_filled_hex_render_group->normal_buffer, vbuf_len); gl_buffer& normal_buf = * rgInitGLBuffer(&g_filled_hex_render_group.normal_buffer, vbuf_len);
gl_buffer& line_buf = * rgInitGLBuffer(&g_hex_line_render_group->vertex_buffer, line_buf_len); gl_buffer& line_buf = * rgInitGLBuffer(&g_hex_line_render_group.vertex_buffer, line_buf_len);
if (!vbuf.buffer || !cbuf.buffer || !line_buf.buffer || !normal_buf.buffer) if (!vbuf.buffer || !cbuf.buffer || !line_buf.buffer || !normal_buf.buffer)
return false; return false;
@ -411,6 +410,7 @@ initHexGridBuffers(std::vector<hex_info>* hexes)
rgSendBufferToGL(&line_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); rgSendBufferToGL(&line_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
// TODO: add a color buffer to hex_line and debug render groups to re-use // TODO: add a color buffer to hex_line and debug render groups to re-use
// fragment shaders and simplify draw rgDraw() // fragment shaders and simplify draw rgDraw()
#endif
return true; return true;
} }
@ -422,30 +422,53 @@ createScene(std::vector<hex_info>* hexes, Entity* entities, uint32 entity_count)
if (!initHexGridBuffers(hexes)) if (!initHexGridBuffers(hexes))
return false; return false;
// debug draw vertexes // debug draw vertices
#if 0
rgInitGLBuffer(&g_debug_render_group->vertex_buffer, 4 * 3); // 4 vertices * 3 floats per vertex rgInitGLBuffer(&g_debug_render_group->vertex_buffer, 4 * 3); // 4 vertices * 3 floats per vertex
if (!g_debug_render_group->vertex_buffer.buffer) if (!g_debug_render_group->vertex_buffer.buffer)
return false; return false;
rgSendBufferToGL(&g_debug_render_group->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); rgSendBufferToGL(&g_debug_render_group->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
#endif
// entities // entities
// TODO: wtf, I only accounted for 1 entity in the entity render group :( // TODO: wtf, I only accounted for 1 entity in the entity render group :(
// probably need one render_group struct for each entity // probably need one render_group struct for each entity
for (uint i = 0; i < entity_count; i++) #if 1
rgInitEntity(g_entity_render_group, &entities[i]); const char* vs_code = utilDumpTextFile(DEFAULT_VERTEX_SHADER_FILE);
const char* fs_code = utilDumpTextFile(DEFAULT_FRAGMENT_SHADER_FILE);
rg_shader_program sp;
bool shader_errors = !rgInitShaderProgram(sp, vs_code, fs_code);
utilSafeFree(vs_code);
utilSafeFree(fs_code);
if (shader_errors)
return false;
for (uint i = 0; i < entity_count; i++) {
rgInitEntity(&entities[i]);
entities[i].ren_group->shader = sp;
}
#else
if (!rgInitEntity(&entities[0])) {
LOG(ERROR) << "Error initialzing entity\n";
return false;
}
#endif
// lights // lights
// TODO: load light properties from scene/level files // TODO: load light properties from scene/level files
g_test_light.light_ID = glGetUniformLocation(g_entity_render_group->program_id, "light_position"); //g_test_light.light_ID = glGetUniformLocation(g_entity_render_group.program_id, "light_position");
if (entities[0].ren_group != nullptr) {
g_test_light.light_ID = glGetUniformLocation(entities[0].ren_group->shader.program_id, "light_position");
g_test_light.position = glm::vec3(640, 500, 400); // above center of hexgrid g_test_light.position = glm::vec3(640, 500, 400); // above center of hexgrid
g_test_light.direction = glm::vec3(0, 0, 0) - g_test_light.position; // back towards test entity g_test_light.direction = glm::vec3(0, 0, 0) - g_test_light.position; // back towards test entity
g_test_light.color = glm::vec3(1.f, 1.f, 1.f); g_test_light.color = glm::vec3(1.f, 1.f, 1.f);
g_test_light.intensity = 1.f; g_test_light.intensity = 1.f;
}
return true; return true;
} }
@ -541,12 +564,13 @@ renderFrame(std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count)
glClearColor(g_clear_col.R, g_clear_col.G, g_clear_col.B, g_clear_col.A); glClearColor(g_clear_col.R, g_clear_col.G, g_clear_col.B, g_clear_col.A);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glm::mat4 m_model = g_scene_matrices.model; //glm::mat4 m_model = g_scene_matrices.model;
glm::mat4 m_view = g_scene_matrices.view; glm::mat4 m_view = g_scene_matrices.view;
glm::mat4 m_projection = g_scene_matrices.projection; glm::mat4 m_projection = g_scene_matrices.projection;
// filled hexes // filled hexes
#if 0
// get new colors every frame // get new colors every frame
gl_render_group* rg = g_filled_hex_render_group; gl_render_group* rg = g_filled_hex_render_group;
rgFillColorBuffer(rg->color_buffer.buffer, rg->color_buffer.buffer_len, hexes); rgFillColorBuffer(rg->color_buffer.buffer, rg->color_buffer.buffer_len, hexes);
@ -557,14 +581,16 @@ renderFrame(std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count)
rgDraw(g_hex_line_render_group, GL_LINES, m_model, m_view, m_projection, rgDraw(g_hex_line_render_group, GL_LINES, m_model, m_view, m_projection,
g_test_light.position, g_test_light.light_ID); g_test_light.position, g_test_light.light_ID);
#endif
// TODO: update and send array of lights (pos, dir, color, intesity to shaders
// every frame through rgDrawIndexed()
// entities // entities
for (uint i = 0; i < entity_count; i++) { for (uint i = 0; i < entity_count; i++) {
// TODO: find a way to store model xform on the meMeshGroup object
glm::mat4 model_transform = entities[i].mesh_group.meshes[0]->model_transform;
rgDraw( rgDraw(
g_entity_render_group, GL_TRIANGLES, entities[i].ren_group, model_transform, m_view, m_projection,
entities[i].mesh->model_transform, m_view, m_projection,
g_test_light.position, g_test_light.light_ID g_test_light.position, g_test_light.light_ID
); );
} }
@ -573,8 +599,9 @@ renderFrame(std::vector<hex_info> *hexes, Entity* entities, uint32 entity_count)
void void
renderDebug(std::vector<Point> &vertices) renderDebug(std::vector<Point> &vertices)
{ {
#if 0
// TODO: indexed line drawing // TODO: indexed line drawing
// copy vertexes to render group // copy vertices to render group
GLfloat* buf = g_debug_render_group->vertex_buffer.buffer; GLfloat* buf = g_debug_render_group->vertex_buffer.buffer;
buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0; buf[0] = vertices[0].x; buf[1] = vertices[0].y; buf[2] = 0;
buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0; buf[3] = vertices[1].x; buf[4] = vertices[1].y; buf[2] = 0;
@ -583,19 +610,22 @@ renderDebug(std::vector<Point> &vertices)
rgDraw(g_debug_render_group, GL_LINE_LOOP, g_scene_matrices.model, g_scene_matrices.view, rgDraw(g_debug_render_group, GL_LINE_LOOP, g_scene_matrices.model, g_scene_matrices.view,
g_scene_matrices.projection, g_test_light.position, g_test_light.light_ID, true); g_scene_matrices.projection, g_test_light.position, g_test_light.light_ID, true);
#endif
} }
void void
freeBuffers() freeBuffers()
{ {
std::vector<gl_render_group*> groups = { LOG(DEBUG) << "redo freeBuffers function after render_group update\n";
#if 0
std::vector<render_group> groups = {
g_filled_hex_render_group, g_filled_hex_render_group,
g_hex_line_render_group, g_hex_line_render_group,
g_debug_render_group, g_debug_render_group,
g_entity_render_group
}; };
for (gl_render_group* group : groups) for (render_group group : groups)
rgFree(group); rgFree(group);
#endif
} }

23
src/util.cpp

@ -7,6 +7,7 @@
#include "util.h" #include "util.h"
const uint MAX_FILESIZE = 2 * 1024 * 1024; // 2MB const uint MAX_FILESIZE = 2 * 1024 * 1024; // 2MB
const uint MAX_STRING_LENGTH = 1024;
char * char *
utilDumpTextFile(const char* filename) utilDumpTextFile(const char* filename)
@ -30,6 +31,19 @@ utilDumpTextFile(const char* filename)
return buf; return buf;
} }
void *
utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int line)
{
void* mem = std::calloc(item_count, type_size);
if (mem == nullptr) {
LOG(ERROR) << "Memory allocation failed, called from "
<< file_name << ":" << line;
}
return mem;
}
// TODO: search/replace other calls to std::free with this // TODO: search/replace other calls to std::free with this
void void
utilSafeFree(void* mem) utilSafeFree(void* mem)
@ -40,3 +54,12 @@ utilSafeFree(void* mem)
} }
} }
// TODO: re-use non-const version, macro or cast away const
void utilSafeFree(const void* mem)
{
if (mem != nullptr) {
std::free((void *) mem);
mem = nullptr;
}
}

6
src/util.h

@ -74,7 +74,11 @@ utilConvertColor(GLfloat buf[3], uint32 color)
buf[2] = (GLfloat) ((color >> 8) & 0xFF) / (GLfloat) 255; buf[2] = (GLfloat) ((color >> 8) & 0xFF) / (GLfloat) 255;
} }
char * utilDumpTextFile(const char* filename); // NOTE: Wrapper for calloc that will send error message on out of memory
void * utilLogAlloc(uint item_count, uint type_size, const char* file_name, const int line);
#define UTIL_ALLOC(len, type) (type *) utilLogAlloc((len), sizeof(type), __FILE__, __LINE__)
char * utilDumpTextFile(const char* filename);
void utilSafeFree(void* mem); void utilSafeFree(void* mem);
void utilSafeFree(const void* mem);

Loading…
Cancel
Save