예제 #1
0
파일: Screen.cpp 프로젝트: fathat/game-src
void Screen3D::TakeScreenshot(char* basefilename)
{
	//declarations
	IDirect3DSurface9* FrontBuffer; //this is our pointer to the memory location containing our copy of the
                                //front buffer
	IDirect3DSurface9* Thumbnail;
	HRESULT hr;

	//Create surface for stuff to be copied to
	
	//D3DDevice->CreateOffscreenPlainSurface(DisplayMode.Width, DisplayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &FrontBuffer, NULL);
	hr = D3DDevice->CreateOffscreenPlainSurface(100, 75, D3DFMT_X8R8G8B8, D3DPOOL_SCRATCH , &Thumbnail, NULL);

	//now we copy the front buffer into our surface
	//HRESULT hr = D3DDevice->GetFrontBufferData(0, FrontBuffer);
	hr = D3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &FrontBuffer);

	

	//make sure we got the front buffer
	if(hr != D3D_OK)
	{
		Thumbnail->Release(); 
		FrontBuffer->Release(); 
		return;
	}

	//load the image into the thumbnail
	D3DXLoadSurfaceFromSurface(Thumbnail, NULL, NULL, FrontBuffer, NULL, NULL, D3DX_DEFAULT, 0);

	//write screen shot to a bitmap file, as well as a thumbnail
	std::string BmpFileName = "..\\screenshots\\";
	std::string ThumbFileName = "..\\screenshots\\_";
	BmpFileName += basefilename;
	BmpFileName += ".bmp";
	ThumbFileName += basefilename;
	ThumbFileName += ".bmp";
	D3DXSaveSurfaceToFile(BmpFileName.c_str(), D3DXIFF_BMP, FrontBuffer, NULL, NULL);
	D3DXSaveSurfaceToFile(ThumbFileName.c_str(), D3DXIFF_BMP, Thumbnail, NULL, NULL);

	//release the surface so there is no memory leak
	FrontBuffer->Release();
	Thumbnail->Release();

}
예제 #2
0
//截图
void ScreenShot (char *filename)
{
	IDirect3DSurface9	*tmp = NULL;
	IDirect3DSurface9	*back = NULL;

	//生成固定颜色模式的离屏表面(Width和 Height为屏幕或窗口的宽高)
	Device->CreateOffscreenPlainSurface(Width, Height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tmp, NULL);

	// 获得BackBuffer的D3D Surface
	Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back);

	// Copy一下,,需要时转换颜色格式
	D3DXLoadSurfaceFromSurface(tmp, NULL, NULL, back, NULL, NULL, D3DX_FILTER_NONE, 0);

	// 保存成BMP格式
	D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, tmp, NULL, NULL);

	// 释放Surface,防止内存泄漏
	tmp->Release();
	back->Release();
}
bool CApplicationRenderer::CopySurface(LPDIRECT3DSURFACE8 pSurfaceSource, const RECT* rcSource, LPDIRECT3DSURFACE8 pSurfaceDest, const RECT* rcDest)
{
  if (m_Resolution == HDTV_1080i)
  {
    //CopRects doesn't work at all in 1080i, D3DXLoadSurfaceFromSurface does but is ridiculously slow...
    return SUCCEEDED(D3DXLoadSurfaceFromSurface(pSurfaceDest, NULL, rcDest, pSurfaceSource, NULL, rcSource, D3DX_FILTER_NONE, 0));
  }
  else
  {
    if (rcDest)
    {
      const POINT ptDest = { rcDest->left, rcDest->top };
      return SUCCEEDED(g_graphicsContext.Get3DDevice()->CopyRects(pSurfaceSource, rcSource, rcSource?1:0, pSurfaceDest, &ptDest));
    }
    else
    {
      const POINT ptDest = { 0, 0 };
      return SUCCEEDED(g_graphicsContext.Get3DDevice()->CopyRects(pSurfaceSource, rcSource, rcSource?1:0, pSurfaceDest, &ptDest));
    }
  }
}
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;
}
예제 #5
0
void ReplaceTextureLevel(IDirect3DTexture8* srcTexture, IDirect3DTexture8* repTexture, UINT level)
{
    IDirect3DSurface8* src = NULL;
    IDirect3DSurface8* dest = NULL;

    if (SUCCEEDED(srcTexture->GetSurfaceLevel(level, &dest))) {
        if (SUCCEEDED(repTexture->GetSurfaceLevel(level, &src))) {
            //DumpTexture(srcTexture);
            if (SUCCEEDED(D3DXLoadSurfaceFromSurface(
                            dest, NULL, NULL,
                            src, NULL, NULL,
                            D3DX_DEFAULT, 0))) {
                //LogWithNumber(&k_boot,"ReplaceTextureLevel: replacing level %d COMPLETE", level);

            } else {
                //LogWithNumber(&k_boot,"ReplaceTextureLevel: replacing level %d FAILED", level);
            }
            src->Release();
        }
        dest->Release();
    }
}
예제 #6
0
bool CN3Texture::Convert(D3DFORMAT Format, int nWidth, int nHeight, BOOL bGenerateMipMap)
{
	if(m_lpTexture == NULL) return false;

	D3DSURFACE_DESC dsd;
	m_lpTexture->GetLevelDesc(0, &dsd);
	if(0 >= nWidth || 0 >= nHeight)
	{
		nWidth = dsd.Width;
		nHeight = dsd.Height;
	}

	LPDIRECT3DTEXTURE8 lpTexOld = m_lpTexture;

	m_lpTexture = NULL;
	if(this->Create(nWidth, nHeight, Format, bGenerateMipMap) == false) return false;
	if(bGenerateMipMap)
	{
		LPDIRECT3DSURFACE8 lpTSOld;
		lpTexOld->GetSurfaceLevel(0, &lpTSOld);
		this->GenerateMipMap(lpTSOld); // MipMap 생성
		lpTSOld->Release();
	}
	else
	{
		LPDIRECT3DSURFACE8 lpTSNew;
		LPDIRECT3DSURFACE8 lpTSOld;
		m_lpTexture->GetSurfaceLevel(0, &lpTSNew);
		lpTexOld->GetSurfaceLevel(0, &lpTSOld);
		D3DXLoadSurfaceFromSurface(lpTSNew, NULL, NULL, lpTSOld, NULL, NULL, D3DX_FILTER_NONE, 0); // 첫번재 레벨 서피스 복사.
		lpTSOld->Release();
		lpTSNew->Release();
	}

	lpTexOld->Release(); lpTexOld = NULL;
	
	return true;
}
예제 #7
0
void CGXRenderTexture::LoadTexture(TxtrCacheEntry* pEntry)
{
#if 0
	//This function copies the current color buffer (m_pTexture for this RenderTexture) to pEntry->pTexture
	bool IsBeingRendered = m_beingRendered;
	if( IsBeingRendered )
	{
		TXTRBUF_DUMP(TRACE0("Warning, loading from render_texture while it is being rendered"));

		SetAsRenderTarget(false);
		//return;
	}

	CTexture *pSurf = pEntry->pTexture;
	TxtrInfo &ti = pEntry->ti;

	// Need to load texture from the saved back buffer

	MYLPDIRECT3DTEXTURE pNewTexture = MYLPDIRECT3DTEXTURE(pSurf->GetTexture());
	MYLPDIRECT3DSURFACE pNewSurface = NULL;
	HRESULT res = pNewTexture->GetSurfaceLevel(0,&pNewSurface);
	MYLPDIRECT3DSURFACE pSourceSurface = NULL;
	(MYLPDIRECT3DTEXTURE(m_pTexture->GetTexture()))->GetSurfaceLevel(0,&pSourceSurface);

	int left = (pEntry->ti.Address- m_pInfo->CI_Info.dwAddr )%m_pInfo->CI_Info.bpl + pEntry->ti.LeftToLoad;
	int top = (pEntry->ti.Address- m_pInfo->CI_Info.dwAddr)/m_pInfo->CI_Info.bpl + pEntry->ti.TopToLoad;
	RECT srcrect = {uint32(left*m_pInfo->scaleX) ,uint32(top*m_pInfo->scaleY), 
		uint32(min(m_width, left+(int)ti.WidthToLoad)*m_pInfo->scaleX), 
		uint32(min(m_height,top+(int)ti.HeightToLoad)*m_pInfo->scaleY) };

	if( pNewSurface != NULL && pSourceSurface != NULL )
	{
		if( left < m_width && top<m_height )
		{
			RECT dstrect = {0,0,ti.WidthToLoad,ti.HeightToLoad};
			HRESULT res = D3DXLoadSurfaceFromSurface(pNewSurface,NULL,&dstrect,pSourceSurface,NULL,&srcrect,D3DX_FILTER_POINT ,0xFF000000);
			DEBUGGER_IF_DUMP(( res != S_OK), {DebuggerAppendMsg("Error to reload texture from render_texture, res=%x", res);} );
예제 #8
0
INT TcolorMap::OnResetDevice()
{
	HRESULT hr;

	if(NULL == m_pTx)
	{
		hr = D3DXCreateTexture(m_pDev, m_iW, m_iH, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTx);

		if(FAILED(hr))
			return -1;

		m_pTx->GetSurfaceLevel(0,&m_pSf);

		m_pDev->GetRenderTarget(0,&m_pBckC);
		m_pDev->GetDepthStencilSurface(&m_pBckD);

		if(FAILED(hr))
			return -1;
	}

	if(m_pTxT)
	{
		PDSF	pSrc;
		PDSF	pDst =m_pSf;
		hr = m_pTxT->GetSurfaceLevel(0,&pSrc);

		hr = D3DXLoadSurfaceFromSurface(pDst, NULL, NULL, m_pSf, NULL, NULL, D3DX_FILTER_NONE, 0x0);

		if(FAILED(hr))
			return -1;

		SAFE_RELEASE(	pSrc	);
		SAFE_RELEASE(	m_pTxT	);
	}

	return 0;
}
예제 #9
0
bool CN3Texture::GenerateMipMap(LPDIRECT3DSURFACE8 lpSurfSrc)
{
	if(m_lpTexture == NULL) return false;

	// MipMap 이 몇개 필요한지 계산..
	int nMMC = m_lpTexture->GetLevelCount();
	int nMMC2 = 0;
	for(int nW = m_Header.nWidth, nH = m_Header.nHeight; nW >=4 && nH >= 4; nW /=2, nH /= 2) nMMC2++;

	bool bNeedReleaseSurf = false;
	if(NULL == lpSurfSrc) 
	{
		bNeedReleaseSurf = true;
		if(D3D_OK != m_lpTexture->GetSurfaceLevel(0, &lpSurfSrc)) return false;
	}

	HRESULT rval = D3D_OK;
	if(nMMC < nMMC2) // 적으면 새로 생성..
	{
		LPDIRECT3DTEXTURE8 lpTexOld = m_lpTexture;
		m_lpTexture = NULL;
		rval = this->CreateFromSurface(lpSurfSrc, m_Header.Format, TRUE);
		if(bNeedReleaseSurf) { lpSurfSrc->Release(); lpSurfSrc = NULL; }
		lpTexOld->Release(); lpTexOld = NULL;

		if(D3D_OK == rval)
		{
			m_Header.bMipMap = TRUE;
			return true;
		}
		else
		{
			m_Header.bMipMap = FALSE;
			return FALSE;
		}
	}
	else // MipMap 이 있으면 그냥 표면만 복사
	{
		if(false == bNeedReleaseSurf) // 다른 서피스에서 복사해야 되는 거면 0 레벨도 복사..
		{
			LPDIRECT3DSURFACE8 lpSurfDest;
			m_lpTexture->GetSurfaceLevel(0, &lpSurfDest);
			DWORD dwFilter = D3DX_FILTER_TRIANGLE; // 기본 필터는 없다..
			HRESULT rval = D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfSrc, NULL, NULL, dwFilter, 0); // 작은 맵 체인에 서피스 이미지 축소 복사 
			lpSurfDest->Release(); lpSurfDest = NULL;
		}

		for(int i = 1; i < nMMC2; i++)
		{
			LPDIRECT3DSURFACE8 lpSurfDest, lpSurfUp;
			m_lpTexture->GetSurfaceLevel(i-1, &lpSurfUp);
			m_lpTexture->GetSurfaceLevel(i, &lpSurfDest);
			DWORD dwFilter = D3DX_FILTER_TRIANGLE; // 기본 필터는 없다..
			HRESULT rval = D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfUp, NULL, NULL, dwFilter, 0); // 작은 맵 체인에 서피스 이미지 축소 복사 
			lpSurfDest->Release();
			lpSurfUp->Release();
		}

		if(bNeedReleaseSurf) { lpSurfSrc->Release(); lpSurfSrc = NULL; }
		if(D3D_OK == rval)
		{
			m_Header.bMipMap = TRUE;
			return true;
		}
		else
		{
			m_Header.bMipMap = FALSE;
			return FALSE;
		}
	}
}
예제 #10
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
    HRESULT hr;
    TCHAR sz[512];

    m_bDrawWater        = TRUE;
    m_bDrawCaustics     = TRUE;
    m_bDrawEnvironment  = TRUE;


    // Initialize the font's internal textures
    m_pFont->InitDeviceObjects( m_pd3dDevice );
    m_pFontSmall->InitDeviceObjects( m_pd3dDevice );

    // Floor
    DXUtil_FindMediaFile(sz, _T("Water.bmp"));
    D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, 
        D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, 
        D3DX_DEFAULT, 0, NULL, NULL, &m_pFloorTex);


    // Sky
    TCHAR* szSkyTex[6] =
    {
        _T("lobbyxpos.bmp"), _T("lobbyxneg.bmp"),
        _T("lobbyypos.bmp"), _T("lobbyyneg.bmp"),
        _T("lobbyzneg.bmp"), _T("lobbyzpos.bmp")
    };

    for(UINT i = 0; i < 6; i++)
    {
        DXUtil_FindMediaFile(sz, szSkyTex[i]);
        D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT, 
            1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 
            0, NULL, NULL, &m_pSkyTex[i]);
    }

    if(SUCCEEDED(D3DXCreateCubeTexture(m_pd3dDevice, 128, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, &m_pSkyCubeTex)))
    {
        for(UINT i = 0; i < 6; i++)
        {
            if(m_pSkyTex[i])
            {
                IDirect3DSurface8 *pSrc;
                IDirect3DSurface8 *pDest;

                m_pSkyTex[i]->GetSurfaceLevel(0, &pSrc);
                m_pSkyCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES) i, 0, &pDest);

                if(pSrc && pDest)
                    D3DXLoadSurfaceFromSurface(pDest, NULL, NULL, pSrc, NULL, NULL, D3DX_DEFAULT, 0);

                SAFE_RELEASE(pDest);
                SAFE_RELEASE(pSrc);
            }
        }

        D3DXFilterCubeTexture(m_pSkyCubeTex, NULL, 0, D3DX_DEFAULT);
    }



    // OnCreateDevice
    if(FAILED(hr = m_Water.OnCreateDevice(m_pd3dDevice)))
        return hr;

    if(FAILED(hr = m_Environment.OnCreateDevice(m_pd3dDevice)))
        return hr;

    return S_OK;
}
예제 #11
0
bool CN3Texture::Save(HANDLE hFile)
{
	if(NULL == m_lpTexture) return false;

	CN3BaseFileAccess::Save(hFile);

	DWORD dwRWC = 0;

	D3DSURFACE_DESC sd;
	m_lpTexture->GetLevelDesc(0, &sd);

	int nMMC = m_lpTexture->GetLevelCount();
	(nMMC > 1) ? m_Header.bMipMap = TRUE : m_Header.bMipMap = FALSE;
	if(TRUE == m_Header.bMipMap) // MipMap 갯수가 맞는지 확인..
	{
		int nMMC2 = 0;
		for(int nW = sd.Width, nH = sd.Height; nW >=4 && nH >= 4; nW /=2, nH /= 2) nMMC2++;
		if(nMMC < nMMC2)
		{
#ifdef _N3GAME
			CLogWriter::Write("N3Texture save warning - Invalid MipMap Count (%s)", m_szFileName.c_str());
#endif
			m_Header.bMipMap = FALSE;
			nMMC = 1;
		}
		else
		{
			nMMC = nMMC2;
		}
	}

	m_Header.szID[0] = 'N';
	m_Header.szID[1] = 'T';
	m_Header.szID[2] = 'F';
	m_Header.szID[3] = 3; // Noah Texture File Ver '3'
	m_Header.nWidth = sd.Width;
	m_Header.nHeight = sd.Height;
	m_Header.bMipMap = (nMMC > 1) ? TRUE : FALSE;
	
	WriteFile(hFile, &m_Header, sizeof(m_Header), &dwRWC, NULL); // 헤더를 쓰고

	if(m_lpTexture == NULL) return false;

	if(	D3DFMT_DXT1 == sd.Format || 
		D3DFMT_DXT2 == sd.Format || 
		D3DFMT_DXT3 == sd.Format || 
		D3DFMT_DXT4 == sd.Format || 
		D3DFMT_DXT5 == sd.Format )
	{
		D3DLOCKED_RECT LR;

		for(int i = 0; i < nMMC; i++)
		{
			m_lpTexture->GetLevelDesc(i, &sd);

			m_lpTexture->LockRect(i, &LR, NULL, NULL);
			WriteFile(hFile, (BYTE*)LR.pBits, sd.Size, &dwRWC, NULL); // 일렬로 된 데이터를 쓰고..
			m_lpTexture->UnlockRect(i);
		}

		// 추가로 압축되지 않은 형식을 써준다.. 절반 크기이다.
		// 압축되지 않은 형식을 해상도를 한단계 낮추어서 저장.
		LPDIRECT3DSURFACE8 lpSurfSrc = NULL, lpSurfDest = NULL;
		D3DFORMAT fmtExtra = D3DFMT_UNKNOWN;
		if(D3DFMT_DXT1 == sd.Format) fmtExtra = D3DFMT_A1R5G5B5;
		else fmtExtra = D3DFMT_A4R4G4B4;
		
		int nMMC2 = nMMC - 1;
		if(nMMC == 1) nMMC2 = nMMC;
		for(i = 0; i < nMMC2; i++)
		{
			m_lpTexture->GetLevelDesc(i, &sd);
			m_lpTexture->GetSurfaceLevel(i, &lpSurfSrc);
			int nW = sd.Width / 2, nH = sd.Height / 2;
			s_lpD3DDev->CreateImageSurface(nW, nH, fmtExtra, &lpSurfDest);
			D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0); // 서피스 복사.
			int nPixelSize = 2;
			lpSurfDest->LockRect(&LR, NULL, NULL);
			for(int y = 0; y < nH; y++)
			{
				WriteFile(hFile, (BYTE*)LR.pBits + y * LR.Pitch, nW * 2, &dwRWC, NULL);
			}
			lpSurfDest->UnlockRect();
			lpSurfDest->Release(); lpSurfDest = NULL; 
			lpSurfSrc->Release(); lpSurfSrc = NULL;
		}

		if(nMMC == 1 && m_Header.nWidth >= 1024) // 부두를 위해 256 * 256 짜리 하나 더 저장해준다..
		{
			m_lpTexture->GetLevelDesc(0, &sd);
			m_lpTexture->GetSurfaceLevel(0, &lpSurfSrc);
			int nW = 256, nH = 256;
			s_lpD3DDev->CreateImageSurface(nW, nH, fmtExtra, &lpSurfDest);
			D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0); // 서피스 복사.
			int nPixelSize = 2;
			lpSurfDest->LockRect(&LR, NULL, NULL);
			for(int y = 0; y < nH; y++)
			{
				WriteFile(hFile, (BYTE*)LR.pBits + y * LR.Pitch, nW * 2, &dwRWC, NULL);
			}
			lpSurfDest->UnlockRect();
			lpSurfDest->Release(); lpSurfDest = NULL; 
			lpSurfSrc->Release(); lpSurfSrc = NULL;
		}
	}
	else // 일반적인 포맷이면.
	{
		int nPixelSize = 0;
		if(	D3DFMT_A1R5G5B5 == sd.Format ||
			D3DFMT_A4R4G4B4 == sd.Format) nPixelSize = 2;
		else if(D3DFMT_R8G8B8 == sd.Format) nPixelSize = 3;
		else if(D3DFMT_A8R8G8B8 == sd.Format || D3DFMT_X8R8G8B8 == sd.Format) nPixelSize = 4;
		else 
		{
			__ASSERT(0, "this Texture Format Not Supported");
		}

		D3DLOCKED_RECT LR;
		for(int i = 0; i < nMMC; i++)
		{
			m_lpTexture->GetLevelDesc(i, &sd);
			m_lpTexture->LockRect(i, &LR, NULL, 0); // 각 레벨 Lock
			int nH = sd.Height;
			for(int y = 0; y < nH; y++) // 그냥 픽셀 저장..
				WriteFile(hFile, (BYTE*)LR.pBits + y * LR.Pitch, sd.Width * nPixelSize, &dwRWC, NULL);
			m_lpTexture->UnlockRect(i);
		}

		if(nMMC == 1 && m_Header.nWidth >= 512) // 부두를 위해 256 * 256 짜리 하나 더 저장해준다..
		{
			LPDIRECT3DSURFACE8 lpSurfSrc = NULL, lpSurfDest = NULL;

			m_lpTexture->GetLevelDesc(0, &sd);
			m_lpTexture->GetSurfaceLevel(0, &lpSurfSrc);
			int nW = 256, nH = 256;
			s_lpD3DDev->CreateImageSurface(nW, nH, sd.Format, &lpSurfDest);
			HRESULT rval = D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0); // 서피스 복사.
			lpSurfDest->LockRect(&LR, NULL, NULL);
			for(int y = 0; y < nH; y++)
			{
				WriteFile(hFile, (BYTE*)LR.pBits + y * LR.Pitch, nW * 2, &dwRWC, NULL);
			}
			lpSurfDest->UnlockRect();
			lpSurfDest->Release(); lpSurfDest = NULL; 
			lpSurfSrc->Release(); lpSurfSrc = NULL;
		}
	}

	return true;
}
예제 #12
0
HRESULT CDxtexDoc::LoadAlphaIntoSurface(CString& strPath, LPDIRECT3DSURFACE9 psurf)
{
    HRESULT hr;
    D3DSURFACE_DESC sd;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 ptexAlpha;
    LPDIRECT3DSURFACE9 psurfAlpha;
    LPDIRECT3DSURFACE9 psurfTarget;

    psurf->GetDesc(&sd);

    // Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface
    hr = D3DXCreateTextureFromFileEx(pd3ddev, strPath, sd.Width, sd.Height, 1, 0, 
        D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, 
        D3DX_DEFAULT, 0, NULL, NULL, &ptexAlpha);
    hr = ptexAlpha->GetSurfaceLevel(0, &psurfAlpha);

    // Copy the target surface into an A8R8G8B8 surface
    hr = pd3ddev->CreateOffscreenPlainSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &psurfTarget, NULL);
    hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurf, NULL, NULL, 
        D3DX_DEFAULT, 0);

    // Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha
    D3DLOCKED_RECT lrSrc;
    D3DLOCKED_RECT lrDest;

    hr = psurfAlpha->LockRect(&lrSrc, NULL, D3DLOCK_READONLY);
    hr = psurfTarget->LockRect(&lrDest, NULL, 0);

    DWORD xp;
    DWORD yp;
    DWORD* pdwRowSrc = (DWORD*)lrSrc.pBits;
    DWORD* pdwRowDest = (DWORD*)lrDest.pBits;
    DWORD* pdwSrc;
    DWORD* pdwDest;
    DWORD dwAlpha;
    LONG dataBytesPerRow = 4 * sd.Width;

    for (yp = 0; yp < sd.Height; yp++)
    {
        pdwSrc = pdwRowSrc;
        pdwDest = pdwRowDest;
        for (xp = 0; xp < sd.Width; xp++)
        {
            dwAlpha = *pdwSrc << 24;
            *pdwDest &= 0x00ffffff;
            *pdwDest |= dwAlpha;

            pdwSrc++;
            pdwDest++;
        }
        pdwRowSrc += lrSrc.Pitch / 4;
        pdwRowDest += lrDest.Pitch / 4;
    }

    psurfAlpha->UnlockRect();
    psurfTarget->UnlockRect();

    // Copy psurfTarget back into real surface
    hr = D3DXLoadSurfaceFromSurface(psurf, NULL, NULL, psurfTarget, NULL, NULL, 
        D3DX_DEFAULT, 0);
    
    // Release allocated interfaces
    ReleasePpo(&psurfTarget);
    ReleasePpo(&psurfAlpha);
    ReleasePpo(&ptexAlpha);

    return S_OK;
}
예제 #13
0
void ConvertFile(const char* Dir, const char* Filename, double MaxMSE)
{
	HRESULT hr;
	LPDIRECT3DSURFACE8 pSrcSurf = NULL;
	char OutFilename[52];
	if (Dir)
		_snprintf(OutFilename, 52, "%s\\%s", Dir, Filename);
	else
		_snprintf(OutFilename, 52, "%s", Filename);
	OutFilename[51] = 0;

	printf("%s: ", OutFilename);
	TRACE1("%s:\n", OutFilename);
	int n = strlen(OutFilename);
	if (n < 40)
		printf("%*c", 40-n, ' ');

	if (pSrcSurf)
		pSrcSurf->Release();
	pSrcSurf = NULL;

	// Load up the file
	D3DXIMAGE_INFO info;
	hr = D3DXGetImageInfoFromFile(Filename, &info);
	CheckHR(hr);

	PrintImageInfo(info);

	UINT Width = PadPow2(info.Width);
	UINT Height = PadPow2(info.Height);

	float Waste = 100.f * (float)(Width * Height - info.Width * info.Height) / (float)(Width * Height);

	UncompressedSize += Width * Height * 4;
	TotalSrcPixels += info.Width * info.Height;
	TotalDstPixels += Width * Height;

  // Special case for 256-colour files - just directly drop into a P8 xpr
	if (info.Format == D3DFMT_P8)
	{
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
		CheckHR(hr);

		hr = D3DXLoadSurfaceFromFile(pSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
		CheckHR(hr);

		FixTransparency(pSrcSurf);

		if (Width * Height > 4096)
		{
			// DXT1 for P8s if lossless and more than 4k image
			LPDIRECT3DSURFACE8 pTempSurf;
			hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pTempSurf);
			CheckHR(hr);

			hr = D3DXLoadSurfaceFromSurface(pTempSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
			CheckHR(hr);

			double CMSE, AMSE;
			TRACE0(" Checking     DXT1: ");
			if (!GetFormatMSE(info, pTempSurf, D3DFMT_DXT1, CMSE, AMSE))
			{
				pTempSurf->Release();
				return;
			}
			TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE);
			if (CMSE <= 1e-6 && AMSE <= 1e-6)
			{
				printf("DXT1     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
				TRACE0(" Selected Format: DXT1\n");
				WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_DXT1, NULL);

				pTempSurf->Release();
				return;
			}
			pTempSurf->Release();
		}

		printf("P8       %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: P8\n");

		LPDIRECT3DSURFACE8 pTempSurf;
		DWORD pal[256];
		ConvertP8(pSrcSurf, pTempSurf, pal, info);

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_P8, pal);
		pTempSurf->Release();
		return;
	}

  // test linear format versus non-linear format
  // Linear format requires 64 pixel aligned width, whereas
  // Non-linear format requires power of 2 width and height
  bool useLinearFormat(false);
  UINT linearWidth = (info.Width + 0x3f) & ~0x3f;
  if (AllowLinear && linearWidth * info.Height < Width * Height)
    useLinearFormat = true;

	hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
	CheckHR(hr);
  
	hr = D3DXLoadSurfaceFromFile(pSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
	CheckHR(hr);

  // create the linear version as well
	LPDIRECT3DSURFACE8 pLinearSrcSurf = NULL;
  if (useLinearFormat)
  {
	  hr = pD3DDevice->CreateImageSurface(linearWidth, info.Height, D3DFMT_A8R8G8B8, &pLinearSrcSurf);
	  CheckHR(hr);
	  hr = D3DXLoadSurfaceFromFile(pLinearSrcSurf, NULL, NULL, Filename, NULL, D3DX_FILTER_NONE, 0, NULL);
	  CheckHR(hr);
  }


	// special case for small files - all textures are alloced on page granularity so just output uncompressed
	// dxt is crap on small files anyway
	if (Width * Height <= 1024)
	{
    if (useLinearFormat)
    {
      // correct sizing amounts
	    UncompressedSize -= Width * Height * 4;
      UncompressedSize += linearWidth * info.Height * 4;
	    TotalDstPixels -= Width * Height;
      TotalDstPixels += linearWidth * info.Height;

	    Waste = 100.f * (float)(linearWidth * info.Height - info.Width * info.Height) / (float)(linearWidth * info.Height);
		  printf("LIN_A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", linearWidth, info.Height, Waste);
		  TRACE0(" Selected Format: LIN_A8R8G8B8\n");
      WriteXPR(OutFilename, info, pLinearSrcSurf, XB_D3DFMT_LIN_A8R8G8B8, NULL);
    }
    else
    {
		  printf("A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		  TRACE0(" Selected Format: A8R8G8B8\n");
      WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_A8R8G8B8, NULL);
    }
		return;
	}

	FixTransparency(pSrcSurf);

	// Find the best format within specified tolerance
	double CMSE, AMSE[2];

	// DXT1 is the preferred format as it's smallest
	TRACE0(" Checking     DXT1: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT1, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);
	if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
	{
		printf("DXT1     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: DXT1\n");

		WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT1, NULL);
		return;
	}

	// Use P8 is possible as it's lossless
	LPDIRECT3DSURFACE8 pTempSurf;
	DWORD pal[256];
	if (ConvertP8(pSrcSurf, pTempSurf, pal, info))
	{
		printf("P8       %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: P8\n");

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_P8, pal);
		pTempSurf->Release();
		return;
	}

	// DXT3/5 are the same size so use whichever is better if good enough
	// CMSE will be equal for both
	TRACE0(" Checking     DXT3: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT3, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);

	TRACE0(" Checking     DXT5: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT5, CMSE, AMSE[1]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[1]);

	if (AMSE[0] <= AMSE[1])
	{
		if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
		{
			printf("DXT3     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
			TRACE0(" Selected Format: DXT3\n");

			WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT3, NULL);
			return;
		}
	}
	else
	{
		if (CMSE <= MaxMSE && AMSE[1] <= MaxMSE)
		{
			printf("DXT5     %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
			TRACE0(" Selected Format: DXT5\n");

			WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_DXT5, NULL);
			return;
		}
	}

	// No good compressed format so use uncompressed

	// A1R5G5B5 is worth a try I guess...
	TRACE0(" Checking A1R5G5B5: ");
	if (!GetFormatMSE(info, pSrcSurf, D3DFMT_A1R5G5B5, CMSE, AMSE[0]))
		return;
	TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE[0]);
	if (CMSE <= MaxMSE && AMSE[0] <= MaxMSE)
	{
		printf("A1R5G5B5 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: A1R5G5B5\n");

		LPDIRECT3DSURFACE8 pTempSurf;
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A1R5G5B5, &pTempSurf);
		CheckHR(hr);

		hr = D3DXLoadSurfaceFromSurface(pTempSurf, NULL, NULL, pSrcSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
		CheckHR(hr);

		WriteXPR(OutFilename, info, pTempSurf, XB_D3DFMT_A1R5G5B5, NULL);

		pTempSurf->Release();
		return;
	}

	// Use A8R8G8B8
  if (useLinearFormat)
  {
    // correct sizing information
	  UncompressedSize -= Width * Height * 4;
    UncompressedSize += linearWidth * info.Height * 4;
	  TotalDstPixels -= Width * Height;
    TotalDstPixels += linearWidth * info.Height;
	  Waste = 100.f * (float)(linearWidth * info.Height - info.Width * info.Height) / (float)(linearWidth * info.Height);
		printf("LIN_A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", linearWidth, info.Height, Waste);
		TRACE0(" Selected Format: LIN_A8R8G8B8\n");
    WriteXPR(OutFilename, info, pLinearSrcSurf, XB_D3DFMT_LIN_A8R8G8B8, NULL);
  }
  else
  {
		printf("A8R8G8B8 %4dx%-4d (%5.2f%% waste)\n", Width, Height, Waste);
		TRACE0(" Selected Format: A8R8G8B8\n");
    WriteXPR(OutFilename, info, pSrcSurf, XB_D3DFMT_A8R8G8B8, NULL);
  }

	if (pSrcSurf)
		pSrcSurf->Release();
}
예제 #14
0
void CDxtexDoc::OpenSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 ptex = NULL;
    LPDIRECT3DSURFACE9 psurfOrig = NULL;
    LPDIRECT3DSURFACE9 psurfNew = NULL;

    if (!PromptForBmp(&fileName))
        return;

    if (IsVolumeMap())
    {
        hr = D3DXCreateTextureFromFile(pd3ddev, fileName, &ptex);
        hr = ptex->GetSurfaceLevel(0, &psurfOrig);
    }
    else if (IsCubeMap())
    {
        hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
        if (m_ptexNew != NULL)
            hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
        hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_DEFAULT, 0, NULL);
    }
    else
    {
        hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
        if (m_ptexNew != NULL)
            hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
        hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_DEFAULT, 0, NULL);
    }

    // Look for "foo_a.bmp" for alpha channel
    int i = fileName.ReverseFind('.');
    fileName = fileName.Left(i) + "_a.bmp";
    CFileStatus status;
    if (CFile::GetStatus(fileName, status))
    {
        if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
            return;
    }

    if (IsVolumeMap())
    {
        LPDIRECT3DVOLUME9 pvol;
        hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvol);
        hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
        ReleasePpo(&pvol);
        if (m_ptexNew)
        {
            hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetVolumeLevel(lwMip, &pvol);
            hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
            ReleasePpo(&pvol);
        }
    }
    else if (psurfNew != NULL)
    {
        hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_DEFAULT, 0);
    }

    ReleasePpo(&psurfOrig);
    ReleasePpo(&psurfNew);
    ReleasePpo(&ptex);

    SetModifiedFlag(TRUE);
    UpdateAllViews(NULL, 1);
}
예제 #15
0
void CDxtexDoc::GenerateMipMaps() 
{
    LONG lwTempH;
    LONG lwTempW;
    LONG lwPowsW;
    LONG lwPowsH;
    LPDIRECT3DTEXTURE9 pddsNew = NULL;
    D3DFORMAT fmt;
    HRESULT hr;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 pmiptex = NULL;
    LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
    LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL;
    LPDIRECT3DTEXTURE9 pmiptexNew = NULL;
    LPDIRECT3DCUBETEXTURE9 pcubetexNew = NULL;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexNew = NULL;
    LPDIRECT3DSURFACE9 psurfSrc;
    LPDIRECT3DSURFACE9 psurfDest;
    LPDIRECT3DVOLUME9 pvolSrc;
    LPDIRECT3DVOLUME9 pvolDest;

    if (IsVolumeMap())
        pvoltex = (LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig;
    else if (IsCubeMap())
        pcubetex = (LPDIRECT3DCUBETEXTURE9)m_ptexOrig;
    else
        pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;

    if (pvoltex != NULL)
    {
        D3DVOLUME_DESC vd;
        pvoltex->GetLevelDesc(0, &vd);
        fmt = vd.Format;
    }
    else if (pcubetex != NULL)
    {
        D3DSURFACE_DESC sd;
        pcubetex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }
    else
    {
        D3DSURFACE_DESC sd;
        pmiptex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }

    lwTempW = m_dwWidth;
    lwTempH = m_dwHeight;
    lwPowsW = 0;
    lwPowsH = 0;
    while (lwTempW > 0)
    {
        lwPowsW++;
        lwTempW = lwTempW / 2;
    }
    while (lwTempH > 0)
    {
        lwPowsH++;
        lwTempH = lwTempH / 2;
    }
    m_numMips = lwPowsW > lwPowsH ? lwPowsW : lwPowsH;

    // Create destination mipmap surface - same format as source
    if (pvoltex != NULL)
    {
        if (FAILED(hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, 
            m_numMips, 0, fmt, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL)))
        {
            goto LFail;
        }
        hr = pvoltex->GetVolumeLevel(0, &pvolSrc);
        hr = pvoltexNew->GetVolumeLevel(0, &pvolDest);
        hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, pvolSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&pvolSrc);
        ReleasePpo(&pvolDest);
        hr = D3DXFilterVolumeTexture(pvoltexNew, NULL, 0, D3DX_DEFAULT);
    }
    else if (pmiptex != NULL)
    {
        if (FAILED(hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
             0, fmt, D3DPOOL_MANAGED, &pmiptexNew, NULL)))
        {
            goto LFail;
        }
        hr = pmiptex->GetSurfaceLevel(0, &psurfSrc);
        hr = pmiptexNew->GetSurfaceLevel(0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = D3DXFilterTexture(pmiptexNew, NULL, 0, D3DX_DEFAULT);
    }
    else
    {
        if (FAILED(hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
             0, fmt, D3DPOOL_MANAGED, &pcubetexNew, NULL)))
        {
            goto LFail;
        }
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = D3DXFilterCubeTexture(pcubetexNew, NULL, 0, D3DX_DEFAULT);
    }

    ReleasePpo(&m_ptexOrig);
    if (pvoltexNew != NULL)
        m_ptexOrig = pvoltexNew;
    else if (pcubetexNew != NULL)
        m_ptexOrig = pcubetexNew;
    else
        m_ptexOrig = pmiptexNew;

    if (m_ptexNew != NULL)
    {
        // Rather than filtering down the (probably-compressed) m_ptexNew 
        // top level, compress each mip level from the (probably-uncompressed)
        // m_ptexOrig levels.
        if (pvoltexNew != NULL)
        {
            D3DVOLUME_DESC vd;
            ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetLevelDesc(0, &vd);
            fmt = vd.Format;
        }
        else if (pcubetexNew != NULL)
        {
            D3DSURFACE_DESC sd;
            ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
            fmt = sd.Format;
        }
        else
        {
            D3DSURFACE_DESC sd;
            ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
            fmt = sd.Format;
        }
        Compress(fmt, FALSE);
    }

    m_bTitleModsChanged = TRUE; // Generate title bar update
    UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
    SetModifiedFlag();
    return;

