mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-24 17:41:56 +00:00
1001 lines
30 KiB
C++
1001 lines
30 KiB
C++
|
/***********************************************************************************************
|
|||
|
*
|
|||
|
* Copyright <EFBFBD> DreamWorks Interactive. 1996
|
|||
|
*
|
|||
|
* Direct3D implementation of ScreenRender.hpp
|
|||
|
*
|
|||
|
* Bugs:
|
|||
|
* In ramp model, the specular colour shows up much too large...if the material has a
|
|||
|
* specular component, then there's white when the diffuse lighting is large, even if
|
|||
|
* there's no specular lighting.
|
|||
|
*
|
|||
|
* To do:
|
|||
|
* DirectDraw driver must be selected w/regard to 3D caps.
|
|||
|
* Main screen must be created under driver control.
|
|||
|
* If driver can only work in video mem, we need to indicate that.
|
|||
|
* Our rasteriser must be able to take a predeclared Z buffer of arbitrary depth.
|
|||
|
* Figure out Z buffer format, figure out whether we can access surfaces on cards.
|
|||
|
*
|
|||
|
* Experiment with D3D doing: Transform, Lighting, Clipping, Rasterising.
|
|||
|
* Figure out how big to make ex buffer, how to manage it.
|
|||
|
* Incorporate render options into trianges.
|
|||
|
* Figure out how to change state optimally.
|
|||
|
*
|
|||
|
* Store specular shading correctly; fog also; store full RGB shading if supported.
|
|||
|
* Determine proper culling order for renderer.
|
|||
|
* Determine *all* driver caps, and integrate them with render options.
|
|||
|
* Should alpha values be set??? Where is alpha turned on or off?
|
|||
|
* Incorporate max execute buffer size/vertex count.
|
|||
|
*
|
|||
|
* Change CD3DVidTextureList to a map or priority queue.
|
|||
|
* Make D3DMaterials incorporate solid colours when solid rendering.
|
|||
|
*
|
|||
|
***********************************************************************************************
|
|||
|
*
|
|||
|
* $Log:: /JP2_PC/Source/Lib/Renderer/D3d/ScreenRenderD3D.cpp $
|
|||
|
*
|
|||
|
* 28 97/06/23 20:31 Speter
|
|||
|
* Made gcfScreen a static member of CScreenRender.
|
|||
|
*
|
|||
|
* 27 97-04-04 12:38 Speter
|
|||
|
* A big change: now pipeline uses CRenderPolygon rather than SRenderTriangle (currently always
|
|||
|
* as a triangle). Changed associated variable names and comments.
|
|||
|
*
|
|||
|
* 26 97-04-02 12:48 Speter
|
|||
|
* Updated for new render settings.
|
|||
|
*
|
|||
|
* 25 97/02/21 15:21 Speter
|
|||
|
* Removed fZ from SRenderVertex. Removed f_zadjust param from DrawTriangles(). Moved
|
|||
|
* prasScreen to CScreenRender from derived classes.
|
|||
|
*
|
|||
|
* 24 97/01/20 11:50 Speter
|
|||
|
* Moved pixBackground and gcfScreen vars from CScreenRender to derived classes. Added erfCOPY
|
|||
|
* to default settings.
|
|||
|
*
|
|||
|
* 23 97/01/16 11:53 Speter
|
|||
|
* Many changes for new CScreenRender class. Replaced seterfModify and seterfDefault values
|
|||
|
* with constant values and access functions.
|
|||
|
*
|
|||
|
* 22 97/01/10 17:59 Speter
|
|||
|
* Moved prasZBuffer from CScreenRender base class to derived classes that need it.
|
|||
|
*
|
|||
|
* 21 1/08/97 7:45p Pkeet
|
|||
|
* Replaced the 'NonConst' macro. Used a reference cast in the new operator for 'D3DExBuf' to
|
|||
|
* prevent a compiler error under Visual C++ 5.0.
|
|||
|
*
|
|||
|
* 20 97/01/07 11:17 Speter
|
|||
|
* Changed to new rptr_new macro, and new rptr_dynamic_cast functionality.
|
|||
|
*
|
|||
|
*
|
|||
|
* 19 96/12/31 16:58 Speter
|
|||
|
* Updated for rptr.
|
|||
|
*
|
|||
|
* 18 96/12/06 15:16 Speter
|
|||
|
* BeginFrame() now clears background.
|
|||
|
*
|
|||
|
* 17 96/12/02 17:50 Speter
|
|||
|
* Changed ValidateRenderState() call to CheckRenderState().
|
|||
|
*
|
|||
|
* 16 96/11/27 19:32 Speter
|
|||
|
* Updated for change to CCom: ptCom member changed to ptPtr.
|
|||
|
*
|
|||
|
* 15 11/19/96 7:02p Pkeet
|
|||
|
* Added the 'fZAdjust' parameter.
|
|||
|
*
|
|||
|
* 14 96/10/22 11:12 Speter
|
|||
|
* Added include for <list.h>, necessary due to new Entity includes.
|
|||
|
*
|
|||
|
* 13 96/10/14 15:41 Speter
|
|||
|
* Updated for change in CRaster. ppalAttached is now in pxf.
|
|||
|
*
|
|||
|
* 12 96/10/04 18:00 Speter
|
|||
|
* Removed CSet<ERenderFeature> param from DrawTriangles.
|
|||
|
*
|
|||
|
* 11 96/09/27 11:31 Speter
|
|||
|
* Oops. Changed <float> in geometry types to <>.
|
|||
|
*
|
|||
|
* 10 96/09/23 17:09 Speter
|
|||
|
* Updated for replacement of two D3DDEVICEDESCs with one.
|
|||
|
* No longer lock raster surfaces in BeginFrame and EndFrame.
|
|||
|
*
|
|||
|
* 9 96/09/12 16:26 Speter
|
|||
|
* Incorporated new TReflectVal usage.
|
|||
|
*
|
|||
|
* 8 96/09/09 18:10 Speter
|
|||
|
* Made specular hilites work (at least for RGB model).
|
|||
|
* Added call to ValidateRenderState().
|
|||
|
*
|
|||
|
* 7 96/09/05 11:51 Speter
|
|||
|
* Implemented seterfState and seterfModify handling.
|
|||
|
* Added checks to allow it to work w/o Z buffer.
|
|||
|
* Fixed bug by setting v2Scale to unity when no texture in VidTexture.
|
|||
|
* First pass at specular support.
|
|||
|
*
|
|||
|
* 6 96/08/20 14:34 Speter
|
|||
|
* Created CD3DVidTexture class, and associated classes. Now manage textures in a rudimentary
|
|||
|
* texture list.
|
|||
|
*
|
|||
|
* 5 96/08/19 16:05 Speter
|
|||
|
* Now checks D3D.bValid before adding any drivers to the list.
|
|||
|
*
|
|||
|
* 4 96/08/19 13:08 Speter
|
|||
|
* Added interface for CRenderDesc.
|
|||
|
* Changed prasScreen to prasvScreen.
|
|||
|
* Added prasvZBuffer member.
|
|||
|
* Added destructor, cleaning up objects.
|
|||
|
* Moved to do's etc. up to top of file.
|
|||
|
* Removed dummy code.
|
|||
|
*
|
|||
|
* 3 96/08/15 18:39 Speter
|
|||
|
* Got textures working.
|
|||
|
* Moved Lock() and Unlock() into Begin/EndFrame().
|
|||
|
* Added more comments/questions.
|
|||
|
*
|
|||
|
* 2 96/08/14 11:35 Speter
|
|||
|
* Added much functionality, now draws untextured polys.
|
|||
|
* Changed prefixes, added classes and functions, added many comments.
|
|||
|
*
|
|||
|
* 1 96/08/09 11:02 Speter
|
|||
|
* New files which implement CScreenRender for D3D.
|
|||
|
*
|
|||
|
**********************************************************************************************/
|
|||
|
|
|||
|
#include "Common.hpp"
|
|||
|
#include "D3D.hpp"
|
|||
|
|
|||
|
#include "Lib/View/RasterVid.hpp"
|
|||
|
#include "../ScreenRender.hpp"
|
|||
|
|
|||
|
#include <list.h>
|
|||
|
|
|||
|
/*
|
|||
|
Class name: CD3DDevice int void
|
|||
|
|
|||
|
Current:
|
|||
|
Prefix: d3ddev i
|
|||
|
Global: d3ddevMain iCount Func()
|
|||
|
Class: d3ddevDev iCount Func()
|
|||
|
Local: d3ddev_cur i_count
|
|||
|
d3ddev i
|
|||
|
New:
|
|||
|
Prefix: d3d_dev i
|
|||
|
Global: D3DDevMain ICount Func()
|
|||
|
Class: D3DDev_Dev I_Count _Func()
|
|||
|
D3DDev I
|
|||
|
Local: d3d_dev_cur i_count
|
|||
|
d3d_dev i
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
class CD3DDevice: public CCom<IDirect3DDevice>
|
|||
|
{
|
|||
|
public:
|
|||
|
CD3DDevice()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
CD3DDevice(CDDSurface* pDDSurface, GUID* pGUID)
|
|||
|
{
|
|||
|
Init(pDDSurface, pGUID);
|
|||
|
}
|
|||
|
|
|||
|
void Init(CDDSurface* pDDSurface, GUID* pGUID)
|
|||
|
{
|
|||
|
D3D.err = pDDSurface->QueryInterface(pGUID, (void**)&ptPtr);
|
|||
|
Assert(ptPtr);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
class CD3DViewport: public CCom<IDirect3DViewport>
|
|||
|
{
|
|||
|
public:
|
|||
|
CD3DViewport()
|
|||
|
{
|
|||
|
D3D.err = D3D_Main->CreateViewport(&ptPtr, 0);
|
|||
|
Assert(ptPtr);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
class CD3DTexture: public CCom<IDirect3DTexture>
|
|||
|
{
|
|||
|
public:
|
|||
|
CD3DTexture()
|
|||
|
: d3dhTex(0)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
CD3DTexture(CRasterVid& rasv)
|
|||
|
{
|
|||
|
Init(rasv);
|
|||
|
}
|
|||
|
|
|||
|
void Init(CRasterVid& rasv)
|
|||
|
{
|
|||
|
// Initialise the COM object from the DD Surface.
|
|||
|
D3D.err = rasv.pddsDraw->QueryInterface(IID_IDirect3DTexture, (void**)&ptPtr);
|
|||
|
}
|
|||
|
};
|
|||
|
*/
|
|||
|
|
|||
|
void Convert
|
|||
|
(
|
|||
|
D3DTLVERTEX* pd3d_tlvert,
|
|||
|
const SRenderVertex& rv,
|
|||
|
CVector2<> v2_scale // Texture coord scaling params.
|
|||
|
)
|
|||
|
{
|
|||
|
Assert(bWithin(rv.v3Screen.tZ, 0.0, 1.0));
|
|||
|
pd3d_tlvert->dvSX = rv.v3Screen.tX;
|
|||
|
pd3d_tlvert->dvSY = rv.v3Screen.tY;
|
|||
|
pd3d_tlvert->dvSZ = 1 / rv.v3Screen.tZ;
|
|||
|
pd3d_tlvert->dvRHW = rv.v3Screen.tZ;
|
|||
|
|
|||
|
// Set the colour values. Since we have only intensity, we set grey colours.
|
|||
|
// In D3D ramp mode, the blue component indicates intensity.
|
|||
|
int i_shade, i_hilite;
|
|||
|
|
|||
|
if (rv.rvIntensity <= rvMAX_COLOURED)
|
|||
|
{
|
|||
|
i_shade = iFastPosFloatToInt(rv.rvIntensity / rvMAX_COLOURED * 255.9f);
|
|||
|
i_hilite = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
i_shade = 255;
|
|||
|
i_hilite = iFastPosFloatToInt((rv.rvIntensity - rvMAX_COLOURED) / (1 - rvMAX_COLOURED) * 255.9f);
|
|||
|
}
|
|||
|
|
|||
|
pd3d_tlvert->dcColor = RGBA_MAKE(i_shade, i_shade, i_shade, 0);
|
|||
|
pd3d_tlvert->dcSpecular = RGBA_MAKE(i_hilite, i_hilite, i_hilite, 0);
|
|||
|
|
|||
|
// Texture coordinates convert directly, as they are in [0,1] float range.
|
|||
|
pd3d_tlvert->dvTU = rv.tcTex.tX * v2_scale.tX;
|
|||
|
pd3d_tlvert->dvTV = rv.tcTex.tY * v2_scale.tY;
|
|||
|
|
|||
|
Assert(bWithin(pd3d_tlvert->dvTU, 0.0f, 1.0f));
|
|||
|
Assert(bWithin(pd3d_tlvert->dvTV, 0.0f, 1.0f));
|
|||
|
}
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
class CD3DVidTexture
|
|||
|
//
|
|||
|
// Prefix: d3dvtex
|
|||
|
//
|
|||
|
// Contains all structures needed by D3D to render textures.
|
|||
|
// Also works with textureless (solid) materials.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
public:
|
|||
|
rptr<CRasterVid> prasvSource; // Source texture raster.
|
|||
|
CCom<IDirect3DTexture> d3dTextureSource; // D3D Texture interface for it.
|
|||
|
rptr<CRasterVid> prasvVid; // Video memory texture raster.
|
|||
|
CCom<IDirect3DTexture> d3dTextureVid; // Texture interface for it.
|
|||
|
D3DTEXTUREHANDLE d3dhTexture; // Handle for video texture.
|
|||
|
CD3DMaterial d3dmatTexture; // The material associated with the texture.
|
|||
|
bool bLoaded; // Whether it's currently loaded.
|
|||
|
|
|||
|
CVector2<> v2Scale; // Scaling required for texture coordinates,
|
|||
|
// due to possible difference in raster and
|
|||
|
// surface sizes.
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Constructor and destructor.
|
|||
|
//
|
|||
|
|
|||
|
CD3DVidTexture(rptr<CRasterVid> prasv_source, CCom<IDirect3DDevice> d3ddev)
|
|||
|
{
|
|||
|
prasvSource = prasv_source;
|
|||
|
|
|||
|
if (prasvSource)
|
|||
|
{
|
|||
|
// We have a texture raster.
|
|||
|
|
|||
|
Assert(prasvSource->pddsDraw);
|
|||
|
|
|||
|
// Create the source texture interface.
|
|||
|
D3D.err = prasvSource->pddsDraw->QueryInterface(IID_IDirect3DTexture, (void**)&d3dTextureSource);
|
|||
|
|
|||
|
// Create the video texture.
|
|||
|
prasvVid = rptr_new CRasterVid(prasvSource->iWidth, prasvSource->iHeight, prasvSource->iPixelBits,
|
|||
|
Set(erasTexture) + erasVideoMem);
|
|||
|
|
|||
|
// Create an empty palette for the raster.
|
|||
|
prasvVid->AttachPalette(prasvSource->pxf.ppalAttached);
|
|||
|
|
|||
|
// Create the video texture interface.
|
|||
|
D3D.err = prasvVid->pddsDraw->QueryInterface(IID_IDirect3DTexture, (void**)&d3dTextureVid);
|
|||
|
|
|||
|
// Retrieve the video texture handle.
|
|||
|
D3D.err = d3dTextureVid->GetHandle(d3ddev, &d3dhTexture);
|
|||
|
|
|||
|
//
|
|||
|
// Set the scaling values.
|
|||
|
//
|
|||
|
CDDSize<DDSURFACEDESC> ddsd;
|
|||
|
|
|||
|
D3D.err = prasvVid->pddsDraw->GetSurfaceDesc(&ddsd);
|
|||
|
v2Scale.tX = (float) prasvSource->iWidth / ddsd.dwWidth;
|
|||
|
v2Scale.tY = (float) prasvSource->iHeight / ddsd.dwHeight;
|
|||
|
|
|||
|
bLoaded = false;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Set null structure values.
|
|||
|
d3dhTexture = 0;
|
|||
|
bLoaded = true;
|
|||
|
v2Scale.tX = v2Scale.tY = 1.0f;
|
|||
|
}
|
|||
|
|
|||
|
// Create the material.
|
|||
|
CDDSize<D3DMATERIAL> d3dmat_desc;
|
|||
|
|
|||
|
//
|
|||
|
// D3D always modulates vertex colours with material colour.
|
|||
|
// Therefore, since we've already calculated the *real* colour the vertex should be,
|
|||
|
// we need a material with a white diffuse and specular colour.
|
|||
|
//
|
|||
|
d3dmat_desc.dwRampSize = 32;
|
|||
|
d3dmat_desc.dcvDiffuse.dvR =
|
|||
|
d3dmat_desc.dcvDiffuse.dvG =
|
|||
|
d3dmat_desc.dcvDiffuse.dvB = (D3DVALUE)1;
|
|||
|
d3dmat_desc.dcvSpecular = d3dmat_desc.dcvDiffuse;
|
|||
|
d3dmat_desc.hTexture = d3dhTexture;
|
|||
|
|
|||
|
d3dmatTexture.Init(d3dmat_desc, d3ddev);
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Member functions.
|
|||
|
//
|
|||
|
|
|||
|
bool bLoad()
|
|||
|
{
|
|||
|
if (!bLoaded)
|
|||
|
//
|
|||
|
// Load the source texture into the dest.
|
|||
|
// You would think that the return value would indicate a specific error condition,
|
|||
|
// such as being out of video memory, as in other DirectX return codes, but no.
|
|||
|
// In Direct3D, return values are things like D3DERR_TEXTURE_LOAD_FAILED, which is
|
|||
|
// useless. So we must simply return a sucess code from here, and assume that failure
|
|||
|
// is due to lack of video memory.
|
|||
|
//
|
|||
|
bLoaded = d3dTextureVid->Load(d3dTextureSource) == 0;
|
|||
|
return bLoaded;
|
|||
|
}
|
|||
|
|
|||
|
bool bUnload()
|
|||
|
{
|
|||
|
if (!bLoaded || !d3dTextureVid)
|
|||
|
return false;
|
|||
|
D3D.err = d3dTextureVid->Unload();
|
|||
|
bLoaded = false;
|
|||
|
return true;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
class CD3DVidTextureList: public list<CD3DVidTexture*>
|
|||
|
//
|
|||
|
// lsd3dvtex
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
public:
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Destructor.
|
|||
|
//
|
|||
|
|
|||
|
~CD3DVidTextureList()
|
|||
|
{
|
|||
|
// Delete all our VidTextures.
|
|||
|
for (iterator it = begin(); it != end(); it++)
|
|||
|
delete (*it);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Member functions.
|
|||
|
//
|
|||
|
|
|||
|
CD3DVidTexture* pd3dvtexLoad(rptr<CRasterVid> prasv_source, CCom<IDirect3DDevice> d3ddev)
|
|||
|
{
|
|||
|
CD3DVidTexture* pd3dvtex = 0;
|
|||
|
|
|||
|
// Search through the list a texture already using prasv_source.
|
|||
|
for (iterator it = begin(); it != end(); it++)
|
|||
|
{
|
|||
|
if ((*it)->prasvSource == prasv_source)
|
|||
|
{
|
|||
|
pd3dvtex = *it;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!pd3dvtex)
|
|||
|
{
|
|||
|
// Must add a vid texture to the list.
|
|||
|
pd3dvtex = new CD3DVidTexture(prasv_source, d3ddev);
|
|||
|
push_back(pd3dvtex);
|
|||
|
}
|
|||
|
|
|||
|
// Now attempt to Load it.
|
|||
|
while (!pd3dvtex->bLoad())
|
|||
|
{
|
|||
|
// We must unload something from the front of the list.
|
|||
|
for (iterator it = begin(); it != end(); it++)
|
|||
|
{
|
|||
|
if ((*it)->bUnload())
|
|||
|
break;
|
|||
|
}
|
|||
|
if (it == end())
|
|||
|
// We reached end of list w/o unloading anything.
|
|||
|
// I guess we can't load this texture.
|
|||
|
return pd3dvtex;
|
|||
|
}
|
|||
|
|
|||
|
return pd3dvtex;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
class CScreenRenderD3D: public CScreenRender
|
|||
|
//
|
|||
|
// Prefix: scrend3d
|
|||
|
//
|
|||
|
// Implementation of CScreenRender interface for Direct3D.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
private:
|
|||
|
rptr<CRasterVid> prasvScreen; // CRasterVid version of the main screen.
|
|||
|
rptr<CRasterVid> prasvZBuffer; // CRasterVid version of the z-buffer.
|
|||
|
CCom<IDirect3DDevice> D3DDevice; // The attached D3D device (driver).
|
|||
|
CDirect3D::SDeviceDesc* pDeviceDesc; // The description of the device.
|
|||
|
CCom<IDirect3DViewport> D3DViewport; // The D3D viewport.
|
|||
|
CD3DExBuf D3DExBuf; // The execute buffer.
|
|||
|
CD3DVidTextureList D3DVidTextureList; // The list of textures loaded.
|
|||
|
|
|||
|
CSet<ERenderFeature> seterf_Modify; // Which flags are modifiable.
|
|||
|
CSet<ERenderFeature> seterf_Default; // Which flags are on by default.
|
|||
|
CSet<ERenderFeature> seterfLast; // The last render state encountered.
|
|||
|
|
|||
|
// Settings derived from pSettings.
|
|||
|
TPixel pixBackground; // The pixel corresponding to clrBackground.
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
CScreenRenderD3D(SSettings* pscrenset, rptr<CRasterVid> prasv_screen, uint u_driver)
|
|||
|
: CScreenRender(pscrenset, rptr_cast(CRaster, prasv_screen))
|
|||
|
{
|
|||
|
prasvScreen = prasv_screen;
|
|||
|
|
|||
|
pDeviceDesc = &D3D.sadevdList[u_driver];
|
|||
|
|
|||
|
// Create a D3DDevice attached to the surface.
|
|||
|
D3D.err = prasvScreen->pddsDraw->QueryInterface
|
|||
|
(
|
|||
|
pDeviceDesc->Guid, // The device ID.
|
|||
|
(void**)&D3DDevice // Put the device here.
|
|||
|
);
|
|||
|
Assert(D3DDevice);
|
|||
|
|
|||
|
// Create the Z buffer if supported.
|
|||
|
|
|||
|
uint u_depths = pDeviceDesc->d3ddevcap.dwDeviceZBufferBitDepth;
|
|||
|
if (u_depths)
|
|||
|
{
|
|||
|
// Find the Z buffer bit depth from this driver's D3D device description
|
|||
|
int i_depth;
|
|||
|
|
|||
|
if (u_depths & DDBD_32)
|
|||
|
i_depth = 32;
|
|||
|
else if (u_depths & DDBD_24)
|
|||
|
i_depth = 24;
|
|||
|
else if (u_depths & DDBD_16)
|
|||
|
i_depth = 16;
|
|||
|
else if (u_depths & DDBD_8)
|
|||
|
i_depth = 8;
|
|||
|
else
|
|||
|
Assert(false);
|
|||
|
|
|||
|
prasvZBuffer = rptr_new CRasterVid
|
|||
|
(
|
|||
|
prasvScreen->iWidth, prasvScreen->iHeight, // Same dimensions as screen.
|
|||
|
i_depth, // The required depth.
|
|||
|
Set(erasZBuffer) + // Set the Z buffer flag.
|
|||
|
// For hardware drivers, the Z-Buffer MUST be in video memory.
|
|||
|
// (Otherwise, it MUST be in system memory).
|
|||
|
Set(erasVideoMem) * pDeviceDesc->bIsHW
|
|||
|
);
|
|||
|
|
|||
|
// Attach the Z-buffer to the draw buffer so D3D will find it.
|
|||
|
D3D.err = prasvScreen->pddsDraw->AddAttachedSurface(prasvZBuffer->pddsDraw);
|
|||
|
}
|
|||
|
|
|||
|
// Create the viewport.
|
|||
|
D3D.err = D3D->CreateViewport(&D3DViewport, 0);
|
|||
|
Assert(D3DViewport);
|
|||
|
|
|||
|
// Attach it to the device.
|
|||
|
D3D.err = D3DDevice->AddViewport(D3DViewport);
|
|||
|
|
|||
|
// Initialise it.
|
|||
|
CDDSize<D3DVIEWPORT> d3dvpdesc;
|
|||
|
d3dvpdesc.dwWidth = prasvScreen->iWidth;
|
|||
|
d3dvpdesc.dwHeight = prasvScreen->iHeight;
|
|||
|
|
|||
|
// Scaling does not apply to TLVERTICES, but set them to 1.0 just in case.
|
|||
|
d3dvpdesc.dvScaleX = 1.0f;
|
|||
|
d3dvpdesc.dvScaleY = 1.0f;
|
|||
|
d3dvpdesc.dvMaxX = (D3DVALUE)(d3dvpdesc.dwWidth - 1);
|
|||
|
d3dvpdesc.dvMaxY = (D3DVALUE)(d3dvpdesc.dwHeight - 1);
|
|||
|
|
|||
|
D3D.err = D3DViewport->SetViewport(&d3dvpdesc);
|
|||
|
|
|||
|
/*
|
|||
|
// Create the background material for the viewport.
|
|||
|
CCom<IDirect3DMaterial> d3d_material_bg;
|
|||
|
CDDSize<D3DMATERIAL> d3d_material_desc;
|
|||
|
D3DMATERIALHANDLE d3dhmat;
|
|||
|
|
|||
|
// Set ramp size to 1, and all colours 0. This makes everything black.
|
|||
|
d3d_material_desc.dwRampSize = 1;
|
|||
|
|
|||
|
D3D.err = D3D->CreateMaterial(&d3d_material_bg, 0);
|
|||
|
D3D.err = d3d_material_bg->SetMaterial(&d3d_material_desc);
|
|||
|
D3D.err = d3d_material_bg->GetHandle(D3DDevice, &d3dhmat);
|
|||
|
D3D.err = D3DViewport->SetBackground(d3dhmat);
|
|||
|
*/
|
|||
|
// Allocate the execute buffer. Make up some size for now.
|
|||
|
D3DExBuf.Allocate(D3DDevice, 32*1024);
|
|||
|
|
|||
|
// Set seterfState to default.
|
|||
|
seterf_Default[erfRASTER_CLIP] = 1;
|
|||
|
|
|||
|
// If culling is supported, assume it's on by default.
|
|||
|
seterf_Default[erfRASTER_CULL] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwMiscCaps &
|
|||
|
(D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW);
|
|||
|
|
|||
|
seterf_Default[erfZ_BUFFER]
|
|||
|
[erfZ_WRITE]
|
|||
|
[erfZ_TEST] = prasvZBuffer != 0;
|
|||
|
|
|||
|
seterf_Default[erfCOPY] = 0;
|
|||
|
seterf_Default[erfLIGHT] = 1;
|
|||
|
seterf_Default[erfLIGHT_SHADE] = 1;
|
|||
|
seterf_Default[erfFOG] = 0;
|
|||
|
seterf_Default[erfFOG_SHADE] = 0;
|
|||
|
seterf_Default[erfCOLOURED_LIGHTS] = pDeviceDesc->d3ddevcap.dcmColorModel == D3DCOLOR_RGB;
|
|||
|
|
|||
|
seterf_Default[erfTEXTURE] = 1;
|
|||
|
seterf_Default[erfTRANSPARENT] = 0;
|
|||
|
seterf_Default[erfBUMP] = 0;
|
|||
|
|
|||
|
seterf_Default[erfSUBPIXEL] = 0;
|
|||
|
seterf_Default[erfPERSPECTIVE] = 0;
|
|||
|
seterf_Default[erfDITHER] = 0;
|
|||
|
seterf_Default[erfFILTER] = 0;
|
|||
|
seterf_Default[erfFILTER_EDGES] = 0;
|
|||
|
|
|||
|
// Set seterf_Modify based on caps fields.
|
|||
|
seterf_Modify[erfRASTER_CLIP] =
|
|||
|
pDeviceDesc->d3ddevcap.dtcTransformCaps.dwCaps & D3DTRANSFORMCAPS_CLIP;
|
|||
|
// && pDeviceDesc->d3ddevcap.bClipping;
|
|||
|
|
|||
|
// Set cull modifiable if both CULLNONE and another culling option are supported.
|
|||
|
seterf_Modify[erfRASTER_CULL] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwMiscCaps &
|
|||
|
(D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW) &&
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwMiscCaps &
|
|||
|
D3DPMISCCAPS_CULLNONE;
|
|||
|
|
|||
|
Assert(pDeviceDesc->d3ddevcap.dpcTriCaps.dwZCmpCaps & D3DPCMPCAPS_LESSEQUAL);
|
|||
|
|
|||
|
seterf_Modify[erfZ_BUFFER] = prasvZBuffer != 0;
|
|||
|
seterf_Modify[erfZ_WRITE] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKZ;
|
|||
|
seterf_Modify[erfZ_TEST] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZTEST;
|
|||
|
|
|||
|
seterf_Modify[erfCOPY] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureBlendCaps &
|
|||
|
D3DPTBLENDCAPS_COPY;
|
|||
|
seterf_Modify[erfLIGHT] =
|
|||
|
(pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureBlendCaps & D3DPTBLENDCAPS_MODULATE) &&
|
|||
|
(pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps &
|
|||
|
(D3DPSHADECAPS_COLORFLATMONO | D3DPSHADECAPS_COLORFLATRGB));
|
|||
|
seterf_Modify[erfLIGHT_SHADE] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps &
|
|||
|
(D3DPSHADECAPS_COLORGOURAUDMONO | D3DPSHADECAPS_COLORGOURAUDRGB);
|
|||
|
|
|||
|
seterf_Modify[erfFOG] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_FOGFLAT;
|
|||
|
seterf_Modify[erfFOG_SHADE] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_FOGGOURAUD;
|
|||
|
seterf_Modify[erfCOLOURED_LIGHTS] =
|
|||
|
(pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_COLORGOURAUDMONO) &&
|
|||
|
(pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_COLORGOURAUDRGB);
|
|||
|
seterf_Modify[erfSPECULAR] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwShadeCaps &
|
|||
|
(D3DPSHADECAPS_SPECULARGOURAUDMONO | D3DPSHADECAPS_SPECULARGOURAUDRGB);
|
|||
|
|
|||
|
seterf_Modify[erfTEXTURE] =
|
|||
|
pDeviceDesc->d3ddevcap.dwDevCaps &
|
|||
|
(D3DDEVCAPS_TEXTURESYSTEMMEMORY | D3DDEVCAPS_TEXTUREVIDEOMEMORY);
|
|||
|
seterf_Modify[erfTRANSPARENT] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY;
|
|||
|
|
|||
|
seterf_Modify[erfBUMP] = 0;
|
|||
|
|
|||
|
seterf_Modify[erfSUBPIXEL] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_SUBPIXEL;
|
|||
|
seterf_Modify[erfPERSPECTIVE] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE;
|
|||
|
seterf_Modify[erfDITHER] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER;
|
|||
|
seterf_Modify[erfFILTER] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR;
|
|||
|
seterf_Modify[erfFILTER_EDGES] =
|
|||
|
pDeviceDesc->d3ddevcap.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_BORDER;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
~CScreenRenderD3D()
|
|||
|
{
|
|||
|
// Remove the attached Z-buffer.
|
|||
|
if (prasvZBuffer)
|
|||
|
{
|
|||
|
D3D.err = prasvScreen->pddsDraw->DeleteAttachedSurface(0, prasvZBuffer->pddsDraw);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private:
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Member functions.
|
|||
|
//
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
void FlushBuffer(uint u_vertices = 0)
|
|||
|
{
|
|||
|
if (D3DExBuf.uLen == 0)
|
|||
|
// Empty.
|
|||
|
return;
|
|||
|
|
|||
|
// Flush the execute buffer commands to the device
|
|||
|
// (because we're done with the frame, or it's full).
|
|||
|
D3DExBuf.Finish(u_vertices);
|
|||
|
D3DExBuf.Execute(D3DViewport, D3DEXECUTE_CLIPPED);
|
|||
|
|
|||
|
// Check out the results.
|
|||
|
CDDSize<D3DEXECUTEDATA> d3d_exdata;
|
|||
|
D3DExBuf->GetExecuteData(&d3d_exdata);
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
//
|
|||
|
// Overrides.
|
|||
|
//
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual CSet<ERenderFeature> seterfModify()
|
|||
|
{
|
|||
|
return seterf_Modify;
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual CSet<ERenderFeature> seterfDefault()
|
|||
|
{
|
|||
|
return seterf_Default;
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual void BeginFrame()
|
|||
|
{
|
|||
|
CorrectRenderState(pSettings->seterfState);
|
|||
|
|
|||
|
// Clear the Z buffer (only).
|
|||
|
if (pSettings->seterfState[erfZ_BUFFER])
|
|||
|
{
|
|||
|
Assert(prasvZBuffer);
|
|||
|
|
|||
|
D3DRECT d3drect;
|
|||
|
d3drect.x1 = d3drect.y1 = 0;
|
|||
|
d3drect.x2 = prasvZBuffer->iWidth;
|
|||
|
d3drect.y2 = prasvZBuffer->iHeight;
|
|||
|
D3D.err = D3DViewport->Clear(1, &d3drect, D3DCLEAR_ZBUFFER);
|
|||
|
|
|||
|
// prasvZBuffer->Lock();
|
|||
|
}
|
|||
|
|
|||
|
// Clear the screen.
|
|||
|
if (pSettings->bClearBackground)
|
|||
|
{
|
|||
|
Assert(prasvScreen);
|
|||
|
Assert(prasvScreen->pixFromColour(pSettings->clrBackground) == pixBackground);
|
|||
|
prasvScreen->Clear(pixBackground);
|
|||
|
}
|
|||
|
|
|||
|
// prasvScreen->Lock();
|
|||
|
D3D.err = D3DDevice->BeginScene();
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual void EndFrame()
|
|||
|
{
|
|||
|
D3D.err = D3DDevice->EndScene();
|
|||
|
/*
|
|||
|
prasvScreen->Unlock();
|
|||
|
if (prasvZBuffer)
|
|||
|
prasvZBuffer->Unlock();
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual void SetRenderState(CSet<ERenderFeature> seterf)
|
|||
|
// Add state instructions to execute buffer.
|
|||
|
{
|
|||
|
// If there is no D3D Viewport, we must return because it is not required.
|
|||
|
if (!D3DViewport)
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
// To do: Light states.
|
|||
|
|
|||
|
// Put a STATERENDER op in the buffer.
|
|||
|
// Remember its position, so we can fill in the count later.
|
|||
|
SD3DInsStates* pd3dins = new((CMArray<char>&)D3DExBuf) SD3DInsStates(D3DOP_STATERENDER, 0);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_CULLMODE,
|
|||
|
seterf[erfRASTER_CULL] ?
|
|||
|
// If we want software culling, then set CW if supported, else CCW.
|
|||
|
(pDeviceDesc->d3ddevcap.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_CULLCW ?
|
|||
|
D3DCULL_CCW : D3DCULL_CCW)
|
|||
|
: D3DCULL_NONE);
|
|||
|
|
|||
|
// Z-buffer.
|
|||
|
// To do: Figure out how to do Z write-only, if possible.
|
|||
|
/*
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_ZFUNC,
|
|||
|
D3DCMP_LESSEQUAL);
|
|||
|
*/
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_ZENABLE,
|
|||
|
!!seterf[erfZ_BUFFER]);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_ZWRITEENABLE,
|
|||
|
!!seterf[erfZ_WRITE]);
|
|||
|
|
|||
|
// Shading.
|
|||
|
|
|||
|
// To do: make first vertex contain average lighting.
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_SHADEMODE,
|
|||
|
seterf[erfLIGHT_SHADE] ? D3DSHADE_GOURAUD : D3DSHADE_FLAT);
|
|||
|
|
|||
|
// To do: work out interaction w/ FOGFLAT, FOGGOURAUD caps.
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_FOGENABLE,
|
|||
|
!!seterf[erfFOG]);
|
|||
|
|
|||
|
// To do:
|
|||
|
// Figure out start and end.
|
|||
|
// D3DExBuf << SD3DState(D3DRENDERSTATE_FOGCOLOR,
|
|||
|
|
|||
|
// Use default fog mode, start, and end.
|
|||
|
/*
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_FOGTABLEMODE,
|
|||
|
seterfState[erfFOG] ? D3DFOG_LINEAR : D3DFOG_NONE);
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_FOGTABLESTART,
|
|||
|
1.0f);
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_FOGTABLEEND,
|
|||
|
100.0f);
|
|||
|
*/
|
|||
|
|
|||
|
// To do: coloured support in lighting.
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_MONOENABLE,
|
|||
|
!seterf[erfCOLOURED_LIGHTS]);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_SPECULARENABLE,
|
|||
|
!seterf[erfSPECULAR]);
|
|||
|
|
|||
|
// Texture.
|
|||
|
|
|||
|
// To do: disable textures (enable solid colouring).
|
|||
|
|
|||
|
// To do: test transparencies. MODULATEMASK isn't it.
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_TEXTUREMAPBLEND,
|
|||
|
seterf[erfCOPY] ?
|
|||
|
D3DTBLEND_COPY
|
|||
|
: seterf[erfTRANSPARENT] ?
|
|||
|
D3DTBLEND_MODULATEMASK
|
|||
|
:
|
|||
|
D3DTBLEND_MODULATE);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_SUBPIXEL,
|
|||
|
!!seterf[erfSUBPIXEL]);
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_SUBPIXELX,
|
|||
|
!!seterf[erfSUBPIXEL]);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_TEXTUREPERSPECTIVE,
|
|||
|
!!seterf[erfPERSPECTIVE]);
|
|||
|
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_DITHERENABLE,
|
|||
|
!!seterf[erfDITHER]);
|
|||
|
|
|||
|
// To do: add mip-mapping.
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_TEXTUREMIN,
|
|||
|
seterf[erfFILTER] ? D3DFILTER_LINEAR : D3DFILTER_NEAREST);
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_TEXTUREMAG,
|
|||
|
seterf[erfFILTER] ? D3DFILTER_LINEAR : D3DFILTER_NEAREST);
|
|||
|
|
|||
|
// To do: test this, see what the hell it does.
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_ANTIALIAS,
|
|||
|
!!seterf[erfFILTER_EDGES]);
|
|||
|
|
|||
|
// Set the bloody count;
|
|||
|
pd3dins->wCount = (SD3DState*) D3DExBuf.ptEnd() - (SD3DState*) (pd3dins+1);
|
|||
|
|
|||
|
// To do: create fill mode.
|
|||
|
}
|
|||
|
|
|||
|
//******************************************************************************************
|
|||
|
virtual void DrawPolygons
|
|||
|
(
|
|||
|
CPArray<CRenderPolygon> parpoly
|
|||
|
)
|
|||
|
{
|
|||
|
if (parpoly.uLen == 0)
|
|||
|
return;
|
|||
|
|
|||
|
// For now, assume one texture per object.
|
|||
|
rptr<CRasterVid> prasv;
|
|||
|
CD3DVidTexture* pd3dvtex = 0;
|
|||
|
|
|||
|
if (parpoly[0U].ptexTexture && parpoly[0U].ptexTexture->prasTexture)
|
|||
|
prasv = rptr_dynamic_cast(CRasterVid, rptr_nonconst(parpoly[0U].ptexTexture->prasTexture));
|
|||
|
|
|||
|
// Load the material.
|
|||
|
pd3dvtex = D3DVidTextureList.pd3dvtexLoad(prasv, D3DDevice);
|
|||
|
|
|||
|
// Start filling the Execute buffer.
|
|||
|
D3DExBuf.Reset();
|
|||
|
|
|||
|
// First store the vertices.
|
|||
|
D3DTLVERTEX* ad3dvertex = new((CMArray<char>&)D3DExBuf) D3DTLVERTEX[parv_vertices.uLen];
|
|||
|
for (uint u = 0; u < parv_vertices.uLen; u++)
|
|||
|
Convert(&ad3dvertex[u], parv_vertices[u], pd3dvtex->v2Scale);
|
|||
|
|
|||
|
//
|
|||
|
// Now store all the instructions.
|
|||
|
//
|
|||
|
|
|||
|
D3DExBuf << SD3DInsStates(D3DOP_STATELIGHT, 1);
|
|||
|
D3DExBuf << SD3DState(D3DLIGHTSTATE_MATERIAL, pd3dvtex->d3dmatTexture.d3dHandle);
|
|||
|
|
|||
|
// The D3DOP_PROCESSVERTICES instruction is required, even though it just performs a COPY.
|
|||
|
D3DExBuf << SD3DInsProcessVertices(
|
|||
|
D3DPROCESSVERTICES_COPY | D3DPROCESSVERTICES_UPDATEEXTENTS,
|
|||
|
0, parv_vertices.uLen);
|
|||
|
|
|||
|
// Validate state if necessary.
|
|||
|
CorrectRenderState(pSettings->seterfState);
|
|||
|
|
|||
|
if (pSettings->seterfState ^ seterfLast)
|
|||
|
{
|
|||
|
SetRenderState(pSettings->seterfState);
|
|||
|
seterfLast = pSettings->seterfState;
|
|||
|
}
|
|||
|
|
|||
|
D3DExBuf << SD3DInsStates(D3DOP_STATERENDER, 1);
|
|||
|
D3DExBuf << SD3DState(D3DRENDERSTATE_TEXTUREHANDLE,
|
|||
|
pSettings->seterfState[erfTEXTURE] ? pd3dvtex->d3dhTexture : 0);
|
|||
|
|
|||
|
// A single triangle instruction, with the number of trianges we're drawing.
|
|||
|
D3DExBuf.PutInsTriangles(parpoly.uLen);
|
|||
|
for (CRenderPolygon* prpoly = parpoly; prpoly < parpoly.ptEnd(); prpoly++)
|
|||
|
{
|
|||
|
Assert(prpoly->ptexTexture == parpoly[0U].ptexTexture);
|
|||
|
D3DExBuf << SD3DTriangle
|
|||
|
(
|
|||
|
// Convert RenderVertex pointers to indices.
|
|||
|
// Pass in clockwise order.
|
|||
|
prpoly->aprvVertices[2] - parv_vertices,
|
|||
|
prpoly->aprvVertices[1] - parv_vertices,
|
|||
|
prpoly->aprvVertices[0] - parv_vertices
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
D3DExBuf.Finish(parv_vertices.uLen);
|
|||
|
|
|||
|
/*
|
|||
|
prasvScreen->Unlock();
|
|||
|
if (prasvZBuffer)
|
|||
|
prasvZBuffer->Unlock();
|
|||
|
*/
|
|||
|
|
|||
|
D3DExBuf.Execute(D3DViewport, D3DEXECUTE_CLIPPED);
|
|||
|
|
|||
|
/*
|
|||
|
prasvScreen->Lock();
|
|||
|
if (prasvZBuffer)
|
|||
|
prasvZBuffer->Lock();
|
|||
|
*/
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
class CRenderDescD3D: public CRenderDesc
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
private:
|
|||
|
uint uDriver;
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
// Constructor.
|
|||
|
//
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
CRenderDescD3D(uint u_driver)
|
|||
|
: CRenderDesc(D3D.sadevdList[u_driver].strName), uDriver(u_driver)
|
|||
|
{
|
|||
|
Assert(D3D.bValid);
|
|||
|
}
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
virtual CScreenRender* pScreenRenderCreate(SSettings* pscrenset, rptr<CRaster> pras_screen, rptr<CRaster> pras_zbuffer)
|
|||
|
{
|
|||
|
Assert(D3D.bValid);
|
|||
|
|
|||
|
// Not allowed to pass in an explicit z-buffer. And screen must be a CRasterVid.
|
|||
|
Assert(!pras_zbuffer);
|
|||
|
return new CScreenRenderD3D(pscrenset, rptr_dynamic_cast(CRasterVid, pras_screen), uDriver);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//**********************************************************************************************
|
|||
|
//
|
|||
|
void AddRenderDescD3D()
|
|||
|
//
|
|||
|
// Add RenderDescs for all available D3D drivers to sapRenderDesc.
|
|||
|
//
|
|||
|
//**************************************
|
|||
|
{
|
|||
|
// Ensure that the D3D var has been initialised.
|
|||
|
InitPtr(pD3D);
|
|||
|
|
|||
|
if (!D3D.bValid)
|
|||
|
{
|
|||
|
//
|
|||
|
// There is no Direct3D support.
|
|||
|
// Don't add any CRenderDescs, and that should be the end of the story.
|
|||
|
// Since all access to Direct3D is through the CRenderDesc and CScreenRender interfaces,
|
|||
|
// we won't have to worry about anyone else thinking Direct3D exists.
|
|||
|
//
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Add all the drivers.
|
|||
|
for (uint u = 0; u < D3D.sadevdList.uLen; u++)
|
|||
|
sapRenderDesc << new CRenderDescD3D(u);
|
|||
|
}
|