@@ -80,8 +80,7 @@ struct ChunkProg: public GlProgram { | |||
GLint pos = uniformLoc("pos"); | |||
GLint vertex = attribLoc("vertex"); | |||
GLint tileTex = uniformLoc("tileTex"); | |||
GLint tileTexWidth = uniformLoc("tileTexWidth"); | |||
GLint tileTexHeight = uniformLoc("tileTexHeight"); | |||
GLint tileTexSize = uniformLoc("tileTexSize"); | |||
GLint tiles = uniformLoc("tiles"); | |||
GLuint vbo; | |||
@@ -157,9 +156,8 @@ void Renderer::draw() { | |||
glUniform1iv(state_->chunkProg.tiles, sizeof(tiles) / sizeof(*tiles), tiles); | |||
glCheck(); | |||
glUniform1f(state_->chunkProg.tileTexWidth, | |||
(float)(int)(state_->atlasTex.width() / SwanCommon::TILE_SIZE)); | |||
glUniform1f(state_->chunkProg.tileTexHeight, | |||
glUniform2f(state_->chunkProg.tileTexSize, | |||
(float)(int)(state_->atlasTex.width() / SwanCommon::TILE_SIZE), | |||
(float)(int)(state_->atlasTex.height() / SwanCommon::TILE_SIZE)); | |||
glCheck(); | |||
@@ -21,7 +21,7 @@ struct AtlasState { | |||
TileAtlas::TileAtlas(): state_(std::make_unique<AtlasState>()) { | |||
GLint size; | |||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); | |||
state_->tilesPerLine = std::min(size / SwanCommon::TILE_SIZE, 8); | |||
state_->tilesPerLine = std::min(size / SwanCommon::TILE_SIZE, 1024); | |||
} | |||
TileAtlas::~TileAtlas() = default; | |||
@@ -31,10 +31,7 @@ void TileAtlas::addTile(size_t tileId, const void *data, size_t len) { | |||
const unsigned char *bytes = (const unsigned char *)data; | |||
size_t x = tileId % state_->tilesPerLine; | |||
size_t y = tileId / state_->tilesPerLine; | |||
if (y >= state_->tilesPerLine) { | |||
std::cerr << "Cygnet: Warning: Tile ID " << tileId << " too big for texture atlas\n"; | |||
return; | |||
} | |||
std::cerr << "Tile " << tileId << " to " << x << ", " << y << '\n'; | |||
if (state_->width <= x) { | |||
state_->width = x + 1; | |||
@@ -46,7 +43,7 @@ void TileAtlas::addTile(size_t tileId, const void *data, size_t len) { | |||
size_t requiredSize = state_->tilesPerLine * SwanCommon::TILE_SIZE * | |||
state_->height * SwanCommon::TILE_SIZE * 4; | |||
state_->data.reserve(requiredSize); | |||
state_->data.resize(requiredSize); | |||
for (size_t ty = 0; ty < rows; ++ty) { | |||
const unsigned char *src = bytes + ty * SwanCommon::TILE_SIZE * 4; |
@@ -47,23 +47,19 @@ const char *chunkFr = R"glsl( | |||
varying vec2 v_tileCoord; | |||
uniform sampler2D tileTex; | |||
uniform float tileTexWidth; | |||
uniform float tileTexHeight; | |||
uniform vec2 tileTexSize; | |||
uniform int tiles[CHUNK_WIDTH * CHUNK_HEIGHT]; | |||
void main() { | |||
float tileX = floor(v_tileCoord.x); | |||
float tileY = floor(-v_tileCoord.y); | |||
int tileIndex = int(tileY * float(CHUNK_WIDTH) + tileX); | |||
vec2 tilePos = floor(vec2(v_tileCoord.x, -v_tileCoord.y)); | |||
int tileIndex = int(tilePos.y * float(CHUNK_WIDTH) + tilePos.x); | |||
float tileID = float(tiles[tileIndex]); | |||
float atlasX = floor(mod(tileID, tileTexWidth)) + v_tileCoord.x - tileX; | |||
float atlasY = floor(tileID / tileTexWidth) + (-v_tileCoord.y - tileY); | |||
vec2 atlasPos = vec2( | |||
tileID + v_tileCoord.x - tilePos.x, | |||
floor(tileID / tileTexSize.x) + (-v_tileCoord.y - tilePos.y)); | |||
float x = atlasX / tileTexWidth; | |||
float y = atlasY / tileTexHeight; | |||
gl_FragColor = texture2D(tileTex, vec2(x, y)); | |||
gl_FragColor = texture2D(tileTex, fract(atlasPos / tileTexSize)); | |||
} | |||
)glsl"; | |||