LFail:
    ReleasePpo(&pddsNew);
}
예제 #16
0
파일: Font.cpp 프로젝트: Aishiro/ATools
QRect CFont::_findGlyphRect(int width, int height)
{
	Row* row = nullptr;
	float bestRatio = 0;
	for (auto it = m_rows.begin(); it != m_rows.end() && !row; ++it)
	{
		const float ratio = static_cast<float>(height) / (*it).height;

		if ((ratio < 0.7f) || (ratio > 1.f))
			continue;
		if (width > m_textureSize.width() - (*it).width)
			continue;
		if (ratio < bestRatio)
			continue;

		row = &(*it);
		bestRatio = ratio;
	}

	if (!row)
	{
		int rowHeight = height + height / 10;
		while (m_nextRow + rowHeight >= m_textureSize.width())
		{
			D3DCAPS9 d3dCaps;
			m_device->GetDeviceCaps(&d3dCaps);

			if ((m_textureSize.width() * 2 <= d3dCaps.MaxTextureWidth) && (m_textureSize.height() * 2 <= d3dCaps.MaxTextureHeight))
			{
				LPDIRECT3DTEXTURE9 pNewTexture;
				m_device->CreateTexture(m_textureSize.width() * 2, m_textureSize.height() * 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pNewTexture, null);

				LPDIRECT3DSURFACE9 destSurface = null;
				LPDIRECT3DSURFACE9 srcSurface = null;

				pNewTexture->GetSurfaceLevel(0, &destSurface);
				m_texture->GetSurfaceLevel(0, &srcSurface);

				const RECT rect[] = { 0, 0, m_textureSize.width(), m_textureSize.height() };

				D3DXLoadSurfaceFromSurface(destSurface, null, rect, srcSurface, null, rect, D3DX_DEFAULT, 0);

				Release(srcSurface);
				Release(destSurface);
				Release(m_texture);

				m_texture = pNewTexture;

				m_textureSize.rwidth() *= 2;
				m_textureSize.rheight() *= 2;

				for (auto it = m_glyphs.begin(); it != m_glyphs.end(); it++)
				{
					(*it).tu1 /= 2.0f;
					(*it).tu2 /= 2.0f;
					(*it).tv1 /= 2.0f;
					(*it).tv2 /= 2.0f;
				}
			}
			else
			{
				qWarning("Failed to add a new character to the font: the maximum texture size has been reached");
				return QRect(0, 0, 2, 2);
			}
		}

		m_rows.push_back(Row(m_nextRow, rowHeight));
		m_nextRow += rowHeight;
		row = &m_rows.back();
	}

	const QRect rect(QPoint(row->width, row->top), QPoint(row->width + width, row->top + height));
	row->width += width;
	return rect;
}
예제 #17
0
//-----------------------------------------------------------------------------
// PresentSwapChain
//
// Presents a swap chain that contains a video frame by doing a callback
// via the sink.
//
// pSwapChain: Pointer to the swap chain.
// pSurface: Pointer to the swap chain's back buffer surface.
//-----------------------------------------------------------------------------
HRESULT D3DPresentEngine::PresentSwapChain(IDirect3DSwapChain9* pSwapChain, IDirect3DSurface9* pSurface)
{
    HRESULT hr = S_OK;

    if (m_hwnd == NULL)
    {
        return MF_E_INVALIDREQUEST;
    }
	
	if(!m_pRenderSurface)
	{
		D3DSURFACE_DESC desc;
		
		// Get the surface description
		pSurface->GetDesc(&desc);

		// Create a surface the same size as our sample
		hr = this->m_pDevice->CreateRenderTarget(desc.Width, 
												 desc.Height, 
												 desc.Format, 
												 desc.MultiSampleType, 
												 desc.MultiSampleQuality, 
												 true, 
												 &m_pRenderSurface, 
												 NULL);
		if(hr != S_OK)
			goto bottom;
	}

	if(m_pRenderSurface)
	{
		D3DSURFACE_DESC originalDesc;
		// Get the surface description of this sample
		pSurface->GetDesc(&originalDesc);

		D3DSURFACE_DESC renderDesc;
		// Get the surface description of the render surface
		m_pRenderSurface->GetDesc(&renderDesc);

		// Compare the descriptions to make sure they match
		if(originalDesc.Width != renderDesc.Width || 
		   originalDesc.Height != renderDesc.Height ||
		   originalDesc.Format != renderDesc.Format)
		{
			// Release the old render surface
			SAFE_RELEASE(m_pRenderSurface);
			
			// Create a new render surface that matches the size of this surface 
			hr = this->m_pDevice->CreateRenderTarget(originalDesc.Width, 
													 originalDesc.Height, 
													 originalDesc.Format, 
													 originalDesc.MultiSampleType, 
													 originalDesc.MultiSampleQuality, 
													 true, 
													 &m_pRenderSurface, 
													 NULL);
		if(hr != S_OK)
			goto bottom;
		}
	}

	if(m_pRenderSurface)
	{
		// Copy the passed surface to our rendered surface
		hr = D3DXLoadSurfaceFromSurface(m_pRenderSurface,
										NULL,
										NULL,
										pSurface,
										NULL,
										NULL,
										D3DX_FILTER_NONE,
										0);
	}

	if(hr != S_OK)
			goto bottom;

	// Do the callback, passing the rendered surface
	if(m_pCallback)
		hr = m_pCallback->PresentSurfaceCB(m_pRenderSurface);

    LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSwapChain failed.", hr);

bottom:

    return hr;
}
/**
* Locks rectangle on both (left/right) surfaces.
***/
HRESULT WINAPI D3D9ProxySurface::LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags)
{
	SHOW_CALL("D3D9ProxySurface::LockRect");

	D3DSURFACE_DESC desc;
	m_pActualSurface->GetDesc(&desc);
	if (desc.Pool != D3DPOOL_DEFAULT)
	{
		//Can't really handle stereo for this, so just lock on the original texture
		return m_pActualSurface->LockRect(pLockedRect, pRect, Flags);
	}

	//Guard against multithreaded access as this could be causing us problems
	std::lock_guard<std::mutex> lck (m_mtx);

	//Create lockable system memory surfaces
	if (pRect && !fullSurface)
	{
		lockedRects.push_back(*pRect);
	}
	else
	{
		lockedRects.clear();
		fullSurface = true;
	}

	HRESULT hr = D3DERR_INVALIDCALL;
	IDirect3DSurface9 *pSurface = NULL;
	bool createdTexture = false;
	if (!lockableSysMemTexture)
	{
		hr = m_pOwningDevice->getActual()->CreateTexture(desc.Width, desc.Height, 1, 0, 
			desc.Format, D3DPOOL_SYSTEMMEM, &lockableSysMemTexture, NULL);

		if (FAILED(hr))
			return hr;

		createdTexture = true;
	}

	lockableSysMemTexture->GetSurfaceLevel(0, &pSurface);

	//Only copy the render taget (if possible) on the creation of the memory texture
	if (createdTexture)
	{
		hr = D3DXLoadSurfaceFromSurface(pSurface, NULL, NULL, m_pActualSurface, NULL, NULL, D3DX_DEFAULT, 0);
		if (FAILED(hr))
		{
#ifdef _DEBUG
			vireio::debugf("Failed: D3DXLoadSurfaceFromSurface hr = 0x%0.8x", hr);
#endif
		}
	}

	//And finally, lock the memory surface
	hr = pSurface->LockRect(pLockedRect, pRect, Flags);
	if (FAILED(hr))
		return hr;

	lockedRect = *pLockedRect;

	pSurface->Release();

	return hr;
}
예제 #19
0
HRESULT RSManager::redirectSetRenderTarget(DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
	nrts++;
	//if(RenderTargetIndex==0) lastReplacement = -1;
	//SurfSurfMap::iterator it = renderTexSurfTargets.find(pRenderTarget);
	//if(it != renderTexSurfTargets.end()) {
	//	SDLOG(1, "Redirected SetRenderTarget(%d, %p) to %p\n", RenderTargetIndex, pRenderTarget, it->second);
	//	if(capturing) dumpSurface("redirectRenderTarget", it->second);
	//	lastReplacement = renderTexSurfIndices[pRenderTarget];
	//	return d3ddev->SetRenderTarget(RenderTargetIndex, it->second);
	//}
	//if(capturing && hudStarted) {
	//	//SurfIntMap::iterator it = renderTexSurfIndices.find(pRenderTarget);
	//	//if(it != renderTexSurfIndices.end()) {
	//		dumpSurface("hudTarget", pRenderTarget);
	//		capturing = false;
	//	//}
	//}
	// determine where we are rendering to
	//{
	//	SurfIntMap::iterator it = mainRenderSurfIndices.find(pRenderTarget);
	//	if(it != mainRenderSurfIndices.end()) {
	//		SDLOG(4, " - rendersurface #%d\n", it->second);
	//	} else {
	//		if(IDirect3DTexture9* tex = getSurfTexture(pRenderTarget)) {
	//			TexIntMap::iterator it = mainRenderTexIndices.find(tex);
	//			if(it != mainRenderTexIndices.end()) {
	//				SDLOG(4, " - rendertexture #%d\n", it->second);
	//			}
	//			tex->Release();
	//		} else {
	//			IDirect3DSurface9* backBuffer;
	//			d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
	//			if(pRenderTarget == backBuffer) {
	//				SDLOG(4, " - backbuffer\n");
	//			}
	//			backBuffer->Release();
	//		}
	//	}
	//}
	if(capturing) {
		IDirect3DSurface9 *oldRenderTarget, *depthStencilSurface;
		d3ddev->GetRenderTarget(0, &oldRenderTarget);
		d3ddev->GetDepthStencilSurface(&depthStencilSurface);
		char buffer[64];
		sprintf(buffer, "%03d_oldRenderTarget_%p_.tga", nrts, oldRenderTarget);
		SDLOG(0, "Capturing surface %p as %s\n", oldRenderTarget, buffer);
		D3DXSaveSurfaceToFile(buffer, D3DXIFF_TGA, oldRenderTarget, NULL, NULL);
		if(depthStencilSurface) {
			sprintf(buffer, "%03d_oldRenderTargetDepth_%p_.tga", nrts, oldRenderTarget);
			SDLOG(0, "Capturing depth surface %p as %s\n", depthStencilSurface, buffer);
			D3DXSaveSurfaceToFile(buffer, D3DXIFF_TGA, depthStencilSurface, NULL, NULL);
		}
		SAFERELEASE(oldRenderTarget);
		SAFERELEASE(depthStencilSurface);
	}
	
	if(nrts == 1) { // we are switching to the RT that will be the main rendering target for this frame
		// store it for later use
		mainRT = pRenderTarget;
		SDLOG(0, "Storing RT as main RT: %p\n", mainRT);
	}

	if(nrts == 11) { // we are switching to the RT used to store the Z value in the 24 RGB bits (among other things)
		// lets store it for later use
		zSurf = pRenderTarget;
		SDLOG(0, "Storing RT as Z buffer RT: %p\n", zSurf);
	}

	if(mainRT && pRenderTarget == mainRT) {
		SDLOG(0, "MainRT uses: %d + 1\n", mainRTuses);
		++mainRTuses;
	}

	// we are switching away from the initial 3D-rendered image, do AA and SSAO
	if(mainRTuses == 2 && mainRT && zSurf && ((ssao && doSsao) || (doAA && (smaa || fxaa)))) { 
		IDirect3DSurface9 *oldRenderTarget;
		d3ddev->GetRenderTarget(0, &oldRenderTarget);
		if(oldRenderTarget == mainRT) {
			// final renderbuffer has to be from texture, just making sure here
			if(IDirect3DTexture9* tex = getSurfTexture(oldRenderTarget)) {
				// check size just to make even more sure
				D3DSURFACE_DESC desc;
				oldRenderTarget->GetDesc(&desc);
				if(desc.Width == Settings::get().getRenderWidth() && desc.Height == Settings::get().getRenderHeight()) {
					IDirect3DTexture9 *zTex = getSurfTexture(zSurf);
					//if(takeScreenshot) D3DXSaveTextureToFile("0effect_pre.bmp", D3DXIFF_BMP, tex, NULL);
					//if(takeScreenshot) D3DXSaveTextureToFile("0effect_z.bmp", D3DXIFF_BMP, zTex, NULL);
					storeRenderState();
					d3ddev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
					d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
					d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
					// perform AA processing
					if(!lowFPSmode && doAA && (smaa || fxaa)) {
						if(smaa) smaa->go(tex, tex, rgbaBuffer1Surf, SMAA::INPUT_COLOR);
						else fxaa->go(tex, rgbaBuffer1Surf);
						d3ddev->StretchRect(rgbaBuffer1Surf, NULL, oldRenderTarget, NULL, D3DTEXF_NONE);
					}
					// perform SSAO
					if(ssao && doSsao) {
						ssao->go(tex, zTex, rgbaBuffer1Surf);
						d3ddev->StretchRect(rgbaBuffer1Surf, NULL, oldRenderTarget, NULL, D3DTEXF_NONE);
					}
					restoreRenderState();
					zTex->Release();
					//if(takeScreenshot) D3DXSaveSurfaceToFile("1effect_buff.bmp", D3DXIFF_BMP, rgbaBuffer1Surf, NULL, NULL);
					//if(takeScreenshot) D3DXSaveSurfaceToFile("1effect_post.bmp", D3DXIFF_BMP, oldRenderTarget, NULL, NULL);
				}
				tex->Release();				
			}
		}
		oldRenderTarget->Release();
	}

	// DoF blur stuff
	if(gauss && doDofGauss) {
		IDirect3DSurface9 *oldRenderTarget;
		d3ddev->GetRenderTarget(0, &oldRenderTarget);
		D3DSURFACE_DESC desc;
		oldRenderTarget->GetDesc(&desc);
		unsigned dofIndex = isDof(desc.Width, desc.Height);
		if(dofIndex) {
			doft[dofIndex]++;
			SDLOG(6,"DOF index: %u, doft: %u\n", dofIndex, doft[dofIndex]);
			//if(takeScreenshot) {
			//	char buffer[256];
			//	sprintf(buffer, "dof%1u_doft%1u.bmp", dofIndex, doft[dofIndex]);
			//	D3DXSaveSurfaceToFile(buffer, D3DXIFF_BMP, oldRenderTarget, NULL, NULL);
			//}
			if(dofIndex == 1 && doft[1] == 4) {
				IDirect3DTexture9 *oldRTtex = getSurfTexture(oldRenderTarget);
				if(oldRTtex) {
					storeRenderState();
					for(size_t i=0; i<Settings::get().getDOFBlurAmount(); ++i) gauss->go(oldRTtex, oldRenderTarget);
					restoreRenderState();
					oldRTtex->Release();
				}
			} 
		}
		oldRenderTarget->Release();
	}

	// Timing for hudless screenshots
	if(mainRTuses == 11 && takeScreenshot) {
		IDirect3DSurface9 *oldRenderTarget;
		d3ddev->GetRenderTarget(0, &oldRenderTarget);
		if(oldRenderTarget != mainRT) {
			static int toggleSS = 0;
			toggleSS = (toggleSS+1)%2;
			if(!toggleSS) {
				takeScreenshot = false;
				SDLOG(0, "Capturing screenshot\n");
				char timebuf[128], buffer[512];
				time_t ltime;
				time(&ltime);
				struct tm *timeinfo;
				timeinfo = localtime(&ltime);
				strftime(timebuf, 128, "screenshot_%Y-%m-%d_%H-%M-%S.png", timeinfo);
				sprintf(buffer, "%s\\%s", Settings::get().getScreenshotDir().c_str(), timebuf);
				SDLOG(0, " - to %s\n", buffer);
				
				D3DSURFACE_DESC desc;
				oldRenderTarget->GetDesc(&desc);
				IDirect3DSurface9 *convertedSurface;
				d3ddev->CreateRenderTarget(desc.Width, desc.Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, true, &convertedSurface, NULL);
				D3DXLoadSurfaceFromSurface(convertedSurface, NULL, NULL, oldRenderTarget, NULL, NULL, D3DX_FILTER_POINT, 0);
				D3DXSaveSurfaceToFile(buffer, D3DXIFF_PNG, convertedSurface, NULL, NULL);
				convertedSurface->Release();
			}
		}
		oldRenderTarget->Release();
	}

	if(rddp >= 4) { // we just finished rendering the frame (pre-HUD)
		IDirect3DSurface9 *oldRenderTarget;
		d3ddev->GetRenderTarget(0, &oldRenderTarget);
		// final renderbuffer has to be from texture, just making sure here
		if(IDirect3DTexture9* tex = getSurfTexture(oldRenderTarget)) {
			// check size just to make even more sure
			D3DSURFACE_DESC desc;
			oldRenderTarget->GetDesc(&desc);
			if(desc.Width == Settings::get().getRenderWidth() && desc.Height == Settings::get().getRenderHeight()) {
				// HUD stuff
				if(hud && doHud && rddp == 9) {
					SDLOG(0, "Starting HUD rendering\n");
					hddp = 0;
					onHudRT = true;
					d3ddev->SetRenderTarget(0, rgbaBuffer1Surf);
					d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0,0,0,0), 0.0f, 0);
					prevRenderTex = tex;
					prevRenderTarget = pRenderTarget;
					tex->Release();
					oldRenderTarget->Release();
					
					d3ddev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
					d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_ADD);
					d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
					d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
					return S_OK;
				}
			}
			tex->Release();
		}
		oldRenderTarget->Release();
	}
	if(onHudRT) {
		finishHudRendering();
	}
	if(rddp < 4 || rddp > 8) rddp = 0;
	else rddp++;
	return d3ddev->SetRenderTarget(RenderTargetIndex, pRenderTarget);
}
예제 #20
0
bool DirectXTextureManager::loadTileSetFromTexture(Game *game,
	wstring dir,
	wstring sourceImageFileName,
	int tileWidth,
	int tileHeight)
{
	// CONVERT THE FILE NAME INTO A WINDOW LONG CHAR wchar_t (LPCWSTR)
	wstring sourcePath = dir + sourceImageFileName;

	LPDIRECT3DTEXTURE9 textureToDivide;
	LPDIRECT3DSURFACE9 surfaceToDivide;
	//DXLoad
	//D3DXLoadSurfaceFromMemory()
	unsigned int result = fillTexture(sourcePath, &textureToDivide);
	textureToDivide->GetSurfaceLevel(0, &surfaceToDivide);//~15 seconds
	if (result != S_OK) return false;

	// DETERMINE THE NUMBER OF TILE ROWS AND COLUMNS
	D3DSURFACE_DESC surfaceDesc;
	surfaceToDivide->GetDesc(&surfaceDesc);
	int textureWidth = surfaceDesc.Width;
	int textureHeight = surfaceDesc.Height;
	int columns = textureWidth / tileWidth;
	int rows = textureHeight / tileHeight;
	DirectXGraphics *dxg = (DirectXGraphics*)graphics;

	LPDIRECT3DDEVICE9 graphicsDevice = ((DirectXGraphics*)graphics)->getGraphicsDevice();

	// THE TILE SET IMAGE LOADED SUCCESSFULLY, SO LET'S CUT IT UP
	// MAYBE IF IM FEELING CRAZY LATER ILL MULTI THREAD THIS
	for (int row = 0; row < rows; row++)
	{
		for (int column = 0; column < columns; column++)
		{
			LPDIRECT3DTEXTURE9 extractedTexture;
			LPDIRECT3DSURFACE9 extractedSurface;
			result = graphicsDevice->CreateRenderTarget(tileWidth,
				tileHeight,
				D3DFMT_A8R8G8B8,
				D3DMULTISAMPLE_NONE, 0, false, &extractedSurface, NULL);
			if (result != S_OK) return false;

			RECT sourceRect;
			sourceRect.left = column * tileWidth;
			sourceRect.right = tileWidth + (column * tileWidth) - 1;
			sourceRect.top = row * tileHeight;
			sourceRect.bottom = tileHeight + (row * tileHeight) - 1;

			graphicsDevice->StretchRect(surfaceToDivide, &sourceRect, extractedSurface, NULL, D3DTEXF_NONE);

			// BUILD A UNIQUE FILE NAME FOR THIS TEXTURE
			wstring textureFilename = sourceImageFileName;

			unsigned int id = wstringTable.getNumWStringsInTable();
			wchar_t dot = '.';
			int dotIndex = textureFilename.rfind(dot);
			textureFilename = textureFilename.substr(0, dotIndex);
			wstringstream idWss;
			idWss << id;
			wstring idText;
			idWss >> idText;
			textureFilename = textureFilename + idText + L".png";
			textureFilename = wstring(dir.begin(), dir.end()) + textureFilename;

			//D3DXCreateTextureFromFile()
			//D3DxCreateTexture
			HRESULT result = D3DXCreateTexture(graphicsDevice, tileWidth, tileHeight, 1, D3DPOOL_DEFAULT, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &extractedTexture);
			if (result != S_OK) return false;
			LPDIRECT3DSURFACE9 t;
			extractedTexture->GetSurfaceLevel(0, &t);
			D3DXLoadSurfaceFromSurface(t, NULL, NULL, extractedSurface, NULL, NULL, D3DX_FILTER_NONE, 0);
					

			// ADD IT TO THE STRING TABLE
			wstringTable.putWStringInTable(textureFilename);

			// AND ADD IT TO THE TEXTURES
			textures[textureFilename] = extractedTexture;
			extractedSurface->Release();
			t->Release();
		}
	}
	surfaceToDivide->Release();
	textureToDivide->Release();
	return true;
}
예제 #21
0
////////////////////////////////////////////////////////////////
//
// CPixelsManager::SetTexturePixels
//
// Copy pixels into texture
//
////////////////////////////////////////////////////////////////
bool CPixelsManager::SetTexturePixels ( IDirect3DBaseTexture9* pD3DBaseTexture, const CPixels& pixels, const RECT* pRect, uint uiSurfaceIndex )
{
    if ( !pD3DBaseTexture )
        return false;

    IDirect3DSurface9* pD3DSurface = NULL;
    CAutoReleaseMe < IDirect3DSurface9 > Thanks( pD3DSurface );

    D3DRESOURCETYPE resourceType = pD3DBaseTexture->GetType ();
    if ( resourceType == D3DRTYPE_VOLUMETEXTURE )
    {
        return SetVolumeTexturePixels ( (IDirect3DVolumeTexture9*)pD3DBaseTexture, pixels, pRect, uiSurfaceIndex );
    }
    else
    if ( resourceType == D3DRTYPE_CUBETEXTURE )
    {
        D3DCUBEMAP_FACES FaceType = (D3DCUBEMAP_FACES)uiSurfaceIndex;
        ((IDirect3DCubeTexture9*)pD3DBaseTexture)->GetCubeMapSurface ( FaceType, 0, &pD3DSurface );
        if ( !pD3DSurface )
            return false;
    }
    else
    if ( resourceType == D3DRTYPE_TEXTURE )
    {
        ((IDirect3DTexture9*)pD3DBaseTexture)->GetSurfaceLevel ( 0, &pD3DSurface );
        if ( !pD3DSurface )
            return false;
    }


    bool bResult = false;
    D3DSURFACE_DESC Desc;
    pD3DSurface->GetDesc ( &Desc );

    if ( Desc.Usage == D3DUSAGE_RENDERTARGET )
    {
        // Get pixels onto offscreen surface
        IDirect3DSurface9* pLockableSurface = GetRTLockableSurface ( pD3DSurface );

        // Then
        bResult = SetSurfacePixels ( pLockableSurface, pixels, pRect );

        // And write back
        if ( bResult )
            if ( FAILED ( D3DXLoadSurfaceFromSurface ( pD3DSurface, NULL, NULL, pLockableSurface, NULL, NULL, D3DX_FILTER_NONE, 0 ) ) )
                return false;
    }
    else
    if ( Desc.Usage == 0 )
    {
        if ( Desc.Format == D3DFMT_A8R8G8B8 || Desc.Format == D3DFMT_X8R8G8B8 || Desc.Format == D3DFMT_R5G6B5 )
        {
            // Direct reading will work here
            bResult = SetSurfacePixels ( pD3DSurface, pixels, pRect );
        }
        else
        {
            // If not a simple format, use D3DX to convert
            if ( !GetMatchingOffscreenSurface ( pD3DSurface, m_pTempOffscreenSurface, D3DFMT_A8R8G8B8 ) )
                return false;

            if ( FAILED ( D3DXLoadSurfaceFromSurface ( m_pTempOffscreenSurface, NULL, NULL, pD3DSurface, NULL, NULL, D3DX_FILTER_NONE, 0 ) ) )
                return false;

            // Then
            bResult = SetSurfacePixels ( m_pTempOffscreenSurface, pixels, pRect );

            // And write back
            if ( bResult )
                if ( FAILED ( D3DXLoadSurfaceFromSurface ( pD3DSurface, NULL, NULL, m_pTempOffscreenSurface, NULL, NULL, D3DX_FILTER_NONE, 0 ) ) )
                    return false;
        }
    }

    return bResult;
}
예제 #22
0
////////////////////////////////////////////////////////////////
//
// CPixelsManager::GetTexturePixels
//
// Copy pixels from texture
//
////////////////////////////////////////////////////////////////
bool CPixelsManager::GetTexturePixels ( IDirect3DBaseTexture9* pD3DBaseTexture, CPixels& outPixels, const RECT* pRect, uint uiSurfaceIndex )
{
    if ( !pD3DBaseTexture )
        return false;

    IDirect3DSurface9* pD3DSurface = NULL;
    CAutoReleaseMe < IDirect3DSurface9 > Thanks( pD3DSurface );

    D3DRESOURCETYPE resourceType = pD3DBaseTexture->GetType ();
    if ( resourceType == D3DRTYPE_VOLUMETEXTURE )
    {
        return GetVolumeTexturePixels ( (IDirect3DVolumeTexture9*)pD3DBaseTexture, outPixels, pRect, uiSurfaceIndex );
    }
    else
    if ( resourceType == D3DRTYPE_CUBETEXTURE )
    {
        D3DCUBEMAP_FACES FaceType = (D3DCUBEMAP_FACES)uiSurfaceIndex;
        ((IDirect3DCubeTexture9*)pD3DBaseTexture)->GetCubeMapSurface ( FaceType, 0, &pD3DSurface );
        if ( !pD3DSurface )
            return false;
    }
    else
    if ( resourceType == D3DRTYPE_TEXTURE )
    {
        ((IDirect3DTexture9*)pD3DBaseTexture)->GetSurfaceLevel ( 0, &pD3DSurface );
        if ( !pD3DSurface )
            return false;
    }



    bool bResult = false;
    D3DSURFACE_DESC Desc;
    pD3DSurface->GetDesc ( &Desc );

    if ( Desc.Usage == D3DUSAGE_RENDERTARGET )
    {
        // Check we are allowed to read the render target
        bool bAllowScreenUpload = true;
        CVARS_GET ( "allow_screen_upload", bAllowScreenUpload );
        if ( bAllowScreenUpload )
        {
            // Get pixels onto offscreen surface
            IDirect3DSurface9* pLockableSurface = GetRTLockableSurface ( pD3DSurface );

            // Then
            bResult = GetSurfacePixels ( pLockableSurface, outPixels, pRect );
        }
        else
        {
            // If not allowed, return dummy data
            uint uiPixelsWidth = 32;
            uint uiPixelsHeight = 32;
            outPixels.SetSize ( uiPixelsWidth * uiPixelsHeight * XRGB_BYTES_PER_PIXEL + SIZEOF_PLAIN_TAIL );
            memset ( outPixels.GetData (), 0xEF, outPixels.GetSize () );
            bResult = SetPlainDimensions ( outPixels, uiPixelsWidth, uiPixelsHeight );
        }
    }
    else
    if ( Desc.Usage == 0 )
    {
        if ( Desc.Format == D3DFMT_A8R8G8B8 || Desc.Format == D3DFMT_X8R8G8B8 || Desc.Format == D3DFMT_R5G6B5 )
        {
            // Direct reading will work here
            bResult = GetSurfacePixels ( pD3DSurface, outPixels, pRect );
        }
        else
        {
            // If not a simple format, use D3DX to convert
            if ( !GetMatchingOffscreenSurface ( pD3DSurface, m_pTempOffscreenSurface, D3DFMT_A8R8G8B8 ) )
                return false;

            if ( FAILED ( D3DXLoadSurfaceFromSurface ( m_pTempOffscreenSurface, NULL, NULL, pD3DSurface, NULL, NULL, D3DX_FILTER_NONE, 0 ) ) )
                return false;

            // Then
            bResult = GetSurfacePixels ( m_pTempOffscreenSurface, outPixels, pRect );
        }
    }

    return bResult;
}
void* CDX9TextureObject::Read( int level, bool bForceUpdateRead )
{
	ReadyData();

	//level currently ignored, read cannot read mipmaps
	if( m_Texture )
	{
		LPDIRECT3DDEVICE9 pDevice;
		if( !m_Renderer )
		{
			return NULL;
		}
		pDevice = (LPDIRECT3DDEVICE9)m_Renderer->GetAPIDevice();
		if( !pDevice )
		{
			return NULL;
		}

		int iTextureSize = (GetColorDepth() / 8) * GetWidth() * GetHeight();
		// delete the old buffer if our current one is the wrong size
		if (m_pLocalBuffer && (iTextureSize != m_iLocalBufferSize))
		{
			delete[] m_pLocalBuffer;
			m_pLocalBuffer = NULL;
			m_iLocalBufferSize = 0;
		}
		// allocate a new buffer if we don't have one
		if (!m_pLocalBuffer)
		{
			m_pLocalBuffer = new unsigned char[iTextureSize];
			m_iLocalBufferSize = iTextureSize;
		}
		else
		{
			// return current buffer if we aren't forcing a read
			if (!bForceUpdateRead)
				return m_pLocalBuffer;
		}
		//check what kind of a surface it is, we have to get the surface if it's a rendertarget!
		if( !m_bRenderTarget )
		{
			if( m_Compressed )
			{
				LPDIRECT3DSURFACE9 Src = NULL;
				m_Texture->GetSurfaceLevel( 0, &Src );				
				//convert format to argb first
				LPDIRECT3DSURFACE9 tempSurf = NULL;
				HRESULT hr = pDevice->CreateOffscreenPlainSurface( GetWidth(), GetHeight(),
									D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tempSurf, NULL );
				if( hr != D3D_OK ||
					tempSurf == NULL ||
					Src == NULL )
				{
					SAFE_RELEASE( Src );
					SAFE_RELEASE( tempSurf );
					return NULL;
				}

				hr = D3DXLoadSurfaceFromSurface( tempSurf, NULL, NULL, Src, NULL, NULL, D3DX_DEFAULT, 0 );			
				if( hr != D3D_OK )
				{
					return NULL;
				}

				//lock the texture and read the data
				D3DLOCKED_RECT  lockrect;
				hr = tempSurf->LockRect( &lockrect, NULL, D3DLOCK_READONLY );
				if( hr == D3D_OK )
				{
					UINT pixelsize = (GetColorDepth()/8);
					BYTE * srcbits = (BYTE*)lockrect.pBits;
					BYTE * destbits = (BYTE*)m_pLocalBuffer;
					//write the texture to the buffer
					for( UINT i = 0; i < m_Height; i++ )
					{
						memcpy( destbits, srcbits, m_Width*pixelsize );
						//move by pitch
						srcbits  +=  lockrect.Pitch;
						destbits += m_Width*pixelsize;
					}
				}
				tempSurf->UnlockRect();
				SAFE_RELEASE( tempSurf );
				SAFE_RELEASE( Src );
				return m_pLocalBuffer;
			}
			else
			{
				//lock the texture and read the data
				D3DLOCKED_RECT  lockrect;
				HRESULT hr = m_Texture->LockRect( 0, &lockrect, NULL, D3DLOCK_READONLY );
				if( hr == D3D_OK )
				{
					UINT pixelsize = (GetColorDepth()/8);
					BYTE * srcbits = (BYTE*)lockrect.pBits;
					BYTE * destbits = (BYTE*)m_pLocalBuffer;
					//write the texture to the buffer
					for( UINT i = 0; i < m_Height; i++ )
					{
						memcpy( destbits, srcbits, m_Width*pixelsize );
						//move by pitch
						srcbits  +=  lockrect.Pitch;
						destbits += m_Width*pixelsize;
					}
				}
				m_Texture->UnlockRect( 0 );
				return m_pLocalBuffer;
			}
		}else//we are render target, need surface
		{			
			LPDIRECT3DSURFACE9 RenderSurf = NULL;
			LPDIRECT3DSURFACE9 OffSurf = NULL;
			m_Texture->GetSurfaceLevel( 0, &RenderSurf );
			
			if( RenderSurf )
			{
				D3DSURFACE_DESC tDesc;
				m_Texture->GetLevelDesc(0, &tDesc );
				if( FAILED(pDevice->CreateOffscreenPlainSurface( tDesc.Width,
													tDesc.Height,
													tDesc.Format,
													D3DPOOL_SYSTEMMEM,													
													&OffSurf,
													NULL )))
				{
					RenderSurf->Release();
					return NULL;
				}
				if( FAILED( pDevice->GetRenderTargetData( RenderSurf, OffSurf ) ))
				{
					RenderSurf->Release();
					OffSurf->Release();
					return NULL;
				}
				//No need for rendertarget surface anymore
				RenderSurf->Release();
				//lock the texture and read the data
				D3DLOCKED_RECT  lockrect;
				HRESULT hr = OffSurf->LockRect( &lockrect, NULL, D3DLOCK_READONLY );
				if( hr == D3D_OK )
				{
					UINT pixelsize = (GetColorDepth()/8);
					BYTE * srcbits = (BYTE*)lockrect.pBits;
					BYTE * destbits = (BYTE*)m_pLocalBuffer;
					//write the texture to the buffer
					for( UINT i = 0; i < m_Height; i++ )
					{
						memcpy( destbits, srcbits, m_Width*pixelsize );
						//move by pitch
						srcbits  +=  lockrect.Pitch;
						destbits += m_Width*pixelsize;
					}
				}
				OffSurf->UnlockRect();
				OffSurf->Release();
			}
			return m_pLocalBuffer;

		}
	}
	return NULL;
}
예제 #24
0
int Render(){
	HRESULT r;
//	D3DLOCKED_RECT LockedRect;//locked area of display memory(buffer really) we are drawing to
	LPDIRECT3DSURFACE8 pBackSurf = 0;
	if(!g_pDevice){
		SetError("Cannot render because there is no device");
		return E_FAIL;
	}

	//clear the display arera with colour black, ignore stencil buffer
	g_pDevice->Clear(0,0,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,25), 1.0f, 0);

	//get pointer to backbuffer
	r=g_pDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO, &pBackSurf);
	if(FAILED(r)){
		SetError("Couldn't get backbuffer");
	}
