tileset::tileset(std::string const& tsd_file_name) { p_read(tsd_file_name); // Calculate vertics and indices for tileset std::vector<vertex::pos2_tex2> vertices; std::vector<GLuint> indices; uvec2 const& texture_dim = p_texture->get_dimensions(); uvec2 const num_tiles = texture_dim / p_tile_size; p_num_tiles = num_tiles.x() * num_tiles.y(); // Dimensions of a single tile when entire tileset is considered using coordinates [0, 1] vec2 const tile_tex_coord_dim = vec2((float)p_tile_size) / vec2(texture_dim); uvec2 curr_tile; for(curr_tile.y() = 0; curr_tile.y() < num_tiles.y(); ++curr_tile.y()) { for(curr_tile.x() = 0; curr_tile.x() < num_tiles.x(); ++curr_tile.x()) { // Since size = current max index + 1, the index of the first vertex we add is equal to // the size of the vector before it is added. size_t curr_tile_base_vertex = vertices.size(); // Calculate the texture coordinates for this tile vec2 tc_min = vec2(curr_tile) * tile_tex_coord_dim; vec2 tc_max = tc_min + tile_tex_coord_dim; vertices.emplace_back( vec2{-0.5f, -0.5f}, vec2{tc_min.x(), tc_max.y()} ); vertices.emplace_back( vec2{ 0.5f, -0.5f}, vec2{tc_max.x(), tc_max.y()} ); vertices.emplace_back( vec2{ 0.5f, 0.5f}, vec2{tc_max.x(), tc_min.y()} ); vertices.emplace_back( vec2{-0.5f, 0.5f}, vec2{tc_min.x(), tc_min.y()} ); GLuint bottom_left_index = curr_tile_base_vertex + 0; GLuint bottom_right_index = curr_tile_base_vertex + 1; GLuint top_right_index = curr_tile_base_vertex + 2; GLuint top_left_index = curr_tile_base_vertex + 3; indices.emplace_back(bottom_left_index); indices.emplace_back(bottom_right_index); indices.emplace_back(top_left_index); indices.emplace_back(top_left_index); indices.emplace_back(bottom_right_index); indices.emplace_back(top_right_index); } } p_tile_vertices.set_data( vertices.data(), vertices.size(), indices.data(), indices.size(), GL_STATIC_DRAW); }
inline uvec2 max(const uvec2& a, unsigned int b) { return uvec2( a.x() > b ? a.x() : b, a.y() > b ? a.y() : b); }
inline uvec2 max(const uvec2& a, const uvec2& b) { return uvec2( a.x() > b.x() ? a.x() : b.x(), a.y() > b.y() ? a.y() : b.y()); }
inline uvec2 min(const uvec2& a, const uvec2& b) { return uvec2( a.x() < b.x() ? a.x() : b.x(), a.y() < b.y() ? a.y() : b.y()); }
inline float dot(const uvec2& v1, const uvec2& v2) { return (float)(v1.x()*v2.x() + v1.y()*v2.y()); }
void setUniform(const uvec2& value) { setUniform2ui(1, value.ptr()); }