From 31d80aedf866e68b86cc93c3bd5d46e87dd5bad1 Mon Sep 17 00:00:00 2001 From: Shredder Date: Sat, 25 Apr 2026 04:47:07 +0500 Subject: [PATCH] Massive Java Parity Update - fileshredder 3D/Fancy Clouds have been ported over Sky Rendering is now an option between Java and PE Java Sky/Fog color option is now accurate using the original color ramp instead of PE's slightly lower one Grass Sides are now tinted, and can be toggled in settings Added stars, the sun, and the moon in the daylight cycle Sunset color has been added, appears when the sun is rising or falling, buggy on PE's sky rendering option. Fixed leaves being rendered bright green when foliage tinting was turned off. Enabled Tall Grass generation code Tall Grass is now tinted. Other compile options have to be tested --- data/images/misc/water.png | Bin 0 -> 306 bytes data/images/terrain/moon.png | Bin 0 -> 910 bytes data/images/terrain/sun.png | Bin 0 -> 799 bytes src/client/Minecraft.cpp | 6 +- src/client/Options.cpp | 8 + src/client/Options.h | 2 + src/client/gui/Gui.cpp | 3 + src/client/gui/screens/OptionsScreen.cpp | 2 + src/client/renderer/GameRenderer.cpp | 49 +- src/client/renderer/LevelRenderer.cpp | 365 +++++++++- src/client/renderer/LevelRenderer.h | 11 + src/client/renderer/TileRenderer.cpp | 681 ++++++++++-------- src/client/renderer/TileRenderer.h | 6 + src/world/entity/animal/Sheep.cpp | 9 +- src/world/item/DyePowderItem.cpp | 7 +- src/world/item/ShearsItem.h | 2 +- src/world/level/FoliageColor.h | 2 +- src/world/level/Level.cpp | 9 +- src/world/level/biome/Biome.cpp | 21 + src/world/level/biome/Biome.h | 8 + .../level/levelgen/RandomLevelSource.cpp | 4 +- src/world/level/tile/LeafTile.h | 1 + src/world/level/tile/TallGrass.cpp | 25 +- 23 files changed, 864 insertions(+), 357 deletions(-) create mode 100644 data/images/misc/water.png create mode 100644 data/images/terrain/moon.png create mode 100644 data/images/terrain/sun.png diff --git a/data/images/misc/water.png b/data/images/misc/water.png new file mode 100644 index 0000000000000000000000000000000000000000..8b92f9bcf74590e50f4eed14ad30e63b634705ea GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6-MC9V-A z!TD(=<%vb93;~Imc_n&&t|1C##(KtPE1y471*$pf>Eak-;oloIy5((r`rAv< z+c(9?XYS$6bXla_IG_8G!ZR-Ei5>qJ9zM@q;p6#$jXy|5W&vyOTxIw5Yd*+^`W>j% zEV*H7cz-5e>s(WdEJOal?E(i=<@KTjTqdtyczccEtI6y#iU(r1vfkaj_|Auf{Mz() z;WiyBWDGwE9F$X@x^d>I^q10tJe;SKS8ZHt)-753^V_VsAG1LoV(@hJb6Mw<&;$T3 C&3H)w literal 0 HcmV?d00001 diff --git a/data/images/terrain/moon.png b/data/images/terrain/moon.png new file mode 100644 index 0000000000000000000000000000000000000000..61cebbc7e37dab2eabff7bb7256ae17c549c20c0 GIT binary patch literal 910 zcmV;919AL`P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+xt=~>kP00RC=L_t(oN6nW_a??N%g=Oo*3a}$luTRk-u@kfv%D>o1?2`5RF(INJj>+E8F*e=--vSCi?1z`!OI#;S zsUK%Nxkf)81W{kd{Zt?grcx~csUR8voII=+lWD>@$tg~Ulw<`T!_aF(8H2G3)B;jL z1OTr3Ah}j7iCxkp8&NtKQ<_iOgYRLC!Kg|K5~vYEfTRY{fm$`H!DN2oY&fGqvCtTu zX}I6GCvZLp&tYm{Zn2{kz*P_LKwT#*Z$1*ofsk0QHN zzNTXGge!d}$tKH}99x>KUTNT*ui+lXV5~ui9nuqpdpgixtU}!f4B+Iiy|?NYPWB5g z`Ie^ZHyl?qJHM8|Ij#Z3AXEvqgL^`)U=>_1G;B}+Uw*3|O$A>?cBya`9i3M0F?rK6L zvW~Z^{cA@xp{;`Z9z#otV-w`4#}JFdaSIVIMyuBkT!^||iuG;S;mhbhc^&Iwq_5;| zK1ke(*xe^twItj3|D%4Ch99OKe3p9vl@+)52mg3u(tv1yJi^v&&mJ+@Hyp4*efZ{d k-Px# literal 0 HcmV?d00001 diff --git a/data/images/terrain/sun.png b/data/images/terrain/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..d3433441fbed6519f5925436583ac2a6b518f211 GIT binary patch literal 799 zcmV+)1K|9LP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02y>eSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+xt=~>kP00NImL_t(oN7a|vR^mVqh7%GX5J245qaO9B z&oYnd`*<-=Q8f>q7JdUmamq??j%VP+egwgvG2$}J~ujl18fU48YQ-m zY_s12)c|x26)ekAb4e`E)188j^kv`m+W~QaSg9S@gO10kO(vsC_)Tp(9koR3=%9;@ zVERBJh&BMqakd`V0~SSQvsq^Id0q*>vE*S79dxnj15u(a04>JBl`+l~v@CO5F2}Z7 z^$UCG0Emr)ctzrBbRe4YJ3z82cN((6SsZx1p4iFBG|1_xi~eR0xEKTsL z=^fMxzF6eJsREy!6?T4J*yZJ{C9JUrj6kp@0f!iE<|3^j>empWID1Nmp@JVDd!`C} zb2GQw+p-dV{h2kO&_Nd)zy*O%wL(>B0Wf%;eH!{l*>RxY7Z-(HUClzk`}>7GJS^<- zaT$bX*4RS_-53I2_{6ur9cgGo08l?zgizVjM@oq!9A00~?e4A&!JeL0_WZoEmlqeF zSz`|!bOnJAd{NP+3Jwq;;_|Ea%AS5wQnFHTg1x>T+1uNZy}z%6@XQ)}g1`n_d{9Yz zY8K*QtO4TkD|?2DzEWBo6Tm)y?G!;^gDpN(g}4p%9H;^Upi~emdxnetQev_U0QS)@ z)gC(NVuNj51$=7`dI7xuSq`U(#68uD=%>_f!2V6acIj$?!UGZMhy z|BeSgkaQ0vyb%XIk~IK+fIR4-G`<%MaxDK57n3f8TGCYHA79Pl``Tca(_L5U?_AC6 d6Ym~Z|3Byt_NjE?O~U{H002ovPDHLkV1jmmUEcrz literal 0 HcmV?d00001 diff --git a/src/client/Minecraft.cpp b/src/client/Minecraft.cpp index 0ea8e9db..2a05eb2e 100755 --- a/src/client/Minecraft.cpp +++ b/src/client/Minecraft.cpp @@ -1156,6 +1156,10 @@ void Minecraft::init() FoliageColor::setUseTint(tint); GrassColor::setUseTint(tint); + bool sideTint = options.getBooleanValue(OPTIONS_TINTED_SIDE); + TileRenderer::setUseTint(sideTint); + + // Platform specific initialization here font = new Font(&options, "font/default8.png", textures); @@ -1408,7 +1412,7 @@ void Minecraft::_levelGenerated() if (level && level->dimension) { // For example, if you want FogType or any other option - level->dimension->FogType = options.getBooleanValue(OPTIONS_FOG_TYPE); + level->dimension->FogType = options.getIntValue(OPTIONS_FOG_TYPE); } diff --git a/src/client/Options.cpp b/src/client/Options.cpp index 78cef1a6..ee9aced2 100755 --- a/src/client/Options.cpp +++ b/src/client/Options.cpp @@ -68,6 +68,10 @@ OptionInt fogType("fogType", 0, 0, 2); OptionBool javaHud("javaHud", false); +OptionBool betaSky("betaSky", false); + +OptionBool tintedSide("tintedSide", false); + OptionBool blockOutline("blockOutline", false); OptionBool restoredAnims("restoredAnims", true); @@ -183,6 +187,10 @@ void Options::initTable() { // more options yay m_options[OPTIONS_FOG_TYPE] = &fogType; + m_options[OPTIONS_BETA_SKY] = &betaSky; + + m_options[OPTIONS_TINTED_SIDE] = &tintedSide; + m_options[OPTIONS_JAVA_HUD] = &javaHud; m_options[OPTIONS_AUTOJUMP] = &autoJump; diff --git a/src/client/Options.h b/src/client/Options.h index 7d1d3b40..826bfb30 100755 --- a/src/client/Options.h +++ b/src/client/Options.h @@ -90,6 +90,8 @@ enum OptionId { OPTIONS_FOG_TYPE, OPTIONS_JAVA_HUD, OPTIONS_RESTORED_ANIMS, + OPTIONS_TINTED_SIDE, + OPTIONS_BETA_SKY, // Should be last! OPTIONS_COUNT }; diff --git a/src/client/gui/Gui.cpp b/src/client/gui/Gui.cpp index 04892360..c9f63ea5 100755 --- a/src/client/gui/Gui.cpp +++ b/src/client/gui/Gui.cpp @@ -121,6 +121,9 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) { if (!minecraft->options.getBooleanValue(OPTIONS_HIDEGUI)) { renderToolBar(a, ySlot, screenWidth); + font->drawShadow("Minecraft - Pocket Edition ", 2, 2, 0xffffffff); +// font->drawShadow("This is a demo, not the finished product", 2, 10 + 2, 0xffffffff); + glEnable(GL_BLEND); bool isChatting = (minecraft->screen && (dynamic_cast(minecraft->screen) || dynamic_cast(minecraft->screen))); unsigned int max = 10; diff --git a/src/client/gui/screens/OptionsScreen.cpp b/src/client/gui/screens/OptionsScreen.cpp index 88fbb634..9e537219 100755 --- a/src/client/gui/screens/OptionsScreen.cpp +++ b/src/client/gui/screens/OptionsScreen.cpp @@ -233,8 +233,10 @@ void OptionsScreen::generateOptionScreens() { .addOptionItem(OPTIONS_BAR_ON_TOP, minecraft) .addOptionItem(OPTIONS_RPI_CURSOR, minecraft) .addOptionItem(OPTIONS_FOLIAGE_TINT, minecraft) + .addOptionItem(OPTIONS_TINTED_SIDE, minecraft) .addOptionItem(OPTIONS_JAVA_HUD, minecraft) .addOptionItem(OPTIONS_FOG_TYPE, minecraft) + .addOptionItem(OPTIONS_BETA_SKY, minecraft) .addOptionItem(OPTIONS_RESTORED_ANIMS, minecraft); } diff --git a/src/client/renderer/GameRenderer.cpp b/src/client/renderer/GameRenderer.cpp index aab7f2ac..aab253ab 100755 --- a/src/client/renderer/GameRenderer.cpp +++ b/src/client/renderer/GameRenderer.cpp @@ -272,17 +272,6 @@ void GameRenderer::renderLevel(float a) { screenScissorArea.w, screenScissorArea.h); } - if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { - setupFog(-1); - TIMER_POP_PUSH("sky"); - glFogf(GL_FOG_START, renderDistance * 0.2f); - glFogf(GL_FOG_END, renderDistance *0.75); - levelRenderer->renderSky(a); - glFogf(GL_FOG_START, renderDistance * 0.6f); - glFogf(GL_FOG_END, renderDistance); - } - glEnable2(GL_FOG); - setupFog(1); if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { glShadeModel2(GL_SMOOTH); @@ -295,10 +284,29 @@ void GameRenderer::renderLevel(float a) { TIMER_POP_PUSH("culling"); mc->levelRenderer->cull(&frustum, a); mc->levelRenderer->updateDirtyChunks(cameraEntity, false); - + // this sky rendering code below was originally before the frustrum and culling stuff but sunset color breaks for some reason in that place, so i moved i after those two - shredder if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { + setupFog(-1); + TIMER_POP_PUSH("sky"); + // @TODO - EXTREME JANK BELOW, it works but i have to do heavy cleanup here, also to test if the glfogf commands even affect fog in anyway. + if(mc->options.getBooleanValue(OPTIONS_BETA_SKY) && (mc->options.getIntValue(OPTIONS_VIEW_DISTANCE) < 2)){ + levelRenderer->renderSky(a); // how java renders the sky instead of how pe doing prepareandrenderclouds. + } else if (!mc->options.getBooleanValue(OPTIONS_BETA_SKY)){ + glFogf(GL_FOG_START, renderDistance * 0.2f); + glFogf(GL_FOG_END, renderDistance *0.75); + + glFogf(GL_FOG_START, renderDistance * 0.6f); + glFogf(GL_FOG_END, renderDistance); + } + } + glEnable2(GL_FOG); + setupFog(1); + // MCPE renders clouds using this, but this method breaks 3d clouds and also breaks 2d clouds transparency viewed from above, add as a Legacy Sky or Fast Sky option. - shredder + if(!mc->options.getBooleanValue(OPTIONS_BETA_SKY)){ + if(mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)) { prepareAndRenderClouds(levelRenderer, a); } + } setupFog(0); glEnable2(GL_FOG); @@ -306,7 +314,9 @@ void GameRenderer::renderLevel(float a) { mc->textures->loadAndBindTexture("terrain.png"); Lighting::turnOff(); - glDisable2(GL_ALPHA_TEST); +// glDisable2(GL_ALPHA_TEST); // vanilla pe disables alpha test here, i renable it so grass side textures dont become opaque - shredder + glEnable2(GL_ALPHA_TEST); // + glDisable2(GL_BLEND); glEnable2(GL_CULL_FACE); TIMER_POP_PUSH("terrain-0"); @@ -374,11 +384,14 @@ void GameRenderer::renderLevel(float a) { } glDisable2(GL_FOG); - // - // setupFog(0); - // glEnable2(GL_FOG); - //// levelRenderer->renderClouds(a); - // glDisable2(GL_FOG); + // Normally this is commented out, but this is how java does it and should fix both 2d/3d clouds, a + if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){ + setupFog(0); + glEnable2(GL_FOG); + levelRenderer->renderClouds(a); + glDisable2(GL_FOG); + } + // SHREDDER END setupFog(1); if (zoom == 1 && !mc->options.getBooleanValue(OPTIONS_HIDEGUI)) { diff --git a/src/client/renderer/LevelRenderer.cpp b/src/client/renderer/LevelRenderer.cpp index 0c776825..6ce0d9ba 100755 --- a/src/client/renderer/LevelRenderer.cpp +++ b/src/client/renderer/LevelRenderer.cpp @@ -76,6 +76,9 @@ LevelRenderer::LevelRenderer( Minecraft* mc) //for (int i = 0; i < numListsOrBuffers; ++i) printf("bufId %d: %d\t", i, chunkBuffers[i]); glGenBuffers2(1, &skyBuffer); + glGenBuffers2(1, &voidBuffer); + glGenBuffers2(1, &starBuffer); + generateStars(); generateSky(); #else int maxChunksWidth = 1024 / CHUNK_SIZE; @@ -94,6 +97,8 @@ LevelRenderer::~LevelRenderer() #ifdef OPENGL_ES glDeleteBuffers(numListsOrBuffers, chunkBuffers); glDeleteBuffers(1, &skyBuffer); + glDeleteBuffers(1, &voidBuffer); + glDeleteBuffers(1, &starBuffer); delete[] chunkBuffers; #else glDeleteLists(numListsOrBuffers, chunkLists); @@ -121,6 +126,25 @@ void LevelRenderer::generateSky() { } t.end(true, skyBuffer); + + yy = (float) (-16); + t.begin(); + + // pretty much the same thing as the sky one above except uses inverted values to generate the void plane. + + voidVertexCount = 0; + for (int xx = -s * d; xx <= s * d; xx += s) { + for (int zz = -s * d; zz <= s * d; zz += s) { + t.vertex((float) xx + 0, yy, (float) zz + s); + t.vertex((float)(xx + s), yy, (float) zz + s); + t.vertex((float)(xx + s), yy, (float)(zz + 0)); + t.vertex((float) xx + 0, yy, (float)(zz + 0)); + //LOGI("x, z: %d, %d\n", xx, zz); + voidVertexCount += 4; + } + } + + t.end(true, voidBuffer); //LOGI("skyvertexcount: %d\n", skyVertexCount); //glEndList(); } @@ -146,10 +170,6 @@ void LevelRenderer::setLevel( Level* level ) level->addListener(this); allChanged(); } - if (mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION)) { - mc->useAmbientOcclusion = !mc->useAmbientOcclusion; - allChanged(); - } } void LevelRenderer::allChanged() @@ -168,6 +188,9 @@ void LevelRenderer::allChanged() FoliageColor::setUseTint(tint); GrassColor::setUseTint(tint); + bool sideTint = mc->options.getBooleanValue(OPTIONS_TINTED_SIDE); + TileRenderer::setUseTint(sideTint); + int dist = (512 >> 3) << (3 - lastViewDistance); if (lastViewDistance <= 2 && mc->isPowerVR()) @@ -325,6 +348,37 @@ int LevelRenderer::render( Mob* player, int layer, float alpha ) allChanged(); } + bool SmoothLightState = mc->options.getBooleanValue(OPTIONS_AMBIENT_OCCLUSION); + if (SmoothLightState != mc->useAmbientOcclusion){ + mc->useAmbientOcclusion = SmoothLightState; + allChanged(); + } + + + bool tint = mc->options.getBooleanValue(OPTIONS_FOLIAGE_TINT); + if (tint != LastTint) { + LastTint = tint; + + + FoliageColor::setUseTint(tint); + GrassColor::setUseTint(tint); + + allChanged(); + } + + + bool sideTint = mc->options.getBooleanValue(OPTIONS_TINTED_SIDE); + + if (sideTint != LastSideTint) { + LastSideTint = sideTint; + + + TileRenderer::setUseTint(sideTint); + + allChanged(); + } + + TIMER_PUSH("sortchunks"); for (int i = 0; i < 10; i++) { @@ -513,14 +567,14 @@ void LevelRenderer::render(const AABB& b) const { Tesselator& t = Tesselator::instance; -// glColor4f2(1, 1, 1, 1); + // glColor4f2(1, 1, 1, 1); -// textures->loadAndBindTexture("terrain.png"); // uh need to check java - shredder + // textures->loadAndBindTexture("terrain.png"); // uh need to check java - shredder //t.begin(); -// t.color(255, 255, 255, 255); // again not needed, for some reason the vanilla source code tints it... white? maybe this was used for something else in MCPE's dev at one point? - shredder + // t.color(255, 255, 255, 255); // again not needed, for some reason the vanilla source code tints it... white? maybe this was used for something else in MCPE's dev at one point? - shredder -// t.offset(((Mob*)mc->player)->getPos(0).negated()); // why does this even exist normally, it just makes the thing... not render + // t.offset(((Mob*)mc->player)->getPos(0).negated()); // why does this even exist normally, it just makes the thing... not render t.begin(GL_LINE_STRIP); t.vertex(b.x0, b.y0, b.z0); @@ -1016,6 +1070,57 @@ std::string LevelRenderer::gatherStats1() { // int[] toRender = new int[50000]; // IntBuffer resultBuffer = MemoryTracker.createIntBuffer(64); + void LevelRenderer::generateStars() { + // ported from java beta again, + // converted the doubles into floats to be consistent, shouldnt affect much - shredder + + Random random = Random(10842L); + Tesselator& t = Tesselator::instance; + t.begin(); + starVertexCount = 0; + + for (int i = 0; i < 1500; i++) { + float d = random.nextFloat() * 2.0F - 1.0F; + float e = random.nextFloat() * 2.0F - 1.0F; + float f = random.nextFloat() * 2.0F - 1.0F; + float g = 0.25F + random.nextFloat() * 0.25F; + float h = d * d + e * e + f * f; + if (h < 1.0 && h > 0.01) { + h = 1.0 / Mth::sqrt(h); + d *= h; + e *= h; + f *= h; + float j = d * 100.0; + float k = e * 100.0; + float l = f * 100.0; + float m = Mth::atan2(d, f); + float n = Mth::sin(m); + float o = Mth::cos(m); + float p = Mth::atan2(Mth::sqrt(d * d + f * f), e); + float q = Mth::sin(p); + float r = Mth::cos(p); + float s = random.nextDouble() * Mth::PI * 2.0; + float t2 = Mth::sin(s); + float u = Mth::cos(s); + + for (int v = 0; v < 4; v++) { + float w = 0.0; + float x = ((v & 2) - 1) * g; + float y = ((v + 1 & 2) - 1) * g; + float aa = x * u - y * t2; + float ab = y * u + x * t2; + float ad = aa * q + w * r; + float ae = w * q - aa * r; + float af = ae * n - ab * o; + float ah = ab * n + ae * o; + t.vertex(j + af, k + ad, l + ah); + } + starVertexCount += 4; + } + } + + t.end(true, starBuffer); + } void LevelRenderer::renderSky(float alpha) { if (mc->level->dimension->foggy) return; @@ -1036,19 +1141,120 @@ void LevelRenderer::renderSky(float alpha) { } glColor4f2(sr, sg, Mth::Min(1.0f, sb), 1); - //Tesselator& t = Tesselator::instance; - + Tesselator& t = Tesselator::instance; + // @TODO shredder - should not enable or disable depth mask if using legacy sky because mcpe sky rendering is awful and will render clouds above terrain + if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){ + glDepthMask(false); + } glEnable2(GL_FOG); glColor4f2(sr, sg, sb, 1.0f); #ifdef OPENGL_ES drawArrayVT(skyBuffer, skyVertexCount); #endif - glEnable2(GL_TEXTURE_2D); + glDisable(GL_FOG); + glDisable(GL_ALPHA_TEST); + + // thanks to the mcpe 0.1 decomp project a bit for this part, was not getting the gl states correctly, gles is painful - shredder + + // Sunrise + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + float* c = level->dimension->getSunriseColor(level->getTimeOfDay(alpha), alpha); + if (c != nullptr) + { + glDisable(GL_TEXTURE_2D); + + + glPushMatrix(); + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + glRotatef(level->getTimeOfDay(alpha) > 0.5f ? 180 : 0, 0.0f, 0.0f, 1.0f); + + t.begin(GL_TRIANGLE_FAN); + t.color(c[0], c[1], c[2], c[3]); + t.vertex(0.0f, 100.0f, 0.0f); + t.color(c[0], c[1], c[2], 0.0f); + + int steps = 16; + for (int i = 0; i <= steps; i++) + { + float a = i * 3.1415927f * 2.0f / steps; + float sin = Mth::sin(a); + float cos = Mth::cos(a); + t.vertex((sin * 120.0f), (cos * 120.0f), (-cos * 40.0f * c[3])); + } + + t.draw(); + glPopMatrix(); + } + + // gets the time of day and rotates the sun and moon png based on the time + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_ONE, GL_ONE); + glPushMatrix(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTranslatef(sc.x, sc.y, sc.z); + glRotatef(0.0f, 0.0f, 0.0f, 1.0f); + glRotatef(level->getTimeOfDay(alpha) * 360.0f, 1.0f, 0.0f, 0.0f); + + float ss = 30.0f; + + + textures->loadAndBindTexture("terrain/sun.png"); + t.begin(); + t.vertexUV(-ss, 100.0f, -ss, 0.0f, 0.0f); + t.vertexUV(ss, 100.0f, -ss, 1.0f, 0.0f); + t.vertexUV(ss, 100.0f, ss, 1.0f, 1.0f); + t.vertexUV(-ss, 100.0f, ss, 0.0f, 1.0f); + t.draw(); + + ss = 20.0f; + textures->loadAndBindTexture("terrain/moon.png"); + t.begin(); + t.vertexUV(-ss, -100.0f, ss, 1.0f, 1.0f); + t.vertexUV(ss, -100.0f, ss, 0.0f, 1.0f); + t.vertexUV(ss, -100.0f, -ss, 0.0f, 0.0f); + t.vertexUV(-ss, -100.0f, -ss, 1.0f, 0.0f); + t.draw(); + + + glDisable(GL_TEXTURE_2D); + + float a = level->getStarBrightness(alpha); + if (a > 0.0f) + { + glColor4f(a, a, a, a); + drawArrayVT(starBuffer, starVertexCount); + } + + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glEnable(GL_FOG); + glPopMatrix(); + + // ported over void plane (the blue bottom plane seen in java) because pocket edition lacks it @TODO test if it's buggy - shredder + + glColor3f(sc.x * 0.2f + 0.04f, sc.y * 0.2f + 0.04f, sc.z * 0.6f + 0.1f); + glDisable(GL_TEXTURE_2D); + drawArrayVT(voidBuffer, voidVertexCount); + glEnable(GL_TEXTURE_2D); + + // @TODO shredder - should not enable or disable depth mask if using legacy sky because mcpe sky rendering is awful and will render clouds above terrain + if(mc->options.getBooleanValue(OPTIONS_BETA_SKY)){ + glDepthMask(true); + } } void LevelRenderer::renderClouds( float alpha ) { //if (!mc->level->dimension->isNaturalDimension()) return; + if (mc->options.getBooleanValue(OPTIONS_FANCY_GRAPHICS)){ + renderAdvancedClouds(alpha); + return; + } glEnable2(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); float yOffs = (float) (mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha); @@ -1097,6 +1303,142 @@ void LevelRenderer::renderClouds( float alpha ) { glEnable(GL_CULL_FACE); } +void LevelRenderer::renderAdvancedClouds(float alpha) { + + // ported from java beta, tesselation code for the 3d clouds, renders broken if mcpe sky rendering option is used - shredder + + glDisable(GL_CULL_FACE); + + float px = mc->player->xOld + (mc->player->x - mc->player->xOld) * alpha; + float py = mc->player->yOld + (mc->player->y - mc->player->yOld) * alpha; + float pz = mc->player->zOld + (mc->player->z - mc->player->zOld) * alpha; + + Tesselator& t = Tesselator::instance; + float ss = 12.0f; + float h = 4.0f; + + float cloudTime = (float)ticks + alpha; + + double xo = (px + cloudTime * 0.03f) / ss; + double zo = pz / ss + 0.33f; + + float yy = 108.0f - py + 0.33f; + + int xWraps = Mth::floor(xo / 2048.0); + int zWraps = Mth::floor(zo / 2048.0); + xo -= xWraps * 2048; + zo -= zWraps * 2048; + + textures->loadAndBindTexture("environment/clouds.png"); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + Vec3 cc = level->getCloudColor(alpha); + float cr = cc.x; + float cg = cc.y; + float cb = cc.z; + + float uvScale = 1.0f / 256.0f; + float uo = (float)Mth::floor(xo) * uvScale; + float vo = (float)Mth::floor(zo) * uvScale; + + float xOffs = (float)(xo - Mth::floor(xo)); + float zOffs = (float)(zo - Mth::floor(zo)); + + int D = 8; + int radius = 3; + float e = 1.0f / 1024.0f; + + glPushMatrix(); + glScalef(ss, 1.0f, ss); + + for (int pass = 0; pass < 2; pass++) { + + if (pass == 0) glColorMask(false, false, false, false); + else glColorMask(true, true, true, true); + + for (int xPos = -radius + 1; xPos <= radius; xPos++) { + for (int zPos = -radius + 1; zPos <= radius; zPos++) { + t.begin(); + float xx = (float)(xPos * D); + float zz = (float)(zPos * D); + float xp = xx - xOffs; + float zp = zz - zOffs; + + + if (yy > -h - 1.0f) { + t.color(cr * 0.7f, cg * 0.7f, cb * 0.7f, 0.8f); + t.normal(0.0f, -1.0f, 0.0f); + t.vertexUV(xp + 0, yy + 0, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + D, yy + 0, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + D, yy + 0, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo); + t.vertexUV(xp + 0, yy + 0, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo); + } + + + if (yy <= h + 1.0f) { + t.color(cr, cg, cb, 0.8f); + t.normal(0.0f, 1.0f, 0.0f); + t.vertexUV(xp + 0, yy + h - e, zp + D, (xx + 0) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + D, yy + h - e, zp + D, (xx + D) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + D, yy + h - e, zp + 0, (xx + D) * uvScale + uo, (zz + 0) * uvScale + vo); + t.vertexUV(xp + 0, yy + h - e, zp + 0, (xx + 0) * uvScale + uo, (zz + 0) * uvScale + vo); + } + + t.color(cr * 0.9f, cg * 0.9f, cb * 0.9f, 0.8f); + + + if (xPos > -1) { + t.normal(-1.0f, 0.0f, 0.0f); + for (int i = 0; i < D; i++) { + t.vertexUV(xp + i + 0, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + i + 0, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + i + 0, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo); + t.vertexUV(xp + i + 0, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo); + } + } + if (xPos <= 1) { + t.normal(1.0f, 0.0f, 0.0f); + for (int i = 0; i < D; i++) { + t.vertexUV(xp + i + 1 - e, yy + 0, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + i + 1 - e, yy + h, zp + D, (xx + i + 0.5f) * uvScale + uo, (zz + D) * uvScale + vo); + t.vertexUV(xp + i + 1 - e, yy + h, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo); + t.vertexUV(xp + i + 1 - e, yy + 0, zp + 0, (xx + i + 0.5f) * uvScale + uo, (zz + 0) * uvScale + vo); + } + } + + t.color(cr * 0.8f, cg * 0.8f, cb * 0.8f, 0.8f); + + + if (zPos > -1) { + t.normal(0.0f, 0.0f, -1.0f); + for (int i = 0; i < D; i++) { + t.vertexUV(xp + 0, yy + h, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + D, yy + h, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + D, yy + 0, zp + i + 0, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + 0, yy + 0, zp + i + 0, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + } + } + if (zPos <= 1) { + t.normal(0.0f, 0.0f, 1.0f); + for (int i = 0; i < D; i++) { + t.vertexUV(xp + 0, yy + h, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + D, yy + h, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + D, yy + 0, zp + i + 1 - e, (xx + D) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + t.vertexUV(xp + 0, yy + 0, zp + i + 1 - e, (xx + 0) * uvScale + uo, (zz + i + 0.5f) * uvScale + vo); + } + } + t.endOverrideAndDraw(); + } + } + } + + glPopMatrix(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); + glEnable(GL_CULL_FACE); +} + void LevelRenderer::playSound(const std::string& name, float x, float y, float z, float volume, float pitch) { // @todo: deny sounds here if sound is off (rather than waiting 'til SoundEngine) float dd = 16; @@ -1259,6 +1601,7 @@ void LevelRenderer::renderHitSelect( Player* player, const HitResult& h, int mod void LevelRenderer::onGraphicsReset() { + generateStars(); generateSky(); // Get new buffers diff --git a/src/client/renderer/LevelRenderer.h b/src/client/renderer/LevelRenderer.h index 2a9c7e23..2fa29c8a 100755 --- a/src/client/renderer/LevelRenderer.h +++ b/src/client/renderer/LevelRenderer.h @@ -43,7 +43,9 @@ public: void renderDebug(const AABB& b, float a) const; void renderSky(float alpha); + void generateStars(); void renderClouds(float alpha); + void renderAdvancedClouds(float alpha); void renderEntities(Vec3 cam, Culler* culler, float a); void renderSameAsLast(int layer, float alpha); void renderHit(Player* player, const HitResult& h, int mode, /*ItemInstance*/void* inventoryItem, float a); @@ -116,6 +118,9 @@ private: // shredder added again... int lastFogType; + bool LastTint; + bool LastSideTint; + int ticks; int starList, skyList, darkList; @@ -124,6 +129,12 @@ private: GLuint skyBuffer; int skyVertexCount; + GLuint voidBuffer; + int voidVertexCount; + + GLuint starBuffer; + int starVertexCount; + // /*public*/ std::vector renderableTileEntities; Textures* textures; // /*private*/ TileRenderer tileRenderer; diff --git a/src/client/renderer/TileRenderer.cpp b/src/client/renderer/TileRenderer.cpp index 8c1c91cf..e61334ca 100755 --- a/src/client/renderer/TileRenderer.cpp +++ b/src/client/renderer/TileRenderer.cpp @@ -19,8 +19,10 @@ #include "tileentity/TileEntityRenderer.h" #include "EntityTileRenderer.h" -TileRenderer::TileRenderer( LevelSource* level /* = NULL */ ) -: level(level), +bool TileRenderer::sideTinting = false; + +TileRenderer::TileRenderer(LevelSource* level /* = NULL */ ) + : level(level), fixedTexture(-1), xFlipTexture(false), noCulling(false), @@ -58,6 +60,11 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r float c2 = 0.8f; float c3 = 0.6f; + // added these to get biome color and save it before its overriden - shredder + float biomeR = r; + float biomeG = g; + float biomeB = b; + float r11 = c11 * r; float g11 = c11 * g; @@ -101,6 +108,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r if (tt->zz0 > 0) br = centerBrightness; t.color(r2 * br, g2 * br, b2 * br); renderNorth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 2)); + if ((tt->getTexture(level, x, y, z, 2) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture + t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB); + renderNorth(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient + } changed = true; } @@ -109,6 +120,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r if (tt->zz1 < 1) br = centerBrightness; t.color(r2 * br, g2 * br, b2 * br); renderSouth(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 3)); + if ((tt->getTexture(level, x, y, z, 3) == 3) && sideTinting){ // checking if the texture from terrain.png is the normal grass side texture + t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB); + renderSouth(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient + } changed = true; } @@ -117,6 +132,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r if (tt->xx0 > 0) br = centerBrightness; t.color(r3 * br, g3 * br, b3 * br); renderWest(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 4)); + if ((tt->getTexture(level, x, y, z, 4) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture + t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB); + renderWest(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient + } changed = true; } @@ -125,6 +144,10 @@ bool TileRenderer::tesselateBlockInWorld( Tile* tt, int x, int y, int z, float r if (tt->xx1 < 1) br = centerBrightness; t.color(r3 * br, g3 * br, b3 * br); renderEast(tt, xf, yf, zf, tt->getTexture(level, x, y, z, 5)); + if ((tt->getTexture(level, x, y, z, 5) == 3) && sideTinting) { // checking if the texture from terrain.png is the normal grass side texture + t.color(c2 * br * biomeR, c2 * br * biomeG, c2 * br * biomeB); + renderEast(tt, xf, yf, zf, 38); // rendering an extra face over the side of the cube that is a grayscale grass fringe tinted by t.color using biome colors, kinda inefficient + } changed = true; } @@ -148,38 +171,38 @@ bool TileRenderer::tesselateInWorld( Tile* tt, int x, int y, int z ) return tesselateBlockInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_WATER) { return tesselateWaterInWorld(tt, x, y, z); - } else if (shape == Tile::SHAPE_CACTUS) { - return tesselateCactusInWorld(tt, x, y, z); + } else if (shape == Tile::SHAPE_CACTUS) { + return tesselateCactusInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_CROSS_TEXTURE) { return tesselateCrossInWorld(tt, x, y, z); } else if(shape == Tile::SHAPE_STEM) { return tesselateStemInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_ROWS) { - return tesselateRowInWorld(tt, x, y, z); + return tesselateRowInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_TORCH) { return tesselateTorchInWorld(tt, x, y, z); - } else if (shape == Tile::SHAPE_FIRE) { - return tesselateFireInWorld(tt, x, y, z); - //} else if (shape == Tile::SHAPE_RED_DUST) { - // return tesselateDustInWorld(tt, x, y, z); + } else if (shape == Tile::SHAPE_FIRE) { + return tesselateFireInWorld(tt, x, y, z); + //} else if (shape == Tile::SHAPE_RED_DUST) { + // return tesselateDustInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_LADDER) { return tesselateLadderInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_DOOR) { return tesselateDoorInWorld(tt, x, y, z); - //} else if (shape == Tile::SHAPE_RAIL) { - // return tesselateRailInWorld(tt, x, y, z); + //} else if (shape == Tile::SHAPE_RAIL) { + // return tesselateRailInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_STAIRS) { return tesselateStairsInWorld((StairTile*)tt, x, y, z); - } else if (shape == Tile::SHAPE_FENCE) { - return tesselateFenceInWorld((FenceTile*)tt, x, y, z); + } else if (shape == Tile::SHAPE_FENCE) { + return tesselateFenceInWorld((FenceTile*)tt, x, y, z); } else if (shape == Tile::SHAPE_FENCE_GATE) { return tesselateFenceGateInWorld((FenceGateTile*) tt, x, y, z); - //} else if (shape == Tile::SHAPE_LEVER) { - // return tesselateLeverInWorld(tt, x, y, z); - //} else if (shape == Tile::SHAPE_BED) { - // return tesselateBedInWorld(tt, x, y, z); - //} else if (shape == Tile::SHAPE_DIODE) { - // return tesselateDiodeInWorld(tt, x, y, z); + //} else if (shape == Tile::SHAPE_LEVER) { + // return tesselateLeverInWorld(tt, x, y, z); + //} else if (shape == Tile::SHAPE_BED) { + // return tesselateBedInWorld(tt, x, y, z); + //} else if (shape == Tile::SHAPE_DIODE) { + // return tesselateDiodeInWorld(tt, x, y, z); } else if (shape == Tile::SHAPE_IRON_FENCE) { return tesselateThinFenceInWorld((ThinFenceTile*) tt, x, y, z); } else if(shape == Tile::SHAPE_BED) { @@ -232,10 +255,10 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) int tex = tt->getTexture(0); if (fixedTexture >= 0) tex = fixedTexture; - + float br = tt->getBrightness( level, x, y, z ); t.color( br, br, br ); - + int xt = ((tex & 0xf) << 4); int yt = tex & 0xf0; @@ -340,82 +363,82 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) if ( Tile::fire->canBurn( level, x - 1, y, z ) ) { t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + 1.0f ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); + 1.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); + 0.0f ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); + 0.0f ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); + 1.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + 1.0f ), ( float )( u1 ), ( float )( v0 ) ); } if ( Tile::fire->canBurn( level, x + 1, y, z ) ) { t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); + 0.0f ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); + 1.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + 1.0f ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + 1.0f ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f - 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); + 1.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f - 0 ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); + 0.0f ), ( float )( u0 ), ( float )( v0 ) ); } if ( Tile::fire->canBurn( level, x, y, z - 1 ) ) { t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u1 ), ( float )( v0 ) ); + r ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u0 ), ( float )( v0 ) ); + r ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u0 ), ( float )( v0 ) ); + r ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u1 ), ( float )( v0 ) ); + r ), ( float )( u1 ), ( float )( v0 ) ); } if ( Tile::fire->canBurn( level, x, y, z + 1 ) ) { t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u0 ), ( float )( v0 ) ); + r ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u1 ), ( float )( v0 ) ); + r ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u1 ), ( float )( v0 ) ); + r ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u0 ), ( float )( v0 ) ); + r ), ( float )( u0 ), ( float )( v0 ) ); } if ( Tile::fire->canBurn( level, x, y + 1.0f, z ) ) { @@ -440,13 +463,13 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) if ( ( ( x + y + z ) & 1 ) == 0 ) { t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + - 0 ), ( float )( u1 ), ( float )( v0 ) ); + 0 ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + - 0 ), ( float )( u1 ), ( float )( v1 ) ); + 0 ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + - 1 ), ( float )( u0 ), ( float )( v1 ) ); + 1 ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + - 1 ), ( float )( u0 ), ( float )( v0 ) ); + 1 ), ( float )( u0 ), ( float )( v0 ) ); u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 256.0f; @@ -454,24 +477,24 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) v1 = (yt + 15.99f) / 256.0f; t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + 1.0f ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); + 1.0f ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + - 0 ), ( float )( u0 ), ( float )( v1 ) ); + 0 ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + - 0 ), ( float )( u0 ), ( float )( v0 ) ); + 0 ), ( float )( u0 ), ( float )( v0 ) ); } else { t.vertexUV( ( float )( x + 0.0f ), ( float )( y + - h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); + h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + - 0.0f ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + - 0.0f ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + - h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); + h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 256.0f; @@ -479,13 +502,13 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) v1 = (yt + 15.99f) / 256.0f; t.vertexUV( ( float )( x + 1.0f ), ( float )( y + - h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); + h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x + 1.0f ), ( float )( y + - 0.0f ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); + 0.0f ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + - 0.0f ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); + 0.0f ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x + 0.0f ), ( float )( y + - h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); + h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); } } } @@ -958,46 +981,46 @@ float TileRenderer::getWaterHeight( int x, int y, int z, const Material* m ) } void TileRenderer::renderBlock(Tile* tt, LevelSource* level, int x, int y, int z) { - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - Tesselator& t = Tesselator::instance; - t.begin(); + Tesselator& t = Tesselator::instance; + t.begin(); - float center = tt->getBrightness(level, x, y, z); - float br = tt->getBrightness(level, x, y - 1, z); - if (br < center) br = center; + float center = tt->getBrightness(level, x, y, z); + float br = tt->getBrightness(level, x, y - 1, z); + if (br < center) br = center; - t.color(c10 * br, c10 * br, c10 * br); - renderFaceDown(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(0)); + t.color(c10 * br, c10 * br, c10 * br); + renderFaceDown(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(0)); - br = tt->getBrightness(level, x, y + 1, z); - if (br < center) br = center; - t.color(c11 * br, c11 * br, c11 * br); - renderFaceUp(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(1)); + br = tt->getBrightness(level, x, y + 1, z); + if (br < center) br = center; + t.color(c11 * br, c11 * br, c11 * br); + renderFaceUp(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(1)); - br = tt->getBrightness(level, x, y, z - 1); - if (br < center) br = center; - t.color(c2 * br, c2 * br, c2 * br); - renderNorth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(2)); + br = tt->getBrightness(level, x, y, z - 1); + if (br < center) br = center; + t.color(c2 * br, c2 * br, c2 * br); + renderNorth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(2)); - br = tt->getBrightness(level, x, y, z + 1); - if (br < center) br = center; - t.color(c2 * br, c2 * br, c2 * br); - renderSouth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(3)); + br = tt->getBrightness(level, x, y, z + 1); + if (br < center) br = center; + t.color(c2 * br, c2 * br, c2 * br); + renderSouth(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(3)); - br = tt->getBrightness(level, x - 1, y, z); - if (br < center) br = center; - t.color(c3 * br, c3 * br, c3 * br); - renderWest(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(4)); + br = tt->getBrightness(level, x - 1, y, z); + if (br < center) br = center; + t.color(c3 * br, c3 * br, c3 * br); + renderWest(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(4)); - br = tt->getBrightness(level, x + 1, y, z); - if (br < center) br = center; - t.color(c3 * br, c3 * br, c3 * br); - renderEast(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(5)); - t.draw(); + br = tt->getBrightness(level, x + 1, y, z); + if (br < center) br = center; + t.color(c3 * br, c3 * br, c3 * br); + renderEast(tt, -0.5f, -0.5f, -0.5f, tt->getTexture(5)); + t.draw(); } bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, float pBaseBlue ) @@ -1197,6 +1220,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, c4g *= ll4; c4b *= ll4; renderNorth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 2)); + if (tt->getTexture(level, pX, pY, pZ, 2) == 3 && sideTinting) + { + c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue; + c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue; + c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue; + c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue; + + renderNorth(tt, (float) pX, (float) pY, (float) pZ, 38); + } i = true; } if ((noCulling) || (tt->shouldRenderFace(level, pX, pY, pZ + 1, 3))) { @@ -1250,6 +1282,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, c4g *= ll4; c4b *= ll4; renderSouth(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 3)); + if (tt->getTexture(level, pX, pY, pZ, 3) == 3 && sideTinting) + { + c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue; + c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue; + c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue; + c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue; + + renderSouth(tt, (float) pX, (float) pY, (float) pZ, 38); + } i = true; } if ((noCulling) || (tt->shouldRenderFace(level, pX - 1, pY, pZ, 4))) { @@ -1302,6 +1343,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, c4g *= ll4; c4b *= ll4; renderWest(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 4)); + if (tt->getTexture(level, pX, pY, pZ, 4) == 3 && sideTinting) + { + c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue; + c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue; + c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue; + c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue; + + renderWest(tt, (float) pX, (float) pY, (float) pZ, 38); + } i = true; } if ((noCulling) || (tt->shouldRenderFace(level, pX + 1, pY, pZ, 5))) { @@ -1355,6 +1405,15 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, c4b *= ll4; renderEast(tt, (float) pX, (float) pY, (float) pZ, tt->getTexture(level, pX, pY, pZ, 5)); + if (tt->getTexture(level, pX, pY, pZ, 5) == 3 && sideTinting) + { + c1r *= pBaseRed; c1g *= pBaseGreen; c1b *= pBaseBlue; + c2r *= pBaseRed; c2g *= pBaseGreen; c2b *= pBaseBlue; + c3r *= pBaseRed; c3g *= pBaseGreen; c3b *= pBaseBlue; + c4r *= pBaseRed; c4g *= pBaseGreen; c4b *= pBaseBlue; + + renderEast(tt, (float) pX, (float) pY, (float) pZ, 38); + } i = true; } applyAmbienceOcclusion = false; @@ -1362,124 +1421,124 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusion( Tile* tt, int pX, } bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z) { - int col = tt->getColor(level, x, y, z); - float r = ((col >> 16) & 0xff) / 255.0f; - float g = ((col >> 8) & 0xff) / 255.0f; - float b = ((col) & 0xff) / 255.0f; - return tesselateCactusInWorld(tt, x, y, z, r, g, b); + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + return tesselateCactusInWorld(tt, x, y, z, r, g, b); } bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z, float r, float g, float b) { - Tesselator& t = Tesselator::instance; + Tesselator& t = Tesselator::instance; - bool changed = false; - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + bool changed = false; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - float r10 = c10 * r; - float r11 = c11 * r; - float r2 = c2 * r; - float r3 = c3 * r; + float r10 = c10 * r; + float r11 = c11 * r; + float r2 = c2 * r; + float r3 = c3 * r; - float g10 = c10 * g; - float g11 = c11 * g; - float g2 = c2 * g; - float g3 = c3 * g; + float g10 = c10 * g; + float g11 = c11 * g; + float g2 = c2 * g; + float g3 = c3 * g; - float b10 = c10 * b; - float b11 = c11 * b; - float b2 = c2 * b; - float b3 = c3 * b; + float b10 = c10 * b; + float b11 = c11 * b; + float b2 = c2 * b; + float b3 = c3 * b; - float s = 1 / 16.0f; + float s = 1 / 16.0f; const float X = (float)x; const float Y = (float)y; const float Z = (float)z; - float centerBrightness = tt->getBrightness(level, x, y, z); + float centerBrightness = tt->getBrightness(level, x, y, z); - if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) { - float br = tt->getBrightness(level, x, y - 1, z); - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r10 * br, g10 * br, b10 * br); - renderFaceDown(tt, X, Y, Z, tt->getTexture(level, x, y, z, 0)); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) { + float br = tt->getBrightness(level, x, y - 1, z); + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r10 * br, g10 * br, b10 * br); + renderFaceDown(tt, X, Y, Z, tt->getTexture(level, x, y, z, 0)); + changed = true; + } - if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) { - float br = tt->getBrightness(level, x, y + 1, z); - if (tt->yy1 != 1 && !tt->material->isLiquid()) br = centerBrightness; - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r11 * br, g11 * br, b11 * br); - renderFaceUp(tt, X, Y, Z, tt->getTexture(level, x, y, z, 1)); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) { + float br = tt->getBrightness(level, x, y + 1, z); + if (tt->yy1 != 1 && !tt->material->isLiquid()) br = centerBrightness; + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r11 * br, g11 * br, b11 * br); + renderFaceUp(tt, X, Y, Z, tt->getTexture(level, x, y, z, 1)); + changed = true; + } - if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) { - float br = tt->getBrightness(level, x, y, z - 1); - if (tt->zz0 > 0) br = centerBrightness; - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r2 * br, g2 * br, b2 * br); - t.addOffset(0, 0, s); - renderNorth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 2)); - t.addOffset(0, 0, -s); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) { + float br = tt->getBrightness(level, x, y, z - 1); + if (tt->zz0 > 0) br = centerBrightness; + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r2 * br, g2 * br, b2 * br); + t.addOffset(0, 0, s); + renderNorth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 2)); + t.addOffset(0, 0, -s); + changed = true; + } - if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) { - float br = tt->getBrightness(level, x, y, z + 1); - if (tt->zz1 < 1) br = centerBrightness; - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r2 * br, g2 * br, b2 * br); - t.addOffset(0, 0, -s); - renderSouth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 3)); - t.addOffset(0, 0, s); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) { + float br = tt->getBrightness(level, x, y, z + 1); + if (tt->zz1 < 1) br = centerBrightness; + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r2 * br, g2 * br, b2 * br); + t.addOffset(0, 0, -s); + renderSouth(tt, X, Y, Z, tt->getTexture(level, x, y, z, 3)); + t.addOffset(0, 0, s); + changed = true; + } - if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) { - float br = tt->getBrightness(level, x - 1, y, z); - if (tt->xx0 > 0) br = centerBrightness; - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r3 * br, g3 * br, b3 * br); - t.addOffset(s, 0, 0); - renderWest(tt, X, Y, Z, tt->getTexture(level, x, y, z, 4)); - t.addOffset(-s, 0, 0); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) { + float br = tt->getBrightness(level, x - 1, y, z); + if (tt->xx0 > 0) br = centerBrightness; + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r3 * br, g3 * br, b3 * br); + t.addOffset(s, 0, 0); + renderWest(tt, X, Y, Z, tt->getTexture(level, x, y, z, 4)); + t.addOffset(-s, 0, 0); + changed = true; + } - if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) { - float br = tt->getBrightness(level, x + 1, y, z); - if (tt->xx1 < 1) br = centerBrightness; - // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = -// Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; - t.color(r3 * br, g3 * br, b3 * br); - t.addOffset(-s, 0, 0); - renderEast(tt, X, Y, Z, tt->getTexture(level, x, y, z, 5)); - t.addOffset(s, 0, 0); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) { + float br = tt->getBrightness(level, x + 1, y, z); + if (tt->xx1 < 1) br = centerBrightness; + // if (Tile::lightEmission[tt->id] > br*Level.MAX_BRIGHTNESS) br = + // Tile::lightEmission[tt->id]/Level.MAX_BRIGHTNESS; + t.color(r3 * br, g3 * br, b3 * br); + t.addOffset(-s, 0, 0); + renderEast(tt, X, Y, Z, tt->getTexture(level, x, y, z, 5)); + t.addOffset(s, 0, 0); + changed = true; + } - return changed; + return changed; } bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) { - bool changed = true; + bool changed = true; - float a = 6 / 16.0f; - float b = 10 / 16.0f; - tt->setShape(a, 0, a, b, 1, b); - tesselateBlockInWorld(tt, x, y, z); + float a = 6 / 16.0f; + float b = 10 / 16.0f; + tt->setShape(a, 0, a, b, 1, b); + tesselateBlockInWorld(tt, x, y, z); - bool vertical = false; - bool horizontal = false; + bool vertical = false; + bool horizontal = false; bool l = tt->connectsTo(level, x - 1, y, z); bool r = tt->connectsTo(level, x + 1, y, z); @@ -1487,42 +1546,42 @@ bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) { bool d = tt->connectsTo(level, x, y, z + 1); if (l || r) vertical = true; - if (u || d) horizontal = true; + if (u || d) horizontal = true; - if (!vertical && !horizontal) vertical = true; + if (!vertical && !horizontal) vertical = true; - a = 7 / 16.0f; - b = 9 / 16.0f; - float h0 = 12 / 16.0f; - float h1 = 15 / 16.0f; + a = 7 / 16.0f; + b = 9 / 16.0f; + float h0 = 12 / 16.0f; + float h1 = 15 / 16.0f; - float x0 = l ? 0 : a; - float x1 = r ? 1 : b; - float z0 = u ? 0 : a; - float z1 = d ? 1 : b; + float x0 = l ? 0 : a; + float x1 = r ? 1 : b; + float z0 = u ? 0 : a; + float z1 = d ? 1 : b; - if (vertical) { - tt->setShape(x0, h0, a, x1, h1, b); - tesselateBlockInWorld(tt, x, y, z); - } - if (horizontal) { - tt->setShape(a, h0, z0, b, h1, z1); - tesselateBlockInWorld(tt, x, y, z); - } + if (vertical) { + tt->setShape(x0, h0, a, x1, h1, b); + tesselateBlockInWorld(tt, x, y, z); + } + if (horizontal) { + tt->setShape(a, h0, z0, b, h1, z1); + tesselateBlockInWorld(tt, x, y, z); + } - h0 = 6 / 16.0f; - h1 = 9 / 16.0f; - if (vertical) { - tt->setShape(x0, h0, a, x1, h1, b); - tesselateBlockInWorld(tt, x, y, z); - } - if (horizontal) { - tt->setShape(a, h0, z0, b, h1, z1); - tesselateBlockInWorld(tt, x, y, z); - } + h0 = 6 / 16.0f; + h1 = 9 / 16.0f; + if (vertical) { + tt->setShape(x0, h0, a, x1, h1, b); + tesselateBlockInWorld(tt, x, y, z); + } + if (horizontal) { + tt->setShape(a, h0, z0, b, h1, z1); + tesselateBlockInWorld(tt, x, y, z); + } - tt->setShape(0, 0, 0, 1, 1, 1); - return changed; + tt->setShape(0, 0, 0, 1, 1, 1); + return changed; } bool TileRenderer::tesselateFenceGateInWorld(FenceGateTile* tt, int x, int y, int z) { @@ -2308,7 +2367,7 @@ void TileRenderer::renderEast( Tile* tt, float x, float y, float z, int tex ) void TileRenderer::renderTile( Tile* tile, int data ) { Tesselator& t = Tesselator::instance; - + t.color(0xff, 0xff, 0xff); // i disabled this, this is normally enabled in normal mcpe see if this fits OPTION_NORMAL_LIGHTING - shredder int shape = tile->getRenderShape(); @@ -2324,7 +2383,7 @@ void TileRenderer::renderTile( Tile* tile, int data ) t.normal(0.0f, 1.0f, 0.0f); renderFaceUp(tile, 0, 0, 0, tile->getTexture(1, data)); - + t.normal(0.0f, 0.0f, -1.0f); renderNorth(tile, 0, 0, 0, tile->getTexture(2, data)); @@ -2403,110 +2462,110 @@ void TileRenderer::renderTile( Tile* tile, int data ) t.addOffset(s, 0, 0); t.draw(); t.offset(0, 0, 0);//0.5f, 0.5f, 0.5f); - } else if (shape == Tile::SHAPE_ROWS) { - t.begin(); - t.normal(0, -1, 0); - tesselateRowTexture(tile, data, -0.5f, -0.5f, -0.5f); + } else if (shape == Tile::SHAPE_ROWS) { + t.begin(); + t.normal(0, -1, 0); + tesselateRowTexture(tile, data, -0.5f, -0.5f, -0.5f); //} else if (shape == Tile::SHAPE_TORCH) { //// t.begin(); //// t.normal(0, -1, 0); /// tesselateTorch(tile, -0.5f, -0.5f, -0.5f, 0, 0); //// t.end(); - } else if (shape == Tile::SHAPE_ENTITYTILE_ANIMATED) { - EntityTileRenderer::instance->render(tile, data, 1.0f); - //glEnable(GL_RESCALE_NORMAL); - } else if (shape == Tile::SHAPE_STAIRS) { - t.addOffset(-0.5f, -0.5f, -0.5f); - t.begin(); - for (int i = 0; i < 2; i++) { - if (i == 0) tile->setShape(0, 0, 0, 1, 1, 0.5f); - if (i == 1) tile->setShape(0, 0, 0.5f, 1, 0.5f, 1); + } else if (shape == Tile::SHAPE_ENTITYTILE_ANIMATED) { + EntityTileRenderer::instance->render(tile, data, 1.0f); + //glEnable(GL_RESCALE_NORMAL); + } else if (shape == Tile::SHAPE_STAIRS) { + t.addOffset(-0.5f, -0.5f, -0.5f); + t.begin(); + for (int i = 0; i < 2; i++) { + if (i == 0) tile->setShape(0, 0, 0, 1, 1, 0.5f); + if (i == 1) tile->setShape(0, 0, 0.5f, 1, 0.5f, 1); - t.normal(0.0f, -1.0f, 0.0f); - renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); - t.normal(0.0f, 1.0f, 0.0f); - renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); - t.normal(0.0f, 0.0f, -1.0f); - renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); - t.normal(0.0f, 0.0f, 1.0f); - renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); - t.normal(-1.0f, 0.0f, 0.0f); - renderWest(tile, 0, 0, 0, tile->getTexture(4)); + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4)); - t.normal(1.0f, 0.0f, 0.0f); - renderEast(tile, 0, 0, 0, tile->getTexture(5)); - } - t.draw(); - t.addOffset(0.5f, 0.5f, 0.5f); + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5)); } - else if (shape == Tile::SHAPE_FENCE) { - t.addOffset(-0.5f, -0.5f, -0.5f); - t.begin(); - for (int i = 0; i < 4; i++) { - float w = 2 / 16.0f; - if (i == 0) tile->setShape(0.5f - w, 0, 0, 0.5f + w, 1, w * 2); - if (i == 1) tile->setShape(0.5f - w, 0, 1 - w * 2, 0.5f + w, 1, 1); - w = 1 / 16.0f; - if (i == 2) tile->setShape(0.5f - w, 1 - w * 3, -w * 2, 0.5f + w, 1 - w, 1 + w * 2); - if (i == 3) tile->setShape(0.5f - w, 0.5f - w * 3, -w * 2, 0.5f + w, 0.5f - w, 1 + w * 2); + t.draw(); + t.addOffset(0.5f, 0.5f, 0.5f); + } + else if (shape == Tile::SHAPE_FENCE) { + t.addOffset(-0.5f, -0.5f, -0.5f); + t.begin(); + for (int i = 0; i < 4; i++) { + float w = 2 / 16.0f; + if (i == 0) tile->setShape(0.5f - w, 0, 0, 0.5f + w, 1, w * 2); + if (i == 1) tile->setShape(0.5f - w, 0, 1 - w * 2, 0.5f + w, 1, 1); + w = 1 / 16.0f; + if (i == 2) tile->setShape(0.5f - w, 1 - w * 3, -w * 2, 0.5f + w, 1 - w, 1 + w * 2); + if (i == 3) tile->setShape(0.5f - w, 0.5f - w * 3, -w * 2, 0.5f + w, 0.5f - w, 1 + w * 2); - t.normal(0.0f, -1.0f, 0.0f); - renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); - t.normal(0.0f, 1.0f, 0.0f); - renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); - t.normal(0.0f, 0.0f, -1.0f); - renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); - t.normal(0.0f, 0.0f, 1.0f); - renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); - t.normal(-1.0f, 0.0f, 0.0f); - renderWest(tile, 0, 0, 0, tile->getTexture(4)); + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4)); - t.normal(1.0f, 0.0f, 0.0f); - renderEast(tile, 0, 0, 0, tile->getTexture(5)); - } - t.draw(); - t.addOffset(0.5f, 0.5f, 0.5f); - tile->setShape(0, 0, 0, 1, 1, 1); - } else if (shape == Tile::SHAPE_FENCE_GATE) { - t.addOffset(-0.5f, -0.5f, -0.5f); - t.begin(); - for (int i = 0; i < 3; i++) { - float w = 1 / 16.0f; - if (i == 0) tile->setShape(0.5f - w, .3f, 0, 0.5f + w, 1, w * 2); - if (i == 1) tile->setShape(0.5f - w, .3f, 1 - w * 2, 0.5f + w, 1, 1); - if (i == 2) tile->setShape(0.5f - w, .5f, w * 2, 0.5f + w, 1 - w, 1 - w * 2); - - t.normal(0.0f, -1.0f, 0.0f); - renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); - - t.normal(0.0f, 1.0f, 0.0f); - renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); - - t.normal(0.0f, 0.0f, -1.0f); - renderNorth(tile, 0, 0, 0, tile->getTexture(2)); - - t.normal(0.0f, 0.0f, 1.0f); - renderSouth(tile, 0, 0, 0, tile->getTexture(3)); - - t.normal(-1.0f, 0.0f, 0.0f); - renderWest(tile, 0, 0, 0, tile->getTexture(4)); - - t.normal(1.0f, 0.0f, 0.0f); - renderEast(tile, 0, 0, 0, tile->getTexture(5)); - } - t.draw(); - t.addOffset(0.5f, 0.5f, 0.5f); - tile->setShape(0, 0, 0, 1, 1, 1); + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5)); } + t.draw(); + t.addOffset(0.5f, 0.5f, 0.5f); + tile->setShape(0, 0, 0, 1, 1, 1); + } else if (shape == Tile::SHAPE_FENCE_GATE) { + t.addOffset(-0.5f, -0.5f, -0.5f); + t.begin(); + for (int i = 0; i < 3; i++) { + float w = 1 / 16.0f; + if (i == 0) tile->setShape(0.5f - w, .3f, 0, 0.5f + w, 1, w * 2); + if (i == 1) tile->setShape(0.5f - w, .3f, 1 - w * 2, 0.5f + w, 1, 1); + if (i == 2) tile->setShape(0.5f - w, .5f, w * 2, 0.5f + w, 1 - w, 1 - w * 2); + + t.normal(0.0f, -1.0f, 0.0f); + renderFaceDown(tile, 0, 0, 0, tile->getTexture(0)); + + t.normal(0.0f, 1.0f, 0.0f); + renderFaceUp(tile, 0, 0, 0, tile->getTexture(1)); + + t.normal(0.0f, 0.0f, -1.0f); + renderNorth(tile, 0, 0, 0, tile->getTexture(2)); + + t.normal(0.0f, 0.0f, 1.0f); + renderSouth(tile, 0, 0, 0, tile->getTexture(3)); + + t.normal(-1.0f, 0.0f, 0.0f); + renderWest(tile, 0, 0, 0, tile->getTexture(4)); + + t.normal(1.0f, 0.0f, 0.0f); + renderEast(tile, 0, 0, 0, tile->getTexture(5)); + } + t.draw(); + t.addOffset(0.5f, 0.5f, 0.5f); + tile->setShape(0, 0, 0, 1, 1, 1); + } } diff --git a/src/client/renderer/TileRenderer.h b/src/client/renderer/TileRenderer.h index 83351bd7..c463abf3 100755 --- a/src/client/renderer/TileRenderer.h +++ b/src/client/renderer/TileRenderer.h @@ -10,6 +10,7 @@ class ThinFenceTile; class StairTile; class LevelSource; class Material; +class Minecraft; class TileRenderer { @@ -60,6 +61,10 @@ public: void renderTile(Tile* tile, int data); void renderGuiTile(Tile* tile, int data); + static void setUseTint(bool value) { + sideTinting = value; + } + static bool canRender(int renderShape); private: float getWaterHeight(int x, int y, int z, const Material* m); @@ -68,6 +73,7 @@ private: int fixedTexture; bool xFlipTexture; bool noCulling; + static bool sideTinting; bool applyAmbienceOcclusion; float ll000, llx00, ll0y0, ll00z, llX00, ll0Y0, ll00Z; diff --git a/src/world/entity/animal/Sheep.cpp b/src/world/entity/animal/Sheep.cpp index 9039fa1d..52294344 100755 --- a/src/world/entity/animal/Sheep.cpp +++ b/src/world/entity/animal/Sheep.cpp @@ -1,5 +1,6 @@ #include "Sheep.h" #include "../../item/DyePowderItem.h" +#include "../../level/tile/TallGrass.h" #include "../../level/tile/LevelEvent.h" const float Sheep::COLOR[][3] = { @@ -198,7 +199,7 @@ void Sheep::updateAi() int yy = Mth::floor(y); int zz = Mth::floor(z); - if (/*(level->getTile(xx, yy, zz) == Tile::tallgrass->id && level->getData(xx, yy, zz) == TallGrass::TALL_GRASS) || */ level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) { + if ((level->getTile(xx, yy, zz) == Tile::tallgrass->id && level->getData(xx, yy, zz) == TallGrass::TALL_GRASS) || level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) { eatAnimationTick = EAT_ANIMATION_TICKS; level->broadcastEntityEvent(this, EntityEvent::EAT_GRASS); } @@ -208,11 +209,11 @@ void Sheep::updateAi() int zz = Mth::floor(z); bool ate = false; - /* if (level->getTile(xx, yy, zz) == Tile::tallgrass->id) { - level->levelEvent(LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz, Tile::tallgrass->id + TallGrass::TALL_GRASS * 256); + if (level->getTile(xx, yy, zz) == Tile::tallgrass->id) { + level->levelEvent(NULL, LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy, zz, Tile::tallgrass->id + TallGrass::TALL_GRASS * 256); level->setTile(xx, yy, zz, 0); ate = true; - } else */if (level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) { + } else if (level->getTile(xx, yy - 1, zz) == ((Tile*)Tile::grass)->id) { level->levelEvent(NULL, LevelEvent::PARTICLES_DESTROY_BLOCK, xx, yy - 1, zz, ((Tile*)Tile::grass)->id); level->setTile(xx, yy - 1, zz, Tile::dirt->id); ate = true; diff --git a/src/world/item/DyePowderItem.cpp b/src/world/item/DyePowderItem.cpp index 11c7964c..2252c9de 100755 --- a/src/world/item/DyePowderItem.cpp +++ b/src/world/item/DyePowderItem.cpp @@ -10,6 +10,7 @@ #include "../level/tile/ClothTile.h" #include "../level/tile/CropTile.h" #include "../level/tile/StemTile.h" +#include "../level/tile/TallGrass.h" const std::string DyePowderItem::COLOR_DESCS[] = { "black", "red", "green", "brown", "blue", "purple", "cyan", "silver", "gray", "pink", "lime", "yellow", "lightBlue", "magenta", "orange", "white" @@ -91,9 +92,9 @@ bool DyePowderItem::useOn( ItemInstance* itemInstance, Player* player, Level* le continue; if (level->getTile(xx, yy, zz) == 0) { - /*if (random.nextInt(10) != 0) { - level->setTileAndData(xx, yy, zz, Tile::tallgrass.id, TallGrass.TALL_GRASS); - } else*/ if (random.nextInt(3) != 0) { + if (random.nextInt(10) != 0) { + level->setTileAndData(xx, yy, zz, Tile::tallgrass->id, TallGrass::TALL_GRASS); + } else if (random.nextInt(3) != 0) { level->setTile(xx, yy, zz, Tile::flower->id); } else { level->setTile(xx, yy, zz, Tile::rose->id); diff --git a/src/world/item/ShearsItem.h b/src/world/item/ShearsItem.h index d73b2f54..30d4d57e 100755 --- a/src/world/item/ShearsItem.h +++ b/src/world/item/ShearsItem.h @@ -22,7 +22,7 @@ public: /*@Override*/ bool mineBlock(ItemInstance* itemInstance, int tile, int x, int y, int z/*, Mob* owner*/) { - if (tile == ((Tile*)Tile::leaves)->id || tile == Tile::web->id /*|| tile == Tile::tallgrass->id || tile == Tile::vine->id*/) { + if (tile == ((Tile*)Tile::leaves)->id || tile == Tile::web->id || tile == Tile::tallgrass->id /*|| tile == Tile::vine->id*/) { itemInstance->hurt(1);//, owner); return true; } diff --git a/src/world/level/FoliageColor.h b/src/world/level/FoliageColor.h index 98d77b7a..4d1a4467 100755 --- a/src/world/level/FoliageColor.h +++ b/src/world/level/FoliageColor.h @@ -43,7 +43,7 @@ public: } static int getDefaultColor() { - return 0xFFFFFF; + return 0x48b518; } private: diff --git a/src/world/level/Level.cpp b/src/world/level/Level.cpp index bb5ac0e0..14aa54ec 100755 --- a/src/world/level/Level.cpp +++ b/src/world/level/Level.cpp @@ -1174,7 +1174,14 @@ Vec3 Level::getSkyColor(Entity* source, float a) { float br = Mth::cos(td * Mth::PI * 2) * 2 + 0.5f; if (br < 0.0f) br = 0.0f; - if (br > 0.75f) br = 0.75f; //@note; was 1.0f + if (dimension->FogType == 1) // @TODO - probably make this not dependent on dimension type honestly - shredder + { + if (br > 1.0f) br = 1.0f; //@ uses the normal javasky color ramp when java sky type is choosen, + } else + { + if (br > 0.8f) br = 0.8f; //@note; was 1.0f + } + int xx = Mth::floor(source->x); int zz = Mth::floor(source->z); diff --git a/src/world/level/biome/Biome.cpp b/src/world/level/biome/Biome.cpp index 2c8638f5..4c09842c 100755 --- a/src/world/level/biome/Biome.cpp +++ b/src/world/level/biome/Biome.cpp @@ -9,6 +9,7 @@ #include "../../level/tile/TallGrass.h" #include "../../../util/Color.h" +#include "../GrassColor.h" Biome* Biome::rainForest = NULL; Biome* Biome::swampland = NULL; @@ -217,6 +218,26 @@ int Biome::getSkyColor( float temp ) return Color::getHSBColor(224 / 360.0f - temp * 0.05f, 0.50f + temp * 0.1f, 1.0f).getRGB(); } +float Biome::getDownfall() +{ + return downfall; +} + + +float Biome::getTemperature() +{ + return temperature; +} + + +int Biome::getGrassColor() +{ + float temp = Mth::clamp(getTemperature(), 0.0f, 1.0f); + float rain = Mth::clamp(getDownfall(), 0.0f, 1.0f); + + return GrassColor::get(temp, rain); +} + Biome::MobList& Biome::getMobs(const MobCategory& category) { if (&category == &MobCategory::monster) diff --git a/src/world/level/biome/Biome.h b/src/world/level/biome/Biome.h index 48a49d56..af44be4e 100755 --- a/src/world/level/biome/Biome.h +++ b/src/world/level/biome/Biome.h @@ -78,7 +78,13 @@ public: virtual float adjustScale(float scale); virtual float adjustDepth(float depth); + + virtual int getSkyColor(float temp); + virtual int getGrassColor(); + + virtual float getDownfall(); + virtual float getTemperature(); virtual MobList& getMobs(const MobCategory& category); virtual float getCreatureProbability(); @@ -88,6 +94,8 @@ public: char topMaterial; char material; int leafColor; + float temperature; + float downfall; private: static Biome* map[64*64]; }; diff --git a/src/world/level/levelgen/RandomLevelSource.cpp b/src/world/level/levelgen/RandomLevelSource.cpp index 3868faa4..4e3c4b28 100755 --- a/src/world/level/levelgen/RandomLevelSource.cpp +++ b/src/world/level/levelgen/RandomLevelSource.cpp @@ -419,7 +419,7 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { FlowerFeature feature(Tile::mushroom2->id); feature.place(level, &random, x, y, z); } - /*int grassCount = 1; + int grassCount = 1; for (int i = 0; i < grassCount; i++) { int x = xo + random.nextInt(16) + 8; int y = random.nextInt(Level::genDepth); @@ -429,7 +429,7 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { grassFeature->place(level, &random, x, y, z); delete grassFeature; } - }*/ + } for (int i = 0; i < 10; i++) { int x = xo + random.nextInt(16) + 8; int y = random.nextInt(128); diff --git a/src/world/level/tile/LeafTile.h b/src/world/level/tile/LeafTile.h index 53d98842..6095d126 100755 --- a/src/world/level/tile/LeafTile.h +++ b/src/world/level/tile/LeafTile.h @@ -60,6 +60,7 @@ public: return FoliageColor::getDefaultColor(); } + // return FoliageColor::getDefaultColor(); we need to hook this up with OPTION_FOLIAGE_TINT level->getBiomeSource()->getBiomeBlock(x, z, 1, 1); float temperature = level->getBiomeSource()->temperatures[0]; diff --git a/src/world/level/tile/TallGrass.cpp b/src/world/level/tile/TallGrass.cpp index 7a0350c2..b3fc6e65 100755 --- a/src/world/level/tile/TallGrass.cpp +++ b/src/world/level/tile/TallGrass.cpp @@ -1,8 +1,12 @@ #include "TallGrass.h" #include "../FoliageColor.h" +#include "../GrassColor.h" #include "../../entity/player/Player.h" #include "../../item/Item.h" #include "../../item/ShearsItem.h" +#include "../Level.h" +#include "../LevelSource.h" +#include "../biome/BiomeSource.h" TallGrass::TallGrass( int id, int tex ) : super(id, tex, Material::replaceable_plant) { float ss = 0.4f; @@ -17,9 +21,14 @@ int TallGrass::getTexture( int face, int data ) { } int TallGrass::getColor() { - /*double temp = 0.5; - double rain = 1.0; - return GrassColor.get(temp, rain);*/ + //double temp = 0.5; + //double rain = 1.0; + // converted to float for consistency - shredder + float temp = 0.5; + float rain = 1.0; + if (GrassColor::useTint){ + return GrassColor::get(temp, rain); + } return 0x339933; } @@ -31,7 +40,15 @@ int TallGrass::getColor( int auxData ) { int TallGrass::getColor( LevelSource* level, int x, int y, int z ) { int d = level->getData(x, y, z); if (d == DEAD_SHRUB) return 0xffffff; - + float temp = level->getBiomeSource()->temperatures[0]; // shredder added + float rain = level->getBiomeSource()->downfalls[0]; // shredder added + if (GrassColor::useTint){ + return GrassColor::get(temp, rain); + } + // @TODO port this function from beta 1.6.6 probably, for now im using biomesource to tint it directly above - shredder + //if (GrassColor::useTint){ + //return level->getBiome(x, z)->getGrassColor(); + //} return 0x339933;//level->getBiome(x, z)->getGrassColor(); }