From 127acd9e21b29dd05dc8e09e122a2f7edd1710e3 Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Mon, 14 Jan 2019 00:49:03 -0500 Subject: [PATCH] stashing changes for hex add/remove --- TODO.md | 3 ++ src/hexgame.cpp | 2 +- src/hexgrid.cpp | 102 +++++++++++++++++++++++++++++++++++++++++-- src/hexgrid.h | 5 ++- src/render_group.cpp | 20 ++++----- src/render_group.h | 28 ++++++------ src/renderer.cpp | 2 +- src/scene_loader.cpp | 36 ++++++++++----- 8 files changed, 157 insertions(+), 41 deletions(-) diff --git a/TODO.md b/TODO.md index 1ee6ed1..2d4bdcb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,8 @@ ## TODO: +- move populateHex functions from scene_loader to hexgrid and refactor + - consider that the hexgrid hash map needs to grow and shrink + - hexgrid render_group buffers need to be updated when size changes - better (flat) level mesh for testing grid position - make hashmap grid type - in-game editor for adding removing hexes to line up with terrain/indoor meshes diff --git a/src/hexgame.cpp b/src/hexgame.cpp index 0fa9111..7fd8010 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -195,7 +195,7 @@ handleMouseDown(SDL_MouseButtonEvent &e) v3f ray = cameraCreateRay(rs->cam, coords, dims); v3f xsect; if (cameraIntersectPlane(rs->cam, ray, gs->grid.position, gs->grid.normal, xsect)) - hgAddHex(gs->grid, xsect); + hgAddHex(gs->grid, xsect, rs->filled_hex_render_group, rs->hex_line_render_group); break; } case NONE: diff --git a/src/hexgrid.cpp b/src/hexgrid.cpp index 3e3c132..8bd7e51 100644 --- a/src/hexgrid.cpp +++ b/src/hexgrid.cpp @@ -7,6 +7,8 @@ // forward declarations hex_info createHexInfo(hexgrid& hg, int q, int r); void createHexagonGrid(hexgrid& hg); +bool incrementGLBufferCount(render_group* rg, uint len); +void insertHexVertexData(render_group* rg_filled, render_group* rg_lines, hex_info& hxi); // interface @@ -27,19 +29,31 @@ hgCreateHexes(hexgrid& hg) // TODO: testing add/remove hex interface bool -hgAddHex(hexgrid& hg, v3f hex_coords) +hgAddHex(hexgrid& hg, v3f hex_coords, render_group* rg_filled, render_group* rg_lines) { hex_info* hxi = hgGetSingleHex(hg, hex_coords.x, hex_coords.y); if (hxi) { hxi->selected = true; + return false; } else { Hex h = hex_round(pixel_to_hex(hg.hexlib_layout, Point(hex_coords.x, hex_coords.y))); hex_info new_hex = createHexInfo(hg, h.q, h.r); // TODO: need to reseize the GL buffers for filled hexes & hex lines here - //hg.hex_map.insert({h, new_hex}); - } - return false; + uint filled_increment = 54; + uint lines_increment = 36; + + if (incrementGLBufferCount(rg_filled, filled_increment) && + incrementGLBufferCount(rg_lines, lines_increment)) + { + insertHexVertexData(rg_filled, rg_lines, new_hex); + hg.hex_map.insert({h, new_hex}); + return true; + } else { + LOG(ERROR) << "Attempting to add hex failed\n"; + return false; + } + } } bool @@ -223,3 +237,83 @@ createHexagonGrid(hexgrid& hg) } } } + +bool +incrementGLBufferCount(render_group* rg, uint len) +{ + render_object* ro = rg->render_objects[0]; + gl_buffer& vb = ro->vertex_buffer; + gl_buffer& nb = ro->normal_buffer; + gl_buffer& ub = ro->uv_buffer; + + if (vb.count + len <= vb.max_count && + nb.count + len <= nb.max_count && + ub.count + len <= ub.max_count) + { + vb.count += len; + nb.count += len; + ub.count += len; + + return true; + } else { + return false; + } +} + +void +insertHexVertexData(render_group* rg_filled, render_group* rg_lines, hex_info& hxi) +{ + gl_buffer& filled_vbuf = rg_filled->render_objects[0]->vertex_buffer; + gl_buffer& lines_vbuf = rg_lines->render_objects[0]->vertex_buffer; + uint filled_verts_per_hex = 54; + uint line_verts_per_hex = 36; + uint i_filled = hxi.hexID * filled_verts_per_hex; + uint i_lines = hxi.hexID * line_verts_per_hex; + + assert(filled_vbuf.max_count >= i_filled + filled_verts_per_hex && + lines_vbuf.max_count >= i_lines + line_verts_per_hex); + + // copy/pasted from scene_loader + // TODO: move scene_loader hex stuff to this file and refactor + GLfloat* fb = filled_vbuf.buffer; + uint idx = i_filled; + + // triangles + for (uint j = 0; j < 6; j++) { + // vertex 0 + fb[idx + 0] = (GLfloat) hxi.XPos; + fb[idx + 1] = (GLfloat) hxi.YPos; + fb[idx + 2] = (GLfloat) 0.f; + + // vertex 1 + fb[idx + 3] = (GLfloat) hxi.vertices[j].x; + fb[idx + 4] = (GLfloat) hxi.vertices[j].y; + fb[idx + 5] = (GLfloat) 0.f; + + if (j == 5) { // re-use the first point for the last triangle + // vertex 2 + fb[idx + 6] = (GLfloat) hxi.vertices[0].x; + fb[idx + 7] = (GLfloat) hxi.vertices[0].y; + fb[idx + 8] = (GLfloat) 0.f; + } else { + // vertex 2 + fb[idx + 6] = (GLfloat) hxi.vertices[j + 1].x; + fb[idx + 7] = (GLfloat) hxi.vertices[j + 1].y; + fb[idx + 8] = (GLfloat) 0.f; + } + + idx += 9; // NOTE: 3 vertices * 3 floats; + } + glBindBuffer(GL_ARRAY_BUFFER, filled_vbuf.buffer_id); + // TODO: we don't actually have to upload the whole buffer w/ buffersubdata + glBufferSubData(GL_ARRAY_BUFFER, 0, filled_vbuf.count * sizeof(GLfloat), filled_vbuf.buffer); + + gl_buffer& normal_buf = rg_filled->render_objects[0]->normal_buffer; + for (uint i = 0; i < filled_verts_per_hex; i+=3) { + normal_buf.buffer[i_filled + i + 0] = 0.f; + normal_buf.buffer[i_filled + i + 1] = 0.f; + normal_buf.buffer[i_filled + i + 2] = 1.f; + } + glBindBuffer(GL_ARRAY_BUFFER, normal_buf.buffer_id); + glBufferSubData(GL_ARRAY_BUFFER, 0, normal_buf.count * sizeof(GLfloat), normal_buf.buffer); +} diff --git a/src/hexgrid.h b/src/hexgrid.h index 3100bcd..c5c15a1 100644 --- a/src/hexgrid.h +++ b/src/hexgrid.h @@ -8,6 +8,9 @@ #include "render_group.h" #include "util.h" +// NOTE: padding some extra space for hex buffers to grow +#define MAX_HEX_COUNT 8192 + // TODO: rename to "hex_draw_mode" to fit project style enum HexDrawMode @@ -77,7 +80,7 @@ bool hgCreateHexes(hexgrid& hg); // TODO: testing add/remove hex interface -bool hgAddHex(hexgrid& hg, v3f hex_coords); +bool hgAddHex(hexgrid& hg, v3f hex_coords, render_group* rg_filled, render_group* rg_lines); bool hgRemoveHex(hexgrid& hg, v3i hex_coords); diff --git a/src/render_group.cpp b/src/render_group.cpp index 2edc3a6..b97d66a 100644 --- a/src/render_group.cpp +++ b/src/render_group.cpp @@ -171,7 +171,7 @@ rgBufferData(gl_buffer* buffer, GLenum usage, GLenum target) { glGenBuffers(1, &buffer->buffer_id); glBindBuffer(target, buffer->buffer_id); - glBufferData(target, buffer->buffer_len * sizeof(GLfloat), buffer->buffer, usage); + glBufferData(target, buffer->max_count * sizeof(GLfloat), buffer->buffer, usage); } void @@ -195,7 +195,7 @@ rgDraw(render_group* rg, glm::mat4 model_matrix, if (update_vertex_data) { - glBufferSubData(GL_ARRAY_BUFFER, 0, ro->vertex_buffer.buffer_len * sizeof(GLfloat), + glBufferSubData(GL_ARRAY_BUFFER, 0, ro->vertex_buffer.count * sizeof(GLfloat), ro->vertex_buffer.buffer); } @@ -232,7 +232,7 @@ rgDraw(render_group* rg, glm::mat4 model_matrix, glUniform1i(rg->shader.sampler_id, 0); if (update_color_data) { - glBufferSubData(GL_ARRAY_BUFFER, 0, ro->uv_buffer.buffer_len * sizeof(GLfloat), + glBufferSubData(GL_ARRAY_BUFFER, 0, ro->uv_buffer.count * sizeof(GLfloat), ro->uv_buffer.buffer); } } @@ -240,9 +240,9 @@ rgDraw(render_group* rg, glm::mat4 model_matrix, // draw if (rg->draw_indexed) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ro->index_buffer.buffer_id); - glDrawElements(rg->draw_mode, ro->index_buffer.buffer_len, GL_UNSIGNED_INT, 0); + glDrawElements(rg->draw_mode, ro->index_buffer.count, GL_UNSIGNED_INT, 0); } else { - glDrawArrays(rg->draw_mode, 0, ro->vertex_buffer.buffer_len / 3); + glDrawArrays(rg->draw_mode, 0, ro->vertex_buffer.count / 3); } // cleanup @@ -283,15 +283,15 @@ allocateRenderObject(uint buffer_len, uint index_len) return nullptr; ro->vertex_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat); - ro->vertex_buffer.buffer_len = buffer_len; + ro->vertex_buffer.count = ro->vertex_buffer.max_count = buffer_len; ro->normal_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat); - ro->normal_buffer.buffer_len = buffer_len; + ro->normal_buffer.count = ro->normal_buffer.max_count = buffer_len; ro->uv_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat); - ro->uv_buffer.buffer_len = buffer_len; + ro->uv_buffer.count = ro->uv_buffer.max_count = buffer_len; if (index_len > 0) { ro->index_buffer.buffer = UTIL_ALLOC(index_len, uint); - ro->index_buffer.buffer_len = index_len; + ro->index_buffer.count = index_len; } if (ro->vertex_buffer.buffer == nullptr || @@ -391,7 +391,7 @@ sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target) { glGenBuffers(1, &index_buffer->buffer_id); glBindBuffer(target, index_buffer->buffer_id); - glBufferData(target, index_buffer->buffer_len * sizeof(uint), index_buffer->buffer, usage); + glBufferData(target, index_buffer->count * sizeof(uint), index_buffer->buffer, usage); } diff --git a/src/render_group.h b/src/render_group.h index 713b4aa..c0e406c 100644 --- a/src/render_group.h +++ b/src/render_group.h @@ -13,17 +13,30 @@ struct Entity; struct gl_buffer { GLuint buffer_id; - size_t buffer_len; // NOTE: number of elements in buffer + uint count; // NOTE: number of elements in buffer + uint max_count; // NOTE: maxium number of elements buffer can fit GLfloat* buffer; }; struct gl_index_buffer { GLuint buffer_id; - size_t buffer_len; + uint count; // NOTE: number of elements in buffer + uint max_count; // NOTE: maxium number of elements buffer can fit uint* buffer; }; +struct render_object +{ + bool use_texture; + GLuint tex_id; + + gl_buffer vertex_buffer; + gl_buffer normal_buffer; + gl_buffer uv_buffer; + gl_index_buffer index_buffer; +}; + struct rg_shader_program { GLuint program_id; @@ -38,17 +51,6 @@ struct rg_shader_program GLuint num_lights_id; }; -struct render_object -{ - bool use_texture; - GLuint tex_id; - - gl_buffer vertex_buffer; - gl_buffer normal_buffer; - gl_buffer uv_buffer; - gl_index_buffer index_buffer; -}; - struct render_group { uint num_objects; diff --git a/src/renderer.cpp b/src/renderer.cpp index 4f137fd..0d6c6f1 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -186,7 +186,7 @@ renRenderFrame(render_state* rs, hexgrid& hg, Entity* entities, uint32 entity_co // get new colors every frame render_group* rg = rs->filled_hex_render_group; gl_buffer& uv_buf = rg->render_objects[0]->uv_buffer; - hgUpdateUVBuffer(hg, uv_buf.buffer, uv_buf.buffer_len); + hgUpdateUVBuffer(hg, uv_buf.buffer, uv_buf.count); rgDraw(rg, m_model, m_view, m_projection, rs->lights, rs->num_lights, false, true); diff --git a/src/scene_loader.cpp b/src/scene_loader.cpp index 4e9f39f..a83efe5 100644 --- a/src/scene_loader.cpp +++ b/src/scene_loader.cpp @@ -24,11 +24,11 @@ struct slSceneDoc bool parseFile(rapidjson::Document* doc, const char* data_dir, const char* file_name); glm::vec3 parseVec3(const rapidjson::Value& node); 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 populateFilledHexGLBuffers(hexgrid& hg, render_group* rg_filled); void populateLineGLBuffers(hexgrid& hg, render_group* rg_lines); +void setHexBufferCount(render_object* ro, uint count); // interface @@ -150,16 +150,19 @@ slParseHexGrid(slSceneDoc* sd, hexgrid& hg, util_image& palette_image) bool slCreateHexRenderGroups(hexgrid& hg, render_state* rs) { + assert(hg.hex_map.size() < MAX_HEX_COUNT); + // NOTE: 6 triangles * 3 vertices per triangle * 3 floats per vertex - uint buf_len = hg.hex_map.size() * 6 * 3 * 3; + uint buf_len = MAX_HEX_COUNT * 6 * 3 * 3; rs->filled_hex_render_group = rgInitSingle(rs->default_shader, buf_len, true); + render_group* rg_filled = rs->filled_hex_render_group; + setHexBufferCount(rg_filled->render_objects[0], hg.hex_map.size() * 54); // NOTE: 6 lines * 2 vertices per line * 3 floats per vertex - buf_len = hg.hex_map.size() * 6 * 2 * 3; + buf_len = MAX_HEX_COUNT * 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; + setHexBufferCount(rg_lines->render_objects[0], hg.hex_map.size() * 36); if ((rg_filled == nullptr) || (rg_lines == nullptr)) { LOG(ERROR) << "Error allocating render_group, exiting\n"; @@ -292,13 +295,13 @@ populateFilledHexGLBuffers(hexgrid& hg, render_group* rg_filled) gl_buffer& normal_buf = ro->normal_buffer; gl_buffer& uv_buf = ro->uv_buffer; - assert((hg.hex_map.size() * 6 * 3 * 3) == vbuf.buffer_len); + assert((hg.hex_map.size() * 6 * 3 * 3) == vbuf.count); // fill uv_buffer with palette texture coords - hgUpdateUVBuffer(hg, uv_buf.buffer, uv_buf.buffer_len); + hgUpdateUVBuffer(hg, uv_buf.buffer, uv_buf.count); // cheat at vertex normals since all hexes lay flat on z-axis - for (uint i = 0; i < normal_buf.buffer_len; i += 3) { + for (uint i = 0; i < normal_buf.count; i += 3) { normal_buf.buffer[i] = 0.f; normal_buf.buffer[i + 1] = 0.f; normal_buf.buffer[i + 2] = 1.f; @@ -349,17 +352,17 @@ populateLineGLBuffers(hexgrid& hg, render_group* rg_lines) gl_buffer& normal_buf = ro->normal_buffer; gl_buffer& uv_buf = ro->uv_buffer; - assert((hg.hex_map.size() * 6 * 2 * 3) == vbuf.buffer_len); + assert((hg.hex_map.size() * 6 * 2 * 3) == vbuf.count); // cheat at vertex normals since all hexes lay flat on z-axis - for (uint i = 0; i < normal_buf.buffer_len; i += 3) { + for (uint i = 0; i < normal_buf.count; i += 3) { normal_buf.buffer[i] = 0.f; normal_buf.buffer[i + 1] = 0.f; normal_buf.buffer[i + 2] = 1.f; } // fill uv_buffer with palette texture coords - for (uint i = 0; i < uv_buf.buffer_len; i += 3) { + for (uint i = 0; i < uv_buf.count; i += 3) { uv_buf.buffer[i + 0] = hg.line_color_uv.x; uv_buf.buffer[i + 1] = hg.line_color_uv.y; uv_buf.buffer[i + 2] = 0; @@ -391,3 +394,14 @@ populateLineGLBuffers(hexgrid& hg, render_group* rg_lines) } } } + +void +setHexBufferCount(render_object* ro, uint count) +{ + assert(ro != nullptr); + + // NOTE: hexgrid buffers aren't indexed + ro->vertex_buffer.count = count; + ro->normal_buffer.count = count; + ro->uv_buffer.count = count; +}