JD2022-TU1/main/extern/Camcam/LIBS/Render/D3D_BASE.cpp

1649 lines
55 KiB
C++

#include "D3D_Class.h"
#include "SCENE.h"
#include <assert.h>
#ifdef __D3D
//#define CAMCAM_NO_D3DX
#ifdef CAMCAM_NO_D3DX
HRESULT WINAPI
D3DXCreateTexture(
LPDIRECT3DDEVICE9 pDevice,
UINT Width,
UINT Height,
UINT MipLevels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
LPDIRECT3DTEXTURE9* ppTexture)
{
return pDevice->CreateTexture(Width,Height,MipLevels,Usage,Format,Pool,ppTexture,NULL);
}
MATRIX D3D_2_MATRIX(const D3DXMATRIX* MD3D)
{
MATRIX Res;
Res.Identity();
Res.I.x = MD3D->_11;Res.I.y = MD3D->_12;Res.I.z = MD3D->_13;
Res.J.x = MD3D->_21;Res.J.y = MD3D->_22;Res.J.z = MD3D->_23;
Res.K.x = MD3D->_31;Res.K.y = MD3D->_32;Res.K.z = MD3D->_33;
Res.T.x = MD3D->_41;Res.T.y = MD3D->_42;Res.T.z = MD3D->_43;
return Res;
}
D3DXMATRIX MATRIX_2_D3D( MATRIX &Res)
{
D3DXMATRIX Out;
D3DXMatrixIdentity(&Out);
Out._11 = Res.I.x;Out._12 = Res.I.y;Out._13 = Res.I.z;
Out._21 = Res.J.x;Out._22 = Res.J.y;Out._23 = Res.J.z;
Out._31 = Res.K.x;Out._32 = Res.K.y;Out._33 = Res.K.z;
Out._41 = Res.T.x;Out._42 = Res.T.y;Out._43 = Res.T.z;
return Out;
}
D3DXMATRIX* WINAPI D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz )
{
D3DXMatrixIdentity(pOut);
pOut->_41 = sx;
pOut->_42 = sy;
pOut->_43 = sz;
return pOut;
}
D3DXMATRIX* WINAPI D3DXMatrixScaling( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz )
{
D3DXMatrixIdentity(pOut);
pOut->_11 = sx;
pOut->_22 = sy;
pOut->_33 = sz;
return pOut;
}
D3DXMATRIX* WINAPI D3DXMatrixMultiply( D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2 )
{
int i,j;
for (i=0; i<4; i++)
{
for (j=0; j<4; j++)
{
pout->m[i][j] = pm1->m[i][0] * pm2->m[0][j] + pm1->m[i][1] * pm2->m[1][j] + pm1->m[i][2] * pm2->m[2][j] + pm1->m[i][3] * pm2->m[3][j];
}
}
return pout;
}
//*/
D3DXVECTOR4* WINAPI D3DXVec4Cross( D3DXVECTOR4 *Out, CONST D3DXVECTOR4 *U, CONST D3DXVECTOR4 *V,
CONST D3DXVECTOR4 *W)
{
float a = V->x*W->y - V->y*W->x;
float b = V->x*W->z - V->z*W->x;
float c = V->x*W->w - V->w*W->x;
float d = V->y*W->z - V->z*W->y;
float e = V->y*W->w - V->w*W->y;
float f = V->z*W->w - V->w*W->z;
Out->x = f*U->y - e*U->z + d*U->w;
Out->y = f*U->x + c*U->z - b*U->w;
Out->z = e*U->x - c*U->y + a*U->w;
Out->w = d*U->x + b*U->y - a*U->z;
return Out;
}
FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pm)
{
D3DXVECTOR4 minor, v1, v2, v3;
FLOAT det;
v1.x = pm->m[0][0]; v1.y = pm->m[1][0]; v1.z = pm->m[2][0]; v1.w = pm->m[3][0];
v2.x = pm->m[0][1]; v2.y = pm->m[1][1]; v2.z = pm->m[2][1]; v2.w = pm->m[3][1];
v3.x = pm->m[0][2]; v3.y = pm->m[1][2]; v3.z = pm->m[2][2]; v3.w = pm->m[3][2];
D3DXVec4Cross(&minor,&v1,&v2,&v3);
det = - (pm->m[0][3] * minor.x + pm->m[1][3] * minor.y + pm->m[2][3] * minor.z + pm->m[3][3] * minor.w);
return det;
}
D3DXMATRIX* WINAPI D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM )
{
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
pOut->m[i][j] = pM->m[j][i];
return pOut;
}
D3DXMATRIX* WINAPI D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM )
{
D3DXMATRIX mT;
D3DXMatrixTranspose( &mT, pM );
D3DXVec4Cross( ((D3DXVECTOR4 *)&pOut->_11) , ((D3DXVECTOR4 *)&mT._21), ((D3DXVECTOR4 *)&mT._31), ((D3DXVECTOR4 *)&mT._41));
D3DXVec4Cross( ((D3DXVECTOR4 *)&pOut->_21) , ((D3DXVECTOR4 *)&mT._11), ((D3DXVECTOR4 *)&mT._31), ((D3DXVECTOR4 *)&mT._41));
D3DXVec4Cross( ((D3DXVECTOR4 *)&pOut->_31) , ((D3DXVECTOR4 *)&mT._11), ((D3DXVECTOR4 *)&mT._21), ((D3DXVECTOR4 *)&mT._41));
D3DXVec4Cross( ((D3DXVECTOR4 *)&pOut->_41) , ((D3DXVECTOR4 *)&mT._11), ((D3DXVECTOR4 *)&mT._21), ((D3DXVECTOR4 *)&mT._31));
for (int i=0; i<4; i++)
for (int j=0; j<4; j++)
pOut->m[i][j] *= *pDeterminant;
return pOut;
}
D3DXVECTOR4* WINAPI D3DXVec4Transform( D3DXVECTOR4 *result, CONST D3DXVECTOR4 *pos, CONST D3DXMATRIX *ModelView )
{
result->x = pos->x*ModelView->_11 + pos->y*ModelView->_21 + pos->z*ModelView->_31 + pos->w*ModelView->_41;
result->y = pos->x*ModelView->_12 + pos->y*ModelView->_22 + pos->z*ModelView->_32 + pos->w*ModelView->_42;
result->z = pos->x*ModelView->_13 + pos->y*ModelView->_23 + pos->z*ModelView->_33 + pos->w*ModelView->_43;
result->w = pos->x*ModelView->_14 + pos->y*ModelView->_24 + pos->z*ModelView->_34 + pos->w*ModelView->_44;
return result;
}
#else
#pragma comment(lib, "..\\LIBS\\DX9_Aug_2007\\lib\\d3dx9d.lib")
#endif
bool D3D_DI::IsTextureValid(unsigned int oglRef)
{
// This is needed to avoid crashes in D3D with binding an
// invalid texture (which happens)
return (oglRef != 0xFFFFFFFF && oglRef != 0xFFFFFFFE);
}
void D3D_DI::SetFog(u32 OnOff,float NearV , float farV , u32 Color)
{
assert(false);
}
void D3D_DI::SetViewport(s32 X,s32 Y,s32 SX,s32 SY)
{
f32 AreaX,AreaY;
f32 fSX,fSW;
AreaX = CurrentRect.right - CurrentRect.left;
AreaY = CurrentRect.bottom - CurrentRect.top;
fSW = SY * AreaX/AreaY;
CurrentViewport[0] = X;
CurrentViewport[1] = Y;
CurrentViewport[2] = SX;
CurrentViewport[3] = SY;
D3DVIEWPORT9 Viewport1 = {(float)X - (fSW - (float)SX) / 2.0f, FB_SY - SY - Y, fSW, SY, 0, 1};
d3ddev->SetViewport(&Viewport1);
RECT scisRect = {X<0 ? 0 : X, FB_SY - SY - (Y<0 ? 0 : Y), (X<0 ? 0 : X) + SX, FB_SY - (Y<0 ? 0 : Y)};
d3ddev->SetScissorRect(&scisRect);//*/
D3DVIEWPORT9 Viewport2 = {X, FB_SY - SY - Y, SX, SY};
d3ddev->SetViewport(&Viewport2);
SetClipping(X, Y, SX, SY);
ActivRect.left = X;
ActivRect.top = Y;
ActivRect.right = X + SX;
ActivRect.bottom = Y + SY;
}
void D3D_DI::SetClipping(s32 X,s32 Y,s32 SX,s32 SY)
{
ScissorRect.right = X;
ScissorRect.top = Y;
ScissorRect.bottom = Y + SY;
ScissorRect.left = X + SX;
RECT ScissorRect2 = {X, FB_SY - SY - Y, X + SX, FB_SY - Y};
d3ddev->SetScissorRect(&ScissorRect2);
d3ddev->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
}
void D3D_DI::BeginTextureTarget(u32 TextureIndex,u32 SaveFrontBuffer)
{
#if 1
QuadRotation_ON = 0;
ZBIas = 1.0f;
memcpy(SavedCurrentViewport,CurrentViewport,sizeof(SavedCurrentViewport));
RenderTargetState = 1;
RenderTargetBaseX = CurrentViewport[0];
RenderTargetBaseY = CurrentViewport[1];
if (RenderTargetBaseX + AllRef[TextureIndex].pExtRef->SX > FB_SX)
RenderTargetBaseX = FB_SX - AllRef[TextureIndex].pExtRef->SX ;
if (RenderTargetBaseY + AllRef[TextureIndex].pExtRef->SY > FB_SY)
RenderTargetBaseY = FB_SY - AllRef[TextureIndex].pExtRef->SY ;
if (RenderTargetBaseX < 0)
RenderTargetBaseX = 0;
if (RenderTargetBaseY < 0)
RenderTargetBaseY = 0;
SetViewport(RenderTargetBaseX, RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY);
if (MotherClass) MotherClass->PickReportCurrent.PickFrozed++;
/* Save front buffer */
if (SaveFrontBuffer)
{
RenderTargetState |= 2;
ValidateLayer(NUMBER_OF_WORKING_REF - 3);
int texIndex = (NUMBER_OF_WORKING_REF - 3) % NUMBER_OF_OGL_WORKING_REF;
CopyTextureFromBackBuffer(_D3D_TEX(OGLWorkingRef[texIndex]), 0 , 0 , RenderTargetBaseX , RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY);
}
/* Reload Texture */
SetBackGround(TextureIndex);
D3DVIEWPORT9 Viewport = {RenderTargetBaseX, FB_SY - AllRef[TextureIndex].pExtRef->SY - RenderTargetBaseY, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY};
d3ddev->SetViewport(&Viewport);
RECT scisRect = {RenderTargetBaseX, FB_SY - AllRef[TextureIndex].pExtRef->SY - RenderTargetBaseY, RenderTargetBaseX + AllRef[TextureIndex].pExtRef->SX, FB_SY - RenderTargetBaseY};
d3ddev->SetScissorRect(&scisRect);
ActivRect.left = RenderTargetBaseX;
ActivRect.top = RenderTargetBaseY;
ActivRect.right = AllRef[TextureIndex].pExtRef->SX + RenderTargetBaseX;
ActivRect.bottom = AllRef[TextureIndex].pExtRef->SY + RenderTargetBaseY;
// Save front buffer
CurrentRect.left = CurrentRect.top = 0;
CurrentRect.right = AllRef[TextureIndex].pExtRef->SX;
CurrentRect.bottom = AllRef[TextureIndex].pExtRef->SY;//*/
//*/
#endif
}
void D3D_DI::EndTextureTarget(u32 TextureIndex,u32 bUpdateSoftBuffer)
{
#if 1
HRESULT result;
QuadRotation_ON = 0;
d3ddev->SetTexture(0, _D3D_TEX(AllRef[TextureIndex].OGLRef));
EnableTextureOps();
SafeCopyTextureFromBackBuffer( (IDirect3DTexture9**) &(AllRef[TextureIndex].OGLRef), 0, 0,
RenderTargetBaseX, RenderTargetBaseY,
AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY);
if (bUpdateSoftBuffer)
ReadFrameBuffer(RenderTargetBaseX, RenderTargetBaseY, AllRef[TextureIndex].pExtRef->PITCH, AllRef[TextureIndex].pExtRef->SY, AllRef[TextureIndex].pExtRef);
// restore front buffer
if (RenderTargetState & 2)
{
LayerOperation(5, NUMBER_OF_WORKING_REF - 3, 0xffffffff, 0.0f, 0.0f) ;
}
CurrentRect = hDCRect;
SetViewport(SavedCurrentViewport[0], SavedCurrentViewport[1], SavedCurrentViewport[2], SavedCurrentViewport[3]);
RenderTargetBaseX = RenderTargetBaseY = RenderTargetState = 0;
if (MotherClass && MotherClass->PickReportCurrent.PickFrozed) MotherClass->PickReportCurrent.PickFrozed--;
ZBIas = 1.0f;
#endif
}
void D3D_DI::ValidateLayer(u32 Index)
{
Index %= NUMBER_OF_OGL_WORKING_REF;
if (OGLWorkingRef[Index] != -1)
{
EnableTextureOps();
d3ddev->SetTexture(0, _D3D_TEX(OGLWorkingRef[Index]));
/*glGetTexParameteriv(GL_TEXTURE_2D ,GL_TEXTURE_RESIDENT,&param);
if (!param)
{
// ForceReload
glDeleteTextures(1, &OGLWorkingRef[Index]);
OGLWorkingRef[Index] = -1;
}//*/
}
D3DSURFACE_DESC desc;
if(OGLWorkingRef[Index] == -1)
{
HRESULT result;
if (Index == NUMBER_OF_OGL_WORKING_REF - 1)
{
result = D3DXCreateTexture(d3ddev,
OGLTextureSizeX, OGLTextureSizeY,
1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT, (IDirect3DTexture9**) &OGLWorkingRef[Index]);
}
else
{
result = D3DXCreateTexture(d3ddev,
OGLTextureSizeX, OGLTextureSizeY,
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, // substitute for luminance
D3DPOOL_DEFAULT, (IDirect3DTexture9**) &OGLWorkingRef[Index]);
}
assert(result == D3D_OK);
//D3DSURFACE_DESC desc;
//result = (_D3D_TEX(OGLWorkingRef[Index]))->GetLevelDesc(0, &desc); assert(result==D3D_OK);
LPDIRECT3DSURFACE9 tb = NULL;
result = (_D3D_TEX(OGLWorkingRef[Index]))->GetSurfaceLevel(0, &tb);
assert(result==D3D_OK);
d3ddev->ColorFill(tb, NULL, 0xff000000); // fill in solid black
tb->Release();
d3ddev->SetTexture(0, _D3D_TEX(OGLWorkingRef[Index]));
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
EnableTextureOps();
/*
if (Index == NUMBER_OF_OGL_WORKING_REF - 1)
CopyTextureFromBackBuffer(_D3D_TEX(OGLWorkingRef[Index]), 0, 0, 0, 0, OGLTextureSizeX, OGLTextureSizeY, 1);
else//*/
CopyTextureFromBackBuffer(_D3D_TEX(OGLWorkingRef[Index]), 0, 0, 0, 0, OGLTextureSizeX, OGLTextureSizeY);
}
}
u32 D3D_DI::GetTexFreeIndex()
{
u32 Counter = MaxOglTexture;
while (Counter--)
{
if (AllRef[Counter].OGLRef == 0xffffffff) return Counter;
}
return -1;
}
void D3D_DI::DrawLine(u32 Color,Vector *A,Vector *B, int Lenght)
{
#ifndef CAMCAM_NO_D3DX
D3DCOLOR color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
LPD3DXLINE line;
D3DXCreateLine(d3ddev, &line);
if (Lenght == 0) Lenght = 1;
line->SetWidth((FLOAT) Lenght);
D3DXVECTOR3 temp[2];
temp[0].x = A->x; temp[0].y = A->y; temp[0].z = A->z;
temp[1].x = B->x; temp[1].y = B->y; temp[1].z = B->z;
D3DXMATRIX mat, matWorld, matView, matProjection;
d3ddev->GetTransform(D3DTS_WORLD, &matWorld);
d3ddev->GetTransform(D3DTS_VIEW, &matView);
//d3ddev->GetTransform(D3DTS_PROJECTION, &matProjection);
GetMatrix(0, (float*)&matProjection);
mat = matWorld * matView * matProjection;
D3DXVec3TransformCoord(&temp[0], &temp[0], &mat);
D3DXVec3TransformCoord(&temp[1], &temp[1], &mat);
f32 SX = CurrentViewport[2];
f32 SY = CurrentViewport[3];
D3DXVECTOR2 temp2[2]; // you have to transform coords back from NDC to window coords
temp2[0].x = (temp[0].x/2.0+0.5f)*SX; temp2[0].y = (0.5f-temp[0].y/2.0)*SY;
temp2[1].x = (temp[1].x/2.0+0.5f)*SX; temp2[1].y = (0.5f-temp[1].y/2.0)*SY;
line->Draw(temp2, 2, color);
line->Release();
#endif
}
void D3D_DI::ReadFrameBuffer(s32 X,s32 Y,s32 SX,s32 SY, MAP *dest)
{
static LPDIRECT3DSURFACE9 tb = NULL;
LPDIRECT3DSURFACE9 fb = NULL, sb = NULL;
D3DSURFACE_DESC sbDesc, tbDesc, fbDesc;
D3DLOCKED_RECT lockedRect;
HRESULT result;
if (!(MotherClass && MotherClass->SkipFunctions & SKIP_GLREAD))
{
result = d3ddev->GetRenderTarget(0, &fb);
assert (result == D3D_OK);
result = fb->GetDesc(&fbDesc);
assert (result == D3D_OK);
// if intermediary textures (VRAM and Main RAM) not created or sizes differ
// create both a new VRAM texture and a CPU RAM surface
if (srTex2 != NULL)
{
result = srTex2->GetSurfaceLevel(0, &sb); assert(result==D3D_OK);
result = sb->GetDesc(&sbDesc); assert(result==D3D_OK);
}
if (srTex2 == NULL || sbDesc.Width != SX || sbDesc.Height != SY)
{
if (sb) sb->Release();
if (srTex2) srTex2->Release();
// the temporary texture located in VRAM
result = D3DXCreateTexture(d3ddev,
SX, SY,
1, D3DUSAGE_RENDERTARGET,
fbDesc.Format, D3DPOOL_DEFAULT, &srTex2); assert(result==D3D_OK);
result = srTex2->GetSurfaceLevel(0, &sb); assert(result==D3D_OK);
result = sb->GetDesc(&sbDesc); assert(result==D3D_OK);
// the temporary texture located in CPU RAM
d3ddev->CreateOffscreenPlainSurface(SX, SY, fbDesc.Format, D3DPOOL_SYSTEMMEM, &tb, 0);
}
RECT fbRect = {X, FB_SY - SY - Y, X + SX, FB_SY - Y};
RECT sbRect = {0, 0, SX, SY};
// first stretchrect the contents you want into temp texture in VRAM
result = d3ddev->StretchRect(fb, &fbRect, sb, &sbRect, D3DTEXF_LINEAR);
assert (result == D3D_OK);
// transfer only the portion you need from VRAM to Main RAM due to low transfer speed
result = d3ddev->GetRenderTargetData(sb, tb);
assert (result == D3D_OK);
// lock CPU RAM texture and copy it onto destination
result = tb->LockRect(&lockedRect, 0, 0); // lock entire texture
assert (result == D3D_OK);
{
DWORD* imageData = (DWORD*)lockedRect.pBits;
int pitch = lockedRect.Pitch / sizeof(DWORD);
int PITCH = dest->PITCH;
s32 *pBASE = dest->GetBase();
for(int i = 0; i < SY; i++)
{
for (int j = 0; j < SX; j++)
pBASE[i*PITCH + j] = imageData[(SY - 1 - i)*pitch + j];
}
}
result = tb->UnlockRect();
assert (result == D3D_OK);//
}
if (fb) fb->Release(); fb = NULL; // release pointer to framebuffer
if (sb) sb->Release(); sb = NULL;
//if (tb) tb->Release(); tb = NULL;
}
void D3D_DI::UpdateTexture_BM_2_HW(u32 TextureIndex, bool isDynamic)
{
if (MotherClass && MotherClass->SkipFunctions & SKIP_GLWRITE)
return;
//*/
if(IsTextureValid(AllRef[TextureIndex].OGLRef))
{
HRESULT result;
D3DSURFACE_DESC desc;
_D3D_TEX(AllRef[TextureIndex].OGLRef)->GetLevelDesc(0, &desc);
if (isDynamic) // if texture is updated more than once, change its type to dynamic. perf optimization
{
if ((desc.Usage & D3DUSAGE_DYNAMIC) == 0)
{
_D3D_TEX(AllRef[TextureIndex].OGLRef)->Release();
AllRef[TextureIndex].OGLRef = 0xDEADBEEF;
result = D3DXCreateTexture(d3ddev,
desc.Width, desc.Height,
1, D3DUSAGE_DYNAMIC, desc.Format,
D3DPOOL_DEFAULT, (IDirect3DTexture9**) &(AllRef[TextureIndex].OGLRef));
assert (result == D3D_OK);
}
}//*/
D3DLOCKED_RECT lockedRect;
_D3D_TEX(AllRef[TextureIndex].OGLRef)->LockRect(0, &lockedRect, 0, 0); // lock entire texture
if (AllRef[TextureIndex].pExtRef->GetBase() != NULL)
{
int width = AllRef[TextureIndex].pExtRef->SX;
int height = AllRef[TextureIndex].pExtRef->SY;
int pitch = AllRef[TextureIndex].pExtRef->PITCH;
int iPixelDataSize = sizeof(DWORD);
if (desc.Format == D3DFMT_L8) iPixelDataSize = 1;
int WIDTH = desc.Width;
int HEIGHT = desc.Height;
int PITCH = lockedRect.Pitch / iPixelDataSize;
if (desc.Format == D3DFMT_L8)
{
char* imageData = (char*) lockedRect.pBits;
memset(imageData, 0, PITCH*HEIGHT*iPixelDataSize); // set default to all black
char* sourceData = (char*) AllRef[TextureIndex].pExtRef->GetBase();
for(int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
imageData[i*PITCH + j] = sourceData[4*(i*pitch + j)+2]; // just copy over red component. courtesy of opengl
}
} else
{
DWORD* imageData = (DWORD*)lockedRect.pBits;
s32 *pBASE = AllRef[TextureIndex].pExtRef->GetBase();
memset(imageData, 0, PITCH*HEIGHT*iPixelDataSize); // set default to all black
for(int i = 0; i < height; i++)
memcpy(imageData+(i)*PITCH, pBASE+i*pitch, width*iPixelDataSize);
}
}
_D3D_TEX(AllRef[TextureIndex].OGLRef)->UnlockRect(0);
}
}
void D3D_DI::UpdateTexture_HW_2_BM(u32 TextureIndex,u32 bUpdateSoftBuffer,s32 X, s32 Y)
{
d3ddev->SetTexture(0, _D3D_TEX( AllRef[TextureIndex].OGLRef ));
EnableTextureOps();
SafeCopyTextureFromBackBuffer((IDirect3DTexture9**) &(AllRef[TextureIndex].OGLRef), 0, 0, X, Y, AllRef[TextureIndex].pExtRef->SX, AllRef[TextureIndex].pExtRef->SY);
if (bUpdateSoftBuffer)
ReadFrameBuffer(X, Y, AllRef[TextureIndex].pExtRef->PITCH, AllRef[TextureIndex].pExtRef->SY, AllRef[TextureIndex].pExtRef);
}
void D3D_DI::SetTextureColorMode(u32 Index,u32 ColorMode)
{
if (Index != -1)
{
if (ColorMode != AllRef[Index].ColorMode)
{
if (AllRef[Index].pExtRef)
{
if (AllRef[Index].OGLRef != -1)
{
assert(false);
/*glDeleteTextures(1, &AllRef[Index].OGLRef);
glGenTextures(1, &AllRef[Index].OGLRef);
glBindTexture(GL_TEXTURE_2D, AllRef[Index].OGLRef);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER,0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
AllRef[Index].ColorMode = ColorMode;
switch (ColorMode)
{
case 1:glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_LUMINANCE, 0 , 0 , GetUpperPO2(AllRef[Index].pExtRef->SX), GetUpperPO2(AllRef[Index].pExtRef->SY), 0);break;
default:glCopyTexImage2D(GL_TEXTURE_2D, 0 , GL_RGBA, 0 , 0 , GetUpperPO2(AllRef[Index].pExtRef->SX), GetUpperPO2(AllRef[Index].pExtRef->SY), 0);break;
}
UpdateTexture_BM_2_HW(Index);//*/
//d3dTex[AllRef[Index].OGLRef]->Release();
//CreateTexture(Index, ColorMode);
}
}
}
}
}
void D3D_DI::CreateTexture(u32 IndexToCreate,u32 ColorMode)
{
//if (IndexToCreate == 2046) ColorMode = 1;
HRESULT result;
AllRef[IndexToCreate].OGLRef = MaxOglTexture - IndexToCreate - 1;
switch (ColorMode)
{
case 1: // luminance
result = D3DXCreateTexture(d3ddev,
GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY),
1, 0, D3DFMT_L8, D3DPOOL_MANAGED,
(IDirect3DTexture9**) &AllRef[IndexToCreate].OGLRef
);
break;
default:
result = D3DXCreateTexture(d3ddev,
GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY),
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
(IDirect3DTexture9**) &AllRef[IndexToCreate].OGLRef
);
break;
}
assert(result==D3D_OK);
/*
LPDIRECT3DSURFACE9 tb = NULL;
result = (_D3D_TEX(AllRef[IndexToCreate].OGLRef))->GetSurfaceLevel(0, &tb);
assert(result==D3D_OK);
result = d3ddev->ColorFill(tb, NULL, 0xff000000); // fill in solid black
assert(result==D3D_OK);
//*/
AllRef[IndexToCreate].ColorMode = ColorMode; // RGBA
AllRef[IndexToCreate].ClampMode = 0;
d3ddev->SetTexture(0, _D3D_TEX(AllRef[IndexToCreate].OGLRef));
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
EnableTextureOps();
/*
switch (ColorMode)
{
case 1: SafeCopyTextureFromBackBuffer((IDirect3DTexture9**) &(AllRef[IndexToCreate].OGLRef), 0, 0, 0, 0, GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY), 1); break;
default: SafeCopyTextureFromBackBuffer((IDirect3DTexture9**) &(AllRef[IndexToCreate].OGLRef), 0, 0, 0, 0, GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX), GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY), 0); break;
}
// TODO: Fill in CopyTex
/*
if (
(GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX) > 16) &&
(GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY) > 16)
)
{
u32 BlackMap[16 * 16];
memset(BlackMap, 0, sizeof(BlackMap));
for (u32 XC = 0 ; XC < GetUpperPO2(AllRef[IndexToCreate].pExtRef->SX) ; XC += 16)
for (u32 YC = 0 ; YC < GetUpperPO2(AllRef[IndexToCreate].pExtRef->SY) ; YC += 16)
//glTexSubImage2D(GL_TEXTURE_2D,0,XC,YC,16,16,GL_BGRA_EXT,GL_UNSIGNED_BYTE,BlackMap);
memcpy(imageData+i*pitch, AllRef[TextureIndex].pExtRef->BASE+i*PITCH, width*sizeof(DWORD));
}
//*/
UpdateTexture_BM_2_HW(IndexToCreate, false);
}
u32 D3D_DI::CreateTexture(MAP *pExternalReferenceRGBA,u32 ColorMode, bool forceCreation)
{
u32 Index = GetTexFreeIndex();
if (Index == -1) return -1;
AllRef[Index].pExtRef = pExternalReferenceRGBA;
CreateTexture(Index,ColorMode);
return Index;
}
u32 D3D_DI::CreateLayerTexture(MAP *pExternalReferenceRGBA,u32 LayerIndex)
{
u32 Index = GetTexFreeIndex();
if (Index == -1) return -1;
AllRef[Index].pExtRef = pExternalReferenceRGBA;
AllRef[Index].ColorMode = 0; // RGBA
ValidateLayer(LayerIndex % NUMBER_OF_OGL_WORKING_REF);
AllRef[Index].OGLRef = OGLWorkingRef[LayerIndex % NUMBER_OF_OGL_WORKING_REF];
AllRef[Index].ClampMode = 0;
return Index;
}
void D3D_DI::DestroyLayerTexture(u32 TextureIndex)
{
if ((TextureIndex != -1) && (AllRef[TextureIndex].OGLRef != -1))
{
//_D3D_TEX(AllRef[TextureIndex].OGLRef])->Release();
AllRef[TextureIndex].OGLRef = -1; // NOT DESTROY IN HARD !!
//OGLWorkingRef[TextureIndex] = -1;
}
}
void D3D_DI::DestroyTexture(u32 TextureIndex)
{
if ((TextureIndex != -1) && (AllRef[TextureIndex].OGLRef != -1))
{
_D3D_TEX(AllRef[TextureIndex].OGLRef)->Release();
AllRef[TextureIndex].OGLRef = -1;
// AllRef[TextureIndex].pExtRef = NULL;
}
}
void D3D_DI::Setexture(u32 TextureIndex,float *UVMatrix)
{
if ((TextureIndex == -1) || (AllRef[TextureIndex].OGLRef == -1))
{
DisableTextureOps();
ulCurrentTexture = -1;
}
else
{
float FakeUVMatrix[] = {1,0,0,1,0,0};
float BorderCorectionUVMatrix[] = {1,0,0,1,0,0};
if (UVMatrix == NULL) UVMatrix = (float*)&FakeUVMatrix;
EnableTextureOps();
d3ddev->SetTexture(0, _D3D_TEX(AllRef[TextureIndex].OGLRef));
/*{
GLint param;
glGetTexParameteriv(GL_TEXTURE_2D ,GL_TEXTURE_RESIDENT,&param);
if (!param)
{
// Force Re-create
glDeleteTextures(1, &AllRef[TextureIndex].OGLRef);
CreateTexture(TextureIndex,0);
glBindTexture(GL_TEXTURE_2D, AllRef[TextureIndex].OGLRef);
}
}//*/
ulCurrentTexture = TextureIndex;
if (ulCurrentTexture != -1)
{
float CX,CY,YC;
//(float)AllRef[ulCurrentTexture].pExtRef->SX / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX)
float width = GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX);
float height = GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SY);
CX = (float)AllRef[ulCurrentTexture].pExtRef->SX / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX);
CY = (float)AllRef[ulCurrentTexture].pExtRef->SY / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SY);
if ((CX != 1.0f) || (CY != 1.0f))
{
float BCX,BCY;
memcpy(BorderCorectionUVMatrix,UVMatrix,sizeof(BorderCorectionUVMatrix));
if (CX != 1.0f)
{
BCX = ((float)(AllRef[ulCurrentTexture].pExtRef->SX - 1) / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SX)) / CX;
BorderCorectionUVMatrix[0] *= BCX;
BorderCorectionUVMatrix[2] *= BCX;
BorderCorectionUVMatrix[4] *= BCX;
}
if (CY != 1.0f)
{
BCY = ((float)(AllRef[ulCurrentTexture].pExtRef->SY - 1) / GetUpperPO2((float)AllRef[ulCurrentTexture].pExtRef->SY)) / CY;
BorderCorectionUVMatrix[1] *= BCY;
BorderCorectionUVMatrix[3] *= BCY;
BorderCorectionUVMatrix[5] *= BCY;
UVMatrix = (float *)BorderCorectionUVMatrix;
}
}
float Persp2[16]= {
CX*UVMatrix[0], CY*UVMatrix[1], 0, 0,
CX*UVMatrix[2], CY*UVMatrix[3], 0, 0,
0, 0, 1, 0,
CX*UVMatrix[4], CY*UVMatrix[5], 0, 1,
};
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
//D3DXMatrixTranspose((D3DXMATRIX*)&Persp2, (D3DXMATRIX*)&Persp2);
D3DXMATRIX mTrans, mTex; memcpy(&mTex, Persp2, sizeof(D3DXMATRIX));
D3DXMatrixTranslation(&mTrans, 1.0f/FB_SX, 1.0f/FB_SY, 0.0f);
mTex = mTex * mTrans;
//SetMatrix(2, (float*)&mTex);
SetMatrix(2, Persp2);
/*
// the following block of code flips the y coordinates of the texture
D3DXMATRIX mTexture; d3ddev->GetTransform(D3DTS_TEXTURE0, &mTexture);
D3DXMATRIX mTrans, mScale;
D3DXMatrixScaling(&mScale, 1.0f, -1.0f, 1.0f);
D3DXMatrixTranslation(&mTrans, 0.0f, CY, 0.0f); // to adjust off-center y
mTexture = mTexture * mTrans * mScale;
d3ddev->SetTransform(D3DTS_TEXTURE0, &mTexture);//*/
}
}
}
void D3D_DI::Perspective(float f)
{
float AX,AY;
AX = ActivRect.right - ActivRect.left;
AY = ActivRect.bottom - ActivRect.top;
f32 zn = 0.001f;
f32 zf = 1000.0f;
if (f < 0.0f)
{
f32 _4x4[16] = {
-2.0f/f,0, 0, 0,
0, -2.0f/f*AX/AY, 0, 0,
0, 0, -0.1, 0,
0, 0, 0, 1,
};
f32 _4x4Offset[16] = { // need to offset bcz OGL has NDC z values -1 to 1 but D3D has 0 to 1
1 ,0, 0, 0,
0, 1, 0, 0,
0, 0, 0.5f, 0,
0, 0, 0.5f, 1,
};
D3DXMatrixMultiply((D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4Offset);
SetMatrix(0, _4x4);
} else
{
f32 _4x4[16] = {
f, 0, 0, 0,
0,f*AX/AY, 0, 0,
0, 0, 0, 1,//zf/(zf-zn) , 1,
0, 0, 0.1, 0,//-zn*zf/(zf-zn), 0,
};
f32 _4x4Offset[16] = {
1 ,0, 0, 0,
0, 1, 0, 0,
0, 0, 0.5f, 0,
0, 0, 0.5f, 1,
};
D3DXMatrixMultiply((D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4Offset);
SetMatrix(0, _4x4);
}
fFocUsed = f;
}
void D3D_DI::Holographic(Vector *pUP,float wx)
{
f32 AX,AY;
f32 f;
AX = ActivRect.right - ActivRect.left;
AY = ActivRect.bottom - ActivRect.top;
f = pUP->z / wx ;
f32 Xp = (pUP->x );
f32 Yp = (pUP->y );
f32 Zp = (-pUP->z );
f32 _4x4[16] =
{
-f, 0, 0, 0,
0, -f*AX/AY, 0, 0,
Xp/wx, Yp/wx*AX/AY, -pUP->z * 0.025, 1,
0, 0, 0.1, pUP->z,
};
f32 _4x4Offset[16] = {
1 ,0, 0, 0,
0, 1, 0, 0,
0, 0, 0.5f, 0,
0, 0, 0.5f, 1,
};
D3DXMatrixMultiply((D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4,
(D3DXMATRIX*)_4x4Offset);
SetMatrix(0, _4x4);
return;
}
#define MACRO_OrthoMat(l,r,b,t,n,f)\
{\
2/(r-l),0, 0, -(r+l)/(r-l),\
0, 2/(t-b),0, -(t+b)/(t-b),\
0, 0, -2/(f-n), -(f+n)/(f-n),\
0, 0, 0, 1,\
};
void D3D_DI::Ortho() // PIXEL mode ortho (ex Draw point 10,10 mean pixel 10,10)
{
float AreaX,AreaY;
AreaX = CurrentRect.right - CurrentRect.left;
AreaY = CurrentRect.bottom - CurrentRect.top;
float areaYX = AreaY/AreaX;
D3DXMATRIX proj;
D3DXMatrixIdentity(&proj);
//d3ddev->SetTransform(D3DTS_PROJECTION, &proj);
SetMatrix(0, (float*)&proj);
float _4x4[16] =
MACRO_OrthoMat((-1.0), (1.0f), (AreaY/AreaX), (-AreaY/AreaX), (-1.0), (1.0));
SetMatrix(0,_4x4);
fFocUsed = 0;
}
void D3D_DI::Clear(u32 Color)
{
MousePickingCurrentZ = -100000000.0f;
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
//Color = 0xFF123456;
D3DCOLOR color = D3DCOLOR_ARGB((Color >> 24) & 0xFF,(Color)&0xFF, (Color>>8)&0xFF, (Color>>16)&0xFF);
if(QuadHideColor & 1)
{
int alpha = (QuadHideColor & 2) ? 0 : D3DCOLORWRITEENABLE_ALPHA;
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, alpha);
ClearColorWithQuad(Color);
}
else
{
int alpha = (QuadHideColor & 2) ? 0 : D3DCOLORWRITEENABLE_ALPHA;
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE,
D3DCOLORWRITEENABLE_RED |
D3DCOLORWRITEENABLE_GREEN |
D3DCOLORWRITEENABLE_BLUE | alpha);
if(alpha) // if write all, use simple clear
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
}
else // else if selective clear, use quad clear
{
ClearColorWithQuad(Color);
}
}
//*/
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, NULL, 0.0f, 0);
//d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
ZBIas = 1.0f;
FORCE_RENDER_FLAG |= 4;//*/
};
void D3D_DI::ClearZ()
{
MousePickingCurrentZ = -100000000.0f;
//d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, NULL, 0.0f, 0);
ZBIas = 1.0f;
FORCE_RENDER_FLAG |= 4;
};
void D3D_DI::Matrix(MATRIX *MatrixToSet)
{
//glMatrixMode(GL_MODELVIEW);
D3DXMATRIX mat;
if (MatrixToSet)
{
float _4x4[16];
memset(_4x4, 0, sizeof(_4x4));
*(Vector *)&_4x4[0] = MatrixToSet->I;
*(Vector *)&_4x4[4] = MatrixToSet->J;
*(Vector *)&_4x4[8] = MatrixToSet->K;
*(Vector *)&_4x4[12] = MatrixToSet->T;
_4x4[15] = 1.0f;
memcpy(&mat, _4x4, sizeof(D3DXMATRIX));
} else // identity mat
{
D3DXMatrixIdentity(&mat);
}
d3ddev->SetTransform(D3DTS_WORLD, &mat);
}
void D3D_DI::ToggleTextures(bool state)
{
if (state==true) EnableTextureOps();
else DisableTextureOps();
}
#define ENABLE(a,b) { b!=0 ? d3ddev->SetRenderState(a, true) : d3ddev->SetRenderState(a, false); }
//#pragma optimize ("",off)
void D3D_DI::SetRS(RS *RM1,u32 TextureIndex)
{
RS LocalRM;
LocalRM = *RM1;
if (MotherClass)
{
u8 *pBase,*pEnd,*pOr,*pAnd;
pBase = (u8*)&LocalRM;
pEnd = pBase + sizeof(RS);
pOr = (u8*)&(MotherClass->MaterialOr.RenderState);
pAnd = (u8*)&(MotherClass->MaterialAnd.RenderState);
while (pBase < pEnd) *(pBase++) = (*(pBase) & *(pAnd++)) | *(pOr++);
TextureIndex = ( TextureIndex & MotherClass->MaterialAnd.TextureMediaIndex) | MotherClass->MaterialOr.TextureMediaIndex;
}
if (FORCE_RENDER_FLAG & (4+8))
{
LastRS = LocalRM;
u8 Xor,*pBase,*pEnd;
pBase = (u8*)&LastRS;
pEnd = pBase + sizeof(RS);
while (pBase < pEnd) *(pBase++) ^= 0xff;
FORCE_RENDER_FLAG &= ~4;
}
if (LastRS.BACKFACE != LocalRM.BACKFACE)
{
if (LocalRM.BACKFACE)
{
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
} else
{
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
}
}
if (FORCE_RENDER_FLAG & 2)
{
d3ddev->SetRenderState(D3DRS_ZENABLE, false);
}
else
{
if (LastRS.NOZTEST != LocalRM.NOZTEST)
ENABLE(D3DRS_ZENABLE,(LocalRM.NOZTEST^1));
}
if (LastRS.WIRED != LocalRM.WIRED)
{
d3ddev->SetRenderState(D3DRS_FILLMODE, LocalRM.WIRED == 0 ? D3DFILL_SOLID : D3DFILL_WIREFRAME);
}
if (FORCE_RENDER_FLAG & 1)
d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, false);
else
{
if (LastRS.NOZWRITE != LocalRM.NOZWRITE)
d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, LocalRM.NOZWRITE == 0 ? true : false);
}
if (LastRS.BACKFACE_INVERT != LocalRM.BACKFACE_INVERT && LocalRM.BACKFACE)
{
d3ddev->SetRenderState(D3DRS_CULLMODE, LocalRM.BACKFACE_INVERT == 0 ? D3DCULL_CCW : D3DCULL_CW);
}
if (LastRS.TEXTURED != LocalRM.TEXTURED)
ToggleTextures(LocalRM.TEXTURED);
if (LastRS.SECONDPASS != LocalRM.SECONDPASS)
{
if (LocalRM.SECONDPASS)
{
u32 Counter;
float _4x4[16];
GetMatrix(1, _4x4);
Counter = 15;
while (Counter--) _4x4[Counter] *= 0.995f;
SetMatrix(1, _4x4);
}
}
if (LastRS.BlendingMode != LocalRM.BlendingMode)
{
if (LocalRM.BlendingMode)
{
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
switch (LocalRM.BlendingMode)
{
case 1: //Alpha
//LocalRM.AlphaThreshold = 5;
if (LocalRM.INVERTALPHA) {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
} else {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
break;
case 2: //add
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
break;
case 3: //Alpha premult
if (LocalRM.INVERTALPHA) {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
} else {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
break;
case 4: //PREVIOUS ALPHA
if (LocalRM.INVERTALPHA) {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTALPHA);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
}
else {
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
}
break;
case 5: //Multiply
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
break;
case 6: //Multiply Invert
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
break;
case 7: //Multiply x2
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
break;
}
}
else
{
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
}
}
if (LastRS.AlphaThreshold != LocalRM.AlphaThreshold)
{
if (LocalRM.AlphaThreshold)
{
d3ddev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
d3ddev->SetRenderState(D3DRS_ALPHAREF, LocalRM.AlphaThreshold);
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, true);
}
else
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, false);
}
if (/*LocalRM.AnimFPS && */(LocalRM.AnimNbX != 1 || LocalRM.AnimNbY != 1))
{
float NewUVMatrix[6];
u16 TextureIdx, XTextureIdx, YTextureIdx;
NewUVMatrix[0] = LocalRM.UVMATRIX[0]/LocalRM.AnimNbX;
NewUVMatrix[1] = LocalRM.UVMATRIX[1]/LocalRM.AnimNbX;
NewUVMatrix[2] = LocalRM.UVMATRIX[2]/LocalRM.AnimNbY;
NewUVMatrix[3] = LocalRM.UVMATRIX[3]/LocalRM.AnimNbY;
if (LocalRM.AnimTime)
{
TextureIdx = ((int)((double)(timeGetTime() - LocalRM.AnimTime) *LocalRM.AnimFPS / 1000)) % (LocalRM.AnimNbX*LocalRM.AnimNbY);
XTextureIdx = TextureIdx % LocalRM.AnimNbX;
YTextureIdx = TextureIdx / LocalRM.AnimNbX;
YTextureIdx = LocalRM.AnimNbY - YTextureIdx - 1;
} else
{
XTextureIdx = 0;
YTextureIdx = LocalRM.AnimNbY - 1;
}
NewUVMatrix[4] = (LocalRM.UVMATRIX[0] + LocalRM.UVMATRIX[1])*XTextureIdx/LocalRM.AnimNbX + LocalRM.UVMATRIX[4];
NewUVMatrix[5] = (LocalRM.UVMATRIX[2] + LocalRM.UVMATRIX[3])*YTextureIdx/LocalRM.AnimNbY + LocalRM.UVMATRIX[5];
Setexture(TextureIndex, NewUVMatrix);
} else
Setexture(TextureIndex, LocalRM.UVMATRIX);
if (LocalRM.TEXTUREREPEAT_U)
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
else
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
if (LocalRM.TEXTUREREPEAT_V)
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
else
d3ddev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
if (LocalRM.TEXTUREBILINEAR)
{
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
} else
{
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
}
DWORD ZFonc = D3DCMP_GREATEREQUAL;
u32 ZNeedUpdate = 0;
if (LastRS.ZEQUAL != LocalRM.ZEQUAL)
{
ZNeedUpdate = 1;
if (LocalRM.ZEQUAL)
ZFonc = D3DCMP_EQUAL;
}
if (LastRS.ZPASS != LocalRM.ZPASS)
{
ZNeedUpdate = 1;
if (LocalRM.ZPASS)
ZFonc = D3DCMP_ALWAYS;
}
if (ZNeedUpdate)
d3ddev->SetRenderState(D3DRS_ZFUNC, ZFonc);
if (LastRS.HIDECOLOR != LocalRM.HIDECOLOR)
{
if (LocalRM.HIDECOLOR)
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, 0x00000000 | (LocalRM.HIDEALPHA ? 0x00 : D3DCOLORWRITEENABLE_ALPHA));
else
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | (LocalRM.HIDEALPHA ? 0x00 : D3DCOLORWRITEENABLE_ALPHA));
}
if ((LastRS.MappingMode == 3) ||(LastRS.MappingMode == 2))
{
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); // disable texture generation
}
if (LastRS.MappingMode != LocalRM.MappingMode)
{
if (LocalRM.MappingMode)
{
switch (LocalRM.MappingMode)
{
//case 0:
// d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
// break;
case 1: //chrome
{
D3DXMATRIX mTrans, mScale, mTexture, mPersp, mWorld, mView;
d3ddev->GetTransform(D3DTS_TEXTURE0, &mTexture);
d3ddev->GetTransform(D3DTS_WORLD, &mWorld);
d3ddev->GetTransform(D3DTS_VIEW, &mView);
D3DXMatrixTranslation(&mTrans, 0.5, 0.5, -1);
D3DXMatrixScaling(&mScale, -0.5, -0.5, -0.5);
D3DXMATRIX mScale2, mTrans2;
D3DXMatrixTranslation(&mTrans2, 0.0f, 1.0f, 0.0f);
D3DXMatrixScaling(&mScale2, 1.0f, -1.0f, 1.0f);
mWorld._41 = mWorld._42 = mWorld._43 = 0.0f;
//mTexture = mScale2 * mTrans2 * mTexture * mScale * mWorld * mTrans;
mTexture = mScale * mWorld * mTrans * mTexture;
d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU);
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
SetMatrix(2, (float *)&mTexture);
}
break;
case 2: //Planar Z
{
f32 _4x4_Persp[16]; D3DXMATRIX mPersp;
f32 _4x4_Model[16]; D3DXMATRIX mWorld;
f32 _4x4_Texture[16]; D3DXMATRIX mTexture;
GetMatrix(0, _4x4_Persp); memcpy(mPersp, _4x4_Persp, sizeof(D3DXMATRIX));
GetMatrix(1, _4x4_Model); memcpy(mWorld, _4x4_Model, sizeof(D3DXMATRIX));
GetMatrix(2, _4x4_Texture); memcpy(mTexture, _4x4_Texture, sizeof(D3DXMATRIX));
D3DXMATRIX mView, mModelView, mInvModelView;
d3ddev->GetTransform(D3DTS_VIEW, &mView);
mModelView = mWorld * mView;
f32 det = D3DXMatrixDeterminant(&mModelView);
D3DXMatrixInverse(&mInvModelView, &det, &mModelView);
mTexture = mInvModelView * mTexture;
d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
SetMatrix(2, (float*)&mTexture);
}
break;
case 3: //Screen
{
D3DXMATRIX mTrans, mScale, mTexture, mPersp;
d3ddev->GetTransform(D3DTS_TEXTURE0, &mTexture);
//d3ddev->GetTransform(D3DTS_PROJECTION, &mPersp);
GetMatrix(0, (float*)&mPersp);
//D3DXMatrixIdentity(&mTexture);
D3DXMatrixTranslation(&mTrans, 0.5, 0.5, 0);
if (TextureIndex != -1) D3DXMatrixScaling(&mScale, 0.5f, 0.5f * ((float)FB_SY / (float)FB_SX) * (float)AllRef[TextureIndex].pExtRef->SX/(float)AllRef[TextureIndex].pExtRef->SY, 1);
mTexture = mPersp * mScale * mTrans * mTexture;
d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
SetMatrix(2, (float*)&mTexture);
}
break;
}
}
}
CurrentRS = LocalRM;
LastRS = LocalRM;
if (FORCE_RENDER_FLAG & 2)
{
LastRS.NOZTEST = 1;
}
if (FORCE_RENDER_FLAG & 1)
{
LastRS.NOZWRITE = 1;
}
//*/
}
void D3D_DI::GetMatrix(u32 Mode,float *pDest)
{
D3DXMATRIX mat, temp, mScale, mTrans;
switch (Mode)
{
case 0: // Projection
d3ddev->GetTransform(D3DTS_PROJECTION, &mat);
D3DXMatrixIdentity(&mTrans);
mTrans._41 = 0.5f*2.0f/(float)CurrentViewport[2];
mTrans._42 = -0.5f*2.0f/(float)CurrentViewport[3];
mat = mat * mTrans;//*/
break;
case 1: // Model
d3ddev->GetTransform(D3DTS_WORLD, &mat);
break;
case 2: // Texture
d3ddev->GetTransform(D3DTS_TEXTURE0, &mat);
/*D3DXMATRIX mScale, mTrans;
D3DXMatrixScaling(&mScale, 1.0f, -1.0f, 1.0f);
D3DXMatrixTranslation(&mTrans, 0.0f, 1.0f, 0.0f);
mat = mat * mScale * mTrans;//*/
break;
}
memcpy(pDest, &mat, sizeof(D3DXMATRIX));
}
void D3D_DI::SetMatrix(u32 Mode,float *pDest)
{
D3DXMATRIX mScale, mTrans, mTex, mProj;
switch (Mode)
{
case 0://Projection
memcpy(&mProj, pDest, sizeof(D3DXMATRIX));
//D3DXMatrixTranslation(&mTrans, -0.5f*2.0f/(float)CurrentViewport[2], 0.5f*2.0f/(float)CurrentViewport[3], 0.0f);
//D3DXMatrixIdentity(&mTrans);
//mTrans._41 = 0.5f*2.0f/(float)CurrentViewport[2];
//mTrans._42 = -0.5f*2.0f/(float)CurrentViewport[3];
D3DXMatrixIdentity(&mTrans);
mTrans._41 = -0.5f*2.0f/(float)CurrentViewport[2];
mTrans._42 = 0.5f*2.0f/(float)CurrentViewport[3];
mProj = mProj * mTrans;
d3ddev->SetTransform(D3DTS_PROJECTION, &mProj);
break;
case 1://Model
d3ddev->SetTransform(D3DTS_WORLD, (D3DXMATRIX*)pDest);
break;
case 2://Texture
memcpy(&mTex, pDest, sizeof(D3DXMATRIX));
D3DXMatrixScaling(&mScale, 1.0f, -1.0f, 1.0f);
D3DXMatrixTranslation(&mTrans, 0.5f*1.0f/FB_SX, 0.5f*1.0f/FB_SY, 0.0f);
//mTex = mTrans * mTex;//*/
d3ddev->SetTransform(D3DTS_TEXTURE0, &mTex);
break;
}
//*/
}
void D3D_DI::EnableTextureOps()
{
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1 , D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2 , D3DTA_DIFFUSE);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1 , D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG2 , D3DTA_DIFFUSE);
}
void D3D_DI::DisableTextureOps()
{
d3ddev->SetTexture(0, NULL);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1 , D3DTA_DIFFUSE);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1 , D3DTA_DIFFUSE);
//*/
}
void D3D_DI::SafeCopyTextureFromBackBuffer(LPDIRECT3DTEXTURE9* ppDest, int xOffset, int yOffset,
int x, int y, int width, int height, bool isLuminance)
{
HRESULT result;
D3DSURFACE_DESC desc;
LPDIRECT3DTEXTURE9 pDest = *ppDest;
pDest->GetLevelDesc(0, &desc);
if ((desc.Usage & D3DUSAGE_RENDERTARGET) == 0)
{
pDest->Release();
result = D3DXCreateTexture(d3ddev,
desc.Width, desc.Height,
1, D3DUSAGE_RENDERTARGET, desc.Format,
D3DPOOL_DEFAULT, ppDest);
pDest = *ppDest;
assert (result == D3D_OK);
/*
D3DSURFACE_DESC desc;
_D3D_TEX(pDest)->GetLevelDesc(0, &desc);
D3DLOCKED_RECT lockedRect;
_D3D_TEX(pDest)->LockRect(0, &lockedRect, 0, 0); // lock entire texture
DWORD* imageData = (DWORD*)lockedRect.pBits;
int HEIGHT = desc.Height;
int PITCH = lockedRect.Pitch;
memset(imageData, 0x00, PITCH*HEIGHT); // set default to all black
_D3D_TEX(pDest)->UnlockRect(0);
//*/
}
CopyTextureFromBackBuffer(pDest, xOffset, yOffset, x, y, width, height, isLuminance);
}
void D3D_DI::CopyTextureFromBackBuffer(LPDIRECT3DTEXTURE9 pDest, int xOffset, int yOffset,
int x, int y, int width, int height, bool isLuminance)
{
HRESULT result = D3D_OK;
LPDIRECT3DSURFACE9 fb = NULL, tb = NULL, sb = NULL;
D3DSURFACE_DESC sbDesc, tbDesc, fbDesc;
result = pDest->GetSurfaceLevel(0, &tb); assert(result==D3D_OK);
result = tb->GetDesc(&tbDesc); assert(result==D3D_OK);
result = d3ddev->GetRenderTarget(0, &fb); assert(result==D3D_OK);
result = fb->GetDesc(&fbDesc); assert(result==D3D_OK);
int right = x + width;
right = right > FB_SX ? FB_SX : right;
int bottom = y + height;
bottom = bottom > FB_SY ? FB_SY : bottom;
int clampedWidth = right - x;
int clampedHeight = bottom - y;
if (srTex == NULL)
{
result = D3DXCreateTexture(d3ddev, FB_SX, FB_SY,
1, D3DUSAGE_RENDERTARGET, tbDesc.Format, D3DPOOL_DEFAULT, &srTex); assert(result==D3D_OK);
}
// Get surface to temp tex
result = srTex->GetSurfaceLevel(0, &sb); assert(result==D3D_OK);
result = sb->GetDesc(&sbDesc); assert(result==D3D_OK);
if (sbDesc.Width != FB_SX || sbDesc.Height != FB_SY)
{
// If temp tex and working tex dimensions dont match,
// Create a new temp tex
sb->Release();
srTex->Release();
result = D3DXCreateTexture(d3ddev,
FB_SX, FB_SY,
1, D3DUSAGE_RENDERTARGET,
tbDesc.Format, D3DPOOL_DEFAULT, &srTex); assert(result==D3D_OK);
result = srTex->GetSurfaceLevel(0, &sb); assert(result==D3D_OK);
result = sb->GetDesc(&sbDesc); assert(result==D3D_OK);
}
//*/
RECT fbRect = {x, FB_SY - clampedHeight - y, x + clampedWidth, FB_SY - y};
RECT sbRect = {0, 0, clampedWidth, clampedHeight};
RECT tbRect = {xOffset, yOffset, xOffset + clampedWidth, yOffset + clampedHeight};
// Copy frame buffer to temp texture
result = d3ddev->StretchRect(fb , &fbRect, sb, &sbRect, D3DTEXF_LINEAR); assert(result==D3D_OK);
D3DVIEWPORT9 fbPort;
D3DVIEWPORT9 tbPort = {xOffset, yOffset, clampedWidth, clampedHeight, 0.0f, 1.0f} ;
// Save all states
result = d3ddev->GetViewport(&fbPort); assert(result == D3D_OK);
DWORD colorWriteEnable, zEnable, cullMode, alphaBlend, alphaTest;
DWORD textureTransFlag, colorOp, alphaOp, colorArg1, colorArg2, alphaArg, colorConstant;
DWORD textureTransFlags2, colorOps2, alphaOps2, colorArg1s2, colorArg2s2, alphaArgs2, colorConstants2;
d3ddev->GetRenderState(D3DRS_COLORWRITEENABLE, &colorWriteEnable);
d3ddev->GetRenderState(D3DRS_ZENABLE, &zEnable);
d3ddev->GetRenderState(D3DRS_CULLMODE, &cullMode);
d3ddev->GetRenderState(D3DRS_ALPHATESTENABLE, &alphaTest);
d3ddev->GetRenderState(D3DRS_ALPHABLENDENABLE, &alphaBlend);
d3ddev->GetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, &textureTransFlag);
d3ddev->GetTextureStageState(0, D3DTSS_CONSTANT, &colorConstant);
d3ddev->GetTextureStageState(0, D3DTSS_COLOROP, &colorOp);
d3ddev->GetTextureStageState(0, D3DTSS_ALPHAOP, &alphaOp);
d3ddev->GetTextureStageState(0, D3DTSS_COLORARG1, &colorArg1);
d3ddev->GetTextureStageState(0, D3DTSS_COLORARG2, &colorArg2);
d3ddev->GetTextureStageState(0, D3DTSS_ALPHAARG1, &alphaArg);
SAVE_MATRIXES();
// Set new states
result = d3ddev->SetRenderTarget(0, tb); assert(result == D3D_OK);
result = d3ddev->SetViewport(&tbPort); assert(result == D3D_OK);
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE,
D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
d3ddev->SetRenderState(D3DRS_ZENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
d3ddev->SetTexture(0, srTex);
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
D3DXMATRIX identityMat;
D3DXMatrixIdentity(&identityMat);
//result = d3ddev->SetTransform(D3DTS_PROJECTION, &identityMat); assert(result==D3D_OK);
SetMatrix(0, (float*)&identityMat);
result = d3ddev->SetTransform(D3DTS_WORLD, &identityMat); assert(result==D3D_OK); ;
if (isLuminance || tbDesc.Format == D3DFMT_X8R8G8B8) // copy to dest buffer in black and white. alpha is all 1
{
d3ddev->GetTextureStageState(1, D3DTSS_CONSTANT, &colorConstants2);
d3ddev->GetTextureStageState(1, D3DTSS_COLOROP, &colorOps2);
d3ddev->GetTextureStageState(1, D3DTSS_COLORARG1, &colorArg1s2);
d3ddev->GetTextureStageState(1, D3DTSS_COLORARG2, &colorArg2s2);
//*/
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, // we dont want dotproduct to interfere with alpha
D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
d3ddev->SetTextureStageState(0, D3DTSS_CONSTANT, 0x80808080);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MULTIPLYADD);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG0, D3DTA_CONSTANT);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(1, D3DTSS_CONSTANT, ( 0x00 << 24 ) | ((int)(0.5f*(255 + 255)) << 16) | ((int)(0.5f*(255 + 0)) << 8) | (int)(0.5f*(255 + 0)));
d3ddev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
d3ddev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
d3ddev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CONSTANT);
}
// And draw!
DrawQuad(0xffffffff, -1.0f, -1.0f, 2.0f, 2.0f, 0.0f, 0.0f, clampedWidth/(float)FB_SX, clampedHeight/(float)FB_SY);
// Restore all states
RESTORE_MATRIXES();
result = d3ddev->SetRenderTarget(0, fb); assert(result==D3D_OK);
result = d3ddev->SetViewport(&fbPort); assert(result==D3D_OK);
if (isLuminance || tbDesc.Format == D3DFMT_X8R8G8B8)
{
//d3ddev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
d3ddev->SetTextureStageState(1, D3DTSS_CONSTANT, colorConstants2);
d3ddev->SetTextureStageState(1, D3DTSS_COLOROP, colorOps2);
d3ddev->SetTextureStageState(1, D3DTSS_COLORARG1, colorArg1s2);
d3ddev->SetTextureStageState(1, D3DTSS_COLORARG2, colorArg2s2);
//*/
}
d3ddev->SetTextureStageState(0, D3DTSS_CONSTANT, colorConstant);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, colorOp);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, alphaOp);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, colorArg1);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, colorArg2);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, alphaArg);
d3ddev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, textureTransFlag);
d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, colorWriteEnable);
d3ddev->SetRenderState(D3DRS_ZENABLE, zEnable);
d3ddev->SetRenderState(D3DRS_CULLMODE, cullMode);
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, alphaTest);
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlend);
//*/
if (fb) fb->Release();
if (tb) tb->Release();
if (sb) sb->Release();
}
void D3D_DI::ClearColorWithQuad(unsigned int color)
{
HRESULT result;
DWORD zEnable, zWriteEnable, cullMode, texFactor;
DWORD colorOp, alphaOp, colorArg, alphaArg, alphaBlend, alphaTest;
D3DVIEWPORT9 oldPort;
d3ddev->GetRenderState(D3DRS_ZENABLE, &zEnable);
d3ddev->GetRenderState(D3DRS_ZWRITEENABLE, &zWriteEnable);
d3ddev->GetRenderState(D3DRS_CULLMODE, &cullMode);
d3ddev->GetRenderState(D3DRS_ALPHATESTENABLE, &alphaTest);
d3ddev->GetRenderState(D3DRS_ALPHABLENDENABLE, &alphaBlend);
d3ddev->GetRenderState(D3DRS_TEXTUREFACTOR, &texFactor);
d3ddev->GetTextureStageState(0, D3DTSS_COLOROP, &colorOp);
d3ddev->GetTextureStageState(0, D3DTSS_ALPHAOP, &alphaOp);
d3ddev->GetTextureStageState(0, D3DTSS_COLORARG1, &colorArg);
d3ddev->GetTextureStageState(0, D3DTSS_ALPHAARG1, &alphaArg);
result = d3ddev->GetViewport(&oldPort);
SAVE_MATRIXES();
// Set new states
IDirect3DSurface9* pSurface = NULL;
d3ddev->GetRenderTarget(0, &pSurface);
D3DSURFACE_DESC surfaceDesc;
pSurface->GetDesc(&surfaceDesc);
pSurface->Release();
D3DVIEWPORT9 vPort = {0.0f, 0.0f, surfaceDesc.Width, surfaceDesc.Height, 0, 1};
//result = d3ddev->SetViewport(&vPort); assert(result == D3D_OK);
d3ddev->SetRenderState(D3DRS_ZENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
d3ddev->SetRenderState(D3DRS_TEXTUREFACTOR, color);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
D3DXMATRIX identityMat;
D3DXMatrixIdentity(&identityMat);
//result = d3ddev->SetTransform(D3DTS_PROJECTION, &identityMat); assert(result==D3D_OK);
SetMatrix(0, (float*)&identityMat);
result = d3ddev->SetTransform(D3DTS_WORLD, &identityMat); assert(result==D3D_OK); ;
// And draw!
DrawQuad(color, -1.0f, -1.0f, 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f);
// Restore all states
RESTORE_MATRIXES();
//result = d3ddev->SetRenderTarget(0, fb); assert(result==D3D_OK);
result = d3ddev->SetViewport(&oldPort); assert(result==D3D_OK);
d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, colorOp);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, alphaOp);
d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, colorArg);
d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, alphaArg);
d3ddev->SetRenderState(D3DRS_TEXTUREFACTOR, texFactor);
d3ddev->SetRenderState(D3DRS_ZENABLE, zEnable);
d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, zWriteEnable);
d3ddev->SetRenderState(D3DRS_CULLMODE, cullMode);
d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, alphaTest);
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, alphaBlend);
}
void D3D_DI::ModifyTextureTranslation(D3DXMATRIX* pMat)
{
pMat->_31 = pMat->_41; pMat->_41 = 0.0f;
pMat->_32 = pMat->_42; pMat->_42 = 0.0f;
}
#endif