Quellcode durchsuchen

way faster chunk rendering

opengl-renderer-broken
Martin Dørum vor 4 Jahren
Ursprung
Commit
660c6f9f7a
4 geänderte Dateien mit 40 neuen und 12 gelöschten Zeilen
  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 Datei anzeigen

@@ -21,13 +21,15 @@ public:

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

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

private:
static sf::Uint8 *imgbuf;

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

+ 24
- 3
libswan/src/Chunk.cc Datei anzeigen

@@ -4,6 +4,8 @@

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) {
tiles_[pos.x_][pos.y_] = id;
drawBlock(world, pos, id);
@@ -14,7 +16,7 @@ Tile &Chunk::getTile(World &world, RelPos pos) {
}

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;
}

@@ -22,12 +24,31 @@ void Chunk::drawBlock(World &world, RelPos pos, Tile::ID 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 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) {

+ 12
- 7
libswan/src/World.cc Datei anzeigen

@@ -1,12 +1,17 @@
#include "World.h"

#include <SFML/System/Clock.hpp>

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) {
if (!plane.hasChunk(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;
}
abspos += dir;
@@ -16,15 +21,15 @@ static bool chunkLine(int l, int &left, WorldPlane &plane, ChunkPos &abspos, con
}

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

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;
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;
}
}

+ 1
- 1
libswan/src/WorldPlane.cc Datei anzeigen

@@ -46,7 +46,7 @@ Chunk &WorldPlane::getChunk(ChunkPos pos) {
if (iter == chunks_.end()) {
iter = chunks_.emplace(pos, new Chunk(pos)).first;
gen_->genChunk(*this, *iter->second);
iter->second->redraw(*world_);
iter->second->render(*world_);
}

return *iter->second;

Laden…
Abbrechen
Speichern