Skip to content

Commit

Permalink
* Actually implement greedy meshing.
Browse files Browse the repository at this point in the history
  • Loading branch information
iProgramMC committed Apr 6, 2024
1 parent 2ce1893 commit d899d90
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 65 deletions.
151 changes: 119 additions & 32 deletions source/client/renderer/Chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include "world/level/Level.hpp"
#include "world/level/Region.hpp"
#include "TileRenderer.hpp"
#include "client/app/Minecraft.hpp"

#define ENABLE_GREEDY_MESHING (true)

int Chunk::updates;

Expand Down Expand Up @@ -125,54 +128,138 @@ bool Chunk::isDirty()
return m_bDirty;
}

void Chunk::renderFaceDown()
void Chunk::renderXExpandableFaces(TileRenderer& tileRenderer, Region& region, int layer, int direction, bool& bNeedAnotherLayer)
{
}
int minX = m_pos.x, maxX = m_pos.x + field_10;
int minY = m_pos.y, maxY = m_pos.y + field_14;
int minZ = m_pos.z, maxZ = m_pos.z + field_18;

// Draw face down and non-solids
for (int y = minY; y < maxY; y++)
for (int z = minZ; z < maxZ; z++)
for (int x = minX; x < maxX; x++)
{
TileID tile = region.getTile(x, y, z);
if (tile == 0) continue;

void Chunk::renderFaceUp()
{
}
Tile* pTile = Tile::tiles[tile];
int tshape = pTile->getRenderShape();
int tlayer = pTile->getRenderLayer();

void Chunk::renderNorth()
{
if (layer != tlayer) {
bNeedAnotherLayer = true;
continue;
}

// Sadly, biome colored grass won't work
if (!TileRenderer::canRenderGreedy(tshape) ||
(tile == TILE_GRASS && tileRenderer.m_bBiomeColors))
{
if (direction == DIR_YNEG)
tileRenderer.tesselateInWorld(pTile, x, y, z);

continue;
}

int x2 = x;
// Count the amount of tiles on +X that we are repeating for.
while (x2 < m_pos.x + 16 && region.getTile(x2, y, z) == tile)
x2++;

// The group is x2 - x tiles wide. Render it
tileRenderer.setGroupSize(x2 - x);
if (tileRenderer.tesselateBlockInWorldDir(pTile, x, y, z, -1.0f, -1.0f, -1.0f, direction))
{
// Decrease x2 as we actually want the last tile within the group.
x2--;
// Skip all other tiles, as they were rendered in this iteration.
x = x2;
}
}
}

void Chunk::renderSouth()
void Chunk::renderZExpandableFaces(TileRenderer& tileRenderer, Region& region, int layer, int direction, bool& bNeedAnotherLayer)
{
}
int minX = m_pos.x, maxX = m_pos.x + field_10;
int minY = m_pos.y, maxY = m_pos.y + field_14;
int minZ = m_pos.z, maxZ = m_pos.z + field_18;

// Draw face down and non-solids
for (int y = minY; y < maxY; y++)
for (int x = minX; x < maxX; x++)
for (int z = minZ; z < maxZ; z++)
{
TileID tile = region.getTile(x, y, z);
if (tile == 0) continue;

void Chunk::renderWest()
{
}
Tile* pTile = Tile::tiles[tile];
int tshape = pTile->getRenderShape();
int tlayer = pTile->getRenderLayer();

void Chunk::renderEast()
{
if (layer != tlayer) {
bNeedAnotherLayer = true;
continue;
}

// Sadly, biome colored grass won't work
if (!TileRenderer::canRenderGreedy(tshape) ||
(tile == TILE_GRASS && tileRenderer.m_bBiomeColors))
continue;

int z2 = z;
// Count the amount of tiles on +Z that we are repeating for.
while (z2 < m_pos.z + 16 && region.getTile(x, y, z2) == tile)
z2++;

// The group is z2 - z tiles wide. Render it
tileRenderer.setGroupSize(z2 - z);
if (tileRenderer.tesselateBlockInWorldDir(pTile, x, y, z, -1.0f, -1.0f, -1.0f, direction))
{
// Decrease z2 as we actually want the last tile within the group.
z2--;
// Skip all other tiles, as they were rendered in this iteration.
z = z2;
}
}
}

