JurassicParkTrespasser/jp2_pc/Source/Lib/Renderer/D3d/D3D.cpp

275 lines
8.9 KiB
C++
Raw Permalink Normal View History

2018-01-01 22:07:24 +00:00
/***********************************************************************************************
*
* Copyright <EFBFBD> DreamWorks Interactive. 1996
*
* Implementation of D3D.hpp.
*
***********************************************************************************************
*
* $Log:: /JP2_PC/Source/Lib/Renderer/D3d/D3D.cpp $
*
* 9 12/20/96 6:11p Mlange
* Temporarily disabled Direct3D. Textures are now no longer forced to a power of 2.
*
* 8 96/11/27 19:32 Speter
* Updated for change to CCom: ptCom member changed to ptPtr.
*
* 7 10/31/96 6:41p Agrant
* changed the _NTSDK ifndef to NO_D3D.
* To disable D3D, just define NO_D3D in the D3D library build settings.
*
* 6 96/08/29 12:47 Speter
* Disable querying IDirect3D interface under NT, due to unknown problem.
*
* 5 96/08/19 16:17 Speter
* Now actually handle lack of Direct3D support, rather than pretending to, as in previous
* check-in.
*
* 4 96/08/19 16:04 Speter
* Added bValid flag to CDirect3D class. Now app can check whether Direct3D support exists.
*
* 3 96/08/19 13:06 Speter
* Changed name of initD3D to InitD3D.
* Added CInitDD instance to Direct3D constructor.
*
* 2 96/08/14 11:02 Speter
* Changed type prefixes, changed pD3DMain to D3D.
* Added CD3D::CError class for error reporting.
* Added SD3DInstruction, and subtypes, for use in filling execute buffers.
* Added CD3DMaterial class.
*
* 1 96/08/09 10:54 Speter
* First version, basic D3D functionality.
*
**********************************************************************************************/
#define NO_D3D
#include "Common.hpp"
#include "D3D.hpp"
//**********************************************************************************************
//
// CDirect3D implementation.
//
//******************************************************************************************
//
// class CError implementation.
//
//**************************************************************************************
void CDirect3D::CError::operator =(int i_err)
{
if (i_err == 0)
return;
switch (i_err)
{
case D3DERR_BADMAJORVERSION:
TerminalError(ERROR_D3D, true, "Bad major version");
case D3DERR_BADMINORVERSION:
TerminalError(ERROR_D3D, true, "Bad minor version");
case D3DERR_EXECUTE_CLIPPED_FAILED:
TerminalError(ERROR_D3D, true, "Execute clipped failed");
case D3DERR_EXECUTE_CREATE_FAILED:
TerminalError(ERROR_D3D, true, "Execute create failed");
case D3DERR_EXECUTE_DESTROY_FAILED:
TerminalError(ERROR_D3D, true, "Execute destroy failed");
case D3DERR_EXECUTE_FAILED:
TerminalError(ERROR_D3D, true, "Execute failed");
case D3DERR_EXECUTE_LOCK_FAILED:
TerminalError(ERROR_D3D, true, "Execute lock failed");
case D3DERR_EXECUTE_LOCKED:
TerminalError(ERROR_D3D, true, "Execute locked");
case D3DERR_EXECUTE_NOT_LOCKED:
TerminalError(ERROR_D3D, true, "Execute not locked");
case D3DERR_EXECUTE_UNLOCK_FAILED:
TerminalError(ERROR_D3D, true, "Execute unlock failed");
case D3DERR_LIGHT_SET_FAILED:
TerminalError(ERROR_D3D, true, "Light set failed");
case D3DERR_MATERIAL_CREATE_FAILED:
TerminalError(ERROR_D3D, true, "Material create failed");
case D3DERR_MATERIAL_DESTROY_FAILED:
TerminalError(ERROR_D3D, true, "Material destroy failed");
case D3DERR_MATERIAL_GETDATA_FAILED:
TerminalError(ERROR_D3D, true, "Material get data failed");
case D3DERR_MATERIAL_SETDATA_FAILED:
TerminalError(ERROR_D3D, true, "Material set data failed");
case D3DERR_MATRIX_CREATE_FAILED:
TerminalError(ERROR_D3D, true, "Material create failed");
case D3DERR_MATRIX_DESTROY_FAILED:
TerminalError(ERROR_D3D, true, "Material destroy failed");
case D3DERR_MATRIX_GETDATA_FAILED:
TerminalError(ERROR_D3D, true, "Matrix get data failed");
case D3DERR_MATRIX_SETDATA_FAILED:
TerminalError(ERROR_D3D, true, "Matrix set data failed");
case D3DERR_SCENE_BEGIN_FAILED:
TerminalError(ERROR_D3D, true, "Scene begin failed");
case D3DERR_SCENE_END_FAILED:
TerminalError(ERROR_D3D, true, "Scene end failed");
case D3DERR_SCENE_IN_SCENE:
TerminalError(ERROR_D3D, true, "Currently in scene");
case D3DERR_SCENE_NOT_IN_SCENE:
TerminalError(ERROR_D3D, true, "Not currently in scene");
case D3DERR_SETVIEWPORTDATA_FAILED:
TerminalError(ERROR_D3D, true, "Viewport set data failed");
case D3DERR_TEXTURE_CREATE_FAILED:
TerminalError(ERROR_D3D, true, "Texture create failed");
case D3DERR_TEXTURE_DESTROY_FAILED:
TerminalError(ERROR_D3D, true, "Texture destroy failed");
case D3DERR_TEXTURE_GETSURF_FAILED:
TerminalError(ERROR_D3D, true, "Texture get surface failed");
case D3DERR_TEXTURE_LOAD_FAILED:
TerminalError(ERROR_D3D, true, "Texture load failed");
case D3DERR_TEXTURE_LOCK_FAILED:
TerminalError(ERROR_D3D, true, "Texture lock failed");
case D3DERR_TEXTURE_LOCKED:
TerminalError(ERROR_D3D, true, "Texture locked");
case D3DERR_TEXTURE_NO_SUPPORT:
TerminalError(ERROR_D3D, true, "Texture not supported");
case D3DERR_TEXTURE_NOT_LOCKED:
TerminalError(ERROR_D3D, true, "Texture not locked");
case D3DERR_TEXTURE_SWAP_FAILED:
TerminalError(ERROR_D3D, true, "Texture swap failed");
case D3DERR_TEXTURE_UNLOCK_FAILED:
TerminalError(ERROR_D3D, true, "Texture unlock failed");
default:
DirectDraw::err = i_err;
}
}
static HRESULT PASCAL EnumDevicesCallback(
GUID* pguid, char* str_desc, char* str_name,
D3DDEVICEDESC* pd3ddevcap_hw, D3DDEVICEDESC* pd3ddevcap_sw,
void* p)
{
CDirect3D* pd3d = (CDirect3D*)p;
new(pd3d->sadevdList) CDirect3D::SDeviceDesc(pguid, str_name, str_desc, pd3ddevcap_hw, pd3ddevcap_sw);
return D3DENUMRET_OK;
}
CDirect3D::CDirect3D()
{
CInitDD init_dd;
// Ensure only pD3D is ever initialised.
Assert(!pD3D);
#ifndef NO_D3D
// Create the COM object from the DirectDraw COM object.
if (DirectDraw::pdd->QueryInterface(IID_IDirect3D, (void**)&ptPtr) != 0
|| ptPtr == 0)
{
// There is no Direct3D support on this system.
// The rest of the program will have to check for this.
bValid = false;
return;
}
bValid = true;
// Get a list of drivers.
ptPtr->EnumDevices(EnumDevicesCallback, this);
#else
bValid = false;
#endif
}
// The sole instance.
CDirect3D* pD3D;
//******************************************************************************************
//
// CD3DExBuf implementation.
//
//******************************************************************************************
void CD3DExBuf::Allocate(CCom<IDirect3DDevice> d3d_dev, uint u_size)
{
Assert(D3D.bValid);
// Ensure we haven't already allocated it.
Assert(!ptPtr);
// Create an execute buffer of the desired size.
CDDSize<D3DEXECUTEBUFFERDESC> d3d_exbuf_desc;
d3d_exbuf_desc.dwFlags = D3DDEB_BUFSIZE;
d3d_exbuf_desc.dwBufferSize = u_size;
D3D.err = d3d_dev->CreateExecuteBuffer(&d3d_exbuf_desc, &ptPtr, NULL);
// Set the array data (we have a max size, but no pointer yet).
Set(0, u_size);
D3DDevice = d3d_dev;
}
//******************************************************************************************
void CD3DExBuf::Reset()
{
// Create an execute buffer of the desired size.
CDDSize<D3DEXECUTEBUFFERDESC> d3d_exbuf_desc;
// Lock the execute buffer so it can be filled.
D3D.err = (*this)->Lock(&d3d_exbuf_desc);
// Clear it out for good measure.
memset(d3d_exbuf_desc.lpData, 0, d3d_exbuf_desc.dwBufferSize);
// Set the array data with the pointer.
atArray = (char*) d3d_exbuf_desc.lpData;
uLen = 0;
}
//******************************************************************************************
void CD3DExBuf::Finish(uint u_vertices)
{
if (uLen == 0)
{
// We have an empty buffer, so merely unlock and return.
D3D.err = ptPtr->Unlock();
return;
}
// Add the OP_EXIT command.
*this << SD3DInstruction(D3DOP_EXIT);
// Prepare for Execute command.
// Unlock the buffer, as we're done filling it.
D3D.err = ptPtr->Unlock();
// Set the stats for it.
CDDSize<D3DEXECUTEDATA> d3d_exdata;
d3d_exdata.dwVertexOffset = 0;
d3d_exdata.dwVertexCount = u_vertices;
d3d_exdata.dwInstructionOffset = u_vertices * sizeof(D3DTLVERTEX);
// uLen is the total amount of data in the buffer, so the instruction length
// is uLen minus the amount of data for the vertices.
d3d_exdata.dwInstructionLength = uLen - d3d_exdata.dwInstructionOffset;
D3D.err = ptPtr->SetExecuteData(&d3d_exdata);
}
//******************************************************************************************
void CD3DExBuf::Execute(IDirect3DViewport* pd3d_viewport, uint u_flags)
{
if (uLen == 0)
return;
D3D.err = D3DDevice->Execute(*this, pd3d_viewport, u_flags);
// Check out the results.
CDDSize<D3DEXECUTEDATA> d3d_exdata;
(*this)->GetExecuteData(&d3d_exdata);
}