예제 #1
0
파일: volume.c 프로젝트: AmesianX/wine
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;
}
예제 #2
0
파일: CreateDX.cpp 프로젝트: 2asoft/xray
	ETOOLS_API HRESULT WINAPI	
		D3DX_GetImageInfoFromFileInMemory(
		LPCVOID					pSrcData, 
		UINT					SrcDataSize, 
		D3DXIMAGE_INFO*			pSrcInfo)
	{
		return D3DXGetImageInfoFromFileInMemory(pSrcData, SrcDataSize, pSrcInfo);
	}
예제 #3
0
	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;
	}
예제 #4
0
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!
}
예제 #5
0
파일: devicedx8.cpp 프로젝트: skopp/rush
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
예제 #6
0
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");
}
예제 #7
0
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;
	}
}
예제 #8
0
//从内存中读取纹理到纹理列表
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;
}
예제 #9
0
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, &params );
			}
			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, &params );

			}
			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 );

}
예제 #10
0
파일: Texture.cpp 프로젝트: awdavies/cop
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;
    }
}