From 9cdb2043cc614a8c3631a616b4b18cb006e4a27c Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Sun, 16 Dec 2018 06:07:54 -0500 Subject: [PATCH] move hexgrid buffer functions from renderer to hexgrid --- src/hexgame.cpp | 10 +++ src/hexgrid.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++- src/hexgrid.h | 4 +- src/renderer.cpp | 165 +---------------------------------------------- src/renderer.h | 3 +- 5 files changed, 168 insertions(+), 167 deletions(-) diff --git a/src/hexgame.cpp b/src/hexgame.cpp index b4085b2..1cc3834 100644 --- a/src/hexgame.cpp +++ b/src/hexgame.cpp @@ -2,8 +2,10 @@ * TODO: * - renderer * - move hexgrid buffer functions from renderer to hexgrid + * - remove references to hexes from renderer functions * - move hex functions from hexgame.cpp to hexgrid * - add prefix to interface function names for eg) gooey.h, renderer.h + * - clean up main(), split out initialization and scene loading to new functions * - check over renderer, camera, gooey init after changes * - pass in frame time to camera movement functions to decouple speed from framerate * - attempt to fix bug with starting camera xform @@ -541,6 +543,14 @@ int main(int argc, char* argv[]) 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; diff --git a/src/hexgrid.cpp b/src/hexgrid.cpp index e612884..c225c92 100644 --- a/src/hexgrid.cpp +++ b/src/hexgrid.cpp @@ -1,21 +1,75 @@ #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); // interface void -hgCreateHexes(hexgrid hg) +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); + } 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); + } + + 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; +} + hex_info* hgGetSingleHex(int32 x, int32 y) { @@ -28,6 +82,28 @@ hgResetHexes() } +void +hgUpdateColorBuffer(gl_buffer& color_buf, std::vector* hex_array) +{ + uint buf_idx = 0; + uint buf_len_per_hex = 54; // NOTE: 6 triangles * 3 vertices * 3 floats + GLfloat color[3]; + + for (uint i = 0; i < hex_array->size(); i++) { + buf_idx = i * buf_len_per_hex; + hex_info hxi = (*hex_array)[i]; + + // TODO: check performance of this since we call multiple times per frame + // maybe can cache glfloat triplets somewhere + utilConvertColor(color, hxi.current_color); + + for (uint j = 0; j < buf_len_per_hex; j += 3) { + color_buf.buffer[buf_idx + j] = color[0]; + color_buf.buffer[buf_idx + j + 1] = color[1]; + color_buf.buffer[buf_idx + j + 2] = color[2]; + } + } +} // internal @@ -63,3 +139,78 @@ createHexagonGrid(hexgrid hg) } } } + +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; + } + } +} diff --git a/src/hexgrid.h b/src/hexgrid.h index 82803ee..29e77e3 100644 --- a/src/hexgrid.h +++ b/src/hexgrid.h @@ -58,6 +58,8 @@ struct hexgrid }; -void hgCreateHexes(hexgrid hg); +void hgCreateHexes(hexgrid& hg); +render_group* hgInitGLBuffers(hexgrid& hg, rg_shader_program program, bool is_filled_hex); hex_info* hgGetSingleHex(int32 x, int32 y); void hgResetHexes(); +void hgUpdateColorBuffer(gl_buffer& color_buf, std::vector* hex_array); diff --git a/src/renderer.cpp b/src/renderer.cpp index 9fb5f26..4b4c682 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -35,14 +35,8 @@ clear_col g_clear_col { 75.f / 255.f, 135.f / 255.f, 135.f / 255.f, 1.f }; // forward declarations -void initMatrices(projection_type p); void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); -// TODO: move hex logic to new file -bool initHexGridBuffers(render_state* rs, std::vector* hexes); -void fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex); -void fillColorBuffer(GLfloat buf[], int len, std::vector* hexes); -void fillHexLineBuffer(GLfloat buf[], int len, std::vector* hexes); // interface @@ -172,9 +166,6 @@ createScene(render_state* rs, std::vector* hexes, Entity* entities, ui entities[i].ren_group->shader = rs->default_shader; } - if (!initHexGridBuffers(rs, hexes)) - return false; - // debug draw vertices uint debug_buf_len = 12; // 4 vertices, 3 floats per vertex @@ -220,7 +211,7 @@ renderFrame(render_state* rs, std::vector *hexes, Entity* entities, ui render_group* rg = rs->filled_hex_render_group; gl_buffer& color_buf = rg->render_objects[0]->color_buffer; // TODO: this needs optimization for large grids, very performance intensive - fillColorBuffer(color_buf.buffer, color_buf.buffer_len, hexes); + hgUpdateColorBuffer(color_buf, hexes); rgDraw(rg, m_model, m_view, m_projection, rs->lights, rs->num_lights, false, true); @@ -262,157 +253,3 @@ openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, << ", message: " << message << "\n"; } -// TODO: move hex logic to new file -bool -initHexGridBuffers(render_state* rs, std::vector* hexes) -{ - // TODO: index duplicate vertices - // 6 triangles * 3 vertices per triangle * 3 floats per vertex = 54 - 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 vbuf_len = hexes->size() * 6 * 3 * 3; - - rs->filled_hex_render_group = rgInitSingle(rs->default_shader, vbuf_len, true); - - if (rs->filled_hex_render_group == nullptr) - return false; - - gl_buffer& vbuf = rs->filled_hex_render_group->render_objects[0]->vertex_buffer; - gl_buffer& cbuf = rs->filled_hex_render_group->render_objects[0]->color_buffer; - gl_buffer& normal_buf = rs->filled_hex_render_group->render_objects[0]->normal_buffer; - - for (uint i = 0; i < hexes->size(); i++) - fillTriangleBufferFromHex(vbuf.buffer, i * 54, (*hexes)[i]); - - rgBufferData(&vbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); - fillColorBuffer(cbuf.buffer, vbuf_len, hexes); - rgBufferData(&cbuf, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); - - // cheat at vertex normals since all hexes lay flat on z-axis - - for (uint i = 0; i < vbuf_len; i += 3) { - normal_buf.buffer[i] = 0.f; - normal_buf.buffer[i + 1] = 0.f; - normal_buf.buffer[i + 2] = 1.f; - } - rgBufferData(&normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - - // hex lines - - rs->hex_line_render_group = rgInitSingle(rs->default_shader, line_buf_len, true, 0, GL_LINES); - - if (rs->hex_line_render_group == nullptr) - return false; - - gl_buffer& line_buf = rs->hex_line_render_group->render_objects[0]->vertex_buffer; - gl_buffer& line_color_buf = rs->hex_line_render_group->render_objects[0]->color_buffer; - gl_buffer& line_normal_buf = rs->hex_line_render_group->render_objects[0]->normal_buffer; - fillHexLineBuffer(line_buf.buffer, line_buf_len, hexes); - rgBufferData(&line_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - - for (uint i = 0; i < line_buf_len; i++) - line_color_buf.buffer[i] = 0.f; - - rgBufferData(&line_color_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - - for (uint i = 0; i < line_buf_len; i += 3) { - line_normal_buf.buffer[i] = 0.f; - line_normal_buf.buffer[i + 1] = 0.f; - line_normal_buf.buffer[i + 2] = 1.f; - } - - rgBufferData(&line_normal_buf, GL_STATIC_DRAW, GL_ARRAY_BUFFER); - - return true; -} - -void -fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex) -{ - // triangles - for (int i = 0; i < 6; i++) - { - // 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[i].x; - buf[idx + 4] = (GLfloat) hex.vertices[i].y; - buf[idx + 5] = (GLfloat) 0.f; - - if (i == 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[i + 1].x; - buf[idx + 7] = (GLfloat) hex.vertices[i + 1].y; - buf[idx + 8] = (GLfloat) 0.f; - } - - // we've added 9 GLfloats per loop - idx += 9; - } -} - -void -fillColorBuffer(GLfloat buf[], int len, std::vector* 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]; - // TODO: check performance of this since we call multiple times per frame - // maybe can cache glfloat triplets somewhere - 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]; - } - } -} - -void -fillHexLineBuffer(GLfloat buf[], int len, std::vector* hexes) -{ - Point p1, p2; - int idx = 0; - for (int i = 0; i < (int) hexes->size(); i++) - { - hex_info hxi = (*hexes)[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]; - } - - buf[idx + 0] = p1.x; - buf[idx + 1] = p1.y; - buf[idx + 2] = 0.f; - buf[idx + 3] = p2.x; - buf[idx + 4] = p2.y; - buf[idx + 5] = 0.f; - idx += 6; - } - } -} diff --git a/src/renderer.h b/src/renderer.h index 924bb35..20bbf71 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -36,6 +36,7 @@ struct render_state render_group* filled_hex_render_group; render_group* hex_line_render_group; render_group* debug_render_group; + // NOTE: entity render groups are stored on the entity object rg_shader_program default_shader; rg_point_light* lights = nullptr; @@ -47,6 +48,6 @@ bool initRenderer(render_state* rs); void freeBuffers(render_state* rs); bool addTexture(SDL_Handles &handles, const char * path); bool createScene(render_state* rs, std::vector* hexes, Entity* entities, uint32 entity_count); -void renderFrame(render_state* rs, std::vector *hexes, Entity* entities, uint32 entity_count); +void renderFrame(render_state* rs, std::vector* hexes, Entity* entities, uint32 entity_count); void renderDebug(render_state* rs, std::vector &vertices);