Browse Source

move hexgrid buffer functions from renderer to hexgrid

master
cinnaboot 8 years ago
parent
commit
9cdb2043cc
  1. 10
      src/hexgame.cpp
  2. 153
      src/hexgrid.cpp
  3. 4
      src/hexgrid.h
  4. 165
      src/renderer.cpp
  5. 1
      src/renderer.h

10
src/hexgame.cpp

@ -2,8 +2,10 @@
* TODO: * TODO:
* - renderer * - renderer
* - move hexgrid buffer functions from renderer to hexgrid * - move hexgrid buffer functions from renderer to hexgrid
* - remove references to hexes from renderer functions
* - move hex functions from hexgame.cpp to hexgrid * - move hex functions from hexgame.cpp to hexgrid
* - add prefix to interface function names for eg) gooey.h, renderer.h * - 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 * - check over renderer, camera, gooey init after changes
* - pass in frame time to camera movement functions to decouple speed from framerate * - pass in frame time to camera movement functions to decouple speed from framerate
* - attempt to fix bug with starting camera xform * - attempt to fix bug with starting camera xform
@ -541,6 +543,14 @@ int main(int argc, char* argv[])
slParseCamera(sd, rs->cam); slParseCamera(sd, rs->cam);
slParseHexGrid(sd, g->grid); 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)) { if (!slParseLights(sd, rs->lights, rs->num_lights, rs->max_lights)) {
LOG(ERROR) << "Error loading lights, exiting\n"; LOG(ERROR) << "Error loading lights, exiting\n";
return 1; return 1;

153
src/hexgrid.cpp

@ -1,21 +1,75 @@
#include "aixlog.hpp" #include "aixlog.hpp"
#include "render_group.h"
#include "hexgrid.h" #include "hexgrid.h"
// forward declarations // forward declarations
void createHexagonGrid(hexgrid hg); void createHexagonGrid(hexgrid hg);
void populateFilledHexBuffer(gl_buffer& vertex_buf, std::vector<hex_info>* hex_array);
void populateLineBuffer(gl_buffer& vertex_buf, std::vector<hex_info>* hex_array);
// interface // interface
void void
hgCreateHexes(hexgrid hg) hgCreateHexes(hexgrid& hg)
{ {
if (hg.gridT == HEXAGON) if (hg.gridT == HEXAGON)
createHexagonGrid(hg); 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* hex_info*
hgGetSingleHex(int32 x, int32 y) hgGetSingleHex(int32 x, int32 y)
{ {
@ -28,6 +82,28 @@ hgResetHexes()
} }
void
hgUpdateColorBuffer(gl_buffer& color_buf, std::vector<hex_info>* 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 // internal
@ -63,3 +139,78 @@ createHexagonGrid(hexgrid hg)
} }
} }
} }
void
populateFilledHexBuffer(gl_buffer& vertex_buf, std::vector<hex_info>* 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_info>* 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;
}
}
}

4
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); hex_info* hgGetSingleHex(int32 x, int32 y);
void hgResetHexes(); void hgResetHexes();
void hgUpdateColorBuffer(gl_buffer& color_buf, std::vector<hex_info>* hex_array);

165
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 // forward declarations
void initMatrices(projection_type p);
void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, void openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const void* userParam); GLsizei length, const GLchar* message, const void* userParam);
// TODO: move hex logic to new file
bool initHexGridBuffers(render_state* rs, std::vector<hex_info>* hexes);
void fillTriangleBufferFromHex(GLfloat buf[], int idx, const hex_info &hex);
void fillColorBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes);
void fillHexLineBuffer(GLfloat buf[], int len, std::vector<hex_info>* hexes);
// interface // interface
@ -172,9 +166,6 @@ createScene(render_state* rs, std::vector<hex_info>* hexes, Entity* entities, ui
entities[i].ren_group->shader = rs->default_shader; entities[i].ren_group->shader = rs->default_shader;
} }
if (!initHexGridBuffers(rs, hexes))
return false;
// debug draw vertices // debug draw vertices
uint debug_buf_len = 12; // 4 vertices, 3 floats per vertex uint debug_buf_len = 12; // 4 vertices, 3 floats per vertex
@ -220,7 +211,7 @@ renderFrame(render_state* rs, std::vector<hex_info> *hexes, Entity* entities, ui
render_group* rg = rs->filled_hex_render_group; render_group* rg = rs->filled_hex_render_group;
gl_buffer& color_buf = rg->render_objects[0]->color_buffer; gl_buffer& color_buf = rg->render_objects[0]->color_buffer;
// TODO: this needs optimization for large grids, very performance intensive // 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, rgDraw(rg, m_model, m_view, m_projection,
rs->lights, rs->num_lights, false, true); rs->lights, rs->num_lights, false, true);
@ -262,157 +253,3 @@ openglDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
<< ", message: " << message << "\n"; << ", message: " << message << "\n";
} }
// TODO: move hex logic to new file
bool
initHexGridBuffers(render_state* rs, std::vector<hex_info>* 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<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];
// 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<hex_info>* 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;
}
}
}

1
src/renderer.h

@ -36,6 +36,7 @@ struct render_state
render_group* filled_hex_render_group; render_group* filled_hex_render_group;
render_group* hex_line_render_group; render_group* hex_line_render_group;
render_group* debug_render_group; render_group* debug_render_group;
// NOTE: entity render groups are stored on the entity object
rg_shader_program default_shader; rg_shader_program default_shader;
rg_point_light* lights = nullptr; rg_point_light* lights = nullptr;

Loading…
Cancel
Save