mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-02 10:22:52 -04:00
Rudimentary lighting palette and memory test
This commit is contained in:
parent
d3d31a874c
commit
f03b538abb
190
src/Lighting.c
190
src/Lighting.c
@ -7,6 +7,11 @@
|
||||
#include "Logger.h"
|
||||
#include "Event.h"
|
||||
#include "Game.h"
|
||||
#include "String.h"
|
||||
#include "Chat.h"
|
||||
#include "ExtMath.h"
|
||||
#include "Options.h"
|
||||
cc_bool Lighting_Modern;
|
||||
struct _Lighting Lighting;
|
||||
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
|
||||
|
||||
@ -99,6 +104,156 @@ static void ClassicLighting_Refresh(void) {
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------Modern lighting------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/* TODO: Evil goodly hack, move chunk variables to World.h */
|
||||
int ModernLighting_ChunkCount;
|
||||
int ModernLighting_ChunksX;
|
||||
int ModernLighting_ChunksY;
|
||||
int ModernLighting_ChunksZ;
|
||||
|
||||
/* A 16x16 palette of sun and block light colors. */
|
||||
/* It is indexed by a byte where the leftmost 4 bits represent sunlight level and the rightmost 4 bits represent blocklight level */
|
||||
/* E.G. modernLighting_palette[0b_0010_0001] will give us the color for sun level 2 and block level 1 (lowest level is 0) */
|
||||
static PackedCol modernLighting_palette[MODERN_LIGHTING_LEVELS * MODERN_LIGHTING_LEVELS];
|
||||
|
||||
typedef cc_uint8* LightingChunk;
|
||||
static cc_uint8* chunkLightingDataFlags;
|
||||
#define CHUNK_UNCALCULATED 0
|
||||
#define CHUNK_CALCULATED 1
|
||||
#define CHUNK_ALL_DARK 2
|
||||
static LightingChunk* chunkLightingData;
|
||||
static cc_uint8 allDarkChunkLightingData[CHUNK_SIZE_3];
|
||||
|
||||
#define Modern_MakePaletteIndex(sun, block) ((sun << MODERN_LIGHTING_SUN_SHIFT) | block)
|
||||
|
||||
/* Fill in modernLighting_palette with values based on the current environment colors in lieu of recieving a palette from the server */
|
||||
static void ModernLighting_InitPalette(void) {
|
||||
PackedCol darkestShadow, defaultBlockLight, blockColor, sunColor, invertedBlockColor, invertedSunColor, finalColor;
|
||||
int sunLevel, blockLevel;
|
||||
float blockLerp;
|
||||
cc_uint8 R, G, B;
|
||||
|
||||
defaultBlockLight = PackedCol_Make(255, 238, 204, 255); /* A very mildly orange tinted light color */
|
||||
darkestShadow = PackedCol_Lerp(Env.ShadowCol, 0, 0.75f); /* Use a darkened version of shadow color as the darkest color in sun ramp */
|
||||
|
||||
for (sunLevel = 0; sunLevel < MODERN_LIGHTING_LEVELS; sunLevel++) {
|
||||
for (blockLevel = 0; blockLevel < MODERN_LIGHTING_LEVELS; blockLevel++) {
|
||||
/* We want the brightest light level to be the sun env color, with all other 15 levels being interpolation */
|
||||
/* between shadow color and darkest shadow color */
|
||||
if (sunLevel == MODERN_LIGHTING_LEVELS-1) {
|
||||
sunColor = Env.SunCol;
|
||||
}
|
||||
else {
|
||||
sunColor = PackedCol_Lerp(darkestShadow, Env.ShadowCol, sunLevel / (float)(MODERN_LIGHTING_LEVELS - 2) );
|
||||
}
|
||||
blockLerp = blockLevel / (float)(MODERN_LIGHTING_LEVELS-1);
|
||||
blockLerp *= blockLerp;
|
||||
blockLerp *= (MATH_PI / 2);
|
||||
blockLerp = Math_Cos(blockLerp);
|
||||
blockColor = PackedCol_Lerp(0, defaultBlockLight, 1 - blockLerp);
|
||||
|
||||
/* With Screen blend mode, the values of the pixels in the two layers are inverted, multiplied, and then inverted again. */
|
||||
R = 255 - PackedCol_R(sunColor);
|
||||
G = 255 - PackedCol_G(sunColor);
|
||||
B = 255 - PackedCol_B(sunColor);
|
||||
invertedSunColor = PackedCol_Make(R, G, B, 255);
|
||||
R = 255 - PackedCol_R(blockColor);
|
||||
G = 255 - PackedCol_G(blockColor);
|
||||
B = 255 - PackedCol_B(blockColor);
|
||||
invertedBlockColor = PackedCol_Make(R, G, B, 255);
|
||||
|
||||
finalColor = PackedCol_Tint(invertedSunColor, invertedBlockColor);
|
||||
R = 255 - PackedCol_R(finalColor);
|
||||
G = 255 - PackedCol_G(finalColor);
|
||||
B = 255 - PackedCol_B(finalColor);
|
||||
modernLighting_palette[Modern_MakePaletteIndex(sunLevel, blockLevel)] = PackedCol_Make(R, G, B, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ModernLighting_AllocState(void) {
|
||||
ModernLighting_InitPalette();
|
||||
ModernLighting_ChunksX = (World.Width + CHUNK_MAX) >> CHUNK_SHIFT;
|
||||
ModernLighting_ChunksY = (World.Height + CHUNK_MAX) >> CHUNK_SHIFT;
|
||||
ModernLighting_ChunksZ = (World.Length + CHUNK_MAX) >> CHUNK_SHIFT;
|
||||
ModernLighting_ChunkCount = ModernLighting_ChunksX * ModernLighting_ChunksY * ModernLighting_ChunksZ;
|
||||
|
||||
chunkLightingDataFlags = (cc_uint8*)Mem_TryAllocCleared(ModernLighting_ChunkCount, sizeof(cc_uint8));
|
||||
chunkLightingData = (LightingChunk*)Mem_TryAllocCleared(ModernLighting_ChunkCount, sizeof(LightingChunk));
|
||||
}
|
||||
static void ModernLighting_FreeState(void) {
|
||||
int i;
|
||||
/* This function can be called multiple times without calling ModernLighting_AllocState, so... */
|
||||
if (chunkLightingDataFlags == NULL) { return; }
|
||||
|
||||
for (i = 0; i < ModernLighting_ChunkCount; i++) {
|
||||
if (chunkLightingDataFlags[i] > CHUNK_CALCULATED || chunkLightingDataFlags[i] == CHUNK_UNCALCULATED) { continue; }
|
||||
Mem_Free(chunkLightingData[i]);
|
||||
}
|
||||
Mem_Free(chunkLightingDataFlags);
|
||||
Mem_Free(chunkLightingData);
|
||||
chunkLightingDataFlags = NULL;
|
||||
chunkLightingData = NULL;
|
||||
}
|
||||
|
||||
/* Gives the index into array of chunk pointers based on chunk x y z */
|
||||
#define ChunkIndex(x, y, z) (((y) * ModernLighting_ChunksZ + (z)) * ModernLighting_ChunksX + (x))
|
||||
/* Gives the index into array of chunk data */
|
||||
#define ChunkDataIndex(x, y, z) (((y) * CHUNK_SIZE + (z)) * CHUNK_SIZE + (x))
|
||||
|
||||
static void CalculateChunkLighting(int chunkIndex) {
|
||||
int i;
|
||||
chunkLightingData[chunkIndex] = (cc_uint8*)Mem_TryAlloc(CHUNK_SIZE_3, sizeof(cc_uint8));
|
||||
|
||||
for (i = 0; i < CHUNK_SIZE_3; i++) {
|
||||
chunkLightingData[chunkIndex][i] = i % 256;
|
||||
}
|
||||
}
|
||||
static void ModernLighting_LightHint(void) { } /* ??? */
|
||||
static void ModernLighting_OnBlockChanged(void) { }
|
||||
static void ModernLighting_Refresh(void) {
|
||||
ModernLighting_InitPalette();
|
||||
/* Set all the chunk lighting data flags to CHUNK_UNCALCULATED? */
|
||||
}
|
||||
static cc_bool ModernLighting_IsLit(int x, int y, int z) { return true; }
|
||||
static cc_bool ModernLighting_IsLit_Fast(int x, int y, int z) { return true; }
|
||||
|
||||
static PackedCol ModernLighting_Color(int x, int y, int z) {
|
||||
if (!World_Contains(x, y, z)) return Env.SunCol;
|
||||
//cc_uint8 thing = y % MODERN_LIGHTING_LEVELS;
|
||||
//cc_uint8 thing2 = z % MODERN_LIGHTING_LEVELS;
|
||||
//return y * z * x;
|
||||
int cx, cy, cz;
|
||||
int dx, dy, dz;
|
||||
int chunkIndex;
|
||||
int chunkDataIndex;
|
||||
|
||||
cx = x / CHUNK_SIZE;
|
||||
cy = y / CHUNK_SIZE;
|
||||
cz = z / CHUNK_SIZE;
|
||||
chunkIndex = ChunkIndex(cx, cy, cz);
|
||||
|
||||
//cc_string msg; char msgBuffer[STRING_SIZE * 2]; String_InitArray(msg, msgBuffer);
|
||||
//String_Format3(&msg, "Hi x %i, y %i, z %i", &cx, &cy, &cz);
|
||||
//Logger_Log(&msg);
|
||||
|
||||
if (chunkLightingDataFlags[chunkIndex] == CHUNK_UNCALCULATED) {
|
||||
CalculateChunkLighting(chunkIndex);
|
||||
chunkLightingDataFlags[chunkIndex] = CHUNK_CALCULATED;
|
||||
}
|
||||
/* Get coordinates into the chunk data*/
|
||||
dx = x % CHUNK_SIZE;
|
||||
dy = y % CHUNK_SIZE;
|
||||
dz = z % CHUNK_SIZE;
|
||||
chunkDataIndex = ChunkDataIndex(dx, dy, dz);
|
||||
cc_uint8 lightData = chunkLightingData[chunkIndex]
|
||||
[chunkDataIndex];
|
||||
|
||||
return modernLighting_palette[lightData];
|
||||
}
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------Lighting update------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
@ -392,13 +547,46 @@ static void ClassicLighting_SetActive(void) {
|
||||
Lighting.AllocState = ClassicLighting_AllocState;
|
||||
Lighting.LightHint = ClassicLighting_LightHint;
|
||||
}
|
||||
static void ModernLighting_SetActive(void) {
|
||||
Lighting.OnBlockChanged = ModernLighting_OnBlockChanged;
|
||||
Lighting.Refresh = ModernLighting_Refresh;
|
||||
Lighting.IsLit = ModernLighting_IsLit;
|
||||
Lighting.Color = ModernLighting_Color;
|
||||
Lighting.Color_XSide = ModernLighting_Color;
|
||||
|
||||
Lighting.IsLit_Fast = ModernLighting_IsLit_Fast;
|
||||
Lighting.Color_Sprite_Fast = ModernLighting_Color;
|
||||
Lighting.Color_YMax_Fast = ModernLighting_Color;
|
||||
Lighting.Color_YMin_Fast = ModernLighting_Color;
|
||||
Lighting.Color_XSide_Fast = ModernLighting_Color;
|
||||
Lighting.Color_ZSide_Fast = ModernLighting_Color;
|
||||
|
||||
Lighting.FreeState = ModernLighting_FreeState;
|
||||
Lighting.AllocState = ModernLighting_AllocState;
|
||||
Lighting.LightHint = ModernLighting_LightHint;
|
||||
}
|
||||
static void Lighting_ApplyActive(void) {
|
||||
if (Lighting_Modern) {
|
||||
ModernLighting_SetActive();
|
||||
}
|
||||
else {
|
||||
ClassicLighting_SetActive();
|
||||
}
|
||||
}
|
||||
void Lighting_SwitchActive(void) {
|
||||
Lighting.FreeState();
|
||||
Lighting_ApplyActive();
|
||||
Lighting.AllocState();
|
||||
}
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------Lighting component----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
|
||||
static void OnInit(void) { ClassicLighting_SetActive(); }
|
||||
static void OnInit(void) {
|
||||
if (!Game_ClassicMode) Lighting_Modern = Options_GetBool(OPT_MODERN_LIGHTING, false);
|
||||
Lighting_ApplyActive();
|
||||
}
|
||||
static void OnReset(void) { Lighting.FreeState(); }
|
||||
static void OnNewMapLoaded(void) { Lighting.AllocState(); }
|
||||
|
||||
|
@ -10,6 +10,12 @@ Copyright 2014-2022 ClassiCube | Licensed under BSD-3
|
||||
*/
|
||||
struct IGameComponent;
|
||||
extern struct IGameComponent Lighting_Component;
|
||||
/* Whether MC-style 16-level lighting should be used. */
|
||||
extern cc_bool Lighting_Modern;
|
||||
/* How many unique "levels" of light there are when modern lighting is used. */
|
||||
#define MODERN_LIGHTING_LEVELS 16
|
||||
/* How many bits to shift sunlight level to the left when storing it in a byte along with blocklight level*/
|
||||
#define MODERN_LIGHTING_SUN_SHIFT 4
|
||||
|
||||
CC_VAR extern struct _Lighting {
|
||||
/* Releases/Frees the per-level lighting state */
|
||||
@ -49,4 +55,6 @@ CC_VAR extern struct _Lighting {
|
||||
PackedCol (*Color_XSide_Fast)(int x, int y, int z);
|
||||
PackedCol (*Color_ZSide_Fast)(int x, int y, int z);
|
||||
} Lighting;
|
||||
|
||||
void Lighting_SwitchActive(void);
|
||||
#endif
|
||||
|
40
src/Menus.c
40
src/Menus.c
@ -27,6 +27,7 @@
|
||||
#include "Deflate.h"
|
||||
#include "Stream.h"
|
||||
#include "Builder.h"
|
||||
#include "Lighting.h"
|
||||
#include "Logger.h"
|
||||
#include "Options.h"
|
||||
#include "Input.h"
|
||||
@ -2739,6 +2740,13 @@ static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
|
||||
Builder_ApplyActive();
|
||||
MapRenderer_Refresh();
|
||||
}
|
||||
static void GraphicsOptionsScreen_GetModernLighting(cc_string* v) { Menu_GetBool(v, Lighting_Modern); }
|
||||
static void GraphicsOptionsScreen_SetModernLighting(const cc_string* v) {
|
||||
Lighting_Modern = Menu_SetBool(v, OPT_MODERN_LIGHTING);
|
||||
Lighting_SwitchActive();
|
||||
Builder_ApplyActive();
|
||||
MapRenderer_Refresh();
|
||||
}
|
||||
|
||||
static void GraphicsOptionsScreen_GetCamera(cc_string* v) { Menu_GetBool(v, Camera.Smooth); }
|
||||
static void GraphicsOptionsScreen_SetCamera(const cc_string* v) { Camera.Smooth = Menu_SetBool(v, OPT_CAMERA_SMOOTH); }
|
||||
@ -2767,34 +2775,37 @@ static void GraphicsOptionsScreen_SetCameraMass(const cc_string* c) {
|
||||
Options_Set(OPT_CAMERA_MASS, c);
|
||||
}
|
||||
|
||||
#define GraphicsOptionsButtonCount 9
|
||||
static void GraphicsOptionsScreen_InitWidgets(struct MenuOptionsScreen* s) {
|
||||
static const struct MenuOptionDesc buttons[8] = {
|
||||
{ -1, -100, "Camera Mass", MenuOptionsScreen_Input,
|
||||
static const struct MenuOptionDesc buttons[GraphicsOptionsButtonCount] = {
|
||||
{ -1, -150, "Camera Mass", MenuOptionsScreen_Input,
|
||||
GraphicsOptionsScreen_GetCameraMass, GraphicsOptionsScreen_SetCameraMass },
|
||||
{ -1, -50, "FPS mode", MenuOptionsScreen_Enum,
|
||||
{ -1, -100, "FPS mode", MenuOptionsScreen_Enum,
|
||||
MenuOptionsScreen_GetFPS, MenuOptionsScreen_SetFPS },
|
||||
{ -1, 0, "View distance", MenuOptionsScreen_Input,
|
||||
{ -1, -50, "View distance", MenuOptionsScreen_Input,
|
||||
GraphicsOptionsScreen_GetViewDist, GraphicsOptionsScreen_SetViewDist },
|
||||
{ -1, 50, "Advanced lighting", MenuOptionsScreen_Bool,
|
||||
{ -1, 0, "Smooth lighting", MenuOptionsScreen_Bool,
|
||||
GraphicsOptionsScreen_GetSmooth, GraphicsOptionsScreen_SetSmooth },
|
||||
{ -1, 50, "Modern lighting", MenuOptionsScreen_Bool,
|
||||
GraphicsOptionsScreen_GetModernLighting, GraphicsOptionsScreen_SetModernLighting },
|
||||
|
||||
{ 1, -100, "Smooth camera", MenuOptionsScreen_Bool,
|
||||
{ 1, -150, "Smooth camera", MenuOptionsScreen_Bool,
|
||||
GraphicsOptionsScreen_GetCamera, GraphicsOptionsScreen_SetCamera },
|
||||
{ 1, -50, "Names", MenuOptionsScreen_Enum,
|
||||
{ 1, -100, "Names", MenuOptionsScreen_Enum,
|
||||
GraphicsOptionsScreen_GetNames, GraphicsOptionsScreen_SetNames },
|
||||
{ 1, 0, "Shadows", MenuOptionsScreen_Enum,
|
||||
{ 1, -50, "Shadows", MenuOptionsScreen_Enum,
|
||||
GraphicsOptionsScreen_GetShadows, GraphicsOptionsScreen_SetShadows },
|
||||
{ 1, 50, "Mipmaps", MenuOptionsScreen_Bool,
|
||||
{ 1, 0, "Mipmaps", MenuOptionsScreen_Bool,
|
||||
GraphicsOptionsScreen_GetMipmaps, GraphicsOptionsScreen_SetMipmaps }
|
||||
};
|
||||
|
||||
s->numCore = 8;
|
||||
s->maxVertices += 8 * BUTTONWIDGET_MAX;
|
||||
s->numCore = GraphicsOptionsButtonCount;
|
||||
s->maxVertices += GraphicsOptionsButtonCount * BUTTONWIDGET_MAX;
|
||||
MenuOptionsScreen_InitButtons(s, buttons, Array_Elems(buttons), Menu_SwitchOptions);
|
||||
}
|
||||
|
||||
void GraphicsOptionsScreen_Show(void) {
|
||||
static struct MenuInputDesc descs[8];
|
||||
static struct MenuInputDesc descs[GraphicsOptionsButtonCount];
|
||||
static const char* extDescs[Array_Elems(descs)];
|
||||
|
||||
extDescs[0] = "&eChange the smoothness of the smooth camera.";
|
||||
@ -2804,13 +2815,14 @@ void GraphicsOptionsScreen_Show(void) {
|
||||
"&eNoLimit: &fRenders as many frames as possible each second.\n" \
|
||||
"&cNoLimit is pointless - it wastefully renders frames that you don't even see!";
|
||||
extDescs[3] = "&cNote: &eSmooth lighting is still experimental and can heavily reduce performance.";
|
||||
extDescs[5] = \
|
||||
extDescs[4] = "&cNote: &eModern lighting will reduce performance and increase memory usage.";
|
||||
extDescs[6] = \
|
||||
"&eNone: &fNo names of players are drawn.\n" \
|
||||
"&eHovered: &fName of the targeted player is drawn see-through.\n" \
|
||||
"&eAll: &fNames of all other players are drawn normally.\n" \
|
||||
"&eAllHovered: &fAll names of players are drawn see-through.\n" \
|
||||
"&eAllUnscaled: &fAll names of players are drawn see-through without scaling.";
|
||||
extDescs[6] = \
|
||||
extDescs[7] = \
|
||||
"&eNone: &fNo entity shadows are drawn.\n" \
|
||||
"&eSnapToBlock: &fA square shadow is shown on block you are directly above.\n" \
|
||||
"&eCircle: &fA circular shadow is shown across the blocks you are above.\n" \
|
||||
|
@ -23,6 +23,7 @@ Copyright 2014-2022 ClassiCube | Licensed under BSD-3
|
||||
#define OPT_ENTITY_SHADOW "entityshadow"
|
||||
#define OPT_RENDER_TYPE "normal"
|
||||
#define OPT_SMOOTH_LIGHTING "gfx-smoothlighting"
|
||||
#define OPT_MODERN_LIGHTING "gfx-modernlighting"
|
||||
#define OPT_MIPMAPS "gfx-mipmaps"
|
||||
#define OPT_CHAT_LOGGING "chat-logging"
|
||||
#define OPT_WINDOW_WIDTH "window-width"
|
||||
|
Loading…
x
Reference in New Issue
Block a user