mirror of
https://github.com/celisej567/mcpe.git
synced 2025-12-31 17:49:17 +03:00
2728 lines
78 KiB
C++
2728 lines
78 KiB
C++
/********************************************************************
|
|
Minecraft: Pocket Edition - Decompilation Project
|
|
Copyright (C) 2023 iProgramInCpp
|
|
|
|
The following code is licensed under the BSD 1 clause license.
|
|
SPDX-License-Identifier: BSD-1-Clause
|
|
********************************************************************/
|
|
|
|
#include "TileRenderer.hpp"
|
|
#include "client/app/Minecraft.hpp"
|
|
#include "client/renderer/PatchManager.hpp"
|
|
#include "world/tile/FireTile.hpp"
|
|
#include "world/tile/LiquidTile.hpp"
|
|
#include "client/renderer/GrassColor.hpp"
|
|
#include "client/renderer/FoliageColor.hpp"
|
|
|
|
bool TileRenderer::m_bFancyGrass = false;
|
|
bool TileRenderer::m_bBiomeColors = false;
|
|
|
|
void TileRenderer::_init()
|
|
{
|
|
m_textureOverride = -1;
|
|
field_8 = false;
|
|
m_bDisableCulling = false;
|
|
m_bAmbientOcclusion = false;
|
|
field_C = 0;
|
|
field_10 = 0;
|
|
field_14 = 0;
|
|
field_18 = 0;
|
|
field_1C = 0;
|
|
field_20 = 0;
|
|
field_24 = 0;
|
|
field_28 = 0;
|
|
field_2C = 0;
|
|
field_30 = 0;
|
|
field_34 = 0;
|
|
field_38 = 0;
|
|
field_3C = 0;
|
|
field_40 = 0;
|
|
field_44 = 0;
|
|
field_48 = 0;
|
|
field_4C = 0;
|
|
field_50 = 0;
|
|
field_54 = 0;
|
|
field_58 = 0;
|
|
field_5C = 0;
|
|
field_60 = 0;
|
|
field_64 = 0;
|
|
field_68 = 0;
|
|
field_6C = 0;
|
|
field_70 = 0;
|
|
field_74 = 0;
|
|
field_78 = 1;
|
|
field_AC = false;
|
|
field_AD = false;
|
|
field_AE = false;
|
|
field_AF = false;
|
|
field_B0 = false;
|
|
field_B1 = false;
|
|
field_B2 = false;
|
|
field_B3 = false;
|
|
field_B4 = false;
|
|
field_B5 = false;
|
|
field_B6 = false;
|
|
field_B7 = false;
|
|
}
|
|
|
|
TileRenderer::TileRenderer()
|
|
{
|
|
_init();
|
|
#ifndef ORIGINAL_CODE
|
|
// @BUG: Not initializing level source
|
|
m_pLevelSource = nullptr;
|
|
#endif
|
|
}
|
|
|
|
TileRenderer::TileRenderer(LevelSource* pLevelSource)
|
|
{
|
|
_init();
|
|
m_pLevelSource = pLevelSource;
|
|
}
|
|
|
|
float TileRenderer::getWaterHeight(int x, int y, int z, const Material* pCheckMtl)
|
|
{
|
|
int iBias = 0;
|
|
float fHeight = 0.0f;
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
int checkX = x - (i & 1);
|
|
int checkY = y;
|
|
int checkZ = z - ((i >> 1) & 1);
|
|
|
|
if (m_pLevelSource->getMaterial(checkX, checkY + 1, checkZ) == pCheckMtl)
|
|
return 1.0f;
|
|
|
|
Material* pMtl = m_pLevelSource->getMaterial(checkX, checkY, checkZ);
|
|
if (pMtl == pCheckMtl)
|
|
{
|
|
int data = m_pLevelSource->getData(checkX, checkY, checkZ);
|
|
if (data >= 8 || data == 0)
|
|
{
|
|
fHeight += LiquidTile::getWaterVolume(data) * 10.0f;
|
|
iBias += 10;
|
|
}
|
|
|
|
fHeight += LiquidTile::getWaterVolume(data);
|
|
iBias++;
|
|
continue;
|
|
}
|
|
|
|
if (!pMtl->isSolid())
|
|
{
|
|
fHeight++;
|
|
iBias++;
|
|
}
|
|
}
|
|
|
|
return 1.0f - fHeight / float(iBias);
|
|
}
|
|
|
|
bool TileRenderer::canRender(int renderShape)
|
|
{
|
|
return renderShape == SHAPE_SOLID || renderShape == SHAPE_STAIRS;
|
|
}
|
|
|
|
// @NOTE: This sucks! Very badly! But it's how they did it.
|
|
void TileRenderer::renderEast(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_l, texU_r, texV_u, texV_d;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.z < 0.0f || aabb.max.z > 1.0f)
|
|
{
|
|
texU_l = C_RATIO * (texX);
|
|
texU_r = C_RATIO * (texX + 15.99f);
|
|
}
|
|
// if flipping on the Z coordinate
|
|
else if (field_8)
|
|
{
|
|
texU_r = C_RATIO * (texX + aabb.min.z * 16);
|
|
texU_l = C_RATIO * (texX + aabb.max.z * 16 - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_l = C_RATIO * (texX + aabb.min.z * 16);
|
|
texU_r = C_RATIO * (texX + aabb.max.z * 16 - 0.01f);
|
|
}
|
|
|
|
if (aabb.min.y < 0.0f || aabb.max.y > 1.0f)
|
|
{
|
|
texV_u = C_RATIO * (texY);
|
|
texV_d = C_RATIO * (texY + 15.99f);
|
|
}
|
|
else
|
|
{
|
|
texV_u = C_RATIO * (texY + aabb.min.y * 16.0f);
|
|
texV_d = C_RATIO * (texY + aabb.max.y * 16.0f - 0.01f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_l, texV_d);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_r, texV_d);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_r, texV_u);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_l, texV_u);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_l, texV_d);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_r, texV_d);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_r, texV_u);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_l, texV_u);
|
|
}
|
|
|
|
void TileRenderer::renderWest(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_l, texU_r, texV_u, texV_d;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.z < 0.0f || aabb.max.z > 1.0f)
|
|
{
|
|
texU_l = C_RATIO * (texX);
|
|
texU_r = C_RATIO * (texX + 15.99f);
|
|
}
|
|
// if flipping on the Z coordinate
|
|
else if (field_8)
|
|
{
|
|
texU_r = C_RATIO * (texX + aabb.min.z * 16);
|
|
texU_l = C_RATIO * (texX + aabb.max.z * 16 - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_l = C_RATIO * (texX + aabb.min.z * 16);
|
|
texU_r = C_RATIO * (texX + aabb.max.z * 16 - 0.01f);
|
|
}
|
|
|
|
if (aabb.min.y < 0.0f || aabb.max.y>1.0f)
|
|
{
|
|
texV_u = C_RATIO * (texY);
|
|
texV_d = C_RATIO * (texY + 15.99f);
|
|
}
|
|
else
|
|
{
|
|
texV_u = C_RATIO * (texY + aabb.min.y * 16.0f);
|
|
texV_d = C_RATIO * (texY + aabb.max.y * 16.0f - 0.01f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_r, texV_u);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_l, texV_u);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_l, texV_d);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_r, texV_d);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_r, texV_u);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_l, texV_u);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_l, texV_d);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_r, texV_d);
|
|
}
|
|
|
|
void TileRenderer::renderSouth(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_l, texU_r, texV_u, texV_d;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.x < 0.0f || aabb.max.x > 1.0f)
|
|
{
|
|
texU_l = C_RATIO * (texX);
|
|
texU_r = C_RATIO * (texX + 15.99f);
|
|
}
|
|
// if flipping on the X coordinate
|
|
else if (field_8)
|
|
{
|
|
texU_r = C_RATIO * (texX + aabb.min.x * 16);
|
|
texU_l = C_RATIO * (texX + aabb.max.x * 16 - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_l = C_RATIO * (texX + aabb.min.x * 16);
|
|
texU_r = C_RATIO * (texX + aabb.max.x * 16 - 0.01f);
|
|
}
|
|
|
|
if (aabb.min.y < 0.0f || aabb.max.y>1.0f)
|
|
{
|
|
texV_u = C_RATIO * (texY);
|
|
texV_d = C_RATIO * (texY + 15.99f);
|
|
}
|
|
else
|
|
{
|
|
texV_u = C_RATIO * (texY + aabb.min.y * 16.0f);
|
|
texV_d = C_RATIO * (texY + aabb.max.y * 16.0f - 0.01f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_l, texV_u);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_l, texV_d);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_r, texV_d);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_r, texV_u);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_l, texV_u);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_l, texV_d);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_r, texV_d);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_r, texV_u);
|
|
}
|
|
|
|
void TileRenderer::renderNorth(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_l, texU_r, texV_u, texV_d;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.x < 0.0f || aabb.max.x > 1.0f)
|
|
{
|
|
texU_l = C_RATIO * (texX);
|
|
texU_r = C_RATIO * (texX + 15.99f);
|
|
}
|
|
// if flipping on the X coordinate
|
|
else if (field_8)
|
|
{
|
|
texU_r = C_RATIO * (texX + aabb.min.x * 16);
|
|
texU_l = C_RATIO * (texX + aabb.max.x * 16 - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_l = C_RATIO * (texX + aabb.min.x * 16);
|
|
texU_r = C_RATIO * (texX + aabb.max.x * 16 - 0.01f);
|
|
}
|
|
|
|
if (aabb.min.y < 0.0f || aabb.max.y>1.0f)
|
|
{
|
|
texV_u = C_RATIO * (texY);
|
|
texV_d = C_RATIO * (texY + 15.99f);
|
|
}
|
|
else
|
|
{
|
|
texV_u = C_RATIO * (texY + aabb.min.y * 16.0f);
|
|
texV_d = C_RATIO * (texY + aabb.max.y * 16.0f - 0.01f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_r, texV_u);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_l, texV_u);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_l, texV_d);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_r, texV_d);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_r, texV_u);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_l, texV_u);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_l, texV_d);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_r, texV_d);
|
|
}
|
|
|
|
void TileRenderer::renderFaceDown(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_1, texU_2, texV_1, texV_2;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.x >= 0.0f && aabb.max.x <= 1.0f)
|
|
{
|
|
texU_1 = C_RATIO * (texX + 16.0f * aabb.min.x);
|
|
texU_2 = C_RATIO * (texX + 16.0f * aabb.max.x - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_1 = C_RATIO * (texX);
|
|
texU_2 = C_RATIO * (texX + 15.99f);
|
|
}
|
|
|
|
if (aabb.min.z >= 0.0f && aabb.max.z <= 1.0f)
|
|
{
|
|
texV_1 = C_RATIO * (texY + 16.0f * aabb.min.z);
|
|
texV_2 = C_RATIO * (texY + 16.0f * aabb.max.z - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texV_1 = C_RATIO * (texY);
|
|
texV_2 = C_RATIO * (texY + 15.99f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_2, texV_2);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_2, texV_1);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_1, texV_1);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_1, texV_2);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.max.z + z, texU_2, texV_2);
|
|
t.vertexUV(aabb.max.x + x, aabb.max.y + y, aabb.min.z + z, texU_2, texV_1);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.min.z + z, texU_1, texV_1);
|
|
t.vertexUV(aabb.min.x + x, aabb.max.y + y, aabb.max.z + z, texU_1, texV_2);
|
|
}
|
|
|
|
void TileRenderer::renderFaceUp(Tile* tile, float x, float y, float z, int texture)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_1, texU_2, texV_1, texV_2;
|
|
|
|
AABB& aabb = tile->m_aabb;
|
|
|
|
if (aabb.min.x >= 0.0f && aabb.max.x <= 1.0f)
|
|
{
|
|
texU_1 = C_RATIO * (texX + 16.0f * aabb.min.x);
|
|
texU_2 = C_RATIO * (texX + 16.0f * aabb.max.x - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texU_1 = C_RATIO * (texX);
|
|
texU_2 = C_RATIO * (texX + 15.99f);
|
|
}
|
|
|
|
if (aabb.min.z >= 0.0f && aabb.max.z <= 1.0f)
|
|
{
|
|
texV_1 = C_RATIO * (texY + 16.0f * aabb.min.z);
|
|
texV_2 = C_RATIO * (texY + 16.0f * aabb.max.z - 0.01f);
|
|
}
|
|
else
|
|
{
|
|
texV_1 = C_RATIO * (texY);
|
|
texV_2 = C_RATIO * (texY + 15.99f);
|
|
}
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
if (m_bAmbientOcclusion)
|
|
{
|
|
t.color(m_vtxRed[0], m_vtxGreen[0], m_vtxBlue[0]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_1, texV_2);
|
|
t.color(m_vtxRed[1], m_vtxGreen[1], m_vtxBlue[1]);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_1, texV_1);
|
|
t.color(m_vtxRed[2], m_vtxGreen[2], m_vtxBlue[2]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_2, texV_1);
|
|
t.color(m_vtxRed[3], m_vtxGreen[3], m_vtxBlue[3]);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_2, texV_2);
|
|
return;
|
|
}
|
|
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.max.z + z, texU_1, texV_2);
|
|
t.vertexUV(aabb.min.x + x, aabb.min.y + y, aabb.min.z + z, texU_1, texV_1);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.min.z + z, texU_2, texV_1);
|
|
t.vertexUV(aabb.max.x + x, aabb.min.y + y, aabb.max.z + z, texU_2, texV_2);
|
|
}
|
|
|
|
void TileRenderer::tesselateCrossTexture(Tile* tile, int data, float x, float y, float z)
|
|
{
|
|
static constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
int texture = m_textureOverride;
|
|
if (texture < 0)
|
|
texture = tile->getTexture(DIR_YNEG, data);
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
// calculate U and V coordinates
|
|
float texU_l = texX * C_RATIO, texU_r = (texX + 15.99f) * C_RATIO;
|
|
float texV_u = texY * C_RATIO, texV_d = (texY + 15.99f) * C_RATIO;
|
|
|
|
float cenX = x + 0.5f, cenZ = z + 0.5f;
|
|
|
|
float x1 = cenX - 0.45f, x2 = cenX + 0.45f;
|
|
float z1 = cenZ - 0.45f, z2 = cenZ + 0.45f;
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
// face 1
|
|
t.vertexUV(x1, y + 1, z1, texU_l, texV_u);
|
|
t.vertexUV(x1, y + 0, z1, texU_l, texV_d);
|
|
t.vertexUV(x2, y + 0, z2, texU_r, texV_d);
|
|
t.vertexUV(x2, y + 1, z2, texU_r, texV_u);
|
|
|
|
// face 2
|
|
t.vertexUV(x2, y + 1, z2, texU_l, texV_u);
|
|
t.vertexUV(x2, y + 0, z2, texU_l, texV_d);
|
|
t.vertexUV(x1, y + 0, z1, texU_r, texV_d);
|
|
t.vertexUV(x1, y + 1, z1, texU_r, texV_u);
|
|
|
|
// face 3
|
|
t.vertexUV(x1, y + 1, z2, texU_l, texV_u);
|
|
t.vertexUV(x1, y + 0, z2, texU_l, texV_d);
|
|
t.vertexUV(x2, y + 0, z1, texU_r, texV_d);
|
|
t.vertexUV(x2, y + 1, z1, texU_r, texV_u);
|
|
|
|
// face 4
|
|
t.vertexUV(x2, y + 1, z1, texU_l, texV_u);
|
|
t.vertexUV(x2, y + 0, z1, texU_l, texV_d);
|
|
t.vertexUV(x1, y + 0, z2, texU_r, texV_d);
|
|
t.vertexUV(x1, y + 1, z2, texU_r, texV_u);
|
|
}
|
|
|
|
bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z, float r, float g, float b)
|
|
{
|
|
float topR = r, topG = g, topB = b;
|
|
|
|
if (tile == Tile::grass)
|
|
r = g = b = 1.0f;
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
float fLightHere = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
bool bDrewAnything = false;
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x, y - 1, z, DIR_YNEG))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x, y - 1, z);
|
|
t.color(r * 0.5f * fLight, g * 0.5f * fLight, b * 0.5f * fLight);
|
|
|
|
renderFaceUp(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YNEG));
|
|
}
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x, y + 1, z, DIR_YPOS))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x, y + 1, z);
|
|
if (tile->m_aabb.max.y != 1.0f && !tile->m_pMaterial->isLiquid())
|
|
fLight = fLightHere;
|
|
|
|
t.color(topR * fLight, topG * fLight, topB * fLight);
|
|
|
|
renderFaceDown(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YPOS));
|
|
}
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x, y, z - 1, DIR_ZNEG))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x, y, z - 1);
|
|
if (tile->m_aabb.min.z > 0.0f)
|
|
fLight = fLightHere;
|
|
|
|
t.color(r * 0.8f * fLight, g * 0.8f * fLight, b * 0.8f * fLight);
|
|
int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZNEG);
|
|
renderNorth(tile, float(x), float(y), float(z), texture);
|
|
|
|
if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0)
|
|
{
|
|
t.color(topR * 0.8f * fLight, topG * 0.8f * fLight, topB * 0.8f * fLight);
|
|
renderNorth(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
}
|
|
}
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x, y, z + 1, DIR_ZPOS))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x, y, z + 1);
|
|
if (tile->m_aabb.max.z < 1.0f)
|
|
fLight = fLightHere;
|
|
|
|
t.color(r * 0.8f * fLight, g * 0.8f * fLight, b * 0.8f * fLight);
|
|
int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZPOS);
|
|
renderSouth(tile, float(x), float(y), float(z), texture);
|
|
|
|
if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0)
|
|
{
|
|
t.color(topR * 0.8f * fLight, topG * 0.8f * fLight, topB * 0.8f * fLight);
|
|
renderSouth(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
}
|
|
}
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x - 1, y, z, DIR_XNEG))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x - 1, y, z);
|
|
if (tile->m_aabb.min.x > 0.0f)
|
|
fLight = fLightHere;
|
|
|
|
t.color(r * 0.6f * fLight, g * 0.6f * fLight, b * 0.6f * fLight);
|
|
int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XNEG);
|
|
renderWest(tile, float(x), float(y), float(z), texture);
|
|
|
|
if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0)
|
|
{
|
|
t.color(topR * 0.6f * fLight, topG * 0.6f * fLight, topB * 0.6f * fLight);
|
|
renderWest(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
}
|
|
}
|
|
|
|
if (m_bDisableCulling || tile->shouldRenderFace(m_pLevelSource, x + 1, y, z, DIR_XPOS))
|
|
{
|
|
bDrewAnything = true;
|
|
|
|
float fLight = tile->getBrightness(m_pLevelSource, x + 1, y, z);
|
|
if (tile->m_aabb.max.x < 1.0f)
|
|
fLight = fLightHere;
|
|
|
|
t.color(r * 0.6f * fLight, g * 0.6f * fLight, b * 0.6f * fLight);
|
|
int texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XPOS);
|
|
renderEast(tile, float(x), float(y), float(z), texture);
|
|
|
|
if (m_bFancyGrass && texture == TEXTURE_GRASS_SIDE && this->m_textureOverride < 0)
|
|
{
|
|
t.color(topR * 0.6f * fLight, topG * 0.6f * fLight, topB * 0.6f * fLight);
|
|
renderEast(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
}
|
|
}
|
|
|
|
return bDrewAnything;
|
|
}
|
|
|
|
bool TileRenderer::tesselateBlockInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
int color = getTileColor(tile, x, y, z);
|
|
|
|
float r = float(GET_RED (color)) / 255.0f;
|
|
float g = float(GET_GREEN(color)) / 255.0f;
|
|
float b = float(GET_BLUE (color)) / 255.0f;
|
|
|
|
if (Minecraft::useAmbientOcclusion)
|
|
{
|
|
#ifdef ENH_USE_OWN_AO
|
|
return tesselateBlockInWorldWithAmbienceOcclusionV2(tile, x, y, z, r, g, b);
|
|
#else
|
|
return tesselateBlockInWorldWithAmbienceOcclusion(tile, x, y, z, r, g, b);
|
|
#endif
|
|
}
|
|
|
|
return tesselateBlockInWorld(tile, x, y, z, r, g, b);
|
|
}
|
|
|
|
bool TileRenderer::tesselateCrossInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
float bright = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
t.color(bright, bright, bright);
|
|
|
|
tesselateCrossTexture(tile, m_pLevelSource->getData(x, y, z), float(x), float(y), float(z));
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TileRenderer::tesselateWaterInWorld(Tile* tile1, int x, int y, int z)
|
|
{
|
|
constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
LiquidTile* tile = (LiquidTile*)tile1;
|
|
bool bRenderFaceDown, bRenderFaceUp, bRenderSides[4];
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
bRenderFaceDown = tile->shouldRenderFace(m_pLevelSource, x, y + 1, z, DIR_YPOS);
|
|
bRenderFaceUp = tile->shouldRenderFace(m_pLevelSource, x, y - 1, z, DIR_YNEG);
|
|
|
|
bRenderSides[0] = tile->shouldRenderFace(m_pLevelSource, x, y, z - 1, DIR_ZNEG);
|
|
bRenderSides[1] = tile->shouldRenderFace(m_pLevelSource, x, y, z + 1, DIR_ZPOS);
|
|
bRenderSides[2] = tile->shouldRenderFace(m_pLevelSource, x - 1, y, z, DIR_XNEG);
|
|
bRenderSides[3] = tile->shouldRenderFace(m_pLevelSource, x + 1, y, z, DIR_XPOS);
|
|
|
|
if (!bRenderFaceDown &&
|
|
!bRenderFaceUp &&
|
|
!bRenderSides[0] &&
|
|
!bRenderSides[1] &&
|
|
!bRenderSides[2] &&
|
|
!bRenderSides[3])
|
|
return false;
|
|
|
|
int tileData = m_pLevelSource->getData(x, y, z);
|
|
float
|
|
fHeight1 = getWaterHeight(x, y, z, tile->m_pMaterial),
|
|
fHeight2 = getWaterHeight(x, y, z + 1, tile->m_pMaterial),
|
|
fHeight3 = getWaterHeight(x + 1, y, z + 1, tile->m_pMaterial),
|
|
fHeight4 = getWaterHeight(x + 1, y, z, tile->m_pMaterial);
|
|
|
|
// @TODO: fix gotos
|
|
bool bFlag1, bFlag2;
|
|
if (!m_bDisableCulling)
|
|
{
|
|
bFlag1 = bRenderFaceDown;
|
|
if (!bRenderFaceDown)
|
|
{
|
|
if (!bRenderFaceUp)
|
|
goto label_8;
|
|
|
|
goto label_6;
|
|
}
|
|
}
|
|
|
|
{
|
|
// @NOTE: Have to use tile1 because for whatever reason MSVC doesn't think an overload
|
|
// for `tile` exists that takes 2 int arguments
|
|
int texFaceDown = tile->getTexture(DIR_YPOS, tileData);
|
|
float slopeAngle = tile->getSlopeAngle(m_pLevelSource, x, y, z, tile->m_pMaterial);
|
|
|
|
int texX, texY;
|
|
|
|
if (slopeAngle > -999.0f)
|
|
{
|
|
int texNorth = tile->getTexture(DIR_ZNEG, tileData);
|
|
texX = texNorth & 0xF0;
|
|
texY = (texNorth & 0xF) * 16;
|
|
}
|
|
else
|
|
{
|
|
texX = texFaceDown & 0xF0;
|
|
texY = (texFaceDown & 0xF) * 16;
|
|
}
|
|
|
|
float texUV_1, texUV_2, texUV_3, texUV_4, texUV_5, texUV_6, texUV_7, texUV_8;
|
|
if (slopeAngle >= -999.0f)
|
|
{
|
|
texUV_1 = float(texY + 16) * C_RATIO;
|
|
texUV_2 = float(texX + 16) * C_RATIO;
|
|
}
|
|
else
|
|
{
|
|
slopeAngle = 0.0f;
|
|
texUV_1 = float(texY + 8) * C_RATIO;
|
|
texUV_2 = float(texX + 8) * C_RATIO;
|
|
}
|
|
|
|
texUV_3 = C_RATIO * 8.0f * Mth::sin(slopeAngle);
|
|
texUV_4 = C_RATIO * 8.0f * Mth::cos(slopeAngle);
|
|
|
|
float bright = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
texUV_5 = texUV_1 - texUV_4;
|
|
texUV_6 = texUV_2 - texUV_4;
|
|
|
|
t.color(bright, bright, bright);
|
|
texUV_7 = texUV_2 + texUV_4;
|
|
texUV_8 = texUV_1 + texUV_4;
|
|
|
|
t.vertexUV(x + 0.0f, y + fHeight1, z + 0.0f, (texUV_1 - texUV_4) - texUV_3, texUV_6 + texUV_3);
|
|
t.vertexUV(x + 0.0f, y + fHeight2, z + 1.0f, texUV_3 + texUV_5, texUV_7 + texUV_3);
|
|
t.vertexUV(x + 1.0f, y + fHeight3, z + 1.0f, texUV_8 + texUV_3, texUV_7 - texUV_3);
|
|
t.vertexUV(x + 1.0f, y + fHeight4, z + 0.0f, texUV_8 - texUV_3, texUV_6 - texUV_3);
|
|
}
|
|
|
|
if (m_bDisableCulling)
|
|
goto label_7;
|
|
|
|
bFlag1 = true;
|
|
if (bRenderFaceUp)
|
|
{
|
|
label_6:
|
|
label_7:
|
|
float bright = tile->getBrightness(m_pLevelSource, x, y - 1, z);
|
|
t.color(bright * 0.5f, bright * 0.5f, bright * 0.5f);
|
|
renderFaceUp(tile1, float(x), float(y), float(z), tile->getTexture(DIR_YNEG));
|
|
bFlag1 = true;
|
|
}
|
|
|
|
label_8:
|
|
bFlag2 = bFlag1;
|
|
//bool bRenderedSides = false;
|
|
|
|
for (int dir = 0; dir < 4; dir++)
|
|
{
|
|
int checkX = x, checkZ = z;
|
|
switch (dir)
|
|
{
|
|
case 0: checkZ--; break;
|
|
case 1: checkZ++; break;
|
|
case 2: checkX--; break;
|
|
case 3: checkX++; break;
|
|
}
|
|
|
|
int texture = tile1->getTexture(dir + DIR_ZNEG, tileData);
|
|
if (!m_bDisableCulling && !bRenderSides[dir])
|
|
continue;
|
|
|
|
float vtxX1, vtxX2, vtxZ1, vtxZ2, height1, height2;
|
|
switch (dir)
|
|
{
|
|
case 0:
|
|
{
|
|
vtxX1 = float(x);
|
|
vtxX2 = float(x + 1);
|
|
vtxZ1 = float(z);
|
|
vtxZ2 = float(z);
|
|
height1 = fHeight1;
|
|
height2 = fHeight4;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
vtxX1 = float(x + 1);
|
|
vtxX2 = float(x);
|
|
vtxZ1 = float(z + 1);
|
|
vtxZ2 = float(z + 1);
|
|
height1 = fHeight3;
|
|
height2 = fHeight2;
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
vtxX1 = float(x);
|
|
vtxX2 = float(x);
|
|
vtxZ1 = float(z + 1);
|
|
vtxZ2 = float(z);
|
|
height1 = fHeight2;
|
|
height2 = fHeight1;
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
vtxX1 = float(x + 1);
|
|
vtxX2 = float(x + 1);
|
|
vtxZ1 = float(z);
|
|
vtxZ2 = float(z + 1);
|
|
height1 = fHeight4;
|
|
height2 = fHeight3;
|
|
break;
|
|
}
|
|
}
|
|
|
|
float texU_1, texU_2, texV_1, texV_2, texV_3;
|
|
|
|
int texX = (texture & 0xF) * 16;
|
|
int texY = (texture >> 4) * 16;
|
|
texU_1 = C_RATIO * float(texX);
|
|
texU_2 = C_RATIO * (float(texX) + 15.99f);
|
|
texV_1 = C_RATIO * (float(texY) + (1.0f - height1) * 16.0f);
|
|
texV_2 = C_RATIO * (float(texY) + (1.0f - height2) * 16.0f);
|
|
texV_3 = C_RATIO * (float(texY + 16.0f) - 0.01f);
|
|
bFlag2 = true;
|
|
//bRenderedSides = true;
|
|
|
|
float brightMul = dir >= DIR_XNEG ? 0.6f : 0.8f;
|
|
float bright = tile->getBrightness(m_pLevelSource, checkX, y, checkZ);
|
|
t.color(bright* brightMul, bright* brightMul, bright* brightMul);
|
|
t.vertexUV(vtxX1, float(y) + height1, vtxZ1, texU_1, texV_1);
|
|
t.vertexUV(vtxX2, float(y) + height2, vtxZ2, texU_2, texV_2);
|
|
t.vertexUV(vtxX2, float(y) + 0.0f, vtxZ2, texU_2, texV_3);
|
|
t.vertexUV(vtxX1, float(y) + 0.0f, vtxZ1, texU_1, texV_3);
|
|
}
|
|
|
|
tile->m_aabb.min.y = 0.0f;
|
|
tile->m_aabb.max.y = 1.0f;
|
|
|
|
return bFlag2;
|
|
}
|
|
|
|
#ifdef ENH_FIX_INVIS_STAIRS
|
|
#define PROC_RESULT(x) bRenderedAnything = (x) || bRenderedAnything;
|
|
#else
|
|
#define PROC_RESULT(x) (x)
|
|
#endif
|
|
|
|
bool TileRenderer::tesselateStairsInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
bool bRenderedAnything = false;
|
|
|
|
switch (m_pLevelSource->getData(x, y, z))
|
|
{
|
|
case 0:
|
|
{
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
tile->setShape(0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 0.5f, 1.0f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
tile->setShape(0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
tile->setShape(0.0f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
tile->setShape(0.0f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f);
|
|
PROC_RESULT(tesselateBlockInWorld(tile, x, y, z));
|
|
break;
|
|
}
|
|
}
|
|
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
// @BUG: In a chunk that only contains stairs, everything will be invisible, because this
|
|
// function returns 0.
|
|
return bRenderedAnything;
|
|
}
|
|
|
|
bool TileRenderer::tesselateDoorInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
Tesselator& t = Tesselator::instance;
|
|
float fBrightHere = tile->getBrightness(m_pLevelSource, x, y, z), fBright;
|
|
int texture;
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x, y - 1, z);
|
|
if (tile->m_aabb.min.y > 0.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright * 0.5f, fBright * 0.5f, fBright * 0.5f);
|
|
renderFaceUp(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YNEG));
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x, y + 1, z);
|
|
if (tile->m_aabb.max.y < 1.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright, fBright, fBright);
|
|
renderFaceDown(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YPOS));
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x, y, z - 1);
|
|
if (tile->m_aabb.min.z > 0.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright * 0.8f, fBright * 0.8f, fBright * 0.8f);
|
|
texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZNEG);
|
|
if (texture < 0) texture = -texture, field_8 = true;
|
|
renderNorth(tile, float(x), float(y), float(z), texture);
|
|
field_8 = false;
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x, y, z + 1);
|
|
if (tile->m_aabb.max.z < 1.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright * 0.8f, fBright * 0.8f, fBright * 0.8f);
|
|
texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_ZPOS);
|
|
if (texture < 0) texture = -texture, field_8 = true;
|
|
renderSouth(tile, float(x), float(y), float(z), texture);
|
|
field_8 = false;
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x - 1, y, z);
|
|
if (tile->m_aabb.min.x > 0.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright * 0.6f, fBright * 0.6f, fBright * 0.6f);
|
|
texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XNEG);
|
|
if (texture < 0) texture = -texture, field_8 = true;
|
|
renderWest(tile, float(x), float(y), float(z), texture);
|
|
field_8 = false;
|
|
|
|
fBright = tile->getBrightness(m_pLevelSource, x + 1, y, z);
|
|
if (tile->m_aabb.max.x < 1.0f) fBright = fBrightHere;
|
|
if (Tile::lightEmission[tile->m_ID]) fBright = 1.0f;
|
|
t.color(fBright * 0.6f, fBright * 0.6f, fBright * 0.6f);
|
|
texture = tile->getTexture(m_pLevelSource, x, y, z, DIR_XPOS);
|
|
if (texture < 0) texture = -texture, field_8 = true;
|
|
renderEast(tile, float(x), float(y), float(z), texture);
|
|
field_8 = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void TileRenderer::tesselateTorch(Tile* tile, float x, float y, float z, float a, float b)
|
|
{
|
|
constexpr float C_RATIO = 1.0f / 256.0f;
|
|
constexpr float C_ONE_PIXEL = 1.0f / 16.0f;
|
|
constexpr float C_HALF_TILE = 1.0f / 2.0f;
|
|
constexpr float C_UNK_1 = 0.375f;
|
|
|
|
int texture = tile->getTexture(DIR_YNEG);
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
// @TODO: Clean up a bit
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_1 = texX * C_RATIO;
|
|
float texU_2 = (texX + 15.99f) * C_RATIO;
|
|
float texV_1 = (texY * C_RATIO) + 1.0f / 32.0f;
|
|
float texV_2 = (texY + 15.99f) * C_RATIO;
|
|
|
|
float x1 = x + 0.5f, z1 = z + 0.5f;
|
|
float z2 = z1 + (float)(b * C_UNK_1);
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
float x_1 = (x1 + (a * C_UNK_1)) - C_ONE_PIXEL;
|
|
float x_2 = (x1 + (a * C_UNK_1)) + C_ONE_PIXEL;
|
|
float x_3 = x1 - C_ONE_PIXEL;
|
|
float x_4 = x1 + C_ONE_PIXEL;
|
|
float x_5 = x1 - C_HALF_TILE;
|
|
float x_6 = x1 + C_HALF_TILE;
|
|
float x_7 = x_6 + a;
|
|
float x_8 = x_3 + a;
|
|
float x_9 = x_4 + a;
|
|
float x_0 = x_5 + a;
|
|
|
|
float y_1 = y + C_ONE_PIXEL * 10.0f;
|
|
float y_2 = y + 1.0f;
|
|
float y_3 = y + 0.0f;
|
|
|
|
float z_1 = z2 - C_ONE_PIXEL;
|
|
float z_2 = z2 + C_ONE_PIXEL;
|
|
float z_3 = z1 - 0.5f;
|
|
float z_4 = z1 + 0.5f;
|
|
float z_5 = z1 - C_ONE_PIXEL;
|
|
float z_6 = z1 + C_ONE_PIXEL;
|
|
float z_7 = z_3 + b;
|
|
float z_8 = z_4 + b;
|
|
float z_9 = z_5 + b;
|
|
float z_0 = z_6 + b;
|
|
|
|
float texU_3 = texU_1 + 0.027344f;
|
|
float texU_4 = texU_1 + 0.035156f;
|
|
float texV_3 = texY * C_RATIO;
|
|
float texV_4 = texY * C_RATIO + 0.023438f;
|
|
|
|
t.vertexUV(x_1, y_1, z_1, texU_3, texV_4);
|
|
t.vertexUV(x_1, y_1, z_2, texU_3, texV_1);
|
|
t.vertexUV(x_2, y_1, z_2, texU_4, texV_1);
|
|
t.vertexUV(x_2, y_1, z_1, texU_4, texV_4);
|
|
t.vertexUV(x_3, y_2, z_3, texU_1, texV_3);
|
|
t.vertexUV(x_8, y_3, z_7, texU_1, texV_2);
|
|
t.vertexUV(x_8, y_3, z_8, texU_2, texV_2);
|
|
t.vertexUV(x_3, y_2, z_4, texU_2, texV_3);
|
|
t.vertexUV(x_4, y_2, z_4, texU_1, texV_3);
|
|
t.vertexUV(x_9, y_3, z_8, texU_1, texV_2);
|
|
t.vertexUV(x_9, y_3, z_7, texU_2, texV_2);
|
|
t.vertexUV(x_4, y_2, z_3, texU_2, texV_3);
|
|
t.vertexUV(x_5, y_2, z_6, texU_1, texV_3);
|
|
t.vertexUV(x_0, y_3, z_0, texU_1, texV_2);
|
|
t.vertexUV(x_7, y_3, z_0, texU_2, texV_2);
|
|
t.vertexUV(x_6, y_2, z_6, texU_2, texV_3);
|
|
t.vertexUV(x_6, y_2, z_5, texU_1, texV_3);
|
|
t.vertexUV(x_7, y_3, z_9, texU_1, texV_2);
|
|
t.vertexUV(x_0, y_3, z_9, texU_2, texV_2);
|
|
t.vertexUV(x_5, y_2, z_5, texU_2, texV_3);
|
|
}
|
|
|
|
bool TileRenderer::tesselateTorchInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
int data = m_pLevelSource->getData(x, y, z);
|
|
float bright = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
if (Tile::lightEmission[tile->m_ID] > 0)
|
|
bright = 1.0f;
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
t.color(bright, bright, bright);
|
|
|
|
switch (data)
|
|
{
|
|
case 1:
|
|
tesselateTorch(tile, float(x) - 0.1f, float(y) + 0.2f, float(z), -0.4f, 0.0f);
|
|
break;
|
|
case 2:
|
|
tesselateTorch(tile, float(x) + 0.1f, float(y) + 0.2f, float(z), 0.4f, 0.0f);
|
|
break;
|
|
case 3:
|
|
tesselateTorch(tile, float(x), float(y) + 0.2f, float(z) - 0.1f, 0.0f, -0.4f);
|
|
break;
|
|
case 4:
|
|
tesselateTorch(tile, float(x), float(y) + 0.2f, float(z) + 0.1f, 0.0f, 0.4f);
|
|
break;
|
|
default:
|
|
tesselateTorch(tile, float(x), float(y), float(z), 0.0f, 0.0f);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TileRenderer::tesselateLadderInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
int texture = tile->getTexture(DIR_YNEG);
|
|
|
|
if (m_textureOverride >= 0)
|
|
texture = m_textureOverride;
|
|
|
|
float bright = m_pLevelSource->getBrightness(x, y, z);
|
|
t.color(bright, bright, bright);
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_1 = C_RATIO * texX;
|
|
float texU_2 = C_RATIO * (texX + 15.99f);
|
|
float texV_1 = C_RATIO * texY;
|
|
float texV_2 = C_RATIO * (texY + 15.99f);
|
|
|
|
switch (m_pLevelSource->getData(x, y, z))
|
|
{
|
|
case 2:
|
|
t.vertexUV(float(x + 1), float(y + 1), float(z + 1) - 0.05f, texU_1, texV_1);
|
|
t.vertexUV(float(x + 1), float(y + 0), float(z + 1) - 0.05f, texU_1, texV_2);
|
|
t.vertexUV(float(x + 0), float(y + 0), float(z + 1) - 0.05f, texU_2, texV_2);
|
|
t.vertexUV(float(x + 0), float(y + 1), float(z + 1) - 0.05f, texU_2, texV_1);
|
|
break;
|
|
case 3:
|
|
t.vertexUV(float(x + 1), float(y + 0), float(z) + 0.05f, texU_2, texV_2);
|
|
t.vertexUV(float(x + 1), float(y + 1), float(z) + 0.05f, texU_2, texV_1);
|
|
t.vertexUV(float(x + 0), float(y + 1), float(z) + 0.05f, texU_1, texV_1);
|
|
t.vertexUV(float(x + 0), float(y + 0), float(z) + 0.05f, texU_1, texV_2);
|
|
break;
|
|
case 4:
|
|
t.vertexUV(float(x + 1) - 0.05f, float(y + 0), float(z + 1), texU_2, texV_2);
|
|
t.vertexUV(float(x + 1) - 0.05f, float(y + 1), float(z + 1), texU_2, texV_1);
|
|
t.vertexUV(float(x + 1) - 0.05f, float(y + 1), float(z + 0), texU_1, texV_1);
|
|
t.vertexUV(float(x + 1) - 0.05f, float(y + 0), float(z + 0), texU_1, texV_2);
|
|
break;
|
|
case 5:
|
|
t.vertexUV(float(x) + 0.05f, float(y + 1), float(z + 1), texU_1, texV_1);
|
|
t.vertexUV(float(x) + 0.05f, float(y + 0), float(z + 1), texU_1, texV_2);
|
|
t.vertexUV(float(x) + 0.05f, float(y + 0), float(z + 0), texU_2, texV_2);
|
|
t.vertexUV(float(x) + 0.05f, float(y + 1), float(z + 0), texU_2, texV_1);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TileRenderer::tesselateFireInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
constexpr float C_RATIO = 1.0f / 256.0f;
|
|
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
int texture = tile->getTexture(DIR_YNEG);
|
|
float bright = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
t.color(bright, bright, bright);
|
|
|
|
FireTile* pFireTile = (FireTile*)Tile::fire;
|
|
|
|
float texX = float(16 * (texture % 16));
|
|
float texY = float(16 * (texture / 16));
|
|
|
|
float texU_1 = C_RATIO * (texX);
|
|
float texU_2 = C_RATIO * (texX + 15.99f);
|
|
float texV_1 = C_RATIO * (texY);
|
|
float texV_2 = C_RATIO * (texY + 15.99f);
|
|
float xf = float(x), yf = float(y), zf = float(z);
|
|
|
|
if (m_pLevelSource->isSolidTile(x, y - 1, z) || pFireTile->canBurn(m_pLevelSource, x, y - 1, z))
|
|
{
|
|
t.vertexUV(xf + 0.5f - 0.3f, yf + 1.4f, zf + 1.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.5f + 0.2f, yf + 0.0f, zf + 1.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.5f + 0.2f, yf + 0.0f, zf + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.5f - 0.3f, yf + 1.4f, zf + 0.0f, texU_1, texV_1);
|
|
|
|
t.vertexUV(xf + 0.5f + 0.3f, yf + 1.4f, zf + 0.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.5f - 0.2f, yf + 0.0f, zf + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.5f - 0.2f, yf + 0.0f, zf + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.5f + 0.3f, yf + 1.4f, zf + 1.0f, texU_1, texV_1);
|
|
|
|
t.vertexUV(xf + 1.0f, yf + 1.4f, zf + 0.5f + 0.3f, texU_2, texV_1);
|
|
t.vertexUV(xf + 1.0f, yf + 0.0f, zf + 0.5f - 0.2f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.0f, yf + 0.0f, zf + 0.5f - 0.2f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.0f, yf + 1.4f, zf + 0.5f + 0.3f, texU_1, texV_1);
|
|
|
|
t.vertexUV(xf + 0.0f, yf + 1.4f, zf + 0.5f - 0.3f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.0f, yf + 0.0f, zf + 0.5f + 0.2f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f, yf + 0.0f, zf + 0.5f + 0.2f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f, yf + 1.4f, zf + 0.5f - 0.3f, texU_1, texV_1);
|
|
|
|
t.vertexUV(xf + 0.5f - 0.4f, yf + 1.4f, zf + 0.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 0.5f - 0.5f, yf + 0.0f, zf + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.5f - 0.5f, yf + 0.0f, zf + 1.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.5f - 0.4f, yf + 1.4f, zf + 1.0f, texU_2, texV_1);
|
|
|
|
t.vertexUV(xf + 0.5f + 0.4f, yf + 1.4f, zf + 1.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 0.5f + 0.5f, yf + 0.0f, zf + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.5f + 0.5f, yf + 0.0f, zf + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.5f + 0.4f, yf + 1.4f, zf + 0.0f, texU_2, texV_1);
|
|
|
|
t.vertexUV(xf + 0.0f, yf + 1.4f, zf + 0.5f + 0.4f, texU_1, texV_1);
|
|
t.vertexUV(xf + 0.0f, yf + 0.0f, zf + 0.5f + 0.5f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f, yf + 0.0f, zf + 0.5f + 0.5f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f, yf + 1.4f, zf + 0.5f + 0.4f, texU_2, texV_1);
|
|
|
|
t.vertexUV(xf + 1.0f, yf + 1.4f, zf + 0.5f - 0.4f, texU_1, texV_1);
|
|
t.vertexUV(xf + 1.0f, yf + 0.0f, zf + 0.5f - 0.5f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.0f, yf + 0.0f, zf + 0.5f - 0.5f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.0f, yf + 1.4f, zf + 0.5f - 0.4f, texU_2, texV_1);
|
|
|
|
return true;
|
|
}
|
|
|
|
if (((y / 2 + x / 2 + z / 2) & 1) == 0)
|
|
std::swap(texU_1, texU_2);
|
|
|
|
if (pFireTile->canBurn(m_pLevelSource, x - 1, y, z))
|
|
{
|
|
t.vertexUV(xf + 0.2f, (yf + 1.4f) + 0.0625f, zf + 1.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 0.0f, (yf + 0.0f) + 0.0625f, zf + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.0f, (yf + 0.0f) + 0.0625f, zf + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.2f, (yf + 1.4f) + 0.0625f, zf + 0.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.2f, (yf + 1.4f) + 0.0625f, zf + 0.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.0f, (yf + 0.0f) + 0.0625f, zf + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.0f, (yf + 0.0f) + 0.0625f, zf + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.2f, (yf + 1.4f) + 0.0625f, zf + 1.0f, texU_1, texV_1);
|
|
}
|
|
|
|
if (pFireTile->canBurn(m_pLevelSource, x + 1, y, z))
|
|
{
|
|
t.vertexUV(xf + 1.0f - 0.2f, (y + 1.4f) + 0.0625f, z + 0.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 1.0f + 0.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f + 0.0f, (y + 0.0f) + 0.0625f, z + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f - 0.2f, (y + 1.4f) + 0.0625f, z + 1.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 1.0f - 0.2f, (y + 1.4f) + 0.0625f, z + 1.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 1.0f + 0.0f, (y + 0.0f) + 0.0625f, z + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f + 0.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f - 0.2f, (y + 1.4f) + 0.0625f, z + 0.0f, texU_2, texV_1);
|
|
}
|
|
|
|
if (pFireTile->canBurn(m_pLevelSource, x, y, z - 1))
|
|
{
|
|
t.vertexUV(x + 0.0f, (y + 1.4f) + 0.0625f, z + 0.2f, texU_1, texV_1);
|
|
t.vertexUV(x + 0.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(x + 1.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(x + 1.0f, (y + 1.4f) + 0.0625f, z + 0.2f, texU_2, texV_1);
|
|
t.vertexUV(x + 1.0f, (y + 1.4f) + 0.0625f, z + 0.2f, texU_2, texV_1);
|
|
t.vertexUV(x + 1.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(x + 0.0f, (y + 0.0f) + 0.0625f, z + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(x + 0.0f, (y + 1.4f) + 0.0625f, z + 0.2f, texU_1, texV_1);
|
|
}
|
|
|
|
if (pFireTile->canBurn(m_pLevelSource, x, y, z + 1))
|
|
{
|
|
t.vertexUV(x + 1.0f, (y + 1.4f) + 0.0625f, z + 1.0f - 0.2f, texU_2, texV_1);
|
|
t.vertexUV(x + 1.0f, (y + 0.0f) + 0.0625f, z + 1.0f + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(x + 0.0f, (y + 0.0f) + 0.0625f, z + 1.0f + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(x + 0.0f, (y + 1.4f) + 0.0625f, z + 1.0f - 0.2f, texU_1, texV_1);
|
|
t.vertexUV(x + 0.0f, (y + 1.4f) + 0.0625f, z + 1.0f - 0.2f, texU_1, texV_1);
|
|
t.vertexUV(x + 0.0f, (y + 0.0f) + 0.0625f, z + 1.0f + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(x + 1.0f, (y + 0.0f) + 0.0625f, z + 1.0f + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(x + 1.0f, (y + 1.4f) + 0.0625f, z + 1.0f - 0.2f, texU_2, texV_1);
|
|
}
|
|
|
|
if (pFireTile->canBurn(m_pLevelSource, x, y + 1, z))
|
|
{
|
|
// @NOTE: Converting z and x to uint8_t for whatever reason
|
|
if (((uint8_t(z) + uint8_t(x) + y + 1) & 1) != 0)
|
|
{
|
|
float y1f = float(y + 1);
|
|
t.vertexUV(xf + 0.0f, y1f - 0.2f, zf + 0.5f + 0.5f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.0f, y1f + 0.0f, zf + 0.5f - 0.5f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f, y1f + 0.0f, zf + 0.5f - 0.5f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f, y1f - 0.2f, zf + 0.5f + 0.5f, texU_1, texV_1);
|
|
t.vertexUV(xf + 1.0f, y1f - 0.2f, zf + 0.5f - 0.5f, texU_2, texV_1);
|
|
t.vertexUV(xf + 1.0f, y1f + 0.0f, zf + 0.5f + 0.5f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.0f, y1f + 0.0f, zf + 0.5f + 0.5f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.0f, y1f - 0.2f, zf + 0.5f - 0.5f, texU_1, texV_1);
|
|
}
|
|
else
|
|
{
|
|
float y1f = float(y + 1);
|
|
t.vertexUV(xf + 0.0f, y1f - 0.2f, zf + 0.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 1.0f, y1f + 0.0f, zf + 0.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 1.0f, y1f + 0.0f, zf + 1.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 0.0f, y1f - 0.2f, zf + 1.0f, texU_1, texV_1);
|
|
t.vertexUV(xf + 1.0f, y1f - 0.2f, zf + 1.0f, texU_2, texV_1);
|
|
t.vertexUV(xf + 0.0f, y1f + 0.0f, zf + 1.0f, texU_2, texV_2);
|
|
t.vertexUV(xf + 0.0f, y1f + 0.0f, zf + 0.0f, texU_1, texV_2);
|
|
t.vertexUV(xf + 1.0f, y1f - 0.2f, zf + 0.0f, texU_1, texV_1);
|
|
}
|
|
}
|
|
|
|
// @NOTE: Returning true when you may not necessarily have rendered something?
|
|
return true;
|
|
}
|
|
|
|
bool TileRenderer::tesselateInWorld(Tile* tile, int x, int y, int z)
|
|
{
|
|
int shape = tile->getRenderShape();
|
|
tile->updateShape(m_pLevelSource, x, y, z);
|
|
|
|
switch (shape)
|
|
{
|
|
// @NOTE: In the original Minecraft PE, if a shape is undefined, the tile is invisible.
|
|
// @NOTE: In v0.1.0, fire is invisible.
|
|
#ifndef ORIGINAL_CODE
|
|
case SHAPE_NONE:
|
|
return false;
|
|
case SHAPE_FIRE:
|
|
return tesselateFireInWorld(tile, x, y, z);
|
|
default:
|
|
#endif
|
|
case SHAPE_SOLID:
|
|
return tesselateBlockInWorld(tile, x, y, z);
|
|
case SHAPE_WATER:
|
|
return tesselateWaterInWorld(tile, x, y, z);
|
|
case SHAPE_CROSS:
|
|
return tesselateCrossInWorld(tile, x, y, z);
|
|
case SHAPE_TORCH:
|
|
return tesselateTorchInWorld(tile, x, y, z);
|
|
case SHAPE_LADDER:
|
|
return tesselateLadderInWorld(tile, x, y, z);
|
|
case SHAPE_DOOR:
|
|
return tesselateDoorInWorld(tile, x, y, z);
|
|
case SHAPE_STAIRS:
|
|
return tesselateStairsInWorld(tile, x, y, z);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool TileRenderer::tesselateInWorldNoCulling(Tile* tile, int x, int y, int z)
|
|
{
|
|
m_bDisableCulling = true;
|
|
bool r = tesselateInWorld(tile, x, y, z);
|
|
m_bDisableCulling = false;
|
|
return r;
|
|
}
|
|
|
|
bool TileRenderer::tesselateInWorld(Tile* tile, int x, int y, int z, int a)
|
|
{
|
|
m_textureOverride = a;
|
|
bool r = tesselateInWorld(tile, x, y, z);
|
|
m_textureOverride = -1;
|
|
return r;
|
|
}
|
|
|
|
bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion(Tile* a2, int a3, int a4, int a5, float a6, float a7, float a8)
|
|
{
|
|
float v12; // r0
|
|
LevelSource* v13; // r1
|
|
float v14; // r0
|
|
LevelSource* v15; // r1
|
|
float v16; // r0
|
|
LevelSource* v17; // r1
|
|
float v18; // r0
|
|
LevelSource* v19; // r1
|
|
float v20; // r0
|
|
LevelSource* v21; // r1
|
|
float v22; // r0
|
|
LevelSource* v23; // r1
|
|
char v24; // r3
|
|
LevelSource* v25; // r0
|
|
char v26; // r3
|
|
LevelSource* v27; // r0
|
|
char v28; // r3
|
|
LevelSource* v29; // r0
|
|
char v30; // r3
|
|
LevelSource* v31; // r0
|
|
char v32; // r3
|
|
LevelSource* v33; // r0
|
|
char v34; // r3
|
|
LevelSource* v35; // r0
|
|
char v36; // r3
|
|
LevelSource* v37; // r0
|
|
char v38; // r3
|
|
LevelSource* v39; // r0
|
|
char v40; // r3
|
|
LevelSource* v41; // r0
|
|
char v42; // r3
|
|
LevelSource* v43; // r0
|
|
char v44; // r3
|
|
LevelSource* v45; // r0
|
|
int v46; // r8
|
|
float v47; // r0
|
|
LevelSource* v48; // r1
|
|
float v49; // r0
|
|
LevelSource* v50; // r1
|
|
float v51; // r0
|
|
LevelSource* v52; // r1
|
|
float v53; // r0
|
|
bool v54; // r3
|
|
float v55; // s12
|
|
float v56; // s11
|
|
float v57; // s8
|
|
float v58; // s14
|
|
float v59; // s13
|
|
float v60; // s9
|
|
float v61; // s10
|
|
float v62; // s13
|
|
float v63; // s11
|
|
float v64; // s10
|
|
float v65; // s14
|
|
float v66; // s15
|
|
float v67; // s12
|
|
LevelSource* v68; // r1
|
|
int v69; // r8
|
|
int v70; // r0
|
|
float v71; // r0
|
|
LevelSource* v72; // r1
|
|
float v73; // r0
|
|
LevelSource* v74; // r1
|
|
float v75; // r0
|
|
LevelSource* v76; // r1
|
|
float v77; // r0
|
|
bool v78; // r3
|
|
float v79; // s13
|
|
float v80; // s10
|
|
float v81; // s9
|
|
float v82; // s11
|
|
float v83; // s12
|
|
float v84; // s15
|
|
float v85; // s12
|
|
float v86; // s10
|
|
float v87; // s15
|
|
float v88; // s13
|
|
float v89; // s14
|
|
LevelSource* v90; // r1
|
|
int v91; // r0
|
|
float v92; // r0
|
|
LevelSource* v93; // r1
|
|
float v94; // r0
|
|
LevelSource* v95; // r1
|
|
float v96; // r0
|
|
LevelSource* v97; // r1
|
|
float v98; // r0
|
|
bool v99; // r3
|
|
float v100; // s13
|
|
float v101; // s11
|
|
float v102; // s8
|
|
float v103; // s14
|
|
float v104; // s12
|
|
float v105; // s10
|
|
float v106; // s11
|
|
float v107; // s12
|
|
float v108; // s9
|
|
float v109; // s10
|
|
float v110; // s11
|
|
float v111; // s13
|
|
float v112; // s15
|
|
float v113; // s14
|
|
float v114; // s12
|
|
LevelSource* v115; // r1
|
|
int v116; // r0
|
|
float v117; // r0
|
|
LevelSource* v118; // r1
|
|
float v119; // r0
|
|
LevelSource* v120; // r1
|
|
float v121; // r0
|
|
LevelSource* v122; // r1
|
|
float v123; // r0
|
|
bool v124; // r3
|
|
float v125; // s15
|
|
float v126; // s11
|
|
float v127; // s8
|
|
float v128; // s12
|
|
float v129; // s13
|
|
float v130; // s9
|
|
float v131; // s10
|
|
float v132; // s13
|
|
float v133; // s11
|
|
float v134; // s10
|
|
float v135; // s15
|
|
float v136; // s14
|
|
float v137; // s12
|
|
LevelSource* v138; // r1
|
|
int v139; // r0
|
|
float v140; // r0
|
|
LevelSource* v141; // r1
|
|
float v142; // r0
|
|
LevelSource* v143; // r1
|
|
float v144; // r0
|
|
LevelSource* v145; // r1
|
|
float v146; // r0
|
|
bool v147; // r3
|
|
float v148; // s12
|
|
float v149; // s9
|
|
float v150; // s11
|
|
float v151; // s14
|
|
float v152; // s10
|
|
float v153; // s13
|
|
float v154; // s9
|
|
float v155; // s12
|
|
float v156; // s13
|
|
float v157; // s9
|
|
float v158; // s10
|
|
float v159; // s11
|
|
float v160; // s15
|
|
float v161; // s14
|
|
float v162; // s12
|
|
LevelSource* v163; // r1
|
|
int v164; // r0
|
|
float v165; // r0
|
|
LevelSource* v166; // r1
|
|
float v167; // r0
|
|
LevelSource* v168; // r1
|
|
float v169; // r0
|
|
LevelSource* v170; // r1
|
|
float v171; // r0
|
|
bool v172; // r3
|
|
float v173; // r0
|
|
bool v174; // r3
|
|
float v175; // r0
|
|
bool v176; // r3
|
|
float v177; // r0
|
|
float v178; // s15
|
|
float v179; // s13
|
|
float v180; // s10
|
|
float v181; // s12
|
|
float v182; // s9
|
|
float v183; // s11
|
|
float v184; // s13
|
|
float v185; // s15
|
|
float v186; // s13
|
|
float v187; // s11
|
|
float v188; // s10
|
|
float v189; // s14
|
|
float v190; // s15
|
|
float v191; // s12
|
|
LevelSource* v192; // r1
|
|
int v193; // r0
|
|
int result; // r0
|
|
bool v195; // r3
|
|
bool v196; // r3
|
|
float v197; // r0
|
|
bool v198; // r3
|
|
float v199; // r0
|
|
bool v200; // r3
|
|
float v201; // r0
|
|
bool v202; // r3
|
|
float v203; // r0
|
|
float v204; // r0
|
|
bool v205; // r3
|
|
float v206; // r0
|
|
float v207; // r0
|
|
float v208; // r0
|
|
bool v209; // r3
|
|
float v210; // r0
|
|
float v211; // r0
|
|
bool v212; // r3
|
|
float v213; // r0
|
|
int v214; // [sp+Ch] [bp-5Ch]
|
|
int v215; // [sp+10h] [bp-58h]
|
|
int v216; // [sp+14h] [bp-54h]
|
|
int v217; // [sp+18h] [bp-50h]
|
|
int v218; // [sp+1Ch] [bp-4Ch]
|
|
int v219; // [sp+20h] [bp-48h]
|
|
int v220; // [sp+24h] [bp-44h]
|
|
int v221; // [sp+28h] [bp-40h]
|
|
int v222; // [sp+2Ch] [bp-3Ch]
|
|
|
|
this->m_bAmbientOcclusion = 1;
|
|
v12 = a2->getBrightness(this->m_pLevelSource, a3, a4, a5);
|
|
v13 = this->m_pLevelSource;
|
|
this->field_C = v12;
|
|
v14 = a2->getBrightness(v13, a3 - 1, a4, a5);
|
|
v218 = a4 - 1;
|
|
v15 = this->m_pLevelSource;
|
|
this->field_10 = v14;
|
|
v16 = a2->getBrightness(v15, a3, a4 - 1, a5);
|
|
v217 = a5 - 1;
|
|
v17 = this->m_pLevelSource;
|
|
this->field_14 = v16;
|
|
v18 = a2->getBrightness(v17, a3, a4, a5 - 1);
|
|
v214 = a3 + 1;
|
|
v19 = this->m_pLevelSource;
|
|
this->field_18 = v18;
|
|
v20 = a2->getBrightness(v19, a3 + 1, a4, a5);
|
|
v216 = a4 + 1;
|
|
v21 = this->m_pLevelSource;
|
|
this->field_1C = v20;
|
|
v22 = a2->getBrightness(v21, a3, a4 + 1, a5);
|
|
v215 = a5 + 1;
|
|
v23 = this->m_pLevelSource;
|
|
this->field_20 = v22;
|
|
this->field_24 = a2->getBrightness(v23, a3, a4, a5 + 1);
|
|
v24 = Tile::translucent[this->m_pLevelSource->getTile(a3 + 1, a4 + 1, a5)];
|
|
v25 = this->m_pLevelSource;
|
|
this->field_AD = v24;
|
|
v26 = Tile::translucent[v25->getTile(a3 + 1, a4 - 1, a5)];
|
|
v27 = this->m_pLevelSource;
|
|
this->field_B5 = v26;
|
|
v28 = Tile::translucent[v27->getTile(a3 + 1, a4, a5 + 1)];
|
|
v29 = this->m_pLevelSource;
|
|
this->field_B1 = v28;
|
|
v30 = Tile::translucent[v29->getTile(a3 + 1, a4, a5 - 1)];
|
|
v31 = this->m_pLevelSource;
|
|
this->field_B3 = v30;
|
|
v32 = Tile::translucent[v31->getTile(a3 - 1, a4 + 1, a5)];
|
|
v33 = this->m_pLevelSource;
|
|
this->field_AE = v32;
|
|
v34 = Tile::translucent[v33->getTile(a3 - 1, a4 - 1, a5)];
|
|
v35 = this->m_pLevelSource;
|
|
this->field_B6 = v34;
|
|
v36 = Tile::translucent[v35->getTile(a3 - 1, a4, a5 - 1)];
|
|
v37 = this->m_pLevelSource;
|
|
this->field_B0 = v36;
|
|
v38 = Tile::translucent[v37->getTile(a3 - 1, a4, a5 + 1)];
|
|
v39 = this->m_pLevelSource;
|
|
this->field_B2 = v38;
|
|
v40 = Tile::translucent[v39->getTile(a3, a4 + 1, a5 + 1)];
|
|
v41 = this->m_pLevelSource;
|
|
this->field_AF = v40;
|
|
v42 = Tile::translucent[v41->getTile(a3, a4 + 1, a5 - 1)];
|
|
v43 = this->m_pLevelSource;
|
|
this->field_AC = v42;
|
|
v44 = Tile::translucent[v43->getTile(a3, a4 - 1, a5 + 1)];
|
|
v45 = this->m_pLevelSource;
|
|
this->field_B7 = v44;
|
|
this->field_B4 = Tile::translucent[v45->getTile(a3, a4 - 1, a5 - 1)];
|
|
if (a2->m_TextureFrame == 3)
|
|
{
|
|
v219 = 0;
|
|
v220 = 0;
|
|
v46 = 0;
|
|
v221 = 0;
|
|
v222 = 0;
|
|
}
|
|
else
|
|
{
|
|
v46 = 1;
|
|
v219 = 1;
|
|
v220 = 1;
|
|
v221 = 1;
|
|
v222 = 1;
|
|
}
|
|
if (!this->m_bDisableCulling
|
|
&& !a2->shouldRenderFace(this->m_pLevelSource, a3, v218, a5, this->m_bDisableCulling))
|
|
{
|
|
v69 = 0;
|
|
goto LABEL_20;
|
|
}
|
|
if (this->field_78 > 0)
|
|
{
|
|
v47 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, a5);
|
|
v48 = this->m_pLevelSource;
|
|
this->field_2C = v47;
|
|
v49 = a2->getBrightness(v48, a3, v218, v217);
|
|
v50 = this->m_pLevelSource;
|
|
this->field_34 = v49;
|
|
v51 = a2->getBrightness(v50, a3, v218, v215);
|
|
v52 = this->m_pLevelSource;
|
|
this->field_38 = v51;
|
|
v53 = a2->getBrightness(v52, v214, v218, a5);
|
|
v54 = this->field_B4;
|
|
this->field_40 = v53;
|
|
if (v54 || this->field_B6)
|
|
this->field_28 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v217);
|
|
else
|
|
this->field_28 = this->field_2C;
|
|
if (this->field_B7 || this->field_B6)
|
|
this->field_30 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v215);
|
|
else
|
|
this->field_30 = this->field_2C;
|
|
if (this->field_B4 || this->field_B5)
|
|
this->field_3C = a2->getBrightness(this->m_pLevelSource, v214, v218, v217);
|
|
else
|
|
this->field_3C = this->field_40;
|
|
if (this->field_B7 || this->field_B5)
|
|
{
|
|
v203 = a2->getBrightness(this->m_pLevelSource, v214, v218, v215);
|
|
v55 = this->field_40;
|
|
v56 = v203;
|
|
this->field_44 = v203;
|
|
}
|
|
else
|
|
{
|
|
v55 = this->field_40;
|
|
v56 = v55;
|
|
this->field_44 = v55;
|
|
}
|
|
v57 = this->field_2C;
|
|
v58 = this->field_14;
|
|
v59 = this->field_38;
|
|
v60 = (float)((float)((float)(v57 + this->field_30) + v59) + v58) * 0.25f;
|
|
v61 = this->field_34;
|
|
v62 = (float)((float)(v56 + (float)(v59 + v58)) + v55) * 0.25f;
|
|
v63 = (float)((float)(v55 + (float)(v58 + v61)) + this->field_3C) * 0.25f;
|
|
v64 = (float)(v61 + (float)(v58 + (float)(v57 + this->field_28))) * 0.25f;
|
|
if (v46)
|
|
goto LABEL_18;
|
|
LABEL_34:
|
|
v66 = 0.5f;
|
|
this->m_vtxRed[3] = 0.5f;
|
|
this->m_vtxRed[2] = 0.5f;
|
|
this->m_vtxRed[1] = 0.5f;
|
|
this->m_vtxRed[0] = 0.5f;
|
|
this->m_vtxGreen[3] = 0.5f;
|
|
this->m_vtxGreen[2] = 0.5f;
|
|
this->m_vtxGreen[1] = 0.5f;
|
|
this->m_vtxGreen[0] = 0.5f;
|
|
v65 = 0.5f;
|
|
v67 = 0.5f;
|
|
goto LABEL_19;
|
|
}
|
|
v62 = this->field_14;
|
|
v63 = v62;
|
|
v64 = v62;
|
|
v60 = v62;
|
|
if (!v46)
|
|
goto LABEL_34;
|
|
LABEL_18:
|
|
v65 = a6 * 0.5f;
|
|
v66 = a7 * 0.5f;
|
|
this->m_vtxRed[3] = a6 * 0.5f;
|
|
this->m_vtxRed[2] = a6 * 0.5f;
|
|
this->m_vtxRed[1] = a6 * 0.5f;
|
|
this->m_vtxRed[0] = a6 * 0.5f;
|
|
v67 = a8 * 0.5f;
|
|
this->m_vtxGreen[3] = a7 * 0.5f;
|
|
this->m_vtxGreen[2] = a7 * 0.5f;
|
|
this->m_vtxGreen[1] = a7 * 0.5f;
|
|
this->m_vtxGreen[0] = a7 * 0.5f;
|
|
LABEL_19:
|
|
v68 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v60 * v65;
|
|
this->m_vtxGreen[0] = v60 * v66;
|
|
this->m_vtxBlue[0] = v60 * v67;
|
|
this->m_vtxRed[1] = v64 * v65;
|
|
this->m_vtxGreen[1] = v64 * v66;
|
|
this->m_vtxBlue[1] = v64 * v67;
|
|
this->m_vtxRed[2] = v63 * v65;
|
|
this->m_vtxGreen[2] = v63 * v66;
|
|
this->m_vtxGreen[3] = v62 * v66;
|
|
this->m_vtxBlue[2] = v63 * v67;
|
|
this->m_vtxRed[3] = v62 * v65;
|
|
this->m_vtxBlue[3] = v62 * v67;
|
|
v70 = a2->getTexture(v68, a3, a4, a5, 0);
|
|
renderFaceUp(a2, (float)a3, (float)a4, (float)a5, v70);
|
|
LABEL_20:
|
|
if (this->m_bDisableCulling || a2->shouldRenderFace(this->m_pLevelSource, a3, v216, a5, 1))
|
|
{
|
|
if (this->field_78 <= 0)
|
|
{
|
|
v87 = this->field_20;
|
|
v89 = v87;
|
|
v88 = v87;
|
|
v85 = v87;
|
|
goto LABEL_36;
|
|
}
|
|
v71 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, a5);
|
|
v72 = this->m_pLevelSource;
|
|
this->field_4C = v71;
|
|
v73 = a2->getBrightness(v72, v214, v216, a5);
|
|
v74 = this->m_pLevelSource;
|
|
this->field_5C = v73;
|
|
v75 = a2->getBrightness(v74, a3, v216, v217);
|
|
v76 = this->m_pLevelSource;
|
|
this->field_54 = v75;
|
|
v77 = a2->getBrightness(v76, a3, v216, v215);
|
|
v78 = this->field_AC;
|
|
this->field_60 = v77;
|
|
if (v78 || this->field_AE)
|
|
{
|
|
v197 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v217);
|
|
v198 = this->field_AC;
|
|
this->field_48 = v197;
|
|
if (v198)
|
|
goto LABEL_125;
|
|
}
|
|
else
|
|
{
|
|
this->field_48 = this->field_4C;
|
|
}
|
|
if (!this->field_AD)
|
|
{
|
|
this->field_58 = this->field_5C;
|
|
LABEL_27:
|
|
if (this->field_AF || this->field_AE)
|
|
{
|
|
v211 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v215);
|
|
v212 = this->field_AF;
|
|
this->field_50 = v211;
|
|
if (v212)
|
|
goto LABEL_141;
|
|
}
|
|
else
|
|
{
|
|
this->field_50 = this->field_4C;
|
|
}
|
|
if (!this->field_AD)
|
|
{
|
|
v79 = this->field_5C;
|
|
v80 = v79;
|
|
this->field_64 = v79;
|
|
LABEL_32:
|
|
v81 = this->field_4C;
|
|
v82 = this->field_20;
|
|
v83 = this->field_60;
|
|
v84 = (float)(v81 + this->field_50) + v83;
|
|
v85 = (float)((float)(v80 + (float)(v83 + v82)) + v79) * 0.25f;
|
|
v86 = this->field_54;
|
|
v87 = (float)(v84 + v82) * 0.25f;
|
|
v88 = (float)((float)(v79 + (float)(v82 + v86)) + this->field_58) * 0.25f;
|
|
v89 = (float)(v86 + (float)(v82 + (float)(v81 + this->field_48))) * 0.25f;
|
|
LABEL_36:
|
|
v90 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v85 * a6;
|
|
this->m_vtxGreen[0] = v85 * a7;
|
|
this->m_vtxBlue[0] = v85 * a8;
|
|
this->m_vtxRed[1] = v88 * a6;
|
|
this->m_vtxGreen[1] = v88 * a7;
|
|
this->m_vtxBlue[1] = v88 * a8;
|
|
this->m_vtxRed[2] = v89 * a6;
|
|
this->m_vtxGreen[2] = v89 * a7;
|
|
this->m_vtxBlue[2] = v89 * a8;
|
|
this->m_vtxRed[3] = v87 * a6;
|
|
this->m_vtxGreen[3] = v87 * a7;
|
|
this->m_vtxBlue[3] = v87 * a8;
|
|
v91 = a2->getTexture(v90, a3, a4, a5, 1);
|
|
renderFaceDown(a2, (float)a3, (float)a4, (float)a5, v91);
|
|
goto LABEL_37;
|
|
}
|
|
LABEL_141:
|
|
v213 = a2->getBrightness(this->m_pLevelSource, v214, v216, v215);
|
|
v79 = this->field_5C;
|
|
v80 = v213;
|
|
this->field_64 = v213;
|
|
goto LABEL_32;
|
|
}
|
|
LABEL_125:
|
|
this->field_58 = a2->getBrightness(this->m_pLevelSource, v214, v216, v217);
|
|
goto LABEL_27;
|
|
}
|
|
LABEL_37:
|
|
if (!this->m_bDisableCulling && !a2->shouldRenderFace(this->m_pLevelSource, a3, a4, v217, 2))
|
|
{
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_54;
|
|
goto LABEL_107;
|
|
}
|
|
if (this->field_78 <= 0)
|
|
{
|
|
v111 = this->field_18;
|
|
v110 = v111;
|
|
v109 = v111;
|
|
v108 = v111;
|
|
if (!v222)
|
|
goto LABEL_50;
|
|
goto LABEL_52;
|
|
}
|
|
v92 = a2->getBrightness(this->m_pLevelSource, a3 - 1, a4, v217);
|
|
v93 = this->m_pLevelSource;
|
|
this->field_68 = v92;
|
|
v94 = a2->getBrightness(v93, a3, v218, v217);
|
|
v95 = this->m_pLevelSource;
|
|
this->field_34 = v94;
|
|
v96 = a2->getBrightness(v95, a3, v216, v217);
|
|
v97 = this->m_pLevelSource;
|
|
this->field_54 = v96;
|
|
v98 = a2->getBrightness(v97, v214, a4, v217);
|
|
v99 = this->field_B0;
|
|
this->field_6C = v98;
|
|
if (v99 || this->field_B4)
|
|
{
|
|
v201 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v217);
|
|
v202 = this->field_B0;
|
|
this->field_28 = v201;
|
|
if (v202)
|
|
goto LABEL_131;
|
|
}
|
|
else
|
|
{
|
|
this->field_28 = this->field_68;
|
|
}
|
|
if (this->field_AC)
|
|
{
|
|
LABEL_131:
|
|
this->field_48 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v217);
|
|
goto LABEL_44;
|
|
}
|
|
this->field_48 = this->field_68;
|
|
LABEL_44:
|
|
if (this->field_B3 || this->field_B4)
|
|
{
|
|
v204 = a2->getBrightness(this->m_pLevelSource, v214, v218, v217);
|
|
v205 = this->field_B3;
|
|
this->field_3C = v204;
|
|
if (v205)
|
|
goto LABEL_136;
|
|
}
|
|
else
|
|
{
|
|
this->field_3C = this->field_6C;
|
|
}
|
|
if (!this->field_AC)
|
|
{
|
|
v100 = this->field_6C;
|
|
v101 = v100;
|
|
this->field_58 = v100;
|
|
goto LABEL_49;
|
|
}
|
|
LABEL_136:
|
|
v206 = a2->getBrightness(this->m_pLevelSource, v214, v216, v217);
|
|
v100 = this->field_6C;
|
|
v101 = v206;
|
|
this->field_58 = v206;
|
|
LABEL_49:
|
|
v102 = this->field_68;
|
|
v103 = this->field_18;
|
|
v104 = this->field_54;
|
|
v105 = (float)((float)(v102 + this->field_48) + v103) + v104;
|
|
v106 = v101 + (float)((float)(v103 + v104) + v100);
|
|
v107 = this->field_34;
|
|
v108 = v105 * 0.25f;
|
|
v109 = v106 * 0.25f;
|
|
v110 = (float)(v100 + (float)((float)(v103 + v107) + this->field_3C)) * 0.25f;
|
|
v111 = (float)(v103 + (float)(v107 + (float)(v102 + this->field_28))) * 0.25f;
|
|
if (!v222)
|
|
{
|
|
LABEL_50:
|
|
v112 = 0.8f;
|
|
this->m_vtxRed[3] = 0.8f;
|
|
this->m_vtxRed[2] = 0.8f;
|
|
this->m_vtxRed[1] = 0.8f;
|
|
this->m_vtxRed[0] = 0.8f;
|
|
this->m_vtxGreen[3] = 0.8f;
|
|
this->m_vtxGreen[2] = 0.8f;
|
|
this->m_vtxGreen[1] = 0.8f;
|
|
this->m_vtxGreen[0] = 0.8f;
|
|
v113 = 0.8f;
|
|
v114 = 0.8f;
|
|
goto LABEL_53;
|
|
}
|
|
LABEL_52:
|
|
v113 = a6 * 0.8f;
|
|
v112 = a7 * 0.8f;
|
|
this->m_vtxRed[3] = a6 * 0.8f;
|
|
this->m_vtxRed[2] = a6 * 0.8f;
|
|
this->m_vtxRed[1] = a6 * 0.8f;
|
|
this->m_vtxRed[0] = a6 * 0.8f;
|
|
v114 = a8 * 0.8f;
|
|
this->m_vtxGreen[3] = a7 * 0.8f;
|
|
this->m_vtxGreen[2] = a7 * 0.8f;
|
|
this->m_vtxGreen[1] = a7 * 0.8f;
|
|
this->m_vtxGreen[0] = a7 * 0.8f;
|
|
LABEL_53:
|
|
v115 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v108 * v113;
|
|
this->m_vtxGreen[0] = v108 * v112;
|
|
this->m_vtxBlue[0] = v108 * v114;
|
|
this->m_vtxRed[1] = v109 * v113;
|
|
this->m_vtxGreen[1] = v109 * v112;
|
|
this->m_vtxBlue[1] = v109 * v114;
|
|
this->m_vtxRed[2] = v110 * v113;
|
|
this->m_vtxGreen[2] = v110 * v112;
|
|
this->m_vtxGreen[3] = v111 * v112;
|
|
this->m_vtxBlue[2] = v110 * v114;
|
|
this->m_vtxRed[3] = v111 * v113;
|
|
this->m_vtxBlue[3] = v111 * v114;
|
|
v116 = a2->getTexture(v115, a3, a4, a5, 2);
|
|
renderNorth(a2, (float)a3, (float)a4, (float)a5, v116);
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_54;
|
|
LABEL_107:
|
|
if (!a2->shouldRenderFace(this->m_pLevelSource, a3, a4, v215, 3))
|
|
{
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_70;
|
|
goto LABEL_109;
|
|
}
|
|
LABEL_54:
|
|
if (this->field_78 <= 0)
|
|
{
|
|
v132 = this->field_24;
|
|
v133 = v132;
|
|
v134 = v132;
|
|
v130 = v132;
|
|
if (!v221)
|
|
goto LABEL_66;
|
|
goto LABEL_68;
|
|
}
|
|
v117 = a2->getBrightness(this->m_pLevelSource, a3 - 1, a4, v215);
|
|
v118 = this->m_pLevelSource;
|
|
this->field_70 = v117;
|
|
v119 = a2->getBrightness(v118, v214, a4, v215);
|
|
v120 = this->m_pLevelSource;
|
|
this->field_74 = v119;
|
|
v121 = a2->getBrightness(v120, a3, v218, v215);
|
|
v122 = this->m_pLevelSource;
|
|
this->field_38 = v121;
|
|
v123 = a2->getBrightness(v122, a3, v216, v215);
|
|
v124 = this->field_B2;
|
|
this->field_60 = v123;
|
|
if (v124 || this->field_B7)
|
|
{
|
|
v199 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v215);
|
|
v200 = this->field_B2;
|
|
this->field_30 = v199;
|
|
if (v200)
|
|
goto LABEL_129;
|
|
}
|
|
else
|
|
{
|
|
this->field_30 = this->field_70;
|
|
}
|
|
if (this->field_AF)
|
|
{
|
|
LABEL_129:
|
|
this->field_50 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v215);
|
|
goto LABEL_60;
|
|
}
|
|
this->field_50 = this->field_70;
|
|
LABEL_60:
|
|
if (this->field_B1 || this->field_B7)
|
|
{
|
|
v208 = a2->getBrightness(this->m_pLevelSource, v214, v218, v215);
|
|
v209 = this->field_B1;
|
|
this->field_44 = v208;
|
|
if (v209)
|
|
goto LABEL_139;
|
|
}
|
|
else
|
|
{
|
|
this->field_44 = this->field_74;
|
|
}
|
|
if (!this->field_AF)
|
|
{
|
|
v125 = this->field_74;
|
|
v126 = v125;
|
|
this->field_64 = v125;
|
|
goto LABEL_65;
|
|
}
|
|
LABEL_139:
|
|
v210 = a2->getBrightness(this->m_pLevelSource, v214, v216, v215);
|
|
v125 = this->field_74;
|
|
v126 = v210;
|
|
this->field_64 = v210;
|
|
LABEL_65:
|
|
v127 = this->field_70;
|
|
v128 = this->field_24;
|
|
v129 = this->field_60;
|
|
v130 = (float)((float)((float)(v127 + this->field_50) + v128) + v129) * 0.25f;
|
|
v131 = this->field_38;
|
|
v132 = (float)(v126 + (float)((float)(v128 + v129) + v125)) * 0.25f;
|
|
v133 = (float)(v125 + (float)((float)(v128 + v131) + this->field_44)) * 0.25f;
|
|
v134 = (float)(v128 + (float)(v131 + (float)(v127 + this->field_30))) * 0.25f;
|
|
if (!v221)
|
|
{
|
|
LABEL_66:
|
|
v135 = 0.8f;
|
|
this->m_vtxRed[3] = 0.8f;
|
|
this->m_vtxRed[2] = 0.8f;
|
|
this->m_vtxRed[1] = 0.8f;
|
|
this->m_vtxRed[0] = 0.8f;
|
|
this->m_vtxGreen[3] = 0.8f;
|
|
this->m_vtxGreen[2] = 0.8f;
|
|
this->m_vtxGreen[1] = 0.8f;
|
|
this->m_vtxGreen[0] = 0.8f;
|
|
v136 = 0.8f;
|
|
v137 = 0.8f;
|
|
goto LABEL_69;
|
|
}
|
|
LABEL_68:
|
|
v136 = a6 * 0.8f;
|
|
v135 = a7 * 0.8f;
|
|
this->m_vtxRed[3] = a6 * 0.8f;
|
|
this->m_vtxRed[2] = a6 * 0.8f;
|
|
this->m_vtxRed[1] = a6 * 0.8f;
|
|
this->m_vtxRed[0] = a6 * 0.8f;
|
|
v137 = a8 * 0.8f;
|
|
this->m_vtxGreen[3] = a7 * 0.8f;
|
|
this->m_vtxGreen[2] = a7 * 0.8f;
|
|
this->m_vtxGreen[1] = a7 * 0.8f;
|
|
this->m_vtxGreen[0] = a7 * 0.8f;
|
|
LABEL_69:
|
|
v138 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v130 * v136;
|
|
this->m_vtxGreen[0] = v130 * v135;
|
|
this->m_vtxBlue[0] = v130 * v137;
|
|
this->m_vtxRed[1] = v134 * v136;
|
|
this->m_vtxGreen[1] = v134 * v135;
|
|
this->m_vtxBlue[1] = v134 * v137;
|
|
this->m_vtxRed[2] = v133 * v136;
|
|
this->m_vtxGreen[2] = v133 * v135;
|
|
this->m_vtxGreen[3] = v132 * v135;
|
|
this->m_vtxBlue[2] = v133 * v137;
|
|
this->m_vtxRed[3] = v132 * v136;
|
|
this->m_vtxBlue[3] = v132 * v137;
|
|
v139 = a2->getTexture(v138, a3, a4, a5, 3);
|
|
renderSouth(a2, (float)a3, (float)a4, (float)a5, v139);
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_70;
|
|
LABEL_109:
|
|
if (!a2->shouldRenderFace(this->m_pLevelSource, a3 - 1, a4, a5, 4))
|
|
{
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_88;
|
|
goto LABEL_111;
|
|
}
|
|
LABEL_70:
|
|
if (this->field_78 <= 0)
|
|
{
|
|
v156 = this->field_10;
|
|
v159 = v156;
|
|
v158 = v156;
|
|
v157 = v156;
|
|
if (!v220)
|
|
{
|
|
LABEL_84:
|
|
v160 = 0.6f;
|
|
this->m_vtxRed[3] = 0.6f;
|
|
this->m_vtxRed[2] = 0.6f;
|
|
this->m_vtxRed[1] = 0.6f;
|
|
this->m_vtxRed[0] = 0.6f;
|
|
this->m_vtxGreen[3] = 0.6f;
|
|
this->m_vtxGreen[2] = 0.6f;
|
|
this->m_vtxGreen[1] = 0.6f;
|
|
this->m_vtxGreen[0] = 0.6f;
|
|
v161 = 0.6f;
|
|
v162 = 0.6f;
|
|
goto LABEL_87;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v140 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, a5);
|
|
v141 = this->m_pLevelSource;
|
|
this->field_2C = v140;
|
|
v142 = a2->getBrightness(v141, a3 - 1, a4, v217);
|
|
v143 = this->m_pLevelSource;
|
|
this->field_68 = v142;
|
|
v144 = a2->getBrightness(v143, a3 - 1, a4, v215);
|
|
v145 = this->m_pLevelSource;
|
|
this->field_70 = v144;
|
|
v146 = a2->getBrightness(v145, a3 - 1, v216, a5);
|
|
v147 = this->field_B0;
|
|
this->field_4C = v146;
|
|
if (v147 || this->field_B6)
|
|
this->field_28 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v217);
|
|
else
|
|
this->field_28 = this->field_68;
|
|
if (this->field_B2 || this->field_B6)
|
|
this->field_30 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v218, v215);
|
|
else
|
|
this->field_30 = this->field_70;
|
|
if (this->field_B0 || this->field_AE)
|
|
this->field_48 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v217);
|
|
else
|
|
this->field_48 = this->field_68;
|
|
if (this->field_B2 || this->field_AE)
|
|
{
|
|
v207 = a2->getBrightness(this->m_pLevelSource, a3 - 1, v216, v215);
|
|
v148 = this->field_70;
|
|
v149 = v207;
|
|
this->field_50 = v207;
|
|
}
|
|
else
|
|
{
|
|
v148 = this->field_70;
|
|
v149 = v148;
|
|
this->field_50 = v148;
|
|
}
|
|
v150 = this->field_2C;
|
|
v151 = this->field_10;
|
|
v152 = this->field_4C;
|
|
v153 = (float)((float)(v150 + this->field_30) + v151) + v148;
|
|
v154 = v149 + (float)((float)(v151 + v148) + v152);
|
|
v155 = this->field_68;
|
|
v156 = v153 * 0.25f;
|
|
v157 = v154 * 0.25f;
|
|
v158 = (float)(v152 + (float)((float)(v151 + v155) + this->field_48)) * 0.25f;
|
|
v159 = (float)(v151 + (float)(v155 + (float)(v150 + this->field_28))) * 0.25f;
|
|
if (!v220)
|
|
goto LABEL_84;
|
|
}
|
|
v161 = a6 * 0.6f;
|
|
v160 = a7 * 0.6f;
|
|
this->m_vtxRed[3] = a6 * 0.6f;
|
|
this->m_vtxRed[2] = a6 * 0.6f;
|
|
this->m_vtxRed[1] = a6 * 0.6f;
|
|
this->m_vtxRed[0] = a6 * 0.6f;
|
|
v162 = a8 * 0.6f;
|
|
this->m_vtxGreen[3] = a7 * 0.6f;
|
|
this->m_vtxGreen[2] = a7 * 0.6f;
|
|
this->m_vtxGreen[1] = a7 * 0.6f;
|
|
this->m_vtxGreen[0] = a7 * 0.6f;
|
|
LABEL_87:
|
|
v163 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v161 * v157;
|
|
this->m_vtxGreen[0] = v160 * v157;
|
|
this->m_vtxBlue[0] = v162 * v157;
|
|
this->m_vtxRed[1] = v161 * v158;
|
|
this->m_vtxGreen[1] = v160 * v158;
|
|
this->m_vtxBlue[1] = v162 * v158;
|
|
this->m_vtxRed[2] = v161 * v159;
|
|
this->m_vtxGreen[2] = v160 * v159;
|
|
this->m_vtxGreen[3] = v160 * v156;
|
|
this->m_vtxBlue[2] = v162 * v159;
|
|
this->m_vtxRed[3] = v161 * v156;
|
|
this->m_vtxBlue[3] = v162 * v156;
|
|
v164 = a2->getTexture(v163, a3, a4, a5, 4);
|
|
renderWest(a2, (float)a3, (float)a4, (float)a5, v164);
|
|
if (this->m_bDisableCulling)
|
|
goto LABEL_88;
|
|
LABEL_111:
|
|
if (!a2->shouldRenderFace(this->m_pLevelSource, v214, a4, a5, 5))
|
|
goto LABEL_102;
|
|
LABEL_88:
|
|
if (this->field_78 <= 0)
|
|
{
|
|
v186 = this->field_1C;
|
|
v187 = v186;
|
|
v188 = v186;
|
|
v182 = v186;
|
|
if (v219)
|
|
goto LABEL_100;
|
|
LABEL_104:
|
|
v190 = 0.6f;
|
|
this->m_vtxRed[3] = 0.6f;
|
|
this->m_vtxRed[2] = 0.6f;
|
|
this->m_vtxRed[1] = 0.6f;
|
|
this->m_vtxRed[0] = 0.6f;
|
|
this->m_vtxGreen[3] = 0.6f;
|
|
this->m_vtxGreen[2] = 0.6f;
|
|
this->m_vtxGreen[1] = 0.6f;
|
|
this->m_vtxGreen[0] = 0.6f;
|
|
v189 = 0.6f;
|
|
v191 = 0.6f;
|
|
goto LABEL_101;
|
|
}
|
|
v165 = a2->getBrightness(this->m_pLevelSource, v214, v218, a5);
|
|
v166 = this->m_pLevelSource;
|
|
this->field_40 = v165;
|
|
v167 = a2->getBrightness(v166, v214, a4, v217);
|
|
v168 = this->m_pLevelSource;
|
|
this->field_6C = v167;
|
|
v169 = a2->getBrightness(v168, v214, a4, v215);
|
|
v170 = this->m_pLevelSource;
|
|
this->field_74 = v169;
|
|
v171 = a2->getBrightness(v170, v214, v216, a5);
|
|
v172 = this->field_B5;
|
|
this->field_5C = v171;
|
|
if (v172 || this->field_B3)
|
|
{
|
|
v173 = a2->getBrightness(this->m_pLevelSource, v214, v218, v217);
|
|
v174 = this->field_B5;
|
|
this->field_3C = v173;
|
|
if (v174 || this->field_B1)
|
|
goto LABEL_93;
|
|
LABEL_121:
|
|
this->field_44 = this->field_74;
|
|
goto LABEL_94;
|
|
}
|
|
v196 = this->field_B1;
|
|
this->field_3C = this->field_6C;
|
|
if (!v196)
|
|
goto LABEL_121;
|
|
LABEL_93:
|
|
this->field_44 = a2->getBrightness(this->m_pLevelSource, v214, v218, v215);
|
|
LABEL_94:
|
|
if (this->field_AD || this->field_B3)
|
|
{
|
|
v175 = a2->getBrightness(this->m_pLevelSource, v214, v216, v217);
|
|
v176 = this->field_AD;
|
|
this->field_58 = v175;
|
|
if (v176 || this->field_B1)
|
|
goto LABEL_98;
|
|
}
|
|
else
|
|
{
|
|
v195 = this->field_B1;
|
|
this->field_58 = this->field_6C;
|
|
if (v195)
|
|
{
|
|
LABEL_98:
|
|
v177 = a2->getBrightness(this->m_pLevelSource, v214, v216, v215);
|
|
v178 = this->field_74;
|
|
v179 = v177;
|
|
this->field_64 = v177;
|
|
goto LABEL_99;
|
|
}
|
|
}
|
|
v178 = this->field_74;
|
|
v179 = v178;
|
|
this->field_64 = v178;
|
|
LABEL_99:
|
|
v180 = this->field_40;
|
|
v181 = this->field_1C;
|
|
v182 = (float)((float)((float)(v180 + this->field_44) + v181) + v178) * 0.25f;
|
|
v183 = this->field_5C;
|
|
v184 = v179 + (float)((float)(v181 + v178) + v183);
|
|
v185 = this->field_6C;
|
|
v186 = v184 * 0.25f;
|
|
v187 = (float)(v183 + (float)((float)(v181 + v185) + this->field_58)) * 0.25f;
|
|
v188 = (float)(v181 + (float)(v185 + (float)(v180 + this->field_3C))) * 0.25f;
|
|
if (!v219)
|
|
goto LABEL_104;
|
|
LABEL_100:
|
|
v189 = a6 * 0.6f;
|
|
v190 = a7 * 0.6f;
|
|
this->m_vtxRed[3] = a6 * 0.6f;
|
|
this->m_vtxRed[2] = a6 * 0.6f;
|
|
this->m_vtxRed[1] = a6 * 0.6f;
|
|
this->m_vtxRed[0] = a6 * 0.6f;
|
|
v191 = a8 * 0.6f;
|
|
this->m_vtxGreen[3] = a7 * 0.6f;
|
|
this->m_vtxGreen[2] = a7 * 0.6f;
|
|
this->m_vtxGreen[1] = a7 * 0.6f;
|
|
this->m_vtxGreen[0] = a7 * 0.6f;
|
|
LABEL_101:
|
|
v192 = this->m_pLevelSource;
|
|
v69 = 1;
|
|
this->m_vtxRed[0] = v189 * v182;
|
|
this->m_vtxGreen[0] = v190 * v182;
|
|
this->m_vtxBlue[0] = v191 * v182;
|
|
this->m_vtxRed[1] = v189 * v188;
|
|
this->m_vtxGreen[1] = v190 * v188;
|
|
this->m_vtxBlue[1] = v191 * v188;
|
|
this->m_vtxRed[2] = v189 * v187;
|
|
this->m_vtxGreen[2] = v190 * v187;
|
|
this->m_vtxGreen[3] = v190 * v186;
|
|
this->m_vtxBlue[2] = v191 * v187;
|
|
this->m_vtxRed[3] = v189 * v186;
|
|
this->m_vtxBlue[3] = v191 * v186;
|
|
v193 = a2->getTexture(v192, a3, a4, a5, 5);
|
|
renderEast(a2, (float)a3, (float)a4, (float)a5, v193);
|
|
LABEL_102:
|
|
result = v69;
|
|
this->m_bAmbientOcclusion = 0;
|
|
return result;
|
|
}
|
|
|
|
// this is very hacky
|
|
#ifdef ENH_SHADE_HELD_TILES
|
|
|
|
#ifdef MOD_DONT_COLOR_GRASS
|
|
# define SHADE_IS_DECOLOR_GRASS_DEFINED true
|
|
#else
|
|
# define SHADE_IS_DECOLOR_GRASS_DEFINED false
|
|
#endif
|
|
|
|
#define SHADE_DEFINE float red = 1, grn = 1, blu = 1
|
|
|
|
#define SHADE_PREPARE do { \
|
|
red = bright, grn = bright, blu = bright; \
|
|
if (GetPatchManager()->IsGrassTinted()) { \
|
|
if (tile->m_ID == Tile::leaves->m_ID) \
|
|
red *= 0.35f, grn *= 0.65f, blu *= 0.25f; \
|
|
if (tile->m_ID == Tile::grass->m_ID) \
|
|
red *= 0.25f, grn *= 0.60f, blu *= 0.25f; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define SHADE_IF_NEEDED(col) t.color(col*red,col*grn,col*blu,1.0f)
|
|
|
|
#define SHADE_FIXUP_GRASS do { \
|
|
if (tile->m_ID == Tile::grass->m_ID) \
|
|
red = bright, grn = bright, blu = bright; \
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define SHADE_DEFINE 0
|
|
#define SHADE_PREPARE 0
|
|
#define SHADE_IF_NEEDED(col) 0
|
|
#define SHADE_FIXUP_GRASS(col) 0
|
|
|
|
#endif
|
|
|
|
void TileRenderer::renderTile(Tile* tile, int data RENDER_TILE_ARG_PATCH)
|
|
{
|
|
Tesselator& t = Tesselator::instance;
|
|
|
|
#ifdef ENH_SHADE_HELD_TILES
|
|
t.color(bright, bright, bright);
|
|
#else
|
|
t.color(255, 255, 255);
|
|
#endif
|
|
|
|
int shape = tile->getRenderShape();
|
|
if (shape == SHAPE_SOLID)
|
|
{
|
|
glTranslatef(-0.5f, -0.5f, -0.5f);
|
|
t.begin();
|
|
SHADE_DEFINE;
|
|
SHADE_PREPARE;
|
|
SHADE_IF_NEEDED(1.0f);
|
|
renderFaceDown(tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_YPOS, data));
|
|
SHADE_FIXUP_GRASS;
|
|
SHADE_IF_NEEDED(0.5f);
|
|
renderFaceUp (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_YNEG, data));
|
|
SHADE_IF_NEEDED(0.8f);
|
|
renderNorth (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_ZNEG, data));
|
|
renderSouth (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_ZPOS, data));
|
|
SHADE_IF_NEEDED(0.6f);
|
|
renderWest (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_XNEG, data));
|
|
renderEast (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_XPOS, data));
|
|
SHADE_IF_NEEDED(1.0f);
|
|
t.draw();
|
|
glTranslatef(0.5f, 0.5f, 0.5f);
|
|
return;
|
|
}
|
|
if (shape == SHAPE_CROSS)
|
|
{
|
|
// unused
|
|
t.begin();
|
|
tesselateCrossTexture(tile, data, -0.5f, -0.5f, -0.5f);
|
|
t.draw();
|
|
return;
|
|
}
|
|
if (shape == SHAPE_STAIRS)
|
|
{
|
|
// Fixed version from 0.1.1j+
|
|
t.addOffset(-0.5f, -0.5f, -0.5f);
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
if (!i)
|
|
tile->setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
|
|
else
|
|
tile->setShape(0.0f, 0.0f, 0.5f, 1.0f, 0.5f, 1.0f);
|
|
|
|
|
|
t.begin();
|
|
SHADE_DEFINE;
|
|
SHADE_PREPARE;
|
|
SHADE_IF_NEEDED(0.5f);
|
|
renderFaceUp (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_YNEG, data));
|
|
SHADE_IF_NEEDED(1.0f);
|
|
renderFaceDown(tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_YPOS, data));
|
|
SHADE_IF_NEEDED(0.6f);
|
|
renderNorth (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_ZNEG, data));
|
|
renderSouth (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_ZPOS, data));
|
|
SHADE_IF_NEEDED(0.8f);
|
|
renderWest (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_XNEG, data));
|
|
renderEast (tile, 0.0f, 0.0f, 0.0f, tile->getTexture(DIR_XPOS, data));
|
|
SHADE_IF_NEEDED(1.0f);
|
|
t.draw();
|
|
}
|
|
t.addOffset(0.5f, 0.5f, 0.5f);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
#ifdef ENH_USE_OWN_AO
|
|
bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionV2(Tile* tile, int x, int y, int z, float r, float g, float b)
|
|
{
|
|
// START OF AUXILIARY DATA FOR AO
|
|
|
|
// Well, this is a big enum.
|
|
enum eDirection
|
|
{
|
|
EDIR_HERE, // Here (no change in coordinates)
|
|
EDIR_N, // -Z
|
|
EDIR_S, // +Z
|
|
EDIR_W, // -X
|
|
EDIR_E, // +X
|
|
EDIR_NW, // -X-Z
|
|
EDIR_NE, // +X-Z
|
|
EDIR_SW, // -X+Z
|
|
EDIR_SE, // +X+Z
|
|
|
|
EDIR_U, // +Y
|
|
EDIR_UN, // +Y-Z
|
|
EDIR_US, // +Y+Z
|
|
EDIR_UW, // +Y-X
|
|
EDIR_UE, // +Y+X
|
|
EDIR_UNW,// +Y-X-Z
|
|
EDIR_UNE,// +Y+X-Z
|
|
EDIR_USW,// +Y-X+Z
|
|
EDIR_USE,// +Y+X+Z
|
|
|
|
EDIR_D, // -Y
|
|
EDIR_DN, // -Y-Z
|
|
EDIR_DS, // -Y+Z
|
|
EDIR_DW, // -Y-X
|
|
EDIR_DE, // -Y+X
|
|
EDIR_DNW,// -Y-X-Z
|
|
EDIR_DNE,// -Y+X-Z
|
|
EDIR_DSW,// -Y-X+Z
|
|
EDIR_DSE,// -Y+X+Z
|
|
EDIR_COUNT,
|
|
};
|
|
|
|
// for DIR_? directions
|
|
static const int diffX[] = { 0,0,0,0,-1,1 };
|
|
static const int diffZ[] = { 0,0,-1,1,0,0 };
|
|
static const int diffY[] = { -1,1,0,0,0,0 };
|
|
|
|
// for EDIR_? directions
|
|
static const int diffEX[] = { 0,0,0,-1,+1,-1,+1,-1,+1,0,0,0,-1,+1,-1,+1,-1,+1,0,0,0,-1,+1,-1,+1,-1,+1 };
|
|
static const int diffEZ[] = { 0,-1,+1,0,0,-1,-1,+1,+1,0,-1,+1,0,0,-1,-1,+1,+1,0,-1,+1,0,0,-1,-1,+1,+1 };
|
|
static const int diffEY[] = { 0,0,0,0,0,0,0,0,0, +1,+1,+1,+1,+1,+1,+1,+1,+1, -1,-1,-1,-1,-1,-1,-1,-1,-1 };
|
|
|
|
// Convert a DIR_? to an EDIR_?
|
|
static const int dirToEdir[] = { EDIR_D, EDIR_U, EDIR_N, EDIR_S, EDIR_W, EDIR_E };
|
|
|
|
// this is a huge table. Essentially this tells us which 3 tiles we should base our lighting value on aside from the
|
|
// one that's pointed to by the face we're rendering.
|
|
// The array is 6 * 4 * 3. 6 for the directions, 4 for the number of vertices per face, and 3 for the number of other tiles we'll check.
|
|
|
|
static const int massLUT[] = {
|
|
EDIR_DS, EDIR_DW, EDIR_DSW, EDIR_DN, EDIR_DW, EDIR_DNW, EDIR_DN, EDIR_DE, EDIR_DNE, EDIR_DS, EDIR_DE, EDIR_DSE,
|
|
EDIR_US, EDIR_UE, EDIR_USE, EDIR_UN, EDIR_UE, EDIR_UNE, EDIR_UN, EDIR_UW, EDIR_UNW, EDIR_US, EDIR_UW, EDIR_USW,
|
|
EDIR_UN, EDIR_NW, EDIR_UNW, EDIR_UN, EDIR_NE, EDIR_UNE, EDIR_DN, EDIR_NE, EDIR_DNE, EDIR_DN, EDIR_NW, EDIR_DNW,
|
|
EDIR_US, EDIR_SW, EDIR_USW, EDIR_DS, EDIR_SW, EDIR_DSW, EDIR_DS, EDIR_SE, EDIR_DSE, EDIR_US, EDIR_SE, EDIR_USE,
|
|
EDIR_UW, EDIR_SW, EDIR_USW, EDIR_UW, EDIR_NW, EDIR_UNW, EDIR_DW, EDIR_NW, EDIR_DNW, EDIR_DW, EDIR_SW, EDIR_DSW,
|
|
EDIR_DE, EDIR_SE, EDIR_DSE, EDIR_DE, EDIR_NE, EDIR_DNE, EDIR_UE, EDIR_NE, EDIR_UNE, EDIR_UE, EDIR_SE, EDIR_USE,
|
|
};
|
|
|
|
// Depending on the face, add a multiplier to our lighting value. This is the same as in regular block rendering without AO.
|
|
static const float lightingMult[] = { 0.5f, 1.0f, 0.8f, 0.8f, 0.6f, 0.6f };
|
|
|
|
// END OF AUXILIARY DATA FOR AO
|
|
|
|
bool bBother = false;
|
|
|
|
// Check if we should bother at all. Most of the time, we don't. There are some calculations that we shouldn't do unless necessary
|
|
for (int dir = DIR_YNEG; dir <= DIR_XPOS; dir++)
|
|
{
|
|
int tileX = x + diffX[dir], tileY = y + diffY[dir], tileZ = z + diffZ[dir];
|
|
|
|
if (!m_bDisableCulling && !tile->shouldRenderFace(m_pLevelSource, tileX, tileY, tileZ, dir))
|
|
continue;
|
|
|
|
bBother = true;
|
|
break;
|
|
}
|
|
|
|
if (!bBother)
|
|
return false;
|
|
|
|
float topR = r, topG = g, topB = b;
|
|
|
|
if (tile == Tile::grass)
|
|
r = g = b = 1.0f;
|
|
|
|
//Tesselator& t = Tesselator::instance;
|
|
|
|
//float fLightHere = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
float lights[EDIR_COUNT];
|
|
|
|
// Get the brightness of the tile we're processing, as well as all tiles around it
|
|
lights[EDIR_HERE] = tile->getBrightness(m_pLevelSource, x, y, z);
|
|
|
|
for (int i = 1; i < EDIR_COUNT; i++)
|
|
{
|
|
lights[i] = tile->getBrightness(m_pLevelSource, x + diffEX[i], y + diffEY[i], z + diffEZ[i]);
|
|
}
|
|
|
|
// Render all the faces.
|
|
for (int dir = DIR_YNEG; dir <= DIR_XPOS; dir++)
|
|
{
|
|
int tileX = x + diffX[dir], tileY = y + diffY[dir], tileZ = z + diffZ[dir];
|
|
|
|
// check if we should bother in the first place
|
|
if (!m_bDisableCulling && !tile->shouldRenderFace(m_pLevelSource, tileX, tileY, tileZ, dir))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
float fR = r, fG = g, fB = b;
|
|
if (dir == DIR_YPOS)
|
|
fR = topR, fG = topG, fB = topB;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
m_vtxRed[i] = m_vtxGreen[i] = m_vtxBlue[i] = 1.0f;
|
|
|
|
const int* table = &massLUT[dir * 12];
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
// average: the light at the tile the face's normal would point towards, and 3 other tiles
|
|
// chosen based on the vertex corner number
|
|
float br = lights[dirToEdir[dir]];
|
|
for (int j = 0; j < 3; j++)
|
|
br += lights[table[j + i * 3]];
|
|
|
|
br *= 0.25f;
|
|
|
|
m_vtxRed[i] = br;
|
|
m_vtxGreen[i] = br;
|
|
m_vtxBlue[i] = br;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
m_vtxRed [i] *= fR * lightingMult[dir];
|
|
m_vtxGreen[i] *= fG * lightingMult[dir];
|
|
m_vtxBlue [i] *= fB * lightingMult[dir];
|
|
}
|
|
|
|
m_bAmbientOcclusion = true;
|
|
|
|
switch (dir) {
|
|
case DIR_YNEG:
|
|
renderFaceUp (tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YNEG));
|
|
break;
|
|
case DIR_YPOS:
|
|
renderFaceDown(tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_YPOS));
|
|
break;
|
|
case DIR_ZNEG:
|
|
renderNorth (tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_ZNEG));
|
|
break;
|
|
case DIR_ZPOS:
|
|
renderSouth (tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_ZPOS));
|
|
break;
|
|
case DIR_XNEG:
|
|
renderWest (tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_XNEG));
|
|
break;
|
|
case DIR_XPOS:
|
|
renderEast (tile, float(x), float(y), float(z), tile->getTexture(m_pLevelSource, x, y, z, DIR_XPOS));
|
|
break;
|
|
}
|
|
|
|
if (TileRenderer::m_bFancyGrass && tile->getTexture(m_pLevelSource, x, y, z, dir) == TEXTURE_GRASS_SIDE && (dir == DIR_XNEG || dir == DIR_XPOS || dir == DIR_ZNEG || dir == DIR_ZPOS))
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
m_vtxRed[i] = m_vtxGreen[i] = m_vtxBlue[i] = 1.0f;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
// average: the light at the tile the face's normal would point towards, and 3 other tiles
|
|
// chosen based on the vertex corner number
|
|
float br = lights[dirToEdir[dir]];
|
|
for (int j = 0; j < 3; j++)
|
|
br += lights[table[j + i * 3]];
|
|
|
|
br *= 0.25f;
|
|
|
|
m_vtxRed[i] = br;
|
|
m_vtxGreen[i] = br;
|
|
m_vtxBlue[i] = br;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
m_vtxRed[i] *= topR * lightingMult[dir];
|
|
m_vtxGreen[i] *= topG * lightingMult[dir];
|
|
m_vtxBlue[i] *= topB * lightingMult[dir];
|
|
}
|
|
|
|
switch (dir) {
|
|
case DIR_YNEG:
|
|
renderFaceUp(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
case DIR_YPOS:
|
|
renderFaceDown(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
case DIR_ZNEG:
|
|
renderNorth(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
case DIR_ZPOS:
|
|
renderSouth(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
case DIR_XNEG:
|
|
renderWest(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
case DIR_XPOS:
|
|
renderEast(tile, float(x), float(y), float(z), TEXTURE_NONE38);
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_bAmbientOcclusion = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
int TileRenderer::getTileColor(Tile* tile, int x, int y, int z)
|
|
{
|
|
if (tile == nullptr)
|
|
{
|
|
return 0xffffff;
|
|
}
|
|
|
|
if (tile == Tile::grass && GrassColor::isAvailable() && m_bBiomeColors)
|
|
{
|
|
m_pLevelSource->getBiomeSource()->getBiomeBlock(x, z, 1, 1);
|
|
return GrassColor::get(m_pLevelSource->getBiomeSource()->field_4[0], m_pLevelSource->getBiomeSource()->field_8[0]);
|
|
}
|
|
if (tile == Tile::leaves && FoliageColor::isAvailable() && m_bBiomeColors)
|
|
{
|
|
int data = m_pLevelSource->getData(x, y, z);
|
|
|
|
if ((data & 1) == 1)
|
|
{
|
|
return FoliageColor::getEvergreenColor();
|
|
}
|
|
if ((data & 2) == 2)
|
|
{
|
|
return FoliageColor::getBirchColor();
|
|
}
|
|
|
|
m_pLevelSource->getBiomeSource()->getBiomeBlock(x, z, 1, 1);
|
|
return FoliageColor::get(m_pLevelSource->getBiomeSource()->field_4[0], m_pLevelSource->getBiomeSource()->field_8[0]);
|
|
}
|
|
|
|
return tile->getColor(m_pLevelSource, x, y, z);
|
|
}
|