diff options
| author | qwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com> | 2026-03-05 17:17:45 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-05 17:17:45 -0600 |
| commit | 0666959d312dc74903f55d1071488a90239330f1 (patch) | |
| tree | 5c6886f7ec65a7828bc6e34a469514e418bcf78b /Minecraft.Client/GameRenderer.cpp | |
| parent | 9370cbc7d878df1615d8ce76bc459e8b414d0f19 (diff) | |
| parent | eed770b121aa4ce38f002db042d0137c24c6d344 (diff) | |
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.Client/GameRenderer.cpp')
| -rw-r--r-- | Minecraft.Client/GameRenderer.cpp | 395 |
1 files changed, 262 insertions, 133 deletions
diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index d3c5e8d3..390f114d 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -51,6 +51,7 @@ #include "TexturePackRepository.h" #include "TexturePack.h" #include "TextureAtlas.h" +#include "Common/PostProcesser.h" bool GameRenderer::anaglyph3d = false; int GameRenderer::anaglyphPass = 0; @@ -186,7 +187,7 @@ GameRenderer::~GameRenderer() } void GameRenderer::tick(bool first) // 4J - add bFirst -{ +{ tickFov(); tickLightTexture(); // 4J - change brought forward from 1.8.2 fogBrO = fogBr; @@ -308,11 +309,9 @@ void GameRenderer::pick(float a) vector<shared_ptr<Entity> > *objects = mc->level->getEntities(mc->cameraTargetPlayer, mc->cameraTargetPlayer->bb->expand(b->x * (range), b->y * (range), b->z * (range))->grow(overlap, overlap, overlap)); double nearest = dist; - AUTO_VAR(itEnd, objects->end()); - for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) - { - shared_ptr<Entity> e = *it; //objects->at(i); - if (!e->isPickable()) continue; + for (auto& e : *objects ) + { + if ( e == nullptr || !e->isPickable() ) continue; float rr = e->getPickRadius(); AABB *bb = e->bb->grow(rr, rr, rr); @@ -325,7 +324,7 @@ void GameRenderer::pick(float a) nearest = 0; } } - else if (p != NULL) + else if (p != nullptr) { double dd = from->distanceTo(p->pos); if (e == mc->cameraTargetPlayer->riding != NULL) @@ -335,7 +334,7 @@ void GameRenderer::pick(float a) hovered = e; } } - else + else { hovered = e; nearest = dd; @@ -595,7 +594,7 @@ void GameRenderer::unZoomRegion() 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 - // they are maybe be too generous for performance. + // they are maybe be too generous for performance. aspect = mc->width / (float) mc->height; fov = getFov(a, applyEffects); @@ -735,14 +734,14 @@ void GameRenderer::renderItemInHand(float a, int eye) bool bNoLegAnim =(localplayer->getAnimOverrideBitmask()&( (1<<HumanoidModel::eAnim_NoLegAnim) | (1<<HumanoidModel::eAnim_NoBobbing) ))!=0; if(app.GetGameSettings(localplayer->GetXboxPad(),eGameSetting_ViewBob) && !localplayer->abilities.flying && !bNoLegAnim) bobView(a); - // 4J: Skip hand rendering if render hand is off + // 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()) + if (!mc->options->hideGui && !mc->gameMode->isCutScene()) { turnOnLightLayer(a); PIXBeginNamedEvent(0,"Item in hand render"); @@ -770,7 +769,7 @@ void GameRenderer::renderItemInHand(float a, int eye) // 4J - change brought forward from 1.8.2 void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO -#if 0 +#if 0 if (SharedConstants::TEXTURE_LIGHTING) { glClientActiveTexture(GL_TEXTURE1); @@ -834,124 +833,253 @@ void GameRenderer::tickLightTexture() void GameRenderer::updateLightTexture(float a) { - // 4J-JEV: Now doing light textures on PER PLAYER basis. - // 4J - we *had* added separate light textures for all dimensions, and this loop to update them all here - for(int j = 0; j < XUSER_MAX_COUNT; j++ ) - { - // Loop over all the players - shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j]; - if (player == NULL) continue; - - Level *level = player->level; // 4J - was mc->level when it was just to update the one light texture - - float skyDarken1 = level->getSkyDarken((float) 1); - for (int i = 0; i < 256; i++) - { - float darken = skyDarken1 * 0.95f + 0.05f; - float sky = level->dimension->brightnessRamp[i / 16] * darken; - float block = level->dimension->brightnessRamp[i % 16] * (blr * 0.1f + 1.5f); - - if (level->skyFlashTime > 0) - { - sky = level->dimension->brightnessRamp[i / 16]; - } - - float rs = sky * (skyDarken1 * 0.65f + 0.35f); - float gs = sky * (skyDarken1 * 0.65f + 0.35f); - float bs = sky; - - float rb = block; - float gb = block * ((block * 0.6f + 0.4f) * 0.6f + 0.4f); - float bb = block * ((block * block) * 0.6f + 0.4f); - - float _r = (rs + rb); - float _g = (gs + gb); - float _b = (bs + bb); - - _r = _r * 0.96f + 0.03f; - _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); - _b = (0.25f + bb * 0.75f); - } - - if (player->hasEffect(MobEffect::nightVision)) - { - float scale = getNightVisionScale(player, a); - { - float dist = 1.0f / _r; - if (dist > (1.0f / _g)) - { - dist = (1.0f / _g); - } - if (dist > (1.0f / _b)) - { - dist = (1.0f / _b); - } - _r = _r * (1.0f - scale) + (_r * dist) * scale; - _g = _g * (1.0f - scale) + (_g * dist) * scale; - _b = _b * (1.0f - scale) + (_b * dist) * scale; - } - } - - if (_r > 1) _r = 1; - if (_g > 1) _g = 1; - if (_b > 1) _b = 1; - - float brightness = mc->options->gamma; - - float ir = 1 - _r; - float ig = 1 - _g; - float ib = 1 - _b; - ir = 1 - (ir * ir * ir * ir); - ig = 1 - (ig * ig * ig * ig); - ib = 1 - (ib * ib * ib * ib); - _r = _r * (1 - brightness) + ir * brightness; - _g = _g * (1 - brightness) + ig * brightness; - _b = _b * (1 - brightness) + ib * brightness; - - _r = _r * 0.96f + 0.03f; - _g = _g * 0.96f + 0.03f; - _b = _b * 0.96f + 0.03f; - - if (_r > 1) _r = 1; - if (_g > 1) _g = 1; - if (_b > 1) _b = 1; - if (_r < 0) _r = 0; - if (_g < 0) _g = 0; - if (_b < 0) _b = 0; - - int alpha = 255; - int r = (int) (_r * 255); - int g = (int) (_g * 255); - int b = (int) (_b * 255); + CachePlayerGammas(); + + for (int j = 0; j < XUSER_MAX_COUNT; j++) + { + shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j]; + if (player == nullptr) + continue; + + Level *level = player->level; + + const float skyDarken1 = level->getSkyDarken(1.0f); + for (int i = 0; i < 256; i++) + { + const float darken = skyDarken1 * 0.95f + 0.05f; + float sky = level->dimension->brightnessRamp[i / 16] * darken; + const float block = level->dimension->brightnessRamp[i % 16] * (blr * 0.1f + 1.5f); + + if (level->skyFlashTime < 0) + { + sky = level->dimension->brightnessRamp[i / 16]; + } + + const float rs = sky * (skyDarken1 * 0.65f + 0.35f); + const float gs = sky * (skyDarken1 * 0.65f + 0.35f); + const float bs = sky; + + const float rb = block; + const float gb = block * ((block * 0.6f + 0.4f) * 0.6f + 0.4f); + const float bb = block * ((block * block) * 0.6f + 0.4f); + + float _r = (rs + rb); + float _g = (gs + gb); + float _b = (bs + bb); + + _r = _r * 0.96f + 0.03f; + _g = _g * 0.96f + 0.03f; + _b = _b * 0.96f + 0.03f; + + if (darkenWorldAmount > 0) + { + const float amount = darkenWorldAmountO + (darkenWorldAmount - darkenWorldAmountO) * a; + _r = _r * (1.0f - amount) + (_r * 0.7f) * amount; + _g = _g * (1.0f - amount) + (_g * 0.6f) * amount; + _b = _b * (1.0f - amount) + (_b * 0.6f) * amount; + } + + if (level->dimension->id == 1) + { + _r = (0.22f + rb * 0.75f); + _g = (0.28f + gb * 0.75f); + _b = (0.25f + bb * 0.75f); + } + + if (player->hasEffect(MobEffect::nightVision)) + { + const float scale = getNightVisionScale(player, a); + float dist = 1.0f / _r; + if (dist > (1.0f / _g)) + dist = (1.0f / _g); + if (dist > (1.0f / _b)) + dist = (1.0f / _b); + _r = _r * (1.0f - scale) + (_r * dist) * scale; + _g = _g * (1.0f - scale) + (_g * dist) * scale; + _b = _b * (1.0f - scale) + (_b * dist) * scale; + } + + if (_r > 1.0f) + _r = 1.0f; + if (_r < 0.0f) + _r = 0.0f; + if (_g > 1.0f) + _g = 1.0f; + if (_g < 0.0f) + _g = 0.0f; + if (_b > 1.0f) + _b = 1.0f; + if (_b < 0.0f) + _b = 0.0f; + + constexpr int alpha = 255; + const int r = static_cast<int>(_r * 255); + const int g = static_cast<int>(_g * 255); + const int b = static_cast<int>(_b * 255); #if ( defined _DURANGO || defined _WIN64 || __PSVITA__ ) - lightPixels[j][i] = alpha << 24 | b << 16 | g << 8 | r; + lightPixels[j][i] = alpha << 24 | b << 16 | g << 8 | r; #elif ( defined _XBOX || defined __ORBIS__ ) - lightPixels[j][i] = alpha << 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 | alpha; + 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 + mc->textures->replaceTextureDirect(lightPixels[j], 16, 16, getLightTexture(j, level)); + } +} - //_updateLightTexture = false; - } +float GameRenderer::ComputeGammaFromSlider(float slider0to100) +{ + float slider = slider0to100; + slider = max(slider, 0.0f); + slider = min(slider, 100.0f); + + if (slider > 50.0f) + return 1.0f + (slider - 50.0f) / 50.0f * 3.0f; // 1.0 -> 4.0 + else + return 1.0f - (50.0f - slider) / 50.0f * 0.85f; // 1.0 -> 0.15 +} + +void GameRenderer::CachePlayerGammas() +{ + for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES; ++j) + { + std::shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j]; + if (!player) + { + m_cachedGammaPerPlayer[j] = 1.0f; + continue; + } + + const float slider = app.GetGameSettings(j, eGameSetting_Gamma); // 0..100 + m_cachedGammaPerPlayer[j] = ComputeGammaFromSlider(slider); + } +} + +bool GameRenderer::ComputeViewportForPlayer(int j, D3D11_VIEWPORT &outViewport) const +{ + int active = 0; + int indexMap[NUM_LIGHT_TEXTURES] = {-1, -1, -1, -1}; + for (int i = 0; i < XUSER_MAX_COUNT && i < NUM_LIGHT_TEXTURES; ++i) + { + if (Minecraft::GetInstance()->localplayers[i]) + indexMap[active++] = i; + } + + if (active <= 1) + { + outViewport.TopLeftX = 0.0f; + outViewport.TopLeftY = 0.0f; + outViewport.Width = static_cast<FLOAT>(mc->width); + outViewport.Height = static_cast<FLOAT>(mc->height); + outViewport.MinDepth = 0.0f; + outViewport.MaxDepth = 1.0f; + return true; + } + + int k = -1; + for (int ord = 0; ord < active; ++ord) + if (indexMap[ord] == j) + { + k = ord; + break; + } + if (k < 0) + return false; + + const float width = static_cast<float>(mc->width); + const float height = static_cast<float>(mc->height); + + if (active == 2) + { + const float halfH = height * 0.5f; + outViewport.TopLeftX = 0.0f; + outViewport.Width = width; + outViewport.MinDepth = 0.0f; + outViewport.MaxDepth = 1.0f; + if (k == 0) + { + outViewport.TopLeftY = 0.0f; + outViewport.Height = halfH; + } + else + { + outViewport.TopLeftY = halfH; + outViewport.Height = halfH; + } + return true; + } + else + { + const float halfW = width * 0.5f; + const float halfH = height * 0.5f; + const int row = (k >= 2) ? 1 : 0; + const int col = (k % 2); + outViewport.TopLeftX = col ? halfW : 0.0f; + outViewport.TopLeftY = row ? halfH : 0.0f; + outViewport.Width = halfW; + outViewport.Height = halfH; + outViewport.MinDepth = 0.0f; + outViewport.MaxDepth = 1.0f; + return true; + } +} + +uint32_t GameRenderer::BuildPlayerViewports(D3D11_VIEWPORT *outViewports, float *outGammas, UINT maxCount) const +{ + UINT count = 0; + for (int j = 0; j < XUSER_MAX_COUNT && j < NUM_LIGHT_TEXTURES && count < maxCount; ++j) + { + if (!Minecraft::GetInstance()->localplayers[j]) + continue; + D3D11_VIEWPORT vp; + if (!ComputeViewportForPlayer(j, vp)) + continue; + outViewports[count] = vp; + outGammas[count] = m_cachedGammaPerPlayer[j]; + ++count; + } + return count; +} + +void GameRenderer::ApplyGammaPostProcess() const +{ + D3D11_VIEWPORT vps[NUM_LIGHT_TEXTURES]; + float gammas[NUM_LIGHT_TEXTURES]; + const UINT n = BuildPlayerViewports(vps, gammas, NUM_LIGHT_TEXTURES); + if (n == 0) + return; + + bool anyEffect = false; + for (UINT i = 0; i < n; ++i) + { + if (gammas[i] < 0.99f || gammas[i] > 1.01f) + { + anyEffect = true; + break; + } + } + if (!anyEffect) + return; + + if (n == 1) + { + PostProcesser::GetInstance().SetGamma(gammas[0]); + PostProcesser::GetInstance().Apply(); + } + else + { + PostProcesser::GetInstance().CopyBackbuffer(); + for (UINT i = 0; i < n; ++i) + { + PostProcesser::GetInstance().SetGamma(gammas[i]); + PostProcesser::GetInstance().SetViewport(vps[i]); + PostProcesser::GetInstance().ApplyFromCopied(); + } + PostProcesser::GetInstance().ResetViewport(); + } } float GameRenderer::getNightVisionScale(shared_ptr<Player> player, float a) @@ -1041,6 +1169,7 @@ void GameRenderer::render(float a, bool bFirst) lastNsTime = System::nanoTime(); + ApplyGammaPostProcess(); if (!mc->options->hideGui || mc->screen != NULL) { @@ -1111,7 +1240,7 @@ int GameRenderer::runUpdate(LPVOID lpParam) Vec3::CreateNewThreadStorage(); AABB::CreateNewThreadStorage(); IntCache::CreateNewThreadStorage(); - Tesselator::CreateNewThreadStorage(1024*1024); + Tesselator::CreateNewThreadStorage(1024*1024); Compression::UseDefaultThreadStorage(); RenderManager.InitialiseContext(); #ifdef _LARGE_WORLDS @@ -1185,7 +1314,7 @@ int GameRenderer::runUpdate(LPVOID lpParam) AABB::resetPool(); Vec3::resetPool(); - IntCache::Reset(); + IntCache::Reset(); m_updateEvents->Set(eUpdateEventIsFinished); } @@ -1217,7 +1346,7 @@ void GameRenderer::DisableUpdateThread() if( !updateRunning) return; app.DebugPrintf("------------------DisableUpdateThread--------------------\n"); updateRunning = false; - m_updateEvents->Clear(eUpdateCanRun); + m_updateEvents->Clear(eUpdateCanRun); m_updateEvents->WaitForSingle(eUpdateEventIsFinished,INFINITE); #endif } @@ -1588,7 +1717,7 @@ void GameRenderer::renderSnowAndRain(float a) turnOnLightLayer(a); - if (rainXa == NULL) + if (rainXa == NULL) { rainXa = new float[32 * 32]; rainZa = new float[32 * 32]; @@ -1709,9 +1838,9 @@ void GameRenderer::renderSnowAndRain(float a) float Alpha = ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel; int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; t->tileRainQuad(x - xa + 0.5, yy0, z - za + 0.5, 0 * s, yy0 * s / 4.0f + ra * s, - x + xa + 0.5, yy0, z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s, - x + xa + 0.5, yy1, z + za + 0.5, 1 * s, yy1 * s / 4.0f + ra * s, - x - xa + 0.5, yy1, z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s, + x + xa + 0.5, yy0, z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s, + x + xa + 0.5, yy1, z + za + 0.5, 1 * s, yy1 * s / 4.0f + ra * s, + x - xa + 0.5, yy1, z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s, br, br, br, Alpha, br, br, br, 0, tex2); #else t->tex2(level->getLightColor(x, yl, z, 0)); @@ -1747,9 +1876,9 @@ void GameRenderer::renderSnowAndRain(float a) float Alpha = ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel; int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; t->tileRainQuad(x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, yy0 * s / 4.0f + ra * s + vo, - x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, yy0 * s / 4.0f + ra * s + vo, - x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, yy1 * s / 4.0f + ra * s + vo, - x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, yy1 * s / 4.0f + ra * s + vo, + x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, yy0 * s / 4.0f + ra * s + vo, + x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, yy1 * s / 4.0f + ra * s + vo, + x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, yy1 * s / 4.0f + ra * s + vo, br, br, br, Alpha, br, br, br, Alpha, tex2); #else t->tex2((level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4); |
