Colored block lighting
This commit is contained in:
@@ -19,7 +19,7 @@ jobs:
|
||||
# echo "deb [signed-by=/usr/share/keyrings/ubuntu-archive-keyring.gpg] http://archive.ubuntu.com/ubuntu noble main" | sudo tee /tmp/only.list
|
||||
# sudo apt-get update -o Dir::Etc::sourcelist=/tmp/only.list -o Dir::Etc::sourceparts="-" -qq
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential cmake zip unzip make libxrandr-dev g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 g++-mingw-i686-x86-64 gcc-mingw-i686-x86-64 libxinerama-dev libxcursor-dev libxi-dev libgl-dev
|
||||
sudo apt install -y build-essential cmake zip unzip make libxrandr-dev g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 g++-mingw-w64-i686 gcc-mingw-w64-i686 libxinerama-dev libxcursor-dev libxi-dev libgl-dev
|
||||
|
||||
- name: Build makeheaders
|
||||
run: |
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.2 KiB |
+201
-13
@@ -42,10 +42,10 @@ const BlockDef BLOCKS[] = {
|
||||
BlockDef{ "workbench", R_TranslucentAllSides, B_Stone, 3, 0, 23, 22, 23},
|
||||
BlockDef{ "blue_block", R_Normal, B_Stone, 5, 0, 22},
|
||||
BlockDef{ "yellow_block", R_Normal, B_Stone, 5, 0, 23},
|
||||
BlockDef{ "cyan_block", R_Normal, B_Stone, 5, 0, 24},
|
||||
BlockDef{ "magenta_block", R_Normal, B_Stone, 5, 0, 25},
|
||||
BlockDef{ "white_block", R_Normal, B_Stone, 5, 0, 26},
|
||||
BlockDef{ "black_block", R_Normal, B_Stone, 5, 0, 27},
|
||||
BlockDef{ "red_block", R_Normal, B_Stone, 5, 0, 24},
|
||||
BlockDef{ "green_block", R_Normal, B_Stone, 5, 0, 25},
|
||||
BlockDef{ "blue_block", R_Normal, B_Stone, 5, 0, 26},
|
||||
BlockDef{ "white_block", R_Normal, B_Stone, 5, 0, 27},
|
||||
BlockDef{ "leaves", R_TranslucentAllSides, B_Grass, 1, 0, 28},
|
||||
BlockDef{ "copper_ore", R_Normal, B_Stone, 7, 1, 5},
|
||||
BlockDef{ "silver_ore", R_Normal, B_Stone, 7, 2, 6},
|
||||
@@ -127,6 +127,36 @@ int GetSkyLight(World &world, int x, int y, int z) {
|
||||
int skyLight = (light >> 12) & 0xF;
|
||||
return skyLight;
|
||||
}
|
||||
int GetRLight(World &world, int x, int y, int z) {
|
||||
if(CheckOOBWorld(x, y, z)) return 0;
|
||||
int locX = x % CHUNK_SIZE;
|
||||
int locZ = z % CHUNK_SIZE;
|
||||
int cx = x / CHUNK_SIZE;
|
||||
int cz = z / CHUNK_SIZE;
|
||||
uint16_t light = world.chunks[GetIndexWorld(cx, cz)].light[GetIndexChunk(locX, y, locZ)];
|
||||
int skyLight = (light >> 8) & 0xF;
|
||||
return skyLight;
|
||||
}
|
||||
int GetGLight(World &world, int x, int y, int z) {
|
||||
if(CheckOOBWorld(x, y, z)) return 0;
|
||||
int locX = x % CHUNK_SIZE;
|
||||
int locZ = z % CHUNK_SIZE;
|
||||
int cx = x / CHUNK_SIZE;
|
||||
int cz = z / CHUNK_SIZE;
|
||||
uint16_t light = world.chunks[GetIndexWorld(cx, cz)].light[GetIndexChunk(locX, y, locZ)];
|
||||
int skyLight = (light >> 4) & 0xF;
|
||||
return skyLight;
|
||||
}
|
||||
int GetBLight(World &world, int x, int y, int z) {
|
||||
if(CheckOOBWorld(x, y, z)) return 0;
|
||||
int locX = x % CHUNK_SIZE;
|
||||
int locZ = z % CHUNK_SIZE;
|
||||
int cx = x / CHUNK_SIZE;
|
||||
int cz = z / CHUNK_SIZE;
|
||||
uint16_t light = world.chunks[GetIndexWorld(cx, cz)].light[GetIndexChunk(locX, y, locZ)];
|
||||
int skyLight = light & 0xF;
|
||||
return skyLight;
|
||||
}
|
||||
Color GetLight(World &world, int x, int y, int z) {
|
||||
if(CheckOOBWorld(x, y, z)) return {0, 0, 0, 0};
|
||||
int locX = x % CHUNK_SIZE;
|
||||
@@ -135,8 +165,19 @@ Color GetLight(World &world, int x, int y, int z) {
|
||||
int cz = z / CHUNK_SIZE;
|
||||
uint16_t light = world.chunks[GetIndexWorld(cx, cz)].light[GetIndexChunk(locX, y, locZ)];
|
||||
int skyLight = ((light >> 12) & 0xF) * 16;
|
||||
//return {((light >> 8) & 0xF) * 16 + skyLight, (light >> 4) * 16 + skyLight, (light & 0xF) * 16 + skyLight, 255};
|
||||
return {skyLight, skyLight, skyLight, 255};
|
||||
Color sky = {skyLight, skyLight, skyLight, 255};
|
||||
Color r = {((light >> 8) & 0xF) * 16 + skyLight, 0, 0, 255};
|
||||
Color g = {0, ((light >> 4) & 0xF) * 16 + skyLight, 0, 255};
|
||||
Color b = {0, 0, ((light >> 0) & 0xF) * 16 + skyLight, 255};
|
||||
Color f = ColorTint(sky, r);
|
||||
f = ColorTint(f, g);
|
||||
f = ColorTint(f, b);
|
||||
return {
|
||||
fmin((int)sky.r + (int)r.r, 255),
|
||||
fmin((int)sky.g + (int)g.g, 255),
|
||||
fmin((int)sky.b + (int)b.b, 255),
|
||||
255
|
||||
};
|
||||
}
|
||||
bool CanTick(int blockType) { // TODO: make smarter in case other blocks can tick too!
|
||||
return blockType == BLOCK_SAND;
|
||||
@@ -244,7 +285,20 @@ void SetBlock(World &world, int x, int y, int z, int t) {
|
||||
}
|
||||
|
||||
void SetLightChunk(Chunk *c, int x, int y, int z, uint8_t sky, uint8_t r, uint8_t g, uint8_t b) {
|
||||
c->light[GetIndexChunk(x,y,z)] = sky << 12 | r << 8 | g << 4 | b;
|
||||
int target = c->light[GetIndexChunk(x,y,z)];
|
||||
if(sky > 0) {
|
||||
target |= sky << 12;
|
||||
}
|
||||
if(r > 0) {
|
||||
target |= r << 8;
|
||||
}
|
||||
if(g > 0) {
|
||||
target |= g << 4;
|
||||
}
|
||||
if(b > 0) {
|
||||
target |= b;
|
||||
}
|
||||
c->light[GetIndexChunk(x,y,z)] = target;
|
||||
}
|
||||
void SetLight(World &world, int x, int y, int z, uint8_t sky, uint8_t r, uint8_t g, uint8_t b) {
|
||||
if(CheckOOBWorld(x, y, z)) { return; }
|
||||
@@ -553,6 +607,9 @@ void RebuildOpaqueMask(Chunk &chunk) {
|
||||
}
|
||||
|
||||
void RebuildLighting(World &world, int startX, int startZ) {
|
||||
const Vector3I dirs[6] = { (Vector3I){ 1, 0, 0 }, (Vector3I){ -1, 0, 0 }, (Vector3I){ 0, 1, 0 }, (Vector3I){ 0,-1, 0 }, (Vector3I){ 0, 0, 1 }, (Vector3I){ 0, 0,-1 } };
|
||||
|
||||
// sky lighting
|
||||
std::queue<LightNode> nodes;
|
||||
|
||||
for (int cx = -1; cx <= 1; cx++)
|
||||
@@ -566,24 +623,20 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
||||
if (y < 0) continue;
|
||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y + 1, z + chunk.z * CHUNK_SIZE };
|
||||
if (CheckOOBWorld(pos.x, pos.y, pos.z)) continue;
|
||||
|
||||
for (int _y = WORLD_HEIGHT; _y >= y; _y--)
|
||||
{
|
||||
SetLight(world, pos.x, _y, pos.z, 15, 0, 0, 0);
|
||||
}
|
||||
|
||||
LightNode node{pos, 15};
|
||||
SetLight(world, pos.x, pos.y, pos.z, 15, 0, 0, 0);
|
||||
nodes.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Vector3I dirs[6] = { (Vector3I){ 1, 0, 0 }, (Vector3I){ -1, 0, 0 }, (Vector3I){ 0, 1, 0 }, (Vector3I){ 0,-1, 0 }, (Vector3I){ 0, 0, 1 }, (Vector3I){ 0, 0,-1 } };
|
||||
|
||||
while (!nodes.empty()) {
|
||||
std::cout << nodes.size() << std::endl;
|
||||
LightNode node = nodes.front();
|
||||
nodes.pop();
|
||||
|
||||
@@ -595,7 +648,7 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
||||
};
|
||||
|
||||
if (CheckOOBWorld(newPos.x, newPos.y, newPos.z)) continue;
|
||||
if (GetBlock(world, newPos.x, newPos.y, newPos.z) != BLOCK_AIR) continue;
|
||||
if (TestOpaqueMaskWorld(world, newPos.x, newPos.y, newPos.z)) continue;
|
||||
int newValue = node.value - 1;
|
||||
if (newValue <= 0) continue;
|
||||
|
||||
@@ -605,6 +658,141 @@ void RebuildLighting(World &world, int startX, int startZ) {
|
||||
nodes.push({ newPos, newValue });
|
||||
}
|
||||
}
|
||||
|
||||
// red lighting
|
||||
std::queue<LightNode> nodesR;
|
||||
|
||||
for (int cx = -1; cx <= 1; cx++)
|
||||
{
|
||||
for (int cz = -1; cz <= 1; cz++) {
|
||||
Chunk &chunk = world.chunks[GetIndexWorld(startX+cx, startZ+cz)];
|
||||
for (int i = 0; i < CHUNK_DATA_SIZE; i++)
|
||||
{
|
||||
int x, y, z;
|
||||
GetXYZFromIndex(i, &x, &y, &z);
|
||||
if (CheckOOBWorld(x, y, z)) continue;
|
||||
if(chunk.blocks[i] != 18 && chunk.blocks[i] != 21) continue;
|
||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||
std::cout << pos.y << std::endl;
|
||||
LightNode node{pos, 15};
|
||||
nodesR.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!nodesR.empty()) {
|
||||
std::cout << nodesR.size() << std::endl;
|
||||
LightNode node = nodesR.front();
|
||||
nodesR.pop();
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Vector3I newPos = {
|
||||
node.position.x + dirs[i].x,
|
||||
node.position.y + dirs[i].y,
|
||||
node.position.z + dirs[i].z
|
||||
};
|
||||
|
||||
if (CheckOOBWorld(newPos.x, newPos.y, newPos.z)) continue;
|
||||
if (TestOpaqueMaskWorld(world, newPos.x, newPos.y, newPos.z)) continue;
|
||||
int newValue = node.value - 1;
|
||||
if (newValue <= 0) continue;
|
||||
|
||||
if (GetRLight(world, newPos.x, newPos.y, newPos.z) >= newValue) continue;
|
||||
|
||||
SetLight(world, newPos.x, newPos.y, newPos.z, 0, newValue, 0, 0);
|
||||
nodesR.push({ newPos, newValue });
|
||||
}
|
||||
}
|
||||
|
||||
// green lighting
|
||||
std::queue<LightNode> nodesG;
|
||||
|
||||
for (int cx = -1; cx <= 1; cx++)
|
||||
{
|
||||
for (int cz = -1; cz <= 1; cz++) {
|
||||
Chunk &chunk = world.chunks[GetIndexWorld(startX+cx, startZ+cz)];
|
||||
for (int i = 0; i < CHUNK_DATA_SIZE; i++)
|
||||
{
|
||||
int x, y, z;
|
||||
GetXYZFromIndex(i, &x, &y, &z);
|
||||
if (CheckOOBWorld(x, y, z)) continue;
|
||||
if(chunk.blocks[i] != 19 && chunk.blocks[i] != 21) continue;
|
||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||
std::cout << pos.y << std::endl;
|
||||
LightNode node{pos, 15};
|
||||
nodesG.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!nodesG.empty()) {
|
||||
std::cout << nodesG.size() << std::endl;
|
||||
LightNode node = nodesG.front();
|
||||
nodesG.pop();
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Vector3I newPos = {
|
||||
node.position.x + dirs[i].x,
|
||||
node.position.y + dirs[i].y,
|
||||
node.position.z + dirs[i].z
|
||||
};
|
||||
|
||||
if (CheckOOBWorld(newPos.x, newPos.y, newPos.z)) continue;
|
||||
if (TestOpaqueMaskWorld(world, newPos.x, newPos.y, newPos.z)) continue;
|
||||
int newValue = node.value - 1;
|
||||
if (newValue <= 0) continue;
|
||||
|
||||
if (GetGLight(world, newPos.x, newPos.y, newPos.z) >= newValue) continue;
|
||||
|
||||
SetLight(world, newPos.x, newPos.y, newPos.z, 0, 0, newValue, 0);
|
||||
nodesG.push({ newPos, newValue });
|
||||
}
|
||||
}
|
||||
|
||||
// blue lighting
|
||||
std::queue<LightNode> nodesB;
|
||||
|
||||
for (int cx = -1; cx <= 1; cx++)
|
||||
{
|
||||
for (int cz = -1; cz <= 1; cz++) {
|
||||
Chunk &chunk = world.chunks[GetIndexWorld(startX+cx, startZ+cz)];
|
||||
for (int i = 0; i < CHUNK_DATA_SIZE; i++)
|
||||
{
|
||||
int x, y, z;
|
||||
GetXYZFromIndex(i, &x, &y, &z);
|
||||
if (CheckOOBWorld(x, y, z)) continue;
|
||||
if(chunk.blocks[i] != 20 && chunk.blocks[i] != 21) continue;
|
||||
Vector3I pos = { x + chunk.x * CHUNK_SIZE, y, z + chunk.z * CHUNK_SIZE };
|
||||
std::cout << pos.y << std::endl;
|
||||
LightNode node{pos, 15};
|
||||
nodesB.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!nodesB.empty()) {
|
||||
std::cout << nodesB.size() << std::endl;
|
||||
LightNode node = nodesB.front();
|
||||
nodesB.pop();
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Vector3I newPos = {
|
||||
node.position.x + dirs[i].x,
|
||||
node.position.y + dirs[i].y,
|
||||
node.position.z + dirs[i].z
|
||||
};
|
||||
|
||||
if (CheckOOBWorld(newPos.x, newPos.y, newPos.z)) continue;
|
||||
if (TestOpaqueMaskWorld(world, newPos.x, newPos.y, newPos.z)) continue;
|
||||
int newValue = node.value - 1;
|
||||
if (newValue <= 0) continue;
|
||||
|
||||
if (GetBLight(world, newPos.x, newPos.y, newPos.z) >= newValue) continue;
|
||||
|
||||
SetLight(world, newPos.x, newPos.y, newPos.z, 0, 0, 0, newValue);
|
||||
nodesB.push({ newPos, newValue });
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef SERVER
|
||||
//Generates an opaque CRD (ChunkRenderData). Outputs the CRD.
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
#define DEFAULT_FONT_SIZE 16
|
||||
#define TPS 30.0
|
||||
#define TPS_DIV 1.0 / TPS
|
||||
#define RENDER_DISTANCE 2
|
||||
#define RENDER_DISTANCE 5
|
||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||
#define MAX_HP 100
|
||||
#define PATH_APPEND "resources/"
|
||||
@@ -307,6 +307,9 @@ extern const BlockDef BLOCKS[];
|
||||
int GetBlock(World&world,int x,int y,int z);
|
||||
int GetHighestBlock(World&world,int x,int z);
|
||||
int GetSkyLight(World&world,int x,int y,int z);
|
||||
int GetRLight(World&world,int x,int y,int z);
|
||||
int GetGLight(World&world,int x,int y,int z);
|
||||
int GetBLight(World&world,int x,int y,int z);
|
||||
Color GetLight(World&world,int x,int y,int z);
|
||||
bool CanTick(int blockType);
|
||||
bool GetCloud(int x,int z);
|
||||
@@ -463,10 +466,10 @@ inline void unpack6(uint8_t v,bool *b0,bool *b1,bool *b2,bool *b3,bool *b4,bool
|
||||
*b5 = (v >> 5) & 1;
|
||||
};
|
||||
inline void GetXYZFromIndex(int index,int *x,int *y,int *z){
|
||||
*x = index & 15;
|
||||
int tmp = index << 4;
|
||||
*z = tmp & 15;
|
||||
*y = tmp << 4;
|
||||
*y = index / (CHUNK_SIZE * CHUNK_SIZE);
|
||||
int rem = index % (CHUNK_SIZE * CHUNK_SIZE);
|
||||
*z = rem / CHUNK_SIZE;
|
||||
*x = rem % CHUNK_SIZE;
|
||||
};
|
||||
inline int GetIndexChunk(int x,int y,int z){
|
||||
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
||||
|
||||
@@ -20,14 +20,15 @@ inline void unpack6(uint8_t v, bool *b0, bool *b1, bool *b2, bool *b3, bool *b4,
|
||||
*b5 = (v >> 5) & 1;
|
||||
}
|
||||
|
||||
inline void GetXYZFromIndex(int index, int *x, int *y, int *z) {
|
||||
*x = index & 15;
|
||||
int tmp = index << 4;
|
||||
*z = tmp & 15;
|
||||
*y = tmp << 4;
|
||||
inline void GetXYZFromIndex(int index, int* x, int* y, int* z) {
|
||||
*y = index / (CHUNK_SIZE * CHUNK_SIZE);
|
||||
int rem = index % (CHUNK_SIZE * CHUNK_SIZE);
|
||||
*z = rem / CHUNK_SIZE;
|
||||
*x = rem % CHUNK_SIZE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int GetIndexChunk(int x, int y, int z) {
|
||||
if(x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_HEIGHT || z >= CHUNK_SIZE) return 0;
|
||||
return x + CHUNK_SIZE * (z + CHUNK_SIZE * y);
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
#define TPS 30.0
|
||||
#define TPS_DIV 1.0 / TPS
|
||||
//Rendering
|
||||
#define RENDER_DISTANCE 2
|
||||
#define RENDER_DISTANCE 5
|
||||
#define RENDER_DISTANCE_SQUARED RENDER_DISTANCE*RENDER_DISTANCE
|
||||
|
||||
//Game stuff
|
||||
|
||||
Reference in New Issue
Block a user