This commit is contained in:
2026-02-12 11:18:51 +00:00
parent 414e52de9e
commit b0511f3830
4 changed files with 350 additions and 47 deletions

View File

@@ -43,8 +43,168 @@ namespace VoxelIsometricRenderer
int ZWorldPos;
LightShape Shape;
byte[,,] LightLevels;
float[] LightLevelModifier = new float[] { 1.5f, 1.5f, 1.5f };
float[] LightLevelModifier = new float[] { 1.0f, 1.0f, 1.0f };
int Brightness = 64;
public void SetPosition(int[] pos)
{
XWorldPos = pos[0];
YWorldPos = pos[1];
ZWorldPos = pos[2];
}
public int[] GetPosition()
{
return new int[] { XWorldPos, YWorldPos, ZWorldPos };
}
public int[] GetRadius()
{
return new int[] {RangeX,RangeY, RangeZ };
}
public int GetAverageRadius()
{
return (RangeX + RangeY + RangeZ) / 3;
}
public float[] GetRGBLightLevels(int level)
{
float Multiplier = (float)level / 255.0f;
return new float[] { LightLevelModifier[0] * Multiplier, LightLevelModifier[1] * Multiplier, LightLevelModifier[2] * Multiplier };
}
public int GetLightLevel(int RelativeBlockX, int RelativeBlockY, int RelativeBlockZ, int face, bool BlocksLight)
{
int CentreX = LightLevels.GetLength(0) / 2;
int CentreY = LightLevels.GetLength(1) / 2;
int CentreZ = LightLevels.GetLength(2) / 2;
int LightLevel = 0;
if(RelativeBlockX >= 0 && RelativeBlockX < LightLevels.GetLength(0) &&
RelativeBlockY >= 0 && RelativeBlockY < LightLevels.GetLength(1) &&
RelativeBlockZ >= 0 && RelativeBlockZ < LightLevels.GetLength(2))
{
LightLevel = LightLevels[RelativeBlockX,RelativeBlockY,RelativeBlockZ];
int DirectionX = 0;
if (BlocksLight)
{
switch (face)
{
case 0:
if (CentreZ < RelativeBlockZ)
{
DirectionX = 180;
}
if (CentreZ == RelativeBlockZ)
{
DirectionX = 90;
}
if (CentreZ > RelativeBlockZ)
{
DirectionX = 0;
}
break;
case 1:
if (CentreZ > RelativeBlockZ)
{
DirectionX = 180;
}
if (CentreZ == RelativeBlockZ)
{
DirectionX = 90;
}
if (CentreZ < RelativeBlockZ)
{
DirectionX = 0;
}
break;
case 2:
if (CentreX < RelativeBlockX)
{
DirectionX = 180;
}
if (CentreX == RelativeBlockX)
{
DirectionX = 90;
}
if (CentreX > RelativeBlockX)
{
DirectionX = 0;
}
break;
case 3:
if (CentreX > RelativeBlockX)
{
DirectionX = 180;
}
if (CentreX == RelativeBlockX)
{
DirectionX = 90;
}
if (CentreX < RelativeBlockX)
{
DirectionX = 0;
}
break;
case 4:
if (CentreY < RelativeBlockY)
{
DirectionX = 180;
}
if(CentreY == RelativeBlockY)
{
DirectionX = 90;
}
if(CentreY > RelativeBlockY)
{
DirectionX = 0;
}
break;
case 5:
if (CentreY > RelativeBlockY)
{
DirectionX = 180;
}
if (CentreY == RelativeBlockY)
{
DirectionX = 90;
}
if (CentreY < RelativeBlockY)
{
DirectionX = 0;
}
break;
}
/* if (CentreZ < RelativeBlockZ && RelativeBlockZ > RelativeBlockX)
{
for (int i = RelativeBlockZ; i < LightLevels.GetLength(2); i++)
{
LightLevels[RelativeBlockX, RelativeBlockY, i] = 0;
}
} else if (CentreZ > RelativeBlockZ && RelativeBlockZ < RelativeBlockX)
{
for (int i = RelativeBlockZ; i >= 0; i--)
{
LightLevels[RelativeBlockX, RelativeBlockY, i] = 0;
}
} else
{
if (CentreX < RelativeBlockX && RelativeBlockX > RelativeBlockZ)
{
for (int i = RelativeBlockX; i < LightLevels.GetLength(0); i++)
{
LightLevels[i, RelativeBlockY, RelativeBlockZ] = 0;
}
}
else if (CentreX > RelativeBlockX && RelativeBlockX < RelativeBlockZ)
{
for (int i = RelativeBlockZ; i >= 0; i--)
{
LightLevels[i, RelativeBlockY, RelativeBlockZ] = 0;
}
}
}*/
LightLevel = (int)(LightLevel * ((1 + Math.Cos(Math.PI * DirectionX / 180)) / 2));
// MessageBox.Show(LightLevel + "");
}
}
return LightLevel;
}
public static bool IsWithinCircle(int Radius, int CentreX, int CentreY, int posX, int PosY)
{
return LightingManager.Square(posX - CentreX) + LightingManager.Square(PosY - CentreY) < LightingManager.Square(Radius);
@@ -174,11 +334,31 @@ namespace VoxelIsometricRenderer
public static List<LightSource> Lights = new List<LightSource>();
public static LightDirection SunAngle = LightDirection.North;
public static float MaxBloom = 1.05f;
public static float[] RenderLightOnCube(int WorldX, int WorldY, int WorldZ, int face)
public static float[] GetLightsOnCube(int WorldX, int WorldY, int WorldZ, int face, bool BlocksLight)
{
return new float[] { 0, 0, 0 };
}
float[] RGBLevels = new float[] { 0, 0, 0 };
int LightCount = 0;
Lights.ForEach(Light =>
{
int DistX = WorldX - (Light.GetPosition()[0] - Light.GetRadius()[0]);
int DistY = WorldY - (Light.GetPosition()[1] - Light.GetRadius()[1]);
int DistZ = WorldZ - (Light.GetPosition()[2] - Light.GetRadius()[2]);
if (DistX > 0 && DistY > 0 && DistZ > 0 && DistX - Light.GetRadius()[0] < 0 && DistY - Light.GetRadius()[1] < 0 && DistZ - Light.GetRadius()[2] < 0)
{
//MessageBox.Show("X: " + DistX + " Y: " + DistY + " Z: " + DistZ);
float[] LightRGB = new float[3];
LightCount++;
int LightLevel = Light.GetLightLevel(DistX, DistY, DistZ, face, BlocksLight);
LightRGB = Light.GetRGBLightLevels(LightLevel);
RGBLevels[0] += LightRGB[0];
RGBLevels[1] += LightRGB[1];
RGBLevels[2] += LightRGB[2];
}
});
//return RGBLevels;
return new float[] { RGBLevels[0] != 0 ? RGBLevels[0]/LightCount : 0, RGBLevels[1] != 0 ? RGBLevels[1]/LightCount : 0, RGBLevels[2] != 0 ? RGBLevels[2]/LightCount : 0 };
}
public static void UpdateLighting()
{
float[] AngleRanges = new float[] { 0, 45, 90, 135, 180, 225, 270, 315 };
@@ -252,32 +432,37 @@ namespace VoxelIsometricRenderer
if (faces[i] >= 0 && GeneratedFaceTextures[faces[i], i].Height > ImageHeight) ImageHeight = GeneratedFaceTextures[faces[i], i].Height;
}
Bitmap GeneratedModel = new Bitmap(ImageWidth, ImageHeight);
voxel.Draw(Graphics.FromImage(GeneratedModel),0,0,0,0,0,0);
voxel.Draw(Graphics.FromImage(GeneratedModel),0,0,0,0,0,0,false);
voxel.SetPreCompiledModel(PreCompiledModels.Count);
PreCompiledModels.Add(GeneratedModel);
GeneratedModel.Save("Model" + voxel.GetModelNum() + ".png");
}
public static float GetSunlightValue(int face, int ShadowLevel)
{
return (LightingManager.SkyLightModifiedValues[face] * LightingManager.DefaultValues[face])/(float)ShadowLevel;
return (LightingManager.SkyLightModifiedValues[face] * LightingManager.DefaultValues[face]) / (float)ShadowLevel;
}
public static float GetShadingValue(float LightValue, int RGBIndex, int FaceIndex)
{
return (float)Math.Max(LightValue * LightingManager.AmbientColouring[RGBIndex], LightingManager.AmbientMinimums[FaceIndex]);
return GetShadingValue(LightValue, RGBIndex, FaceIndex, new float[] { 0, 0, 0 });
}
public static ImageAttributes GetShadow(int face) { return GetShadow(face, 0, 0,0,0); }
public static ImageAttributes GetShadow(int face, int WorldX, int WorldY, int WorldZ, int ShadowLevel)
public static float GetShadingValue(float LightValue, int RGBIndex, int FaceIndex, float[] Lights)
{
//if (Lights[RGBIndex] > 0) MessageBox.Show(Lights[RGBIndex] + "");
return ((float)Math.Max(LightValue * LightingManager.AmbientColouring[RGBIndex], LightingManager.AmbientMinimums[FaceIndex])) + Lights[RGBIndex] * 10;
}
public static ImageAttributes GetShadow(int face) { return GetShadow(face, 0, 0,0,0, false); }
public static ImageAttributes GetShadow(int face, int WorldX, int WorldY, int WorldZ, int ShadowLevel, bool BlocksLight)
{
ImageAttributes imageAttributes;
float[][] colorMatrixElements;
float[] Lights = LightingManager.RenderLightOnCube(WorldX, WorldY, WorldZ, face);
float[] Lights = LightingManager.GetLightsOnCube(WorldX, WorldY, WorldZ, face, BlocksLight);
ColorMatrix colorMatrix;
switch (face) {
case 0:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face,Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, 0, 0, 1}}; // three translations of 0.2
@@ -287,9 +472,9 @@ namespace VoxelIsometricRenderer
return imageAttributes;
case 1:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face, Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, 0, 0, 1}}; // three translations of 0.2
@@ -299,9 +484,9 @@ namespace VoxelIsometricRenderer
return imageAttributes;
case 2:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face, Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, 0, 0, 1}}; // three translations of 0.2
@@ -311,9 +496,9 @@ namespace VoxelIsometricRenderer
return imageAttributes;
case 3:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face, Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, 0, 0, 1}}; // three translations of 0.2
@@ -323,9 +508,9 @@ namespace VoxelIsometricRenderer
return imageAttributes;
case 4:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face, Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, 0, 0, 1}}; // three translations of 0.2
@@ -335,9 +520,9 @@ namespace VoxelIsometricRenderer
return imageAttributes;
case 5:
colorMatrixElements = new float[][]{
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face), 0, 0}, // blue
new float[] { GetShadingValue(GetSunlightValue(face,ShadowLevel), 0,face, Lights), 0, 0, 0, 0}, // red
new float[] {0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 1, face, Lights), 0, 0, 0}, // green
new float[] {0, 0, GetShadingValue(GetSunlightValue(face,ShadowLevel), 2, face, Lights), 0, 0}, // blue
new float[] {0, 0, 0, 1, 0}, // alpha
new float[] {0, 0, -0, 0, 1}}; // three translations of 0.2
@@ -635,7 +820,7 @@ namespace VoxelIsometricRenderer
VoxelNum = TextureManager.VoxelCount;
TextureManager.VoxelCount++;
}
virtual public void Draw(Graphics g, int x, int y, int WorldX, int WorldY, int WorldZ, int ShadowLevel)
virtual public void Draw(Graphics g, int x, int y, int WorldX, int WorldY, int WorldZ, int ShadowLevel, bool BlocksLight)
{
for (int i = 0; i < DrawOrder.Length; i++) {
if (DrawOrder[i] > 0 && DrawOrder[i] < 6 && faces[DrawOrder[i]] >= 0)
@@ -647,7 +832,7 @@ namespace VoxelIsometricRenderer
{
case 0:
Side = GetRenderedSide(DrawOrder[i]);
g.DrawImage(Side, new Rectangle(x, y, Side.Width, Side.Height), 0, 0, Side.Width, Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(DrawOrder[i], WorldX, WorldY,WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle(x, y, Side.Width, Side.Height), 0, 0, Side.Width, Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(DrawOrder[i], WorldX, WorldY,WorldZ, ShadowLevel, BlocksLight));
break;
default:
@@ -655,23 +840,23 @@ namespace VoxelIsometricRenderer
{
case 0:
Side = GetRenderedSide(0);
g.DrawImage(Side, new Rectangle(x - (Side.Width / 4), y, Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(0, WorldX, WorldY, WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle(x - (Side.Width / 4), y, Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(0, WorldX, WorldY, WorldZ, ShadowLevel, BlocksLight));
break;
case 1:
Side = GetRenderedSide(1);
g.DrawImage(Side, new Rectangle(x + (Side.Width / 4), y - (Side.Height / 4), Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(1, WorldX, WorldY, WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle(x + (Side.Width / 4), y - (Side.Height / 4), Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(1, WorldX, WorldY, WorldZ, ShadowLevel, BlocksLight));
break;
case 2:
Side = GetRenderedSide(2);
g.DrawImage(Side, new Rectangle(x - (Side.Width / 4), y - (Side.Height / 4), Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(2, WorldX, WorldY, WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle(x - (Side.Width / 4), y - (Side.Height / 4), Side.Width, Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(2, WorldX, WorldY, WorldZ, ShadowLevel, BlocksLight));
break;
case 3:
Side = GetRenderedSide(3);
g.DrawImage(Side, new Rectangle( x + (Side.Width / 4),y,Side.Width,Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(3, WorldX, WorldY, WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle( x + (Side.Width / 4),y,Side.Width,Side.Height),0,0,Side.Width,Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(3, WorldX, WorldY, WorldZ, ShadowLevel, BlocksLight));
break;
default:
Side = GetRenderedSide(DrawOrder[i]);
g.DrawImage(Side, new Rectangle(x, y, Side.Width, Side.Height), 0, 0, Side.Width, Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(DrawOrder[i], WorldX, WorldY, WorldZ, ShadowLevel));
g.DrawImage(Side, new Rectangle(x, y, Side.Width, Side.Height), 0, 0, Side.Width, Side.Height, GraphicsUnit.Pixel, TextureManager.GetShadow(DrawOrder[i], WorldX, WorldY, WorldZ, ShadowLevel, BlocksLight));
break;
}
break;
@@ -1009,12 +1194,12 @@ namespace VoxelIsometricRenderer
public static int[] GetDrawLocation(int x, int y, int z, int offsetX, int offsetY, int offsetZ)
{
return new int[]{(int)((((double)(x + offsetX) * 0.5) + ((double)(z + offsetZ) * -0.5))*(double)BlockSize),
(int)((((double)(x + offsetX) * 0.5) + ((double)(z + offsetZ) * 0.5) - (offsetY + (y)))*((double)BlockSize/2.0)) };
(int)((((double)(x + offsetX) * 0.5) + ((double)(z + offsetZ) * 0.5) - (-offsetY + (y)))*((double)BlockSize/2.0)) };
}
public static void RenderBlock(Graphics g, int BlockID,int WorldX, int WorldY, int WorldZ, int ShadowLevel)
{
int[] location = GetDrawLocation(WorldX, WorldY, WorldZ, 0, 0, 0);
VoxelRegistry.FetchVoxel(blocks[BlockID].FetchVoxelID()).Draw(g, location[0] + 300, location[1] + 300, WorldX, WorldY, WorldZ, ShadowLevel);
int[] location = GetDrawLocation(WorldX, WorldY, WorldZ, PlayerObject.GetPos()[0], PlayerObject.GetPos()[1], PlayerObject.GetPos()[2]);
VoxelRegistry.FetchVoxel(blocks[BlockID].FetchVoxelID()).Draw(g, location[0] + (Terrain4.width/4) , location[1] + (Terrain4.height/2), WorldX, WorldY, WorldZ, ShadowLevel, FetchBlockState(BlockID).hasBlocksLight());
}
public static int CheckInBlock(Block block,int x, int y, int z)
{