Browse Source

moved hex logic from scene_loader to hexgrid and refactored

master
cinnaboot 8 years ago
parent
commit
e2b886f3fb
  1. 8
      TODO.md
  2. 9
      src/hexgame.cpp
  3. 245
      src/hexgrid.cpp
  4. 17
      src/hexgrid.h
  5. 1
      src/render_group.h
  6. 1
      src/renderer.cpp
  7. 1
      src/renderer.h
  8. 163
      src/scene_loader.cpp

8
TODO.md

@ -1,8 +1,5 @@
## 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
@ -13,9 +10,11 @@
- show vertex count, mesh filename, ...
- add 3d orientation widget to gooey
- renderer
- add name property to render_group to help debugging
- consolodate textures into just the render_state->palette_image
- update copyMeshInfo() and meMeshInfo struct to remove image loading from filename
- update rgInitEntity() to set tex_id of palette_image
- remove render_object->use_texture
- check over renderer, camera, gooey init after changes
- pass in frame time to camera movement functions to decouple speed from framerate
- test camera speed when moving with composite vector
@ -48,8 +47,9 @@
- add config.js/yaml for application config (remove some defines everywhere)
- maybe try deferred rendering at some point to use a ton of lights
- use assimp material info in shaders for fancier lighting
- add fancy GL error handler https://gist.github.com/liam-middlebrook/c52b069e4be2d87a6d2f
- add cpu performance counters in render loop
- hgUpdateUV buffer can probably be improved by adding selected hexes to a small cache structure
- hgUpdateUVBuffer can probably be improved by adding selected hexes to a small cache structure
- can also try passing in small chunks with glBufferSubData instead of overwriting whole buffer
- check for memory leaks w/ valgrind

9
src/hexgame.cpp