bool Chunk::renderLayer(TileRenderer& tileRenderer, Region& region, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int layer)
bool Chunk::renderLayer(TileRenderer& tileRenderer, Region& region, int layer)
{
Tesselator& t = Tesselator::instance;
t.begin();
t.offset(float(-m_pos.x), float(-m_pos.y), float(-m_pos.z));

bool bDrewThisLayer = false, bNeedAnotherLayer = false;
for (int y = minY; y < maxY; y++)
{
for (int z = minZ; z < maxZ; z++)
{
for (int x = minX; x < maxX; x++)
{
TileID tile = region.getTile(x, y, z);
if (tile <= 0) continue;
bool bNeedAnotherLayer = false;

Tile* pTile = Tile::tiles[tile];
int minX = m_pos.x, maxX = m_pos.x + field_10;
int minY = m_pos.y, maxY = m_pos.y + field_14;
int minZ = m_pos.z, maxZ = m_pos.z + field_18;

if (layer == pTile->getRenderLayer())
tileRenderer.tesselateInWorld(pTile, x, y, z);
else
bNeedAnotherLayer = true;
}
}
if (ENABLE_GREEDY_MESHING && !Minecraft::useAmbientOcclusion)
{
renderXExpandableFaces(tileRenderer, region, layer, DIR_YNEG, bNeedAnotherLayer);
renderXExpandableFaces(tileRenderer, region, layer, DIR_YPOS, bNeedAnotherLayer);
renderXExpandableFaces(tileRenderer, region, layer, DIR_ZNEG, bNeedAnotherLayer);
renderXExpandableFaces(tileRenderer, region, layer, DIR_ZPOS, bNeedAnotherLayer);
renderZExpandableFaces(tileRenderer, region, layer, DIR_XNEG, bNeedAnotherLayer);
renderZExpandableFaces(tileRenderer, region, layer, DIR_XPOS, bNeedAnotherLayer);
}
else
{
for (int y = minY; y < maxY; y++)
for (int z = minZ; z < maxZ; z++)
for (int x = minX; x < maxX; x++)
{
TileID tile = region.getTile(x, y, z);
if (tile <= 0) continue;

Tile* pTile = Tile::tiles[tile];

if (layer == pTile->getRenderLayer())
tileRenderer.tesselateInWorld(pTile, x, y, z);
else
bNeedAnotherLayer = true;
}
}

if (!t.empty())
Expand Down Expand Up @@ -219,7 +306,7 @@ void Chunk::rebuild()

for (int layer = 0; layer < 2; layer++)
{
bool stop = renderLayer(tileRenderer, region, minX, minY, minZ, maxX, maxY, maxZ, layer);
bool stop = renderLayer(tileRenderer, region, layer);
if (!stop)
break;
}
Expand Down
10 changes: 3 additions & 7 deletions source/client/renderer/Chunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,9 @@ class Chunk
bool m_bDirty;

private:
void renderFaceDown();
void renderFaceUp();
void renderNorth();
void renderSouth();
void renderWest();
void renderEast();
void renderXExpandableFaces(TileRenderer& tre, Region& rgn, int layerNo, int direction, bool& bNeedAnotherLayer);
void renderZExpandableFaces(TileRenderer& tre, Region& rgn, int layerNo, int direction, bool& bNeedAnotherLayer);

bool renderLayer(TileRenderer& tre, Region& rgn, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, int layerNo);
bool renderLayer(TileRenderer& tre, Region& rgn, int layerNo);
};

Loading

0 comments on commit d899d90

Please sign in to comment.