1649 lines
55 KiB
C++
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,¶m);
|
|
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,¶m);
|
|
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
|