diff --git a/Core/GameEngine/Include/GameClient/TerrainVisual.h b/Core/GameEngine/Include/GameClient/TerrainVisual.h index 5c679b58b43..98a49f77d8b 100644 --- a/Core/GameEngine/Include/GameClient/TerrainVisual.h +++ b/Core/GameEngine/Include/GameClient/TerrainVisual.h @@ -160,10 +160,7 @@ typedef enum _TerrainLOD CPP_11(: Int) { TERRAIN_LOD_INVALID, TERRAIN_LOD_MIN, // note that this is less than max - TERRAIN_LOD_STRETCH_NO_CLOUDS, - TERRAIN_LOD_HALF_CLOUDS, TERRAIN_LOD_NO_CLOUDS, - TERRAIN_LOD_STRETCH_CLOUDS, TERRAIN_LOD_NO_WATER, TERRAIN_LOD_MAX, // note that this is larger than min TERRAIN_LOD_AUTOMATIC, @@ -177,10 +174,7 @@ static const char *const TerrainLODNames[] = { "NONE", "MIN", - "STRETCH_NO_CLOUDS", - "HALF_CLOUDS", "NO_CLOUDS", - "STRETCH_CLOUDS", "NO_WATER", "MAX", "AUTOMATIC", diff --git a/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h index 1f20a4db26e..a8cf74b0057 100644 --- a/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h @@ -94,6 +94,8 @@ class HeightMapRenderObjClass : public BaseHeightMapRenderObjClass VERTEX_FORMAT *m_vertexBufferBackup; ///< In memory copy of the vertex buffer data for quick update of dynamic lighting. Int m_originX; ///< Origin point in the grid. Slides around. Int m_originY; ///< Origin point in the grid. Slides around. + Int m_desiredDrawWidth; // Regular draw width requested by the view system. + Int m_desiredDrawHeight; // Regular draw height requested by the view system. Int m_oversizeDrawWidth; // Oversize draw width required by mission scripts for cinematic sequences. Int m_oversizeDrawHeight; // Oversize draw height required by mission scripts for cinematic sequences. DX8IndexBufferClass *m_indexBuffer; ///reset(); //need reset here since initHeightData will load new shroud. BaseHeightMapRenderObjClass *newROBJ = nullptr; - if (TheGlobalData->m_terrainLOD==7) { + if (TheGlobalData->m_terrainLOD == TERRAIN_LOD_MAX) { newROBJ = TheHeightMap; if (newROBJ==nullptr) { newROBJ = NEW_REF( HeightMapRenderObjClass, () ); @@ -351,8 +351,7 @@ void BaseHeightMapRenderObjClass::adjustTerrainLOD(Int adj) newROBJ = NEW_REF( FlatHeightMapRenderObjClass, () ); } } - if (TheGlobalData->m_terrainLOD == 5) - newROBJ = nullptr; + RTS3DScene *pMyScene = (RTS3DScene *)Scene; if (pMyScene) { pMyScene->Remove_Render_Object(this); diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp index 0789177cf81..30b1df84b21 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp @@ -1048,6 +1048,8 @@ m_vertexBufferTiles(nullptr), m_vertexBufferBackup(nullptr), m_originX(0), m_originY(0), +m_desiredDrawWidth(WorldHeightMap::NORMAL_DRAW_WIDTH), +m_desiredDrawHeight(WorldHeightMap::NORMAL_DRAW_HEIGHT), m_oversizeDrawWidth(0), m_oversizeDrawHeight(0), m_indexBuffer(nullptr), @@ -1081,45 +1083,19 @@ void HeightMapRenderObjClass::adjustTerrainLOD(Int adj) case TERRAIN_LOD_MIN: TheWritableGlobalData->m_useCloudMap = false; TheWritableGlobalData->m_useLightMap = false ; TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = true; - break; - case TERRAIN_LOD_HALF_CLOUDS: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = true; - break; - case TERRAIN_LOD_STRETCH_NO_CLOUDS: TheWritableGlobalData->m_useCloudMap = false; - TheWritableGlobalData->m_useLightMap = false; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = true; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - case TERRAIN_LOD_STRETCH_CLOUDS: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = true; - TheWritableGlobalData->m_useHalfHeightMap = false; break; case TERRAIN_LOD_NO_CLOUDS: TheWritableGlobalData->m_useCloudMap = false; TheWritableGlobalData->m_useLightMap = false; TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; break; default: case TERRAIN_LOD_NO_WATER: TheWritableGlobalData->m_useCloudMap = true; TheWritableGlobalData->m_useLightMap = true; TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; break; case TERRAIN_LOD_MAX: TheWritableGlobalData->m_useCloudMap = true; TheWritableGlobalData->m_useLightMap = true; TheWritableGlobalData->m_useWaterPlane = true; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; break; } if (m_map==nullptr) return; @@ -1178,17 +1154,13 @@ void HeightMapRenderObjClass::oversizeTerrain(Int tilesToOversize) { m_oversizeDrawWidth = WorldHeightMap::NORMAL_DRAW_WIDTH + VERTEX_BUFFER_TILE_LENGTH * tilesToOversize; m_oversizeDrawHeight = WorldHeightMap::NORMAL_DRAW_HEIGHT + VERTEX_BUFFER_TILE_LENGTH * tilesToOversize; - m_oversizeDrawWidth = std::min(m_oversizeDrawWidth, m_map->getXExtent()); - m_oversizeDrawHeight = std::min(m_oversizeDrawHeight, m_map->getYExtent()); - setTerrainDrawSize(m_oversizeDrawWidth, m_oversizeDrawHeight); + setTerrainDrawSize(0, 0); } else { m_oversizeDrawWidth = 0; m_oversizeDrawHeight = 0; - Int width = std::min((Int)WorldHeightMap::NORMAL_DRAW_WIDTH, m_map->getXExtent()); - Int height = std::min((Int)WorldHeightMap::NORMAL_DRAW_HEIGHT, m_map->getYExtent()); - setTerrainDrawSize(width, height); + setTerrainDrawSize(m_desiredDrawWidth, m_desiredDrawHeight); } } @@ -1197,15 +1169,17 @@ void HeightMapRenderObjClass::setTerrainDrawSize(Int width, Int height) if (m_map == nullptr) return; - if (m_oversizeDrawWidth != 0) - width = m_oversizeDrawWidth; - else - width = std::min(width, m_map->getXExtent()); + if (width > 0) + m_desiredDrawWidth = width; - if (m_oversizeDrawHeight != 0) - height = m_oversizeDrawHeight; - else - height = std::min(height, m_map->getYExtent()); + if (height > 0) + m_desiredDrawHeight = height; + + width = std::max(m_oversizeDrawWidth, m_desiredDrawWidth); + height = std::max(m_oversizeDrawHeight, m_desiredDrawHeight); + + width = std::min(width, m_map->getXExtent()); + height = std::min(height, m_map->getYExtent()); if (width == m_map->getDrawWidth() && height == m_map->getDrawHeight()) return; @@ -1670,8 +1644,17 @@ void HeightMapRenderObjClass::updateCenter(CameraClass *camera, const Vector3 *c BaseHeightMapRenderObjClass::updateCenter(camera, cameraPivot, pLightsIterator); + m_updating = true; + if (m_x >= m_map->getXExtent() && m_y >= m_map->getYExtent()) - { + { + if (m_needFullUpdate) + { + m_needFullUpdate = false; + updateBlock(0, 0, m_x-1, m_y-1, m_map, pLightsIterator); + } + + m_updating = false; return; // no need to center. } @@ -1792,7 +1775,6 @@ void HeightMapRenderObjClass::updateCenter(CameraClass *camera, const Vector3 *c WorldHeightMap::DrawArea newDrawArea = m_map->createDrawArea(newOrgX, newOrgY); - m_updating = true; if (m_needFullUpdate) { m_needFullUpdate = false; diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp index e8f4bcfbfef..682699a50b4 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp @@ -810,73 +810,7 @@ void W3DTreeBuffer::loadTreesInVertexAndIndexBuffers(RefRenderObjListIterator *p Vector3 normal(0.0f,0.0f,1.0f); diffuse = doLighting(&normal, objectLighting, &emissive, 0xFFFFFFFF, 1.0f); } - /* - * - // If we are doing reduced resolution terrain, do reduced - // poly trees. - Bool doPanel = (TheGlobalData->m_useHalfHeightMap || TheGlobalData->m_stretchTerrain); - - if (doPanel) { - if (m_trees[curTree].rotates) { - theSin = -lookAtVector.X; - theCos = lookAtVector.Y; - } - // panel start is index offset, there are 3 index per triangle. - if (m_trees[curTree].panelStart/3 + 2 > numIndex) { - continue; // not enough polygons for the offset. jba. - } - for (j=0; j<6; j++) { - i = ((Int *)pPoly)[j+m_trees[curTree].panelStart]; - if (m_curNumTreeVertices >= MAX_TREE_VERTEX) - break; - // Update the uv values. The W3D models each have their own texture, and - // we use one texture with all images in one, so we have to change the uvs to - // match. - Real U, V; - if (type==SHRUB) { - // shrub texture is tucked in the corner - U = ((512-64)+uvs[i].U*64.0f)/512.0f; - V = ((256-64)+uvs[i].V*64.0f)/256.0f; - } else if (type==FENCE) { - U = uvs[i].U*0.5f; - V = 1.0f + uvs[i].V; - } else { - U = typeOffset+uvs[i].U*0.5f; - V = uvs[i].V; - } - - curVb->u1 = U; - curVb->v1 = V/2.0; - Vector3 vLoc; - vLoc.X = pVert[i].X*scale*theCos - pVert[i].Y*scale*theSin; - vLoc.Y = pVert[i].Y*scale*theCos + pVert[i].X*scale*theSin; - - vLoc.X += loc.X; - vLoc.Y += loc.Y; - vLoc.Z = loc.Z + pVert[i].Z*scale; - - curVb->x = vLoc.X; - curVb->y = vLoc.Y; - curVb->z = vLoc.Z; - if (doVertexLighting) { - curVb->diffuse = doLighting(&vLoc, shadeR, shadeG, shadeB, m_trees[curTree].bounds, pDynamicLightsIterator); - } else { - curVb->diffuse = diffuse; - } - curVb++; - m_curNumTreeVertices++; - } - - for (i=0; i<6; i++) { - if (m_curNumTreeIndices+4 > MAX_TREE_INDEX) - break; - curIb--; - *curIb = startVertex + i; - m_curNumTreeIndices++; - } - } else { - */ Real Uscale = m_treeTypes[type].m_tileWidth * (Real)TILE_PIXEL_EXTENT / (Real)m_textureWidth; Real Vscale = m_treeTypes[type].m_tileWidth * (Real)TILE_PIXEL_EXTENT / (Real)m_textureHeight; Real UOffset = m_treeTypes[type].m_textureOrigin.x/(Real)m_textureWidth; diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 3f684ea7597..bc7d5bca59d 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -3717,30 +3717,58 @@ void W3DView::Add_Camera_Shake (const Coord3D & position,float radius,float dura CameraShakerSystem.Add_Camera_Shake(vpos,radius,duration,power); } +bool W3DView::getDesiredTerrainDrawSize(ICoord2D &dimensions) const +{ + if (TheGlobalData && TheGlobalData->m_drawEntireTerrain) + { + DEBUG_ASSERTCRASH(TheTerrainRenderObject != nullptr, ("TheTerrainRenderObject is null")); + + if (WorldHeightMap *heightMap = TheTerrainRenderObject->getMap()) + { + dimensions.x = heightMap->getXExtent(); + dimensions.y = heightMap->getYExtent(); + return true; + } + } + else + { + const Real cameraPitch = asin(fabs(m_3DCamera->Get_Forward_Dir().Z)); + + if (cameraPitch > ViewDefaultLowPitchRadians || !m_isUserControlled) + { + // TheSuperHackers @info The scripted camera always uses the regular draw sizes + // and uses terrain oversize if it needs to enlarge. + dimensions.x = WorldHeightMap::NORMAL_DRAW_WIDTH; + dimensions.y = WorldHeightMap::NORMAL_DRAW_HEIGHT; + return true; + } + else + { + // TheSuperHackers @tweak xezon 31/12/2025 Increases visible terrain area when lowering the camera pitch. + // Note: The default camera pitch in Generals was 37.5, which we prefer to keep the normal draw size for. + dimensions.x = WorldHeightMap::LOW_ANGLE_DRAW_WIDTH; + dimensions.y = WorldHeightMap::LOW_ANGLE_DRAW_HEIGHT; + return true; + } + } + + return false; +} + void W3DView::updateTerrain() { DEBUG_ASSERTCRASH(TheTerrainRenderObject != nullptr, ("TheTerrainRenderObject is null")); - RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator(); - const Vector3 cameraPivot(m_pos.x, m_pos.y, m_pos.z); - const Real cameraPitch = asin(fabs(m_3DCamera->Get_Forward_Dir().Z)); - Int drawWidth; - Int drawHeight; + ICoord2D drawSize; - if (cameraPitch > ViewDefaultLowPitchRadians) - { - drawWidth = WorldHeightMap::NORMAL_DRAW_WIDTH; - drawHeight = WorldHeightMap::NORMAL_DRAW_HEIGHT; - } - else + if (getDesiredTerrainDrawSize(drawSize)) { - // TheSuperHackers @tweak xezon 31/12/2025 Increases visible terrain area when lowering the camera pitch. - // Note: The default camera pitch in Generals was 37.5, which we prefer to keep the normal draw size for. - drawWidth = WorldHeightMap::LOW_ANGLE_DRAW_WIDTH; - drawHeight = WorldHeightMap::LOW_ANGLE_DRAW_HEIGHT; + TheTerrainRenderObject->setTerrainDrawSize(drawSize.x, drawSize.y); } - TheTerrainRenderObject->setTerrainDrawSize(drawWidth, drawHeight); + RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator(); + + const Vector3 cameraPivot(m_pos.x, m_pos.y, m_pos.z); TheTerrainRenderObject->updateCenter(m_3DCamera, &cameraPivot, it); if (it) diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp index cff40a8d32c..0bc1f9b35ef 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp @@ -487,10 +487,6 @@ WorldHeightMap::WorldHeightMap(ChunkInputStream *pStrm, Bool logicalDataOnly): m_sourceTiles[i]=nullptr; m_edgeTiles[i]=nullptr; } - if (TheGlobalData && TheGlobalData->m_stretchTerrain) { - m_drawWidthX=STRETCH_DRAW_WIDTH; - m_drawHeightY=STRETCH_DRAW_HEIGHT; - } DataChunkInput file( pStrm ); @@ -529,16 +525,6 @@ WorldHeightMap::WorldHeightMap(ChunkInputStream *pStrm, Bool logicalDataOnly): } } } - if (TheGlobalData && TheGlobalData->m_drawEntireTerrain) { - m_drawWidthX=m_width; - m_drawHeightY=m_height; - } - if (m_drawWidthX > m_width) { - m_drawWidthX = m_width; - } - if (m_drawHeightY > m_height) { - m_drawHeightY = m_height; - } TheSidesList->validateSides(); setupAlphaTiles(); @@ -2221,19 +2207,8 @@ Region2D WorldHeightMap::getDrawRegion2D() WorldHeightMap::DrawArea WorldHeightMap::createDrawArea(Int xOrg, Int yOrg) { DrawArea area; - area.sizeX = m_drawWidthX; - area.sizeY = m_drawHeightY; - - if (TheGlobalData && TheGlobalData->m_stretchTerrain) { - area.sizeX = STRETCH_DRAW_WIDTH; - area.sizeY = STRETCH_DRAW_HEIGHT; - } - if (TheGlobalData && TheGlobalData->m_drawEntireTerrain) { - area.sizeX = m_width; - area.sizeY = m_height; - } - area.sizeX = std::min(area.sizeX, m_width); - area.sizeY = std::min(area.sizeY, m_height); + area.sizeX = std::min(m_drawWidthX, m_width); + area.sizeY = std::min(m_drawHeightY, m_height); area.originX = clamp(0, xOrg, m_width - area.sizeX); area.originY = clamp(0, yOrg, m_height - area.sizeY); diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 4c5130e1c05..84604a2dde4 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -132,8 +132,8 @@ class GlobalData : public SubsystemInterface Bool m_trilinearTerrainTex; Bool m_multiPassTerrain; Bool m_adjustCliffTextures; - Bool m_stretchTerrain; - Bool m_useHalfHeightMap; + Bool m_stretchTerrain; // TheSuperHackers @info Legacy, unused + Bool m_useHalfHeightMap; // TheSuperHackers @info Legacy, unused Bool m_drawEntireTerrain; _TerrainLOD m_terrainLOD; Bool m_enableDynamicLOD; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 91541e588d0..eda60aeac0d 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -1713,8 +1713,7 @@ void W3DDisplay::calculateTerrainLOD() default: curLOD = TERRAIN_LOD_DISABLE; break; case TERRAIN_LOD_AUTOMATIC: curLOD = TERRAIN_LOD_MAX; break; case TERRAIN_LOD_MAX: curLOD = TERRAIN_LOD_NO_WATER; break; - case TERRAIN_LOD_HALF_CLOUDS: curLOD = TERRAIN_LOD_DISABLE; break; - case TERRAIN_LOD_NO_WATER: curLOD = TERRAIN_LOD_HALF_CLOUDS; break; + case TERRAIN_LOD_NO_WATER: curLOD = TERRAIN_LOD_DISABLE; break; } if (curLOD == TERRAIN_LOD_DISABLE) { break;