Add ability to rotate skybox

This commit is contained in:
UnknownShadow200 2017-09-27 10:12:05 +10:00
parent fdb83f143e
commit b85afc73f9
10 changed files with 146 additions and 102 deletions

View File

@ -55,5 +55,7 @@ namespace ClassicalSharp.Events {
WeatherFade,
ExpFog,
SidesOffset,
SkyboxHorSpeed,
SkyboxVerSpeed,
}
}

View File

@ -72,6 +72,12 @@ namespace ClassicalSharp.Map {
/// <summary> Whether exponential fog mode is used by default. </summary>
public bool ExpFog;
/// <summary> Horizontal skybox rotation speed. </summary>
public float SkyboxHorSpeed;
/// <summary> Vertical skybox rotation speed. </summary>
public float SkyboxVerSpeed;
Game game;
public WorldEnv(Game game) {
this.game = game;
@ -83,6 +89,7 @@ namespace ClassicalSharp.Map {
EdgeHeight = -1; SidesOffset = -2; CloudHeight = -1;
EdgeBlock = Block.StillWater; SidesBlock = Block.Bedrock;
CloudsSpeed = 1; WeatherSpeed = 1; WeatherFade = 1;
SkyboxHorSpeed = 0; SkyboxVerSpeed = 0;
ResetLight();
SkyCol = DefaultSkyColour;
@ -156,6 +163,14 @@ namespace ClassicalSharp.Map {
/// EnvVariableChanged event with variable 'ExpFog'. </summary>
public void SetExpFog(bool expFog) { Set(expFog, ref ExpFog, EnvVar.ExpFog); }
/// <summary> Sets horizontal speed of skybox rotation, and raises
/// EnvVariableChanged event with variable 'SkyboxHorSpeed'. </summary>
public void SetSkyboxHorSpeed(float speed) { Set(speed, ref SkyboxHorSpeed, EnvVar.SkyboxHorSpeed); }
/// <summary> Sets vertical speed of skybox rotation, and raises
/// EnvVariableChanged event with variable 'SkyboxVerSpeed'. </summary>
public void SetSkyboxVerSpeed(float speed) { Set(speed, ref SkyboxVerSpeed, EnvVar.SkyboxVerSpeed); }
/// <summary> Sets weather, and raises
/// EnvVariableChanged event with variable 'Weather'. </summary>
public void SetWeather(Weather weather) {

View File

@ -360,6 +360,10 @@ namespace ClassicalSharp.Network.Protocols {
env.SetExpFog(value != 0); break;
case 9:
env.SetSidesOffset(value); break;
case 10:
env.SetSkyboxHorSpeed(value / 128f); break;
case 11:
env.SetSkyboxVerSpeed(value / 128f); break;
}
}

View File

@ -2,6 +2,7 @@
using System;
using ClassicalSharp.Events;
using ClassicalSharp.GraphicsAPI;
using ClassicalSharp.Map;
using OpenTK;
namespace ClassicalSharp.Renderers {
@ -64,11 +65,20 @@ namespace ClassicalSharp.Renderers {
game.Graphics.SetBatchFormat(VertexFormat.P3fT2fC4b);
Matrix4 m = Matrix4.Identity, rotY, rotX;
Vector2 rotation = game.Camera.GetCameraOrientation();
Matrix4.RotateY(out rotY, rotation.X); // yaw
// Base skybox rotation
float rotTime = (float)(game.accumulator * 2 * Math.PI); // So speed of 1 rotates whole skybox every second
WorldEnv env = game.World.Env;
Matrix4.RotateY(out rotY, env.SkyboxHorSpeed * rotTime);
Matrix4.Mult(out m, ref m, ref rotY);
Matrix4.RotateX(out rotX, rotation.Y); // pitch
Matrix4.RotateX(out rotX, env.SkyboxVerSpeed * rotTime);
Matrix4.Mult(out m, ref m, ref rotX);
// Rotate around camera
Vector2 rotation = game.Camera.GetCameraOrientation();
Matrix4.RotateY(out rotY, rotation.X); // Camera yaw
Matrix4.Mult(out m, ref m, ref rotY);
Matrix4.RotateX(out rotX, rotation.Y); // Cammera pitch
Matrix4.Mult(out m, ref m, ref rotX);
Matrix4.Mult(out m, ref m, ref game.Camera.tiltM);

View File

@ -148,6 +148,10 @@ void ZLibHeader_Read(Stream* s, ZLibHeader* header) {
#define DeflateState_UncompressedHeader 1
#define DeflateState_UncompressedData 2
#define DeflateState_DynamicHeader 3
#define DeflateState_DynamicCodeLens 4
#define DeflateState_DynamicLits 5
#define DeflateState_DynamicDists 6
#define DeflateState_CompressedData 7
#define DeflateState_Done 250
@ -184,11 +188,11 @@ state->NumBits -= tmp;
#define DEFLATE_NEXTBLOCK_STATE(state) state->State = state->LastBlock ? DeflateState_Done : DeflateState_Header;
void Deflate_Process(DeflateState* state) {
bool Deflate_Step(DeflateState* state) {
switch (state->State) {
case DeflateState_Header: {
while (state->NumBits < 3) {
if (state->AvailIn == 0) return;
if (state->AvailIn == 0) return false;
DEFLATE_GET_BYTE(state);
}
@ -203,10 +207,10 @@ void Deflate_Process(DeflateState* state) {
state->State = DeflateState_UncompressedHeader;
} break;
case 1: { /* Compressed with FIXED huffman table*/
case 1: { /* TODO: Compressed with FIXED huffman table*/
} break;
case 2: { /* Compressed with dynamic huffman table */
case 2: { /* TODO: Compressed with dynamic huffman table */
} break;
@ -218,7 +222,7 @@ void Deflate_Process(DeflateState* state) {
case DeflateState_UncompressedHeader: {
while (state->NumBits < 32) {
if (state->AvailIn == 0) return;
if (state->AvailIn == 0) return false;
DEFLATE_GET_BYTE(state);
}
@ -228,40 +232,77 @@ void Deflate_Process(DeflateState* state) {
if (len != (nlen ^ 0xFFFFUL)) {
ErrorHandler_Fail("DEFLATE - Uncompressed block LEN check failed");
}
state->UncompressedLen = len;
state->Index = len; /* Reuse for 'uncompressed length' */
state->State = DeflateState_UncompressedData;
} break;
case DeflateState_UncompressedData: {
/* TODO: HOW TO HANDLE INFINITE LOOP HERE ?????????? */
/* TODO TODO TODO TODO TODO TODO */
while (state->AvailIn > 0 && state->AvailOut > 0) {
if (state->AvailIn > 0 || state->AvailOut > 0) return false;
UInt32 copyLen = min(state->AvailIn, state->AvailOut);
copyLen = min(copyLen, state->UncompressedLen);
copyLen = min(copyLen, state->Index);
Platform_MemCpy(state->Output, state->Input, copyLen);
state->Output += copyLen;
state->AvailIn -= copyLen;
state->AvailOut -= copyLen;
state->UncompressedLen -= copyLen;
state->Index -= copyLen;
if (state->UncompressedLen == 0) {
if (state->Index == 0) {
state->State = DEFLATE_NEXTBLOCK_STATE(state);
break;
}
}
} break;
case DeflateState_DynamicHeader: {
while (state->NumBits < 14) {
if (state->AvailIn == 0) return;
if (state->AvailIn == 0) return false;
DEFLATE_GET_BYTE(state);
}
UInt32 numLits, numDists, numCodeLens;
DEFLATE_CONSUME_BITS(state, 5, numLits); numLits += 257;
DEFLATE_CONSUME_BITS(state, 5, numDists); numDists += 1;
DEFLATE_CONSUME_BITS(state, 4, numCodeLens); numCodeLens += 4;
DEFLATE_CONSUME_BITS(state, 5, state->NumLits); state->NumLits += 257;
DEFLATE_CONSUME_BITS(state, 5, state->NumDists); state->NumDists += 1;
DEFLATE_CONSUME_BITS(state, 4, state->NumCodeLens); state->NumCodeLens += 4;
state->State = DeflateState_DynamicCodeLens;
} break;
case DeflateState_DynamicCodeLens: {
while (state->Index < state->NumCodeLens) {
while (state->NumBits < 3) {
if (state->AvailIn == 0) return false;
DEFLATE_GET_BYTE(state);
}
}
state->Index = 0;
state->State = DeflateState_DynamicLits;
} break;
case DeflateState_DynamicLits: {
while (state->Index < state->NumLits) {
/* TODO ???????? */
}
state->Index = 0;
state->State = DeflateState_DynamicDists;
} break;
case DeflateState_DynamicDists: {
while (state->Index < state->NumDists) {
/* TODO ???????? */
}
state->Index = 0;
state->State = DeflateState_CompressedData;
} break;
case DeflateState_CompressedData: {
/* TODO ????? */
}
case DeflateState_Done:
return false;
}
return true;
}
void Deflate_Process(DeflateState* state) {
while (state->AvailIn > 0 || state->AvailOut > 0) {
if (!Deflate_Step(state)) return;
}
}

View File

@ -47,7 +47,8 @@ typedef struct DeflateState_ {
UInt8* Output; /* Pointer for output data */
UInt32 AvailOut; /* Max number of bytes to output */
UInt32 UncompressedLen;
UInt32 Index; /* General purpose reusable index / counter */
UInt32 NumCodeLens, NumLits, NumDists;
} DeflateState;
void Deflate_Init(DeflateState* state, Stream* source);

View File

@ -67,12 +67,16 @@ typedef Int32 EnvVar;
#define EnvVar_WeatherFade 7
#define EnvVar_Weather 8
#define EnvVar_ExpFog 9
#define EnvVar_SkyboxHorSpeed 10
#define EnvVar_SkyboxVerSpeed 11
#define EnvVar_SkyCol 12
#define EnvVar_CloudsCol 13
#define EnvVar_FogCol 14
#define EnvVar_SunCol 15
#define EnvVar_ShadowCol 16
#define EnvVar_SkyCol 10
#define EnvVar_CloudsCol 11
#define EnvVar_FogCol 12
#define EnvVar_SunCol 13
#define EnvVar_ShadowCol 14
/*

View File

@ -10,6 +10,7 @@
#include "VertexStructs.h"
#include "World.h"
#include "EnvRenderer.h"
#include "ExtMath.h"
GfxResourceID skybox_tex, skybox_vb = -1;
#define SKYBOX_COUNT (6 * 4)
@ -33,17 +34,25 @@ void SkyboxRenderer_Render(Real64 deltaTime) {
Gfx_SetBatchFormat(VertexFormat_P3fT2fC4b);
Matrix m = Matrix_Identity;
Vector2 rotation = Camera_ActiveCamera->GetCameraOrientation();
Matrix rotX, rotY;
Matrix_RotateY(&rotY, rotation.Y); /* Yaw */
/* Base skybox rotation */
Real32 rotTime = (Real32)(Game_Accumulator * 2 * MATH_PI); /* So speed of 1 rotates whole skybox every second */
Matrix_RotateY(&rotY, WorldEnv_SkyboxHorSpeed * rotTime);
Matrix_MulBy(&m, &rotY);
Matrix_RotateX(&rotX, rotation.X); /* Pitch */
Matrix_RotateX(&rotX, WorldEnv_SkyboxVerSpeed * rotTime);
Matrix_MulBy(&m, &rotX);
/* Rotate around camera */
Vector2 rotation = Camera_ActiveCamera->GetCameraOrientation();
Matrix_RotateY(&rotY, rotation.Y); /* Camera yaw */
Matrix_MulBy(&m, &rotY);
Matrix_RotateX(&rotX, rotation.X); /* Camera pitch */
Matrix_MulBy(&m, &rotX);
/* Tilt skybox too. */
Matrix_MulBy(&m, &Camera_TiltM);
Gfx_LoadMatrix(&m);
Gfx_LoadMatrix(&m);
Gfx_BindVb(skybox_vb);
Gfx_DrawVb_IndexedTris(SKYBOX_COUNT);

View File

@ -112,6 +112,8 @@ void WorldEnv_Reset(void) {
WorldEnv_CloudsSpeed = 1.0f;
WorldEnv_WeatherSpeed = 1.0f;
WorldEnv_WeatherFade = 1.0f;
WorldEnv_SkyboxHorSpeed = 0.0f;
WorldEnv_SkyboxVerSpeed = 0.0f;
WorldEnv_ResetLight();
WorldEnv_SkyCol = WorldEnv_DefaultSkyCol;
@ -178,6 +180,14 @@ void WorldEnv_SetExpFog(bool expFog) {
WorldEnv_Set(expFog, WorldEnv_ExpFog, EnvVar_ExpFog);
}
void WorldEnv_SetSkyboxHorSpeed(Real32 speed) {
WorldEnv_Set(speed, WorldEnv_SkyboxHorSpeed, EnvVar_SkyboxHorSpeed);
}
void WorldEnv_SetSkyboxVerSpeed(Real32 speed) {
WorldEnv_Set(speed, WorldEnv_SkyboxVerSpeed, EnvVar_SkyboxVerSpeed);
}
void WorldEnv_SetSkyCol(PackedCol col) {
WorldEnv_SetCol(col, WorldEnv_SkyCol, EnvVar_SkyCol);

View File

@ -9,208 +9,156 @@
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
*/
/* Weather types a world can have. */
typedef Int32 Weather;
#define Weather_Sunny 0
#define Weather_Rainy 1
#define Weather_Snowy 2
/* Converts a single integer index into coordinates. */
#define World_Unpack(index, x, y, z)\
x = index % World_Width;\
z = (index / World_Width) % World_Length;\
y = (index / World_Width) / World_Length;
/* Packs a coordinate into a single integer index. */
#define World_Pack(x, y, z) (((y) * World_Length + (z)) * World_Width + (x))
/* Raw blocks of this world. */
BlockID* World_Blocks;
/* Size of blocks array. */
Int32 World_BlocksSize;
/* Length of world on X axis.*/
Int32 World_Width;
/* Length of world on Y axis (vertical).*/
Int32 World_Height;
/* Length of world on Z axis.*/
Int32 World_Length;
/* Largest valid X coordinate. */
Int32 World_MaxX;
/* Largest valid Y coordinate. */
Int32 World_MaxY;
/* Largest valid Z coordinate. */
Int32 World_MaxZ;
/* Amount a packed index must be changed by to advance Y coordinate. */
Int32 World_OneY;
/* Unique uuid/guid of this particular world. */
UInt8 World_Uuid[16];
/* Current terrain.png or texture pack url of this map. */
String World_TextureUrl;
/* TODO: how to initalise this string */
/* Resets all of the properties to their defaults. */
void World_Reset(void);
/* Updates the underlying block array, heightmap, and dimensions of this map. */
void World_SetNewMap(BlockID* blocks, Int32 blocksSize, Int32 width, Int32 height, Int32 length);
BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z);
/* Sets the block at the given coordinates without bounds checking. */
#define World_SetBlock(x, y, z, blockId) World_Blocks[World_Pack(x, y, z)] = blockId
/* Sets the block at the given coordinates without bounds checking. */
#define World_SetBlock_3I(p, blockId) World_Blocks[World_Pack(p.X, p.Y, p.Z)] = blockId
/* Returns the block at the given coordinates without bounds checking. */
#define World_GetBlock(x, y, z) World_Blocks[World_Pack(x, y, z)]
/* Returns the block at the given world coordinates without bounds checking. */
#define World_GetBlock_3I(x, y, z) World_Blocks[World_Pack(p.X, p.Y, p.Z)]
/* Returns block at given coordinates if coordinates are inside the map, 0 if outside. */
BlockID World_SafeGetBlock(Int32 x, Int32 y, Int32 z);
/* Returns block at given coordinates if coordinates are inside the map, 0 if outside. */
BlockID World_SafeGetBlock_3I(Vector3I p);
/* Returns whether given coordinates are contained inside this map. */
bool World_IsValidPos(Int32 x, Int32 y, Int32 z);
/* Returns whether given coordinates are contained inside this map. */
bool World_IsValidPos_3I(Vector3I p);
/* Unpacks the given index into the map's block array into its original world coordinates. */
Vector3I World_GetCoords(Int32 index);
/* Block that surrounds map the map horizontally (default water) */
BlockID WorldEnv_EdgeBlock;
/* Block that surrounds the map that fills the bottom of the map horizontally,
fills part of the vertical sides of the map, and also surrounds map the map horizontally. (default bedrock) */
BlockID WorldEnv_SidesBlock;
/* Height of the map edge. */
Int32 WorldEnv_EdgeHeight;
/* Offset of height of map sides from height of map edge. */
Int32 WorldEnv_SidesOffset;
/* Height of the map sides. */
#define WorldEnv_SidesHeight (WorldEnv_EdgeHeight + WorldEnv_SidesOffset)
/* Height of the clouds. */
Int32 WorldEnv_CloudsHeight;
/* Modifier of how fast clouds travel across the world, defaults to 1. */
Real32 WorldEnv_CloudsSpeed;
/* Modifier of how fast rain/snow falls, defaults to 1. */
Real32 WorldEnv_WeatherSpeed;
/* Modifier of how fast rain/snow fades, defaults to 1. */
Real32 WorldEnv_WeatherFade;
/* Current weather for this particular map. */
Weather WorldEnv_Weather;
/* Whether exponential fog mode is used by default. */
bool WorldEnv_ExpFog;
/* Horizontal skybox rotation speed. */
Real32 WorldEnv_SkyboxHorSpeed;
/* Vertical skybox rotation speed. */
Real32 WorldEnv_SkyboxVerSpeed;
/* Colour of the sky located behind / above clouds. */
PackedCol WorldEnv_SkyCol;
PackedCol WorldEnv_DefaultSkyCol;
/* Colour applied to the fog/horizon looking out horizontally.
Note the true horizon colour is a blend of this and sky colour. */
PackedCol WorldEnv_FogCol;
PackedCol WorldEnv_DefaultFogCol;
/* Colour applied to the clouds. */
PackedCol WorldEnv_CloudsCol;
PackedCol WorldEnv_DefaultCloudsCol;
/* Colour applied to blocks located in direct sunlight. */
PackedCol WorldEnv_SunCol;
PackedCol WorldEnv_SunXSide, WorldEnv_SunZSide, WorldEnv_SunYBottom;
PackedCol WorldEnv_DefaultSunCol;
/* Colour applied to blocks located in shadow / hidden from direct sunlight. */
PackedCol WorldEnv_ShadowCol;
PackedCol WorldEnv_ShadowXSide, WorldEnv_ShadowZSide, WorldEnv_ShadowYBottom;
PackedCol WorldEnv_DefaultShadowCol;
/* Resets all of the environment properties to their defaults. */
void WorldEnv_Reset(void);
/*Resets sun and shadow environment properties to their defaults. */
void WorldEnv_ResetLight(void);
/* Sets edge block to the given block, and raises event with variable 'EdgeBlock'. */
void WorldEnv_SetEdgeBlock(BlockID block);
/* Sets sides block to the given block, and raises event with variable 'SidesBlock'. */
void WorldEnv_SetSidesBlock(BlockID block);
/* Sets height of the map edges, raises event with variable 'EdgeHeight'. */
void WorldEnv_SetEdgeHeight(Int32 height);
/* Sets offset of the height of the map sides from map edges, raises event with variable 'SidesLevel'. */
void WorldEnv_SetSidesOffset(Int32 offset);
/* Sets clouds height in world space, raises event with variable 'CloudsHeight'. */
void WorldEnv_SetCloudsHeight(Int32 height);
/* Sets clouds speed, raises event with variable 'CloudsSpeed'. */
void WorldEnv_SetCloudsSpeed(Real32 speed);
/* Sets weather speed, raises event with variable 'WeatherSpeed'. */
void WorldEnv_SetWeatherSpeed(Real32 speed);
void WorldEnv_SetWeatherSpeed(Real32 speed);
/* Sets weather fade rate, raises event with variable 'WeatherFade'. */
void WorldEnv_SetWeatherFade(Real32 rate);
/* Sets weather, raises event with variable 'Weather'. */
void WorldEnv_SetWeather(Weather weather);
/* Sets whether exponential fog is used, raises event with variable 'ExpFog'. */
void WorldEnv_SetExpFog(bool expFog);
/* Sets horizontal speed of skybox rotation, raises event with variable 'SkyboxHorSpeed'. */
void WorldEnv_SetSkyboxHorSpeed(Real32 speed);
/* Sets vertical speed of skybox rotation, raises event with variable 'SkyboxVerSpeed'. */
void WorldEnv_SetSkyboxVerSpeed(Real32 speed);
/* Sets sky colour, raises event with variable 'SkyCol'. */
void WorldEnv_SetSkyCol(PackedCol col);
/* Sets fog colour, raises event with variable 'FogCol'. */
void WorldEnv_SetFogCol(PackedCol col);
/* Sets clouds colour, and raises event with variable 'CloudsCol'. */
void WorldEnv_SetCloudsCol(PackedCol col);
/* Sets sun colour, and raises event with variable 'SunCol'. */
void WorldEnv_SetSunCol(PackedCol col);
/* Sets shadow colour, and raises event with variable 'ShadowCol'. */
void WorldEnv_SetShadowCol(PackedCol col);
#endif