HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, const D3DBOX *dst_box, const void *src_data, UINT src_data_size, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info) { HRESULT hr; D3DBOX box; D3DXIMAGE_INFO image_info; TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_data %p, src_data_size %u, src_box %p, " "filter %#x, color_key 0x%08x, src_info %p.\n", dst_volume, dst_palette, dst_box, src_data, src_data_size, src_box, filter, color_key, src_info); if (!dst_volume || !src_data) return D3DERR_INVALIDCALL; if (FAILED(hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &image_info))) return hr; if (src_box) { if (src_box->Right > image_info.Width || src_box->Bottom > image_info.Height || src_box->Back > image_info.Depth) return D3DERR_INVALIDCALL; box = *src_box; } else { box.Left = 0; box.Top = 0; box.Right = image_info.Width; box.Bottom = image_info.Height; box.Front = 0; box.Back = image_info.Depth; } if (image_info.ImageFileFormat != D3DXIFF_DDS) { FIXME("File format %#x is not supported yet\n", image_info.ImageFileFormat); return E_NOTIMPL; } hr = load_volume_from_dds(dst_volume, dst_palette, dst_box, src_data, &box, filter, color_key, &image_info); if (FAILED(hr)) return hr; if (src_info) *src_info = image_info; return D3D_OK; }
ETOOLS_API HRESULT WINAPI D3DX_GetImageInfoFromFileInMemory( LPCVOID pSrcData, UINT SrcDataSize, D3DXIMAGE_INFO* pSrcInfo) { return D3DXGetImageInfoFromFileInMemory(pSrcData, SrcDataSize, pSrcInfo); }
bool DisplaySurface::Create(const boost::any& _rConfig) { CreateInfo* pInfo = boost::any_cast<CreateInfo*>(_rConfig); FilePtr pFile = NULL; bool bResult = (NULL != pInfo); { pFile = FS::GetRoot()->OpenFile(pInfo->m_strPath, FS::EOpenMode_READBINARY); bResult = (NULL != pFile); } if (false != bResult) { int sSize = pFile->Size(); unsigned char* pBuffer = new unsigned char[sSize]; sSize = pFile->Read(pBuffer, sSize); bResult = SUCCEEDED(D3DXGetImageInfoFromFileInMemory(pBuffer, sSize, &m_oInfo)); if (false != bResult) { #pragma message(__FUNCTION__" : for better support some image formats must be converted into supported surface format. For example luminance image should be translated into paletted surface.") bResult = SUCCEEDED(m_rDisplay.GetDevicePtr()->CreateOffscreenPlainSurface(m_oInfo.Width, m_oInfo.Height, m_oInfo.Format, D3DPOOL_DEFAULT, &m_pSurface, NULL)); } if (false != bResult) { bResult = SUCCEEDED(D3DXLoadSurfaceFromFileInMemory(m_pSurface, NULL, NULL, pBuffer, sSize, NULL, D3DX_FILTER_NONE, 0xff000000, NULL)); } if (false != bResult) { m_uBPP = m_rDisplay.GetFormatBitsPerPixel(m_oInfo.Format); bResult = (0 != m_uBPP); } delete[] pBuffer; FS::GetRoot()->CloseFile(pFile); } return bResult; }
std::string CGameMap::initialize() { assert( !mCells ); /* Format of map data: string Tissue Name int32 Tissue Bitmap Length byte[] Tissue Bitmap (200*200) string Entites text file string Streams text file string Walls text files */ const BYTE* data; // // parse name mName = bu::receiveStr(); // TBD: workaround around Richard's funky stuff int lastSlash = mName.find_last_of( "\\//" ); if( lastSlash >= 0 ) mName = mName.substr( lastSlash+1, mName.length()-lastSlash ); CONS << "Game map name: " << mName << endl; // // read map bitmap int bmpSize = bu::receiveInt(); net::receiveChunk( data, bmpSize, true ); // compute CRC of the bitmap const char* bmpFile = (const char*)data; mCRC = boost::crc<32,0xFFFFFFFF,0,0,false,false>( bmpFile, bmpSize ); HRESULT hr; D3DXIMAGE_INFO bitmapInfo; hr = D3DXGetImageInfoFromFileInMemory( bmpFile, bmpSize, &bitmapInfo ); if( FAILED(hr) ) { return "Error in game map - incorrect tissue bitmap format"; } assert( bitmapInfo.Width > 10 && bitmapInfo.Height > 10 ); assert( bitmapInfo.Width * bitmapInfo.Height <= 256*256 ); if( bitmapInfo.Width < 10 || bitmapInfo.Height < 10 ) { return "Error in game map - map is too small"; } if( bitmapInfo.Width * bitmapInfo.Height > 256*256 ) { return "Error in game map - map is too large"; } mCellsX = bitmapInfo.Width; mCellsY = bitmapInfo.Height; mCells = new SCell[ mCellsX * mCellsY ]; CD3DDevice& dx = CD3DDevice::getInstance(); IDirect3DSurface9* surface = 0; hr = dx.getDevice().CreateOffscreenPlainSurface( bitmapInfo.Width, bitmapInfo.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL ); assert( SUCCEEDED(hr) ); hr = D3DXLoadSurfaceFromFileInMemory( surface, NULL, NULL, bmpFile, bmpSize, NULL, D3DX_DEFAULT, 0, NULL ); if( FAILED(hr) ) { return "Error in game map - incorrect cells map format"; } D3DLOCKED_RECT lr; surface->LockRect( &lr, NULL, D3DLOCK_READONLY ); const char* linePtr = (const char*)lr.pBits; for( int y = 0; y < mCellsY; ++y ) { const D3DCOLOR* p = (const D3DCOLOR*)linePtr; for( int x = 0; x < mCellsX; ++x ) { SCell& cell = mCells[y*mCellsX+x]; switch( *p ) { case 0xFFff0000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_BLOOD; break; case 0xFF00ff00: cell.type = CELL_BLOOD2; cell.color = CCOLOR_BLOOD; break; case 0xFF0000ff: cell.type = CELL_BLOOD3; cell.color = CCOLOR_BLOOD; break; case 0xFF800000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_BONE; break; case 0xFF008000: cell.type = CELL_BLOOD2; cell.color = CCOLOR_BONE; break; case 0xFF000080: cell.type = CELL_BLOOD3; cell.color = CCOLOR_BONE; break; case 0xFFC80000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_NEURON; break; case 0xFF00C800: cell.type = CELL_BLOOD2; cell.color = CCOLOR_NEURON; break; case 0xFF0000C8: cell.type = CELL_BLOOD3; cell.color = CCOLOR_NEURON; break; default: cell.type = CELL_BONE; cell.color = CCOLOR_BLOOD; } cell.height = MIN_CELL_HEIGHT; cell.nearBone = true; ++p; } linePtr += lr.Pitch; } surface->UnlockRect(); surface->Release(); // check map validity if( !checkMapValidity() ) return "Tissue contains invalid topology (cells adjacent only diagonally)"; // // read entities std::string pts = bu::receiveStr(); char* ptsFile = (char*)pts.c_str(); // HACK const char* tokens = "\n\r"; const char* pline = strtok( ptsFile, tokens ); do { if( !pline ) break; int etype, eposx, eposy; int fread = sscanf( pline, "%i:%i:%i", &eposx, &eposy, &etype ); if( fread != 3 ) break; mPoints.push_back( SPoint(ePointType(etype), eposx, eposy ) ); } while( pline = strtok( NULL, tokens ) ); // // read streams std::string strms = bu::receiveStr(); // streams char* strmsFile = (char*)strms.c_str(); // HACK pline = strtok( strmsFile, tokens ); do { if( !pline ) break; int sx, sy, sw, sh, sdir; int fread = sscanf( pline, "%i:%i:%i:%i:%i", &sx, &sy, &sw, &sh, &sdir ); assert( sx >= 0 && sx < mCellsX ); assert( sy >= 0 && sy < mCellsY ); assert( sx+sw <= mCellsX ); assert( sy+sh <= mCellsY ); assert( sdir >= 0 && sdir <= 3 ); assert( fread == 5 ); if( fread != 5 ) break; SStream strm; strm.x = sx; strm.y = sy; strm.width = sw; strm.height = sh; switch( sdir ) { case 0: strm.deltaX = 0; strm.deltaY = 1; break; case 1: strm.deltaX = 0; strm.deltaY = -1; break; case 2: strm.deltaX = 1; strm.deltaY = 0; break; case 3: strm.deltaX = -1; strm.deltaY = 0; break; } mStreams.push_back( strm ); } while( pline = strtok( NULL, tokens ) ); // TBD: walls bu::receiveStr(); // walls // // all is loaded now // calculate cell heights calcCellHeights(); // add some decorative elements static int DECOR_TYPES_IN_TISSUE[DECOR_POINT_TYPE_COUNT] = { (1<<CCOLOR_BLOOD), (1<<CCOLOR_BLOOD), (1<<CCOLOR_BLOOD), (1<<CCOLOR_BONE), (1<<CCOLOR_BONE), (1<<CCOLOR_BONE) | (1<<CCOLOR_BLOOD), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON)|(1<<CCOLOR_BLOOD)|(1<<CCOLOR_BONE), }; const int DECOR_PTS_COUNT = 125; const int MAX_TRY_COUNT = DECOR_PTS_COUNT * 10; int decPtsCounter = 0; int tryCounter = 0; while( decPtsCounter < DECOR_PTS_COUNT && tryCounter < MAX_TRY_COUNT ) { ++tryCounter; int x = gRandom.getUInt() % mCellsX; int y = gRandom.getUInt() % mCellsY; const SCell& cell = mCells[pos2index(x,y)]; if( !isBlood(cell.type) || cell.nearBone ) continue; if( cell.height < 2.0f ) continue; int ptType = gRandom.getUInt() % DECOR_POINT_TYPE_COUNT; if( !(DECOR_TYPES_IN_TISSUE[ptType] & (1<<cell.color)) ) continue; mPoints.push_back( SPoint(PT_DECORATIVE,x,y, ptType) ); decPtsCounter++; } // register level texture CSharedTextureBundle::getInstance().registerTexture( RID_TEX_LEVEL, *new CGameMapTextureCreator( *this ) ); return ""; // all ok! }
int JRenderServer::GetTextureID( const char* texName ) { if (!texName || !m_pDevice) return -1; for (int i = 0; i < m_Textures.size(); i++) { if (!stricmp( m_Textures[i].m_Name.c_str(), texName )) return i; } FInStream is; g_pFileServer->OpenMedia( texName, "", is ); if (!is) return -1; int nBytes = is.GetTotalSize(); BYTE* buf = new BYTE[nBytes]; is.Read( buf, nBytes ); D3DXIMAGE_INFO info; HRESULT hRes = D3DXGetImageInfoFromFileInMemory( buf, nBytes, &info ); DXBaseTexture* pTex = NULL; TextureFile tex; tex.m_pDepthStencil = NULL; tex.m_Name = texName; TextureProperties& tp = tex.m_Prop; if (info.ResourceType == D3DRTYPE_CUBETEXTURE) { IDirect3DCubeTexture8* pCubeTexture = NULL; hRes = D3DXCreateCubeTextureFromFileInMemoryEx( m_pDevice, buf, nBytes, D3DX_DEFAULT, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0x00000000, NULL, NULL, &pCubeTexture ); pTex = pCubeTexture; D3DSURFACE_DESC desc; pCubeTexture->GetLevelDesc( 0, &desc ); tp.m_Format = ConvertColorFormat( desc.Format ); tp.m_Height = desc.Height; tp.m_Width = desc.Width; tp.m_PoolType = ConvertPoolType( desc.Pool ); } else { DXTexture* pTexture2D = NULL; hRes = D3DXCreateTextureFromFileInMemoryEx( m_pDevice, buf, nBytes, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED , D3DX_DEFAULT, D3DX_DEFAULT, 0x00000000, NULL, NULL, &pTexture2D ); pTex = pTexture2D; D3DSURFACE_DESC desc; pTexture2D->GetLevelDesc( 0, &desc ); tp.m_Format = ConvertColorFormat( desc.Format ); tp.m_Height = desc.Height; tp.m_Width = desc.Width; tp.m_PoolType = ConvertPoolType( desc.Pool ); } delete []buf; if (!pTex || hRes != S_OK) return -1; tp.m_bAutoGenMips = false; tp.m_NMips = pTex->GetLevelCount(); strcpy( tp.m_Name, texName ); tex.m_pTexture = pTex; m_Textures.push_back( tex ); return m_Textures.size() - 1; } // JRenderServer::GetTextureID
static void test_D3DXGetImageInfo(void) { HRESULT hr; D3DXIMAGE_INFO info; BOOL testdummy_ok, testbitmap_ok; hr = create_file("testdummy.bmp", noimage, sizeof(noimage)); /* invalid image */ testdummy_ok = SUCCEEDED(hr); hr = create_file("testbitmap.bmp", bmp01, sizeof(bmp01)); /* valid image */ testbitmap_ok = SUCCEEDED(hr); /* D3DXGetImageInfoFromFile */ if(testbitmap_ok) { hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info); ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */ ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); } else skip("Couldn't create \"testbitmap.bmp\"\n"); if(testdummy_ok) { hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */ ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); } else skip("Couldn't create \"testdummy.bmp\"\n"); hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", NULL); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromFileA("", &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromFileA(NULL, &info); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileA(NULL, NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); /* D3DXGetImageInfoFromResource */ todo_wine { hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL); ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); } hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), NULL); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", NULL); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromResourceA(NULL, NULL, NULL); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); /* D3DXGetImageInfoFromFileInMemory */ hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), &info); ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)+5, &info); /* too large size */ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01), NULL); ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL); ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK); hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); todo_wine { hr = D3DXGetImageInfoFromFileInMemory(bmp01, sizeof(bmp01)-1, &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); } hr = D3DXGetImageInfoFromFileInMemory(bmp01+1, sizeof(bmp01)-1, &info); ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA); hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, &info); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(bmp01, 0, NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, &info); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, &info); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, &info); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); /* cleanup */ if(testdummy_ok) DeleteFileA("testdummy.bmp"); if(testbitmap_ok) DeleteFileA("testbitmap.bmp"); }
bool LoadaImgFromMem(char *mem,unsigned long size,unsigned int hn,unsigned int vn,unsigned int *delay,wchar_t *name) { LPDIRECT3DTEXTURE9 tex_all; //获取图片信息 D3DXIMAGE_INFO imageInfo; D3DXGetImageInfoFromFileInMemory(mem, size, &imageInfo); unsigned int width = imageInfo.Width; unsigned int height = imageInfo.Height; unsigned int h_width = width/hn; unsigned int v_height = height/vn; long bytenum = h_width*v_height*4; unsigned int all = hn*vn; byte **pixel_buf = new byte*[all]; for(unsigned int i=0;i<all;i++) { pixel_buf[i] = new byte[bytenum]; } if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_pd3dD,mem,size,imageInfo.Width,imageInfo.Height,imageInfo.MipLevels,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,D3DX_FILTER_NONE,D3DX_DEFAULT,0,NULL,NULL,&tex_all))) { MessageBox(0,name,TEXT("读取图片错误"),MB_OK); return 0; } else { //对tex进行处理 D3DLOCKED_RECT locked_rect; tex_all->LockRect(0, &locked_rect, NULL, 0); BYTE *pByte = (BYTE *) locked_rect.pBits; int p1 = 0,p2 = 0,p2_base = 0; for(unsigned int n=0;n<all;n++) { p2_base = (n/hn)*locked_rect.Pitch*v_height+(n%hn)*h_width*4; for(unsigned int h=0;h<v_height;h++) { for(unsigned int w=0;w<h_width;w++) { pixel_buf[n][p1] = pByte[p2_base+p2]; pixel_buf[n][p1+1] = pByte[p2_base+p2+1]; pixel_buf[n][p1+2] = pByte[p2_base+p2+2]; pixel_buf[n][p1+3] = pByte[p2_base+p2+3]; p1+=4; p2+=4; } p2 = p2 + locked_rect.Pitch - h_width*4; } p1 = 0; p2 = 0; } tex_all->UnlockRect(0); tex_all->Release(); /////////////////////////////////////////////////////// frames *tempf = new frames; tempf->frame_number = all; frame *f = new frame[all]; for(unsigned int i=0;i<all;i++) { if(delay) f[i].delay = delay[i]; else f[i].delay = 0; f[i].tex = new mytex; if (g_pd3dD->CreateTexture(h_width, v_height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &f[i].tex->tex, NULL) == D3D_OK) { //对tex进行处理 D3DLOCKED_RECT locked_rect; f[i].tex->tex->LockRect(0, &locked_rect, NULL, 0); //直接复制内存块 CopyMemory(locked_rect.pBits,pixel_buf[i],bytenum); f[i].tex->tex->UnlockRect(0); f[i].tex->width = h_width; f[i].tex->height = v_height; } else return 0; } tempf->f = f; framelist *temp = new framelist; int namelen = wcslen(name); temp->name = new wchar_t[namelen]; wcscpy(temp->name,name); temp->fs = tempf; temp->next = 0; unsigned int i = BKDRHash(name); if(!framelist_headp[i]) { framelist_headp[i] = temp; framelist_nowp[i] = framelist_headp[i]; } else { framelist_nowp[i]->next = temp; framelist_nowp[i] = temp; } return true; } }
//从内存中读取纹理到纹理列表 bool LoadImgFromMem(char *mem,unsigned long size,bool mask,wchar_t *name) { texlist *temp = new texlist; temp->tex = new mytex; int namelen = wcslen(name); if(namelen<1) return false; temp->name = new wchar_t[namelen]; wcscpy(temp->name,name); temp->next = 0; //获取图片信息 D3DXIMAGE_INFO imageInfo; D3DXGetImageInfoFromFileInMemory(mem, size, &imageInfo); temp->tex->height = imageInfo.Height; if(mask) temp->tex->width = imageInfo.Width/2; else temp->tex->width = imageInfo.Width; if(!mask) { //从内存中创建贴图 if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_pd3dD,mem,size,imageInfo.Width,imageInfo.Height,imageInfo.MipLevels,0,imageInfo.Format, D3DPOOL_MANAGED,D3DX_FILTER_NONE,D3DX_DEFAULT,0,NULL,NULL,&temp->tex->tex))) { MessageBox(0,name,TEXT("读取图片错误"),MB_OK); return 0; } /* UINT SizeX=0,SizeY=0; if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_pd3dD,mem,size,SizeX,SizeY,D3DX_FROM_FILE,0,D3DFMT_FROM_FILE, D3DPOOL_MANAGED,D3DX_FILTER_NONE,D3DX_DEFAULT,0,&imageInfo,NULL,&temp->tex->tex))) { MessageBox(0,name,TEXT("读取图片错误"),MB_OK); return 0; } if(SizeX==(UINT)-2) imageInfo.Width = SizeX; if(SizeY==(UINT)-2) imageInfo.Height = SizeY; temp->tex->height = imageInfo.Height; if(mask) temp->tex->width = imageInfo.Width/2; else temp->tex->width = imageInfo.Width;*/ } else { unsigned int width = temp->tex->width; unsigned int height = temp->tex->height; long bytenum = width*height*4; byte* masked_pixel_buf = new byte[bytenum]; if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_pd3dD,mem,size,imageInfo.Width,imageInfo.Height,imageInfo.MipLevels,0,imageInfo.Format, D3DPOOL_MANAGED,D3DX_FILTER_NONE,D3DX_DEFAULT,0,NULL,NULL,&temp->tex->tex))) { MessageBox(0,name,TEXT("读取图片错误"),MB_OK); return 0; } else { //对tex进行处理 D3DLOCKED_RECT locked_rect; temp->tex->tex->LockRect(0, &locked_rect, NULL, 0); BYTE *pByte = (BYTE *) locked_rect.pBits; BYTE *pmaskByte = (BYTE *) locked_rect.pBits + width*4; unsigned int iOffset = locked_rect.Pitch/2; //每行的字节数 unsigned int i=0; for(unsigned int iRow=0; iRow<height; iRow++ ) { for(unsigned int iCol=0; iCol<width; iCol++ ) { masked_pixel_buf[i] = pByte[0]; masked_pixel_buf[i+1] = pByte[1]; masked_pixel_buf[i+2] = pByte[2]; masked_pixel_buf[i+3] = 0xff - pmaskByte[0]; i += 4; pByte += 4; pmaskByte += 4; } pByte += iOffset; pmaskByte += iOffset; } temp->tex->tex->UnlockRect(0); temp->tex->tex->Release(); if (g_pd3dD->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &temp->tex->tex, NULL) == D3D_OK) { //对tex进行处理 D3DLOCKED_RECT locked_rect; temp->tex->tex->LockRect(0, &locked_rect, NULL, 0); //直接复制内存块 CopyMemory(locked_rect.pBits,masked_pixel_buf,bytenum); temp->tex->tex->UnlockRect(0); } else return 0; } } unsigned int i = BKDRHash(name); if(!texlist_headp[i]) { texlist_headp[i] = temp; texlist_nowp[i] = texlist_headp[i]; } else { texlist_nowp[i]->next = temp; texlist_nowp[i] = temp; } return true; }
void r3dTexture::LoadTextureInternal(int index, void* FileInMemoryData, uint32_t FileInMemorySize, D3DFORMAT TargetTexFormat, int DownScale, int DownScaleMinDim, int SystemMem, const char* DEBUG_NAME ) { D3DPOOL targetPool = SystemMem ? D3DPOOL_SYSTEMMEM : r3dDefaultTexturePool ; int TgW = 0; int TgH = 0; int TgD = 0; R3D_DEIVCE_QUEUE_OBJ( D3DXIMAGE_INFO, pInfo) ; ZeroMemory(&pInfo, sizeof (pInfo)); D3DXGetImageInfoFromFileInMemory( FileInMemoryData, FileInMemorySize, &pInfo ); int Mip = 1; int DownScaledDueToMaxDim = 1; UINT ScaledWidth = pInfo.Width; UINT ScaledHeight = pInfo.Height; UINT ScaledDepth = pInfo.Depth; if( int maxDim = r_max_texture_dim->GetInt() ) { CalcDownScaleToMatchMaxDim( DownScaledDueToMaxDim, ScaledWidth , maxDim ); CalcDownScaleToMatchMaxDim( DownScaledDueToMaxDim, ScaledHeight , maxDim ); CalcDownScaleToMatchMaxDim( DownScaledDueToMaxDim, ScaledDepth , maxDim ); ScaledWidth = R3D_MAX( int( ScaledWidth / DownScaledDueToMaxDim ), 1 ); ScaledHeight = R3D_MAX( int( ScaledHeight / DownScaledDueToMaxDim ), 1 ); ScaledDepth = R3D_MAX( int( ScaledDepth / DownScaledDueToMaxDim ), 1 ); } int NextDownScale = R3D_MAX( DownScale / DownScaledDueToMaxDim, 1 ); ScaledWidth = R3D_MAX( int( ScaledWidth / NextDownScale ), 1 ); ScaledHeight = R3D_MAX( int( ScaledHeight / NextDownScale ), 1 ); ScaledDepth = R3D_MAX( int( ScaledDepth / NextDownScale ), 1 ); UINT totalMipDown = ilog2( R3D_MAX( R3D_MAX( pInfo.Width / ScaledWidth, pInfo.Height / ScaledHeight ), pInfo.Depth / ScaledDepth ) ); // too small or may be incompatible with DXT after downscale if( ( (int)pInfo.Width <= DownScaleMinDim || (int)pInfo.Height <= DownScaleMinDim ) || ( pInfo.Width < 16 || pInfo.Height < 16 ) ) { totalMipDown = 0 ; ScaledWidth = pInfo.Width; ScaledHeight = pInfo.Height; ScaledDepth = pInfo.Depth; } TgW = ScaledWidth; TgH = ScaledHeight; TgD = ScaledDepth; bCubemap = pInfo.ResourceType == D3DRTYPE_CUBETEXTURE; int ScaleFilter = totalMipDown ? D3DX_FILTER_POINT : D3DX_FILTER_NONE ; r3d_assert( !(TgD > 1 && bCubemap) ); const bool ALLOW_ASYNC = !!g_async_d3dqueue->GetInt() ; if( bCubemap ) { if( totalMipDown && totalMipDown < pInfo.MipLevels ) { r3dDeviceTunnel::D3DXCreateCubeTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, pInfo.Width, pInfo.MipLevels - totalMipDown, 0, TargetTexFormat, targetPool, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0x00000000, &pInfo, NULL, &m_TexArray[ index ], ALLOW_ASYNC ); R3D_DEIVCE_QUEUE_OBJ( DownTexParams, parms ) ; parms.texTunnel = &m_TexArray[ index ] ; parms.mipsDown = totalMipDown ; AddCustomDeviceQueueItem( DoDownCube, &parms ); } else { r3dDeviceTunnel::D3DXCreateCubeTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, ScaledWidth, pInfo.MipLevels, 0, TargetTexFormat, targetPool, ScaleFilter, ScaleFilter, 0x00000000, &pInfo, NULL, &m_TexArray[ index ], ALLOW_ASYNC ) ; } } else { if( TgD <= 1 ) { if( totalMipDown && totalMipDown < pInfo.MipLevels ) { // load original texture r3dDeviceTunnel::D3DXCreateTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, pInfo.Width, pInfo.Height, pInfo.MipLevels, 0, TargetTexFormat, targetPool, D3DX_FILTER_NONE, D3DX_FILTER_NONE ,0x00000000, &pInfo, NULL, &m_TexArray[ index ], DEBUG_NAME, ALLOW_ASYNC ); // create downscaled version by copying mip levels into a new texture R3D_DEIVCE_QUEUE_OBJ( DownTexParams, params ) ; params.texTunnel = &m_TexArray[ index ] ; params.mipsDown = totalMipDown ; AddCustomDeviceQueueItem( DoDownTex2D, ¶ms ); } else { r3dDeviceTunnel::D3DXCreateTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, ScaledWidth, ScaledHeight, pInfo.MipLevels, 0, TargetTexFormat, targetPool, ScaleFilter, ScaleFilter, 0x00000000, &pInfo, NULL, &m_TexArray[ index ], DEBUG_NAME, ALLOW_ASYNC ); } } else { if( totalMipDown && totalMipDown < pInfo.MipLevels ) { r3dDeviceTunnel::D3DXCreateVolumeTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, ScaledWidth, ScaledHeight, ScaledDepth, pInfo.MipLevels - totalMipDown, 0, TargetTexFormat, targetPool, D3DX_FILTER_POINT, D3DX_FILTER_POINT, 0x00000000, &pInfo, NULL, &m_TexArray[ index ], ALLOW_ASYNC ); R3D_DEIVCE_QUEUE_OBJ( DownTexParams, params ) ; params.texTunnel = &m_TexArray[ index ] ; params.mipsDown = totalMipDown ; AddCustomDeviceQueueItem( DoDownTex3D, ¶ms ); } else { r3dDeviceTunnel::D3DXCreateVolumeTextureFromFileInMemoryEx( FileInMemoryData, FileInMemorySize, ScaledWidth, ScaledHeight, ScaledDepth, pInfo.MipLevels, 0, TargetTexFormat, targetPool, ScaleFilter, ScaleFilter, 0x00000000, &pInfo, NULL, &m_TexArray[ index ], ALLOW_ASYNC ); } } } if( !ALLOW_ASYNC ) { free( FileInMemoryData ); FileInMemoryData = 0 ; } if( !g_async_d3dqueue->GetInt() ) { if(!m_TexArray[ index ].Valid()) // failed to load? { r3dArtBug("Failed to load texture '%s'\n", Location.FileName); } } Width = TgW; Height = TgH; Depth = TgD; TexFormat = pInfo.Format; R3D_DEIVCE_QUEUE_OBJ( PostLoadStuffParams, parms ) ; parms.FileName = Location.FileName ; parms.oNumMips = &NumMipMaps ; parms.tunnel = &m_TexArray[index] ; parms.StuffTofree = FileInMemoryData ; if( g_async_d3dqueue->GetInt() ) AddCustomDeviceQueueItem( DoPostLoadStuff, &parms ); else ProcessCustomDeviceQueueItem( DoPostLoadStuff, &parms ); }
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; } }