////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// void CResourceManager::_ParseList(sh_list& dest, LPCSTR names) { if (0==names) names = "$null"; ZeroMemory (&dest, sizeof(dest)); char* P = (char*) names; svector<char,128> N; while (*P) { if (*P == ',') { // flush N.push_back (0); strlwr (N.begin()); fix_texture_name( N.begin() ); //. andy if (strext(N.begin())) *strext(N.begin())=0; dest.push_back(N.begin()); N.clear (); } else { N.push_back (*P); } P++; } if (N.size()) { // flush N.push_back (0); strlwr (N.begin()); fix_texture_name( N.begin() ); //. andy if (strext(N.begin())) *strext(N.begin())=0; dest.push_back(N.begin()); } }
CTexture* CResourceManager::_FindTexture(LPCSTR Name) { // copypaste from _CreateTexture if (0 == xr_strcmp(Name, "null")) return 0; R_ASSERT(Name && Name[0]); string_path filename; strcpy_s(filename, Name); //. andy if (strext(Name)) *strext(Name)=0; fix_texture_name(filename); LPSTR N = LPSTR(filename); char *ch = strstr(N, "*"); if (NULL == ch) // no wildcard? { map_TextureIt I = m_textures.find(N); if (I != m_textures.end()) return I->second; } else { // alpet: test for wildcard matching ch[0] = 0; // remove * for (map_TextureIt t = m_textures.begin(); t != m_textures.end(); t++) if (strstr(t->second->cName.c_str(), N)) return t->second; } return NULL; }
u32 CBlender_Compile::i_Sampler (LPCSTR _name) { // string256 name; strcpy_s (name,_name); //. andy if (strext(name)) *strext(name)=0; fix_texture_name (name); // Find index ref_constant C = ctable.get(name); if (!C) return u32(-1); R_ASSERT (C->type == RC_sampler); u32 stage = C->samp.index; // Create texture // while (stage>=passTextures.size()) passTextures.push_back (NULL); return stage; }
void CBlender_Compile::r_dx10Texture(LPCSTR ResourceName, LPCSTR texture) { VERIFY(ResourceName); if (!texture) return; // string256 TexName; strcpy_s (TexName,texture); fix_texture_name (TexName); // Find index ref_constant C = ctable.get(ResourceName); //VERIFY(C); if (!C) return; R_ASSERT (C->type == RC_dx10texture); u32 stage = C->samp.index; passTextures.push_back (mk_pair(stage, ref_texture(DEV->_CreateTexture(TexName)))); }
//-------------------------------------------------------------------------------------------------------------- CTexture* CResourceManager::_CreateTexture (LPCSTR _Name) { // DBG_VerifyTextures (); if (0==xr_strcmp(_Name,"null")) return 0; R_ASSERT (_Name && _Name[0]); string_path Name; strcpy_s (Name,_Name); //. andy if (strext(Name)) *strext(Name)=0; fix_texture_name (Name); // ***** first pass - search already loaded texture LPSTR N = LPSTR(Name); map_TextureIt I = m_textures.find (N); if (I!=m_textures.end()) return I->second; else { CTexture * T = xr_new<CTexture>(); T->dwFlags |= xr_resource_flagged::RF_REGISTERED; m_textures.insert (mk_pair(T->set_name(Name),T)); T->Preload (); if (Device.b_is_Ready && !bDeferredLoad) T->Load(); return T; } }
u32 CBlender_Compile::r_dx10Sampler(LPCSTR ResourceName) { // TEST //return ((u32)-1); VERIFY(ResourceName); string256 name; strcpy_s (name,ResourceName); fix_texture_name (name); // Find index //ref_constant C = ctable.get(ResourceName); ref_constant C = ctable.get(name); //VERIFY(C); if (!C) return u32(-1); R_ASSERT (C->type == RC_sampler); u32 stage = C->samp.index; // init defaults here // Use D3DTADDRESS_CLAMP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT if (0==xr_strcmp(ResourceName,"smp_nofilter")) { i_dx10Address( stage, D3DTADDRESS_CLAMP); i_dx10Filter(stage, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); } // Use D3DTADDRESS_CLAMP, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR if (0==xr_strcmp(ResourceName,"smp_rtlinear")) { i_dx10Address( stage, D3DTADDRESS_CLAMP); i_dx10Filter(stage, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR); } // Use D3DTADDRESS_WRAP, D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR if (0==xr_strcmp(ResourceName,"smp_linear")) { i_dx10Address( stage, D3DTADDRESS_WRAP); i_dx10Filter(stage, D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR); } // Use D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC if (0==xr_strcmp(ResourceName,"smp_base")) { i_dx10Address( stage, D3DTADDRESS_WRAP); i_dx10FilterAnizo( stage, TRUE); //i_dx10Filter(stage, D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR); } // Use D3DTADDRESS_CLAMP, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR if (0==xr_strcmp(ResourceName,"smp_material")) { i_dx10Address( stage, D3DTADDRESS_CLAMP); i_dx10Filter(stage, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR); RS.SetSAMP(stage,D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP); } if (0==xr_strcmp(ResourceName,"smp_smap")) { i_dx10Address( stage, D3DTADDRESS_CLAMP); i_dx10Filter(stage, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR); RS.SetSAMP(stage, XRDX10SAMP_COMPARISONFILTER, TRUE); RS.SetSAMP(stage, XRDX10SAMP_COMPARISONFUNC, D3D10_COMPARISON_LESS_EQUAL); } if (0==xr_strcmp(ResourceName,"smp_jitter")) { i_dx10Address( stage, D3DTADDRESS_WRAP); i_dx10Filter(stage, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT); } return stage; }
void uber_deffer (CBlender_Compile& C, bool hq, LPCSTR _vspec, LPCSTR _pspec, BOOL _aref, LPCSTR _detail_replace, bool DO_NOT_FINISH) { // Uber-parse string256 fname,fnameA,fnameB; xr_strcpy (fname,*C.L_textures[0]); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name(fname); ref_texture _t; _t.create (fname); bool bump = _t.bump_exist (); // detect lmap bool lmap = true; if (C.L_textures.size()<3) lmap = false; else { pcstr tex = C.L_textures[2].c_str(); if (tex[0]=='l' && tex[1]=='m' && tex[2]=='a' && tex[3]=='p') lmap = true ; else lmap = false; } string256 ps,vs,dt; strconcat (sizeof(vs),vs,"deffer_", _vspec, lmap?"_lmh":"" ); strconcat (sizeof(ps),ps,"deffer_", _pspec, lmap?"_lmh":"" ); xr_strcpy (dt,sizeof(dt),_detail_replace?_detail_replace:( C.detail_texture?C.detail_texture:"" ) ); // detect detail bump string256 texDetailBump = {'\0'}; string256 texDetailBumpX = {'\0'}; bool bHasDetailBump = false; if (C.bDetail_Bump) { LPCSTR detail_bump_texture = DEV->m_textures_description.GetBumpName(dt).c_str(); // Detect and use detail bump if ( detail_bump_texture ) { bHasDetailBump = true; xr_strcpy ( texDetailBump, sizeof(texDetailBump), detail_bump_texture); xr_strcpy ( texDetailBumpX, sizeof(texDetailBumpX), detail_bump_texture); xr_strcat ( texDetailBumpX, "#"); } } if (_aref) { xr_strcat(ps,"_aref"); } if (!bump) { fnameA[0] = fnameB[0] = 0; xr_strcat (vs,"_flat"); xr_strcat (ps,"_flat"); if (hq && (C.bDetail_Diffuse || C.bDetail_Bump) ) { xr_strcat (vs,"_d"); xr_strcat (ps,"_d"); } } else { xr_strcpy (fnameA,_t.bump_get().c_str()); strconcat (sizeof(fnameB),fnameB,fnameA,"#"); xr_strcat (vs,"_bump"); if (hq && C.bUseSteepParallax) { xr_strcat (ps,"_steep"); } else { xr_strcat (ps,"_bump"); } if (hq && (C.bDetail_Diffuse || C.bDetail_Bump) ) { xr_strcat (vs,"_d" ); if (bHasDetailBump) xr_strcat (ps,"_db" ); // bump & detail & hq else xr_strcat (ps,"_d" ); } } // HQ if (bump && hq) { xr_strcat (vs,"-hq"); xr_strcat (ps,"-hq"); } // Uber-construct #if defined(USE_DX10) || defined(USE_DX11) # ifdef USE_DX11 if (bump && hq && RImplementation.o.dx11_enable_tessellation && C.TessMethod!=0) { char hs[256], ds[256];// = "DX11\\tess", ds[256] = "DX11\\tess"; char params[256] = "("; if (C.TessMethod == CBlender_Compile::TESS_PN || C.TessMethod == CBlender_Compile::TESS_PN_HM) { RImplementation.addShaderOption("TESS_PN", "1"); xr_strcat(params, "TESS_PN,"); } if (C.TessMethod == CBlender_Compile::TESS_HM || C.TessMethod == CBlender_Compile::TESS_PN_HM) { RImplementation.addShaderOption("TESS_HM", "1"); xr_strcat(params, "TESS_HM,"); } if (lmap) { RImplementation.addShaderOption("USE_LM_HEMI", "1"); xr_strcat(params, "USE_LM_HEMI,"); } if (C.bDetail_Diffuse) { RImplementation.addShaderOption("USE_TDETAIL", "1"); xr_strcat(params, "USE_TDETAIL,"); } if (C.bDetail_Bump) { RImplementation.addShaderOption("USE_TDETAIL_BUMP", "1"); xr_strcat(params, "USE_TDETAIL_BUMP,"); } xr_strcat(params, ")"); strconcat(sizeof(vs),vs,"deffer_", _vspec, "_bump", params); strconcat(sizeof(ps),ps,"deffer_", _pspec, _aref?"_aref":"", "_bump", params); strconcat(sizeof(hs),hs,"DX11\\tess", params); strconcat(sizeof(ds),ds,"DX11\\tess", params); VERIFY(strstr(vs, "bump")!=0); VERIFY(strstr(ps, "bump")!=0); C.r_TessPass (vs, hs, ds, "null", ps, FALSE); RImplementation.clearAllShaderOptions(); u32 stage = C.r_dx10Sampler("smp_bump_ds"); if (stage != -1) { C.i_dx10Address(stage, D3DTADDRESS_WRAP); C.i_dx10FilterAnizo(stage, TRUE); } if (ps_r2_ls_flags_ext.test(R2FLAGEXT_WIREFRAME)) C.R().SetRS(D3DRS_FILLMODE, D3DFILL_WIREFRAME); C.r_dx10Texture ("s_tbump", fnameA); C.r_dx10Texture ("s_tbumpX", fnameB); // should be before base bump if (bHasDetailBump) { C.r_dx10Texture ("s_tdetailBumpX", texDetailBumpX); } } else # endif C.r_Pass (vs,ps, FALSE); //C.r_Sampler ("s_base", C.L_textures[0], false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); //C.r_Sampler ("s_bumpX", fnameB, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); // should be before base bump //C.r_Sampler ("s_bump", fnameA, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); //C.r_Sampler ("s_bumpD", dt, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); //C.r_Sampler ("s_detail", dt, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); C.r_dx10Texture ("s_base", C.L_textures[0]); C.r_dx10Texture ("s_bumpX", fnameB); // should be before base bump C.r_dx10Texture ("s_bump", fnameA); C.r_dx10Texture ("s_bumpD", dt); C.r_dx10Texture ("s_detail", dt); if (bHasDetailBump) { C.r_dx10Texture ("s_detailBump", texDetailBump); C.r_dx10Texture ("s_detailBumpX", texDetailBumpX); } C.r_dx10Sampler ("smp_base"); if (lmap) { //C.r_Sampler("s_hemi", C.L_textures[2], false, D3DTADDRESS_CLAMP, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR); C.r_dx10Texture ("s_hemi", C.L_textures[2]); C.r_dx10Sampler ("smp_rtlinear"); } #else // USE_DX10 C.r_Pass (vs,ps, FALSE); VERIFY(C.L_textures[0].size()); if(bump) { VERIFY2(xr_strlen(fnameB), C.L_textures[0].c_str()); VERIFY2(xr_strlen(fnameA), C.L_textures[0].c_str()); } if(bHasDetailBump) { VERIFY2(xr_strlen(texDetailBump), C.L_textures[0].c_str()); VERIFY2(xr_strlen(texDetailBumpX), C.L_textures[0].c_str()); } C.r_Sampler ("s_base", C.L_textures[0], false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); C.r_Sampler ("s_bumpX", fnameB, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); // should be before base bump C.r_Sampler ("s_bump", fnameA, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); C.r_Sampler ("s_bumpD", dt, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); C.r_Sampler ("s_detail", dt, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); if (bHasDetailBump) { C.r_Sampler ("s_detailBump", texDetailBump, false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); C.r_Sampler ("s_detailBumpX",texDetailBumpX,false, D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC,D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC); } if (lmap)C.r_Sampler("s_hemi", C.L_textures[2], false, D3DTADDRESS_CLAMP, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR); #endif // USE_DX10 if (!DO_NOT_FINISH) C.r_End (); }
void uber_shadow(CBlender_Compile& C, LPCSTR _vspec) { // Uber-parse string256 fname,fnameA,fnameB; xr_strcpy (fname,*C.L_textures[0]); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name(fname); ref_texture _t; _t.create (fname); bool bump = _t.bump_exist (); // detect lmap bool lmap = true; if (C.L_textures.size()<3) lmap = false; else { pcstr tex = C.L_textures[2].c_str(); if (tex[0]=='l' && tex[1]=='m' && tex[2]=='a' && tex[3]=='p') lmap = true ; else lmap = false; } string256 vs,dt; xr_strcpy (dt,sizeof(dt),C.detail_texture?C.detail_texture:""); // detect detail bump string256 texDetailBump = {'\0'}; string256 texDetailBumpX = {'\0'}; bool bHasDetailBump = false; if (C.bDetail_Bump) { LPCSTR detail_bump_texture = DEV->m_textures_description.GetBumpName(dt).c_str(); // Detect and use detail bump if ( detail_bump_texture ) { bHasDetailBump = true; xr_strcpy ( texDetailBump, sizeof(texDetailBump), detail_bump_texture); xr_strcpy ( texDetailBumpX, sizeof(texDetailBumpX), detail_bump_texture); xr_strcat ( texDetailBumpX, "#"); } } if (!bump) { fnameA[0] = fnameB[0] = 0; } else { xr_strcpy (fnameA,_t.bump_get().c_str()); strconcat (sizeof(fnameB),fnameB,fnameA,"#"); } if (bump && RImplementation.o.dx11_enable_tessellation && C.TessMethod!=0) { char hs[256], ds[256];// = "DX11\\tess", ds[256] = "DX11\\tess"; char params[256] = "("; if (C.TessMethod == CBlender_Compile::TESS_PN || C.TessMethod == CBlender_Compile::TESS_PN_HM) { RImplementation.addShaderOption("TESS_PN", "1"); xr_strcat(params, "TESS_PN,"); } if (C.TessMethod == CBlender_Compile::TESS_HM || C.TessMethod == CBlender_Compile::TESS_PN_HM) { RImplementation.addShaderOption("TESS_HM", "1"); xr_strcat(params, "TESS_HM,"); } if (lmap) { RImplementation.addShaderOption("USE_LM_HEMI", "1"); xr_strcat(params, "USE_LM_HEMI,"); } if (C.bDetail_Diffuse) { RImplementation.addShaderOption("USE_TDETAIL", "1"); xr_strcat(params, "USE_TDETAIL,"); } if (C.bDetail_Bump) { RImplementation.addShaderOption("USE_TDETAIL_BUMP", "1"); xr_strcat(params, "USE_TDETAIL_BUMP,"); } xr_strcat(params, ")"); strconcat(sizeof(vs),vs,"deffer_", _vspec, "_bump", params); strconcat(sizeof(hs),hs,"DX11\\tess", params); strconcat(sizeof(ds),ds,"DX11\\tess_shadow", params); C.r_TessPass (vs, hs, ds, "null", "dumb", FALSE,TRUE,TRUE,FALSE); RImplementation.clearAllShaderOptions(); C.r_dx10Texture ("s_base", C.L_textures[0]); C.r_dx10Texture ("s_bumpX", fnameB); // should be before base bump C.r_dx10Texture ("s_bump", fnameA); if (bHasDetailBump) { C.r_dx10Texture ("s_detailBump", texDetailBump); C.r_dx10Texture ("s_detailBumpX", texDetailBumpX); } u32 stage = C.r_dx10Sampler("smp_bump_ds"); if (stage != -1) { C.i_dx10Address(stage, D3DTADDRESS_WRAP); C.i_dx10FilterAnizo(stage, TRUE); } if (ps_r2_ls_flags_ext.test(R2FLAGEXT_WIREFRAME)) C.R().SetRS(D3DRS_FILLMODE, D3DFILL_WIREFRAME); } else C.r_Pass ("shadow_direct_base","dumb", FALSE,TRUE,TRUE,FALSE); }
/* ID3DTexture2D* TW_LoadTextureFromTexture ( ID3DTexture2D* t_from, D3DFORMAT& t_dest_fmt, int levels_2_skip, u32& w, u32& h ) { // Calculate levels & dimensions ID3DTexture2D* t_dest = NULL; D3DSURFACE_DESC t_from_desc0 ; R_CHK (t_from->GetLevelDesc (0,&t_from_desc0)); int levels_exist = t_from->GetLevelCount(); int top_width = t_from_desc0.Width; int top_height = t_from_desc0.Height; Reduce (top_width,top_height,levels_exist,levels_2_skip); // Create HW-surface if (D3DX_DEFAULT==t_dest_fmt) t_dest_fmt = t_from_desc0.Format; R_CHK (D3DXCreateTexture( HW.pDevice, top_width,top_height, levels_exist,0,t_dest_fmt, D3DPOOL_MANAGED,&t_dest )); // Copy surfaces & destroy temporary ID3DTexture2D* T_src= t_from; ID3DTexture2D* T_dst= t_dest; int L_src = T_src->GetLevelCount ()-1; int L_dst = T_dst->GetLevelCount ()-1; for (; L_dst>=0; L_src--,L_dst--) { // Get surfaces IDirect3DSurface9 *S_src, *S_dst; R_CHK (T_src->GetSurfaceLevel (L_src,&S_src)); R_CHK (T_dst->GetSurfaceLevel (L_dst,&S_dst)); // Copy R_CHK (D3DXLoadSurfaceFromSurface(S_dst,NULL,NULL,S_src,NULL,NULL,D3DX_FILTER_NONE,0)); // Release surfaces _RELEASE (S_src); _RELEASE (S_dst); } // OK w = top_width; h = top_height; return t_dest; } template <class _It> IC void TW_Iterate_1OP ( ID3DTexture2D* t_dst, ID3DTexture2D* t_src, const _It pred ) { DWORD mips = t_dst->GetLevelCount(); R_ASSERT (mips == t_src->GetLevelCount()); for (DWORD i = 0; i < mips; i++) { D3DLOCKED_RECT Rsrc,Rdst; D3DSURFACE_DESC desc,descS; t_dst->GetLevelDesc (i, &desc); t_src->GetLevelDesc (i, &descS); VERIFY (desc.Format==descS.Format); VERIFY (desc.Format==D3DFMT_A8R8G8B8); t_src->LockRect (i,&Rsrc,0,0); t_dst->LockRect (i,&Rdst,0,0); for (u32 y = 0; y < desc.Height; y++) { for (u32 x = 0; x < desc.Width; x++) { DWORD& pSrc = *(((DWORD*)((BYTE*)Rsrc.pBits + (y * Rsrc.Pitch)))+x); DWORD& pDst = *(((DWORD*)((BYTE*)Rdst.pBits + (y * Rdst.Pitch)))+x); pDst = pred(pDst,pSrc); } } t_dst->UnlockRect (i); t_src->UnlockRect (i); } } template <class _It> IC void TW_Iterate_2OP ( ID3DTexture2D* t_dst, ID3DTexture2D* t_src0, ID3DTexture2D* t_src1, const _It pred ) { DWORD mips = t_dst->GetLevelCount(); R_ASSERT (mips == t_src0->GetLevelCount()); R_ASSERT (mips == t_src1->GetLevelCount()); for (DWORD i = 0; i < mips; i++) { D3DLOCKED_RECT Rsrc0,Rsrc1,Rdst; D3DSURFACE_DESC desc,descS0,descS1; t_dst->GetLevelDesc (i, &desc); t_src0->GetLevelDesc (i, &descS0); t_src1->GetLevelDesc (i, &descS1); VERIFY (desc.Format==descS0.Format); VERIFY (desc.Format==descS1.Format); VERIFY (desc.Format==D3DFMT_A8R8G8B8); t_src0->LockRect (i,&Rsrc0, 0,0); t_src1->LockRect (i,&Rsrc1, 0,0); t_dst->LockRect (i,&Rdst, 0,0); for (u32 y = 0; y < desc.Height; y++) { for (u32 x = 0; x < desc.Width; x++) { DWORD& pSrc0 = *(((DWORD*)((BYTE*)Rsrc0.pBits + (y * Rsrc0.Pitch)))+x); DWORD& pSrc1 = *(((DWORD*)((BYTE*)Rsrc1.pBits + (y * Rsrc1.Pitch)))+x); DWORD& pDst = *(((DWORD*)((BYTE*)Rdst.pBits + (y * Rdst.Pitch)))+x); pDst = pred(pDst,pSrc0,pSrc1); } } t_dst->UnlockRect (i); t_src0->UnlockRect (i); t_src1->UnlockRect (i); } } IC u32 it_gloss_rev (u32 d, u32 s) { return color_rgba ( color_get_A(s), // gloss color_get_B(d), color_get_G(d), color_get_R(d) ); } IC u32 it_gloss_rev_base(u32 d, u32 s) { u32 occ = color_get_A(d)/3; u32 def = 8; u32 gloss = (occ*1+def*3)/4; return color_rgba ( gloss, // gloss color_get_B(d), color_get_G(d), color_get_R(d) ); } IC u32 it_difference (u32 d, u32 orig, u32 ucomp) { return color_rgba( 128+(int(color_get_R(orig))-int(color_get_R(ucomp)))*2, // R-error 128+(int(color_get_G(orig))-int(color_get_G(ucomp)))*2, // G-error 128+(int(color_get_B(orig))-int(color_get_B(ucomp)))*2, // B-error 128+(int(color_get_A(orig))-int(color_get_A(ucomp)))*2 ); // A-error } IC u32 it_height_rev (u32 d, u32 s) { return color_rgba ( color_get_A(d), // diff x color_get_B(d), // diff y color_get_G(d), // diff z color_get_R(s) ); // height } IC u32 it_height_rev_base(u32 d, u32 s) { return color_rgba ( color_get_A(d), // diff x color_get_B(d), // diff y color_get_G(d), // diff z (color_get_R(s)+color_get_G(s)+color_get_B(s))/3 ); // height } */ ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize, bool bStaging) { // Moved here just to avoid warning #ifdef USE_DX11 D3DX11_IMAGE_INFO IMG; #else D3DX10_IMAGE_INFO IMG; #endif ZeroMemory(&IMG, sizeof(IMG)); // Staging control static bool bAllowStaging = !strstr(Core.Params,"-no_staging"); bStaging &= bAllowStaging; ID3DBaseTexture* pTexture2D = NULL; //IDirect3DCubeTexture9* pTextureCUBE = NULL; string_path fn; //u32 dwWidth,dwHeight; u32 img_size = 0; int img_loaded_lod = 0; //D3DFORMAT fmt; u32 mip_cnt=u32(-1); // validation R_ASSERT (fRName); R_ASSERT (fRName[0]); // make file name string_path fname; xr_strcpy(fname,fRName); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name (fname); IReader* S = NULL; if (!FS.exist(fn,"$game_textures$", fname, ".dds") && strstr(fname,"_bump")) goto _BUMP_from_base; if (FS.exist(fn,"$level$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_saves$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_textures$", fname, ".dds")) goto _DDS; #ifdef _EDITOR ELog.Msg(mtError,"Can't find texture '%s'",fname); return 0; #else Msg("! Can't find texture '%s'",fname); R_ASSERT(FS.exist(fn,"$game_textures$", "ed\\ed_not_existing_texture",".dds")); goto _DDS; // Debug.fatal(DEBUG_INFO,"Can't find texture '%s'",fname); #endif _DDS: { // Load and get header S = FS.r_open (fn); #ifdef DEBUG Msg ("* Loaded: %s[%d]",fn,S->length()); #endif // DEBUG img_size = S->length (); R_ASSERT (S); //R_CHK2 (D3DXGetImageInfoFromFileInMemory (S->pointer(),S->length(),&IMG), fn); #ifdef USE_DX11 R_CHK2 (D3DX11GetImageInfoFromMemory(S->pointer(),S->length(), 0, &IMG, 0), fn); #else R_CHK2 (D3DX10GetImageInfoFromMemory(S->pointer(),S->length(), 0, &IMG, 0), fn); #endif //if (IMG.ResourceType == D3DRTYPE_CUBETEXTURE) goto _DDS_CUBE; if (IMG.MiscFlags & D3D_RESOURCE_MISC_TEXTURECUBE) goto _DDS_CUBE; else goto _DDS_2D; _DDS_CUBE: { //R_CHK(D3DXCreateCubeTextureFromFileInMemoryEx( // HW.pDevice, // S->pointer(),S->length(), // D3DX_DEFAULT, // IMG.MipLevels,0, // IMG.Format, // D3DPOOL_MANAGED, // D3DX_DEFAULT, // D3DX_DEFAULT, // 0,&IMG,0, // &pTextureCUBE // )); // Inited to default by provided default constructor #ifdef USE_DX11 D3DX11_IMAGE_LOAD_INFO LoadInfo; #else D3DX10_IMAGE_LOAD_INFO LoadInfo; #endif //LoadInfo.Usage = D3D_USAGE_IMMUTABLE; if (bStaging) { LoadInfo.Usage = D3D_USAGE_STAGING; LoadInfo.BindFlags = 0; LoadInfo.CpuAccessFlags = D3D_CPU_ACCESS_WRITE; } else { LoadInfo.Usage = D3D_USAGE_DEFAULT; LoadInfo.BindFlags = D3D_BIND_SHADER_RESOURCE; } LoadInfo.pSrcInfo = &IMG; #ifdef USE_DX11 R_CHK(D3DX11CreateTextureFromMemory( HW.pDevice, S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 )); #else R_CHK(D3DX10CreateTextureFromMemory( HW.pDevice, S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 )); #endif FS.r_close (S); // OK mip_cnt = IMG.MipLevels; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } _DDS_2D: { // Check for LMAP and compress if needed strlwr (fn); // Load SYS-MEM-surface, bound to device restrictions //ID3DTexture2D* T_sysmem; //R_CHK2(D3DXCreateTextureFromFileInMemoryEx // ( // HW.pDevice,S->pointer(),S->length(), // D3DX_DEFAULT,D3DX_DEFAULT, // IMG.MipLevels,0, // IMG.Format, // D3DPOOL_SYSTEMMEM, // D3DX_DEFAULT, // D3DX_DEFAULT, // 0,&IMG,0, // &T_sysmem // ), fn); img_loaded_lod = get_texture_load_lod(fn); // Inited to default by provided default constructor #ifdef USE_DX11 D3DX11_IMAGE_LOAD_INFO LoadInfo; #else D3DX10_IMAGE_LOAD_INFO LoadInfo; #endif //LoadInfo.FirstMipLevel = img_loaded_lod; LoadInfo.Width = IMG.Width; LoadInfo.Height = IMG.Height; if (img_loaded_lod) { Reduce(LoadInfo.Width, LoadInfo.Height, IMG.MipLevels, img_loaded_lod); } //LoadInfo.Usage = D3D_USAGE_IMMUTABLE; if (bStaging) { LoadInfo.Usage = D3D_USAGE_STAGING; LoadInfo.BindFlags = 0; LoadInfo.CpuAccessFlags = D3D_CPU_ACCESS_WRITE; } else { LoadInfo.Usage = D3D_USAGE_DEFAULT; LoadInfo.BindFlags = D3D_BIND_SHADER_RESOURCE; } LoadInfo.pSrcInfo = &IMG; #ifdef USE_DX11 R_CHK2(D3DX11CreateTextureFromMemory ( HW.pDevice,S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 ), fn); #else R_CHK2(D3DX10CreateTextureFromMemory ( HW.pDevice,S->pointer(),S->length(), &LoadInfo, 0, &pTexture2D, 0 ), fn); #endif FS.r_close (S); mip_cnt = IMG.MipLevels; // OK ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } } _BUMP_from_base: { //Msg ("! auto-generated bump map: %s",fname); Msg ("! Fallback to default bump map: %s",fname); ////////////////// if (strstr(fname,"_bump#")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump#", ".dds"), "ed_dummy_bump#"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } if (strstr(fname,"_bump")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump", ".dds"),"ed_dummy_bump"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } ////////////////// } return 0; }
ID3DBaseTexture* CRender::texture_load(LPCSTR fRName, u32& ret_msize) { ID3DTexture2D* pTexture2D = NULL; IDirect3DCubeTexture9* pTextureCUBE = NULL; string_path fn; u32 dwWidth,dwHeight; u32 img_size = 0; int img_loaded_lod = 0; D3DFORMAT fmt; u32 mip_cnt=u32(-1); // validation R_ASSERT (fRName); R_ASSERT (fRName[0]); // make file name string_path fname; xr_strcpy(fname,fRName); //. andy if (strext(fname)) *strext(fname)=0; fix_texture_name (fname); IReader* S = NULL; //if (FS.exist(fn,"$game_textures$",fname, ".dds") && strstr(fname,"_bump")) goto _BUMP; if (!FS.exist(fn,"$game_textures$", fname, ".dds") && strstr(fname,"_bump")) goto _BUMP_from_base; if (FS.exist(fn,"$level$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_saves$", fname, ".dds")) goto _DDS; if (FS.exist(fn,"$game_textures$", fname, ".dds")) goto _DDS; #ifdef _EDITOR ELog.Msg(mtError,"Can't find texture '%s'",fname); return 0; #else Msg("! Can't find texture '%s'",fname); R_ASSERT(FS.exist(fn,"$game_textures$", "ed\\ed_not_existing_texture",".dds")); goto _DDS; // Debug.fatal(DEBUG_INFO,"Can't find texture '%s'",fname); #endif _DDS: { // Load and get header D3DXIMAGE_INFO IMG; S = FS.r_open (fn); #ifdef DEBUG Msg ("* Loaded: %s[%d]b",fn,S->length()); #endif // DEBUG img_size = S->length (); R_ASSERT (S); HRESULT const result = D3DXGetImageInfoFromFileInMemory (S->pointer(),S->length(),&IMG); if ( FAILED(result) ) { Msg ("! Can't get image info for texture '%s'",fn); FS.r_close (S); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } if (IMG.ResourceType == D3DRTYPE_CUBETEXTURE) goto _DDS_CUBE; else goto _DDS_2D; _DDS_CUBE: { HRESULT const result = D3DXCreateCubeTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT, IMG.MipLevels,0, IMG.Format, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0,&IMG,0, &pTextureCUBE ); FS.r_close (S); if ( FAILED(result) ) { Msg ("! Can't load texture '%s'",fn); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } // OK dwWidth = IMG.Width; dwHeight = IMG.Height; fmt = IMG.Format; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); mip_cnt = pTextureCUBE->GetLevelCount(); return pTextureCUBE; } _DDS_2D: { strlwr (fn); // Load SYS-MEM-surface, bound to device restrictions ID3DTexture2D* T_sysmem; HRESULT const result = D3DXCreateTextureFromFileInMemoryEx( HW.pDevice,S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, IMG.MipLevels,0, IMG.Format, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT, D3DX_DEFAULT, 0,&IMG,0, &T_sysmem ); FS.r_close (S); if ( FAILED(result) ) { Msg ("! Can't load texture '%s'",fn); string_path temp; R_ASSERT ( FS.exist( temp, "$game_textures$", "ed\\ed_not_existing_texture", ".dds" ) ); strlwr (temp); R_ASSERT ( xr_strcmp(temp,fn) ); xr_strcpy ( fn, temp ); goto _DDS; } img_loaded_lod = get_texture_load_lod(fn); pTexture2D = TW_LoadTextureFromTexture(T_sysmem,IMG.Format, img_loaded_lod, dwWidth, dwHeight); mip_cnt = pTexture2D->GetLevelCount(); _RELEASE (T_sysmem); // OK fmt = IMG.Format; ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return pTexture2D; } } /* _BUMP: { // Load SYS-MEM-surface, bound to device restrictions D3DXIMAGE_INFO IMG; IReader* S = FS.r_open (fn); msize = S->length (); ID3DTexture2D* T_height_gloss; R_CHK(D3DXCreateTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, D3DX_DEFAULT,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT,D3DX_DEFAULT, 0,&IMG,0,&T_height_gloss )); FS.r_close (S); //TW_Save (T_height_gloss,fname,"debug-0","original"); // Create HW-surface, compute normal map ID3DTexture2D* T_normal_1 = 0; R_CHK(D3DXCreateTexture (HW.pDevice,IMG.Width,IMG.Height,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1)); R_CHK(D3DXComputeNormalMap (T_normal_1,T_height_gloss,0,0,D3DX_CHANNEL_RED,_BUMPHEIGH)); //TW_Save (T_normal_1,fname,"debug-1","normal"); // Transfer gloss-map TW_Iterate_1OP (T_normal_1,T_height_gloss,it_gloss_rev); //TW_Save (T_normal_1,fname,"debug-2","normal-G"); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_1C = TW_LoadTextureFromTexture(T_normal_1,fmt,psTextureLOD,dwWidth,dwHeight); //TW_Save (T_normal_1C,fname,"debug-3","normal-G-C"); #if RENDER==R_R2 // Decompress (back) fmt = D3DFMT_A8R8G8B8; ID3DTexture2D* T_normal_1U = TW_LoadTextureFromTexture(T_normal_1C,fmt,0,dwWidth,dwHeight); // TW_Save (T_normal_1U,fname,"debug-4","normal-G-CU"); // Calculate difference ID3DTexture2D* T_normal_1D = 0; R_CHK(D3DXCreateTexture(HW.pDevice,dwWidth,dwHeight,T_normal_1U->GetLevelCount(),0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1D)); TW_Iterate_2OP (T_normal_1D,T_normal_1,T_normal_1U,it_difference); // TW_Save (T_normal_1D,fname,"debug-5","normal-G-diff"); // Reverse channels back + transfer heightmap TW_Iterate_1OP (T_normal_1D,T_height_gloss,it_height_rev); // TW_Save (T_normal_1D,fname,"debug-6","normal-G-diff-H"); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_2C = TW_LoadTextureFromTexture(T_normal_1D,fmt,0,dwWidth,dwHeight); // TW_Save (T_normal_2C,fname,"debug-7","normal-G-diff-H-C"); _RELEASE (T_normal_1U ); _RELEASE (T_normal_1D ); // string256 fnameB; strconcat (fnameB,"$user$",fname,"X"); ref_texture t_temp = dxRenderDeviceRender::Instance().Resources->_CreateTexture (fnameB); t_temp->surface_set (T_normal_2C ); _RELEASE (T_normal_2C ); // texture should keep reference to it by itself #endif // release and return // T_normal_1C - normal.gloss, reversed // T_normal_2C - 2*error.height, non-reversed _RELEASE (T_height_gloss ); _RELEASE (T_normal_1 ); return T_normal_1C; } */ _BUMP_from_base: { Msg ("! auto-generated bump map: %s",fname); ////////////////// #ifndef _EDITOR if (strstr(fname,"_bump#")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump#", ".dds"), "ed_dummy_bump#"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } if (strstr(fname,"_bump")) { R_ASSERT2 (FS.exist(fn,"$game_textures$", "ed\\ed_dummy_bump", ".dds"),"ed_dummy_bump"); S = FS.r_open (fn); R_ASSERT2 (S, fn); img_size = S->length (); goto _DDS_2D; } #endif ////////////////// *strstr (fname,"_bump") = 0; R_ASSERT2 (FS.exist(fn,"$game_textures$", fname, ".dds"),fname); // Load SYS-MEM-surface, bound to device restrictions D3DXIMAGE_INFO IMG; S = FS.r_open (fn); img_size = S->length (); ID3DTexture2D* T_base; R_CHK2(D3DXCreateTextureFromFileInMemoryEx( HW.pDevice, S->pointer(),S->length(), D3DX_DEFAULT,D3DX_DEFAULT, D3DX_DEFAULT,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, D3DX_DEFAULT,D3DX_DEFAULT, 0,&IMG,0,&T_base ), fn); FS.r_close (S); // Create HW-surface ID3DTexture2D* T_normal_1 = 0; R_CHK(D3DXCreateTexture (HW.pDevice,IMG.Width,IMG.Height,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &T_normal_1)); R_CHK(D3DXComputeNormalMap (T_normal_1,T_base,0,D3DX_NORMALMAP_COMPUTE_OCCLUSION,D3DX_CHANNEL_LUMINANCE,_BUMPHEIGH)); // Transfer gloss-map TW_Iterate_1OP (T_normal_1,T_base,it_gloss_rev_base); // Compress fmt = D3DFMT_DXT5; img_loaded_lod = get_texture_load_lod(fn); ID3DTexture2D* T_normal_1C = TW_LoadTextureFromTexture(T_normal_1, fmt, img_loaded_lod, dwWidth, dwHeight); mip_cnt = T_normal_1C->GetLevelCount(); #if RENDER==R_R2 // Decompress (back) fmt = D3DFMT_A8R8G8B8; ID3DTexture2D* T_normal_1U = TW_LoadTextureFromTexture(T_normal_1C,fmt,0,dwWidth,dwHeight); // Calculate difference ID3DTexture2D* T_normal_1D = 0; R_CHK(D3DXCreateTexture(HW.pDevice,dwWidth,dwHeight,T_normal_1U->GetLevelCount(),0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&T_normal_1D)); TW_Iterate_2OP (T_normal_1D,T_normal_1,T_normal_1U,it_difference); // Reverse channels back + transfer heightmap TW_Iterate_1OP (T_normal_1D,T_base,it_height_rev_base); // Compress fmt = D3DFMT_DXT5; ID3DTexture2D* T_normal_2C = TW_LoadTextureFromTexture(T_normal_1D,fmt,0,dwWidth,dwHeight); _RELEASE (T_normal_1U ); _RELEASE (T_normal_1D ); // string256 fnameB; strconcat (sizeof(fnameB),fnameB,"$user$",fname,"_bumpX"); ref_texture t_temp = dxRenderDeviceRender::Instance().Resources->_CreateTexture (fnameB); t_temp->surface_set (T_normal_2C ); _RELEASE (T_normal_2C ); // texture should keep reference to it by itself #endif // T_normal_1C - normal.gloss, reversed // T_normal_2C - 2*error.height, non-reversed _RELEASE (T_base); _RELEASE (T_normal_1); ret_msize = calc_texture_size(img_loaded_lod, mip_cnt, img_size); return T_normal_1C; } }