Пример #1
0
// Prepare scene for terrain rendering
void PrepareScene(CAnyProjection3D &apr, CDrawPort *pdp, CTerrain *ptrTerrain)
{
  ASSERT(ptrTerrain!=NULL);
  ASSERT(ptrTerrain->tr_penEntity!=NULL);

  // Set current terrain
  _ptrTerrain = ptrTerrain;

  // Set drawport
  _pdp = pdp;

  // Prepare and set the projection
  apr->ObjectPlacementL() = CPlacement3D(FLOAT3D(0,0,0), ANGLE3D(0,0,0));
  apr->Prepare();
  _aprProjection = apr;
  _pdp->SetProjection( _aprProjection);

  CEntity *pen = ptrTerrain->tr_penEntity;

  // calculate projection of viewer in absolute space
  const FLOATmatrix3D &mViewer = _aprProjection->pr_ViewerRotationMatrix;
  _vViewer(1) = -mViewer(3,1);
  _vViewer(2) = -mViewer(3,2);
  _vViewer(3) = -mViewer(3,3);
  // calculate projection of viewer in object space
  _vViewerObj = _vViewer * !pen->en_mRotation;


  const CPlacement3D &plTerrain = pen->GetLerpedPlacement();

  _mObjectToView  = mViewer * pen->en_mRotation;
  _vObjectToView  = (plTerrain.pl_PositionVector - _aprProjection->pr_vViewerPosition) * mViewer;

  // make transform matrix 
  const FLOATmatrix3D &m = _mObjectToView;
  const FLOAT3D       &v = _vObjectToView;
  FLOAT glm[16];
  glm[0] = m(1,1);  glm[4] = m(1,2);  glm[ 8] = m(1,3);  glm[12] = v(1);
  glm[1] = m(2,1);  glm[5] = m(2,2);  glm[ 9] = m(2,3);  glm[13] = v(2);
  glm[2] = m(3,1);  glm[6] = m(3,2);  glm[10] = m(3,3);  glm[14] = v(3);
  glm[3] = 0;       glm[7] = 0;       glm[11] = 0;       glm[15] = 1;
  gfxSetViewMatrix(glm);

  // Get viewer in absolute space
  _vViewerAbs = (_aprProjection->ViewerPlacementR().pl_PositionVector - 
                 pen->en_plPlacement.pl_PositionVector) * !pen->en_mRotation;

  gfxDisableBlend();
  gfxDisableTexture();
  gfxDisableAlphaTest();
  gfxEnableDepthTest();
  gfxEnableDepthWrite();
  gfxCullFace(GFX_BACK);
}
Пример #2
0
// fill rate benchmark
static DOUBLE FillRatePass(INDEX ct)
{
  if( !_pdp->Lock()) {
    ASSERT(FALSE);
    return 0.0;
  }
  StartTimer();

  _pdp->Fill(C_GRAY|255);
  _pdp->FillZBuffer(1.0f);

  GFXVertex avtx[4];
  avtx[0].x = 0;          avtx[0].y = 0;          avtx[0].z = 0.5f;  
  avtx[1].x = 0;          avtx[1].y = _pixSizeJ;  avtx[1].z = 0.5f;  
  avtx[2].x = _pixSizeI;  avtx[2].y = _pixSizeJ;  avtx[2].z = 0.5f;  
  avtx[3].x = _pixSizeI;  avtx[3].y = 0;          avtx[3].z = 0.5f;  
  GFXTexCoord atex[4] = { {0,0}, {0,1}, {1,1}, {1,0} };
  GFXColor    acol[4] = { 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFF00FF };
  INDEX_T     aidx[6] = { 0,1,2, 0,2,3};
  gfxSetVertexArray( &avtx[0], 4);
  gfxSetTexCoordArray( &atex[0], FALSE);
  gfxSetColorArray( &acol[0]);

  if(_bTexture) {
    gfxEnableTexture();
    if(_bMultiTexture) {
      gfxSetTextureUnit(1);
      gfxEnableTexture();
      gfxSetTexture( _ulTexObject, _tpLocal);
      gfxSetTexCoordArray(atex, FALSE);
      gfxSetTextureUnit(0);
    }
  } else {
    gfxDisableTexture();
  }

  if(_bBlend) {
    gfxEnableBlend();
    if(_bTexture) {
      gfxBlendFunc( GFX_SRC_ALPHA, GFX_INV_SRC_ALPHA); 
    } else {
      gfxBlendFunc( GFX_ONE, GFX_ONE);
    }
  } else {
    gfxDisableBlend();
  }

  if(_bDepth) {
    gfxEnableDepthTest();
    gfxEnableDepthWrite();
  } else {
    gfxDisableDepthTest();
    gfxDisableDepthWrite();
  }
  gfxDisableAlphaTest();

  for( INDEX i=0; i<ct; i++) gfxDrawElements( 6, &aidx[0]);

  if(_bMultiTexture) {
    gfxSetTextureUnit(1);
    gfxDisableTexture();
    gfxSetTextureUnit(0);
  }
  _pdp->Unlock();

  gfxFinish();
  _pvp->SwapBuffers();

  return StopTimer();
}
Пример #3
0
static DOUBLE TrisTroughputPass(INDEX ct)
{
  if( !_pdp->Lock()) {
    ASSERT(FALSE);
    return 0.0;
  }

  StartTimer();

  gfxSetFrustum( -0.5f, +0.5f, -0.5f, +0.5f, 0.5f, 2.0f);
  gfxSetViewMatrix(NULL);
  gfxCullFace(GFX_NONE);

  _pdp->Fill(C_GRAY|255);
  _pdp->FillZBuffer(1.0f);

  if(_bTexture) {
    gfxEnableTexture();
  } else {
    gfxDisableTexture();
  }

  if(_bBlend) {
    gfxEnableBlend();
    gfxBlendFunc( GFX_ONE, GFX_ONE);
  } else {
    gfxDisableBlend();
  }

  if(_bDepth) {
    gfxEnableDepthTest();
    gfxEnableDepthWrite();
  } else {
    gfxDisableDepthTest();
    gfxDisableDepthWrite();
  }
  gfxDisableAlphaTest();

  gfxSetVertexArray( &_avtx[0], _avtx.Count());
  gfxLockArrays();
  gfxSetTexCoordArray( &_atex[0], FALSE);
  gfxSetColorArray( &_acol[0]);

  if(_bMultiTexture) {
    gfxSetTextureUnit(1);
    gfxEnableTexture();
    gfxSetTexture( _ulTexObject, _tpLocal);
    gfxSetTexCoordArray( &_atex[0], FALSE);
    gfxSetTextureUnit(0);
  }
  for( INDEX i=0; i<ct; i++) gfxDrawElements( _aiElements.Count(), &_aiElements[0]);
  gfxUnlockArrays();

  if(_bMultiTexture) {
    gfxSetTextureUnit(1);
    gfxDisableTexture();
    gfxSetTextureUnit(0);
  }
  _pdp->Unlock();

  gfxFinish();
  _pvp->SwapBuffers();

  return StopTimer();
}
Пример #4
0
// Enable/Disable depth test
void shaEnableDepthTest(void)
{
  gfxEnableDepthTest();
}
Пример #5
0
// read depth buffer and update visibility flag of depth points
static void UpdateDepthPointsVisibility( const CDrawPort *pdp, const INDEX iMirrorLevel,
                                         DepthInfo *pdi, const INDEX ctCount)
{
  const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  ASSERT(GfxValidApi(eAPI));
  ASSERT( pdp!=NULL && ctCount>0);
  const CRaster *pra = pdp->dp_Raster;

  // OpenGL
  if( eAPI==GAT_OGL)
  { 
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    FLOAT fPointOoK;
    // for each stored point
    for( INDEX idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      const PIX pixJ = pra->ra_Height-1 - di.di_pixJ; // OpenGL has Y-inversed buffer!
      pglReadPixels( di.di_pixI, pixJ, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fPointOoK);
      OGL_CHECKERROR;
      // it is visible if there is nothing nearer in z-buffer already
      di.di_bVisible = (di.di_fOoK<fPointOoK);
    }
    // done
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }

  // Direct3D
#ifdef SE1_D3D
  if( eAPI==GAT_D3D)
  {
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // ok, this will get really complicated ...
    // We'll have to do it thru back buffer because darn DX8 won't let us have values from z-buffer;
    // Anyway, we'll lock backbuffer, read color from the lens location and try to write little triangle there
    // with slightly modified color. Then we'll readout that color and see if triangle passes z-test. Voila! :)
    // P.S. To avoid lock-modify-lock, we need to batch all the locks in one. Uhhhh ... :(
    COLOR col;
    INDEX idi;
    SLONG slColSize;
    HRESULT hr;
    D3DLOCKED_RECT rectLocked;
    D3DSURFACE_DESC surfDesc;
    LPDIRECT3DSURFACE8 pBackBuffer;
    // fetch back buffer (different for full screen and windowed mode)
    const BOOL bFullScreen = _pGfx->gl_ulFlags & GLF_FULLSCREEN;
    if( bFullScreen) {
      hr = _pGfx->gl_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    } else {
      hr = pra->ra_pvpViewPort->vp_pSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    }
    // what, cannot get a back buffer?
    if( hr!=D3D_OK) { 
      // to hell with it all
      _sfStats.StopTimer(CStatForm::STI_GFXAPI);
      return;
    }
    // keep format of back-buffer
    pBackBuffer->GetDesc(&surfDesc);
    const D3DFORMAT d3dfBack = surfDesc.Format;
    
    // prepare array that'll back-buffer colors from depth point locations
    _acolDelayed.Push(ctCount);
    // store all colors
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      // fetch pixel
      _acolDelayed[idi] = 0;
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read, convert and store original color
      _acolDelayed[idi] = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
    }

    // prepare to draw little triangles there with slightly adjusted colors
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    gfxEnableDepthTest();
    gfxDisableDepthWrite();
    gfxDisableBlend();
    gfxDisableAlphaTest();
    gfxDisableTexture();
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // prepare array and shader
    _avtxDelayed.Push(ctCount*3);
    d3dSetVertexShader(D3DFVF_CTVERTEX);

    // draw one trianle around each depth point
    INDEX ctVertex = 0;
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      const ULONG d3dCol = rgba2argb(col^0x20103000);
      const PIX pixI = di.di_pixI - pdp->dp_MinI; // convert raster loc to drawport loc
      const PIX pixJ = di.di_pixJ - pdp->dp_MinJ;
      // batch it and advance to next triangle
      CTVERTEX &vtx0 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx1 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx2 = _avtxDelayed[ctVertex++];
      vtx0.fX=pixI;   vtx0.fY=pixJ-2; vtx0.fZ=di.di_fOoK; vtx0.ulColor=d3dCol; vtx0.fU=vtx0.fV=0;
      vtx1.fX=pixI-2; vtx1.fY=pixJ+2; vtx1.fZ=di.di_fOoK; vtx1.ulColor=d3dCol; vtx1.fU=vtx0.fV=0;
      vtx2.fX=pixI+2; vtx2.fY=pixJ;   vtx2.fZ=di.di_fOoK; vtx2.ulColor=d3dCol; vtx2.fU=vtx0.fV=0;
    }
    // draw a bunch
    hr = _pGfx->gl_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, ctVertex/3, &_avtxDelayed[0], sizeof(CTVERTEX));
    D3D_CHECKERROR(hr);

    // readout colors again and compare to old ones
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      // fetch pixel
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read new color
      const COLOR colNew = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
      // if we managed to write adjusted color, point is visible!
      di.di_bVisible = (col!=colNew);
    }
    // phew, done! :)
    D3DRELEASE( pBackBuffer, TRUE);
    _acolDelayed.PopAll();
    _avtxDelayed.PopAll();
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }
#endif // SE1_D3D
}