deargui-vpl/ref/virtools/Includes/CKDX8Rasterizer.h

490 lines
16 KiB
C++

#ifndef CKRASTERIZERDX8_H
#define CKRASTERIZERDX8_H "$Id:$"
/*************************************************************************/
/* File : CKDX8Rasterizer.h */
/* Author : Romain Sididris */
/* */
/* + Direct X 8 Rasterizer declaration */
/* + Some methods of these classes are already implemented in the */
/* CKRasterizerLib library as they are common to all rasterizers */
/* */
/* Virtools SDK */
/* Copyright (c) Virtools 2000, All Rights Reserved. */
/*************************************************************************/
// Ensure we are using correct DirectDraw version
#define DIRECTDRAW_VERSION 0x0801
#ifdef _XBOX
#define D3DCOMPILE_PUREDEVICE 1
#include <Xtl.h>
#else
#define _NOD3DX
#include <d3d8.h>
#include <d3dx8.h>
//DDraw is included here only to get the Total Video memory and Free Video Memory
#include "ddraw.h"
#endif
#include "CKRasterizer.h"
#include "XBitArray.h"
//---Implemented in CKDX8PixelFormatUtils.cpp :
D3DFORMAT VxPixelFormatToD3DFormat8(VX_PIXELFORMAT pf);
VX_PIXELFORMAT D3DFormatToVxPixelFormat8(D3DFORMAT ddpf);
D3DFORMAT TextureDescToD3DFormat8(CKTextureDesc* desc);
void D3DFormatToTextureDesc8(D3DFORMAT ddpf,CKTextureDesc* desc);
//------
class CKDX8RasterizerDriver;
class CKDX8RasterizerContext;
class CKDX8Rasterizer;
typedef BOOL (*SetDXRenderStateFunc)(CKDX8RasterizerContext* ctx,CKDWORD Value);
typedef BOOL (*GetDXRenderStateFunc)(CKDX8RasterizerContext* ctx,CKDWORD* Value);
#define PREPAREDXSTRUCT(x) { memset(&x, 0, sizeof(x)); x.dwSize = sizeof(x); }
#define SAFERELEASE(x) { if (x) x->Release(); x = NULL; }
#define SAFELASTRELEASE(x) { int refCount= 0; if (x) refCount= x->Release(); x = NULL; XASSERT(refCount == 0); }
// Store texture operation required to perform blending between two texture stages
typedef struct CKStageBlend8 {
D3DTEXTUREOP Cop;
CKDWORD Carg1;
CKDWORD Carg2;
D3DTEXTUREOP Aop;
CKDWORD Aarg1;
CKDWORD Aarg2;
} CKStageBlend;
/*******************************************
A texture object for DX8 : contains the
texture surface pointer
*********************************************/
typedef struct CKDX8TextureDesc : public CKTextureDesc
{
public:
union {
LPDIRECT3DTEXTURE8 DxTexture;
LPDIRECT3DCUBETEXTURE8 DxCubeTexture;
LPDIRECT3DVOLUMETEXTURE8 DxVolumeTexture;
};
//----- For render target textures...
LPDIRECT3DTEXTURE8 DxRenderTexture;
//----- For non managed surface to be locked (DX8 does not support direct locking anymore)
LPDIRECT3DSURFACE8 DxLockedSurface;
DWORD LockedFlags;
public:
CKDX8TextureDesc() { DxTexture=NULL; DxRenderTexture=NULL; DxLockedSurface = NULL;}
~CKDX8TextureDesc() {
#ifdef _XBOX
int refcount;
#define FREE_RESOURCE(p) if(p->Common & 0x01000000){ /*D3DCREATED*/\
refcount = p->Release();\
}else{\
D3D_FreeContiguousMemory((void*)(p->Data | 0x80000000));\
delete p;\
}
if(DxTexture){
DxTexture->BlockUntilNotBusy();
FREE_RESOURCE(DxTexture);
}
if(DxRenderTexture){
DxRenderTexture->BlockUntilNotBusy();
FREE_RESOURCE(DxRenderTexture);
}
if(DxLockedSurface){
DxLockedSurface->BlockUntilNotBusy();
FREE_RESOURCE(DxLockedSurface);
}
#else
SAFERELEASE(DxTexture);
SAFERELEASE(DxRenderTexture);
SAFERELEASE(DxLockedSurface);
#endif
}
} CKDX8TextureDesc;
/********************************************
Same override for vertex buffers
*************************************************/
typedef struct CKDX8VertexBufferDesc : public CKVertexBufferDesc
{
public:
LPDIRECT3DVERTEXBUFFER8 DxBuffer;
public:
CKDX8VertexBufferDesc() {
DxBuffer=NULL;
}
~CKDX8VertexBufferDesc() {
#ifdef _XBOX
int refcount = 0;
if(DxBuffer){
BYTE* Data=NULL;
DxBuffer->Lock(0,0,(LPBYTE*)&Data,0);
DxBuffer->Unlock();
refcount = DxBuffer->Release();
}
if(refcount)
int j = 0;
#else
SAFERELEASE(DxBuffer);
#endif
}
} CKDX8VertexBufferDesc;
/********************************************
Same override for index buffers
*************************************************/
typedef struct CKDX8IndexBufferDesc : public CKIndexBufferDesc
{
public:
LPDIRECT3DINDEXBUFFER8 DxBuffer;
public:
CKDX8IndexBufferDesc() { DxBuffer=NULL; }
~CKDX8IndexBufferDesc() {
#ifdef _XBOX
int refcount = 0;
if(DxBuffer){
BYTE* Data=NULL;
DxBuffer->Lock(0,0,(LPBYTE*)&Data,0);
DxBuffer->Unlock();
refcount = DxBuffer->Release();
}
if(refcount)
int j = 0;
#else
SAFERELEASE(DxBuffer);
#endif
}
} CKDX8IndexBufferDesc;
/********************************************
Vertex Shaders....
*************************************************/
typedef struct CKDX8VertexShaderDesc : public CKVertexShaderDesc
{
public:
CKDWORD DxShader;
CKDX8RasterizerContext* Owner;
XArray<BYTE> m_FunctionData;
public:
BOOL Create(CKDX8RasterizerContext* Ctx,CKVertexShaderDesc* Format);
virtual ~CKDX8VertexShaderDesc();
CKDX8VertexShaderDesc() { DxShader = 0; Owner = 0; }
} CKDX8VertexShaderDesc;
/********************************************
Pixel Shaders....
*************************************************/
typedef struct CKDX8PixelShaderDesc : public CKPixelShaderDesc
{
public:
CKDWORD DxShader;
CKDX8RasterizerContext* Owner;
public:
BOOL Create(CKDX8RasterizerContext* Ctx,CKDWORD* Function);
virtual ~CKDX8PixelShaderDesc();
CKDX8PixelShaderDesc() { DxShader = 0; Owner = 0; }
} CKDX8PixelShaderDesc;
/*****************************************************************
CKDX8RasterizerContext override
******************************************************************/
class CKDX8RasterizerContext : public CKRasterizerContext
{
friend class RCKRenderContext;
public:
//--- Construction/destruction
CKDX8RasterizerContext(CKDX8RasterizerDriver* Driver);
virtual ~CKDX8RasterizerContext();
//--- Creation
virtual BOOL Create(WIN_HANDLE Window,int PosX=0,int PosY=0,int Width=0,int Height=0,int Bpp=-1,BOOL Fullscreen=0,int RefreshRate=0,int Zbpp=-1,int StencilBpp=-1);
virtual BOOL IsLost();
//---
virtual BOOL Resize(int PosX=0,int PosY=0,int Width=0,int Height=0,CKDWORD Flags=0);
virtual BOOL Clear(CKDWORD Flags=CKRST_CTXCLEAR_ALL,CKDWORD Ccol=0,float Z=1.0f,CKDWORD Stencil=0,int RectCount=0,CKRECT* rects=NULL);
virtual BOOL BackToFront();
//--- Scene
virtual BOOL BeginScene();
virtual BOOL EndScene();
//--- Lighting & Material States
virtual BOOL SetLight(CKDWORD Light,CKLightData* data);
virtual BOOL EnableLight(CKDWORD Light,BOOL Enable);
virtual BOOL SetMaterial(CKMaterialData* mat);
//--- Viewport State
virtual BOOL SetViewport(CKViewportData* data);
//--- Transform Matrix
virtual BOOL SetTransformMatrix(VXMATRIX_TYPE Type,const VxMatrix& Mat);
//--- Render states
virtual BOOL SetRenderState(VXRENDERSTATETYPE State,CKDWORD Value) ;
virtual BOOL GetRenderState(VXRENDERSTATETYPE State,CKDWORD* Value);
//--- Texture States
virtual BOOL SetTexture(CKDWORD Texture,int Stage=0);
virtual BOOL SetTextureStageState(int Stage,CKRST_TEXTURESTAGESTATETYPE Tss,CKDWORD Value);
//--- Vertex & Pixel shaders
virtual BOOL SetVertexShader(CKDWORD VShaderIndex);
virtual BOOL SetPixelShader(CKDWORD PShaderIndex);
virtual BOOL SetVertexShaderConstant(CKDWORD Register,const void* Data,CKDWORD CstCount);
virtual BOOL SetPixelShaderConstant(CKDWORD Register,const void* Data,CKDWORD CstCount);
//--- Drawing
virtual BOOL DrawPrimitive(VXPRIMITIVETYPE pType,WORD* indices,int indexcount,VxDrawPrimitiveData* data);
virtual BOOL DrawPrimitiveVB(VXPRIMITIVETYPE pType,CKDWORD VertexBuffer,CKDWORD StartIndex,CKDWORD VertexCount,WORD* indices=NULL,int indexcount=NULL);
virtual BOOL DrawPrimitiveVBIB(VXPRIMITIVETYPE pType,CKDWORD VB,CKDWORD IB,CKDWORD MinVIndex,CKDWORD VertexCount,CKDWORD StartIndex,int Indexcount);
//--- Creation of Textures, Sprites and Vertex Buffer
virtual BOOL CreateObject(CKDWORD ObjIndex,CKRST_OBJECTTYPE Type,void* DesiredFormat);
//--- Vertex Buffers
virtual void* LockVertexBuffer(CKDWORD VB,CKDWORD StartVertex,CKDWORD VertexCount,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT);
virtual BOOL UnlockVertexBuffer(CKDWORD VB);
//--- Textures
virtual BOOL LoadCubeMapTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,CKRST_CUBEFACE Face,int miplevel=-1);
virtual BOOL LoadTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,int miplevel=-1);
virtual BOOL CopyToTexture(CKDWORD Texture,VxRect* Src,VxRect* Dest,CKRST_CUBEFACE Face = CKRST_CUBEFACE_XPOS );
//--- Sprites
virtual BOOL DrawSprite(CKDWORD Sprite,VxRect* src,VxRect* dst);
//--- For web content the render context can be transparent (no clear of backbuffer but instead
//--- a copy of what is currently on screen)
#ifndef _XBOX
virtual void SetTransparentMode(BOOL Trans);
virtual void RestoreScreenBackup();
#endif
virtual void* GetImplementationSpecificData() { return &m_DirectXData; }
//--- Utils
virtual int CopyToMemoryBuffer(CKRECT* rect,VXBUFFER_TYPE buffer,VxImageDescEx& img_desc);
virtual int CopyFromMemoryBuffer(CKRECT* rect,VXBUFFER_TYPE buffer,const VxImageDescEx& img_desc);
//-- Sets the rendering to occur on a texture (reset the texture format to match )
virtual BOOL SetTargetTexture(CKDWORD TextureObject,int Width = 0, int Height = 0,CKRST_CUBEFACE Face = CKRST_CUBEFACE_XPOS , BOOL GenerateMipMap = FALSE);
virtual BOOL SetUserClipPlane(CKDWORD ClipPlaneIndex,const VxPlane& PlaneEquation);
virtual BOOL GetUserClipPlane(CKDWORD ClipPlaneIndex,VxPlane& PlaneEquation);
virtual void* LockIndexBuffer(CKDWORD IB,CKDWORD StartIndex,CKDWORD IndexCount,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT);
virtual BOOL UnlockIndexBuffer(CKDWORD IB);
//---------------------------------------------------------------------
//---- New methods to lock video memory (DX only)
virtual BOOL LockTextureVideoMemory(CKDWORD Texture,VxImageDescEx& Desc,int MipLevel = 0,VX_LOCKFLAGS Flags = VX_LOCK_DEFAULT);
virtual BOOL UnlockTextureVideoMemory(CKDWORD Texture,int MipLevel = 0);
//---- To Enable more direct creation of system objects without
//---- CK2_3D holding a copy of the texture
virtual BOOL CreateTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param);
virtual BOOL CreateTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param);
virtual BOOL CreateCubeTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param);
virtual BOOL CreateCubeTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param);
virtual BOOL CreateVolumeTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param);
virtual BOOL CreateVolumeTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param);
virtual BOOL LoadVolumeMapTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,DWORD Depth,int miplevel);
virtual void EnsureVBBufferNotInUse(CKVertexBufferDesc* desc);
virtual void EnsureIBBufferNotInUse(CKIndexBufferDesc* desc);
virtual float GetSurfacesVideoMemoryOccupation(int* NbTextures,int* NbSprites,float* TextureSize,float* SpriteSize);
#ifdef _XBOX
void SetViewZone(const VxRect& Zone);
BOOL DrawSolidRect(const VxRect& Zone,DWORD Color);
BOOL CreateTextureFromXpr(CKDWORD Texture,const char* Filename,TexFromFile* param);
BOOL CreateTextureFromXprInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param);
#endif
protected:
//-----------------------
void UpdateDirectXData();
BOOL InternalDrawPrimitiveVB(VXPRIMITIVETYPE pType,CKDX8VertexBufferDesc* VB,CKDWORD StartIndex,CKDWORD VertexCount,WORD* indices,int indexcount,BOOL Clip);
void SetupStreams(LPDIRECT3DVERTEXBUFFER8 Buffer,CKDWORD VFormat,CKDWORD VSize);
//--- Objects creation
BOOL CreateTexture(CKDWORD Texture,CKTextureDesc* DesiredFormat);
BOOL CreateVertexShader(CKDWORD VShader,CKVertexShaderDesc* DesiredFormat);
BOOL CreatePixelShader(CKDWORD PShader,CKPixelShaderDesc* DesiredFormat);
BOOL CreateVertexBuffer(CKDWORD VB,CKVertexBufferDesc* DesiredFormat);
BOOL CreateIndexBuffer(CKDWORD IB,CKIndexBufferDesc* DesiredFormat);
//---- Cleanup
void FlushNonManagedObjects();
void ReleaseIndexBuffers();
void ClearStreamCache();
void ReleaseScreenBackup();
void ResetDevice();
CKDWORD DX8PresentInterval(DWORD PresentInterval);
#ifdef _NOD3DX
BOOL LoadSurface(const D3DSURFACE_DESC& ddsd,const D3DLOCKED_RECT& LockRect,const VxImageDescEx& SurfDesc);
#endif
public:
//--- Temp Z-Buffers for texture rendering...
void ReleaseTempZBuffers() {
for (int i=0;i<256;++i) {
SAFELASTRELEASE(m_TempZBuffers[i]);
}
}
LPDIRECT3DSURFACE8 GetTempZBuffer(int Width,int Height);
LPDIRECT3DDEVICE8 m_Device;
D3DPRESENT_PARAMETERS m_PresentParams;
VxDirectXData m_DirectXData;
BOOL m_SoftwareVertexProcessing;
BOOL m_SoftwareShader;
//----------------------------------------------------
//--- Index buffer filled when drawing primitives
CKDX8IndexBufferDesc* m_IndexBuffer[2]; // Clip/unclipped
//-----------------------------------------------------
//--- Render Target if rendering is redirected to a texture
LPDIRECT3DSURFACE8 m_DefaultBackBuffer; // Backup pointer of previous back buffer
LPDIRECT3DSURFACE8 m_DefaultDepthBuffer; // Backup pointer of previous depth buffer
volatile BOOL m_InCreateDestroy;
//--- For web content the render context can be transparent (no clear of backbuffer but instead
//--- a copy of what is currently on screen)
LPDIRECT3DSURFACE8 m_ScreenBackup;
//-------------------------------------------------
//--- to avoid redoundant calls to SetVertexShader & SetStreamSource :
//--- a cache with the current vertex format and source VB
CKDWORD m_CurrentVertexShaderCache;
CKDWORD m_CurrentVertexFormatCache;
LPDIRECT3DVERTEXBUFFER8 m_CurrentVertexBufferCache;
CKDWORD m_CurrentVertexSizeCache;
//--------------------------------------------------
// Render states which must be disabled or which values must be translated...
CKDWORD* m_TranslatedRenderStates[VXRENDERSTATE_MAXSTATE];
//-----------------------------------------------------
// + To do texture rendering, Z-buffers are created when
// needed for any given size (power of two)
// These Z buffers are stored in the rasterizer context
// TempZbuffers array and are attached when doing
// texture rendering
LPDIRECT3DSURFACE8 m_TempZBuffers[256];
#ifdef _XBOX
VxRect m_ViewZone;
CKViewportData m_DeviceViewport;
int m_RealWidth;
int m_RealHeight;
DWORD m_StageTextureInfo;
VxMatrix m_TextureScaleMatrix[4];
VxMatrix m_TextureMatrix[4];
#endif
};
#ifdef _XBOX
#define STAGE_LINEAR_MASK 0x0000000f
#define STAGE_YUV_MASK 0x000000f0
#define STAGE_YUV_DECAL 4
#define IS_STAGE_LINEAR(stage) (m_StageTextureInfo&(1<<stage))
#define SET_STAGE_LINEAR(stage) (m_StageTextureInfo|=(1<<stage))
#define REMOVE_STAGE_LINEAR(stage) (m_StageTextureInfo&=~(1<<stage))
#define IS_STAGE_YUV(stage) (m_StageTextureInfo& ((1<<stage)<<STAGE_YUV_DECAL))
#define SET_STAGE_YUV(stage) (m_StageTextureInfo |=((1<<stage)<<STAGE_YUV_DECAL))
#define REMOVE_STAGE_YUV(stage) (m_StageTextureInfo &=~((1<<stage)<<STAGE_YUV_DECAL))
#endif
/*****************************************************************
CKDX8RasterizerDriver overload
******************************************************************/
class CKDX8RasterizerDriver : public CKRasterizerDriver
{
public:
CKDX8RasterizerDriver(CKDX8Rasterizer* rst);
virtual ~CKDX8RasterizerDriver();
//--- Contexts
virtual CKRasterizerContext* CreateContext();
BOOL InitializeCaps(int AdapterIndex);
BOOL IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat );
D3DFORMAT FindNearestTextureFormat(CKTextureDesc* desc);
D3DFORMAT FindNearestRenderTargetFormat(int Bpp,BOOL Windowed);
D3DFORMAT FindNearestDepthFormat(D3DFORMAT pf,int ZBpp,int StencilBpp);
public:
BOOL m_Inited;
UINT m_AdapterIndex;
D3DCAPS8 m_D3DCaps;
D3DADAPTER_IDENTIFIER8 m_D3DIdentifier;
XArray<D3DFORMAT> m_RenderFormats;
BOOL m_IsHTL; // Transfom & Lighting
};
/*****************************************************************
CKDX8Rasterizer overload
******************************************************************/
class CKDX8Rasterizer : public CKRasterizer
{
public:
CKDX8Rasterizer();
virtual ~CKDX8Rasterizer();
virtual BOOL Start(WIN_HANDLE AppWnd);
virtual void Close(void);
public:
BOOL m_Init;
LPDIRECT3D8 m_D3D8;
// Stage Blends
void InitBlendStages();
CKStageBlend* m_BlendStages[256];
};
#endif