From 8f90088611f68a9830c1c9b6599d28946c1cec51 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 21 Mar 2026 22:28:58 -0500 Subject: [PATCH] TU19: merge Minecraft.Client/Rendering --- Minecraft.Client/Rendering/Camera.cpp | 8 +- Minecraft.Client/Rendering/Camera.h | 8 +- Minecraft.Client/Rendering/Chunk.cpp | 48 +- .../Rendering/Culling/DirtyChunkSorter.cpp | 2 +- .../Rendering/Culling/DirtyChunkSorter.h | 7 +- .../Rendering/Culling/DistanceChunkSorter.h | 3 +- .../Rendering/Culling/ViewportCuller.cpp | 4 +- .../Rendering/Culling/ViewportCuller.h | 3 +- .../EntityRenderers/ArrowRenderer.cpp | 14 +- .../Rendering/EntityRenderers/ArrowRenderer.h | 4 + .../Rendering/EntityRenderers/BatRenderer.cpp | 44 + .../Rendering/EntityRenderers/BatRenderer.h | 22 + .../EntityRenderers/BeaconRenderer.cpp | 140 ++ .../EntityRenderers/BeaconRenderer.h | 14 + .../EntityRenderers/BlazeRenderer.cpp | 13 +- .../Rendering/EntityRenderers/BlazeRenderer.h | 3 +- .../EntityRenderers/BoatRenderer.cpp | 14 +- .../Rendering/EntityRenderers/BoatRenderer.h | 4 + .../EntityRenderers/CaveSpiderRenderer.cpp | 19 + .../EntityRenderers/CaveSpiderRenderer.h | 17 + .../EntityRenderers/ChestRenderer.cpp | 51 +- .../Rendering/EntityRenderers/ChestRenderer.h | 9 +- .../EntityRenderers/ChickenRenderer.cpp | 10 +- .../EntityRenderers/ChickenRenderer.h | 6 +- .../Rendering/EntityRenderers/CowRenderer.cpp | 6 + .../Rendering/EntityRenderers/CowRenderer.h | 5 + .../EntityRenderers/CreeperRenderer.cpp | 24 +- .../EntityRenderers/CreeperRenderer.h | 15 +- .../EntityRenderers/DefaultRenderer.h | 3 + .../EntityRenderers/EnchantTableRenderer.cpp | 6 +- .../EntityRenderers/EnchantTableRenderer.h | 3 +- .../EntityRenderers/EnderChestRenderer.cpp | 11 +- .../EntityRenderers/EnderChestRenderer.h | 2 +- .../EntityRenderers/EnderCrystalRenderer.cpp | 16 +- .../EntityRenderers/EnderCrystalRenderer.h | 3 +- .../EntityRenderers/EnderDragonRenderer.cpp | 51 +- .../EntityRenderers/EnderDragonRenderer.h | 26 +- .../EntityRenderers/EnderManRenderer.cpp | 41 +- .../EntityRenderers/EnderManRenderer.h | 12 +- .../EntityRenderDispatcher.cpp | 126 +- .../EntityRenderers/EntityRenderDispatcher.h | 13 +- .../EntityRenderers/EntityRenderer.cpp | 48 +- .../EntityRenderers/EntityRenderer.h | 22 +- .../EntityRenderers/EntityTileRenderer.cpp | 6 + .../EntityRenderers/EntityTileRenderer.h | 1 + .../EntityRenderers/ExperienceOrbRenderer.cpp | 20 +- .../EntityRenderers/ExperienceOrbRenderer.h | 11 +- .../EntityRenderers/FallingTileRenderer.cpp | 90 +- .../EntityRenderers/FallingTileRenderer.h | 1 + .../EntityRenderers/FireballRenderer.cpp | 10 +- .../EntityRenderers/FireballRenderer.h | 3 +- .../EntityRenderers/FishingHookRenderer.cpp | 26 +- .../EntityRenderers/FishingHookRenderer.h | 4 + .../EntityRenderers/GhastRenderer.cpp | 17 +- .../Rendering/EntityRenderers/GhastRenderer.h | 7 +- .../EntityRenderers/GiantMobRenderer.cpp | 10 +- .../EntityRenderers/GiantMobRenderer.h | 4 +- .../EntityRenderers/HorseRenderer.cpp | 103 + .../Rendering/EntityRenderers/HorseRenderer.h | 34 + .../EntityRenderers/HumanoidMobRenderer.cpp | 162 +- .../EntityRenderers/HumanoidMobRenderer.h | 25 +- .../EntityRenderers/ItemFrameRenderer.cpp | 13 +- .../EntityRenderers/ItemFrameRenderer.h | 2 +- .../EntityRenderers/ItemInHandRenderer.cpp | 231 +- .../EntityRenderers/ItemInHandRenderer.h | 21 +- .../EntityRenderers/ItemRenderer.cpp | 117 +- .../Rendering/EntityRenderers/ItemRenderer.h | 5 +- .../EntityRenderers/ItemSpriteRenderer.cpp | 8 +- .../EntityRenderers/ItemSpriteRenderer.h | 1 + .../EntityRenderers/LavaSlimeRenderer.cpp | 23 +- .../EntityRenderers/LavaSlimeRenderer.h | 8 +- .../EntityRenderers/LeashKnotRenderer.cpp | 36 + .../EntityRenderers/LeashKnotRenderer.h | 20 + .../EntityRenderers/LivingEntityRenderer.cpp | 616 ++++++ .../EntityRenderers/LivingEntityRenderer.h | 61 + .../EntityRenderers/MinecartRenderer.cpp | 84 +- .../EntityRenderers/MinecartRenderer.h | 15 +- .../MinecartSpawnerRenderer.cpp | 15 + .../EntityRenderers/MinecartSpawnerRenderer.h | 10 + .../Rendering/EntityRenderers/MobRenderer.cpp | 581 ++---- .../Rendering/EntityRenderers/MobRenderer.h | 54 +- .../EntityRenderers/MobSpawnerRenderer.cpp | 8 +- .../EntityRenderers/MobSpawnerRenderer.h | 4 + .../EntityRenderers/MushroomCowRenderer.cpp | 35 +- .../EntityRenderers/MushroomCowRenderer.h | 8 +- .../EntityRenderers/OcelotRenderer.cpp | 40 +- .../EntityRenderers/OcelotRenderer.h | 20 +- .../EntityRenderers/PaintingRenderer.cpp | 121 +- .../EntityRenderers/PaintingRenderer.h | 2 + .../Rendering/EntityRenderers/PigRenderer.cpp | 23 +- .../Rendering/EntityRenderers/PigRenderer.h | 8 +- .../EntityRenderers/PistonPieceRenderer.cpp | 10 +- .../EntityRenderers/PistonPieceRenderer.h | 2 + .../EntityRenderers/PlayerRenderer.cpp | 206 +- .../EntityRenderers/PlayerRenderer.h | 39 +- .../EntityRenderers/ProgressRenderer.cpp | 2 +- .../EntityRenderers/ProgressRenderer.h | 2 +- .../EntityRenderers/SheepRenderer.cpp | 36 +- .../Rendering/EntityRenderers/SheepRenderer.h | 8 +- .../EntityRenderers/SignRenderer.cpp | 4 +- .../Rendering/EntityRenderers/SignRenderer.h | 1 + .../EntityRenderers/SilverfishRenderer.cpp | 11 +- .../EntityRenderers/SilverfishRenderer.h | 12 +- .../EntityRenderers/SkeletonRenderer.cpp | 34 + .../EntityRenderers/SkeletonRenderer.h | 17 + .../EntityRenderers/SkullTileRenderer.cpp | 34 +- .../EntityRenderers/SkullTileRenderer.h | 5 + .../EntityRenderers/SlimeRenderer.cpp | 16 +- .../Rendering/EntityRenderers/SlimeRenderer.h | 7 +- .../EntityRenderers/SnowManRenderer.cpp | 19 +- .../EntityRenderers/SnowManRenderer.h | 6 +- .../EntityRenderers/SpiderRenderer.cpp | 22 +- .../EntityRenderers/SpiderRenderer.h | 11 +- .../EntityRenderers/SquidRenderer.cpp | 13 +- .../Rendering/EntityRenderers/SquidRenderer.h | 10 +- .../EntityRenderers/TheEndPortalRenderer.cpp | 30 +- .../EntityRenderers/TheEndPortalRenderer.h | 6 + .../TileEntityRenderDispatcher.cpp | 17 +- .../TileEntityRenderDispatcher.h | 4 +- .../EntityRenderers/TileEntityRenderer.cpp | 9 +- .../EntityRenderers/TileEntityRenderer.h | 8 +- .../EntityRenderers/TileRenderer.cpp | 1857 ++++++++++++----- .../Rendering/EntityRenderers/TileRenderer.h | 24 +- .../EntityRenderers/TntMinecartRenderer.cpp | 43 + .../EntityRenderers/TntMinecartRenderer.h | 10 + .../Rendering/EntityRenderers/TntRenderer.cpp | 21 +- .../Rendering/EntityRenderers/TntRenderer.h | 3 +- .../EntityRenderers/VillagerGolemRenderer.cpp | 32 +- .../EntityRenderers/VillagerGolemRenderer.h | 18 +- .../EntityRenderers/VillagerRenderer.cpp | 47 +- .../EntityRenderers/VillagerRenderer.h | 24 +- .../EntityRenderers/WitchRenderer.cpp | 105 + .../Rendering/EntityRenderers/WitchRenderer.h | 23 + .../EntityRenderers/WitherBossRenderer.cpp | 108 + .../EntityRenderers/WitherBossRenderer.h | 27 + .../EntityRenderers/WitherSkullRenderer.cpp | 48 + .../EntityRenderers/WitherSkullRenderer.h | 21 + .../EntityRenderers/WolfRenderer.cpp | 30 +- .../Rendering/EntityRenderers/WolfRenderer.h | 14 +- .../EntityRenderers/ZombieRenderer.cpp | 29 +- .../EntityRenderers/ZombieRenderer.h | 25 +- Minecraft.Client/Rendering/GameRenderer.cpp | 676 +++--- Minecraft.Client/Rendering/GameRenderer.h | 19 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 578 ++--- Minecraft.Client/Rendering/LevelRenderer.h | 23 +- .../Rendering/Models/BatModel.cpp | 102 + Minecraft.Client/Rendering/Models/BatModel.h | 21 + .../Rendering/Models/BlazeModel.cpp | 3 +- .../Rendering/Models/BlazeModel.h | 1 + .../Rendering/Models/BookModel.cpp | 3 +- Minecraft.Client/Rendering/Models/BookModel.h | 1 + .../Rendering/Models/ChickenModel.cpp | 3 +- .../Rendering/Models/ChickenModel.h | 1 + .../Rendering/Models/CreeperModel.cpp | 3 +- .../Rendering/Models/CreeperModel.h | 1 + .../Rendering/Models/DragonModel.cpp | 4 +- .../Rendering/Models/DragonModel.h | 2 +- .../Rendering/Models/EnderManModel.cpp | 3 +- .../Rendering/Models/EnderManModel.h | 1 + .../Rendering/Models/GhastModel.cpp | 3 +- .../Rendering/Models/GhastModel.h | 1 + .../Rendering/Models/HumanoidModel.cpp | 78 +- .../Rendering/Models/HumanoidModel.h | 4 +- .../Rendering/Models/LavaSlimeModel.cpp | 6 +- .../Rendering/Models/LavaSlimeModel.h | 4 +- .../Rendering/Models/LeashKnotModel.cpp | 35 + .../Rendering/Models/LeashKnotModel.h | 19 + Minecraft.Client/Rendering/Models/Model.h | 11 +- .../Rendering/Models/ModelHorse.cpp | 687 ++++++ .../Rendering/Models/ModelHorse.h | 68 + .../Rendering/Models/ModelPart.cpp | 5 + Minecraft.Client/Rendering/Models/ModelPart.h | 3 +- .../Rendering/Models/OcelotModel.cpp | 47 +- .../Rendering/Models/OcelotModel.h | 11 +- .../Rendering/Models/QuadrupedModel.cpp | 3 +- .../Rendering/Models/QuadrupedModel.h | 1 + .../Rendering/Models/SheepFurModel.cpp | 7 +- .../Rendering/Models/SheepFurModel.h | 7 +- .../Rendering/Models/SheepModel.cpp | 7 +- .../Rendering/Models/SheepModel.h | 5 +- .../Rendering/Models/SilverfishModel.cpp | 4 +- .../Rendering/Models/SilverfishModel.h | 1 + .../Rendering/Models/SkeletonHeadModel.cpp | 6 +- .../Rendering/Models/SkeletonHeadModel.h | 3 +- .../Rendering/Models/SkeletonModel.cpp | 12 +- .../Rendering/Models/SkeletonModel.h | 3 + .../Rendering/Models/SkiModel.cpp | 55 + Minecraft.Client/Rendering/Models/SkiModel.h | 22 + .../Rendering/Models/SlimeModel.cpp | 2 +- .../Rendering/Models/SnowManModel.cpp | 5 +- .../Rendering/Models/SnowManModel.h | 1 + .../Rendering/Models/SpiderModel.cpp | 3 +- .../Rendering/Models/SpiderModel.h | 1 + .../Rendering/Models/SquidModel.cpp | 3 +- .../Rendering/Models/SquidModel.h | 1 + .../Rendering/Models/VillagerGolemModel.cpp | 7 +- .../Rendering/Models/VillagerGolemModel.h | 5 +- .../Rendering/Models/VillagerModel.cpp | 22 +- .../Rendering/Models/VillagerModel.h | 7 +- .../Rendering/Models/VillagerZombieModel.cpp | 3 +- .../Rendering/Models/VillagerZombieModel.h | 3 +- .../Rendering/Models/WitchModel.cpp | 71 + .../Rendering/Models/WitchModel.h | 19 + .../Rendering/Models/WitherBossModel.cpp | 79 + .../Rendering/Models/WitherBossModel.h | 23 + .../Rendering/Models/WolfModel.cpp | 9 +- Minecraft.Client/Rendering/Models/WolfModel.h | 3 +- .../Rendering/Models/ZombieModel.cpp | 3 +- .../Rendering/Models/ZombieModel.h | 1 + .../Particles/FireworksParticles.cpp | 455 ++++ .../Rendering/Particles/FireworksParticles.h | 85 + .../Rendering/Particles/FootstepParticle.cpp | 6 +- .../Rendering/Particles/FootstepParticle.h | 1 + .../Particles/HugeExplosionParticle.cpp | 6 +- .../Particles/HugeExplosionParticle.h | 1 + .../Rendering/Particles/Particle.cpp | 12 +- .../Rendering/Particles/ParticleEngine.cpp | 194 +- .../Rendering/Particles/ParticleEngine.h | 24 +- 218 files changed, 7654 insertions(+), 2698 deletions(-) create mode 100644 Minecraft.Client/Rendering/EntityRenderers/BatRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/BatRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.h create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.cpp create mode 100644 Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.h create mode 100644 Minecraft.Client/Rendering/Models/BatModel.cpp create mode 100644 Minecraft.Client/Rendering/Models/BatModel.h create mode 100644 Minecraft.Client/Rendering/Models/LeashKnotModel.cpp create mode 100644 Minecraft.Client/Rendering/Models/LeashKnotModel.h create mode 100644 Minecraft.Client/Rendering/Models/ModelHorse.cpp create mode 100644 Minecraft.Client/Rendering/Models/ModelHorse.h create mode 100644 Minecraft.Client/Rendering/Models/SkiModel.cpp create mode 100644 Minecraft.Client/Rendering/Models/SkiModel.h create mode 100644 Minecraft.Client/Rendering/Models/WitchModel.cpp create mode 100644 Minecraft.Client/Rendering/Models/WitchModel.h create mode 100644 Minecraft.Client/Rendering/Models/WitherBossModel.cpp create mode 100644 Minecraft.Client/Rendering/Models/WitherBossModel.h create mode 100644 Minecraft.Client/Rendering/Particles/FireworksParticles.cpp create mode 100644 Minecraft.Client/Rendering/Particles/FireworksParticles.h diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index e085cf06c..0b77091af 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -89,11 +89,12 @@ zPlayerOffs = position->get(2); ya = cosf(xRot * PI / 180.0f); } -TilePos* Camera::getCameraTilePos(std::shared_ptr player, double alpha) { +TilePos* Camera::getCameraTilePos(std::shared_ptr player, + double alpha) { return new TilePos(getCameraPos(player, alpha)); } -Vec3* Camera::getCameraPos(std::shared_ptr player, double alpha) { +Vec3* Camera::getCameraPos(std::shared_ptr player, double alpha) { double xx = player->xo + (player->x - player->xo) * alpha; double yy = player->yo + (player->y - player->yo) * alpha + player->getHeadHeight(); @@ -106,7 +107,8 @@ Vec3* Camera::getCameraPos(std::shared_ptr player, double alpha) { return Vec3::newTemp(xt, yt, zt); } -int Camera::getBlockAt(Level* level, std::shared_ptr player, float alpha) { +int Camera::getBlockAt(Level* level, std::shared_ptr player, + float alpha) { Vec3* p = Camera::getCameraPos(player, alpha); TilePos tp = TilePos(p); int t = level->getTile(tp.x, tp.y, tp.z); diff --git a/Minecraft.Client/Rendering/Camera.h b/Minecraft.Client/Rendering/Camera.h index 019a6efa7..ce2dcb6ce 100644 --- a/Minecraft.Client/Rendering/Camera.h +++ b/Minecraft.Client/Rendering/Camera.h @@ -24,8 +24,10 @@ public: static void prepare(std::shared_ptr player, bool mirror); - static TilePos* getCameraTilePos(std::shared_ptr player, double alpha); - static Vec3* getCameraPos(std::shared_ptr player, double alpha); - static int getBlockAt(Level* level, std::shared_ptr player, + static TilePos* getCameraTilePos(std::shared_ptr player, + double alpha); + static Vec3* getCameraPos(std::shared_ptr player, + double alpha); + static int getBlockAt(Level* level, std::shared_ptr player, float alpha); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 746d29d79..ccc786872 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -204,8 +204,8 @@ void Chunk::rebuild() { LevelChunk::touchedSky = false; - // std::unordered_set > - //oldTileEntities(renderableTileEntities.begin(),renderableTileEntities.end()); + // unordered_set > + // oldTileEntities(renderableTileEntities.begin(),renderableTileEntities.end()); //// 4J removed this & next line renderableTileEntities.clear(); std::vector > @@ -242,7 +242,7 @@ void Chunk::rebuild() { // the whole thing LevelSource* region = - new Region(level, x0 - r, y0 - r, z0 - r, x1 + r, y1 + r, z1 + r); + new Region(level, x0 - r, y0 - r, z0 - r, x1 + r, y1 + r, z1 + r, r); TileRenderer* tileRenderer = new TileRenderer(region, this->x, this->y, this->z, tileIds); @@ -294,27 +294,27 @@ void Chunk::rebuild() { // of rock, dirt, unbreakable tiles, or have already been // determined to meet this criteria themselves and have a tile // of 255 set. - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; tileId = tileIds[offset + (((xx - 1) << 11) | ((zz + 0) << 7) | (indexY + 0))]; - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; tileId = tileIds[offset + (((xx + 1) << 11) | ((zz + 0) << 7) | (indexY + 0))]; - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; tileId = tileIds[offset + (((xx + 0) << 11) | ((zz - 1) << 7) | (indexY + 0))]; - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; tileId = tileIds[offset + (((xx + 0) << 11) | ((zz + 1) << 7) | (indexY + 0))]; - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; // Treat the bottom of the world differently - we shouldn't ever @@ -332,7 +332,7 @@ void Chunk::rebuild() { tileId = tileIds[yMinusOneOffset + (((xx + 0) << 11) | ((zz + 0) << 7) | indexYMinusOne)]; - if (!((tileId == Tile::rock_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; @@ -346,7 +346,7 @@ void Chunk::rebuild() { tileId = tileIds[yPlusOneOffset + (((xx + 0) << 11) | ((zz + 0) << 7) | indexYPlusOne)]; - if (!((tileId == Tile::rock_Id) || (tileId == Tile::dirt_Id) || + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; @@ -416,7 +416,7 @@ void Chunk::rebuild() { // If flagged as not visible, drop out straight away if (tileId == 0xff) continue; // int tileId = - //region->getTile(x,y,z); + // region->getTile(x,y,z); if (tileId > 0) { if (!started) { started = true; @@ -425,8 +425,8 @@ void Chunk::rebuild() { glNewList(lists + currentLayer, GL_COMPILE); MemSect(0); glPushMatrix(); - glDepthMask(true); // 4J added - t->useCompactVertices(false); // 4J added + glDepthMask(true); // 4J added + t->useCompactVertices(true); // 4J added translateToPos(); float ss = 1.000001f; // 4J - have removed this scale as I don't think we @@ -666,8 +666,6 @@ TileCompressData_SPU g_tileCompressDataIn __attribute__((__aligned__(16))); unsigned char* g_tileCompressDataOut = (unsigned char*)&g_rebuildDataIn.m_tileIds; -#define TILE_RENDER_SPU - void RunSPURebuild() { static C4JSpursJobQueue::Port p("C4JSpursJob_ChunkUpdate"); C4JSpursJob_CompressedTile tileJob(&g_tileCompressDataIn, @@ -702,8 +700,8 @@ void Chunk::rebuild_SPU() { LevelChunk::touchedSky = false; - // std::unordered_set > - //oldTileEntities(renderableTileEntities.begin(),renderableTileEntities.end()); + // unordered_set > + // oldTileEntities(renderableTileEntities.begin(),renderableTileEntities.end()); //// 4J removed this & next line renderableTileEntities.clear(); std::vector > @@ -715,7 +713,7 @@ void Chunk::rebuild_SPU() { int r = 1; - Region region(level, x0 - r, y0 - r, z0 - r, x1 + r, y1 + r, z1 + r); + Region region(level, x0 - r, y0 - r, z0 - r, x1 + r, y1 + r, z1 + r, r); TileRenderer tileRenderer(®ion); int lists = levelRenderer->getGlobalIndexForChunk(this->x, this->y, this->z, @@ -754,8 +752,8 @@ void Chunk::rebuild_SPU() { glNewList(lists + currentLayer, GL_COMPILE); MemSect(0); glPushMatrix(); - glDepthMask(true); // 4J added - t->useCompactVertices(false); // 4J added + glDepthMask(true); // 4J added + t->useCompactVertices(true); // 4J added translateToPos(); float ss = 1.000001f; // 4J - have removed this scale as I don't think we should need it, @@ -775,19 +773,11 @@ void Chunk::rebuild_SPU() { (unsigned int*)g_rebuildDataIn.m_tesselator.m_PPUArray); g_rebuildDataIn.m_tesselator._array = &tesselatorArray; g_rebuildDataIn.m_currentLayer = currentLayer; -#ifdef TILE_RENDER_SPU g_tileCompressDataIn.setForChunk(®ion, x0, y0, z0); RunSPURebuild(); g_rebuildDataOut.storeInTesselator(); pOutData = &g_rebuildDataOut; -#else - g_rebuildDataIn.disableUnseenTiles(); - TileRenderer_SPU* pTileRenderer = - new TileRenderer_SPU(&g_rebuildDataIn); - g_rebuildDataIn.tesselateAllTiles(pTileRenderer); - g_rebuildDataIn.storeInTesselator(); - pOutData = &g_rebuildDataIn; -#endif + if (pOutData->m_flags & ChunkRebuildData::e_flag_Rendered) rendered = true; diff --git a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp index cfb90360b..9901135a6 100644 --- a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp +++ b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp @@ -3,7 +3,7 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" #include "../Chunk.h" -DirtyChunkSorter::DirtyChunkSorter(std::shared_ptr cameraEntity, +DirtyChunkSorter::DirtyChunkSorter(std::shared_ptr cameraEntity, int playerIndex) // 4J - added player index { this->cameraEntity = cameraEntity; diff --git a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.h b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.h index 523a8754e..be64b7ae0 100644 --- a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.h +++ b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.h @@ -2,13 +2,14 @@ class Chunk; class Mob; -class DirtyChunkSorter { +class DirtyChunkSorter + : public std::binary_function { private: - std::shared_ptr cameraEntity; + std::shared_ptr cameraEntity; int playerIndex; // 4J added public: - DirtyChunkSorter(std::shared_ptr cameraEntity, + DirtyChunkSorter(std::shared_ptr cameraEntity, int playerIndex); // 4J - added player index bool operator()(const Chunk* a, const Chunk* b) const; }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Culling/DistanceChunkSorter.h b/Minecraft.Client/Rendering/Culling/DistanceChunkSorter.h index 2557d9ece..6cf18578b 100644 --- a/Minecraft.Client/Rendering/Culling/DistanceChunkSorter.h +++ b/Minecraft.Client/Rendering/Culling/DistanceChunkSorter.h @@ -2,7 +2,8 @@ class Entity; class Chunk; -class DistanceChunkSorter { +class DistanceChunkSorter + : public std::binary_function { private: double ix, iy, iz; diff --git a/Minecraft.Client/Rendering/Culling/ViewportCuller.cpp b/Minecraft.Client/Rendering/Culling/ViewportCuller.cpp index 7b07efaaf..addd4b097 100644 --- a/Minecraft.Client/Rendering/Culling/ViewportCuller.cpp +++ b/Minecraft.Client/Rendering/Culling/ViewportCuller.cpp @@ -47,8 +47,8 @@ bool ViewportCuller::Face::fullyInFront(double x0, double y0, double z0, return true; } -ViewportCuller::ViewportCuller(std::shared_ptr mob, double fogDistance, - float a) { +ViewportCuller::ViewportCuller(std::shared_ptr mob, + double fogDistance, float a) { float yRot = mob->yRotO + (mob->yRot - mob->yRotO) * a; float xRot = mob->xRotO + (mob->xRot - mob->xRotO) * a; diff --git a/Minecraft.Client/Rendering/Culling/ViewportCuller.h b/Minecraft.Client/Rendering/Culling/ViewportCuller.h index 0d634f9b1..72373dd49 100644 --- a/Minecraft.Client/Rendering/Culling/ViewportCuller.h +++ b/Minecraft.Client/Rendering/Culling/ViewportCuller.h @@ -27,7 +27,8 @@ private: double xOff, yOff, zOff; public: - ViewportCuller(std::shared_ptr mob, double fogDistance, float a); + ViewportCuller(std::shared_ptr mob, double fogDistance, + float a); virtual bool isVisible(AABB bb); virtual bool cubeInFrustum(double x0, double y0, double z0, double x1, double y1, double z1); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.cpp index 83d7764e5..1c619b2f3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.cpp @@ -3,13 +3,16 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.projectile.h" #include "../../../Minecraft.World/Util/Mth.h" +ResourceLocation ArrowRenderer::ARROW_LOCATION = + ResourceLocation(TN_ITEM_ARROWS); + void ArrowRenderer::render(std::shared_ptr _arrow, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type Arrow rather than std::shared_ptr we have here - do some - // casting around instead + // type Arrow rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr arrow = std::dynamic_pointer_cast(_arrow); - bindTexture(TN_ITEM_ARROWS); // 4J - was L"/item/arrows.png" + bindTexture(_arrow); // 4J - was L"/item/arrows.png" glPushMatrix(); @@ -98,4 +101,9 @@ void ArrowRenderer::render(std::shared_ptr _arrow, double x, double y, } glDisable(GL_RESCALE_NORMAL); glPopMatrix(); +} + +ResourceLocation* ArrowRenderer::getTextureLocation( + std::shared_ptr mob) { + return &ARROW_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.h index 0491c6990..5b79a83f7 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ArrowRenderer.h @@ -2,7 +2,11 @@ #include "EntityRenderer.h" class ArrowRenderer : public EntityRenderer { +private: + static ResourceLocation ARROW_LOCATION; + public: virtual void render(std::shared_ptr _arrow, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.cpp new file mode 100644 index 000000000..ce3e7859d --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.cpp @@ -0,0 +1,44 @@ +#include "../../Platform/stdafx.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.ambient.h" +#include "BatRenderer.h" +#include "../Models/BatModel.h" + +ResourceLocation BatRenderer::BAT_LOCATION = ResourceLocation(TN_MOB_BAT); + +BatRenderer::BatRenderer() : MobRenderer(new BatModel(), 0.25f) { + modelVersion = ((BatModel*)model)->modelVersion(); +} + +void BatRenderer::render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a) { + int modelVersion = (dynamic_cast(model))->modelVersion(); + if (modelVersion != this->modelVersion) { + this->modelVersion = modelVersion; + model = new BatModel(); + } + MobRenderer::render(_mob, x, y, z, rot, a); +} + +ResourceLocation* BatRenderer::getTextureLocation(std::shared_ptr mob) { + return &BAT_LOCATION; +} + +void BatRenderer::scale(std::shared_ptr mob, float a) { + glScalef(.35f, .35f, .35f); +} + +void BatRenderer::setupPosition(std::shared_ptr mob, double x, + double y, double z) { + MobRenderer::setupPosition(mob, x, y, z); +} + +void BatRenderer::setupRotations(std::shared_ptr _mob, float bob, + float bodyRot, float a) { + std::shared_ptr mob = std::dynamic_pointer_cast(_mob); + if (!mob->isResting()) { + glTranslatef(0, cos(bob * .3f) * .1f, 0); + } else { + glTranslatef(0, -.1f, 0); + } + MobRenderer::setupRotations(mob, bob, bodyRot, a); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.h new file mode 100644 index 000000000..3006efac6 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/BatRenderer.h @@ -0,0 +1,22 @@ +#pragma once +#include "MobRenderer.h" + +class BatModel; + +class BatRenderer : public MobRenderer { + static ResourceLocation BAT_LOCATION; + int modelVersion; + +public: + BatRenderer(); + virtual void render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a); + +protected: + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); + virtual void scale(std::shared_ptr mob, float a); + virtual void setupPosition(std::shared_ptr mob, double x, + double y, double z); + virtual void setupRotations(std::shared_ptr mob, float bob, + float bodyRot, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.cpp new file mode 100644 index 000000000..017dee765 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.cpp @@ -0,0 +1,140 @@ +#include "../../Platform/stdafx.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" +#include "BeaconRenderer.h" +#include "../Tesselator.h" + +ResourceLocation BeaconRenderer::BEAM_LOCATION = + ResourceLocation(TN_MISC_BEACON_BEAM); + +void BeaconRenderer::render(std::shared_ptr _beacon, double x, + double y, double z, float a, bool setColor, + float alpha, bool useCompiled) { + std::shared_ptr beacon = + std::dynamic_pointer_cast(_beacon); + + float scale = beacon->getAndUpdateClientSideScale(); + + if (scale > 0) { + Tesselator* t = Tesselator::getInstance(); + + bindTexture(&BEAM_LOCATION); + + // TODO: 4J: Put this back in + // assert(0); + // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDepthMask(true); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + float tt = beacon->getLevel()->getGameTime() + a; + float texVOff = -tt * .20f - floor(-tt * .10f); + + { + int r = 1; + + double rot = tt * .025 * (1 - (r & 1) * 2.5); + + t->begin(); + t->color(255, 255, 255, 32); + + double rr1 = r * 0.2; + + double wnx = .5 + cos(rot + PI * .75) * rr1; + double wnz = .5 + sin(rot + PI * .75) * rr1; + double enx = .5 + cos(rot + PI * .25) * rr1; + double enz = .5 + sin(rot + PI * .25) * rr1; + + double wsx = .5 + cos(rot + PI * 1.25) * rr1; + double wsz = .5 + sin(rot + PI * 1.25) * rr1; + double esx = .5 + cos(rot + PI * 1.75) * rr1; + double esz = .5 + sin(rot + PI * 1.75) * rr1; + + double top = 256 * scale; + + double uu1 = 0; + double uu2 = 1; + double vv2 = -1 + texVOff; + double vv1 = 256 * scale * (.5 / rr1) + vv2; + + t->vertexUV(x + wnx, y + top, z + wnz, uu2, vv1); + t->vertexUV(x + wnx, y, z + wnz, uu2, vv2); + t->vertexUV(x + enx, y, z + enz, uu1, vv2); + t->vertexUV(x + enx, y + top, z + enz, uu1, vv1); + + t->vertexUV(x + esx, y + top, z + esz, uu2, vv1); + t->vertexUV(x + esx, y, z + esz, uu2, vv2); + t->vertexUV(x + wsx, y, z + wsz, uu1, vv2); + t->vertexUV(x + wsx, y + top, z + wsz, uu1, vv1); + + t->vertexUV(x + enx, y + top, z + enz, uu2, vv1); + t->vertexUV(x + enx, y, z + enz, uu2, vv2); + t->vertexUV(x + esx, y, z + esz, uu1, vv2); + t->vertexUV(x + esx, y + top, z + esz, uu1, vv1); + + t->vertexUV(x + wsx, y + top, z + wsz, uu2, vv1); + t->vertexUV(x + wsx, y, z + wsz, uu2, vv2); + t->vertexUV(x + wnx, y, z + wnz, uu1, vv2); + t->vertexUV(x + wnx, y + top, z + wnz, uu1, vv1); + + t->end(); + } + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(false); + + { + t->begin(); + t->color(255, 255, 255, 32); + + double wnx = .2; + double wnz = .2; + double enx = .8; + double enz = .2; + + double wsx = .2; + double wsz = .8; + double esx = .8; + double esz = .8; + + double top = 256 * scale; + + double uu1 = 0; + double uu2 = 1; + double vv2 = -1 + texVOff; + double vv1 = 256 * scale + vv2; + + t->vertexUV(x + wnx, y + top, z + wnz, uu2, vv1); + t->vertexUV(x + wnx, y, z + wnz, uu2, vv2); + t->vertexUV(x + enx, y, z + enz, uu1, vv2); + t->vertexUV(x + enx, y + top, z + enz, uu1, vv1); + + t->vertexUV(x + esx, y + top, z + esz, uu2, vv1); + t->vertexUV(x + esx, y, z + esz, uu2, vv2); + t->vertexUV(x + wsx, y, z + wsz, uu1, vv2); + t->vertexUV(x + wsx, y + top, z + wsz, uu1, vv1); + + t->vertexUV(x + enx, y + top, z + enz, uu2, vv1); + t->vertexUV(x + enx, y, z + enz, uu2, vv2); + t->vertexUV(x + esx, y, z + esz, uu1, vv2); + t->vertexUV(x + esx, y + top, z + esz, uu1, vv1); + + t->vertexUV(x + wsx, y + top, z + wsz, uu2, vv1); + t->vertexUV(x + wsx, y, z + wsz, uu2, vv2); + t->vertexUV(x + wnx, y, z + wnz, uu1, vv2); + t->vertexUV(x + wnx, y + top, z + wnz, uu1, vv1); + + t->end(); + } + + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + + glDepthMask(true); + } +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.h new file mode 100644 index 000000000..d7994913a --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/BeaconRenderer.h @@ -0,0 +1,14 @@ +#pragma once +#include "TileEntityRenderer.h" + +class BeaconTileEntity; + +class BeaconRenderer : public TileEntityRenderer { +private: + static ResourceLocation BEAM_LOCATION; + +public: + virtual void render(std::shared_ptr _beacon, double x, double y, + double z, float a, bool setColor, float alpha, + bool useCompiled); +}; diff --git a/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.cpp index 8670234d2..30242923f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.cpp @@ -3,15 +3,17 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "BlazeRenderer.h" +ResourceLocation BlazeRenderer::BLAZE_LOCATION = ResourceLocation(TN_MOB_BLAZE); + BlazeRenderer::BlazeRenderer() : MobRenderer(new BlazeModel(), 0.5f) { - this->modelVersion = ((BlazeModel*)model)->modelVersion(); + modelVersion = ((BlazeModel*)model)->modelVersion(); } void BlazeRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type Blaze rather than std::shared_ptr we have here - do some - // casting around instead + // type Blaze rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); int modelVersion = ((BlazeModel*)model)->modelVersion(); @@ -20,4 +22,9 @@ void BlazeRenderer::render(std::shared_ptr _mob, double x, double y, model = new BlazeModel(); } MobRenderer::render(mob, x, y, z, rot, a); +} + +ResourceLocation* BlazeRenderer::getTextureLocation( + std::shared_ptr mob) { + return &BLAZE_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.h index 12284da6b..992e8d04f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/BlazeRenderer.h @@ -1,9 +1,9 @@ #pragma once - #include "MobRenderer.h" class BlazeRenderer : public MobRenderer { private: + static ResourceLocation BLAZE_LOCATION; int modelVersion; public: @@ -11,4 +11,5 @@ public: virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.cpp index 3018a7c8e..a6ef9dd0a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.cpp @@ -4,6 +4,8 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" #include "../../../Minecraft.World/Util/Mth.h" +ResourceLocation BoatRenderer::BOAT_LOCATION = ResourceLocation(TN_ITEM_BOAT); + BoatRenderer::BoatRenderer() : EntityRenderer() { this->shadowRadius = 0.5f; model = new BoatModel(); @@ -12,8 +14,8 @@ BoatRenderer::BoatRenderer() : EntityRenderer() { void BoatRenderer::render(std::shared_ptr _boat, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type Boat rather than std::shared_ptr we have here - do some - // casting around instead + // type Boat rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr boat = std::dynamic_pointer_cast(_boat); glPushMatrix(); @@ -29,13 +31,17 @@ void BoatRenderer::render(std::shared_ptr _boat, double x, double y, 0); } - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" float ss = 12 / 16.0f; glScalef(ss, ss, ss); glScalef(1 / ss, 1 / ss, 1 / ss); - bindTexture(TN_ITEM_BOAT); // 4J was L"/item/boat.png" + bindTexture(boat); glScalef(-1, -1, 1); model->render(boat, 0, 0, -0.1f, 0, 0, 1 / 16.0f, true); glPopMatrix(); +} + +ResourceLocation* BoatRenderer::getTextureLocation( + std::shared_ptr mob) { + return &BOAT_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.h index 06e490794..b1a5c83ce 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/BoatRenderer.h @@ -2,6 +2,9 @@ #include "EntityRenderer.h" class BoatRenderer : public EntityRenderer { +private: + static ResourceLocation BOAT_LOCATION; + protected: Model* model; @@ -10,4 +13,5 @@ public: virtual void render(std::shared_ptr boat, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.cpp new file mode 100644 index 000000000..9a5445672 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.cpp @@ -0,0 +1,19 @@ +#include "../../Platform/stdafx.h" +#include "CaveSpiderRenderer.h" + +ResourceLocation CaveSpiderRenderer::CAVE_SPIDER_LOCATION = + ResourceLocation(TN_MOB_CAVE_SPIDER); +float CaveSpiderRenderer::s_scale = 0.7f; + +CaveSpiderRenderer::CaveSpiderRenderer() : SpiderRenderer() { + shadowRadius *= s_scale; +} + +void CaveSpiderRenderer::scale(std::shared_ptr mob, float a) { + glScalef(s_scale, s_scale, s_scale); +} + +ResourceLocation* CaveSpiderRenderer::getTextureLocation( + std::shared_ptr mob) { + return &CAVE_SPIDER_LOCATION; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.h new file mode 100644 index 000000000..97314abfa --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/CaveSpiderRenderer.h @@ -0,0 +1,17 @@ +#pragma once +#include "SpiderRenderer.h" + +class CaveSpider; + +class CaveSpiderRenderer : public SpiderRenderer { +private: + static ResourceLocation CAVE_SPIDER_LOCATION; + static float s_scale; + +public: + CaveSpiderRenderer(); + +protected: + virtual void scale(std::shared_ptr mob, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.cpp index f2050f311..cc6a181d8 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.cpp @@ -5,10 +5,34 @@ #include "../Models/ModelPart.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" +#include "../../../Minecraft.World/Level/Calendar.h" -ChestRenderer::ChestRenderer() { +ResourceLocation ChestRenderer::CHEST_LARGE_TRAP_LOCATION = + ResourceLocation(TN_TILE_LARGE_TRAP_CHEST); +// ResourceLocation ChestRenderer::CHEST_LARGE_XMAS_LOCATION = +// ResourceLocation(TN_TILE_LARGE_XMAS_CHEST); +ResourceLocation ChestRenderer::CHEST_LARGE_LOCATION = + ResourceLocation(TN_TILE_LARGE_CHEST); +ResourceLocation ChestRenderer::CHEST_TRAP_LOCATION = + ResourceLocation(TN_TILE_TRAP_CHEST); +// ResourceLocation ChestRenderer::CHEST_XMAS_LOCATION = +// ResourceLocation(TN_TILE_XMAS_CHEST); +ResourceLocation ChestRenderer::CHEST_LOCATION = + ResourceLocation(TN_TILE_CHEST); + +ChestRenderer::ChestRenderer() : TileEntityRenderer() { chestModel = new ChestModel(); largeChestModel = new LargeChestModel(); + + xmasTextures = false; + + // 4J Stu - Disable this +#if 0 + if (Calendar::GetMonth() + 1 == 12 && Calendar::GetDayOfMonth() >= 24 && Calendar::GetDayOfMonth() <= 26) + { + xmasTextures = true; + } +#endif } ChestRenderer::~ChestRenderer() { @@ -31,7 +55,7 @@ void ChestRenderer::render(std::shared_ptr _chest, double x, Tile* tile = chest->getTile(); data = chest->getData(); - if (tile != NULL && data == 0) { + if (dynamic_cast(tile) != NULL && data == 0) { ((ChestTile*)tile) ->recalcLockDir(chest->getLevel(), chest->x, chest->y, chest->z); @@ -45,10 +69,29 @@ void ChestRenderer::render(std::shared_ptr _chest, double x, ChestModel* model; if (chest->e.lock() != NULL || chest->s.lock() != NULL) { model = largeChestModel; - bindTexture(TN_TILE_LARGE_CHEST); // 4J Was "/item/largechest.png" + + if (chest->getType() == ChestTile::TYPE_TRAP) { + bindTexture(&CHEST_LARGE_TRAP_LOCATION); + } + // else if (xmasTextures) + //{ + // bindTexture(&CHEST_LARGE_XMAS_LOCATION); + // } + else { + bindTexture(&CHEST_LARGE_LOCATION); + } } else { model = chestModel; - bindTexture(TN_TILE_CHEST); // 4J Was "/item/chest.png" + if (chest->getType() == ChestTile::TYPE_TRAP) { + bindTexture(&CHEST_TRAP_LOCATION); + } + // else if (xmasTextures) + //{ + // bindTexture(&CHEST_XMAS_LOCATION); + // } + else { + bindTexture(&CHEST_LOCATION); + } } glPushMatrix(); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.h index 9fe5ba593..505346a5f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ChestRenderer.h @@ -1,13 +1,20 @@ #pragma once - #include "TileEntityRenderer.h" class ChestModel; class ChestRenderer : public TileEntityRenderer { private: + static ResourceLocation CHEST_LARGE_TRAP_LOCATION; + // static ResourceLocation CHEST_LARGE_XMAS_LOCATION; + static ResourceLocation CHEST_LARGE_LOCATION; + static ResourceLocation CHEST_TRAP_LOCATION; + // static ResourceLocation CHEST_XMAS_LOCATION; + static ResourceLocation CHEST_LOCATION; + ChestModel* chestModel; ChestModel* largeChestModel; + boolean xmasTextures; public: ChestRenderer(); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.cpp index dbc846b12..096ffd459 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.cpp @@ -3,6 +3,9 @@ #include "ChickenRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +ResourceLocation ChickenRenderer::CHICKEN_LOCATION = + ResourceLocation(TN_MOB_CHICKEN); + ChickenRenderer::ChickenRenderer(Model* model, float shadow) : MobRenderer(model, shadow) {} @@ -11,7 +14,7 @@ void ChickenRenderer::render(std::shared_ptr _mob, double x, double y, MobRenderer::render(_mob, x, y, z, rot, a); } -float ChickenRenderer::getBob(std::shared_ptr _mob, float a) { +float ChickenRenderer::getBob(std::shared_ptr _mob, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); @@ -20,4 +23,9 @@ float ChickenRenderer::getBob(std::shared_ptr _mob, float a) { float flapSpeed = mob->oFlapSpeed + (mob->flapSpeed - mob->oFlapSpeed) * a; return (Mth::sin(flap) + 1) * flapSpeed; +} + +ResourceLocation* ChickenRenderer::getTextureLocation( + std::shared_ptr mob) { + return &CHICKEN_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.h index 642c0ed00..a441a3067 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ChickenRenderer.h @@ -2,11 +2,15 @@ #include "MobRenderer.h" class ChickenRenderer : public MobRenderer { +private: + static ResourceLocation CHICKEN_LOCATION; + public: ChickenRenderer(Model* model, float shadow); virtual void render(std::shared_ptr _mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - virtual float getBob(std::shared_ptr _mob, float a); + virtual float getBob(std::shared_ptr _mob, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.cpp index 34206f879..7daee01cc 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.cpp @@ -1,10 +1,16 @@ #include "../../Platform/stdafx.h" #include "CowRenderer.h" +ResourceLocation CowRenderer::COW_LOCATION = ResourceLocation(TN_MOB_COW); + CowRenderer::CowRenderer(Model* model, float shadow) : MobRenderer(model, shadow) {} void CowRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { MobRenderer::render(_mob, x, y, z, rot, a); +} + +ResourceLocation* CowRenderer::getTextureLocation(std::shared_ptr mob) { + return &COW_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.h index 14b5b9230..4f932c980 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/CowRenderer.h @@ -2,8 +2,13 @@ #include "MobRenderer.h" class CowRenderer : public MobRenderer { +private: + static ResourceLocation COW_LOCATION; + public: CowRenderer(Model* model, float shadow); + virtual void render(std::shared_ptr _mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.cpp index c3ada0872..062344713 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.cpp @@ -4,11 +4,16 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "../../../Minecraft.World/Util/Mth.h" +ResourceLocation CreeperRenderer::POWER_LOCATION = + ResourceLocation(TN_POWERED_CREEPER); +ResourceLocation CreeperRenderer::CREEPER_LOCATION = + ResourceLocation(TN_MOB_CREEPER); + CreeperRenderer::CreeperRenderer() : MobRenderer(new CreeperModel(), 0.5f) { armorModel = new CreeperModel(2); } -void CreeperRenderer::scale(std::shared_ptr mob, float a) { +void CreeperRenderer::scale(std::shared_ptr mob, float a) { std::shared_ptr creeper = std::dynamic_pointer_cast(mob); float g = creeper->getSwelling(a); @@ -23,8 +28,8 @@ void CreeperRenderer::scale(std::shared_ptr mob, float a) { glScalef(s, hs, s); } -int CreeperRenderer::getOverlayColor(std::shared_ptr mob, float br, - float a) { +int CreeperRenderer::getOverlayColor(std::shared_ptr mob, + float br, float a) { std::shared_ptr creeper = std::dynamic_pointer_cast(mob); float step = creeper->getSwelling(a); @@ -44,7 +49,7 @@ int CreeperRenderer::getOverlayColor(std::shared_ptr mob, float br, return (_a << 24) | (r << 16) | (g << 8) | b; } -int CreeperRenderer::prepareArmor(std::shared_ptr _mob, int layer, +int CreeperRenderer::prepareArmor(std::shared_ptr _mob, int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version @@ -57,7 +62,7 @@ int CreeperRenderer::prepareArmor(std::shared_ptr _mob, int layer, if (layer == 1) { float time = mob->tickCount + a; - bindTexture(TN_POWERED_CREEPER); // was L"/armor/power.png"); + bindTexture(&POWER_LOCATION); glMatrixMode(GL_TEXTURE); glLoadIdentity(); float uo = time * 0.01f; @@ -83,7 +88,12 @@ int CreeperRenderer::prepareArmor(std::shared_ptr _mob, int layer, return -1; } -int CreeperRenderer::prepareArmorOverlay(std::shared_ptr mob, int layer, - float a) { +int CreeperRenderer::prepareArmorOverlay(std::shared_ptr mob, + int layer, float a) { return -1; +} + +ResourceLocation* CreeperRenderer::getTextureLocation( + std::shared_ptr mob) { + return &CREEPER_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.h index 75b34d344..05651815b 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/CreeperRenderer.h @@ -3,15 +3,20 @@ class CreeperRenderer : public MobRenderer { private: + static ResourceLocation POWER_LOCATION; + static ResourceLocation CREEPER_LOCATION; Model* armorModel; public: CreeperRenderer(); protected: - virtual void scale(std::shared_ptr _mob, float a); - virtual int getOverlayColor(std::shared_ptr mob, float br, float a); - virtual int prepareArmor(std::shared_ptr mob, int layer, float a); - virtual int prepareArmorOverlay(std::shared_ptr _mob, int layer, - float a); + virtual void scale(std::shared_ptr _mob, float a); + virtual int getOverlayColor(std::shared_ptr mob, float br, + float a); + virtual int prepareArmor(std::shared_ptr mob, int layer, + float a); + virtual int prepareArmorOverlay(std::shared_ptr _mob, + int layer, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/DefaultRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/DefaultRenderer.h index 6811a800d..bcf5b42a8 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/DefaultRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/DefaultRenderer.h @@ -5,4 +5,7 @@ class DefaultRenderer : public EntityRenderer { public: virtual void render(std::shared_ptr entity, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob) { + return NULL; + }; }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.cpp index b7a66b504..2c416d899 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.cpp @@ -4,6 +4,9 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "EnchantTableRenderer.h" +ResourceLocation EnchantTableRenderer::BOOK_LOCATION = + ResourceLocation(TN_ITEM_BOOK); + EnchantTableRenderer::EnchantTableRenderer() { bookModel = new BookModel(); } EnchantTableRenderer::~EnchantTableRenderer() { delete bookModel; } @@ -38,7 +41,7 @@ void EnchantTableRenderer::render(std::shared_ptr _table, double x, glRotatef(-yRot * 180 / PI, 0, 1, 0); glRotatef(80, 0, 0, 1); - bindTexture(TN_ITEM_BOOK); // 4J was "/item/book.png" + bindTexture(&BOOK_LOCATION); // 4J was "/item/book.png" float ff1 = table->oFlip + (table->flip - table->oFlip) * a + 0.25f; float ff2 = table->oFlip + (table->flip - table->oFlip) * a + 0.75f; @@ -51,6 +54,7 @@ void EnchantTableRenderer::render(std::shared_ptr _table, double x, if (ff2 > 1) ff2 = 1; float o = table->oOpen + (table->open - table->oOpen) * a; + glEnable(GL_CULL_FACE); bookModel->render(nullptr, tt, ff1, ff2, o, 0, 1 / 16.0f, true); glPopMatrix(); } diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.h index fa7de9dcf..5bf2487fd 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EnchantTableRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "TileEntityRenderer.h" class BookModel; @@ -9,6 +8,8 @@ class EnchantTableRenderer : public TileEntityRenderer { friend class UIControl_EnchantmentBook; private: + static ResourceLocation BOOK_LOCATION; + BookModel* bookModel; public: diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.cpp index 876c48d2e..d27799560 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.cpp @@ -3,6 +3,9 @@ #include "../Models/ModelPart.h" #include "EnderChestRenderer.h" +ResourceLocation EnderChestRenderer::ENDER_CHEST_LOCATION = + ResourceLocation(TN_TILE_ENDER_CHEST); + void EnderChestRenderer::render(std::shared_ptr _chest, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled) { @@ -16,7 +19,7 @@ void EnderChestRenderer::render(std::shared_ptr _chest, double x, data = chest->getData(); } - bindTexture(TN_TILE_ENDER_CHEST); //"/item/enderchest.png"); + bindTexture(&ENDER_CHEST_LOCATION); glPushMatrix(); glEnable(GL_RESCALE_NORMAL); @@ -32,12 +35,6 @@ void EnderChestRenderer::render(std::shared_ptr _chest, double x, if (data == 4) rot = 90; if (data == 5) rot = -90; - // if (data == 2) { - // glTranslatef(1, 0, 0); - // } - // if (data == 5) { - // glTranslatef(0, 0, -1); - // } glRotatef(rot, 0, 1, 0); glTranslatef(-0.5f, -0.5f, -0.5f); diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.h index b6df8e638..afa310b3a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderChestRenderer.h @@ -1,10 +1,10 @@ #pragma once - #include "TileEntityRenderer.h" #include "../Models/ChestModel.h" class EnderChestRenderer : public TileEntityRenderer { private: + static ResourceLocation ENDER_CHEST_LOCATION; ChestModel chestModel; public: diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.cpp index fb9dad13c..bdb9b17f0 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.cpp @@ -3,6 +3,9 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.boss.enderdragon.h" #include "EnderCrystalRenderer.h" +ResourceLocation EnderCrystalRenderer::ENDER_CRYSTAL_LOCATION = + ResourceLocation(TN_MOB_ENDERDRAGON_ENDERCRYSTAL); + EnderCrystalRenderer::EnderCrystalRenderer() { currentModel = -1; this->shadowRadius = 0.5f; @@ -11,8 +14,8 @@ EnderCrystalRenderer::EnderCrystalRenderer() { void EnderCrystalRenderer::render(std::shared_ptr _crystal, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type EnderCrystal rather than std::shared_ptr we have here - do - // some casting around instead + // type EnderCrystal rather than shared_ptr we have here - do some + // casting around instead std::shared_ptr crystal = std::dynamic_pointer_cast(_crystal); if (currentModel != EnderCrystalModel::MODEL_ID) { @@ -23,12 +26,15 @@ void EnderCrystalRenderer::render(std::shared_ptr _crystal, double x, float tt = crystal->time + a; glPushMatrix(); glTranslatef((float)x, (float)y, (float)z); - bindTexture( - TN_MOB_ENDERDRAGON_ENDERCRYSTAL); // 4J was - // "/mob/enderdragon/crystal.png" + bindTexture(&ENDER_CRYSTAL_LOCATION); float hh = sin(tt * 0.2f) / 2 + 0.5f; hh = hh * hh + hh; model->render(crystal, 0, tt * 3, hh * 0.2f, 0, 0, 1 / 16.0f, true); glPopMatrix(); +} + +ResourceLocation* EnderCrystalRenderer::getTextureLocation( + std::shared_ptr mob) { + return &ENDER_CRYSTAL_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.h index caa764121..bbca58ad2 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderCrystalRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "EntityRenderer.h" class Model; @@ -8,10 +7,12 @@ class EnderCrystalRenderer : public EntityRenderer { private: int currentModel; Model* model; + static ResourceLocation ENDER_CRYSTAL_LOCATION; public: EnderCrystalRenderer(); virtual void render(std::shared_ptr _crystal, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.cpp index 09a6e1d0e..fb42045de 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.cpp @@ -4,19 +4,25 @@ #include "../Tesselator.h" #include "../Lighting.h" #include "EnderDragonRenderer.h" +#include "../../UI/BossMobGuiInfo.h" -std::shared_ptr EnderDragonRenderer::bossInstance; -int EnderDragonRenderer::currentModel; +ResourceLocation EnderDragonRenderer::DRAGON_EXPLODING_LOCATION = + ResourceLocation(TN_MOB_ENDERDRAGON_SHUFFLE); +ResourceLocation EnderDragonRenderer::CRYSTAL_BEAM_LOCATION = + ResourceLocation(TN_MOB_ENDERDRAGON_BEAM); +ResourceLocation EnderDragonRenderer::DRAGON_EYES_LOCATION = + ResourceLocation(TN_MOB_ENDERDRAGON_ENDEREYES); +ResourceLocation EnderDragonRenderer::DRAGON_LOCATION = + ResourceLocation(TN_MOB_ENDERDRAGON); EnderDragonRenderer::EnderDragonRenderer() : MobRenderer(new DragonModel(0), 0.5f) { - currentModel = 0; dragonModel = (DragonModel*)model; - this->setArmor(model); + setArmor(model); // TODO: Make second constructor that assigns this. } -void EnderDragonRenderer::setupRotations(std::shared_ptr _mob, float bob, - float bodyRot, float a) { +void EnderDragonRenderer::setupRotations(std::shared_ptr _mob, + float bob, float bodyRot, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = @@ -47,8 +53,8 @@ void EnderDragonRenderer::setupRotations(std::shared_ptr _mob, float bob, } } -void EnderDragonRenderer::renderModel(std::shared_ptr _mob, float wp, - float ws, float bob, +void EnderDragonRenderer::renderModel(std::shared_ptr _mob, + float wp, float ws, float bob, float headRotMinusBodyRot, float headRotx, float scale) { // 4J - dynamic cast required because we aren't using templates/generics in @@ -62,8 +68,7 @@ void EnderDragonRenderer::renderModel(std::shared_ptr _mob, float wp, glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, tt); bindTexture( - mob->customTextureUrl, - TN_MOB_ENDERDRAGON_SHUFFLE); // 4J was + &DRAGON_EXPLODING_LOCATION); // 4J was // "/mob/enderdragon/shuffle.png" model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); @@ -72,7 +77,7 @@ void EnderDragonRenderer::renderModel(std::shared_ptr _mob, float wp, glDepthFunc(GL_EQUAL); } - bindTexture(mob->customTextureUrl, mob->getTexture()); + bindTexture(mob); model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true); if (mob->hurtTime > 0) { @@ -103,11 +108,7 @@ void EnderDragonRenderer::render(std::shared_ptr _mob, double x, // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); - EnderDragonRenderer::bossInstance = mob; - if (currentModel != DragonModel::MODEL_ID) { - model = new DragonModel(0); - currentModel = DragonModel::MODEL_ID; - } + BossMobGuiInfo::setBossHealth(mob, false); MobRenderer::render(mob, x, y, z, rot, a); if (mob->nearestCrystal != NULL) { float tt = mob->nearestCrystal->time + a; @@ -150,7 +151,7 @@ void EnderDragonRenderer::render(std::shared_ptr _mob, double x, glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); bindTexture( - TN_MOB_ENDERDRAGON_BEAM); // 4J was "/mob/enderdragon/beam.png" + &CRYSTAL_BEAM_LOCATION); // 4J was "/mob/enderdragon/beam.png" glShadeModel(GL_SMOOTH); @@ -184,8 +185,13 @@ void EnderDragonRenderer::render(std::shared_ptr _mob, double x, } } -void EnderDragonRenderer::additionalRendering(std::shared_ptr _mob, - float a) { +ResourceLocation* EnderDragonRenderer::getTextureLocation( + std::shared_ptr mob) { + return &DRAGON_LOCATION; +} + +void EnderDragonRenderer::additionalRendering( + std::shared_ptr _mob, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = @@ -242,8 +248,8 @@ void EnderDragonRenderer::additionalRendering(std::shared_ptr _mob, } } -int EnderDragonRenderer::prepareArmor(std::shared_ptr _mob, int layer, - float a) { +int EnderDragonRenderer::prepareArmor(std::shared_ptr _mob, + int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = @@ -255,8 +261,7 @@ int EnderDragonRenderer::prepareArmor(std::shared_ptr _mob, int layer, if (layer != 0) return -1; bindTexture( - TN_MOB_ENDERDRAGON_ENDEREYES); // 4J was - // "/mob/enderdragon/ender_eyes.png" + &DRAGON_EYES_LOCATION); // 4J was "/mob/enderdragon/ender_eyes.png" float br = 1; glEnable(GL_BLEND); // 4J Stu - We probably don't need to do this on 360 either (as we force it diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.h index 25659a509..4377bd158 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderDragonRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "MobRenderer.h" #ifdef _XBOX @@ -8,11 +7,11 @@ class EnderDragon; class DragonModel; class EnderDragonRenderer : public MobRenderer { -public: - static std::shared_ptr bossInstance; - private: - static int currentModel; + static ResourceLocation DRAGON_EXPLODING_LOCATION; + static ResourceLocation CRYSTAL_BEAM_LOCATION; + static ResourceLocation DRAGON_EYES_LOCATION; + static ResourceLocation DRAGON_LOCATION; protected: DragonModel* dragonModel; @@ -21,19 +20,20 @@ public: EnderDragonRenderer(); protected: - virtual void setupRotations(std::shared_ptr _mob, float bob, + virtual void setupRotations(std::shared_ptr _mob, float bob, float bodyRot, float a); - -protected: - void renderModel(std::shared_ptr _mob, float wp, float ws, - float bob, float headRotMinusBodyRot, float headRotx, - float scale); + virtual void renderModel(std::shared_ptr _mob, float wp, + float ws, float bob, float headRotMinusBodyRot, + float headRotx, float scale); public: virtual void render(std::shared_ptr _mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - virtual void additionalRendering(std::shared_ptr _mob, float a); - virtual int prepareArmor(std::shared_ptr _mob, int layer, float a); + virtual void additionalRendering(std::shared_ptr _mob, + float a); + virtual int prepareArmor(std::shared_ptr _mob, int layer, + float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.cpp index 14f7420e2..351181f16 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.cpp @@ -1,9 +1,15 @@ #include "../../Platform/stdafx.h" #include "EnderManRenderer.h" #include "../Models/EnderManModel.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" +ResourceLocation EndermanRenderer::ENDERMAN_EYES_LOCATION = + ResourceLocation(TN_MOB_ENDERMAN_EYES); +ResourceLocation EndermanRenderer::ENDERMAN_LOCATION = + ResourceLocation(TN_MOB_ENDERMAN); + EndermanRenderer::EndermanRenderer() : MobRenderer(new EndermanModel(), 0.5f) { model = (EndermanModel*)MobRenderer::model; this->setArmor(model); @@ -12,8 +18,8 @@ EndermanRenderer::EndermanRenderer() : MobRenderer(new EndermanModel(), 0.5f) { void EndermanRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type Boat rather than std::shared_ptr we have here - do some - // casting around instead + // type Boat rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); model->carrying = mob->getCarryingTile() > 0; @@ -28,10 +34,16 @@ void EndermanRenderer::render(std::shared_ptr _mob, double x, double y, MobRenderer::render(mob, x, y, z, rot, a); } -void EndermanRenderer::additionalRendering(std::shared_ptr _mob, float a) { +ResourceLocation* EndermanRenderer::getTextureLocation( + std::shared_ptr mob) { + return &ENDERMAN_LOCATION; +} + +void EndermanRenderer::additionalRendering(std::shared_ptr _mob, + float a) { // 4J - original version used generics and thus had an input parameter of - // type Boat rather than std::shared_ptr we have here - do some - // casting around instead + // type Boat rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::additionalRendering(_mob, a); @@ -45,7 +57,7 @@ void EndermanRenderer::additionalRendering(std::shared_ptr _mob, float a) { s *= 1.00f; glRotatef(20, 1, 0, 0); glRotatef(45, 0, 1, 0); - glScalef(s, -s, s); + glScalef(-s, -s, s); if (SharedConstants::TEXTURE_LIGHTING) { int col = mob->getLightColor(a); @@ -57,7 +69,7 @@ void EndermanRenderer::additionalRendering(std::shared_ptr _mob, float a) { } glColor4f(1, 1, 1, 1); - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + bindTexture(&TextureAtlas::LOCATION_BLOCKS); // TODO: bind by icon tileRenderer->renderTile(Tile::tiles[mob->getCarryingTile()], mob->getCarryingData(), 1); glPopMatrix(); @@ -65,16 +77,16 @@ void EndermanRenderer::additionalRendering(std::shared_ptr _mob, float a) { } } -int EndermanRenderer::prepareArmor(std::shared_ptr _mob, int layer, - float a) { +int EndermanRenderer::prepareArmor(std::shared_ptr _mob, + int layer, float a) { // 4J - original version used generics and thus had an input parameter of - // type Boat rather than std::shared_ptr we have here - do some - // casting around instead + // type Boat rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); if (layer != 0) return -1; - bindTexture(TN_MOB_ENDERMAN_EYES); // 4J was L"/mob/enderman_eyes.png" + bindTexture(&ENDERMAN_EYES_LOCATION); // 4J was L"/mob/enderman_eyes.png" float br = 1; glEnable(GL_BLEND); // 4J Stu - We probably don't need to do this on 360 either (as we force it @@ -87,10 +99,11 @@ int EndermanRenderer::prepareArmor(std::shared_ptr _mob, int layer, glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_LIGHTING); - if (mob->isInvisible()) + if (mob->isInvisible()) { glDepthMask(false); - else + } else { glDepthMask(true); + } if (SharedConstants::TEXTURE_LIGHTING) { int col = 0xf0f0; diff --git a/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.h index 1c1693cc1..408669205 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EnderManRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "MobRenderer.h" class EnderMan; @@ -9,14 +8,17 @@ class EndermanRenderer : public MobRenderer { private: EndermanModel* model; Random random; + static ResourceLocation ENDERMAN_EYES_LOCATION; + static ResourceLocation ENDERMAN_LOCATION; public: EndermanRenderer(); - virtual void render(std::shared_ptr _mob, double x, double y, - double z, float rot, float a); - virtual void additionalRendering(std::shared_ptr _mob, float a); + void render(std::shared_ptr _mob, double x, double y, double z, + float rot, float a); + ResourceLocation* getTextureLocation(std::shared_ptr mob); + void additionalRendering(std::shared_ptr _mob, float a); protected: - virtual int prepareArmor(std::shared_ptr _mob, int layer, float a); + int prepareArmor(std::shared_ptr _mob, int layer, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.cpp b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.cpp index 4e59b19d3..264e80488 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.cpp @@ -50,6 +50,14 @@ #include "EnderDragonRenderer.h" #include "EnderCrystalRenderer.h" #include "BlazeRenderer.h" +#include "SkeletonRenderer.h" +#include "WitchRenderer.h" +#include "WitherBossRenderer.h" +#include "LeashKnotRenderer.h" +#include "WitherSkullRenderer.h" +#include "TntMinecartRenderer.h" +#include "MinecartSpawnerRenderer.h" +#include "HorseRenderer.h" #include "../Models/SpiderModel.h" #include "../Models/PigModel.h" #include "../Models/SheepModel.h" @@ -65,12 +73,15 @@ #include "../Models/HumanoidModel.h" #include "../Models/SheepFurModel.h" #include "../Models/SkeletonModel.h" +#include "../Models/ModelHorse.h" #include "../../GameState/Options.h" #include "ItemFrameRenderer.h" #include "OcelotRenderer.h" #include "VillagerGolemRenderer.h" #include "../Models/OcelotModel.h" #include "ZombieRenderer.h" +#include "BatRenderer.h" +#include "CaveSpiderRenderer.h" double EntityRenderDispatcher::xOff = 0.0; double EntityRenderDispatcher::yOff = 0.0; @@ -85,7 +96,7 @@ void EntityRenderDispatcher::staticCtor() { EntityRenderDispatcher::EntityRenderDispatcher() { glEnable(GL_LIGHTING); renderers[eTYPE_SPIDER] = new SpiderRenderer(); - renderers[eTYPE_CAVESPIDER] = new SpiderRenderer(); + renderers[eTYPE_CAVESPIDER] = new CaveSpiderRenderer(); renderers[eTYPE_PIG] = new PigRenderer(new PigModel(), new PigModel(0.5f), 0.7f); renderers[eTYPE_SHEEP] = @@ -96,17 +107,16 @@ EntityRenderDispatcher::EntityRenderDispatcher() { renderers[eTYPE_WOLF] = new WolfRenderer(new WolfModel(), new WolfModel(), 0.5f); renderers[eTYPE_CHICKEN] = new ChickenRenderer(new ChickenModel(), 0.3f); - renderers[eTYPE_OZELOT] = new OzelotRenderer(new OzelotModel(), 0.4f); + renderers[eTYPE_OCELOT] = new OcelotRenderer(new OcelotModel(), 0.4f); renderers[eTYPE_SILVERFISH] = new SilverfishRenderer(); renderers[eTYPE_CREEPER] = new CreeperRenderer(); renderers[eTYPE_ENDERMAN] = new EndermanRenderer(); renderers[eTYPE_SNOWMAN] = new SnowManRenderer(); - renderers[eTYPE_SKELETON] = - new HumanoidMobRenderer(new SkeletonModel(), 0.5f); + renderers[eTYPE_SKELETON] = new SkeletonRenderer(); + renderers[eTYPE_WITCH] = new WitchRenderer(); renderers[eTYPE_BLAZE] = new BlazeRenderer(); renderers[eTYPE_ZOMBIE] = new ZombieRenderer(); - renderers[eTYPE_PIGZOMBIE] = - new HumanoidMobRenderer(new ZombieModel(), 0.5f); + renderers[eTYPE_PIGZOMBIE] = new ZombieRenderer(); renderers[eTYPE_SLIME] = new SlimeRenderer(new SlimeModel(16), new SlimeModel(0), 0.25f); renderers[eTYPE_LAVASLIME] = new LavaSlimeRenderer(); @@ -116,12 +126,19 @@ EntityRenderDispatcher::EntityRenderDispatcher() { renderers[eTYPE_SQUID] = new SquidRenderer(new SquidModel(), 0.7f); renderers[eTYPE_VILLAGER] = new VillagerRenderer(); renderers[eTYPE_VILLAGERGOLEM] = new VillagerGolemRenderer(); + renderers[eTYPE_BAT] = new BatRenderer(); + renderers[eTYPE_MOB] = new MobRenderer(new HumanoidModel(), 0.5f); + renderers[eTYPE_ENDERDRAGON] = new EnderDragonRenderer(); renderers[eTYPE_ENDER_CRYSTAL] = new EnderCrystalRenderer(); + + renderers[eTYPE_WITHERBOSS] = new WitherBossRenderer(); + renderers[eTYPE_ENTITY] = new DefaultRenderer(); renderers[eTYPE_PAINTING] = new PaintingRenderer(); renderers[eTYPE_ITEM_FRAME] = new ItemFrameRenderer(); + renderers[eTYPE_LEASHFENCEKNOT] = new LeashKnotRenderer(); renderers[eTYPE_ARROW] = new ArrowRenderer(); renderers[eTYPE_SNOWBALL] = new ItemSpriteRenderer(Item::snowBall); renderers[eTYPE_THROWNENDERPEARL] = @@ -132,19 +149,31 @@ EntityRenderDispatcher::EntityRenderDispatcher() { renderers[eTYPE_THROWNPOTION] = new ItemSpriteRenderer(Item::potion, PotionBrewing::THROWABLE_MASK); renderers[eTYPE_THROWNEXPBOTTLE] = new ItemSpriteRenderer(Item::expBottle); - renderers[eTYPE_FIREBALL] = new FireballRenderer(2.0f); + renderers[eTYPE_FIREWORKS_ROCKET] = new ItemSpriteRenderer(Item::fireworks); + renderers[eTYPE_LARGE_FIREBALL] = new FireballRenderer(2.0f); renderers[eTYPE_SMALL_FIREBALL] = new FireballRenderer(0.5f); renderers[eTYPE_DRAGON_FIREBALL] = new FireballRenderer(2.0f); // 4J Added TU9 + renderers[eTYPE_WITHER_SKULL] = new WitherSkullRenderer(); renderers[eTYPE_ITEMENTITY] = new ItemRenderer(); renderers[eTYPE_EXPERIENCEORB] = new ExperienceOrbRenderer(); renderers[eTYPE_PRIMEDTNT] = new TntRenderer(); renderers[eTYPE_FALLINGTILE] = new FallingTileRenderer(); - renderers[eTYPE_MINECART] = new MinecartRenderer(); + + renderers[eTYPE_MINECART_TNT] = new TntMinecartRenderer(); + renderers[eTYPE_MINECART_SPAWNER] = new MinecartSpawnerRenderer(); + renderers[eTYPE_MINECART_RIDEABLE] = new MinecartRenderer(); + + renderers[eTYPE_MINECART_FURNACE] = new MinecartRenderer(); + renderers[eTYPE_MINECART_CHEST] = new MinecartRenderer(); + renderers[eTYPE_MINECART_HOPPER] = new MinecartRenderer(); + renderers[eTYPE_BOAT] = new BoatRenderer(); renderers[eTYPE_FISHINGHOOK] = new FishingHookRenderer(); + + renderers[eTYPE_HORSE] = new HorseRenderer(new ModelHorse(), .75f); + renderers[eTYPE_LIGHTNINGBOLT] = new LightningBoltRenderer(); - renderers[eTYPE_ARROW] = new ArrowRenderer(); glDisable(GL_LIGHTING); AUTO_VAR(itEnd, renderers.end()); @@ -157,23 +186,25 @@ EntityRenderDispatcher::EntityRenderDispatcher() { } EntityRenderer* EntityRenderDispatcher::getRenderer(eINSTANCEOF e) { + if ((e & eTYPE_PLAYER) == eTYPE_PLAYER) e = eTYPE_PLAYER; // EntityRenderer * r = renderers[e]; AUTO_VAR(it, renderers.find(e)); // 4J Stu - The .at and [] accessors // insert elements if they don't exist if (it == renderers.end()) { + app.DebugPrintf("Couldn't find renderer for entity of type %d\n", e); // New renderer mapping required in above table __debugbreak(); } /* 4J - not doing this hierarchical search anymore. We need to explicitly -add renderers for any eINSTANCEOF type that we want to be able to render if (it -== renderers.end() && e != Entity::_class) + add renderers for any eINSTANCEOF type that we want to be able to render if + (it == renderers.end() && e != Entity::_class) { EntityRenderer *r = getRenderer(dynamic_cast( -e->getSuperclass() )); renderers.insert( classToRendererMap::value_type( e, r ) -); return r; - //assert(false); -}*/ + e->getSuperclass() )); renderers.insert( classToRendererMap::value_type( e, + r ) ); return r; + //assert(false); + }*/ return it->second; } @@ -181,14 +212,16 @@ EntityRenderer* EntityRenderDispatcher::getRenderer(std::shared_ptr e) { return getRenderer(e->GetType()); } -void EntityRenderDispatcher::prepare(Level* level, Textures* textures, - Font* font, std::shared_ptr player, - Options* options, float a) { +void EntityRenderDispatcher::prepare( + Level* level, Textures* textures, Font* font, + std::shared_ptr player, + std::shared_ptr crosshairPickMob, Options* options, float a) { this->level = level; this->textures = textures; this->options = options; this->cameraEntity = player; this->font = font; + this->crosshairPickMob = crosshairPickMob; if (player->isSleeping()) { int t = level->getTile(Mth::floor(player->x), Mth::floor(player->y), @@ -275,4 +308,61 @@ void EntityRenderDispatcher::registerTerrainTextures( EntityRenderer* renderer = it->second; renderer->registerTerrainTextures(iconRegister); } +} + +void EntityRenderDispatcher::renderHitbox(std::shared_ptr entity, + double x, double y, double z, + float rot, float a) { + glDepthMask(false); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + + glPushMatrix(); + Tesselator* t = Tesselator::getInstance(); + + t->begin(); + t->color(255, 255, 255, 32); + + double wnx = -entity->bbWidth / 2; + double wnz = -entity->bbWidth / 2; + double enx = entity->bbWidth / 2; + double enz = -entity->bbWidth / 2; + + double wsx = -entity->bbWidth / 2; + double wsz = entity->bbWidth / 2; + double esx = entity->bbWidth / 2; + double esz = entity->bbWidth / 2; + + double top = entity->bbHeight; + + t->vertex(x + wnx, y + top, z + wnz); + t->vertex(x + wnx, y, z + wnz); + t->vertex(x + enx, y, z + enz); + t->vertex(x + enx, y + top, z + enz); + + t->vertex(x + esx, y + top, z + esz); + t->vertex(x + esx, y, z + esz); + t->vertex(x + wsx, y, z + wsz); + t->vertex(x + wsx, y + top, z + wsz); + + t->vertex(x + enx, y + top, z + enz); + t->vertex(x + enx, y, z + enz); + t->vertex(x + esx, y, z + esz); + t->vertex(x + esx, y + top, z + esz); + + t->vertex(x + wsx, y + top, z + wsz); + t->vertex(x + wsx, y, z + wsz); + t->vertex(x + wnx, y, z + wnz); + t->vertex(x + wnx, y + top, z + wnz); + + t->end(); + glPopMatrix(); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDepthMask(true); } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h index 4e6b50a31..11d8a1709 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h @@ -15,7 +15,7 @@ private: // 4J - was: // Map, EntityRenderer> renderers //= new HashMap, EntityRenderer>(); + // Entity>>(); public: static EntityRenderDispatcher* instance; @@ -29,7 +29,8 @@ public: Textures* textures; ItemInHandRenderer* itemInHandRenderer; Level* level; - std::shared_ptr cameraEntity; + std::shared_ptr cameraEntity; + std::shared_ptr crosshairPickMob; float playerRotY; float playerRotX; Options* options; @@ -44,7 +45,9 @@ public: EntityRenderer* getRenderer(eINSTANCEOF e); EntityRenderer* getRenderer(std::shared_ptr e); void prepare(Level* level, Textures* textures, Font* font, - std::shared_ptr player, Options* options, float a); + std::shared_ptr player, + std::shared_ptr crosshairPickMob, + Options* options, float a); void render(std::shared_ptr entity, float a); void render(std::shared_ptr entity, double x, double y, double z, float rot, float a, bool bItemFrame = false, @@ -53,4 +56,8 @@ public: double distanceToSqr(double x, double y, double z); Font* getFont(); void registerTerrainTextures(IconRegister* iconRegister); + +private: + void renderHitbox(std::shared_ptr entity, double x, double y, + double z, float rot, float a); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp index 485254d0a..9b4d7bda3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp @@ -1,16 +1,20 @@ #include "../../Platform/stdafx.h" #include "EntityRenderer.h" -#include "../Models/HumanoidModel.h" #include "EntityRenderDispatcher.h" +#include "../Models/HumanoidModel.h" +#include "../../Player/LocalPlayer.h" #include "../../GameState/Options.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.h" -#include "../../../Minecraft.World/Entities/Entity.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.h" #include "../../../Minecraft.World/Level/Level.h" #include "../../../Minecraft.World/Util/AABB.h" #include "../../../Minecraft.World/Util/Mth.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" -#include "../../Player/LocalPlayer.h" + +ResourceLocation EntityRenderer::SHADOW_LOCATION = + ResourceLocation(TN__CLAMP__MISC_SHADOW); // 4J - added EntityRenderer::EntityRenderer() { @@ -22,12 +26,12 @@ EntityRenderer::EntityRenderer() { EntityRenderer::~EntityRenderer() { delete tileRenderer; } -void EntityRenderer::bindTexture(int resourceName) { - entityRenderDispatcher->textures->bindTexture(resourceName); +void EntityRenderer::bindTexture(std::shared_ptr entity) { + bindTexture(getTextureLocation(entity)); } -void EntityRenderer::bindTexture(const std::wstring& resourceName) { - entityRenderDispatcher->textures->bindTexture(resourceName); +void EntityRenderer::bindTexture(ResourceLocation* location) { + entityRenderDispatcher->textures->bindTexture(location); } bool EntityRenderer::bindTexture(const std::wstring& urlTexture, @@ -79,7 +83,7 @@ void EntityRenderer::renderFlame(std::shared_ptr e, double x, double y, float s = e->bbWidth * 1.4f; glScalef(s, s, s); MemSect(31); - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + bindTexture(&TextureAtlas::LOCATION_BLOCKS); MemSect(0); Tesselator* t = Tesselator::getInstance(); @@ -139,33 +143,24 @@ void EntityRenderer::renderShadow(std::shared_ptr e, double x, double y, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); MemSect(31); - entityRenderDispatcher->textures->bindTexture( - TN__CLAMP__MISC_SHADOW); // L"%clamp%/misc/shadow.png")); + entityRenderDispatcher->textures->bindTexture(&SHADOW_LOCATION); MemSect(0); Level* level = getLevel(); glDepthMask(false); float r = shadowRadius; - std::shared_ptr mob = std::dynamic_pointer_cast(e); - bool isLocalPlayer = false; float fYLocalPlayerShadowOffset = 0.0f; - // if (std::dynamic_pointer_cast(e) != NULL) - if (mob != NULL) { - // std::shared_ptr mob = std::dynamic_pointer_cast(e); + if (e->instanceof(eTYPE_MOB)) { + std::shared_ptr mob = std::dynamic_pointer_cast(e); r *= mob->getSizeScale(); - std::shared_ptr animal = std::dynamic_pointer_cast(mob); - if (animal != NULL) { - if (animal->isBaby()) { + if (mob->instanceof(eTYPE_ANIMAL)) { + if (std::dynamic_pointer_cast(mob)->isBaby()) { r *= 0.5f; } } - - if (std::dynamic_pointer_cast(mob) != NULL) { - isLocalPlayer = true; - } } double ex = e->xOld + (e->x - e->xOld) * a; @@ -174,7 +169,7 @@ void EntityRenderer::renderShadow(std::shared_ptr e, double x, double y, // 4J-PB - local players seem to have a position at their head, and remote // players have a foot position. get the shadow to render by changing the // check here depending on the player type - if (isLocalPlayer) { + if (e->instanceof(eTYPE_LOCALPLAYER)) { ey -= 1.62; fYLocalPlayerShadowOffset = -1.62f; } @@ -394,4 +389,9 @@ void EntityRenderer::postRender(std::shared_ptr entity, double x, Font* EntityRenderer::getFont() { return entityRenderDispatcher->getFont(); } -void EntityRenderer::registerTerrainTextures(IconRegister* iconRegister) {} \ No newline at end of file +void EntityRenderer::registerTerrainTextures(IconRegister* iconRegister) {} + +ResourceLocation* EntityRenderer::getTextureLocation( + std::shared_ptr mob) { + return NULL; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.h index 21a7969ce..f25cdd880 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.h @@ -1,15 +1,17 @@ #pragma once - #include "../Models/Model.h" #include "TileRenderer.h" #include "../Tesselator.h" #include "../../Textures/Textures.h" #include "ItemInHandRenderer.h" +#include "../../Textures/ResourceLocation.h" + class Tile; class Entity; class Level; class AABB; class IconRegister; +class ResourceLocation; class EntityRenderDispatcher; class Font; @@ -22,8 +24,12 @@ protected: EntityRenderDispatcher* entityRenderDispatcher; private: - Model* model; // 4J - TODO - check why exactly this is here, it seems to - // get shadowed by classes inheriting from this by their own + static ResourceLocation SHADOW_LOCATION; + +protected: + Model* model; // TODO 4J: Check why exactly this is here, it seems to get + // shadowed by classes inheriting from this by their own + protected: TileRenderer* tileRenderer; // 4J - changed to protected so derived classes // can use instead of shadowing their own @@ -41,14 +47,14 @@ public: double z, float rot, float a) = 0; protected: - virtual void bindTexture(int resourceName); // 4J - added - virtual void bindTexture(const std::wstring& resourceName); - - virtual bool bindTexture(const std::wstring& urlTexture, - int backupTexture); // 4J added + virtual void bindTexture(std::shared_ptr entity); + virtual void bindTexture(ResourceLocation* location); + virtual bool bindTexture(const std::wstring& urlTexture, int backupTexture); virtual bool bindTexture(const std::wstring& urlTexture, const std::wstring& backupTexture); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); + private: virtual void renderFlame(std::shared_ptr e, double x, double y, double z, float a); diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.cpp index 0d6423815..cf4a3d687 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.cpp @@ -1,12 +1,15 @@ #include "../../Platform/stdafx.h" #include "EntityTileRenderer.h" #include "TileEntityRenderDispatcher.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" EntityTileRenderer* EntityTileRenderer::instance = new EntityTileRenderer; EntityTileRenderer::EntityTileRenderer() { chest = std::shared_ptr(new ChestTileEntity()); + trappedChest = std::shared_ptr( + new ChestTileEntity(ChestTile::TYPE_TRAP)); enderChest = std::shared_ptr(new EnderChestTileEntity()); } @@ -16,6 +19,9 @@ void EntityTileRenderer::render(Tile* tile, int data, float brightness, if (tile->id == Tile::enderChest_Id) { TileEntityRenderDispatcher::instance->render( enderChest, 0, 0, 0, 0, setColor, alpha, useCompiled); + } else if (tile->id == Tile::chest_trap_Id) { + TileEntityRenderDispatcher::instance->render( + trappedChest, 0, 0, 0, 0, setColor, alpha, useCompiled); } else { TileEntityRenderDispatcher::instance->render( chest, 0, 0, 0, 0, setColor, alpha, useCompiled); diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.h index a9d5ab6e1..e7cfb7112 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityTileRenderer.h @@ -10,6 +10,7 @@ public: private: std::shared_ptr chest; + std::shared_ptr trappedChest; std::shared_ptr enderChest; public: diff --git a/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.cpp index a5e767353..b7f40a6e6 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.cpp @@ -8,13 +8,12 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "../../../Minecraft.World/Util/JavaMath.h" -ExperienceOrbRenderer::ExperienceOrbRenderer() { - // 4J In class Java initialisors - tileRenderer = new TileRenderer(); - setColor = true; +ResourceLocation ExperienceOrbRenderer::XP_ORB_LOCATION = + ResourceLocation(TN_ITEM_EXPERIENCE_ORB); - this->shadowRadius = 0.15f; - this->shadowStrength = 0.75f; +ExperienceOrbRenderer::ExperienceOrbRenderer() { + shadowRadius = 0.15f; + shadowStrength = 0.75f; } void ExperienceOrbRenderer::render(std::shared_ptr _orb, double x, @@ -25,8 +24,7 @@ void ExperienceOrbRenderer::render(std::shared_ptr _orb, double x, glTranslatef((float)x, (float)y, (float)z); int icon = orb->getIcon(); - bindTexture(TN_ITEM_EXPERIENCE_ORB); // 4J was L"/item/xporb.png" - Tesselator* t = Tesselator::getInstance(); + bindTexture(orb); // 4J was L"/item/xporb.png" float u0 = ((icon % 4) * 16 + 0) / 64.0f; float u1 = ((icon % 4) * 16 + 16) / 64.0f; @@ -57,6 +55,7 @@ void ExperienceOrbRenderer::render(std::shared_ptr _orb, double x, glRotatef(-entityRenderDispatcher->playerRotX, 1, 0, 0); float s = 0.3f; glScalef(s, s, s); + Tesselator* t = Tesselator::getInstance(); t->begin(); t->color(col, 128); t->normal(0, 1, 0); @@ -71,6 +70,11 @@ void ExperienceOrbRenderer::render(std::shared_ptr _orb, double x, glPopMatrix(); } +ResourceLocation* ExperienceOrbRenderer::getTextureLocation( + std::shared_ptr mob) { + return &XP_ORB_LOCATION; +} + void ExperienceOrbRenderer::blit(int x, int y, int sx, int sy, int w, int h) { float blitOffset = 0; float us = 1 / 256.0f; diff --git a/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.h index 2812f9280..7ee5b6a0e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ExperienceOrbRenderer.h @@ -1,17 +1,16 @@ #pragma once - #include "EntityRenderer.h" class ExperienceOrbRenderer : public EntityRenderer { private: - TileRenderer* tileRenderer; + static ResourceLocation XP_ORB_LOCATION; public: - bool setColor; - ExperienceOrbRenderer(); - void render(std::shared_ptr _orb, double x, double y, double z, - float rot, float a); + virtual void render(std::shared_ptr _orb, double x, double y, + double z, float rot, float a); void blit(int x, int y, int sx, int sy, int w, int h); + + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.cpp index d47bf7efa..83544880c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.cpp @@ -1,5 +1,6 @@ #include "../../Platform/stdafx.h" #include "FallingTileRenderer.h" +#include "../../Textures/TextureAtlas.h" #include "TileRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" @@ -17,46 +18,57 @@ void FallingTileRenderer::render(std::shared_ptr _tile, double x, // our version std::shared_ptr tile = std::dynamic_pointer_cast(_tile); - glPushMatrix(); - glTranslatef((float)x, (float)y, (float)z); - - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - Tile* tt = Tile::tiles[tile->tile]; - Level* level = tile->getLevel(); - glDisable(GL_LIGHTING); - glColor4f(1, 1, 1, - 1); // 4J added - this wouldn't be needed in real opengl as the - // block render has vertex colours and so this isn't use, but - // our pretend gl always modulates with this - if (tt == Tile::anvil && tt->getRenderShape() == Tile::SHAPE_ANVIL) { - tileRenderer->level = level; - Tesselator* t = Tesselator::getInstance(); - t->begin(); - t->offset(-Mth::floor(tile->x) - 0.5f, -Mth::floor(tile->y) - 0.5f, - -Mth::floor(tile->z) - 0.5f); - tileRenderer->tesselateAnvilInWorld((AnvilTile*)tt, Mth::floor(tile->x), - Mth::floor(tile->y), - Mth::floor(tile->z), tile->data); - t->offset(0, 0, 0); - t->end(); - } else if (tt == Tile::dragonEgg) { - tileRenderer->level = level; - Tesselator* t = Tesselator::getInstance(); - t->begin(); - t->offset(-Mth::floor(tile->x) - 0.5f, -Mth::floor(tile->y) - 0.5f, - -Mth::floor(tile->z) - 0.5f); - tileRenderer->tesselateInWorld( - tt, Mth::floor(tile->x), Mth::floor(tile->y), Mth::floor(tile->z)); - t->offset(0, 0, 0); - t->end(); - } else if (tt != NULL) { - tileRenderer->setShape(tt); - tileRenderer->renderBlock(tt, level, Mth::floor(tile->x), - Mth::floor(tile->y), Mth::floor(tile->z), - tile->data); + if (level->getTile(floor(tile->x), floor(tile->y), floor(tile->z)) != + tile->tile) { + glPushMatrix(); + glTranslatef((float)x, (float)y, (float)z); + + bindTexture(tile); // 4J was L"/terrain.png" + Tile* tt = Tile::tiles[tile->tile]; + + Level* level = tile->getLevel(); + + glDisable(GL_LIGHTING); + glColor4f(1, 1, 1, + 1); // 4J added - this wouldn't be needed in real opengl as + // the block render has vertex colours and so this isn't + // use, but our pretend gl always modulates with this + if (tt == Tile::anvil && tt->getRenderShape() == Tile::SHAPE_ANVIL) { + tileRenderer->level = level; + Tesselator* t = Tesselator::getInstance(); + t->begin(); + t->offset(-Mth::floor(tile->x) - 0.5f, -Mth::floor(tile->y) - 0.5f, + -Mth::floor(tile->z) - 0.5f); + tileRenderer->tesselateAnvilInWorld( + (AnvilTile*)tt, Mth::floor(tile->x), Mth::floor(tile->y), + Mth::floor(tile->z), tile->data); + t->offset(0, 0, 0); + t->end(); + } else if (tt == Tile::dragonEgg) { + tileRenderer->level = level; + Tesselator* t = Tesselator::getInstance(); + t->begin(); + t->offset(-Mth::floor(tile->x) - 0.5f, -Mth::floor(tile->y) - 0.5f, + -Mth::floor(tile->z) - 0.5f); + tileRenderer->tesselateInWorld(tt, Mth::floor(tile->x), + Mth::floor(tile->y), + Mth::floor(tile->z)); + t->offset(0, 0, 0); + t->end(); + } else if (tt != NULL) { + tileRenderer->setShape(tt); + tileRenderer->renderBlock(tt, level, Mth::floor(tile->x), + Mth::floor(tile->y), Mth::floor(tile->z), + tile->data); + } + glEnable(GL_LIGHTING); + glPopMatrix(); } - glEnable(GL_LIGHTING); - glPopMatrix(); +} + +ResourceLocation* FallingTileRenderer::getTextureLocation( + std::shared_ptr mob) { + return &TextureAtlas::LOCATION_BLOCKS; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.h index 30772c7de..ad0e5b4c3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/FallingTileRenderer.h @@ -10,4 +10,5 @@ public: virtual void render(std::shared_ptr _tile, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp index 32c72d991..87251b8c9 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp @@ -1,6 +1,7 @@ #include "../../Platform/stdafx.h" #include "FireballRenderer.h" #include "EntityRenderDispatcher.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.projectile.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" @@ -25,7 +26,7 @@ void FireballRenderer::render(std::shared_ptr _fireball, double x, Icon* icon = Item::fireball->getIcon( fireball->GetType() == eTYPE_DRAGON_FIREBALL ? 1 : 0); // 14 + 2 * 16; MemSect(31); - bindTexture(TN_GUI_ITEMS); // 4J was L"/gui/items.png" + bindTexture(fireball); MemSect(0); Tesselator* t = Tesselator::getInstance(); @@ -68,7 +69,7 @@ void FireballRenderer::renderFlame(std::shared_ptr e, double x, float s = e->bbWidth * 1.4f; glScalef(s, s, s); MemSect(31); - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + bindTexture(&TextureAtlas::LOCATION_BLOCKS); MemSect(0); Tesselator* t = Tesselator::getInstance(); @@ -112,4 +113,9 @@ void FireballRenderer::renderFlame(std::shared_ptr e, double x, t->end(); glPopMatrix(); glEnable(GL_LIGHTING); +} + +ResourceLocation* FireballRenderer::getTextureLocation( + std::shared_ptr mob) { + return &TextureAtlas::LOCATION_ITEMS; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.h index cbe2fb37d..b31ae4f0e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.h @@ -13,6 +13,7 @@ public: private: // 4J Added override - virtual void renderFlame(std::shared_ptr e, double x, double y, + virtual void renderFlame(std::shared_ptr entity, double x, double y, double z, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp index b329752fd..9d4b7e0f1 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp @@ -8,6 +8,9 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "../../Player/MultiPlayerLocalPlayer.h" +ResourceLocation FishingHookRenderer::PARTICLE_LOCATION = + ResourceLocation(TN_PARTICLES); + void FishingHookRenderer::render(std::shared_ptr _hook, double x, double y, double z, float rot, float a) { // 4J - dynamic cast required because we aren't using templates/generics in @@ -22,13 +25,13 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f); int xi = 1; int yi = 2; - bindTexture(TN_PARTICLES); // 4J was L"/particles.png" + bindTexture(hook); // 4J was L"/particles.png" Tesselator* t = Tesselator::getInstance(); - float u0 = ((xi) * 8 + 0) / 128.0f; - float u1 = ((xi) * 8 + 8) / 128.0f; - float v0 = ((yi) * 8 + 0) / 128.0f; - float v1 = ((yi) * 8 + 8) / 128.0f; + float u0 = (xi * 8 + 0) / 128.0f; + float u1 = (xi * 8 + 8) / 128.0f; + float v0 = (yi * 8 + 0) / 128.0f; + float v1 = (yi * 8 + 8) / 128.0f; float r = 1.0f; float xo = 0.5f; @@ -53,7 +56,7 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, if (hook->owner != NULL) { float swing = hook->owner->getAttackAnim(a); - float swing2 = (float)Mth::sin((sqrt(swing)) * PI); + float swing2 = (float)Mth::sin(sqrt(swing) * PI); Vec3* vv = Vec3::newTemp(-0.5, 0.03, 0.8); vv->xRot(-(hook->owner->xRotO + @@ -71,10 +74,10 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, hook->owner->yo + (hook->owner->y - hook->owner->yo) * a + vv->y; double zp = hook->owner->zo + (hook->owner->z - hook->owner->zo) * a + vv->z; - double yOffset = hook->owner != std::dynamic_pointer_cast( + double yOffset = hook->owner == std::dynamic_pointer_cast( Minecraft::GetInstance()->player) - ? hook->owner->getHeadHeight() - : 0; + ? 0 + : hook->owner->getHeadHeight(); // 4J-PB - changing this to be per player // if (this->entityRenderDispatcher->options->thirdPersonView) @@ -117,3 +120,8 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, glEnable(GL_TEXTURE_2D); } } + +ResourceLocation* FishingHookRenderer::getTextureLocation( + std::shared_ptr mob) { + return &PARTICLE_LOCATION; +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.h index 9e49dcf46..dd9cd4162 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.h @@ -2,7 +2,11 @@ #include "EntityRenderer.h" class FishingHookRenderer : public EntityRenderer { +private: + static ResourceLocation PARTICLE_LOCATION; + public: virtual void render(std::shared_ptr _hook, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.cpp index 29637645d..0eb074802 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.cpp @@ -3,9 +3,13 @@ #include "../Models/GhastModel.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" +ResourceLocation GhastRenderer::GHAST_LOCATION = ResourceLocation(TN_MOB_GHAST); +ResourceLocation GhastRenderer::GHAST_SHOOTING_LOCATION = + ResourceLocation(TN_MOB_GHAST_FIRE); + GhastRenderer::GhastRenderer() : MobRenderer(new GhastModel(), 0.5f) {} -void GhastRenderer::scale(std::shared_ptr mob, float a) { +void GhastRenderer::scale(std::shared_ptr mob, float a) { std::shared_ptr ghast = std::dynamic_pointer_cast(mob); float ss = (ghast->oCharge + (ghast->charge - ghast->oCharge) * a) / 20.0f; @@ -15,4 +19,15 @@ void GhastRenderer::scale(std::shared_ptr mob, float a) { float hs = (8 + 1 / ss) / 2; glScalef(hs, s, hs); glColor4f(1, 1, 1, 1); +} + +ResourceLocation* GhastRenderer::getTextureLocation( + std::shared_ptr mob) { + std::shared_ptr ghast = std::dynamic_pointer_cast(mob); + + if (ghast->isCharging()) { + return &GHAST_SHOOTING_LOCATION; + } + + return &GHAST_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.h index d552871fd..f4a092a12 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/GhastRenderer.h @@ -2,9 +2,14 @@ #include "MobRenderer.h" class GhastRenderer : public MobRenderer { +private: + static ResourceLocation GHAST_LOCATION; + static ResourceLocation GHAST_SHOOTING_LOCATION; + public: GhastRenderer(); protected: - virtual void scale(std::shared_ptr mob, float a); + virtual void scale(std::shared_ptr mob, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.cpp index 7e6035b0d..8206f8635 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.cpp @@ -1,11 +1,19 @@ #include "../../Platform/stdafx.h" #include "GiantMobRenderer.h" +ResourceLocation GiantMobRenderer::ZOMBIE_LOCATION = + ResourceLocation(TN_ITEM_ARROWS); + GiantMobRenderer::GiantMobRenderer(Model* model, float shadow, float _scale) : MobRenderer(model, shadow * _scale) { this->_scale = _scale; } -void GiantMobRenderer::scale(std::shared_ptr mob, float a) { +void GiantMobRenderer::scale(std::shared_ptr mob, float a) { glScalef(_scale, _scale, _scale); +} + +ResourceLocation* GiantMobRenderer::getTextureLocation( + std::shared_ptr mob) { + return &ZOMBIE_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.h index 872592147..c17f5742c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/GiantMobRenderer.h @@ -3,11 +3,13 @@ class GiantMobRenderer : public MobRenderer { private: + static ResourceLocation ZOMBIE_LOCATION; float _scale; public: GiantMobRenderer(Model* model, float shadow, float scale); protected: - virtual void scale(std::shared_ptr mob, float a); + virtual void scale(std::shared_ptr mob, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp new file mode 100644 index 000000000..963053f25 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.cpp @@ -0,0 +1,103 @@ +#include "../../Platform/stdafx.h" +#include "HorseRenderer.h" +#include "MobRenderer.h" +#include "EntityRenderDispatcher.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" + +ResourceLocation HorseRenderer::HORSE_LOCATION = + ResourceLocation(TN_MOB_HORSE_WHITE); +ResourceLocation HorseRenderer::HORSE_MULE_LOCATION = + ResourceLocation(TN_MOB_MULE); +ResourceLocation HorseRenderer::HORSE_DONKEY_LOCATION = + ResourceLocation(TN_MOB_DONKEY); +ResourceLocation HorseRenderer::HORSE_ZOMBIE_LOCATION = + ResourceLocation(TN_MOB_HORSE_ZOMBIE); +ResourceLocation HorseRenderer::HORSE_SKELETON_LOCATION = + ResourceLocation(TN_MOB_HORSE_SKELETON); + +std::map HorseRenderer::LAYERED_LOCATION_CACHE; + +HorseRenderer::HorseRenderer(Model* model, float f) : MobRenderer(model, f) {} + +void HorseRenderer::adjustHeight(std::shared_ptr mob, + float FHeight) { + glTranslatef(0.0F, FHeight, 0.0F); +} + +void HorseRenderer::scale(std::shared_ptr entityliving, float f) { + float sizeFactor = 1.0f; + + int type = std::dynamic_pointer_cast(entityliving)->getType(); + if (type == EntityHorse::TYPE_DONKEY) { + sizeFactor *= 0.87F; + } else if (type == EntityHorse::TYPE_MULE) { + sizeFactor *= 0.92F; + } + glScalef(sizeFactor, sizeFactor, sizeFactor); + MobRenderer::scale(entityliving, f); +} + +void HorseRenderer::renderModel(std::shared_ptr mob, float wp, + float ws, float bob, float headRotMinusBodyRot, + float headRotx, float scale) { + if (mob->isInvisible()) { + model->setupAnim(wp, ws, bob, headRotMinusBodyRot, headRotx, scale, + mob); + } else { + EntityRenderer::bindTexture(mob); + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, + true); + // Ensure that any extra layers of texturing are disabled after + // rendering this horse + RenderManager.TextureBind(1, -1); + } +} + +void HorseRenderer::bindTexture(ResourceLocation* location) { + // Set up (potentially) multiple texture layers for the horse + entityRenderDispatcher->textures->bindTextureLayers(location); +} + +ResourceLocation* HorseRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr horse = + std::dynamic_pointer_cast(entity); + + if (!horse->hasLayeredTextures()) { + switch (horse->getType()) { + default: + case EntityHorse::TYPE_HORSE: + return &HORSE_LOCATION; + case EntityHorse::TYPE_MULE: + return &HORSE_MULE_LOCATION; + case EntityHorse::TYPE_DONKEY: + return &HORSE_DONKEY_LOCATION; + case EntityHorse::TYPE_UNDEAD: + return &HORSE_ZOMBIE_LOCATION; + case EntityHorse::TYPE_SKELETON: + return &HORSE_SKELETON_LOCATION; + } + } + + return getOrCreateLayeredTextureLocation(horse); +} + +ResourceLocation* HorseRenderer::getOrCreateLayeredTextureLocation( + std::shared_ptr horse) { + std::wstring textureName = horse->getLayeredTextureHashName(); + + AUTO_VAR(it, LAYERED_LOCATION_CACHE.find(textureName)); + + ResourceLocation* location; + if (it != LAYERED_LOCATION_CACHE.end()) { + location = it->second; + } else { + LAYERED_LOCATION_CACHE[textureName] = + new ResourceLocation(horse->getLayeredTextureLayers()); + + it = LAYERED_LOCATION_CACHE.find(textureName); + location = it->second; + } + + return location; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.h new file mode 100644 index 000000000..31f7c281c --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/HorseRenderer.h @@ -0,0 +1,34 @@ +#pragma once +#include "MobRenderer.h" +#include "../../Textures/ResourceLocation.h" + +class EntityHorse; +class PathfinderMob; + +class HorseRenderer : public MobRenderer { +private: + static std::map LAYERED_LOCATION_CACHE; + + static ResourceLocation HORSE_LOCATION; + static ResourceLocation HORSE_MULE_LOCATION; + static ResourceLocation HORSE_DONKEY_LOCATION; + static ResourceLocation HORSE_ZOMBIE_LOCATION; + static ResourceLocation HORSE_SKELETON_LOCATION; + +public: + HorseRenderer(Model* model, float f); + +protected: + void adjustHeight(std::shared_ptr mob, float FHeight); + virtual void scale(std::shared_ptr entityliving, float f); + virtual void renderModel(std::shared_ptr mob, float wp, + float ws, float bob, float headRotMinusBodyRot, + float headRotx, float scale); + virtual void bindTexture(ResourceLocation* location); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + +private: + ResourceLocation* getOrCreateLayeredTextureLocation( + std::shared_ptr horse); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.cpp index 2b9406c30..fb461b221 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.cpp @@ -10,11 +10,18 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "../../../Minecraft.World/Headers/net.minecraft.h" +const std::wstring HumanoidMobRenderer::MATERIAL_NAMES[5] = { + L"cloth", L"chain", L"iron", L"diamond", L"gold"}; +std::map + HumanoidMobRenderer::ARMOR_LOCATION_CACHE; + void HumanoidMobRenderer::_init(HumanoidModel* humanoidModel, float scale) { this->humanoidModel = humanoidModel; this->_scale = scale; armorParts1 = NULL; armorParts2 = NULL; + + createArmorParts(); } HumanoidMobRenderer::HumanoidMobRenderer(HumanoidModel* humanoidModel, @@ -27,8 +34,66 @@ HumanoidMobRenderer::HumanoidMobRenderer(HumanoidModel* humanoidModel, float shadow, float scale) : MobRenderer(humanoidModel, shadow) { _init(humanoidModel, scale); +} - createArmorParts(); +ResourceLocation* HumanoidMobRenderer::getArmorLocation(ArmorItem* armorItem, + int layer) { + return getArmorLocation(armorItem, layer, false); +} + +ResourceLocation* HumanoidMobRenderer::getArmorLocation(ArmorItem* armorItem, + int layer, + bool overlay) { + switch (armorItem->modelIndex) { + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + }; + std::wstring path = + std::wstring(L"armor/" + MATERIAL_NAMES[armorItem->modelIndex]) + .append(L"_") + .append(_toString(layer == 2 ? 2 : 1)) + .append((overlay ? L"_b" : L"")) + .append(L".png"); + + std::map::iterator it = + ARMOR_LOCATION_CACHE.find(path); + + ResourceLocation* location; + if (it != ARMOR_LOCATION_CACHE.end()) { + location = &it->second; + } else { + ARMOR_LOCATION_CACHE.insert(std::pair( + path, ResourceLocation(path))); + + it = ARMOR_LOCATION_CACHE.find(path); + location = &it->second; + } + + return location; +} + +void HumanoidMobRenderer::prepareSecondPassArmor( + std::shared_ptr mob, int layer, float a) { + std::shared_ptr itemInstance = mob->getArmor(3 - layer); + if (itemInstance != NULL) { + Item* item = itemInstance->getItem(); + if (dynamic_cast(item) != NULL) { + bindTexture( + getArmorLocation(dynamic_cast(item), layer, true)); + + float brightness = + SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a); + glColor3f(brightness, brightness, brightness); + } + } } void HumanoidMobRenderer::createArmorParts() { @@ -36,7 +101,98 @@ void HumanoidMobRenderer::createArmorParts() { armorParts2 = new HumanoidModel(0.5f); } -void HumanoidMobRenderer::additionalRendering(std::shared_ptr mob, +int HumanoidMobRenderer::prepareArmor(std::shared_ptr _mob, + int layer, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(_mob); + + std::shared_ptr itemInstance = mob->getArmor(3 - layer); + if (itemInstance != NULL) { + Item* item = itemInstance->getItem(); + if (dynamic_cast(item) != NULL) { + ArmorItem* armorItem = dynamic_cast(item); + bindTexture(getArmorLocation(armorItem, layer)); + + HumanoidModel* armor = layer == 2 ? armorParts2 : armorParts1; + + armor->head->visible = layer == 0; + armor->hair->visible = layer == 0; + armor->body->visible = layer == 1 || layer == 2; + armor->arm0->visible = layer == 1; + armor->arm1->visible = layer == 1; + armor->leg0->visible = layer == 2 || layer == 3; + armor->leg1->visible = layer == 2 || layer == 3; + + setArmor(armor); + armor->attackTime = model->attackTime; + armor->riding = model->riding; + armor->young = model->young; + + float brightness = + SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a); + if (armorItem->getMaterial() == ArmorItem::ArmorMaterial::CLOTH) { + int color = armorItem->getColor(itemInstance); + float red = (float)((color >> 16) & 0xFF) / 0xFF; + float green = (float)((color >> 8) & 0xFF) / 0xFF; + float blue = (float)(color & 0xFF) / 0xFF; + glColor3f(brightness * red, brightness * green, + brightness * blue); + + if (itemInstance->isEnchanted()) return 0x1f; + return 0x10; + + } else { + glColor3f(brightness, brightness, brightness); + } + + if (itemInstance->isEnchanted()) return 15; + + return 1; + } + } + return -1; +} + +void HumanoidMobRenderer::render(std::shared_ptr _mob, double x, + double y, double z, float rot, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(_mob); + + float brightness = + SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a); + glColor3f(brightness, brightness, brightness); + std::shared_ptr item = mob->getCarriedItem(); + + prepareCarriedItem(mob, item); + + double yp = y - mob->heightOffset; + if (mob->isSneaking()) { + yp -= 2 / 16.0f; + } + MobRenderer::render(mob, x, yp, z, rot, a); + armorParts1->bowAndArrow = armorParts2->bowAndArrow = + humanoidModel->bowAndArrow = false; + armorParts1->sneaking = armorParts2->sneaking = humanoidModel->sneaking = + false; + armorParts1->holdingRightHand = armorParts2->holdingRightHand = + humanoidModel->holdingRightHand = 0; +} + +ResourceLocation* HumanoidMobRenderer::getTextureLocation( + std::shared_ptr mob) { + // TODO -- Figure out of we need some data in here + return NULL; +} + +void HumanoidMobRenderer::prepareCarriedItem( + std::shared_ptr mob, std::shared_ptr item) { + armorParts1->holdingRightHand = armorParts2->holdingRightHand = + humanoidModel->holdingRightHand = item != NULL ? 1 : 0; + armorParts1->sneaking = armorParts2->sneaking = humanoidModel->sneaking = + mob->isSneaking(); +} + +void HumanoidMobRenderer::additionalRendering(std::shared_ptr mob, float a) { float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a); @@ -138,6 +294,6 @@ void HumanoidMobRenderer::additionalRendering(std::shared_ptr mob, } } -void HumanoidMobRenderer::scale(std::shared_ptr mob, float a) { +void HumanoidMobRenderer::scale(std::shared_ptr mob, float a) { glScalef(_scale, _scale, _scale); } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.h index 42488e2d9..30f2c69c4 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/HumanoidMobRenderer.h @@ -1,9 +1,15 @@ #pragma once #include "MobRenderer.h" + class HumanoidModel; class Giant; +class ArmorItem; class HumanoidMobRenderer : public MobRenderer { +private: + static const std::wstring MATERIAL_NAMES[5]; + static std::map ARMOR_LOCATION_CACHE; + protected: HumanoidModel* humanoidModel; float _scale; @@ -13,12 +19,27 @@ protected: void _init(HumanoidModel* humanoidModel, float scale); public: + static ResourceLocation* getArmorLocation(ArmorItem* armorItem, int layer); + static ResourceLocation* getArmorLocation(ArmorItem* armorItem, int layer, + bool overlay); + HumanoidMobRenderer(HumanoidModel* humanoidModel, float shadow); HumanoidMobRenderer(HumanoidModel* humanoidModel, float shadow, float scale); + virtual void prepareSecondPassArmor(std::shared_ptr mob, + int layer, float a); + protected: virtual void createArmorParts(); - virtual void additionalRendering(std::shared_ptr mob, float a); - void scale(std::shared_ptr mob, float a); + virtual int prepareArmor(std::shared_ptr _mob, int layer, + float a); + virtual void render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); + virtual void prepareCarriedItem(std::shared_ptr mob, + std::shared_ptr item); + virtual void additionalRendering(std::shared_ptr mob, + float a); + virtual void scale(std::shared_ptr mob, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.cpp index d9846a6a0..1db85e589 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.cpp @@ -4,6 +4,7 @@ #include "EntityRenderDispatcher.h" // #include "ItemFrame" #include "ItemFrameRenderer.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Util/JavaMath.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" @@ -18,6 +19,9 @@ #include "../../Textures/CompassTexture.h" #include "../Minimap.h" +ResourceLocation ItemFrameRenderer::MAP_BACKGROUND_LOCATION = + ResourceLocation(TN_MISC_MAPBG); + void ItemFrameRenderer::registerTerrainTextures(IconRegister* iconRegister) { backTexture = iconRegister->registerIcon(L"itemframe_back"); } @@ -25,8 +29,8 @@ void ItemFrameRenderer::registerTerrainTextures(IconRegister* iconRegister) { void ItemFrameRenderer::render(std::shared_ptr _itemframe, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type EnderCrystal rather than std::shared_ptr we have here - do - // some casting around instead + // type EnderCrystal rather than shared_ptr we have here - do some + // casting around instead std::shared_ptr itemFrame = std::dynamic_pointer_cast(_itemframe); @@ -51,7 +55,8 @@ void ItemFrameRenderer::drawFrame(std::shared_ptr itemFrame) { Minecraft* pMinecraft = Minecraft::GetInstance(); glPushMatrix(); - entityRenderDispatcher->textures->bindTexture(TN_TERRAIN); + entityRenderDispatcher->textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); glRotatef(itemFrame->yRot, 0, 1, 0); Tile* wood = Tile::wood; @@ -142,7 +147,7 @@ void ItemFrameRenderer::drawItem(std::shared_ptr entity) { } if (itemEntity->getItem()->getItem() == Item::map) { - entityRenderDispatcher->textures->bindTexture(TN_MISC_MAPBG); + entityRenderDispatcher->textures->bindTexture(&MAP_BACKGROUND_LOCATION); Tesselator* t = Tesselator::getInstance(); glRotatef(180, 0, 1, 0); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.h index 12626a614..02e32a167 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemFrameRenderer.h @@ -3,9 +3,9 @@ class ItemFrameRenderer : public EntityRenderer { private: + static ResourceLocation MAP_BACKGROUND_LOCATION; Icon* backTexture; - //@Override public: void registerTerrainTextures(IconRegister* iconRegister); virtual void render(std::shared_ptr _itemframe, double x, double y, diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.cpp index 92e3fa52d..cc318adf0 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.cpp @@ -3,11 +3,12 @@ #include "TileRenderer.h" #include "../Tesselator.h" #include "../../Textures/Textures.h" +#include "../../Textures/TextureAtlas.h" #include "EntityRenderer.h" #include "PlayerRenderer.h" #include "EntityRenderDispatcher.h" #include "../Lighting.h" -#include "../../Player/MultiPlayerLocalPlayer.h" +#include "MultiPlayerLocalPlayer.h" #include "../Minimap.h" #include "../../Level/MultiPlayerLevel.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" @@ -17,10 +18,19 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.h" -int ItemInHandRenderer::list = -1; +ResourceLocation ItemInHandRenderer::ENCHANT_GLINT_LOCATION = + ResourceLocation(TN__BLUR__MISC_GLINT); +ResourceLocation ItemInHandRenderer::MAP_BACKGROUND_LOCATION = + ResourceLocation(TN_MISC_MAPBG); +ResourceLocation ItemInHandRenderer::UNDERWATER_LOCATION = + ResourceLocation(TN_MISC_WATER); + +int ItemInHandRenderer::listItem = -1; +int ItemInHandRenderer::listTerrain = -1; int ItemInHandRenderer::listGlint = -1; -ItemInHandRenderer::ItemInHandRenderer(Minecraft* mc, bool optimisedMinimap) { +ItemInHandRenderer::ItemInHandRenderer(Minecraft* minecraft, + bool optimisedMinimap) { // 4J - added height = 0; oHeight = 0; @@ -28,20 +38,20 @@ ItemInHandRenderer::ItemInHandRenderer(Minecraft* mc, bool optimisedMinimap) { tileRenderer = new TileRenderer(); lastSlot = -1; - this->mc = mc; - minimap = - new Minimap(mc->font, mc->options, mc->textures, optimisedMinimap); + this->minecraft = minecraft; + minimap = new Minimap(minecraft->font, minecraft->options, + minecraft->textures, optimisedMinimap); // 4J - replaced mesh that is used to render held items with individual // cubes, so we can make it all join up properly without seams. This has a // lot more quads in it than the original, so is now precompiled with a UV // matrix offset to put it in the final place for the current icon. Compile // it on demand for the first ItemInHandRenderer (list is static) - if (list == -1) { - list = MemoryTracker::genLists(1); + if (listItem == -1) { + listItem = MemoryTracker::genLists(1); float dd = 1 / 16.0f; - glNewList(list, GL_COMPILE); + glNewList(listItem, GL_COMPILE); Tesselator* t = Tesselator::getInstance(); t->begin(); for (int yp = 0; yp < 16; yp++) @@ -92,6 +102,62 @@ ItemInHandRenderer::ItemInHandRenderer(Minecraft* mc, bool optimisedMinimap) { glEndList(); } + // Terrain texture is a different layout from the item texture + if (listTerrain == -1) { + listTerrain = MemoryTracker::genLists(1); + float dd = 1 / 16.0f; + + glNewList(listTerrain, GL_COMPILE); + Tesselator* t = Tesselator::getInstance(); + t->begin(); + for (int yp = 0; yp < 16; yp++) + for (int xp = 0; xp < 16; xp++) { + float u = (15 - xp) / 256.0f; + float v = (15 - yp) / 512.0f; + u += 0.5f / 256.0f; + v += 0.5f / 512.0f; + float x0 = xp / 16.0f; + float x1 = x0 + 1.0f / 16.0f; + float y0 = yp / 16.0f; + float y1 = y0 + 1.0f / 16.0f; + float z0 = 0.0f; + float z1 = -dd; + + t->normal(0, 0, 1); + t->vertexUV(x0, y0, z0, u, v); + t->vertexUV(x1, y0, z0, u, v); + t->vertexUV(x1, y1, z0, u, v); + t->vertexUV(x0, y1, z0, u, v); + t->normal(0, 0, -1); + t->vertexUV(x0, y1, z1, u, v); + t->vertexUV(x1, y1, z1, u, v); + t->vertexUV(x1, y0, z1, u, v); + t->vertexUV(x0, y0, z1, u, v); + t->normal(-1, 0, 0); + t->vertexUV(x0, y0, z1, u, v); + t->vertexUV(x0, y0, z0, u, v); + t->vertexUV(x0, y1, z0, u, v); + t->vertexUV(x0, y1, z1, u, v); + t->normal(1, 0, 0); + t->vertexUV(x1, y1, z1, u, v); + t->vertexUV(x1, y1, z0, u, v); + t->vertexUV(x1, y0, z0, u, v); + t->vertexUV(x1, y0, z1, u, v); + t->normal(0, 1, 0); + t->vertexUV(x1, y0, z0, u, v); + t->vertexUV(x0, y0, z0, u, v); + t->vertexUV(x0, y0, z1, u, v); + t->vertexUV(x1, y0, z1, u, v); + t->normal(0, -1, 0); + t->vertexUV(x1, y1, z1, u, v); + t->vertexUV(x0, y1, z1, u, v); + t->vertexUV(x0, y1, z0, u, v); + t->vertexUV(x1, y1, z0, u, v); + } + t->end(); + glEndList(); + } + // Also create special object for glint overlays - this is the same as the // previous one, with a different UV scalings, and depth test set to equal if (listGlint == -1) { @@ -159,7 +225,7 @@ ItemInHandRenderer::ItemInHandRenderer(Minecraft* mc, bool optimisedMinimap) { } } -void ItemInHandRenderer::renderItem(std::shared_ptr mob, +void ItemInHandRenderer::renderItem(std::shared_ptr mob, std::shared_ptr item, int layer, bool setColor /* = true*/) { // 4J - code borrowed from render method below, although not factoring in @@ -179,10 +245,11 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, if (item->getIconType() == Icon::TYPE_TERRAIN && tile != NULL && TileRenderer::canRender(tile->getRenderShape())) { MemSect(31); - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + minecraft->textures->bindTexture( + minecraft->textures->getTextureLocation(Icon::TYPE_TERRAIN)); MemSect(0); tileRenderer->renderTile( - tile, item->getAuxValue(), + Tile::tiles[item->id], item->getAuxValue(), SharedConstants::TEXTURE_LIGHTING ? 1.0f : mob->getBrightness( @@ -196,12 +263,10 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, return; } - if (item->getIconType() == Icon::TYPE_TERRAIN) { - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - } else { - mc->textures->bindTexture( - TN_GUI_ITEMS); // 4J was L"/gui/items.png" - } + bool bIsTerrain = item->getIconType() == Icon::TYPE_TERRAIN; + minecraft->textures->bindTexture( + minecraft->textures->getTextureLocation(item->getIconType())); + MemSect(0); Tesselator* t = Tesselator::getInstance(); @@ -241,13 +306,12 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, float dd = 1 / 16.0f; renderItem3D(t, u0, v0, u1, v1, icon->getSourceWidth(), - icon->getSourceHeight(), 1 / 16.0f, false); + icon->getSourceHeight(), 1 / 16.0f, false, bIsTerrain); if (item != NULL && item->isFoil() && layer == 0) { glDepthFunc(GL_EQUAL); glDisable(GL_LIGHTING); - mc->textures->bind(mc->textures->loadTexture( - TN__BLUR__MISC_GLINT)); // 4J was L"%blur%/misc/glint.png" + minecraft->textures->bindTexture(&ENCHANT_GLINT_LOCATION); glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_ONE); float br = 0.76f; @@ -263,7 +327,7 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, glTranslatef(sx, 0, 0); glRotatef(-50, 0, 0, 1); - renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true); + renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true, bIsTerrain); glPopMatrix(); glPushMatrix(); glScalef(ss, ss, ss); @@ -271,7 +335,7 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, (3000 + 1873.0f) * 8; glTranslatef(-sx, 0, 0); glRotatef(10, 0, 0, 1); - renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true); + renderItem3D(t, 0, 0, 1, 1, 256, 256, 1 / 16.0f, true, bIsTerrain); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glDisable(GL_BLEND); @@ -289,7 +353,8 @@ void ItemInHandRenderer::renderItem(std::shared_ptr mob, // 4J added useList parameter void ItemInHandRenderer::renderItem3D(Tesselator* t, float u0, float v0, float u1, float v1, int width, int height, - float depth, bool isGlint) { + float depth, bool isGlint, + bool isTerrain) { float r = 1.0f; // 4J - replaced mesh that is used to render held items with individual @@ -308,7 +373,7 @@ void ItemInHandRenderer::renderItem3D(Tesselator* t, float u0, float v0, glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(u0, v0, 0); - glCallList(list); + glCallList(isTerrain ? listTerrain : listItem); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } @@ -318,12 +383,8 @@ void ItemInHandRenderer::renderItem3D(Tesselator* t, float u0, float v0, } void ItemInHandRenderer::render(float a) { - // 4jcraft: null checks here fix player hand rendering on linux - // TOOD: determine why these are null in the first place - if (!mc->player || !mc->level) return; - float h = oHeight + (height - oHeight) * a; - std::shared_ptr player = mc->player; + std::shared_ptr player = minecraft->player; // 4J - added so we can adjust the position of the hands for horizontal & // vertical split screens @@ -370,14 +431,14 @@ void ItemInHandRenderer::render(float a) { std::shared_ptr item = selectedItem; - float br = mc->level->getBrightness( + float br = minecraft->level->getBrightness( Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); // 4J - change brought forward from 1.8.2 if (SharedConstants::TEXTURE_LIGHTING) { br = 1; - int col = mc->level->getLightColor(Mth::floor(player->x), - Mth::floor(player->y), - Mth::floor(player->z), 0); + int col = minecraft->level->getLightColor(Mth::floor(player->x), + Mth::floor(player->y), + Mth::floor(player->z), 0); int u = col % 65536; int v = col / 65536; glMultiTexCoord2f(GL_TEXTURE1, u / 1.0f, v / 1.0f); @@ -428,12 +489,13 @@ void ItemInHandRenderer::render(float a) { { // 4J-PB - if we've got a player texture, use that // glBindTexture(GL_TEXTURE_2D, - // mc->textures->loadHttpTexture(mc->player->customTextureUrl, - // mc->player->getTexture())); - glBindTexture(GL_TEXTURE_2D, mc->textures->loadMemTexture( - mc->player->customTextureUrl, - mc->player->getTexture())); - mc->textures->clearLastBoundId(); + // minecraft->textures->loadHttpTexture(minecraft->player->customTextureUrl, + // minecraft->player->getTexture())); + glBindTexture(GL_TEXTURE_2D, + minecraft->textures->loadMemTexture( + minecraft->player->customTextureUrl, + minecraft->player->getTexture())); + minecraft->textures->clearLastBoundId(); for (int i = 0; i < 2; i++) { int flip = i * 2 - 1; glPushMatrix(); @@ -445,7 +507,8 @@ void ItemInHandRenderer::render(float a) { glRotatef((float)(-65 * flip), 0, 1, 0); EntityRenderer* er = - EntityRenderDispatcher::instance->getRenderer(mc->player); + EntityRenderDispatcher::instance->getRenderer( + minecraft->player); PlayerRenderer* playerRenderer = (PlayerRenderer*)er; float ss = 1; glScalef(ss, ss, ss); @@ -484,7 +547,8 @@ void ItemInHandRenderer::render(float a) { glScalef(s, s, s); MemSect(31); - mc->textures->bindTexture(TN_MISC_MAPBG); // 4J was L"/misc/mapbg.png" + minecraft->textures->bindTexture( + &MAP_BACKGROUND_LOCATION); // 4J was L"/misc/mapbg.png" MemSect(0); Tesselator* t = Tesselator::getInstance(); @@ -503,11 +567,11 @@ void ItemInHandRenderer::render(float a) { t->end(); std::shared_ptr data = - Item::map->getSavedData(item, mc->level); + Item::map->getSavedData(item, minecraft->level); PIXBeginNamedEvent(0, "Minimap render"); if (data != NULL) - minimap->render(mc->player, mc->textures, data, - mc->player->entityId); + minimap->render(minecraft->player, minecraft->textures, data, + minecraft->player->entityId); PIXEndNamedEvent(); glPopMatrix(); @@ -653,15 +717,15 @@ void ItemInHandRenderer::render(float a) { // 4J-PB - if we've got a player texture, use that // glBindTexture(GL_TEXTURE_2D, - // mc->textures->loadHttpTexture(mc->player->customTextureUrl, - // mc->player->getTexture())); + // minecraft->textures->loadHttpTexture(minecraft->player->customTextureUrl, + // minecraft->player->getTexture())); MemSect(31); - glBindTexture(GL_TEXTURE_2D, - mc->textures->loadMemTexture(mc->player->customTextureUrl, - mc->player->getTexture())); + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadMemTexture( + minecraft->player->customTextureUrl, + minecraft->player->getTexture())); MemSect(0); - mc->textures->clearLastBoundId(); + minecraft->textures->clearLastBoundId(); glTranslatef(-1.0f, +3.6f, +3.5f); glRotatef(120, 0, 0, 1); glRotatef(180 + 20, 1, 0, 0); @@ -670,7 +734,7 @@ void ItemInHandRenderer::render(float a) { glTranslatef(5.6f, 0, 0); EntityRenderer* er = - EntityRenderDispatcher::instance->getRenderer(mc->player); + EntityRenderDispatcher::instance->getRenderer(minecraft->player); PlayerRenderer* playerRenderer = (PlayerRenderer*)er; float ss = 1; glScalef(ss, ss, ss); @@ -694,35 +758,32 @@ void ItemInHandRenderer::render(float a) { void ItemInHandRenderer::renderScreenEffect(float a) { glDisable(GL_ALPHA_TEST); - if (mc->player->isOnFire()) { - MemSect(31); - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - MemSect(0); + if (minecraft->player->isOnFire()) { renderFire(a); } - if (mc->player->isInWall()) // Inside a tile + if (minecraft->player->isInWall()) // Inside a tile { - int x = Mth::floor(mc->player->x); - int y = Mth::floor(mc->player->y); - int z = Mth::floor(mc->player->z); + int x = Mth::floor(minecraft->player->x); + int y = Mth::floor(minecraft->player->y); + int z = Mth::floor(minecraft->player->z); - MemSect(31); - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - MemSect(0); - int tile = mc->level->getTile(x, y, z); - if (mc->level->isSolidBlockingTile(x, y, z)) { + int tile = minecraft->level->getTile(x, y, z); + if (minecraft->level->isSolidBlockingTile(x, y, z)) { renderTex(a, Tile::tiles[tile]->getTexture(2)); } else { for (int i = 0; i < 8; i++) { - float xo = ((i >> 0) % 2 - 0.5f) * mc->player->bbWidth * 0.9f; - float yo = ((i >> 1) % 2 - 0.5f) * mc->player->bbHeight * 0.2f; - float zo = ((i >> 2) % 2 - 0.5f) * mc->player->bbWidth * 0.9f; + float xo = + ((i >> 0) % 2 - 0.5f) * minecraft->player->bbWidth * 0.9f; + float yo = + ((i >> 1) % 2 - 0.5f) * minecraft->player->bbHeight * 0.2f; + float zo = + ((i >> 2) % 2 - 0.5f) * minecraft->player->bbWidth * 0.9f; int xt = Mth::floor(x + xo); int yt = Mth::floor(y + yo); int zt = Mth::floor(z + zo); - if (mc->level->isSolidBlockingTile(xt, yt, zt)) { - tile = mc->level->getTile(xt, yt, zt); + if (minecraft->level->isSolidBlockingTile(xt, yt, zt)) { + tile = minecraft->level->getTile(xt, yt, zt); } } } @@ -731,9 +792,10 @@ void ItemInHandRenderer::renderScreenEffect(float a) { renderTex(a, Tile::tiles[tile]->getTexture(2)); } - if (mc->player->isUnderLiquid(Material::water)) { + if (minecraft->player->isUnderLiquid(Material::water)) { MemSect(31); - mc->textures->bindTexture(TN_MISC_WATER); // 4J was L"/misc/water.png" + minecraft->textures->bindTexture( + &UNDERWATER_LOCATION); // 4J was L"/misc/water.png" MemSect(0); renderWater(a); } @@ -741,6 +803,9 @@ void ItemInHandRenderer::renderScreenEffect(float a) { } void ItemInHandRenderer::renderTex(float a, Icon* slot) { + minecraft->textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); // TODO: get this data from Icon + Tesselator* t = Tesselator::getInstance(); float br = 0.1f; @@ -777,9 +842,11 @@ void ItemInHandRenderer::renderTex(float a, Icon* slot) { } void ItemInHandRenderer::renderWater(float a) { + minecraft->textures->bindTexture(&UNDERWATER_LOCATION); + Tesselator* t = Tesselator::getInstance(); - float br = mc->player->getBrightness(a); + float br = minecraft->player->getBrightness(a); glColor4f(br, br, br, 0.5f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -794,8 +861,8 @@ void ItemInHandRenderer::renderWater(float a) { float y1 = +1; float z0 = -0.5f; - float uo = -mc->player->yRot / 64.0f; - float vo = +mc->player->xRot / 64.0f; + float uo = -minecraft->player->yRot / 64.0f; + float vo = +minecraft->player->xRot / 64.0f; t->begin(); t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(size + uo), @@ -815,7 +882,15 @@ void ItemInHandRenderer::renderWater(float a) { void ItemInHandRenderer::renderFire(float a) { Tesselator* t = Tesselator::getInstance(); - glColor4f(1, 1, 1, 0.9f); + + unsigned int col = Minecraft::GetInstance()->getColourTable()->getColor( + eMinecraftColour_Fire_Overlay); + float aCol = ((col >> 24) & 0xFF) / 255.0f; + float rCol = ((col >> 16) & 0xFF) / 255.0f; + float gCol = ((col >> 8) & 0xFF) / 255.0; + float bCol = (col & 0xFF) / 255.0; + + glColor4f(rCol, gCol, bCol, aCol); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -823,6 +898,8 @@ void ItemInHandRenderer::renderFire(float a) { for (int i = 0; i < 2; i++) { glPushMatrix(); Icon* slot = Tile::fire->getTextureLayer(1); + minecraft->textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); // TODO: Get this from Icon float u0 = slot->getU0(true); float u1 = slot->getU1(true); @@ -856,7 +933,7 @@ void ItemInHandRenderer::renderFire(float a) { void ItemInHandRenderer::tick() { oHeight = height; - std::shared_ptr player = mc->player; + std::shared_ptr player = minecraft->player; std::shared_ptr nextTile = player->inventory->getSelected(); bool matches = diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.h index 682b3c183..5be62cbbe 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemInHandRenderer.h @@ -3,18 +3,24 @@ class Minecraft; class ItemInstance; class Minimap; -class Mob; +class LivingEntity; class TileRenderer; class Tesselator; class ItemInHandRenderer { +public: + // 4J - made these public + static ResourceLocation ENCHANT_GLINT_LOCATION; + static ResourceLocation MAP_BACKGROUND_LOCATION; + static ResourceLocation UNDERWATER_LOCATION; + private: - Minecraft* mc; + Minecraft* minecraft; std::shared_ptr selectedItem; float height; float oHeight; TileRenderer* tileRenderer; - static int list, listGlint; + static int listItem, listGlint, listTerrain; public: // 4J Stu - Made public so we can use it from ItemFramRenderer @@ -24,12 +30,13 @@ public: ItemInHandRenderer( Minecraft* mc, bool optimisedMinimap = true); // 4J Added optimisedMinimap param - void renderItem(std::shared_ptr mob, + void renderItem(std::shared_ptr mob, std::shared_ptr item, int layer, bool setColor = true); // 4J added setColor parameter - static void renderItem3D(Tesselator* t, float u0, float v0, float u1, - float v1, int width, int height, float depth, - bool isGlint); // 4J added isGlint parameter + static void renderItem3D( + Tesselator* t, float u0, float v0, float u1, float v1, int width, + int height, float depth, bool isGlint, + bool isTerrain); // 4J added isGlint and isTerrain parameter public: void render(float a); void renderScreenEffect(float a); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index 801ee9e97..d84974bc5 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -10,14 +10,19 @@ #include "../../../Minecraft.World/Util/StringHelpers.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.h" #include "../../GameState/Options.h" +#include "../../Textures/TextureAtlas.h" + +#ifdef _XBOX +extern IDirect3DDevice9* g_pD3DDevice; +#endif ItemRenderer::ItemRenderer() : EntityRenderer() { random = new Random(); setColor = true; blitOffset = 0; - this->shadowRadius = 0.15f; - this->shadowStrength = 0.75f; + shadowRadius = 0.15f; + shadowStrength = 0.75f; // 4J added m_bItemFrame = false; @@ -25,15 +30,38 @@ ItemRenderer::ItemRenderer() : EntityRenderer() { ItemRenderer::~ItemRenderer() { delete random; } +ResourceLocation* ItemRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr itemEntity = + std::dynamic_pointer_cast(entity); + return getTextureLocation(itemEntity->getItem()->getIconType()); +} + +ResourceLocation* ItemRenderer::getTextureLocation(int iconType) { + if (iconType == Icon::TYPE_TERRAIN) { + return &TextureAtlas::LOCATION_BLOCKS; // L"/terrain.png")); + } else { +#ifdef _XBOX + // 4J - make sure we've got linear sampling on minification here as + // non-mipmapped things like this currently default to having point + // sampling, which makes very small icons render rather badly + g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); +#endif + return &TextureAtlas::LOCATION_ITEMS; // L"/gui/items.png")); + } +} + void ItemRenderer::render(std::shared_ptr _itemEntity, double x, double y, double z, float rot, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr itemEntity = std::dynamic_pointer_cast(_itemEntity); + bindTexture(itemEntity); random->setSeed(187); std::shared_ptr item = itemEntity->getItem(); + if (item->getItem() == NULL) return; glPushMatrix(); float bob = @@ -46,11 +74,13 @@ void ItemRenderer::render(std::shared_ptr _itemEntity, double x, if (itemEntity->getItem()->count > 1) count = 2; if (itemEntity->getItem()->count > 5) count = 3; if (itemEntity->getItem()->count > 20) count = 4; + if (itemEntity->getItem()->count > 40) count = 5; glTranslatef((float)x, (float)y + bob, (float)z); glEnable(GL_RESCALE_NORMAL); Tile* tile = Tile::tiles[item->id]; + if (item->getIconType() == Icon::TYPE_TERRAIN && tile != NULL && TileRenderer::canRender(tile->getRenderShape())) { glRotatef(spin, 0, 1, 0); @@ -61,7 +91,6 @@ void ItemRenderer::render(std::shared_ptr _itemEntity, double x, glRotatef(-90, 0, 1, 0); } - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" float s = 1 / 4.0f; int shape = tile->getRenderShape(); if (shape == Tile::SHAPE_CROSS_TEXTURE || shape == Tile::SHAPE_STEM || @@ -85,7 +114,8 @@ void ItemRenderer::render(std::shared_ptr _itemEntity, double x, tileRenderer->renderTile(tile, item->getAuxValue(), br); glPopMatrix(); } - } else if (item->getItem()->hasMultipleSpriteLayers()) { + } else if (item->getIconType() == Icon::TYPE_ITEM && + item->getItem()->hasMultipleSpriteLayers()) { if (m_bItemFrame) { glScalef(1 / 1.95f, 1 / 1.95f, 1 / 1.95f); glTranslatef(0, -0.05f, 0); @@ -94,7 +124,7 @@ void ItemRenderer::render(std::shared_ptr _itemEntity, double x, glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f); } - bindTexture(TN_GUI_ITEMS); // 4J was "/gui/items.png" + bindTexture(&TextureAtlas::LOCATION_ITEMS); // 4J was "/gui/items.png" for (int layer = 0; layer <= 1; layer++) { random->setSeed(187); @@ -129,13 +159,9 @@ void ItemRenderer::render(std::shared_ptr _itemEntity, double x, // 4J Stu - For rendering the static compass, we give it a non-zero aux // value if (item->id == Item::compass_Id) item->setAuxValue(255); - Icon* icon = item->getIcon(); if (item->id == Item::compass_Id) item->setAuxValue(0); - if (item->getIconType() == Icon::TYPE_TERRAIN) { - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - } else { - bindTexture(TN_GUI_ITEMS); // 4J was L"/gui/items.png" - } + + Icon* icon = item->getIcon(); if (setColor) { int col = Item::items[item->id]->getColor(item, 0); float red = ((col >> 16) & 0xff) / 255.0f; @@ -218,25 +244,31 @@ void ItemRenderer::renderItemBillboard(std::shared_ptr entity, for (int i = 0; i < count; i++) { glTranslatef(0, 0, width + margin); + + bool bIsTerrain = false; if (item->getIconType() == Icon::TYPE_TERRAIN && Tile::tiles[item->id] != NULL) { - bindTexture(TN_TERRAIN); // Was L"/terrain.png"); + bIsTerrain = true; + bindTexture(&TextureAtlas::LOCATION_BLOCKS); // TODO: Do this + // sanely by Icon } else { - bindTexture(TN_GUI_ITEMS); // L"/gui/items.png"); + bindTexture(&TextureAtlas::LOCATION_ITEMS); // TODO: Do this + // sanely by Icon } + glColor4f(red, green, blue, 1); // 4J Stu - u coords were swapped in Java // ItemInHandRenderer::renderItem3D(t, u1, v0, u0, v1, // icon->getSourceWidth(), icon->getSourceHeight(), width, false); ItemInHandRenderer::renderItem3D( t, u0, v0, u1, v1, icon->getSourceWidth(), - icon->getSourceHeight(), width, false); + icon->getSourceHeight(), width, false, bIsTerrain); if (item != NULL && item->isFoil()) { glDepthFunc(GL_EQUAL); glDisable(GL_LIGHTING); entityRenderDispatcher->textures->bindTexture( - TN__BLUR__MISC_GLINT); // was L"%blur%/misc/glint.png"); + &ItemInHandRenderer::ENCHANT_GLINT_LOCATION); glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_ONE); float br = 0.76f; @@ -251,7 +283,7 @@ void ItemRenderer::renderItemBillboard(std::shared_ptr entity, glRotatef(-50, 0, 0, 1); ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, - true); + true, bIsTerrain); glPopMatrix(); glPushMatrix(); glScalef(ss, ss, ss); @@ -260,7 +292,7 @@ void ItemRenderer::renderItemBillboard(std::shared_ptr entity, glTranslatef(-sx, 0, 0); glRotatef(10, 0, 0, 1); ItemInHandRenderer::renderItem3D(t, 0, 0, 1, 1, 255, 255, width, - true); + true, bIsTerrain); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glDisable(GL_BLEND); @@ -307,17 +339,12 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, renderGuiItem(font, textures, item, x, y, fScale, fScale, fAlpha, true); } -#ifdef _XBOX -extern IDirect3DDevice9* g_pD3DDevice; -#endif - // 4J - this used to take x and y as ints, and no scale and alpha - but this // interface is now implemented as a wrapper round this more fully featured one void ItemRenderer::renderGuiItem(Font* font, Textures* textures, std::shared_ptr item, float x, float y, float fScaleX, float fScaleY, float fAlpha, bool useCompiled) { - if (!item) return; int itemId = item->id; int itemAuxValue = item->getAuxValue(); Icon* itemIcon = item->getIcon(); @@ -326,20 +353,17 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, TileRenderer::canRender(Tile::tiles[itemId]->getRenderShape())) { PIXBeginNamedEvent(0, "3D gui item render %d\n", itemId); MemSect(31); - textures->bindTexture(TN_TERRAIN); // L"/terrain.png")); + textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); MemSect(0); Tile* tile = Tile::tiles[itemId]; glPushMatrix(); // 4J - original code left here for reference - // 4jcraft: re-enable said original code to fix hotbar block rendering -#if 1 - glTranslatef((float)(x), (float)(y), 0.0f); - // glScalef(fScale, fScale, fScale); - glScalef(fScaleX, fScaleY, - 1.0f); // 4jcraft: tweaked to use the new variables - glTranslatef(-2.0f, 3.0f, -3.0f + blitOffset); - glScalef(10.0f, 10.0f, 10.0f); +#if 0 + glTranslatef((float)(x), (float)(y), 0.0f); + glScalef(fScale, fScale, fScale); + glTranslatef(-2.0f,3.0f, -3.0f + blitOffset); + glScalef(10.0f, 10.0f, 10.0f); glTranslatef(1.0f, 0.5f, 8.0f); glScalef(1.0f, 1.0f, -1.0f); glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); @@ -360,8 +384,9 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glRotatef(45.0f, 0.0f, 1.0f, 0.0f); // Rotate round y axis (centre at origin) #endif - // 4J-PB - pass the alpha value in - the grass block render has the top - // surface coloured differently to the rest of the block + // 4J-PB - pass the alpha value in - the grass block + // render has the top surface coloured differently to + // the rest of the block glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); @@ -371,7 +396,9 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, PIXBeginNamedEvent(0, "Potion gui item render %d\n", itemIcon); // special double-layered glDisable(GL_LIGHTING); - textures->bindTexture(TN_GUI_ITEMS); // "/gui/items.png" + + ResourceLocation* location = getTextureLocation(item->getIconType()); + textures->bindTexture(location); for (int layer = 0; layer <= 1; layer++) { Icon* fillingIcon = @@ -397,14 +424,17 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glDisable(GL_LIGHTING); MemSect(31); if (item->getIconType() == Icon::TYPE_TERRAIN) { - textures->bindTexture(TN_TERRAIN); // L"/terrain.png")); + textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); // L"/terrain.png")); } else { textures->bindTexture( - TN_GUI_ITEMS); // L"/gui/items.png")); + &TextureAtlas::LOCATION_ITEMS); // L"/gui/items.png")); #ifdef _XBOX - // 4J - make sure we've got linear sampling on - // minification here as non-mipmapped things - // like this currently + // 4J - make sure we've got + // linear sampling on + // minification here as + // non-mipmapped things like + // this currently // default to having point sampling, which makes very small icons // render rather badly g_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); @@ -474,7 +504,8 @@ void ItemRenderer::renderAndDecorateItem( glDisable(GL_LIGHTING); glDepthMask(false); textures->bindTexture( - TN__BLUR__MISC_GLINT); // 4J was "%blur%/misc/glint.png" + &ItemInHandRenderer:: + ENCHANT_GLINT_LOCATION); // 4J was "%blur%/misc/glint.png" blitOffset -= 50; if (!isConstantBlended) glEnable(GL_BLEND); @@ -585,10 +616,6 @@ void ItemRenderer::renderGuiItemDecorations(Font* font, Textures* textures, return; } - glEnable(GL_BLEND); - RenderManager.StateSetBlendFactor(0xffffff | - (((unsigned int)(fAlpha * 0xff)) << 24)); - glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); if (item->count > 1 || !countText.empty() || item->GetForceNumberDisplay()) { MemSect(31); @@ -605,7 +632,7 @@ void ItemRenderer::renderGuiItemDecorations(Font* font, Textures* textures, glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); font->drawShadow(amount, x + 19 - 2 - font->width(amount), y + 6 + 3, - 0xffffff); + 0xffffff | (((unsigned int)(fAlpha * 0xff)) << 24)); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); } diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.h index d3e0df372..4f0df8bbf 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.h @@ -9,7 +9,7 @@ class ItemEntity; class ItemRenderer : public EntityRenderer { private: // TileRenderer *tileRenderer; // 4J - removed - this is shadowing the - //tilerenderer from entityrenderer + // tilerenderer from entityrenderer Random* random; bool m_bItemFrame; @@ -21,6 +21,9 @@ public: virtual ~ItemRenderer(); virtual void render(std::shared_ptr _itemEntity, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + virtual ResourceLocation* getTextureLocation(int iconType); private: virtual void renderItemBillboard(std::shared_ptr entity, diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.cpp index 51d3a9ba3..79171fc78 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.cpp @@ -1,6 +1,7 @@ #include "../../Platform/stdafx.h" #include "ItemSpriteRenderer.h" #include "EntityRenderDispatcher.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.projectile.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.item.alchemy.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" @@ -32,7 +33,7 @@ void ItemSpriteRenderer::render(std::shared_ptr e, double x, double y, glTranslatef((float)x, (float)y, (float)z); glEnable(GL_RESCALE_NORMAL); glScalef(1 / 2.0f, 1 / 2.0f, 1 / 2.0f); - bindTexture(TN_GUI_ITEMS); // 4J - was L"/gui/items.png" + bindTexture(e); Tesselator* t = Tesselator::getInstance(); if (icon == PotionItem::getTexture(PotionItem::THROWABLE_ICON)) { @@ -79,4 +80,9 @@ void ItemSpriteRenderer::renderIcon(Tesselator* t, Icon* icon) { t->vertexUV((float)(0 - xo), (float)(r - yo), (float)(0), (float)(u0), (float)(v0)); t->end(); +} + +ResourceLocation* ItemSpriteRenderer::getTextureLocation( + std::shared_ptr mob) { + return &TextureAtlas::LOCATION_ITEMS; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.h index 103e5aaa6..5f2b13e42 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemSpriteRenderer.h @@ -13,6 +13,7 @@ public: // ItemSpriteRenderer(Item *icon); virtual void render(std::shared_ptr e, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); private: void renderIcon(Tesselator* t, Icon* icon); diff --git a/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.cpp index b75b36ae5..932449062 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.cpp @@ -3,29 +3,22 @@ #include "../Models/LavaSlimeModel.h" #include "LavaSlimeRenderer.h" +ResourceLocation LavaSlimeRenderer::MAGMACUBE_LOCATION = + ResourceLocation(TN_MOB_LAVA); + LavaSlimeRenderer::LavaSlimeRenderer() : MobRenderer(new LavaSlimeModel(), .25f) { this->modelVersion = ((LavaSlimeModel*)model)->getModelVersion(); } -void LavaSlimeRenderer::render(std::shared_ptr _mob, double x, double y, - double z, float rot, float a) { - // 4J - original version used generics and thus had an input parameter of - // type LavaSlime rather than std::shared_ptr we have here - do - // some casting around instead - std::shared_ptr mob = std::dynamic_pointer_cast(_mob); - int modelVersion = ((LavaSlimeModel*)model)->getModelVersion(); - if (modelVersion != this->modelVersion) { - this->modelVersion = modelVersion; - model = new LavaSlimeModel(); - app.DebugPrintf("new lava slime model\n"); - } - MobRenderer::render(mob, x, y, z, rot, a); +ResourceLocation* LavaSlimeRenderer::getTextureLocation( + std::shared_ptr mob) { + return &MAGMACUBE_LOCATION; } -void LavaSlimeRenderer::scale(std::shared_ptr _slime, float a) { +void LavaSlimeRenderer::scale(std::shared_ptr _slime, float a) { // 4J - original version used generics and thus had an input parameter of - // type LavaSlime rather than std::shared_ptr we have here - do some + // type LavaSlime rather than shared_ptr we have here - do some // casting around instead std::shared_ptr slime = std::dynamic_pointer_cast(_slime); diff --git a/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.h index 0afc0b515..ab8d7d4d4 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/LavaSlimeRenderer.h @@ -1,17 +1,15 @@ #pragma once - #include "MobRenderer.h" class LavaSlimeRenderer : public MobRenderer { private: int modelVersion; + static ResourceLocation MAGMACUBE_LOCATION; public: LavaSlimeRenderer(); - - virtual void render(std::shared_ptr _mob, double x, double y, - double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - virtual void scale(std::shared_ptr _slime, float a); + virtual void scale(std::shared_ptr _slime, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.cpp new file mode 100644 index 000000000..3988e9af4 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.cpp @@ -0,0 +1,36 @@ +#include "../../Platform/stdafx.h" +#include "LeashKnotRenderer.h" +#include "../Models/LeashKnotModel.h" + +ResourceLocation LeashKnotRenderer::KNOT_LOCATION = + ResourceLocation(TN_ITEM_LEASHKNOT); + +LeashKnotRenderer::LeashKnotRenderer() : EntityRenderer() { + model = new LeashKnotModel(); +} + +LeashKnotRenderer::~LeashKnotRenderer() { delete model; } + +void LeashKnotRenderer::render(std::shared_ptr entity, double x, + double y, double z, float rot, float a) { + glPushMatrix(); + glDisable(GL_CULL_FACE); + + glTranslatef((float)x, (float)y, (float)z); + + float scale = 1 / 16.0f; + glEnable(GL_RESCALE_NORMAL); + glScalef(-1, -1, 1); + + glEnable(GL_ALPHA_TEST); + + bindTexture(entity); + model->render(entity, 0, 0, 0, 0, 0, scale, true); + + glPopMatrix(); +} + +ResourceLocation* LeashKnotRenderer::getTextureLocation( + std::shared_ptr entity) { + return &KNOT_LOCATION; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.h new file mode 100644 index 000000000..fbae3a06c --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/LeashKnotRenderer.h @@ -0,0 +1,20 @@ +#pragma once +#include "EntityRenderer.h" + +class LeashKnotModel; + +class LeashKnotRenderer : public EntityRenderer { +private: + static ResourceLocation KNOT_LOCATION; + LeashKnotModel* model; + +public: + LeashKnotRenderer(); + ~LeashKnotRenderer(); + virtual void render(std::shared_ptr entity, double x, double y, + double z, float rot, float a); + +protected: + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp new file mode 100644 index 000000000..d2183890e --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp @@ -0,0 +1,616 @@ +#include "../../Platform/stdafx.h" +#include "LivingEntityRenderer.h" +#include "../Lighting.h" +#include "../Cube.h" +#include "../Models/ModelPart.h" +#include "EntityRenderDispatcher.h" +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../../Minecraft.World/Entities/Mobs/Arrow.h" +#include "../../../Minecraft.World/Util/Mth.h" +#include "../../../Minecraft.World/Player/Player.h" + +ResourceLocation LivingEntityRenderer::ENCHANT_GLINT_LOCATION = + ResourceLocation(TN__BLUR__MISC_GLINT); +int LivingEntityRenderer::MAX_ARMOR_LAYERS = 4; + +LivingEntityRenderer::LivingEntityRenderer(Model* model, float shadow) { + this->model = model; + shadowRadius = shadow; + armor = NULL; +} + +void LivingEntityRenderer::setArmor(Model* armor) { this->armor = armor; } + +float LivingEntityRenderer::rotlerp(float from, float to, float a) { + float diff = to - from; + while (diff < -180) diff += 360; + while (diff >= 180) diff -= 360; + return from + a * diff; +} + +void LivingEntityRenderer::render(std::shared_ptr _mob, double x, + double y, double z, float rot, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(_mob); + + glPushMatrix(); + glDisable(GL_CULL_FACE); + + model->attackTime = getAttackAnim(mob, a); + if (armor != NULL) armor->attackTime = model->attackTime; + model->riding = mob->isRiding(); + if (armor != NULL) armor->riding = model->riding; + model->young = mob->isBaby(); + if (armor != NULL) armor->young = model->young; + + /*try*/ + { + float bodyRot = rotlerp(mob->yBodyRotO, mob->yBodyRot, a); + float headRot = rotlerp(mob->yHeadRotO, mob->yHeadRot, a); + + if (mob->isRiding() && mob->riding->instanceof(eTYPE_LIVINGENTITY)) { + std::shared_ptr riding = + std::dynamic_pointer_cast(mob->riding); + bodyRot = rotlerp(riding->yBodyRotO, riding->yBodyRot, a); + + float headDiff = Mth::wrapDegrees(headRot - bodyRot); + if (headDiff < -85) headDiff = -85; + if (headDiff >= 85) headDiff = +85; + bodyRot = headRot - headDiff; + if (headDiff * headDiff > 50 * 50) { + bodyRot += headDiff * 0.2f; + } + } + + float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a); + + setupPosition(mob, x, y, z); + + float bob = getBob(mob, a); + setupRotations(mob, bob, bodyRot, a); + + float fScale = 1 / 16.0f; + glEnable(GL_RESCALE_NORMAL); + glScalef(-1, -1, 1); + + scale(mob, a); + glTranslatef(0, -24 * fScale - 0.125f / 16.0f, 0); + + float ws = mob->walkAnimSpeedO + + (mob->walkAnimSpeed - mob->walkAnimSpeedO) * a; + float wp = mob->walkAnimPos - mob->walkAnimSpeed * (1 - a); + if (mob->isBaby()) { + wp *= 3.0f; + } + + if (ws > 1) ws = 1; + + glEnable(GL_ALPHA_TEST); + model->prepareMobModel(mob, wp, ws, a); + renderModel(mob, wp, ws, bob, headRot - bodyRot, headRotx, fScale); + + for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { + int armorType = prepareArmor(mob, i, a); + if (armorType > 0) { + armor->prepareMobModel(mob, wp, ws, a); + armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, + fScale, true); + if ((armorType & 0xf0) == 16) { + prepareSecondPassArmor(mob, i, a); + armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, + fScale, true); + } + // 4J - added condition here for rendering player as part of the + // gui. Avoiding rendering the glint here as it involves using + // its own blending, and for gui rendering we are globally + // blending to be able to offer user configurable gui opacity. + // Note that I really don't know why GL_BLEND is turned off at + // the end of the first armour layer anyway, or why alpha + // testing is turned on... but we definitely don't want to be + // turning blending off during the gui render. + if (!entityRenderDispatcher->isGuiRender) { + if ((armorType & 0xf) == 0xf) { + float time = mob->tickCount + a; + bindTexture(&ENCHANT_GLINT_LOCATION); + glEnable(GL_BLEND); + float br = 0.5f; + glColor4f(br, br, br, 1); + glDepthFunc(GL_EQUAL); + glDepthMask(false); + + for (int j = 0; j < 2; j++) { + glDisable(GL_LIGHTING); + float brr = 0.76f; + glColor4f(0.5f * brr, 0.25f * brr, 0.8f * brr, 1); + glBlendFunc(GL_SRC_COLOR, GL_ONE); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + float uo = time * (0.001f + j * 0.003f) * 20; + float ss = 1 / 3.0f; + glScalef(ss, ss, ss); + glRotatef(30 - (j) * 60.0f, 0, 0, 1); + glTranslatef(0, uo, 0); + glMatrixMode(GL_MODELVIEW); + armor->render(mob, wp, ws, bob, headRot - bodyRot, + headRotx, fScale, false); + } + + glColor4f(1, 1, 1, 1); + glMatrixMode(GL_TEXTURE); + glDepthMask(true); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_LIGHTING); + glDisable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + } + glDisable(GL_BLEND); + } + glEnable(GL_ALPHA_TEST); + } + } + glDepthMask(true); + + additionalRendering(mob, a); + float br = mob->getBrightness(a); + int overlayColor = getOverlayColor(mob, br, a); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + + if (((overlayColor >> 24) & 0xff) > 0 || mob->hurtTime > 0 || + mob->deathTime > 0) { + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthFunc(GL_EQUAL); + + // 4J - changed these renders to not use the compiled version of + // their models, because otherwise the render states set about (in + // particular the depth & alpha test) don't work with our command + // buffer versions + if (mob->hurtTime > 0 || mob->deathTime > 0) { + glColor4f(br, 0, 0, 0.4f); + model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, + fScale, false); + for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { + if (prepareArmorOverlay(mob, i, a) >= 0) { + glColor4f(br, 0, 0, 0.4f); + armor->render(mob, wp, ws, bob, headRot - bodyRot, + headRotx, fScale, false); + } + } + } + + if (((overlayColor >> 24) & 0xff) > 0) { + float r = ((overlayColor >> 16) & 0xff) / 255.0f; + float g = ((overlayColor >> 8) & 0xff) / 255.0f; + float b = ((overlayColor) & 0xff) / 255.0f; + float aa = ((overlayColor >> 24) & 0xff) / 255.0f; + glColor4f(r, g, b, aa); + model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, + fScale, false); + for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { + if (prepareArmorOverlay(mob, i, a) >= 0) { + glColor4f(r, g, b, aa); + armor->render(mob, wp, ws, bob, headRot - bodyRot, + headRotx, fScale, false); + } + } + } + + glDepthFunc(GL_LEQUAL); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glEnable(GL_TEXTURE_2D); + } + glDisable(GL_RESCALE_NORMAL); + } + /* catch (Exception e) + { + e.printStackTrace(); + }*/ + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_CULL_FACE); + + glPopMatrix(); + + MemSect(31); + renderName(mob, x, y, z); + MemSect(0); +} + +void LivingEntityRenderer::renderModel(std::shared_ptr mob, + float wp, float ws, float bob, + float headRotMinusBodyRot, + float headRotx, float scale) { + bindTexture(mob); + if (!mob->isInvisible()) { + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, + true); + } else if (!mob->isInvisibleTo(std::dynamic_pointer_cast( + Minecraft::GetInstance()->player))) { + glPushMatrix(); + glColor4f(1, 1, 1, 0.15f); + glDepthMask(false); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glAlphaFunc(GL_GREATER, 1.0f / 255.0f); + model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, + true); + glDisable(GL_BLEND); + glAlphaFunc(GL_GREATER, .1f); + glPopMatrix(); + glDepthMask(true); + } else { + model->setupAnim(wp, ws, bob, headRotMinusBodyRot, headRotx, scale, + mob); + } +} + +void LivingEntityRenderer::setupPosition(std::shared_ptr mob, + double x, double y, double z) { + glTranslatef((float)x, (float)y, (float)z); +} + +void LivingEntityRenderer::setupRotations(std::shared_ptr mob, + float bob, float bodyRot, float a) { + glRotatef(180 - bodyRot, 0, 1, 0); + if (mob->deathTime > 0) { + float fall = (mob->deathTime + a - 1) / 20.0f * 1.6f; + fall = sqrt(fall); + if (fall > 1) fall = 1; + glRotatef(fall * getFlipDegrees(mob), 0, 0, 1); + } else { + std::wstring name = mob->getAName(); + if (name == L"Dinnerbone" || name == L"Grumm") { + if (!mob->instanceof(eTYPE_PLAYER) || + !std::dynamic_pointer_cast(mob)->isCapeHidden()) { + glTranslatef(0, mob->bbHeight + 0.1f, 0); + glRotatef(180, 0, 0, 1); + } + } + } +} + +float LivingEntityRenderer::getAttackAnim(std::shared_ptr mob, + float a) { + return mob->getAttackAnim(a); +} + +float LivingEntityRenderer::getBob(std::shared_ptr mob, float a) { + return (mob->tickCount + a); +} + +void LivingEntityRenderer::additionalRendering( + std::shared_ptr mob, float a) {} + +void LivingEntityRenderer::renderArrows(std::shared_ptr mob, + float a) { + int arrowCount = mob->getArrowCount(); + if (arrowCount > 0) { + std::shared_ptr arrow = std::shared_ptr( + new Arrow(mob->level, mob->x, mob->y, mob->z)); + Random random = Random(mob->entityId); + Lighting::turnOff(); + for (int i = 0; i < arrowCount; i++) { + glPushMatrix(); + ModelPart* modelPart = model->getRandomModelPart(random); + Cube* cube = + modelPart->cubes[random.nextInt(modelPart->cubes.size())]; + modelPart->translateTo(1 / 16.0f); + float xd = random.nextFloat(); + float yd = random.nextFloat(); + float zd = random.nextFloat(); + float xo = (cube->x0 + (cube->x1 - cube->x0) * xd) / 16.0f; + float yo = (cube->y0 + (cube->y1 - cube->y0) * yd) / 16.0f; + float zo = (cube->z0 + (cube->z1 - cube->z0) * zd) / 16.0f; + glTranslatef(xo, yo, zo); + xd = xd * 2 - 1; + yd = yd * 2 - 1; + zd = zd * 2 - 1; + if (true) { + xd *= -1; + yd *= -1; + zd *= -1; + } + float sd = (float)sqrt(xd * xd + zd * zd); + arrow->yRotO = arrow->yRot = (float)(atan2(xd, zd) * 180 / PI); + arrow->xRotO = arrow->xRot = (float)(atan2(yd, sd) * 180 / PI); + double x = 0; + double y = 0; + double z = 0; + float yRot = 0; + entityRenderDispatcher->render(arrow, x, y, z, yRot, a); + glPopMatrix(); + } + Lighting::turnOn(); + } +} + +int LivingEntityRenderer::prepareArmorOverlay(std::shared_ptr mob, + int layer, float a) { + return prepareArmor(mob, layer, a); +} + +int LivingEntityRenderer::prepareArmor(std::shared_ptr mob, + int layer, float a) { + return -1; +} + +void LivingEntityRenderer::prepareSecondPassArmor( + std::shared_ptr mob, int layer, float a) {} + +float LivingEntityRenderer::getFlipDegrees(std::shared_ptr mob) { + return 90; +} + +int LivingEntityRenderer::getOverlayColor(std::shared_ptr mob, + float br, float a) { + return 0; +} + +void LivingEntityRenderer::scale(std::shared_ptr mob, float a) {} + +void LivingEntityRenderer::renderName(std::shared_ptr mob, + double x, double y, double z) { + if (shouldShowName(mob) || Minecraft::renderDebug()) { + float size = 1.60f; + float s = 1 / 60.0f * size; + double dist = mob->distanceToSqr(entityRenderDispatcher->cameraEntity); + + float maxDist = mob->isSneaking() ? 32 : 64; + + if (dist < maxDist * maxDist) { + std::wstring msg = mob->getDisplayName(); + + if (!msg.empty()) { + if (mob->isSneaking()) { + if (app.GetGameSettings(eGameSetting_DisplayHUD) == 0) { + // 4J-PB - turn off gamertag render + return; + } + + if (app.GetGameHostOption(eGameHostOption_Gamertags) == 0) { + // turn off gamertags if the host has set them off + return; + } + + Font* font = getFont(); + glPushMatrix(); + glTranslatef((float)x + 0, (float)y + mob->bbHeight + 0.5f, + (float)z); + glNormal3f(0, 1, 0); + + glRotatef(-entityRenderDispatcher->playerRotY, 0, 1, 0); + glRotatef(entityRenderDispatcher->playerRotX, 1, 0, 0); + + glScalef(-s, -s, s); + glDisable(GL_LIGHTING); + + glTranslatef(0, 0.25f / s, 0); + glDepthMask(false); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + Tesselator* t = Tesselator::getInstance(); + + glDisable(GL_TEXTURE_2D); + t->begin(); + int w = font->width(msg) / 2; + t->color(0.f, 0.f, 0.f, 0.25f); + t->vertex(-w - 1, -1, 0); + t->vertex(-w - 1, +8, 0); + t->vertex(+w + 1, +8, 0); + t->vertex(+w + 1, -1, 0); + t->end(); + glEnable(GL_TEXTURE_2D); + glDepthMask(true); + font->draw(msg, -font->width(msg) / 2, 0, 0x20ffffff); + glEnable(GL_LIGHTING); + glDisable(GL_BLEND); + glColor4f(1, 1, 1, 1); + glPopMatrix(); + } else { + renderNameTags(mob, x, y, z, msg, s, dist); + } + } + } + } +} + +bool LivingEntityRenderer::shouldShowName(std::shared_ptr mob) { + return Minecraft::renderNames() && + mob != entityRenderDispatcher->cameraEntity && + !mob->isInvisibleTo(Minecraft::GetInstance()->player) && + mob->rider.lock() == NULL; +} + +void LivingEntityRenderer::renderNameTags(std::shared_ptr mob, + double x, double y, double z, + const std::wstring& msg, float scale, + double dist) { + if (mob->isSleeping()) { + renderNameTag(mob, msg, x, y - 1.5f, z, 64); + } else { + renderNameTag(mob, msg, x, y, z, 64); + } +} + +// 4J Added parameter for color here so that we can colour players names +void LivingEntityRenderer::renderNameTag(std::shared_ptr mob, + const std::wstring& name, double x, + double y, double z, int maxDist, + int color /*= 0xff000000*/) { + if (app.GetGameSettings(eGameSetting_DisplayHUD) == 0) { + // 4J-PB - turn off gamertag render + return; + } + + if (app.GetGameHostOption(eGameHostOption_Gamertags) == 0) { + // turn off gamertags if the host has set them off + return; + } + + float dist = mob->distanceTo(entityRenderDispatcher->cameraEntity); + + if (dist > maxDist) { + return; + } + + Font* font = getFont(); + + float size = 1.60f; + float s = 1 / 60.0f * size; + + glPushMatrix(); + glTranslatef((float)x + 0, (float)y + 2.3f, (float)z); + glNormal3f(0, 1, 0); + + glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); + glRotatef(this->entityRenderDispatcher->playerRotX, 1, 0, 0); + + glScalef(-s, -s, s); + glDisable(GL_LIGHTING); + + // 4J Stu - If it's beyond readable distance, then just render a coloured + // box + int readableDist = PLAYER_NAME_READABLE_FULLSCREEN; + if (!RenderManager.IsHiDef()) { + readableDist = PLAYER_NAME_READABLE_DISTANCE_SD; + } else if (app.GetLocalPlayerCount() > 2) { + readableDist = PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN; + } + + float textOpacity = 1.0f; + if (dist >= readableDist) { + int diff = dist - readableDist; + + textOpacity /= (diff / 2); + + if (diff > readableDist) textOpacity = 0.0f; + } + + if (textOpacity < 0.0f) textOpacity = 0.0f; + if (textOpacity > 1.0f) textOpacity = 1.0f; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + Tesselator* t = Tesselator::getInstance(); + + int offs = 0; + + std::wstring playerName; + WCHAR wchName[2]; + + if (mob->instanceof(eTYPE_PLAYER)) { + std::shared_ptr player = std::dynamic_pointer_cast(mob); + + if (app.isXuidDeadmau5(player->getXuid())) offs = -10; + +#if defined(__PS3__) || defined(__ORBIS__) + // Check we have all the font characters for this player name + switch (player->GetPlayerNameValidState()) { + case Player::ePlayerNameValid_NotSet: + if (font->AllCharactersValid(name)) { + playerName = name; + player->SetPlayerNameValidState(true); + } else { + memset(wchName, 0, sizeof(WCHAR) * 2); + swprintf(wchName, 2, L"%d", player->getPlayerIndex() + 1); + playerName = wchName; + player->SetPlayerNameValidState(false); + } + break; + case Player::ePlayerNameValid_True: + playerName = name; + break; + case Player::ePlayerNameValid_False: + memset(wchName, 0, sizeof(WCHAR) * 2); + swprintf(wchName, 2, L"%d", player->getPlayerIndex() + 1); + playerName = wchName; + break; + } +#else + playerName = name; +#endif + } else { + playerName = name; + } + + if (textOpacity > 0.0f) { + glColor4f(1.0f, 1.0f, 1.0f, textOpacity); + + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + + glDisable(GL_TEXTURE_2D); + + t->begin(); + int w = font->width(playerName) / 2; + + if (textOpacity < 1.0f) { + t->color(color, 255 * textOpacity); + } else { + t->color(0.0f, 0.0f, 0.0f, 0.25f); + } + t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); + t->vertex((float)(-w - 1), (float)(+8 + offs + 1), (float)(0)); + t->vertex((float)(+w + 1), (float)(+8 + offs + 1), (float)(0)); + t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); + t->end(); + + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + glDepthFunc(GL_ALWAYS); + glLineWidth(2.0f); + t->begin(GL_LINE_STRIP); + t->color(color, 255 * textOpacity); + t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); + t->vertex((float)(-w - 1), (float)(+8 + offs + 1), (float)(0)); + t->vertex((float)(+w + 1), (float)(+8 + offs + 1), (float)(0)); + t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); + t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); + t->end(); + glDepthFunc(GL_LEQUAL); + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_TEXTURE_2D); + font->draw(playerName, -font->width(playerName) / 2, offs, 0x20ffffff); + glEnable(GL_DEPTH_TEST); + + glDepthMask(true); + } + + if (textOpacity < 1.0f) { + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + t->begin(); + int w = font->width(playerName) / 2; + t->color(color, 255); + t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); + t->vertex((float)(-w - 1), (float)(+8 + offs), (float)(0)); + t->vertex((float)(+w + 1), (float)(+8 + offs), (float)(0)); + t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); + t->end(); + glDepthFunc(GL_LEQUAL); + glEnable(GL_TEXTURE_2D); + + glTranslatef(0.0f, 0.0f, -0.04f); + } + + if (textOpacity > 0.0f) { + int textColor = (((int)(textOpacity * 255) << 24) | 0xffffff); + font->draw(playerName, -font->width(playerName) / 2, offs, textColor); + } + + glEnable(GL_LIGHTING); + glDisable(GL_BLEND); + glColor4f(1, 1, 1, 1); + glPopMatrix(); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.h new file mode 100644 index 000000000..b6d73b003 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.h @@ -0,0 +1,61 @@ +#pragma once +#include "../../Textures/ResourceLocation.h" +#include "EntityRenderer.h" +#include "../../../Minecraft.World/Entities/LivingEntity.h" + +class LivingEntity; + +class LivingEntityRenderer : public EntityRenderer { + static const int PLAYER_NAME_READABLE_FULLSCREEN = 16; + static const int PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN = 8; + static const int PLAYER_NAME_READABLE_DISTANCE_SD = 8; + + static ResourceLocation ENCHANT_GLINT_LOCATION; + static int MAX_ARMOR_LAYERS; + +protected: + // Model *model; // 4J Stu - This shadows the one in EntityRenderer + Model* armor; + +public: + LivingEntityRenderer(Model* model, float shadow); + virtual void render(std::shared_ptr mob, double x, double y, + double z, float rot, float a); + virtual void setArmor(Model* armor); + +private: + float rotlerp(float from, float to, float a); + +protected: + virtual void renderModel(std::shared_ptr mob, float wp, + float ws, float bob, float headRotMinusBodyRot, + float headRotx, float scale); + virtual void setupPosition(std::shared_ptr mob, double x, + double y, double z); + virtual void setupRotations(std::shared_ptr mob, float bob, + float bodyRot, float a); + virtual float getAttackAnim(std::shared_ptr mob, float a); + virtual float getBob(std::shared_ptr mob, float a); + virtual void additionalRendering(std::shared_ptr mob, + float a); + virtual void renderArrows(std::shared_ptr mob, float a); + virtual int prepareArmorOverlay(std::shared_ptr mob, + int layer, float a); + virtual int prepareArmor(std::shared_ptr mob, int layer, + float a); + virtual void prepareSecondPassArmor(std::shared_ptr mob, + int layer, float a); + virtual float getFlipDegrees(std::shared_ptr mob); + virtual int getOverlayColor(std::shared_ptr mob, float br, + float a); + virtual void scale(std::shared_ptr mob, float a); + virtual void renderName(std::shared_ptr mob, double x, + double y, double z); + virtual bool shouldShowName(std::shared_ptr mob); + virtual void renderNameTags(std::shared_ptr mob, double x, + double y, double z, const std::wstring& msg, + float scale, double dist); + virtual void renderNameTag(std::shared_ptr mob, + const std::wstring& name, double x, double y, + double z, int maxDist, int color = 0xff000000); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp index ddfdc0be9..b8ca04ad5 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp @@ -1,12 +1,16 @@ #include "../../Platform/stdafx.h" #include "MinecartRenderer.h" #include "../Models/MinecartModel.h" +#include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" +ResourceLocation MinecartRenderer::MINECART_LOCATION(TN_ITEM_CART); + MinecartRenderer::MinecartRenderer() { this->shadowRadius = 0.5f; model = new MinecartModel(); + renderer = new TileRenderer(); } void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, @@ -68,32 +72,76 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, 0); } - if (cart->type != Minecart::RIDEABLE) { - glPushMatrix(); - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - float ss = 12 / 16.0f; - glScalef(ss, ss, ss); + int yOffset = cart->getDisplayOffset(); + Tile* tile = cart->getDisplayTile(); + int tileData = cart->getDisplayData(); + + if (tile != NULL) { + glPushMatrix(); + + bindTexture(&TextureAtlas::LOCATION_BLOCKS); + float ss = 12 / 16.0f; + + glScalef(ss, ss, ss); + glTranslatef(0 / 16.f, yOffset / 16.f, 0 / 16.f); + renderMinecartContents(cart, a, tile, tileData); - // 4J - changes here brought forward from 1.2.3 - if (cart->type == Minecart::CHEST) { - glTranslatef(0 / 16.0f, 8 / 16.0f, 0 / 16.0f); - TileRenderer* tr = new TileRenderer(); - tr->renderTile(Tile::chest, 0, cart->getBrightness(a)); - delete tr; - } else if (cart->type == Minecart::FURNACE) { - glTranslatef(0, 6 / 16.0f, 0); - TileRenderer* tr = new TileRenderer(); - tr->renderTile(Tile::furnace, 0, cart->getBrightness(a)); - delete tr; - } glPopMatrix(); glColor4f(1, 1, 1, 1); + bindTexture(cart); } - bindTexture(TN_ITEM_CART); // 4J - was L"/item/cart.png" + glScalef(-1, -1, 1); + model->render(cart, 0, 0, -0.1f, 0, 0, 1 / 16.0f, true); + glPopMatrix(); + + /* + if (cart->type != Minecart::RIDEABLE) + { + glPushMatrix(); + bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + float ss = 12 / 16.0f; + glScalef(ss, ss, ss); + + // 4J - changes here brought forward from 1.2.3 + if (cart->type == Minecart::CHEST) + { + glTranslatef(0 / 16.0f, 8 / 16.0f, 0 / 16.0f); + TileRenderer *tr = new TileRenderer(); + tr->renderTile(Tile::chest, 0, cart->getBrightness(a)); + delete tr; + } + else if (cart->type == Minecart::FURNACE) + { + glTranslatef(0, 6 / 16.0f, 0); + TileRenderer *tr = new TileRenderer(); + tr->renderTile(Tile::furnace, 0, cart->getBrightness(a)); + delete tr; + } + glPopMatrix(); + glColor4f(1, 1, 1, 1); + } + + bindTexture(TN_ITEM_CART); // 4J - was L"/item/cart.png" glScalef(-1, -1, 1); // model.render(0, 0, cart->getLootContent() * 7.1f - 0.1f, 0, 0, 1 / // 16.0f); model->render(cart, 0, 0, -0.1f, 0, 0, 1 / 16.0f, true); glPopMatrix(); + */ } + +ResourceLocation* MinecartRenderer::getTextureLocation( + std::shared_ptr mob) { + return &MINECART_LOCATION; +} + +void MinecartRenderer::renderMinecartContents(std::shared_ptr cart, + float a, Tile* tile, + int tileData) { + float brightness = cart->getBrightness(a); + + glPushMatrix(); + renderer->renderTile(tile, tileData, brightness); + glPopMatrix(); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.h index 5c0ee7c35..c53d3e032 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.h @@ -1,12 +1,23 @@ #pragma once #include "EntityRenderer.h" +class Minecart; + class MinecartRenderer : public EntityRenderer { +private: + static ResourceLocation MINECART_LOCATION; + protected: Model* model; + TileRenderer* renderer; public: MinecartRenderer(); - void render(std::shared_ptr _cart, double x, double y, double z, - float rot, float a); + virtual void render(std::shared_ptr _cart, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); + +protected: + virtual void renderMinecartContents(std::shared_ptr cart, float a, + Tile* tile, int tileData); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.cpp new file mode 100644 index 000000000..90f2da54a --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.cpp @@ -0,0 +1,15 @@ +#include "../../Platform/stdafx.h" +#include "MinecartSpawnerRenderer.h" +#include "../../../Minecraft.World/Blocks/Tile.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" +#include "MobSpawnerRenderer.h" + +void MinecartSpawnerRenderer::renderMinecartContents( + std::shared_ptr cart, float a, Tile* tile, int tileData) { + MinecartRenderer::renderMinecartContents(cart, a, tile, tileData); + + if (tile == Tile::mobSpawner) { + MobSpawnerRenderer::render(cart->getSpawner(), cart->x, cart->y, + cart->z, a); + } +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.h new file mode 100644 index 000000000..af9a0823a --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartSpawnerRenderer.h @@ -0,0 +1,10 @@ +#pragma once +#include "MinecartRenderer.h" + +class MinecartSpawner; + +class MinecartSpawnerRenderer : public MinecartRenderer { +protected: + void renderMinecartContents(std::shared_ptr cart, float a, + Tile* tile, int tileData); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.cpp index 18493e235..8055bab43 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.cpp @@ -1,5 +1,6 @@ #include "../../Platform/stdafx.h" #include "MobRenderer.h" +#include "LivingEntityRenderer.h" #include "../../Player/MultiPlayerLocalPlayer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" @@ -8,475 +9,139 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "EntityRenderDispatcher.h" -MobRenderer::MobRenderer(Model* model, float shadow) : EntityRenderer() { - this->model = model; - this->shadowRadius = shadow; - - this->armor = NULL; -} - -void MobRenderer::setArmor(Model* armor) { this->armor = armor; } - -float MobRenderer::rotlerp(float from, float to, float a) { - float diff = to - from; - while (diff < -180) diff += 360; - while (diff >= 180) diff -= 360; - return from + a * diff; -} +MobRenderer::MobRenderer(Model* model, float shadow) + : LivingEntityRenderer(model, shadow) {} void MobRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { - // 4J - added - this used to use generics so the input parameter could be a - // mob (or derived type), but we aren't able to do that so dynamically - // casting to get the more specific type here. std::shared_ptr mob = std::dynamic_pointer_cast(_mob); - glPushMatrix(); - glDisable(GL_CULL_FACE); - model->attackTime = getAttackAnim(mob, a); - if (armor != NULL) armor->attackTime = model->attackTime; - model->riding = mob->isRiding(); - if (armor != NULL) armor->riding = model->riding; - model->young = mob->isBaby(); - if (armor != NULL) armor->young = model->young; - - // 4J - removed try/catch - // try - // { - float bodyRot = rotlerp(mob->yBodyRotO, mob->yBodyRot, a); - float headRot = rotlerp(mob->yHeadRotO, mob->yHeadRot, a); - - if (mob->isRiding() && std::dynamic_pointer_cast(mob->riding)) { - std::shared_ptr riding = - std::dynamic_pointer_cast(mob->riding); - bodyRot = rotlerp(riding->yBodyRotO, riding->yBodyRot, a); - - float headDiff = Mth::wrapDegrees(headRot - bodyRot); - if (headDiff < -85) headDiff = -85; - if (headDiff >= 85) headDiff = +85; - bodyRot = headRot - headDiff; - if (headDiff * headDiff > 50 * 50) { - bodyRot += headDiff * 0.2f; - } - } - - float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a); - - setupPosition(mob, x, y, z); - - float bob = getBob(mob, a); - setupRotations(mob, bob, bodyRot, a); - - float _scale = 1 / 16.0f; - glEnable(GL_RESCALE_NORMAL); - glScalef(-1, -1, 1); - - scale(mob, a); - glTranslatef(0, -24 * _scale - 0.125f / 16.0f, 0); - - float ws = - mob->walkAnimSpeedO + (mob->walkAnimSpeed - mob->walkAnimSpeedO) * a; - float wp = mob->walkAnimPos - mob->walkAnimSpeed * (1 - a); - if (mob->isBaby()) { - wp *= 3.0f; - } - - if (ws > 1) ws = 1; - - MemSect(31); - bindTexture(mob->customTextureUrl, mob->getTexture()); - MemSect(0); - glEnable(GL_ALPHA_TEST); - - model->prepareMobModel(mob, wp, ws, a); - renderModel(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale); - for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { - int armorType = prepareArmor(mob, i, a); - if (armorType > 0) { - armor->prepareMobModel(mob, wp, ws, a); - armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, - true); - if ((armorType & 0xf0) == 16) { - prepareSecondPassArmor(mob, i, a); - armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, - _scale, true); - } - // 4J - added condition here for rendering player as part of the - // gui. Avoiding rendering the glint here as it involves using its - // own blending, and for gui rendering we are globally blending to - // be able to offer user configurable gui opacity. Note that I - // really don't know why GL_BLEND is turned off at the end of the - // first armour layer anyway, or why alpha testing is turned on... - // but we definitely don't want to be turning blending off during - // the gui render. - if (!entityRenderDispatcher->isGuiRender) { - if ((armorType & 0xf) == - 0xf) // MGH - fix for missing enchantment glow - { - float time = mob->tickCount + a; - bindTexture( - TN__BLUR__MISC_GLINT); // 4J was - // "%blur%/misc/glint.png" - glEnable(GL_BLEND); - float br = 0.5f; - glColor4f(br, br, br, 1); - glDepthFunc(GL_EQUAL); - glDepthMask(false); - - for (int j = 0; j < 2; j++) { - glDisable(GL_LIGHTING); - float brr = 0.76f; - glColor4f(0.5f * brr, 0.25f * brr, 0.8f * brr, 1); - glBlendFunc(GL_SRC_COLOR, GL_ONE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - float uo = time * (0.001f + j * 0.003f) * 20; - float ss = 1 / 3.0f; - glScalef(ss, ss, ss); - glRotatef(30 - (j) * 60.0f, 0, 0, 1); - glTranslatef(0, uo, 0); - glMatrixMode(GL_MODELVIEW); - armor->render(mob, wp, ws, bob, headRot - bodyRot, - headRotx, _scale, false); - } - - glColor4f(1, 1, 1, 1); - glMatrixMode(GL_TEXTURE); - glDepthMask(true); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_LIGHTING); - glDisable(GL_BLEND); - glDepthFunc(GL_LEQUAL); - } - glDisable(GL_BLEND); - } - glEnable(GL_ALPHA_TEST); - } - } - - glDepthMask(true); - - additionalRendering(mob, a); - float br = mob->getBrightness(a); - int overlayColor = getOverlayColor(mob, br, a); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - - if (((overlayColor >> 24) & 0xff) > 0 || mob->hurtTime > 0 || - mob->deathTime > 0) { - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthFunc(GL_EQUAL); - - // 4J - changed these renders to not use the compiled version of their - // models, because otherwise the render states set about (in particular - // the depth & alpha test) don't work with our command buffer versions - if (mob->hurtTime > 0 || mob->deathTime > 0) { - glColor4f(br, 0, 0, 0.4f); - model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, - false); - for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { - if (prepareArmorOverlay(mob, i, a) >= 0) { - glColor4f(br, 0, 0, 0.4f); - armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, - _scale, false); - } - } - } - - if (((overlayColor >> 24) & 0xff) > 0) { - float r = ((overlayColor >> 16) & 0xff) / 255.0f; - float g = ((overlayColor >> 8) & 0xff) / 255.0f; - float b = ((overlayColor) & 0xff) / 255.0f; - float aa = ((overlayColor >> 24) & 0xff) / 255.0f; - glColor4f(r, g, b, aa); - model->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, _scale, - false); - for (int i = 0; i < MAX_ARMOR_LAYERS; i++) { - if (prepareArmorOverlay(mob, i, a) >= 0) { - glColor4f(r, g, b, aa); - armor->render(mob, wp, ws, bob, headRot - bodyRot, headRotx, - _scale, false); - } - } - } - - glDepthFunc(GL_LEQUAL); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glEnable(GL_TEXTURE_2D); - } - glDisable(GL_RESCALE_NORMAL); - // } - // catch (Exception e) { - // // System.out.println("Failed: " + modelNames[model]); - // e.printStackTrace(); - // } - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - - glEnable(GL_CULL_FACE); - - glPopMatrix(); - - MemSect(31); - renderName(mob, x, y, z); - MemSect(0); + LivingEntityRenderer::render(mob, x, y, z, rot, a); + renderLeash(mob, x, y, z, rot, a); } -void MobRenderer::renderModel(std::shared_ptr mob, float wp, float ws, - float bob, float headRotMinusBodyRot, - float headRotx, float scale) { - std::shared_ptr player = - std::dynamic_pointer_cast(Minecraft::GetInstance()->player); - - bindTexture(mob->customTextureUrl, mob->getTexture()); - if (!mob->isInvisible()) { - model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, - true); - } else if (!mob->isInvisibleTo(player)) { - glPushMatrix(); - glColor4f(1, 1, 1, 0.15f); - glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glAlphaFunc(GL_GREATER, 1.0f / 255.0f); - model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, - true); - glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, .1f); - glPopMatrix(); - glDepthMask(true); - } else { - model->setupAnim(wp, ws, bob, headRotMinusBodyRot, headRotx, - scale); //, mob); - } +bool MobRenderer::shouldShowName(std::shared_ptr mob) { + return LivingEntityRenderer::shouldShowName(mob) && + (mob->shouldShowName() || + std::dynamic_pointer_cast(mob)->hasCustomName() && + mob == entityRenderDispatcher->crosshairPickMob); } -void MobRenderer::setupPosition(std::shared_ptr mob, double x, double y, - double z) { - glTranslatef((float)x, (float)y, (float)z); -} - -void MobRenderer::setupRotations(std::shared_ptr mob, float bob, - float bodyRot, float a) { - glRotatef(180 - bodyRot, 0, 1, 0); - if (mob->deathTime > 0) { - float fall = (mob->deathTime + a - 1) / 20.0f * 1.6f; - fall = (float)sqrt(fall); - if (fall > 1) fall = 1; - glRotatef(fall * getFlipDegrees(mob), 0, 0, 1); - } -} - -float MobRenderer::getAttackAnim(std::shared_ptr mob, float a) { - return mob->getAttackAnim(a); -} - -float MobRenderer::getBob(std::shared_ptr mob, float a) { - return (mob->tickCount + a); -} - -void MobRenderer::additionalRendering(std::shared_ptr mob, float a) {} - -int MobRenderer::prepareArmorOverlay(std::shared_ptr mob, int layer, - float a) { - return prepareArmor(mob, layer, a); -} - -int MobRenderer::prepareArmor(std::shared_ptr mob, int layer, float a) { - return -1; -} - -void MobRenderer::prepareSecondPassArmor(std::shared_ptr mob, int layer, - float a) {} - -float MobRenderer::getFlipDegrees(std::shared_ptr mob) { return 90; } - -int MobRenderer::getOverlayColor(std::shared_ptr mob, float br, float a) { - return 0; -} - -void MobRenderer::scale(std::shared_ptr mob, float a) {} - -void MobRenderer::renderName(std::shared_ptr mob, double x, double y, - double z) { - if (Minecraft::renderDebug()) { - // renderNameTag(mob, _toString(mob->entityId), x, y, z, 64); - } -} - -// 4J Added parameter for color here so that we can colour players names -void MobRenderer::renderNameTag(std::shared_ptr mob, - const std::wstring& OriginalName, double x, - double y, double z, int maxDist, - int color /*= 0xffffffff*/) { - if (app.GetGameSettings(eGameSetting_DisplayHUD) == 0) { - // 4J-PB - turn off gamertag render - return; - } - - if (app.GetGameHostOption(eGameHostOption_Gamertags) == 0) { - // turn off gamertags if the host has set them off - return; - } - - float dist = mob->distanceTo(entityRenderDispatcher->cameraEntity); - - if (dist > maxDist) { - return; - } - - Font* font = getFont(); - - float size = 1.60f; - float s = 1 / 60.0f * size; - - glPushMatrix(); - glTranslatef((float)x + 0, (float)y + 2.3f, (float)z); - glNormal3f(0, 1, 0); - - glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); - glRotatef(this->entityRenderDispatcher->playerRotX, 1, 0, 0); - - glScalef(-s, -s, s); - glDisable(GL_LIGHTING); - - // 4J Stu - If it's beyond readable distance, then just render a coloured - // box - int readableDist = PLAYER_NAME_READABLE_FULLSCREEN; - if (!RenderManager.IsHiDef()) { - readableDist = PLAYER_NAME_READABLE_DISTANCE_SD; - } else if (app.GetLocalPlayerCount() > 2) { - readableDist = PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN; - } - - float textOpacity = 1.0f; - if (dist >= readableDist) { - int diff = dist - readableDist; - - textOpacity /= (diff / 2); - - if (diff > readableDist) textOpacity = 0.0f; - } - - if (textOpacity < 0.0f) textOpacity = 0.0f; - if (textOpacity > 1.0f) textOpacity = 1.0f; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Tesselator* t = Tesselator::getInstance(); - - int offs = 0; - std::shared_ptr player = std::dynamic_pointer_cast(mob); - if (player != NULL && app.isXuidDeadmau5(player->getXuid())) offs = -10; - - std::wstring playerName; - WCHAR wchName[2]; - -#if defined(__PS3__) || defined(__ORBIS__) - // Check we have all the font characters for this player name - switch (player->GetPlayerNameValidState()) { - case Player::ePlayerNameValid_NotSet: - if (font->AllCharactersValid(OriginalName)) { - playerName = OriginalName; - player->SetPlayerNameValidState(true); - } else { - memset(wchName, 0, sizeof(WCHAR) * 2); - swprintf(wchName, 2, L"%d", player->getPlayerIndex() + 1); - playerName = wchName; - player->SetPlayerNameValidState(false); - } - break; - case Player::ePlayerNameValid_True: - playerName = OriginalName; - break; - case Player::ePlayerNameValid_False: - memset(wchName, 0, sizeof(WCHAR) * 2); - swprintf(wchName, 2, L"%d", player->getPlayerIndex() + 1); - playerName = wchName; - break; - } - -#else - playerName = OriginalName; -#endif - - if (textOpacity > 0.0f) { - glColor4f(1.0f, 1.0f, 1.0f, textOpacity); - - glDepthMask(false); - glDisable(GL_DEPTH_TEST); - - glDisable(GL_TEXTURE_2D); - - t->begin(); - int w = font->width(playerName) / 2; - - if (textOpacity < 1.0f) { - t->color(color, 255 * textOpacity); - } else { - t->color(0.0f, 0.0f, 0.0f, 0.25f); - } - t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); - t->vertex((float)(-w - 1), (float)(+8 + offs + 1), (float)(0)); - t->vertex((float)(+w + 1), (float)(+8 + offs + 1), (float)(0)); - t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); - t->end(); - - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - glDepthFunc(GL_ALWAYS); - glLineWidth(2.0f); - t->begin(GL_LINE_STRIP); - t->color(color, 255 * textOpacity); - t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); - t->vertex((float)(-w - 1), (float)(+8 + offs + 1), (float)(0)); - t->vertex((float)(+w + 1), (float)(+8 + offs + 1), (float)(0)); - t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); - t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); - t->end(); - glDepthFunc(GL_LEQUAL); - glDepthMask(false); - glDisable(GL_DEPTH_TEST); - - glEnable(GL_TEXTURE_2D); - font->draw(playerName, -font->width(playerName) / 2, offs, 0x20ffffff); - glEnable(GL_DEPTH_TEST); - - glDepthMask(true); - } - - if (textOpacity < 1.0f) { +void MobRenderer::renderLeash(std::shared_ptr entity, double x, double y, + double z, float rot, float a) { + std::shared_ptr roper = entity->getLeashHolder(); + // roper = entityRenderDispatcher.cameraEntity; + if (roper != NULL) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + y -= (1.6 - entity->bbHeight) * .5; + Tesselator* tessellator = Tesselator::getInstance(); + double roperYRot = + lerp(roper->yRotO, roper->yRot, a * .5f) * Mth::RAD_TO_GRAD; + double roperXRot = + lerp(roper->xRotO, roper->xRot, a * .5f) * Mth::RAD_TO_GRAD; + double rotOffCos = cos(roperYRot); + double rotOffSin = sin(roperYRot); + double yOff = sin(roperXRot); + if (roper->instanceof(eTYPE_HANGING_ENTITY)) { + rotOffCos = 0; + rotOffSin = 0; + yOff = -1; + } + double swingOff = cos(roperXRot); + double endX = lerp(roper->xo, roper->x, a) - (rotOffCos * 0.7) - + (rotOffSin * 0.5 * swingOff); + double endY = lerp(roper->yo + roper->getHeadHeight() * .7, + roper->y + roper->getHeadHeight() * .7, a) - + (yOff * 0.5) - .25; + double endZ = lerp(roper->zo, roper->z, a) - (rotOffSin * 0.7) + + (rotOffCos * 0.5 * swingOff); + + double entityYRot = + lerp(entity->yBodyRotO, entity->yBodyRot, a) * Mth::RAD_TO_GRAD + + PI * .5; + rotOffCos = cos(entityYRot) * entity->bbWidth * .4; + rotOffSin = sin(entityYRot) * entity->bbWidth * .4; + double startX = lerp(entity->xo, entity->x, a) + rotOffCos; + double startY = lerp(entity->yo, entity->y, a); + double startZ = lerp(entity->zo, entity->z, a) + rotOffSin; + x += rotOffCos; + z += rotOffSin; + + double dx = (float)(endX - startX); + double dy = (float)(endY - startY); + double dz = (float)(endZ - startZ); + glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - t->begin(); - int w = font->width(playerName) / 2; - t->color(color, 255); - t->vertex((float)(-w - 1), (float)(-1 + offs), (float)(0)); - t->vertex((float)(-w - 1), (float)(+8 + offs), (float)(0)); - t->vertex((float)(+w + 1), (float)(+8 + offs), (float)(0)); - t->vertex((float)(+w + 1), (float)(-1 + offs), (float)(0)); - t->end(); - glDepthFunc(GL_LEQUAL); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + + unsigned int lightCol = + Minecraft::GetInstance()->getColourTable()->getColor( + eMinecraftColour_Leash_Light_Colour); + float rLightCol = ((lightCol >> 16) & 0xFF) / 255.0f; + float gLightCol = ((lightCol >> 8) & 0xFF) / 255.0; + float bLightCol = (lightCol & 0xFF) / 255.0; + + unsigned int darkCol = + Minecraft::GetInstance()->getColourTable()->getColor( + eMinecraftColour_Leash_Dark_Colour); + float rDarkCol = ((darkCol >> 16) & 0xFF) / 255.0f; + float gDarkCol = ((darkCol >> 8) & 0xFF) / 255.0; + float bDarkCol = (darkCol & 0xFF) / 255.0; + + int steps = 24; + double width = .025; + tessellator->begin(GL_TRIANGLE_STRIP); + for (int k = 0; k <= steps; k++) { + if (k % 2 == 0) { + tessellator->color(rLightCol, gLightCol, bLightCol, 1.0F); + } else { + tessellator->color(rDarkCol, gDarkCol, bDarkCol, 1.0F); + } + float aa = (float)k / (float)steps; + tessellator->vertex( + x + (dx * aa) + 0, + y + (dy * ((aa * aa) + aa) * 0.5) + + ((((float)steps - (float)k) / (steps * 0.75F)) + 0.125F), + z + (dz * aa)); + tessellator->vertex( + x + (dx * aa) + width, + y + (dy * ((aa * aa) + aa) * 0.5) + + ((((float)steps - (float)k) / (steps * 0.75F)) + 0.125F) + + width, + z + (dz * aa)); + } + tessellator->end(); + + tessellator->begin(GL_TRIANGLE_STRIP); + for (int k = 0; k <= steps; k++) { + if (k % 2 == 0) { + tessellator->color(rLightCol, gLightCol, bLightCol, 1.0F); + } else { + tessellator->color(rDarkCol, gDarkCol, bDarkCol, 1.0F); + } + float aa = (float)k / (float)steps; + tessellator->vertex( + x + (dx * aa) + 0, + y + (dy * ((aa * aa) + aa) * 0.5) + + ((((float)steps - (float)k) / (steps * 0.75F)) + 0.125F) + + width, + z + (dz * aa)); + tessellator->vertex( + x + (dx * aa) + width, + y + (dy * ((aa * aa) + aa) * 0.5) + + ((((float)steps - (float)k) / (steps * 0.75F)) + 0.125F), + z + (dz * aa) + width); + } + tessellator->end(); + + glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); - - glTranslatef(0.0f, 0.0f, -0.04f); + glEnable(GL_CULL_FACE); } - - if (textOpacity > 0.0f) { - int textColor = (((int)(textOpacity * 255) << 24) | 0xffffff); - font->draw(playerName, -font->width(playerName) / 2, offs, textColor); - } - - glEnable(GL_LIGHTING); - glDisable(GL_BLEND); - glColor4f(1, 1, 1, 1); - glPopMatrix(); } + +double MobRenderer::lerp(double prev, double next, double a) { + return prev + (next - prev) * a; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.h index 3f432ccd6..7c1d4ce07 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/MobRenderer.h @@ -1,58 +1,26 @@ #pragma once -#include "EntityRenderer.h" +#include "LivingEntityRenderer.h" class Mob; -#define PLAYER_NAME_READABLE_FULLSCREEN 16 +// This was used in MobRenderer but lots of code moved to LivingEntity and I +// haven't put this back yet +/*#define PLAYER_NAME_READABLE_FULLSCREEN 16 #define PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN 8 -#define PLAYER_NAME_READABLE_DISTANCE_SD 8 +#define PLAYER_NAME_READABLE_DISTANCE_SD 8*/ // 4J - this used to be a generic : public class MobRenderer // extends EntityRenderer -class MobRenderer : public EntityRenderer { -private: - static const int MAX_ARMOR_LAYERS = 4; - -protected: - Model* model; - Model* armor; - +class MobRenderer : public LivingEntityRenderer { public: MobRenderer(Model* model, float shadow); - virtual void setArmor(Model* armor); - -private: - float rotlerp(float from, float to, float a); - -public: virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); protected: - virtual void renderModel(std::shared_ptr mob, float wp, float ws, - float bob, float headRotMinusBodyRot, - float headRotx, float scale); - virtual void setupPosition(std::shared_ptr mob, double x, double y, - double z); - virtual void setupRotations(std::shared_ptr mob, float bob, - float bodyRot, float a); - virtual float getAttackAnim(std::shared_ptr mob, float a); - virtual float getBob(std::shared_ptr mob, float a); - virtual void additionalRendering(std::shared_ptr mob, float a); - virtual int prepareArmorOverlay(std::shared_ptr mob, int layer, - float a); - virtual int prepareArmor(std::shared_ptr mob, int layer, float a); - virtual void prepareSecondPassArmor(std::shared_ptr mob, int layer, - float a); - virtual float getFlipDegrees(std::shared_ptr mob); - virtual int getOverlayColor(std::shared_ptr mob, float br, float a); - virtual void scale(std::shared_ptr mob, float a); - virtual void renderName(std::shared_ptr mob, double x, double y, - double z); - virtual void renderNameTag(std::shared_ptr mob, - const std::wstring& name, double x, double y, - double z, int maxDist, int color = 0xff000000); + virtual bool shouldShowName(std::shared_ptr mob); + virtual void renderLeash(std::shared_ptr entity, double x, double y, + double z, float rot, float a); -public: - // 4J Added - virtual Model* getModel() { return model; } +private: + double lerp(double prev, double next, double a); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.cpp index 9cad4a1eb..1787410d6 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.cpp @@ -12,13 +12,18 @@ void MobSpawnerRenderer::render(std::shared_ptr _spawner, double x, // our version std::shared_ptr spawner = std::dynamic_pointer_cast(_spawner); + render(spawner->getSpawner(), x, y, z, a); + glPopMatrix(); +} +void MobSpawnerRenderer::render(BaseMobSpawner* spawner, double x, double y, + double z, float a) { glPushMatrix(); glTranslatef((float)x + 0.5f, (float)y, (float)z + 0.5f); std::shared_ptr e = spawner->getDisplayEntity(); if (e != NULL) { - e->setLevel(spawner->level); + e->setLevel(spawner->getLevel()); float s = 7 / 16.0f; glTranslatef(0, 0.4f, 0); glRotatef( @@ -30,5 +35,4 @@ void MobSpawnerRenderer::render(std::shared_ptr _spawner, double x, e->moveTo(x, y, z, 0, 0); EntityRenderDispatcher::instance->render(e, 0, 0, 0, 0, a); } - glPopMatrix(); } diff --git a/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.h index b66593105..4bc455e3e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/MobSpawnerRenderer.h @@ -1,11 +1,15 @@ #pragma once #include "TileEntityRenderer.h" +class BaseMobSpawner; + class MobSpawnerRenderer : public TileEntityRenderer { private: std::unordered_map > models; public: + static void render(BaseMobSpawner* spawner, double x, double y, double z, + float a); virtual void render(std::shared_ptr _spawner, double x, double y, double z, float a, bool setColor, float alpha = 1.0f, diff --git a/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.cpp index 50ea811e6..a45b8b20f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.cpp @@ -1,9 +1,13 @@ #include "../../Platform/stdafx.h" -#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" -#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" -#include "../Models/QuadrupedModel.h" #include "../Models/ModelPart.h" #include "MushroomCowRenderer.h" +#include "../../Textures/TextureAtlas.h" +#include "../Models/QuadrupedModel.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" + +ResourceLocation MushroomCowRenderer::MOOSHROOM_LOCATION = + ResourceLocation(TN_MOB_RED_COW); MushroomCowRenderer::MushroomCowRenderer(Model* model, float shadow) : MobRenderer(model, shadow) {} @@ -11,34 +15,34 @@ MushroomCowRenderer::MushroomCowRenderer(Model* model, float shadow) void MushroomCowRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { // 4J - original version used generics and thus had an input parameter of - // type MushroomCow rather than std::shared_ptr we have here - do - // some casting around instead - // std::shared_ptr mob = + // type MushroomCow rather than shared_ptr we have here - do some + // casting around instead + // shared_ptr mob = // std::dynamic_pointer_cast(_mob); // 4J Stu - No need to do the cast, just pass through as-is MobRenderer::render(_mob, x, y, z, rot, a); } -void MushroomCowRenderer::additionalRendering(std::shared_ptr _mob, - float a) { +void MushroomCowRenderer::additionalRendering( + std::shared_ptr _mob, float a) { // 4J - original version used generics and thus had an input parameter of - // type MushroomCow rather than std::shared_ptr we have here - do some + // type MushroomCow rather than shared_ptr we have here - do some // casting around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::additionalRendering(mob, a); if (mob->isBaby()) return; - bindTexture(TN_TERRAIN); // 4J was "/terrain.png" + bindTexture(&TextureAtlas::LOCATION_BLOCKS); // 4J was "/terrain.png" glEnable(GL_CULL_FACE); glPushMatrix(); glScalef(1, -1, 1); glTranslatef(0.2f, 0.4f, 0.5f); glRotatef(42, 0, 1, 0); - tileRenderer->renderTile(Tile::mushroom2, 0, 1); + tileRenderer->renderTile(Tile::mushroom_red, 0, 1); glTranslatef(0.1f, 0, -0.6f); glRotatef(42, 0, 1, 0); - tileRenderer->renderTile(Tile::mushroom2, 0, 1); + tileRenderer->renderTile(Tile::mushroom_red, 0, 1); glPopMatrix(); glPushMatrix(); @@ -46,8 +50,13 @@ void MushroomCowRenderer::additionalRendering(std::shared_ptr _mob, glScalef(1, -1, 1); glTranslatef(0, 0.75f, -0.2f); glRotatef(12, 0, 1, 0); - tileRenderer->renderTile(Tile::mushroom2, 0, 1); + tileRenderer->renderTile(Tile::mushroom_red, 0, 1); glPopMatrix(); glDisable(GL_CULL_FACE); +} + +ResourceLocation* MushroomCowRenderer::getTextureLocation( + std::shared_ptr mob) { + return &MOOSHROOM_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.h index 3631d5456..9a5f0ae5f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/MushroomCowRenderer.h @@ -1,8 +1,10 @@ #pragma once - #include "MobRenderer.h" class MushroomCowRenderer : public MobRenderer { +private: + static ResourceLocation MOOSHROOM_LOCATION; + public: MushroomCowRenderer(Model* model, float shadow); @@ -10,5 +12,7 @@ public: double z, float rot, float a); protected: - virtual void additionalRendering(std::shared_ptr _mob, float a); + virtual void additionalRendering(std::shared_ptr _mob, + float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.cpp index 385caed40..134c6db22 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.cpp @@ -1,20 +1,46 @@ #include "../../Platform/stdafx.h" -#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" #include "OcelotRenderer.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" -OzelotRenderer::OzelotRenderer(Model* model, float shadow) +ResourceLocation OcelotRenderer::CAT_BLACK_LOCATION = + ResourceLocation(TN_MOB_CAT_BLACK); +ResourceLocation OcelotRenderer::CAT_OCELOT_LOCATION = + ResourceLocation(TN_MOB_OCELOT); +ResourceLocation OcelotRenderer::CAT_RED_LOCATION = + ResourceLocation(TN_MOB_CAT_RED); +ResourceLocation OcelotRenderer::CAT_SIAMESE_LOCATION = + ResourceLocation(TN_MOB_CAT_SIAMESE); + +OcelotRenderer::OcelotRenderer(Model* model, float shadow) : MobRenderer(model, shadow) {} -void OzelotRenderer::render(std::shared_ptr _mob, double x, double y, +void OcelotRenderer::render(std::shared_ptr _mob, double x, double y, double z, float rot, float a) { MobRenderer::render(_mob, x, y, z, rot, a); } -void OzelotRenderer::scale(std::shared_ptr _mob, float a) { +ResourceLocation* OcelotRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr cat = std::dynamic_pointer_cast(entity); + + switch (cat->getCatType()) { + default: + case Ocelot::TYPE_OCELOT: + return &CAT_OCELOT_LOCATION; + case Ocelot::TYPE_BLACK: + return &CAT_BLACK_LOCATION; + case Ocelot::TYPE_RED: + return &CAT_RED_LOCATION; + case Ocelot::TYPE_SIAMESE: + return &CAT_SIAMESE_LOCATION; + } +} + +void OcelotRenderer::scale(std::shared_ptr _mob, float a) { // 4J - original version used generics and thus had an input parameter of - // type Blaze rather than std::shared_ptr we have here - do some - // casting around instead - std::shared_ptr mob = std::dynamic_pointer_cast(_mob); + // type Blaze rather than shared_ptr we have here - do some casting + // around instead + std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::scale(mob, a); if (mob->isTame()) { glScalef(.8f, .8f, .8f); diff --git a/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.h index e262f6a2d..23e64b92a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/OcelotRenderer.h @@ -1,14 +1,20 @@ #pragma once - #include "MobRenderer.h" -class OzelotRenderer : public MobRenderer { -public: - OzelotRenderer(Model* model, float shadow); +class OcelotRenderer : public MobRenderer { +private: + static ResourceLocation CAT_BLACK_LOCATION; + static ResourceLocation CAT_OCELOT_LOCATION; + static ResourceLocation CAT_RED_LOCATION; + static ResourceLocation CAT_SIAMESE_LOCATION; - void render(std::shared_ptr _mob, double x, double y, double z, - float rot, float a); +public: + OcelotRenderer(Model* model, float shadow); + virtual void render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a); protected: - void scale(std::shared_ptr _mob, float a); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + virtual void scale(std::shared_ptr _mob, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.cpp index 04870f3b9..91449b4b6 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.cpp @@ -6,6 +6,8 @@ #include "../../../Minecraft.World/Util/Random.h" #include "../../../Minecraft.World/Util/Mth.h" +ResourceLocation PaintingRenderer::PAINTING_LOCATION(TN_ART_KZ); + PaintingRenderer::PaintingRenderer() { random = new Random(); } void PaintingRenderer::render(std::shared_ptr _painting, double x, @@ -21,7 +23,7 @@ void PaintingRenderer::render(std::shared_ptr _painting, double x, glTranslatef((float)x, (float)y, (float)z); glRotatef(rot, 0, 1, 0); glEnable(GL_RESCALE_NORMAL); - bindTexture(TN_ART_KZ); // 4J was L"/art/kz.png" + bindTexture(painting); // 4J was L"/art/kz.png" Painting::Motive* motive = painting->motive; @@ -37,10 +39,27 @@ void PaintingRenderer::renderPainting(std::shared_ptr painting, int w, float xx0 = -w / 2.0f; float yy0 = -h / 2.0f; - float z0 = -0.5f; - float z1 = +0.5f; + float edgeWidth = 0.5f; - for (int xs = 0; xs < w / 16; xs++) + // Back + float bu0 = (12 * 16) / 256.0f; + float bu1 = (12 * 16 + 16) / 256.0f; + float bv0 = (0) / 256.0f; + float bv1 = (0 + 16) / 256.0f; + + // Border + float uu0 = (12 * 16) / 256.0f; + float uu1 = (12 * 16 + 16) / 256.0f; + float uv0 = (0.5f) / 256.0f; + float uv1 = (0.5f) / 256.0f; + + // Border + float su0 = (12 * 16 + 0.5f) / 256.0f; + float su1 = (12 * 16 + 0.5f) / 256.0f; + float sv0 = (0) / 256.0f; + float sv1 = (0 + 16) / 256.0f; + + for (int xs = 0; xs < w / 16; xs++) { for (int ys = 0; ys < h / 16; ys++) { float x0 = xx0 + (xs + 1) * 16; float x1 = xx0 + (xs) * 16; @@ -49,89 +68,52 @@ void PaintingRenderer::renderPainting(std::shared_ptr painting, int w, setBrightness(painting, (x0 + x1) / 2, (y0 + y1) / 2); + // Painting float fu0 = (uo + w - (xs) * 16) / 256.0f; float fu1 = (uo + w - (xs + 1) * 16) / 256.0f; float fv0 = (vo + h - (ys) * 16) / 256.0f; float fv1 = (vo + h - (ys + 1) * 16) / 256.0f; - float bu0 = (12 * 16) / 256.0f; - float bu1 = (12 * 16 + 16) / 256.0f; - float bv0 = (0) / 256.0f; - float bv1 = (0 + 16) / 256.0f; - - float uu0 = (12 * 16) / 256.0f; - float uu1 = (12 * 16 + 16) / 256.0f; - float uv0 = (0.5f) / 256.0f; - float uv1 = (0.5f) / 256.0f; - - float su0 = (12 * 16 + 0.5f) / 256.0f; - float su1 = (12 * 16 + 0.5f) / 256.0f; - float sv0 = (0) / 256.0f; - float sv1 = (0 + 16) / 256.0f; - Tesselator* t = Tesselator::getInstance(); t->begin(); t->normal(0, 0, -1); - t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(fu1), - (float)(fv0)); - t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(fu0), - (float)(fv0)); - t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(fu0), - (float)(fv1)); - t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(fu1), - (float)(fv1)); + t->vertexUV(x0, y1, -edgeWidth, fu1, fv0); + t->vertexUV(x1, y1, -edgeWidth, fu0, fv0); + t->vertexUV(x1, y0, -edgeWidth, fu0, fv1); + t->vertexUV(x0, y0, -edgeWidth, fu1, fv1); t->normal(0, 0, 1); - t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(bu0), - (float)(bv0)); - t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(bu1), - (float)(bv0)); - t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(bu1), - (float)(bv1)); - t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(bu0), - (float)(bv1)); + t->vertexUV(x0, y0, edgeWidth, bu0, bv0); + t->vertexUV(x1, y0, edgeWidth, bu1, bv0); + t->vertexUV(x1, y1, edgeWidth, bu1, bv1); + t->vertexUV(x0, y1, edgeWidth, bu0, bv1); t->normal(0, 1, 0); - t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(uu0), - (float)(uv0)); - t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(uu1), - (float)(uv0)); - t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(uu1), - (float)(uv1)); - t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(uu0), - (float)(uv1)); + t->vertexUV(x0, y0, -edgeWidth, uu0, uv0); + t->vertexUV(x1, y0, -edgeWidth, uu1, uv0); + t->vertexUV(x1, y0, edgeWidth, uu1, uv1); + t->vertexUV(x0, y0, edgeWidth, uu0, uv1); t->normal(0, -1, 0); - t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(uu0), - (float)(uv0)); - t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(uu1), - (float)(uv0)); - t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(uu1), - (float)(uv1)); - t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(uu0), - (float)(uv1)); + t->vertexUV(x0, y1, edgeWidth, uu0, uv0); + t->vertexUV(x1, y1, edgeWidth, uu1, uv0); + t->vertexUV(x1, y1, -edgeWidth, uu1, uv1); + t->vertexUV(x0, y1, -edgeWidth, uu0, uv1); t->normal(-1, 0, 0); - t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(su1), - (float)(sv0)); - t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(su1), - (float)(sv1)); - t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(su0), - (float)(sv1)); - t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(su0), - (float)(sv0)); + t->vertexUV(x0, y0, edgeWidth, su1, sv0); + t->vertexUV(x0, y1, edgeWidth, su1, sv1); + t->vertexUV(x0, y1, -edgeWidth, su0, sv1); + t->vertexUV(x0, y0, -edgeWidth, su0, sv0); t->normal(1, 0, 0); - t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(su1), - (float)(sv0)); - t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(su1), - (float)(sv1)); - t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(su0), - (float)(sv1)); - t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(su0), - (float)(sv0)); + t->vertexUV(x1, y0, -edgeWidth, su1, sv0); + t->vertexUV(x1, y1, -edgeWidth, su1, sv1); + t->vertexUV(x1, y1, edgeWidth, su0, sv1); + t->vertexUV(x1, y0, edgeWidth, su0, sv0); t->end(); } + } } void PaintingRenderer::setBrightness(std::shared_ptr painting, @@ -149,4 +131,9 @@ void PaintingRenderer::setBrightness(std::shared_ptr painting, int v = col / 65536; glMultiTexCoord2f(0, u, v); glColor3f(1, 1, 1); +} + +ResourceLocation* PaintingRenderer::getTextureLocation( + std::shared_ptr mob) { + return &PAINTING_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.h index 43c65e7ef..31a5574b2 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/PaintingRenderer.h @@ -7,6 +7,7 @@ class Random; class PaintingRenderer : public EntityRenderer { private: Random* random; + static ResourceLocation PAINTING_LOCATION; public: PaintingRenderer(); // 4J -added @@ -17,4 +18,5 @@ private: void renderPainting(std::shared_ptr painting, int w, int h, int uo, int vo); void setBrightness(std::shared_ptr painting, float ss, float ya); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.cpp index 648b4b5fd..c1281fc66 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.cpp @@ -2,23 +2,36 @@ #include "PigRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +ResourceLocation PigRenderer::PIG_LOCATION = ResourceLocation(TN_MOB_PIG); +ResourceLocation PigRenderer::SADDLE_LOCATION = ResourceLocation(TN_MOB_SADDLE); + PigRenderer::PigRenderer(Model* model, Model* armor, float shadow) : MobRenderer(model, shadow) { setArmor(armor); } -int PigRenderer::prepareArmor(std::shared_ptr _pig, int layer, float a) { +int PigRenderer::prepareArmor(std::shared_ptr _pig, int layer, + float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr pig = std::dynamic_pointer_cast(_pig); - MemSect(31); - bindTexture(TN_MOB_SADDLE); // 4J was L"/mob/saddle.png" - MemSect(0); - return (layer == 0 && pig->hasSaddle()) ? 1 : -1; + if (layer == 0 && pig->hasSaddle()) { + MemSect(31); + bindTexture(&SADDLE_LOCATION); + MemSect(0); + + return 1; + } + + return -1; } void PigRenderer::render(std::shared_ptr mob, double x, double y, double z, float rot, float a) { MobRenderer::render(mob, x, y, z, rot, a); +} + +ResourceLocation* PigRenderer::getTextureLocation(std::shared_ptr mob) { + return &PIG_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.h index a209366f5..d91a1c6da 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/PigRenderer.h @@ -2,13 +2,19 @@ #include "MobRenderer.h" class PigRenderer : public MobRenderer { +private: + static ResourceLocation PIG_LOCATION; + static ResourceLocation SADDLE_LOCATION; + public: PigRenderer(Model* model, Model* armor, float shadow); protected: - virtual int prepareArmor(std::shared_ptr _pig, int layer, float a); + virtual int prepareArmor(std::shared_ptr _pig, int layer, + float a); public: virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.cpp index 40c68bfaf..33cc8d933 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.cpp @@ -1,12 +1,16 @@ #include "../../Platform/stdafx.h" #include "PistonPieceRenderer.h" -#include "../Tesselator.h" #include "../Lighting.h" +#include "../Tesselator.h" +#include "../../Textures/TextureAtlas.h" #include "TileRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" -#include "../../../Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.h" +#include "../Minecraft.World/PistonPieceEntity.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" +ResourceLocation PistonPieceRenderer::SIGN_LOCATION = + ResourceLocation(TN_ITEM_SIGN); + PistonPieceRenderer::PistonPieceRenderer() { tileRenderer = NULL; } void PistonPieceRenderer::render(std::shared_ptr _entity, double x, @@ -25,7 +29,7 @@ void PistonPieceRenderer::render(std::shared_ptr _entity, double x, // progress of 1 { Tesselator* t = Tesselator::getInstance(); - bindTexture(TN_TERRAIN); + bindTexture(&TextureAtlas::LOCATION_BLOCKS); Lighting::turnOff(); glColor4f(1, 1, 1, diff --git a/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.h index fbeeba4ae..a74bcbbe3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/PistonPieceRenderer.h @@ -1,10 +1,12 @@ #pragma once #include "TileEntityRenderer.h" + class PistonPieceEntity; class TileRenderer; class PistonPieceRenderer : public TileEntityRenderer { private: + static ResourceLocation SIGN_LOCATION; TileRenderer* tileRenderer; public: diff --git a/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp index 88c8b3c07..499312663 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp @@ -1,6 +1,7 @@ #include "../../Platform/stdafx.h" #include "PlayerRenderer.h" #include "SkullTileRenderer.h" +#include "HumanoidMobRenderer.h" #include "../Models/HumanoidModel.h" #include "../Models/ModelPart.h" #include "../../Player/LocalPlayer.h" @@ -28,10 +29,11 @@ const unsigned int PlayerRenderer::s_nametagColors[MINECRAFT_NET_MAX_PLAYERS] = #endif }; -const std::wstring PlayerRenderer::MATERIAL_NAMES[5] = { - L"cloth", L"chain", L"iron", L"diamond", L"gold"}; +ResourceLocation PlayerRenderer::DEFAULT_LOCATION = + ResourceLocation(TN_MOB_CHAR); -PlayerRenderer::PlayerRenderer() : MobRenderer(new HumanoidModel(0), 0.5f) { +PlayerRenderer::PlayerRenderer() + : LivingEntityRenderer(new HumanoidModel(0), 0.5f) { humanoidModel = (HumanoidModel*)model; armorParts1 = new HumanoidModel(1.0f); @@ -45,8 +47,8 @@ unsigned int PlayerRenderer::getNametagColour(int index) { return 0xFF000000; } -int PlayerRenderer::prepareArmor(std::shared_ptr _player, int layer, - float a) { +int PlayerRenderer::prepareArmor(std::shared_ptr _player, + int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr player = std::dynamic_pointer_cast(_player); @@ -63,8 +65,8 @@ int PlayerRenderer::prepareArmor(std::shared_ptr _player, int layer, Item* item = itemInstance->getItem(); if (dynamic_cast(item)) { ArmorItem* armorItem = dynamic_cast(item); - bindTexture(L"armor/" + MATERIAL_NAMES[armorItem->modelIndex] + - L"_" + _toString(layer == 2 ? 2 : 1) + L".png"); + bindTexture( + HumanoidMobRenderer::getArmorLocation(armorItem, layer)); HumanoidModel* armor = layer == 2 ? armorParts2 : armorParts1; @@ -106,8 +108,8 @@ int PlayerRenderer::prepareArmor(std::shared_ptr _player, int layer, return -1; } -void PlayerRenderer::prepareSecondPassArmor(std::shared_ptr _player, - int layer, float a) { +void PlayerRenderer::prepareSecondPassArmor( + std::shared_ptr _player, int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr player = std::dynamic_pointer_cast(_player); @@ -117,8 +119,8 @@ void PlayerRenderer::prepareSecondPassArmor(std::shared_ptr _player, Item* item = itemInstance->getItem(); if (dynamic_cast(item)) { ArmorItem* armorItem = dynamic_cast(item); - bindTexture(L"armor/" + MATERIAL_NAMES[armorItem->modelIndex] + - L"_" + _toString(layer == 2 ? 2 : 1) + L"_b.png"); + bindTexture(HumanoidMobRenderer::getArmorLocation((ArmorItem*)item, + layer, true)); float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 @@ -173,8 +175,7 @@ void PlayerRenderer::render(std::shared_ptr _mob, double x, double y, mob->isSneaking(); double yp = y - mob->heightOffset; - if (mob->isSneaking() && - (std::dynamic_pointer_cast(mob) == NULL)) { + if (mob->isSneaking() && !mob->instanceof(eTYPE_LOCALPLAYER)) { yp -= 2 / 16.0f; } @@ -208,7 +209,7 @@ void PlayerRenderer::render(std::shared_ptr _mob, double x, double y, } } - MobRenderer::render(mob, x, yp, z, rot, a); + LivingEntityRenderer::render(mob, x, yp, z, rot, a); // turn them off again if (pAdditionalModelParts && pAdditionalModelParts->size() != 0) { @@ -227,91 +228,14 @@ void PlayerRenderer::render(std::shared_ptr _mob, double x, double y, humanoidModel->holdingRightHand = 0; } -void PlayerRenderer::renderName(std::shared_ptr _mob, double x, double y, - double z) { - // 4J - dynamic cast required because we aren't using templates/generics in - // our version - std::shared_ptr mob = std::dynamic_pointer_cast(_mob); +void PlayerRenderer::additionalRendering(std::shared_ptr _mob, + float a) { + float brightness = + SharedConstants::TEXTURE_LIGHTING ? 1 : _mob->getBrightness(a); + glColor3f(brightness, brightness, brightness); - if (Minecraft::renderNames() && - mob != entityRenderDispatcher->cameraEntity && - !mob->isInvisibleTo( - Minecraft::GetInstance() - ->player)) // 4J-JEV: Todo, move to LivingEntityRenderer. - { - float size = 1.60f; - float s = 1 / 60.0f * size; - double dist = mob->distanceToSqr(entityRenderDispatcher->cameraEntity); - - float maxDist = mob->isSneaking() ? 32.0f : 64.0f; - - if (dist < maxDist * maxDist) { - // Truncate display names longer than 16 char - std::wstring msg = mob->getDisplayName(); - if (msg.length() > 16) { - msg.resize(16); - msg += L"..."; - } - - if (mob->isSneaking()) { - if (app.GetGameSettings(eGameSetting_DisplayHUD) == 0) { - // 4J-PB - turn off gamertag render - return; - } - - if (app.GetGameHostOption(eGameHostOption_Gamertags) == 0) { - // turn off gamertags if the host has set them off - return; - } - - Font* font = getFont(); - glPushMatrix(); - glTranslatef((float)x + 0, (float)y + 2.3f, (float)z); - glNormal3f(0, 1, 0); - - glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); - glRotatef(this->entityRenderDispatcher->playerRotX, 1, 0, 0); - - glScalef(-s, -s, s); - glDisable(GL_LIGHTING); - - glTranslatef(0, (float)0.25f / s, 0); - glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Tesselator* t = Tesselator::getInstance(); - - glDisable(GL_TEXTURE_2D); - t->begin(); - int w = font->width(msg) / 2; - t->color(0.0f, 0.0f, 0.0f, 0.25f); - t->vertex((float)(-w - 1), (float)(-1), (float)(0)); - t->vertex((float)(-w - 1), (float)(+8), (float)(0)); - t->vertex((float)(+w + 1), (float)(+8), (float)(0)); - t->vertex((float)(+w + 1), (float)(-1), (float)(0)); - t->end(); - glEnable(GL_TEXTURE_2D); - glDepthMask(true); - font->draw(msg, -font->width(msg) / 2, 0, 0x20ffffff); - glEnable(GL_LIGHTING); - glDisable(GL_BLEND); - glColor4f(1, 1, 1, 1); - glPopMatrix(); - } else { - if (mob->isSleeping()) { - renderNameTag(mob, msg, x, y - 1.5f, z, 64, - s_nametagColors[mob->getPlayerIndex()]); - } else { - renderNameTag(mob, msg, x, y, z, 64, - s_nametagColors[mob->getPlayerIndex()]); - } - } - } - } -} - -void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { - MobRenderer::additionalRendering(_mob, a); + LivingEntityRenderer::additionalRendering(_mob, a); + LivingEntityRenderer::renderArrows(_mob, a); // 4J - dynamic cast required because we aren't using templates/generics in // our version @@ -337,7 +261,7 @@ void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { glScalef(s, -s, s); } - this->entityRenderDispatcher->itemInHandRenderer->renderItem( + entityRenderDispatcher->itemInHandRenderer->renderItem( mob, headGear, 0); } else if (headGear->getItem()->id == Item::skull_Id) { float s = 17 / 16.0f; @@ -378,8 +302,11 @@ void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { glPopMatrix(); } } - // 4J-PB - // if (bindTexture(mob->cloakTexture, L"" )) + + // 4J: removed + /*boolean loaded = mob->getCloakTexture()->isLoaded(); +boolean b1 = !mob->isInvisible(); +boolean b2 = !mob->isCapeHidden();*/ if (bindTexture(mob->customTextureUrl2, L"") && !mob->isInvisible()) { glPushMatrix(); glTranslatef(0, 0, 2 / 16.0f); @@ -448,7 +375,7 @@ void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { s *= 0.75f; glRotatef(20, 1, 0, 0); glRotatef(45, 0, 1, 0); - glScalef(s, -s, s); + glScalef(-s, -s, s); } else if (item->id == Item::bow->id) { float s = 10 / 16.0f; glTranslatef(0 / 16.0f, 2 / 16.0f, 5 / 16.0f); @@ -495,6 +422,12 @@ void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { mob, item, layer, false); } } else { + int col = item->getItem()->getColor(item, 0); + float red = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; + + glColor4f(red, g, b, 1); this->entityRenderDispatcher->itemInHandRenderer->renderItem( mob, item, 0); } @@ -503,18 +436,53 @@ void PlayerRenderer::additionalRendering(std::shared_ptr _mob, float a) { } } -void PlayerRenderer::scale(std::shared_ptr player, float a) { +void PlayerRenderer::renderNameTags(std::shared_ptr player, + double x, double y, double z, + std::wstring msg, float scale, + double dist) { +#if 0 + if (dist < 10 * 10) + { + Scoreboard *scoreboard = player->getScoreboard(); + Objective *objective = scoreboard->getDisplayObjective(Scoreboard::DISPLAY_SLOT_BELOW_NAME); + + if (objective != NULL) + { + Score *score = scoreboard->getPlayerScore(player->getAName(), objective); + + if (player->isSleeping()) + { + renderNameTag(player, score->getScore() + " " + objective->getDisplayName(), x, y - 1.5f, z, 64); + } + else + { + renderNameTag(player, score->getScore() + " " + objective->getDisplayName(), x, y, z, 64); + } + + y += getFont()->lineHeight * 1.15f * scale; + } + } +#endif + + LivingEntityRenderer::renderNameTags(player, x, y, z, msg, scale, dist); +} + +void PlayerRenderer::scale(std::shared_ptr player, float a) { float s = 15 / 16.0f; glScalef(s, s, s); } void PlayerRenderer::renderHand() { + float brightness = 1; + glColor3f(brightness, brightness, brightness); + humanoidModel->m_uiAnimOverrideBitmask = Minecraft::GetInstance()->player->getAnimOverrideBitmask(); armorParts1->eating = armorParts2->eating = humanoidModel->eating = humanoidModel->idle = false; humanoidModel->attackTime = 0; - humanoidModel->setupAnim(0, 0, 0, 0, 0, 1 / 16.0f); + humanoidModel->setupAnim(0, 0, 0, 0, 0, 1 / 16.0f, + Minecraft::GetInstance()->player); // 4J-PB - does this skin have its arm0 disabled? (Dalek, etc) if ((humanoidModel->m_uiAnimOverrideBitmask & (1 << HumanoidModel::eAnim_DisableRenderArm0)) == 0) { @@ -522,23 +490,27 @@ void PlayerRenderer::renderHand() { } } -void PlayerRenderer::setupPosition(std::shared_ptr _mob, double x, +void PlayerRenderer::setupPosition(std::shared_ptr _mob, double x, double y, double z) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); if (mob->isAlive() && mob->isSleeping()) { - MobRenderer::setupPosition(mob, x + mob->bedOffsetX, - y + mob->bedOffsetY, z + mob->bedOffsetZ); + LivingEntityRenderer::setupPosition( + mob, x + mob->bedOffsetX, y + mob->bedOffsetY, z + mob->bedOffsetZ); } else { - MobRenderer::setupPosition(mob, x, y, z); + if (mob->isRiding() && (mob->getAnimOverrideBitmask() & + (1 << HumanoidModel::eAnim_SmallModel)) != 0) { + y += 0.5f; + } + LivingEntityRenderer::setupPosition(mob, x, y, z); } } -void PlayerRenderer::setupRotations(std::shared_ptr _mob, float bob, - float bodyRot, float a) { +void PlayerRenderer::setupRotations(std::shared_ptr _mob, + float bob, float bodyRot, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); @@ -548,7 +520,7 @@ void PlayerRenderer::setupRotations(std::shared_ptr _mob, float bob, glRotatef(getFlipDegrees(mob), 0, 0, 1); glRotatef(270, 0, 1, 0); } else { - MobRenderer::setupRotations(mob, bob, bodyRot, a); + LivingEntityRenderer::setupRotations(mob, bob, bodyRot, a); } } @@ -561,3 +533,15 @@ void PlayerRenderer::renderShadow(std::shared_ptr e, double x, double y, } EntityRenderer::renderShadow(e, x, y, z, pow, a); } + +// 4J Added override +void PlayerRenderer::bindTexture(std::shared_ptr entity) { + std::shared_ptr player = std::dynamic_pointer_cast(entity); + bindTexture(player->customTextureUrl, player->getTexture()); +} + +ResourceLocation* PlayerRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr player = std::dynamic_pointer_cast(entity); + return new ResourceLocation((_TEXTURE_NAME)player->getTexture()); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.h index 3d2118366..e754b9a3c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.h @@ -1,9 +1,14 @@ #pragma once #include "MobRenderer.h" #include "../../../Minecraft.World/Player/Player.h" + class HumanoidModel; -class PlayerRenderer : public MobRenderer { +class PlayerRenderer : public LivingEntityRenderer { +public: + // 4J: Made public for use in skull renderer + static ResourceLocation DEFAULT_LOCATION; + private: // 4J Added static const unsigned int s_nametagColors[MINECRAFT_NET_MAX_PLAYERS]; @@ -21,31 +26,43 @@ private: static const std::wstring MATERIAL_NAMES[5]; protected: - virtual int prepareArmor(std::shared_ptr _player, int layer, float a); - virtual void prepareSecondPassArmor(std::shared_ptr mob, int layer, - float a); + virtual int prepareArmor(std::shared_ptr _player, int layer, + float a); + virtual void prepareSecondPassArmor(std::shared_ptr mob, + int layer, float a); public: virtual void render(std::shared_ptr _mob, double x, double y, double z, float rot, float a); protected: - virtual void renderName(std::shared_ptr _mob, double x, double y, - double z); - virtual void additionalRendering(std::shared_ptr _mob, float a); - virtual void scale(std::shared_ptr _player, float a); + virtual void additionalRendering(std::shared_ptr _mob, + float a); + void renderNameTags(std::shared_ptr player, double x, + double y, double z, std::wstring msg, float scale, + double dist); + + virtual void scale(std::shared_ptr _player, float a); public: void renderHand(); protected: - virtual void setupPosition(std::shared_ptr _mob, double x, double y, - double z); - virtual void setupRotations(std::shared_ptr _mob, float bob, + virtual void setupPosition(std::shared_ptr _mob, double x, + double y, double z); + virtual void setupRotations(std::shared_ptr _mob, float bob, float bodyRot, float a); private: virtual void renderShadow(std::shared_ptr e, double x, double y, double z, float pow, float a); // 4J Added override + +public: + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + + using LivingEntityRenderer::bindTexture; + virtual void bindTexture( + std::shared_ptr entity); // 4J Added override }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp index 2cb865c0d..2552a16f1 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.cpp @@ -81,7 +81,7 @@ void ProgressRenderer::progressStagePercentage(int i) { } - __int64 now = System::currentTimeMillis(); + int64_t now = System::currentTimeMillis(); if (now - lastTime < 20) return; lastTime = now; diff --git a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h index 28ba3c68b..978ffeefc 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h @@ -24,7 +24,7 @@ private: int status; Minecraft* minecraft; int title; - __int64 lastTime; + int64_t lastTime; bool noAbort; std::wstring m_wstrText; eProgressStringType m_eType; diff --git a/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.cpp index 7a99f5a43..a95f9f971 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.cpp @@ -3,12 +3,16 @@ #include "../../Player/MultiPlayerLocalPlayer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +ResourceLocation SheepRenderer::SHEEP_LOCATION = ResourceLocation(TN_MOB_SHEEP); +ResourceLocation SheepRenderer::SHEEP_FUR_LOCATION = + ResourceLocation(TN_MOB_SHEEP_FUR); + SheepRenderer::SheepRenderer(Model* model, Model* armor, float shadow) : MobRenderer(model, shadow) { setArmor(armor); } -int SheepRenderer::prepareArmor(std::shared_ptr _sheep, int layer, +int SheepRenderer::prepareArmor(std::shared_ptr _sheep, int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version @@ -21,8 +25,31 @@ int SheepRenderer::prepareArmor(std::shared_ptr _sheep, int layer, // sheep armour) in '1.7.5'. { MemSect(31); - bindTexture(TN_MOB_SHEEP_FUR); // 4J was L"/mob/sheep_fur.png" + bindTexture(&SHEEP_FUR_LOCATION); MemSect(0); + + if (sheep->hasCustomName() && + sheep->getCustomName().compare(L"jeb_") == 0) { + // easter egg... + int colorDuration = 25; + int value = (sheep->tickCount / colorDuration) + sheep->entityId; + int c1 = value % Sheep::COLOR_LENGTH; + int c2 = (value + 1) % Sheep::COLOR_LENGTH; + float subStep = + ((sheep->tickCount % colorDuration) + a) / (float)colorDuration; + + glColor3f(Sheep::COLOR[c1][0] * (1.0f - subStep) + + Sheep::COLOR[c2][0] * subStep, + Sheep::COLOR[c1][1] * (1.0f - subStep) + + Sheep::COLOR[c2][1] * subStep, + Sheep::COLOR[c1][2] * (1.0f - subStep) + + Sheep::COLOR[c2][2] * subStep); + } else { + int color = sheep->getColor(); + glColor3f(Sheep::COLOR[color][0], Sheep::COLOR[color][1], + Sheep::COLOR[color][2]); + } + // 4J - change brought forward from 1.8.2 float brightness = SharedConstants::TEXTURE_LIGHTING ? 1.0f : sheep->getBrightness(a); @@ -39,3 +66,8 @@ void SheepRenderer::render(std::shared_ptr mob, double x, double y, double z, float rot, float a) { MobRenderer::render(mob, x, y, z, rot, a); } + +ResourceLocation* SheepRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SHEEP_LOCATION; +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.h index cd4ff0e97..50c829b2c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SheepRenderer.h @@ -2,13 +2,19 @@ #include "MobRenderer.h" class SheepRenderer : public MobRenderer { +private: + static ResourceLocation SHEEP_LOCATION; + static ResourceLocation SHEEP_FUR_LOCATION; + public: SheepRenderer(Model* model, Model* armor, float shadow); protected: - virtual int prepareArmor(std::shared_ptr _sheep, int layer, float a); + virtual int prepareArmor(std::shared_ptr _sheep, int layer, + float a); public: virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.cpp index 3d1ecd2e9..b368f0760 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.cpp @@ -7,6 +7,8 @@ #include "../../../Minecraft.World/Entities/Entity.h" #include "../../../Minecraft.World/Level/Level.h" +ResourceLocation SignRenderer::SIGN_LOCATION = ResourceLocation(TN_ITEM_SIGN); + SignRenderer::SignRenderer() { signModel = new SignModel(); } void SignRenderer::render(std::shared_ptr _sign, double x, double y, @@ -41,7 +43,7 @@ void SignRenderer::render(std::shared_ptr _sign, double x, double y, signModel->cube2->visible = false; } - bindTexture(TN_ITEM_SIGN); // 4J was L"/item/sign.png" + bindTexture(&SIGN_LOCATION); // 4J was L"/item/sign.png" glPushMatrix(); glScalef(size, -size, -size); diff --git a/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.h index cc763391b..4c2b4a27b 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SignRenderer.h @@ -4,6 +4,7 @@ class SignModel; class SignRenderer : public TileEntityRenderer { private: + static ResourceLocation SIGN_LOCATION; SignModel* signModel; public: diff --git a/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.cpp index 61df0e757..ad88672d0 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.cpp @@ -3,10 +3,12 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "../Models/SilverfishModel.h" +ResourceLocation SilverfishRenderer::SILVERFISH_LOCATION(TN_MOB_SILVERFISH); + SilverfishRenderer::SilverfishRenderer() : MobRenderer(new SilverfishModel(), 0.3f) {} -float SilverfishRenderer::getFlipDegrees(std::shared_ptr spider) { +float SilverfishRenderer::getFlipDegrees(std::shared_ptr spider) { return 180; } @@ -15,7 +17,12 @@ void SilverfishRenderer::render(std::shared_ptr _mob, double x, MobRenderer::render(_mob, x, y, z, rot, a); } -int SilverfishRenderer::prepareArmor(std::shared_ptr _silverfish, +ResourceLocation* SilverfishRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SILVERFISH_LOCATION; +} + +int SilverfishRenderer::prepareArmor(std::shared_ptr _silverfish, int layer, float a) { return -1; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.h index eadf51cfe..dddae6f4a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SilverfishRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "MobRenderer.h" class Silverfish; @@ -7,17 +6,20 @@ class Silverfish; class SilverfishRenderer : public MobRenderer { private: // int modelVersion; + static ResourceLocation SILVERFISH_LOCATION; public: SilverfishRenderer(); protected: - float getFlipDegrees(std::shared_ptr spider); + float getFlipDegrees(std::shared_ptr spider); public: - void render(std::shared_ptr _mob, double x, double y, double z, - float rot, float a); + virtual void render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - int prepareArmor(std::shared_ptr _silverfish, int layer, float a); + virtual int prepareArmor(std::shared_ptr _silverfish, + int layer, float a); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.cpp new file mode 100644 index 000000000..7538ff352 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.cpp @@ -0,0 +1,34 @@ +#include "../../Platform/stdafx.h" +#include "SkeletonRenderer.h" +#include "../Models/SkeletonModel.h" +#include "../../../Minecraft.World/Entities/Mobs/Skeleton.h" + +ResourceLocation SkeletonRenderer::SKELETON_LOCATION = + ResourceLocation(TN_MOB_SKELETON); +ResourceLocation SkeletonRenderer::WITHER_SKELETON_LOCATION = + ResourceLocation(TN_MOB_WITHER_SKELETON); + +SkeletonRenderer::SkeletonRenderer() + : HumanoidMobRenderer(new SkeletonModel(), .5f) {} + +void SkeletonRenderer::scale(std::shared_ptr mob, float a) { + if (std::dynamic_pointer_cast(mob)->getSkeletonType() == + Skeleton::TYPE_WITHER) { + glScalef(1.2f, 1.2f, 1.2f); + } +} + +void SkeletonRenderer::translateWeaponItem() { + glTranslatef(1.5f / 16.0f, 3 / 16.0f, 0); +} + +ResourceLocation* SkeletonRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr skeleton = + std::dynamic_pointer_cast(entity); + + if (skeleton->getSkeletonType() == Skeleton::TYPE_WITHER) { + return &WITHER_SKELETON_LOCATION; + } + return &SKELETON_LOCATION; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.h new file mode 100644 index 000000000..e7f88883b --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/SkeletonRenderer.h @@ -0,0 +1,17 @@ +#pragma once +#include "HumanoidMobRenderer.h" + +class SkeletonRenderer : public HumanoidMobRenderer { +private: + static ResourceLocation SKELETON_LOCATION; + static ResourceLocation WITHER_SKELETON_LOCATION; + +public: + SkeletonRenderer(); + +protected: + virtual void scale(std::shared_ptr mob, float a); + void translateWeaponItem(); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.cpp index ef501bb4a..71a8265c7 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.cpp @@ -1,12 +1,22 @@ #include "../../Platform/stdafx.h" -#include "../../../Minecraft.World/Blocks/TileEntities/SkullTileEntity.h" -#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" -#include "../../../Minecraft.World/Headers/net.minecraft.h" -#include "../Models/SkeletonHeadModel.h" #include "SkullTileRenderer.h" +#include "../Models/SkeletonHeadModel.h" +#include "PlayerRenderer.h" +#include "../../../Minecraft.World/Blocks/TileEntities/SkullTileEntity.h" +#include "../../../Minecraft.World/Headers/net.minecraft.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" SkullTileRenderer* SkullTileRenderer::instance = NULL; +ResourceLocation SkullTileRenderer::SKELETON_LOCATION = + ResourceLocation(TN_MOB_SKELETON); +ResourceLocation SkullTileRenderer::WITHER_SKELETON_LOCATION = + ResourceLocation(TN_MOB_WITHER_SKELETON); +ResourceLocation SkullTileRenderer::ZOMBIE_LOCATION = + ResourceLocation(TN_MOB_ZOMBIE); +ResourceLocation SkullTileRenderer::CREEPER_LOCATION = + ResourceLocation(TN_MOB_CREEPER); + SkullTileRenderer::SkullTileRenderer() { skeletonModel = new SkeletonHeadModel(0, 0, 64, 32); zombieModel = new SkeletonHeadModel(0, 0, 64, 64); @@ -41,38 +51,38 @@ void SkullTileRenderer::renderSkull(float x, float y, float z, int face, switch (type) { case SkullTileEntity::TYPE_WITHER: - bindTexture(TN_MOB_WITHER_SKELETON); + bindTexture(&WITHER_SKELETON_LOCATION); break; case SkullTileEntity::TYPE_ZOMBIE: - bindTexture(TN_MOB_ZOMBIE); + bindTexture(&ZOMBIE_LOCATION); // model = zombieModel; break; case SkullTileEntity::TYPE_CHAR: // if (!extra.empty()) //{ - // std::wstring url = "http://skins.minecraft.net/MinecraftSkins/" - //+ StringUtil.stripColor(extra) + ".png"; + // wstring url = "http://skins.minecraft.net/MinecraftSkins/" + + // StringUtil.stripColor(extra) + ".png"; // if //(!instance->tileEntityRenderDispatcher->textures->hasHttpTexture(url)) // { // instance->tileEntityRenderDispatcher->textures->addHttpTexture(url, - //new MobSkinTextureProcessor()); + // new MobSkinTextureProcessor()); // } // bindTexture(url, "/mob/char.png"); //} // else { - bindTexture(TN_MOB_CHAR); + bindTexture(&PlayerRenderer::DEFAULT_LOCATION); } break; case SkullTileEntity::TYPE_CREEPER: - bindTexture(TN_MOB_CREEPER); + bindTexture(&CREEPER_LOCATION); break; case SkullTileEntity::TYPE_SKELETON: default: - bindTexture(TN_MOB_SKELETON); + bindTexture(&SKELETON_LOCATION); break; } diff --git a/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.h index 8f47eb6da..31837fa62 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SkullTileRenderer.h @@ -9,6 +9,11 @@ public: static SkullTileRenderer* instance; private: + static ResourceLocation SKELETON_LOCATION; + static ResourceLocation WITHER_SKELETON_LOCATION; + static ResourceLocation ZOMBIE_LOCATION; + static ResourceLocation CREEPER_LOCATION; + // note: this head fits most mobs, just change texture SkeletonHeadModel* skeletonModel; SkeletonHeadModel* zombieModel; diff --git a/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.cpp index 19ee0cad0..21def8ae8 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.cpp @@ -2,19 +2,22 @@ #include "SlimeRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" +ResourceLocation SlimeRenderer::SLIME_LOCATION = ResourceLocation(TN_MOB_SLIME); + SlimeRenderer::SlimeRenderer(Model* model, Model* armor, float shadow) : MobRenderer(model, shadow) { this->armor = armor; } -int SlimeRenderer::prepareArmor(std::shared_ptr _slime, int layer, +int SlimeRenderer::prepareArmor(std::shared_ptr _slime, int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr slime = std::dynamic_pointer_cast(_slime); - if (slime->isInvisible()) return 0; - + if (slime->isInvisible()) { + return 0; + } if (layer == 0) { setArmor(armor); @@ -31,7 +34,7 @@ int SlimeRenderer::prepareArmor(std::shared_ptr _slime, int layer, return -1; } -void SlimeRenderer::scale(std::shared_ptr _slime, float a) { +void SlimeRenderer::scale(std::shared_ptr _slime, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr slime = std::dynamic_pointer_cast(_slime); @@ -41,4 +44,9 @@ void SlimeRenderer::scale(std::shared_ptr _slime, float a) { (size * 0.5f + 1); float w = 1 / (ss + 1); glScalef(w * size, 1 / w * size, w * size); +} + +ResourceLocation* SlimeRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SLIME_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.h index 0ab5ae7a9..5f6fa397e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SlimeRenderer.h @@ -4,11 +4,14 @@ class SlimeRenderer : public MobRenderer { private: Model* armor; + static ResourceLocation SLIME_LOCATION; public: SlimeRenderer(Model* model, Model* armor, float shadow); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - virtual int prepareArmor(std::shared_ptr _slime, int layer, float a); - virtual void scale(std::shared_ptr _slime, float a); + virtual int prepareArmor(std::shared_ptr _slime, int layer, + float a); + virtual void scale(std::shared_ptr _slime, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.cpp index 039ec74d8..06cae1fef 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.cpp @@ -7,15 +7,19 @@ #include "EntityRenderDispatcher.h" #include "SnowManRenderer.h" +ResourceLocation SnowManRenderer::SNOWMAN_LOCATION = + ResourceLocation(TN_MOB_SNOWMAN); + SnowManRenderer::SnowManRenderer() : MobRenderer(new SnowManModel(), 0.5f) { model = (SnowManModel*)MobRenderer::model; this->setArmor(model); } -void SnowManRenderer::additionalRendering(std::shared_ptr _mob, float a) { +void SnowManRenderer::additionalRendering(std::shared_ptr _mob, + float a) { // 4J - original version used generics and thus had an input parameter of - // type SnowMan rather than std::shared_ptr we have here - do some - // casting around instead + // type SnowMan rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::additionalRendering(mob, a); @@ -33,9 +37,14 @@ void SnowManRenderer::additionalRendering(std::shared_ptr _mob, float a) { glScalef(s, -s, s); } - this->entityRenderDispatcher->itemInHandRenderer->renderItem( - mob, headGear, 0); + entityRenderDispatcher->itemInHandRenderer->renderItem(mob, headGear, + 0); glPopMatrix(); } +} + +ResourceLocation* SnowManRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SNOWMAN_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.h index 62a14b0e7..800766688 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SnowManRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "MobRenderer.h" class SnowManModel; @@ -7,10 +6,13 @@ class SnowManModel; class SnowManRenderer : public MobRenderer { private: SnowManModel* model; + static ResourceLocation SNOWMAN_LOCATION; public: SnowManRenderer(); protected: - virtual void additionalRendering(std::shared_ptr _mob, float a); + virtual void additionalRendering(std::shared_ptr _mob, + float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.cpp index 527e77034..5f05ed823 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.cpp @@ -3,23 +3,28 @@ #include "../Models/SpiderModel.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" +ResourceLocation SpiderRenderer::SPIDER_LOCATION = + ResourceLocation(TN_MOB_SPIDER); +ResourceLocation SpiderRenderer::SPIDER_EYES_LOCATION = + ResourceLocation(TN_MOB_SPIDER_EYES); + SpiderRenderer::SpiderRenderer() : MobRenderer(new SpiderModel(), 1.0f) { this->setArmor(new SpiderModel()); } -float SpiderRenderer::getFlipDegrees(std::shared_ptr spider) { +float SpiderRenderer::getFlipDegrees(std::shared_ptr spider) { return 180; } -int SpiderRenderer::prepareArmor(std::shared_ptr _spider, int layer, - float a) { +int SpiderRenderer::prepareArmor(std::shared_ptr _spider, + int layer, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr spider = std::dynamic_pointer_cast(_spider); if (layer != 0) return -1; MemSect(31); - bindTexture(TN_MOB_SPIDER_EYES); // 4J was L"/mob/spider_eyes.png" + bindTexture(&SPIDER_EYES_LOCATION); MemSect(0); // 4J - changes brought forward from 1.8.2 float br = 1.0f; // was (1-spider->getBrightness(1))*0.5f; @@ -56,10 +61,7 @@ int SpiderRenderer::prepareArmor(std::shared_ptr _spider, int layer, return 1; } -void SpiderRenderer::scale(std::shared_ptr _mob, float a) { - // 4J - dynamic cast required because we aren't using templates/generics in - // our version - std::shared_ptr mob = std::dynamic_pointer_cast(_mob); - float scale = mob->getModelScale(); - glScalef(scale, scale, scale); +ResourceLocation* SpiderRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SPIDER_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.h index cf7906472..6c413c303 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SpiderRenderer.h @@ -2,11 +2,16 @@ #include "MobRenderer.h" class SpiderRenderer : public MobRenderer { +private: + static ResourceLocation SPIDER_LOCATION; + static ResourceLocation SPIDER_EYES_LOCATION; + public: SpiderRenderer(); protected: - virtual float getFlipDegrees(std::shared_ptr spider); - virtual int prepareArmor(std::shared_ptr _spider, int layer, float a); - void scale(std::shared_ptr _mob, float a); + virtual float getFlipDegrees(std::shared_ptr spider); + virtual int prepareArmor(std::shared_ptr _spider, int layer, + float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.cpp index aa140dd6c..411be9141 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.cpp @@ -2,6 +2,8 @@ #include "SquidRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +ResourceLocation SquidRenderer::SQUID_LOCATION = ResourceLocation(TN_MOB_SQUID); + SquidRenderer::SquidRenderer(Model* model, float shadow) : MobRenderer(model, shadow) {} @@ -10,8 +12,8 @@ void SquidRenderer::render(std::shared_ptr mob, double x, double y, MobRenderer::render(mob, x, y, z, rot, a); } -void SquidRenderer::setupRotations(std::shared_ptr _mob, float bob, - float bodyRot, float a) { +void SquidRenderer::setupRotations(std::shared_ptr _mob, + float bob, float bodyRot, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); @@ -26,11 +28,16 @@ void SquidRenderer::setupRotations(std::shared_ptr _mob, float bob, glTranslatef(0, -1.2f, 0); } -float SquidRenderer::getBob(std::shared_ptr _mob, float a) { +float SquidRenderer::getBob(std::shared_ptr _mob, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); return mob->oldTentacleAngle + (mob->tentacleAngle - mob->oldTentacleAngle) * a; +} + +ResourceLocation* SquidRenderer::getTextureLocation( + std::shared_ptr mob) { + return &SQUID_LOCATION; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.h index 0da4dddd8..c57da408c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/SquidRenderer.h @@ -2,15 +2,17 @@ #include "MobRenderer.h" class SquidRenderer : public MobRenderer { -public: - SquidRenderer(Model* model, float shadow); +private: + static ResourceLocation SQUID_LOCATION; public: + SquidRenderer(Model* model, float shadow); virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); protected: - virtual void setupRotations(std::shared_ptr _mob, float bob, + virtual void setupRotations(std::shared_ptr _mob, float bob, float bodyRot, float a); - virtual float getBob(std::shared_ptr _mob, float a); + virtual float getBob(std::shared_ptr _mob, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.cpp index f39b3297c..2a780c229 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.cpp @@ -7,21 +7,28 @@ #include "../../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "TheEndPortalRenderer.h" +ResourceLocation TheEndPortalRenderer::END_SKY_LOCATION = + ResourceLocation(TN_MISC_TUNNEL); +ResourceLocation TheEndPortalRenderer::END_PORTAL_LOCATION = + ResourceLocation(TN_MISC_PARTICLEFIELD); +int TheEndPortalRenderer::RANDOM_SEED = 31100; +Random TheEndPortalRenderer::RANDOM = Random(RANDOM_SEED); + void TheEndPortalRenderer::render(std::shared_ptr _table, double x, double y, double z, float a, bool setColor, float alpha, bool useCompiled) { // 4J Convert as we aren't using a templated class std::shared_ptr table = std::dynamic_pointer_cast(_table); - float xx = (float)(tileEntityRenderDispatcher->xPlayer); - float yy = (float)(tileEntityRenderDispatcher->yPlayer); - float zz = (float)(tileEntityRenderDispatcher->zPlayer); + float xx = (float)tileEntityRenderDispatcher->xPlayer; + float yy = (float)tileEntityRenderDispatcher->yPlayer; + float zz = (float)tileEntityRenderDispatcher->zPlayer; glDisable(GL_LIGHTING); - Random random(31100); + RANDOM.setSeed(RANDOM_SEED); - float hoff = (12) / 16.0f; + float hoff = 12 / 16.0f; for (int i = 0; i < 16; i++) { glPushMatrix(); @@ -30,7 +37,7 @@ void TheEndPortalRenderer::render(std::shared_ptr _table, double x, float br = 1.0f / (dist + 1); if (i == 0) { - this->bindTexture(TN_MISC_TUNNEL); // 4J was "/misc/tunnel.png" + this->bindTexture(&END_SKY_LOCATION); br = 0.1f; dist = 65; sscale = 1 / 8.0f; @@ -38,8 +45,7 @@ void TheEndPortalRenderer::render(std::shared_ptr _table, double x, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } if (i == 1) { - this->bindTexture( - TN_MISC_PARTICLEFIELD); // 4J was "/misc/particlefield.png" + this->bindTexture(&END_PORTAL_LOCATION); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); sscale = 1 / 2.0f; @@ -79,7 +85,7 @@ void TheEndPortalRenderer::render(std::shared_ptr _table, double x, glPushMatrix(); glLoadIdentity(); - glTranslatef(0, (System::currentTimeMillis() % 700000 / 700000.0f), 0); + glTranslatef(0, System::currentTimeMillis() % 700000 / 700000.0f, 0); glScalef(sscale, sscale, sscale); glTranslatef(0.5f, 0.5f, 0); glRotatef((i * i * 4321 + i * 9) * 2.0f, 0, 0, 1); @@ -96,9 +102,9 @@ void TheEndPortalRenderer::render(std::shared_ptr _table, double x, // the texture coord in the pixel shader t->begin(); - float r = random.nextFloat() * 0.5f + 0.1f; - float g = random.nextFloat() * 0.5f + 0.4f; - float b = random.nextFloat() * 0.5f + 0.5f; + float r = RANDOM.nextFloat() * 0.5f + 0.1f; + float g = RANDOM.nextFloat() * 0.5f + 0.4f; + float b = RANDOM.nextFloat() * 0.5f + 0.5f; if (i == 0) r = g = b = 1; t->color(r * br, g * br, b * br, 1.0f); t->vertex(x, y + hoff, z); diff --git a/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.h index e2b9ed564..ef7b1bda1 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/TheEndPortalRenderer.h @@ -3,6 +3,12 @@ #include "TileEntityRenderer.h" class TheEndPortalRenderer : public TileEntityRenderer { +private: + static ResourceLocation END_SKY_LOCATION; + static ResourceLocation END_PORTAL_LOCATION; + static int RANDOM_SEED; + static Random RANDOM; + public: virtual void render(std::shared_ptr _table, double x, double y, double z, float a, bool setColor, float alpha = 1.0f, diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.cpp index 9d82d0885..25e9553fe 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.cpp @@ -4,7 +4,7 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" -#include "../../../Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.h" +#include "../Minecraft.World/PistonPieceEntity.h" #include "SignRenderer.h" #include "MobSpawnerRenderer.h" #include "PistonPieceRenderer.h" @@ -13,6 +13,7 @@ #include "TheEndPortalRenderer.h" #include "SkullTileRenderer.h" #include "EnderChestRenderer.h" +#include "BeaconRenderer.h" TileEntityRenderDispatcher* TileEntityRenderDispatcher::instance = NULL; double TileEntityRenderDispatcher::xOff = 0; @@ -44,6 +45,7 @@ TileEntityRenderDispatcher::TileEntityRenderDispatcher() { renderers[eTYPE_THEENDPORTALTILEENTITY] = new TheEndPortalRenderer(); renderers[eTYPE_SKULLTILEENTITY] = new SkullTileRenderer(); renderers[eTYPE_FURNACETILEENTITY] = NULL; + renderers[eTYPE_BEACONTILEENTITY] = new BeaconRenderer(); glDisable(GL_LIGHTING); AUTO_VAR(itEnd, renderers.end()); @@ -65,15 +67,15 @@ TileEntityRenderer* TileEntityRenderDispatcher::getRenderer(eINSTANCEOF e) { /* 4J - not doing this hierarchical search anymore. We need to explicitly add renderers for any eINSTANCEOF type that we want to be able to render - if (it == renderers.end() && e != TileEntity::_class) + if (it == renderers.end() && e != TileEntity::_class) { - r = getRenderer(dynamic_cast( + r = getRenderer(dynamic_cast( e->getSuperclass() )); // 4J - added condition here to only add if a valid renderer found if( r ) renderers.insert( classToTileRendererMap::value_type( e, r ) ); //assert(false); - } + } else if(it != renderers.end() && e != TileEntity::_class) r = (*it).second; */ @@ -93,12 +95,13 @@ TileEntityRenderer* TileEntityRenderDispatcher::getRenderer( void TileEntityRenderDispatcher::prepare(Level* level, Textures* textures, Font* font, - std::shared_ptr player, float a) { + std::shared_ptr player, + float a) { if (this->level != level) { setLevel(level); } this->textures = textures; - this->cameraEntity = player; + cameraEntity = player; this->font = font; playerRotY = player->yRotO + (player->yRot - player->yRotO) * a; @@ -111,7 +114,7 @@ void TileEntityRenderDispatcher::prepare(Level* level, Textures* textures, void TileEntityRenderDispatcher::render(std::shared_ptr e, float a, bool setColor /*=true*/) { - if (e->distanceToSqr(xPlayer, yPlayer, zPlayer) < 64 * 64) { + if (e->distanceToSqr(xPlayer, yPlayer, zPlayer) < e->getViewDistance()) { // 4J - changes brought forward from 1.8.2 if (SharedConstants::TEXTURE_LIGHTING) { int col = level->getLightColor(e->x, e->y, e->z, 0); diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.h b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.h index b23e78aa8..b748eb846 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.h +++ b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderDispatcher.h @@ -27,7 +27,7 @@ public: Textures* textures; Level* level; - std::shared_ptr cameraEntity; + std::shared_ptr cameraEntity; float playerRotY; float playerRotX; double xPlayer, yPlayer, zPlayer; @@ -40,7 +40,7 @@ public: bool hasRenderer(std::shared_ptr e); TileEntityRenderer* getRenderer(std::shared_ptr e); void prepare(Level* level, Textures* textures, Font* font, - std::shared_ptr player, float a); + std::shared_ptr player, float a); void render(std::shared_ptr e, float a, bool setColor = true); void render(std::shared_ptr entity, double x, double y, double z, float a, bool setColor = true, float alpha = 1.0f, diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.cpp index 08af4cbb7..e265a5e8c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.cpp @@ -2,15 +2,16 @@ #include "TileEntityRenderer.h" #include "TileEntityRenderDispatcher.h" -void TileEntityRenderer::bindTexture(int resourceName) { +void TileEntityRenderer::bindTexture(ResourceLocation* location) { Textures* t = tileEntityRenderDispatcher->textures; - if (t != NULL) t->bind(t->loadTexture(resourceName)); + if (t != NULL) t->bind(t->loadTexture(location->getTexture())); } void TileEntityRenderer::bindTexture(const std::wstring& urlTexture, - int backupTexture) { + ResourceLocation* location) { Textures* t = tileEntityRenderDispatcher->textures; - if (t != NULL) t->bind(t->loadHttpTexture(urlTexture, backupTexture)); + if (t != NULL) + t->bind(t->loadHttpTexture(urlTexture, location->getTexture())); } Level* TileEntityRenderer::getLevel() { diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.h index 005ae2c26..a3656ebbf 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/TileEntityRenderer.h @@ -1,5 +1,7 @@ #pragma once #include "../../Textures/Textures.h" +#include "../../Textures/ResourceLocation.h" + class TileEntityRenderDispatcher; class TileEntity; class Level; @@ -12,16 +14,16 @@ protected: public: virtual void render(std::shared_ptr entity, double x, double y, double z, float a, bool setColor, float alpha, - bool useCompiled) = 0; // 4J added setColor param and + bool useCompiled) = 0; // 4J added setColor param, // alpha and useCompiled virtual void onNewLevel(Level* level) {} protected: void bindTexture( - int resourceName); // 4J - changed from std::wstring to int + ResourceLocation* location); // 4J - changed from std::wstring to int void bindTexture( const std::wstring& urlTexture, - int backupTexture); // 4J - changed from std::wstring to int + ResourceLocation* location); // 4J - changed from std::wstring to int private: Level* getLevel(); diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index 0b082a170..ce0004739 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -21,7 +21,6 @@ void TileRenderer::_init() { fixedTexture = NULL; xFlipTexture = false; noCulling = false; - blsmooth = 1; applyAmbienceOcclusion = false; setColor = true; northFlip = FLIP_NONE; @@ -182,7 +181,18 @@ void TileRenderer::setFixedTexture(Icon* fixedTexture) { void TileRenderer::clearFixedTexture() { this->fixedTexture = NULL; } -bool TileRenderer::hasFixedTexture() { return fixedTexture != NULL; } +bool TileRenderer::hasFixedTexture() { +#ifdef __PSVITA__ + // AP - alpha cut out is expensive on vita. Pass on the Alpha Cut out flag + // to the tesselator + if (fixedTexture) { + Tesselator* t = Tesselator::getInstance(); + t->setAlphaCutOut(fixedTexture->getFlags() & Icon::IS_ALPHA_CUT_OUT); + } +#endif + + return fixedTexture != NULL; +} void TileRenderer::setShape(float x0, float y0, float z0, float x1, float y1, float z1) { @@ -379,9 +389,15 @@ bool TileRenderer::tesselateInWorld( case Tile::SHAPE_BED: retVal = tesselateBedInWorld(tt, x, y, z); break; + case Tile::SHAPE_REPEATER: + retVal = tesselateRepeaterInWorld((RepeaterTile*)tt, x, y, z); + break; case Tile::SHAPE_DIODE: retVal = tesselateDiodeInWorld((DiodeTile*)tt, x, y, z); break; + case Tile::SHAPE_COMPARATOR: + retVal = tesselateComparatorInWorld((ComparatorTile*)tt, x, y, z); + break; case Tile::SHAPE_PISTON_BASE: retVal = tesselatePistonBaseInWorld(tt, x, y, z, false, forceData); break; @@ -392,6 +408,9 @@ bool TileRenderer::tesselateInWorld( case Tile::SHAPE_IRON_FENCE: retVal = tesselateThinFenceInWorld((ThinFenceTile*)tt, x, y, z); break; + case Tile::SHAPE_THIN_PANE: + retVal = tesselateThinPaneInWorld(tt, x, y, z); + break; case Tile::SHAPE_VINE: retVal = tesselateVineInWorld(tt, x, y, z); break; @@ -418,6 +437,12 @@ bool TileRenderer::tesselateInWorld( case Tile::SHAPE_COCOA: retVal = tesselateCocoaInWorld((CocoaTile*)tt, x, y, z); break; + case Tile::SHAPE_BEACON: + retVal = tesselateBeaconInWorld(tt, x, y, z); + break; + case Tile::SHAPE_HOPPER: + retVal = tesselateHopperInWorld(tt, x, y, z); + break; }; t->setMipmapEnable(true); // 4J added @@ -683,6 +708,9 @@ bool TileRenderer::tesselateBrewingStandInWorld(BrewingStandTile* tt, int x, tesselateBlockInWorld(tt, x, y, z); setFixedTexture(tt->getBaseTexture()); + + // Fix faceculling when attached to blocks + noCulling = true; setShape(9.0f / 16.0f, 0.0f, 5.0f / 16.0f, 15.0f / 16.0f, 2 / 16.0f, 11.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); @@ -692,6 +720,7 @@ bool TileRenderer::tesselateBrewingStandInWorld(BrewingStandTile* tt, int x, setShape(2.0f / 16.0f, 0.0f, 9.0f / 16.0f, 8.0f / 16.0f, 2 / 16.0f, 15.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); + noCulling = false; clearFixedTexture(); @@ -860,10 +889,10 @@ bool TileRenderer::tesselateFlowerPotInWorld(FlowerPotTile* tt, int x, int y, plant = Tile::flower; break; case FlowerPotTile::TYPE_MUSHROOM_BROWN: - plant = Tile::mushroom1; + plant = Tile::mushroom_brown; break; case FlowerPotTile::TYPE_MUSHROOM_RED: - plant = Tile::mushroom2; + plant = Tile::mushroom_red; break; } @@ -1016,8 +1045,9 @@ bool TileRenderer::tesselateAnvilInWorld(AnvilTile* tt, int x, int y, int z, float TileRenderer::tesselateAnvilPiece(AnvilTile* tt, int x, int y, int z, int part, float bottom, float width, - float height, float length, bool rotate, - bool render, int data) { + float height, float length, + bool rotate, bool render, + int data) { if (rotate) { float swap = width; width = length; @@ -1100,6 +1130,181 @@ bool TileRenderer::tesselateTorchInWorld(Tile* tt, int x, int y, int z) { return true; } +bool TileRenderer::tesselateRepeaterInWorld(RepeaterTile* tt, int x, int y, + int z) { + int data = level->getData(x, y, z); + int dir = data & DiodeTile::DIRECTION_MASK; + int delay = (data & RepeaterTile::DELAY_MASK) >> RepeaterTile::DELAY_SHIFT; + + Tesselator* t = Tesselator::getInstance(); + + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (Tile::lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } + + double h = -3.0f / 16.0f; + bool hasLockSignal = tt->isLocked(level, x, y, z, data); + double transmitterX = 0; + double transmitterZ = 0; + double receiverX = 0; + double receiverZ = 0; + + switch (dir) { + case Direction::SOUTH: + receiverZ = -5.0f / 16.0f; + transmitterZ = RepeaterTile::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::NORTH: + receiverZ = 5.0f / 16.0f; + transmitterZ = -RepeaterTile::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::EAST: + receiverX = -5.0f / 16.0f; + transmitterX = RepeaterTile::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::WEST: + receiverX = 5.0f / 16.0f; + transmitterX = -RepeaterTile::DELAY_RENDER_OFFSETS[delay]; + break; + } + + // render transmitter + if (!hasLockSignal) { + tesselateTorch((Tile*)tt, x + transmitterX, y + h, z + transmitterZ, 0, + 0, 0); + } else { + Icon* lockTex = getTexture(Tile::unbreakable); + setFixedTexture(lockTex); + + float west = 2.0f; + float east = 14.0f; + float north = 7.0f; + float south = 9.0f; + + switch (dir) { + case Direction::SOUTH: + case Direction::NORTH: + break; + case Direction::EAST: + case Direction::WEST: + west = 7.f; + east = 9.f; + north = 2.f; + south = 14.f; + break; + } + setShape(west / 16.0f + (float)transmitterX, 2.f / 16.0f, + north / 16.0f + (float)transmitterZ, + east / 16.0f + (float)transmitterX, 4.f / 16.0f, + south / 16.0f + (float)transmitterZ); + double u0 = lockTex->getU(west); + double v0 = lockTex->getV(north); + double u1 = lockTex->getU(east); + double v1 = lockTex->getV(south); + t->vertexUV(x + west / 16.0f + transmitterX, y + 4.0f / 16.0f, + z + north / 16.0f + transmitterZ, u0, v0); + t->vertexUV(x + west / 16.0f + transmitterX, y + 4.0f / 16.0f, + z + south / 16.0f + transmitterZ, u0, v1); + t->vertexUV(x + east / 16.0f + transmitterX, y + 4.0f / 16.0f, + z + south / 16.0f + transmitterZ, u1, v1); + t->vertexUV(x + east / 16.0f + transmitterX, y + 4.0f / 16.0f, + z + north / 16.0f + transmitterZ, u1, v0); + tesselateBlockInWorld(tt, x, y, z); + setShape(0, 0, 0, 1, 2.0f / 16.0f, 1); + clearFixedTexture(); + } + + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (Tile::lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } + + // render receiver + tesselateTorch(tt, x + receiverX, y + h, z + receiverZ, 0, 0, 0); + + // render floor + tesselateDiodeInWorld(tt, x, y, z); + + return true; +} + +bool TileRenderer::tesselateComparatorInWorld(ComparatorTile* tt, int x, int y, + int z) { + Tesselator* t = Tesselator::getInstance(); + + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (Tile::lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } + + int data = level->getData(x, y, z); + int dir = data & DirectionalTile::DIRECTION_MASK; + double extenderX = 0; + double extenderY = -3.0f / 16.0f; + double extenderZ = 0; + double inputXStep = 0; + double inputZStep = 0; + Icon* extenderTex; + + if (tt->isReversedOutputSignal(data)) { + extenderTex = Tile::redstoneTorch_on->getTexture(Facing::DOWN); + } else { + extenderY -= 3 / 16.0f; + extenderTex = Tile::redstoneTorch_off->getTexture(Facing::DOWN); + } + + switch (dir) { + case Direction::SOUTH: + extenderZ = -5.0f / 16.0f; + inputZStep = 1; + break; + case Direction::NORTH: + extenderZ = 5.0f / 16.0f; + inputZStep = -1; + break; + case Direction::EAST: + extenderX = -5.0f / 16.0f; + inputXStep = 1; + break; + case Direction::WEST: + extenderX = 5.0f / 16.0f; + inputXStep = -1; + break; + } + + // Render the two input torches + tesselateTorch( + (Tile*)tt, x + (4 / 16.0f * inputXStep) + (3 / 16.0f * inputZStep), + y - 3 / 16.0f, z + (4 / 16.0f * inputZStep) + (3 / 16.0f * inputXStep), + 0, 0, data); + tesselateTorch( + (Tile*)tt, x + (4 / 16.0f * inputXStep) + (-3 / 16.0f * inputZStep), + y - 3 / 16.0f, z + (4 / 16.0f * inputZStep) + (-3 / 16.0f * inputXStep), + 0, 0, data); + + setFixedTexture(extenderTex); + tesselateTorch((Tile*)tt, x + extenderX, y + extenderY, z + extenderZ, 0, 0, + data); + clearFixedTexture(); + + tesselateDiodeInWorld((DiodeTile*)tt, x, y, z, dir); + + return true; +} + bool TileRenderer::tesselateDiodeInWorld(DiodeTile* tt, int x, int y, int z) { Tesselator* t = Tesselator::getInstance(); @@ -1127,43 +1332,9 @@ void TileRenderer::tesselateDiodeInWorld(DiodeTile* tt, int x, int y, int z, int data = level->getData(x, y, z); + // 4J-JEV - It's now been moved. // 4J Stu - This block gets moved in a later version, but we don't need that - // yet BEGIN TORCH SECTION - { - int dir = data & DiodeTile::DIRECTION_MASK; - int delay = (data & DiodeTile::DELAY_MASK) >> DiodeTile::DELAY_SHIFT; - float h = -3.0f / 16.0f; - float transmitterX = 0.0f; - float transmitterZ = 0.0f; - float receiverX = 0.0f; - float receiverZ = 0.0f; - - switch (dir) { - case Direction::SOUTH: - receiverZ = -5.0f / 16.0f; - transmitterZ = DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::NORTH: - receiverZ = 5.0f / 16.0f; - transmitterZ = -DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::EAST: - receiverX = -5.0f / 16.0f; - transmitterX = DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::WEST: - receiverX = 5.0f / 16.0f; - transmitterX = -DiodeTile::DELAY_RENDER_OFFSETS[delay]; - break; - } - - // render transmitter - tesselateTorch(tt, x + transmitterX, y + h, z + transmitterZ, 0.0f, - 0.0f, 0); - // render receiver - tesselateTorch(tt, x + receiverX, y + h, z + receiverZ, 0.0f, 0.0f, 0); - } - // END TORCH SECTION + // yet Icon* tex = getTexture(tt, Facing::UP, data); float u0 = tex->getU0(true); @@ -1604,7 +1775,7 @@ bool TileRenderer::tesselateLeverInWorld(Tile* tt, int x, int y, int z) { Tesselator* t = Tesselator::getInstance(); bool hadFixed = hasFixedTexture(); - if (!hadFixed) this->setFixedTexture(getTexture(Tile::stoneBrick)); + if (!hadFixed) this->setFixedTexture(getTexture(Tile::cobblestone)); float w1 = 4.0f / 16.0f; float w2 = 3.0f / 16.0f; float h = 3.0f / 16.0f; @@ -3049,6 +3220,371 @@ bool TileRenderer::tesselateVineInWorld(Tile* tt, int x, int y, int z) { return true; } +bool TileRenderer::tesselateThinPaneInWorld(Tile* tt, int x, int y, int z) { + int depth = level->getMaxBuildHeight(); + Tesselator* t = Tesselator::getInstance(); + + t->tex2(tt->getLightColor(level, x, y, 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; + + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); + + r = cr; + g = cg; + b = cb; + } + t->color(r, g, b); + + Icon* tex; + Icon* edgeTex; + + bool stained = dynamic_cast(tt) != NULL; + if (hasFixedTexture()) { + tex = fixedTexture; + edgeTex = fixedTexture; + } else { + int data = level->getData(x, y, z); + tex = getTexture(tt, 0, data); + edgeTex = (stained) ? ((StainedGlassPaneBlock*)tt)->getEdgeTexture(data) + : ((ThinFenceTile*)tt)->getEdgeTexture(); + } + + double u0 = tex->getU0(); + double iu0 = tex->getU(7); + double iu1 = tex->getU(9); + double u1 = tex->getU1(); + double v0 = tex->getV0(); + double v1 = tex->getV1(); + + double eiu0 = edgeTex->getU(7); + double eiu1 = edgeTex->getU(9); + double ev0 = edgeTex->getV0(); + double ev1 = edgeTex->getV1(); + double eiv0 = edgeTex->getV(7); + double eiv1 = edgeTex->getV(9); + + double x0 = x; + double x1 = x + 1; + double z0 = z; + double z1 = z + 1; + double ix0 = x + .5 - 1.0 / 16.0; + double ix1 = x + .5 + 1.0 / 16.0; + double iz0 = z + .5 - 1.0 / 16.0; + double iz1 = z + .5 + 1.0 / 16.0; + + bool n = (stained) + ? ((StainedGlassPaneBlock*)tt) + ->attachsTo(level->getTile(x, y, z - 1)) + : ((ThinFenceTile*)tt)->attachsTo(level->getTile(x, y, z - 1)); + bool s = (stained) + ? ((StainedGlassPaneBlock*)tt) + ->attachsTo(level->getTile(x, y, z + 1)) + : ((ThinFenceTile*)tt)->attachsTo(level->getTile(x, y, z + 1)); + bool w = (stained) + ? ((StainedGlassPaneBlock*)tt) + ->attachsTo(level->getTile(x - 1, y, z)) + : ((ThinFenceTile*)tt)->attachsTo(level->getTile(x - 1, y, z)); + bool e = (stained) + ? ((StainedGlassPaneBlock*)tt) + ->attachsTo(level->getTile(x + 1, y, z)) + : ((ThinFenceTile*)tt)->attachsTo(level->getTile(x + 1, y, z)); + + double noZFightingOffset = 0.001; + double yt = 1.0 - noZFightingOffset; + double yb = 0.0 + noZFightingOffset; + + bool none = !(n || s || w || e); + + if (w || none) { + if (w && e) { + if (!n) { + t->vertexUV(x1, y + yt, iz0, u1, v0); + t->vertexUV(x1, y + yb, iz0, u1, v1); + t->vertexUV(x0, y + yb, iz0, u0, v1); + t->vertexUV(x0, y + yt, iz0, u0, v0); + } else { + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(x0, y + yb, iz0, u0, v1); + t->vertexUV(x0, y + yt, iz0, u0, v0); + + t->vertexUV(x1, y + yt, iz0, u1, v0); + t->vertexUV(x1, y + yb, iz0, u1, v1); + t->vertexUV(ix1, y + yb, iz0, iu1, v1); + t->vertexUV(ix1, y + yt, iz0, iu1, v0); + } + if (!s) { + t->vertexUV(x0, y + yt, iz1, u0, v0); + t->vertexUV(x0, y + yb, iz1, u0, v1); + t->vertexUV(x1, y + yb, iz1, u1, v1); + t->vertexUV(x1, y + yt, iz1, u1, v0); + } else { + t->vertexUV(x0, y + yt, iz1, u0, v0); + t->vertexUV(x0, y + yb, iz1, u0, v1); + t->vertexUV(ix0, y + yb, iz1, iu0, v1); + t->vertexUV(ix0, y + yt, iz1, iu0, v0); + + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(x1, y + yb, iz1, u1, v1); + t->vertexUV(x1, y + yt, iz1, u1, v0); + } + + t->vertexUV(x0, y + yt, iz1, eiu1, ev0); + t->vertexUV(x1, y + yt, iz1, eiu1, ev1); + t->vertexUV(x1, y + yt, iz0, eiu0, ev1); + t->vertexUV(x0, y + yt, iz0, eiu0, ev0); + + t->vertexUV(x1, y + yb, iz1, eiu0, ev1); + t->vertexUV(x0, y + yb, iz1, eiu0, ev0); + t->vertexUV(x0, y + yb, iz0, eiu1, ev0); + t->vertexUV(x1, y + yb, iz0, eiu1, ev1); + } else { + if (!(n || none)) { + t->vertexUV(ix1, y + yt, iz0, iu1, v0); + t->vertexUV(ix1, y + yb, iz0, iu1, v1); + t->vertexUV(x0, y + yb, iz0, u0, v1); + t->vertexUV(x0, y + yt, iz0, u0, v0); + } else { + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(x0, y + yb, iz0, u0, v1); + t->vertexUV(x0, y + yt, iz0, u0, v0); + } + if (!(s || none)) { + t->vertexUV(x0, y + yt, iz1, u0, v0); + t->vertexUV(x0, y + yb, iz1, u0, v1); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + } else { + t->vertexUV(x0, y + yt, iz1, u0, v0); + t->vertexUV(x0, y + yb, iz1, u0, v1); + t->vertexUV(ix0, y + yb, iz1, iu0, v1); + t->vertexUV(ix0, y + yt, iz1, iu0, v0); + } + + t->vertexUV(x0, y + yt, iz1, eiu1, ev0); + t->vertexUV(ix0, y + yt, iz1, eiu1, eiv0); + t->vertexUV(ix0, y + yt, iz0, eiu0, eiv0); + t->vertexUV(x0, y + yt, iz0, eiu0, ev0); + + t->vertexUV(ix0, y + yb, iz1, eiu0, eiv0); + t->vertexUV(x0, y + yb, iz1, eiu0, ev0); + t->vertexUV(x0, y + yb, iz0, eiu1, ev0); + t->vertexUV(ix0, y + yb, iz0, eiu1, eiv0); + } + } else if (!(n || s)) { + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yb, iz1, iu1, v1); + t->vertexUV(ix0, y + yt, iz1, iu1, v0); + } + + if ((e || none) && !w) { + if (!(s || none)) { + t->vertexUV(ix0, y + yt, iz1, iu0, v0); + t->vertexUV(ix0, y + yb, iz1, iu0, v1); + t->vertexUV(x1, y + yb, iz1, u1, v1); + t->vertexUV(x1, y + yt, iz1, u1, v0); + } else { + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(x1, y + yb, iz1, u1, v1); + t->vertexUV(x1, y + yt, iz1, u1, v0); + } + if (!(n || none)) { + t->vertexUV(x1, y + yt, iz0, u1, v0); + t->vertexUV(x1, y + yb, iz0, u1, v1); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + } else { + t->vertexUV(x1, y + yt, iz0, u1, v0); + t->vertexUV(x1, y + yb, iz0, u1, v1); + t->vertexUV(ix1, y + yb, iz0, iu1, v1); + t->vertexUV(ix1, y + yt, iz0, iu1, v0); + } + + t->vertexUV(ix1, y + yt, iz1, eiu1, eiv1); + t->vertexUV(x1, y + yt, iz1, eiu1, ev0); + t->vertexUV(x1, y + yt, iz0, eiu0, ev0); + t->vertexUV(ix1, y + yt, iz0, eiu0, eiv1); + + t->vertexUV(x1, y + yb, iz1, eiu0, ev1); + t->vertexUV(ix1, y + yb, iz1, eiu0, eiv1); + t->vertexUV(ix1, y + yb, iz0, eiu1, eiv1); + t->vertexUV(x1, y + yb, iz0, eiu1, ev1); + } else if (!(e || n || s)) { + t->vertexUV(ix1, y + yt, iz1, iu0, v0); + t->vertexUV(ix1, y + yb, iz1, iu0, v1); + t->vertexUV(ix1, y + yb, iz0, iu1, v1); + t->vertexUV(ix1, y + yt, iz0, iu1, v0); + } + + if (n || none) { + if (n && s) { + if (!w) { + t->vertexUV(ix0, y + yt, z0, u0, v0); + t->vertexUV(ix0, y + yb, z0, u0, v1); + t->vertexUV(ix0, y + yb, z1, u1, v1); + t->vertexUV(ix0, y + yt, z1, u1, v0); + } else { + t->vertexUV(ix0, y + yt, z0, u0, v0); + t->vertexUV(ix0, y + yb, z0, u0, v1); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + + t->vertexUV(ix0, y + yt, iz1, iu1, v0); + t->vertexUV(ix0, y + yb, iz1, iu1, v1); + t->vertexUV(ix0, y + yb, z1, u1, v1); + t->vertexUV(ix0, y + yt, z1, u1, v0); + } + if (!e) { + t->vertexUV(ix1, y + yt, z1, u1, v0); + t->vertexUV(ix1, y + yb, z1, u1, v1); + t->vertexUV(ix1, y + yb, z0, u0, v1); + t->vertexUV(ix1, y + yt, z0, u0, v0); + } else { + t->vertexUV(ix1, y + yt, iz0, iu0, v0); + t->vertexUV(ix1, y + yb, iz0, iu0, v1); + t->vertexUV(ix1, y + yb, z0, u0, v1); + t->vertexUV(ix1, y + yt, z0, u0, v0); + + t->vertexUV(ix1, y + yt, z1, u1, v0); + t->vertexUV(ix1, y + yb, z1, u1, v1); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + } + + t->vertexUV(ix1, y + yt, z0, eiu1, ev0); + t->vertexUV(ix0, y + yt, z0, eiu0, ev0); + t->vertexUV(ix0, y + yt, z1, eiu0, ev1); + t->vertexUV(ix1, y + yt, z1, eiu1, ev1); + + t->vertexUV(ix0, y + yb, z0, eiu0, ev0); + t->vertexUV(ix1, y + yb, z0, eiu1, ev0); + t->vertexUV(ix1, y + yb, z1, eiu1, ev1); + t->vertexUV(ix0, y + yb, z1, eiu0, ev1); + } else { + if (!(w || none)) { + t->vertexUV(ix0, y + yt, z0, u0, v0); + t->vertexUV(ix0, y + yb, z0, u0, v1); + t->vertexUV(ix0, y + yb, iz1, iu1, v1); + t->vertexUV(ix0, y + yt, iz1, iu1, v0); + } else { + t->vertexUV(ix0, y + yt, z0, u0, v0); + t->vertexUV(ix0, y + yb, z0, u0, v1); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + } + if (!(e || none)) { + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(ix1, y + yb, z0, u0, v1); + t->vertexUV(ix1, y + yt, z0, u0, v0); + } else { + t->vertexUV(ix1, y + yt, iz0, iu0, v0); + t->vertexUV(ix1, y + yb, iz0, iu0, v1); + t->vertexUV(ix1, y + yb, z0, u0, v1); + t->vertexUV(ix1, y + yt, z0, u0, v0); + } + + t->vertexUV(ix1, y + yt, z0, eiu1, ev0); + t->vertexUV(ix0, y + yt, z0, eiu0, ev0); + t->vertexUV(ix0, y + yt, iz0, eiu0, eiv0); + t->vertexUV(ix1, y + yt, iz0, eiu1, eiv0); + + t->vertexUV(ix0, y + yb, z0, eiu0, ev0); + t->vertexUV(ix1, y + yb, z0, eiu1, ev0); + t->vertexUV(ix1, y + yb, iz0, eiu1, eiv0); + t->vertexUV(ix0, y + yb, iz0, eiu0, eiv0); + } + } else if (!(e || w)) { + t->vertexUV(ix1, y + yt, iz0, iu1, v0); + t->vertexUV(ix1, y + yb, iz0, iu1, v1); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + } + + if ((s || none) && !n) { + if (!(w || none)) { + t->vertexUV(ix0, y + yt, iz0, iu0, v0); + t->vertexUV(ix0, y + yb, iz0, iu0, v1); + t->vertexUV(ix0, y + yb, z1, u1, v1); + t->vertexUV(ix0, y + yt, z1, u1, v0); + } else { + t->vertexUV(ix0, y + yt, iz1, iu1, v0); + t->vertexUV(ix0, y + yb, iz1, iu1, v1); + t->vertexUV(ix0, y + yb, z1, u1, v1); + t->vertexUV(ix0, y + yt, z1, u1, v0); + } + if (!(e || none)) { + t->vertexUV(ix1, y + yt, z1, u1, v0); + t->vertexUV(ix1, y + yb, z1, u1, v1); + t->vertexUV(ix1, y + yb, iz0, iu0, v1); + t->vertexUV(ix1, y + yt, iz0, iu0, v0); + } else { + t->vertexUV(ix1, y + yt, z1, u1, v0); + t->vertexUV(ix1, y + yb, z1, u1, v1); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + } + + t->vertexUV(ix1, y + yt, iz1, eiu1, eiv1); + t->vertexUV(ix0, y + yt, iz1, eiu0, eiv1); + t->vertexUV(ix0, y + yt, z1, eiu0, ev1); + t->vertexUV(ix1, y + yt, z1, eiu1, ev1); + + t->vertexUV(ix0, y + yb, iz1, eiu0, eiv1); + t->vertexUV(ix1, y + yb, iz1, eiu1, eiv1); + t->vertexUV(ix1, y + yb, z1, eiu1, ev1); + t->vertexUV(ix0, y + yb, z1, eiu0, ev1); + } else if (!(s || e || w)) { + t->vertexUV(ix0, y + yt, iz1, iu0, v0); + t->vertexUV(ix0, y + yb, iz1, iu0, v1); + t->vertexUV(ix1, y + yb, iz1, iu1, v1); + t->vertexUV(ix1, y + yt, iz1, iu1, v0); + } + + t->vertexUV(ix1, y + yt, iz0, eiu1, eiv0); + t->vertexUV(ix0, y + yt, iz0, eiu0, eiv0); + t->vertexUV(ix0, y + yt, iz1, eiu0, eiv1); + t->vertexUV(ix1, y + yt, iz1, eiu1, eiv1); + + t->vertexUV(ix0, y + yb, iz0, eiu0, eiv0); + t->vertexUV(ix1, y + yb, iz0, eiu1, eiv0); + t->vertexUV(ix1, y + yb, iz1, eiu1, eiv1); + t->vertexUV(ix0, y + yb, iz1, eiu0, eiv1); + + if (none) { + t->vertexUV(x0, y + yt, iz0, iu0, v0); + t->vertexUV(x0, y + yb, iz0, iu0, v1); + t->vertexUV(x0, y + yb, iz1, iu1, v1); + t->vertexUV(x0, y + yt, iz1, iu1, v0); + + t->vertexUV(x1, y + yt, iz1, iu0, v0); + t->vertexUV(x1, y + yb, iz1, iu0, v1); + t->vertexUV(x1, y + yb, iz0, iu1, v1); + t->vertexUV(x1, y + yt, iz0, iu1, v0); + + t->vertexUV(ix1, y + yt, z0, iu1, v0); + t->vertexUV(ix1, y + yb, z0, iu1, v1); + t->vertexUV(ix0, y + yb, z0, iu0, v1); + t->vertexUV(ix0, y + yt, z0, iu0, v0); + + t->vertexUV(ix0, y + yt, z1, iu0, v0); + t->vertexUV(ix0, y + yb, z1, iu0, v1); + t->vertexUV(ix1, y + yb, z1, iu1, v1); + t->vertexUV(ix1, y + yt, z1, iu1, v0); + } + return true; +} + bool TileRenderer::tesselateThinFenceInWorld(ThinFenceTile* tt, int x, int y, int z) { int depth = level->getMaxBuildHeight(); @@ -3532,11 +4068,8 @@ bool TileRenderer::tesselateCrossInWorld(Tile* tt, int x, int y, int z) { float zt = (float)z; if (tt == Tile::tallgrass) { - // 4jcraft add a bunch of casts to prevent overflow (i pray to god) - int64_t seed = - ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); - seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + - ((uint64_t)seed * 11ULL)); + int64_t seed = (x * 3129871) ^ (z * 116129781l) ^ (y); + seed = seed * seed * 42317861 + seed * 11; xt += ((((seed >> 16) & 0xf) / 15.0f) - 0.5f) * 0.5f; yt += ((((seed >> 20) & 0xf) / 15.0f) - 1.0f) * 0.2f; @@ -3791,11 +4324,9 @@ bool TileRenderer::tesselateLilypadInWorld(Tile* tt, int x, int y, int z) { float u1 = tex->getU1(true); float v1 = tex->getV1(true); - // 4jcraft add a bunch of casts to prevent overflow (i pray to god) - int64_t seed = - ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); - seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + - ((uint64_t)seed * 11ULL)); + int64_t seed = (x * 3129871) ^ (z * 116129781l) ^ (y); + seed = seed * seed * 42317861 + seed * 11; + int dir = (int)((seed >> 16) & 0x3); t->tex2(getLightColor(tt, level, x, y, z)); @@ -4292,7 +4823,7 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tt, int x, int y, int z) { 0) // 4J - TODO/remove (Minecraft::useAmbientOcclusion()) { return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( - tt, x, y, z, r, g, b, 0); + tt, x, y, z, r, g, b, 0, smoothShapeLighting); } else { return tesselateBlockInWorld(tt, x, y, z, r, g, b); } @@ -4320,7 +4851,7 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tt, int x, int y, int z, 0) // 4J - TODO/remove (Minecraft::useAmbientOcclusion()) { return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( - tt, x, y, z, r, g, b, faceFlags); + tt, x, y, z, r, g, b, faceFlags, smoothShapeLighting); } else { return tesselateBlockInWorld(tt, x, y, z, r, g, b); } @@ -4572,7 +5103,7 @@ bool TileRenderer::tesselateCocoaInWorld(CocoaTile* tt, int x, int y, int z) { // 4J - brought changes forward from 1.8.2 bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( Tile* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, - float pBaseBlue, int faceFlags) { + float pBaseBlue, int faceFlags, bool smoothShapeLighting) { // 4J - the texture is (originally) obtained for each face in the block, if // those faces are visible. For a lot of blocks, the textures don't vary // from face to face - this is particularly an issue for leaves as they not @@ -4619,131 +5150,98 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( } applyAmbienceOcclusion = true; - float ll1 = ll000; - float ll2 = ll000; - float ll3 = ll000; - float ll4 = ll000; - bool tint0 = true; - bool tint1 = true; - bool tint2 = true; - bool tint3 = true; - bool tint4 = true; - bool tint5 = true; + bool i = false; + float ll1 = 0; + float ll2 = 0; + float ll3 = 0; + float ll4 = 0; - ll000 = getShadeBrightness(tt, level, pX, pY, pZ); - llx00 = getShadeBrightness(tt, level, pX - 1, pY, pZ); - ll0y0 = getShadeBrightness(tt, level, pX, pY - 1, pZ); - ll00z = getShadeBrightness(tt, level, pX, pY, pZ - 1); - llX00 = getShadeBrightness(tt, level, pX + 1, pY, pZ); - ll0Y0 = getShadeBrightness(tt, level, pX, pY + 1, pZ); - ll00Z = getShadeBrightness(tt, level, pX, pY, pZ + 1); + bool tintSides = true; - // 4J - these changes brought forward from 1.2.3 int centerColor = getLightColor(tt, level, pX, pY, pZ); - int ccx00 = centerColor; - int cc0y0 = centerColor; - int cc00z = centerColor; - int ccX00 = centerColor; - int cc0Y0 = centerColor; - int cc00Z = centerColor; - - if (tileShapeY0 <= 0 || !level->isSolidRenderTile(pX, pY - 1, pZ)) - cc0y0 = getLightColor(tt, level, pX, pY - 1, pZ); - if (tileShapeY1 >= 1 || !level->isSolidRenderTile(pX, pY + 1, pZ)) - cc0Y0 = getLightColor(tt, level, pX, pY + 1, pZ); - if (tileShapeX0 <= 0 || !level->isSolidRenderTile(pX - 1, pY, pZ)) - ccx00 = getLightColor(tt, level, pX - 1, pY, pZ); - if (tileShapeX1 >= 1 || !level->isSolidRenderTile(pX + 1, pY, pZ)) - ccX00 = getLightColor(tt, level, pX + 1, pY, pZ); - if (tileShapeZ0 <= 0 || !level->isSolidRenderTile(pX, pY, pZ - 1)) - cc00z = getLightColor(tt, level, pX, pY, pZ - 1); - if (tileShapeZ1 >= 1 || !level->isSolidRenderTile(pX, pY, pZ + 1)) - cc00Z = getLightColor(tt, level, pX, pY, pZ + 1); Tesselator* t = Tesselator::getInstance(); t->tex2(0xf000f); - llTransXY0 = isTranslucentAt(level, pX + 1, pY + 1, pZ); - llTransXy0 = isTranslucentAt(level, pX + 1, pY - 1, pZ); - llTransX0Z = isTranslucentAt(level, pX + 1, pY, pZ + 1); - llTransX0z = isTranslucentAt(level, pX + 1, pY, pZ - 1); - llTransxY0 = isTranslucentAt(level, pX - 1, pY + 1, pZ); - llTransxy0 = isTranslucentAt(level, pX - 1, pY - 1, pZ); - llTransx0z = isTranslucentAt(level, pX - 1, pY, pZ - 1); - llTransx0Z = isTranslucentAt(level, pX - 1, pY, pZ + 1); - llTrans0YZ = isTranslucentAt(level, pX, pY + 1, pZ + 1); - llTrans0Yz = isTranslucentAt(level, pX, pY + 1, pZ - 1); - llTrans0yZ = isTranslucentAt(level, pX, pY - 1, pZ + 1); - llTrans0yz = isTranslucentAt(level, pX, pY - 1, pZ - 1); - if (uniformTex == NULL) { - if (getTexture(tt)->getFlags() == Icon::IS_GRASS_TOP) - tint0 = tint2 = tint3 = tint4 = tint5 = false; + if (getTexture(tt)->getFlags() == Icon::IS_GRASS_TOP) tintSides = false; + } else if (hasFixedTexture()) { + tintSides = false; } - if (hasFixedTexture()) tint0 = tint2 = tint3 = tint4 = tint5 = false; if (faceFlags & 0x01) { - if (blsmooth > 0) { - if (tileShapeY0 <= 0) - pY--; // 4J - condition brought forward from 1.2.3 + if (tileShapeY0 <= 0) pY--; - ccxy0 = getLightColor(tt, level, pX - 1, pY, pZ); - cc0yz = getLightColor(tt, level, pX, pY, pZ - 1); - cc0yZ = getLightColor(tt, level, pX, pY, pZ + 1); - ccXy0 = getLightColor(tt, level, pX + 1, pY, pZ); + ccxy0 = getLightColor(tt, level, pX - 1, pY, pZ); + cc0yz = getLightColor(tt, level, pX, pY, pZ - 1); + cc0yZ = getLightColor(tt, level, pX, pY, pZ + 1); + ccXy0 = getLightColor(tt, level, pX + 1, pY, pZ); - llxy0 = getShadeBrightness(tt, level, pX - 1, pY, pZ); - ll0yz = getShadeBrightness(tt, level, pX, pY, pZ - 1); - ll0yZ = getShadeBrightness(tt, level, pX, pY, pZ + 1); - llXy0 = getShadeBrightness(tt, level, pX + 1, pY, pZ); + llxy0 = getShadeBrightness(tt, level, pX - 1, pY, pZ); + ll0yz = getShadeBrightness(tt, level, pX, pY, pZ - 1); + ll0yZ = getShadeBrightness(tt, level, pX, pY, pZ + 1); + llXy0 = getShadeBrightness(tt, level, pX + 1, pY, pZ); - if (llTrans0yz || llTransxy0) { - llxyz = getShadeBrightness(tt, level, pX - 1, pY, pZ - 1); - ccxyz = getLightColor(tt, level, pX - 1, pY, pZ - 1); - } else { - llxyz = llxy0; - ccxyz = ccxy0; - } - if (llTrans0yZ || llTransxy0) { - llxyZ = getShadeBrightness(tt, level, pX - 1, pY, pZ + 1); - ccxyZ = getLightColor(tt, level, pX - 1, pY, pZ + 1); - } else { - llxyZ = llxy0; - ccxyZ = ccxy0; - } - if (llTrans0yz || llTransXy0) { - llXyz = getShadeBrightness(tt, level, pX + 1, pY, pZ - 1); - ccXyz = getLightColor(tt, level, pX + 1, pY, pZ - 1); - } else { - llXyz = llXy0; - ccXyz = ccXy0; - } - if (llTrans0yZ || llTransXy0) { - llXyZ = getShadeBrightness(tt, level, pX + 1, pY, pZ + 1); - ccXyZ = getLightColor(tt, level, pX + 1, pY, pZ + 1); - } else { - llXyZ = llXy0; - ccXyZ = ccXy0; - } + bool llTransXy0 = Tile::transculent[level->getTile(pX + 1, pY - 1, pZ)]; + bool llTransxy0 = Tile::transculent[level->getTile(pX - 1, pY - 1, pZ)]; + bool llTrans0yZ = Tile::transculent[level->getTile(pX, pY - 1, pZ + 1)]; + bool llTrans0yz = Tile::transculent[level->getTile(pX, pY - 1, pZ - 1)]; - if (tileShapeY0 <= 0) - pY++; // 4J - condition brought forward from 1.2.3 - ll1 = (llxyZ + llxy0 + ll0yZ + ll0y0) / 4.0f; - ll4 = (ll0yZ + ll0y0 + llXyZ + llXy0) / 4.0f; - ll3 = (ll0y0 + ll0yz + llXy0 + llXyz) / 4.0f; - ll2 = (llxy0 + llxyz + ll0y0 + ll0yz) / 4.0f; - - tc1 = blend(ccxyZ, ccxy0, cc0yZ, cc0y0); - tc4 = blend(cc0yZ, ccXyZ, ccXy0, cc0y0); - tc3 = blend(cc0yz, ccXy0, ccXyz, cc0y0); - tc2 = blend(ccxy0, ccxyz, cc0yz, cc0y0); + if (llTrans0yz || llTransxy0) { + llxyz = getShadeBrightness(tt, level, pX - 1, pY, pZ - 1); + ccxyz = getLightColor(tt, level, pX - 1, pY, pZ - 1); } else { - ll1 = ll2 = ll3 = ll4 = ll0y0; - tc1 = tc2 = tc3 = tc4 = ccxy0; + llxyz = llxy0; + ccxyz = ccxy0; + } + if (llTrans0yZ || llTransxy0) { + llxyZ = getShadeBrightness(tt, level, pX - 1, pY, pZ + 1); + ccxyZ = getLightColor(tt, level, pX - 1, pY, pZ + 1); + } else { + llxyZ = llxy0; + ccxyZ = ccxy0; + } + if (llTrans0yz || llTransXy0) { + llXyz = getShadeBrightness(tt, level, pX + 1, pY, pZ - 1); + ccXyz = getLightColor(tt, level, pX + 1, pY, pZ - 1); + } else { + llXyz = llXy0; + ccXyz = ccXy0; + } + if (llTrans0yZ || llTransXy0) { + llXyZ = getShadeBrightness(tt, level, pX + 1, pY, pZ + 1); + ccXyZ = getLightColor(tt, level, pX + 1, pY, pZ + 1); + } else { + llXyZ = llXy0; + ccXyZ = ccXy0; + } + + if (tileShapeY0 <= 0) pY++; + + int cc0y0 = centerColor; + if (tileShapeY0 <= 0 || !level->isSolidRenderTile(pX, pY - 1, pZ)) + cc0y0 = tt->getLightColor(level, pX, pY - 1, pZ); + float ll0y0 = tt->getShadeBrightness(level, pX, pY - 1, pZ); + + ll1 = (llxyZ + llxy0 + ll0yZ + ll0y0) / 4.0f; + ll4 = (ll0yZ + ll0y0 + llXyZ + llXy0) / 4.0f; + ll3 = (ll0y0 + ll0yz + llXy0 + llXyz) / 4.0f; + ll2 = (llxy0 + llxyz + ll0y0 + ll0yz) / 4.0f; + + tc1 = blend(ccxyZ, ccxy0, cc0yZ, cc0y0); + tc4 = blend(cc0yZ, ccXyZ, ccXy0, cc0y0); + tc3 = blend(cc0yz, ccXy0, ccXyz, cc0y0); + tc2 = blend(ccxy0, ccxyz, cc0yz, cc0y0); + + if (tintSides) { + c1r = c2r = c3r = c4r = pBaseRed * 0.5f; + c1g = c2g = c3g = c4g = pBaseGreen * 0.5f; + c1b = c2b = c3b = c4b = pBaseBlue * 0.5f; + } else { + c1r = c2r = c3r = c4r = 0.5f; + c1g = c2g = c3g = c4g = 0.5f; + c1b = c2b = c3b = c4b = 0.5f; } - c1r = c2r = c3r = c4r = (tint0 ? pBaseRed : 1.0f) * 0.5f; - c1g = c2g = c3g = c4g = (tint0 ? pBaseGreen : 1.0f) * 0.5f; - c1b = c2b = c3b = c4b = (tint0 ? pBaseBlue : 1.0f) * 0.5f; c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -4760,69 +5258,75 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( renderFaceDown( tt, (double)pX, (double)pY, (double)pZ, uniformTex ? uniformTex : getTexture(tt, level, pX, pY, pZ, 0)); + i = true; } if (faceFlags & 0x02) { - if (blsmooth > 0) { - if (tileShapeY1 >= 1) - pY++; // 4J - condition brought forward from 1.2.3 + if (tileShapeY1 >= 1) + pY++; // 4J - condition brought forward from 1.2.3 - ccxY0 = getLightColor(tt, level, pX - 1, pY, pZ); - ccXY0 = getLightColor(tt, level, pX + 1, pY, pZ); - cc0Yz = getLightColor(tt, level, pX, pY, pZ - 1); - cc0YZ = getLightColor(tt, level, pX, pY, pZ + 1); + ccxY0 = getLightColor(tt, level, pX - 1, pY, pZ); + ccXY0 = getLightColor(tt, level, pX + 1, pY, pZ); + cc0Yz = getLightColor(tt, level, pX, pY, pZ - 1); + cc0YZ = getLightColor(tt, level, pX, pY, pZ + 1); - llxY0 = getShadeBrightness(tt, level, pX - 1, pY, pZ); - llXY0 = getShadeBrightness(tt, level, pX + 1, pY, pZ); - ll0Yz = getShadeBrightness(tt, level, pX, pY, pZ - 1); - ll0YZ = getShadeBrightness(tt, level, pX, pY, pZ + 1); + llxY0 = getShadeBrightness(tt, level, pX - 1, pY, pZ); + llXY0 = getShadeBrightness(tt, level, pX + 1, pY, pZ); + ll0Yz = getShadeBrightness(tt, level, pX, pY, pZ - 1); + ll0YZ = getShadeBrightness(tt, level, pX, pY, pZ + 1); - if (llTrans0Yz || llTransxY0) { - llxYz = getShadeBrightness(tt, level, pX - 1, pY, pZ - 1); - ccxYz = getLightColor(tt, level, pX - 1, pY, pZ - 1); - } else { - llxYz = llxY0; - ccxYz = ccxY0; - } - if (llTrans0Yz || llTransXY0) { - llXYz = getShadeBrightness(tt, level, pX + 1, pY, pZ - 1); - ccXYz = getLightColor(tt, level, pX + 1, pY, pZ - 1); - } else { - llXYz = llXY0; - ccXYz = ccXY0; - } - if (llTrans0YZ || llTransxY0) { - llxYZ = getShadeBrightness(tt, level, pX - 1, pY, pZ + 1); - ccxYZ = getLightColor(tt, level, pX - 1, pY, pZ + 1); - } else { - llxYZ = llxY0; - ccxYZ = ccxY0; - } - if (llTrans0YZ || llTransXY0) { - llXYZ = getShadeBrightness(tt, level, pX + 1, pY, pZ + 1); - ccXYZ = getLightColor(tt, level, pX + 1, pY, pZ + 1); - } else { - llXYZ = llXY0; - ccXYZ = ccXY0; - } - if (tileShapeY1 >= 1) - pY--; // 4J - condition brought forward from 1.2.3 + bool llTransXY0 = Tile::transculent[level->getTile(pX + 1, pY + 1, pZ)]; + bool llTransxY0 = Tile::transculent[level->getTile(pX - 1, pY + 1, pZ)]; + bool llTrans0YZ = Tile::transculent[level->getTile(pX, pY + 1, pZ + 1)]; + bool llTrans0Yz = Tile::transculent[level->getTile(pX, pY + 1, pZ - 1)]; - ll4 = (llxYZ + llxY0 + ll0YZ + ll0Y0) / 4.0f; - ll1 = (ll0YZ + ll0Y0 + llXYZ + llXY0) / 4.0f; - ll2 = (ll0Y0 + ll0Yz + llXY0 + llXYz) / 4.0f; - ll3 = (llxY0 + llxYz + ll0Y0 + ll0Yz) / 4.0f; - - tc4 = blend(ccxYZ, ccxY0, cc0YZ, cc0Y0); - tc1 = blend(cc0YZ, ccXYZ, ccXY0, cc0Y0); - tc2 = blend(cc0Yz, ccXY0, ccXYz, cc0Y0); - tc3 = blend(ccxY0, ccxYz, cc0Yz, cc0Y0); + if (llTrans0Yz || llTransxY0) { + llxYz = getShadeBrightness(tt, level, pX - 1, pY, pZ - 1); + ccxYz = getLightColor(tt, level, pX - 1, pY, pZ - 1); } else { - ll1 = ll2 = ll3 = ll4 = ll0Y0; - tc1 = tc2 = tc3 = tc4 = cc0Y0; + llxYz = llxY0; + ccxYz = ccxY0; } - c1r = c2r = c3r = c4r = (tint1 ? pBaseRed : 1.0f); - c1g = c2g = c3g = c4g = (tint1 ? pBaseGreen : 1.0f); - c1b = c2b = c3b = c4b = (tint1 ? pBaseBlue : 1.0f); + if (llTrans0Yz || llTransXY0) { + llXYz = getShadeBrightness(tt, level, pX + 1, pY, pZ - 1); + ccXYz = getLightColor(tt, level, pX + 1, pY, pZ - 1); + } else { + llXYz = llXY0; + ccXYz = ccXY0; + } + if (llTrans0YZ || llTransxY0) { + llxYZ = getShadeBrightness(tt, level, pX - 1, pY, pZ + 1); + ccxYZ = getLightColor(tt, level, pX - 1, pY, pZ + 1); + } else { + llxYZ = llxY0; + ccxYZ = ccxY0; + } + if (llTrans0YZ || llTransXY0) { + llXYZ = getShadeBrightness(tt, level, pX + 1, pY, pZ + 1); + ccXYZ = getLightColor(tt, level, pX + 1, pY, pZ + 1); + } else { + llXYZ = llXY0; + ccXYZ = ccXY0; + } + if (tileShapeY1 >= 1) pY--; + + int cc0Y0 = centerColor; + if (tileShapeY1 >= 1 || !level->isSolidRenderTile(pX, pY + 1, pZ)) + cc0Y0 = tt->getLightColor(level, pX, pY + 1, pZ); + float ll0Y0 = tt->getShadeBrightness(level, pX, pY + 1, pZ); + + ll4 = (llxYZ + llxY0 + ll0YZ + ll0Y0) / 4.0f; + ll1 = (ll0YZ + ll0Y0 + llXYZ + llXY0) / 4.0f; + ll2 = (ll0Y0 + ll0Yz + llXY0 + llXYz) / 4.0f; + ll3 = (llxY0 + llxYz + ll0Y0 + ll0Yz) / 4.0f; + + tc4 = blend(ccxYZ, ccxY0, cc0YZ, cc0Y0); + tc1 = blend(cc0YZ, ccXYZ, ccXY0, cc0Y0); + tc2 = blend(cc0Yz, ccXY0, ccXYz, cc0Y0); + tc3 = blend(ccxY0, ccxYz, cc0Yz, cc0Y0); + + c1r = c2r = c3r = c4r = pBaseRed; + c1g = c2g = c3g = c4g = pBaseGreen; + c1b = c2b = c3b = c4b = pBaseBlue; c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -4838,57 +5342,66 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( renderFaceUp( tt, (double)pX, (double)pY, (double)pZ, uniformTex ? uniformTex : getTexture(tt, level, pX, pY, pZ, 1)); + i = true; } if (faceFlags & 0x04) { - if (blsmooth > 0) { - if (tileShapeZ0 <= 0) - pZ--; // 4J - condition brought forward from 1.2.3 - llx0z = getShadeBrightness(tt, level, pX - 1, pY, pZ); - ll0yz = getShadeBrightness(tt, level, pX, pY - 1, pZ); - ll0Yz = getShadeBrightness(tt, level, pX, pY + 1, pZ); - llX0z = getShadeBrightness(tt, level, pX + 1, pY, pZ); + if (tileShapeZ0 <= 0) + pZ--; // 4J - condition brought forward from 1.2.3 + llx0z = getShadeBrightness(tt, level, pX - 1, pY, pZ); + ll0yz = getShadeBrightness(tt, level, pX, pY - 1, pZ); + ll0Yz = getShadeBrightness(tt, level, pX, pY + 1, pZ); + llX0z = getShadeBrightness(tt, level, pX + 1, pY, pZ); - ccx0z = getLightColor(tt, level, pX - 1, pY, pZ); - cc0yz = getLightColor(tt, level, pX, pY - 1, pZ); - cc0Yz = getLightColor(tt, level, pX, pY + 1, pZ); - ccX0z = getLightColor(tt, level, pX + 1, pY, pZ); + ccx0z = getLightColor(tt, level, pX - 1, pY, pZ); + cc0yz = getLightColor(tt, level, pX, pY - 1, pZ); + cc0Yz = getLightColor(tt, level, pX, pY + 1, pZ); + ccX0z = getLightColor(tt, level, pX + 1, pY, pZ); - if (llTransx0z || llTrans0yz) { - llxyz = getShadeBrightness(tt, level, pX - 1, pY - 1, pZ); - ccxyz = getLightColor(tt, level, pX - 1, pY - 1, pZ); - } else { - llxyz = llx0z; - ccxyz = ccx0z; - } - if (llTransx0z || llTrans0Yz) { - llxYz = getShadeBrightness(tt, level, pX - 1, pY + 1, pZ); - ccxYz = getLightColor(tt, level, pX - 1, pY + 1, pZ); - } else { - llxYz = llx0z; - ccxYz = ccx0z; - } - if (llTransX0z || llTrans0yz) { - llXyz = getShadeBrightness(tt, level, pX + 1, pY - 1, pZ); - ccXyz = getLightColor(tt, level, pX + 1, pY - 1, pZ); - } else { - llXyz = llX0z; - ccXyz = ccX0z; - } - if (llTransX0z || llTrans0Yz) { - llXYz = getShadeBrightness(tt, level, pX + 1, pY + 1, pZ); - ccXYz = getLightColor(tt, level, pX + 1, pY + 1, pZ); - } else { - llXYz = llX0z; - ccXYz = ccX0z; - } - if (tileShapeZ0 <= 0) - pZ++; // 4J - condition brought forward from 1.2.3 + bool llTransX0z = Tile::transculent[level->getTile(pX + 1, pY, pZ - 1)]; + bool llTransx0z = Tile::transculent[level->getTile(pX - 1, pY, pZ - 1)]; + bool llTrans0Yz = Tile::transculent[level->getTile(pX, pY + 1, pZ - 1)]; + bool llTrans0yz = Tile::transculent[level->getTile(pX, pY - 1, pZ - 1)]; - if (smoothShapeLighting && - false) // minecraft->options->ambientOcclusion >= - // Options::AO_MAX) // 4J - disabling AO_MAX - // until we work out exactly what its peformance - // implications are/what it fixes + if (llTransx0z || llTrans0yz) { + llxyz = getShadeBrightness(tt, level, pX - 1, pY - 1, pZ); + ccxyz = getLightColor(tt, level, pX - 1, pY - 1, pZ); + } else { + llxyz = llx0z; + ccxyz = ccx0z; + } + if (llTransx0z || llTrans0Yz) { + llxYz = getShadeBrightness(tt, level, pX - 1, pY + 1, pZ); + ccxYz = getLightColor(tt, level, pX - 1, pY + 1, pZ); + } else { + llxYz = llx0z; + ccxYz = ccx0z; + } + if (llTransX0z || llTrans0yz) { + llXyz = getShadeBrightness(tt, level, pX + 1, pY - 1, pZ); + ccXyz = getLightColor(tt, level, pX + 1, pY - 1, pZ); + } else { + llXyz = llX0z; + ccXyz = ccX0z; + } + if (llTransX0z || llTrans0Yz) { + llXYz = getShadeBrightness(tt, level, pX + 1, pY + 1, pZ); + ccXYz = getLightColor(tt, level, pX + 1, pY + 1, pZ); + } else { + llXYz = llX0z; + ccXYz = ccX0z; + } + if (tileShapeZ0 <= 0) pZ++; + + int cc00z = centerColor; + if (tileShapeZ0 <= 0 || !level->isSolidRenderTile(pX, pY, pZ - 1)) + cc00z = tt->getLightColor(level, pX, pY, pZ - 1); + float ll00z = tt->getShadeBrightness(level, pX, pY, pZ - 1); + + { + if (smoothShapeLighting) // MGH - unifying + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting + // and + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting2 { float _ll1 = (llx0z + llxYz + ll00z + ll0Yz) / 4.0f; float _ll2 = (ll00z + ll0Yz + llX0z + llXYz) / 4.0f; @@ -4935,6 +5448,7 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tileShapeY0 * tileShapeX0, (1.0 - tileShapeY0) * tileShapeX0, (1.0 - tileShapeY0) * (1.0 - tileShapeX0)); + } else { ll1 = (llx0z + llxYz + ll00z + ll0Yz) / 4.0f; ll2 = (ll00z + ll0Yz + llX0z + llXYz) / 4.0f; @@ -4946,13 +5460,17 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tc3 = blend(cc0yz, ccXyz, ccX0z, cc00z); tc4 = blend(ccxyz, ccx0z, cc0yz, cc00z); } - } else { - ll1 = ll2 = ll3 = ll4 = ll00z; - tc1 = tc2 = tc3 = tc4 = cc00z; } - c1r = c2r = c3r = c4r = (tint2 ? pBaseRed : 1.0f) * 0.8f; - c1g = c2g = c3g = c4g = (tint2 ? pBaseGreen : 1.0f) * 0.8f; - c1b = c2b = c3b = c4b = (tint2 ? pBaseBlue : 1.0f) * 0.8f; + + if (tintSides) { + c1r = c2r = c3r = c4r = pBaseRed * 0.8f; + c1g = c2g = c3g = c4g = pBaseGreen * 0.8f; + c1b = c2b = c3b = c4b = pBaseBlue * 0.8f; + } else { + c1r = c2r = c3r = c4r = 0.8f; + c1g = c2g = c3g = c4g = 0.8f; + c1b = c2b = c3b = c4b = 0.8f; + } c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -4991,57 +5509,67 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( GrassTile::getSideTextureOverlay()); t->setMipmapEnable(prev); } + + i = true; } if (faceFlags & 0x08) { - if (blsmooth > 0) { - if (tileShapeZ1 >= 1) - pZ++; // 4J - condition brought forward from 1.2.3 + if (tileShapeZ1 >= 1) pZ++; - llx0Z = getShadeBrightness(tt, level, pX - 1, pY, pZ); - llX0Z = getShadeBrightness(tt, level, pX + 1, pY, pZ); - ll0yZ = getShadeBrightness(tt, level, pX, pY - 1, pZ); - ll0YZ = getShadeBrightness(tt, level, pX, pY + 1, pZ); + llx0Z = getShadeBrightness(tt, level, pX - 1, pY, pZ); + llX0Z = getShadeBrightness(tt, level, pX + 1, pY, pZ); + ll0yZ = getShadeBrightness(tt, level, pX, pY - 1, pZ); + ll0YZ = getShadeBrightness(tt, level, pX, pY + 1, pZ); - ccx0Z = getLightColor(tt, level, pX - 1, pY, pZ); - ccX0Z = getLightColor(tt, level, pX + 1, pY, pZ); - cc0yZ = getLightColor(tt, level, pX, pY - 1, pZ); - cc0YZ = getLightColor(tt, level, pX, pY + 1, pZ); + ccx0Z = getLightColor(tt, level, pX - 1, pY, pZ); + ccX0Z = getLightColor(tt, level, pX + 1, pY, pZ); + cc0yZ = getLightColor(tt, level, pX, pY - 1, pZ); + cc0YZ = getLightColor(tt, level, pX, pY + 1, pZ); - if (llTransx0Z || llTrans0yZ) { - llxyZ = getShadeBrightness(tt, level, pX - 1, pY - 1, pZ); - ccxyZ = getLightColor(tt, level, pX - 1, pY - 1, pZ); - } else { - llxyZ = llx0Z; - ccxyZ = ccx0Z; - } - if (llTransx0Z || llTrans0YZ) { - llxYZ = getShadeBrightness(tt, level, pX - 1, pY + 1, pZ); - ccxYZ = getLightColor(tt, level, pX - 1, pY + 1, pZ); - } else { - llxYZ = llx0Z; - ccxYZ = ccx0Z; - } - if (llTransX0Z || llTrans0yZ) { - llXyZ = getShadeBrightness(tt, level, pX + 1, pY - 1, pZ); - ccXyZ = getLightColor(tt, level, pX + 1, pY - 1, pZ); - } else { - llXyZ = llX0Z; - ccXyZ = ccX0Z; - } - if (llTransX0Z || llTrans0YZ) { - llXYZ = getShadeBrightness(tt, level, pX + 1, pY + 1, pZ); - ccXYZ = getLightColor(tt, level, pX + 1, pY + 1, pZ); - } else { - llXYZ = llX0Z; - ccXYZ = ccX0Z; - } - if (tileShapeZ1 >= 1) - pZ--; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && - false) // minecraft->options->ambientOcclusion >= - // Options::AO_MAX) // 4J - disabling AO_MAX until - // we work out exactly what its peformance implications - // are/what it fixes + bool llTransX0Z = Tile::transculent[level->getTile(pX + 1, pY, pZ + 1)]; + bool llTransx0Z = Tile::transculent[level->getTile(pX - 1, pY, pZ + 1)]; + bool llTrans0YZ = Tile::transculent[level->getTile(pX, pY + 1, pZ + 1)]; + bool llTrans0yZ = Tile::transculent[level->getTile(pX, pY - 1, pZ + 1)]; + + if (llTransx0Z || llTrans0yZ) { + llxyZ = getShadeBrightness(tt, level, pX - 1, pY - 1, pZ); + ccxyZ = getLightColor(tt, level, pX - 1, pY - 1, pZ); + } else { + llxyZ = llx0Z; + ccxyZ = ccx0Z; + } + if (llTransx0Z || llTrans0YZ) { + llxYZ = getShadeBrightness(tt, level, pX - 1, pY + 1, pZ); + ccxYZ = getLightColor(tt, level, pX - 1, pY + 1, pZ); + } else { + llxYZ = llx0Z; + ccxYZ = ccx0Z; + } + if (llTransX0Z || llTrans0yZ) { + llXyZ = getShadeBrightness(tt, level, pX + 1, pY - 1, pZ); + ccXyZ = getLightColor(tt, level, pX + 1, pY - 1, pZ); + } else { + llXyZ = llX0Z; + ccXyZ = ccX0Z; + } + if (llTransX0Z || llTrans0YZ) { + llXYZ = getShadeBrightness(tt, level, pX + 1, pY + 1, pZ); + ccXYZ = getLightColor(tt, level, pX + 1, pY + 1, pZ); + } else { + llXYZ = llX0Z; + ccXYZ = ccX0Z; + } + if (tileShapeZ1 >= 1) pZ--; + + int cc00Z = centerColor; + if (tileShapeZ1 >= 1 || !level->isSolidRenderTile(pX, pY, pZ + 1)) + cc00Z = tt->getLightColor(level, pX, pY, pZ + 1); + float ll00Z = tt->getShadeBrightness(level, pX, pY, pZ + 1); + + { + if (smoothShapeLighting) // MGH - unifying + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting + // and + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting2 { float _ll1 = (llx0Z + llxYZ + ll00Z + ll0YZ) / 4.0f; float _ll4 = (ll00Z + ll0YZ + llX0Z + llXYZ) / 4.0f; @@ -5099,13 +5627,17 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tc3 = blend(cc0yZ, ccXyZ, ccX0Z, cc00Z); tc2 = blend(ccxyZ, ccx0Z, cc0yZ, cc00Z); } - } else { - ll1 = ll2 = ll3 = ll4 = ll00Z; - tc1 = tc2 = tc3 = tc4 = cc00Z; } - c1r = c2r = c3r = c4r = (tint3 ? pBaseRed : 1.0f) * 0.8f; - c1g = c2g = c3g = c4g = (tint3 ? pBaseGreen : 1.0f) * 0.8f; - c1b = c2b = c3b = c4b = (tint3 ? pBaseBlue : 1.0f) * 0.8f; + + if (tintSides) { + c1r = c2r = c3r = c4r = pBaseRed * 0.8f; + c1g = c2g = c3g = c4g = pBaseGreen * 0.8f; + c1b = c2b = c3b = c4b = pBaseBlue * 0.8f; + } else { + c1r = c2r = c3r = c4r = 0.8f; + c1g = c2g = c3g = c4g = 0.8f; + c1b = c2b = c3b = c4b = 0.8f; + } c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -5118,6 +5650,7 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( c4r *= ll4; c4g *= ll4; c4b *= ll4; + Icon* tex = uniformTex ? uniformTex : getTexture(tt, level, pX, pY, pZ, 3); renderSouth(tt, (double)pX, (double)pY, (double)pZ, tex); @@ -5142,56 +5675,70 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( GrassTile::getSideTextureOverlay()); t->setMipmapEnable(prev); } + + i = true; } - if (faceFlags & 0x10) { - if (blsmooth > 0) { - if (tileShapeX0 <= 0) - pX--; // 4J - condition brought forward from 1.2.3 - llxy0 = getShadeBrightness(tt, level, pX, pY - 1, pZ); - llx0z = getShadeBrightness(tt, level, pX, pY, pZ - 1); - llx0Z = getShadeBrightness(tt, level, pX, pY, pZ + 1); - llxY0 = getShadeBrightness(tt, level, pX, pY + 1, pZ); + if (faceFlags & 0x10) // ((noCulling) || (tt->shouldRenderFace(level, pX - + // 1, pY, pZ, 4))) + { + if (tileShapeX0 <= 0) + pX--; // 4J - condition brought forward from 1.2.3 + llxy0 = getShadeBrightness(tt, level, pX, pY - 1, pZ); + llx0z = getShadeBrightness(tt, level, pX, pY, pZ - 1); + llx0Z = getShadeBrightness(tt, level, pX, pY, pZ + 1); + llxY0 = getShadeBrightness(tt, level, pX, pY + 1, pZ); - ccxy0 = getLightColor(tt, level, pX, pY - 1, pZ); - ccx0z = getLightColor(tt, level, pX, pY, pZ - 1); - ccx0Z = getLightColor(tt, level, pX, pY, pZ + 1); - ccxY0 = getLightColor(tt, level, pX, pY + 1, pZ); + ccxy0 = getLightColor(tt, level, pX, pY - 1, pZ); + ccx0z = getLightColor(tt, level, pX, pY, pZ - 1); + ccx0Z = getLightColor(tt, level, pX, pY, pZ + 1); + ccxY0 = getLightColor(tt, level, pX, pY + 1, pZ); - if (llTransx0z || llTransxy0) { - llxyz = getShadeBrightness(tt, level, pX, pY - 1, pZ - 1); - ccxyz = getLightColor(tt, level, pX, pY - 1, pZ - 1); - } else { - llxyz = llx0z; - ccxyz = ccx0z; - } - if (llTransx0Z || llTransxy0) { - llxyZ = getShadeBrightness(tt, level, pX, pY - 1, pZ + 1); - ccxyZ = getLightColor(tt, level, pX, pY - 1, pZ + 1); - } else { - llxyZ = llx0Z; - ccxyZ = ccx0Z; - } - if (llTransx0z || llTransxY0) { - llxYz = getShadeBrightness(tt, level, pX, pY + 1, pZ - 1); - ccxYz = getLightColor(tt, level, pX, pY + 1, pZ - 1); - } else { - llxYz = llx0z; - ccxYz = ccx0z; - } - if (llTransx0Z || llTransxY0) { - llxYZ = getShadeBrightness(tt, level, pX, pY + 1, pZ + 1); - ccxYZ = getLightColor(tt, level, pX, pY + 1, pZ + 1); - } else { - llxYZ = llx0Z; - ccxYZ = ccx0Z; - } - if (tileShapeX0 <= 0) - pX++; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && - false) // minecraft->options->ambientOcclusion >= - // Options::AO_MAX) // 4J - disabling AO_MAX until we - // work out exactly what its peformance implications - // are/what it fixes + bool llTransxY0 = Tile::transculent[level->getTile(pX - 1, pY + 1, pZ)]; + bool llTransxy0 = Tile::transculent[level->getTile(pX - 1, pY - 1, pZ)]; + bool llTransx0z = Tile::transculent[level->getTile(pX - 1, pY, pZ - 1)]; + bool llTransx0Z = Tile::transculent[level->getTile(pX - 1, pY, pZ + 1)]; + + if (llTransx0z || llTransxy0) { + llxyz = getShadeBrightness(tt, level, pX, pY - 1, pZ - 1); + ccxyz = getLightColor(tt, level, pX, pY - 1, pZ - 1); + } else { + llxyz = llx0z; + ccxyz = ccx0z; + } + if (llTransx0Z || llTransxy0) { + llxyZ = getShadeBrightness(tt, level, pX, pY - 1, pZ + 1); + ccxyZ = getLightColor(tt, level, pX, pY - 1, pZ + 1); + } else { + llxyZ = llx0Z; + ccxyZ = ccx0Z; + } + if (llTransx0z || llTransxY0) { + llxYz = getShadeBrightness(tt, level, pX, pY + 1, pZ - 1); + ccxYz = getLightColor(tt, level, pX, pY + 1, pZ - 1); + } else { + llxYz = llx0z; + ccxYz = ccx0z; + } + if (llTransx0Z || llTransxY0) { + llxYZ = getShadeBrightness(tt, level, pX, pY + 1, pZ + 1); + ccxYZ = getLightColor(tt, level, pX, pY + 1, pZ + 1); + } else { + llxYZ = llx0Z; + ccxYZ = ccx0Z; + } + if (tileShapeX0 <= 0) + pX++; // 4J - condition brought forward from 1.2.3 + + int ccx00 = centerColor; + if (tileShapeX0 <= 0 || !level->isSolidRenderTile(pX - 1, pY, pZ)) + ccx00 = tt->getLightColor(level, pX - 1, pY, pZ); + float llx00 = tt->getShadeBrightness(level, pX - 1, pY, pZ); + + { + if (smoothShapeLighting) // MGH - unifying + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting + // and + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting2 { float _ll4 = (llxy0 + llxyZ + llx00 + llx0Z) / 4.0f; float _ll1 = (llx00 + llx0Z + llxY0 + llxYZ) / 4.0f; @@ -5245,13 +5792,18 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tc2 = blend(ccx0z, ccxYz, ccxY0, ccx00); tc3 = blend(ccxyz, ccxy0, ccx0z, ccx00); } - } else { - ll1 = ll2 = ll3 = ll4 = llx00; - tc1 = tc2 = tc3 = tc4 = ccx00; } - c1r = c2r = c3r = c4r = (tint4 ? pBaseRed : 1.0f) * 0.6f; - c1g = c2g = c3g = c4g = (tint4 ? pBaseGreen : 1.0f) * 0.6f; - c1b = c2b = c3b = c4b = (tint4 ? pBaseBlue : 1.0f) * 0.6f; + + if (tintSides) { + c1r = c2r = c3r = c4r = pBaseRed * 0.6f; + c1g = c2g = c3g = c4g = pBaseGreen * 0.6f; + c1b = c2b = c3b = c4b = pBaseBlue * 0.6f; + } else { + c1r = c2r = c3r = c4r = 0.6f; + c1g = c2g = c3g = c4g = 0.6f; + c1b = c2b = c3b = c4b = 0.6f; + } + c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -5288,56 +5840,69 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( GrassTile::getSideTextureOverlay()); t->setMipmapEnable(prev); } + + i = true; } - if (faceFlags & 0x20) { - if (blsmooth > 0) { - if (tileShapeX1 >= 1) - pX++; // 4J - condition brought forward from 1.2.3 - llXy0 = getShadeBrightness(tt, level, pX, pY - 1, pZ); - llX0z = getShadeBrightness(tt, level, pX, pY, pZ - 1); - llX0Z = getShadeBrightness(tt, level, pX, pY, pZ + 1); - llXY0 = getShadeBrightness(tt, level, pX, pY + 1, pZ); + if (faceFlags & 0x20) // ((noCulling) || (tt->shouldRenderFace(level, pX + + // 1, pY, pZ, 5))) + { + if (tileShapeX1 >= 1) pX++; + llXy0 = getShadeBrightness(tt, level, pX, pY - 1, pZ); + llX0z = getShadeBrightness(tt, level, pX, pY, pZ - 1); + llX0Z = getShadeBrightness(tt, level, pX, pY, pZ + 1); + llXY0 = getShadeBrightness(tt, level, pX, pY + 1, pZ); - ccXy0 = getLightColor(tt, level, pX, pY - 1, pZ); - ccX0z = getLightColor(tt, level, pX, pY, pZ - 1); - ccX0Z = getLightColor(tt, level, pX, pY, pZ + 1); - ccXY0 = getLightColor(tt, level, pX, pY + 1, pZ); + ccXy0 = getLightColor(tt, level, pX, pY - 1, pZ); + ccX0z = getLightColor(tt, level, pX, pY, pZ - 1); + ccX0Z = getLightColor(tt, level, pX, pY, pZ + 1); + ccXY0 = getLightColor(tt, level, pX, pY + 1, pZ); - if (llTransXy0 || llTransX0z) { - llXyz = getShadeBrightness(tt, level, pX, pY - 1, pZ - 1); - ccXyz = getLightColor(tt, level, pX, pY - 1, pZ - 1); - } else { - llXyz = llX0z; - ccXyz = ccX0z; - } - if (llTransXy0 || llTransX0Z) { - llXyZ = getShadeBrightness(tt, level, pX, pY - 1, pZ + 1); - ccXyZ = getLightColor(tt, level, pX, pY - 1, pZ + 1); - } else { - llXyZ = llX0Z; - ccXyZ = ccX0Z; - } - if (llTransXY0 || llTransX0z) { - llXYz = getShadeBrightness(tt, level, pX, pY + 1, pZ - 1); - ccXYz = getLightColor(tt, level, pX, pY + 1, pZ - 1); - } else { - llXYz = llX0z; - ccXYz = ccX0z; - } - if (llTransXY0 || llTransX0Z) { - llXYZ = getShadeBrightness(tt, level, pX, pY + 1, pZ + 1); - ccXYZ = getLightColor(tt, level, pX, pY + 1, pZ + 1); - } else { - llXYZ = llX0Z; - ccXYZ = ccX0Z; - } - if (tileShapeX1 >= 1) - pX--; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && - false) // minecraft->options->ambientOcclusion >= - // Options::AO_MAX) // 4J - disabling AO_MAX until we - // work out exactly what its peformance implications - // are/what it fixes + bool llTransXY0 = Tile::transculent[level->getTile(pX + 1, pY + 1, pZ)]; + bool llTransXy0 = Tile::transculent[level->getTile(pX + 1, pY - 1, pZ)]; + bool llTransX0Z = Tile::transculent[level->getTile(pX + 1, pY, pZ + 1)]; + bool llTransX0z = Tile::transculent[level->getTile(pX + 1, pY, pZ - 1)]; + + if (llTransXy0 || llTransX0z) { + llXyz = getShadeBrightness(tt, level, pX, pY - 1, pZ - 1); + ccXyz = getLightColor(tt, level, pX, pY - 1, pZ - 1); + } else { + llXyz = llX0z; + ccXyz = ccX0z; + } + if (llTransXy0 || llTransX0Z) { + llXyZ = getShadeBrightness(tt, level, pX, pY - 1, pZ + 1); + ccXyZ = getLightColor(tt, level, pX, pY - 1, pZ + 1); + } else { + llXyZ = llX0Z; + ccXyZ = ccX0Z; + } + if (llTransXY0 || llTransX0z) { + llXYz = getShadeBrightness(tt, level, pX, pY + 1, pZ - 1); + ccXYz = getLightColor(tt, level, pX, pY + 1, pZ - 1); + } else { + llXYz = llX0z; + ccXYz = ccX0z; + } + if (llTransXY0 || llTransX0Z) { + llXYZ = getShadeBrightness(tt, level, pX, pY + 1, pZ + 1); + ccXYZ = getLightColor(tt, level, pX, pY + 1, pZ + 1); + } else { + llXYZ = llX0Z; + ccXYZ = ccX0Z; + } + if (tileShapeX1 >= 1) + pX--; // 4J - condition brought forward from 1.2.3 + + int ccX00 = centerColor; + if (tileShapeX1 >= 1 || !level->isSolidRenderTile(pX + 1, pY, pZ)) + ccX00 = tt->getLightColor(level, pX + 1, pY, pZ); + float llX00 = tt->getShadeBrightness(level, pX + 1, pY, pZ); + + { + if (smoothShapeLighting) // MGH - unifying + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting + // and + // tesselateBlockInWorldWithAmbienceOcclusionTexLighting2 { float _ll1 = (llXy0 + llXyZ + llX00 + llX0Z) / 4.0f; float _ll2 = (llXyz + llXy0 + llX0z + llX00) / 4.0f; @@ -5395,13 +5960,16 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tc3 = blend(ccX0z, ccXYz, ccXY0, ccX00); tc2 = blend(ccXyz, ccXy0, ccX0z, ccX00); } - } else { - ll1 = ll2 = ll3 = ll4 = llX00; - tc1 = tc2 = tc3 = tc4 = ccX00; } - c1r = c2r = c3r = c4r = (tint5 ? pBaseRed : 1.0f) * 0.6f; - c1g = c2g = c3g = c4g = (tint5 ? pBaseGreen : 1.0f) * 0.6f; - c1b = c2b = c3b = c4b = (tint5 ? pBaseBlue : 1.0f) * 0.6f; + if (tintSides) { + c1r = c2r = c3r = c4r = pBaseRed * 0.6f; + c1g = c2g = c3g = c4g = pBaseGreen * 0.6f; + c1b = c2b = c3b = c4b = pBaseBlue * 0.6f; + } else { + c1r = c2r = c3r = c4r = 0.6f; + c1g = c2g = c3g = c4g = 0.6f; + c1b = c2b = c3b = c4b = 0.6f; + } c1r *= ll1; c1g *= ll1; c1b *= ll1; @@ -5415,8 +5983,7 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( c4g *= ll4; c4b *= ll4; - Icon* tex = - uniformTex ? uniformTex : getTexture(tt, level, pX, pY, pZ, 5); + Icon* tex = getTexture(tt, level, pX, pY, pZ, 5); renderEast(tt, (double)pX, (double)pY, (double)pZ, tex); if (fancy && (tex->getFlags() == Icon::IS_GRASS_SIDE) && !hasFixedTexture()) { @@ -5432,14 +5999,10 @@ bool TileRenderer::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( c2b *= pBaseBlue; c3b *= pBaseBlue; c4b *= pBaseBlue; - - bool prev = t->setMipmapEnable( - false); // 4J added - this is rendering the little bit of grass - // at the top of the side of dirt, don't mipmap it renderEast(tt, (double)pX, (double)pY, (double)pZ, GrassTile::getSideTextureOverlay()); - t->setMipmapEnable(prev); } + i = true; } applyAmbienceOcclusion = false; @@ -5629,6 +6192,32 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tt, int x, int y, int z, float r, return changed; } +bool TileRenderer::tesselateBeaconInWorld(Tile* tt, int x, int y, int z) { + float obsHeight = 3.0f / 16.0f; + + setFixedTexture(getTexture(Tile::glass)); + setShape(0, 0, 0, 1, 1, 1); + tesselateBlockInWorld(tt, x, y, z); + + // Force drawing of all faces else the inner-block of the beacon gets + // culled. + noCulling = true; + setFixedTexture(getTexture(Tile::obsidian)); + setShape(2.0f / 16.0f, 0.1f / 16.0f, 2.0f / 16.0f, 14.0f / 16.0f, obsHeight, + 14.0f / 16.0f); + tesselateBlockInWorld(tt, x, y, z); + + setFixedTexture(getTexture(Tile::beacon)); + setShape(3.0f / 16.0f, obsHeight, 3.0f / 16.0f, 13.0f / 16.0f, + 14.0f / 16.0f, 13.0f / 16.0f); + tesselateBlockInWorld(tt, x, y, z); + noCulling = false; + + clearFixedTexture(); + + return true; +} + 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; @@ -5673,110 +6262,46 @@ bool TileRenderer::tesselateCactusInWorld(Tile* tt, int x, int y, int z, float b2 = c2 * b; float b3 = c3 * b; - float s = 1 / 16.0f; + float faceOffset = 1 / 16.0f; - float centerBrightness = 0.0f; - int centerColor = 0; - if (SharedConstants::TEXTURE_LIGHTING) { - centerColor = getLightColor(tt, level, x, y, z); - } else { - centerBrightness = tt->getBrightness(level, x, y, z); - } + int centerColor = tt->getLightColor(level, x, y, z); if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeY0 > 0 ? centerColor - : getLightColor(tt, level, x, y - 1, z)); - t->color(r10, g10, b10); - } else { - float br = tt->getBrightness(level, x, y - 1, z); - t->color(r10 * br, g10 * br, b10 * br); - } + t->tex2(tileShapeY0 > 0 ? centerColor + : tt->getLightColor(level, x, y - 1, z)); + t->color(r10, g10, b10); renderFaceDown(tt, x, y, z, getTexture(tt, level, x, y, z, 0)); - changed = true; } if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeY1 < 1 ? centerColor - : getLightColor(tt, level, x, y + 1, z)); - t->color(r11, g11, b11); - } else { - float br = tt->getBrightness(level, x, y + 1, z); - if (tileShapeY1 != 1 && !tt->material->isLiquid()) - br = centerBrightness; - t->color(r11 * br, g11 * br, b11 * br); - } + t->tex2(tileShapeY1 < 1 ? centerColor + : tt->getLightColor(level, x, y + 1, z)); + t->color(r11, g11, b11); renderFaceUp(tt, x, y, z, getTexture(tt, level, x, y, z, 1)); - changed = true; } - if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeZ0 > 0 ? centerColor - : getLightColor(tt, level, x, y, z - 1)); - t->color(r2, g2, b2); - } else { - float br = tt->getBrightness(level, x, y, z - 1); - if (tileShapeZ0 > 0) br = centerBrightness; - t->color(r2 * br, g2 * br, b2 * br); - } - t->addOffset(0, 0, s); - renderNorth(tt, x, y, z, getTexture(tt, level, x, y, z, 2)); - t->addOffset(0, 0, -s); - changed = true; - } + // North/South + t->tex2(centerColor); + t->color(r2, g2, b2); + t->addOffset(0, 0, faceOffset); + renderNorth(tt, x, y, z, getTexture(tt, level, x, y, z, 2)); + t->addOffset(0, 0, -faceOffset); - if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeZ1 < 1 ? centerColor - : getLightColor(tt, level, x, y, z + 1)); - t->color(r2, g2, b2); - } else { - float br = tt->getBrightness(level, x, y, z + 1); - if (tileShapeZ1 < 1) br = centerBrightness; - t->color(r2 * br, g2 * br, b2 * br); - } + t->addOffset(0, 0, -faceOffset); + renderSouth(tt, x, y, z, getTexture(tt, level, x, y, z, 3)); + t->addOffset(0, 0, faceOffset); - t->addOffset(0, 0, -s); - renderSouth(tt, x, y, z, getTexture(tt, level, x, y, z, 3)); - t->addOffset(0, 0, s); - changed = true; - } + // West/East + t->color(r3, g3, b3); + t->addOffset(faceOffset, 0, 0); + renderWest(tt, x, y, z, getTexture(tt, level, x, y, z, 4)); + t->addOffset(-faceOffset, 0, 0); - if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeX0 > 0 ? centerColor - : getLightColor(tt, level, x - 1, y, z)); - t->color(r3, g3, b3); - } else { - float br = tt->getBrightness(level, x - 1, y, z); - if (tileShapeX0 > 0) br = centerBrightness; - t->color(r3 * br, g3 * br, b3 * br); - } - t->addOffset(s, 0, 0); - renderWest(tt, x, y, z, getTexture(tt, level, x, y, z, 4)); - t->addOffset(-s, 0, 0); - changed = true; - } + t->addOffset(-faceOffset, 0, 0); + renderEast(tt, x, y, z, getTexture(tt, level, x, y, z, 5)); + t->addOffset(faceOffset, 0, 0); - if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) { - if (SharedConstants::TEXTURE_LIGHTING) { - t->tex2(tileShapeX1 < 1 ? centerColor - : getLightColor(tt, level, x + 1, y, z)); - t->color(r3, g3, b3); - } else { - float br = tt->getBrightness(level, x + 1, y, z); - if (tileShapeX1 < 1) br = centerBrightness; - t->color(r3 * br, g3 * br, b3 * br); - } - t->addOffset(-s, 0, 0); - renderEast(tt, x, y, z, getTexture(tt, level, x, y, z, 5)); - t->addOffset(s, 0, 0); - changed = true; - } - - return changed; + return true; } bool TileRenderer::tesselateFenceInWorld(FenceTile* tt, int x, int y, int z) { @@ -6158,6 +6683,222 @@ bool TileRenderer::tesselateFenceGateInWorld(FenceGateTile* tt, int x, int y, return changed; } +bool TileRenderer::tesselateHopperInWorld(Tile* tt, int x, int y, int z) { + Tesselator* t = Tesselator::getInstance(); + + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, 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; + + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); + + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); + + return tesselateHopperInWorld(tt, x, y, z, level->getData(x, y, z), false); +} + +bool TileRenderer::tesselateHopperInWorld(Tile* tt, int x, int y, int z, + int data, bool render) { + Tesselator* t = Tesselator::getInstance(); + int facing = HopperTile::getAttachedFace(data); + + // bounding box first + double bottom = 10.0 / 16.0; + setShape(0, bottom, 0, 1, 1, 1); + + if (render) { + t->begin(); + t->normal(0, -1, 0); + renderFaceDown(tt, 0, 0, 0, getTexture(tt, 0, data)); + t->end(); + + t->begin(); + t->normal(0, 1, 0); + renderFaceUp(tt, 0, 0, 0, getTexture(tt, 1, data)); + t->end(); + + t->begin(); + t->normal(0, 0, -1); + renderNorth(tt, 0, 0, 0, getTexture(tt, 2, data)); + t->end(); + + t->begin(); + t->normal(0, 0, 1); + renderSouth(tt, 0, 0, 0, getTexture(tt, 3, data)); + t->end(); + + t->begin(); + t->normal(-1, 0, 0); + renderWest(tt, 0, 0, 0, getTexture(tt, 4, data)); + t->end(); + + t->begin(); + t->normal(1, 0, 0); + renderEast(tt, 0, 0, 0, getTexture(tt, 5, data)); + t->end(); + } else { + tesselateBlockInWorld(tt, x, y, z); + } + + if (!render) { + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, 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; + + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); + + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); + } + + // render inside + Icon* hopperTex = HopperTile::getTexture(HopperTile::TEXTURE_OUTSIDE); + Icon* bottomTex = HopperTile::getTexture(HopperTile::TEXTURE_INSIDE); + float cWidth = 2.0f / 16.0f; + + if (render) { + t->begin(); + t->normal(1, 0, 0); + renderEast(tt, -1.0f + cWidth, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(-1, 0, 0); + renderWest(tt, 1.0f - cWidth, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 0, 1); + renderSouth(tt, 0, 0, -1.0f + cWidth, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 0, -1); + renderNorth(tt, 0, 0, 1.0f - cWidth, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 1, 0); + renderFaceUp(tt, 0, -1.0f + bottom, 0, bottomTex); + t->end(); + } else { + renderEast(tt, x - 1.0f + cWidth, y, z, hopperTex); + renderWest(tt, x + 1.0f - cWidth, y, z, hopperTex); + renderSouth(tt, x, y, z - 1.0f + cWidth, hopperTex); + renderNorth(tt, x, y, z + 1.0f - cWidth, hopperTex); + renderFaceUp(tt, x, y - 1.0f + bottom, z, bottomTex); + } + + // render bottom box + setFixedTexture(hopperTex); + double inset = 4.0 / 16.0; + double lboxy0 = 4.0 / 16.0; + double lboxy1 = bottom; + setShape(inset, lboxy0, inset, 1.0 - inset, lboxy1 - .002, 1.0 - inset); + + if (render) { + t->begin(); + t->normal(1, 0, 0); + renderEast(tt, 0, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(-1, 0, 0); + renderWest(tt, 0, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 0, 1); + renderSouth(tt, 0, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 0, -1); + renderNorth(tt, 0, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(0, 1, 0); + renderFaceUp(tt, 0, 0, 0, hopperTex); + t->end(); + + t->begin(); + t->normal(0, -1, 0); + renderFaceDown(tt, 0, 0, 0, hopperTex); + t->end(); + } else { + tesselateBlockInWorld(tt, x, y, z); + } + + if (!render) { + // render pipe + double pipe = 6.0 / 16.0; + double pipeW = 4.0 / 16.0; + setFixedTexture(hopperTex); + + // down + if (facing == Facing::DOWN) { + setShape(pipe, 0, pipe, 1.0 - pipe, 4.0 / 16.0, 1.0 - pipe); + tesselateBlockInWorld(tt, x, y, z); + } + // north + if (facing == Facing::NORTH) { + setShape(pipe, lboxy0, 0, 1.0 - pipe, lboxy0 + pipeW, inset); + tesselateBlockInWorld(tt, x, y, z); + } + // south + if (facing == Facing::SOUTH) { + setShape(pipe, lboxy0, 1.0 - inset, 1.0 - pipe, lboxy0 + pipeW, + 1.0); + tesselateBlockInWorld(tt, x, y, z); + } + // west + if (facing == Facing::WEST) { + setShape(0, lboxy0, pipe, inset, lboxy0 + pipeW, 1.0 - pipe); + tesselateBlockInWorld(tt, x, y, z); + } + // east + if (facing == Facing::EAST) { + setShape(1.0 - inset, lboxy0, pipe, 1.0, lboxy0 + pipeW, + 1.0 - pipe); + tesselateBlockInWorld(tt, x, y, z); + } + } + + clearFixedTexture(); + + return true; +} + bool TileRenderer::tesselateStairsInWorld(StairTile* tt, int x, int y, int z) { tt->setBaseShape(level, x, y, z); setShape(tt); @@ -7069,9 +7810,8 @@ void TileRenderer::renderTile(Tile* tile, int data, float brightness, bool isGrass = tile->id == Tile::grass_Id; - if (tile == Tile::dispenser || - tile == Tile::furnace) // || tile == Tile.dropper - { + if (tile == Tile::dispenser || tile == Tile::furnace || + tile == Tile::dropper) { data = 3; } @@ -7509,7 +8249,7 @@ void TileRenderer::renderTile(Tile* tile, int data, float brightness, setShape(0, 0, 0, 1, 1, 1); } else if (shape == Tile::SHAPE_ANVIL) { glTranslatef(-0.5f, -0.5f, -0.5f); - tesselateAnvilInWorld((AnvilTile*)tile, 0, 0, 0, data, true); + tesselateAnvilInWorld((AnvilTile*)tile, 0, 0, 0, data << 2, true); glTranslatef(0.5f, 0.5f, 0.5f); } else if (shape == Tile::SHAPE_PORTAL_FRAME) { // 4J added @@ -7549,7 +8289,63 @@ void TileRenderer::renderTile(Tile* tile, int data, float brightness, glTranslatef(0.5f, 0.5f, 0.5f); tile->updateDefaultShape(); + + } else if (shape == Tile::SHAPE_BEACON) { + for (int i = 0; i < 3; i++) { + if (i == 0) { + setShape(2.0f / 16.0f, 0, 2.0f / 16.0f, 14.0f / 16.0f, + 3.0f / 16.0f, 14.0f / 16.0f); + setFixedTexture(getTexture(Tile::obsidian)); + } else if (i == 1) { + setShape(3.0f / 16.0f, 3.0f / 16.0f, 3.0f / 16.0f, + 13.0f / 16.0f, 14.0f / 16.0f, 13.0f / 16.0f); + setFixedTexture(getTexture(Tile::beacon)); + } else if (i == 2) { + setShape(0, 0, 0, 1, 1, 1); + setFixedTexture(getTexture(Tile::glass)); + } + + glTranslatef(-0.5f, -0.5f, -0.5f); + t->begin(); + t->normal(0, -1, 0); + renderFaceDown(tile, 0, 0, 0, getTexture(tile, 0, data)); + t->end(); + + t->begin(); + t->normal(0, 1, 0); + renderFaceUp(tile, 0, 0, 0, getTexture(tile, 1, data)); + t->end(); + + t->begin(); + t->normal(0, 0, -1); + renderNorth(tile, 0, 0, 0, getTexture(tile, 2, data)); + t->end(); + + t->begin(); + t->normal(0, 0, 1); + renderSouth(tile, 0, 0, 0, getTexture(tile, 3, data)); + t->end(); + + t->begin(); + t->normal(-1, 0, 0); + renderWest(tile, 0, 0, 0, getTexture(tile, 4, data)); + t->end(); + + t->begin(); + t->normal(1, 0, 0); + renderEast(tile, 0, 0, 0, getTexture(tile, 5, data)); + t->end(); + + glTranslatef(0.5f, 0.5f, 0.5f); + } + setShape(0, 0, 0, 1, 1, 1); + clearFixedTexture(); + } else if (shape == Tile::SHAPE_HOPPER) { + glTranslatef(-0.5f, -0.5f, -0.5f); + tesselateHopperInWorld(tile, 0, 0, 0, 0, true); + glTranslatef(0.5f, 0.5f, 0.5f); } + t->setMipmapEnable(true); // 4J added } @@ -7566,6 +8362,7 @@ bool TileRenderer::canRender(int renderShape) { if (renderShape == Tile::SHAPE_PISTON_BASE) return true; if (renderShape == Tile::SHAPE_PORTAL_FRAME) return true; if (renderShape == Tile::SHAPE_WALL) return true; + if (renderShape == Tile::SHAPE_BEACON) return true; if (renderShape == Tile::SHAPE_ANVIL) return true; return false; } diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.h index 5f34f0989..c5b96e4ef 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.h @@ -13,6 +13,8 @@ class BrewingStandTile; class CauldronTile; class EggTile; class TheEndPortalFrameTile; +class RepeaterTile; +class ComparatorTile; class DiodeTile; class FireTile; class StemTile; @@ -21,6 +23,8 @@ class CocoaTile; class AnvilTile; class FlowerPotTile; class WallTile; +class BeaconTile; +class HopperTile; class Icon; class Minecraft; @@ -111,12 +115,15 @@ private: bool render); float tesselateAnvilPiece(AnvilTile* tt, int x, int y, int z, int part, float bottom, float width, float height, - float length, bool rotate, bool render, int data); + float length, bool std::rotate, bool render, + int data); public: bool tesselateTorchInWorld(Tile* tt, int x, int y, int z); private: + bool tesselateRepeaterInWorld(RepeaterTile* tt, int x, int y, int z); + bool tesselateComparatorInWorld(ComparatorTile* tt, int x, int y, int z); bool tesselateDiodeInWorld(DiodeTile* tt, int x, int y, int z); void tesselateDiodeInWorld(DiodeTile* tt, int x, int y, int z, int dir); static const int FLIP_NONE = 0, FLIP_CW = 1, FLIP_CCW = 2, FLIP_180 = 3; @@ -162,6 +169,7 @@ public: bool tesselateRailInWorld(RailTile* tt, int x, int y, int z); bool tesselateLadderInWorld(Tile* tt, int x, int y, int z); bool tesselateVineInWorld(Tile* tt, int x, int y, int z); + bool tesselateThinPaneInWorld(Tile* tt, int x, int y, int z); bool tesselateThinFenceInWorld(ThinFenceTile* tt, int x, int y, int z); bool tesselateCrossInWorld(Tile* tt, int x, int y, int z); bool tesselateStemInWorld(Tile* _tt, int x, int y, int z); @@ -194,30 +202,26 @@ public: private: bool applyAmbienceOcclusion; - float ll000, llx00, ll0y0, ll00z, llX00, ll0Y0, ll00Z; float llxyz, llxy0, llxyZ, ll0yz, ll0yZ, llXyz, llXy0; float llXyZ, llxYz, llxY0, llxYZ, ll0Yz, llXYz, llXY0; float ll0YZ, llXYZ, llx0z, llX0z, llx0Z, llX0Z; + // 4J - brought forward changes from 1.8.2 - int ccx00, cc00z, cc0Y0, cc00Z; int ccxyz, ccxy0, ccxyZ, cc0yz, cc0yZ, ccXyz, ccXy0; int ccXyZ, ccxYz, ccxY0, ccxYZ, cc0Yz, ccXYz, ccXY0; int cc0YZ, ccXYZ, ccx0z, ccX0z, ccx0Z, ccX0Z; - int blsmooth; + int tc1, tc2, tc3, tc4; // 4J - brought forward changes from 1.8.2 float c1r, c2r, c3r, c4r; float c1g, c2g, c3g, c4g; float c1b, c2b, c3b, c4b; - bool llTrans0Yz, llTransXY0, llTransxY0, llTrans0YZ; - bool llTransx0z, llTransX0Z, llTransx0Z, llTransX0z; - bool llTrans0yz, llTransXy0, llTransxy0, llTrans0yZ; public: // 4J - brought forward changes from 1.8.2 // AP - added faceFlags so we can cull earlier bool tesselateBlockInWorldWithAmbienceOcclusionTexLighting( Tile* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, - float pBaseBlue, int faceFlags); + float pBaseBlue, int faceFlags, bool smoothShapeLighting); private: int blend(int a, int b, int c, int def); @@ -227,6 +231,7 @@ private: public: bool tesselateBlockInWorld(Tile* tt, int x, int y, int z, float r, float g, float b); + bool tesselateBeaconInWorld(Tile* tt, int x, int y, int z); bool tesselateCactusInWorld(Tile* tt, int x, int y, int z); bool tesselateCactusInWorld(Tile* tt, int x, int y, int z, float r, float g, float b); @@ -234,6 +239,9 @@ public: bool tesselateWallInWorld(WallTile* tt, int x, int y, int z); bool tesselateEggInWorld(EggTile* tt, int x, int y, int z); bool tesselateFenceGateInWorld(FenceGateTile* tt, int x, int y, int z); + bool tesselateHopperInWorld(Tile* tt, int x, int y, int z); + bool tesselateHopperInWorld(Tile* tt, int x, int y, int z, int data, + bool render); bool tesselateStairsInWorld(StairTile* tt, int x, int y, int z); bool tesselateDoorInWorld(Tile* tt, int x, int y, int z); void renderFaceUp(Tile* tt, double x, double y, double z, Icon* tex); diff --git a/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.cpp new file mode 100644 index 000000000..ef7900b58 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.cpp @@ -0,0 +1,43 @@ +#include "../../Platform/stdafx.h" +#include "TntMinecartRenderer.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" + +void TntMinecartRenderer::renderMinecartContents( + std::shared_ptr _cart, float a, Tile* tile, int tileData) { + std::shared_ptr cart = + std::dynamic_pointer_cast(_cart); + + int fuse = cart->getFuse(); + + if (fuse > -1) { + if (fuse - a + 1 < 10) { + float g = 1 - ((fuse - a + 1) / 10.0f); + if (g < 0) g = 0; + if (g > 1) g = 1; + g *= g; + g *= g; + float s = 1.0f + g * 0.3f; + glScalef(s, s, s); + } + } + + MinecartRenderer::renderMinecartContents(cart, a, tile, tileData); + + if (fuse > -1 && fuse / 5 % 2 == 0) { + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); + glColor4f(1, 1, 1, (1 - ((fuse - a + 1) / 100.0f)) * 0.8f); + + glPushMatrix(); + renderer->renderTile(Tile::tnt, 0, 1); + glPopMatrix(); + + glColor4f(1, 1, 1, 1); + glDisable(GL_BLEND); + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + } +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.h new file mode 100644 index 000000000..d1286ac14 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/TntMinecartRenderer.h @@ -0,0 +1,10 @@ +#pragma once +#include "MinecartRenderer.h" + +class Minecart; + +class TntMinecartRenderer : public MinecartRenderer { +protected: + void renderMinecartContents(std::shared_ptr cart, float a, + Tile* tile, int tileData); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.cpp index 0ceabb23a..86754c5aa 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.cpp @@ -1,11 +1,12 @@ #include "../../Platform/stdafx.h" #include "TntRenderer.h" +#include "../../Textures/TextureAtlas.h" #include "TileRenderer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" TntRenderer::TntRenderer() { - tileRenderer = new TileRenderer(); + renderer = new TileRenderer(); this->shadowRadius = 0.5f; } @@ -28,26 +29,30 @@ void TntRenderer::render(std::shared_ptr _tnt, double x, double y, } float br = (1 - ((tnt->life - a + 1) / 100.0f)) * 0.8f; - bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + bindTexture(tnt); // 4J - change brought forward from 1.8.2 float brightness = SharedConstants::TEXTURE_LIGHTING ? 1.0f : tnt->getBrightness(a); - tileRenderer->renderTile(Tile::tnt, 0, brightness); + renderer->renderTile(Tile::tnt, 0, brightness); if (tnt->life / 5 % 2 == 0) { glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); glColor4f(1, 1, 1, br); - tileRenderer->setColor = false; // 4J added so that renderTile doesn't - // set its own colour here - tileRenderer->renderTile(Tile::tnt, 0, 1); - tileRenderer->setColor = true; // 4J added so that renderTile doesn't - // set its own colour here + renderer->setColor = false; // 4J added so that renderTile doesn't set + // its own colour here + renderer->renderTile(Tile::tnt, 0, 1); + renderer->setColor = true; // 4J added so that renderTile doesn't set + // its own colour here glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); } glPopMatrix(); +} + +ResourceLocation* TntRenderer::getTextureLocation(std::shared_ptr mob) { + return &TextureAtlas::LOCATION_BLOCKS; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.h index 64a679364..c966df159 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/TntRenderer.h @@ -3,10 +3,11 @@ class TntRenderer : public EntityRenderer { private: - TileRenderer* tileRenderer; + TileRenderer* renderer; public: TntRenderer(); virtual void render(std::shared_ptr _tnt, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.cpp index 046b41d7c..8d1650c98 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.cpp @@ -3,28 +3,27 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" #include "../Models/VillagerGolemModel.h" #include "../Models/ModelPart.h" +#include "../../Textures/TextureAtlas.h" #include "VillagerGolemRenderer.h" +ResourceLocation VillagerGolemRenderer::GOLEM_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_GOLEM); + VillagerGolemRenderer::VillagerGolemRenderer() : MobRenderer(new VillagerGolemModel(), 0.5f) { golemModel = (VillagerGolemModel*)model; } -int VillagerGolemRenderer::prepareArmor(VillagerGolemModel* villagerGolem, - int layer, float a) { - return -1; -} - void VillagerGolemRenderer::render(std::shared_ptr mob, double x, double y, double z, float rot, float a) { MobRenderer::render(mob, x, y, z, rot, a); } -void VillagerGolemRenderer::setupRotations(std::shared_ptr _mob, float bob, - float bodyRot, float a) { +void VillagerGolemRenderer::setupRotations(std::shared_ptr _mob, + float bob, float bodyRot, float a) { // 4J - original version used generics and thus had an input parameter of - // type Blaze rather than std::shared_ptr we have here - do some - // casting around instead + // type Blaze rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::setupRotations(mob, bob, bodyRot, a); @@ -37,11 +36,16 @@ void VillagerGolemRenderer::setupRotations(std::shared_ptr _mob, float bob, glRotatef(6.5f * triangleWave, 0, 0, 1); } -void VillagerGolemRenderer::additionalRendering(std::shared_ptr _mob, - float a) { +ResourceLocation* VillagerGolemRenderer::getTextureLocation( + std::shared_ptr mob) { + return &GOLEM_LOCATION; +} + +void VillagerGolemRenderer::additionalRendering( + std::shared_ptr _mob, float a) { // 4J - original version used generics and thus had an input parameter of - // type Blaze rather than std::shared_ptr we have here - do some - // casting around instead + // type Blaze rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); MobRenderer::additionalRendering(mob, a); @@ -66,7 +70,7 @@ void VillagerGolemRenderer::additionalRendering(std::shared_ptr _mob, } glColor4f(1, 1, 1, 1); - bindTexture(TN_TERRAIN); //"/terrain.png"); + bindTexture(&TextureAtlas::LOCATION_BLOCKS); // TODO: By Icon tileRenderer->renderTile(Tile::rose, 0, 1); glPopMatrix(); glDisable(GL_RESCALE_NORMAL); diff --git a/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.h index 52c200940..50891b542 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/VillagerGolemRenderer.h @@ -7,19 +7,17 @@ class VillagerGolemModel; class VillagerGolemRenderer : public MobRenderer { private: VillagerGolemModel* golemModel; + static ResourceLocation GOLEM_LOCATION; public: VillagerGolemRenderer(); + virtual void render(std::shared_ptr mob, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); protected: - int prepareArmor(VillagerGolemModel* villagerGolem, int layer, float a); - -public: - void render(std::shared_ptr mob, double x, double y, double z, - float rot, float a); - -protected: - void setupRotations(std::shared_ptr _mob, float bob, float bodyRot, - float a); - void additionalRendering(std::shared_ptr mob, float a); + virtual void setupRotations(std::shared_ptr _mob, float bob, + float bodyRot, float a); + virtual void additionalRendering(std::shared_ptr mob, + float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.cpp index ebba76fed..e91151b5f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.cpp @@ -3,12 +3,25 @@ #include "../Models/VillagerModel.h" #include "VillagerRenderer.h" +ResourceLocation VillagerRenderer::VILLAGER_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_VILLAGER); +ResourceLocation VillagerRenderer::VILLAGER_FARMER_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_FARMER); +ResourceLocation VillagerRenderer::VILLAGER_LIBRARIAN_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_LIBRARIAN); +ResourceLocation VillagerRenderer::VILLAGER_PRIEST_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_PRIEST); +ResourceLocation VillagerRenderer::VILLAGER_SMITH_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_SMITH); +ResourceLocation VillagerRenderer::VILLAGER_BUTCHER_LOCATION = + ResourceLocation(TN_MOB_VILLAGER_BUTCHER); + VillagerRenderer::VillagerRenderer() : MobRenderer(new VillagerModel(0), 0.5f) { villagerModel = (VillagerModel*)model; } -int VillagerRenderer::prepareArmor(std::shared_ptr villager, int layer, - float a) { +int VillagerRenderer::prepareArmor(std::shared_ptr villager, + int layer, float a) { return -1; } @@ -17,17 +30,35 @@ void VillagerRenderer::render(std::shared_ptr mob, double x, double y, MobRenderer::render(mob, x, y, z, rot, a); } -void VillagerRenderer::renderName(std::shared_ptr mob, double x, double y, - double z) {} +ResourceLocation* VillagerRenderer::getTextureLocation( + std::shared_ptr _mob) { + std::shared_ptr mob = std::dynamic_pointer_cast(_mob); -void VillagerRenderer::additionalRendering(std::shared_ptr mob, float a) { + switch (mob->getProfession()) { + case Villager::PROFESSION_FARMER: + return &VILLAGER_FARMER_LOCATION; + case Villager::PROFESSION_LIBRARIAN: + return &VILLAGER_LIBRARIAN_LOCATION; + case Villager::PROFESSION_PRIEST: + return &VILLAGER_PRIEST_LOCATION; + case Villager::PROFESSION_SMITH: + return &VILLAGER_SMITH_LOCATION; + case Villager::PROFESSION_BUTCHER: + return &VILLAGER_BUTCHER_LOCATION; + default: + return &VILLAGER_LOCATION; + } +} + +void VillagerRenderer::additionalRendering(std::shared_ptr mob, + float a) { MobRenderer::additionalRendering(mob, a); } -void VillagerRenderer::scale(std::shared_ptr _mob, float a) { +void VillagerRenderer::scale(std::shared_ptr _mob, float a) { // 4J - original version used generics and thus had an input parameter of - // type Blaze rather than std::shared_ptr we have here - do some - // casting around instead + // type Blaze rather than shared_ptr we have here - do some casting + // around instead std::shared_ptr mob = std::dynamic_pointer_cast(_mob); float s = 15 / 16.0f; if (mob->getAge() < 0) { diff --git a/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.h index 90d2591b8..b40e6cf21 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/VillagerRenderer.h @@ -1,26 +1,30 @@ #pragma once - #include "MobRenderer.h" class VillagerModel; class VillagerRenderer : public MobRenderer { +private: + static ResourceLocation VILLAGER_LOCATION; + static ResourceLocation VILLAGER_FARMER_LOCATION; + static ResourceLocation VILLAGER_LIBRARIAN_LOCATION; + static ResourceLocation VILLAGER_PRIEST_LOCATION; + static ResourceLocation VILLAGER_SMITH_LOCATION; + static ResourceLocation VILLAGER_BUTCHER_LOCATION; + protected: VillagerModel* villagerModel; public: VillagerRenderer(); - -protected: - virtual int prepareArmor(std::shared_ptr villager, int layer, float a); - -public: virtual void render(std::shared_ptr mob, double x, double y, double z, float rot, float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr _mob); protected: - virtual void renderName(std::shared_ptr mob, double x, double y, - double z); - virtual void additionalRendering(std::shared_ptr mob, float a); - virtual void scale(std::shared_ptr player, float a); + virtual int prepareArmor(std::shared_ptr villager, int layer, + float a); + virtual void additionalRendering(std::shared_ptr mob, + float a); + virtual void scale(std::shared_ptr player, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.cpp new file mode 100644 index 000000000..ca5aafab4 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.cpp @@ -0,0 +1,105 @@ +#include "../../Platform/stdafx.h" +#include "EntityRenderDispatcher.h" +#include "WitchRenderer.h" +#include "../Models/WitchModel.h" +#include "../Models/ModelPart.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" + +ResourceLocation WitchRenderer::WITCH_LOCATION = ResourceLocation(TN_MOB_WITCH); + +WitchRenderer::WitchRenderer() : MobRenderer(new WitchModel(0), 0.5f) { + witchModel = dynamic_cast(model); +} + +void WitchRenderer::render(std::shared_ptr entity, double x, double y, + double z, float rot, float a) { + std::shared_ptr mob = std::dynamic_pointer_cast(entity); + + std::shared_ptr item = mob->getCarriedItem(); + + witchModel->holdingItem = item != NULL; + MobRenderer::render(mob, x, y, z, rot, a); +} + +ResourceLocation* WitchRenderer::getTextureLocation( + std::shared_ptr entity) { + return &WITCH_LOCATION; +} + +void WitchRenderer::additionalRendering(std::shared_ptr entity, + float a) { + std::shared_ptr mob = std::dynamic_pointer_cast(entity); + + float brightness = + SharedConstants::TEXTURE_LIGHTING ? 1 : mob->getBrightness(a); + glColor3f(brightness, brightness, brightness); + + MobRenderer::additionalRendering(mob, a); + + std::shared_ptr item = mob->getCarriedItem(); + + if (item != NULL) { + glPushMatrix(); + + if (model->young) { + float s = 0.5f; + glTranslatef(0 / 16.0f, 10 / 16.0f, 0 / 16.0f); + glRotatef(-20, -1, 0, 0); + glScalef(s, s, s); + } + + witchModel->nose->translateTo(1 / 16.0f); + glTranslatef(-1 / 16.0f, 8.5f / 16.0f, 3.5f / 16.0f); + + if (item->id < 256 && + TileRenderer::canRender(Tile::tiles[item->id]->getRenderShape())) { + float s = 8 / 16.0f; + glTranslatef(-0 / 16.0f, 3 / 16.0f, -5 / 16.0f); + s *= 0.75f; + glRotatef(20, 1, 0, 0); + glRotatef(45, 0, 1, 0); + glScalef(s, -s, s); + } else if (item->id == Item::bow->id) { + float s = 10 / 16.0f; + glTranslatef(0 / 16.0f, 2 / 16.0f, 5 / 16.0f); + glRotatef(-20, 0, 1, 0); + glScalef(s, -s, s); + glRotatef(-100, 1, 0, 0); + glRotatef(45, 0, 1, 0); + } else if (Item::items[item->id]->isHandEquipped()) { + float s = 10 / 16.0f; + if (Item::items[item->id]->isMirroredArt()) { + glRotatef(180, 0, 0, 1); + glTranslatef(0, -2 / 16.0f, 0); + } + translateWeaponItem(); + glScalef(s, -s, s); + glRotatef(-100, 1, 0, 0); + glRotatef(45, 0, 1, 0); + } else { + float s = 6 / 16.0f; + glTranslatef(+4 / 16.0f, +3 / 16.0f, -3 / 16.0f); + glScalef(s, s, s); + glRotatef(60, 0, 0, 1); + glRotatef(-90, 1, 0, 0); + glRotatef(20, 0, 0, 1); + } + + glRotatef(-15, 1, 0, 0); + glRotatef(40, 0, 0, 1); + + entityRenderDispatcher->itemInHandRenderer->renderItem(mob, item, 0); + if (item->getItem()->hasMultipleSpriteLayers()) { + entityRenderDispatcher->itemInHandRenderer->renderItem(mob, item, + 1); + } + glPopMatrix(); + } +} + +void WitchRenderer::translateWeaponItem() { glTranslatef(0, 3 / 16.0f, 0); } + +void WitchRenderer::scale(std::shared_ptr mob, float a) { + float s = 15 / 16.0f; + glScalef(s, s, s); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.h new file mode 100644 index 000000000..217e4de23 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitchRenderer.h @@ -0,0 +1,23 @@ +#pragma once +#include "MobRenderer.h" + +class WitchModel; + +class WitchRenderer : public MobRenderer { +private: + static ResourceLocation WITCH_LOCATION; + WitchModel* witchModel; + +public: + WitchRenderer(); + virtual void render(std::shared_ptr entity, double x, double y, + double z, float rot, float a); + +protected: + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + virtual void additionalRendering(std::shared_ptr mob, + float a); + virtual void translateWeaponItem(); + virtual void scale(std::shared_ptr mob, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.cpp new file mode 100644 index 000000000..c0d38e65e --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.cpp @@ -0,0 +1,108 @@ +#include "../../Platform/stdafx.h" +#include "WitherBossRenderer.h" +#include "../Models/WitherBossModel.h" +#include "MobRenderer.h" +#include "../../../Minecraft.World/Entities/Mobs/WitherBoss.h" +#include "../../UI/BossMobGuiInfo.h" + +ResourceLocation WitherBossRenderer::WITHER_ARMOR_LOCATION = + ResourceLocation(TN_MOB_WITHER_ARMOR); +ResourceLocation WitherBossRenderer::WITHER_INVULERABLE_LOCATION = + ResourceLocation(TN_MOB_WITHER_INVULNERABLE); +ResourceLocation WitherBossRenderer::WITHER_LOCATION = + ResourceLocation(TN_MOB_WITHER); + +WitherBossRenderer::WitherBossRenderer() + : MobRenderer(new WitherBossModel(), 1.0f) { + modelVersion = dynamic_cast(model)->modelVersion(); +} + +void WitherBossRenderer::render(std::shared_ptr entity, double x, + double y, double z, float rot, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(entity); + + BossMobGuiInfo::setBossHealth(mob, true); + + int modelVersion = dynamic_cast(model)->modelVersion(); + if (modelVersion != this->modelVersion) { + this->modelVersion = modelVersion; + model = new WitherBossModel(); + } + MobRenderer::render(entity, x, y, z, rot, a); +} + +ResourceLocation* WitherBossRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr mob = + std::dynamic_pointer_cast(entity); + + int invulnerableTicks = mob->getInvulnerableTicks(); + if (invulnerableTicks <= 0 || + ((invulnerableTicks <= (SharedConstants::TICKS_PER_SECOND * 4)) && + (invulnerableTicks / 5) % 2 == 1)) { + return &WITHER_LOCATION; + } + return &WITHER_INVULERABLE_LOCATION; +} + +void WitherBossRenderer::scale(std::shared_ptr _mob, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(_mob); + int inTicks = mob->getInvulnerableTicks(); + if (inTicks > 0) { + float scale = 2.0f - (((float)inTicks - a) / + (SharedConstants::TICKS_PER_SECOND * 11)) * + .5f; + glScalef(scale, scale, scale); + } else { + glScalef(2, 2, 2); + } +} + +int WitherBossRenderer::prepareArmor(std::shared_ptr entity, + int layer, float a) { + std::shared_ptr mob = + std::dynamic_pointer_cast(entity); + + if (mob->isPowered()) { + if (mob->isInvisible()) { + glDepthMask(false); + } else { + glDepthMask(true); + } + + if (layer == 1) { + float time = mob->tickCount + a; + bindTexture(&WITHER_ARMOR_LOCATION); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + float uo = cos(time * 0.02f) * 3; + float vo = time * 0.01f; + glTranslatef(uo, vo, 0); + setArmor(model); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_BLEND); + float br = 0.5f; + glColor4f(br, br, br, 1); + glDisable(GL_LIGHTING); + glBlendFunc(GL_ONE, GL_ONE); + glTranslatef(0, -.01f, 0); + glScalef(1.1f, 1.1f, 1.1f); + return 1; + } + if (layer == 2) { + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_LIGHTING); + glDisable(GL_BLEND); + } + } + return -1; +} + +int WitherBossRenderer::prepareArmorOverlay( + std::shared_ptr entity, int layer, float a) { + return -1; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.h new file mode 100644 index 000000000..fe0a12f73 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitherBossRenderer.h @@ -0,0 +1,27 @@ +#pragma once +#include "MobRenderer.h" + +class WitherBoss; +class LivingEntity; + +class WitherBossRenderer : public MobRenderer { +private: + static ResourceLocation WITHER_INVULERABLE_LOCATION; + static ResourceLocation WITHER_ARMOR_LOCATION; + static ResourceLocation WITHER_LOCATION; + int modelVersion; + +public: + WitherBossRenderer(); + virtual void render(std::shared_ptr entity, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); + +protected: + virtual void scale(std::shared_ptr mob, float a); + virtual int prepareArmor(std::shared_ptr entity, int layer, + float a); + virtual int prepareArmorOverlay(std::shared_ptr entity, + int layer, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.cpp new file mode 100644 index 000000000..dc2794f09 --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.cpp @@ -0,0 +1,48 @@ +#include "../../Platform/stdafx.h" +#include "WitherSkullRenderer.h" +#include "../Models/SkeletonHeadModel.h" +#include "../../../Minecraft.World/Entities/WitherSkull.h" + +ResourceLocation WitherSkullRenderer::WITHER_ARMOR_LOCATION( + TN_MOB_WITHER_INVULNERABLE); +ResourceLocation WitherSkullRenderer::WITHER_LOCATION(TN_MOB_WITHER); + +WitherSkullRenderer::WitherSkullRenderer() { model = new SkeletonHeadModel(); } + +void WitherSkullRenderer::render(std::shared_ptr entity, double x, + double y, double z, float rot, float a) { + glPushMatrix(); + glDisable(GL_CULL_FACE); + + float headRot = rotlerp(entity->yRotO, entity->yRot, a); + float headRotx = entity->xRotO + (entity->xRot - entity->xRotO) * a; + + glTranslatef((float)x, (float)y, (float)z); + + float scale = 1 / 16.0f; + glEnable(GL_RESCALE_NORMAL); + glScalef(-1, -1, 1); + + glEnable(GL_ALPHA_TEST); + + bindTexture(entity); + + model->render(entity, 0, 0, 0, headRot, headRotx, scale, true); + + glPopMatrix(); +} + +ResourceLocation* WitherSkullRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr mob = + std::dynamic_pointer_cast(entity); + + return mob->isDangerous() ? &WITHER_ARMOR_LOCATION : &WITHER_LOCATION; +} + +float WitherSkullRenderer::rotlerp(float from, float to, float a) { + float diff = to - from; + while (diff < -180) diff += 360; + while (diff >= 180) diff -= 360; + return from + a * diff; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.h new file mode 100644 index 000000000..2c002ed3e --- /dev/null +++ b/Minecraft.Client/Rendering/EntityRenderers/WitherSkullRenderer.h @@ -0,0 +1,21 @@ +#pragma once +#include "EntityRenderer.h" + +class SkeletonHeadModel; + +class WitherSkullRenderer : public EntityRenderer { +private: + static ResourceLocation WITHER_ARMOR_LOCATION; + static ResourceLocation WITHER_LOCATION; + + SkeletonHeadModel* model; + +public: + WitherSkullRenderer(); + void render(std::shared_ptr entity, double x, double y, double z, + float rot, float a); + ResourceLocation* getTextureLocation(std::shared_ptr entity); + +private: + float rotlerp(float from, float to, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.cpp index 12731b706..ddeb8acf3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.cpp @@ -3,12 +3,21 @@ #include "../../Player/MultiPlayerLocalPlayer.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +ResourceLocation* WolfRenderer::WOLF_LOCATION = + new ResourceLocation(TN_MOB_WOLF); +ResourceLocation* WolfRenderer::WOLF_TAME_LOCATION = + new ResourceLocation(TN_MOB_WOLF_TAME); +ResourceLocation* WolfRenderer::WOLF_ANGRY_LOCATION = + new ResourceLocation(TN_MOB_WOLF_ANGRY); +ResourceLocation* WolfRenderer::WOLF_COLLAR_LOCATION = + new ResourceLocation(TN_MOB_WOLF_COLLAR); + WolfRenderer::WolfRenderer(Model* model, Model* armor, float shadow) : MobRenderer(model, shadow) { setArmor(armor); } -float WolfRenderer::getBob(std::shared_ptr _mob, float a) { +float WolfRenderer::getBob(std::shared_ptr _mob, float a) { // 4J - dynamic cast required because we aren't using templates/generics in // our version std::shared_ptr mob = std::dynamic_pointer_cast(_mob); @@ -16,20 +25,21 @@ float WolfRenderer::getBob(std::shared_ptr _mob, float a) { return mob->getTailAngle(); } -int WolfRenderer::prepareArmor(std::shared_ptr mob, int layer, float a) { +int WolfRenderer::prepareArmor(std::shared_ptr mob, int layer, + float a) { if (mob->isInvisibleTo(Minecraft::GetInstance()->player)) return -1; // 4J-JEV: Todo, merge with java fix in '1.7.5'. std::shared_ptr wolf = std::dynamic_pointer_cast(mob); if (layer == 0 && wolf->isWet()) { float brightness = wolf->getBrightness(a) * wolf->getWetShade(a); - bindTexture(wolf->getTexture()); + bindTexture(WOLF_LOCATION); glColor3f(brightness, brightness, brightness); return 1; } if (layer == 1 && wolf->isTame()) { - bindTexture(TN_MOB_WOLF_COLLAR); + bindTexture(WOLF_COLLAR_LOCATION); float brightness = SharedConstants::TEXTURE_LIGHTING ? 1 : wolf->getBrightness(a); int color = wolf->getCollarColor(); @@ -41,3 +51,15 @@ int WolfRenderer::prepareArmor(std::shared_ptr mob, int layer, float a) { } return -1; } + +ResourceLocation* WolfRenderer::getTextureLocation( + std::shared_ptr _mob) { + std::shared_ptr mob = std::dynamic_pointer_cast(_mob); + if (mob->isTame()) { + return WOLF_TAME_LOCATION; + } + if (mob->isAngry()) { + return WOLF_ANGRY_LOCATION; + } + return WOLF_LOCATION; +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.h index 45d5c264f..a89b6d8ce 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/WolfRenderer.h @@ -2,10 +2,18 @@ #include "MobRenderer.h" class WolfRenderer : public MobRenderer { +private: + static ResourceLocation* WOLF_LOCATION; + static ResourceLocation* WOLF_TAME_LOCATION; + static ResourceLocation* WOLF_ANGRY_LOCATION; + static ResourceLocation* WOLF_COLLAR_LOCATION; + public: WolfRenderer(Model* model, Model* armor, float shadow); protected: - virtual float getBob(std::shared_ptr _mob, float a); - virtual int prepareArmor(std::shared_ptr mob, int layer, float a); -}; + virtual float getBob(std::shared_ptr _mob, float a); + virtual int prepareArmor(std::shared_ptr mob, int layer, + float a); + virtual ResourceLocation* getTextureLocation(std::shared_ptr mob); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.cpp index 2fce366fb..e3ed0cb03 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.cpp @@ -4,6 +4,11 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "ZombieRenderer.h" +ResourceLocation ZombieRenderer::ZOMBIE_PIGMAN_LOCATION(TN_MOB_PIGZOMBIE); +ResourceLocation ZombieRenderer::ZOMBIE_LOCATION(TN_MOB_ZOMBIE); +ResourceLocation ZombieRenderer::ZOMBIE_VILLAGER_LOCATION( + TN_MOB_ZOMBIE_VILLAGER); + ZombieRenderer::ZombieRenderer() : HumanoidMobRenderer(new ZombieModel(), .5f, 1.0f) { modelVersion = 1; @@ -33,7 +38,7 @@ void ZombieRenderer::createArmorParts() { villagerArmorParts2 = new VillagerZombieModel(0.5f, 0, true); } -int ZombieRenderer::prepareArmor(std::shared_ptr _mob, int layer, +int ZombieRenderer::prepareArmor(std::shared_ptr _mob, int layer, float a) { std::shared_ptr mob = std::dynamic_pointer_cast(_mob); swapArmor(mob); @@ -47,7 +52,23 @@ void ZombieRenderer::render(std::shared_ptr _mob, double x, double y, HumanoidMobRenderer::render(_mob, x, y, z, rot, a); } -void ZombieRenderer::additionalRendering(std::shared_ptr _mob, float a) { +ResourceLocation* ZombieRenderer::getTextureLocation( + std::shared_ptr entity) { + std::shared_ptr mob = std::dynamic_pointer_cast(entity); + + // TODO Extract this clusterfck into 3 renderers + if (entity->instanceof(eTYPE_PIGZOMBIE)) { + return &ZOMBIE_PIGMAN_LOCATION; + } + + if (mob->isVillager()) { + return &ZOMBIE_VILLAGER_LOCATION; + } + return &ZOMBIE_LOCATION; +} + +void ZombieRenderer::additionalRendering(std::shared_ptr _mob, + float a) { std::shared_ptr mob = std::dynamic_pointer_cast(_mob); swapArmor(mob); HumanoidMobRenderer::additionalRendering(_mob, a); @@ -74,8 +95,8 @@ void ZombieRenderer::swapArmor(std::shared_ptr mob) { humanoidModel = (HumanoidModel*)model; } -void ZombieRenderer::setupRotations(std::shared_ptr _mob, float bob, - float bodyRot, float a) { +void ZombieRenderer::setupRotations(std::shared_ptr _mob, + float bob, float bodyRot, float a) { std::shared_ptr mob = std::dynamic_pointer_cast(_mob); if (mob->isConverting()) { bodyRot += (float)(cos(mob->tickCount * 3.25) * PI * .25f); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.h b/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.h index 5ab79f053..25f3008b8 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.h +++ b/Minecraft.Client/Rendering/EntityRenderers/ZombieRenderer.h @@ -1,5 +1,4 @@ #pragma once - #include "HumanoidMobRenderer.h" class VillagerZombieModel; @@ -7,6 +6,10 @@ class Zombie; class ZombieRenderer : public HumanoidMobRenderer { private: + static ResourceLocation ZOMBIE_PIGMAN_LOCATION; + static ResourceLocation ZOMBIE_LOCATION; + static ResourceLocation ZOMBIE_VILLAGER_LOCATION; + HumanoidModel* defaultModel; VillagerZombieModel* villagerModel; @@ -23,20 +26,24 @@ public: ZombieRenderer(); protected: - void createArmorParts(); - int prepareArmor(std::shared_ptr _mob, int layer, float a); + virtual void createArmorParts(); + virtual int prepareArmor(std::shared_ptr _mob, int layer, + float a); public: - void render(std::shared_ptr _mob, double x, double y, double z, - float rot, float a); + virtual void render(std::shared_ptr _mob, double x, double y, + double z, float rot, float a); + virtual ResourceLocation* getTextureLocation( + std::shared_ptr entity); protected: - void additionalRendering(std::shared_ptr _mob, float a); + virtual void additionalRendering(std::shared_ptr _mob, + float a); private: - void swapArmor(std::shared_ptr mob); + virtual void swapArmor(std::shared_ptr mob); protected: - void setupRotations(std::shared_ptr _mob, float bob, float bodyRot, - float a); + virtual void setupRotations(std::shared_ptr _mob, float bob, + float bodyRot, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 5ac8efc91..5662d361f 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1,7 +1,6 @@ #include "../Platform/stdafx.h" #include "GameRenderer.h" #include "EntityRenderers/ItemInHandRenderer.h" -#include "Input/Input.h" #include "LevelRenderer.h" #include "Frustum.h" #include "FrustumCuller.h" @@ -19,14 +18,15 @@ #include "../Level/MultiPlayerLevel.h" #include "Chunk.h" #include "../../Minecraft.World/Headers/net.minecraft.world.entity.h" -#include "../../Minecraft.World/Headers/net.minecraft.world.level.h" #include "../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" -#include "../../Minecraft.World/Headers/net.minecraft.world.phys.h" +#include "../../Minecraft.World/Headers/net.minecraft.world.item.enchantment.h" +#include "../../Minecraft.World/Headers/net.minecraft.world.level.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.material.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.chunk.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.biome.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.dimension.h" +#include "../../Minecraft.World/Headers/net.minecraft.world.phys.h" #include "../../Minecraft.World/Platform/System.h" #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "../../Minecraft.World/Util/ThreadName.h" @@ -45,10 +45,12 @@ #include "Models/HumanoidModel.h" #include "../../Minecraft.World/Items/Item.h" #include "../../Minecraft.World/IO/Streams/Compression.h" -#include "../Platform/PS3/PS3Extras/ShutdownManager.h" +#include "PS3/PS3Extras/ShutdownManager.h" +#include "../UI/BossMobGuiInfo.h" #include "../Textures/Packs/TexturePackRepository.h" #include "../Textures/Packs/TexturePack.h" +#include "../Textures/TextureAtlas.h" bool GameRenderer::anaglyph3d = false; int GameRenderer::anaglyphPass = 0; @@ -58,7 +60,7 @@ C4JThread* GameRenderer::m_updateThread; C4JThread::EventArray* GameRenderer::m_updateEvents; bool GameRenderer::nearThingsToDo = false; bool GameRenderer::updateRunning = false; -std::vector GameRenderer::m_deleteStackByte; +std::vector GameRenderer::m_deleteStackByte; std::vector GameRenderer::m_deleteStackSparseLightStorage; std::vector GameRenderer::m_deleteStackCompressedTileStorage; @@ -66,6 +68,11 @@ std::vector GameRenderer::m_deleteStackSparseDataStorage; #endif CRITICAL_SECTION GameRenderer::m_csDeleteStack; +ResourceLocation GameRenderer::RAIN_LOCATION = + ResourceLocation(TN_ENVIRONMENT_RAIN); +ResourceLocation GameRenderer::SNOW_LOCATION = + ResourceLocation(TN_ENVIRONMENT_SNOW); + GameRenderer::GameRenderer(Minecraft* mc) { // 4J - added this block of initialisers renderDistance = 0; @@ -120,6 +127,9 @@ GameRenderer::GameRenderer(Minecraft* mc) { blg = 0.0f; blgt = 0.0f; + darkenWorldAmount = 0.0f; + darkenWorldAmountO = 0.0f; + m_fov = 70.0f; // 4J Stu - Init these so they are setup before the tick @@ -192,62 +202,6 @@ void GameRenderer::tick(bool first) // 4J - add bFirst fovOffsetO = fovOffset; cameraRollO = cameraRoll; - if (ClientConstants::DEADMAU5_CAMERA_CHEATS) { - if (mc->screen == NULL) { - float distanceDelta = 0; - float rotationDelta = 0; - float tiltDelta = 0; - float rollDelta = 0; - - if (Keyboard::isKeyDown(Keyboard::KEY_U)) { - distanceDelta -= .3f * mc->options->cameraSpeed; - } else if (Keyboard::isKeyDown(Keyboard::KEY_O)) { - distanceDelta += .3f * mc->options->cameraSpeed; - } - if (Keyboard::isKeyDown(Keyboard::KEY_J)) { - rotationDelta += 8.0f * mc->options->cameraSpeed; - } else if (Keyboard::isKeyDown(Keyboard::KEY_L)) { - rotationDelta -= 8.0f * mc->options->cameraSpeed; - } - if (Keyboard::isKeyDown(Keyboard::KEY_I)) { - tiltDelta += 6.0f * mc->options->cameraSpeed; - } else if (Keyboard::isKeyDown(Keyboard::KEY_K)) { - tiltDelta -= 6.0f * mc->options->cameraSpeed; - } - if (Keyboard::isKeyDown(Keyboard::KEY_Y) && - Keyboard::isKeyDown(Keyboard::KEY_H)) { - fovOffset = 0; - } else if (Keyboard::isKeyDown(Keyboard::KEY_Y)) { - fovOffset -= 3.0f; - } else if (Keyboard::isKeyDown(Keyboard::KEY_H)) { - fovOffset += 3.0f; - } - if (Keyboard::isKeyDown(Keyboard::KEY_N) && - Keyboard::isKeyDown(Keyboard::KEY_M)) { - cameraRoll = 0; - } else if (Keyboard::isKeyDown(Keyboard::KEY_N)) { - rollDelta -= 8.0f * mc->options->cameraSpeed; - } else if (Keyboard::isKeyDown(Keyboard::KEY_M)) { - rollDelta += 8.0f * mc->options->cameraSpeed; - } - - if (mc->options->smoothCamera) { - distanceDelta = smoothDistance.getNewDeltaValue( - distanceDelta, .5f * mc->options->sensitivity); - rotationDelta = smoothRotation.getNewDeltaValue( - rotationDelta, .5f * mc->options->sensitivity); - tiltDelta = smoothTilt.getNewDeltaValue( - tiltDelta, .5f * mc->options->sensitivity); - rollDelta = smoothRoll.getNewDeltaValue( - rollDelta, .5f * mc->options->sensitivity); - } - thirdDistance += distanceDelta; - thirdRotation += rotationDelta; - thirdTilt += tiltDelta; - cameraRoll += rollDelta; - } - } - if (mc->options->smoothCamera) { // update player view in tick() instead of render() to maintain // camera movement regardless of FPS @@ -280,6 +234,19 @@ void GameRenderer::tick(bool first) // 4J - add bFirst tickRain(); PIXEndNamedEvent(); + darkenWorldAmountO = darkenWorldAmount; + if (BossMobGuiInfo::darkenWorld) { + darkenWorldAmount += + 1.0f / ((float)SharedConstants::TICKS_PER_SECOND * 1); + if (darkenWorldAmount > 1) { + darkenWorldAmount = 1; + } + BossMobGuiInfo::darkenWorld = false; + } else if (darkenWorldAmount > 0) { + darkenWorldAmount -= + 1.0f / ((float)SharedConstants::TICKS_PER_SECOND * 4); + } + if (mc->player != mc->localplayers[ProfileManager.GetPrimaryPad()]) return; // 4J added for split screen - only do rest of processing for // once per frame @@ -291,6 +258,8 @@ void GameRenderer::pick(float a) { if (mc->cameraTargetPlayer == NULL) return; if (mc->level == NULL) return; + mc->crosshairPickMob = nullptr; + double range = mc->gameMode->getPickRange(); delete mc->hitResult; MemSect(31); @@ -362,7 +331,11 @@ void GameRenderer::pick(float a) { } } else if (p != NULL) { double dd = from->distanceTo(p->pos); - if (dd < nearest || nearest == 0) { + if (e == mc->cameraTargetPlayer->riding != NULL) { + if (nearest == 0) { + hovered = e; + } + } else { hovered = e; nearest = dd; } @@ -374,6 +347,10 @@ void GameRenderer::pick(float a) { if (nearest < dist || (mc->hitResult == NULL)) { if (mc->hitResult != NULL) delete mc->hitResult; mc->hitResult = new HitResult(hovered); + if (hovered->instanceof(eTYPE_LIVINGENTITY)) { + mc->crosshairPickMob = + std::dynamic_pointer_cast(hovered); + } } } } @@ -391,6 +368,9 @@ void GameRenderer::tickFov() { oFov[playerIdx] = fov[playerIdx]; fov[playerIdx] += (tFov[playerIdx] - fov[playerIdx]) * 0.5f; + + if (fov[playerIdx] > 1.5f) fov[playerIdx] = 1.5f; + if (fov[playerIdx] < 0.1f) fov[playerIdx] = 0.1f; } float GameRenderer::getFov(float a, bool applyEffects) { @@ -402,8 +382,7 @@ float GameRenderer::getFov(float a, bool applyEffects) { float fov = m_fov; // 70; if (applyEffects) { fov += mc->options->fov * 40; - fov *= this->oFov[playerIdx] + - (this->fov[playerIdx] - this->oFov[playerIdx]) * a; + fov *= oFov[playerIdx] + (this->fov[playerIdx] - oFov[playerIdx]) * a; } if (player->getHealth() <= 0) { float duration = player->deathTime + a; @@ -419,7 +398,7 @@ float GameRenderer::getFov(float a, bool applyEffects) { } void GameRenderer::bobHurt(float a) { - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; float hurt = player->hurtTime - a; @@ -441,13 +420,10 @@ void GameRenderer::bobHurt(float a) { } void GameRenderer::bobView(float a) { + if (!mc->cameraTargetPlayer->instanceof(eTYPE_LIVINGENTITY)) return; + std::shared_ptr player = std::dynamic_pointer_cast(mc->cameraTargetPlayer); - if (player == NULL) { - return; - } - // std::shared_ptr player = - // std::dynamic_pointer_cast(mc->cameraTargetPlayer); float wda = player->walkDist - player->walkDistO; float b = -(player->walkDist + wda * a); @@ -461,7 +437,7 @@ void GameRenderer::bobView(float a) { } void GameRenderer::moveCameraToPlayer(float a) { - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; std::shared_ptr localplayer = std::dynamic_pointer_cast(mc->cameraTargetPlayer); float heightOffset = player->heightOffset - 1.62f; @@ -511,16 +487,20 @@ void GameRenderer::moveCameraToPlayer(float a) { // 4J - corrected bug where this used to just take player->xRot & // yRot directly and so wasn't taking into account interpolation, // allowing camera to go through walls - float yRot = player->yRotO + (player->yRot - player->yRotO) * a; - float xRot = player->xRotO + (player->xRot - player->xRotO) * a; + float playerYRot = + player->yRotO + (player->yRot - player->yRotO) * a; + float playerXRot = + player->xRotO + (player->xRot - player->xRotO) * a; + float yRot = playerYRot; + float xRot = playerXRot; // Thirdperson view values are now 0 for disabled, 1 for original // mode, 2 for reversed. if (localplayer->ThirdPersonView() == 2) { - // Reverse y rotation - note that this is only used in doing + // Reverse x rotation - note that this is only used in doing // collision to calculate our view distance, the actual rotation // itself is just below this else {} block - yRot += 180.0f; + xRot += 180.0f; } double xd = -Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * @@ -550,13 +530,15 @@ void GameRenderer::moveCameraToPlayer(float a) { } } - // 4J - removed extra rotations here that aren't needed because our - // xRot/yRot don't ever deviate from the player's view direction - // glRotatef(player->xRot - xRot, 1, 0, 0); - // glRotatef(player->yRot - yRot, 0, 1, 0); + if (localplayer->ThirdPersonView() == 2) { + glRotatef(180, 0, 1, 0); + } + + glRotatef(playerXRot - xRot, 1, 0, 0); + glRotatef(playerYRot - yRot, 0, 1, 0); glTranslatef(0, 0, (float)-cameraDist); - // glRotatef(yRot - player->yRot, 0, 1, 0); - // glRotatef(xRot - player->xRot, 1, 0, 0); + glRotatef(yRot - playerYRot, 0, 1, 0); + glRotatef(xRot - playerXRot, 1, 0, 0); } } else { glTranslatef(0, 0, -0.1f); @@ -564,15 +546,8 @@ void GameRenderer::moveCameraToPlayer(float a) { if (!mc->options->fixedCamera) { glRotatef(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0); - if (localplayer->ThirdPersonView() == 2) { - // Third person view is now 0 for disabled, 1 for original, 2 for - // flipped - glRotatef(player->yRotO + (player->yRot - player->yRotO) * a, 0, 1, - 0); - } else { - glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, - 0, 1, 0); - } + glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, + 1, 0); } glTranslatef(0, heightOffset, 0); @@ -585,9 +560,9 @@ void GameRenderer::moveCameraToPlayer(float a) { } void GameRenderer::zoomRegion(double zoom, double xa, double ya) { - this->zoom = zoom; - this->zoom_x = xa; - this->zoom_y = ya; + zoom = zoom; + zoom_x = xa; + zoom_y = ya; } void GameRenderer::unZoomRegion() { zoom = 1; } @@ -597,13 +572,9 @@ void GameRenderer::unZoomRegion() { zoom = 1; } void GameRenderer::getFovAndAspect(float& fov, float& aspect, float a, bool applyEffects) { // 4J - split out aspect ratio and fov here so we can adjust for viewports - - // we might need to revisit these as avoid pixel streching, its UGLEYYY - { - int fbw = mc->width; - int fbh = mc->height; - RenderManager.GetFramebufferSize(fbw, fbh); - aspect = fbw / (float)fbh; - } + // we might need to revisit these as they are maybe be too generous for + // performance. + aspect = mc->width / (float)mc->height; fov = getFov(a, applyEffects); if ((mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_TOP) || @@ -695,8 +666,14 @@ void GameRenderer::setupCamera(float a, int eye) { void GameRenderer::renderItemInHand(float a, int eye) { if (cameraFlip > 0) return; + // 4J-JEV: I'm fairly confident this method would crash if the cameratarget + // isnt a local player anyway, but oh well. std::shared_ptr localplayer = - std::dynamic_pointer_cast(mc->cameraTargetPlayer); + mc->cameraTargetPlayer->instanceof(eTYPE_LOCALPLAYER) + ? std::dynamic_pointer_cast(mc->cameraTargetPlayer) + : nullptr; + + bool renderHand = true; // 4J-PB - to turn off the hand for screenshots, but not when the item held // is a map @@ -706,7 +683,7 @@ void GameRenderer::renderItemInHand(float a, int eye) { if (!(item && item->getItem()->id == Item::map_Id) && app.GetGameSettings(localplayer->GetXboxPad(), eGameSetting_DisplayHand) == 0) - return; + renderHand = false; } glMatrixMode(GL_PROJECTION); @@ -749,36 +726,33 @@ void GameRenderer::renderItemInHand(float a, int eye) { !localplayer->abilities.flying && !bNoLegAnim) bobView(a); - // 4J-PB - changing this to be per player - // if (!mc->options->thirdPersonView && - // !mc->cameraTargetPlayer->isSleeping()) - if (!localplayer->ThirdPersonView() && - !mc->cameraTargetPlayer->isSleeping()) { - if (!mc->options->hideGui && !mc->gameMode->isCutScene()) { - turnOnLightLayer(a, true); - PIXBeginNamedEvent(0, "Item in hand render"); - // 4jcraft: add null pointer check to itemInHandRenderer to prevent - // a occasional seg fault - if (itemInHandRenderer != nullptr) { + // 4J: Skip hand rendering if render hand is off + if (renderHand) { + // 4J-PB - changing this to be per player + // if (!mc->options->thirdPersonView && + // !mc->cameraTargetPlayer->isSleeping()) + if (!localplayer->ThirdPersonView() && + !mc->cameraTargetPlayer->isSleeping()) { + if (!mc->options->hideGui && !mc->gameMode->isCutScene()) { + turnOnLightLayer(a); + PIXBeginNamedEvent(0, "Item in hand render"); itemInHandRenderer->render(a); + PIXEndNamedEvent(); + turnOffLightLayer(a); } - PIXEndNamedEvent(); - turnOffLightLayer(a); } } glPopMatrix(); + // 4J-PB - changing this to be per player // if (!mc->options->thirdPersonView && // !mc->cameraTargetPlayer->isSleeping()) if (!localplayer->ThirdPersonView() && !mc->cameraTargetPlayer->isSleeping()) { - // 4jcraft: add null pointer check to itemInHandRenderer to prevent a - // occasional seg fault - if (itemInHandRenderer != nullptr) { - itemInHandRenderer->renderScreenEffect(a); - } + itemInHandRenderer->renderScreenEffect(a); bobHurt(a); } + // 4J-PB - changing this to be per player // if (mc->options->bobView) bobView(a); if (app.GetGameSettings(localplayer->GetXboxPad(), eGameSetting_ViewBob) && @@ -787,66 +761,55 @@ void GameRenderer::renderItemInHand(float a, int eye) { } // 4J - change brought forward from 1.8.2 -void GameRenderer::turnOffLightLayer( - double alpha) { // 4J - TODO - // 4jcraft: manually handle this in order to ensure that - // the light layer is turned off correctly -#if 1 - if (SharedConstants::TEXTURE_LIGHTING) { - glClientActiveTexture(GL_TEXTURE1); - glActiveTexture(GL_TEXTURE1); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - glClientActiveTexture(GL_TEXTURE0); - glActiveTexture(GL_TEXTURE0); - } +void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO +#if 0 + if (SharedConstants::TEXTURE_LIGHTING) + { + glClientActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glClientActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); + } #endif - // RenderManager.TextureBindVertex(-1); + RenderManager.TextureBindVertex(-1); } // 4J - change brought forward from 1.8.2 -void GameRenderer::turnOnLightLayer(double alpha, - bool scaleLight) { // 4J - TODO +void GameRenderer::turnOnLightLayer(double alpha) { // 4J - TODO #if 0 - if (SharedConstants::TEXTURE_LIGHTING) + if (SharedConstants::TEXTURE_LIGHTING) { - glClientActiveTexture(GL_TEXTURE1); - glActiveTexture(GL_TEXTURE1); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); -// float s = 1 / 16f / 15.0f*16/14.0f; - float s = 1 / 16.0f / 15.0f * 15 / 16; - glScalef(s, s, s); - glTranslatef(8f, 8f, 8f); - glMatrixMode(GL_MODELVIEW); + glClientActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE1); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + // float s = 1 / 16f / 15.0f*16/14.0f; + float s = 1 / 16.0f / 15.0f * 15 / 16; + glScalef(s, s, s); + glTranslatef(8f, 8f, 8f); + glMatrixMode(GL_MODELVIEW); - mc->textures->bind(lightTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + mc->textures->bind(lightTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glColor4f(1, 1, 1, 1); - glEnable(GL_TEXTURE_2D); - glClientActiveTexture(GL_TEXTURE0); - glActiveTexture(GL_TEXTURE0); - } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glColor4f(1, 1, 1, 1); + glEnable(GL_TEXTURE_2D); + glClientActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); + } #endif - // update light texture - // todo: check implementation of getLightTexture. RenderManager.TextureBindVertex( - getLightTexture(mc->player->GetXboxPad(), mc->level), scaleLight); -#if 0 + getLightTexture(mc->player->GetXboxPad(), mc->level)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); -#endif } // 4J - change brought forward from 1.8.2 @@ -882,7 +845,7 @@ void GameRenderer::updateLightTexture(float a) { float block = level->dimension->brightnessRamp[i % 16] * (blr * 0.1f + 1.5f); - if (level->lightningBoltTime > 0) { + if (level->skyFlashTime > 0) { sky = level->dimension->brightnessRamp[i / 16]; } @@ -902,6 +865,14 @@ void GameRenderer::updateLightTexture(float a) { _g = _g * 0.96f + 0.03f; _b = _b * 0.96f + 0.03f; + if (darkenWorldAmount > 0) { + float amount = darkenWorldAmountO + + (darkenWorldAmount - darkenWorldAmountO) * a; + _r = _r * (1.0f - amount) + (_r * .7f) * amount; + _g = _g * (1.0f - amount) + (_g * .6f) * amount; + _b = _b * (1.0f - amount) + (_b * .6f) * amount; + } + if (level->dimension->id == 1) { _r = (0.22f + rb * 0.75f); _g = (0.28f + gb * 0.75f); @@ -924,14 +895,12 @@ void GameRenderer::updateLightTexture(float a) { } } - float brightness = - mc->options->gamma; // 4jcraft: since the java UI has a - // brightness slider again, lets use it. - // it'll still be 0.0f for iggy UI anyway if (_r > 1) _r = 1; if (_g > 1) _g = 1; if (_b > 1) _b = 1; + float brightness = 0.0f; // 4J - TODO - was mc->options->gamma; + float ir = 1 - _r; float ig = 1 - _g; float ib = 1 - _b; @@ -953,22 +922,25 @@ void GameRenderer::updateLightTexture(float a) { if (_g < 0) _g = 0; if (_b < 0) _b = 0; - int a = 255; + int alpha = 255; int r = (int)(_r * 255); int g = (int)(_g * 255); int b = (int)(_b * 255); #if (defined _DURANGO || defined _WIN64 || __PSVITA__ || __linux__) - lightPixels[j][i] = a << 24 | b << 16 | g << 8 | r; + lightPixels[j][i] = alpha << 24 | b << 16 | g << 8 | r; #elif (defined _XBOX || defined __ORBIS__) - lightPixels[j][i] = a << 24 | r << 16 | g << 8 | b; + lightPixels[j][i] = alpha << 24 | r << 16 | g << 8 | b; #else - lightPixels[j][i] = r << 24 | g << 16 | b << 8 | a; + lightPixels[j][i] = r << 24 | g << 16 | b << 8 | alpha; #endif } mc->textures->replaceTextureDirect(lightPixels[j], 16, 16, getLightTexture(j, level)); + // lightTexture->upload(); // 4J: not relevant + + //_updateLightTexture = false; } } @@ -1006,7 +978,7 @@ void GameRenderer::render(float a, bool bFirst) { } #if 0 // 4J - TODO - if (mc->mouseGrabbed) { + if (mc->mouseGrabbed && focused) { mc->mouseHandler.poll(); float ss = mc->options->sensitivity * 0.6f + 0.2f; @@ -1017,21 +989,6 @@ void GameRenderer::render(float a, bool bFirst) { int yAxis = 1; if (mc->options->invertYMouse) yAxis = -1; - if (Minecraft.DEADMAU5_CAMERA_CHEATS) { - if (!mc->options->fixedCamera) { - if (Keyboard.isKeyDown(Keyboard.KEY_J)) { - xo = -12f * mc->options->sensitivity; - } else if (Keyboard.isKeyDown(Keyboard.KEY_L)) { - xo = 12f * mc->options->sensitivity; - } - if (Keyboard.isKeyDown(Keyboard.KEY_I)) { - yo = 12f * mc->options->sensitivity; - } else if (Keyboard.isKeyDown(Keyboard.KEY_K)) { - yo = -12f * mc->options->sensitivity; - } - } - } - if (mc->options->smoothCamera) { xo = smoothTurnX.getNewDeltaValue(xo, .05f * sens); @@ -1046,70 +1003,51 @@ void GameRenderer::render(float a, bool bFirst) { if (mc->noRender) return; GameRenderer::anaglyph3d = mc->options->anaglyph3d; - { - int fbw, fbh; - RenderManager.GetFramebufferSize(fbw, fbh); - glViewport(0, 0, fbw, fbh); -#ifdef _ENABLEIGGY - // 4jcraft: use framebuffer dimensions for ScreenSizeCalculator so the - // title screen GUI coordinates match the actual viewport size. - ScreenSizeCalculator ssc(mc->options, fbw, fbh); -#else - ScreenSizeCalculator ssc(mc->options, mc->width, mc->height); -#endif - int screenWidth = ssc.getWidth(); - int screenHeight = ssc.getHeight(); - int xMouse = InputManager.GetMouseX() * screenWidth / fbw; - int yMouse = InputManager.GetMouseY() * screenHeight / fbh - 1; + glViewport(0, 0, mc->width, mc->height); // 4J - added + ScreenSizeCalculator ssc(mc->options, mc->width, mc->height); + int screenWidth = ssc.getWidth(); + int screenHeight = ssc.getHeight(); + int xMouse = Mouse::getX() * screenWidth / mc->width; + int yMouse = screenHeight - Mouse::getY() * screenHeight / mc->height - 1; - int maxFps = getFpsCap(mc->options->framerateLimit); + int maxFps = getFpsCap(mc->options->framerateLimit); - if (mc->level != NULL) { - if (maxFps == 0) { - renderLevel(a, 0); - } else { - renderLevel(a, lastNsTime + 1000000000 / maxFps); - } - - lastNsTime = System::nanoTime(); - - if (!mc->options->hideGui || mc->screen != NULL) { - mc->gui->render(a, mc->screen != NULL, xMouse, yMouse); - } + if (mc->level != NULL) { + if (mc->options->framerateLimit == 0) { + renderLevel(a, 0); } else { - { - int fbw, fbh; - RenderManager.GetFramebufferSize(fbw, fbh); - glViewport(0, 0, fbw, fbh); - } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - setupGuiScreen(); - - lastNsTime = System::nanoTime(); + renderLevel(a, lastNsTime + 1000000000 / maxFps); } - if (mc->screen != NULL) { - glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.01f); - mc->screen->render(xMouse, yMouse, a); - if (mc->screen != NULL && mc->screen->particles != NULL) - mc->screen->particles->render(a); - glDisable(GL_BLEND); + lastNsTime = System::nanoTime(); + + if (!mc->options->hideGui || mc->screen != NULL) { + mc->gui->render(a, mc->screen != NULL, xMouse, yMouse); } + } else { + glViewport(0, 0, mc->width, mc->height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + setupGuiScreen(); + + lastNsTime = System::nanoTime(); + } + + if (mc->screen != NULL) { + glClear(GL_DEPTH_BUFFER_BIT); + mc->screen->render(xMouse, yMouse, a); + if (mc->screen != NULL && mc->screen->particles != NULL) + mc->screen->particles->render(a); } } + void GameRenderer::renderLevel(float a) { renderLevel(a, 0); } #ifdef MULTITHREAD_ENABLE // Request that an item be deleted, when it is safe to do so -void GameRenderer::AddForDelete(std::uint8_t* deleteThis) { +void GameRenderer::AddForDelete(uint8_t* deleteThis) { EnterCriticalSection(&m_csDeleteStack); m_deleteStackByte.push_back(deleteThis); } @@ -1228,9 +1166,9 @@ int GameRenderer::runUpdate(void* lpParam) { #endif void GameRenderer::EnableUpdateThread() { -// #ifdef __PS3__ // MGH - disable the update on PS3 for now -// return; -// #endif + // #ifdef __PS3__ // MGH - disable the update on PS3 for now + // return; + // #endif #ifdef MULTITHREAD_ENABLE if (updateRunning) return; app.DebugPrintf( @@ -1242,9 +1180,9 @@ void GameRenderer::EnableUpdateThread() { } void GameRenderer::DisableUpdateThread() { -// #ifdef __PS3__ // MGH - disable the update on PS3 for now -// return; -// #endif + // #ifdef __PS3__ // MGH - disable the update on PS3 for now + // return; + // #endif #ifdef MULTITHREAD_ENABLE if (!updateRunning) return; app.DebugPrintf( @@ -1255,7 +1193,7 @@ void GameRenderer::DisableUpdateThread() { #endif } -void GameRenderer::renderLevel(float a, __int64 until) { +void GameRenderer::renderLevel(float a, int64_t until) { // if (updateLightTexture) updateLightTexture(); // 4J - TODO - // Java 1.0.1 has this line enabled, should check why - don't want to put it // in now in case it breaks split-screen @@ -1278,7 +1216,7 @@ void GameRenderer::renderLevel(float a, __int64 until) { } pick(a); - std::shared_ptr cameraEntity = mc->cameraTargetPlayer; + std::shared_ptr cameraEntity = mc->cameraTargetPlayer; LevelRenderer* levelRenderer = mc->levelRenderer; ParticleEngine* particleEngine = mc->particleEngine; double xOff = @@ -1297,11 +1235,7 @@ void GameRenderer::renderLevel(float a, __int64 until) { glColorMask(true, false, false, false); } - { - int fbw, fbh; - RenderManager.GetFramebufferSize(fbw, fbh); - glViewport(0, 0, fbw, fbh); - } + glViewport(0, 0, mc->width, mc->height); setupClearColor(a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); @@ -1354,17 +1288,27 @@ void GameRenderer::renderLevel(float a, __int64 until) { if (until == 0) break; - __int64 diff = until - System::nanoTime(); + int64_t diff = until - System::nanoTime(); if (diff < 0) break; if (diff > 1000000000) break; } while (true); PIXEndNamedEvent(); } #endif + + if (cameraEntity->y < Level::genDepth) { + prepareAndRenderClouds(levelRenderer, a); + } + Frustum::getFrustum(); // 4J added - re-calculate frustum as rendering + // the clouds does a scale & recalculates one + // that isn't any good for the rest of the level + // rendering + setupFog(0, a); glEnable(GL_FOG); MemSect(31); - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + mc->textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); // 4J was L"/terrain.png" MemSect(0); Lighting::turnOff(); PIXBeginNamedEvent(0, "Level render"); @@ -1399,27 +1343,25 @@ void GameRenderer::renderLevel(float a, __int64 until) { PIXEndNamedEvent(); PIXBeginNamedEvent(0, "Particle render"); turnOnLightLayer(a); // 4J - brought forward from 1.8.2 - particleEngine->renderLit(cameraEntity, a); + particleEngine->renderLit(cameraEntity, a, + ParticleEngine::OPAQUE_LIST); Lighting::turnOff(); setupFog(0, a); - particleEngine->render(cameraEntity, a); + particleEngine->render(cameraEntity, a, + ParticleEngine::OPAQUE_LIST); PIXEndNamedEvent(); turnOffLightLayer(a); // 4J - brought forward from 1.8.2 - std::shared_ptr player = - std::dynamic_pointer_cast(cameraEntity); - if (mc->hitResult != NULL && + if ((mc->hitResult != NULL) && cameraEntity->isUnderLiquid(Material::water) && - player != NULL) //&& !mc->options.hideGui) + cameraEntity->instanceof( + eTYPE_PLAYER)) //&& !mc->options.hideGui) { - // std::shared_ptr player = - // std::dynamic_pointer_cast(cameraEntity); + std::shared_ptr player = + std::dynamic_pointer_cast(cameraEntity); glDisable(GL_ALPHA_TEST); levelRenderer->renderHit(player, mc->hitResult, 0, player->inventory->getSelected(), a); - levelRenderer->renderHitOutline( - player, mc->hitResult, 0, player->inventory->getSelected(), - a); glEnable(GL_ALPHA_TEST); } } @@ -1432,7 +1374,8 @@ void GameRenderer::renderLevel(float a, __int64 until) { glEnable(GL_BLEND); glDisable(GL_CULL_FACE); MemSect(31); - mc->textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + mc->textures->bindTexture( + &TextureAtlas::LOCATION_BLOCKS); // 4J was L"/terrain.png" MemSect(0); // 4J - have changed this fancy rendering option to work with our // command buffers. The original used to use frame buffer flags to @@ -1469,23 +1412,34 @@ void GameRenderer::renderLevel(float a, __int64 until) { PIXEndNamedEvent(); } + // 4J - added - have split out translucent particle rendering so that it + // happens after the water is rendered, primarily for fireworks + PIXBeginNamedEvent(0, "Particle render (translucent)"); + Lighting::turnOn(); + turnOnLightLayer(a); // 4J - brought forward from 1.8.2 + particleEngine->renderLit(cameraEntity, a, + ParticleEngine::TRANSLUCENT_LIST); + Lighting::turnOff(); + setupFog(0, a); + particleEngine->render(cameraEntity, a, + ParticleEngine::TRANSLUCENT_LIST); + PIXEndNamedEvent(); + turnOffLightLayer(a); // 4J - brought forward from 1.8.2 + ////////////////////////// End of 4J added section + glDepthMask(true); glEnable(GL_CULL_FACE); glDisable(GL_BLEND); - if (zoom == 1 && (std::dynamic_pointer_cast(cameraEntity) != - NULL)) //&& !mc->options.hideGui) + if ((zoom == 1) && + cameraEntity->instanceof(eTYPE_PLAYER)) //&& !mc->options.hideGui) { if (mc->hitResult != NULL && !cameraEntity->isUnderLiquid(Material::water)) { std::shared_ptr player = std::dynamic_pointer_cast(cameraEntity); glDisable(GL_ALPHA_TEST); - levelRenderer->renderHit(player, mc->hitResult, 0, - player->inventory->getSelected(), a); - levelRenderer->renderHitOutline( - player, mc->hitResult, 0, player->inventory->getSelected(), - a); + levelRenderer->renderHitOutline(player, mc->hitResult, 0, a); glEnable(GL_ALPHA_TEST); } } @@ -1504,16 +1458,8 @@ void GameRenderer::renderLevel(float a, __int64 until) { std::dynamic_pointer_cast(cameraEntity), a); glDisable(GL_BLEND); - if (mc->options->isCloudsOn()) { - glPushMatrix(); - setupFog(0, a); - glEnable(GL_FOG); - PIXBeginNamedEvent(0, "Rendering clouds"); - levelRenderer->renderClouds(a); - PIXEndNamedEvent(); - glDisable(GL_FOG); - setupFog(1, a); - glPopMatrix(); + if (cameraEntity->y >= Level::genDepth) { + prepareAndRenderClouds(levelRenderer, a); } // 4J - rain rendering moved here so that it renders after clouds & can @@ -1537,6 +1483,21 @@ void GameRenderer::renderLevel(float a, __int64 until) { glColorMask(true, true, true, false); } +void GameRenderer::prepareAndRenderClouds(LevelRenderer* levelRenderer, + float a) { + if (mc->options->isCloudsOn()) { + glPushMatrix(); + setupFog(0, a); + glEnable(GL_FOG); + PIXBeginNamedEvent(0, "Rendering clouds"); + levelRenderer->renderClouds(a); + PIXEndNamedEvent(); + glDisable(GL_FOG); + setupFog(1, a); + glPopMatrix(); + } +} + void GameRenderer::tickRain() { float rainLevel = mc->level->getRainLevel(1); @@ -1546,7 +1507,7 @@ void GameRenderer::tickRain() { rainLevel /= (mc->levelRenderer->activePlayers() + 1); random->setSeed(_tick * 312987231l); - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; Level* level = mc->level; int x0 = Mth::floor(player->x); @@ -1625,7 +1586,7 @@ void GameRenderer::renderSnowAndRain(float a) { // 4J - rain is relatively low poly, but high fill-rate - better to clip it RenderManager.StateSetEnableViewportClipPlanes(true); - this->turnOnLightLayer(a); + turnOnLightLayer(a); if (rainXa == NULL) { rainXa = new float[32 * 32]; @@ -1642,7 +1603,7 @@ void GameRenderer::renderSnowAndRain(float a) { } } - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; Level* level = mc->level; int x0 = Mth::floor(player->x); @@ -1658,7 +1619,7 @@ void GameRenderer::renderSnowAndRain(float a) { MemSect(31); mc->textures->bindTexture( - TN_ENVIRONMENT_SNOW); // 4J was L"/environment/snow.png" + &SNOW_LOCATION); // 4J was L"/environment/snow.png" MemSect(0); double xo = player->xOld + (player->x - player->xOld) * a; @@ -1725,7 +1686,7 @@ void GameRenderer::renderSnowAndRain(float a) { if (mode != 0) { if (mode >= 0) t->end(); mode = 0; - mc->textures->bindTexture(TN_ENVIRONMENT_RAIN); + mc->textures->bindTexture(&RAIN_LOCATION); t->begin(); } @@ -1776,7 +1737,7 @@ void GameRenderer::renderSnowAndRain(float a) { if (mode != 1) { if (mode >= 0) t->end(); mode = 1; - mc->textures->bindTexture(TN_ENVIRONMENT_SNOW); + mc->textures->bindTexture(&SNOW_LOCATION); t->begin(); } float ra = (((_tick) & 511) + a) / 512.0f; @@ -1825,7 +1786,7 @@ void GameRenderer::renderSnowAndRain(float a) { glEnable(GL_CULL_FACE); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER, 0.1f); - this->turnOffLightLayer(a); + turnOffLightLayer(a); RenderManager.StateSetEnableViewportClipPlanes(false); } @@ -1842,7 +1803,6 @@ void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) { #else ScreenSizeCalculator ssc(mc->options, mc->width, mc->height, forceScale); #endif - glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -1854,7 +1814,7 @@ void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) { void GameRenderer::setupClearColor(float a) { Level* level = mc->level; - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; float whiteness = 1.0f / (4 - mc->options->viewDistance); whiteness = 1 - (float)pow((double)whiteness, 0.25); @@ -1914,23 +1874,25 @@ void GameRenderer::setupClearColor(float a) { fg = (float)cc->y; fb = (float)cc->z; } else if (t != 0 && Tile::tiles[t]->material == Material::water) { + float clearness = EnchantmentHelper::getOxygenBonus(player) * 0.2f; + unsigned int colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Under_Water_Clear_Colour); - std::uint8_t redComponent = ((colour >> 16) & 0xFF); - std::uint8_t greenComponent = ((colour >> 8) & 0xFF); - std::uint8_t blueComponent = ((colour) & 0xFF); + uint8_t redComponent = ((colour >> 16) & 0xFF); + uint8_t greenComponent = ((colour >> 8) & 0xFF); + uint8_t blueComponent = ((colour) & 0xFF); - fr = (float)redComponent / 256; // 0.02f; - fg = (float)greenComponent / 256; // 0.02f; - fb = (float)blueComponent / 256; // 0.2f; + fr = (float)redComponent / 256 + clearness; // 0.02f; + fg = (float)greenComponent / 256 + clearness; // 0.02f; + fb = (float)blueComponent / 256 + clearness; // 0.2f; } else if (t != 0 && Tile::tiles[t]->material == Material::lava) { unsigned int colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Under_Lava_Clear_Colour); - std::uint8_t redComponent = ((colour >> 16) & 0xFF); - std::uint8_t greenComponent = ((colour >> 8) & 0xFF); - std::uint8_t blueComponent = ((colour) & 0xFF); + uint8_t redComponent = ((colour >> 16) & 0xFF); + uint8_t greenComponent = ((colour >> 8) & 0xFF); + uint8_t blueComponent = ((colour) & 0xFF); fr = (float)redComponent / 256; // 0.6f; fg = (float)greenComponent / 256; // 0.1f; @@ -1964,6 +1926,14 @@ void GameRenderer::setupClearColor(float a) { fb *= yy; } + if (darkenWorldAmount > 0) { + float amount = + darkenWorldAmountO + (darkenWorldAmount - darkenWorldAmountO) * a; + fr = fr * (1.0f - amount) + (fr * .7f) * amount; + fg = fg * (1.0f - amount) + (fg * .6f) * amount; + fb = fb * (1.0f - amount) + (fb * .6f) * amount; + } + if (player->hasEffect(MobEffect::nightVision)) { float scale = getNightVisionScale(mc->player, a); { @@ -1997,11 +1967,11 @@ void GameRenderer::setupClearColor(float a) { } void GameRenderer::setupFog(int i, float alpha) { - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; // 4J - check for creative mode brought forward from 1.2.3 bool creative = false; - if (std::dynamic_pointer_cast(player)) { + if (player->instanceof(eTYPE_PLAYER)) { creative = (std::dynamic_pointer_cast(player))->abilities.instabuild; } @@ -2010,17 +1980,17 @@ void GameRenderer::setupFog(int i, float alpha) { __debugbreak(); // 4J TODO /* -glFog(GL_FOG_COLOR, getBuffer(0, 0, 0, 1)); -glFogi(GL_FOG_MODE, GL_LINEAR); -glFogf(GL_FOG_START, 0); -glFogf(GL_FOG_END, 8); + glFog(GL_FOG_COLOR, getBuffer(0, 0, 0, 1)); + glFogi(GL_FOG_MODE, GL_LINEAR); + glFogf(GL_FOG_START, 0); + glFogf(GL_FOG_END, 8); -if (GLContext.getCapabilities().GL_NV_fog_distance) { - glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, -NVFogDistance.GL_EYE_RADIAL_NV); -} + if (GLContext.getCapabilities().GL_NV_fog_distance) { + glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, + NVFogDistance.GL_EYE_RADIAL_NV); + } -glFogf(GL_FOG_START, 0); + glFogf(GL_FOG_START, 0); */ return; } @@ -2056,79 +2026,18 @@ glFogf(GL_FOG_START, 0); } else if (isInClouds) { glFogi(GL_FOG_MODE, GL_EXP); glFogf(GL_FOG_DENSITY, 0.1f); // was 0.06 - - unsigned int colour = - Minecraft::GetInstance()->getColourTable()->getColor( - eMinecraftColour_In_Cloud_Fog_Colour); - std::uint8_t redComponent = ((colour >> 16) & 0xFF); - std::uint8_t greenComponent = ((colour >> 8) & 0xFF); - std::uint8_t blueComponent = ((colour) & 0xFF); - - float rr = (float)redComponent / 256; // 1.0f; - float gg = (float)greenComponent / 256; // 1.0f; - float bb = (float)blueComponent / 256; // 1.0f; - - if (mc->options->anaglyph3d) { - float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; - float ggg = (rr * 30 + gg * 70) / (100); - float bbb = (rr * 30 + bb * 70) / (100); - - rr = rrr; - gg = ggg; - bb = bbb; - } } else if (t > 0 && Tile::tiles[t]->material == Material::water) { glFogi(GL_FOG_MODE, GL_EXP); if (player->hasEffect(MobEffect::waterBreathing)) { glFogf(GL_FOG_DENSITY, 0.05f); // was 0.06 } else { - glFogf(GL_FOG_DENSITY, 0.1f); // was 0.06 - } - - unsigned int colour = - Minecraft::GetInstance()->getColourTable()->getColor( - eMinecraftColour_Under_Water_Fog_Colour); - std::uint8_t redComponent = ((colour >> 16) & 0xFF); - std::uint8_t greenComponent = ((colour >> 8) & 0xFF); - std::uint8_t blueComponent = ((colour) & 0xFF); - - float rr = (float)redComponent / 256; // 0.4f; - float gg = (float)greenComponent / 256; // 0.4f; - float bb = (float)blueComponent / 256; // 0.9f; - - if (mc->options->anaglyph3d) { - float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; - float ggg = (rr * 30 + gg * 70) / (100); - float bbb = (rr * 30 + bb * 70) / (100); - - rr = rrr; - gg = ggg; - bb = bbb; + glFogf(GL_FOG_DENSITY, + 0.1f - (EnchantmentHelper::getOxygenBonus(player) * + 0.03f)); // was 0.06 } } else if (t > 0 && Tile::tiles[t]->material == Material::lava) { glFogi(GL_FOG_MODE, GL_EXP); glFogf(GL_FOG_DENSITY, 2.0f); // was 0.06 - - unsigned int colour = - Minecraft::GetInstance()->getColourTable()->getColor( - eMinecraftColour_Under_Lava_Fog_Colour); - std::uint8_t redComponent = ((colour >> 16) & 0xFF); - std::uint8_t greenComponent = ((colour >> 8) & 0xFF); - std::uint8_t blueComponent = ((colour) & 0xFF); - - float rr = (float)redComponent / 256; // 0.4f; - float gg = (float)greenComponent / 256; // 0.3f; - float bb = (float)blueComponent / 256; // 0.3f; - - if (mc->options->anaglyph3d) { - float rrr = (rr * 30 + gg * 59 + bb * 11) / 100; - float ggg = (rr * 30 + gg * 70) / (100); - float bbb = (rr * 30 + bb * 70) / (100); - - rr = rrr; - gg = ggg; - bb = bbb; - } } else { float distance = renderDistance; if (!mc->level->dimension->hasCeiling) { @@ -2161,7 +2070,7 @@ glFogf(GL_FOG_START, 0); /* 4J - removed - TODO investigate if (GLContext.getCapabilities().GL_NV_fog_distance) { - glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, + glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); } */ @@ -2187,9 +2096,6 @@ int GameRenderer::getFpsCap(int option) { int maxFps = 200; if (option == 1) maxFps = 120; if (option == 2) maxFps = 35; -#ifndef ENABLE_VSYNC - if (option == 3) maxFps = 0; -#endif return maxFps; } diff --git a/Minecraft.Client/Rendering/GameRenderer.h b/Minecraft.Client/Rendering/GameRenderer.h index c6012c18a..f9ddcc70b 100644 --- a/Minecraft.Client/Rendering/GameRenderer.h +++ b/Minecraft.Client/Rendering/GameRenderer.h @@ -11,8 +11,13 @@ class SparseDataStorage; #include "../../Minecraft.World/Util/SmoothFloat.h" #include "../../Minecraft.World/Util/C4JThread.h" +#include "../Textures/ResourceLocation.h" class GameRenderer { +private: + static ResourceLocation RAIN_LOCATION; + static ResourceLocation SNOW_LOCATION; + public: static bool anaglyph3d; static int anaglyphPass; @@ -67,6 +72,9 @@ private: float oFov[4]; float tFov[4]; + float darkenWorldAmount; + float darkenWorldAmountO; + bool isInClouds; float m_fov; @@ -103,8 +111,8 @@ public: private: void renderItemInHand(float a, int eye); - __int64 lastActiveTime; - __int64 lastNsTime; + int64_t lastActiveTime; + int64_t lastNsTime; // 4J - changes brought forward from 1.8.2 bool _updateLightTexture; @@ -114,7 +122,7 @@ public: float blg; float blgt; void turnOffLightLayer(double alpha); - void turnOnLightLayer(double alpha, bool scaleLight = false); + void turnOnLightLayer(double alpha); private: void tickLightTexture(); @@ -129,6 +137,7 @@ public: private: Random* random; int rainSoundTime; + void prepareAndRenderClouds(LevelRenderer* levelRenderer, float a); void tickRain(); private: @@ -174,13 +183,13 @@ public: static bool nearThingsToDo; static bool updateRunning; #endif - static std::vector m_deleteStackByte; + static std::vector m_deleteStackByte; static std::vector m_deleteStackSparseLightStorage; static std::vector m_deleteStackCompressedTileStorage; static std::vector m_deleteStackSparseDataStorage; static CRITICAL_SECTION m_csDeleteStack; - static void AddForDelete(std::uint8_t* deleteThis); + static void AddForDelete(uint8_t* deleteThis); static void AddForDelete(SparseLightStorage* deleteThis); static void AddForDelete(CompressedTileStorage* deleteThis); static void AddForDelete(SparseDataStorage* deleteThis); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index da691360b..f9773b79e 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "LevelRenderer.h" #include "../Textures/Textures.h" +#include "../Textures/TextureAtlas.h" #include "Tesselator.h" #include "Chunk.h" #include "EntityRenderers/EntityRenderDispatcher.h" @@ -36,6 +37,7 @@ #include "Particles/DripParticle.h" #include "Particles/EnchantmentTableParticle.h" #include "Particles/DragonBreathParticle.h" +#include "Particles/FireworksParticles.h" #include "Lighting.h" #include "../GameState/Options.h" #include "../Network/MultiPlayerChunkCache.h" @@ -60,6 +62,8 @@ #include "FrustumCuller.h" #include "../../Minecraft.World/Util/BasicTypeContainers.h" +// #define DISABLE_SPU_CODE + #ifdef __PS3__ #include "../Platform/PS3/SPU_Tasks/LevelRenderer_cull/LevelRenderer_cull.h" #include "../Platform/PS3/SPU_Tasks/LevelRenderer_FindNearestChunk/LevelRenderer_FindNearestChunk.h" @@ -71,6 +75,16 @@ static LevelRenderer_FindNearestChunk_DataIn g_findNearestChunkDataIn __attribute__((__aligned__(16))); #endif +ResourceLocation LevelRenderer::MOON_LOCATION = + ResourceLocation(TN_TERRAIN_MOON); +ResourceLocation LevelRenderer::MOON_PHASES_LOCATION = + ResourceLocation(TN_TERRAIN_MOON_PHASES); +ResourceLocation LevelRenderer::SUN_LOCATION = ResourceLocation(TN_TERRAIN_SUN); +ResourceLocation LevelRenderer::CLOUDS_LOCATION = + ResourceLocation(TN_ENVIRONMENT_CLOUDS); +ResourceLocation LevelRenderer::END_SKY_LOCATION = + ResourceLocation(TN_MISC_TUNNEL); + const unsigned int HALO_RING_RADIUS = 100; #ifdef _LARGE_WORLDS @@ -147,7 +161,7 @@ LevelRenderer::LevelRenderer(Minecraft* mc, Textures* textures) { emptyChunks = 0; for (int i = 0; i < 4; i++) { // sortedChunks[i] = NULL; // 4J - removed - not sorting - //our chunks anymore + // our chunks anymore chunks[i] = ClipChunkArray(); lastPlayerCount[i] = 0; } @@ -366,7 +380,7 @@ void LevelRenderer::setLevel(int playerIndex, MultiPlayerLevel* level) { allChanged(playerIndex); } else { // printf("NULLing player %d, chunks @ - //0x%x\n",playerIndex,chunks[playerIndex]); + // 0x%x\n",playerIndex,chunks[playerIndex]); if (chunks[playerIndex].data != NULL) { for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { chunks[playerIndex][i].chunk->_delete(); @@ -376,8 +390,9 @@ void LevelRenderer::setLevel(int playerIndex, MultiPlayerLevel* level) { chunks[playerIndex].data = NULL; chunks[playerIndex].length = 0; // delete sortedChunks[playerIndex]; // 4J - - //removed - not sorting our chunks anymore sortedChunks[playerIndex] - //= NULL; // 4J - removed - not sorting our chunks anymore + // removed - not sorting our chunks anymore + // sortedChunks[playerIndex] = NULL; // 4J - removed - not + // sorting our chunks anymore } // 4J Stu - If we do this for splitscreen players leaving, then all the @@ -415,7 +430,7 @@ void LevelRenderer::allChanged(int playerIndex) { // called then (on 360 at least) we can get a deadlock when starting a game // in splitscreen. // EnterCriticalSection(&m_csDirtyChunks); - if (level[playerIndex] == NULL) { + if (level == NULL) { return; } @@ -450,8 +465,8 @@ void LevelRenderer::allChanged(int playerIndex) { } chunks[playerIndex] = ClipChunkArray(xChunks * yChunks * zChunks); - // sortedChunks[playerIndex] = new std::vector(xChunks * yChunks * - //zChunks); // 4J - removed - not sorting our chunks anymore + // sortedChunks[playerIndex] = new vector(xChunks * yChunks * + // zChunks); // 4J - removed - not sorting our chunks anymore int id = 0; int count = 0; @@ -482,8 +497,8 @@ void LevelRenderer::allChanged(int playerIndex) { count++; // sortedChunks[playerIndex]->at((z //* yChunks + y) * xChunks + x) = chunks[playerIndex]->at((z * - //yChunks + y) * xChunks + x); // 4J - removed - not sorting - //our chunks anymore + // yChunks + y) * xChunks + x); // 4J - removed - not sorting + // our chunks anymore id += 3; } @@ -491,14 +506,14 @@ void LevelRenderer::allChanged(int playerIndex) { } nonStackDirtyChunksAdded(); - if (level[playerIndex] != NULL) { + if (level != NULL) { std::shared_ptr player = mc->cameraTargetPlayer; if (player != NULL) { this->resortChunks(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); // sort(sortedChunks[playerIndex]->begin(),sortedChunks[playerIndex]->end(), - //DistanceChunkSorter(player)); // 4J - removed - not sorting - //our chunks anymore + // DistanceChunkSorter(player)); // 4J - removed - not sorting + // our chunks anymore } } @@ -517,9 +532,9 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { // (like particle render) may depend on it for those frames. TileEntityRenderDispatcher::instance->prepare( level[playerIndex], textures, mc->font, mc->cameraTargetPlayer, a); - EntityRenderDispatcher::instance->prepare(level[playerIndex], textures, - mc->font, mc->cameraTargetPlayer, - mc->options, a); + EntityRenderDispatcher::instance->prepare( + level[playerIndex], textures, mc->font, mc->cameraTargetPlayer, + mc->crosshairPickMob, mc->options, a); if (noEntityRenderFrames > 0) { noEntityRenderFrames--; @@ -545,8 +560,7 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { TileEntityRenderDispatcher::zOff = (player->zOld + (player->z - player->zOld) * a); - mc->gameRenderer->turnOnLightLayer( - a, true); // 4J - brought forward from 1.8.2 + mc->gameRenderer->turnOnLightLayer(a); // 4J - brought forward from 1.8.2 std::vector > entities = level[playerIndex]->getAllEntities(); @@ -565,14 +579,29 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { for (AUTO_VAR(it, entities.begin()); it != itEndEnts; it++) { std::shared_ptr entity = *it; // entities[i]; - if ((entity->shouldRender(cam) && - (entity->noCulling || culler->isVisible(entity->bb)))) { + bool shouldRender = + (entity->shouldRender(cam) && + (entity->noCulling || culler->isVisible(entity->bb))); + + // Render the mob if the mob's leash holder is within the culler + if (!shouldRender && entity->instanceof(eTYPE_MOB)) { + std::shared_ptr mob = std::dynamic_pointer_cast(entity); + if (mob->isLeashed() && (mob->getLeashHolder() != NULL)) { + std::shared_ptr leashHolder = mob->getLeashHolder(); + shouldRender = culler->isVisible(leashHolder->bb); + } + } + + if (shouldRender) { // 4J-PB - changing this to be per player // if (entity == mc->cameraTargetPlayer && // !mc->options->thirdPersonView && // !mc->cameraTargetPlayer->isSleeping()) continue; std::shared_ptr localplayer = - std::dynamic_pointer_cast(mc->cameraTargetPlayer); + mc->cameraTargetPlayer->instanceof(eTYPE_LOCALPLAYER) + ? std::dynamic_pointer_cast( + mc->cameraTargetPlayer) + : nullptr; if (localplayer && entity == mc->cameraTargetPlayer && !localplayer->ThirdPersonView() && @@ -701,8 +730,8 @@ void LevelRenderer::resortChunks(int xc, int yc, int zc) { LeaveCriticalSection(&m_csDirtyChunks); } -int LevelRenderer::render(std::shared_ptr player, int layer, double alpha, - bool updateChunks) { +int LevelRenderer::render(std::shared_ptr player, int layer, + double alpha, bool updateChunks) { int playerIndex = mc->player->GetXboxPad(); // 4J - added - if the number of players has changed, we need to rebuild @@ -772,7 +801,7 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { // sorted chunk list, anymore mc->gameRenderer->turnOnLightLayer( alpha); // 4J - brought forward from 1.8.2 - std::shared_ptr player = mc->cameraTargetPlayer; + std::shared_ptr player = mc->cameraTargetPlayer; double xOff = player->xOld + (player->x - player->xOld) * alpha; double yOff = player->yOld + (player->y - player->yOld) * alpha; double zOff = player->zOld + (player->z - player->zOld) * alpha; @@ -811,46 +840,27 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { bool first = true; int count = 0; - int dbgNotVisible = 0, dbgNoIdx = 0, dbgEmpty = 0, dbgCalled = 0, - dbgCallOk = 0; ClipChunk* pClipChunk = chunks[playerIndex].data; unsigned char emptyFlag = LevelRenderer::CHUNK_FLAG_EMPTY0 << layer; for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { - if (!pClipChunk->visible) { - dbgNotVisible++; - continue; - } - if (pClipChunk->globalIdx == -1) { - dbgNoIdx++; - continue; - } - if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == - emptyFlag) { - dbgEmpty++; - continue; - } + if (!pClipChunk->visible) + continue; // This will be set if the chunk isn't visible, or isn't + // compiled, or has both empty flags set + if (pClipChunk->globalIdx == -1) + continue; // Not sure if we should ever encounter this... TODO + // check + if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) + continue; // Check that this particular layer isn't empty // List can be calculated directly from the chunk's global idex int list = pClipChunk->globalIdx * 2 + layer; list += chunkLists; - dbgCalled++; if (RenderManager.CBuffCall(list, first)) { first = false; - dbgCallOk++; } count++; } - static int _dbgRC = 0; - _dbgRC++; - if (_dbgRC <= 2 || (_dbgRC % 3000 == 0)) { - fprintf(stderr, - "[RENDER] renderChunks frame=%d layer=%d total=%d notVis=%d " - "noIdx=%d empty=%d called=%d callOk=%d chunkLists=%d\n", - _dbgRC, layer, chunks[playerIndex].length, dbgNotVisible, - dbgNoIdx, dbgEmpty, dbgCalled, dbgCallOk, chunkLists); - fflush(stderr); - } #ifdef __PSVITA__ // AP - alpha cut out is expensive on vita. Now we render all the alpha cut @@ -989,11 +999,10 @@ void LevelRenderer::renderSky(float alpha) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Lighting::turnOff(); - glColor4f(1, 1, 1, 1); glDepthMask(false); - textures->bind(textures->loadTexture( - TN_MISC_TUNNEL)); // 4J was L"/1_2_2/misc/tunnel.png" + textures->bindTexture( + &END_SKY_LOCATION); // 4J was L"/1_2_2/misc/tunnel.png" Tesselator* t = Tesselator::getInstance(); t->setMipmapEnable(false); for (int i = 0; i < 6; i++) { @@ -1060,7 +1069,6 @@ void LevelRenderer::renderSky(float alpha) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Lighting::turnOff(); - glColor4f(1, 1, 1, 1); float* c = level[playerIndex]->dimension->getSunriseColor( level[playerIndex]->getTimeOfDay(alpha), alpha); @@ -1123,7 +1131,7 @@ void LevelRenderer::renderSky(float alpha) { float ss = 30; MemSect(31); - textures->bindTexture(TN_TERRAIN_SUN); // 4J was L"/terrain/sun.png" + textures->bindTexture(&SUN_LOCATION); MemSect(0); t->begin(); t->vertexUV((float)(-ss), (float)(100), (float)(-ss), (float)(0), @@ -1138,9 +1146,8 @@ void LevelRenderer::renderSky(float alpha) { ss = 20; textures->bindTexture( - TN_TERRAIN_MOON_PHASES); // 4J was - // L"/1_2_2/terrain/moon_phases.png" - int phase = level[playerIndex]->getMoonPhase(alpha); + &MOON_PHASES_LOCATION); // 4J was L"/1_2_2/terrain/moon_phases.png" + int phase = level[playerIndex]->getMoonPhase(); int u = phase % 4; int v = phase / 4 % 2; float u0 = (u + 0) / 4.0f; @@ -1323,8 +1330,7 @@ void LevelRenderer::renderClouds(float alpha) { int d = 256 / s; Tesselator* t = Tesselator::getInstance(); - textures->bindTexture( - TN_ENVIRONMENT_CLOUDS); // 4J was L"/environment/clouds.png" + textures->bindTexture(&CLOUDS_LOCATION); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1611,20 +1617,16 @@ void LevelRenderer::renderAdvancedClouds(float alpha) { // might be in them, but it has more risk of artifacts so we don't want to // do it when not necessary - // 4jcraft: not needed for the tesselator-based implementation - // bool noBFCMode = ( (yy > -h - 1) && (yy <= h + 1) ); - // if( noBFCMode ) - // { - // glDisable(GL_CULL_FACE); - // } - // else - // { - // glEnable(GL_CULL_FACE); - // } + bool noBFCMode = ((yy > -h - 1) && (yy <= h + 1)); + if (noBFCMode) { + glDisable(GL_CULL_FACE); + } else { + glEnable(GL_CULL_FACE); + } MemSect(31); textures->bindTexture( - TN_ENVIRONMENT_CLOUDS); // 4J was L"/environment/clouds.png" + &CLOUDS_LOCATION); // 4J was L"/environment/clouds.png" MemSect(0); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1687,83 +1689,77 @@ void LevelRenderer::renderAdvancedClouds(float alpha) { // geometry to get rid of seams. This is a huge amount more // quads to render, so now using command buffers to render each // section to cut CPU hit. +#if 1 + float xx = (float)(xPos * D); + float zz = (float)(zPos * D); + float xp = xx - xoffs; + float zp = zz - zoffs; - // 4jcraft: switch back to the tesselator-based implementation - // of cloud renders -#if 0 - float xx = (float)(xPos * D); - float zz = (float)(zPos * D); - float xp = xx - xoffs; - float zp = zz - zoffs; + if (!pFrustumData->cubeInFrustum(0 + xp, 0 + yy, 0 + zp, 8 + xp, + 4 + yy, 8 + zp)) + continue; - if( !pFrustumData->cubeInFrustum(0+xp,0+yy,0+zp, 8+xp,4+yy,8+zp) ) - continue; + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(xx / 256.0f + uo, zz / 256.0f + vo, 0); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(xp, yy, zp); + glColor4f(cr, cg, cb, 1.0f); + if (noBFCMode) { + // This is the more complex form of render the clouds, based + // on the way that the original code picked which sides to + // render, with backface culling disabled. This is to give a + // more solid version of the clouds for when the player + // might be inside them. + bool draw[6] = {false, false, false, false, false, false}; + // These rules to decide which sides to draw are the same as + // the original code below + if (yy > -h - 1) draw[0] = true; + if (yy <= h + 1) draw[1] = true; + if (xPos > -1) draw[2] = true; + if (xPos <= 1) draw[3] = true; + if (zPos > -1) draw[4] = true; + if (zPos <= 1) draw[5] = true; - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glTranslatef(xx / 256.0f + uo, zz / 256.0f + vo, 0); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glTranslatef(xp,yy,zp); - - glColor4f(cr, cg, cb, 1.0f ); - if( noBFCMode ) - { - // This is the more complex form of render the clouds, based on the way that the original code picked which sides to render, with backface culling disabled. - // This is to give a more solid version of the clouds for when the player might be inside them. - bool draw[6] = {false,false,false,false,false,false}; - - // These rules to decide which sides to draw are the same as the original code below - if (yy > -h - 1) draw[0] = true; - if (yy <= h + 1) draw[1] = true; - if (xPos > -1) draw[2] = true; - if (xPos <= 1) draw[3] = true; - if (zPos > -1) draw[4] = true; - if (zPos <= 1) draw[5] = true; - - // Top and bottom just render when required - if( draw[0] ) glCallList(cloudList); - if( draw[1] ) glCallList(cloudList + 1); - // For x facing sides, if we are actually in the clouds and about to draw both sides of the x sides too, then - // do a little offsetting here to avoid z fighting - if( draw[0] && draw[1] && draw[2] && draw[3] ) - { - glTranslatef(e, 0.0f, 0.0f ); - glCallList(cloudList + 2); - glTranslatef(-e, 0.0f, 0.0f ); - glCallList(cloudList + 3); - } - else - { - if( draw[2] ) glCallList(cloudList + 2); - if( draw[3] ) glCallList(cloudList + 3); - } - // For z facing sides, if we are actually in the clouds and about to draw both sides of the z sides too, then - // do a little offsetting here to avoid z fighting - if( draw[0] && draw[1] && draw[4] && draw[5] ) - { - glTranslatef(0.0f, 0.0f, e ); - glCallList(cloudList + 4); - glTranslatef(0.0f, 0.0f, -e ); - glCallList(cloudList + 5); - } - else - { - if( draw[4] ) glCallList(cloudList + 4); - if( draw[5] ) glCallList(cloudList + 5); - } - } - else - { - // Simpler form of rendering that we can do most of the time, when we aren't potentially inside a cloud - glCallList(cloudList + 6); - } - glPopMatrix(); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); + // Top and bottom just render when required + if (draw[0]) glCallList(cloudList); + if (draw[1]) glCallList(cloudList + 1); + // For x facing sides, if we are actually in the clouds and + // about to draw both sides of the x sides too, then do a + // little offsetting here to avoid z fighting + if (draw[0] && draw[1] && draw[2] && draw[3]) { + glTranslatef(e, 0.0f, 0.0f); + glCallList(cloudList + 2); + glTranslatef(-e, 0.0f, 0.0f); + glCallList(cloudList + 3); + } else { + if (draw[2]) glCallList(cloudList + 2); + if (draw[3]) glCallList(cloudList + 3); + } + // For z facing sides, if we are actually in the clouds and + // about to draw both sides of the z sides too, then do a + // little offsetting here to avoid z fighting + if (draw[0] && draw[1] && draw[4] && draw[5]) { + glTranslatef(0.0f, 0.0f, e); + glCallList(cloudList + 4); + glTranslatef(0.0f, 0.0f, -e); + glCallList(cloudList + 5); + } else { + if (draw[4]) glCallList(cloudList + 4); + if (draw[5]) glCallList(cloudList + 5); + } + } else { + // Simpler form of rendering that we can do most of the + // time, when we aren't potentially inside a cloud + glCallList(cloudList + 6); + } + glPopMatrix(); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); #else glDisable(GL_CULL_FACE); t->begin(); @@ -1930,7 +1926,7 @@ bool LevelRenderer::updateDirtyChunks() { static int throttle = 0; if( ( throttle % 100 ) == 0 ) { - app.DebugPrintf("CBuffSize: %d\n",memAlloc/(1024*1024)); + app.DebugPrintf("CBuffSize: %d\n",memAlloc/(1024*1024)); } throttle++; */ @@ -2048,7 +2044,7 @@ bool LevelRenderer::updateDirtyChunks() { for (int p = 0; p < XUSER_MAX_COUNT; p++) { // It's possible that the localplayers member can be set to NULL on // the main thread when a player chooses to exit the game So take a - // reference to the player object now. As it is a std::shared_ptr it + // reference to the player object now. As it is a shared_ptr it // should live as long as we need it std::shared_ptr player = mc->localplayers[p]; if (player == NULL) continue; @@ -2061,7 +2057,7 @@ bool LevelRenderer::updateDirtyChunks() { // app.DebugPrintf("!! %d %d %d, %d %d %d {%d,%d} //",px,py,pz,stackChunkDirty,nonStackChunkDirty,onlyRebuild, - //xChunks, zChunks); + // xChunks, zChunks); int considered = 0; int wouldBeNearButEmpty = 0; @@ -2242,9 +2238,10 @@ bool LevelRenderer::updateDirtyChunks() { if (bAtomic || (index == 0)) { // PIXBeginNamedEvent(0,"Rebuilding near chunk %d %d - // %d",chunk->x, chunk->y, chunk->z); static __int64 totalTime = - //0; static __int64 countTime = 0; - // __int64 startTime = System::currentTimeMillis(); + // %d",chunk->x, chunk->y, chunk->z); static int64_t + // totalTime = + // 0; static int64_t countTime = 0; + // int64_t startTime = System::currentTimeMillis(); // app.DebugPrintf("Rebuilding permaChunk %d\n", index); @@ -2256,7 +2253,7 @@ bool LevelRenderer::updateDirtyChunks() { // thread instead, mark the thread it // should have been running on as complete - // __int64 endTime = System::currentTimeMillis(); + // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; // printf("%d : %f\n", countTime, (float)totalTime @@ -2299,11 +2296,11 @@ bool LevelRenderer::updateDirtyChunks() { static Chunk permaChunk; permaChunk.makeCopyForRebuild(chunk); LeaveCriticalSection(&m_csDirtyChunks); - // static __int64 totalTime = 0; - // static __int64 countTime = 0; - // __int64 startTime = System::currentTimeMillis(); + // static int64_t totalTime = 0; + // static int64_t countTime = 0; + // int64_t startTime = System::currentTimeMillis(); permaChunk.rebuild(); - // __int64 endTime = System::currentTimeMillis(); + // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; // printf("%d : %f\n", countTime, (float)totalTime / @@ -2376,7 +2373,7 @@ void LevelRenderer::renderHit(std::shared_ptr player, HitResult* h, br, br, br, (Mth::sin(Minecraft::currentTimeMillis() / 200.0f) * 0.2f + 0.5f)); - textures->bindTexture(TN_TERRAIN); // L"/terrain.png"); + textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); } glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); @@ -2393,7 +2390,7 @@ void LevelRenderer::renderDestroyAnimation(Tesselator* t, if (!destroyingBlocks.empty()) { glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); - textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" + textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); glColor4f(1, 1, 1, 0.5f); glPushMatrix(); @@ -2430,7 +2427,7 @@ void LevelRenderer::renderDestroyAnimation(Tesselator* t, int tileId = level[iPad]->getTile(block->getX(), block->getY(), block->getZ()); Tile* tile = tileId > 0 ? Tile::tiles[tileId] : NULL; - if (tile == NULL) tile = Tile::rock; + if (tile == NULL) tile = Tile::stone; tileRenderer[iPad]->tesselateInWorldFixedTexture( tile, block->getX(), block->getY(), block->getZ(), breakingTextures @@ -2456,9 +2453,8 @@ void LevelRenderer::renderDestroyAnimation(Tesselator* t, } } -void LevelRenderer::renderHitOutline( - std::shared_ptr player, HitResult* h, int mode, - std::shared_ptr inventoryItem, float a) { +void LevelRenderer::renderHitOutline(std::shared_ptr player, + HitResult* h, int mode, float a) { if (mode == 0 && h->type == HitResult::TILE) { int iPad = mc->player->GetXboxPad(); // 4J added @@ -2540,7 +2536,7 @@ void LevelRenderer::setDirty(int x0, int y0, int z0, int x1, int y1, int z1, for (int y = _y0; y <= _y1; y++) { for (int z = _z0; z <= _z1; z++) { // printf("Setting %d %d %d - //dirty\n",x,y,z); + // dirty\n",x,y,z); int index = getGlobalIndexForChunk(x * 16, y * 16, z * 16, level); // Rather than setting the flags directly, add any dirty chunks @@ -2619,7 +2615,7 @@ void LevelRenderer::setDirty(int x0, int y0, int z0, int x1, int y1, int z1, #endif } // setGlobalChunkFlag(x * 16, y * - //16, z * 16, level, CHUNK_FLAG_DIRTY); + // 16, z * 16, level, CHUNK_FLAG_DIRTY); } } } @@ -2847,11 +2843,16 @@ void LevelRenderer::playSound(std::shared_ptr entity, int iSound, double x, double y, double z, float volume, float pitch, float fSoundClipDist) {} +void LevelRenderer::playSoundExceptPlayer(std::shared_ptr player, + int iSound, double x, double y, + double z, float volume, float pitch, + float fSoundClipDist) {} + // 4J-PB - original function. I've changed to an enum instead of string compares // 4J removed - /* -void LevelRenderer::addParticle(const std::wstring& name, double x, double y, -double z, double xa, double ya, double za) +void LevelRenderer::addParticle(const wstring& name, double x, double y, double +z, double xa, double ya, double za) { if (mc == NULL || mc->cameraTargetPlayer == NULL || mc->particleEngine == NULL) return; @@ -2865,37 +2866,36 @@ if (xd * xd + yd * yd + zd * zd > particleDistance * particleDistance) return; int playerIndex = mc->player->GetXboxPad(); // 4J added -if (name== L"bubble") mc->particleEngine->add(std::shared_ptr( -new BubbleParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"smoke") mc->particleEngine->add(std::shared_ptr( new +if (name== L"bubble") mc->particleEngine->add(shared_ptr( new +BubbleParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== +L"smoke") mc->particleEngine->add(shared_ptr( new SmokeParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"note") mc->particleEngine->add(std::shared_ptr( new +L"note") mc->particleEngine->add(shared_ptr( new NoteParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"portal") mc->particleEngine->add(std::shared_ptr( new +L"portal") mc->particleEngine->add(shared_ptr( new PortalParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"explode") mc->particleEngine->add(std::shared_ptr( new +L"explode") mc->particleEngine->add(shared_ptr( new ExplodeParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"flame") mc->particleEngine->add(std::shared_ptr( new +L"flame") mc->particleEngine->add(shared_ptr( new FlameParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"lava") mc->particleEngine->add(std::shared_ptr( new +L"lava") mc->particleEngine->add(shared_ptr( new LavaParticle(level[playerIndex], x, y, z) ) ); else if (name== L"footstep") -mc->particleEngine->add(std::shared_ptr( new +mc->particleEngine->add(shared_ptr( new FootstepParticle(textures, level[playerIndex], x, y, z) ) ); else if (name== -L"splash") mc->particleEngine->add(std::shared_ptr( new +L"splash") mc->particleEngine->add(shared_ptr( new SplashParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"largesmoke") mc->particleEngine->add(std::shared_ptr( new +L"largesmoke") mc->particleEngine->add(shared_ptr( new SmokeParticle(level[playerIndex], x, y, z, xa, ya, za, 2.5f) ) ); else if -(name== L"reddust") mc->particleEngine->add(std::shared_ptr( -new RedDustParticle(level[playerIndex], x, y, z, (float) xa, (float) ya, (float) -za) ) ); else if (name== L"snowballpoof") -mc->particleEngine->add(std::shared_ptr( new +(name== L"reddust") mc->particleEngine->add(shared_ptr( new +RedDustParticle(level[playerIndex], x, y, z, (float) xa, (float) ya, (float) za) +) ); else if (name== L"snowballpoof") +mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::snowBall) ) ); else if -(name== L"snowshovel") -mc->particleEngine->add(std::shared_ptr( new -SnowShovelParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if (name== -L"slime") mc->particleEngine->add(std::shared_ptr( new +(name== L"snowshovel") mc->particleEngine->add(shared_ptr( +new SnowShovelParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); else if +(name== L"slime") mc->particleEngine->add(shared_ptr( new BreakingItemParticle(level[playerIndex], x, y, z, Item::slimeBall)) ) ; else if -(name== L"heart") mc->particleEngine->add(std::shared_ptr( new +(name== L"heart") mc->particleEngine->add(shared_ptr( new HeartParticle(level[playerIndex], x, y, z, xa, ya, za) ) ); } */ @@ -2998,6 +2998,12 @@ std::shared_ptr LevelRenderer::addParticleInternal( particle = std::shared_ptr( new HugeExplosionParticle(textures, lev, x, y, z, xa, ya, za)); break; + case eParticleType_fireworksspark: + particle = std::shared_ptr( + new FireworksParticles::FireworksSparkParticle( + lev, x, y, z, xa, ya, za, mc->particleEngine)); + particle->setAlpha(0.99f); + break; case eParticleType_bubble: particle = std::shared_ptr( @@ -3079,10 +3085,25 @@ std::shared_ptr LevelRenderer::addParticleInternal( new SpellParticle(lev, x, y, z, 0, 0, 0)); particle->setColor((float)xa, (float)ya, (float)za); break; + case eParticleType_mobSpellAmbient: + particle = std::shared_ptr( + new SpellParticle(lev, x, y, z, 0, 0, 0)); + particle->setAlpha(0.15f); + particle->setColor((float)xa, (float)ya, (float)za); + break; case eParticleType_spell: particle = std::shared_ptr( new SpellParticle(lev, x, y, z, xa, ya, za)); break; + case eParticleType_witchMagic: { + particle = std::shared_ptr( + new SpellParticle(lev, x, y, z, xa, ya, za)); + std::dynamic_pointer_cast(particle)->setBaseTex(9 * + 16); + float randBrightness = lev->random->nextFloat() * 0.5f + 0.35f; + particle->setColor(1 * randBrightness, 0 * randBrightness, + 1 * randBrightness); + } break; case eParticleType_instantSpell: particle = std::shared_ptr( new SpellParticle(lev, x, y, z, xa, ya, za)); @@ -3200,44 +3221,33 @@ std::shared_ptr LevelRenderer::addParticleInternal( } void LevelRenderer::entityAdded(std::shared_ptr entity) { - entity->prepareCustomTextures(); - // 4J - these empty string comparisons used to check for NULL references, - // but we don't have string pointers (currently) in entities, hopefully this - // should be equivalent - /* 4J - removed temp */ - // if (entity->customTextureUrl != L"") - // textures->addHttpTexture(entity->customTextureUrl, new - // MobSkinTextureProcessor()); if (entity->customTextureUrl2 != L"") - // textures->addHttpTexture(entity->customTextureUrl2, new - // MobSkinTextureProcessor()); + if (entity->instanceof(eTYPE_PLAYER)) { + std::shared_ptr player = + std::dynamic_pointer_cast(entity); + player->prepareCustomTextures(); - // 4J-PB - adding these from global title storage - if (entity->customTextureUrl != L"") { - textures->addMemTexture(entity->customTextureUrl, - new MobSkinMemTextureProcessor()); + // 4J-PB - adding these from global title storage + if (player->customTextureUrl != L"") { + textures->addMemTexture(player->customTextureUrl, + new MobSkinMemTextureProcessor()); + } + if (player->customTextureUrl2 != L"") { + textures->addMemTexture(player->customTextureUrl2, + new MobSkinMemTextureProcessor()); + } } - if (entity->customTextureUrl2 != L"") { - textures->addMemTexture(entity->customTextureUrl2, - new MobSkinMemTextureProcessor()); - } - - // if (entity->customTextureUrl2 != L"") - // textures->addHttpTexture(entity->customTextureUrl2, new - // MobSkinTextureProcessor()); } void LevelRenderer::entityRemoved(std::shared_ptr entity) { - /* 4J - removed temp - if (entity->customTextureUrl != L"") - textures->removeHttpTexture(entity->customTextureUrl); if - (entity->customTextureUrl2 != L"") - textures->removeHttpTexture(entity->customTextureUrl2); - */ - if (entity->customTextureUrl != L"") { - textures->removeMemTexture(entity->customTextureUrl); - } - if (entity->customTextureUrl2 != L"") { - textures->removeMemTexture(entity->customTextureUrl2); + if (entity->instanceof(eTYPE_PLAYER)) { + std::shared_ptr player = + std::dynamic_pointer_cast(entity); + if (player->customTextureUrl != L"") { + textures->removeMemTexture(player->customTextureUrl); + } + if (player->customTextureUrl2 != L"") { + textures->removeMemTexture(player->customTextureUrl2); + } } } @@ -3258,6 +3268,46 @@ void LevelRenderer::skyColorChanged() { void LevelRenderer::clear() { MemoryTracker::releaseLists(chunkLists); } +void LevelRenderer::globalLevelEvent(int type, int sourceX, int sourceY, + int sourceZ, int data) { + Level* lev; + int playerIndex = mc->player->GetXboxPad(); // 4J added + lev = level[playerIndex]; + + Random* random = lev->random; + + switch (type) { + case LevelEvent::SOUND_WITHER_BOSS_SPAWN: + case LevelEvent::SOUND_DRAGON_DEATH: + if (mc->cameraTargetPlayer != NULL) { + // play the sound at an offset from the player + double dx = sourceX - mc->cameraTargetPlayer->x; + double dy = sourceY - mc->cameraTargetPlayer->y; + double dz = sourceZ - mc->cameraTargetPlayer->z; + + double len = sqrt(dx * dx + dy * dy + dz * dz); + double sx = mc->cameraTargetPlayer->x; + double sy = mc->cameraTargetPlayer->y; + double sz = mc->cameraTargetPlayer->z; + + if (len > 0) { + sx += dx / len * 2; + sy += dy / len * 2; + sz += dz / len * 2; + } + if (type == LevelEvent::SOUND_WITHER_BOSS_SPAWN) { + lev->playLocalSound(sx, sy, sz, eSoundType_MOB_WITHER_SPAWN, + 1.0f, 1.0f, false); + } else if (type == LevelEvent::SOUND_DRAGON_DEATH) { + lev->playLocalSound(sx, sy, sz, + eSoundType_MOB_ENDERDRAGON_END, 5.0f, + 1.0f, false); + } + } + break; + } +} + void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, int y, int z, int data) { int playerIndex = mc->player->GetXboxPad(); // 4J added @@ -3290,15 +3340,15 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, // level[playerIndex]->playSound(x, y, z, // L"random.click", 1.0f, 1.2f); level[playerIndex]->playLocalSound(x, y, z, eSoundType_RANDOM_CLICK, - 1.0f, 1.2f); + 1.0f, 1.2f, false); break; case LevelEvent::SOUND_CLICK: level[playerIndex]->playLocalSound(x, y, z, eSoundType_RANDOM_CLICK, - 1.0f, 1.0f); + 1.0f, 1.0f, false); break; case LevelEvent::SOUND_LAUNCH: level[playerIndex]->playLocalSound(x, y, z, eSoundType_RANDOM_BOW, - 1.0f, 1.2f); + 1.0f, 1.2f, false); break; case LevelEvent::PARTICLES_SHOOT: { int xd = (data % 3) - 1; @@ -3345,7 +3395,8 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, double yp = y; double zp = z; - ePARTICLE_TYPE particle = PARTICLE_ICONCRACK(Item::potion->id, 0); + ePARTICLE_TYPE particle = + PARTICLE_ICONCRACK(Item::potion->id, data); for (int i = 0; i < 8; i++) { addParticle(particle, xp, yp, zp, random->nextGaussian() * 0.15, random->nextDouble() * 0.2, @@ -3383,7 +3434,7 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, } level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_GLASS, 1, - level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, false); } break; case LevelEvent::ENDERDRAGON_FIREBALL_SPLASH: { double xp = x; @@ -3442,38 +3493,45 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, } break; } + case LevelEvent::PARTICLES_PLANT_GROWTH: + DyePowderItem::addGrowthParticles(level[playerIndex], x, y, z, + data); + break; case LevelEvent::SOUND_OPEN_DOOR: if (Math::random() < 0.5) { level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_DOOR_OPEN, - 1.0f, - level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + 1.0f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, + false); } else { level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_RANDOM_DOOR_CLOSE, - 1.0f, - level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + 1.0f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, + false); } break; case LevelEvent::SOUND_FIZZ: level[playerIndex]->playLocalSound( x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_FIZZ, 0.5f, - 2.6f + (random->nextFloat() - random->nextFloat()) * 0.8f); + 2.6f + (random->nextFloat() - random->nextFloat()) * 0.8f, + false); break; case LevelEvent::SOUND_ANVIL_BROKEN: level[playerIndex]->playLocalSound( x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_ANVIL_BREAK, - 1.0f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + 1.0f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, + false); break; case LevelEvent::SOUND_ANVIL_USED: level[playerIndex]->playLocalSound( x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_ANVIL_USE, 1.0f, - level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, false); break; case LevelEvent::SOUND_ANVIL_LAND: level[playerIndex]->playLocalSound( x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_ANVIL_LAND, - 0.3f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f); + 0.3f, level[playerIndex]->random->nextFloat() * 0.1f + 0.9f, + false); break; case LevelEvent::SOUND_PLAY_RECORDING: { RecordingItem* rci = @@ -3497,13 +3555,13 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_GHAST_CHARGE, 2.0f, (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f, - 80.0f); + false, 80.0f); break; case LevelEvent::SOUND_GHAST_FIREBALL: level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_GHAST_FIREBALL, 2.0f, (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f, - 80.0f); + false, 80.0f); break; case LevelEvent::SOUND_ZOMBIE_WOODEN_DOOR: level[playerIndex]->playLocalSound( @@ -3521,6 +3579,18 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_ZOMBIE_METAL, 2.0f, (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); break; + case LevelEvent::SOUND_BLAZE_FIREBALL: + level[playerIndex]->playLocalSound( + x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_GHAST_FIREBALL, 2, + (random->nextFloat() - random->nextFloat()) * 0.2f + + 1.0f); //, false); + break; + case LevelEvent::SOUND_WITHER_BOSS_SHOOT: + level[playerIndex]->playLocalSound( + x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_WITHER_SHOOT, 2, + (random->nextFloat() - random->nextFloat()) * 0.2f + + 1.0f); //, false); + break; case LevelEvent::SOUND_ZOMBIE_INFECTED: level[playerIndex]->playLocalSound( x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_ZOMBIE_INFECT, 2.0f, @@ -3541,6 +3611,11 @@ void LevelRenderer::levelEvent(std::shared_ptr source, int type, int x, EggTile::generateTeleportParticles(level[playerIndex], x, y, z, data); break; + case LevelEvent::SOUND_BAT_LIFTOFF: + level[playerIndex]->playLocalSound( + x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_BAT_TAKEOFF, .05f, + (random->nextFloat() - random->nextFloat()) * 0.2f + 1.0f); + break; } } @@ -3973,9 +4048,7 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { int index = (int)(uintptr_t)lpParam; - while (true) - - { + while (true) { s_activationEventA[index]->WaitForSignal(INFINITE); // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); @@ -3996,3 +4069,38 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { void LevelRenderer::nonStackDirtyChunksAdded() { dirtyChunksLockFreeStack.Push((int*)1); } + +// 4J - for test purposes, check all chunks that are currently present for the +// player. Currently this is implemented to do tests to identify missing client +// chunks in flat worlds, but this could be extended to do other kinds of +// automated testing. Returns the number of chunks that are present, so that +// from the calling function we can determine when chunks have finished +// loading/generating round the current location. +int LevelRenderer::checkAllPresentChunks(bool* faultFound) { + int playerIndex = mc->player->GetXboxPad(); // 4J added + + int presentCount = 0; + ClipChunk* pClipChunk = chunks[playerIndex].data; + for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { + if (pClipChunk->chunk->y == 0) { + bool chunkPresent = level[0]->reallyHasChunk( + pClipChunk->chunk->x >> 4, pClipChunk->chunk->z >> 4); + if (chunkPresent) { + presentCount++; + LevelChunk* levelChunk = level[0]->getChunk( + pClipChunk->chunk->x >> 4, pClipChunk->chunk->z >> 4); + + for (int cx = 4; cx <= 12; cx++) { + for (int cz = 4; cz <= 12; cz++) { + int t0 = levelChunk->getTile(cx, 0, cz); + if ((t0 != Tile::unbreakable_Id) && + (t0 != Tile::dirt_Id)) { + *faultFound = true; + } + } + } + } + } + } + return presentCount; +} diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index da75e8345..1275ee4e8 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -39,6 +39,13 @@ class Tesselator; class LevelRenderer : public LevelListener { friend class Chunk; +private: + static ResourceLocation MOON_LOCATION; + static ResourceLocation MOON_PHASES_LOCATION; + static ResourceLocation SUN_LOCATION; + static ResourceLocation CLOUDS_LOCATION; + static ResourceLocation END_SKY_LOCATION; + public: static const int CHUNK_XZSIZE = 16; #ifdef _LARGE_WORLDS @@ -47,7 +54,7 @@ public: static const int CHUNK_SIZE = 16; #endif static const int CHUNK_Y_COUNT = Level::maxBuildHeight / CHUNK_SIZE; -#if defined _XBOX_ONE +#if (defined _XBOX_ONE || defined _WINDOWS64) static const int MAX_COMMANDBUFFER_ALLOCATIONS = 512 * 1024 * 1024; // 4J - added #elif defined __ORBIS__ @@ -86,7 +93,7 @@ private: void resortChunks(int xc, int yc, int zc); public: - int render(std::shared_ptr player, int layer, double alpha, + int render(std::shared_ptr player, int layer, double alpha, bool updateChunks); private: @@ -110,8 +117,7 @@ public: void renderDestroyAnimation(Tesselator* t, std::shared_ptr player, float a); void renderHitOutline(std::shared_ptr player, HitResult* h, - int mode, std::shared_ptr inventoryItem, - float a); + int mode, float a); void render(AABB* b); void setDirty(int x0, int y0, int z0, int x1, int y1, int z1, Level* level); // 4J - added level param @@ -134,6 +140,9 @@ public: void playSound(std::shared_ptr entity, int iSound, double x, double y, double z, float volume, float pitch, float fSoundClipDist = 16.0f); + void playSoundExceptPlayer(std::shared_ptr player, int iSound, + double x, double y, double z, float volume, + float pitch, float fSoundClipDist = 16.0f); void addParticle(ePARTICLE_TYPE eParticleType, double x, double y, double z, double xa, double ya, double za); // 4J added std::shared_ptr addParticleInternal(ePARTICLE_TYPE eParticleType, @@ -147,6 +156,8 @@ public: // not just the entity storage void skyColorChanged(); void clear(); + void globalLevelEvent(int type, int sourceX, int sourceY, int sourceZ, + int data); void levelEvent(std::shared_ptr source, int type, int x, int y, int z, int data); void destroyTileProgress(int id, int x, int y, int z, int progress); @@ -317,7 +328,7 @@ public: XLockFreeStack dirtyChunksLockFreeStack; bool dirtyChunkPresent; - __int64 lastDirtyChunkFound; + int64_t lastDirtyChunkFound; static const int FORCE_DIRTY_CHUNK_CHECK_PERIOD_MS = 250; #ifdef _LARGE_WORLDS @@ -334,4 +345,6 @@ public: CRITICAL_SECTION m_csChunkFlags; #endif void nonStackDirtyChunksAdded(); + + int checkAllPresentChunks(bool* faultFound); // 4J - added for testing }; diff --git a/Minecraft.Client/Rendering/Models/BatModel.cpp b/Minecraft.Client/Rendering/Models/BatModel.cpp new file mode 100644 index 000000000..49c8f6d36 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/BatModel.cpp @@ -0,0 +1,102 @@ +#include "../../Platform/stdafx.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.ambient.h" +#include "BatModel.h" +#include "ModelPart.h" + +BatModel::BatModel() : Model() { + texWidth = 64; + texHeight = 64; + + head = new ModelPart(this, 0, 0); + head->addBox(-3, -3, -3, 6, 6, 6); + + ModelPart* rightEar = new ModelPart(this, 24, 0); + rightEar->addBox(-4, -6, -2, 3, 4, 1); + head->addChild(rightEar); + ModelPart* leftEar = new ModelPart(this, 24, 0); + leftEar->bMirror = true; + leftEar->addBox(1, -6, -2, 3, 4, 1); + head->addChild(leftEar); + + body = new ModelPart(this, 0, 16); + body->addBox(-3, 4, -3, 6, 12, 6); + body->texOffs(0, 34)->addBox(-5, 16, 0, 10, 6, 1); + + rightWing = new ModelPart(this, 42, 0); + rightWing->addBox(-12, 1, 1.5f, 10, 16, 1); + rightWingTip = new ModelPart(this, 24, 16); + rightWingTip->setPos(-12, 1, 1.5f); + rightWingTip->addBox(-8, 1, 0, 8, 12, 1); + + leftWing = new ModelPart(this, 42, 0); + leftWing->bMirror = true; + leftWing->addBox(2, 1, 1.5f, 10, 16, 1); + leftWingTip = new ModelPart(this, 24, 16); + leftWingTip->bMirror = true; + leftWingTip->setPos(12, 1, 1.5f); + leftWingTip->addBox(0, 1, 0, 8, 12, 1); + + body->addChild(rightWing); + body->addChild(leftWing); + rightWing->addChild(rightWingTip); + leftWing->addChild(leftWingTip); + + // 4J added - compile now to avoid random performance hit first time cubes + // are rendered 4J Stu - Not just performance, but alpha+depth tests don't + // work right unless we compile here + head->compile(1.0f / 16.0f); + body->compile(1.0f / 16.0f); + rightWing->compile(1.0f / 16.0f); + leftWing->compile(1.0f / 16.0f); + rightWingTip->compile(1.0f / 16.0f); + leftWingTip->compile(1.0f / 16.0f); + rightEar->compile(1.0f / 16.0f); + leftEar->compile(1.0f / 16.0f); +} + +int BatModel::modelVersion() { return 36; } + +void BatModel::render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled) { + std::shared_ptr bat = std::dynamic_pointer_cast(entity); + if (bat->isResting()) { + float rad = 180 / PI; + head->xRot = xRot / rad; + head->yRot = PI - yRot / rad; + head->zRot = PI; + + head->setPos(0, -2, 0); + rightWing->setPos(-3, 0, 3); + leftWing->setPos(3, 0, 3); + + body->xRot = PI; + + rightWing->xRot = -PI * .05f; + rightWing->yRot = -PI * .40f; + rightWingTip->yRot = -PI * .55f; + leftWing->xRot = rightWing->xRot; + leftWing->yRot = -rightWing->yRot; + leftWingTip->yRot = -rightWingTip->yRot; + } else { + float rad = 180 / PI; + head->xRot = xRot / rad; + head->yRot = yRot / rad; + head->zRot = 0; + + head->setPos(0, 0, 0); + rightWing->setPos(0, 0, 0); + leftWing->setPos(0, 0, 0); + + body->xRot = PI * .25f + cos(bob * .1f) * .15f; + body->yRot = 0; + + rightWing->yRot = cos(bob * 1.3f) * PI * .25f; + leftWing->yRot = -rightWing->yRot; + rightWingTip->yRot = rightWing->yRot * .5f; + leftWingTip->yRot = -rightWing->yRot * .5f; + } + + head->render(scale, usecompiled); + body->render(scale, usecompiled); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/BatModel.h b/Minecraft.Client/Rendering/Models/BatModel.h new file mode 100644 index 000000000..e4c381147 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/BatModel.h @@ -0,0 +1,21 @@ +#pragma once +#include "Model.h" + +class BatModel : public Model { +private: + ModelPart* head; + ModelPart* body; + ModelPart* rightWing; + ModelPart* leftWing; + ModelPart* rightWingTip; + ModelPart* leftWingTip; + +public: + BatModel(); + + int modelVersion(); + + virtual void render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/BlazeModel.cpp b/Minecraft.Client/Rendering/Models/BlazeModel.cpp index 8fbb67e04..c584ae2ba 100644 --- a/Minecraft.Client/Rendering/Models/BlazeModel.cpp +++ b/Minecraft.Client/Rendering/Models/BlazeModel.cpp @@ -28,7 +28,7 @@ int BlazeModel::modelVersion() { return 8; } void BlazeModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); for (unsigned int i = 0; i < upperBodyParts.length; i++) { @@ -38,6 +38,7 @@ void BlazeModel::render(std::shared_ptr entity, float time, float r, void BlazeModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { float angle = bob * PI * -.1f; for (int i = 0; i < 4; i++) { diff --git a/Minecraft.Client/Rendering/Models/BlazeModel.h b/Minecraft.Client/Rendering/Models/BlazeModel.h index 3abf74199..f6c689c98 100644 --- a/Minecraft.Client/Rendering/Models/BlazeModel.h +++ b/Minecraft.Client/Rendering/Models/BlazeModel.h @@ -14,5 +14,6 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; diff --git a/Minecraft.Client/Rendering/Models/BookModel.cpp b/Minecraft.Client/Rendering/Models/BookModel.cpp index b5b522eef..47af3bb83 100644 --- a/Minecraft.Client/Rendering/Models/BookModel.cpp +++ b/Minecraft.Client/Rendering/Models/BookModel.cpp @@ -46,7 +46,7 @@ BookModel::BookModel() { void BookModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); leftLid->render(scale, usecompiled); rightLid->render(scale, usecompiled); @@ -61,6 +61,7 @@ void BookModel::render(std::shared_ptr entity, float time, float r, void BookModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { float openness = (Mth::sin(time * 0.02f) * 0.10f + 1.25f) * yRot; diff --git a/Minecraft.Client/Rendering/Models/BookModel.h b/Minecraft.Client/Rendering/Models/BookModel.h index 152c9fec8..cef02230a 100644 --- a/Minecraft.Client/Rendering/Models/BookModel.h +++ b/Minecraft.Client/Rendering/Models/BookModel.h @@ -15,5 +15,6 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; diff --git a/Minecraft.Client/Rendering/Models/ChickenModel.cpp b/Minecraft.Client/Rendering/Models/ChickenModel.cpp index b75d80319..e3c2e6ccd 100644 --- a/Minecraft.Client/Rendering/Models/ChickenModel.cpp +++ b/Minecraft.Client/Rendering/Models/ChickenModel.cpp @@ -52,7 +52,7 @@ ChickenModel::ChickenModel() : Model() { void ChickenModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); if (young) { float ss = 2; glPushMatrix(); @@ -84,6 +84,7 @@ void ChickenModel::render(std::shared_ptr entity, float time, float r, void ChickenModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->xRot = xRot / (float)(180 / PI); head->yRot = yRot / (float)(180 / PI); diff --git a/Minecraft.Client/Rendering/Models/ChickenModel.h b/Minecraft.Client/Rendering/Models/ChickenModel.h index 5b21368e6..7180802fe 100644 --- a/Minecraft.Client/Rendering/Models/ChickenModel.h +++ b/Minecraft.Client/Rendering/Models/ChickenModel.h @@ -12,5 +12,6 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; diff --git a/Minecraft.Client/Rendering/Models/CreeperModel.cpp b/Minecraft.Client/Rendering/Models/CreeperModel.cpp index a92685595..c8c970f2e 100644 --- a/Minecraft.Client/Rendering/Models/CreeperModel.cpp +++ b/Minecraft.Client/Rendering/Models/CreeperModel.cpp @@ -53,7 +53,7 @@ CreeperModel::CreeperModel(float g) : Model() { _init(g); } void CreeperModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); body->render(scale, usecompiled); @@ -65,6 +65,7 @@ void CreeperModel::render(std::shared_ptr entity, float time, float r, void CreeperModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->yRot = yRot / (float)(180 / PI); head->xRot = xRot / (float)(180 / PI); diff --git a/Minecraft.Client/Rendering/Models/CreeperModel.h b/Minecraft.Client/Rendering/Models/CreeperModel.h index cb5843522..9c119e2fa 100644 --- a/Minecraft.Client/Rendering/Models/CreeperModel.h +++ b/Minecraft.Client/Rendering/Models/CreeperModel.h @@ -13,5 +13,6 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/DragonModel.cpp b/Minecraft.Client/Rendering/Models/DragonModel.cpp index 59ec47a5d..51eebc1b0 100644 --- a/Minecraft.Client/Rendering/Models/DragonModel.cpp +++ b/Minecraft.Client/Rendering/Models/DragonModel.cpp @@ -106,8 +106,8 @@ DragonModel::DragonModel(float g) : Model() { rearFoot->compile(1.0f / 16.0f); } -void DragonModel::prepareMobModel(std::shared_ptr mob, float time, float r, - float a) { +void DragonModel::prepareMobModel(std::shared_ptr mob, float time, + float r, float a) { this->a = a; } diff --git a/Minecraft.Client/Rendering/Models/DragonModel.h b/Minecraft.Client/Rendering/Models/DragonModel.h index e52112e80..0dd52f588 100644 --- a/Minecraft.Client/Rendering/Models/DragonModel.h +++ b/Minecraft.Client/Rendering/Models/DragonModel.h @@ -24,7 +24,7 @@ private: public: ModelPart* cubes[5]; DragonModel(float g); - void prepareMobModel(std::shared_ptr mob, float time, float r, + void prepareMobModel(std::shared_ptr mob, float time, float r, float a); virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, diff --git a/Minecraft.Client/Rendering/Models/EnderManModel.cpp b/Minecraft.Client/Rendering/Models/EnderManModel.cpp index 377f0a874..0e0d5f25b 100644 --- a/Minecraft.Client/Rendering/Models/EnderManModel.cpp +++ b/Minecraft.Client/Rendering/Models/EnderManModel.cpp @@ -53,8 +53,9 @@ EndermanModel::EndermanModel() : HumanoidModel(0, -14, 64, 32) { void EndermanModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, + HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, entity, uiBitmaskOverrideAnim); head->visible = true; diff --git a/Minecraft.Client/Rendering/Models/EnderManModel.h b/Minecraft.Client/Rendering/Models/EnderManModel.h index a1a8ebce6..d02431a6e 100644 --- a/Minecraft.Client/Rendering/Models/EnderManModel.h +++ b/Minecraft.Client/Rendering/Models/EnderManModel.h @@ -10,5 +10,6 @@ public: EndermanModel(); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/GhastModel.cpp b/Minecraft.Client/Rendering/Models/GhastModel.cpp index 5f8f70153..252f7ca3c 100644 --- a/Minecraft.Client/Rendering/Models/GhastModel.cpp +++ b/Minecraft.Client/Rendering/Models/GhastModel.cpp @@ -35,6 +35,7 @@ GhastModel::GhastModel() : Model() { void GhastModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { for (int i = 0; i < TENTACLESLENGTH; i++) // 4J - 9 was tentacles.length { @@ -45,7 +46,7 @@ void GhastModel::setupAnim(float time, float r, float bob, float yRot, void GhastModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); glPushMatrix(); glTranslatef(0, .6f, 0); diff --git a/Minecraft.Client/Rendering/Models/GhastModel.h b/Minecraft.Client/Rendering/Models/GhastModel.h index 610152766..64aca2e46 100644 --- a/Minecraft.Client/Rendering/Models/GhastModel.h +++ b/Minecraft.Client/Rendering/Models/GhastModel.h @@ -10,6 +10,7 @@ public: GhastModel(); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, diff --git a/Minecraft.Client/Rendering/Models/HumanoidModel.cpp b/Minecraft.Client/Rendering/Models/HumanoidModel.cpp index ef4d78f95..39dbb0610 100644 --- a/Minecraft.Client/Rendering/Models/HumanoidModel.cpp +++ b/Minecraft.Client/Rendering/Models/HumanoidModel.cpp @@ -28,9 +28,6 @@ ModelPart* HumanoidModel::AddOrRetrievePart(SKIN_BOX* pBox) { case eBodyPart_Leg1: pAttachTo = leg1; break; - case eBodyPart_Unknown: - default: - return NULL; } // first check this box doesn't already exist @@ -146,7 +143,7 @@ void HumanoidModel::render(std::shared_ptr entity, float time, float r, m_uiAnimOverrideBitmask = entity->getAnimOverrideBitmask(); } - setupAnim(time, r, bob, yRot, xRot, scale, m_uiAnimOverrideBitmask); + setupAnim(time, r, bob, yRot, xRot, scale, entity, m_uiAnimOverrideBitmask); if (young) { float ss = 2.0f; @@ -192,6 +189,7 @@ void HumanoidModel::render(std::shared_ptr entity, float time, float r, void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { // bool bIsAttacking = (attackTime > -9990.0f); @@ -200,6 +198,7 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, head->xRot = xRot / (float)(180.0f / PI); hair->yRot = head->yRot; hair->xRot = head->xRot; + body->z = 0.0f; // Does the skin have an override for anim? @@ -244,12 +243,19 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, leg1->yRot = 0.0f; if (riding) { - arm0->xRot += -HALF_PI * 0.4f; - arm1->xRot += -HALF_PI * 0.4f; - leg0->xRot = -HALF_PI * 0.8f; - leg1->xRot = -HALF_PI * 0.8f; - leg0->yRot = HALF_PI * 0.2f; - leg1->yRot = -HALF_PI * 0.2f; + if (uiBitmaskOverrideAnim & (1 << eAnim_SmallModel) == 0) { + arm0->xRot += -HALF_PI * 0.4f; + arm1->xRot += -HALF_PI * 0.4f; + leg0->xRot = -HALF_PI * 0.8f; + leg1->xRot = -HALF_PI * 0.8f; + leg0->yRot = HALF_PI * 0.2f; + leg1->yRot = -HALF_PI * 0.2f; + } else { + arm0->xRot += -HALF_PI * 0.4f; + arm1->xRot += -HALF_PI * 0.4f; + leg0->xRot = -HALF_PI * 0.4f; + leg1->xRot = -HALF_PI * 0.4f; + } } else if (idle && !sneaking) { leg0->xRot = -HALF_PI; leg1->xRot = -HALF_PI; @@ -328,22 +334,42 @@ void HumanoidModel::setupAnim(float time, float r, float bob, float yRot, } if (sneaking) { - body->xRot = 0.5f; - leg0->xRot -= 0.0f; - leg1->xRot -= 0.0f; - arm0->xRot += 0.4f; - arm1->xRot += 0.4f; - leg0->z = +4.0f; - leg1->z = +4.0f; - body->y = 0.0f; - arm0->y = 2.0f; - arm1->y = 2.0f; - leg0->y = +9.0f; - leg1->y = +9.0f; - head->y = +1.0f; - hair->y = +1.0f; - ear->y = +1.0f; - cloak->y = 0.0f; + if (uiBitmaskOverrideAnim & (1 << eAnim_SmallModel)) { + body->xRot = -0.5f; + leg0->xRot -= 0.0f; + leg1->xRot -= 0.0f; + arm0->xRot += 0.4f; + arm1->xRot += 0.4f; + leg0->z = -4.0f; + leg1->z = -4.0f; + body->z = 2.0f; + body->y = 0.0f; + arm0->y = 2.0f; + arm1->y = 2.0f; + leg0->y = +9.0f; + leg1->y = +9.0f; + head->y = +1.0f; + hair->y = +1.0f; + ear->y = +1.0f; + cloak->y = 0.0f; + } else { + body->xRot = 0.5f; + leg0->xRot -= 0.0f; + leg1->xRot -= 0.0f; + arm0->xRot += 0.4f; + arm1->xRot += 0.4f; + leg0->z = +4.0f; + leg1->z = +4.0f; + body->y = 0.0f; + arm0->y = 2.0f; + arm1->y = 2.0f; + leg0->y = +9.0f; + leg1->y = +9.0f; + head->y = +1.0f; + hair->y = +1.0f; + ear->y = +1.0f; + cloak->y = 0.0f; + } } else { body->xRot = 0.0f; leg0->z = 0.1f; diff --git a/Minecraft.Client/Rendering/Models/HumanoidModel.h b/Minecraft.Client/Rendering/Models/HumanoidModel.h index 3eb256b77..3d5c06fb8 100644 --- a/Minecraft.Client/Rendering/Models/HumanoidModel.h +++ b/Minecraft.Client/Rendering/Models/HumanoidModel.h @@ -35,7 +35,8 @@ public: eAnim_DisableRenderTorso, eAnim_DisableRenderLeg0, eAnim_DisableRenderLeg1, - eAnim_DisableRenderHair + eAnim_DisableRenderHair, + eAnim_SmallModel // Maggie Simpson for riding horse, etc }; @@ -58,6 +59,7 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); void renderHair(float scale, bool usecompiled); void renderEars(float scale, bool usecompiled); diff --git a/Minecraft.Client/Rendering/Models/LavaSlimeModel.cpp b/Minecraft.Client/Rendering/Models/LavaSlimeModel.cpp index 67d423b62..cf91175ee 100644 --- a/Minecraft.Client/Rendering/Models/LavaSlimeModel.cpp +++ b/Minecraft.Client/Rendering/Models/LavaSlimeModel.cpp @@ -32,8 +32,8 @@ LavaSlimeModel::LavaSlimeModel() { int LavaSlimeModel::getModelVersion() { return 5; } -void LavaSlimeModel::prepareMobModel(std::shared_ptr mob, float time, - float r, float a) { +void LavaSlimeModel::prepareMobModel(std::shared_ptr mob, + float time, float r, float a) { std::shared_ptr lavaSlime = std::dynamic_pointer_cast(mob); @@ -51,7 +51,7 @@ void LavaSlimeModel::prepareMobModel(std::shared_ptr mob, float time, void LavaSlimeModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); insideCube->render(scale, usecompiled); for (int i = 0; i < BODYCUBESLENGTH; i++) { diff --git a/Minecraft.Client/Rendering/Models/LavaSlimeModel.h b/Minecraft.Client/Rendering/Models/LavaSlimeModel.h index 4f9f8ef07..ef15cc39b 100644 --- a/Minecraft.Client/Rendering/Models/LavaSlimeModel.h +++ b/Minecraft.Client/Rendering/Models/LavaSlimeModel.h @@ -9,8 +9,8 @@ class LavaSlimeModel : public Model { public: LavaSlimeModel(); int getModelVersion(); - virtual void prepareMobModel(std::shared_ptr mob, float time, float r, - float a); + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a); virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); diff --git a/Minecraft.Client/Rendering/Models/LeashKnotModel.cpp b/Minecraft.Client/Rendering/Models/LeashKnotModel.cpp new file mode 100644 index 000000000..e94fc1695 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/LeashKnotModel.cpp @@ -0,0 +1,35 @@ +#include "../../Platform/stdafx.h"; +#include "LeashKnotModel.h" +#include "ModelPart.h" + +LeashKnotModel::LeashKnotModel() { _init(0, 0, 32, 32); } + +LeashKnotModel::LeashKnotModel(int u, int v, int tw, int th) { + _init(u, v, tw, th); +} + +void LeashKnotModel::_init(int u, int v, int tw, int th) { + texWidth = tw; + texHeight = th; + knot = new ModelPart(this, u, v); + knot->addBox(-3, -6, -3, 6, 8, 6, 0); + knot->setPos(0, 0, 0); +} + +void LeashKnotModel::render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled) { + setupAnim(time, r, bob, yRot, xRot, scale, entity); + + knot->render(scale, usecompiled); +} + +void LeashKnotModel::setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim) { + Model::setupAnim(time, r, bob, yRot, xRot, scale, entity); + + knot->yRot = yRot / (180 / PI); + knot->xRot = xRot / (180 / PI); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/LeashKnotModel.h b/Minecraft.Client/Rendering/Models/LeashKnotModel.h new file mode 100644 index 000000000..850ba7e1f --- /dev/null +++ b/Minecraft.Client/Rendering/Models/LeashKnotModel.h @@ -0,0 +1,19 @@ +#pragma once +#include "Model.h" + +class LeashKnotModel : public Model { +public: + ModelPart* knot; + + LeashKnotModel(); + LeashKnotModel(int u, int v, int tw, int th); + void _init(int u, int v, int tw, int th); + + virtual void render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled); + virtual void setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/Model.h b/Minecraft.Client/Rendering/Models/Model.h index f1cfc5f74..3bb2212cc 100644 --- a/Minecraft.Client/Rendering/Models/Model.h +++ b/Minecraft.Client/Rendering/Models/Model.h @@ -1,10 +1,11 @@ #pragma once #include "../../../Minecraft.World/Util/Random.h" -#include "SkinBox.h" +#include "../Minecraft.Client/SkinBox.h" class Mob; class ModelPart; class TexOffs; +class LivingEntity; class Model { public: @@ -17,16 +18,16 @@ public: int texHeight; Model(); // 4J added - virtual ~Model() {} virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) {} virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0) {} - virtual void prepareMobModel(std::shared_ptr mob, float time, float r, - float a) {} - virtual ModelPart* getRandomCube(Random random) { + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a) {} + virtual ModelPart* getRandomModelPart(Random random) { return cubes.at(random.nextInt((int)cubes.size())); } virtual ModelPart* AddOrRetrievePart(SKIN_BOX* pBox) { return NULL; } diff --git a/Minecraft.Client/Rendering/Models/ModelHorse.cpp b/Minecraft.Client/Rendering/Models/ModelHorse.cpp new file mode 100644 index 000000000..e71ccfd2a --- /dev/null +++ b/Minecraft.Client/Rendering/Models/ModelHorse.cpp @@ -0,0 +1,687 @@ +#include "../../Platform/stdafx.h" +#include "../../../Minecraft.World/Util/Mth.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" +#include "ModelHorse.h" +#include "ModelPart.h" + +ModelHorse::ModelHorse() { + texWidth = 128; + texHeight = 128; + + // TODO: All rotation magic numbers in this method + Body = new ModelPart(this, 0, 34); + Body->addBox(-5.f, -8.f, -19.f, 10, 10, 24); + Body->setPos(0.f, 11.f, 9.f); + + TailA = new ModelPart(this, 44, 0); + TailA->addBox(-1.f, -1.f, 0.f, 2, 2, 3); + TailA->setPos(0.f, 3.f, 14.f); + setRotation(TailA, -1.134464f, 0.f, 0.f); + + TailB = new ModelPart(this, 38, 7); + TailB->addBox(-1.5f, -2.f, 3.f, 3, 4, 7); + TailB->setPos(0.f, 3.f, 14.f); + setRotation(TailB, -1.134464f, 0.f, 0.f); + + TailC = new ModelPart(this, 24, 3); + TailC->addBox(-1.5f, -4.5f, 9.f, 3, 4, 7); + TailC->setPos(0.f, 3.f, 14.f); + setRotation(TailC, -1.40215f, 0.f, 0.f); + + Leg1A = new ModelPart(this, 78, 29); + Leg1A->addBox(-2.5f, -2.f, -2.5f, 4, 9, 5); + Leg1A->setPos(4.f, 9.f, 11.f); + + Leg1B = new ModelPart(this, 78, 43); + Leg1B->addBox(-2.f, 0.f, -1.5f, 3, 5, 3); + Leg1B->setPos(4.f, 16.f, 11.f); + + Leg1C = new ModelPart(this, 78, 51); + Leg1C->addBox(-2.5f, 5.1f, -2.f, 4, 3, 4); + Leg1C->setPos(4.f, 16.f, 11.f); + + Leg2A = new ModelPart(this, 96, 29); + Leg2A->addBox(-1.5f, -2.f, -2.5f, 4, 9, 5); + Leg2A->setPos(-4.f, 9.f, 11.f); + + Leg2B = new ModelPart(this, 96, 43); + Leg2B->addBox(-1.f, 0.f, -1.5f, 3, 5, 3); + Leg2B->setPos(-4.f, 16.f, 11.f); + + Leg2C = new ModelPart(this, 96, 51); + Leg2C->addBox(-1.5f, 5.1f, -2.f, 4, 3, 4); + Leg2C->setPos(-4.f, 16.f, 11.f); + + Leg3A = new ModelPart(this, 44, 29); + Leg3A->addBox(-1.9f, -1.f, -2.1f, 3, 8, 4); + Leg3A->setPos(4.f, 9.f, -8.f); + + Leg3B = new ModelPart(this, 44, 41); + Leg3B->addBox(-1.9f, 0.f, -1.6f, 3, 5, 3); + Leg3B->setPos(4.f, 16.f, -8.f); + + Leg3C = new ModelPart(this, 44, 51); + Leg3C->addBox(-2.4f, 5.1f, -2.1f, 4, 3, 4); + Leg3C->setPos(4.f, 16.f, -8.f); + + Leg4A = new ModelPart(this, 60, 29); + Leg4A->addBox(-1.1f, -1.f, -2.1f, 3, 8, 4); + Leg4A->setPos(-4.f, 9.f, -8.f); + + Leg4B = new ModelPart(this, 60, 41); + Leg4B->addBox(-1.1f, 0.f, -1.6f, 3, 5, 3); + Leg4B->setPos(-4.f, 16.f, -8.f); + + Leg4C = new ModelPart(this, 60, 51); + Leg4C->addBox(-1.6f, 5.1f, -2.1f, 4, 3, 4); + Leg4C->setPos(-4.f, 16.f, -8.f); + + Head = new ModelPart(this, 0, 0); + Head->addBox(-2.5f, -10.f, -1.5f, 5, 5, 7); + Head->setPos(0.f, 4.f, -10.f); + setRotation(Head, 0.5235988f, 0.f, 0.f); + + UMouth = new ModelPart(this, 24, 18); + UMouth->addBox(-2.f, -10.f, -7.f, 4, 3, 6); + UMouth->setPos(0.f, 3.95f, -10.f); + setRotation(UMouth, 0.5235988f, 0.f, 0.f); + + LMouth = new ModelPart(this, 24, 27); + LMouth->addBox(-2.f, -7.f, -6.5f, 4, 2, 5); + LMouth->setPos(0.f, 4.f, -10.f); + setRotation(LMouth, 0.5235988f, 0.f, 0.f); + + Head->addChild(UMouth); + Head->addChild(LMouth); + + Ear1 = new ModelPart(this, 0, 0); + Ear1->addBox(0.45f, -12.f, 4.f, 2, 3, 1); + Ear1->setPos(0.f, 4.f, -10.f); + setRotation(Ear1, 0.5235988f, 0.f, 0.f); + + Ear2 = new ModelPart(this, 0, 0); + Ear2->addBox(-2.45f, -12.f, 4.f, 2, 3, 1); + Ear2->setPos(0.f, 4.f, -10.f); + setRotation(Ear2, 0.5235988f, 0.f, 0.f); + + MuleEarL = new ModelPart(this, 0, 12); + MuleEarL->addBox(-2.f, -16.f, 4.f, 2, 7, 1); + MuleEarL->setPos(0.f, 4.f, -10.f); + setRotation(MuleEarL, 0.5235988f, 0.f, 0.2617994f); + + MuleEarR = new ModelPart(this, 0, 12); + MuleEarR->addBox(0.f, -16.f, 4.f, 2, 7, 1); + MuleEarR->setPos(0.f, 4.f, -10.f); + setRotation(MuleEarR, 0.5235988f, 0.f, -0.2617994f); + + Neck = new ModelPart(this, 0, 12); + Neck->addBox(-2.05f, -9.8f, -2.f, 4, 14, 8); + Neck->setPos(0.f, 4.f, -10.f); + setRotation(Neck, 0.5235988f, 0.f, 0.f); + + Bag1 = new ModelPart(this, 0, 34); + Bag1->addBox(-3.f, 0.f, 0.f, 8, 8, 3); + Bag1->setPos(-7.5f, 3.f, 10.f); + setRotation(Bag1, 0.f, 1.570796f, 0.f); + + Bag2 = new ModelPart(this, 0, 47); + Bag2->addBox(-3.f, 0.f, 0.f, 8, 8, 3); + Bag2->setPos(4.5f, 3.f, 10.f); + setRotation(Bag2, 0.f, 1.570796f, 0.f); + + Saddle = new ModelPart(this, 80, 0); + Saddle->addBox(-5.f, 0.f, -3.f, 10, 1, 8); + Saddle->setPos(0.f, 2.f, 2.f); + + SaddleB = new ModelPart(this, 106, 9); + SaddleB->addBox(-1.5f, -1.f, -3.f, 3, 1, 2); + SaddleB->setPos(0.f, 2.f, 2.f); + + SaddleC = new ModelPart(this, 80, 9); + SaddleC->addBox(-4.f, -1.f, 3.f, 8, 1, 2); + SaddleC->setPos(0.f, 2.f, 2.f); + + SaddleL2 = new ModelPart(this, 74, 0); + SaddleL2->addBox(-0.5f, 6.f, -1.f, 1, 2, 2); + SaddleL2->setPos(5.f, 3.f, 2.f); + + SaddleL = new ModelPart(this, 70, 0); + SaddleL->addBox(-0.5f, 0.f, -0.5f, 1, 6, 1); + SaddleL->setPos(5.f, 3.f, 2.f); + + SaddleR2 = new ModelPart(this, 74, 4); + SaddleR2->addBox(-0.5f, 6.f, -1.f, 1, 2, 2); + SaddleR2->setPos(-5.f, 3.f, 2.f); + + SaddleR = new ModelPart(this, 80, 0); + SaddleR->addBox(-0.5f, 0.f, -0.5f, 1, 6, 1); + SaddleR->setPos(-5.f, 3.f, 2.f); + + SaddleMouthL = new ModelPart(this, 74, 13); + SaddleMouthL->addBox(1.5f, -8.f, -4.f, 1, 2, 2); + SaddleMouthL->setPos(0.f, 4.f, -10.f); + setRotation(SaddleMouthL, 0.5235988f, 0.f, 0.f); + + SaddleMouthR = new ModelPart(this, 74, 13); + SaddleMouthR->addBox(-2.5f, -8.f, -4.f, 1, 2, 2); + SaddleMouthR->setPos(0.f, 4.f, -10.f); + setRotation(SaddleMouthR, 0.5235988f, 0.f, 0.f); + + SaddleMouthLine = new ModelPart(this, 44, 10); + SaddleMouthLine->addBox(2.6f, -6.f, -6.f, 0, 3, 16); + SaddleMouthLine->setPos(0.f, 4.f, -10.f); + + SaddleMouthLineR = new ModelPart(this, 44, 5); + SaddleMouthLineR->addBox(-2.6f, -6.f, -6.f, 0, 3, 16); + SaddleMouthLineR->setPos(0.f, 4.f, -10.f); + + Mane = new ModelPart(this, 58, 0); + Mane->addBox(-1.f, -11.5f, 5.f, 2, 16, 4); + Mane->setPos(0.f, 4.f, -10.f); + setRotation(Mane, 0.5235988f, 0.f, 0.f); + + HeadSaddle = new ModelPart(this, 80, 12); + HeadSaddle->addBox(-2.5f, -10.1f, -7.f, 5, 5, 12, 0.2f); + HeadSaddle->setPos(0.f, 4.f, -10.f); + setRotation(HeadSaddle, 0.5235988f, 0.f, 0.f); + + // 4J added - compile now to avoid random performance hit first time cubes + // are rendered + Head->compile(1.0f / 16.0f); + ; + UMouth->compile(1.0f / 16.0f); + ; + LMouth->compile(1.0f / 16.0f); + ; + Ear1->compile(1.0f / 16.0f); + ; + Ear2->compile(1.0f / 16.0f); + ; + MuleEarL->compile(1.0f / 16.0f); + ; + MuleEarR->compile(1.0f / 16.0f); + ; + Neck->compile(1.0f / 16.0f); + ; + HeadSaddle->compile(1.0f / 16.0f); + ; + Mane->compile(1.0f / 16.0f); + ; + + Body->compile(1.0f / 16.0f); + ; + TailA->compile(1.0f / 16.0f); + ; + TailB->compile(1.0f / 16.0f); + ; + TailC->compile(1.0f / 16.0f); + ; + + Leg1A->compile(1.0f / 16.0f); + ; + Leg1B->compile(1.0f / 16.0f); + ; + Leg1C->compile(1.0f / 16.0f); + ; + + Leg2A->compile(1.0f / 16.0f); + ; + Leg2B->compile(1.0f / 16.0f); + ; + Leg2C->compile(1.0f / 16.0f); + ; + + Leg3A->compile(1.0f / 16.0f); + ; + Leg3B->compile(1.0f / 16.0f); + ; + Leg3C->compile(1.0f / 16.0f); + ; + + Leg4A->compile(1.0f / 16.0f); + ; + Leg4B->compile(1.0f / 16.0f); + ; + Leg4C->compile(1.0f / 16.0f); + ; + + Bag1->compile(1.0f / 16.0f); + ; + Bag2->compile(1.0f / 16.0f); + ; + + Saddle->compile(1.0f / 16.0f); + ; + SaddleB->compile(1.0f / 16.0f); + ; + SaddleC->compile(1.0f / 16.0f); + ; + + SaddleL->compile(1.0f / 16.0f); + ; + SaddleL2->compile(1.0f / 16.0f); + ; + + SaddleR->compile(1.0f / 16.0f); + ; + SaddleR2->compile(1.0f / 16.0f); + ; + + SaddleMouthL->compile(1.0f / 16.0f); + ; + SaddleMouthR->compile(1.0f / 16.0f); + ; + + SaddleMouthLine->compile(1.0f / 16.0f); + ; + SaddleMouthLineR->compile(1.0f / 16.0f); + ; +} + +void ModelHorse::render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled) { + std::shared_ptr entityhorse = + std::dynamic_pointer_cast(entity); + + int type = entityhorse->getType(); + float eating = entityhorse->getEatAnim(0); + bool adult = (entityhorse->isAdult()); + bool saddled = adult && entityhorse->isSaddled(); + bool chested = adult && entityhorse->isChestedHorse(); + bool largeEars = + type == EntityHorse::TYPE_DONKEY || type == EntityHorse::TYPE_MULE; + float sizeFactor = entityhorse->getFoalScale(); + + bool rider = (entityhorse->rider.lock() != NULL); + + if (saddled) { + HeadSaddle->render(scale, usecompiled); + Saddle->render(scale, usecompiled); + SaddleB->render(scale, usecompiled); + SaddleC->render(scale, usecompiled); + SaddleL->render(scale, usecompiled); + SaddleL2->render(scale, usecompiled); + SaddleR->render(scale, usecompiled); + SaddleR2->render(scale, usecompiled); + SaddleMouthL->render(scale, usecompiled); + SaddleMouthR->render(scale, usecompiled); + + if (rider) { + SaddleMouthLine->render(scale, usecompiled); + SaddleMouthLineR->render(scale, usecompiled); + } + } + + // render legs + if (!adult) { + glPushMatrix(); + glScalef(sizeFactor, .5f + sizeFactor * .5f, sizeFactor); + glTranslatef(0, .95f * (1.0f - sizeFactor), 0); + } + Leg1A->render(scale, usecompiled); + Leg1B->render(scale, usecompiled); + Leg1C->render(scale, usecompiled); + + Leg2A->render(scale, usecompiled); + Leg2B->render(scale, usecompiled); + Leg2C->render(scale, usecompiled); + + Leg3A->render(scale, usecompiled); + Leg3B->render(scale, usecompiled); + Leg3C->render(scale, usecompiled); + + Leg4A->render(scale, usecompiled); + Leg4B->render(scale, usecompiled); + Leg4C->render(scale, usecompiled); + if (!adult) { + glPopMatrix(); + + glPushMatrix(); + glScalef(sizeFactor, sizeFactor, sizeFactor); + glTranslatef(0, 1.35f * (1.0f - sizeFactor), 0); + } + // render body + Body->render(scale, usecompiled); + TailA->render(scale, usecompiled); + TailB->render(scale, usecompiled); + TailC->render(scale, usecompiled); + Neck->render(scale, usecompiled); + Mane->render(scale, usecompiled); + if (!adult) { + glPopMatrix(); + + glPushMatrix(); + float headScale = .5f + (sizeFactor * sizeFactor) * .5f; + glScalef(headScale, headScale, headScale); + if (eating <= 0) { + glTranslatef(0, 1.35f * (1.0f - sizeFactor), 0); + } else { + glTranslatef(0, + .9f * (1.0f - sizeFactor) * eating + + (1.35f * (1.0f - sizeFactor)) * (1.0f - eating), + .15f * (1.0f - sizeFactor) * eating); + } + } + // render head + if (largeEars) { + MuleEarL->render(scale, usecompiled); + MuleEarR->render(scale, usecompiled); + } else { + Ear1->render(scale, usecompiled); + Ear2->render(scale, usecompiled); + } + Head->render(scale, usecompiled); + if (!adult) { + glPopMatrix(); + } + if (chested) { + Bag1->render(scale, usecompiled); + Bag2->render(scale, usecompiled); + } +} + +void ModelHorse::setRotation(ModelPart* model, float x, float y, float z) { + model->xRot = x; + model->yRot = y; + model->zRot = z; +} + +float ModelHorse::rotlerp(float from, float to, float a) { + float diff = to - from; + while (diff < -180) diff += 360; + while (diff >= 180) diff -= 360; + return from + a * diff; +} + +void ModelHorse::prepareMobModel(std::shared_ptr mob, float wp, + float ws, float a) { + Model::prepareMobModel(mob, wp, ws, a); + + float bodyRot = rotlerp(mob->yBodyRotO, mob->yBodyRot, a); + float headRot = rotlerp(mob->yHeadRotO, mob->yHeadRot, a); + float headRotx = (mob->xRotO + (mob->xRot - mob->xRotO) * a); + float headRotMinusBodyRot = headRot - bodyRot; + + // TODO: Magic numbers + float HeadXRot = (headRotx / 57.29578f); + if (headRotMinusBodyRot > 20.f) { + headRotMinusBodyRot = 20.f; + } + if (headRotMinusBodyRot < -20.f) { + headRotMinusBodyRot = -20.f; + } + + /** + * f = distance walked f1 = speed 0 - 1 f2 = timer + */ + if (ws > 0.2f) { + HeadXRot = HeadXRot + (cos(wp * 0.4f) * 0.15f * ws); + } + + std::shared_ptr entityhorse = + std::dynamic_pointer_cast(mob); + + float eating = entityhorse->getEatAnim(a); + float standing = entityhorse->getStandAnim(a); + float iStanding = 1.0f - standing; + float openMouth = entityhorse->getMouthAnim(a); + bool tail = entityhorse->tailCounter != 0; + bool saddled = entityhorse->isSaddled(); + bool rider = entityhorse->rider.lock() != NULL; + float bob = mob->tickCount + a; + + float legAnim1 = cos((wp * 0.6662f) + 3.141593f); + float legXRotAnim = legAnim1 * 0.8f * ws; + + Head->y = 4.0f; + Head->z = -10.f; + TailA->y = 3.f; + TailB->z = 14.f; + Bag2->y = 3.f; + Bag2->z = 10.f; + Body->xRot = 0.f; + + // TODO: Fix these magical numbers + Head->xRot = 0.5235988f + (HeadXRot); + Head->yRot = (headRotMinusBodyRot / 57.29578f); // fixes SMP bug + + // interpolate positions and rotations based on current eating and standing + // animations + { + // TODO: Magic numbers + Head->xRot = standing * ((15 * Mth::DEGRAD) + (HeadXRot)) + + eating * 2.18166f + + (1.0f - std::max(standing, eating)) * Head->xRot; + Head->yRot = standing * (headRotMinusBodyRot / 57.29578f) + + (1.0f - std::max(standing, eating)) * Head->yRot; + + Head->y = standing * -6.f + eating * 11.0f + + (1.0f - std::max(standing, eating)) * Head->y; + Head->z = standing * -1.f + eating * -10.f + + (1.0f - std::max(standing, eating)) * Head->z; + + TailA->y = standing * 9.f + iStanding * TailA->y; + TailB->z = standing * 18.f + iStanding * TailB->z; + Bag2->y = standing * 5.5f + iStanding * Bag2->y; + Bag2->z = standing * 15.f + iStanding * Bag2->z; + Body->xRot = standing * (-45 / 57.29578f) + iStanding * Body->xRot; + } + + Ear1->y = Head->y; + Ear2->y = Head->y; + MuleEarL->y = Head->y; + MuleEarR->y = Head->y; + Neck->y = Head->y; + UMouth->y = 0 + .02f; + LMouth->y = 0; + Mane->y = Head->y; + + Ear1->z = Head->z; + Ear2->z = Head->z; + MuleEarL->z = Head->z; + MuleEarR->z = Head->z; + Neck->z = Head->z; + UMouth->z = 0 + .02f - openMouth * 1; + LMouth->z = 0 + openMouth * 1; + Mane->z = Head->z; + + Ear1->xRot = Head->xRot; + Ear2->xRot = Head->xRot; + MuleEarL->xRot = Head->xRot; + MuleEarR->xRot = Head->xRot; + Neck->xRot = Head->xRot; + UMouth->xRot = 0 - (PI * .03f) * openMouth; + LMouth->xRot = 0 + (PI * .05f) * openMouth; + + Mane->xRot = Head->xRot; + + Ear1->yRot = Head->yRot; + Ear2->yRot = Head->yRot; + MuleEarL->yRot = Head->yRot; + MuleEarR->yRot = Head->yRot; + Neck->yRot = Head->yRot; + UMouth->yRot = 0; + LMouth->yRot = 0; + Mane->yRot = Head->yRot; + + // (if chested) + Bag1->xRot = legXRotAnim / 5.f; + Bag2->xRot = -legXRotAnim / 5.f; + + /** + * knee joints Leg1 and Leg4 use LLegXRot Leg2 and Leg3 use RLegXRot + */ + { + float r90 = PI * .5f; + float r270 = PI * 1.5f; + float r300 = -60 * Mth::DEGRAD; + float standAngle = 15 * Mth::DEGRAD * standing; + float bobValue = Mth::cos((bob * 0.6f) + 3.141593f); + + Leg3A->y = -2.f * standing + 9.f * iStanding; + Leg3A->z = -2.f * standing + -8.f * iStanding; + Leg4A->y = Leg3A->y; + Leg4A->z = Leg3A->z; + + Leg1B->y = + Leg1A->y + + (Mth::sin(r90 + standAngle + iStanding * (-legAnim1 * 0.5f * ws)) * + 7.f); + Leg1B->z = + Leg1A->z + + (Mth::cos(r270 + standAngle + iStanding * (-legAnim1 * 0.5f * ws)) * + 7.f); + + Leg2B->y = + Leg2A->y + + (Mth::sin(r90 + standAngle + iStanding * (legAnim1 * 0.5f * ws)) * + 7.f); + Leg2B->z = + Leg2A->z + + (Mth::cos(r270 + standAngle + iStanding * (legAnim1 * 0.5f * ws)) * + 7.f); + + float rlegRot = (r300 + bobValue) * standing + legXRotAnim * iStanding; + float llegRot = + (r300 + -bobValue) * standing + -legXRotAnim * iStanding; + Leg3B->y = Leg3A->y + (Mth::sin(r90 + rlegRot) * 7.f); + Leg3B->z = Leg3A->z + (Mth::cos(r270 + rlegRot) * 7.f); + + Leg4B->y = Leg4A->y + (Mth::sin(r90 + llegRot) * 7.f); + Leg4B->z = Leg4A->z + (Mth::cos(r270 + llegRot) * 7.f); + + Leg1A->xRot = standAngle + (-legAnim1 * 0.5f * ws) * iStanding; + Leg1B->xRot = + (-5 * Mth::DEGRAD) * standing + + ((-legAnim1 * 0.5f * ws) - std::max(0.0f, legAnim1 * .5f * ws)) * + iStanding; + Leg1C->xRot = Leg1B->xRot; + + Leg2A->xRot = standAngle + (legAnim1 * 0.5f * ws) * iStanding; + Leg2B->xRot = + (-5 * Mth::DEGRAD) * standing + + ((legAnim1 * 0.5f * ws) - std::max(0.0f, -legAnim1 * .5f * ws)) * + iStanding; + Leg2C->xRot = Leg2B->xRot; + + Leg3A->xRot = rlegRot; + Leg3B->xRot = + (Leg3A->xRot + PI * std::max(0.0f, (.2f + bobValue * .2f))) * + standing + + (legXRotAnim + std::max(0.0f, legAnim1 * 0.5f * ws)) * iStanding; + Leg3C->xRot = Leg3B->xRot; + + Leg4A->xRot = llegRot; + Leg4B->xRot = + (Leg4A->xRot + PI * std::max(0.0f, (.2f - bobValue * .2f))) * + standing + + (-legXRotAnim + std::max(0.0f, -legAnim1 * 0.5f * ws)) * iStanding; + Leg4C->xRot = Leg4B->xRot; + } + + Leg1C->y = Leg1B->y; + Leg1C->z = Leg1B->z; + Leg2C->y = Leg2B->y; + Leg2C->z = Leg2B->z; + Leg3C->y = Leg3B->y; + Leg3C->z = Leg3B->z; + Leg4C->y = Leg4B->y; + Leg4C->z = Leg4B->z; + + if (saddled) { + Saddle->y = standing * .5f + iStanding * 2.f; + Saddle->z = standing * 11.f + iStanding * 2.f; + + SaddleB->y = Saddle->y; + SaddleC->y = Saddle->y; + SaddleL->y = Saddle->y; + SaddleR->y = Saddle->y; + SaddleL2->y = Saddle->y; + SaddleR2->y = Saddle->y; + Bag1->y = Bag2->y; + + SaddleB->z = Saddle->z; + SaddleC->z = Saddle->z; + SaddleL->z = Saddle->z; + SaddleR->z = Saddle->z; + SaddleL2->z = Saddle->z; + SaddleR2->z = Saddle->z; + Bag1->z = Bag2->z; + + Saddle->xRot = Body->xRot; + SaddleB->xRot = Body->xRot; + SaddleC->xRot = Body->xRot; + + SaddleMouthLine->y = Head->y; + SaddleMouthLineR->y = Head->y; + HeadSaddle->y = Head->y; + SaddleMouthL->y = Head->y; + SaddleMouthR->y = Head->y; + + SaddleMouthLine->z = Head->z; + SaddleMouthLineR->z = Head->z; + HeadSaddle->z = Head->z; + SaddleMouthL->z = Head->z; + SaddleMouthR->z = Head->z; + + SaddleMouthLine->xRot = HeadXRot; + SaddleMouthLineR->xRot = HeadXRot; + HeadSaddle->xRot = Head->xRot; + SaddleMouthL->xRot = Head->xRot; + SaddleMouthR->xRot = Head->xRot; + HeadSaddle->yRot = Head->yRot; + SaddleMouthL->yRot = Head->yRot; + SaddleMouthLine->yRot = Head->yRot; + SaddleMouthR->yRot = Head->yRot; + SaddleMouthLineR->yRot = Head->yRot; + + if (rider) { + // TODO: Magic number (smells like radians :D) + SaddleL->xRot = -60 / 57.29578f; + SaddleL2->xRot = -60 / 57.29578f; + SaddleR->xRot = -60 / 57.29578f; + SaddleR2->xRot = -60 / 57.29578f; + + SaddleL->zRot = 0.f; + SaddleL2->zRot = 0.f; + SaddleR->zRot = 0.f; + SaddleR2->zRot = 0.f; + } else { + SaddleL->xRot = legXRotAnim / 3.f; + SaddleL2->xRot = legXRotAnim / 3.f; + SaddleR->xRot = legXRotAnim / 3.f; + SaddleR2->xRot = legXRotAnim / 3.f; + + SaddleL->zRot = legXRotAnim / 5.f; + SaddleL2->zRot = legXRotAnim / 5.f; + SaddleR->zRot = -legXRotAnim / 5.f; + SaddleR2->zRot = -legXRotAnim / 5.f; + } + } + + // TODO: Magic number + float tailMov = -1.3089f + (ws * 1.5f); + if (tailMov > 0) { + tailMov = 0; + } + + if (tail) { + TailA->yRot = Mth::cos(bob * 0.7f); + tailMov = 0; + } else { + TailA->yRot = 0.f; + } + TailB->yRot = TailA->yRot; + TailC->yRot = TailA->yRot; + + TailB->y = TailA->y; + TailC->y = TailA->y; + TailB->z = TailA->z; + TailC->z = TailA->z; + + // TODO: Magic number + TailA->xRot = tailMov; + TailB->xRot = tailMov; + TailC->xRot = -0.2618f + tailMov; +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/ModelHorse.h b/Minecraft.Client/Rendering/Models/ModelHorse.h new file mode 100644 index 000000000..a200b873d --- /dev/null +++ b/Minecraft.Client/Rendering/Models/ModelHorse.h @@ -0,0 +1,68 @@ +#pragma once +#include "Model.h" + +class ModelHorse : public Model { +private: + ModelPart* Head; + ModelPart* UMouth; + ModelPart* LMouth; + ModelPart* Ear1; + ModelPart* Ear2; + ModelPart* MuleEarL; + ModelPart* MuleEarR; + ModelPart* Neck; + ModelPart* HeadSaddle; + ModelPart* Mane; + + ModelPart* Body; + ModelPart* TailA; + ModelPart* TailB; + ModelPart* TailC; + + ModelPart* Leg1A; + ModelPart* Leg1B; + ModelPart* Leg1C; + + ModelPart* Leg2A; + ModelPart* Leg2B; + ModelPart* Leg2C; + + ModelPart* Leg3A; + ModelPart* Leg3B; + ModelPart* Leg3C; + + ModelPart* Leg4A; + ModelPart* Leg4B; + ModelPart* Leg4C; + + ModelPart* Bag1; + ModelPart* Bag2; + + ModelPart* Saddle; + ModelPart* SaddleB; + ModelPart* SaddleC; + + ModelPart* SaddleL; + ModelPart* SaddleL2; + + ModelPart* SaddleR; + ModelPart* SaddleR2; + + ModelPart* SaddleMouthL; + ModelPart* SaddleMouthR; + + ModelPart* SaddleMouthLine; + ModelPart* SaddleMouthLineR; + +public: + ModelHorse(); + void prepareMobModel(std::shared_ptr mob, float wp, float ws, + float a); + virtual void render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled); + +private: + void setRotation(ModelPart* model, float x, float y, float z); + float rotlerp(float from, float to, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/ModelPart.cpp b/Minecraft.Client/Rendering/Models/ModelPart.cpp index 833746e3b..0e8ccec9f 100644 --- a/Minecraft.Client/Rendering/Models/ModelPart.cpp +++ b/Minecraft.Client/Rendering/Models/ModelPart.cpp @@ -15,6 +15,7 @@ void ModelPart::_init() { neverRender = false; x = y = z = 0.0f; xRot = yRot = zRot = 0.0f; + translateX = translateY = translateZ = 0.0f; } ModelPart::ModelPart() { _init(); } @@ -138,6 +139,8 @@ void ModelPart::render(float scale, bool usecompiled, if (!visible) return; if (!compiled) compile(scale); + glTranslatef(translateX, translateY, translateZ); + if (xRot != 0 || yRot != 0 || zRot != 0) { glPushMatrix(); glTranslatef(x * scale, y * scale, z * scale); @@ -200,6 +203,8 @@ void ModelPart::render(float scale, bool usecompiled, } } } + + glTranslatef(-translateX, -translateY, -translateZ); } void ModelPart::renderRollable(float scale, bool usecompiled) { diff --git a/Minecraft.Client/Rendering/Models/ModelPart.h b/Minecraft.Client/Rendering/Models/ModelPart.h index f412fc244..6c2356a1b 100644 --- a/Minecraft.Client/Rendering/Models/ModelPart.h +++ b/Minecraft.Client/Rendering/Models/ModelPart.h @@ -3,7 +3,7 @@ #include "../Vertex.h" #include "../Polygon.h" #include "Model.h" -#include "SkinBox.h" +#include "../Minecraft.Client/SkinBox.h" class Cube; @@ -19,6 +19,7 @@ public: std::vector cubes; std::vector children; static const float RAD; + float translateX, translateY, translateZ; private: std::wstring id; diff --git a/Minecraft.Client/Rendering/Models/OcelotModel.cpp b/Minecraft.Client/Rendering/Models/OcelotModel.cpp index ba239b4cc..afafef9a4 100644 --- a/Minecraft.Client/Rendering/Models/OcelotModel.cpp +++ b/Minecraft.Client/Rendering/Models/OcelotModel.cpp @@ -4,24 +4,24 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "OcelotModel.h" -const float OzelotModel::xo = 0; -const float OzelotModel::yo = 16; -const float OzelotModel::zo = -9; +const float OcelotModel::xo = 0; +const float OcelotModel::yo = 16; +const float OcelotModel::zo = -9; -const float OzelotModel::headWalkY = -1 + yo; -const float OzelotModel::headWalkZ = 0 + zo; -const float OzelotModel::bodyWalkY = -4 + yo; -const float OzelotModel::bodyWalkZ = -1 + zo; -const float OzelotModel::tail1WalkY = -1 + yo; -const float OzelotModel::tail1WalkZ = 17 + zo; -const float OzelotModel::tail2WalkY = 4 + yo; -const float OzelotModel::tail2WalkZ = 23 + zo; -const float OzelotModel::backLegY = 2.f + yo; -const float OzelotModel::backLegZ = 14 + zo; -const float OzelotModel::frontLegY = -2.2f + yo; -const float OzelotModel::frontLegZ = 4.f + zo; +const float OcelotModel::headWalkY = -1 + yo; +const float OcelotModel::headWalkZ = 0 + zo; +const float OcelotModel::bodyWalkY = -4 + yo; +const float OcelotModel::bodyWalkZ = -1 + zo; +const float OcelotModel::tail1WalkY = -1 + yo; +const float OcelotModel::tail1WalkZ = 17 + zo; +const float OcelotModel::tail2WalkY = 4 + yo; +const float OcelotModel::tail2WalkZ = 23 + zo; +const float OcelotModel::backLegY = 2.f + yo; +const float OcelotModel::backLegZ = 14 + zo; +const float OcelotModel::frontLegY = -2.2f + yo; +const float OcelotModel::frontLegZ = 4.f + zo; -OzelotModel::OzelotModel() { +OcelotModel::OcelotModel() { state = WALK_STATE; setMapTex(L"head.main", 0, 0); @@ -77,10 +77,10 @@ OzelotModel::OzelotModel() { backLegR->compile(1.0f / 16.0f); } -void OzelotModel::render(std::shared_ptr entity, float time, float r, +void OcelotModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); if (young) { float ss = 2.0f; glPushMatrix(); @@ -111,7 +111,7 @@ void OzelotModel::render(std::shared_ptr entity, float time, float r, } } -void OzelotModel::render(OzelotModel* model, float scale, bool usecompiled) { +void OcelotModel::render(OcelotModel* model, float scale, bool usecompiled) { head->yRot = model->head->yRot; head->xRot = model->head->xRot; head->y = model->head->y; @@ -143,8 +143,9 @@ void OzelotModel::render(OzelotModel* model, float scale, bool usecompiled) { body->render(scale, usecompiled); } -void OzelotModel::setupAnim(float time, float r, float bob, float yRot, +void OcelotModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->xRot = xRot / (float)(180 / PI); head->yRot = yRot / (float)(180 / PI); @@ -173,9 +174,9 @@ void OzelotModel::setupAnim(float time, float r, float bob, float yRot, } } -void OzelotModel::prepareMobModel(std::shared_ptr mob, float time, float r, - float a) { - std::shared_ptr ozelot = std::dynamic_pointer_cast(mob); +void OcelotModel::prepareMobModel(std::shared_ptr mob, float time, + float r, float a) { + std::shared_ptr ozelot = std::dynamic_pointer_cast(mob); body->y = bodyWalkY; body->z = bodyWalkZ; diff --git a/Minecraft.Client/Rendering/Models/OcelotModel.h b/Minecraft.Client/Rendering/Models/OcelotModel.h index c34b8e0d6..774a34662 100644 --- a/Minecraft.Client/Rendering/Models/OcelotModel.h +++ b/Minecraft.Client/Rendering/Models/OcelotModel.h @@ -2,7 +2,7 @@ #include "Model.h" -class OzelotModel : public Model { +class OcelotModel : public Model { private: ModelPart *backLegL, *backLegR; ModelPart *frontLegL, *frontLegR; @@ -33,13 +33,14 @@ private: static const float frontLegZ; public: - OzelotModel(); + OcelotModel(); void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); - void render(OzelotModel* model, float scale, bool usecompiled); + void render(OcelotModel* model, float scale, bool usecompiled); void setupAnim(float time, float r, float bob, float yRot, float xRot, - float scale, unsigned int uiBitmaskOverrideAnim = 0); - void prepareMobModel(std::shared_ptr mob, float time, float r, + float scale, std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); + void prepareMobModel(std::shared_ptr mob, float time, float r, float a); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/QuadrupedModel.cpp b/Minecraft.Client/Rendering/Models/QuadrupedModel.cpp index f5685c209..b6fa90fa2 100644 --- a/Minecraft.Client/Rendering/Models/QuadrupedModel.cpp +++ b/Minecraft.Client/Rendering/Models/QuadrupedModel.cpp @@ -44,7 +44,7 @@ QuadrupedModel::QuadrupedModel(int legSize, float g) : Model() { void QuadrupedModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); if (young) { float ss = 2.0f; @@ -73,6 +73,7 @@ void QuadrupedModel::render(std::shared_ptr entity, float time, float r, void QuadrupedModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { float rad = (float)(180 / PI); head->xRot = xRot / rad; diff --git a/Minecraft.Client/Rendering/Models/QuadrupedModel.h b/Minecraft.Client/Rendering/Models/QuadrupedModel.h index f7dcdc0d9..7346510ee 100644 --- a/Minecraft.Client/Rendering/Models/QuadrupedModel.h +++ b/Minecraft.Client/Rendering/Models/QuadrupedModel.h @@ -11,6 +11,7 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); void render(QuadrupedModel* model, float scale, bool usecompiled); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SheepFurModel.cpp b/Minecraft.Client/Rendering/Models/SheepFurModel.cpp index de078c74e..add8aa551 100644 --- a/Minecraft.Client/Rendering/Models/SheepFurModel.cpp +++ b/Minecraft.Client/Rendering/Models/SheepFurModel.cpp @@ -41,8 +41,8 @@ SheepFurModel::SheepFurModel() : QuadrupedModel(12, 0) { leg3->compile(1.0f / 16.0f); } -void SheepFurModel::prepareMobModel(std::shared_ptr mob, float time, - float r, float a) { +void SheepFurModel::prepareMobModel(std::shared_ptr mob, + float time, float r, float a) { QuadrupedModel::prepareMobModel(mob, time, r, a); std::shared_ptr sheep = std::dynamic_pointer_cast(mob); @@ -52,7 +52,8 @@ void SheepFurModel::prepareMobModel(std::shared_ptr mob, float time, void SheepFurModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - QuadrupedModel::setupAnim(time, r, bob, yRot, xRot, scale); + QuadrupedModel::setupAnim(time, r, bob, yRot, xRot, scale, entity); head->xRot = headXRot; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SheepFurModel.h b/Minecraft.Client/Rendering/Models/SheepFurModel.h index 3b43feafb..5039429f1 100644 --- a/Minecraft.Client/Rendering/Models/SheepFurModel.h +++ b/Minecraft.Client/Rendering/Models/SheepFurModel.h @@ -1,6 +1,8 @@ #pragma once #include "QuadrupedModel.h" +class LivingEntity; + class SheepFurModel : public QuadrupedModel { private: float headXRot; @@ -8,9 +10,10 @@ private: public: SheepFurModel(); - virtual void prepareMobModel(std::shared_ptr mob, float time, float r, - float a); + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SheepModel.cpp b/Minecraft.Client/Rendering/Models/SheepModel.cpp index 8599efe9c..986bd3088 100644 --- a/Minecraft.Client/Rendering/Models/SheepModel.cpp +++ b/Minecraft.Client/Rendering/Models/SheepModel.cpp @@ -20,8 +20,8 @@ SheepModel::SheepModel() : QuadrupedModel(12, 0) { body->compile(1.0f / 16.0f); } -void SheepModel::prepareMobModel(std::shared_ptr mob, float time, float r, - float a) { +void SheepModel::prepareMobModel(std::shared_ptr mob, float time, + float r, float a) { QuadrupedModel::prepareMobModel(mob, time, r, a); std::shared_ptr sheep = std::dynamic_pointer_cast(mob); @@ -31,8 +31,9 @@ void SheepModel::prepareMobModel(std::shared_ptr mob, float time, float r, void SheepModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - QuadrupedModel::setupAnim(time, r, bob, yRot, xRot, scale); + QuadrupedModel::setupAnim(time, r, bob, yRot, xRot, scale, entity); head->xRot = headXRot; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SheepModel.h b/Minecraft.Client/Rendering/Models/SheepModel.h index 6fbfcebc2..5692e7a60 100644 --- a/Minecraft.Client/Rendering/Models/SheepModel.h +++ b/Minecraft.Client/Rendering/Models/SheepModel.h @@ -8,9 +8,10 @@ private: public: SheepModel(); - virtual void prepareMobModel(std::shared_ptr mob, float time, float r, - float a); + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SilverfishModel.cpp b/Minecraft.Client/Rendering/Models/SilverfishModel.cpp index 6ddc1187d..89b8c3c03 100644 --- a/Minecraft.Client/Rendering/Models/SilverfishModel.cpp +++ b/Minecraft.Client/Rendering/Models/SilverfishModel.cpp @@ -56,7 +56,7 @@ int SilverfishModel::modelVersion() { return 38; } void SilverfishModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); for (unsigned int i = 0; i < bodyParts.length; i++) { bodyParts[i]->render(scale, usecompiled); @@ -68,6 +68,7 @@ void SilverfishModel::render(std::shared_ptr entity, float time, void SilverfishModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { for (unsigned int i = 0; i < bodyParts.length; i++) { bodyParts[i]->yRot = Mth::cos(bob * .9f + i * .15f * PI) * PI * .05f * @@ -75,6 +76,7 @@ void SilverfishModel::setupAnim(float time, float r, float bob, float yRot, bodyParts[i]->x = Mth::sin(bob * .9f + i * .15f * PI) * PI * .2f * abs((int)i - 2); } + bodyLayers[0]->yRot = bodyParts[2]->yRot; bodyLayers[1]->yRot = bodyParts[4]->yRot; bodyLayers[1]->x = bodyParts[4]->x; diff --git a/Minecraft.Client/Rendering/Models/SilverfishModel.h b/Minecraft.Client/Rendering/Models/SilverfishModel.h index 9db32edd5..c3c74e623 100644 --- a/Minecraft.Client/Rendering/Models/SilverfishModel.h +++ b/Minecraft.Client/Rendering/Models/SilverfishModel.h @@ -23,5 +23,6 @@ public: float yRot, float xRot, float scale, bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SkeletonHeadModel.cpp b/Minecraft.Client/Rendering/Models/SkeletonHeadModel.cpp index 4b84b1e88..4a251f2e1 100644 --- a/Minecraft.Client/Rendering/Models/SkeletonHeadModel.cpp +++ b/Minecraft.Client/Rendering/Models/SkeletonHeadModel.cpp @@ -28,15 +28,17 @@ SkeletonHeadModel::SkeletonHeadModel(int u, int v, int tw, int th) { void SkeletonHeadModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); } void SkeletonHeadModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - Model::setupAnim(time, r, bob, yRot, xRot, scale, uiBitmaskOverrideAnim); + Model::setupAnim(time, r, bob, yRot, xRot, scale, entity, + uiBitmaskOverrideAnim); head->yRot = yRot / (180 / PI); head->xRot = xRot / (180 / PI); diff --git a/Minecraft.Client/Rendering/Models/SkeletonHeadModel.h b/Minecraft.Client/Rendering/Models/SkeletonHeadModel.h index b276c0ce5..32e6fa035 100644 --- a/Minecraft.Client/Rendering/Models/SkeletonHeadModel.h +++ b/Minecraft.Client/Rendering/Models/SkeletonHeadModel.h @@ -16,5 +16,6 @@ public: void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); void setupAnim(float time, float r, float bob, float yRot, float xRot, - float scale, unsigned int uiBitmaskOverrideAnim = 0); + float scale, std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SkeletonModel.cpp b/Minecraft.Client/Rendering/Models/SkeletonModel.cpp index d6d363257..b90cf661c 100644 --- a/Minecraft.Client/Rendering/Models/SkeletonModel.cpp +++ b/Minecraft.Client/Rendering/Models/SkeletonModel.cpp @@ -1,6 +1,7 @@ #include "../../Platform/stdafx.h" #include "SkeletonModel.h" #include "../../../Minecraft.World/Util/Mth.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.monster.h" #include "ModelPart.h" void SkeletonModel::_init(float g) { @@ -34,10 +35,19 @@ SkeletonModel::SkeletonModel() : ZombieModel(0, 0, 64, 32) { _init(0); } SkeletonModel::SkeletonModel(float g) : ZombieModel(g, 0, 64, 32) { _init(g); } +void SkeletonModel::prepareMobModel(std::shared_ptr mob, + float time, float r, float a) { + ZombieModel::prepareMobModel(mob, time, r, a); + + bowAndArrow = std::dynamic_pointer_cast(mob)->getSkeletonType() == + Skeleton::TYPE_WITHER; +} + void SkeletonModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { bowAndArrow = true; - ZombieModel::setupAnim(time, r, bob, yRot, xRot, scale, + ZombieModel::setupAnim(time, r, bob, yRot, xRot, scale, entity, uiBitmaskOverrideAnim); } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SkeletonModel.h b/Minecraft.Client/Rendering/Models/SkeletonModel.h index db0d093ac..e78e69fc5 100644 --- a/Minecraft.Client/Rendering/Models/SkeletonModel.h +++ b/Minecraft.Client/Rendering/Models/SkeletonModel.h @@ -8,7 +8,10 @@ private: public: SkeletonModel(); SkeletonModel(float g); + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SkiModel.cpp b/Minecraft.Client/Rendering/Models/SkiModel.cpp new file mode 100644 index 000000000..5fca00390 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/SkiModel.cpp @@ -0,0 +1,55 @@ +#include "../../Platform/stdafx.h" +#include "SkiModel.h" + +SkiModel::SkiModel() { _init(false); } + +SkiModel::SkiModel(bool leftSki) { _init(leftSki); } + +void SkiModel::_init(bool leftSki) { + this->leftSki = leftSki; + texWidth = 32; + texHeight = 64; + int xOffTex = 0; + if (!leftSki) { + xOffTex = 14; + } + + cubes = ModelPartArray(2); + cubes[0] = new ModelPart(this, xOffTex, 0); + cubes[1] = new ModelPart(this, xOffTex, 5); + + cubes[0]->addBox(0.f, 0.f, 0.f, 3, 1, 4, 0); + cubes[0]->setPos(0, 0, 0); + + cubes[1]->addBox(0.f, 0.f, 0.f, 3, 52, 1, 0); + cubes[1]->setPos(0, 0, 0); +} + +void SkiModel::render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled) { + for (int i = 0; i < cubes.length; i++) { + cubes[i]->render(scale, usecompiled); + } +} + +void SkiModel::setupAnim(float time, float r, float bob, float yRot, float xRot, + float scale, std::shared_ptr entity) { + cubes[0]->y = 24.2f; + cubes[0]->xRot = PI * .5f; + + cubes[1]->y = 24.2f; + cubes[1]->xRot = PI * .5f; + + if (leftSki) { + cubes[0]->z = -26 - 12 * (cos(time * 0.6662f) * 0.7f) * r; + cubes[1]->z = -26 - 12 * (cos(time * 0.6662f) * 0.7f) * r; + cubes[0]->x = .5f; + cubes[1]->x = .5f; + } else { + cubes[0]->z = -26 + 12 * (cos(time * 0.6662f) * 0.7f) * r; + cubes[1]->z = -26 + 12 * (cos(time * 0.6662f) * 0.7f) * r; + cubes[0]->x = -3.5f; + cubes[1]->x = -3.5f; + } +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SkiModel.h b/Minecraft.Client/Rendering/Models/SkiModel.h new file mode 100644 index 000000000..29502440f --- /dev/null +++ b/Minecraft.Client/Rendering/Models/SkiModel.h @@ -0,0 +1,22 @@ +#pragma once +#include "Model.h" +#include "ModelPart.h" + +class SkiModel : public Model { +public: + ModelPartArray cubes; + +private: + bool leftSki; + +public: + SkiModel(); // 4J added + SkiModel(bool leftSki); + void _init(bool leftSki); // 4J added + virtual void render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled); + virtual void setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SlimeModel.cpp b/Minecraft.Client/Rendering/Models/SlimeModel.cpp index 029d7a1c4..91eac953d 100644 --- a/Minecraft.Client/Rendering/Models/SlimeModel.cpp +++ b/Minecraft.Client/Rendering/Models/SlimeModel.cpp @@ -34,7 +34,7 @@ SlimeModel::SlimeModel(int vOffs) { void SlimeModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); cube->render(scale, usecompiled); if (eye0 != NULL) { diff --git a/Minecraft.Client/Rendering/Models/SnowManModel.cpp b/Minecraft.Client/Rendering/Models/SnowManModel.cpp index 5d9daa888..039f88654 100644 --- a/Minecraft.Client/Rendering/Models/SnowManModel.cpp +++ b/Minecraft.Client/Rendering/Models/SnowManModel.cpp @@ -38,8 +38,9 @@ SnowManModel::SnowManModel() : Model() { void SnowManModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - Model::setupAnim(time, r, bob, yRot, xRot, scale); + Model::setupAnim(time, r, bob, yRot, xRot, scale, entity); head->yRot = yRot / (float)(180 / PI); head->xRot = xRot / (float)(180 / PI); piece1->yRot = (yRot / (float)(180 / PI)) * 0.25f; @@ -62,7 +63,7 @@ void SnowManModel::setupAnim(float time, float r, float bob, float yRot, void SnowManModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); piece1->render(scale, usecompiled); piece2->render(scale, usecompiled); diff --git a/Minecraft.Client/Rendering/Models/SnowManModel.h b/Minecraft.Client/Rendering/Models/SnowManModel.h index 971172a22..5279edc95 100644 --- a/Minecraft.Client/Rendering/Models/SnowManModel.h +++ b/Minecraft.Client/Rendering/Models/SnowManModel.h @@ -9,6 +9,7 @@ public: SnowManModel(); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); diff --git a/Minecraft.Client/Rendering/Models/SpiderModel.cpp b/Minecraft.Client/Rendering/Models/SpiderModel.cpp index da0dff534..538009d1a 100644 --- a/Minecraft.Client/Rendering/Models/SpiderModel.cpp +++ b/Minecraft.Client/Rendering/Models/SpiderModel.cpp @@ -70,7 +70,7 @@ SpiderModel::SpiderModel() : Model() { void SpiderModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); body0->render(scale, usecompiled); @@ -87,6 +87,7 @@ void SpiderModel::render(std::shared_ptr entity, float time, float r, void SpiderModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->yRot = yRot / (float)(180 / PI); head->xRot = xRot / (float)(180 / PI); diff --git a/Minecraft.Client/Rendering/Models/SpiderModel.h b/Minecraft.Client/Rendering/Models/SpiderModel.h index ea2624647..271866e9d 100644 --- a/Minecraft.Client/Rendering/Models/SpiderModel.h +++ b/Minecraft.Client/Rendering/Models/SpiderModel.h @@ -12,5 +12,6 @@ public: bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/SquidModel.cpp b/Minecraft.Client/Rendering/Models/SquidModel.cpp index bf0541d19..34c942132 100644 --- a/Minecraft.Client/Rendering/Models/SquidModel.cpp +++ b/Minecraft.Client/Rendering/Models/SquidModel.cpp @@ -36,6 +36,7 @@ SquidModel::SquidModel() : Model() { void SquidModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { for (int i = 0; i < TENTACLES_LENGTH; i++) // 4J - 8 was tentacles.length { @@ -47,7 +48,7 @@ void SquidModel::setupAnim(float time, float r, float bob, float yRot, void SquidModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); body->render(scale, usecompiled); for (int i = 0; i < TENTACLES_LENGTH; diff --git a/Minecraft.Client/Rendering/Models/SquidModel.h b/Minecraft.Client/Rendering/Models/SquidModel.h index 28bc025a7..80c769969 100644 --- a/Minecraft.Client/Rendering/Models/SquidModel.h +++ b/Minecraft.Client/Rendering/Models/SquidModel.h @@ -10,6 +10,7 @@ public: SquidModel(); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, diff --git a/Minecraft.Client/Rendering/Models/VillagerGolemModel.cpp b/Minecraft.Client/Rendering/Models/VillagerGolemModel.cpp index 4e55acee3..07172fefb 100644 --- a/Minecraft.Client/Rendering/Models/VillagerGolemModel.cpp +++ b/Minecraft.Client/Rendering/Models/VillagerGolemModel.cpp @@ -38,7 +38,7 @@ VillagerGolemModel::VillagerGolemModel(float g, float yOffset) { void VillagerGolemModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); body->render(scale, usecompiled); @@ -50,6 +50,7 @@ void VillagerGolemModel::render(std::shared_ptr entity, float time, void VillagerGolemModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->yRot = yRot / (float)(180 / PI); head->xRot = xRot / (float)(180 / PI); @@ -60,8 +61,8 @@ void VillagerGolemModel::setupAnim(float time, float r, float bob, float yRot, leg1->yRot = 0; } -void VillagerGolemModel::prepareMobModel(std::shared_ptr mob, float time, - float r, float a) { +void VillagerGolemModel::prepareMobModel(std::shared_ptr mob, + float time, float r, float a) { std::shared_ptr vg = std::dynamic_pointer_cast(mob); int attackTick = vg->getAttackAnimationTick(); diff --git a/Minecraft.Client/Rendering/Models/VillagerGolemModel.h b/Minecraft.Client/Rendering/Models/VillagerGolemModel.h index 9dba11416..fda66b16b 100644 --- a/Minecraft.Client/Rendering/Models/VillagerGolemModel.h +++ b/Minecraft.Client/Rendering/Models/VillagerGolemModel.h @@ -23,8 +23,9 @@ public: void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); void setupAnim(float time, float r, float bob, float yRot, float xRot, - float scale, unsigned int uiBitmaskOverrideAnim = 0); - void prepareMobModel(std::shared_ptr mob, float time, float r, + float scale, std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); + void prepareMobModel(std::shared_ptr mob, float time, float r, float a); private: diff --git a/Minecraft.Client/Rendering/Models/VillagerModel.cpp b/Minecraft.Client/Rendering/Models/VillagerModel.cpp index 42990ef1e..31b8fc383 100644 --- a/Minecraft.Client/Rendering/Models/VillagerModel.cpp +++ b/Minecraft.Client/Rendering/Models/VillagerModel.cpp @@ -3,15 +3,15 @@ #include "../../../Minecraft.World/Util/Mth.h" #include "ModelPart.h" -void VillagerModel::_init(float g, float yOffset) { - int xTexSize = 64; - int yTexSize = 64; - +void VillagerModel::_init(float g, float yOffset, int xTexSize, int yTexSize) { head = (new ModelPart(this))->setTexSize(xTexSize, yTexSize); head->setPos(0, 0 + yOffset, 0); head->texOffs(0, 0)->addBox(-4, -10, -4, 8, 10, 8, g); - // head.texOffs(32, 0).addBox(-4, -10, -4, 8, 12, 8, g + 0.5f); - head->texOffs(24, 0)->addBox(-1, -3, -6, 2, 4, 2, g); + + nose = (new ModelPart(this))->setTexSize(xTexSize, yTexSize); + nose->setPos(0, yOffset - 2, 0); + nose->texOffs(24, 0)->addBox(-1, -1, -6, 2, 4, 2, g); + head->addChild(nose); body = (new ModelPart(this))->setTexSize(xTexSize, yTexSize); body->setPos(0, 0 + yOffset, 0); @@ -44,16 +44,17 @@ void VillagerModel::_init(float g, float yOffset) { leg1->compile(1.0f / 16.0f); } -VillagerModel::VillagerModel(float g) : Model() { _init(g, 0); } +VillagerModel::VillagerModel(float g) : Model() { _init(g, 0, 64, 64); } -VillagerModel::VillagerModel(float g, float yOffset) : Model() { - _init(g, yOffset); +VillagerModel::VillagerModel(float g, float yOffset, int xTexSize, int yTexSize) + : Model() { + _init(g, yOffset, xTexSize, yTexSize); } void VillagerModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); head->render(scale, usecompiled); body->render(scale, usecompiled); @@ -64,6 +65,7 @@ void VillagerModel::render(std::shared_ptr entity, float time, float r, void VillagerModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { head->yRot = yRot / (float)(180 / PI); head->xRot = xRot / (float)(180 / PI); diff --git a/Minecraft.Client/Rendering/Models/VillagerModel.h b/Minecraft.Client/Rendering/Models/VillagerModel.h index 59f3b18de..46b104fb4 100644 --- a/Minecraft.Client/Rendering/Models/VillagerModel.h +++ b/Minecraft.Client/Rendering/Models/VillagerModel.h @@ -4,15 +4,16 @@ class VillagerModel : public Model { public: - ModelPart *head, *body, *arms, *leg0, *leg1; + ModelPart *head, *body, *arms, *leg0, *leg1, *nose; - void _init(float g, float yOffset); // 4J added - VillagerModel(float g, float yOffset); + void _init(float g, float yOffset, int xTexSize, int yTexSize); // 4J added + VillagerModel(float g, float yOffset, int xTexSize, int yTexSize); VillagerModel(float g); virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; diff --git a/Minecraft.Client/Rendering/Models/VillagerZombieModel.cpp b/Minecraft.Client/Rendering/Models/VillagerZombieModel.cpp index 152e991cc..221daa9f4 100644 --- a/Minecraft.Client/Rendering/Models/VillagerZombieModel.cpp +++ b/Minecraft.Client/Rendering/Models/VillagerZombieModel.cpp @@ -34,8 +34,9 @@ int VillagerZombieModel::version() { return 10; } void VillagerZombieModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, + HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, entity, uiBitmaskOverrideAnim); float attack2 = Mth::sin(attackTime * PI); diff --git a/Minecraft.Client/Rendering/Models/VillagerZombieModel.h b/Minecraft.Client/Rendering/Models/VillagerZombieModel.h index 201664a68..54a9acec2 100644 --- a/Minecraft.Client/Rendering/Models/VillagerZombieModel.h +++ b/Minecraft.Client/Rendering/Models/VillagerZombieModel.h @@ -12,5 +12,6 @@ public: int version(); void setupAnim(float time, float r, float bob, float yRot, float xRot, - float scale, unsigned int uiBitmaskOverrideAnim = 0); + float scale, std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/WitchModel.cpp b/Minecraft.Client/Rendering/Models/WitchModel.cpp new file mode 100644 index 000000000..20121428c --- /dev/null +++ b/Minecraft.Client/Rendering/Models/WitchModel.cpp @@ -0,0 +1,71 @@ +#include "../../Platform/stdafx.h" +#include "ModelPart.h" +#include "WitchModel.h" +#include "VillagerModel.h" +#include "../../../Minecraft.World/Util/Mth.h" + +WitchModel::WitchModel(float g) : VillagerModel(g, 0, 64, 128) { + mole = (new ModelPart(this))->setTexSize(64, 128); + mole->setPos(0, -2, 0); + mole->texOffs(0, 0)->addBox(0, 3, -6.75f, 1, 1, 1, -0.25f); + nose->addChild(mole); + + hat = (new ModelPart(this))->setTexSize(64, 128); + hat->setPos(-5, -10 - (0.5f / 16.f), -5); + hat->texOffs(0, 64)->addBox(0, 0, 0, 10, 2, 10); + head->addChild(hat); + + ModelPart* hat2 = new ModelPart(this); + hat2->setTexSize(64, 128); + hat2->setPos(1.75f, -4, 2.f); + hat2->texOffs(0, 76)->addBox(0, 0, 0, 7, 4, 7); + hat2->xRot = -3.f * Mth::RAD_TO_GRAD; + hat2->zRot = 1.5f * Mth::RAD_TO_GRAD; + hat->addChild(hat2); + + ModelPart* hat3 = new ModelPart(this); + hat3->setTexSize(64, 128); + hat3->setPos(1.75f, -4, 2.f); + hat3->texOffs(0, 87)->addBox(0, 0, 0, 4, 4, 4); + hat3->xRot = -6.f * Mth::RAD_TO_GRAD; + hat3->zRot = 3.f * Mth::RAD_TO_GRAD; + hat2->addChild(hat3); + + ModelPart* hat4 = new ModelPart(this); + hat4->setTexSize(64, 128); + hat4->setPos(1.75f, -2, 2.f); + hat4->texOffs(0, 95)->addBox(0, 0, 0, 1, 2, 1, 0.25f); + hat4->xRot = -12.f * Mth::RAD_TO_GRAD; + hat4->zRot = 6.f * Mth::RAD_TO_GRAD; + hat3->addChild(hat4); + + // 4J added - compile now to avoid random performance hit first time cubes + // are rendered + mole->compile(1.0f / 16.0f); + hat->compile(1.0f / 16.0f); + hat2->compile(1.0f / 16.0f); + hat3->compile(1.0f / 16.0f); + hat4->compile(1.0f / 16.0f); +} + +void WitchModel::setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim) { + VillagerModel::setupAnim(time, r, bob, yRot, xRot, scale, entity); + + nose->translateX = nose->translateY = nose->translateZ = 0; + + float speed = 0.01f * (entity->entityId % 10); + nose->xRot = (sin(entity->tickCount * speed) * 4.5f) * PI / 180; + nose->yRot = 0; + nose->zRot = (cos(entity->tickCount * speed) * 2.5f) * PI / 180; + + if (holdingItem) { + nose->xRot = -0.9f; + nose->translateZ = -1.5f / 16.f; + nose->translateY = 3 / 16.f; + } +} + +int WitchModel::getModelVersion() { return 0; } \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/WitchModel.h b/Minecraft.Client/Rendering/Models/WitchModel.h new file mode 100644 index 000000000..8ece6b581 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/WitchModel.h @@ -0,0 +1,19 @@ +#pragma once +#include "VillagerModel.h" + +class WitchModel : public VillagerModel { +public: + bool holdingItem; + +private: + ModelPart* mole; + ModelPart* hat; + +public: + WitchModel(float g); + virtual void setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); + int getModelVersion(); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/WitherBossModel.cpp b/Minecraft.Client/Rendering/Models/WitherBossModel.cpp new file mode 100644 index 000000000..d73a06857 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/WitherBossModel.cpp @@ -0,0 +1,79 @@ +#include "../../Platform/stdafx.h" +#include "WitherBossModel.h" +#include "../../../Minecraft.World/Entities/Mobs/WitherBoss.h" +#include "ModelPart.h" + +WitherBossModel::WitherBossModel() { + texWidth = 64; + texHeight = 64; + + upperBodyParts = ModelPartArray(3); + + upperBodyParts[0] = new ModelPart(this, 0, 16); + upperBodyParts[0]->addBox(-10, 3.9f, -.5f, 20, 3, 3); + + upperBodyParts[1] = new ModelPart(this); + upperBodyParts[1]->setTexSize(texWidth, texHeight); + upperBodyParts[1]->setPos(-2, 6.9f, -.5f); + upperBodyParts[1]->texOffs(0, 22)->addBox(0, 0, 0, 3, 10, 3); + upperBodyParts[1]->texOffs(24, 22)->addBox(-4.f, 1.5f, .5f, 11, 2, 2); + upperBodyParts[1]->texOffs(24, 22)->addBox(-4.f, 4, .5f, 11, 2, 2); + upperBodyParts[1]->texOffs(24, 22)->addBox(-4.f, 6.5f, .5f, 11, 2, 2); + + upperBodyParts[2] = new ModelPart(this, 12, 22); + upperBodyParts[2]->addBox(0, 0, 0, 3, 6, 3); + + heads = ModelPartArray(3); + heads[0] = new ModelPart(this, 0, 0); + heads[0]->addBox(-4, -4, -4, 8, 8, 8); + heads[1] = new ModelPart(this, 32, 0); + heads[1]->addBox(-4, -4, -4, 6, 6, 6); + heads[1]->x = -8; + heads[1]->y = 4; + heads[2] = new ModelPart(this, 32, 0); + heads[2]->addBox(-4, -4, -4, 6, 6, 6); + heads[2]->x = 10; + heads[2]->y = 4; +} + +int WitherBossModel::modelVersion() { return 32; } + +void WitherBossModel::render(std::shared_ptr entity, float time, + float r, float bob, float yRot, float xRot, + float scale, bool usecompiled) { + setupAnim(time, r, bob, yRot, xRot, scale, entity); + + for (int i = 0; i < heads.length; i++) { + heads[i]->render(scale, usecompiled); + } + for (int i = 0; i < upperBodyParts.length; i++) { + upperBodyParts[i]->render(scale, usecompiled); + } +} + +void WitherBossModel::setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim) { + float anim = cos(bob * .1f); + upperBodyParts[1]->xRot = (.065f + .05f * anim) * PI; + + upperBodyParts[2]->setPos(-2.f, 6.9f + cos(upperBodyParts[1]->xRot) * 10.f, + -.5f + sin(upperBodyParts[1]->xRot) * 10.f); + upperBodyParts[2]->xRot = (.265f + .1f * anim) * PI; + + heads[0]->yRot = yRot / (180 / PI); + heads[0]->xRot = xRot / (180 / PI); +} + +void WitherBossModel::prepareMobModel(std::shared_ptr mob, + float time, float r, float a) { + std::shared_ptr boss = + std::dynamic_pointer_cast(mob); + + for (int i = 1; i < 3; i++) { + heads[i]->yRot = + (boss->getHeadYRot(i - 1) - mob->yBodyRot) / (180 / PI); + heads[i]->xRot = boss->getHeadXRot(i - 1) / (180 / PI); + } +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/WitherBossModel.h b/Minecraft.Client/Rendering/Models/WitherBossModel.h new file mode 100644 index 000000000..426e619e2 --- /dev/null +++ b/Minecraft.Client/Rendering/Models/WitherBossModel.h @@ -0,0 +1,23 @@ +#pragma once +#include "Model.h" +#include "ModelPart.h" + +class WitherBossModel : public Model { +private: + ModelPartArray upperBodyParts; + ModelPartArray heads; + +public: + WitherBossModel(); + + int modelVersion(); + virtual void render(std::shared_ptr entity, float time, float r, + float bob, float yRot, float xRot, float scale, + bool usecompiled); + virtual void setupAnim(float time, float r, float bob, float yRot, + float xRot, float scale, + std::shared_ptr entity, + unsigned int uiBitmaskOverrideAnim = 0); + virtual void prepareMobModel(std::shared_ptr mob, float time, + float r, float a); +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/WolfModel.cpp b/Minecraft.Client/Rendering/Models/WolfModel.cpp index ebacdb74f..592781450 100644 --- a/Minecraft.Client/Rendering/Models/WolfModel.cpp +++ b/Minecraft.Client/Rendering/Models/WolfModel.cpp @@ -61,7 +61,7 @@ void WolfModel::render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) { Model::render(entity, time, r, bob, yRot, xRot, scale, usecompiled); - setupAnim(time, r, bob, yRot, xRot, scale); + setupAnim(time, r, bob, yRot, xRot, scale, entity); if (young) { float ss = 2; @@ -92,8 +92,8 @@ void WolfModel::render(std::shared_ptr entity, float time, float r, } } -void WolfModel::prepareMobModel(std::shared_ptr mob, float time, float r, - float a) { +void WolfModel::prepareMobModel(std::shared_ptr mob, float time, + float r, float a) { std::shared_ptr wolf = std::dynamic_pointer_cast(mob); if (wolf->isAngry()) { @@ -151,8 +151,9 @@ void WolfModel::prepareMobModel(std::shared_ptr mob, float time, float r, void WolfModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - Model::setupAnim(time, r, bob, yRot, xRot, scale); + Model::setupAnim(time, r, bob, yRot, xRot, scale, entity); head->xRot = xRot / (float)(180 / PI); head->yRot = yRot / (float)(180 / PI); tail->xRot = bob; diff --git a/Minecraft.Client/Rendering/Models/WolfModel.h b/Minecraft.Client/Rendering/Models/WolfModel.h index efdddbc58..ced758eca 100644 --- a/Minecraft.Client/Rendering/Models/WolfModel.h +++ b/Minecraft.Client/Rendering/Models/WolfModel.h @@ -19,9 +19,10 @@ public: virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled); - void prepareMobModel(std::shared_ptr mob, float time, float r, + void prepareMobModel(std::shared_ptr mob, float time, float r, float a); virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Models/ZombieModel.cpp b/Minecraft.Client/Rendering/Models/ZombieModel.cpp index b159f6019..a6213c8c9 100644 --- a/Minecraft.Client/Rendering/Models/ZombieModel.cpp +++ b/Minecraft.Client/Rendering/Models/ZombieModel.cpp @@ -13,8 +13,9 @@ ZombieModel::ZombieModel(float g, bool isArmor) void ZombieModel::setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim) { - HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, + HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, entity, uiBitmaskOverrideAnim); float attack2 = Mth::sin(attackTime * PI); diff --git a/Minecraft.Client/Rendering/Models/ZombieModel.h b/Minecraft.Client/Rendering/Models/ZombieModel.h index 90351967b..7178d2c20 100644 --- a/Minecraft.Client/Rendering/Models/ZombieModel.h +++ b/Minecraft.Client/Rendering/Models/ZombieModel.h @@ -13,5 +13,6 @@ public: virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, + std::shared_ptr entity, unsigned int uiBitmaskOverrideAnim = 0); }; diff --git a/Minecraft.Client/Rendering/Particles/FireworksParticles.cpp b/Minecraft.Client/Rendering/Particles/FireworksParticles.cpp new file mode 100644 index 000000000..bf7f029fb --- /dev/null +++ b/Minecraft.Client/Rendering/Particles/FireworksParticles.cpp @@ -0,0 +1,455 @@ +#include "../../Platform/stdafx.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" +#include "FireworksParticles.h" +#include "../Tesselator.h" +#include "../../../Minecraft.World/Level/Level.h" + +FireworksParticles::FireworksStarter::FireworksStarter( + Level* level, double x, double y, double z, double xd, double yd, double zd, + ParticleEngine* engine, CompoundTag* infoTag) + : Particle(level, x, y, z, 0, 0, 0) { + life = 0; + twinkleDelay = false; + + this->xd = xd; + this->yd = yd; + this->zd = zd; + this->engine = engine; + lifetime = 8; + + if (infoTag != NULL) { + explosions = (ListTag*)infoTag + ->getList(FireworksItem::TAG_EXPLOSIONS) + ->copy(); + if (explosions->size() == 0) { + explosions = NULL; + } else { + lifetime = explosions->size() * 2 - 1; + + // check if any of the explosions has flickering + for (int e = 0; e < explosions->size(); e++) { + CompoundTag* compoundTag = explosions->get(e); + if (compoundTag->getBoolean(FireworksItem::TAG_E_FLICKER)) { + twinkleDelay = true; + lifetime += 15; + break; + } + } + } + } else { + // 4J: + explosions = NULL; + } +} + +void FireworksParticles::FireworksStarter::render(Tesselator* t, float a, + float xa, float ya, float za, + float xa2, float za2) { + // Do nothing +} + +void FireworksParticles::FireworksStarter::tick() { + if (life == 0 && explosions != NULL) { + bool farEffect = isFarAwayFromCamera(); + + bool largeExplosion = false; + if (explosions->size() >= 3) { + largeExplosion = true; + } else { + for (int e = 0; e < explosions->size(); e++) { + CompoundTag* compoundTag = explosions->get(e); + if (compoundTag->getByte(FireworksItem::TAG_E_TYPE) == + FireworksItem::TYPE_BIG) { + largeExplosion = true; + break; + } + } + } + + eSOUND_TYPE soundId; + + if (largeExplosion && farEffect) { + soundId = eSoundType_FIREWORKS_LARGE_BLAST_FAR; + } else if (largeExplosion && !farEffect) { + soundId = eSoundType_FIREWORKS_LARGE_BLAST; + } else if (!largeExplosion && farEffect) { + soundId = eSoundType_FIREWORKS_BLAST_FAR; + } else { + soundId = eSoundType_FIREWORKS_BLAST; + } + + level->playLocalSound(x, y, z, soundId, 20, + .95f + random->nextFloat() * .1f, true, 100.0f); + } + + if ((life % 2) == 0 && explosions != NULL && + (life / 2) < explosions->size()) { + int eIndex = life / 2; + CompoundTag* compoundTag = explosions->get(eIndex); + + int type = compoundTag->getByte(FireworksItem::TAG_E_TYPE); + bool trail = compoundTag->getBoolean(FireworksItem::TAG_E_TRAIL); + bool flicker = compoundTag->getBoolean(FireworksItem::TAG_E_FLICKER); + intArray colors = compoundTag->getIntArray(FireworksItem::TAG_E_COLORS); + intArray fadeColors = + compoundTag->getIntArray(FireworksItem::TAG_E_FADECOLORS); + + if (type == FireworksItem::TYPE_BIG) { + // large ball + createParticleBall(.5, 4, colors, fadeColors, trail, flicker); + } else if (type == FireworksItem::TYPE_STAR) { + double coords[6][2] = { + 0.0, 1.0, + 0.3455, 0.3090, + 0.9511, 0.3090, + 93.0 / 245.0, -31.0 / 245.0, + 150.0 / 245.0, -197.0 / 245.0, + 0.0, -88.0 / 245.0, + }; + coords2DArray coordsArray(6, 2); + for (unsigned int i = 0; i < coordsArray.length; ++i) { + for (unsigned int j = 0; j < coordsArray[i]->length; ++j) { + coordsArray[i]->data[j] = coords[i][j]; + } + } + + // star-shape + createParticleShape(.5, coordsArray, colors, fadeColors, trail, + flicker, false); + + for (unsigned int i = 0; i < coordsArray.length; ++i) { + delete[] coordsArray[i]->data; + } + delete[] coordsArray.data; + } else if (type == FireworksItem::TYPE_CREEPER) { + double coords[12][2] = { + 0.0, 0.2, 0.2, 0.2, 0.2, 0.6, 0.6, 0.6, 0.6, 0.2, 0.2, 0.2, + 0.2, 0.0, 0.4, 0.0, 0.4, -0.6, 0.2, -0.6, 0.2, -0.4, 0.0, -0.4, + }; + coords2DArray coordsArray(12, 2); + for (unsigned int i = 0; i < coordsArray.length; ++i) { + for (unsigned int j = 0; j < coordsArray[i]->length; ++j) { + coordsArray[i]->data[j] = coords[i][j]; + } + } + + // creeper-shape + createParticleShape(.5, coordsArray, colors, fadeColors, trail, + flicker, true); + + for (unsigned int i = 0; i < coordsArray.length; ++i) { + delete[] coordsArray[i]->data; + } + delete[] coordsArray.data; + } else if (type == FireworksItem::TYPE_BURST) { + createParticleBurst(colors, fadeColors, trail, flicker); + } else { + // small ball + createParticleBall(.25, 2, colors, fadeColors, trail, flicker); + } + { + int rgb = colors[0]; + float r = (float)((rgb & 0xff0000) >> 16) / 255.0f; + float g = (float)((rgb & 0x00ff00) >> 8) / 255.0f; + float b = (float)((rgb & 0x0000ff) >> 0) / 255.0f; + std::shared_ptr fireworksOverlayParticle = + std::shared_ptr( + new FireworksParticles::FireworksOverlayParticle(level, x, + y, z)); + fireworksOverlayParticle->setColor(r, g, b); + fireworksOverlayParticle->setAlpha(0.99f); // 4J added + engine->add(fireworksOverlayParticle); + } + } + life++; + if (life > lifetime) { + if (twinkleDelay) { + bool farEffect = isFarAwayFromCamera(); + eSOUND_TYPE soundId = farEffect ? eSoundType_FIREWORKS_TWINKLE_FAR + : eSoundType_FIREWORKS_TWINKLE; + level->playLocalSound(x, y, z, soundId, 20, + .90f + random->nextFloat() * .15f, true, + 100.0f); + } + remove(); + } +} + +bool FireworksParticles::FireworksStarter::isFarAwayFromCamera() { + Minecraft* instance = Minecraft::GetInstance(); + if (instance != NULL && instance->cameraTargetPlayer != NULL) { + if (instance->cameraTargetPlayer->distanceToSqr(x, y, z) < 16 * 16) { + return false; + } + } + return true; +} + +void FireworksParticles::FireworksStarter::createParticle( + double x, double y, double z, double xa, double ya, double za, + intArray rgbColors, intArray fadeColors, bool trail, bool flicker) { + std::shared_ptr fireworksSparkParticle = + std::shared_ptr( + new FireworksSparkParticle(level, x, y, z, xa, ya, za, engine)); + fireworksSparkParticle->setAlpha(0.99f); + fireworksSparkParticle->setTrail(trail); + fireworksSparkParticle->setFlicker(flicker); + + int color = random->nextInt(rgbColors.length); + fireworksSparkParticle->setColor(rgbColors[color]); + if (/*fadeColors != NULL &&*/ fadeColors.length > 0) { + fireworksSparkParticle->setFadeColor( + fadeColors[random->nextInt(fadeColors.length)]); + } + engine->add(fireworksSparkParticle); +} + +void FireworksParticles::FireworksStarter::createParticleBall( + double baseSpeed, int steps, intArray rgbColors, intArray fadeColors, + bool trail, bool flicker) { + double xx = x; + double yy = y; + double zz = z; + + for (int yStep = -steps; yStep <= steps; yStep++) { + for (int xStep = -steps; xStep <= steps; xStep++) { + for (int zStep = -steps; zStep <= steps; zStep++) { + double xa = + xStep + (random->nextDouble() - random->nextDouble()) * .5; + double ya = + yStep + (random->nextDouble() - random->nextDouble()) * .5; + double za = + zStep + (random->nextDouble() - random->nextDouble()) * .5; + double len = sqrt(xa * xa + ya * ya + za * za) / baseSpeed + + random->nextGaussian() * .05; + + createParticle(xx, yy, zz, xa / len, ya / len, za / len, + rgbColors, fadeColors, trail, flicker); + + if (yStep != -steps && yStep != steps && xStep != -steps && + xStep != steps) { + zStep += steps * 2 - 1; + } + } + } + } +} + +void FireworksParticles::FireworksStarter::createParticleShape( + double baseSpeed, coords2DArray coords, intArray rgbColors, + intArray fadeColors, bool trail, bool flicker, bool flat) { + double sx = coords[0]->data[0]; + double sy = coords[0]->data[1]; + + { + createParticle(x, y, z, sx * baseSpeed, sy * baseSpeed, 0, rgbColors, + fadeColors, trail, flicker); + } + + float baseAngle = random->nextFloat() * PI; + double angleMod = (flat ? .034 : .34); + for (int angleStep = 0; angleStep < 3; angleStep++) { + double angle = baseAngle + angleStep * PI * angleMod; + + double ox = sx; + double oy = sy; + + for (int c = 1; c < coords.length; c++) { + double tx = coords[c]->data[0]; + double ty = coords[c]->data[1]; + + for (double subStep = .25; subStep <= 1.0; subStep += .25) { + double xa = (ox + (tx - ox) * subStep) * baseSpeed; + double ya = (oy + (ty - oy) * subStep) * baseSpeed; + + double za = xa * sin(angle); + xa = xa * cos(angle); + + for (double flip = -1; flip <= 1; flip += 2) { + createParticle(x, y, z, xa * flip, ya, za * flip, rgbColors, + fadeColors, trail, flicker); + } + } + ox = tx; + oy = ty; + } + } +} + +void FireworksParticles::FireworksStarter::createParticleBurst( + intArray rgbColors, intArray fadeColors, bool trail, bool flicker) { + double baseOffX = random->nextGaussian() * .05; + double baseOffZ = random->nextGaussian() * .05; + + for (int i = 0; i < 70; i++) { + double xa = xd * .5 + random->nextGaussian() * .15 + baseOffX; + double za = zd * .5 + random->nextGaussian() * .15 + baseOffZ; + double ya = yd * .5 + random->nextDouble() * .5; + + createParticle(x, y, z, xa, ya, za, rgbColors, fadeColors, trail, + flicker); + } +} + +int FireworksParticles::FireworksStarter::getParticleTexture() { + return ParticleEngine::MISC_TEXTURE; +} + +FireworksParticles::FireworksSparkParticle::FireworksSparkParticle( + Level* level, double x, double y, double z, double xa, double ya, double za, + ParticleEngine* engine) + : Particle(level, x, y, z) { + baseTex = 10 * 16; + + xd = xa; + yd = ya; + zd = za; + this->engine = engine; + + size *= 0.75f; + + lifetime = 48 + random->nextInt(12); +#ifdef __PSVITA__ + noPhysics = true; // 4J - optimisation, these are just too slow on Vita to + // be running with physics on +#else + noPhysics = false; +#endif + + trail = false; + flicker = false; + + fadeR = 0.0f; + fadeG = 0.0f; + fadeB = 0.0f; + hasFade = false; +} + +void FireworksParticles::FireworksSparkParticle::setTrail(bool trail) { + this->trail = trail; +} + +void FireworksParticles::FireworksSparkParticle::setFlicker(bool flicker) { + this->flicker = flicker; +} + +void FireworksParticles::FireworksSparkParticle::setColor(int rgb) { + float r = (float)((rgb & 0xff0000) >> 16) / 255.0f; + float g = (float)((rgb & 0x00ff00) >> 8) / 255.0f; + float b = (float)((rgb & 0x0000ff) >> 0) / 255.0f; + float scale = 1.0f; + Particle::setColor(r * scale, g * scale, b * scale); +} + +void FireworksParticles::FireworksSparkParticle::setFadeColor(int rgb) { + fadeR = (float)((rgb & 0xff0000) >> 16) / 255.0f; + fadeG = (float)((rgb & 0x00ff00) >> 8) / 255.0f; + fadeB = (float)((rgb & 0x0000ff) >> 0) / 255.0f; + hasFade = true; +} + +AABB* FireworksParticles::FireworksSparkParticle::getCollideBox() { + return NULL; +} + +bool FireworksParticles::FireworksSparkParticle::isPushable() { return false; } + +void FireworksParticles::FireworksSparkParticle::render(Tesselator* t, float a, + float xa, float ya, + float za, float xa2, + float za2) { + if (!flicker || age < (lifetime / 3) || (((age + lifetime) / 3) % 2) == 0) { + Particle::render(t, a, xa, ya, za, xa2, za2); + } +} + +void FireworksParticles::FireworksSparkParticle::tick() { + xo = x; + yo = y; + zo = z; + + if (age++ >= lifetime) remove(); + if (age > lifetime / 2) { + setAlpha(1.0f - (((float)age - lifetime / 2) / (float)lifetime)); + + if (hasFade) { + rCol = rCol + (fadeR - rCol) * .2f; + gCol = gCol + (fadeG - gCol) * .2f; + bCol = bCol + (fadeB - bCol) * .2f; + } + } + + setMiscTex(baseTex + (7 - age * 8 / lifetime)); + + yd -= 0.004; + move(xd, yd, zd, + true); // 4J - changed so these don't attempt to collide with entities + xd *= 0.91f; + yd *= 0.91f; + zd *= 0.91f; + + if (onGround) { + xd *= 0.7f; + zd *= 0.7f; + } + + if (trail && (age < lifetime / 2) && ((age + lifetime) % 2) == 0) { + std::shared_ptr fireworksSparkParticle = + std::shared_ptr( + new FireworksParticles::FireworksSparkParticle( + level, x, y, z, 0, 0, 0, engine)); + fireworksSparkParticle->setAlpha(0.99f); + fireworksSparkParticle->setColor(rCol, gCol, bCol); + fireworksSparkParticle->age = fireworksSparkParticle->lifetime / 2; + if (hasFade) { + fireworksSparkParticle->hasFade = true; + fireworksSparkParticle->fadeR = fadeR; + fireworksSparkParticle->fadeG = fadeG; + fireworksSparkParticle->fadeB = fadeB; + } + fireworksSparkParticle->flicker = flicker; + engine->add(fireworksSparkParticle); + } +} + +void FireworksParticles::FireworksSparkParticle::setBaseTex(int baseTex) { + this->baseTex = baseTex; +} + +int FireworksParticles::FireworksSparkParticle::getLightColor(float a) { + return SharedConstants::FULLBRIGHT_LIGHTVALUE; +} + +float FireworksParticles::FireworksSparkParticle::getBrightness(float a) { + return 1; +} + +FireworksParticles::FireworksOverlayParticle::FireworksOverlayParticle( + Level* level, double x, double y, double z) + : Particle(level, x, y, z) { + lifetime = 4; +} + +void FireworksParticles::FireworksOverlayParticle::render(Tesselator* t, + float a, float xa, + float ya, float za, + float xa2, + float za2) { + float u0 = 32.0f / 128.0f; + float u1 = u0 + 32.0f / 128.0f; + float v0 = 16.0f / 128.0f; + float v1 = v0 + 32.0f / 128.0f; + float r = 7.1f * sin(((float)age + a - 1.0f) * .25f * PI); + alpha = 0.6f - ((float)age + a - 1.0f) * .25f * .5f; + + float x = (float)(xo + (this->x - xo) * a - xOff); + float y = (float)(yo + (this->y - yo) * a - yOff); + float z = (float)(zo + (this->z - zo) * a - zOff); + + t->color(rCol, gCol, bCol, alpha); + + t->vertexUV(x - xa * r - xa2 * r, y - ya * r, z - za * r - za2 * r, u1, v1); + t->vertexUV(x - xa * r + xa2 * r, y + ya * r, z - za * r + za2 * r, u1, v0); + t->vertexUV(x + xa * r + xa2 * r, y + ya * r, z + za * r + za2 * r, u0, v0); + t->vertexUV(x + xa * r - xa2 * r, y - ya * r, z + za * r - za2 * r, u0, v1); +} \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Particles/FireworksParticles.h b/Minecraft.Client/Rendering/Particles/FireworksParticles.h new file mode 100644 index 000000000..95bb71740 --- /dev/null +++ b/Minecraft.Client/Rendering/Particles/FireworksParticles.h @@ -0,0 +1,85 @@ +#pragma once +#include "Particle.h" +#include "../../../Minecraft.World/IO/NBT/CompoundTag.h" + +class ParticleEngine; + +class FireworksParticles { +public: + class FireworksStarter : public Particle { + public: + virtual eINSTANCEOF GetType() { return eType_FIREWORKSSTARTERPARTICLE; } + + private: + int life; + ParticleEngine* engine; + ListTag* explosions; + bool twinkleDelay; + + public: + FireworksStarter(Level* level, double x, double y, double z, double xd, + double yd, double zd, ParticleEngine* engine, + CompoundTag* infoTag); + virtual void render(Tesselator* t, float a, float xa, float ya, + float za, float xa2, float za2); + virtual void tick(); + bool isFarAwayFromCamera(); + void createParticle(double x, double y, double z, double xa, double ya, + double za, intArray rgbColors, intArray fadeColors, + bool trail, bool flicker); + void createParticleBall(double baseSpeed, int steps, intArray rgbColors, + intArray fadeColors, bool trail, bool flicker); + void createParticleShape(double baseSpeed, coords2DArray coords, + intArray rgbColors, intArray fadeColors, + bool trail, bool flicker, bool flat); + void createParticleBurst(intArray rgbColors, intArray fadeColors, + bool trail, bool flicker); + + public: + int getParticleTexture(); + }; + + class FireworksSparkParticle : public Particle { + public: + virtual eINSTANCEOF GetType() { return eType_FIREWORKSSPARKPARTICLE; } + + private: + int baseTex; + bool trail; + bool flicker; + ParticleEngine* engine; + + float fadeR; + float fadeG; + float fadeB; + bool hasFade; + + public: + FireworksSparkParticle(Level* level, double x, double y, double z, + double xa, double ya, double za, + ParticleEngine* engine); + void setTrail(bool trail); + void setFlicker(bool flicker); + using Particle::setColor; + void setColor(int rgb); + void setFadeColor(int rgb); + virtual AABB* getCollideBox(); + virtual bool isPushable(); + virtual void render(Tesselator* t, float a, float xa, float ya, + float za, float xa2, float za2); + virtual void tick(); + virtual void setBaseTex(int baseTex); + virtual int getLightColor(float a); + virtual float getBrightness(float a); + }; + + class FireworksOverlayParticle : public Particle { + public: + virtual eINSTANCEOF GetType() { return eType_FIREWORKSOVERLAYPARTICLE; } + + FireworksOverlayParticle(Level* level, double x, double y, double z); + + void render(Tesselator* t, float a, float xa, float ya, float za, + float xa2, float za2); + }; +}; \ No newline at end of file diff --git a/Minecraft.Client/Rendering/Particles/FootstepParticle.cpp b/Minecraft.Client/Rendering/Particles/FootstepParticle.cpp index 40961989c..9f1dc5647 100644 --- a/Minecraft.Client/Rendering/Particles/FootstepParticle.cpp +++ b/Minecraft.Client/Rendering/Particles/FootstepParticle.cpp @@ -4,6 +4,10 @@ #include "../Tesselator.h" #include "../../../Minecraft.World/Util/Mth.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.h" +#include "../../Textures/ResourceLocation.h" + +ResourceLocation FootstepParticle::FOOTPRINT_LOCATION = + ResourceLocation(TN_MISC_FOOTSTEP); FootstepParticle::FootstepParticle(Textures* textures, Level* level, double x, double y, double z) @@ -36,7 +40,7 @@ void FootstepParticle::render(Tesselator* t, float a, float xa, float ya, float br = level->getBrightness(Mth::floor(x), Mth::floor(y), Mth::floor(z)); - textures->bindTexture(TN_MISC_FOOTSTEP); // L"/misc/footprint.png")); + textures->bindTexture(&FOOTPRINT_LOCATION); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/Minecraft.Client/Rendering/Particles/FootstepParticle.h b/Minecraft.Client/Rendering/Particles/FootstepParticle.h index 398b6addd..6f2b745a1 100644 --- a/Minecraft.Client/Rendering/Particles/FootstepParticle.h +++ b/Minecraft.Client/Rendering/Particles/FootstepParticle.h @@ -7,6 +7,7 @@ public: virtual eINSTANCEOF GetType() { return eType_FOOTSTEPPARTICLE; } private: + static ResourceLocation FOOTPRINT_LOCATION; int life; int lifeTime; Textures* textures; diff --git a/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.cpp b/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.cpp index eefda7f41..018204c5f 100644 --- a/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.cpp +++ b/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.cpp @@ -4,6 +4,10 @@ #include "../../Textures/Textures.h" #include "../Tesselator.h" #include "../Lighting.h" +#include "../../Textures/ResourceLocation.h" + +ResourceLocation HugeExplosionParticle::EXPLOSION_LOCATION = + ResourceLocation(TN_MISC_EXPLOSION); HugeExplosionParticle::HugeExplosionParticle(Textures* textures, Level* level, double x, double y, double z, @@ -33,7 +37,7 @@ void HugeExplosionParticle::render(Tesselator* t, float a, float xa, float ya, float za, float xa2, float za2) { int tex = (int)((life + a) * 15 / lifeTime); if (tex > 15) return; - textures->bindTexture(TN_MISC_EXPLOSION); // 4J was "/misc/explosion.png" + textures->bindTexture(&EXPLOSION_LOCATION); float u0 = (tex % 4) / 4.0f; float u1 = u0 + 0.999f / 4.0f; diff --git a/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.h b/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.h index 2c44d2148..8afab6869 100644 --- a/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.h +++ b/Minecraft.Client/Rendering/Particles/HugeExplosionParticle.h @@ -4,6 +4,7 @@ class HugeExplosionParticle : public Particle { private: + static ResourceLocation EXPLOSION_LOCATION; int life; int lifeTime; Textures* textures; diff --git a/Minecraft.Client/Rendering/Particles/Particle.cpp b/Minecraft.Client/Rendering/Particles/Particle.cpp index 8fea088a5..bbcadfb69 100644 --- a/Minecraft.Client/Rendering/Particles/Particle.cpp +++ b/Minecraft.Client/Rendering/Particles/Particle.cpp @@ -81,7 +81,17 @@ void Particle::setColor(float r, float g, float b) { this->bCol = b; } -void Particle::setAlpha(float alpha) { this->alpha = alpha; } +void Particle::setAlpha(float alpha) { + // 4J - brought forward from Java 1.8 + if (this->alpha == 1.0f && alpha < 1.0f) { + Minecraft::GetInstance()->particleEngine->markTranslucent( + std::dynamic_pointer_cast(shared_from_this())); + } else if (this->alpha < 1.0f && alpha == 1.0f) { + Minecraft::GetInstance()->particleEngine->markOpaque( + std::dynamic_pointer_cast(shared_from_this())); + } + this->alpha = alpha; +} float Particle::getRedCol() { return rCol; } diff --git a/Minecraft.Client/Rendering/Particles/ParticleEngine.cpp b/Minecraft.Client/Rendering/Particles/ParticleEngine.cpp index 2eb3e59cb..1959ad349 100644 --- a/Minecraft.Client/Rendering/Particles/ParticleEngine.cpp +++ b/Minecraft.Client/Rendering/Particles/ParticleEngine.cpp @@ -2,8 +2,10 @@ #include "ParticleEngine.h" #include "Particle.h" #include "../../Textures/Textures.h" +#include "../../Textures/TextureAtlas.h" #include "../Tesselator.h" #include "TerrainParticle.h" +#include "../../Textures/ResourceLocation.h" #include "../Camera.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.player.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" @@ -11,6 +13,9 @@ #include "../../../Minecraft.World/Util/StringHelpers.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.level.dimension.h" +ResourceLocation ParticleEngine::PARTICLES_LOCATION = + ResourceLocation(TN_PARTICLES); + ParticleEngine::ParticleEngine(Level* level, Textures* textures) { // if (level != NULL) // 4J - removed - we want level to be // initialised to *something* @@ -29,31 +34,51 @@ void ParticleEngine::add(std::shared_ptr p) { int l = p->level->dimension->id == 0 ? 0 : (p->level->dimension->id == -1 ? 1 : 2); - if ((t != DRAGON_BREATH_TEXTURE && - particles[l][t].size() >= MAX_PARTICLES_PER_LAYER) || - particles[l][t].size() >= MAX_DRAGON_BREATH_PARTICLES) - particles[l][t] - .pop_front(); // particles[l][t].erase(particles[l][t].begin()); - particles[l][t].push_back(p); + int maxParticles; + switch (p->GetType()) { + case eTYPE_DRAGONBREATHPARTICLE: + maxParticles = MAX_DRAGON_BREATH_PARTICLES; + break; + case eType_FIREWORKSSPARKPARTICLE: + maxParticles = MAX_FIREWORK_SPARK_PARTICLES; + break; + default: + maxParticles = MAX_PARTICLES_PER_LAYER; + break; + } + int list = p->getAlpha() != 1.0f + ? TRANSLUCENT_LIST + : OPAQUE_LIST; // 4J - Brought forward from Java 1.8 + + if (particles[l][t][list].size() >= maxParticles) { + particles[l][t][list].pop_front(); + } + particles[l][t][list].push_back(p); } void ParticleEngine::tick() { for (int l = 0; l < 3; l++) { for (int tt = 0; tt < TEXTURE_COUNT; tt++) { - for (unsigned int i = 0; i < particles[l][tt].size(); i++) { - std::shared_ptr p = particles[l][tt][i]; - p->tick(); - if (p->removed) { - particles[l][tt][i] = particles[l][tt].back(); - particles[l][tt].pop_back(); - i--; + for (int list = 0; list < LIST_COUNT; + list++) // 4J - Brought forward from Java 1.8 + { + for (unsigned int i = 0; i < particles[l][tt][list].size(); + i++) { + std::shared_ptr p = particles[l][tt][list][i]; + p->tick(); + if (p->removed) { + particles[l][tt][list][i] = + particles[l][tt][list].back(); + particles[l][tt][list].pop_back(); + i--; + } } } } } } -void ParticleEngine::render(std::shared_ptr player, float a) { +void ParticleEngine::render(std::shared_ptr player, float a, int list) { // 4J - change brought forward from 1.2.3 float xa = Camera::xa; float za = Camera::za; @@ -67,55 +92,61 @@ void ParticleEngine::render(std::shared_ptr player, float a) { Particle::zOff = (player->zOld + (player->z - player->zOld) * a); int l = level->dimension->id == 0 ? 0 : (level->dimension->id == -1 ? 1 : 2); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glAlphaFunc(GL_GREATER, 1.0f / 255.0f); + for (int tt = 0; tt < TEXTURE_COUNT; tt++) { if (tt == ENTITY_PARTICLE_TEXTURE) continue; - if (particles[l][tt].empty()) continue; - - MemSect(31); - if (tt == MISC_TEXTURE || tt == DRAGON_BREATH_TEXTURE) - textures->bindTexture(TN_PARTICLES); // 4J was L"/particles.png" - if (tt == TERRAIN_TEXTURE) - textures->bindTexture(TN_TERRAIN); // 4J was L"/terrain.png" - if (tt == ITEM_TEXTURE) - textures->bindTexture(TN_GUI_ITEMS); // 4J was L"/gui/items.png" - MemSect(0); - Tesselator* t = Tesselator::getInstance(); - glColor4f(1.0f, 1.0f, 1.0f, 1); -#if 0 - // Note that these changes were brought in from java (1.5ish), but as with the java version, break rendering of the particles - // next to water - removing for now - glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glAlphaFunc(GL_GREATER, 1.0f / 255.0f); -#endif - t->begin(); - for (unsigned int i = 0; i < particles[l][tt].size(); i++) { - if (t->hasMaxVertices()) { - t->end(); - t->begin(); + if (!particles[l][tt][list].empty()) { + switch (list) { + case TRANSLUCENT_LIST: + glDepthMask(false); + break; + case OPAQUE_LIST: + glDepthMask(true); + break; } - std::shared_ptr p = particles[l][tt][i]; - if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought - // forward from 1.8.2 - { - t->tex2(p->getLightColor(a)); + MemSect(31); + if (tt == MISC_TEXTURE || tt == DRAGON_BREATH_TEXTURE) + textures->bindTexture(&PARTICLES_LOCATION); + if (tt == TERRAIN_TEXTURE) + textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); + if (tt == ITEM_TEXTURE) + textures->bindTexture(&TextureAtlas::LOCATION_ITEMS); + MemSect(0); + Tesselator* t = Tesselator::getInstance(); + glColor4f(1.0f, 1.0f, 1.0f, 1); + + t->begin(); + for (unsigned int i = 0; i < particles[l][tt][list].size(); i++) { + if (t->hasMaxVertices()) { + t->end(); + t->begin(); + } + std::shared_ptr p = particles[l][tt][list][i]; + + if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought + // forward from 1.8.2 + { + t->tex2(p->getLightColor(a)); + } + p->render(t, a, xa, ya, za, xa2, za2); } - p->render(t, a, xa, ya, za, xa2, za2); + t->end(); } - t->end(); -#if 0 - // See comment in previous removed section - glDisable(GL_BLEND); - glDepthMask(true); - glAlphaFunc(GL_GREATER, .1f); -#endif } + + glDisable(GL_BLEND); + glDepthMask(true); + glAlphaFunc(GL_GREATER, .1f); } -void ParticleEngine::renderLit(std::shared_ptr player, float a) { +void ParticleEngine::renderLit(std::shared_ptr player, float a, + int list) { // 4J - added. We call this before ParticleEngine::render in the general // render per player, so if we don't set this here then the offsets will be // from the previous player - a single frame lag for the java game, or @@ -135,18 +166,19 @@ void ParticleEngine::renderLit(std::shared_ptr player, float a) { int l = level->dimension->id == 0 ? 0 : (level->dimension->id == -1 ? 1 : 2); int tt = ENTITY_PARTICLE_TEXTURE; - if (particles[l][tt].empty()) return; - Tesselator* t = Tesselator::getInstance(); - for (unsigned int i = 0; i < particles[l][tt].size(); i++) { - std::shared_ptr p = particles[l][tt][i]; + if (!particles[l][tt][list].empty()) { + Tesselator* t = Tesselator::getInstance(); + for (unsigned int i = 0; i < particles[l][tt][list].size(); i++) { + std::shared_ptr p = particles[l][tt][list][i]; - if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought forward - // from 1.8.2 - { - t->tex2(p->getLightColor(a)); + if (SharedConstants::TEXTURE_LIGHTING) // 4J - change brought + // forward from 1.8.2 + { + t->tex2(p->getLightColor(a)); + } + p->render(t, a, xa, ya, za, xa2, za2); } - p->render(t, a, xa, ya, za, xa2, za2); } } @@ -157,7 +189,9 @@ void ParticleEngine::setLevel(Level* level) { if (level == NULL) { for (int l = 0; l < 3; l++) { for (int tt = 0; tt < TEXTURE_COUNT; tt++) { - particles[l][tt].clear(); + for (int list = 0; list < LIST_COUNT; list++) { + particles[l][tt][list].clear(); + } } } } @@ -213,10 +247,38 @@ void ParticleEngine::crack(int x, int y, int z, int face) { ->scale(0.6f)); } +void ParticleEngine::markTranslucent(std::shared_ptr particle) { + moveParticleInList(particle, OPAQUE_LIST, TRANSLUCENT_LIST); +} + +void ParticleEngine::markOpaque(std::shared_ptr particle) { + moveParticleInList(particle, TRANSLUCENT_LIST, OPAQUE_LIST); +} + +void ParticleEngine::moveParticleInList(std::shared_ptr particle, + int source, int destination) { + int l = particle->level->dimension->id == 0 + ? 0 + : (particle->level->dimension->id == -1 ? 1 : 2); + for (int tt = 0; tt < TEXTURE_COUNT; tt++) { + AUTO_VAR(it, find(particles[l][tt][source].begin(), + particles[l][tt][source].end(), particle)); + if (it != particles[l][tt][source].end()) { + (*it) = particles[l][tt][source].back(); + particles[l][tt][source].pop_back(); + particles[l][tt][destination].push_back(particle); + } + } +} + std::wstring ParticleEngine::countParticles() { int l = level->dimension->id == 0 ? 0 : (level->dimension->id == -1 ? 1 : 2); - return _toString((int)(particles[l][0].size() + - particles[l][1].size() + - particles[l][2].size())); + int total = 0; + for (int tt = 0; tt < TEXTURE_COUNT; tt++) { + for (int list = 0; list < LIST_COUNT; list++) { + total += particles[l][tt][list].size(); + } + } + return _toString(total); } diff --git a/Minecraft.Client/Rendering/Particles/ParticleEngine.h b/Minecraft.Client/Rendering/Particles/ParticleEngine.h index 271bd90ca..2a9c7f8b2 100644 --- a/Minecraft.Client/Rendering/Particles/ParticleEngine.h +++ b/Minecraft.Client/Rendering/Particles/ParticleEngine.h @@ -8,8 +8,10 @@ class Random; class ParticleEngine { private: + static ResourceLocation PARTICLES_LOCATION; static const int MAX_PARTICLES_PER_LAYER = 200; // 4J - reduced from 4000 static const int MAX_DRAGON_BREATH_PARTICLES = 1000; + static const int MAX_FIREWORK_SPARK_PARTICLES = 2000; public: static const int MISC_TEXTURE = 0; @@ -17,16 +19,21 @@ public: static const int ITEM_TEXTURE = 2; static const int ENTITY_PARTICLE_TEXTURE = 3; static const int DRAGON_BREATH_TEXTURE = 4; // 4J Added - static const int TEXTURE_COUNT = 5; + // Brought forward from Java 1.8 + static const int TRANSLUCENT_LIST = 0; + static const int OPAQUE_LIST = 1; + static const int LIST_COUNT = 2; + protected: Level* level; private: std::deque > - particles[3][TEXTURE_COUNT]; // 4J made two arrays to cope with - // simultaneous two dimensions + particles[3][TEXTURE_COUNT] + [LIST_COUNT]; // 4J made three arrays to cope with + // simultaneous two dimensions Textures* textures; Random* random; @@ -35,10 +42,17 @@ public: ~ParticleEngine(); void add(std::shared_ptr p); void tick(); - void render(std::shared_ptr player, float a); - void renderLit(std::shared_ptr player, float a); + void render(std::shared_ptr player, float a, int list); + void renderLit(std::shared_ptr player, float a, int list); void setLevel(Level* level); void destroy(int x, int y, int z, int tid, int data); void crack(int x, int y, int z, int face); + + // 4J - Brought forward from Java 1.8 + void markTranslucent(std::shared_ptr particle); + void markOpaque(std::shared_ptr particle); + void moveParticleInList(std::shared_ptr particle, int source, + int destination); + std::wstring countParticles(); }; \ No newline at end of file