Browse Source

maybe this is good?

feature/new-lighting-engine
Martin Dørum 3 years ago
parent
commit
c80c287a80

+ 4
- 2
libcygnet/include/cygnet/Renderer.h View File

@@ -15,6 +15,7 @@ struct RendererState;

struct RenderChunk {
GLuint tex;
GLuint opacityTex;
};

struct RenderSprite {
@@ -48,8 +49,9 @@ public:
void modifyTile(TileID id, const void *data);

RenderChunk createChunk(
TileID tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]);
void modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id);
TileID tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT],
uint8_t opacities[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]);
void modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id, uint8_t opacity);
void destroyChunk(RenderChunk chunk);

RenderSprite createSprite(void *data, int width, int height, int fh);

+ 23
- 5
libcygnet/src/Renderer.cc View File

@@ -662,9 +662,13 @@ void Renderer::modifyTile(TileID id, const void *data) {
}

RenderChunk Renderer::createChunk(
TileID tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]) {
TileID tiles[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT],
uint8_t opacities[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT]) {
RenderChunk chunk;
glGenTextures(1, &chunk.tex);
GLuint texes[2];
glGenTextures(2, texes);
chunk.tex = texes[0];
chunk.opacityTex = texes[1];
glCheck();

glActiveTexture(GL_TEXTURE0);
@@ -685,6 +689,7 @@ RenderChunk Renderer::createChunk(
GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tiles);
glCheck();
} else if constexpr (std::endian::native == std::endian::big) {
uint8_t buf[SwanCommon::CHUNK_WIDTH * SwanCommon::CHUNK_HEIGHT * 2];
for (size_t y = 0; y < SwanCommon::CHUNK_HEIGHT; ++y) {
@@ -700,13 +705,20 @@ RenderChunk Renderer::createChunk(
GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf);
glCheck();
}

glBindTexture(GL_TEXTURE_2D, chunk.opacityTex);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_LUMINANCE,
SwanCommon::CHUNK_WIDTH, SwanCommon::CHUNK_HEIGHT,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, opacities);
glCheck();

return chunk;
}

void Renderer::modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id) {
void Renderer::modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id, uint8_t opacity) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, chunk.tex);
glCheck();
@@ -720,18 +732,24 @@ void Renderer::modifyChunk(RenderChunk chunk, SwanCommon::Vec2i pos, TileID id)
glTexSubImage2D(
GL_TEXTURE_2D, 0, pos.x, pos.y, 1, 1,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &id);
glCheck();
} else if constexpr (std::endian::native == std::endian::big) {
uint8_t buf[] = { (uint8_t)(id & 0xff), (uint8_t)((id & 0xff00) >> 8) };
glTexSubImage2D(
GL_TEXTURE_2D, 0, pos.x, pos.y, 1, 1,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf);
glCheck();
}

glCheck();
glBindTexture(GL_TEXTURE_2D, chunk.opacityTex);
glTexSubImage2D(
GL_TEXTURE_2D, 0, pos.x, pos.y, 1, 1,
GL_LUMINANCE, GL_UNSIGNED_BYTE, &opacity);
}

void Renderer::destroyChunk(RenderChunk chunk) {
glDeleteTextures(1, &chunk.tex);
GLuint texes[] = {chunk.tex, chunk.opacityTex};
glDeleteTextures(2, texes);
glCheck();
}


+ 11
- 4
libswan/include/swan/Chunk.h View File

@@ -19,7 +19,8 @@ public:
using RelPos = TilePos;

static constexpr size_t DATA_SIZE =
CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID);
CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID) +
CHUNK_WIDTH * CHUNK_HEIGHT;

// What does this chunk want the world gen to do after a tick?
enum class TickAction {
@@ -35,13 +36,19 @@ public:
return (Tile::ID *)data_.get();
}

uint8_t *getOpacityData() {
assert(isActive());
return data_.get() + CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID);
}

Tile::ID getTileID(RelPos pos) {
return getTileData()[pos.y * CHUNK_WIDTH + pos.x];
}

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

@@ -71,7 +78,7 @@ private:

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

ssize_t compressedSize_ = -1; // -1 if not compressed, a positive number if compressed
Cygnet::RenderChunk renderChunk_;

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

@@ -118,11 +118,11 @@ void Chunk::draw(const Context &ctx, Cygnet::Renderer &rnd) {
return;

if (needChunkRender_) {
renderChunk_ = rnd.createChunk(getTileData());
renderChunk_ = rnd.createChunk(getTileData(), getOpacityData());
needChunkRender_ = false;
} else {
for (auto [pos, id]: changeList_) {
rnd.modifyChunk(renderChunk_, pos, id);
for (auto [pos, id, opacity]: changeList_) {
rnd.modifyChunk(renderChunk_, pos, id, opacity);
}
}


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

@@ -105,7 +105,7 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
if (id != old) {
Tile &newTile = world_->getTileByID(id);
Tile &oldTile = world_->getTileByID(old);
chunk.setTileID(rp, id);
chunk.setTileID(rp, id, newTile.isSolid ? 255 : 0);

if (newTile.lightLevel != oldTile.lightLevel) {
if (oldTile.lightLevel > 0) {

Loading…
Cancel
Save