/*
	//get a lock on the surface
	r=pBackSurf->LockRect(&LockedRect, NULL, 0);
	if(FAILED(r)){
		SetError("Could not lock the back buffer");
	}

	DWORD* pData = (DWORD*)(LockedRect.pBits);
	//DRAW CODE GOES HERE - use pData
	Draw(LockedRect.Pitch, pData);

 */
	LPDIRECT3DSURFACE8 pSurface = 0;

	r=LoadBitmapToSurface("baboon.bmp",
		&pSurface, g_pDevice);
	if(FAILED(r)){
		SetError("could not load bitmap surface");
	}

	D3DSURFACE_DESC d3dsd;
	pSurface->GetDesc(&d3dsd);//get info about surface

	POINT DestPoint = {0, 0};
	RECT rect = {0,0, d3dsd.Width, d3dsd.Height};//source dimensions

//	SetError("size x=%d size y=%d format=%d",d3dsd.Width, d3dsd.Height, d3dsd.Format);

//	r=g_pDevice->CopyRects(pSurface, &rect, 1, pBackSurf, &DestPoint);//copy surface to buffer (like a bitblt)

	r=D3DXLoadSurfaceFromSurface(pBackSurf, NULL, NULL, pSurface, NULL, &rect, D3DX_FILTER_TRIANGLE,0);
