From 0090575d13268767c1a15f7a085c7e57f0233a91 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Wed, 2 Jan 2019 13:19:01 -0500 Subject: [PATCH] move hex gl_buffer init from hexgrid to scene_loader --- src/hexgame.cpp | 174 ++++++++++++++++++++++++------------------- src/hexgrid.cpp | 142 +++-------------------------------- src/hexgrid.h | 6 +- src/scene_loader.cpp | 150 ++++++++++++++++++++++++++++++++++++- src/scene_loader.h | 8 +- 5 files changed, 262 insertions(+), 218 deletions(-) diff --git a/src/hexgame.cpp b/src/hexgame.cpp index 70884f7..e193225 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -73,6 +73,99 @@ static render_state* g_render_state; static vector g_polygon_select_vertices = {Point(), Point(), Point(), Point()}; +bool +loadSceneFromJson(game_state* s, render_state* rs) +{ + slSceneDoc* sd = slLoadFile(DATA_DIR, DEFAULT_SCENE_FILE, SCENE_SCHEMA_FILE); + + if (sd != nullptr) { + game_state* g = g_game_state; + render_state* rs = g_render_state; + + if (!slParseEntities(sd, g->entities, g->entity_count, MAX_ENTITIES, DATA_DIR)) { + LOG(ERROR) << "Error loading Entities, exiting\n"; + return false; + } + + slParseCamera(sd, rs->cam); + slParseHexGrid(sd, g->grid); + hgCreateHexes(g->grid); + + if (!slCreateHexRenderGroups(g->grid, rs)) + { + LOG(ERROR) << "Error creating hex render groups\n"; + return false; + } + + if (!slParseLights(sd, rs->lights, rs->num_lights, rs->max_lights)) { + LOG(ERROR) << "Error loading lights, exiting\n"; + return false; + } + + slFreeSceneDoc(sd); + } else { + return false; + } + + return true; +} + +bool +init() +{ + // init global game state + g_game_state = UTIL_ALLOC(1, game_state); + g_game_state->grid.hex_array = new vector; + g_game_state->entities = UTIL_ALLOC(MAX_ENTITIES, Entity); + + // init global render state + g_render_state = UTIL_ALLOC(1, render_state); + g_render_state->is_debug_draw = DEBUG_DRAW; + g_render_state->viewport_dims = v2i(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); + + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + LOG(ERROR) << "Error, SDL_Init: " << SDL_GetError() << "\n"; + return false; + } + + if (!renInit(g_render_state)) { + LOG(ERROR) << "Unable to initialize graphics, exiting\n"; + return false; + } + + if (!gooInit(g_render_state->handles, g_render_state->viewport_dims)) { + LOG(ERROR) << "Fooey, No Gooey!\n"; + return false; + } + + if (!meInitAssimp()) { + LOG(ERROR) << "Error initializing assimp\n"; + return false; + } + + if (!loadSceneFromJson(g_game_state, g_render_state)) { + LOG(ERROR) << "Error loading scene\n"; + return false; + } + + if (!renCreateScene(g_render_state, g_game_state->entities, g_game_state->entity_count)) + { + LOG(ERROR) << "Error in vertex data, exiting\n"; + return false; + } + +#if defined(_WIN32) + LOG(DEBUG) << "TODO: Test SDL_Delay frame timer in win32\n"; + + if (!platform_init(g_render_state->handles.window)) { + LOG(ERROR) << "Couldn't get SDL platform info, exiting\n"; + return false; + } +#endif + + return true; +} + v2i mapMouseToViewport(int32 x, int32 y) { @@ -304,86 +397,11 @@ int main(int argc, char* argv[]) #endif LOG(INFO) << "Application started\n"; - // init global game state - g_game_state = UTIL_ALLOC(1, game_state); - g_game_state->grid.hex_array = new vector; - g_game_state->entities = UTIL_ALLOC(MAX_ENTITIES, Entity); - - // init global render state - g_render_state = UTIL_ALLOC(1, render_state); - g_render_state->is_debug_draw = DEBUG_DRAW; - g_render_state->viewport_dims = v2i(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); - - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - LOG(ERROR) << "Error, SDL_Init: " << SDL_GetError() << "\n"; - return 1; - } - - if (!renInit(g_render_state)) { - LOG(ERROR) << "Unable to initialize graphics, exiting\n"; - return 1; - } - - if (!gooInit(g_render_state->handles, g_render_state->viewport_dims)) { - LOG(ERROR) << "Fooey, No Gooey!\n"; - return 1; - } - - if (!meInitAssimp()) { - LOG(ERROR) << "Error initializing assimp\n"; - return 1; - } - - // load scene from json - - slSceneDoc* sd = slLoadFile(DATA_DIR, DEFAULT_SCENE_FILE, SCENE_SCHEMA_FILE); - - if (sd != nullptr) { - game_state* g = g_game_state; - render_state* rs = g_render_state; - - if (!slParseEntities(sd, g->entities, g->entity_count, MAX_ENTITIES, DATA_DIR)) { - LOG(ERROR) << "Error loading Entities, exiting\n"; - return 1; - } - - slParseCamera(sd, rs->cam); - slParseHexGrid(sd, g->grid); - - rs->filled_hex_render_group = hgInitGLBuffers(g->grid, rs->default_shader, true); - rs->hex_line_render_group = hgInitGLBuffers(g->grid, rs->default_shader, false); - - if ((rs->filled_hex_render_group == nullptr) || (rs->hex_line_render_group == nullptr)) { - LOG(ERROR) << "Error allocating render_group, exiting\n"; - return 1; - } - - if (!slParseLights(sd, rs->lights, rs->num_lights, rs->max_lights)) { - LOG(ERROR) << "Error loading lights, exiting\n"; - return 1; - } - - slFreeSceneDoc(sd); - } else { - LOG(ERROR) << "Error loading scene, exiting\n"; - return 1; - } - - if (!renCreateScene(g_render_state, g_game_state->entities, g_game_state->entity_count)) - { - LOG(ERROR) << "Error in vertex data, exiting\n"; - return 1; + if (!init()) { + LOG(ERROR) << "failed init, exiting\n"; + return -1; } -#if defined(_WIN32) - LOG(DEBUG) << "TODO: Test SDL_Delay frame timer in win32\n"; - - if (!platform_init(g_render_state->handles.window)) { - LOG(ERROR) << "Couldn't get SDL platform info, exiting\n"; - return 1; - } -#endif - // main loop const uint TARGET_FPS = 60; diff --git a/src/hexgrid.cpp b/src/hexgrid.cpp index 2672d6f..079d641 100644 --- a/src/hexgrid.cpp +++ b/src/hexgrid.cpp @@ -1,73 +1,26 @@ #include "aixlog.hpp" -#include "render_group.h" #include "hexgrid.h" // forward declarations -void createHexagonGrid(hexgrid hg); -void populateFilledHexBuffer(gl_buffer& vertex_buf, std::vector* hex_array); -void populateLineBuffer(gl_buffer& vertex_buf, std::vector* hex_array); +bool createHexagonGrid(hexgrid hg); // interface -void +bool hgCreateHexes(hexgrid& hg) { - if (hg.gridT == HEXAGON) - createHexagonGrid(hg); -} - -render_group* -hgInitGLBuffers(hexgrid& hg, rg_shader_program program, bool is_filled_hexes) -{ - // TODO: index duplicate vertices - - render_group* rg = nullptr; - uint buf_len = 0; - - if (is_filled_hexes) { - // NOTE: 6 triangles * 3 vertices per triangle * 3 floats per vertex - buf_len = hg.hex_array->size() * 6 * 3 * 3; - rg = rgInitSingle(program, buf_len, true); + if (hg.gridT == HEXAGON) { + if (!createHexagonGrid(hg)) + return false; } else { - // NOTE: 6 lines * 2 vertices per line * 3 floats per vertex - buf_len = hg.hex_array->size() * 6 * 2 * 3; - rg = rgInitSingle(program, buf_len, true, 0, GL_LINES); + LOG(ERROR) << "Unhandled grid type\n"; + return false; } - if (rg == nullptr) - return rg; - - gl_buffer& vbuf = rg->render_objects[0]->vertex_buffer; - gl_buffer& cbuf = rg->render_objects[0]->color_buffer; - gl_buffer& normal_buf = rg->render_objects[0]->normal_buffer; - - // cheat at vertex normals since all hexes lay flat on z-axis - for (uint i = 0; i < buf_len; i += 3) { - normal_buf.buffer[i] = 0.f; - normal_buf.buffer[i + 1] = 0.f; - normal_buf.buffer[i + 2] = 1.f; - } - - if (is_filled_hexes) { - populateFilledHexBuffer(vbuf, hg.hex_array); - hgUpdateColorBuffer(cbuf, hg.hex_array); - rgBufferData(&cbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); - } else { - populateLineBuffer(vbuf, hg.hex_array); - - for (uint i = 0; i < buf_len; i++) - cbuf.buffer[i] = 0.f; - - rgBufferData(&cbuf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - } - - rgBufferData(&vbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); - rgBufferData(&normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - - return rg; + return true; } hex_info* @@ -228,12 +181,12 @@ hgUpdateColorBuffer(gl_buffer& color_buf, std::vector* hex_array) // internal -void +bool createHexagonGrid(hexgrid hg) { if (hg.hex_array == nullptr) { LOG(ERROR) << "hg.hex_array is not initialized\n"; - return; + return false; } int hr = hg.hex_radius; @@ -259,79 +212,6 @@ createHexagonGrid(hexgrid hg) hg.hex_array->push_back(hxi); } } -} - -void -populateFilledHexBuffer(gl_buffer& vertex_buf, std::vector* hex_array) -{ - GLfloat* buf = vertex_buf.buffer; - - for (uint i = 0; i < hex_array->size(); i++) { - - hex_info hex = (*hex_array)[i]; - uint idx = i * 54; // NOTE: 6 triangles * 3 vertices * 3 floats - - // triangles - for (uint j = 0; j < 6; j++) { - - // vertex 0 - buf[idx + 0] = (GLfloat) hex.XPos; - buf[idx + 1] = (GLfloat) hex.YPos; - buf[idx + 2] = (GLfloat) 0.f; - - // vertex 1 - buf[idx + 3] = (GLfloat) hex.vertices[j].x; - buf[idx + 4] = (GLfloat) hex.vertices[j].y; - buf[idx + 5] = (GLfloat) 0.f; - - if (j == 5) // re-use the first point for the last triangle - { - // vertex 2 - buf[idx + 6] = (GLfloat) hex.vertices[0].x; - buf[idx + 7] = (GLfloat) hex.vertices[0].y; - buf[idx + 8] = (GLfloat) 0.f; - } - else - { - // vertex 2 - buf[idx + 6] = (GLfloat) hex.vertices[j + 1].x; - buf[idx + 7] = (GLfloat) hex.vertices[j + 1].y; - buf[idx + 8] = (GLfloat) 0.f; - } - - idx += 9; // NOTE: 3 vertices * 3 floats; - } - } -} -void -populateLineBuffer(gl_buffer& vertex_buf, std::vector* hex_array) -{ - Point p1, p2; - int idx = 0; - for (int i = 0; i < (int) hex_array->size(); i++) - { - hex_info hxi = (*hex_array)[i]; - for (int j = 0; j < 6; j ++) - { - if (j == 5) // wrap - { - p1 = hxi.vertices[j]; - p2 = hxi.vertices[0]; - } - else - { - p1 = hxi.vertices[j]; - p2 = hxi.vertices[j + 1]; - } - - vertex_buf.buffer[idx + 0] = p1.x; - vertex_buf.buffer[idx + 1] = p1.y; - vertex_buf.buffer[idx + 2] = 0.f; - vertex_buf.buffer[idx + 3] = p2.x; - vertex_buf.buffer[idx + 4] = p2.y; - vertex_buf.buffer[idx + 5] = 0.f; - idx += 6; - } - } + return true; } diff --git a/src/hexgrid.h b/src/hexgrid.h index 63cba90..092181c 100644 --- a/src/hexgrid.h +++ b/src/hexgrid.h @@ -4,6 +4,7 @@ #include #include "hexlib.h" +#include "render_group.h" #include "util.h" @@ -58,10 +59,7 @@ struct hexgrid bool is_selecting = false; }; - -void hgCreateHexes(hexgrid& hg); - -render_group* hgInitGLBuffers(hexgrid& hg, rg_shader_program program, bool is_filled_hex); +bool hgCreateHexes(hexgrid& hg); hex_info* hgGetSingleHex(hexgrid& hg, real32 x, real32 y); diff --git a/src/scene_loader.cpp b/src/scene_loader.cpp index a943d3a..47ab5bd 100644 --- a/src/scene_loader.cpp +++ b/src/scene_loader.cpp @@ -9,10 +9,8 @@ #include "aixlog.hpp" #include "entity.h" -#include "hexgrid.h" #include "hexlib.h" #include "mesh.h" -#include "util.h" #include "scene_loader.h" @@ -29,6 +27,8 @@ glm::vec4 parseVec4(const rapidjson::Value& node); uint32 parseHex32(std::string s); bool validateScene(rapidjson::Document* schema_doc, rapidjson::Document* scene_doc, const char* scene_file); +void populateFilledHexBuffer(hexgrid& hg, render_group* rg_filled); +void populateLineBuffer(hexgrid& hg, render_group* rg_lines); // interface @@ -145,11 +145,44 @@ slParseHexGrid(slSceneDoc* sd, hexgrid& hg) if (hg.gridT == HEXAGON) { hg.hex_radius = json_grid["hex_radius"].GetInt(); } - - hgCreateHexes(hg); } +bool +slCreateHexRenderGroups(hexgrid& hg, render_state* rs) +{ + // NOTE: 6 triangles * 3 vertices per triangle * 3 floats per vertex + uint buf_len = hg.hex_array->size() * 6 * 3 * 3; + rs->filled_hex_render_group = rgInitSingle(rs->default_shader, buf_len, true); + + // NOTE: 6 lines * 2 vertices per line * 3 floats per vertex + buf_len = hg.hex_array->size() * 6 * 2 * 3; + rs->hex_line_render_group = rgInitSingle(rs->default_shader, buf_len, true, 0, GL_LINES); + + render_group* rg_filled = rs->filled_hex_render_group; + render_group* rg_lines = rs->hex_line_render_group; + + if ((rg_filled == nullptr) || (rg_lines == nullptr)) { + LOG(ERROR) << "Error allocating render_group, exiting\n"; + return false; + } + + populateFilledHexBuffer(hg, rg_filled); + populateLineBuffer(hg, rg_lines); + + render_object* ro = rg_filled->render_objects[0]; + rgBufferData(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); + rgBufferData(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER); + rgBufferData(&ro->color_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); + + ro = rg_lines->render_objects[0]; + rgBufferData(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); + rgBufferData(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER); + rgBufferData(&ro->color_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); + + return true; +} + bool slParseLights(slSceneDoc* sd, rg_point_light* lights, uint& num_lights, uint max_lights) { @@ -243,3 +276,112 @@ parseVec4(const rapidjson::Value& node) return v4; } + +void +populateFilledHexBuffer(hexgrid& hg, render_group* rg_filled) +{ + render_object* ro = rg_filled->render_objects[0]; + gl_buffer& vbuf = ro->vertex_buffer; + gl_buffer& cbuf = ro->color_buffer; + gl_buffer& normal_buf = ro->normal_buffer; + + assert((hg.hex_array->size() * 6 * 3 * 3) == vbuf.buffer_len); + + hgUpdateColorBuffer(cbuf, hg.hex_array); + + // cheat at vertex normals since all hexes lay flat on z-axis + for (uint i = 0; i < normal_buf.buffer_len; i += 3) { + normal_buf.buffer[i] = 0.f; + normal_buf.buffer[i + 1] = 0.f; + normal_buf.buffer[i + 2] = 1.f; + } + + GLfloat* buf = vbuf.buffer; + + for (uint i = 0; i < hg.hex_array->size(); i++) { + + hex_info hex = (*hg.hex_array)[i]; + uint idx = i * 54; // NOTE: 6 triangles * 3 vertices * 3 floats + + // triangles + for (uint j = 0; j < 6; j++) { + + // vertex 0 + buf[idx + 0] = (GLfloat) hex.XPos; + buf[idx + 1] = (GLfloat) hex.YPos; + buf[idx + 2] = (GLfloat) 0.f; + + // vertex 1 + buf[idx + 3] = (GLfloat) hex.vertices[j].x; + buf[idx + 4] = (GLfloat) hex.vertices[j].y; + buf[idx + 5] = (GLfloat) 0.f; + + if (j == 5) // re-use the first point for the last triangle + { + // vertex 2 + buf[idx + 6] = (GLfloat) hex.vertices[0].x; + buf[idx + 7] = (GLfloat) hex.vertices[0].y; + buf[idx + 8] = (GLfloat) 0.f; + } + else + { + // vertex 2 + buf[idx + 6] = (GLfloat) hex.vertices[j + 1].x; + buf[idx + 7] = (GLfloat) hex.vertices[j + 1].y; + buf[idx + 8] = (GLfloat) 0.f; + } + + idx += 9; // NOTE: 3 vertices * 3 floats; + } + } +} + +void +populateLineBuffer(hexgrid& hg, render_group* rg_lines) +{ + render_object* ro = rg_lines->render_objects[0]; + gl_buffer& vbuf = ro->vertex_buffer; + gl_buffer& cbuf = ro->color_buffer; + gl_buffer& normal_buf = ro->normal_buffer; + + assert((hg.hex_array->size() * 6 * 2 * 3) == vbuf.buffer_len); + + // fill line color buffer with black + for (uint i = 0; i < cbuf.buffer_len; i++) + cbuf.buffer[i] = 0.f; + + // cheat at vertex normals since all hexes lay flat on z-axis + for (uint i = 0; i < normal_buf.buffer_len; i += 3) { + normal_buf.buffer[i] = 0.f; + normal_buf.buffer[i + 1] = 0.f; + normal_buf.buffer[i + 2] = 1.f; + } + + Point p1, p2; + int idx = 0; + for (int i = 0; i < (int) hg.hex_array->size(); i++) + { + hex_info hxi = (*hg.hex_array)[i]; + for (int j = 0; j < 6; j ++) + { + if (j == 5) // wrap + { + p1 = hxi.vertices[j]; + p2 = hxi.vertices[0]; + } + else + { + p1 = hxi.vertices[j]; + p2 = hxi.vertices[j + 1]; + } + + vbuf.buffer[idx + 0] = p1.x; + vbuf.buffer[idx + 1] = p1.y; + vbuf.buffer[idx + 2] = 0.f; + vbuf.buffer[idx + 3] = p2.x; + vbuf.buffer[idx + 4] = p2.y; + vbuf.buffer[idx + 5] = 0.f; + idx += 6; + } + } +} diff --git a/src/scene_loader.h b/src/scene_loader.h index f66ca05..0f3bbf5 100644 --- a/src/scene_loader.h +++ b/src/scene_loader.h @@ -3,13 +3,15 @@ #include "camera.h" #include "hexgrid.h" -#include "render_group.h" // rg_point_light +#include "renderer.h" +#include "render_group.h" #include "util.h" struct slSceneDoc; slSceneDoc* slLoadFile(const char* data_dir, const char* scene_file, const char* schema_file); + void slFreeSceneDoc(slSceneDoc* sd); bool slParseEntities( @@ -21,5 +23,9 @@ bool slParseEntities( ); void slParseCamera(slSceneDoc* sd, camera& cam); + void slParseHexGrid(slSceneDoc* sd, hexgrid& hg); + +bool slCreateHexRenderGroups(hexgrid& hg, render_state* rs); + bool slParseLights(slSceneDoc* sd, rg_point_light* lights, uint& num_lights, uint max_lights);