diff --git a/src/scene_loader.cpp b/src/scene_loader.cpp index 741a1f7..c1f013b 100644 --- a/src/scene_loader.cpp +++ b/src/scene_loader.cpp @@ -27,8 +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); +void populateFilledHexGLBuffers(hexgrid& hg, render_group* rg_filled, util_image palette_image); +void populateLineGLBuffers(hexgrid& hg, render_group* rg_lines, util_image palette_image); // interface @@ -163,18 +163,26 @@ slCreateHexRenderGroups(hexgrid& hg, render_state* rs) return false; } - populateFilledHexBuffer(hg, rg_filled); - populateLineBuffer(hg, rg_lines); + populateFilledHexGLBuffers(hg, rg_filled, rs->palette_image); + populateLineGLBuffers(hg, rg_lines, rs->palette_image); 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->color_buffer, GL_DYNAMIC_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->color_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); + rgBufferData(&ro->uv_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER); return true; } @@ -274,15 +282,25 @@ parseVec4(const rapidjson::Value& node) } void -populateFilledHexBuffer(hexgrid& hg, render_group* rg_filled) +populateFilledHexGLBuffers(hexgrid& hg, render_group* rg_filled, util_image palette_image) { 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; + gl_buffer& uv_buf = ro->uv_buffer; assert((hg.hex_array->size() * 6 * 3 * 3) == vbuf.buffer_len); + // fill uv_buffer with palette texture coords + v2f fill_color_coords = utilGetPaletteCoords(palette_image, hg.fill_color); + + for (uint i = 0; i < uv_buf.buffer_len; i += 3) { + uv_buf.buffer[i + 0] = fill_color_coords.x; + uv_buf.buffer[i + 1] = fill_color_coords.y; + uv_buf.buffer[i + 2] = 0; + } + hgUpdateColorBuffer(cbuf, hg.hex_array); // cheat at vertex normals since all hexes lay flat on z-axis @@ -333,12 +351,13 @@ populateFilledHexBuffer(hexgrid& hg, render_group* rg_filled) } void -populateLineBuffer(hexgrid& hg, render_group* rg_lines) +populateLineGLBuffers(hexgrid& hg, render_group* rg_lines, util_image palette_image) { 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; + gl_buffer& uv_buf = ro->uv_buffer; assert((hg.hex_array->size() * 6 * 2 * 3) == vbuf.buffer_len); @@ -353,6 +372,15 @@ populateLineBuffer(hexgrid& hg, render_group* rg_lines) normal_buf.buffer[i + 2] = 1.f; } + // fill uv_buffer with palette texture coords + v2f uv_coords = utilGetPaletteCoords(palette_image, hg.hex_line_color); + + for (uint i = 0; i < uv_buf.buffer_len; i += 3) { + uv_buf.buffer[i + 0] = uv_coords.x; + uv_buf.buffer[i + 1] = uv_coords.y; + uv_buf.buffer[i + 2] = 0; + } + Point p1, p2; int idx = 0; for (int i = 0; i < (int) hg.hex_array->size(); i++) diff --git a/src/util.cpp b/src/util.cpp index bb9520e..1705d2f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -120,25 +121,36 @@ utilFreeImage(util_image image) } // need to init default values from scene file, or finally make default config? -util_RGBA -renGetPaletteColor(util_image& palette_image, uint color_index) +v2f +utilGetPaletteCoords(util_image& palette_image, uint color_index) { - util_RGBA color; + v2i tex_coords; + v2f normalized; if (PALETTE_ROWS * PALETTE_COLUMNS < color_index) { LOG(ERROR) << "index out of range\n"; - return color; + return normalized; } if (palette_image.pixels == nullptr) { LOG(ERROR) << "palatte image not loaded\n"; - return color; + return normalized; } - // get start of pixel (remember to account for palette border) - // read num_channels bytes - // pad extra 0xFF byte if 3 channels - // convert 4 uint8 bytes to normalized RGBA floats - - return color; + // NOTE: we're aiming to sample near the middle of the palette 'square' so GL_NEAREST + // doesn't try to sample the border color + v2i palette_square; + palette_square.x = palette_image.w / PALETTE_ROWS; + palette_square.y = palette_image.h / PALETTE_COLUMNS; + uint v_row = (uint) std::floor(color_index / PALETTE_ROWS); + uint u_column = color_index % PALETTE_ROWS; + tex_coords.x = u_column * palette_square.x + palette_square.x / 2; + tex_coords.y = v_row * palette_square.y + palette_square.y / 2; + // NOTE: flip y coord + tex_coords.y = palette_image.h - tex_coords.y; + + normalized.x = (float) tex_coords.x / palette_image.w; + normalized.y = (float) tex_coords.y / palette_image.h; + + return normalized; } diff --git a/src/util.h b/src/util.h index 1702794..c3db28b 100644 --- a/src/util.h +++ b/src/util.h @@ -108,4 +108,4 @@ util_image utilLoadImage(const char* base_dir, const char* filename); void utilFreeImage(util_image image); -util_RGBA utilGetPaletteColor(util_image& palette_image, uint color_index); +v2f utilGetPaletteCoords(util_image& palette_image, uint color_index);