ETOOLS_API HRESULT WINAPI D3DX_ComputeNormalMap( LPDIRECT3DTEXTURE9 pTexture, LPDIRECT3DTEXTURE9 pSrcTexture, const PALETTEENTRY *pSrcPalette, DWORD Flags, DWORD Channel, FLOAT Amplitude) { return D3DXComputeNormalMap( pTexture, pSrcTexture, pSrcPalette, Flags, Channel, Amplitude); }
//------------------------------------------------------------- // Name: InitDeviceObjects() // Desc: 디바이스가 생성된후의 초기화 // 프레임버퍼 포맷과 디바이스 종류가 변한뒤에 호출 // 여기서 확보한 메모리는 DeleteDeviceObjects()에서 해제 //------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() { HRESULT hr; LPDIRECT3DTEXTURE9 pHeightTexture; D3DSURFACE_DESC desc; // 법선맵 생성 D3DUtil_CreateTexture( m_pd3dDevice,// 높이맵 읽기 _T("height.bmp"), &pHeightTexture ); pHeightTexture->GetLevelDesc(0,&desc);// 텍스처 정보 얻기 D3DXCreateTexture(m_pd3dDevice, desc.Width, desc.Height, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &m_pNormalMap);// 텍스처 생성 D3DXComputeNormalMap(m_pNormalMap, // 법선맵 생성 pHeightTexture, NULL, 0, D3DX_CHANNEL_RED, 1.0f); SAFE_RELEASE( pHeightTexture ); // 필요없어진 리소스 해제 // 정점선언 오브젝트 생성 if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ))) return DXTRACE_ERR ("CreateVertexDeclaration", hr); // 주전자 읽기 if(FAILED(hr=m_pMesh ->Create( m_pd3dDevice, _T("t-pot.x")))) return DXTRACE_ERR( "Load Object", hr ); // 지형 읽기 if(FAILED(hr=m_pMeshBg->Create( m_pd3dDevice, _T("map.x")))) return DXTRACE_ERR( "Load Ground", hr ); // 셰이더 읽기 LPD3DXBUFFER pErr=NULL; if( FAILED( hr = D3DXCreateEffectFromFile( m_pd3dDevice, "hlsl.fx", NULL, NULL, 0 , NULL, &m_pEffect, &pErr ))){ // 셰이더 읽기 실패 MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer() , "ERROR", MB_OK); }else{ m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" ); m_hmWVP = m_pEffect->GetParameterByName( NULL, "mWVP" ); m_hvLightDir = m_pEffect->GetParameterByName( NULL, "vLightDir" ); m_hvColor = m_pEffect->GetParameterByName( NULL, "vColor" ); m_hvEyePos = m_pEffect->GetParameterByName( NULL, "vEyePos" ); m_htDecaleTex= m_pEffect->GetParameterByName( NULL, "DecaleTex" ); m_htNormalMap= m_pEffect->GetParameterByName( NULL, "NormalMap" ); } SAFE_RELEASE(pErr); // 폰트 m_pFont->InitDeviceObjects( m_pd3dDevice ); return S_OK; }
Texture* TextureFilters::normalMap(Texture* texture, int amplify, bool inPlace) { Texture* newTexture = new Texture(); D3DXComputeNormalMap(newTexture->getD3D9Texture(), texture->getD3D9Texture(), NULL, 0, D3DX_CHANNEL_RED, (float)amplify); LPDIRECT3DSURFACE9 surface; newTexture->getD3D9Texture()->GetSurfaceLevel(0, &surface); D3DXLoadSurfaceFromSurface(newTexture->d3d9Surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0); return newTexture; }
//------------------------------------------------------------------------------- void CMaterialManager::HMtoNMIfNecessary( IDirect3DTexture9* piTexture, IDirect3DTexture9** piTextureOut, bool bWasOriginallyHM) { ai_assert(NULL != piTexture); ai_assert(NULL != piTextureOut); bool bMustConvert = false; uintptr_t iElement = 3; *piTextureOut = piTexture; // Lock the input texture and try to determine its type. // Criteria: // - If r,g,b channel are identical it MUST be a height map // - If one of the rgb channels is used and the others are empty it // must be a height map, too. // - If the average color of the whole image is something inside the // purple range we can be sure it is a normal map // // - Otherwise we assume it is a normal map // To increase performance we take not every pixel D3DLOCKED_RECT sRect; D3DSURFACE_DESC sDesc; piTexture->GetLevelDesc(0,&sDesc); if (FAILED(piTexture->LockRect(0,&sRect,NULL,D3DLOCK_READONLY))) { return; } const int iPitchDiff = (int)sRect.Pitch - (int)(sDesc.Width * 4); struct SColor { union { struct {unsigned char b,g,r,a;}; char _array[4]; }; }; const SColor* pcData = (const SColor*)sRect.pBits; union { const SColor* pcPointer; const unsigned char* pcCharPointer; }; pcPointer = pcData; // 1. If r,g,b channel are identical it MUST be a height map bool bIsEqual = true; for (unsigned int y = 0; y < sDesc.Height;++y) { for (unsigned int x = 0; x < sDesc.Width;++x) { if (pcPointer->b != pcPointer->r || pcPointer->b != pcPointer->g) { bIsEqual = false; break; } pcPointer++; } pcCharPointer += iPitchDiff; } if (bIsEqual)bMustConvert = true; else { // 2. If one of the rgb channels is used and the others are empty it // must be a height map, too. pcPointer = pcData; while (*pcCharPointer == 0)pcCharPointer++; iElement = (uintptr_t)(pcCharPointer - (unsigned char*)pcData) % 4; unsigned int aiIndex[3] = {0,1,2}; if (3 != iElement)aiIndex[iElement] = 3; pcPointer = pcData; bIsEqual = true; if (3 != iElement) { for (unsigned int y = 0; y < sDesc.Height;++y) { for (unsigned int x = 0; x < sDesc.Width;++x) { for (unsigned int ii = 0; ii < 3;++ii) { // don't take the alpha channel into account. // if the texture was stored n RGB888 format D3DX has // converted it to ARGB8888 format with a fixed alpha channel if (aiIndex[ii] != 3 && pcPointer->_array[aiIndex[ii]] != 0) { bIsEqual = false; break; } } pcPointer++; } pcCharPointer += iPitchDiff; } if (bIsEqual)bMustConvert = true; else { // If the average color of the whole image is something inside the // purple range we can be sure it is a normal map // (calculate the average color line per line to prevent overflows!) pcPointer = pcData; aiColor3D clrColor; for (unsigned int y = 0; y < sDesc.Height;++y) { aiColor3D clrColorLine; for (unsigned int x = 0; x < sDesc.Width;++x) { clrColorLine.r += pcPointer->r; clrColorLine.g += pcPointer->g; clrColorLine.b += pcPointer->b; pcPointer++; } clrColor.r += clrColorLine.r /= (float)sDesc.Width; clrColor.g += clrColorLine.g /= (float)sDesc.Width; clrColor.b += clrColorLine.b /= (float)sDesc.Width; pcCharPointer += iPitchDiff; } clrColor.r /= (float)sDesc.Height; clrColor.g /= (float)sDesc.Height; clrColor.b /= (float)sDesc.Height; if (!(clrColor.b > 215 && clrColor.r > 100 && clrColor.r < 140 && clrColor.g > 100 && clrColor.g < 140)) { // Unable to detect. Believe the original value obtained from the loader if (bWasOriginallyHM) { bMustConvert = true; } } } } } piTexture->UnlockRect(0); // if the input data is assumed to be a height map we'll // need to convert it NOW if (bMustConvert) { D3DSURFACE_DESC sDesc; piTexture->GetLevelDesc(0, &sDesc); IDirect3DTexture9* piTempTexture; if(FAILED(g_piDevice->CreateTexture( sDesc.Width, sDesc.Height, piTexture->GetLevelCount(), sDesc.Usage, sDesc.Format, sDesc.Pool, &piTempTexture, NULL))) { CLogDisplay::Instance().AddEntry( "[ERROR] Unable to create normal map texture", D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); return; } DWORD dwFlags; if (3 == iElement)dwFlags = D3DX_CHANNEL_LUMINANCE; else if (2 == iElement)dwFlags = D3DX_CHANNEL_RED; else if (1 == iElement)dwFlags = D3DX_CHANNEL_GREEN; else /*if (0 == iElement)*/dwFlags = D3DX_CHANNEL_BLUE; if(FAILED(D3DXComputeNormalMap(piTempTexture, piTexture,NULL,0,dwFlags,1.0f))) { CLogDisplay::Instance().AddEntry( "[ERROR] Unable to compute normal map from height map", D3DCOLOR_ARGB(0xFF,0xFF,0x0,0x0)); piTempTexture->Release(); return; } *piTextureOut = piTempTexture; piTexture->Release(); } }
HRESULT RacorX8::RestoreDeviceObjects() { HRESULT hr; IDirect3DDevice8* device; hr = m_spD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, m_iVP, &m_dpps, &device); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateDevice failed!", L"Error", 0); return E_FAIL; } m_spDevice.reset(device, [](IDirect3DDevice8* device) { device->Release(); }); //CreateSphere(); LoadXFile("sphere.x"); IDirect3DVertexBuffer8* vbNormal; hr = m_spDevice->CreateVertexBuffer(m_iNumVertices * 2 * sizeof SimpleVertex, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_MANAGED, &vbNormal); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVertexBuffer failed!", L"Error", 0); return E_FAIL; } hr = CreateNormal<ShaderVertex, SimpleVertex>(m_spVB.get(), vbNormal); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateNormal failed!", L"Error", 0); return E_FAIL; } m_spVBNormal.reset(vbNormal, [](IDirect3DVertexBuffer8* vbNormal){vbNormal->Release(); }); IDirect3DVertexBuffer8* vbTangent; hr = m_spDevice->CreateVertexBuffer(m_iNumVertices * 2 * sizeof SimpleVertex, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_MANAGED, &vbTangent); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVertexBuffer failed!", L"Error", 0); return E_FAIL; } hr = CreateTangent<ShaderVertex, SimpleVertex>(m_spVB.get(), vbTangent); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateTangent failed!", L"Error", 0); return E_FAIL; } m_spVBTangent.reset(vbTangent, [](IDirect3DVertexBuffer8* vbTangent){vbTangent->Release(); }); //DWORD dwDecl[MAX_FVF_DECL_SIZE]; //ZeroMemory(dwDecl, sizeof dwDecl); //pSphere->GetDeclaration(dwDecl); DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3), D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2), D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"specular.vso", &m_dwVSH); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"specular.pso", &m_dwPSH); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"specularBump.pso", &m_dwPSHBump); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } if (m_bPS14Avaliable) { hr = CreatePSFromBinFile(m_spDevice.get(), L"specularBump14.pso", &m_dwPSHBump14); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } } DWORD declLine[] = { D3DVSD_STREAM(0), D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), declLine, L"line.vso", &m_dwVSHLine); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"line.pso", &m_dwVPHLine); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } IDirect3DTexture8* color_map; hr = D3DXCreateTextureFromFile(m_spDevice.get(), _T("earth.bmp"), &color_map); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTextureFromFile failed!", L"Error", 0); return E_FAIL; } m_spColorMap.reset(color_map, [](IDirect3DTexture8* color_map){ color_map->Release(); }); IDirect3DTexture8* heightMap; hr = D3DXCreateTextureFromFile(m_spDevice.get(), _T("earthbump.bmp"), &heightMap); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTextureFromFile failed!", L"Error", 0); return E_FAIL; } m_spHeightMap.reset(heightMap, [](IDirect3DTexture8* heightMap) { heightMap->Release(); }); D3DSURFACE_DESC desc; m_spHeightMap->GetLevelDesc(0, &desc); IDirect3DTexture8* normalMap; hr = D3DXCreateTexture(m_spDevice.get(), desc.Width, desc.Height, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &normalMap); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTexture failed!", L"Error", 0); return E_FAIL; } m_spNormalMap.reset(normalMap, [](IDirect3DTexture8* normalMap){ normalMap->Release(); }); hr = D3DXComputeNormalMap(m_spNormalMap.get(), m_spHeightMap.get(), NULL, 0, D3DX_CHANNEL_RED, 10); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXComputeNormalMap failed!", L"Error", 0); return E_FAIL; } IDirect3DTexture8* power; hr = D3DXCreateTexture(m_spDevice.get(), 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &power); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTexture failed!", L"Error", 0); return E_FAIL; } m_spPower.reset(power, [](IDirect3DTexture8* power){ power->Release(); }); FLOAT fPower = 16.0f; hr = D3DXFillTexture(power, LightEval, &fPower); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXFillTexture failed!", L"Error", 0); return E_FAIL; } m_spDevice->SetViewport(&m_Viewport); m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_spDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); //m_spDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //m_spDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); //m_spDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); //m_spDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); //m_spDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_spDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); m_spDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); //m_spDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //m_spDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); //m_spDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); m_spDevice->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); m_spDevice->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); D3DXVECTOR4 vLight(0.0f, 0.0f, 1.0f, 0.0f); D3DXVec4Normalize(&vLight, &vLight); m_spDevice->SetVertexShaderConstant(12, &vLight, 1); D3DXVECTOR4 half(0.5f, 0.5f, 0.5f, 0.5f); m_spDevice->SetVertexShaderConstant(33, &half, 1); return S_OK; }
void DxStdMtl2::LoadTextureData(IHLSLCodeGenerator * codeGen) { Bitmap * bmap; BitmapInfo stBI; TimeValue t = GetCOREInterface()->GetTime(); int nWidth,nHeight; int numberOfTextures = elementContainer.NumberofElementsByType(EffectElements::kEleTex); for(int i=0; i<numberOfTextures;i++) { bool bBump; TextureElement * texEle = static_cast<TextureElement*>(elementContainer.GetElementByType(i,EffectElements::kEleTex)); TSTR mapType = texEle->GetMapName(); Texmap *texmap = codeGen->GetShaderDefinedTexmap(map,mapType.data(),bBump); if(texmap) { BMM_Color_64 *p; nWidth = nHeight = DIMDEFAULT; BitmapDimensions(nWidth,nHeight,texmap); // load and create the D3D texture; /* if(texmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) { BitmapTex *pBT; Bitmap *pTex; pBT = (BitmapTex *)texmap; pTex = pBT->GetBitmap(t); if (pTex) { nWidth = getClosestPowerOf2(pTex->Width()); nHeight = getClosestPowerOf2(pTex->Height()); } } */ stBI.SetType(BMM_TRUE_32); stBI.SetWidth(nWidth); stBI.SetHeight(nHeight); bmap = TheManager->Create(&stBI); if (bmap) { // LPDIRECT3DTEXTURE9 pRenderTex = texEle->GetD3DTexture(); texmap->RenderBitmap(t, bmap, MAPSCALE3D * 2.0f); p = new BMM_Color_64[nWidth*nHeight]; for (int y = 0; y < nHeight; y++) bmap->GetLinearPixels(0, y, nWidth, p + y * nWidth); if(texEle->pTex) { D3DSURFACE_DESC stLD; texEle->pTex->GetLevelDesc(0, &stLD); if (stLD.Width != nWidth || stLD.Height != nHeight) { SAFE_RELEASE(texEle->pTex); } } if(!texEle->pTex) pd3dDevice->CreateTexture(nWidth,nHeight, 0,D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&texEle->pTex, NULL); if(texEle->pTex) { PIXELFMT *pT; D3DLOCKED_RECT stLR; texEle->pTex->LockRect(0, &stLR, 0, 0); pT = (PIXELFMT *)stLR.pBits; for (int i = 0; i < nWidth * nHeight; i++) { pT[i].r = p[i].r >> 8; pT[i].g = p[i].g >> 8; pT[i].b = p[i].b >> 8; pT[i].a = p[i].a >> 8; } texEle->pTex->UnlockRect(0); if(bBump && texmap->ClassID() != GNORMAL_CLASS_ID) { // LPDIRECT3DTEXTURE9 normalTex = texEle->GetD3DBumpTexture(); if(texEle->pBumpTex) { D3DSURFACE_DESC stLD; texEle->pBumpTex->GetLevelDesc(0, &stLD); if (stLD.Width != nWidth || stLD.Height != nHeight) { SAFE_RELEASE(texEle->pBumpTex); } } if(!texEle->pBumpTex) pd3dDevice->CreateTexture(nWidth,nHeight, 0,D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&texEle->pBumpTex, NULL); D3DXComputeNormalMap(texEle->pBumpTex,texEle->pTex,NULL, NULL, D3DX_CHANNEL_RED,30.0f); if(texEle->GetParamHandle()) { pEffectParser->LoadTexture(texEle->pBumpTex, texEle->GetParameterName()); // pEffect->SetTexture(texEle->GetParamHandle(),texEle->pBumpTex); // D3DXSaveTextureToFile("c:\\temp\\normal_notgnormal.dds", D3DXIFF_DDS, texEle->pBumpTex, NULL); SAFE_RELEASE(texEle->pBumpTex); } } else { if(texEle->GetParamHandle()) { pEffectParser->LoadTexture(texEle->pTex, texEle->GetParameterName()); // pEffect->SetTexture(texEle->GetParamHandle(),texEle->pTex); // D3DXSaveTextureToFile("c:\\temp\\normal_gnormal.dds", D3DXIFF_DDS, texEle->pTex, NULL); SAFE_RELEASE(texEle->pTex); } } } bmap->DeleteThis(); } delete p; } else {
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; } }
/**----------------------------------------------------------------------------- * 정점버퍼를 생성하고 정점값을 채워넣는다. *------------------------------------------------------------------------------ */ HRESULT InitVB() { D3DSURFACE_DESC ddsd; D3DLOCKED_RECT d3drc; g_pTexHeight->GetLevelDesc( 0, &ddsd ); /// 텍스처의 정보 g_cxHeight = ddsd.Width; /// 텍스처의 가로크기 g_czHeight = ddsd.Height; /// 텍스처의 세로크기 g_pLog->Log( "Texture Size:[%d,%d]", g_cxHeight, g_czHeight ); if ( FAILED( g_pd3dDevice->CreateVertexBuffer( ddsd.Width*ddsd.Height*sizeof( CUSTOMVERTEX ), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ) { return E_FAIL; } HRESULT hr; // Create normal map texture the size of the original. if ( D3DXCreateTexture( g_pd3dDevice, g_cxHeight, g_czHeight, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pTexNormal ) == D3D_OK ) { g_pLog->Log( "비어있는 텍스쳐 생성! \n" ); if ( ( hr = D3DXComputeNormalMap( g_pTexNormal, g_pTexHeight, NULL, D3DX_NORMALMAP_MIRROR, D3DX_CHANNEL_LUMINANCE, 1000 ) ) == D3D_OK ) { g_pLog->Log( "노멀 맵 생성 성공! \n" ); } } D3DSURFACE_DESC ddsd2; g_pTexNormal->GetLevelDesc( 0, &ddsd2 ); /// 텍스처의 정보 D3DLOCKED_RECT d3drc2; hr = g_pTexNormal->LockRect( 0, &d3drc2, NULL, D3DLOCK_READONLY ); /// 텍스처 메모리 락! g_pTexHeight->LockRect( 0, &d3drc, NULL, D3DLOCK_READONLY ); VOID* pVertices; /// 정점버퍼 락! if ( FAILED( g_pVB->Lock( 0, g_cxHeight*g_czHeight*sizeof( CUSTOMVERTEX ), (void**)&pVertices, 0 ) ) ) { return E_FAIL; } CUSTOMVERTEX v; CUSTOMVERTEX* pV = (CUSTOMVERTEX*)pVertices; for ( DWORD z = 0; z < g_czHeight; z++ ) { for ( DWORD x = 0; x < g_cxHeight; x++ ) { v.p.x = (float)x - g_cxHeight / 2.0f; /// 정점의 x좌표(메시를 원점에 정렬) v.p.z = -( (float)z - g_czHeight / 2.0f ); /// 정점의 z좌표(메시를 원점에 정렬), z축이 모니터안쪽이므로 -를 곱한다. v.p.y = ( (float)( *( (LPDWORD)d3drc.pBits + x + z*( d3drc.Pitch / 4 ) ) & 0x000000ff ) ) / 10.0f; /// DWORD이므로 pitch/4 // v.n.x = v.p.x; // v.n.y = v.p.y; // v.n.z = v.p.z; v.n.x = (float)( ( *( (LPDWORD)d3drc2.pBits + x + z*( d3drc2.Pitch / 4 ) ) & 0x00ff0000 ) >> 16 ) - 128; v.n.y = (float)( ( *( (LPDWORD)d3drc2.pBits + x + z*( d3drc2.Pitch / 4 ) ) & 0x0000ff00 ) >> 8 ); v.n.z = (float)( ( *( (LPDWORD)d3drc2.pBits + x + z*( d3drc2.Pitch / 4 ) ) & 0x000000ff ) ) - 128; D3DXVec3Normalize( &v.n, &v.n ); v.t.x = (float)x / ( g_cxHeight - 1 ); v.t.y = (float)z / ( g_czHeight - 1 ); *pV++ = v; // g_pLog->Log( "[%f,%f,%f]", v.x, v.y, v.z ); } } g_pVB->Unlock(); g_pTexHeight->UnlockRect( 0 ); g_pTexNormal->UnlockRect( 0 ); return S_OK; }