diff --git a/.gitignore b/.gitignore index 2c47411..f8ef2cf 100644 --- a/.gitignore +++ b/.gitignore @@ -198,3 +198,4 @@ xcuserdata/ # Ignore options.txt - where your configuration will be saved /game/options.txt /game/assetsO +/game/assets/snow.png diff --git a/source/client/renderer/GameRenderer.cpp b/source/client/renderer/GameRenderer.cpp index 64f18db..57e1cb0 100644 --- a/source/client/renderer/GameRenderer.cpp +++ b/source/client/renderer/GameRenderer.cpp @@ -55,6 +55,8 @@ void GameRenderer::_init() m_lastUpdatedMS = 0; m_shownFPS = 0; m_shownChunkUpdates = 0; + + m_envTexturePresence = 0; } GameRenderer::GameRenderer(Minecraft* pMinecraft) : @@ -508,20 +510,22 @@ void GameRenderer::renderLevel(float f) { glDisable(GL_ALPHA_TEST); + // added by iProgramInCpp - renders the cracks + pLR->renderHit((Player*)pMob, m_pMinecraft->m_hitResult, 0, nullptr, f); + if (m_pMinecraft->getOptions()->m_bBlockOutlines) pLR->renderHitOutline((Player*)pMob, m_pMinecraft->m_hitResult, 0, nullptr, f); else pLR->renderHitSelect((Player*)pMob, m_pMinecraft->m_hitResult, 0, nullptr, f); - // added by iProgramInCpp - renders the cracks - pLR->renderHit((Player*)pMob, m_pMinecraft->m_hitResult, 0, nullptr, f); - glEnable(GL_ALPHA_TEST); } - // @BUG? glDisable(GL_FOG); + if (false) // @TODO + renderWeather(f); + if (field_44 == 1.0f) { glClear(GL_DEPTH_BUFFER_BIT); @@ -812,6 +816,86 @@ void GameRenderer::prepareAndRenderClouds(LevelRenderer* pLR, float f) glMatrixMode(GL_MODELVIEW); } +void GameRenderer::renderWeather(float f) +{ + if (m_envTexturePresence == 0) + { + bool bLoadedSuccessfully = + m_pMinecraft->m_pTextures->loadTexture("snow.png", false) && + m_pMinecraft->m_pTextures->loadTexture("rain.png", false); + + m_envTexturePresence = bLoadedSuccessfully ? 2 : 1; + } + + if (m_envTexturePresence == 1) + return; + + LocalPlayer* pLP = m_pMinecraft->m_pLocalPlayer; + int bPosX = Mth::floor(pLP->m_pos.x); + int bPosY = Mth::floor(pLP->m_pos.y); + int bPosZ = Mth::floor(pLP->m_pos.z); + Vec3 pos = pLP->getPos(f); + Tesselator& t = Tesselator::instance; + Level* pLevel = m_pMinecraft->m_pLevel; + + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + m_pMinecraft->m_pTextures->loadAndBindTexture("snow.png"); + + int range = m_pMinecraft->getOptions()->m_bFancyGraphics ? 10 : 5; + + for (int currX = bPosX - range; currX <= bPosX + range; currX++) + { + for (int currZ = bPosZ - range; currZ <= bPosZ + range; currZ++) + { + int tsb = pLevel->getTopSolidBlock(currX, currZ); + if (tsb < 0) + tsb = 0; + + int minY = bPosY - range; + int maxY = bPosY + range; + + if (minY < tsb) + minY = tsb; + if (maxY < tsb) + maxY = tsb; + + float offs = 2.0f; + if (minY == maxY) + continue; + + m_random.setSeed(currX * currX * 3121 + currX * 45238971 + currZ * currZ * 418711 + currZ * 13761); + + float x1 = float(field_C) + f; + float x2 = (float(field_C & 0x1FF) + f) / 512.0f; + float x3 = m_random.nextFloat() + x1 * 0.01f * m_random.nextGaussian(); + float x4 = m_random.nextFloat() + x1 * 0.001f * m_random.nextGaussian(); + float f1 = float(currX + 0.5f) - pLP->m_pos.x; + float f2 = float(currZ + 0.5f) - pLP->m_pos.z; + float f3 = Mth::sqrt(f1 * f1 + f2 * f2) / float(range); + float f4 = pLevel->getBrightness(currX, 128, currZ); + t.begin(); + glColor4f(f4, f4, f4, (1.0f - f3 * f3) * 0.7f); + t.offset(-pos.x, -pos.y, -pos.z); + t.vertexUV(float(currX + 0), float(minY), float(currZ + 0), 0.0f * offs + x3, float(minY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 1), float(minY), float(currZ + 1), 1.0f * offs + x3, float(minY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 1), float(maxY), float(currZ + 1), 1.0f * offs + x3, float(maxY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 0), float(maxY), float(currZ + 0), 0.0f * offs + x3, float(maxY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 0), float(minY), float(currZ + 1), 0.0f * offs + x3, float(minY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 1), float(minY), float(currZ + 0), 1.0f * offs + x3, float(minY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 1), float(maxY), float(currZ + 0), 1.0f * offs + x3, float(maxY) * offs / 8.0f + x2 * offs + x4); + t.vertexUV(float(currX + 0), float(maxY), float(currZ + 1), 0.0f * offs + x3, float(maxY) * offs / 8.0f + x2 * offs + x4); + t.offset(0.0f, 0.0f, 0.0f); + t.draw(); + } + } + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); +} + void GameRenderer::onGraphicsReset() { diff --git a/source/client/renderer/GameRenderer.hpp b/source/client/renderer/GameRenderer.hpp index 69e383d..00d11d9 100644 --- a/source/client/renderer/GameRenderer.hpp +++ b/source/client/renderer/GameRenderer.hpp @@ -44,6 +44,7 @@ public: void pick(float); void renderItemInHand(float, int); void prepareAndRenderClouds(LevelRenderer* pLR, float f); + void renderWeather(float f); float getFov(float f); @@ -88,5 +89,8 @@ public: float m_matrix_model_view[16]; int m_shownFPS, m_shownChunkUpdates, m_lastUpdatedMS; + + int m_envTexturePresence; + Random m_random; }; diff --git a/source/client/renderer/Textures.hpp b/source/client/renderer/Textures.hpp index 06debe5..73ed345 100644 --- a/source/client/renderer/Textures.hpp +++ b/source/client/renderer/Textures.hpp @@ -35,7 +35,7 @@ struct TextureData class Textures { public: - int loadTexture(const std::string& name, bool b); + int loadTexture(const std::string& name, bool bRequired); int loadAndBindTexture(const std::string& name); void clear(); void tick(); diff --git a/source/common/Random.cpp b/source/common/Random.cpp index 0ca1536..79fe7e4 100644 --- a/source/common/Random.cpp +++ b/source/common/Random.cpp @@ -18,6 +18,7 @@ Random::Random(TLong seed) { setSeed(seed); + nextNextGaussian = INFINITY; } void Random::setSeed(TLong seed) @@ -105,3 +106,25 @@ int Random::nextInt() { return int(genrand_int32() >> 1); } + +float Random::nextGaussian() +{ + if (!isinf(nextNextGaussian)) + { + double backup = nextNextGaussian; + nextNextGaussian = INFINITY; + return backup; + } + // See Knuth, ACP, Section 3.4.1 Algorithm C. + float v1, v2, s; + do + { + v1 = 2 * nextFloat() - 1; + v2 = 2 * nextFloat() - 1; + s = v1 * v1 + v2 * v2; + } + while (s >= 1 || s == 0); + float mult = sqrtf(-2 * log(s) / s); + nextNextGaussian = v2 * mult; + return v1 * mult; +} diff --git a/source/common/Random.hpp b/source/common/Random.hpp index 694273d..67ee19c 100644 --- a/source/common/Random.hpp +++ b/source/common/Random.hpp @@ -42,6 +42,7 @@ class Random unsigned int rseed; unsigned TLong mt[CMATH_N]; // the array for the state vector int mti; // mti==N+1 means mt[N] is not initialized + double nextNextGaussian; public: Random(TLong seed = getTimeMs()); @@ -53,4 +54,5 @@ public: double genrand_real2(); TLong nextLong(); int nextInt(); + float nextGaussian(); };