diff --git a/.gitignore b/.gitignore index bf3de2f..9e78a77 100644 --- a/.gitignore +++ b/.gitignore @@ -401,7 +401,7 @@ FodyWeavers.xsd /game/assets/particles.png /game/assets/terrain.png -# Ignore the panorama textures. +# Ignore the panorama textures. Adding them yourself will make the title screen use them. /game/assets/gui/background/panorama_0.png /game/assets/gui/background/panorama_1.png /game/assets/gui/background/panorama_2.png @@ -409,6 +409,9 @@ FodyWeavers.xsd /game/assets/gui/background/panorama_4.png /game/assets/gui/background/panorama_5.png +# Ignore the clouds texture. Adding them yourself will make the game use them. +/game/assets/environment/clouds.png + # Avoid including Minecraft Classic assets from Mojang, for now. /game/assets/patches/*.png /game/assets/patches/classic/*.png diff --git a/platforms/sdl/main.cpp b/platforms/sdl/main.cpp index ba09ebf..b255ab5 100644 --- a/platforms/sdl/main.cpp +++ b/platforms/sdl/main.cpp @@ -208,6 +208,13 @@ static EM_BOOL main_loop(double time, void *user_data) } extern bool g_bIsMenuBackgroundAvailable; // client/gui/Screen.cpp +extern bool g_bAreCloudsAvailable; // client/renderer/LevelRenderer.cpp + +void CheckOptionalTextureAvailability() +{ + g_bIsMenuBackgroundAvailable = XPL_ACCESS("assets/gui/background/panorama_0.png", 0) == 0; + g_bAreCloudsAvailable = XPL_ACCESS("assets/environment/clouds.png", 0) == 0; +} // Main int main(int argc, char *argv[]) @@ -237,7 +244,7 @@ int main(int argc, char *argv[]) Minecraft::height = std::stoi(argv[2]); #endif - g_bIsMenuBackgroundAvailable = XPL_ACCESS("assets/gui/background/panorama_0.png", 0) == 0; + CheckOptionalTextureAvailability(); // Create Window window = SDL_CreateWindow("ReMinecraftPE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Minecraft::width, Minecraft::height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); diff --git a/platforms/windows/main.cpp b/platforms/windows/main.cpp index 4da5196..6e7f2ee 100644 --- a/platforms/windows/main.cpp +++ b/platforms/windows/main.cpp @@ -70,8 +70,6 @@ void UpdateMouse() Mouse::setY(g_MousePosY); } -extern bool g_bIsMenuBackgroundAvailable; - LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) @@ -201,6 +199,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) return 0; } +extern bool g_bIsMenuBackgroundAvailable; // client/gui/Screen.cpp +extern bool g_bAreCloudsAvailable; // client/renderer/LevelRenderer.cpp + +void CheckOptionalTextureAvailability() +{ + // Optional features that you really should be able to get away with not including. + g_bIsMenuBackgroundAvailable = XPL_ACCESS("assets/gui/background/panorama_0.png", 0) == 0; + g_bAreCloudsAvailable = XPL_ACCESS("assets/environment/clouds.png", 0) == 0; +} + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { SetInstance(hInstance); @@ -220,7 +228,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLin wc.lpszMenuName = NULL; wc.lpszClassName = g_WindowClassName; - g_bIsMenuBackgroundAvailable = XPL_ACCESS("assets/gui/background/panorama_0.png", 0) == 0; + CheckOptionalTextureAvailability(); RECT wr = { 0,0, g_AppPlatform.getScreenWidth(), g_AppPlatform.getScreenHeight() }; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, false); diff --git a/source/client/gui/Screen.cpp b/source/client/gui/Screen.cpp index 157fb83..8001a83 100644 --- a/source/client/gui/Screen.cpp +++ b/source/client/gui/Screen.cpp @@ -138,6 +138,11 @@ void Screen::renderMenuBackground(float f) g_panoramaAngle += float(30.0 * m_pMinecraft->m_fDeltaTime); + float aspectRatio; + + aspectRatio = 1.0f; + //aspectRatio = float(m_width) / float(m_height); + // not in 0.8 glDisable(GL_BLEND); glDisable(GL_CULL_FACE); @@ -145,7 +150,7 @@ void Screen::renderMenuBackground(float f) glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); + gluPerspective(120.0f, aspectRatio, 0.05f, 10.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); diff --git a/source/client/renderer/GameRenderer.cpp b/source/client/renderer/GameRenderer.cpp index 94f50d0..e61b04b 100644 --- a/source/client/renderer/GameRenderer.cpp +++ b/source/client/renderer/GameRenderer.cpp @@ -430,6 +430,7 @@ void GameRenderer::renderLevel(float f) setupCamera(f, i); saveMatrices(); + /* if (m_pMinecraft->m_options.m_iViewDistance <= 1) { #ifndef ORIGINAL_CODE @@ -440,6 +441,7 @@ void GameRenderer::renderLevel(float f) setupFog(-1); pLR->renderSky(f); } + */ glEnable(GL_FOG); setupFog(1); @@ -457,6 +459,9 @@ void GameRenderer::renderLevel(float f) pLR->cull(&frustumCuller, f); pLR->updateDirtyChunks(pMob, false); + // TODO[v0.6.1]: what is (this+4)+63 (byte)? + prepareAndRenderClouds(pLR, f); + setupFog(0); glEnable(GL_FOG); @@ -486,7 +491,6 @@ void GameRenderer::renderLevel(float f) glDepthMask(true); - #ifndef ORIGINAL_CODE glShadeModel(GL_FLAT); #endif @@ -734,6 +738,34 @@ void GameRenderer::renderItemInHand(float f, int i) bobView(f); } +void GameRenderer::prepareAndRenderClouds(LevelRenderer* pLR, float f) +{ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPerspective(getFov(f), float(Minecraft::width) / float(Minecraft::height), 0.05f, field_8 * 512.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + setupFog(0); + glDepthMask(false); + glEnable(GL_FOG); + glFogf(GL_FOG_START, field_8 * 0.2f); + glFogf(GL_FOG_END, field_8 * 0.75f); + pLR->renderSky(f); + glFogf(GL_FOG_START, field_8 * 4.2f * 0.6f); + glFogf(GL_FOG_END, field_8 * 4.2f); + pLR->renderClouds(f); + glFogf(GL_FOG_START, field_8 * 0.6f); + glFogf(GL_FOG_END, field_8); + glDisable(GL_FOG); + glDepthMask(true); + setupFog(1); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); +} + void GameRenderer::onGraphicsReset() { diff --git a/source/client/renderer/GameRenderer.hpp b/source/client/renderer/GameRenderer.hpp index 6032796..69e383d 100644 --- a/source/client/renderer/GameRenderer.hpp +++ b/source/client/renderer/GameRenderer.hpp @@ -13,6 +13,7 @@ class Minecraft; class Entity; +class LevelRenderer; class GameRenderer { private: @@ -42,6 +43,7 @@ public: void setupFog(int i); void pick(float); void renderItemInHand(float, int); + void prepareAndRenderClouds(LevelRenderer* pLR, float f); float getFov(float f); diff --git a/source/client/renderer/LevelRenderer.cpp b/source/client/renderer/LevelRenderer.cpp index e4ec05c..900c540 100644 --- a/source/client/renderer/LevelRenderer.cpp +++ b/source/client/renderer/LevelRenderer.cpp @@ -44,7 +44,7 @@ LevelRenderer::LevelRenderer(Minecraft* pMC, Textures* pTexs) field_B0 = 0; field_B8 = false; field_BC = -1; - field_C0 = 0; + m_ticksSinceStart = 0; m_nBuffers = 26136; m_pMinecraft = pMC; @@ -583,7 +583,7 @@ void LevelRenderer::render(Mob* pMob, int a, float b) float y6 = pChunk->distanceToSqr(pMob); int y7 = int(Mth::sqrt(y6) / 128.0f + 1.0f); - if (field_C0 % y7 != y3 % y7) + if (m_ticksSinceStart % y7 != y3 % y7) goto label_26; float fXdiff, fYdiff, fZdiff; @@ -693,7 +693,7 @@ void LevelRenderer::setTilesDirty(int x1, int y1, int z1, int x2, int y2, int z2 void LevelRenderer::tick() { - field_C0++; + m_ticksSinceStart++; } /* @@ -1194,6 +1194,62 @@ void LevelRenderer::renderSky(float f) glDepthMask(true); } +bool g_bAreCloudsAvailable = false; // false because 0.1 didn't have them + +void LevelRenderer::renderClouds(float f) +{ + if (!g_bAreCloudsAvailable) + return; + + glEnable(GL_TEXTURE_2D); + glDisable(GL_CULL_FACE); + + float yPos = Lerp(m_pMinecraft->m_pMobPersp->field_98.y, m_pMinecraft->m_pMobPersp->m_pos.y, f); // not certain if this old pos Y is used + m_pTextures->loadAndBindTexture("environment/clouds.png"); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + Vec3 cloudColor = m_pLevel->getCloudColor(f); + + float offX = Lerp(m_pMinecraft->m_pMobPersp->field_3C.x, m_pMinecraft->m_pMobPersp->m_pos.x, f) + (float(m_ticksSinceStart) + f) * 0.3f; + float offZ = Lerp(m_pMinecraft->m_pMobPersp->field_3C.z, m_pMinecraft->m_pMobPersp->m_pos.z, f); + + int dx2048 = Mth::floor(offX / 2048.0f); + int dz2048 = Mth::floor(offZ / 2048.0f); + + offX -= float(dx2048 * 2048); + offZ -= float(dz2048 * 2048); + + Tesselator& t = Tesselator::instance; + + float fYPos = (128.0f - yPos) + 0.33f; + offX /= 2048.0f; + offZ /= 2048.0f; + t.begin(); + t.color(cloudColor.x, cloudColor.y, cloudColor.z, 0.8f); + + const int incr = 32; + const int in2 = 256 / incr; + for (int x = -incr * in2; x < incr * in2; x += incr) + { + for (int z = -incr * in2; z < incr * in2; z += incr) + { + t.vertexUV(float(x) + 0.0f, fYPos, float(z) + incr, float(x + 0.0f) / 2048.0f + offX, float(z + incr) / 2048.0f + offZ); + t.vertexUV(float(x) + incr, fYPos, float(z) + incr, float(x + incr) / 2048.0f + offX, float(z + incr) / 2048.0f + offZ); + t.vertexUV(float(x) + incr, fYPos, float(z) + 0.0f, float(x + incr) / 2048.0f + offX, float(z + 0.0f) / 2048.0f + offZ); + t.vertexUV(float(x) + 0.0f, fYPos, float(z) + 0.0f, float(x + 0.0f) / 2048.0f + offX, float(z + 0.0f) / 2048.0f + offZ); + } + + } + + t.voidBeginAndEndCalls(false); // why?? + t.draw(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); + glEnable(GL_CULL_FACE); +} + void LevelRenderer::skyColorChanged() { for (int i = 0; i < m_chunksLength; i++) diff --git a/source/client/renderer/LevelRenderer.hpp b/source/client/renderer/LevelRenderer.hpp index c7a8412..c378c6b 100644 --- a/source/client/renderer/LevelRenderer.hpp +++ b/source/client/renderer/LevelRenderer.hpp @@ -90,6 +90,7 @@ public: void render(Mob* pMob, int a, float b); void renderEntities(Vec3 pos, Culler*, float f); void renderSky(float); + void renderClouds(float); void checkQueryResults(int, int); void renderSameAsLast(int, float); int renderChunks(int start, int end, int a, float b); @@ -137,7 +138,7 @@ public: Minecraft* m_pMinecraft; bool field_B8; int field_BC; - int field_C0; + int m_ticksSinceStart; //... int m_nBuffers; GLuint* m_pBuffers; diff --git a/source/world/level/Level.cpp b/source/world/level/Level.cpp index c95c566..3f85afd 100644 --- a/source/world/level/Level.cpp +++ b/source/world/level/Level.cpp @@ -1246,6 +1246,25 @@ Vec3 Level::getFogColor(float f) return m_pDimension->getFogColor(getTimeOfDay(f), f); } +Vec3 Level::getCloudColor(float f) +{ + Vec3 result; + + float fTODCosAng = Mth::cos(getSunAngle(f)); + + float mult = 2 * fTODCosAng + 0.5f; + if (mult < 0.0f) + mult = 0.0f; + if (mult > 1.0f) + mult = 1.0f; + + result.x = mult * 0.9f + 0.1f; + result.y = result.x; + result.z = mult * 0.85f + 0.15f; + + return result; +} + bool Level::isUnobstructed(AABB* aabb) { EntityVector* entities = getEntities(nullptr, *aabb); diff --git a/source/world/level/Level.hpp b/source/world/level/Level.hpp index 81d70dd..e2ec60e 100644 --- a/source/world/level/Level.hpp +++ b/source/world/level/Level.hpp @@ -113,6 +113,7 @@ public: bool canSeeSky(int x, int y, int z); Vec3 getSkyColor(Entity* pEnt, float f); Vec3 getFogColor(float f); + Vec3 getCloudColor(float f); bool isUnobstructed(AABB*); bool mayInteract(Player* player, int x, int y, int z); bool mayPlace(TileID tid, int x, int y, int z, bool b); diff --git a/windows_vs/minecraftcpp.vcxproj.filters b/windows_vs/minecraftcpp.vcxproj.filters index bf5a098..104243a 100644 --- a/windows_vs/minecraftcpp.vcxproj.filters +++ b/windows_vs/minecraftcpp.vcxproj.filters @@ -2168,6 +2168,9 @@ thirdparty\zlib + + source\client\network\packets +