// Draw all tiles that are in lowest lod
static void RenderBatchedTiles(void)
{
  // Set texture wrapping
  gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP);
  // Use terrains global top map as texture
  _ptrTerrain->tr_tdTopMap.SetAsCurrent();

  GFXVertex4  *pavVertices     = &_avDelayedVertices[0];
  GFXTexCoord *pauvTexCoords   = &_auvDelayedTexCoords[0];
  GFXTexCoord *pauvShadowMapTC = &_auvDelayedShadowMapTC[0];
  INDEX       *paiIndices      = &_aiDelayedIndices[0];
  INDEX        ctVertices      = _avDelayedVertices.Count();
  INDEX        ctIndices       = _aiDelayedIndices.Count();

  // Prepare white color array
  FillConstColorArray(ctVertices);
  GFXColor    *pacolColors     = &_acolVtxConstColors[0];

  gfxEnableAlphaTest();
  gfxDisableBlend();
  gfxSetVertexArray(pavVertices,ctVertices);
  gfxSetTexCoordArray(pauvTexCoords, FALSE);
  gfxSetColorArray(pacolColors);
  gfxLockArrays();
  gfxDrawElements(ctIndices,paiIndices);
  gfxDisableAlphaTest();
  _ctTris +=ctIndices/2;

  // if shadows are visible
  if(_wrpWorldRenderPrefs.wrp_shtShadows!=CWorldRenderPrefs::SHT_NONE) {
    gfxDepthFunc(GFX_EQUAL);

    gfxBlendFunc(GFX_DST_COLOR,GFX_SRC_COLOR);
    gfxEnableBlend();
    gfxSetTexCoordArray(pauvShadowMapTC, FALSE);
    _ptrTerrain->tr_tdShadowMap.SetAsCurrent();
    gfxDrawElements(ctIndices,paiIndices);
    gfxDepthFunc(GFX_LESS_EQUAL);
  }

  if(_ptrTerrain->GetFlags()&TR_HAS_FOG) {
    RenderFogLayer(-1);
  }
  if(_ptrTerrain->GetFlags()&TR_HAS_HAZE) {
    RenderHazeLayer(-1);
  }
  gfxUnlockArrays();

  // Popall delayed arrays 
  _avDelayedVertices.PopAll();
  _auvDelayedTexCoords.PopAll();
  _auvDelayedShadowMapTC.PopAll();
  _aiDelayedIndices.PopAll();
}
static void RenderHazeLayer(INDEX itt)
{
  FLOAT3D vObjPosition = _ptrTerrain->tr_penEntity->en_plPlacement.pl_PositionVector;

  _fHazeAdd  = -_haze_hp.hp_fNear;
  _fHazeAdd += _vViewer(1) * (vObjPosition(1) - _aprProjection->pr_vViewerPosition(1));
  _fHazeAdd += _vViewer(2) * (vObjPosition(2) - _aprProjection->pr_vViewerPosition(2));
  _fHazeAdd += _vViewer(3) * (vObjPosition(3) - _aprProjection->pr_vViewerPosition(3));

  GFXVertex *pvVtx;
  INDEX     *piIndices;
  INDEX ctVertices;
  INDEX ctIndices;
  // if this is tile 
  if(itt>=0) {
    CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt];
    pvVtx      = &tt.GetVertices()[0];
    piIndices  = &tt.GetIndices()[0];
    ctVertices = tt.GetVertices().Count();
    ctIndices  = tt.GetIndices().Count();
  // else this are batched tiles
  } else {
    pvVtx      = &_avDelayedVertices[0];
    piIndices  = &_aiDelayedIndices[0];
    ctVertices = _avDelayedVertices.Count();
    ctIndices  = _aiDelayedIndices.Count();
  }

  GFXTexCoord *pfHazeTC  = _atcHaze.Push(ctVertices);
  GFXColor    *pcolHaze  = _acolHaze.Push(ctVertices);

  const COLOR colH = AdjustColor( _haze_hp.hp_colColor, _slTexHueShift, _slTexSaturation);
  GFXColor colHaze(colH);
  // for each vertex in tile
  for(INDEX ivx=0;ivx<ctVertices;ivx++) {
    GetHazeMapInVertex(pvVtx[ivx],pfHazeTC[ivx]);
    pcolHaze[ivx] = colHaze;
  }

  // render haze layer
  gfxDepthFunc(GFX_EQUAL);
  gfxSetTextureWrapping( GFX_CLAMP, GFX_CLAMP);
  gfxSetTexture( _haze_ulTexture, _haze_tpLocal);
  gfxSetTexCoordArray(pfHazeTC, FALSE);
  gfxSetColorArray(pcolHaze);
  gfxBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA);
  gfxEnableBlend();
  gfxDrawElements(ctIndices,piIndices);
  gfxDepthFunc(GFX_LESS_EQUAL);

  _atcHaze.PopAll();
  _acolHaze.PopAll();
}
Beispiel #3
0
// Set depth buffer compare mode
void shaDepthFunc(GfxComp eComp)
{
  gfxDepthFunc(eComp);
}
// Render one tile
static void RenderTile(INDEX itt)
{
  ASSERT(_ptrTerrain!=NULL);
  CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt];
  INDEX ctVertices = tt.GetVertices().Count();

  extern INDEX ter_bOptimizeRendering;
  // if tile is in posible lowest lod and doesn't have any border vertices
  if(ter_bOptimizeRendering && tt.GetFlags()&TT_IN_LOWEST_LOD) {
    // delay tile rendering
    BatchTile(itt);
    return;
  }

  GFXVertex4 *pavVertices;
  // if vertex lerping is requested
  if(ter_bLerpVertices==1) {
    // Prepare smoth vertices
    PrepareSmothVertices(itt);
    pavVertices = &_avLerpedVerices[0];
  } else {
    // use non smoth vertices
    pavVertices = &tt.GetVertices()[0];
  }

  // if tile is in highest lod
  if(tt.tt_iLod==0) {
    gfxBlendFunc(GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA);
    gfxSetVertexArray(pavVertices,ctVertices);

    gfxLockArrays();
    // for each tile layer
    INDEX cttl= tt.GetTileLayers().Count();
    for(INDEX itl=0;itl<cttl;itl++) {
      CTerrainLayer &tl = _ptrTerrain->tr_atlLayers[itl];
      // if layer isn't visible
      if(!tl.tl_bVisible) {
        continue; // skip it
      }

      TileLayer &ttl = tt.GetTileLayers()[itl];

      // Set tile stretch
      Matrix12 m12;
      SetMatrixDiagonal(m12,tl.tl_fStretchX);
      gfxSetTextureMatrix2(&m12);

      // Set tile blend mode
      if(tl.tl_fSmoothness==0) {
        gfxDisableBlend();
        gfxEnableAlphaTest();
      } else {
        gfxEnableBlend();
        gfxDisableAlphaTest();
      }

      // if this tile has any polygons in this layer
      INDEX ctIndices = ttl.tl_auiIndices.Count();
      if(ctIndices>0) {
        gfxSetTextureWrapping(GFX_REPEAT,GFX_REPEAT);
        tl.tl_ptdTexture->SetAsCurrent();

        // if this is tile layer 
        if(tl.tl_ltType==LT_TILE) {
          gfxUnlockArrays();
          GFXVertex4 *pavLayerVertices;
          if(ter_bLerpVertices==1) {
            PrepareSmothVerticesOnTileLayer(itt,itl);
            pavLayerVertices = &_avLerpedTileLayerVertices[0];
          } else {
            pavLayerVertices = &ttl.tl_avVertices[0];
          }
          gfxSetVertexArray(pavLayerVertices,ttl.tl_avVertices.Count());
          gfxLockArrays();
          // gfxSetColorArray(&ttl.tl_acColors[0]);
          gfxSetTexCoordArray(&ttl.tl_atcTexCoords[0], FALSE);

          
          // set wireframe mode
          /*
          gfxEnableDepthBias();
          gfxPolygonMode(GFX_LINE);
          gfxDisableTexture();*/
          gfxSetConstantColor(0xFFFFFFFF);

          // Draw tiled layer
          gfxDrawElements(ttl.tl_auiIndices.Count(),&ttl.tl_auiIndices[0]);
          _ctTris +=ttl.tl_auiIndices.Count()/2;

          /*
          // set fill mode
          gfxDisableDepthBias();
          gfxPolygonMode(GFX_FILL);*/

          // Set old vertex array
          gfxUnlockArrays();
          gfxSetVertexArray(pavVertices,ctVertices);
          gfxLockArrays();
        // if this is normal layer
        } else {
          // render layer
          gfxSetColorArray(&ttl.tl_acColors[0]);
          gfxSetTexCoordArray(&ttl.tl_atcTexCoords[0], FALSE);
          gfxDrawElements(ctIndices,&ttl.tl_auiIndices[0]);
          _ctTris +=ctIndices/2;
        }
      }
    }
    gfxSetTextureMatrix2(NULL);
    INDEX ctIndices = tt.GetIndices().Count();
    if(ctIndices>0) {
      INDEX *paiIndices = &tt.GetIndices()[0];

      // if detail map exists
      if(_ptrTerrain->tr_ptdDetailMap!=NULL) {
        gfxSetTextureWrapping(GFX_REPEAT,GFX_REPEAT);
        gfxDisableAlphaTest();
        shaBlendFunc( GFX_DST_COLOR, GFX_SRC_COLOR);
        gfxEnableBlend();
        gfxSetTexCoordArray(&tt.GetDetailTC()[0], FALSE);
        _ptrTerrain->tr_ptdDetailMap->SetAsCurrent();
        gfxDrawElements(ctIndices,paiIndices);
      }

      // if shadows are visible
      if(_wrpWorldRenderPrefs.wrp_shtShadows!=CWorldRenderPrefs::SHT_NONE) {
        gfxDisableAlphaTest();
        shaBlendFunc( GFX_DST_COLOR, GFX_SRC_COLOR);
        gfxEnableBlend();
        gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP);
        gfxSetTexCoordArray(&tt.GetShadowMapTC()[0], FALSE);
        _ptrTerrain->tr_tdShadowMap.SetAsCurrent();
        gfxDrawElements(ctIndices,paiIndices);
      }
    }
  // if tile is not in highest lod
  } else {
    gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP);
    // if tile is in lowest lod
    if(tt.tt_iLod == _ptrTerrain->tr_iMaxTileLod) {
      // use terrains global top map
      _ptrTerrain->tr_tdTopMap.SetAsCurrent();
    // else tile is in some midle lod
    } else {
      // use its own topmap
      tt.GetTopMap()->SetAsCurrent();
    }

    // Render tile
    INDEX ctIndices = tt.GetIndices().Count();
    gfxEnableAlphaTest();
    gfxDisableBlend();
    gfxSetVertexArray(pavVertices,ctVertices);
    gfxSetTexCoordArray(&tt.GetTexCoords()[0], FALSE);
    FillConstColorArray(ctVertices);
    gfxSetColorArray(&_acolVtxConstColors[0]);
    gfxLockArrays();
    gfxDrawElements(ctIndices,&tt.GetIndices()[0]);
    _ctTris +=ctIndices/2;
    gfxDisableAlphaTest();

    // if shadows are visible
    if(_wrpWorldRenderPrefs.wrp_shtShadows!=CWorldRenderPrefs::SHT_NONE) {
      gfxDepthFunc(GFX_EQUAL);
      INDEX ctIndices = tt.GetIndices().Count();
      INDEX *paiIndices = &tt.GetIndices()[0];

      gfxSetTextureWrapping(GFX_CLAMP,GFX_CLAMP);
      gfxBlendFunc(GFX_DST_COLOR,GFX_SRC_COLOR);
      gfxEnableBlend();
      gfxSetTexCoordArray(&tt.GetShadowMapTC()[0], FALSE);
      _ptrTerrain->tr_tdShadowMap.SetAsCurrent();
      gfxDrawElements(ctIndices,paiIndices);
      gfxDepthFunc(GFX_LESS_EQUAL);
    }
  }

  if(_ptrTerrain->GetFlags()&TR_HAS_FOG) {
    RenderFogLayer(itt);
  }
  if(_ptrTerrain->GetFlags()&TR_HAS_HAZE) {
    RenderHazeLayer(itt);
  }

  gfxUnlockArrays();
}
static void RenderFogLayer(INDEX itt)
{
  FLOATmatrix3D &mViewer = _aprProjection->pr_ViewerRotationMatrix;
  FLOAT3D vObjPosition = _ptrTerrain->tr_penEntity->en_plPlacement.pl_PositionVector;

  // get viewer -z in object space
  _vFViewerObj = FLOAT3D(0,0,-1) * !_mObjectToView;
  // get fog direction in object space
  _vHDirObj = _fog_vHDirAbs * !(!mViewer*_mObjectToView);
  // get viewer offset
  _fFogAddZ  = _vViewer(1) * (vObjPosition(1) - _aprProjection->pr_vViewerPosition(1));
  _fFogAddZ += _vViewer(2) * (vObjPosition(2) - _aprProjection->pr_vViewerPosition(2));
  _fFogAddZ += _vViewer(3) * (vObjPosition(3) - _aprProjection->pr_vViewerPosition(3));
  // get fog offset
  _fFogAddH = (_fog_vHDirAbs % vObjPosition) + _fog_fp.fp_fH3;

  GFXVertex *pvVtx;
  INDEX     *piIndices;
  INDEX ctVertices;
  INDEX ctIndices;
  // if this is tile 
  if(itt>=0) {
    CTerrainTile &tt = _ptrTerrain->tr_attTiles[itt];
    pvVtx      = &tt.GetVertices()[0];
    piIndices  = &tt.GetIndices()[0];
    ctVertices = tt.GetVertices().Count();
    ctIndices  = tt.GetIndices().Count();
  // else this are batched tiles
  } else {
    pvVtx      = &_avDelayedVertices[0];
    piIndices  = &_aiDelayedIndices[0];
    ctVertices = _avDelayedVertices.Count();
    ctIndices  = _aiDelayedIndices.Count();
  }

  GFXTexCoord *pfFogTC  = _atcHaze.Push(ctVertices);
  GFXColor    *pcolFog  = _acolHaze.Push(ctVertices);

  const COLOR colF = AdjustColor( _fog_fp.fp_colColor, _slTexHueShift, _slTexSaturation);
  GFXColor colFog(colF);

  // for each vertex in tile
  for(INDEX ivx=0;ivx<ctVertices;ivx++) {
    GetFogMapInVertex(pvVtx[ivx],pfFogTC[ivx]);
    pcolFog[ivx] = colFog;
  }

  // render fog layer
  gfxDepthFunc(GFX_EQUAL);
  gfxSetTextureWrapping( GFX_CLAMP, GFX_CLAMP);
  gfxSetTexture( _fog_ulTexture, _fog_tpLocal);
  gfxSetTexCoordArray(pfFogTC, FALSE);
  gfxSetColorArray(pcolFog);
  gfxBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA);
  gfxEnableBlend();
  gfxDisableAlphaTest();
  gfxDrawElements(ctIndices,piIndices);
  gfxDepthFunc(GFX_LESS_EQUAL);

  _atcHaze.PopAll();
  _acolHaze.PopAll();
}