Browse Source

chunk rendering

feature/replace-renderer
Martin Dørum 3 years ago
parent
commit
7b477216e7
5 changed files with 30 additions and 33 deletions
  1. 2
    6
      libcygnet/src/Renderer.cc
  2. 10
    7
      libswan/include/swan/Chunk.h
  3. 10
    12
      libswan/src/Chunk.cc
  4. 4
    4
      libswan/src/Game.cc
  5. 4
    4
      libswan/src/WorldPlane.cc

+ 2
- 6
libcygnet/src/Renderer.cc View File

@@ -231,10 +231,6 @@ void Renderer::modifyTile(TileID id, const void *data) {

RenderChunk Renderer::createChunk(
TileID tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]) {
// TODO: Maybe don't do this here? Maybe instead store the buffer and
// upload the texture in the draw method?
// The current approach needs createChunk to be called on the graphics thread.

RenderChunk chunk;
glGenTextures(1, &chunk.tex);
glCheck();
@@ -243,8 +239,8 @@ RenderChunk Renderer::createChunk(
glBindTexture(GL_TEXTURE_2D, chunk.tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCheck();

static_assert(

+ 10
- 7
libswan/include/swan/Chunk.h View File

@@ -3,6 +3,7 @@
#include <string.h>
#include <stdint.h>
#include <memory>
#include <cygnet/Renderer.h>

#include "util.h"
#include "common.h"
@@ -49,12 +50,12 @@ public:

void setTileID(RelPos pos, Tile::ID id) {
getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
drawList_.push_back({pos, id});
changeList_.emplace_back(pos, id);
isModified_ = true;
}

void setTileData(RelPos pos, Tile::ID id) {
getTileData()[pos.y * CHUNK_WIDTH + pos.x] = id;
needRender_ = true;
}

uint8_t getLightLevel(RelPos pos) {
@@ -66,14 +67,15 @@ public:
needLightRender_ = true;
}

void compress();
void generateDone();
void keepActive();
void decompress();
void compress(Cygnet::Renderer &rnd);
void destroy(Cygnet::Renderer &rnd) { rnd.destroyChunk(renderChunk_); }
void draw(const Context &ctx, Cygnet::Renderer &rnd);
TickAction tick(float dt);

bool isActive() { return deactivateTimer_ > 0; }
void keepActive();
void markModified() { isModified_ = true; }

ChunkPos pos_;

@@ -83,10 +85,11 @@ private:
bool isCompressed() { return compressedSize_ != -1; }

std::unique_ptr<uint8_t[]> data_;
std::vector<std::pair<RelPos, Tile::ID>> drawList_;
std::vector<std::pair<RelPos, Tile::ID>> changeList_;

ssize_t compressedSize_ = -1; // -1 if not compressed, a positive number if compressed
bool needRender_ = false;
Cygnet::RenderChunk renderChunk_;
bool needChunkRender_ = true;
bool needLightRender_ = false;
float deactivateTimer_ = DEACTIVATE_INTERVAL;
bool isModified_ = false;

+ 10
- 12
libswan/src/Chunk.cc View File

@@ -13,7 +13,7 @@

namespace Swan {

void Chunk::compress() {
void Chunk::compress(Cygnet::Renderer &rnd) {
if (isCompressed())
return;

@@ -45,7 +45,7 @@ void Chunk::compress() {
warn << "Chunk compression error: " << ret << " (Out of memory?)";
}

// TODO: Delete renderChunk_
rnd.destroyChunk(renderChunk_);
}

void Chunk::decompress() {
@@ -64,7 +64,6 @@ void Chunk::decompress() {
}

data_ = std::move(dest);
needRender_ = true;

info
<< "Decompressed chunk " << pos_ << " from "
@@ -72,23 +71,22 @@ void Chunk::decompress() {
<< DATA_SIZE << " bytes.";
compressedSize_ = -1;

// TODO: Create renderChunk_
needChunkRender_ = true;
}

void Chunk::draw(const Context &ctx, Cygnet::Renderer &rnd) {
if (isCompressed())
return;

// The world plane is responsible for managing initial renders
if (needRender_)
return;

if (drawList_.size() > 0) {
//renderList(win.renderer_); TODO
drawList_.clear();
if (needChunkRender_) {
renderChunk_ = rnd.createChunk((Tile::ID *)data_.get());
} else {
for (auto &change: changeList_) {
rnd.modifyChunk(renderChunk_, change.first, change.second);
}
}

// rnd.drawChunk(renderChunk_, (Vec2)pos_ * Vec2{CHUNK_WIDTH, CHUNK_HEIGHT}); TODO
rnd.drawChunk(renderChunk_, (Vec2)pos_ * Vec2{CHUNK_WIDTH, CHUNK_HEIGHT});
}

Chunk::TickAction Chunk::tick(float dt) {

+ 4
- 4
libswan/src/Game.cc View File

@@ -37,10 +37,10 @@ void Game::draw() {
void Game::update(float dt) {
// Zoom the window using the scroll wheel
cam_.zoom += (float)wasWheelScrolled() * 0.1f * cam_.zoom;
if (cam_.zoom > 3)
cam_.zoom = 3;
else if (cam_.zoom < 0.3)
cam_.zoom = 0.3;
if (cam_.zoom > 1)
cam_.zoom = 1;
else if (cam_.zoom < 0.05)
cam_.zoom = 0.05;

world_->update(dt);


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

@@ -70,7 +70,7 @@ Chunk &WorldPlane::getChunk(ChunkPos pos) {
}

Chunk &chunk = slowGetChunk(pos);
tickChunks_.push_back({ pos, &chunk });
tickChunks_.push_back({pos, &chunk});
return chunk;
}

@@ -97,7 +97,7 @@ Chunk &WorldPlane::slowGetChunk(ChunkPos pos) {
lc.blocks[y * CHUNK_HEIGHT + x] = true;
}
if (tile.lightLevel > 0) {
lc.lightSources[{ x, y }] = tile.lightLevel;
lc.lightSources[{x, y}] = tile.lightLevel;
}
}
}
@@ -123,7 +123,6 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
Tile &newTile = world_->getTileByID(id);
Tile &oldTile = world_->getTileByID(old);
chunk.setTileID(rp, id);
chunk.markModified();

if (!oldTile.isSolid && newTile.isSolid) {
lighting_->onSolidBlockAdded(pos);
@@ -275,12 +274,13 @@ void WorldPlane::tick(float dt) {
switch (action) {
case Chunk::TickAction::DEACTIVATE:
info << "Compressing inactive modified chunk " << chunk->pos_;
chunk->compress();
chunk->compress(world_->game_->renderer_);
iter = activeChunks_.erase(iter);
last = activeChunks_.end();
break;
case Chunk::TickAction::DELETE:
info << "Deleting inactive unmodified chunk " << chunk->pos_;
chunk->destroy(world_->game_->renderer_);
chunks_.erase(chunk->pos_);
iter = activeChunks_.erase(iter);
last = activeChunks_.end();

Loading…
Cancel
Save