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

990 lines
43 KiB
C++
Raw Permalink Blame History

/*************************************************************************/
/* File : CKRasterizer.h */
/* Author : Romain Sididris */
/* */
/* + Base classes declaration for rasterizers */
/* The default implementation of the render engine in Virtools use */
/* rasterizers as a common interface to acces a rendering device. */
/* */
/* + A Rasterizer DLL must provide the implemenation for the 3 base */
/* classes by overloading them: */
/* - CKRasterizer: Top level class (One instance per rasterizer) */
/* which upon creation should check for availables drivers. */
/* */
/* - CKRasterizerDriver: One instance should be created for each */
/* available driver (ie graphic card,software,hardware,etc.). It is */
/* used to store capabilities and create rendering contextes */
/* */
/* - CKRasterizerContext: A rendering context with all the methods */
/* to create/load textures, setup lights,materials,render states */
/* and draw primitives. */
/* Many of these methods are similar to DirectX structures */
/* */
/* */
/* */
/* + Some methods of these classes are already implemented in the */
/* CKRasterizerLib library as they are common to all rasterizers */
/* */
/* Virtools SDK */
/* Copyright (c) Virtools 2002, All Rights Reserved. */
/*************************************************************************/
#ifndef CKRASTERIZER_H
#define CKRASTERIZER_H "$Id:$"
#include "VxDefines.h"
#include "XString.h"
#include "XArray.h"
#include "CKRasterizerEnums.h"
#include "CKRasterizerTypes.h"
#include "CKDefines2.h"
#include <float.h>
/**********************************************************
The render engine will call the CKRasterizerGetInfo function (see below)
to gain acces to rasterizer information. This information should be
stored in CKRasterizerInfo structure.
***********************************************************/
struct CKRasterizerInfo {
XString DllName; // Filled by the render engine when parsing Dlls
XString Desc; // Description for this rasterizer (eg: "Open GL Rasterizer")
INSTANCE_HANDLE DllInstance;// Filled by the render engine when loading the DLL
CKRST_STARTFUNCTION StartFct; // A pointer to a function that will create the CKRasterizer Instance
CKRST_CLOSEFUNCTION CloseFct; // A pointer to a function that will destroy the CKRasterizer Instance
CKRST_OPTIONFCT OptionFct;
CKRasterizerInfo() {
DllInstance =NULL;
StartFct =NULL;
CloseFct =NULL;
OptionFct =NULL;
}
};
/*******************************************
+ There is only one function a rasterizer Dll is supposed
to export :"CKRasterizerGetInfo", it will be used by the render engine
to retrieve information about the plugin :
- Description
******************************************/
typedef void (*CKRST_GETINFO)(CKRasterizerInfo*);
// secret
#ifdef _XBOX
#define MAX_FRAMES_AHEAD 3
#else
#define MAX_FRAMES_AHEAD 3
#endif
/****************************************************************
Main class for rasterizer declaration
+ A render engine is started by calling CKRasterizerStart which will try
to create a CKRasterizer object and to initialize it.
+ It will enumerate and create the available drivers on the system.
+ If no driver for 3D rendering is available the function should fail and return NULL.
+ The CKRasterizer object is only used to
- generate texture,sprites and vertex buffer index
( which are simple CKDWORDs to identify a texture or VB across differents contexts or drivers ).
- acces the list of available driver
+ Several rasterizers can work together in which case texture indices should be the same across
them. Each rasterizer must warn the others of its existence through LinkRasterizer
(It is automatically called by the render engine upon registration of the rasterizers)
****************************************************************/
class CKRasterizer
{
public:
CKRasterizer();
virtual ~CKRasterizer();
//---- Initialisation/Destruction
virtual BOOL Start(WIN_HANDLE AppWnd);
virtual void Close(void) { }
//--- Available drivers access
virtual int GetDriverCount() { return m_Drivers.Size(); }
virtual CKRasterizerDriver* GetDriver(CKDWORD index) { return m_Drivers[index]; }
//--- Texture,Sprite,Vertex buffer Index Creation (Implemented by Lib)
//--- (Index are shared amongst all contexts
virtual CKDWORD CreateObjectIndex(CKRST_OBJECTTYPE Type,BOOL WarnOthers=TRUE);
virtual BOOL ReleaseObjectIndex(CKDWORD ObjectIndex,CKRST_OBJECTTYPE Type,BOOL WarnOthers=TRUE);
//--- Implemented by lib : keep a track of other rasterizers
void LinkRasterizer(CKRasterizer* rst);
void RemoveLinkedRasterizer(CKRasterizer* rst);
//--- A Mutex so that rasterizers can synchronize on critical data access
//--- or NULL is no synchroniztion is needed
void SetMutex(VxMutex* mutex) { m_Mutex = mutex; }
//--- A pointer to a function that will get called each time a
// event is launched by a rasterizer context....
void SetEventWatcher(CKRST_EVENTFUNCTION fct,void* argument) { m_EventWatcher = fct; m_EventArgument = argument; }
//----- Buggy driver information
BOOL LoadVideoCardFile(const char* FileName);
CKDriverProblems* FindDriverProblems(const XString& Vendor,const XString& Renderer,const XString& Version,const XString& DeviceDesc,int Bpp);
public:
CKRasterizerContext* m_FullscreenContext; // If a context is currently fullscreen...
XSArray<BYTE> m_ObjectsIndex; // A List of byte mask to keep track of the existing object
CKDWORD m_FirstFreeIndex[8]; // First Free Index for each type of objects...
// indexes (textures,sprites,VBs)
XSArray<CKRasterizer*> m_OtherRasterizers; // The list of other rasterizers..
WIN_HANDLE m_MainWindow; // Application main window used to preform initialisations
XClassArray<CKDriverProblems> m_ProblematicDrivers; // List of driver with identified problems
XArray<CKRasterizerDriver*> m_Drivers;
VxMutex* m_Mutex;
CKRST_EVENTFUNCTION m_EventWatcher;
void* m_EventArgument;
// Implementation specific data to follow....
};
/****************************************************************
+ Once a rasterizer is created and started it enumerates all availables drivers
depending on the number of graphic adapters installed and their
different implementation (Hardware,software,Hardware Transform & Lighting,etc...)
+ Once a driver is chosen (according to its capabilities for example) it can be use
to create one more contexts for drawing (see CreateContext and CKRasterizerContext)
****************************************************************/
class CKRasterizerDriver
{
public:
CKRasterizerDriver(CKRasterizer* Owner);
virtual ~CKRasterizerDriver();
//--- Contexts creation
virtual CKRasterizerContext* CreateContext();
virtual BOOL DestroyContext(CKRasterizerContext* Context);
// See if a given texture format is supported
virtual BOOL FindTextureFormat(VX_PIXELFORMAT format) const;
public:
void InitNULLRasterizerCaps();
BOOL m_Hardware; // Hardware accelerated driver ?
BOOL m_CapsUpToDate; // Driver Capabilities are up to date ?
CKRasterizer* m_Owner; // Owner CKRasterizer object
CKDWORD m_DriverIndex; // Index of this driver in the Rasterizer List of drivers
XArray<VxDisplayMode> m_DisplayModes; // List of availables display modes
XClassArray<CKTextureDesc> m_TextureFormats; // List of availables texture formats
Vx3DCapsDesc m_3DCaps; // 3D capabilities
Vx2DCapsDesc m_2DCaps; // 2D capabilities
XString m_Desc; // Description string
XArray<CKRasterizerContext*> m_Contexts; // Currently created render contextes
BOOL m_Stereo; // Support steroscopic ?
};
/***************************************************
Utility : Convert the attenuation factors from DX5 model
A(d) = a0+ a1.(1-d/R) + a2.(1-d/R)<29>
to DX7 or GL attenuation model
A(d) = 1/(a0 + a1.d + a2.d<>)
( The result is not exactly the same :(
*******************************************************/
inline void ConvertAttenuationModelFromDX5(float& _a0,float& _a1,float& _a2,float range)
{
float a0=(_a0 + _a1 + _a2 == 0.f) ? FLT_MAX : (1/(_a0+_a1+_a2));
float a1= (range == 0.f) ? FLT_MAX : (a0*a0*(_a1+2*_a2)/range);
float a2= (range == 0.f) ? FLT_MAX : ((a1*a1)/a0) + a0*a0*_a2/(range*range);
_a0= a0;
_a1= a1;
_a2= a2;
}
/***************************************************
Utility : From a given DrawprimitiveDataStructure :
returns the corresponding Vertex Buffer Format (CKRST_VERTEXFORMAT) and the
size of a vertex...
*******************************************************/
CKDWORD CKRSTGetVertexFormat(CKRST_DPFLAGS DpFlags,CKDWORD& VertexSize);
/***************************************************
Utility : From a given CKRST_VERTEXFORMAT format :
returns the corresponding size of a vertex...
*******************************************************/
CKDWORD CKRSTGetVertexSize(CKDWORD VertexFormat);
/**************************************************
Copy the content of a DrawPrimitive Data structure inside
a Vertex Buffer memory buffer ( must have been obtained by a call to Lock)
No Assumption or tests are made to check the coherence between the vertex format
and the incoming data
returns the new location of the current VBuffer memory pointer
To use in coordination with LockVertexBuffer
*****************************************************/
BYTE* CKRSTLoadVertexBuffer(BYTE* VBMem,CKDWORD VFormat,CKDWORD VSize,VxDrawPrimitiveData* data);
/**************************************************
Copy the content of a DrawPrimitive Data structure inside
another using the destination structure vertex count and
flags to take decision...
To use in coordination with LockVertexBuffer2
*****************************************************/
void CKRSTLoadVertexBuffer2(VxDrawPrimitiveData* Dest,VxDrawPrimitiveData* Src);
/**************************************************
Setup the DpData structure (data pointers and stride only) according
the DpData.Flags and VBMem pointer...
*****************************************************/
void CKRSTSetupDPFromVertexBuffer(BYTE* VBMem,CKVertexBufferDesc* VB,VxDrawPrimitiveData& DpData);
/**************************************************
When using CKRSTLoadVertexBuffer2 or CKRSTLoadVertexBuffer
vertex can be scaled by a given factor..
*****************************************************/
void SetRSTVertexScaling(const VxVector4& scale);
void SetRSTVertexOffset(const VxVector4& scale);
void SetRSTVertexUVScaling(int stage,const Vx2DVector& scale);
/****************************************************************
+ A context is used to identify where the rendering take place and
to specify how primitives should be drawn.
+ A context is created by its driver, either fullscreen or windowed.
+ A context is also used to create textures,sprites or vertex buffer
and to load their content. When accessing to textures, sprites or vertex buffer
one must use an index identifying the object, this object must have been
created previously by CKRasterizer::CreateObjectIndex() (CKRST_OBJ_TEXTURE,CKRST_OBJ_SPRITE or
CKRST_OBJ_VERTEXBUFFER). The object index is shared across all rasterizer object
so there is no need to recreate it when destroying/creating contextes
+ Several methods are here to set the diferent parameters of the render
engine : Lighting states( Material and Light), Viewport States,
Transformation states, Render States and Texture Stage States
****************************************************************/
class CKRasterizerContext
{
public:
//--- Construction/destruction
CKRasterizerContext(CKRasterizerDriver* Driver);
virtual ~CKRasterizerContext();
//--- Creation (destruction is done by deleting the context CKRasterizerDriver::DestroyContext)
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) { return TRUE; }
virtual BOOL IsLost() {return FALSE;}
//---
virtual BOOL Resize(int PosX=0,int PosY=0,int Width=0,int Height=0,CKDWORD Flags=0) { return TRUE; }
virtual BOOL Clear(CKDWORD Flags=CKRST_CTXCLEAR_ALL,CKDWORD Ccol=0,float Z=1.0f,CKDWORD Stencil=0,int RectCount=0,CKRECT* rects=NULL) { return FALSE; }
virtual BOOL BackToFront() { return FALSE; }
//------------------------------------------------------
//--- Starting/stopping primitive drawing
virtual BOOL BeginScene();
virtual BOOL EndScene();
//----------------------------------------------------
//--- Lighting & Material States
virtual BOOL SetLight(CKDWORD LightIndex,CKLightData* data) { if (data && LightIndex<RST_MAX_LIGHT) m_CurrentLightData[LightIndex] = *data; return FALSE; }
virtual BOOL EnableLight(CKDWORD LightIndex,BOOL Enable) { return FALSE; }
virtual BOOL SetMaterial(CKMaterialData* mat);
//-----------------------------------------------------
//--- Viewport size and position
virtual BOOL SetViewport(CKViewportData* data);
//--- Scissor test rectangle. Please note that setting a new render texture reset the scissor.
// Passing NULL as the scissor rect will extends the scissor to the whole render target
virtual BOOL SetScissorRect(const CKRECT* rect);
const CKRECT& GetScissorRect() { return m_ScissorRect; }
// Get extent of the current render target
void GetRenderTargetSize(int &width, int &height) const;
//--- Transformaion Matrix (World,View or projection )
virtual BOOL SetTransformMatrix(VXMATRIX_TYPE Type,const VxMatrix& Mat);// (default Implementation by Lib)
//----------------------------------------------------------
//--- Rendering states
// To avoid redondant render state calls,a render state cache can be used by
// implementation of CKRasterizerContext by first calling CKRasterizerContext::InternalSetRenderState() before
// actually setting the render state (implmented in .h file to be inlined in implementations)
virtual BOOL SetRenderState(VXRENDERSTATETYPE State,CKDWORD Value) { return InternalSetRenderState(State,Value); }
virtual BOOL GetRenderState(VXRENDERSTATETYPE State,CKDWORD* Value) { return InternalGetRenderState(State,Value); }
//-------------------------------------------------------------
//--- Texture States control the texture and its aspects (filtering, etc.)
//--- Set the current texture to be used for rendering (0 if no texturing)
virtual BOOL SetTexture(CKDWORD Texture,int Stage=0){ return FALSE; }
virtual BOOL SetTextureStageState(int Stage,CKRST_TEXTURESTAGESTATETYPE Tss,CKDWORD Value){
return InternalSetTextureState(Stage,Tss,Value); }
// This resets all the currently set texture stages
virtual void DisableAllTextureStages(); // (Implementated by Lib)
//-------------------------------------------------------------
//--- Vertex & pixel shaders are created as textures and sprites
//--- calling these functions with 0 as argument disables the
//--- usage of programmable shaders and uses the default pipeline
virtual BOOL SetVertexShader(CKDWORD VShaderIndex) { return FALSE; }
virtual BOOL SetPixelShader(CKDWORD PShaderIndex) { return FALSE; }
virtual BOOL SetVertexShaderConstant(CKDWORD Register,const void* Data,CKDWORD CstCount) { return FALSE; }
virtual BOOL SetPixelShaderConstant(CKDWORD Register,const void* Data,CKDWORD CstCount) { return FALSE; }
//----------------------------------------------------------------
//--- Primitive Drawing (From system memory data or Vertex buffer)
// At least a system memory (DrawPrimitive) version must be supported by an implementation
virtual BOOL DrawPrimitive(VXPRIMITIVETYPE pType,WORD* indices,int indexcount,VxDrawPrimitiveData* data){ return FALSE; }
virtual BOOL DrawPrimitiveVB(VXPRIMITIVETYPE pType,CKDWORD VertexBuffer,CKDWORD StartIndex,CKDWORD VertexCount,WORD* indices=NULL,int indexcount=NULL);// (Default Implementation by Lib)
virtual BOOL DrawPrimitiveVBIB(VXPRIMITIVETYPE pType,CKDWORD VB,CKDWORD IB,CKDWORD MinVIndex,CKDWORD VertexCount,CKDWORD StartIndex,int Indexcount);// (Default Implementation by Lib)
//-------------------------------------------------------------
//--- Creation of Textures, Sprites and Vertex Buffer
//--- Once an object index exists and before it can be used a texture,sprite or VB
//--- must be created with this method, The Desired format pointer must point to
//--- a CKTextureDesc , CKSpriteDesc , CKVertexBufferDesc ,CKIndexBufferDesc structure according to
//--- the type of object being created...
virtual BOOL CreateObject(CKDWORD ObjIndex,CKRST_OBJECTTYPE Type,void* DesiredFormat); // (Default Implementation by Lib)
virtual BOOL DeleteObject(CKDWORD ObjIndex,CKRST_OBJECTTYPE Type); // (Implemented by Lib)
virtual BOOL FlushObjects(CKDWORD TypeMask); // (Implemented by Lib)
virtual void UpdateObjectArrays(CKRasterizer* rst,CKDWORD ObjMasks = CKRST_OBJ_ALL); // (Implemented by Lib)
//-------------------------------------------------------------
//--- Textures
virtual BOOL LoadTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,int miplevel=-1) { return FALSE; }
virtual CKTextureDesc* GetTextureData(CKDWORD Texture); // (Implemented by Lib)
//--- Copy the content of this context to a texture
virtual BOOL CopyToTexture(CKDWORD Texture,VxRect* Src,VxRect* Dest,CKRST_CUBEFACE Face = CKRST_CUBEFACE_XPOS )
{ return FALSE; }
//--- Try to set a texture as the target for rendering
virtual BOOL SetTargetTexture(CKDWORD TextureObject,int Width = 0, int Height = 0,CKRST_CUBEFACE Face = CKRST_CUBEFACE_XPOS , BOOL GenerateMipMap = FALSE) { return FALSE; }
//-------------------------------------------------------------
//--- Sprites
virtual BOOL LoadSprite(CKDWORD Sprite,const VxImageDescEx& SurfDesc); // (Implemented by Lib)
virtual CKSpriteDesc* GetSpriteData(CKDWORD Sprite); // (Implemented by Lib)
//-- Draw the sprite on the context using the given source and destination rectangles
virtual BOOL DrawSprite(CKDWORD Sprite,VxRect* src,VxRect* dst){ return FALSE; }
//-------------------------------------------------------------
//--- Vertex Buffers
virtual void* LockVertexBuffer(CKDWORD VB,CKDWORD StartVertex,CKDWORD VertexCount,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT); // (default Implementation by Lib)
virtual BOOL UnlockVertexBuffer(CKDWORD VB); // (default Implementation by Lib)
virtual CKVertexBufferDesc* GetVertexBufferData(CKDWORD VB); // (Implemented by Lib)
virtual BOOL OptimizeVertexBuffer(CKDWORD VB) { return FALSE; }
//-------------------------------------------------------------
//--- Copy the content of this rendering context to a memory buffer (CopyToMemoryBuffer)
//--- or Updates this rendering context with the content of a memory buffer (CopyFromMemoryBuffer)
virtual int CopyToMemoryBuffer(CKRECT* rect,VXBUFFER_TYPE buffer,VxImageDescEx& img_desc) { return 0; }
virtual int CopyFromMemoryBuffer(CKRECT* rect,VXBUFFER_TYPE buffer,const VxImageDescEx& img_desc) { return 0; }
//-------------------------------------------------------------
//--- Each implementation can return here a pointer
//--- to a structure containing its specific data
virtual void* GetImplementationSpecificData() { return NULL; }
//-----------------------------------------------------------------
//--- Transform a set of vertices using the current transformation matrices
//--- from a local coordinate system to screen and/or homogenous coordinates
//--- (Implemented by Lib)
virtual BOOL TransformVertices(int VertexCount,VxTransformData* Data);
//-----------------------------------------------------------------
//--- Computes the visibility of a box in the current viewport
//--- and also computes its screen extents if asked.
//--- (Implemented by Lib)
virtual CKDWORD ComputeBoxVisibility(const VxBbox& box,BOOL World=FALSE,VxRect* extents=NULL);
//-----------------------------------------------------------------
//--- When using threads one must warn the context before/after using its methods of the active calling thread.
//--- (mainly for OpenGL implementation to work correctly on multi-thread applications)
virtual BOOL WarnThread(BOOL Enter) {return FALSE; }
//-----------------------------------------------------------------
//--- For web content the render context can be transparent (no clear of backbuffer but instead
//--- a copy of what is currently on screen)
//--- The AddDirtyrect method warns the context that a rectangle had been redrawn
//--- and should be updated (NULL to update the entire backbuffer)
virtual void SetTransparentMode(BOOL Trans) { m_TransparentMode = Trans; }
virtual void AddDirtyRect(CKRECT* Rect) { if (!Rect) m_CleanAllRects = TRUE; else m_DirtyRects.PushBack(*Rect); }
virtual void RestoreScreenBackup() {}
//-----------------------------------------------------------------
//--- maxanisotropy set - to limit max value, return value = value really set
virtual DWORD SetMaxAnisotropy(DWORD iMaxAnisotropy) {return 2;}
//-----------------------------------------------------------------
//--- User Clip Plane Function
virtual BOOL SetUserClipPlane(CKDWORD ClipPlaneIndex,const VxPlane& PlaneEquation) {return FALSE;}
virtual BOOL GetUserClipPlane(CKDWORD ClipPlaneIndex,VxPlane& PlaneEquation) {return FALSE;}
//--------------------------------------------------------------
// Each rasterizer context
virtual void InitDefaultRenderStatesValue();
//--------- Load a cubemap texture face
virtual BOOL LoadCubeMapTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,CKRST_CUBEFACE Face,int miplevel=-1) { return FALSE; }
//--------- For rasteriszer that supports stereo rendering (OpenGL)
// set the buffer on which next drawing operations should occur
virtual BOOL SetDrawBuffer(CKRST_DRAWBUFFER_FLAGS Flags) { return FALSE; }
//-------------------------------------------------------------
//--- Index Buffers
virtual void* LockIndexBuffer(CKDWORD IB,CKDWORD StartIndex,CKDWORD IndexCount,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT); // (default Implementation by Lib)
virtual BOOL UnlockIndexBuffer(CKDWORD IB); // (default Implementation by Lib)
virtual CKIndexBufferDesc* GetIndexBufferData(CKDWORD IB); // (Implemented by Lib)
// Some implementations may not support call to lock with a single buffer return
// but prefer a VxDrawPrimitiveData to be filled with the pointers and stride of each elements...
// For every rasterizer that support the LockVertexBuffer version there is no need to override this method
// as the default implementation take care of everything
// Data.Flags & Data.VertexCount must be initialized correctly before calling...
virtual BOOL LockVertexBuffer2(CKDWORD VB,CKDWORD StartVertex,VxDrawPrimitiveData& Data,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT) {
BYTE* Memory = (BYTE *)LockVertexBuffer(VB,StartVertex,Data.VertexCount,Lock);
if (!Memory) return FALSE;
CKRSTSetupDPFromVertexBuffer(Memory,m_VertexBuffers[VB],Data);
return TRUE;
}
virtual BOOL DrawPrimitiveSharedVB(VXPRIMITIVETYPE pType,CKDWORD SVertexBuffer,CKDWORD StartIndex,CKDWORD VertexCount,WORD* indices=NULL,int indexcount=NULL);// (Default Implementation by Lib / or handled by the rasterizer eg OpenGL)
virtual BOOL DrawPrimitiveSharedVBIB(VXPRIMITIVETYPE pType,CKDWORD SVB,CKDWORD SIB,CKDWORD MinVIndex,CKDWORD VertexCount,CKDWORD StartIndex,int Indexcount);// (Default Implementation by Lib / or handled by the rasterizer eg OpenGL)
virtual BOOL LockSharedVB2(CKDWORD SVB,CKDWORD StartVertex,VxDrawPrimitiveData& Data,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT);
virtual BOOL UnlockSharedVB(CKDWORD SVB);
virtual CKSharedVBDesc* GetSharedVBData(CKDWORD SVB);
virtual void* LockSharedIB(CKDWORD SIB,CKDWORD StartIndex,CKDWORD IndexCount,CKRST_LOCKFLAGS Lock = CKRST_LOCK_DEFAULT);
virtual BOOL UnlockSharedIB(CKDWORD SIB);
virtual CKSharedIBDesc* GetSharedIBData(CKDWORD SIB);
//---------------------------------------------------------------------
//---- New methods to lock video memory
//---- either by giving a direct access to video buffer
virtual BOOL LockTextureVideoMemory(CKDWORD Texture,VxImageDescEx& Desc,int MipLevel = 0,VX_LOCKFLAGS Flags = VX_LOCK_DEFAULT) {return FALSE; }
virtual BOOL UnlockTextureVideoMemory(CKDWORD Texture,int MipLevel = 0) { return FALSE; }
// secret
struct TexFromFile {
VX_PIXELFORMAT pf;
int MipLevels;
CKDWORD ColorKey; // 0 : No Color Key, 0xFFRRGGBB (R,G,B) color Key
BOOL IsDynamic;
};
//---- To Enable more direct creation of system objects without
//---- CK2_3D holding a copy of the texture
// secret
virtual BOOL CreateTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param){return FALSE;}
// secret
virtual BOOL CreateTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param){return FALSE;}
// secret
virtual BOOL CreateCubeTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param){return FALSE;}
// secret
virtual BOOL CreateCubeTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param){return FALSE;}
// secret
virtual BOOL CreateVolumeTextureFromFile(CKDWORD Texture,const char* Filename,TexFromFile* param){return FALSE;}
// secret
virtual BOOL CreateVolumeTextureFromFileInMemory(CKDWORD Texture,void*mem,DWORD sz,TexFromFile* param){return FALSE;}
virtual BOOL LoadVolumeMapTexture(CKDWORD Texture,const VxImageDescEx& SurfDesc,DWORD Depth,int miplevel) {return FALSE;}
virtual void EnsureVBBufferNotInUse(CKVertexBufferDesc* desc);
virtual void EnsureIBBufferNotInUse(CKIndexBufferDesc* desc);
public:
//Default Lib implementation for Vertex,Index buffers (create them in system memory)
BOOL CreateVertexBuffer(CKDWORD VB,CKVertexBufferDesc* DesiredFormat);
BOOL CreateIndexBuffer(CKDWORD IB,CKIndexBufferDesc* DesiredFormat);
virtual BOOL CreateSharedVertexBuffer(CKDWORD VB,CKSharedVBDesc* DesiredFormat);
virtual BOOL CreateSharedIndexBuffer(CKDWORD IB,CKSharedIBDesc* DesiredFormat);
#ifndef PSP
virtual BOOL DrawPrimitive(VXPRIMITIVETYPE pType,DWORD* indices,int indexcount,VxDrawPrimitiveData* data); // (Default Implementation by Lib)
virtual BOOL DrawPrimitiveVB(VXPRIMITIVETYPE pType,CKDWORD VertexBuffer,CKDWORD StartIndex,CKDWORD VertexCount,DWORD* indices,int indexcount);// (Default Implementation by Lib)
virtual BOOL DrawPrimitiveSharedVB(VXPRIMITIVETYPE pType,CKDWORD SVertexBuffer,CKDWORD StartIndex,CKDWORD VertexCount,DWORD* indices,int indexcount);// (Default Implementation by Lib / or handled by the rasterizer eg OpenGL)
#endif
//Default Lib implementation for sprites (create them using sub-textures)
BOOL CreateSprite(CKDWORD Sprite,CKSpriteDesc* DesiredFormat);
//--- The complete projection matrix is not computed every time a transformation matrix is set...
// calling this function
void UpdateMatrices(CKDWORD Flags);
//-------------------------------------------------------------------------------
//--- Render state cache management (Implemented by Lib)
//--- in inline functions
//--- A rasterizer context implementation should always
//--- call these methods to maintain the render state cache
//--- which avoid redoundant render state calls
inline void FlushRenderStateCache();
inline void InvalidateStateCache(VXRENDERSTATETYPE State);
inline CKDWORD GetRSCacheValue(VXRENDERSTATETYPE State);
inline void LockRenderState(VXRENDERSTATETYPE State,BOOL Locked);
inline void DisableRenderState(VXRENDERSTATETYPE State,BOOL Disabled = TRUE);
inline void OverrideRenderState(VXRENDERSTATETYPE State,BOOL Overridden = TRUE);
inline BOOL InternalSetRenderState(VXRENDERSTATETYPE State,CKDWORD Value);
inline BOOL InternalGetRenderState(VXRENDERSTATETYPE State,CKDWORD* Value);
//--- Same cache management for texture stage states...
inline void FlushTextureStateCache();
inline void InvalidateTextureStateCache(int Stage,CKRST_TEXTURESTAGESTATETYPE State);
inline CKDWORD GetTSCacheValue(int Stage,CKRST_TEXTURESTAGESTATETYPE State);
inline void LockTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,BOOL Locked);
inline void DisableTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,BOOL Disabled = TRUE);
inline BOOL InternalSetTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,CKDWORD Value);
inline BOOL InternalGetTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,CKDWORD* Value);
inline void FlushCaches() {
FlushRenderStateCache();
FlushTextureStateCache();
memset(m_CurrentTextures,0,CKRST_MAX_STAGES * sizeof(CKTextureDesc*));
m_CurrentTextureValidBits = 0; // for a resetup of all textures
}
//---
void ResetDirtyRects() { m_CleanAllRects = FALSE; m_DirtyRects.Resize(0); }
//-------------- Dynamic Vertex buffers --------------
// This method will create a vertex buffer the first time it is called
// with a given vertex format and will later on returns this same
// vertex buffer so it can be used when drawing dynamic primitives
// the returned buffer that can be filled and render with DrawPrimitiveVB
// (Implemented by Lib)
// AddKey is a value that must be < 255 that can be used to have different
// dynamic vertex buffer with the same vertex format
CKDWORD GetDynamicVertexBuffer(CKDWORD VertexFormat,CKDWORD VertexCount,CKDWORD VertexSize,CKDWORD AddKey);
VxDrawPrimitiveData* DoIndexedVertexBlending(VxDrawPrimitiveData* data);
void LaunchEvent(CKRST_EVENTS iEvent) {
if (m_Owner && m_Owner->m_EventWatcher)
m_Owner->m_EventWatcher(this,iEvent,m_Owner->m_EventArgument);
}
void _SetObject(CKDWORD Object,CKRST_OBJECTINDEX ObjectTypeIndex,CKRasterizerObjectDesc* ObjectData);
virtual float GetSurfacesVideoMemoryOccupation(int* NbTextures,int* NbSprites,float* TextureSize,float* SpriteSize);
virtual BOOL FlushPendingGPUCommands() { return FALSE; }
void UpdateStats(VXPRIMITIVETYPE pType, int indexcount, CKDWORD VertexCount);
virtual CKRST_STRETCHRECT_ERROR StretchRect(CKDWORD destTexture, CKRECT* destRect, CKRST_CUBEFACE destFace,
CKDWORD srcTexture, CKRECT* srcRect, CKRST_CUBEFACE srcFace,
CKBOOL filter
) { return CKRST_STRETCHRECT_UNSUPPORTED; }
virtual BOOL ResolveMultisampling(CKBOOL resolveColorBuffer, CKBOOL resolveDepthStencilBuffer) { return FALSE; }
virtual BOOL ResumeMultisampling() { return FALSE; }
virtual BOOL IsMultisamplingResolved() const { return TRUE; }
// TMP TMP : basic occlusion query test
virtual BOOL BeginOcclusionQuery() { return FALSE; }
virtual CKDWORD WaitOcclusionQueryResult() { return 0; }
#ifdef PSP
virtual BOOL CreateTextureFromSubFile(CKDWORD Texture,VxSubFile* sf,TexFromFile* param){return FALSE;}
#endif
public:
CKRasterizerDriver* m_Driver; // Driver that was used to create this context
CKRasterizer* m_Owner; // Main rasterizer object
//----- Size Info
CKDWORD m_PosX; // Top left corner of the context (relative to its window)
CKDWORD m_PosY; // ....
CKDWORD m_Width; // Size of the context
CKDWORD m_Height; // ....
//------ Pixel Format
CKDWORD m_Bpp; // Color buffer bits per pixel
CKDWORD m_ZBpp; // Depth buffer bits per pixel
CKDWORD m_StencilBpp; // Stencil buffer bits per pixel
VX_PIXELFORMAT m_PixelFormat; // Color buffer pixel format
//------- Fullscreen Info
CKDWORD m_Fullscreen; // Currently fullscreen ?
CKDWORD m_RefreshRate; // Fullscreen refresh rate
WIN_HANDLE m_Window; // Window on which the rendering occurs.
BOOL m_SceneBegined;
//------- Transformation matrices (World, View, Projection)
CKDWORD m_MatrixUptodate; // Are m_ViewProjMatrix & m_TotalMatrix up-to-date ?
VxMatrix m_WorldMatrix; // Local->World transformation matrix
VxMatrix m_ViewMatrix; // World->View transformation matrix
VxMatrix m_ProjectionMatrix; // Projection matrix
VxMatrix m_ModelViewMatrix; // World*View
VxMatrix m_ViewProjMatrix; // View*Proj
VxMatrix m_TotalMatrix; // World*View*Proj (from a local coordinate system to screen)
XArray<VxMatrix> m_WorldMatrices; // vertex blend additionnal matrices
//------- Current Viewport Size
CKViewportData m_ViewportData; // Viewport position and size
CKRECT m_ScissorRect;
//------- Texture,sprites,Vertex & index buffers,vertex and pixel shaders objects arrays
XArray<CKTextureDesc*> m_Textures; // Array of texture specific data (format,data,etc..)
XArray<CKSpriteDesc*> m_Sprites; // sprites
XArray<CKVertexBufferDesc*> m_VertexBuffers; // Vertex Buffers
XArray<CKIndexBufferDesc*> m_IndexBuffers; // Index Buffers
XArray<CKVertexShaderDesc*> m_VertexShaders; // Vertex Shaders
XArray<CKPixelShaderDesc*> m_PixelShaders; // Pixel Shaders
XArray<CKSharedVBDesc*> m_SharedVBs; // Shared Vertex Buffers
XArray<CKSharedIBDesc*> m_SharedIBs; // Index Buffers
int m_TotalObjectCounts[eOBJECTCOUNT];
CKDWORD m_TargetTexture;
struct VBPool: public XArray<SharedVBsHolder*> {
~VBPool();
};
//--- These structure holds the Vertex buffers that were created
XHashTable<VBPool*,CKDWORD> m_Pool4SharedVBs[2]; // Dynamic or not...
XArray<SharedIBsHolder*> m_Pool4SharedIBs[2]; // Dynamic or not...
void SharedVertexBufferDestroyed(CKDWORD ObjIndex);
void SharedIndexBufferDestroyed(CKDWORD ObjIndex);
SharedIBsHolder* GetSharedIndexBufferPool(CKSharedIBDesc* DesiredFormat);
SharedVBsHolder* GetSharedVertexBufferPool(CKSharedVBDesc* DesiredFormat);
void CleanPools();
CKRST_STRETCHRECT_ERROR CheckStretchRectParams(CKDWORD destTexture, CKRECT* destRect, CKRST_CUBEFACE destFace,
CKDWORD srcTexture, CKRECT* srcRect, CKRST_CUBEFACE srcFace,
CKBOOL filter);
//--- Debug
int NbVBPoolAllocation;
int NbIBPoolAllocation;
int NbVBPool;
int NbIBPool;
//------- Lighting data
CKMaterialData m_CurrentMaterialData;
CKLightData m_CurrentLightData[RST_MAX_LIGHT];
//---- A special case for the VXRENDERSTATE_INVERSEWINDING render state
//---- which is maintained by the context
BOOL m_InverseWinding;
//--- For web content the render context can be transparent (no clear of backbuffer but instead
//--- a copy of what is currently on screen)
BOOL m_TransparentMode;
BOOL m_CleanAllRects;
XArray<CKRECT> m_DirtyRects;
//----- Currently set textures for each stages...
CKTextureDesc* m_CurrentTextures[CKRST_MAX_STAGES];
CKDWORD m_CurrentTextureValidBits; // Bit set for each stage for which m_CurrentTextures is known to be the correct value
// The case were the value is undefined is when there is a switch from a shader to
// the fixed pipeline
//-------------------------------------
// Special case : some render states can be disabled...
BOOL m_Antialias;
DWORD m_MaxAnisotropy;
//----------------------------------------
// A hash table that stores the index of a dynamic Vertex buffer
// given a vertex format
// 3 Frames of dynamic Vertex Buffers
XHashTable<CKDWORD,CKDWORD> m_DynamicVertexBuffers[MAX_FRAMES_AHEAD];
unsigned int m_CurrentFrame;
XArray<CKSharedVBDesc*> m_SharedVBToFree[MAX_FRAMES_AHEAD];
XArray<CKSharedIBDesc*> m_SharedIBToFree[MAX_FRAMES_AHEAD];
//-------------------------------------
// A cache of renderstate to avoid redoundant renderstate calls
// for texture and render states
CKRenderStateData m_StateCache[VXRENDERSTATE_MAXSTATE];
CKRenderStateData m_TexStateCache[CKRST_MAX_STAGES+1][CKRST_TSS_MAXSTATE];
int m_RenderStateCacheHit; // Render state already set
int m_RenderStateCacheMiss; // Render state not in cache
//----------------------------------------------------------------------
//--- to avoid redoundant call to SetTransform with a unity matrix
//--- we keep track of all possible matrix that are currently at the
//--- identity (a combination of CKRST_MATMASK values )
//--- the default value is 0 and it's the rasterizer implementation
//--- responsability to update and use this value.
CKDWORD m_UnityMatrixMask;
//----------------------------------------------------------------------
//--- Internal structure use in case of Indexed vertex blending
//--- done by the rasterizer
VxDrawPrimitiveData m_InternalDrawPrim;
VxScratch m_ScratchPool;
//--- Highest stage which has been set since the last call to DisableAllTextureStages
// This must be updated by implementations in the implementation of the SetTexture method
int m_MaxSetStage;
//--- Bool set to true if an effect shader is in use
BOOL m_ShaderInUse;
//--- Number of VBL to wait before performing
// the "BackToFront". If (m_PresentInterval == 0) this means an immediate presentation
// otherwise it is the number of VBL swap before rendering...
// This value came in replacement for the WaitForVBL parameter of BackToFront
DWORD m_PresentInterval;
DWORD m_CurrentPresentInterval;
CKRasterizerStats* m_Stats;
CKRasterizerStats m_LocalStats;
//---------------------------------------------------------
CKDWORD m_OffscreenMultiSampleCount;
};
#ifndef NO_CRITICAL_SECTION
/*********************************************************
A simple class to automatically perform a Enter/Leave
critical section when used inside a code scope...
We use a critical section for each call to DX since it seems
it was not necesseraly always multi-thread safe
**********************************************************/
class CKRstCriticalSection {
public:
CKRstCriticalSection(CKRasterizer* Rst):m_Rst(Rst) {
if (Rst && Rst->m_Mutex) {
Rst->m_Mutex->EnterMutex();
}
}
~CKRstCriticalSection() {
if (m_Rst && m_Rst->m_Mutex) {
m_Rst->m_Mutex->LeaveMutex();
}
}
CKRasterizer* m_Rst;
};
#define C_SECTION_RST(x) CKRstCriticalSection CSection(x);
#define C_SECTION() CKRstCriticalSection CSection(m_Owner);
#else
/********************************************************
DO NOT USE CRITICAL SECTION
*********************************************************/
#define C_SECTION_RST(x)
#define C_SECTION()
#endif
/*******************************************************************************
Render State cache management
*******************************************************************************/
inline void CKRasterizerContext::FlushRenderStateCache() {
for (int i=0; i<VXRENDERSTATE_MAXSTATE; ++i) {
m_StateCache[i].Flags &= ~(RSC_VALID|RSC_LOCKED);
m_StateCache[i].Value = m_StateCache[i].DefaultValue;
}
}
inline void CKRasterizerContext::InvalidateStateCache(VXRENDERSTATETYPE State) {
m_StateCache[State].Flags &= ~RSC_VALID;
}
inline CKDWORD CKRasterizerContext::GetRSCacheValue(VXRENDERSTATETYPE State) {
return m_StateCache[State].Value;
}
inline void CKRasterizerContext::LockRenderState(VXRENDERSTATETYPE State,BOOL Locked) {
if (Locked) {
m_StateCache[State].Flags |= RSC_LOCKED;
} else {
m_StateCache[State].Flags &= ~RSC_LOCKED;
}
}
inline void CKRasterizerContext::DisableRenderState(VXRENDERSTATETYPE State,BOOL Disabled) {
if (Disabled) {
m_StateCache[State].Flags |= RSC_DISABLED;
} else {
m_StateCache[State].Flags &= ~RSC_DISABLED;
}
}
inline void CKRasterizerContext::OverrideRenderState(VXRENDERSTATETYPE State,BOOL Overridden) {
if (Overridden) {
m_StateCache[State].Flags |= RSC_OVERRIDDEN;
} else {
m_StateCache[State].Flags &= ~RSC_OVERRIDDEN;
}
}
inline BOOL CKRasterizerContext::InternalSetRenderState(VXRENDERSTATETYPE State,CKDWORD Value) {
#ifdef PSP
CKRenderStateData& sd = m_StateCache[State];
BOOL ret = ((sd.Flags & RSC_VALID) && (sd.Value==Value));
sd.Value=Value;
sd.Flags |= RSC_VALID;
return ret;
#else
if (m_StateCache[State].Flags & (RSC_LOCKED|RSC_DISABLED))
return TRUE;
if ((m_StateCache[State].Flags & RSC_VALID) && (m_StateCache[State].Value==Value)) {
m_RenderStateCacheHit++;
return TRUE;
} else {
m_RenderStateCacheMiss++;
m_StateCache[State].Value=Value;
m_StateCache[State].Flags |= RSC_VALID;
return FALSE;
}
#endif
}
// Returns the value of cached render state or FALSE if the
// cache is invalid
inline BOOL CKRasterizerContext::InternalGetRenderState(VXRENDERSTATETYPE State,CKDWORD* Value) {
if (m_StateCache[State].Flags & RSC_VALID) {
*Value = m_StateCache[State].Value; return TRUE;
} else {
*Value = m_StateCache[State].DefaultValue; return FALSE;
}
}
/*******************************************************************************
Texture State cache management
*******************************************************************************/
inline void CKRasterizerContext::FlushTextureStateCache() {
for (int s=0; s<CKRST_MAX_STAGES; ++s) {
for (int i=0; i<CKRST_TSS_MAXSTATE; ++i) {
m_TexStateCache[s][i].Flags &= ~(RSC_VALID|RSC_LOCKED);
m_TexStateCache[s][i].Value = m_TexStateCache[s][i].DefaultValue;
}
}
}
inline void CKRasterizerContext::InvalidateTextureStateCache(int Stage,CKRST_TEXTURESTAGESTATETYPE State) {
m_TexStateCache[Stage][State].Flags &= ~RSC_VALID;
}
inline CKDWORD CKRasterizerContext::GetTSCacheValue(int Stage,CKRST_TEXTURESTAGESTATETYPE State) {
return m_TexStateCache[Stage][State].Value;
}
inline void CKRasterizerContext::LockTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,BOOL Locked) {
if (Locked) {
m_TexStateCache[Stage][State].Flags |= RSC_LOCKED;
} else {
m_TexStateCache[Stage][State].Flags &= ~RSC_LOCKED;
}
}
inline void CKRasterizerContext::DisableTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,BOOL Disabled) {
if (Disabled) {
m_TexStateCache[Stage][State].Flags |= RSC_DISABLED;
} else {
m_TexStateCache[Stage][State].Flags &= ~RSC_DISABLED;
}
}
inline BOOL CKRasterizerContext::InternalSetTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,CKDWORD Value) {
#ifdef PSP
CKRenderStateData& sd = m_TexStateCache[Stage][State];
BOOL ret = ((sd.Flags & RSC_VALID) && (sd.Value==Value));
sd.Value = Value;
sd.Flags |= RSC_VALID;
return ret;
#else
if (Stage >= CKRST_MAX_STAGES) {
return TRUE;
}
if (m_TexStateCache[Stage][State].Flags & (RSC_LOCKED|RSC_DISABLED))
return TRUE;
if ((m_TexStateCache[Stage][State].Flags & RSC_VALID) && (m_TexStateCache[Stage][State].Value==Value)) {
m_RenderStateCacheHit++;
return TRUE;
} else {
m_MaxSetStage = XMax(Stage,m_MaxSetStage);
m_RenderStateCacheMiss++;
m_TexStateCache[Stage][State].Value=Value;
m_TexStateCache[Stage][State].Flags |= RSC_VALID;
return FALSE;
}
#endif
}
// Returns the value of cached render state or FALSE if the
// cache is invalid
inline BOOL CKRasterizerContext::InternalGetTextureState(int Stage,CKRST_TEXTURESTAGESTATETYPE State,CKDWORD* Value) {
#ifdef PSP
XASSERT(Stage == 0)
#else
if (Stage >= CKRST_MAX_STAGES) {
*Value = 0;
return FALSE;
}
#endif
if (m_TexStateCache[Stage][State].Flags & RSC_VALID) {
*Value = m_TexStateCache[Stage][State].Value;
return TRUE;
} else {
*Value = m_TexStateCache[Stage][State].DefaultValue;
return FALSE;
}
}
#ifdef WIN32
#pragma warning (disable:4035)
/**************************************************
Small util to get the position of a given bit...
*****************************************************/
inline int GetFirstBitpos(CKDWORD data) {
__asm {
mov eax,data
and eax,eax
jz exitnow
bsf eax,eax
inc eax
exitnow:
}
}
#pragma warning (default:4035)
#else
inline int GetFirstBitpos(CKDWORD data) {
CKDWORD Lsb=0;
if (!data) return 0;
while (!(data & 1)) { data>>=1; Lsb++; }
return Lsb+1;
}
#endif
#endif