//	r=D3DXLoadSurfaceFromSurface(pBackSurf, NULL, NULL, pSurface, NULL, &rect, D3DX_FILTER_POINT, 0);
	if(ERROR(r))
		SetError("did not copy surface");

//	SimpleBitmapDraw("baboon.bmp", pBackSurf, 10,10);
	pSurface->Release();
	pSurface = 0;

//	pBackSurf->UnlockRect();
//	pData = 0;

//	pBackSurf->Release();//release lock
//	pBackSurf = 0;

	g_pDevice->Present(NULL, NULL, NULL, NULL);//swap over buffer to primary surface
	return S_OK;
}
예제 #25
0
HRESULT CDxtexDoc::BltAllLevels(D3DCUBEMAP_FACES FaceType, 
    LPDIRECT3DBASETEXTURE9 ptexSrc, LPDIRECT3DBASETEXTURE9 ptexDest)
{
    HRESULT hr;
    LPDIRECT3DTEXTURE9 pmiptexSrc;
    LPDIRECT3DTEXTURE9 pmiptexDest;
    LPDIRECT3DCUBETEXTURE9 pcubetexSrc;
    LPDIRECT3DCUBETEXTURE9 pcubetexDest;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexSrc;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexDest;
    DWORD iLevel;

    if (IsVolumeMap())
    {
        pvoltexSrc = (LPDIRECT3DVOLUMETEXTURE9)ptexSrc;
        pvoltexDest = (LPDIRECT3DVOLUMETEXTURE9)ptexDest;
    }
    else if (IsCubeMap())
    {
        pcubetexSrc = (LPDIRECT3DCUBETEXTURE9)ptexSrc;
        pcubetexDest = (LPDIRECT3DCUBETEXTURE9)ptexDest;
    }
    else
    {
        pmiptexSrc = (LPDIRECT3DTEXTURE9)ptexSrc;
        pmiptexDest = (LPDIRECT3DTEXTURE9)ptexDest;
    }

    for (iLevel = 0; iLevel < m_numMips; iLevel++)
    {
        if (IsVolumeMap())
        {
            LPDIRECT3DVOLUME9 pvolSrc = NULL;
            LPDIRECT3DVOLUME9 pvolDest = NULL;
            hr = pvoltexSrc->GetVolumeLevel(iLevel, &pvolSrc);
            hr = pvoltexDest->GetVolumeLevel(iLevel, &pvolDest);
            hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, 
                pvolSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&pvolSrc);
            ReleasePpo(&pvolDest);
        }
        else if (IsCubeMap())
        {
            LPDIRECT3DSURFACE9 psurfSrc = NULL;
            LPDIRECT3DSURFACE9 psurfDest = NULL;
            hr = pcubetexSrc->GetCubeMapSurface(FaceType, iLevel, &psurfSrc);
            hr = pcubetexDest->GetCubeMapSurface(FaceType, iLevel, &psurfDest);
            hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
                psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&psurfSrc);
            ReleasePpo(&psurfDest);
        }
        else
        {
            LPDIRECT3DSURFACE9 psurfSrc = NULL;
            LPDIRECT3DSURFACE9 psurfDest = NULL;
            hr = pmiptexSrc->GetSurfaceLevel(iLevel, &psurfSrc);
            hr = pmiptexDest->GetSurfaceLevel(iLevel, &psurfDest);
            hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
                psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&psurfSrc);
            ReleasePpo(&psurfDest);
        }
    }

    return S_OK;
}