@ -60,11 +60,12 @@ loadSceneFromJson(game_state* s, render_state* rs)
slParseCamera(sd, rs->cam);
slParseHexGrid(sd, gs->grid, rs->palette_image);
hgCreateHexes(gs->grid);
if (!slCreateHexRenderGroups(gs->grid, rs))
{
LOG(ERROR) << "Error creating hex render groups\n";
if (slCreateHexRenderGroups(gs->grid, rs)) {
if (!hgInit(gs->grid, rs->filled_hex_render_group, rs->hex_line_render_group))
return false;
} else {
LOG(ERROR) << "Error creating hexgrid render groups\n";
return false;
}

245
src/hexgrid.cpp

@ -7,15 +7,20 @@
// 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);
void populateFilledHexGLBuffers(hexgrid& hg, hex_info& hxi, render_group* rg_filled);
void populateLineGLBuffers(hexgrid& hg, hex_info& hxi, render_group* rg_lines);
// interface
// TODO: testing add/remove hex interface
bool
hgCreateHexes(hexgrid& hg)
hgInit(hexgrid& hg, render_group* rg_filled, render_group* rg_lines)
{
Orientation o = (hg.layout_mode == LAYOUT_FLAT) ? layout_flat : layout_pointy;
hg.hexlib_layout = Layout(o, Point(hg.hex_size, hg.hex_size), Point(hg.position.x, hg.position.y));
if (hg.gridT == HEXAGON) {
createHexagonGrid(hg);
} else {
@ -23,37 +28,94 @@ hgCreateHexes(hexgrid& hg)
return false;
}
uint hex_count = hg.hex_map.size();
assert(hex_count < MAX_HEX_COUNT);
render_object* ro_f = rg_filled->render_objects[0];
render_object* ro_l = rg_lines->render_objects[0];
ro_f->vertex_buffer.count = hex_count * IDX_PER_HEX_FILLED;
ro_f->normal_buffer.count = hex_count * IDX_PER_HEX_FILLED;
ro_f->uv_buffer.count = hex_count * IDX_PER_HEX_FILLED;
ro_l->vertex_buffer.count = hex_count * IDX_PER_HEX_LINES;
ro_l->normal_buffer.count = hex_count * IDX_PER_HEX_LINES;
ro_l->uv_buffer.count = hex_count * IDX_PER_HEX_LINES;
ro_f->use_texture = true;
ro_l->use_texture = true;
// populate buffers
for (auto it : hg.hex_map) {
populateFilledHexGLBuffers(hg, it.second, rg_filled);
populateLineGLBuffers(hg, it.second, rg_lines);
}
// send buffers to GL
rgBufferData(&ro_f->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro_f->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro_f->uv_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro_l->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro_l->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro_l->uv_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
return true;
}
// TODO: testing add/remove hex interface
bool
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
uint filled_increment = 54;
uint lines_increment = 36;
if (incrementGLBufferCount(rg_filled, filled_increment) &&
incrementGLBufferCount(rg_lines, lines_increment))
if (!hxi) {
// sanity checks
render_object* ro_f = rg_filled->render_objects[0];
gl_buffer& vb_f = ro_f->vertex_buffer;
gl_buffer& nb_f = ro_f->normal_buffer;
gl_buffer& ub_f = ro_f->uv_buffer;
render_object* ro_l = rg_lines->render_objects[0];
gl_buffer& vb_l = ro_l->vertex_buffer;
gl_buffer& nb_l = ro_l->normal_buffer;
gl_buffer& ub_l = ro_l->uv_buffer;
if (vb_f.count + IDX_PER_HEX_FILLED < vb_f.max_count &&
nb_f.count + IDX_PER_HEX_FILLED < nb_f.max_count &&
ub_f.count + IDX_PER_HEX_FILLED < ub_f.max_count &&
vb_l.count + IDX_PER_HEX_LINES < vb_l.max_count &&
nb_l.count + IDX_PER_HEX_LINES < nb_l.max_count &&
ub_l.count + IDX_PER_HEX_LINES < ub_l.max_count)
{
insertHexVertexData(rg_filled, rg_lines, new_hex);
vb_f.count += IDX_PER_HEX_FILLED;
nb_f.count += IDX_PER_HEX_FILLED;
ub_f.count += IDX_PER_HEX_FILLED;
vb_l.count += IDX_PER_HEX_LINES;
nb_l.count += IDX_PER_HEX_LINES;
ub_l.count += IDX_PER_HEX_LINES;
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);
hg.hex_map.insert({h, new_hex});
populateFilledHexGLBuffers(hg, new_hex, rg_filled);
populateLineGLBuffers(hg, new_hex, rg_lines);
// NOTE: we could send just a part of the buffer if performance ends up being bad here
glBindBuffer(GL_ARRAY_BUFFER, vb_f.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, vb_f.count * sizeof(GLfloat), vb_f.buffer);
glBindBuffer(GL_ARRAY_BUFFER, nb_f.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, nb_f.count * sizeof(GLfloat), nb_f.buffer);
glBindBuffer(GL_ARRAY_BUFFER, ub_f.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, ub_f.count * sizeof(GLfloat), ub_f.buffer);
glBindBuffer(GL_ARRAY_BUFFER, vb_l.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, vb_l.count * sizeof(GLfloat), vb_l.buffer);
glBindBuffer(GL_ARRAY_BUFFER, nb_l.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, nb_l.count * sizeof(GLfloat), nb_l.buffer);
glBindBuffer(GL_ARRAY_BUFFER, ub_l.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, ub_l.count * sizeof(GLfloat), ub_l.buffer);
return true;
} else {
LOG(ERROR) << "Attempting to add hex failed\n";
LOG(ERROR) << "that hex isn't going to fit in the buffer(s)\n";
return false;
}
}
return false;
}
bool
@ -178,17 +240,14 @@ hgUpdateHexConeFill(hexgrid& hg, int32 x, int32 y, float cone_angle, std::vector
void
hgUpdateUVBuffer(hexgrid& hg, float* uv_buffer, uint buf_len)
{
// NOTE: 6 triangles * 3 vertices * 3 floats (not 2 to stay aligned with vbuffer)
uint buf_len_per_hex = 54;
assert(buf_len == hg.hex_map.size() * buf_len_per_hex);
assert(buf_len == hg.hex_map.size() * IDX_PER_HEX_FILLED);
for (auto& it : hg.hex_map) {
hex_info hxi = it.second;
v2f uv_coords = (hxi.selected) ? hg.selected_fill_color_uv : hg.fill_color_uv;
uint buf_idx = hxi.hexID * buf_len_per_hex;
uint buf_idx = hxi.hexID * IDX_PER_HEX_FILLED;
for (uint j = 0; j < buf_len_per_hex; j +=3) {
for (uint j = 0; j < IDX_PER_HEX_FILLED; j +=3) {
uv_buffer[buf_idx + j + 0] = uv_coords.x;
uv_buffer[buf_idx + j + 1] = uv_coords.y;
uv_buffer[buf_idx + j + 2] = 0;
@ -238,82 +297,90 @@ createHexagonGrid(hexgrid& hg)
}
}
bool
incrementGLBufferCount(render_group* rg, uint len)
void
populateFilledHexGLBuffers(hexgrid& hg, hex_info& hxi, render_group* rg_filled)
{
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;
render_object* ro = rg_filled->render_objects[0];
gl_buffer& vbuf = ro->vertex_buffer;
gl_buffer& normal_buf = ro->normal_buffer;
gl_buffer& uv_buf = ro->uv_buffer;
uint idx = hxi.hexID * IDX_PER_HEX_FILLED;
v2f uv_coords = (hxi.selected) ? hg.selected_fill_color_uv : hg.fill_color_uv;
for (uint i = 0; i < IDX_PER_HEX_FILLED; i += 3) {
// cheat at vertex normals since all hexes lay flat on z-axis
normal_buf.buffer[idx + i + 0] = 0.f;
normal_buf.buffer[idx + i + 1] = 0.f;
normal_buf.buffer[idx + i + 2] = 1.f;
// fill uv_buffer with palette texture coords
uv_buf.buffer[idx + i + 0] = uv_coords.x;
uv_buf.buffer[idx + i + 1] = uv_coords.y;
uv_buf.buffer[idx + i + 2] = 0;
}
}
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++) {
for (uint i = idx, j = 0; j < 6; i += 9, j++) {
// vertex 0
fb[idx + 0] = (GLfloat) hxi.XPos;
fb[idx + 1] = (GLfloat) hxi.YPos;
fb[idx + 2] = (GLfloat) 0.f;
vbuf.buffer[i + 0] = (GLfloat) hxi.XPos;
vbuf.buffer[i + 1] = (GLfloat) hxi.YPos;
vbuf.buffer[i + 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;
vbuf.buffer[i + 3] = (GLfloat) hxi.vertices[j].x;
vbuf.buffer[i + 4] = (GLfloat) hxi.vertices[j].y;
vbuf.buffer[i + 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;
vbuf.buffer[i + 6] = (GLfloat) hxi.vertices[0].x;
vbuf.buffer[i + 7] = (GLfloat) hxi.vertices[0].y;
vbuf.buffer[i + 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;
vbuf.buffer[i + 6] = (GLfloat) hxi.vertices[j + 1].x;
vbuf.buffer[i + 7] = (GLfloat) hxi.vertices[j + 1].y;
vbuf.buffer[i + 8] = (GLfloat) 0.f;
}
}
}
idx += 9; // NOTE: 3 vertices * 3 floats;
void
populateLineGLBuffers(hexgrid& hg, hex_info& hxi, render_group* rg_lines)
{
render_object* ro = rg_lines->render_objects[0];
gl_buffer& vbuf = ro->vertex_buffer;
gl_buffer& normal_buf = ro->normal_buffer;
gl_buffer& uv_buf = ro->uv_buffer;
uint idx = hxi.hexID * IDX_PER_HEX_LINES;
for (uint i = 0; i < IDX_PER_HEX_LINES; i += 3) {
// cheat at vertex normals since all hexes lay flat on z-axis
normal_buf.buffer[idx + i + 0] = 0.f;
normal_buf.buffer[idx + i + 1] = 0.f;
normal_buf.buffer[idx + i + 2] = 1.f;
// fill uv_buffer with palette texture coords
uv_buf.buffer[idx + i + 0] = hg.line_color_uv.x;
uv_buf.buffer[idx + i + 1] = hg.line_color_uv.y;
uv_buf.buffer[idx + i + 2] = 0;
}
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;
Point p1, p2;
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;
}
glBindBuffer(GL_ARRAY_BUFFER, normal_buf.buffer_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, normal_buf.count * sizeof(GLfloat), normal_buf.buffer);
}

17
src/hexgrid.h

@ -8,8 +8,9 @@
#include "render_group.h"
#include "util.h"
// NOTE: padding some extra space for hex buffers to grow
#define MAX_HEX_COUNT 8192
#define MAX_HEX_COUNT 8192 // NOTE: padding some extra space for hex buffers to grow
#define IDX_PER_HEX_FILLED 54 // NOTE: 6 triangles * 3 vertices per triangle * 3 floats per vertex
#define IDX_PER_HEX_LINES 36 // NOTE: 6 lines * 2 vertices per line * 3 floats per vertex
// TODO: rename to "hex_draw_mode" to fit project style
@ -33,6 +34,12 @@ enum grid_type
HASH_MAP
};
enum hex_layout_mode
{
LAYOUT_FLAT,
LAYOUT_POINTY
};
struct hex_info
{
uint hexID;
@ -57,8 +64,8 @@ struct hex_hashfunc
struct hexgrid
{
grid_type gridT;
hex_layout_mode layout_mode;
Layout hexlib_layout;
Orientation hexlib_orientation;
v3f position;
v3f normal;
uint hex_size;
@ -76,10 +83,10 @@ struct hexgrid
bool is_selecting;
};
bool hgCreateHexes(hexgrid& hg);
// TODO: testing add/remove hex interface
bool hgInit(hexgrid& hg, render_group* rg_filled, render_group* rg_lines);
bool hgAddHex(hexgrid& hg, v3f hex_coords, render_group* rg_filled, render_group* rg_lines);
bool hgRemoveHex(hexgrid& hg, v3i hex_coords);

1
src/render_group.h

@ -28,6 +28,7 @@ struct gl_index_buffer
struct render_object
{
// TODO: can remove these once we're using the global color palatte for all textures
bool use_texture;
GLuint tex_id;

1
src/renderer.cpp

@ -16,7 +16,6 @@
#include "hexlib.h"
#include "renderer.h"
#include "render_group.h"
#define DEFAULT_VERTEX_SHADER_FILE "../data/default.vs"
#define DEFAULT_FRAGMENT_SHADER_FILE "../data/default.fs"

1
src/renderer.h

@ -14,6 +14,7 @@
#include "camera.h"
#include "entity.h"
#include "hexgrid.h"
#include "render_group.h"
#include "util.h"

163
src/scene_loader.cpp

@ -26,9 +26,6 @@ glm::vec3 parseVec3(const rapidjson::Value& node);
glm::vec4 parseVec4(const rapidjson::Value& node);
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
@ -138,9 +135,7 @@ slParseHexGrid(slSceneDoc* sd, hexgrid& hg, util_image& palette_image)
hg.line_color_uv = utilGetPaletteCoords(palette_image, json_grid["hex_line_color"].GetInt());
std::string orientation_str = json_grid["hexlib_orientation"].GetString();
hg.hexlib_orientation = (orientation_str == "layout_flat") ? layout_flat : layout_pointy;
Layout lo(hg.hexlib_orientation, Point(hg.hex_size, hg.hex_size), Point(hg.position.x, hg.position.y));
hg.hexlib_layout = lo;
hg.layout_mode = (orientation_str == "layout_flat") ? LAYOUT_FLAT : LAYOUT_POINTY;
if (hg.gridT == HEXAGON) {
hg.hex_radius = json_grid["hex_radius"].GetInt();
@ -150,43 +145,20 @@ 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 = MAX_HEX_COUNT * 6 * 3 * 3;
uint buf_len = MAX_HEX_COUNT * IDX_PER_HEX_FILLED;
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 = MAX_HEX_COUNT * 6 * 2 * 3;
buf_len = MAX_HEX_COUNT * IDX_PER_HEX_LINES;
rs->hex_line_render_group = rgInitSingle(rs->default_shader, buf_len, true, 0, GL_LINES);
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)) {
if ((rs->filled_hex_render_group == nullptr) || (rs->hex_line_render_group == nullptr)) {
LOG(ERROR) << "Error allocating render_group, exiting\n";
return false;
}
populateFilledHexGLBuffers(hg, rg_filled);
populateLineGLBuffers(hg, rg_lines);
render_object* ro = rg_filled->render_objects[0];
ro->use_texture = true;
ro->tex_id = rs->palette_id;
rgBufferData(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro->uv_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
ro = rg_lines->render_objects[0];
ro->use_texture = true;
ro->tex_id = rs->palette_id;
rgBufferData(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
rgBufferData(&ro->uv_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
// TODO: can remove these once we're using the global color palatte for all textures
rs->filled_hex_render_group->render_objects[0]->tex_id = rs->palette_id;
rs->hex_line_render_group->render_objects[0]->tex_id = rs->palette_id;
return true;
}
@ -284,124 +256,3 @@ parseVec4(const rapidjson::Value& node)
return v4;
}
// TODO: these should probably move to hexgrid.cpp, and pass in each raw buffer
// to avoid render_group dependancy
void
populateFilledHexGLBuffers(hexgrid& hg, render_group* rg_filled)
{
render_object* ro = rg_filled->render_objects[0];
gl_buffer& vbuf = ro->vertex_buffer;
gl_buffer& normal_buf = ro->normal_buffer;
gl_buffer& uv_buf = ro->uv_buffer;
assert((hg.hex_map.size() * 6 * 3 * 3) == vbuf.count);
// fill uv_buffer with palette texture coords
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.count; 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 (auto& it : hg.hex_map) {
hex_info hex = it.second;
uint idx = hex.hexID * 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
populateLineGLBuffers(hexgrid& hg, render_group* rg_lines)
{
render_object* ro = rg_lines->render_objects[0];
gl_buffer& vbuf = ro->vertex_buffer;
gl_buffer& normal_buf = ro->normal_buffer;
gl_buffer& uv_buf = ro->uv_buffer;
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.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.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;
}
Point p1, p2;
// NOTE: these buffers won't be correctly indexed with hashtable, but that doesn't really
// matter for the lines, since they don't change color
int idx = 0;
for (auto it : hg.hex_map) {
hex_info hxi = it.second;
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;
}
}
}
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;
}

Loading…
Cancel
Save