Browse Source

way faster chunk rendering

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
660c6f9f7a
4 changed files with 40 additions and 12 deletions
  1. 3
    1
      libswan/include/swan/Chunk.h
  2. 24
    3
      libswan/src/Chunk.cc
  3. 12
    7
      libswan/src/World.cc
  4. 1
    1
      libswan/src/WorldPlane.cc

+ 3
- 1
libswan/include/swan/Chunk.h View File



void setTileID(World &world, RelPos pos, Tile::ID id); void setTileID(World &world, RelPos pos, Tile::ID id);
Tile &getTile(World &world, RelPos pos); Tile &getTile(World &world, RelPos pos);
void redraw(World &world);
void render(World &world);
void draw(Win &win); void draw(Win &win);


ChunkPos pos_; ChunkPos pos_;
Tile::ID tiles_[CHUNK_WIDTH][CHUNK_HEIGHT]; Tile::ID tiles_[CHUNK_WIDTH][CHUNK_HEIGHT];


private: private:
static sf::Uint8 *imgbuf;

void drawBlock(RelPos pos, const Tile &t); void drawBlock(RelPos pos, const Tile &t);
void drawBlock(World &world, RelPos pos, Tile::ID id); void drawBlock(World &world, RelPos pos, Tile::ID id);
bool dirty_ = false; bool dirty_ = false;

+ 24
- 3
libswan/src/Chunk.cc View File



namespace Swan { namespace Swan {


sf::Uint8 *Chunk::imgbuf = new sf::Uint8[CHUNK_WIDTH * TILE_SIZE * CHUNK_HEIGHT * TILE_SIZE * 4];

void Chunk::setTileID(World &world, RelPos pos, Tile::ID id) { void Chunk::setTileID(World &world, RelPos pos, Tile::ID id) {
tiles_[pos.x_][pos.y_] = id; tiles_[pos.x_][pos.y_] = id;
drawBlock(world, pos, id); drawBlock(world, pos, id);
} }


void Chunk::drawBlock(RelPos pos, const Tile &t) { void Chunk::drawBlock(RelPos pos, const Tile &t) {
texture_.update(t. image_, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE);
texture_.update(t.image_, pos.x_ * TILE_SIZE, pos.y_ * TILE_SIZE);
dirty_ = true; dirty_ = true;
} }


drawBlock(pos, world.getTileByID(id)); drawBlock(pos, world.getTileByID(id));
} }


void Chunk::redraw(World &world) {
void Chunk::render(World &world) {
Tile::ID prevID = Tile::INVALID_ID;
Tile &tile = Tile::INVALID_TILE;

for (int x = 0; x < CHUNK_WIDTH; ++x) { for (int x = 0; x < CHUNK_WIDTH; ++x) {
for (int y = 0; y < CHUNK_HEIGHT; ++y) { for (int y = 0; y < CHUNK_HEIGHT; ++y) {
drawBlock(world, ChunkPos(x, y), tiles_[x][y]);
Tile::ID id = tiles_[x][y];
if (id != prevID) {
prevID = id;
tile = world.getTileByID(id);
}

const sf::Uint8 *imgptr = tile.image_.getPixelsPtr();
for (int imgy = 0; imgy < TILE_SIZE; ++imgy) {
int pixx = x * TILE_SIZE;
int pixy = y * TILE_SIZE + imgy;
sf::Uint8 *pix = imgbuf +
pixy * CHUNK_WIDTH * TILE_SIZE * 4 +
pixx * 4;
memcpy(pix, imgptr + imgy * TILE_SIZE * 4, TILE_SIZE * 4);
}
} }
} }

texture_.update(imgbuf, CHUNK_WIDTH * TILE_SIZE, CHUNK_HEIGHT * TILE_SIZE, 0, 0);
} }


void Chunk::draw(Win &win) { void Chunk::draw(Win &win) {

+ 12
- 7
libswan/src/World.cc View File

#include "World.h" #include "World.h"


#include <SFML/System/Clock.hpp>

namespace Swan { namespace Swan {


static bool chunkLine(int l, int &left, WorldPlane &plane, ChunkPos &abspos, const Vec2i &dir) {
static bool chunkLine(int l, sf::Clock &clock, WorldPlane &plane, ChunkPos &abspos, const Vec2i &dir) {
for (int i = 0; i < l; ++i) { for (int i = 0; i < l; ++i) {
if (!plane.hasChunk(abspos)) { if (!plane.hasChunk(abspos)) {
plane.getChunk(abspos); plane.getChunk(abspos);
if (--left == 0)

// Don't blow our frame budget on generating chunks,
// but generate as many as possible within the budget
if (clock.getElapsedTime().asSeconds() > 1.0 / 100)
return true; return true;
} }
abspos += dir; abspos += dir;
} }


void World::ChunkRenderer::tick(WorldPlane &plane, ChunkPos abspos) { void World::ChunkRenderer::tick(WorldPlane &plane, ChunkPos abspos) {
sf::Clock clock;
int l = 0; int l = 0;
int left = 4;


for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
if (chunkLine(l, left, plane, abspos, Vec2i(0, -1))) return;
if (chunkLine(l, left, plane, abspos, Vec2i(1, 0))) return;
if (chunkLine(l, clock, plane, abspos, Vec2i(0, -1))) break;
if (chunkLine(l, clock, plane, abspos, Vec2i(1, 0))) break;
l += 1; l += 1;
if (chunkLine(l, left, plane, abspos, Vec2i(0, 1))) return;
if (chunkLine(l, left, plane, abspos, Vec2i(-1, 0))) return;
if (chunkLine(l, clock, plane, abspos, Vec2i(0, 1))) break;
if (chunkLine(l, clock, plane, abspos, Vec2i(-1, 0))) break;
l += 1; l += 1;
} }
} }

+ 1
- 1
libswan/src/WorldPlane.cc View File

if (iter == chunks_.end()) { if (iter == chunks_.end()) {
iter = chunks_.emplace(pos, new Chunk(pos)).first; iter = chunks_.emplace(pos, new Chunk(pos)).first;
gen_->genChunk(*this, *iter->second); gen_->genChunk(*this, *iter->second);
iter->second->redraw(*world_);
iter->second->render(*world_);
} }


return *iter->second; return *iter->second;

Loading…
Cancel
Save