| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: W3DTerrainBackground.cpp ////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- //
- // EA Pacific.
- //
- // Confidential Information
- // Copyright (C) 2003 - All Rights Reserved
- //
- //-----------------------------------------------------------------------------
- //
- // Project: RTS3
- //
- // File name: W3DTerrainBackground.cpp
- //
- // Created: John Ahlquist, March 2003
- //
- // Desc: Draw buffer to handle backup terrain at lower res.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // Includes
- //-----------------------------------------------------------------------------
- #include "W3DDevice/GameClient/W3DTerrainBackground.h"
- #include <stdio.h>
- #include <string.h>
- #include <assetmgr.h>
- #include <texture.h>
- #include "common/GlobalData.h"
- #include "GameClient/View.h"
- #include "W3DDevice/GameClient/TerrainTex.h"
- #include "W3DDevice/GameClient/HeightMap.h"
- #include "WW3D2/DX8Wrapper.h"
- #include "WW3D2/DX8Renderer.h"
- #include "WW3D2/Camera.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- //-----------------------------------------------------------------------------
- // Private Data
- //-----------------------------------------------------------------------------
- // A W3D shader that does alpha, texturing, tests zbuffer, doesn't update zbuffer.
- #define SC_DETAIL ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_ONE, \
- ShaderClass::DSTBLEND_ZERO, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \
- ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \
- ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) )
- static ShaderClass detailShader(SC_DETAIL);
- const Int PIXELS_PER_GRID = 8; // default tex resolution allocated for each tile. jba. [3/24/2003]
- //-----------------------------------------------------------------------------
- // Private Functions
- //-----------------------------------------------------------------------------
- //=============================================================================
- // W3DTerrainBackground::loadTerrainInVertexAndIndexBuffers
- //=============================================================================
- /** Loads the terrain into the vertex buffer for drawing. */
- //=============================================================================
- void W3DTerrainBackground::setFlip(WorldHeightMap *htMap)
- {
- if (m_map==NULL) return;
- if (htMap) {
- REF_PTR_SET(m_map, htMap);
- }
- if (!m_initialized) {
- return;
- }
- setFlipRecursive(0, 0, m_width);
- }
- const Int STEP=4;
- //=============================================================================
- // W3DTerrainBackground::doPartialUpdate
- //=============================================================================
- /** Updates a partial block of vertices from [x0,y0 to x1,y1]
- The coordinates in partialRange are map cell coordinates, relative to the entire map.
- The vertex coordinates and texture coordinates, as well as static lighting are updated.
- */
- void W3DTerrainBackground::doPartialUpdate(const IRegion2D &partialRange, WorldHeightMap *htMap, Bool doTextures )
- {
- if (m_map==NULL) return;
- if (htMap) {
- REF_PTR_SET(m_map, htMap);
- }
- if (!m_initialized) {
- return;
- }
- doTesselatedUpdate(partialRange, htMap, doTextures);
- return;
- Int requiredVertexSize = (m_width+1) * (m_width+1) + 6;
- if (m_vertexTerrainSize<requiredVertexSize || m_vertexTerrain==NULL) {
- m_vertexTerrainSize = requiredVertexSize;
- REF_PTR_RELEASE(m_vertexTerrain);
- REF_PTR_RELEASE(m_indexTerrain);
- m_vertexTerrain=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,m_vertexTerrainSize+4,DX8VertexBufferClass::USAGE_DEFAULT));
- }
- Int requiredIndexSize = (m_width+1) * (m_width+1) + 6;
- if (m_indexTerrainSize<requiredIndexSize || m_indexTerrain==NULL) {
- m_indexTerrainSize = requiredIndexSize;
- REF_PTR_RELEASE(m_indexTerrain);
- m_indexTerrain=NEW_REF(DX8IndexBufferClass,(m_indexTerrainSize+4,DX8IndexBufferClass::USAGE_DEFAULT));
- }
- Int minX = m_xOrigin;
- Int minY = m_yOrigin;
- Int maxX = m_xOrigin + m_width;
- Int maxY = m_yOrigin + m_width;
- Int limitX = m_map->getXExtent()-1;
- Int limitY = m_map->getYExtent()-1;
- if (maxX>limitX) maxX = limitX;
- if (maxY>limitY) maxY = limitY;
- if (partialRange.lo.x > maxX) return;
- if (partialRange.lo.y > maxY) return;
- if (partialRange.hi.x < minX) return;
- if (partialRange.hi.y < minY) return;
- m_curNumTerrainVertices = 0;
- //m_curNumTerrainIndices = 0;
- VertexFormatXYZDUV2 *vb;
- UnsignedShort *ib;
- // Lock the buffer.
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexTerrain);
- vb=(VertexFormatXYZDUV2*)lockVtxBuffer.Get_Vertex_Array();
- // Add to the vertex buffer.
- VertexFormatXYZDUV2 *curVb = vb;
- MinMaxAABoxClass bounds;
- bounds.Init_Empty();
- Int i, j;
- for (j=minY; j<=maxY; j+=STEP) {
- for (i=minX; i<=maxX; i+=STEP) {
- if (m_curNumTerrainVertices >= m_vertexTerrainSize) return;
- curVb->diffuse = (0<<24)|TheTerrainRenderObject->getStaticDiffuse(i,j);
- Vector3 pos;
- pos.Z = ((float)m_map->getHeight(i,j)*MAP_HEIGHT_SCALE);
- pos.X = (i)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- pos.Y = (j)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- curVb->u1 = (float)(i-minX)/(float)(m_width);
- curVb->v1 = 1.0f - (float)(j-minY)/(float)(m_width);
- curVb->x = pos.X;
- curVb->y = pos.Y;
- curVb->z = pos.Z;
- curVb++;
- m_curNumTerrainVertices++;
- bounds.Add_Point(pos);
- }
- }
- m_bounds.Init(bounds);
- if (m_terrainTexture == NULL || doTextures) {
- REF_PTR_RELEASE(m_terrainTexture);
- REF_PTR_RELEASE(m_terrainTexture2X);
- REF_PTR_RELEASE(m_terrainTexture4X);
- m_terrainTexture = m_map->getFlatTexture(m_xOrigin, m_yOrigin, m_width, PIXELS_PER_GRID);
- // DEBUG ONLY. jba. m_terrainTexture = (TerrainTextureClass *)NEW_REF(TextureClass, ("TBBib.tga"));
- m_terrainTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_terrainTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- if (m_curNumTerrainIndices == 0) {
- // Only do the index buffer if it has never been done. Index values don't change. jba.
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexTerrain);
- ib = lockIdxBuffer.Get_Index_Array();
- UnsignedShort *curIb = ib;
- Int yOffset = ((maxX - minX)/STEP+1);
- Int width = yOffset;
- Int height = (maxY - minY)/STEP;
- *curIb++ = width-1;
- m_curNumTerrainIndices++;
- for (j=0; j<height; j++) {
- *curIb++ = j*yOffset + yOffset + width-1;
- m_curNumTerrainIndices++;
- for (i=width-2; i>=0; i--) {
- if (m_curNumTerrainIndices+2 > m_indexTerrainSize) return;
- *curIb++ = j*yOffset + i;
- *curIb++ = j*yOffset + i+yOffset;
- m_curNumTerrainIndices+=2;
- }
- j++;
- if (j<height) {
- *curIb++ = j*yOffset + yOffset;
- m_curNumTerrainIndices++;
- for (i=1; i<width; i++) {
- if (m_curNumTerrainIndices+2 > m_indexTerrainSize) return;
- *curIb++ = j*yOffset + i;
- *curIb++ = j*yOffset + i+yOffset;
- m_curNumTerrainIndices+=2;
- }
- }
- }
- }
- }
- //=============================================================================
- // W3DTerrainBackground::fillVBRecursive
- //=============================================================================
- /** Fills in vertex & index buffers.
- */
- Bool W3DTerrainBackground::advanceLeft(ICoord2D &left, Int xOffset, Int yOffset, Int width)
- {
- while (left.y < yOffset+width) {
- left.y++;
- if (m_map->getFlipState(left.x+m_xOrigin, left.y+m_yOrigin)) {
- return true;
- }
- }
- while (left.x < xOffset+width-1) {
- left.x++;
- if (m_map->getFlipState(left.x+m_xOrigin, left.y+m_yOrigin)) {
- return true;
- }
- }
- return false;
- }
- //=============================================================================
- // W3DTerrainBackground::fillVBRecursive
- //=============================================================================
- /** Fills in vertex & index buffers.
- */
- Bool W3DTerrainBackground::advanceRight(ICoord2D &right, Int xOffset, Int yOffset, Int width)
- {
- while (right.x < xOffset+width) {
- right.x++;
- if (m_map->getFlipState(right.x+m_xOrigin, right.y+m_yOrigin)) {
- return true;
- }
- }
- while (right.y < yOffset+width-1) {
- right.y++;
- if (m_map->getFlipState(right.x+m_xOrigin, right.y+m_yOrigin)) {
- return true;
- }
- }
- return false;
- }
- //=============================================================================
- // W3DTerrainBackground::fillVBRecursive
- //=============================================================================
- /** Fills in vertex & index buffers.
- */
- void W3DTerrainBackground::fillVBRecursive(UnsignedShort *ib, Int xOffset, Int yOffset,
- Int width, UnsignedShort *ndx, Int &curIndex)
- {
-
- Int bottomLeftNdx = ndx[xOffset+yOffset*(m_width+1)];
- Int topRightNdx = ndx[xOffset+width + (yOffset+width)*(m_width+1)];
- Int limitX = m_map->getXExtent()-1;
- Int limitY = m_map->getYExtent()-1;
- Int i, j;
- Bool match = true;
- Int minX = m_xOrigin+xOffset;
- Int minY = m_yOrigin+yOffset;
- Int cornerHeight = m_map->getHeight(minX, minY);
- for (i=0; i<=width; i++) {
- for (j=0; j<=width; j++) {
- Int k = minX+i;
- k = k<limitX?k:limitX;
- Int l = minY+j;
- l = l<limitY?l:limitY;
- if (cornerHeight!=m_map->getHeight(k, l)) {
- match = false;
- break;
- }
- }
- }
- if (width==1) {
- match = true;
- }
- if (match) {
- UnsignedShort prevNdxLeft;
- UnsignedShort prevNdxRight;
- ICoord2D left;
- left.x = xOffset;
- left.y = yOffset;
- ICoord2D right;
- right.x = xOffset;
- right.y = yOffset;
- advanceLeft(left, xOffset, yOffset, width);
- advanceRight(right, xOffset, yOffset, width);
- if (ib) {
- ib[curIndex] = bottomLeftNdx;
- }
- curIndex++;
- prevNdxRight = ndx[right.x+right.y*(m_width+1)];
- if (ib) {
- ib[curIndex] = prevNdxRight;
- }
- curIndex++;
- prevNdxLeft = ndx[left.x+left.y*(m_width+1)];
- if (ib) {
- ib[curIndex] = prevNdxLeft;
- }
- curIndex++;
- Bool didLeft = true;
- Bool didRight = true;
- while (didLeft || didRight) {
- didLeft = advanceLeft(left, xOffset, yOffset, width);
- if (didLeft) {
- if (ib) {
- ib[curIndex] = prevNdxLeft;
- }
- curIndex++;
- if (ib) {
- ib[curIndex] = prevNdxRight;
- }
- curIndex++;
- prevNdxLeft = ndx[left.x+left.y*(m_width+1)];
- if (ib) {
- ib[curIndex] = prevNdxLeft;
- }
- curIndex++;
- }
- didRight = advanceRight(right, xOffset, yOffset, width);
- if (didRight) {
- if (ib) {
- ib[curIndex] = prevNdxLeft;
- }
- curIndex++;
- if (ib) {
- ib[curIndex] = prevNdxRight;
- }
- curIndex++;
- prevNdxRight = ndx[right.x+right.y*(m_width+1)];
- if (ib) {
- ib[curIndex] = prevNdxRight;
- }
- curIndex++;
- }
- }
- if (ib) {
- ib[curIndex] = prevNdxLeft;
- }
- curIndex++;
- if (ib) {
- ib[curIndex] = prevNdxRight;
- }
- curIndex++;
- if (ib) {
- ib[curIndex] = topRightNdx;
- }
- curIndex++;
- return;
- }
- Int halfWidth = width/2;
- fillVBRecursive(ib, xOffset, yOffset, halfWidth, ndx, curIndex);
- fillVBRecursive(ib, xOffset, yOffset+halfWidth, halfWidth, ndx, curIndex);
- fillVBRecursive(ib, xOffset+halfWidth, yOffset, halfWidth, ndx, curIndex);
- fillVBRecursive(ib, xOffset+halfWidth, yOffset+halfWidth, halfWidth, ndx, curIndex);
-
- }
- //=============================================================================
- // W3DTerrainBackground::fillVBRecursive
- //=============================================================================
- /** Fills in vertex & index buffers.
- */
- void W3DTerrainBackground::setFlipRecursive(Int xOffset, Int yOffset, Int width)
- {
-
- Int limitX = m_map->getXExtent()-1;
- Int limitY = m_map->getYExtent()-1;
- Int i, j;
- Bool match = true;
- Int minX = m_xOrigin+xOffset;
- Int minY = m_yOrigin+yOffset;
- Int cornerHeight = m_map->getHeight(minX, minY);
- for (i=0; i<=width; i++) {
- for (j=0; j<=width; j++) {
- Int k = minX+i;
- k = k<limitX?k:limitX;
- Int l = minY+j;
- l = l<limitY?l:limitY;
- if (cornerHeight!=m_map->getHeight(k, l)) {
- match = false;
- break;
- }
- }
- }
- if (width==1) {
- match = true;
- }
- if (match) {
- m_map->setFlipState(minX, minY, true);
- m_map->setFlipState(minX+width, minY, true);
- m_map->setFlipState(minX+width, minY+width, true);
- m_map->setFlipState(minX, minY+width, true);
- return;
- }
- Int halfWidth = width/2;
- setFlipRecursive(xOffset, yOffset, halfWidth);
- setFlipRecursive(xOffset, yOffset+halfWidth, halfWidth);
- setFlipRecursive(xOffset+halfWidth, yOffset, halfWidth);
- setFlipRecursive(xOffset+halfWidth, yOffset+halfWidth, halfWidth);
-
- }
- //=============================================================================
- // W3DTerrainBackground::doTesselatedUpdate
- //=============================================================================
- /** Updates a partial block of vertices from [x0,y0 to x1,y1]
- The coordinates in partialRange are map cell coordinates, relative to the entire map.
- The vertex coordinates and texture coordinates, as well as static lighting are updated.
- */
- void W3DTerrainBackground::doTesselatedUpdate(const IRegion2D &partialRange, WorldHeightMap *htMap, Bool doTextures )
- {
- if (m_map==NULL) return;
- if (htMap) {
- REF_PTR_SET(m_map, htMap);
- }
- if (!m_initialized) {
- return;
- }
- Int minX = m_xOrigin;
- Int minY = m_yOrigin;
- Int maxX = m_xOrigin + m_width;
- Int maxY = m_yOrigin + m_width;
- Int limitX = m_map->getXExtent()-1;
- Int limitY = m_map->getYExtent()-1;
- if (partialRange.lo.x > maxX) return;
- if (partialRange.lo.y > maxY) return;
- if (partialRange.hi.x < minX) return;
- if (partialRange.hi.y < minY) return;
- setFlip(htMap);
- Int count = (m_width+1)*(m_width+1);
- UnsignedShort *ndx = new UnsignedShort[count];
- Int requiredVertex = 0;
- Int i, j;
- for (j=minY; j<=maxY; j++) {
- for (i=minX; i<=maxX; i++) {
- Int ndxNdx = i-minX + (m_width+1)*(j-minY);
- DEBUG_ASSERTCRASH(ndxNdx<count, ("Bad ndxNdx"));
- ndx[ndxNdx] = 0;
- if (m_map->getFlipState(i, j)) {
- requiredVertex++;
- }
- }
- }
- if (m_vertexTerrainSize<requiredVertex || m_vertexTerrain==NULL) {
- m_vertexTerrainSize = requiredVertex;
- REF_PTR_RELEASE(m_vertexTerrain);
- m_vertexTerrain=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV2,m_vertexTerrainSize+4,DX8VertexBufferClass::USAGE_DEFAULT));
- }
- m_curNumTerrainVertices = 0;
- VertexFormatXYZDUV2 *vb;
- // Lock the buffer.
- DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexTerrain);
- vb=(VertexFormatXYZDUV2*)lockVtxBuffer.Get_Vertex_Array();
- VertexFormatXYZDUV2 *curVb = vb;
- // Add to the vertex buffer.
- for (j=minY; j<=maxY; j++) {
- for (i=minX; i<=maxX; i++) {
- if (m_map->getFlipState(i, j)) {
- curVb->diffuse = (0<<24)|TheTerrainRenderObject->getStaticDiffuse(i,j);
- Vector3 pos;
- Int k = i<limitX?i:limitX;
- Int l = j<limitY?j:limitY;
- pos.Z = ((float)m_map->getHeight(k,l)*MAP_HEIGHT_SCALE);
- pos.X = (i)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- pos.Y = (j)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- curVb->u1 = (float)(i-minX)/(float)(m_width);
- curVb->v1 = 1.0f - (float)(j-minY)/(float)(m_width);
- curVb->x = pos.X;
- curVb->y = pos.Y;
- curVb->z = pos.Z;
- curVb++;
- Int ndxNdx = i-minX + (m_width+1)*(j-minY);
- DEBUG_ASSERTCRASH(ndxNdx<count, ("Bad ndxNdx"));
- ndx[ndxNdx] = m_curNumTerrainVertices;
- m_curNumTerrainVertices++;
- }
- }
- }
- Int requiredIndex = 0;
- fillVBRecursive(NULL, 0, 0, m_width, ndx, requiredIndex);
- if (m_indexTerrainSize<requiredIndex || m_indexTerrain==NULL) {
- m_indexTerrainSize = requiredIndex;
- REF_PTR_RELEASE(m_indexTerrain);
- m_indexTerrain=NEW_REF(DX8IndexBufferClass,(m_indexTerrainSize+4,DX8IndexBufferClass::USAGE_DEFAULT));
- }
- m_curNumTerrainIndices = 0;
- UnsignedShort *ib;
- DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexTerrain);
- ib = lockIdxBuffer.Get_Index_Array();
- fillVBRecursive(ib, 0, 0, m_width, ndx, m_curNumTerrainIndices);
- delete ndx;
- ndx = NULL;
- MinMaxAABoxClass bounds;
- bounds.Init_Empty();
- for (j=minY; j<=maxY; j+=1) {
- for (i=minX; i<=maxX; i+=1) {
- Vector3 pos;
- Int k = i<limitX?i:limitX;
- Int l = j<limitY?j:limitY;
- pos.Z = ((float)m_map->getHeight(k,l)*MAP_HEIGHT_SCALE);
- pos.X = (i)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- pos.Y = (j)*MAP_XY_FACTOR - m_map->getBorderSizeInline()*MAP_XY_FACTOR;
- bounds.Add_Point(pos);
- }
- }
- m_bounds.Init(bounds);
- if (m_terrainTexture == NULL || doTextures) {
- REF_PTR_RELEASE(m_terrainTexture);
- REF_PTR_RELEASE(m_terrainTexture2X);
- REF_PTR_RELEASE(m_terrainTexture4X);
- m_terrainTexture = m_map->getFlatTexture(m_xOrigin, m_yOrigin, m_width, PIXELS_PER_GRID);
- // DEBUG ONLY. jba. m_terrainTexture = (TerrainTextureClass *)NEW_REF(TextureClass, ("TBBib.tga"));
- m_terrainTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_terrainTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- }
- //-----------------------------------------------------------------------------
- // Public Functions
- //-----------------------------------------------------------------------------
- //=============================================================================
- // W3DTerrainBackground::~W3DTerrainBackground
- //=============================================================================
- /** Destructor. Releases w3d assets. */
- //=============================================================================
- W3DTerrainBackground::~W3DTerrainBackground(void)
- {
- freeTerrainBuffers();
- REF_PTR_RELEASE(m_terrainTexture);
- REF_PTR_RELEASE(m_terrainTexture2X);
- REF_PTR_RELEASE(m_terrainTexture4X);
- }
- //=============================================================================
- // W3DTerrainBackground::W3DTerrainBackground
- //=============================================================================
- /** Constructor. Sets m_initialized to true if it finds the w3d models it needs
- for the bibs. */
- //=============================================================================
- W3DTerrainBackground::W3DTerrainBackground(void):
- m_vertexTerrain(NULL),
- m_vertexTerrainSize(0),
- m_initialized(FALSE),
- m_indexTerrain(NULL),
- m_indexTerrainSize(0),
- m_terrainTexture(NULL),
- m_terrainTexture2X(NULL),
- m_terrainTexture4X(NULL),
- m_cullStatus(CULL_STATUS_UNKNOWN),
- m_texMultiplier(TEX1X)
- {
- }
- //=============================================================================
- // W3DTerrainBackground::freeTerrainBuffers
- //=============================================================================
- /** Frees the index and vertex buffers. */
- //=============================================================================
- void W3DTerrainBackground::freeTerrainBuffers(void)
- {
- REF_PTR_RELEASE(m_vertexTerrain);
- REF_PTR_RELEASE(m_indexTerrain);
- m_curNumTerrainVertices=0;
- m_curNumTerrainIndices=0;
- m_initialized = false;
- REF_PTR_RELEASE(m_map);
- REF_PTR_RELEASE(m_map);
- }
- //=============================================================================
- // W3DTerrainBackground::allocateTerrainBuffers
- //=============================================================================
- /** Allocates the index and vertex buffers. */
- //=============================================================================
- void W3DTerrainBackground::allocateTerrainBuffers(WorldHeightMap *htMap, Int xOrigin, Int yOrigin, Int width)
- {
- if (htMap==NULL) return;
- freeTerrainBuffers(); // in case already allocated. jba [3/24/2003]
- m_curNumTerrainVertices=0;
- m_curNumTerrainIndices=0;
- m_xOrigin = xOrigin;
- m_yOrigin = yOrigin;
- m_width = width;
- m_initialized = true;
- REF_PTR_SET(m_map, htMap);
- }
- //=============================================================================
- // W3DTerrainBackground::updateCenter
- //=============================================================================
- /** Updates the culling status. */
- //=============================================================================
- void W3DTerrainBackground::updateCenter(CameraClass *camera)
- {
- if (camera->Cull_Box(m_bounds)) {
- m_cullStatus = CULL_STATUS_INVISIBLE;
- } else {
- m_cullStatus = CULL_STATUS_VISIBLE;
- }
- if (m_cullStatus==CULL_STATUS_INVISIBLE) {
- REF_PTR_RELEASE(m_terrainTexture2X);
- REF_PTR_RELEASE(m_terrainTexture4X);
- m_texMultiplier = TEX1X;
- return;
- }
- Vector3 cameraPos = camera->Get_Position();
- const Real mipDistance = 310;
- const Real mipSlop = 40;
- const Real mip4xDistanceSqr = sqr(mipDistance+mipSlop);
- const Real mip2xDistanceSqr = sqr(2*mipDistance+mipSlop);
- const Real mipLODDistanceSqr = sqr(4*mipDistance+mipSlop);
- Real minDistSqr = 2*mip2xDistanceSqr;
- Int i, j, k;
- for (i=-1; i<2; i++) {
- for (j=-1; j<2; j++) {
- for (k=-1; k<2; k++) {
- Vector3 corner = m_bounds.Center;
- corner.X += m_bounds.Extent.X * i;
- corner.Y += m_bounds.Extent.Y * j;
- corner.Z += m_bounds.Extent.Z * k;
- Real distSqr = (cameraPos-corner).Length2();
- if (distSqr<minDistSqr) minDistSqr = distSqr;
- }
- }
- }
- m_texMultiplier = TEX1X;
- if (minDistSqr<mip4xDistanceSqr) {
- m_texMultiplier = TEX4X;
- } else if (minDistSqr<mip2xDistanceSqr) {
- m_texMultiplier = TEX2X;
- } else {
- REF_PTR_RELEASE(m_terrainTexture4X);
- REF_PTR_RELEASE(m_terrainTexture2X);
- Int LOD = 0;
- if (minDistSqr>mipLODDistanceSqr) {
- LOD = 1;
- }
- m_terrainTexture->setLOD(LOD);
- }
- }
- //=============================================================================
- // W3DTerrainBackground::updateCenter
- //=============================================================================
- /** Updates the culling status. */
- //=============================================================================
- void W3DTerrainBackground::updateTexture(void)
- {
- if (m_cullStatus==CULL_STATUS_INVISIBLE) {
- REF_PTR_RELEASE(m_terrainTexture2X);
- REF_PTR_RELEASE(m_terrainTexture4X);
- return;
- }
- if (m_texMultiplier == TEX4X) {
- REF_PTR_RELEASE(m_terrainTexture2X);
- if (m_terrainTexture4X == NULL) {
- m_terrainTexture4X = m_map->getFlatTexture(m_xOrigin, m_yOrigin, m_width, 4*PIXELS_PER_GRID);
- m_terrainTexture4X->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_terrainTexture4X->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- } else if (m_texMultiplier == TEX2X) {
- REF_PTR_RELEASE(m_terrainTexture4X);
- if (m_terrainTexture2X == NULL) {
- m_terrainTexture2X = m_map->getFlatTexture(m_xOrigin, m_yOrigin, m_width, 2*PIXELS_PER_GRID);
- m_terrainTexture2X->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- m_terrainTexture2X->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP);
- }
- } else {
- REF_PTR_RELEASE(m_terrainTexture4X);
- REF_PTR_RELEASE(m_terrainTexture2X);
- }
- }
- //=============================================================================
- // W3DTerrainBackground::renderTerrain
- //=============================================================================
- //=============================================================================
- void W3DTerrainBackground::drawVisiblePolys(RenderInfoClass & rinfo, Bool disableTextures)
- {
- #if 1
- if (m_curNumTerrainIndices == 0) {
- return;
- }
- if (m_cullStatus==CULL_STATUS_INVISIBLE) {
- return;
- }
- // Setup the vertex buffer, shader & texture.
- DX8Wrapper::Set_Index_Buffer(m_indexTerrain,0);
- DX8Wrapper::Set_Vertex_Buffer(m_vertexTerrain);
- if (!disableTextures) {
- if (m_terrainTexture4X) {
- DX8Wrapper::Set_Texture(1, m_terrainTexture4X);
- } else if (m_terrainTexture2X) {
- DX8Wrapper::Set_Texture(1, m_terrainTexture2X);
- } else {
- DX8Wrapper::Set_Texture(1, m_terrainTexture);
- }
- }
- DX8Wrapper::Draw_Triangles( 0, m_curNumTerrainIndices/3, 0, m_curNumTerrainVertices);
- #else
- if (m_curNumTerrainIndices == 0) {
- return;
- }
- if (m_cullStatus==CULL_STATUS_INVISIBLE) {
- return;
- }
- // Setup the vertex buffer, shader & texture.
- DX8Wrapper::Set_Index_Buffer(m_indexTerrain,0);
- DX8Wrapper::Set_Vertex_Buffer(m_vertexTerrain);
- if (!disableTextures) {
- if (m_terrainTexture4X) {
- DX8Wrapper::Set_Texture(0, m_terrainTexture4X);
- } else if (m_terrainTexture2X) {
- DX8Wrapper::Set_Texture(0, m_terrainTexture2X);
- } else {
- DX8Wrapper::Set_Texture(0, m_terrainTexture);
- }
- }
- DX8Wrapper::Draw_Triangles( 0, m_curNumTerrainIndices/3, 0, m_curNumTerrainVertices);
- #endif
- }
|