the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 2104 lines 62 kB view raw
1#include "stdafx.h" 2#include "GameRenderer.h" 3#include "ItemInHandRenderer.h" 4#include "LevelRenderer.h" 5#include "Frustum.h" 6#include "FrustumCuller.h" 7#include "Textures.h" 8#include "Tesselator.h" 9#include "ParticleEngine.h" 10#include "SmokeParticle.h" 11#include "WaterDropParticle.h" 12#include "GameMode.h" 13#include "CreativeMode.h" 14#include "Lighting.h" 15#include "Options.h" 16#include "MultiplayerLocalPlayer.h" 17#include "GuiParticles.h" 18#include "MultiPlayerLevel.h" 19#include "Chunk.h" 20#include "..\Minecraft.World\net.minecraft.world.entity.h" 21#include "..\Minecraft.World\net.minecraft.world.entity.player.h" 22#include "..\Minecraft.World\net.minecraft.world.item.enchantment.h" 23#include "..\Minecraft.World\net.minecraft.world.level.h" 24#include "..\Minecraft.World\net.minecraft.world.level.material.h" 25#include "..\Minecraft.World\net.minecraft.world.level.tile.h" 26#include "..\Minecraft.World\net.minecraft.world.level.chunk.h" 27#include "..\Minecraft.World\net.minecraft.world.level.biome.h" 28#include "..\Minecraft.World\net.minecraft.world.level.dimension.h" 29#include "..\Minecraft.World\net.minecraft.world.phys.h" 30#include "..\Minecraft.World\System.h" 31#include "..\Minecraft.World\FloatBuffer.h" 32#include "..\Minecraft.World\ThreadName.h" 33#include "..\Minecraft.World\SparseLightStorage.h" 34#include "..\Minecraft.World\CompressedTileStorage.h" 35#include "..\Minecraft.World\SparseDataStorage.h" 36#include "..\Minecraft.World\JavaMath.h" 37#include "..\Minecraft.World\Facing.h" 38#include "..\Minecraft.World\MobEffect.h" 39#include "..\Minecraft.World\IntCache.h" 40#include "..\Minecraft.World\SmoothFloat.h" 41#include "..\Minecraft.World\MobEffectInstance.h" 42#include "..\Minecraft.World\Item.h" 43#include "Camera.h" 44#include "..\Minecraft.World\SoundTypes.h" 45#include "HumanoidModel.h" 46#include "..\Minecraft.World\Item.h" 47#include "..\Minecraft.World\compression.h" 48#include "PS3\PS3Extras\ShutdownManager.h" 49#include "BossMobGuiInfo.h" 50 51#include "TexturePackRepository.h" 52#include "TexturePack.h" 53#include "TextureAtlas.h" 54 55bool GameRenderer::anaglyph3d = false; 56int GameRenderer::anaglyphPass = 0; 57 58#ifdef MULTITHREAD_ENABLE 59C4JThread* GameRenderer::m_updateThread; 60C4JThread::EventArray* GameRenderer::m_updateEvents; 61bool GameRenderer::nearThingsToDo = false; 62bool GameRenderer::updateRunning = false; 63vector<byte *> GameRenderer::m_deleteStackByte; 64vector<SparseLightStorage *> GameRenderer::m_deleteStackSparseLightStorage; 65vector<CompressedTileStorage *> GameRenderer::m_deleteStackCompressedTileStorage; 66vector<SparseDataStorage *> GameRenderer::m_deleteStackSparseDataStorage; 67#endif 68CRITICAL_SECTION GameRenderer::m_csDeleteStack; 69 70ResourceLocation GameRenderer::RAIN_LOCATION = ResourceLocation(TN_ENVIRONMENT_RAIN); 71ResourceLocation GameRenderer::SNOW_LOCATION = ResourceLocation(TN_ENVIRONMENT_SNOW); 72 73GameRenderer::GameRenderer(Minecraft *mc) 74{ 75 // 4J - added this block of initialisers 76 renderDistance = 0; 77 _tick = 0; 78 hovered = nullptr; 79 thirdDistance = 4; 80 thirdDistanceO = 4; 81 thirdRotation = 0; 82 thirdRotationO = 0; 83 thirdTilt = 0; 84 thirdTiltO = 0; 85 86 accumulatedSmoothXO = 0; 87 accumulatedSmoothYO = 0; 88 tickSmoothXO = 0; 89 tickSmoothYO = 0; 90 lastTickA = 0; 91 92 cameraPos = Vec3::newPermanent(0.0f,0.0f,0.0f); 93 94 fovOffset = 0; 95 fovOffsetO = 0; 96 cameraRoll = 0; 97 cameraRollO = 0; 98 for( int i = 0; i < 4; i++ ) 99 { 100 fov[i] = 0.0f; 101 oFov[i] = 0.0f; 102 tFov[i] = 0.0f; 103 } 104 isInClouds = false; 105 zoom = 1; 106 zoom_x = 0; 107 zoom_y = 0; 108 rainXa = NULL; 109 rainZa = NULL; 110 lastActiveTime = Minecraft::currentTimeMillis(); 111 lastNsTime = 0; 112 random = new Random(); 113 rainSoundTime = 0; 114 xMod = 0; 115 yMod = 0; 116 lb = MemoryTracker::createFloatBuffer(16); 117 fr = 0.0f; 118 fg = 0.0f; 119 fb = 0.0f; 120 fogBrO = 0.0f; 121 fogBr = 0.0f; 122 cameraFlip = 0; 123 _updateLightTexture = false; 124 blr = 0.0f; 125 blrt = 0.0f; 126 blg = 0.0f; 127 blgt = 0.0f; 128 129 darkenWorldAmount = 0.0f; 130 darkenWorldAmountO = 0.0f; 131 132 m_fov=70.0f; 133 134 // 4J Stu - Init these so they are setup before the tick 135 for( int i = 0; i < 4; i++ ) 136 { 137 fov[i] = oFov[i] = 1.0f; 138 } 139 140 this->mc = mc; 141 itemInHandRenderer = NULL; 142 143 // 4J-PB - set up the local players iteminhand renderers here - needs to be done with lighting enabled so that the render geometry gets compiled correctly 144 glEnable(GL_LIGHTING); 145 mc->localitemInHandRenderers[0] = new ItemInHandRenderer(mc);//itemInHandRenderer; 146 mc->localitemInHandRenderers[1] = new ItemInHandRenderer(mc); 147 mc->localitemInHandRenderers[2] = new ItemInHandRenderer(mc); 148 mc->localitemInHandRenderers[3] = new ItemInHandRenderer(mc); 149 glDisable(GL_LIGHTING); 150 151 // 4J - changes brought forward from 1.8.2 152 BufferedImage *img = new BufferedImage(16, 16, BufferedImage::TYPE_INT_RGB); 153 for( int i = 0; i < NUM_LIGHT_TEXTURES; i++ ) 154 { 155 lightTexture[i] = mc->textures->getTexture(img); // 4J - changed to one light texture per level to support split screen 156 } 157 delete img; 158#ifdef __PS3__ 159 // we're using the RSX now to upload textures to vram, so we need the main ram textures allocated from io space 160 for(int i=0;i<NUM_LIGHT_TEXTURES;i++) 161 lightPixels[i] = intArray((int*)RenderManager.allocIOMem(16*16*sizeof(int)), 16*16); 162#else 163 for(int i=0;i<NUM_LIGHT_TEXTURES;i++) 164 lightPixels[i] = intArray(16*16); 165#endif 166 167#ifdef MULTITHREAD_ENABLE 168 m_updateEvents = new C4JThread::EventArray(eUpdateEventCount, C4JThread::EventArray::e_modeAutoClear); 169 m_updateEvents->Set(eUpdateEventIsFinished); 170 171 InitializeCriticalSection(&m_csDeleteStack); 172 m_updateThread = new C4JThread(runUpdate, NULL, "Chunk update"); 173#ifdef __PS3__ 174 m_updateThread->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL); 175#endif// __PS3__ 176 m_updateThread->SetProcessor(CPU_CORE_CHUNK_UPDATE); 177 m_updateThread->Run(); 178#endif 179} 180 181// 4J Stu Added to go with 1.8.2 change 182GameRenderer::~GameRenderer() 183{ 184 if(rainXa != NULL) delete [] rainXa; 185 if(rainZa != NULL) delete [] rainZa; 186} 187 188void GameRenderer::tick(bool first) // 4J - add bFirst 189{ 190 tickFov(); 191 tickLightTexture(); // 4J - change brought forward from 1.8.2 192 fogBrO = fogBr; 193 thirdDistanceO = thirdDistance; 194 thirdRotationO = thirdRotation; 195 thirdTiltO = thirdTilt; 196 fovOffsetO = fovOffset; 197 cameraRollO = cameraRoll; 198 199 if (mc->options->smoothCamera) 200 { 201 // update player view in tick() instead of render() to maintain 202 // camera movement regardless of FPS 203 float ss = mc->options->sensitivity * 0.6f + 0.2f; 204 float sens = (ss * ss * ss) * 8; 205 tickSmoothXO = smoothTurnX.getNewDeltaValue(accumulatedSmoothXO, 0.05f * sens); 206 tickSmoothYO = smoothTurnY.getNewDeltaValue(accumulatedSmoothYO, 0.05f * sens); 207 lastTickA = 0; 208 209 accumulatedSmoothXO = 0; 210 accumulatedSmoothYO = 0; 211 } 212 213 if (mc->cameraTargetPlayer == NULL) 214 { 215 mc->cameraTargetPlayer = dynamic_pointer_cast<Mob>(mc->player); 216 } 217 218 float brr = mc->level->getBrightness(Mth::floor(mc->cameraTargetPlayer->x), Mth::floor(mc->cameraTargetPlayer->y), Mth::floor(mc->cameraTargetPlayer->z)); 219 float whiteness = (3 - mc->options->viewDistance) / 3.0f; 220 float fogBrT = brr * (1 - whiteness) + whiteness; 221 fogBr += (fogBrT - fogBr) * 0.1f; 222 223 itemInHandRenderer->tick(); 224 225 PIXBeginNamedEvent(0,"Rain tick"); 226 tickRain(); 227 PIXEndNamedEvent(); 228 229 darkenWorldAmountO = darkenWorldAmount; 230 if (BossMobGuiInfo::darkenWorld) 231 { 232 darkenWorldAmount += 1.0f / ((float) SharedConstants::TICKS_PER_SECOND * 1); 233 if (darkenWorldAmount > 1) 234 { 235 darkenWorldAmount = 1; 236 } 237 BossMobGuiInfo::darkenWorld = false; 238 } 239 else if (darkenWorldAmount > 0) 240 { 241 darkenWorldAmount -= 1.0f / ((float) SharedConstants::TICKS_PER_SECOND * 4); 242 } 243 244 if( mc->player != mc->localplayers[ProfileManager.GetPrimaryPad()] ) return; // 4J added for split screen - only do rest of processing for once per frame 245 246 _tick++; 247} 248 249void GameRenderer::pick(float a) 250{ 251 if (mc->cameraTargetPlayer == NULL) return; 252 if (mc->level == NULL) return; 253 254 mc->crosshairPickMob = nullptr; 255 256 double range = mc->gameMode->getPickRange(); 257 delete mc->hitResult; 258 MemSect(31); 259 mc->hitResult = mc->cameraTargetPlayer->pick(range, a); 260 MemSect(0); 261 262 // 4J - added - stop blocks right at the edge of the world from being pickable so we shouldn't be able to directly destroy or create anything there 263 if( mc->hitResult ) 264 { 265 int maxxz = ( ( mc->level->chunkSource->m_XZSize / 2 ) * 16 ) - 2; 266 int minxz = ( -( mc->level->chunkSource->m_XZSize / 2 ) * 16 ) + 1; 267 268 // Don't select the tops of the very edge blocks, or the sides of the next blocks in 269 // 4J Stu - Only block the sides that are facing an outside block 270 int hitx = mc->hitResult->x; 271 int hitz = mc->hitResult->z; 272 int face = mc->hitResult->f; 273 if( face == Facing::WEST && hitx < 0 ) hitx -= 1; 274 if( face == Facing::EAST && hitx > 0 ) hitx += 1; 275 if( face == Facing::NORTH && hitz < 0 ) hitz -= 1; 276 if( face == Facing::SOUTH && hitz > 0 ) hitz += 1; 277 278 if( ( hitx < minxz ) || ( hitx > maxxz) || 279 ( hitz < minxz ) || ( hitz > maxxz) ) 280 { 281 delete mc->hitResult; 282 mc->hitResult = NULL; 283 } 284 } 285 286 double dist = range; 287 Vec3 *from = mc->cameraTargetPlayer->getPos(a); 288 289 if (mc->gameMode->hasFarPickRange()) 290 { 291 dist = range = 6; 292 } 293 else 294 { 295 if (dist > 3) dist = 3; 296 range = dist; 297 } 298 299 if (mc->hitResult != NULL) 300 { 301 dist = mc->hitResult->pos->distanceTo(from); 302 } 303 304 Vec3 *b = mc->cameraTargetPlayer->getViewVector(a); 305 Vec3 *to = from->add(b->x * range, b->y * range, b->z * range); 306 hovered = nullptr; 307 float overlap = 1; 308 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)); 309 double nearest = dist; 310 311 AUTO_VAR(itEnd, objects->end()); 312 for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) 313 { 314 shared_ptr<Entity> e = *it; //objects->at(i); 315 if (!e->isPickable()) continue; 316 317 float rr = e->getPickRadius(); 318 AABB *bb = e->bb->grow(rr, rr, rr); 319 HitResult *p = bb->clip(from, to); 320 if (bb->contains(from)) 321 { 322 if (0 < nearest || nearest == 0) 323 { 324 hovered = e; 325 nearest = 0; 326 } 327 } 328 else if (p != NULL) 329 { 330 double dd = from->distanceTo(p->pos); 331 if (e == mc->cameraTargetPlayer->riding != NULL) 332 { 333 if (nearest == 0) 334 { 335 hovered = e; 336 } 337 } 338 else 339 { 340 hovered = e; 341 nearest = dd; 342 } 343 } 344 delete p; 345 } 346 347 if (hovered != NULL) 348 { 349 if (nearest < dist || (mc->hitResult == NULL)) 350 { 351 if( mc->hitResult != NULL ) 352 delete mc->hitResult; 353 mc->hitResult = new HitResult(hovered); 354 if (hovered->instanceof(eTYPE_LIVINGENTITY)) 355 { 356 mc->crosshairPickMob = dynamic_pointer_cast<LivingEntity>(hovered); 357 } 358 } 359 } 360} 361 362void GameRenderer::SetFovVal(float fov) 363{ 364 m_fov=fov; 365} 366 367float GameRenderer::GetFovVal() 368{ 369 return m_fov; 370} 371 372void GameRenderer::tickFov() 373{ 374 shared_ptr<LocalPlayer>player = dynamic_pointer_cast<LocalPlayer>(mc->cameraTargetPlayer); 375 376 int playerIdx = player ? player->GetXboxPad() : 0; 377 tFov[playerIdx] = player->getFieldOfViewModifier(); 378 379 oFov[playerIdx] = fov[playerIdx]; 380 fov[playerIdx] += (tFov[playerIdx] - fov[playerIdx]) * 0.5f; 381 382 if (fov[playerIdx] > 1.5f) fov[playerIdx] = 1.5f; 383 if (fov[playerIdx] < 0.1f) fov[playerIdx] = 0.1f; 384} 385 386float GameRenderer::getFov(float a, bool applyEffects) 387{ 388 if (cameraFlip > 0 ) return 90; 389 390 shared_ptr<LocalPlayer> player = dynamic_pointer_cast<LocalPlayer>(mc->cameraTargetPlayer); 391 int playerIdx = player ? player->GetXboxPad() : 0; 392 float fov = m_fov;//70; 393 if (applyEffects) 394 { 395 fov += mc->options->fov * 40; 396 fov *= oFov[playerIdx] + (this->fov[playerIdx] - oFov[playerIdx]) * a; 397 } 398 if (player->getHealth() <= 0) 399 { 400 float duration = player->deathTime + a; 401 402 fov /= ((1 - 500 / (duration + 500)) * 2.0f + 1); 403 } 404 405 int t = Camera::getBlockAt(mc->level, player, a); 406 if (t != 0 && Tile::tiles[t]->material == Material::water) fov = fov * 60 / 70; 407 408 return fov + fovOffsetO + (fovOffset - fovOffsetO) * a; 409 410} 411 412void GameRenderer::bobHurt(float a) 413{ 414 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 415 416 float hurt = player->hurtTime - a; 417 418 if (player->getHealth() <= 0) 419 { 420 float duration = player->deathTime + a; 421 422 glRotatef(40 - (40 * 200) / (duration + 200), 0, 0, 1); 423 } 424 425 if (hurt < 0) return; 426 hurt /= player->hurtDuration; 427 hurt = (float) Mth::sin(hurt * hurt * hurt * hurt * PI); 428 429 float rr = player->hurtDir; 430 431 432 glRotatef(-rr, 0, 1, 0); 433 glRotatef(-hurt * 14, 0, 0, 1); 434 glRotatef(+rr, 0, 1, 0); 435 436} 437 438void GameRenderer::bobView(float a) 439{ 440 if (!mc->cameraTargetPlayer->instanceof(eTYPE_LIVINGENTITY)) return; 441 442 shared_ptr<Player> player = dynamic_pointer_cast<Player>(mc->cameraTargetPlayer); 443 444 float wda = player->walkDist - player->walkDistO; 445 float b = -(player->walkDist + wda * a); 446 float bob = player->oBob + (player->bob - player->oBob) * a; 447 float tilt = player->oTilt + (player->tilt - player->oTilt) * a; 448 glTranslatef((float) Mth::sin(b * PI) * bob * 0.5f, -(float) abs(Mth::cos(b * PI) * bob), 0); 449 glRotatef((float) Mth::sin(b * PI) * bob * 3, 0, 0, 1); 450 glRotatef((float) abs(Mth::cos(b * PI - 0.2f) * bob) * 5, 1, 0, 0); 451 glRotatef((float) tilt, 1, 0, 0); 452} 453 454void GameRenderer::moveCameraToPlayer(float a) 455{ 456 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 457 shared_ptr<LocalPlayer> localplayer = dynamic_pointer_cast<LocalPlayer>(mc->cameraTargetPlayer); 458 float heightOffset = player->heightOffset - 1.62f; 459 460 double x = player->xo + (player->x - player->xo) * a; 461 double y = player->yo + (player->y - player->yo) * a - heightOffset; 462 double z = player->zo + (player->z - player->zo) * a; 463 464 465 glRotatef(cameraRollO + (cameraRoll - cameraRollO) * a, 0, 0, 1); 466 467 if (player->isSleeping()) 468 { 469 heightOffset += 1.0; 470 glTranslatef(0.0f, 0.3f, 0); 471 if (!mc->options->fixedCamera) 472 { 473 int t = mc->level->getTile(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); 474 if (t == Tile::bed_Id) 475 { 476 int data = mc->level->getData(Mth::floor(player->x), Mth::floor(player->y), Mth::floor(player->z)); 477 478 int direction = data & 3; 479 glRotatef((float)direction * 90,0.0f, 1.0f, 0.0f); 480 } 481 glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, -1, 0); 482 glRotatef(player->xRotO + (player->xRot - player->xRotO) * a, -1, 0, 0); 483 } 484 } 485 // 4J-PB - changing this to be per player 486 //else if (mc->options->thirdPersonView) 487 else if (localplayer->ThirdPersonView()) 488 { 489 double cameraDist = thirdDistanceO + (thirdDistance - thirdDistanceO) * a; 490 491 if (mc->options->fixedCamera) 492 { 493 494 float rotationY = thirdRotationO + (thirdRotation - thirdRotationO) * a; 495 float xRot = thirdTiltO + (thirdTilt - thirdTiltO) * a; 496 497 glTranslatef(0, 0, (float) -cameraDist); 498 glRotatef(xRot, 1, 0, 0); 499 glRotatef(rotationY, 0, 1, 0); 500 } 501 else 502 { 503 // 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 504 float playerYRot = player->yRotO + (player->yRot - player->yRotO) * a; 505 float playerXRot = player->xRotO + (player->xRot - player->xRotO) * a; 506 float yRot = playerYRot; 507 float xRot = playerXRot; 508 509 // Thirdperson view values are now 0 for disabled, 1 for original mode, 2 for reversed. 510 if( localplayer->ThirdPersonView() == 2 ) 511 { 512 // Reverse x rotation - note that this is only used in doing collision to calculate our view 513 // distance, the actual rotation itself is just below this else {} block 514 xRot += 180.0f; 515 } 516 517 double xd = -Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist; 518 double zd = Mth::cos(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI) * cameraDist; 519 double yd = -Mth::sin(xRot / 180 * PI) * cameraDist; 520 521 for (int i = 0; i < 8; i++) 522 { 523 float xo = (float)((i & 1) * 2 - 1); 524 float yo = (float)(((i >> 1) & 1) * 2 - 1); 525 float zo = (float)(((i >> 2) & 1) * 2 - 1); 526 527 xo *= 0.1f; 528 yo *= 0.1f; 529 zo *= 0.1f; 530 531 // 4J - corrected bug here where zo was also added to x component 532 HitResult *hr = mc->level->clip(Vec3::newTemp(x + xo, y + yo, z + zo), Vec3::newTemp(x - xd + xo, y - yd + yo, z - zd + zo)); 533 if (hr != NULL) 534 { 535 double dist = hr->pos->distanceTo(Vec3::newTemp(x, y, z)); 536 if (dist < cameraDist) cameraDist = dist; 537 delete hr; 538 } 539 } 540 541 if ( localplayer->ThirdPersonView() == 2) 542 { 543 glRotatef(180, 0, 1, 0); 544 } 545 546 glRotatef(playerXRot - xRot, 1, 0, 0); 547 glRotatef(playerYRot - yRot, 0, 1, 0); 548 glTranslatef(0, 0, (float) -cameraDist); 549 glRotatef(yRot - playerYRot, 0, 1, 0); 550 glRotatef(xRot - playerXRot, 1, 0, 0); 551 } 552 } 553 else 554 { 555 glTranslatef(0, 0, -0.1f); 556 } 557 558 if (!mc->options->fixedCamera) 559 { 560 glRotatef(player->xRotO + (player->xRot - player->xRotO) * a, 1, 0, 0); 561 glRotatef(player->yRotO + (player->yRot - player->yRotO) * a + 180, 0, 1, 0); 562 } 563 564 glTranslatef(0, heightOffset, 0); 565 566 x = player->xo + (player->x - player->xo) * a; 567 y = player->yo + (player->y - player->yo) * a - heightOffset; 568 z = player->zo + (player->z - player->zo) * a; 569 570 isInClouds = mc->levelRenderer->isInCloud(x, y, z, a); 571 572} 573 574 575void GameRenderer::zoomRegion(double zoom, double xa, double ya) 576{ 577 zoom = zoom; 578 zoom_x = xa; 579 zoom_y = ya; 580} 581 582void GameRenderer::unZoomRegion() 583{ 584 zoom = 1; 585} 586 587// 4J added as we have more complex adjustments to make for fov & aspect on account of viewports 588void GameRenderer::getFovAndAspect(float& fov, float& aspect, float a, bool applyEffects) 589{ 590 // 4J - split out aspect ratio and fov here so we can adjust for viewports - we might need to revisit these as 591 // they are maybe be too generous for performance. 592 aspect = mc->width / (float) mc->height; 593 fov = getFov(a, applyEffects); 594 595 if( ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_TOP ) || 596 ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_BOTTOM ) ) 597 { 598 aspect *= 2.0f; 599 fov *= 0.7f; // Reduce FOV to make things less fish-eye, at the expense of reducing vertical FOV from single player mode 600 } 601 else if( ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_LEFT ) || 602 ( mc->player->m_iScreenSection == C4JRender::VIEWPORT_TYPE_SPLIT_RIGHT) ) 603 { 604 // Ideally I'd like to make the fov bigger here, but if I do then you an see that the arm isn't very long... 605 aspect *= 0.5f; 606 } 607} 608 609void GameRenderer::setupCamera(float a, int eye) 610{ 611 renderDistance = (float)(16 * 16 >> (mc->options->viewDistance)); 612 glMatrixMode(GL_PROJECTION); 613 glLoadIdentity(); 614 615 float stereoScale = 0.07f; 616 if (mc->options->anaglyph3d) glTranslatef(-(eye * 2 - 1) * stereoScale, 0, 0); 617 618 // 4J - have split out fov & aspect calculation so we can take into account viewports 619 float aspect, fov; 620 getFovAndAspect(fov, aspect, a, true); 621 622 if (zoom != 1) 623 { 624 glTranslatef((float) zoom_x, (float) -zoom_y, 0); 625 glScaled(zoom, zoom, 1); 626 } 627 gluPerspective(fov, aspect, 0.05f, renderDistance * 2); 628 629 if (mc->gameMode->isCutScene()) 630 { 631 float s = 1 / 1.5f; 632 glScalef(1, s, 1); 633 } 634 635 glMatrixMode(GL_MODELVIEW); 636 glLoadIdentity(); 637 if (mc->options->anaglyph3d) glTranslatef((eye * 2 - 1) * 0.10f, 0, 0); 638 639 bobHurt(a); 640 641 // 4J-PB - this is a per-player option 642 //if (mc->options->bobView) bobView(a); 643 644 bool bNoLegAnim =(mc->player->getAnimOverrideBitmask()&(1<<HumanoidModel::eAnim_NoLegAnim))!=0; 645 bool bNoBobbingAnim =(mc->player->getAnimOverrideBitmask()&(1<<HumanoidModel::eAnim_NoBobbing))!=0; 646 647 if(app.GetGameSettings(mc->player->GetXboxPad(),eGameSetting_ViewBob) && !mc->player->abilities.flying && !bNoLegAnim && !bNoBobbingAnim) bobView(a); 648 649 float pt = mc->player->oPortalTime + (mc->player->portalTime - mc->player->oPortalTime) * a; 650 if (pt > 0) 651 { 652 int multiplier = 20; 653 if (mc->player->hasEffect(MobEffect::confusion)) 654 { 655 multiplier = 7; 656 } 657 658 float skew = 5 / (pt * pt + 5) - pt * 0.04f; 659 skew *= skew; 660 glRotatef((_tick + a) * multiplier, 0, 1, 1); 661 glScalef(1 / skew, 1, 1); 662 glRotatef(-(_tick + a) * multiplier, 0, 1, 1); 663 } 664 665 666 moveCameraToPlayer(a); 667 668 if (cameraFlip > 0) 669 { 670 int i = cameraFlip - 1; 671 if (i == 1) glRotatef(90, 0, 1, 0); 672 if (i == 2) glRotatef(180, 0, 1, 0); 673 if (i == 3) glRotatef(-90, 0, 1, 0); 674 if (i == 4) glRotatef(90, 1, 0, 0); 675 if (i == 5) glRotatef(-90, 1, 0, 0); 676 } 677} 678 679void GameRenderer::renderItemInHand(float a, int eye) 680{ 681 if (cameraFlip > 0) return; 682 683 // 4J-JEV: I'm fairly confident this method would crash if the cameratarget isnt a local player anyway, but oh well. 684 shared_ptr<LocalPlayer> localplayer = mc->cameraTargetPlayer->instanceof(eTYPE_LOCALPLAYER) ? dynamic_pointer_cast<LocalPlayer>(mc->cameraTargetPlayer) : nullptr; 685 686 bool renderHand = true; 687 688 // 4J-PB - to turn off the hand for screenshots, but not when the item held is a map 689 if ( localplayer!=NULL) 690 { 691 shared_ptr<ItemInstance> item = localplayer->inventory->getSelected(); 692 if(!(item && item->getItem()->id==Item::map_Id) && app.GetGameSettings(localplayer->GetXboxPad(),eGameSetting_DisplayHand)==0 ) renderHand = false; 693 } 694 695 glMatrixMode(GL_PROJECTION); 696 glLoadIdentity(); 697 698 float stereoScale = 0.07f; 699 if (mc->options->anaglyph3d) glTranslatef(-(eye * 2 - 1) * stereoScale, 0, 0); 700 701 // 4J - have split out fov & aspect calculation so we can take into account viewports 702 float fov, aspect; 703 getFovAndAspect(fov, aspect, a, false); 704 705 if (zoom != 1) 706 { 707 glTranslatef((float) zoom_x, (float) -zoom_y, 0); 708 glScaled(zoom, zoom, 1); 709 } 710 gluPerspective(fov, aspect, 0.05f, renderDistance * 2); 711 712 if (mc->gameMode->isCutScene()) 713 { 714 float s = 1 / 1.5f; 715 glScalef(1, s, 1); 716 } 717 718 glMatrixMode(GL_MODELVIEW); 719 720 glLoadIdentity(); 721 if (mc->options->anaglyph3d) glTranslatef((eye * 2 - 1) * 0.10f, 0, 0); 722 723 glPushMatrix(); 724 bobHurt(a); 725 726 // 4J-PB - changing this to be per player 727 //if (mc->options->bobView) bobView(a); 728 bool bNoLegAnim =(localplayer->getAnimOverrideBitmask()&( (1<<HumanoidModel::eAnim_NoLegAnim) | (1<<HumanoidModel::eAnim_NoBobbing) ))!=0; 729 if(app.GetGameSettings(localplayer->GetXboxPad(),eGameSetting_ViewBob) && !localplayer->abilities.flying && !bNoLegAnim) bobView(a); 730 731 // 4J: Skip hand rendering if render hand is off 732 if (renderHand) 733 { 734 // 4J-PB - changing this to be per player 735 //if (!mc->options->thirdPersonView && !mc->cameraTargetPlayer->isSleeping()) 736 if (!localplayer->ThirdPersonView() && !mc->cameraTargetPlayer->isSleeping()) 737 { 738 if (!mc->options->hideGui && !mc->gameMode->isCutScene()) 739 { 740 turnOnLightLayer(a); 741 PIXBeginNamedEvent(0,"Item in hand render"); 742 itemInHandRenderer->render(a); 743 PIXEndNamedEvent(); 744 turnOffLightLayer(a); 745 } 746 } 747 } 748 glPopMatrix(); 749 750 // 4J-PB - changing this to be per player 751 //if (!mc->options->thirdPersonView && !mc->cameraTargetPlayer->isSleeping()) 752 if (!localplayer->ThirdPersonView() && !mc->cameraTargetPlayer->isSleeping()) 753 { 754 itemInHandRenderer->renderScreenEffect(a); 755 bobHurt(a); 756 } 757 758 // 4J-PB - changing this to be per player 759 //if (mc->options->bobView) bobView(a); 760 if(app.GetGameSettings(localplayer->GetXboxPad(),eGameSetting_ViewBob) && !localplayer->abilities.flying && !bNoLegAnim) bobView(a); 761} 762 763// 4J - change brought forward from 1.8.2 764void GameRenderer::turnOffLightLayer(double alpha) 765{ // 4J - TODO 766#if 0 767 if (SharedConstants::TEXTURE_LIGHTING) 768 { 769 glClientActiveTexture(GL_TEXTURE1); 770 glActiveTexture(GL_TEXTURE1); 771 glDisable(GL_TEXTURE_2D); 772 glClientActiveTexture(GL_TEXTURE0); 773 glActiveTexture(GL_TEXTURE0); 774 } 775#endif 776 RenderManager.TextureBindVertex(-1); 777} 778 779// 4J - change brought forward from 1.8.2 780void GameRenderer::turnOnLightLayer(double alpha) 781{ // 4J - TODO 782#if 0 783 if (SharedConstants::TEXTURE_LIGHTING) 784 { 785 glClientActiveTexture(GL_TEXTURE1); 786 glActiveTexture(GL_TEXTURE1); 787 glMatrixMode(GL_TEXTURE); 788 glLoadIdentity(); 789 // float s = 1 / 16f / 15.0f*16/14.0f; 790 float s = 1 / 16.0f / 15.0f * 15 / 16; 791 glScalef(s, s, s); 792 glTranslatef(8f, 8f, 8f); 793 glMatrixMode(GL_MODELVIEW); 794 795 mc->textures->bind(lightTexture); 796 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 797 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 798 799 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 800 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 802 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 803 glColor4f(1, 1, 1, 1); 804 glEnable(GL_TEXTURE_2D); 805 glClientActiveTexture(GL_TEXTURE0); 806 glActiveTexture(GL_TEXTURE0); 807 } 808#endif 809 RenderManager.TextureBindVertex(getLightTexture(mc->player->GetXboxPad(), mc->level)); 810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 811 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 812 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 813 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 814} 815 816// 4J - change brought forward from 1.8.2 817void GameRenderer::tickLightTexture() 818{ 819 blrt += (float)((Math::random() - Math::random()) * Math::random() * Math::random()); 820 blgt += (float)((Math::random() - Math::random()) * Math::random() * Math::random()); 821 blrt *= 0.9; 822 blgt *= 0.9; 823 blr += (blrt - blr) * 1; 824 blg += (blgt - blg) * 1; 825 _updateLightTexture = true; 826} 827 828void GameRenderer::updateLightTexture(float a) 829{ 830 // 4J-JEV: Now doing light textures on PER PLAYER basis. 831 // 4J - we *had* added separate light textures for all dimensions, and this loop to update them all here 832 for(int j = 0; j < XUSER_MAX_COUNT; j++ ) 833 { 834 // Loop over all the players 835 shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->localplayers[j]; 836 if (player == NULL) continue; 837 838 Level *level = player->level; // 4J - was mc->level when it was just to update the one light texture 839 840 float skyDarken1 = level->getSkyDarken((float) 1); 841 for (int i = 0; i < 256; i++) 842 { 843 float darken = skyDarken1 * 0.95f + 0.05f; 844 float sky = level->dimension->brightnessRamp[i / 16] * darken; 845 float block = level->dimension->brightnessRamp[i % 16] * (blr * 0.1f + 1.5f); 846 847 if (level->skyFlashTime > 0) 848 { 849 sky = level->dimension->brightnessRamp[i / 16]; 850 } 851 852 float rs = sky * (skyDarken1 * 0.65f + 0.35f); 853 float gs = sky * (skyDarken1 * 0.65f + 0.35f); 854 float bs = sky; 855 856 float rb = block; 857 float gb = block * ((block * 0.6f + 0.4f) * 0.6f + 0.4f); 858 float bb = block * ((block * block) * 0.6f + 0.4f); 859 860 float _r = (rs + rb); 861 float _g = (gs + gb); 862 float _b = (bs + bb); 863 864 _r = _r * 0.96f + 0.03f; 865 _g = _g * 0.96f + 0.03f; 866 _b = _b * 0.96f + 0.03f; 867 868 if (darkenWorldAmount > 0) 869 { 870 float amount = darkenWorldAmountO + (darkenWorldAmount - darkenWorldAmountO) * a; 871 _r = _r * (1.0f - amount) + (_r * .7f) * amount; 872 _g = _g * (1.0f - amount) + (_g * .6f) * amount; 873 _b = _b * (1.0f - amount) + (_b * .6f) * amount; 874 } 875 876 if (level->dimension->id == 1) 877 { 878 _r = (0.22f + rb * 0.75f); 879 _g = (0.28f + gb * 0.75f); 880 _b = (0.25f + bb * 0.75f); 881 } 882 883 if (player->hasEffect(MobEffect::nightVision)) 884 { 885 float scale = getNightVisionScale(player, a); 886 { 887 float dist = 1.0f / _r; 888 if (dist > (1.0f / _g)) 889 { 890 dist = (1.0f / _g); 891 } 892 if (dist > (1.0f / _b)) 893 { 894 dist = (1.0f / _b); 895 } 896 _r = _r * (1.0f - scale) + (_r * dist) * scale; 897 _g = _g * (1.0f - scale) + (_g * dist) * scale; 898 _b = _b * (1.0f - scale) + (_b * dist) * scale; 899 } 900 } 901 902 if (_r > 1) _r = 1; 903 if (_g > 1) _g = 1; 904 if (_b > 1) _b = 1; 905 906 float brightness = mc->options->gamma; 907 908 float ir = 1 - _r; 909 float ig = 1 - _g; 910 float ib = 1 - _b; 911 ir = 1 - (ir * ir * ir * ir); 912 ig = 1 - (ig * ig * ig * ig); 913 ib = 1 - (ib * ib * ib * ib); 914 _r = _r * (1 - brightness) + ir * brightness; 915 _g = _g * (1 - brightness) + ig * brightness; 916 _b = _b * (1 - brightness) + ib * brightness; 917 918 _r = _r * 0.96f + 0.03f; 919 _g = _g * 0.96f + 0.03f; 920 _b = _b * 0.96f + 0.03f; 921 922 if (_r > 1) _r = 1; 923 if (_g > 1) _g = 1; 924 if (_b > 1) _b = 1; 925 if (_r < 0) _r = 0; 926 if (_g < 0) _g = 0; 927 if (_b < 0) _b = 0; 928 929 int alpha = 255; 930 int r = (int) (_r * 255); 931 int g = (int) (_g * 255); 932 int b = (int) (_b * 255); 933 934#if ( defined _DURANGO || defined _WIN64 || __PSVITA__ ) 935 lightPixels[j][i] = alpha << 24 | b << 16 | g << 8 | r; 936#elif ( defined _XBOX || defined __ORBIS__ ) 937 lightPixels[j][i] = alpha << 24 | r << 16 | g << 8 | b; 938#else 939 lightPixels[j][i] = r << 24 | g << 16 | b << 8 | alpha; 940#endif 941 } 942 943 mc->textures->replaceTextureDirect( lightPixels[j], 16, 16, getLightTexture(j,level) ); 944 // lightTexture->upload(); // 4J: not relevant 945 946 //_updateLightTexture = false; 947 } 948} 949 950float GameRenderer::getNightVisionScale(shared_ptr<Player> player, float a) 951{ 952 int duration = player->getEffect(MobEffect::nightVision)->getDuration(); 953 if (duration > (SharedConstants::TICKS_PER_SECOND * 10)) 954 { 955 return 1.0f; 956 } 957 else 958 { 959 float flash = max(0.0f, (float)duration - a); 960 return .7f + Mth::sin(flash * PI * .05f) * .3f; // was: .7 + sin(flash*pi*0.2) * .3 961 } 962} 963 964// 4J added, so we can have a light texture for each player to support split screen 965int GameRenderer::getLightTexture(int iPad, Level *level) 966{ 967 // Turn the current dimenions id into an index from 0 to 2 968 // int idx = level->dimension->id; 969 // if( idx == -1 ) idx = 2; 970 971 return lightTexture[iPad]; // 4J-JEV: Changing to Per Player lighting textures. 972} 973 974void GameRenderer::render(float a, bool bFirst) 975{ 976 if( _updateLightTexture && bFirst) updateLightTexture(a); 977 if (Display::isActive()) 978 { 979 lastActiveTime = System::currentTimeMillis(); 980 } 981 else 982 { 983 if (System::currentTimeMillis() - lastActiveTime > 500) 984 { 985 mc->pauseGame(); 986 } 987 } 988 989#if 0 // 4J - TODO 990 if (mc->mouseGrabbed && focused) { 991 mc->mouseHandler.poll(); 992 993 float ss = mc->options->sensitivity * 0.6f + 0.2f; 994 float sens = (ss * ss * ss) * 8; 995 float xo = mc->mouseHandler.xd * sens; 996 float yo = mc->mouseHandler.yd * sens; 997 998 int yAxis = 1; 999 if (mc->options->invertYMouse) yAxis = -1; 1000 1001 if (mc->options->smoothCamera) { 1002 1003 xo = smoothTurnX.getNewDeltaValue(xo, .05f * sens); 1004 yo = smoothTurnY.getNewDeltaValue(yo, .05f * sens); 1005 1006 } 1007 1008 mc->player.turn(xo, yo * yAxis); 1009 } 1010#endif 1011 1012 if (mc->noRender) return; 1013 GameRenderer::anaglyph3d = mc->options->anaglyph3d; 1014 1015 glViewport(0, 0, mc->width, mc->height); // 4J - added 1016 ScreenSizeCalculator ssc(mc->options, mc->width, mc->height); 1017 int screenWidth = ssc.getWidth(); 1018 int screenHeight = ssc.getHeight(); 1019 int xMouse = Mouse::getX() * screenWidth / mc->width; 1020 int yMouse = screenHeight - Mouse::getY() * screenHeight / mc->height - 1; 1021 1022 int maxFps = getFpsCap(mc->options->framerateLimit); 1023 1024 if (mc->level != NULL) 1025 { 1026 if (mc->options->framerateLimit == 0) 1027 { 1028 renderLevel(a, 0); 1029 } 1030 else 1031 { 1032 renderLevel(a, lastNsTime + 1000000000 / maxFps); 1033 } 1034 1035 lastNsTime = System::nanoTime(); 1036 1037 1038 if (!mc->options->hideGui || mc->screen != NULL) 1039 { 1040 mc->gui->render(a, mc->screen != NULL, xMouse, yMouse); 1041 } 1042 } 1043 else 1044 { 1045 glViewport(0, 0, mc->width, mc->height); 1046 glMatrixMode(GL_PROJECTION); 1047 glLoadIdentity(); 1048 glMatrixMode(GL_MODELVIEW); 1049 glLoadIdentity(); 1050 setupGuiScreen(); 1051 1052 lastNsTime = System::nanoTime(); 1053 } 1054 1055 1056 if (mc->screen != NULL) 1057 { 1058 glClear(GL_DEPTH_BUFFER_BIT); 1059 mc->screen->render(xMouse, yMouse, a); 1060 if (mc->screen != NULL && mc->screen->particles != NULL) mc->screen->particles->render(a); 1061 } 1062 1063} 1064 1065void GameRenderer::renderLevel(float a) 1066{ 1067 renderLevel(a, 0); 1068} 1069 1070#ifdef MULTITHREAD_ENABLE 1071// Request that an item be deleted, when it is safe to do so 1072void GameRenderer::AddForDelete(byte *deleteThis) 1073{ 1074 EnterCriticalSection(&m_csDeleteStack); 1075 m_deleteStackByte.push_back(deleteThis); 1076} 1077 1078void GameRenderer::AddForDelete(SparseLightStorage *deleteThis) 1079{ 1080 EnterCriticalSection(&m_csDeleteStack); 1081 m_deleteStackSparseLightStorage.push_back(deleteThis); 1082} 1083 1084void GameRenderer::AddForDelete(CompressedTileStorage *deleteThis) 1085{ 1086 EnterCriticalSection(&m_csDeleteStack); 1087 m_deleteStackCompressedTileStorage.push_back(deleteThis); 1088} 1089 1090void GameRenderer::AddForDelete(SparseDataStorage *deleteThis) 1091{ 1092 EnterCriticalSection(&m_csDeleteStack); 1093 m_deleteStackSparseDataStorage.push_back(deleteThis); 1094} 1095 1096void GameRenderer::FinishedReassigning() 1097{ 1098 LeaveCriticalSection(&m_csDeleteStack); 1099} 1100 1101int GameRenderer::runUpdate(LPVOID lpParam) 1102{ 1103 Minecraft *minecraft = Minecraft::GetInstance(); 1104 Vec3::CreateNewThreadStorage(); 1105 AABB::CreateNewThreadStorage(); 1106 IntCache::CreateNewThreadStorage(); 1107 Tesselator::CreateNewThreadStorage(1024*1024); 1108 Compression::UseDefaultThreadStorage(); 1109 RenderManager.InitialiseContext(); 1110#ifdef _LARGE_WORLDS 1111 Chunk::CreateNewThreadStorage(); 1112#endif 1113 Tile::CreateNewThreadStorage(); 1114 1115 ShutdownManager::HasStarted(ShutdownManager::eRenderChunkUpdateThread,m_updateEvents); 1116 while(ShutdownManager::ShouldRun(ShutdownManager::eRenderChunkUpdateThread)) 1117 { 1118 //m_updateEvents->Clear(eUpdateEventIsFinished); 1119 //m_updateEvents->WaitForSingle(eUpdateCanRun,INFINITE); 1120 // 4J Stu - We Need to have this happen atomically to avoid deadlocks 1121 m_updateEvents->WaitForAll(INFINITE); 1122 1123 if( !ShutdownManager::ShouldRun(ShutdownManager::eRenderChunkUpdateThread) ) 1124 { 1125 break; 1126 } 1127 1128 m_updateEvents->Set(eUpdateCanRun); 1129 1130 // PIXBeginNamedEvent(0,"Updating dirty chunks %d",(count++)&7); 1131 1132 // Update chunks atomically until there aren't any very near ones left - they will be deferred for rendering 1133 // until the call to CBuffDeferredModeEnd if we have anything near to render here 1134 // Now limiting maximum number of updates that can be deferred as have noticed that with redstone clock circuits, it is possible to create 1135 // things that need constant updating, so if you stand near them, the render data Never gets updated and the game just keeps going until it runs out of render memory... 1136 int count = 0; 1137 static const int MAX_DEFERRED_UPDATES = 10; 1138 bool shouldContinue = false; 1139 do 1140 { 1141 shouldContinue = minecraft->levelRenderer->updateDirtyChunks(); 1142 count++; 1143 } while ( shouldContinue && count < MAX_DEFERRED_UPDATES ); 1144 1145 // while( minecraft->levelRenderer->updateDirtyChunks() ) 1146 // ; 1147 RenderManager.CBuffDeferredModeEnd(); 1148 1149 // If any renderable tile entities were flagged in this last block of chunk(s) that were udpated, then change their 1150 // flags to say that this deferred chunk is over and they are actually safe to be removed now 1151 minecraft->levelRenderer->fullyFlagRenderableTileEntitiesToBeRemoved(); 1152 1153 // We've got stacks for things that can only safely be deleted whilst this thread isn't updating things - delete those things now 1154 EnterCriticalSection(&m_csDeleteStack); 1155 for(unsigned int i = 0; i < m_deleteStackByte.size(); i++ ) 1156 { 1157 delete m_deleteStackByte[i]; 1158 } 1159 m_deleteStackByte.clear(); 1160 for(unsigned int i = 0; i < m_deleteStackSparseLightStorage.size(); i++ ) 1161 { 1162 delete m_deleteStackSparseLightStorage[i]; 1163 } 1164 m_deleteStackSparseLightStorage.clear(); 1165 for(unsigned int i = 0; i < m_deleteStackCompressedTileStorage.size(); i++ ) 1166 { 1167 delete m_deleteStackCompressedTileStorage[i]; 1168 } 1169 m_deleteStackCompressedTileStorage.clear(); 1170 for(unsigned int i = 0; i < m_deleteStackSparseDataStorage.size(); i++ ) 1171 { 1172 delete m_deleteStackSparseDataStorage[i]; 1173 } 1174 m_deleteStackSparseDataStorage.clear(); 1175 LeaveCriticalSection(&m_csDeleteStack); 1176 1177 // PIXEndNamedEvent(); 1178 1179 AABB::resetPool(); 1180 Vec3::resetPool(); 1181 IntCache::Reset(); 1182 m_updateEvents->Set(eUpdateEventIsFinished); 1183 } 1184 1185 ShutdownManager::HasFinished(ShutdownManager::eRenderChunkUpdateThread); 1186 return 0; 1187} 1188#endif 1189 1190void GameRenderer::EnableUpdateThread() 1191{ 1192 // #ifdef __PS3__ // MGH - disable the update on PS3 for now 1193 // return; 1194 // #endif 1195#ifdef MULTITHREAD_ENABLE 1196 if( updateRunning) return; 1197 app.DebugPrintf("------------------EnableUpdateThread--------------------\n"); 1198 updateRunning = true; 1199 m_updateEvents->Set(eUpdateCanRun); 1200 m_updateEvents->Set(eUpdateEventIsFinished); 1201#endif 1202} 1203 1204void GameRenderer::DisableUpdateThread() 1205{ 1206 // #ifdef __PS3__ // MGH - disable the update on PS3 for now 1207 // return; 1208 // #endif 1209#ifdef MULTITHREAD_ENABLE 1210 if( !updateRunning) return; 1211 app.DebugPrintf("------------------DisableUpdateThread--------------------\n"); 1212 updateRunning = false; 1213 m_updateEvents->Clear(eUpdateCanRun); 1214 m_updateEvents->WaitForSingle(eUpdateEventIsFinished,INFINITE); 1215#endif 1216} 1217 1218void GameRenderer::renderLevel(float a, __int64 until) 1219{ 1220 // 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 1221 1222 glEnable(GL_CULL_FACE); 1223 glEnable(GL_DEPTH_TEST); 1224 1225 // Is this the primary player? Only do the updating of chunks if it is. This controls the creation of render data for each chunk - all of this we are only 1226 // going to do for the primary player, and the other players can just view whatever they have loaded in - we're sharing render data between players. 1227 bool updateChunks = ( mc->player == mc->localplayers[ProfileManager.GetPrimaryPad()] ); 1228 1229 // if (mc->cameraTargetPlayer == NULL) // 4J - removed condition as we want to update this is mc->player changes for different local players 1230 { 1231 mc->cameraTargetPlayer = mc->player; 1232 } 1233 pick(a); 1234 1235 shared_ptr<LivingEntity> cameraEntity = mc->cameraTargetPlayer; 1236 LevelRenderer *levelRenderer = mc->levelRenderer; 1237 ParticleEngine *particleEngine = mc->particleEngine; 1238 double xOff = cameraEntity->xOld + (cameraEntity->x - cameraEntity->xOld) * a; 1239 double yOff = cameraEntity->yOld + (cameraEntity->y - cameraEntity->yOld) * a; 1240 double zOff = cameraEntity->zOld + (cameraEntity->z - cameraEntity->zOld) * a; 1241 1242 for (int i = 0; i < 2; i++) 1243 { 1244 if (mc->options->anaglyph3d) 1245 { 1246 GameRenderer::anaglyphPass = i; 1247 if (GameRenderer::anaglyphPass == 0) glColorMask(false, true, true, false); 1248 else glColorMask(true, false, false, false); 1249 } 1250 1251 1252 glViewport(0, 0, mc->width, mc->height); 1253 setupClearColor(a); 1254 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1255 glEnable(GL_CULL_FACE); 1256 1257 setupCamera(a, i); 1258 Camera::prepare(mc->player, mc->player->ThirdPersonView() == 2); 1259 1260 Frustum::getFrustum(); 1261 if (mc->options->viewDistance < 2) 1262 { 1263 setupFog(-1, a); 1264 levelRenderer->renderSky(a); 1265 if(mc->skins->getSelected()->getId() == 1026 ) levelRenderer->renderHaloRing(a); 1266 } 1267 glEnable(GL_FOG); 1268 setupFog(1, a); 1269 1270 if (mc->options->ambientOcclusion) 1271 { 1272 GL11::glShadeModel(GL11::GL_SMOOTH); 1273 } 1274 1275 PIXBeginNamedEvent(0,"Culling"); 1276 MemSect(31); 1277 // Culler *frustum = new FrustumCuller(); 1278 FrustumCuller frustObj; 1279 Culler *frustum = &frustObj; 1280 MemSect(0); 1281 frustum->prepare(xOff, yOff, zOff); 1282 1283 mc->levelRenderer->cull(frustum, a); 1284 PIXEndNamedEvent(); 1285 1286#ifndef MULTITHREAD_ENABLE 1287 if ( (i == 0) && updateChunks ) // 4J - added updateChunks condition 1288 { 1289 int PIXPass = 0; 1290 PIXBeginNamedEvent(0,"Updating dirty chunks"); 1291 do 1292 { 1293 PIXBeginNamedEvent(0,"Updating dirty chunks pass %d",PIXPass++); 1294 bool retval = mc->levelRenderer->updateDirtyChunks(cameraEntity, false); 1295 PIXEndNamedEvent(); 1296 if( retval ) break; 1297 1298 1299 if (until == 0) break; 1300 1301 __int64 diff = until - System::nanoTime(); 1302 if (diff < 0) break; 1303 if (diff > 1000000000) break; 1304 } while (true); 1305 PIXEndNamedEvent(); 1306 } 1307#endif 1308 1309 1310 if (cameraEntity->y < Level::genDepth) 1311 { 1312 prepareAndRenderClouds(levelRenderer, a); 1313 } 1314 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 1315 1316 setupFog(0, a); 1317 glEnable(GL_FOG); 1318 MemSect(31); 1319 mc->textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); // 4J was L"/terrain.png" 1320 MemSect(0); 1321 Lighting::turnOff(); 1322 PIXBeginNamedEvent(0,"Level render"); 1323 levelRenderer->render(cameraEntity, 0, a, updateChunks); 1324 PIXEndNamedEvent(); 1325 1326 GL11::glShadeModel(GL11::GL_FLAT); 1327 1328 if (cameraFlip == 0 ) 1329 { 1330 Lighting::turnOn(); 1331 PIXBeginNamedEvent(0,"Entity render"); 1332 // 4J - for entities, don't include the "a" factor that interpolates from the old to new position, as the AABBs for the entities are already fully at the new position 1333 // This fixes flickering minecarts, and pigs that you are riding on 1334 frustum->prepare(cameraEntity->x,cameraEntity->y,cameraEntity->z); 1335 // 4J Stu - When rendering entities, in the end if the dragon is hurt or we have a lot of entities we can end up wrapping 1336 // our index into the temp Vec3 cache and overwrite the one that was storing the camera position 1337 // Fix for #77745 - TU9: Content: Gameplay: Items and mobs not belonging to end world are disappearing when Enderdragon is damaged. 1338 Vec3 *cameraPosTemp = cameraEntity->getPos(a); 1339 cameraPos->x = cameraPosTemp->x; 1340 cameraPos->y = cameraPosTemp->y; 1341 cameraPos->z = cameraPosTemp->z; 1342 levelRenderer->renderEntities(cameraPos, frustum, a); 1343#ifdef __PSVITA__ 1344 // AP - make sure we're using the Alpha cut out effect for particles 1345 glEnable(GL_ALPHA_TEST); 1346#endif 1347 PIXEndNamedEvent(); 1348 PIXBeginNamedEvent(0,"Particle render"); 1349 turnOnLightLayer(a); // 4J - brought forward from 1.8.2 1350 particleEngine->renderLit(cameraEntity, a, ParticleEngine::OPAQUE_LIST); 1351 Lighting::turnOff(); 1352 setupFog(0, a); 1353 particleEngine->render(cameraEntity, a, ParticleEngine::OPAQUE_LIST); 1354 PIXEndNamedEvent(); 1355 turnOffLightLayer(a); // 4J - brought forward from 1.8.2 1356 1357 if ( (mc->hitResult != NULL) && cameraEntity->isUnderLiquid(Material::water) && cameraEntity->instanceof(eTYPE_PLAYER) ) //&& !mc->options.hideGui) 1358 { 1359 shared_ptr<Player> player = dynamic_pointer_cast<Player>(cameraEntity); 1360 glDisable(GL_ALPHA_TEST); 1361 levelRenderer->renderHit(player, mc->hitResult, 0, player->inventory->getSelected(), a); 1362 glEnable(GL_ALPHA_TEST); 1363 } 1364 } 1365 1366 glDisable(GL_BLEND); 1367 glEnable(GL_CULL_FACE); 1368 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1369 glDepthMask(true); 1370 setupFog(0, a); 1371 glEnable(GL_BLEND); 1372 glDisable(GL_CULL_FACE); 1373 MemSect(31); 1374 mc->textures->bindTexture(&TextureAtlas::LOCATION_BLOCKS); // 4J was L"/terrain.png" 1375 MemSect(0); 1376 // 4J - have changed this fancy rendering option to work with our command buffers. The original used to use frame buffer flags to disable 1377 // writing to colour when doing the z-only pass, but that value gets obliterated by our command buffers. Using alpha blend function instead 1378 // to achieve the same effect. 1379 if (true) // (mc->options->fancyGraphics) 1380 { 1381 if (mc->options->ambientOcclusion) 1382 { 1383 GL11::glShadeModel(GL11::GL_SMOOTH); 1384 } 1385 1386 glBlendFunc(GL_ZERO, GL_ONE); 1387 PIXBeginNamedEvent(0,"Fancy second pass - writing z"); 1388 int visibleWaterChunks = levelRenderer->render(cameraEntity, 1, a, updateChunks); 1389 PIXEndNamedEvent(); 1390 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1391 1392 if (visibleWaterChunks > 0) 1393 { 1394 PIXBeginNamedEvent(0,"Fancy second pass - actual rendering"); 1395 levelRenderer->render(cameraEntity, 1, a, updateChunks); // 4J - chanaged, used to be renderSameAsLast but we don't support that anymore 1396 PIXEndNamedEvent(); 1397 } 1398 1399 GL11::glShadeModel(GL11::GL_FLAT); 1400 } 1401 else 1402 { 1403 PIXBeginNamedEvent(0,"Second pass level render"); 1404 levelRenderer->render(cameraEntity, 1, a, updateChunks); 1405 PIXEndNamedEvent(); 1406 } 1407 1408 // 4J - added - have split out translucent particle rendering so that it happens after the water is rendered, primarily for fireworks 1409 PIXBeginNamedEvent(0,"Particle render (translucent)"); 1410 Lighting::turnOn(); 1411 turnOnLightLayer(a); // 4J - brought forward from 1.8.2 1412 particleEngine->renderLit(cameraEntity, a, ParticleEngine::TRANSLUCENT_LIST); 1413 Lighting::turnOff(); 1414 setupFog(0, a); 1415 particleEngine->render(cameraEntity, a, ParticleEngine::TRANSLUCENT_LIST); 1416 PIXEndNamedEvent(); 1417 turnOffLightLayer(a); // 4J - brought forward from 1.8.2 1418 ////////////////////////// End of 4J added section 1419 1420 glDepthMask(true); 1421 glEnable(GL_CULL_FACE); 1422 glDisable(GL_BLEND); 1423 1424 if ( (zoom == 1) && cameraEntity->instanceof(eTYPE_PLAYER) ) //&& !mc->options.hideGui) 1425 { 1426 if (mc->hitResult != NULL && !cameraEntity->isUnderLiquid(Material::water)) 1427 { 1428 shared_ptr<Player> player = dynamic_pointer_cast<Player>(cameraEntity); 1429 glDisable(GL_ALPHA_TEST); 1430 levelRenderer->renderHitOutline(player, mc->hitResult, 0, a); 1431 glEnable(GL_ALPHA_TEST); 1432 } 1433 } 1434 1435 /* 4J - moved rain rendering to after clouds so that it alpha blends onto them properly 1436 PIXBeginNamedEvent(0,"Rendering snow and rain"); 1437 renderSnowAndRain(a); 1438 PIXEndNamedEvent(); 1439 glDisable(GL_FOG); 1440 */ 1441 1442 glEnable(GL_BLEND); 1443 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 1444 levelRenderer->renderDestroyAnimation(Tesselator::getInstance(), dynamic_pointer_cast<Player>(cameraEntity), a); 1445 glDisable(GL_BLEND); 1446 1447 if (cameraEntity->y >= Level::genDepth) 1448 { 1449 prepareAndRenderClouds(levelRenderer, a); 1450 } 1451 1452 // 4J - rain rendering moved here so that it renders after clouds & can blend properly onto them 1453 setupFog(0, a); 1454 glEnable(GL_FOG); 1455 PIXBeginNamedEvent(0,"Rendering snow and rain"); 1456 renderSnowAndRain(a); 1457 PIXEndNamedEvent(); 1458 glDisable(GL_FOG); 1459 1460 1461 if (zoom == 1) 1462 { 1463 glClear(GL_DEPTH_BUFFER_BIT); 1464 renderItemInHand(a, i); 1465 } 1466 1467 1468 if (!mc->options->anaglyph3d) 1469 { 1470 return; 1471 } 1472 } 1473 glColorMask(true, true, true, false); 1474} 1475 1476void GameRenderer::prepareAndRenderClouds(LevelRenderer *levelRenderer, float a) 1477{ 1478 if (mc->options->isCloudsOn()) 1479 { 1480 glPushMatrix(); 1481 setupFog(0, a); 1482 glEnable(GL_FOG); 1483 PIXBeginNamedEvent(0,"Rendering clouds"); 1484 levelRenderer->renderClouds(a); 1485 PIXEndNamedEvent(); 1486 glDisable(GL_FOG); 1487 setupFog(1, a); 1488 glPopMatrix(); 1489 } 1490} 1491 1492void GameRenderer::tickRain() 1493{ 1494 float rainLevel = mc->level->getRainLevel(1); 1495 1496 if (!mc->options->fancyGraphics) rainLevel /= 2; 1497 if (rainLevel == 0) return; 1498 1499 rainLevel /= ( mc->levelRenderer->activePlayers() + 1 ); 1500 1501 random->setSeed(_tick * 312987231l); 1502 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 1503 Level *level = mc->level; 1504 1505 int x0 = Mth::floor(player->x); 1506 int y0 = Mth::floor(player->y); 1507 int z0 = Mth::floor(player->z); 1508 1509 int r = 10; 1510 1511 double rainPosX = 0; 1512 double rainPosY = 0; 1513 double rainPosZ = 0; 1514 int rainPosSamples = 0; 1515 1516 int rainCount = (int) (100 * rainLevel * rainLevel); 1517 if (mc->options->particles == 1) 1518 { 1519 rainCount >>= 1; 1520 } else if (mc->options->particles == 2) 1521 { 1522 rainCount = 0; 1523 } 1524 for (int i = 0; i < rainCount; i++) 1525 { 1526 int x = x0 + random->nextInt(r) - random->nextInt(r); 1527 int z = z0 + random->nextInt(r) - random->nextInt(r); 1528 int y = level->getTopRainBlock(x, z); 1529 int t = level->getTile(x, y - 1, z); 1530 Biome *biome = level->getBiome(x,z); 1531 if (y <= y0 + r && y >= y0 - r && biome->hasRain() && biome->getTemperature() >= 0.2f) 1532 { 1533 float xa = random->nextFloat(); 1534 float za = random->nextFloat(); 1535 if (t > 0) 1536 { 1537 if (Tile::tiles[t]->material == Material::lava) 1538 { 1539 mc->particleEngine->add( shared_ptr<SmokeParticle>( new SmokeParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za, 0, 0, 0) ) ); 1540 } 1541 else 1542 { 1543 if (random->nextInt(++rainPosSamples) == 0) 1544 { 1545 rainPosX = x + xa; 1546 rainPosY = y + 0.1f - Tile::tiles[t]->getShapeY0(); 1547 rainPosZ = z + za; 1548 } 1549 mc->particleEngine->add( shared_ptr<WaterDropParticle>( new WaterDropParticle(level, x + xa, y + 0.1f - Tile::tiles[t]->getShapeY0(), z + za) ) ); 1550 } 1551 } 1552 } 1553 } 1554 1555 1556 if (rainPosSamples > 0 && random->nextInt(3) < rainSoundTime++) 1557 { 1558 rainSoundTime = 0; 1559 MemSect(24); 1560 if (rainPosY > player->y + 1 && level->getTopRainBlock(Mth::floor(player->x), Mth::floor(player->z)) > Mth::floor(player->y)) 1561 { 1562 mc->level->playLocalSound(rainPosX, rainPosY, rainPosZ, eSoundType_AMBIENT_WEATHER_RAIN, 0.1f, 0.5f); 1563 } 1564 else 1565 { 1566 mc->level->playLocalSound(rainPosX, rainPosY, rainPosZ, eSoundType_AMBIENT_WEATHER_RAIN, 0.2f, 1.0f); 1567 } 1568 MemSect(0); 1569 } 1570 1571} 1572 1573// 4J - this whole function updated from 1.8.2 1574void GameRenderer::renderSnowAndRain(float a) 1575{ 1576 float rainLevel = mc->level->getRainLevel(a); 1577 if (rainLevel <= 0) return; 1578 1579 // 4J - rain is relatively low poly, but high fill-rate - better to clip it 1580 RenderManager.StateSetEnableViewportClipPlanes(true); 1581 1582 turnOnLightLayer(a); 1583 1584 if (rainXa == NULL) 1585 { 1586 rainXa = new float[32 * 32]; 1587 rainZa = new float[32 * 32]; 1588 1589 for (int z = 0; z < 32; z++) 1590 { 1591 for (int x = 0; x < 32; x++) 1592 { 1593 float xa = x - 16; 1594 float za = z - 16; 1595 float d = Mth::sqrt(xa * xa + za * za); 1596 rainXa[z << 5 | x] = -za / d; 1597 rainZa[z << 5 | x] = xa / d; 1598 } 1599 } 1600 } 1601 1602 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 1603 Level *level = mc->level; 1604 1605 int x0 = Mth::floor(player->x); 1606 int y0 = Mth::floor(player->y); 1607 int z0 = Mth::floor(player->z); 1608 1609 Tesselator *t = Tesselator::getInstance(); 1610 glDisable(GL_CULL_FACE); 1611 glNormal3f(0, 1, 0); 1612 glEnable(GL_BLEND); 1613 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1614 glAlphaFunc(GL_GREATER, 0.01f); 1615 1616 MemSect(31); 1617 mc->textures->bindTexture(&SNOW_LOCATION); // 4J was L"/environment/snow.png" 1618 MemSect(0); 1619 1620 double xo = player->xOld + (player->x - player->xOld) * a; 1621 double yo = player->yOld + (player->y - player->yOld) * a; 1622 double zo = player->zOld + (player->z - player->zOld) * a; 1623 1624 int yMin = Mth::floor(yo); 1625 1626 1627 int r = 5; 1628 // 4J - was if(mc.options.fancyGraphics) r = 10; 1629 switch( mc->levelRenderer->activePlayers() ) 1630 { 1631 case 1: 1632 default: 1633 r = 9; 1634 break; 1635 case 2: 1636 r = 7; 1637 break; 1638 case 3: 1639 r = 5; 1640 break; 1641 case 4: 1642 r = 5; 1643 break; 1644 } 1645 1646 // 4J - some changes made here to access biome through new interface that caches results in levelchunk flags, as an optimisation 1647 1648 int mode = -1; 1649 float time = _tick + a; 1650 1651 glColor4f(1, 1, 1, 1); 1652 1653 for (int x = x0 - r; x <= x0 + r; x++) 1654 for (int z = z0 - r; z <= z0 + r; z++) 1655 { 1656 int rainSlot = (z - z0 + 16) * 32 + (x - x0 + 16); 1657 float xa = rainXa[rainSlot] * 0.5f; 1658 float za = rainZa[rainSlot] * 0.5f; 1659 1660 // 4J - changes here brought forward from 1.8.2 1661 Biome *b = level->getBiome(x, z); 1662 if (!b->hasRain() && !b->hasSnow()) continue; 1663 1664 int floor = level->getTopRainBlock(x, z); 1665 1666 int yy0 = y0 - r; 1667 int yy1 = y0 + r; 1668 1669 if (yy0 < floor) yy0 = floor; 1670 if (yy1 < floor) yy1 = floor; 1671 float s = 1; 1672 1673 int yl = floor; 1674 if (yl < yMin) yl = yMin; 1675 1676 if (yy0 != yy1) 1677 { 1678 random->setSeed((x * x * 3121 + x * 45238971) ^ (z * z * 418711 + z * 13761)); 1679 1680 // 4J - changes here brought forward from 1.8.2 1681 float temp = b->getTemperature(); 1682 if (level->getBiomeSource()->scaleTemp(temp, floor) >= 0.15f) 1683 { 1684 if (mode != 0) 1685 { 1686 if (mode >= 0) t->end(); 1687 mode = 0; 1688 mc->textures->bindTexture(&RAIN_LOCATION); 1689 t->begin(); 1690 } 1691 1692 float ra = (((_tick + x * x * 3121 + x * 45238971 + z * z * 418711 + z * 13761) & 31) + a) / 32.0f * (3 + random->nextFloat()); 1693 1694 double xd = (x + 0.5f) - player->x; 1695 double zd = (z + 0.5f) - player->z; 1696 float dd = (float) Mth::sqrt(xd * xd + zd * zd) / r; 1697 1698 float br = 1; 1699 t->offset(-xo * 1, -yo * 1, -zo * 1); 1700#ifdef __PSVITA__ 1701 // AP - this will set up the 4 vertices in half the time 1702 float Alpha = ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel; 1703 int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; 1704 t->tileRainQuad(x - xa + 0.5, yy0, z - za + 0.5, 0 * s, yy0 * s / 4.0f + ra * s, 1705 x + xa + 0.5, yy0, z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s, 1706 x + xa + 0.5, yy1, z + za + 0.5, 1 * s, yy1 * s / 4.0f + ra * s, 1707 x - xa + 0.5, yy1, z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s, 1708 br, br, br, Alpha, br, br, br, 0, tex2); 1709#else 1710 t->tex2(level->getLightColor(x, yl, z, 0)); 1711 t->color(br, br, br, ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel); 1712 t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s, yy0 * s / 4.0f + ra * s); 1713 t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s); 1714 t->color(br, br, br, 0.0f); // 4J - added to soften the top visible edge of the rain 1715 t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s, yy1 * s / 4.0f + ra * s); 1716 t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s); 1717#endif 1718 t->offset(0, 0, 0); 1719 t->end(); 1720 } 1721 else 1722 { 1723 if (mode != 1) 1724 { 1725 if (mode >= 0) t->end(); 1726 mode = 1; 1727 mc->textures->bindTexture(&SNOW_LOCATION); 1728 t->begin(); 1729 } 1730 float ra = (((_tick) & 511) + a) / 512.0f; 1731 float uo = random->nextFloat() + time * 0.01f * (float) random->nextGaussian(); 1732 float vo = random->nextFloat() + time * (float) random->nextGaussian() * 0.001f; 1733 double xd = (x + 0.5f) - player->x; 1734 double zd = (z + 0.5f) - player->z; 1735 float dd = (float) sqrt(xd * xd + zd * zd) / r; 1736 float br = 1; 1737 t->offset(-xo * 1, -yo * 1, -zo * 1); 1738#ifdef __PSVITA__ 1739 // AP - this will set up the 4 vertices in half the time 1740 float Alpha = ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel; 1741 int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; 1742 t->tileRainQuad(x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, yy0 * s / 4.0f + ra * s + vo, 1743 x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, yy0 * s / 4.0f + ra * s + vo, 1744 x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, yy1 * s / 4.0f + ra * s + vo, 1745 x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, yy1 * s / 4.0f + ra * s + vo, 1746 br, br, br, Alpha, br, br, br, Alpha, tex2); 1747#else 1748 t->tex2((level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4); 1749 t->color(br, br, br, ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel); 1750 t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, yy0 * s / 4.0f + ra * s + vo); 1751 t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, yy0 * s / 4.0f + ra * s + vo); 1752 t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, yy1 * s / 4.0f + ra * s + vo); 1753 t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, yy1 * s / 4.0f + ra * s + vo); 1754#endif 1755 t->offset(0, 0, 0); 1756 } 1757 } 1758 } 1759 1760 if( mode >= 0 ) t->end(); 1761 glEnable(GL_CULL_FACE); 1762 glDisable(GL_BLEND); 1763 glAlphaFunc(GL_GREATER, 0.1f); 1764 turnOffLightLayer(a); 1765 1766 RenderManager.StateSetEnableViewportClipPlanes(false); 1767} 1768 1769// 4J - added forceScale parameter 1770void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) 1771{ 1772 ScreenSizeCalculator ssc(mc->options, mc->width, mc->height, forceScale); 1773 1774 glClear(GL_DEPTH_BUFFER_BIT); 1775 glMatrixMode(GL_PROJECTION); 1776 glLoadIdentity(); 1777 glOrtho(0, (float)ssc.rawWidth, (float)ssc.rawHeight, 0, 1000, 3000); 1778 glMatrixMode(GL_MODELVIEW); 1779 glLoadIdentity(); 1780 glTranslatef(0, 0, -2000); 1781} 1782 1783void GameRenderer::setupClearColor(float a) 1784{ 1785 Level *level = mc->level; 1786 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 1787 1788 float whiteness = 1.0f / (4 - mc->options->viewDistance); 1789 whiteness = 1 - (float) pow((double)whiteness, 0.25); 1790 1791 Vec3 *skyColor = level->getSkyColor(mc->cameraTargetPlayer, a); 1792 float sr = (float) skyColor->x; 1793 float sg = (float) skyColor->y; 1794 float sb = (float) skyColor->z; 1795 1796 Vec3 *fogColor = level->getFogColor(a); 1797 fr = (float) fogColor->x; 1798 fg = (float) fogColor->y; 1799 fb = (float) fogColor->z; 1800 1801 if (mc->options->viewDistance < 2) 1802 { 1803 Vec3 *sunAngle = Mth::sin(level->getSunAngle(a)) > 0 ? Vec3::newTemp(-1, 0, 0) : Vec3::newTemp(1, 0, 0); 1804 float d = (float) player->getViewVector(a)->dot(sunAngle); 1805 if (d < 0) d = 0; 1806 if (d > 0) 1807 { 1808 float *c = level->dimension->getSunriseColor(level->getTimeOfDay(a), a); 1809 if (c != NULL) 1810 { 1811 d *= c[3]; 1812 fr = fr * (1 - d) + c[0] * d; 1813 fg = fg * (1 - d) + c[1] * d; 1814 fb = fb * (1 - d) + c[2] * d; 1815 } 1816 } 1817 } 1818 1819 fr += (sr - fr) * whiteness; 1820 fg += (sg - fg) * whiteness; 1821 fb += (sb - fb) * whiteness; 1822 1823 float rainLevel = level->getRainLevel(a); 1824 if (rainLevel > 0) 1825 { 1826 float ba = 1 - rainLevel * 0.5f; 1827 float bb = 1 - rainLevel * 0.4f; 1828 fr *= ba; 1829 fg *= ba; 1830 fb *= bb; 1831 } 1832 float thunderLevel = level->getThunderLevel(a); 1833 if (thunderLevel > 0) 1834 { 1835 float ba = 1 - thunderLevel * 0.5f; 1836 fr *= ba; 1837 fg *= ba; 1838 fb *= ba; 1839 } 1840 1841 int t = Camera::getBlockAt(mc->level, player, a); 1842 if (isInClouds) 1843 { 1844 Vec3 *cc = level->getCloudColor(a); 1845 fr = (float) cc->x; 1846 fg = (float) cc->y; 1847 fb = (float) cc->z; 1848 } 1849 else if (t != 0 && Tile::tiles[t]->material == Material::water) 1850 { 1851 float clearness = EnchantmentHelper::getOxygenBonus(player) * 0.2f; 1852 1853 unsigned int colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Under_Water_Clear_Colour ); 1854 byte redComponent = ((colour>>16)&0xFF); 1855 byte greenComponent = ((colour>>8)&0xFF); 1856 byte blueComponent = ((colour)&0xFF); 1857 1858 fr = (float)redComponent/256 + clearness;//0.02f; 1859 fg = (float)greenComponent/256 + clearness;//0.02f; 1860 fb = (float)blueComponent/256 + clearness;//0.2f; 1861 } 1862 else if (t != 0 && Tile::tiles[t]->material == Material::lava) 1863 { 1864 unsigned int colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Under_Lava_Clear_Colour ); 1865 byte redComponent = ((colour>>16)&0xFF); 1866 byte greenComponent = ((colour>>8)&0xFF); 1867 byte blueComponent = ((colour)&0xFF); 1868 1869 fr = (float)redComponent/256;//0.6f; 1870 fg = (float)greenComponent/256;//0.1f; 1871 fb = (float)blueComponent/256;//0.00f; 1872 } 1873 1874 float brr = fogBrO + (fogBr - fogBrO) * a; 1875 fr *= brr; 1876 fg *= brr; 1877 fb *= brr; 1878 1879 double yy = (player->yOld + (player->y - player->yOld) * a) * level->dimension->getClearColorScale(); // 4J - getClearColorScale brought forward from 1.2.3 1880 1881 if (player->hasEffect(MobEffect::blindness)) 1882 { 1883 int duration = player->getEffect(MobEffect::blindness)->getDuration(); 1884 if (duration < 20) 1885 { 1886 yy = yy * (1.0f - (float) duration / 20.0f); 1887 } 1888 else 1889 { 1890 yy = 0; 1891 } 1892 } 1893 1894 if (yy < 1) 1895 { 1896 if (yy < 0) yy = 0; 1897 yy = yy * yy; 1898 fr *= yy; 1899 fg *= yy; 1900 fb *= yy; 1901 } 1902 1903 if (darkenWorldAmount > 0) 1904 { 1905 float amount = darkenWorldAmountO + (darkenWorldAmount - darkenWorldAmountO) * a; 1906 fr = fr * (1.0f - amount) + (fr * .7f) * amount; 1907 fg = fg * (1.0f - amount) + (fg * .6f) * amount; 1908 fb = fb * (1.0f - amount) + (fb * .6f) * amount; 1909 } 1910 1911 if (player->hasEffect(MobEffect::nightVision)) 1912 { 1913 float scale = getNightVisionScale(mc->player, a); 1914 { 1915 float dist = FLT_MAX; // MGH - changed this to avoid divide by zero 1916 if ( (fr > 0) && (dist > (1.0f / fr)) ) 1917 { 1918 dist = (1.0f / fr); 1919 } 1920 if ( (fg > 0) && (dist > (1.0f / fg)) ) 1921 { 1922 dist = (1.0f / fg); 1923 } 1924 if ( (fb > 0) && (dist > (1.0f / fb)) ) 1925 { 1926 dist = (1.0f / fb); 1927 } 1928 fr = fr * (1.0f - scale) + (fr * dist) * scale; 1929 fg = fg * (1.0f - scale) + (fg * dist) * scale; 1930 fb = fb * (1.0f - scale) + (fb * dist) * scale; 1931 } 1932 } 1933 1934 if (mc->options->anaglyph3d) 1935 { 1936 float frr = (fr * 30 + fg * 59 + fb * 11) / 100; 1937 float fgg = (fr * 30 + fg * 70) / (100); 1938 float fbb = (fr * 30 + fb * 70) / (100); 1939 1940 fr = frr; 1941 fg = fgg; 1942 fb = fbb; 1943 } 1944 1945 glClearColor(fr, fg, fb, 0.0f); 1946 1947} 1948 1949void GameRenderer::setupFog(int i, float alpha) 1950{ 1951 shared_ptr<LivingEntity> player = mc->cameraTargetPlayer; 1952 1953 // 4J - check for creative mode brought forward from 1.2.3 1954 bool creative = false; 1955 if ( player->instanceof(eTYPE_PLAYER) ) 1956 { 1957 creative = (dynamic_pointer_cast<Player>(player))->abilities.instabuild; 1958 } 1959 1960 if (i == 999) 1961 { 1962 __debugbreak(); 1963 // 4J TODO 1964 /* 1965 glFog(GL_FOG_COLOR, getBuffer(0, 0, 0, 1)); 1966 glFogi(GL_FOG_MODE, GL_LINEAR); 1967 glFogf(GL_FOG_START, 0); 1968 glFogf(GL_FOG_END, 8); 1969 1970 if (GLContext.getCapabilities().GL_NV_fog_distance) { 1971 glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); 1972 } 1973 1974 glFogf(GL_FOG_START, 0); 1975 */ 1976 return; 1977 } 1978 1979 glFog(GL_FOG_COLOR, getBuffer(fr, fg, fb, 1)); 1980 glNormal3f(0, -1, 0); 1981 glColor4f(1, 1, 1, 1); 1982 1983 int t = Camera::getBlockAt(mc->level, player, alpha); 1984 1985 if (player->hasEffect(MobEffect::blindness)) 1986 { 1987 float distance = 5.0f; 1988 int duration = player->getEffect(MobEffect::blindness)->getDuration(); 1989 if (duration < 20) 1990 { 1991 distance = 5.0f + (renderDistance - 5.0f) * (1.0f - (float) duration / 20.0f); 1992 } 1993 1994 glFogi(GL_FOG_MODE, GL_LINEAR); 1995 if (i < 0) 1996 { 1997 glFogf(GL_FOG_START, 0); 1998 glFogf(GL_FOG_END, distance * 0.8f); 1999 } 2000 else 2001 { 2002 glFogf(GL_FOG_START, distance * 0.25f); 2003 glFogf(GL_FOG_END, distance); 2004 } 2005 // 4J - TODO investigate implementing this 2006 // if (GLContext.getCapabilities().GL_NV_fog_distance) 2007 // { 2008 // glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); 2009 // } 2010 } 2011 else if (isInClouds) 2012 { 2013 glFogi(GL_FOG_MODE, GL_EXP); 2014 glFogf(GL_FOG_DENSITY, 0.1f); // was 0.06 2015 } 2016 else if (t > 0 && Tile::tiles[t]->material == Material::water) 2017 { 2018 glFogi(GL_FOG_MODE, GL_EXP); 2019 if (player->hasEffect(MobEffect::waterBreathing)) 2020 { 2021 glFogf(GL_FOG_DENSITY, 0.05f); // was 0.06 2022 } 2023 else 2024 { 2025 glFogf(GL_FOG_DENSITY, 0.1f - (EnchantmentHelper::getOxygenBonus(player) * 0.03f)); // was 0.06 2026 } 2027 } 2028 else if (t > 0 && Tile::tiles[t]->material == Material::lava) 2029 { 2030 glFogi(GL_FOG_MODE, GL_EXP); 2031 glFogf(GL_FOG_DENSITY, 2.0f); // was 0.06 2032 } 2033 else 2034 { 2035 float distance = renderDistance; 2036 if (!mc->level->dimension->hasCeiling) 2037 { 2038 // 4J - test for doing bedrockfog brought forward from 1.2.3 2039 if (mc->level->dimension->hasBedrockFog() && !creative) 2040 { 2041 double yy = ((player->getLightColor(alpha) & 0xf00000) >> 20) / 16.0 + (player->yOld + (player->y - player->yOld) * alpha + 4) / 32; 2042 if (yy < 1) 2043 { 2044 if (yy < 0) yy = 0; 2045 yy = yy * yy; 2046 float dist = 100 * (float) yy; 2047 if (dist < 5) dist = 5; 2048 if (distance > dist) distance = dist; 2049 } 2050 } 2051 } 2052 2053 glFogi(GL_FOG_MODE, GL_LINEAR); 2054 glFogf(GL_FOG_START, distance * 0.25f); 2055 glFogf(GL_FOG_END, distance); 2056 if (i < 0) 2057 { 2058 glFogf(GL_FOG_START, 0); 2059 glFogf(GL_FOG_END, distance * 0.8f); 2060 } 2061 else 2062 { 2063 glFogf(GL_FOG_START, distance * 0.25f); 2064 glFogf(GL_FOG_END, distance); 2065 } 2066 /* 4J - removed - TODO investigate 2067 if (GLContext.getCapabilities().GL_NV_fog_distance) 2068 { 2069 glFogi(NVFogDistance.GL_FOG_DISTANCE_MODE_NV, NVFogDistance.GL_EYE_RADIAL_NV); 2070 } 2071 */ 2072 2073 if (mc->level->dimension->isFoggyAt((int) player->x, (int) player->z)) 2074 { 2075 glFogf(GL_FOG_START, distance * 0.05f); 2076 glFogf(GL_FOG_END, min(distance, 16 * 16 * .75f) * .5f); 2077 } 2078 } 2079 2080 glEnable(GL_COLOR_MATERIAL); 2081 glColorMaterial(GL_FRONT, GL_AMBIENT); 2082 2083} 2084 2085FloatBuffer *GameRenderer::getBuffer(float a, float b, float c, float d) 2086{ 2087 lb->clear(); 2088 lb->put(a)->put(b)->put(c)->put(d); 2089 lb->flip(); 2090 return lb; 2091} 2092 2093int GameRenderer::getFpsCap(int option) 2094{ 2095 int maxFps = 200; 2096 if (option == 1) maxFps = 120; 2097 if (option == 2) maxFps = 35; 2098 return maxFps; 2099} 2100 2101void GameRenderer::updateAllChunks() 2102{ 2103 // mc->levelRenderer->updateDirtyChunks(mc->cameraTargetPlayer, true); 2104}