/*============================================================================= D3DCGVProgram.h : Direct3D CG programs interface declaration. Copyright 1999 K&M. All Rights Reserved. Revision history: * Created by Honitch Andrey =============================================================================*/ #ifndef __D3DCGVPROGRAM_H__ #define __D3DCGVPROGRAM_H__ #include "cg\cgD3D9.h" #include #define CG_VP_CACHE_VER 3.4 #define VSCONST_0_025_05_1 28 #define VSCONST_FOG 29 #define PSCONST_HDR_FOGCOLOR 31 class CCGVProgram_D3D : public CVProgram { SCGScript *m_Script; SCGScript *m_PosScript; SCGScript *m_SubroutinesScript; SCGScript *m_DeclarationsScript; SCGScript *m_CoreScript; SCGScript *m_InputParmsScript; // FX support std::vector m_Functions; CName m_EntryFunc; bool ActivateCacheItem(SShaderCacheHeaderItem *pItem); bool CreateCacheItem(int nMask, byte *pData, int nLen); TArray m_ParamsNoObj; TArray m_ParamsObj; TArray m_MatrixObj; TArray m_Pointers; int m_CurInst; struct SCacheInstance { int m_Mask; SShaderCache *m_pCache; SCacheInstance() { m_Mask = 0; m_pCache = NULL; } int Size() { int nSize = sizeof(*this); return nSize; } }; struct SCGInstance { int m_Mask; int m_LightMask; CName m_PosScriptName; TArray *m_ParamsNoObj; TArray *m_MatrixNoObj; TArray *m_ParamsObj; TArray *m_MatrixObj; TArray *m_BindConstants; TArray *m_BindVars; int m_nCacheID; union { CGprogram m_CGProgram; void *m_pHandle; }; SCGInstance() { m_Mask = 0; m_LightMask = 0; m_ParamsNoObj = NULL; m_ParamsObj = NULL; m_MatrixNoObj = NULL; m_MatrixObj = NULL; m_BindConstants = NULL; m_BindVars = NULL; m_pHandle = NULL; m_nCacheID = -1; } int Size() { int nSize = sizeof(*this); if (m_ParamsNoObj) nSize += m_ParamsNoObj->GetMemoryUsage()+12; if (m_ParamsObj) nSize += m_ParamsObj->GetMemoryUsage()+12; if (m_MatrixNoObj) nSize += m_MatrixNoObj->GetMemoryUsage()+12; if (m_MatrixObj) nSize += m_MatrixObj->GetMemoryUsage()+12; if (m_BindConstants) nSize += m_BindConstants->GetMemoryUsage()+12; if (m_BindVars) nSize += m_BindVars->GetMemoryUsage()+12; return nSize; } }; TArray m_Insts; TArray m_InstCache; public: int m_dwFrame; TArray m_Params_Inst; virtual int Size() { int nSize = sizeof(*this); for (int i=0; iSize(); } else nSize += sizeof(SCGInstance); } if (m_Script) nSize += m_Script->Size(false); if (m_PosScript) nSize += m_PosScript->Size(false); if (m_SubroutinesScript) nSize += m_SubroutinesScript->Size(false); if (m_DeclarationsScript) nSize += m_DeclarationsScript->Size(false); if (m_CoreScript) nSize += m_CoreScript->Size(false); if (m_InputParmsScript) nSize += m_InputParmsScript->Size(false); nSize += m_ParamsObj.GetMemoryUsage(); nSize += m_ParamsNoObj.GetMemoryUsage(); nSize += m_MatrixObj.GetMemoryUsage(); return nSize; } void mfSaveCGFile(const char *scr) { if (CRenderer::CV_r_shaderssave < 1) return; char name[1024]; if (m_nMaskGen) sprintf(name, "%s$%x(%x).cg", m_Name.c_str(), m_Insts[m_CurInst].m_LightMask, m_nMaskGen); else sprintf(name, "%s.cg", m_Name.c_str()); FILE *fp = fopen(name, "w"); if (fp) { fprintf(fp, scr); fclose (fp); } } CCGVProgram_D3D() { mfInit(); m_CGProfileType = CG_PROFILE_VS_1_1; } void mfInit() { #ifndef WIN64 // NOTE: AMD64 port: find the 64-bit CG runtime if (!gcpRendD3D->m_CGContext) { cgD3D9SetDevice(gcpRendD3D->mfGetD3DDevice()); gcpRendD3D->m_CGContext = cgCreateContext(); assert(gcpRendD3D->m_CGContext); #ifdef _DEBUG cgD3D9EnableDebugTracing(true); #endif } #endif m_dwFrame = 1; m_CurInst = -1; m_Script = NULL; m_SubroutinesScript = NULL; m_CoreScript = NULL; m_InputParmsScript = NULL; m_PosScript = NULL; m_DeclarationsScript = NULL; m_bCGType = true; } void mfFree(); void mfGetSrcFileName(char *srcname, int nSize); void mfGetDstFileName(char *dstname, int nSize, bool bUseASCIICache); TArray *mfGetParams(int Type) { if (!Type) return &m_ParamsNoObj; else return &m_ParamsObj; } void mfUnbind() { gcpRendD3D->mfGetD3DDevice()->SetVertexShader(NULL); } void mfBind() { HRESULT hr; if (m_Insts[m_CurInst].m_pHandle) { hr = gcpRendD3D->mfGetD3DDevice()->SetVertexShader((IDirect3DVertexShader9 *)m_Insts[m_CurInst].m_pHandle); if (FAILED(hr)) return; } if (m_Insts[m_CurInst].m_BindConstants) { int i; for (i=0; iNum(); i++) { SCGBindConst *p = &m_Insts[m_CurInst].m_BindConstants->Get(i); int n = p->m_dwBind; if (m_CurParams[n][0] != p->m_Val[0] || m_CurParams[n][1] != p->m_Val[1] || m_CurParams[n][2] != p->m_Val[2] || m_CurParams[n][3] != p->m_Val[3]) { m_CurParams[n][0] = p->m_Val[0]; m_CurParams[n][1] = p->m_Val[1]; m_CurParams[n][2] = p->m_Val[2]; m_CurParams[n][3] = p->m_Val[3]; gcpRendD3D->mfGetD3DDevice()->SetVertexShaderConstantF(n, &p->m_Val[0], 1); } } } } int mfGetCacheInstanceID(int Mask, const char *name=NULL) { int i; for (i=0; im_cEF.OpenCacheFile(name, (float)CG_VP_CACHE_VER); ci.m_Mask = Mask; m_InstCache.AddElem(ci); return nNum; } int mfGetCGInstanceID(int Type, CVProgram *pPosVP, int LightMask) { CCGVProgram_D3D *pVP = (CCGVProgram_D3D *)pPosVP; SCGInstance *cgc; CName PosName; SCGScript *posScr = pVP->m_PosScript; if (posScr) PosName = posScr->m_Name; else PosName = CName("None"); if (m_CurInst >= 0 && m_Insts.Num() > m_CurInst) { cgc = &m_Insts[m_CurInst]; if (cgc->m_Mask == Type && cgc->m_LightMask == LightMask) { if (!pVP || !posScr || PosName == cgc->m_PosScriptName) return m_CurInst; } } m_dwFrame++; int i; for (i=0; im_Mask == Type && cgc->m_LightMask == LightMask && (!pVP || !posScr || PosName == cgc->m_PosScriptName)) { m_CurInst = i; return i; } } SCGInstance cg; cg.m_Mask = Type; cg.m_LightMask = LightMask; cg.m_BindConstants = NULL; cg.m_BindVars = NULL; cg.m_pHandle = 0; cg.m_CGProgram = NULL; cg.m_ParamsNoObj = NULL; cg.m_MatrixNoObj = NULL; cg.m_ParamsObj = NULL; cg.m_MatrixObj = NULL; if (Type & VPVST_CLIPPLANES3) { if (!cg.m_ParamsNoObj) cg.m_ParamsNoObj = new TArray; SCGParam4f pr; pr.m_nComponents = 1; pr.m_Name = "ClipPlane"; SParamComp_ClipPlane p; pr.m_Flags = PF_CANMERGED; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); } if (Type & VPVST_TCMASK) { if (!cg.m_ParamsNoObj) cg.m_ParamsNoObj = new TArray; int nm = VPVST_TCM0; int ngol = VPVST_TCGOL0; int ngrm = VPVST_TCGRM0; int ngsm = VPVST_TCGSM0; int ngnm = VPVST_TCGNM0; for (int i=0; i<4; i++) { char str[128]; if (Type & (ngol<AddElem(pr); p.m_Row = 1; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); p.m_Row = 2; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); p.m_Row = 3; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); } if (Type & ((ngrm|ngsm)<AddElem(pr); if (!cg.m_MatrixNoObj) cg.m_MatrixNoObj = new TArray; SCGMatrix m; m.m_eCGParamType = ECGP_Matr_View; m.m_Name = "ModelView"; cg.m_MatrixNoObj->AddElem(m); m.m_eCGParamType = ECGP_Matr_View_IT; m.m_Name = "ModelViewIT"; cg.m_MatrixNoObj->AddElem(m); } if (Type & (ngnm<; SCGMatrix m; m.m_eCGParamType = ECGP_Matr_View_IT; m.m_Name = "ModelViewIT"; cg.m_MatrixNoObj->AddElem(m); } if (Type & (nm<AddElem(pr); p.m_Row = 1; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); p.m_Row = 2; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); p.m_Row = 3; pr.m_Comps[0] = SParamComp::mfAdd(&p); cg.m_ParamsNoObj->AddElem(pr); } } } if (pVP && posScr) { cg.m_PosScriptName = PosName; if (cg.m_PosScriptName != m_PosScript->m_Name && pVP->m_ParamsNoObj.Num()) { if (!cg.m_ParamsNoObj) cg.m_ParamsNoObj = new TArray; for (int i=0; im_ParamsNoObj.Num(); i++) { cg.m_ParamsNoObj->AddElem(pVP->m_ParamsNoObj[i]); cg.m_ParamsNoObj->Get(cg.m_ParamsNoObj->Num()-1).m_dwBind = 0; } cg.m_ParamsNoObj->Shrink(); } if (cg.m_PosScriptName != m_PosScript->m_Name && pVP->m_ParamsObj.Num()) { if (!cg.m_ParamsObj) cg.m_ParamsObj = new TArray; for (int i=0; im_ParamsObj.Num(); i++) { cg.m_ParamsObj->AddElem(pVP->m_ParamsObj[i]); cg.m_ParamsObj->Get(cg.m_ParamsObj->Num()-1).m_dwBind = 0; } cg.m_ParamsObj->Shrink(); } } if (cg.m_ParamsNoObj) { TArray ObjP; gRenDev->m_cEF.mfCheckObjectDependParams(cg.m_ParamsNoObj, &ObjP); if (ObjP.Num()) { cg.m_ParamsObj = new TArray; cg.m_ParamsObj->Copy(ObjP); } } m_Insts.AddElem(cg); m_CurInst = m_Insts.Num()-1; return m_CurInst; } char *mfGetObjectCode(CGprogram cgPr) { const char *code = cgGetProgramString(cgPr, CG_COMPILED_PROGRAM); size_t size = strlen(code)+1; char *str = new char[size]; cryMemcpy(str, code, size); return str; } char *mfLoadCG(const char *prog_text) { // NOTE: AMD64 port: find the 64-bit CG runtime CGprofile pr = (CGprofile)m_CGProfileType; char *Buf = fxReplaceInText((char *)prog_text, "vertout OUT", "vertout OUT = (vertout)0"); // make command for execution FILE *fp = fopen("$$in.cg", "w"); if (!fp) return NULL; assert (*Buf); fputs(Buf, fp); fclose (fp); char szCmdLine[512]; sprintf(szCmdLine, "fxc.exe /T %s /Zpr /DCGC=0 /Fc $$out.cg $$in.cg", pr == CG_PROFILE_VS_2_0 ? "vs_2_0" : pr == CG_PROFILE_VS_2_X ? "vs_2_a" : pr == CG_PROFILE_VS_3_0 ? "vs_3_0" : "vs_1_1"); if (m_EntryFunc.GetIndex()) { strcat(szCmdLine, " /E "); strcat(szCmdLine, m_EntryFunc.c_str()); } STARTUPINFO si; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); si.dwX = 100; si.dwY = 100; si.dwFlags = STARTF_USEPOSITION; PROCESS_INFORMATION pi; ZeroMemory( &pi, sizeof(pi) ); if( !CreateProcess( NULL, // No module name (use command line). szCmdLine, // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. CREATE_NO_WINDOW, // No creation flags. NULL, // Use parent's environment block. NULL/*szFolderName*/, // Set starting directory. &si, // Pointer to STARTUPINFO structure. &pi ) // Pointer to PROCESS_INFORMATION structure. ) { iLog->LogError("CreateProcess failed: %s", szCmdLine); return NULL; } while (WAIT_OBJECT_0 != WaitForSingleObject (pi.hProcess, 10000)) iLog->LogWarning ("CG runtime takes forever to compile.. waiting.. (last error %d)", GetLastError()); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); fp = fopen("$$out.cg", "rb"); if (!fp) { Warning( 0,0,"HLSL compiler (fxc.exe) wasn't able to compile vertex shader '%s'", m_Name.c_str()); m_nFailed++; mfSaveCGFile(Buf); remove("$$in.cg"); if (Buf != prog_text) delete [] Buf; return NULL; } fseek(fp, 0, SEEK_END); int size = ftell(fp); fseek(fp, 0, SEEK_SET); if (size < 20) { Warning( 0,0,"HLSL compiler (fxc.exe) wasn't able to compile vertex shader '%s'", m_Name.c_str()); m_nFailed++; mfSaveCGFile(Buf); remove("$$in.cg"); remove("$$out.cg"); if (Buf != prog_text) delete [] Buf; return NULL; } char *pBuf = new char[size+1]; fread(pBuf, sizeof(char), size, fp); pBuf[size] = '\0'; fclose(fp); remove("$$in.cg"); remove("$$out.cg"); if (CRenderer::CV_r_shaderssave == 2) { _chdir("c:\\MasterCD\\TestCG"); mfSaveCGFile(Buf); _chdir("c:\\MasterCD"); } if (Buf != prog_text) delete [] Buf; return pBuf; } LPD3DXBUFFER mfLoad(const char *prog_text) { // Load and create vertex shader HRESULT hr; LPD3DXBUFFER pCode; LPD3DXBUFFER pBuffer = NULL; hr = D3DXAssembleShader(prog_text, strlen(prog_text), NULL, NULL, 0, &pCode, &pBuffer); if (FAILED(hr)) { Warning( 0,0,"WARNING: CCGVProgram_D3D::mfLoad: Could not assemble vertex shader '%s' (%s)\n", m_Name.c_str(), gcpRendD3D->D3DError(hr)); if( pBuffer != NULL) { TCHAR* pstr; TCHAR strOut[4096]; TCHAR* pstrOut; // Need to replace \n with \r\n so edit box shows newlines properly pstr = (TCHAR*)pBuffer->GetBufferPointer(); strOut[0] = '\0'; pstrOut = strOut; for( int i = 0; i < 4096; i++ ) { if( *pstr == '\n' ) *pstrOut++ = '\r'; *pstrOut = *pstr; if( *pstr == '\0' ) break; if( i == 4095 ) *pstrOut = '\0'; pstrOut++; pstr++; } // remove any blank lines at the end while( strOut[lstrlen(strOut) - 1] == '\n' || strOut[lstrlen(strOut) - 1] == '\r' ) { strOut[lstrlen(strOut) - 1] = '\0'; } Warning( 0,0,"WARNING: CCGVProgram_D3D::mfLoad: Shader script error (%s)\n", strOut); SAFE_RELEASE(pBuffer); } } if (pCode && !(m_Flags & VPFI_PRECACHEPHASE)) hr = gcpRendD3D->mfGetD3DDevice()->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), (IDirect3DVertexShader9 **)&m_Insts[m_CurInst].m_pHandle); if (FAILED(hr)) { Warning( 0,0,"CCGVProgram_D3D::mfLoad: Could not create vertex shader '%s' (%s)\n", m_Name.c_str(), gcpRendD3D->D3DError(hr)); return NULL; } return pCode; } SCGBind *mfGetParameterBind(const char *Name) { CName nm = CName(Name, eFN_Add); if (!m_Insts[m_CurInst].m_BindVars) m_Insts[m_CurInst].m_BindVars = new TArray; int i; for (i=0; iNum(); i++) { if (nm == m_Insts[m_CurInst].m_BindVars->Get(i).m_Name) return &m_Insts[m_CurInst].m_BindVars->Get(i); } return NULL; } void mfParameteri(SCGBind *ParamBind, const float *v) { int i; if(!ParamBind) return; if (!ParamBind->m_dwBind || ParamBind->m_dwFrameCreated != m_dwFrame) { ParamBind->m_dwFrameCreated = m_dwFrame; if (m_Insts[m_CurInst].m_BindVars) { for (i=0; iNum(); i++) { SCGBind *p = &m_Insts[m_CurInst].m_BindVars->Get(i); if (p->m_Name == ParamBind->m_Name) { ParamBind->m_dwBind = p->m_dwBind; ParamBind->m_nBindComponents = p->m_nComponents; if (!ParamBind->m_dwBind) ParamBind->m_dwBind = 65536; break; } } if (i == m_Insts[m_CurInst].m_BindVars->Num()) ParamBind->m_dwBind = -1; } else ParamBind->m_dwBind = -1; if (ParamBind->m_dwBind == -1 && CRenderer::CV_r_shaderssave >= 2) iLog->Log("Warning: couldn't find parameter %s for vertex shader %s (%x)", ParamBind->m_Name.c_str(), m_Name.c_str(), m_nMaskGen); } if ((int)ParamBind->m_dwBind == -1) return; int n; int iparms[4]; if (ParamBind->m_dwBind == 65536) n = 0; else n = ParamBind->m_dwBind; if (m_CurParams[n][0] != v[0] || m_CurParams[n][1] != v[1] || m_CurParams[n][2] != v[2] || m_CurParams[n][3] != v[3]) { m_CurParams[n][0] = v[0]; m_CurParams[n][1] = v[1]; m_CurParams[n][2] = v[2]; m_CurParams[n][3] = v[3]; iparms[0] = (int)v[0]; iparms[1] = (int)v[1]; iparms[2] = (int)v[2]; iparms[3] = (int)v[3]; gcpRendD3D->mfGetD3DDevice()->SetVertexShaderConstantI(n, iparms, 1); } v += 4; } void mfParameter(SCGBind *ParamBind, const float *v, int nComps) { if(!ParamBind) { return; } if (!ParamBind->m_dwBind || ParamBind->m_dwFrameCreated != m_dwFrame) { ParamBind->m_dwFrameCreated = m_dwFrame; if (m_Insts[m_CurInst].m_BindVars) { int i; for (i=0; iNum(); i++) { SCGBind *p = &m_Insts[m_CurInst].m_BindVars->Get(i); if (p->m_Name == ParamBind->m_Name) { assert(p->m_nComponents <= nComps); ParamBind->m_dwBind = p->m_dwBind; if (ParamBind->m_dwBind == 0) ParamBind->m_dwBind = 65536; ParamBind->m_nBindComponents = p->m_nComponents; break; } } if (i == m_Insts[m_CurInst].m_BindVars->Num()) ParamBind->m_dwBind = -1; } else ParamBind->m_dwBind = -1; if (ParamBind->m_dwBind == -1 && CRenderer::CV_r_shaderssave >= 2) iLog->Log("Warning: couldn't find parameter %s for vertex shader %s (%x)", ParamBind->m_Name.c_str(), m_Name.c_str(), m_nMaskGen); } if (ParamBind->m_dwBind == -1) return; if (ParamBind->m_dwBind == 65536) { gcpRendD3D->mfGetD3DDevice()->SetVertexShaderConstantF(0, v, 4); //memcpy(&m_CurParams[0][0], v, 4*4*sizeof(float)); } else { for (int i=0; im_nBindComponents; i++) { int n = ParamBind->m_dwBind+i; if (m_CurParams[n][0] != v[0] || m_CurParams[n][1] != v[1] || m_CurParams[n][2] != v[2] || m_CurParams[n][3] != v[3]) { m_CurParams[n][0] = v[0]; m_CurParams[n][1] = v[1]; m_CurParams[n][2] = v[2]; m_CurParams[n][3] = v[3]; gcpRendD3D->mfGetD3DDevice()->SetVertexShaderConstantF(n, v, 1); } v += 4; } } } void mfParameter4i(SCGBind *ParamBind, const vec4_t v) { mfParameteri(ParamBind, v); } void mfParameter4f(SCGBind *ParamBind, const vec4_t v) { mfParameter(ParamBind, v, 1); } void mfParameter4f(const char *Name, const float *v) { SCGBind *pBind = mfGetParameterBind(Name); if (pBind) mfParameter4f(pBind, v); } void mfParameterStateMatrix(SCGMatrix *ParamBind) { static int sFrame; static int sFlags; CD3D9Renderer *r = gcpRendD3D; LPDIRECT3DDEVICE9 dv = r->mfGetD3DDevice(); D3DXMATRIXA16 matWorldViewProj; switch(ParamBind->m_eCGParamType) { case ECGP_Matr_ViewProj: { if (!(r->m_RP.m_ObjFlags & FOB_TRANS_MASK)) { if (r->m_RP.m_PersFlags & RBPF_WASWORLDSPACE) break; r->m_RP.m_PersFlags |= RBPF_WASWORLDSPACE; m_FrameObj = -1; } else { if (r->m_RP.m_PersFlags & RBPF_WASWORLDSPACE) m_FrameObj = -1; r->m_RP.m_PersFlags &= ~RBPF_WASWORLDSPACE; } if (sFrame != r->m_RP.m_FrameObject) { sFrame = r->m_RP.m_FrameObject; if (r->m_RP.m_ClipPlaneEnabled == 2) { // Transform clip plane to clip space Plane p; p.n = r->m_RP.m_CurClipPlane.m_Normal; p.d = r->m_RP.m_CurClipPlane.m_Dist; Plane pTr; pTr = TransformPlane2(r->m_InvCameraProjMatrix, p); r->m_pd3dDevice->SetClipPlane(0, &pTr.n[0]); r->m_RP.m_ClipPlaneWasOverrided = 2; } } if (m_FrameObj != r->m_RP.m_FrameObject) { m_FrameObj = r->m_RP.m_FrameObject; mathMatrixTranspose((float *)&matWorldViewProj, r->m_RP.m_pCurObject->GetVPMatrix().GetData(), g_CpuFlags); mfParameter(ParamBind, (float *)&matWorldViewProj, 4); } } break; case ECGP_Matr_World: { D3DXMatrixIdentity(&matWorldViewProj); mfParameter(ParamBind, &matWorldViewProj(0, 0), 4); } break; case ECGP_Matr_View_IT: { D3DXMatrixMultiply((D3DXMATRIXA16 *)&r->m_ViewMatrix(0,0), (D3DXMATRIXA16 *)&r->m_RP.m_pCurObject->m_Matrix(0,0), (D3DXMATRIXA16 *)&r->m_CameraMatrix(0,0)); D3DXMATRIXA16 *matView = (D3DXMATRIXA16 *)r->m_ViewMatrix.GetData(); D3DXMatrixInverse(&matWorldViewProj, NULL, matView); mfParameter(ParamBind, &matWorldViewProj(0, 0), 4); } break; case ECGP_Matr_View: { D3DXMatrixMultiply((D3DXMATRIXA16 *)&r->m_ViewMatrix(0,0), (D3DXMATRIXA16 *)&r->m_RP.m_pCurObject->m_Matrix(0,0), (D3DXMATRIXA16 *)&r->m_CameraMatrix(0,0)); D3DXMATRIXA16 *matView = (D3DXMATRIXA16 *)r->m_ViewMatrix.GetData(); D3DXMatrixTranspose(&matWorldViewProj, matView); mfParameter(ParamBind, &matWorldViewProj(0, 0), 4); } break; case ECGP_Matr_View_I: { D3DXMatrixMultiply((D3DXMATRIXA16 *)&r->m_ViewMatrix(0,0), (D3DXMATRIXA16 *)&r->m_RP.m_pCurObject->m_Matrix(0,0), (D3DXMATRIXA16 *)&r->m_CameraMatrix(0,0)); D3DXMATRIXA16 *matView = (D3DXMATRIXA16 *)r->m_ViewMatrix.GetData(); D3DXMatrixInverse(&matWorldViewProj, NULL, matView); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); mfParameter(ParamBind, &matWorldViewProj(0, 0), 4); } break; case ECGP_Matr_View_T: { D3DXMatrixMultiply((D3DXMATRIXA16 *)&r->m_ViewMatrix(0,0), (D3DXMATRIXA16 *)&r->m_RP.m_pCurObject->m_Matrix(0,0), (D3DXMATRIXA16 *)&r->m_CameraMatrix(0,0)); D3DXMATRIXA16 *matView = (D3DXMATRIXA16 *)r->m_ViewMatrix.GetData(); mfParameter(ParamBind, (float *)matView, 4); } break; case ECGP_Matr_Obj: { Matrix44 *m = &gRenDev->m_RP.m_pCurObject->m_Matrix; mfParameter(ParamBind, m->GetData(), 4); } break; case ECGP_Matr_Obj_I: { Matrix44 *m = &gRenDev->m_RP.m_pCurObject->GetInvMatrix(); mfParameter(ParamBind, m->GetData(), 4); } break; default: Warning( 0,0,"Unknown matrix state type %d int CG program '%s'", m_Name.c_str()); assert(0); } } void mfDelInst() { if(m_Insts[m_CurInst].m_CGProgram && (int)m_Insts[m_CurInst].m_CGProgram != -1) { if (m_Insts[m_CurInst].m_BindConstants) delete m_Insts[m_CurInst].m_BindConstants; if (m_Insts[m_CurInst].m_BindVars) delete m_Insts[m_CurInst].m_BindVars; if (m_Insts[m_CurInst].m_ParamsNoObj) delete m_Insts[m_CurInst].m_ParamsNoObj; if (m_Insts[m_CurInst].m_ParamsObj) delete m_Insts[m_CurInst].m_ParamsObj; if (m_Insts[m_CurInst].m_MatrixNoObj) delete m_Insts[m_CurInst].m_MatrixNoObj; if (m_Insts[m_CurInst].m_MatrixObj) delete m_Insts[m_CurInst].m_MatrixObj; IDirect3DVertexShader9 *pVS = (IDirect3DVertexShader9 *)m_Insts[m_CurInst].m_pHandle; if (pVS) { pVS->Release(); m_Insts[m_CurInst].m_pHandle = NULL; } } m_Insts[m_CurInst].m_CGProgram = NULL; } bool mfIsValid(int Num) const { return (m_Insts[Num].m_CGProgram != NULL); } SCGScript *mfGenerateScriptVP(CVProgram *pPosVP); char *mfGenerateTCScript(char *Script, int nt); void mfCompileVertAttributes(char *scr, SShader *ef); void mfSetVariables(TArray* Vars); void mfPrecacheLights(int nMask); public: char *mfCreateAdditionalVP(CVProgram *pPosVP); void mfCompileParam4f(char *scr, SShader *ef, TArray *Params); void mfCompileParamStateMatrix(char *scr, SShader *ef, TArray *Params); bool mfActivate(CVProgram *pPosVP); void mfConstructFX(std::vector& Structs, std::vector& Macros, char *entryFunc); void mfAddFXParameter(SFXParam *pr, const char *ParamName, SShader *ef); bool mfGetFXParamNameByID(int nParam, char *ParamName); public: virtual ~CCGVProgram_D3D(); virtual void Release(); virtual bool mfCompile(char *scr); virtual bool mfSet(bool bStat, SShaderPassHW *slw=NULL, int nSetPointers=1); virtual void mfSetVariables(bool bObj, TArray* Vars); virtual void mfReset(); virtual void mfPrecache(); virtual bool mfHasPointer(ESrcPointer ePtr); virtual void mfGatherFXParameters(const char *buf, SShaderPassHW *pSHPass, std::vector& Params, std::vector& Samplers, std::vector& Textures, SShader *ef); virtual void mfPostLoad(); virtual int mfVertexFormat(bool &bUseTangents, bool &bUseLM); void mfSetStateMatrices() { //PROFILE_FRAME(Shader_VShadersMatr); for (int i=0; iNum(); i++) { SCGMatrix *tm = &m_Insts[m_CurInst].m_MatrixObj->Get(i); mfParameterStateMatrix(tm); } } } static int m_nResetDeviceFrame; static void mfSetGlobalParams(); static SCGScript *mfAddNewScript(const char *Name, const char *Script) { int i; if (Name) { CName nm = CName(Name); if (nm.GetIndex()) { for (i=0; im_Name.GetIndex()) continue; if (nm == scr->m_Name) { if (!Script || stricmp(Script, scr->m_Script) == 0) return scr; delete [] scr->m_Script; break; } } } } if (!Script) { if (Name) Warning( 0,0,"Error: CCGVProgram_GL::mfAddNewScript: Couldn't find CG script for name '%s'", Name); return NULL; } SCGScript *scr = new SCGScript; if (Name) scr->m_Name = CName(Name, eFN_Add); size_t len = strlen(Script)+1; scr->m_Script = new char[len]; strcpy(scr->m_Script, Script); if (Name) m_CGScripts.AddElem(scr); return scr; } static void mfDeleteSharedScripts() { int i; for (i=0; im_Script); delete scr; m_CGScripts[i] = NULL; } } static TArray m_CGScripts; static vec4_t m_CurParams[256]; }; #endif // __D3DCGVPROGRAMS_H__