Exemple #1
0
void DistantLand::renderReflectedStatics(const D3DXMATRIX *view, const D3DXMATRIX *proj)
{
    // Select appropriate static clipping distance
    D3DXMATRIX ds_proj = *proj, ds_viewproj;
    float zn = 4.0f, zf = Configuration.DL.NearStaticEnd * kCellSize;

    // Don't draw beyond fully fogged distance; early out if frustum is empty
    zf = std::min(fogEnd, zf);
    if(zf <= zn)
        return;

    // Create a clipping frustum for visibility determination
    editProjectionZ(&ds_proj, zn, zf);
    ds_viewproj = (*view) * ds_proj;

    // Cull sort and draw
    VisibleSet visReflected;
    ViewFrustum range_frustum(&ds_viewproj);
    D3DXVECTOR4 viewsphere(eyePos.x, eyePos.y, eyePos.z, zf);

    currentWorldSpace->NearStatics->GetVisibleMeshes(range_frustum, viewsphere, visReflected);
    currentWorldSpace->FarStatics->GetVisibleMeshes(range_frustum, viewsphere, visReflected);
    currentWorldSpace->VeryFarStatics->GetVisibleMeshes(range_frustum, viewsphere, visReflected);
    visReflected.SortByState();

    device->SetVertexDeclaration(StaticDecl);
    visReflected.Render(device, effect, effect, &ehTex0, 0, &ehWorld, SIZEOFSTATICVERT);
}
Exemple #2
0
void DistantLand::cullGrass(const D3DXMATRIX *view, const D3DXMATRIX *proj)
{
	D3DXMATRIX ds_proj = *proj, ds_viewproj;
	float zn = 4.0f, zf = 7168.0f;

    // Don't draw beyond fully fogged distance; early out if frustum is empty
    if(~Configuration.MGEFlags & EXP_FOG)
        zf = min(fogEnd, zf);
    if(zf <= zn)
        return;

	// Create a clipping frustum for visibility determination
	editProjectionZ(&ds_proj, zn, zf);
	ds_viewproj = (*view) * ds_proj;

    // Cull and sort
	ViewFrustum range_frustum(&ds_viewproj);
    visGrass.RemoveAll();
    currentWorldSpace->GrassStatics->GetVisibleMeshesCoarse(range_frustum, visGrass);
	visGrass.SortByState();

    buildGrassInstanceVB();
}
Exemple #3
0
void DistantLand::renderWaterReflection(const D3DXMATRIX *view, const D3DXMATRIX *proj)
{
    DECLARE_MWBRIDGE

    // Switch to render target
    RenderTargetSwitcher rtsw(texReflection, surfReflectionZ);
    device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, horizonCol, 1.0, 0);

    // Calculate reflected view matrix, mirror plane at water mesh level
    D3DXMATRIX reflView;
    D3DXPLANE plane(0, 0, 1.0, -(mwBridge->WaterLevel() - 1.0));
    D3DXMatrixReflect(&reflView, &plane);
    D3DXMatrixMultiply(&reflView, &reflView, view);
    effect->SetMatrix(ehView, &reflView);

    // Calculate new projection
    D3DXMATRIX reflProj = *proj;
    editProjectionZ(&reflProj, 4.0, Configuration.DL.DrawDist * kCellSize);
    effect->SetMatrix(ehProj, &reflProj);

    // Clipping setup
    D3DXMATRIX clipMat;

    // Clip geometry on opposite side of water plane
    plane *= mwBridge->IsUnderwater(eyePos.z) ? -1.0 : 1.0;

    // If using dynamic ripples, the water level can be lowered by up to 0.5 * waveheight
    // so move clip plane downwards at the cost of some reflection errors
    if(Configuration.MGEFlags & DYNAMIC_RIPPLES)
        plane.d += 0.5 * Configuration.DL.WaterWaveHeight;

    // Doing inverses separately is a lot more numerically stable
    D3DXMatrixInverse(&clipMat, 0, &reflView);
    D3DXMatrixTranspose(&clipMat, &clipMat);
    D3DXPlaneTransform(&plane, &plane, &clipMat);

    D3DXMatrixInverse(&clipMat, 0, &reflProj);
    D3DXMatrixTranspose(&clipMat, &clipMat);
    D3DXPlaneTransform(&plane, &plane, &clipMat);

    if(visDistant.size() == 0)
    {
        // Workaround for a Direct3D bug with clipping planes, where SetClipPlane
        // has no effect on the shader pipeline if the last rendered draw call was using
        // the fixed function pipeline. This is usually covered by distant statics, but
        // not in compact interiors where all distant statics may be culled.
        // Provoking a DrawPrimitive with shader here makes the following SetClipPlane work.
        effect->BeginPass(PASS_WORKAROUND);
        device->SetVertexDeclaration(WaterDecl);
        device->SetStreamSource(0, vbFullFrame, 0, 12);
        device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
        effect->EndPass();
    }

    device->SetClipPlane(0, plane);
    device->SetRenderState(D3DRS_CLIPPLANEENABLE, 1);

    // Rendering
    if(mwBridge->IsExterior() && (Configuration.MGEFlags & REFLECTIVE_WATER))
    {
        // Draw land reflection, with opposite culling
        effect->BeginPass(PASS_RENDERLANDREFL);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
        renderDistantLand(effect, &reflView, &reflProj);
        effect->EndPass();
    }

    if(isDistantCell() && (Configuration.MGEFlags & REFLECT_NEAR))
    {
        // Draw statics reflection, with opposite culling and no dissolve
        DWORD p = (mwBridge->CellHasWeather() && !mwBridge->IsUnderwater(eyePos.z)) ? PASS_RENDERSTATICSEXTERIOR : PASS_RENDERSTATICSINTERIOR;
        effect->SetFloat(ehNearViewRange, 0);
        effect->BeginPass(p);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
        renderReflectedStatics(&reflView, &reflProj);
        effect->EndPass();
        effect->SetFloat(ehNearViewRange, nearViewRange);
    }

    if((Configuration.MGEFlags & REFLECT_SKY) && !recordSky.empty() && !mwBridge->IsUnderwater(eyePos.z))
    {
        // Draw sky reflection, with opposite culling
        effect->BeginPass(PASS_RENDERSKY);
        device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
        renderReflectedSky();
        effect->EndPass();
    }

    // Restore view state
    device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
    effect->SetMatrix(ehView, view);
    effect->SetMatrix(ehProj, proj);
}