Exemple #1
0
void CComboRenderer::Render(DWORD flags)
{
  if ( m_RGBSurface[m_iYUY2RenderBuffer] == NULL )
  {
    RenderLowMem(flags);
  }
  else
  {
    YV12toYUY2();
    CheckScreenSaver();

    /* clear target area, otherwise we won't get any picture */
    D3DRECT target;
    target.x1 = rd.left;
    target.x2 = rd.right;
    target.y1 = rd.top;
    target.y2 = rd.bottom;
    m_pD3DDevice->Clear( 1L, &target, D3DCLEAR_TARGET, m_clearColour, 1.0f, 0L );

    // Don't render if we are waiting an overlay event
    while (!m_pD3DDevice->GetOverlayUpdateStatus()) Sleep(1);

    LPDIRECT3DSURFACE8 pSurface;
    m_YUY2Texture[m_iYUY2RenderBuffer]->GetSurfaceLevel(0, &pSurface);
    m_pD3DDevice->UpdateOverlay( pSurface, &rs, &rd, TRUE, m_clearColour );
    pSurface->Release();
  }

  CXBoxRenderer::Render(flags | RENDER_FLAG_NOOSDALPHA);
}
void CALL HGE_Impl::System_Snapshot(const char *filename)
{
	LPDIRECT3DSURFACE8 pSurf;
	char *shotname, tempname[_MAX_PATH];
	int i;

	if(!filename)
	{
		i=0;
		shotname=Resource_EnumFiles("shot???.bmp");
		while(shotname)
		{
			i++;
			shotname=Resource_EnumFiles();
		}
		sprintf(tempname, "shot%03d.bmp", i);
		filename=Resource_MakePath(tempname);
	}

	if(pD3DDevice)
	{
		pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf);
		D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurf, NULL, NULL);
		pSurf->Release();
	}
}
Exemple #3
0
bool GetFormatMSE(const D3DXIMAGE_INFO& info, LPDIRECT3DSURFACE8 pSrcSurf, D3DFORMAT fmt, double& CMSE, double& AMSE)
{
	LPDIRECT3DSURFACE8 pCompSurf = 0, pDstSurf = 0;
	HRESULT hr;

	// Compress
	int Width = PadPow2(info.Width), Height = PadPow2(info.Height);
	hr = pD3DDevice->CreateImageSurface(Width, Height, fmt, &pCompSurf);
	CheckHR(hr);

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

	// Decompress
	hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf);
	CheckHR(hr);

	hr = D3DXLoadSurfaceFromSurface(pDstSurf, NULL, NULL, pCompSurf, NULL, NULL, D3DX_FILTER_NONE, 0);
	CheckHR(hr);

	pCompSurf->Release(); pCompSurf = 0;

	// calculate mean square error
	D3DLOCKED_RECT slr, dlr;
	hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);
	hr = pDstSurf->LockRect(&dlr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);

	double CTSE = 0.0; // total colour square error
	double ATSE = 0.0; // total alpha square error

	RGBCOLOUR* src = (RGBCOLOUR*)slr.pBits;
	RGBCOLOUR* dst = (RGBCOLOUR*)dlr.pBits;
	for (UINT y = 0; y < info.Height; ++y)
	{
		for (UINT x = 0; x < info.Width; ++x)
		{
			CTSE += (src->b - dst->b) * (src->b - dst->b);
			CTSE += (src->g - dst->g) * (src->g - dst->g);
			CTSE += (src->r - dst->r) * (src->r - dst->r);
			ATSE += (src->a - dst->a) * (src->a - dst->a);
			++src; ++dst;
		}
		src += (slr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR);
		dst += (dlr.Pitch - info.Width*sizeof(RGBCOLOUR)) / sizeof(RGBCOLOUR);
	}
	CMSE = CTSE / double(info.Width * info.Height * 3);
	AMSE = ATSE / double(info.Width * info.Height);

	pSrcSurf->UnlockRect();
	pDstSurf->UnlockRect();
	pDstSurf->Release(); pDstSurf = 0;

	return true;
}
Exemple #4
0
int	CIFMouseCursor::ChangeCursor( int cursorID, int type )
{
	HRESULT hr;
    LPDIRECT3DSURFACE8 pCursorBitmap = NULL;
	BYTE* pCursorBuffer = NULL;
	BYTE* pMouseBuffer;

	DWORD dwSize;

	switch( type )
	{
	case MOUSE_CURSOR_TYPE :
		pMouseBuffer = m_mouseCursorBuffer[cursorID].buf;
		break;
	case ITEM_CURSOR_TYPE :
		pMouseBuffer = m_itemCursorBuffer[cursorID].buf;
		break;
	case SKILL_CURSOR_TYPE : case ACTION_CURSOR_TYPE :
		pMouseBuffer = m_skillCursorBuffer[cursorID].buf;
		break;
	}

	dwSize = 32 * 32 * 4;

    
    m_pd3dDevice->CreateImageSurface( 32, 32, D3DFMT_A8R8G8B8, &pCursorBitmap );

    D3DLOCKED_RECT lr;
    pCursorBitmap->LockRect( &lr, NULL, 0 );
    pCursorBuffer = (BYTE *)lr.pBits;
	memcpy( pCursorBuffer, pMouseBuffer, dwSize );
    pCursorBitmap->UnlockRect();

    if( FAILED( hr = m_pd3dDevice->SetCursorProperties( 0, 0, pCursorBitmap ) ) )
    {
        goto CHANGE_CURSOR_END ;
    }

    hr = S_OK;

CHANGE_CURSOR_END :

    SAFE_RELEASE( pCursorBitmap );

    if( FAILED( hr ) ) return 0;
	return 1;
}
Exemple #5
0
void SimpleBitmapDraw(char* PathName, LPDIRECT3DSURFACE8 pBackSurf, int dpx, int dpy){
	LPDIRECT3DSURFACE8 pSurface = 0;

	LoadBitmapToSurface(PathName, &pSurface, g_pDevice);

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

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

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

//	pSurface->Release();
//	pSurface = 0;

//	pBackSurf->Release();
//	pBackSurf = 0;
//
//	g_pDevice->Present(NULL, NULL, NULL, NULL);//put it on the primary surface
}
Exemple #6
0
// Converts any fully transparent pixels to black so that the mse calcs work for dxt
void FixTransparency(LPDIRECT3DSURFACE8 pSrcSurf)
{
	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	D3DLOCKED_RECT slr;
	if (FAILED(pSrcSurf->LockRect(&slr, NULL, 0)))
		return;

	DWORD* pix = (DWORD*)slr.pBits;
	for (UINT y = 0; y < desc.Width; ++y)
	{
		for (UINT x = 0; x < desc.Height; ++x)
		{
			if (!(*pix & 0xff000000))
				*pix = 0;
			++pix;
		}
	}

	pSrcSurf->UnlockRect();
}
Exemple #7
0
bool CN3Texture::SaveToBitmapFile(const std::string& szFN)
{
	if(szFN.empty()) return false;
	if(NULL == m_lpTexture) return false;

	LPDIRECT3DSURFACE8 lpSurfSrc = NULL;
	m_lpTexture->GetSurfaceLevel(0, &lpSurfSrc);

	if(NULL == lpSurfSrc) return false;

	LPDIRECT3DSURFACE8 lpSurfDest = NULL;
	s_lpD3DDev->CreateImageSurface(m_Header.nWidth, m_Header.nHeight, D3DFMT_A8R8G8B8, &lpSurfDest);

	if(NULL == lpSurfDest) return false;
	if(D3D_OK != D3DXLoadSurfaceFromSurface(lpSurfDest, NULL, NULL, lpSurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0)) // 서피스 복사.
	{
		lpSurfDest->Release(); lpSurfDest = NULL;
		lpSurfSrc->Release(); lpSurfSrc = NULL;
	}

	CBitMapFile bmpf;
	bmpf.Create(m_Header.nWidth, m_Header.nHeight);

	D3DLOCKED_RECT LR;
	lpSurfDest->LockRect(&LR, NULL, 0);
	for(int y = 0; y < m_Header.nHeight; y++)
	{
		BYTE* pPixelsSrc = ((BYTE*)LR.pBits) + y * LR.Pitch;
		BYTE* pPixelsDest = (BYTE*)(bmpf.Pixels(0, y));
		for(int x = 0; x < m_Header.nWidth; x++)
		{
			pPixelsDest[0] = pPixelsSrc[0];
			pPixelsDest[1] = pPixelsSrc[1];
			pPixelsDest[2] = pPixelsSrc[2];
			
			pPixelsSrc += 4;
			pPixelsDest += 3;
		}
	}
	lpSurfDest->UnlockRect();
	
	lpSurfDest->Release(); lpSurfDest = NULL;
	lpSurfSrc->Release(); lpSurfSrc = NULL;

	return bmpf.SaveToFile(szFN.c_str());
}
Exemple #8
0
bool CN3Texture::CreateFromSurface(LPDIRECT3DSURFACE8 lpSurf, D3DFORMAT Format, BOOL bGenerateMipMap)
{
	if(lpSurf == NULL) return false;

	D3DSURFACE_DESC sd;
	lpSurf->GetDesc(&sd);

	if(this->Create(sd.Width, sd.Height, Format, bGenerateMipMap) == false) return false;
	if(bGenerateMipMap)
	{
		this->GenerateMipMap(lpSurf);
	}
	
	return true;
}
Exemple #9
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;
}
// read depth buffer and update visibility flag of depth points
static void UpdateDepthPointsVisibility( const CDrawPort *pdp, const INDEX iMirrorLevel,
                                         DepthInfo *pdi, const INDEX ctCount)
{
  const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  ASSERT(GfxValidApi(eAPI));
  ASSERT( pdp!=NULL && ctCount>0);
  const CRaster *pra = pdp->dp_Raster;

  // OpenGL
  if( eAPI==GAT_OGL)
  { 
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    FLOAT fPointOoK;
    // for each stored point
    for( INDEX idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      const PIX pixJ = pra->ra_Height-1 - di.di_pixJ; // OpenGL has Y-inversed buffer!
      pglReadPixels( di.di_pixI, pixJ, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fPointOoK);
      OGL_CHECKERROR;
      // it is visible if there is nothing nearer in z-buffer already
      di.di_bVisible = (di.di_fOoK<fPointOoK);
    }
    // done
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }

  // Direct3D
#ifdef SE1_D3D
  if( eAPI==GAT_D3D)
  {
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // ok, this will get really complicated ...
    // We'll have to do it thru back buffer because darn DX8 won't let us have values from z-buffer;
    // Anyway, we'll lock backbuffer, read color from the lens location and try to write little triangle there
    // with slightly modified color. Then we'll readout that color and see if triangle passes z-test. Voila! :)
    // P.S. To avoid lock-modify-lock, we need to batch all the locks in one. Uhhhh ... :(
    COLOR col;
    INDEX idi;
    SLONG slColSize;
    HRESULT hr;
    D3DLOCKED_RECT rectLocked;
    D3DSURFACE_DESC surfDesc;
    LPDIRECT3DSURFACE8 pBackBuffer;
    // fetch back buffer (different for full screen and windowed mode)
    const BOOL bFullScreen = _pGfx->gl_ulFlags & GLF_FULLSCREEN;
    if( bFullScreen) {
      hr = _pGfx->gl_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    } else {
      hr = pra->ra_pvpViewPort->vp_pSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    }
    // what, cannot get a back buffer?
    if( hr!=D3D_OK) { 
      // to hell with it all
      _sfStats.StopTimer(CStatForm::STI_GFXAPI);
      return;
    }
    // keep format of back-buffer
    pBackBuffer->GetDesc(&surfDesc);
    const D3DFORMAT d3dfBack = surfDesc.Format;
    
    // prepare array that'll back-buffer colors from depth point locations
    _acolDelayed.Push(ctCount);
    // store all colors
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      // fetch pixel
      _acolDelayed[idi] = 0;
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read, convert and store original color
      _acolDelayed[idi] = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
    }

    // prepare to draw little triangles there with slightly adjusted colors
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    gfxEnableDepthTest();
    gfxDisableDepthWrite();
    gfxDisableBlend();
    gfxDisableAlphaTest();
    gfxDisableTexture();
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // prepare array and shader
    _avtxDelayed.Push(ctCount*3);
    d3dSetVertexShader(D3DFVF_CTVERTEX);

    // draw one trianle around each depth point
    INDEX ctVertex = 0;
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      const ULONG d3dCol = rgba2argb(col^0x20103000);
      const PIX pixI = di.di_pixI - pdp->dp_MinI; // convert raster loc to drawport loc
      const PIX pixJ = di.di_pixJ - pdp->dp_MinJ;
      // batch it and advance to next triangle
      CTVERTEX &vtx0 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx1 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx2 = _avtxDelayed[ctVertex++];
      vtx0.fX=pixI;   vtx0.fY=pixJ-2; vtx0.fZ=di.di_fOoK; vtx0.ulColor=d3dCol; vtx0.fU=vtx0.fV=0;
      vtx1.fX=pixI-2; vtx1.fY=pixJ+2; vtx1.fZ=di.di_fOoK; vtx1.ulColor=d3dCol; vtx1.fU=vtx0.fV=0;
      vtx2.fX=pixI+2; vtx2.fY=pixJ;   vtx2.fZ=di.di_fOoK; vtx2.ulColor=d3dCol; vtx2.fU=vtx0.fV=0;
    }
    // draw a bunch
    hr = _pGfx->gl_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, ctVertex/3, &_avtxDelayed[0], sizeof(CTVERTEX));
    D3D_CHECKERROR(hr);

    // readout colors again and compare to old ones
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      // fetch pixel
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read new color
      const COLOR colNew = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
      // if we managed to write adjusted color, point is visible!
      di.di_bVisible = (col!=colNew);
    }
    // phew, done! :)
    D3DRELEASE( pBackBuffer, TRUE);
    _acolDelayed.PopAll();
    _avtxDelayed.PopAll();
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }
#endif // SE1_D3D
}
Exemple #11
0
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    HRESULT hr;

    // Restore the font
    m_pFont->RestoreDeviceObjects();
    m_pFontSmall->RestoreDeviceObjects();

    // Create light
    D3DLIGHT8 light;
    ZeroMemory(&light, sizeof(light));

    light.Type        = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r   = m_colorLight.r;
    light.Diffuse.g   = m_colorLight.g;
    light.Diffuse.b   = m_colorLight.b;
    light.Diffuse.a   = m_colorLight.a;
    light.Specular.r  = 1.0f;
    light.Specular.g  = 1.0f;
    light.Specular.b  = 1.0f;
    light.Specular.a  = 0.0f;
    light.Direction.x = m_vecLight.x;
    light.Direction.y = m_vecLight.y;
    light.Direction.z = m_vecLight.z;

    m_pd3dDevice->SetLight(0, &light);
    m_pd3dDevice->LightEnable(0, TRUE);


    // Create material
    D3DMATERIAL8 material;
    ZeroMemory(&material, sizeof(material));

    material.Diffuse.a  = 1.0f;
    material.Specular.r = 0.5f;
    material.Specular.g = 0.5f;
    material.Specular.b = 0.5f;
    material.Power      = 20.0f;

    m_pd3dDevice->SetMaterial(&material);

    // Setup render states
    m_pd3dDevice->SetVertexShader(D3DFVF_XYZ);

    m_pd3dDevice->SetTransform(D3DTS_VIEW,  &m_matView);
    m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matIdentity);

    m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,       FALSE);
    m_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);

    m_pd3dDevice->SetRenderState(D3DRS_ZFUNC,     D3DCMP_LESSEQUAL);
    m_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_CW);
    m_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE);
    m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);




    // Create caustic texture
    D3DDISPLAYMODE mode;
    m_pd3dDevice->GetDisplayMode(&mode);

    if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, D3DUSAGE_RENDERTARGET, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)) &&
       FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, 0, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)))
    {
        return hr;
    }

    D3DSURFACE_DESC desc;
    m_pCausticTex->GetSurfaceLevel(0, &m_pCausticSurf);
    m_pCausticSurf->GetDesc(&desc);

    if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height, 
        desc.Format, FALSE, D3DFMT_UNKNOWN, &m_pRenderToSurface)))
    {
        return hr;
    }



    // Shader
    TCHAR sz[512];
    DXUtil_FindMediaFile(sz, _T("water.sha"));

    if(FAILED(hr = D3DXCreateEffectFromFile(m_pd3dDevice, sz, &m_pEffect, NULL)))
        return hr;

    m_pEffect->SetMatrix("mID",  &m_matIdentity);
    m_pEffect->SetMatrix("mENV", &m_matIdentity);

    m_pEffect->SetTexture("tFLR", m_pFloorTex);
    m_pEffect->SetTexture("tCAU", m_pCausticTex);
    m_pEffect->SetTexture("tENV", m_pSkyCubeTex);

    if(FAILED(hr = GetNextTechnique(0, FALSE)))
        return hr;


    // Set surfaces
    if(FAILED(hr = m_Environment.SetSurfaces(
        m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_X], 
        m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Y],
        m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Z], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Z])))
    {
        return hr;
    }


    // OnResetDevice
    if(FAILED(hr = m_Water.OnResetDevice()))
        return hr;

    if(FAILED(hr = m_Environment.OnResetDevice()))
        return hr;

    return S_OK;
}
Exemple #12
0
void CComboRenderer::YV12toYUY2()
{
  int index = m_iYV12RenderBuffer;
  if (!m_RGBSurface[m_iYUY2RenderBuffer]) return;

  /* if we have dimmed our texture, don't overwrite it */
  if( g_application.IsInScreenSaver() && m_bHasDimView ) return;

  if( WaitForSingleObject(m_eventTexturesDone[index], 500) == WAIT_TIMEOUT )
    CLog::Log(LOGWARNING, __FUNCTION__" - Timeout waiting for texture %d", index);

  // Do the YV12 -> YUY2 conversion.
  // ALWAYS use buffer 0 in this case (saves 12 bits/pixel)
  m_pD3DDevice->SetTexture( 0, m_YUVTexture[index][FIELD_FULL][PLANE_Y] );
  m_pD3DDevice->SetTexture( 1, m_YUVTexture[index][FIELD_FULL][PLANE_U] );
  m_pD3DDevice->SetTexture( 2, m_YUVTexture[index][FIELD_FULL][PLANE_Y] );
  m_pD3DDevice->SetTexture( 3, m_YUVTexture[index][FIELD_FULL][PLANE_V] );

  for (int i = 0; i < 4; ++i)
  {
    m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
    m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
    m_pD3DDevice->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_POINT );
    m_pD3DDevice->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_POINT );
  }
  // U and V need to use linear filtering, as they're being doubled vertically
  m_pD3DDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

  m_pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
  m_pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  m_pD3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
  m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  m_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
  m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
  m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
  m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE );
  m_pD3DDevice->SetVertexShader( FVF_YUYVVERTEX );
  m_pD3DDevice->SetPixelShader( m_hPixelShader );
  // Render the image
  LPDIRECT3DSURFACE8 pOldRT;
  m_pD3DDevice->GetRenderTarget(&pOldRT);
  m_pD3DDevice->SetRenderTarget(m_RGBSurface[m_iYUY2RenderBuffer], NULL);

  m_pD3DDevice->Begin(D3DPT_QUADLIST);
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)1.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)0.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)0.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)0.5f, (float)0.5f);
  m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)0.0f, (float)0.0f, 0, 1.0f );

  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)m_iSourceWidth + 1.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)m_iSourceWidth / 2.0f + 0.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)m_iSourceWidth + 0.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)m_iSourceWidth / 2.0f + 0.5f, (float)0.5f );
  m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)m_iSourceWidth / 2.0f, (float)0.0f, 0, 1.0f );

  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)m_iSourceWidth + 1.5f, (float)m_iSourceHeight + 0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)m_iSourceWidth / 2.0f + 0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)m_iSourceWidth + 0.5f, (float)m_iSourceHeight + 0.5f);
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)m_iSourceWidth / 2.0f + 0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
  m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)m_iSourceWidth / 2.0f, (float)m_iSourceHeight, 0, 1.0f );

  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)1.5f, (float)m_iSourceHeight + 0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)0.5f, (float)m_iSourceHeight + 0.5f );
  m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
  m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)0.0f, (float)m_iSourceHeight, 0, 1.0f );
  m_pD3DDevice->End();

  m_pD3DDevice->SetTexture(0, NULL);
  m_pD3DDevice->SetTexture(1, NULL);
  m_pD3DDevice->SetTexture(2, NULL);
  m_pD3DDevice->SetTexture(3, NULL);

  m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE );
  m_pD3DDevice->SetPixelShader( NULL );
  m_pD3DDevice->SetRenderTarget(pOldRT, NULL);

  m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
  m_pD3DDevice->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );

  pOldRT->Release();

  //Okey, when the gpu is done with the textures here, they are free to be modified again
  m_pD3DDevice->InsertCallback(D3DCALLBACK_WRITE,&TextureCallback, (DWORD)m_eventTexturesDone[index]);

  m_pD3DDevice->KickPushBuffer();

  m_bHasDimView = false;
}
Exemple #13
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;
		}
	}
}
Exemple #14
0
void AppendXPRImage(const D3DXIMAGE_INFO& info, LPDIRECT3DSURFACE8 pSrcSurf, XB_D3DFORMAT fmt)
{
	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	HRESULT hr;
	UINT Pitch;
	UINT Size;

	if (fmt == XB_D3DFMT_DXT1 || fmt == XB_D3DFMT_DXT3 || fmt == XB_D3DFMT_DXT5)
	{
		if (fmt == XB_D3DFMT_DXT1)
			Pitch = desc.Width / 2;
		else
			Pitch = desc.Width;
		Size = ((Pitch * desc.Height) + 127) & ~127; // must be 128-byte aligned for any following images
		Pitch *= 4;

		VirtualAlloc(XPRFile.Data, Size, MEM_COMMIT, PAGE_READWRITE);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

    hr = CompressRect(XPRFile.Data, fmt, Pitch, desc.Width, desc.Height, slr.pBits, XB_D3DFMT_LIN_A8R8G8B8, slr.Pitch, 0.5f, 0);
    if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

		pSrcSurf->UnlockRect();
	}
	else
	{
		UINT bpp = BytesPerPixelFromFormat(fmt);
		Pitch = desc.Width * bpp;
		Size = ((Pitch * desc.Height) + 127) & ~127; // must be 128-byte aligned for any following images

		VirtualAlloc(XPRFile.Data, Size, MEM_COMMIT, PAGE_READWRITE);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

		if (IsSwizzledFormat(fmt))
		{
			// Swizzle for xbox
			SwizzleRect(slr.pBits, 0, NULL, XPRFile.Data, desc.Width, desc.Height, NULL, bpp);
		}
		else
		{
			// copy
			BYTE* src = (BYTE*)slr.pBits;
			BYTE* dst = (BYTE*)XPRFile.Data;
			for (UINT y = 0; y < desc.Height; ++y)
			{
				memcpy(dst, src, desc.Width * bpp);
				src += slr.Pitch;
				dst += Pitch;
			}
		}

		pSrcSurf->UnlockRect();
	}

	SetTextureHeader(desc.Width, desc.Height, 1, 0, fmt, D3DPOOL_DEFAULT, 
		&XPRFile.Texture[XPRFile.nImages].D3DTex, XPRFile.Data - XPRFile.DataStart, Pitch);
	if (!(*XPRFile.flags & XPRFLAG_ANIM))
		XPRFile.Texture[XPRFile.nImages].RealSize = (info.Width & 0xffff) | ((info.Height & 0xffff) << 16);
	++XPRFile.nImages;

	XPRFile.Data += Size;
	CompressedSize += Size;
}
void CApplicationRenderer::Process()
{
#ifndef HAS_SDL
  int iWidth = 0;
  int iHeight = 0;
  int iLeft = 0;
  int iTop = 0;
  LPDIRECT3DSURFACE8 lpSurfaceBack = NULL;
  LPDIRECT3DSURFACE8 lpSurfaceFront = NULL;
  while (!m_bStop)
  {
    if (!m_enabled || g_graphicsContext.IsFullScreenVideo())
    {
      Sleep(50);
      continue;
    }

    if (!m_pWindow || iWidth == 0 || iHeight == 0 || m_Resolution != g_graphicsContext.GetVideoResolution())
    {
      m_pWindow = (CGUIDialogBusy*)m_gWindowManager.GetWindow(WINDOW_DIALOG_BUSY);
      if (m_pWindow)
      {
        m_pWindow->Initialize();//need to load the window to determine size.
        if (m_pWindow->GetID() == WINDOW_INVALID)
        {
          //busywindow couldn't be loaded so stop this thread.
          m_pWindow = NULL;
          m_bStop = true;
          break;
        }

        SAFE_RELEASE(m_lpSurface);
        FRECT rect = m_pWindow->GetScaledBounds();
        m_pWindow->ClearAll(); //unload

        iLeft = (int)floor(rect.left);
        iTop =  (int)floor(rect.top);
        iWidth = (int)ceil(rect.right - rect.left);
        iHeight = (int)ceil(rect.bottom - rect.top);
        m_Resolution = g_graphicsContext.GetVideoResolution();
      }
    }

    float t0 = (1000.0f/g_graphicsContext.GetFPS());
    float t1 = m_time + t0; //time when we expect a new render
    float t2 = (float)timeGetTime();
    if (t1 < t2) //we're late rendering
    {
      try
      {
        if (timeGetTime() >= (m_time + g_advancedSettings.m_busyDialogDelay))
        {
          CSingleLock lockg (g_graphicsContext);
          if (m_prevbusycount != m_busycount)
          {
            Sleep(1);
            continue;
          }
          if (!m_pWindow || iWidth == 0 || iHeight == 0)
          {
            Sleep(1000);
            continue;
          }
          if (m_Resolution != g_graphicsContext.GetVideoResolution())
          {
            continue;
          }
          if (m_busycount > 0) m_busycount--;
          //no busy indicator if a progress dialog is showing
          if ((m_gWindowManager.HasModalDialog() && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_VIDEO_INFO) && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_MUSIC_INFO)) || (m_gWindowManager.GetTopMostModalDialogID() == WINDOW_DIALOG_PROGRESS))
          {
            //TODO: render progress dialog here instead of in dialog::Progress
            m_time = timeGetTime();
            lockg.Leave();
            Sleep(1);
            continue;
          }
          if (m_lpSurface == NULL)
          {
            D3DSURFACE_DESC desc;
            g_application.RenderNoPresent();
            HRESULT result = g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceFront);
            if (SUCCEEDED(result))
            {
              lpSurfaceFront->GetDesc( &desc );
              iLeft = 0;
              iTop = 0;
              iWidth = desc.Width;
              iHeight = desc.Height;
            }
            else
            {
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->CreateImageSurface(iWidth, iHeight, desc.Format, &m_lpSurface)))
            {
              SAFE_RELEASE(lpSurfaceFront);
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            //copy part underneeth busy dialog
            const RECT rc = { iLeft, iTop, iLeft + iWidth, iTop + iHeight  };
            const RECT rcDest = { 0, 0, iWidth, iHeight  };
            if (!CopySurface(lpSurfaceFront, &rc, m_lpSurface, &rcDest))
            {
                SAFE_RELEASE(lpSurfaceFront);
                SAFE_RELEASE(m_lpSurface);
                lockg.Leave();
                Sleep(1000);
                continue;
            }

            //copy front buffer to backbuffer(s) to avoid jumping
            bool bBufferCopied = true;
            for (int i = 0; i < g_graphicsContext.GetBackbufferCount(); i++)
            {
              if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( i, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack)))
              {
                bBufferCopied = false;
                break;
              }
              if (!CopySurface(lpSurfaceFront, NULL, lpSurfaceBack, NULL))
              {
                bBufferCopied = false;
                break;
              }
              SAFE_RELEASE(lpSurfaceBack);
            }
            if (!bBufferCopied)
            {
              SAFE_RELEASE(lpSurfaceFront);
              SAFE_RELEASE(lpSurfaceBack);
              SAFE_RELEASE(m_lpSurface);
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            SAFE_RELEASE(lpSurfaceFront);
          }
          if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack)))
          {
              lockg.Leave();
              Sleep(1000);
              continue;
          }
          g_graphicsContext.Get3DDevice()->BeginScene();
          //copy dialog background to backbuffer
          const RECT rc = { 0, 0, iWidth, iHeight };
          const RECT rcDest = { iLeft, iTop, iLeft + iWidth, iTop + iHeight };
          const D3DRECT rc2 = { iLeft, iTop, iLeft + iWidth, iTop + iHeight };
          g_graphicsContext.Get3DDevice()->Clear(1, &rc2, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00010001, 1.0f, 0L);
          if (!CopySurface(m_lpSurface, &rc, lpSurfaceBack, &rcDest))
          {
              SAFE_RELEASE(lpSurfaceBack);
              g_graphicsContext.Get3DDevice()->EndScene();
              lockg.Leave();
              Sleep(1000);
              continue;
          }
          SAFE_RELEASE(lpSurfaceBack);
          if (!m_busyShown)
          {
            m_pWindow->Show();
            m_busyShown = true;
          }
          m_pWindow->Render();

          g_graphicsContext.Get3DDevice()->EndScene();
          //D3DSWAPEFFECT_DISCARD is used so we can't just present the busy rect but can only present the entire screen.
          g_graphicsContext.Get3DDevice()->Present( NULL, NULL, NULL, NULL );
        }
        m_busycount++;
        m_prevbusycount = m_busycount;
      }
      catch (...)
      {
        CLog::Log(LOGERROR, __FUNCTION__" - Exception caught when  busy rendering");
        SAFE_RELEASE(lpSurfaceFront);
        SAFE_RELEASE(lpSurfaceBack);
        SAFE_RELEASE(m_lpSurface);
      }
    }
    Sleep(1);
  }
#endif
}
Exemple #16
0
//-----------------------------------------------------------------------------
// Name: XBUtil_CreateNormalizationCubeMap()
// Desc: Creates a cubemap and fills it with normalized RGBA vectors
//-----------------------------------------------------------------------------
HRESULT XBUtil_CreateNormalizationCubeMap( LPDIRECT3DDEVICE8 pd3dDevice, 
                                           DWORD dwSize, 
                                           LPDIRECT3DCUBETEXTURE8* ppCubeMap )
{
    HRESULT hr;

    // Create the cube map
    if( FAILED( hr = pd3dDevice->CreateCubeTexture( dwSize, 1, 0, D3DFMT_X8R8G8B8, 
                                                    D3DPOOL_DEFAULT, ppCubeMap ) ) )
        return E_FAIL;
    
    // Allocate temp space for swizzling the cubemap surfaces
    DWORD* pSourceBits = new DWORD[ dwSize * dwSize ];

    // Fill all six sides of the cubemap
    for( DWORD i=0; i<6; i++ )
    {
        // Lock the i'th cubemap surface
        LPDIRECT3DSURFACE8 pCubeMapFace;
        (*ppCubeMap)->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pCubeMapFace );

        // Write the RGBA-encoded normals to the surface pixels
        DWORD*      pPixel = pSourceBits;
        D3DXVECTOR3 n;
        FLOAT       w, h;

        for( DWORD y = 0; y < dwSize; y++ )
        {
            h  = (FLOAT)y / (FLOAT)(dwSize-1);  // 0 to 1
            h  = ( h * 2.0f ) - 1.0f;           // -1 to 1
            
            for( DWORD x = 0; x < dwSize; x++ )
            {
                w = (FLOAT)x / (FLOAT)(dwSize-1);   // 0 to 1
                w = ( w * 2.0f ) - 1.0f;            // -1 to 1

                // Calc the normal for this texel
                switch( i )
                {
                    case D3DCUBEMAP_FACE_POSITIVE_X:    // +x
                        n.x = +1.0;
                        n.y = -h;
                        n.z = -w;
                        break;
                        
                    case D3DCUBEMAP_FACE_NEGATIVE_X:    // -x
                        n.x = -1.0;
                        n.y = -h;
                        n.z = +w;
                        break;
                        
                    case D3DCUBEMAP_FACE_POSITIVE_Y:    // y
                        n.x = +w;
                        n.y = +1.0;
                        n.z = +h;
                        break;
                        
                    case D3DCUBEMAP_FACE_NEGATIVE_Y:    // -y
                        n.x = +w;
                        n.y = -1.0;
                        n.z = -h;
                        break;
                        
                    case D3DCUBEMAP_FACE_POSITIVE_Z:    // +z
                        n.x = +w;
                        n.y = -h;
                        n.z = +1.0;
                        break;
                        
                    case D3DCUBEMAP_FACE_NEGATIVE_Z:    // -z
                        n.x = -w;
                        n.y = -h;
                        n.z = -1.0;
                        break;
                }

                // Store the normal as an RGBA color
                D3DXVec3Normalize( &n, &n );
                *pPixel++ = XBUtil_VectorToRGBA( &n );
            }
        }
        
        // Swizzle the result into the cubemap face surface
        D3DLOCKED_RECT lock;
        pCubeMapFace->LockRect( &lock, 0, 0L );
        XGSwizzleRect( pSourceBits, 0, NULL, lock.pBits, dwSize, dwSize,
                       NULL, sizeof(DWORD) );
        pCubeMapFace->UnlockRect();

        // Release the cubemap face
        pCubeMapFace->Release();
    }

    // Free temp space
    SAFE_DELETE_ARRAY( pSourceBits );

    return S_OK;
}
Exemple #17
0
// only works for gifs or other 256-colour anims
void ConvertAnim(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, ' ');

	// Load up the file
	CAnimatedGifSet Anim;
	int nImages = Anim.LoadGIF(Filename);
	if (!nImages)
	{
		puts("ERROR: Unable to load gif (file corrupt?)");
		return;
	}
	if (nImages > 65535)
	{
		printf("ERROR: Too many frames in gif (%d > 65535)\n", nImages);
		return;
	}

	PrintAnimInfo(Anim);

	UINT Width = PadPow2(Anim.FrameWidth);
	UINT Height = PadPow2(Anim.FrameHeight);

	D3DXIMAGE_INFO info;
	info.Width = Anim.FrameWidth;
	info.Height = Anim.FrameHeight;
	info.MipLevels = 1;
	info.Depth = 0;
	info.ResourceType = D3DRTYPE_SURFACE;
	info.Format = D3DFMT_P8;
	info.ImageFileFormat = D3DXIFF_PNG;

	PALETTEENTRY pal[256];
	memcpy(pal, Anim.m_vecimg[0]->Palette, 256 * sizeof(PALETTEENTRY));
	for (int i = 0; i < 256; i++)
		pal[i].peFlags = 0xff; // alpha
	if (Anim.m_vecimg[0]->Transparency && Anim.m_vecimg[0]->Transparent >= 0)
		memset(&pal[Anim.m_vecimg[0]->Transparent], 0, sizeof(PALETTEENTRY));

	// setup xpr header
	WriteXPRHeader((DWORD*)pal, nImages);
	if (nImages > 1)
	{
		XPRFile.AnimInfo->RealSize = (info.Width & 0xffff) | ((info.Height & 0xffff) << 16);
		XPRFile.AnimInfo->nLoops = Anim.nLoops;
	}

	int nActualImages = 0;

	TotalSrcPixels += info.Width * info.Height * nImages;
	TotalDstPixels += Width * Height * nImages;
	float Waste = 100.f * (float)(Width * Height - info.Width * info.Height) / (float)(Width * Height);

	// alloc hash buffer
	BYTE (*HashBuf)[20] = new BYTE[nImages][20];

	for (int i = 0; i < nImages; ++i)
	{
		if (pSrcSurf)
			pSrcSurf->Release();
		pSrcSurf = NULL;

		printf("%3d%%\b\b\b\b", 100 * i / nImages);

		UncompressedSize += Width * Height;
		CAnimatedGif* pGif = Anim.m_vecimg[i];

		if (nImages > 1)
			XPRFile.Texture[i].RealSize = pGif->Delay;

		// generate sha1 hash
		SHA1((BYTE*)pGif->Raster, pGif->BytesPerRow * pGif->Height, HashBuf[i]);

		// duplicate scan
		int j;
		for (j = 0; j < i; ++j)
		{
			if (!memcmp(HashBuf[j], HashBuf[i], 20))
			{
				// duplicate image!
				TRACE2(" %03d: Duplicate of %03d\n", i, j);
				AppendXPRImageLink(j);
				break;
			}
		}
		if (j < i)
			continue;

		++nActualImages;

		// DXT1 for P8s if lossless
		hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pSrcSurf);
		CheckHR(hr);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		CheckHR(hr);

		BYTE* src = (BYTE*)pGif->Raster;
		DWORD* dst = (DWORD*)slr.pBits;
		DWORD* dwPal = (DWORD*)pal;
		for (int y = 0; y < pGif->Height; ++y)
		{
			for (UINT x = 0; x < Width; ++x)
				*dst++ = dwPal[*src++];
		}
		memset(dst, 0, (Height - pGif->Height) * slr.Pitch);

		pSrcSurf->UnlockRect();

		double CMSE, AMSE;
		TRACE1(" %03d: Checking DXT1: ", i);
		if (!GetFormatMSE(info, pSrcSurf, D3DFMT_DXT1, CMSE, AMSE))
			return;
		TRACE2("CMSE=%05.2f, AMSE=%07.2f\n", CMSE, AMSE);
		
		if (CMSE <= 1e-6 && AMSE <= 1e-6)
		{
			TRACE1(" %03d: Selected Format: DXT1\n", i);
			AppendXPRImage(info, pSrcSurf, XB_D3DFMT_DXT1);
		}
		else
		{	
			pSrcSurf->Release();

			hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_P8, &pSrcSurf);
			CheckHR(hr);

			hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
			CheckHR(hr);

			memcpy((BYTE*)slr.pBits, pGif->Raster, pGif->Height * slr.Pitch);
			memset((BYTE*)slr.pBits + pGif->Height * slr.Pitch, pGif->Transparent, (Height - pGif->Height) * slr.Pitch);

			pSrcSurf->UnlockRect();

			TRACE1(" %03d: Selected Format: P8\n", i);
			AppendXPRImage(info, pSrcSurf, XB_D3DFMT_P8);
		}
	}

	delete [] HashBuf;
	
	printf("(%5df) %4dx%-4d (%5.2f%% waste)\n", nActualImages, Width, Height, Waste);

	CommitXPR(OutFilename);
	if (pSrcSurf)
		pSrcSurf->Release();
}
Exemple #18
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();
}
Exemple #19
0
// Converts to P8 format is colours <= 256
bool ConvertP8(LPDIRECT3DSURFACE8 pSrcSurf, LPDIRECT3DSURFACE8& pDstSurf, DWORD* pal, D3DXIMAGE_INFO &info)
{
	pDstSurf = 0;

	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	// convert to p8
  UINT Width = PadPow2(desc.Width);
  UINT Height = PadPow2(desc.Height);
	HRESULT hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf);
	CheckHR(hr);

	D3DLOCKED_RECT slr, dlr;
	hr = pDstSurf->LockRect(&dlr, NULL, 0);
	CheckHR(hr);
	hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);

	DWORD* src = (DWORD*)slr.pBits;
	BYTE* dst = (BYTE*)dlr.pBits;
	int n = 0, i;
	for (UINT y = 0; y < info.Height; ++y)
	{
		for (UINT x = 0; x < info.Width; ++x)
		{
			for (i = 0; i < n; ++i)
			{
				if (pal[i] == *src)
					break;
			}
			if (i == n)
			{
				if (n >= 256)
				{
					TRACE0(" Too many colours for P8\n");
					pSrcSurf->UnlockRect();
					pDstSurf->UnlockRect();
					pDstSurf->Release();
					return false;
				}
				pal[n++] = *src;
			}
			*dst++ = i;
			++src;
		}
		for (UINT x = info.Width; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
	}
  for (UINT y = info.Height; y < Height; ++y)
  {
		for (UINT x = 0; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
  }
	TRACE1(" Colours Used: %d\n", n);

	pDstSurf->UnlockRect();
	pSrcSurf->UnlockRect();

	return true;
}
Exemple #20
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;
}
Exemple #21
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;
}
Exemple #22
0
HANDLE CScreenshot::CreateDibFromCurrentSurface()
{
	LPDIRECT3DSURFACE8		pSurface = 0;
    LPDIRECT3D8				pD3D = 0;
    BYTE					*pbyteDibBuffer = 0;

    D3DDEVICE_CREATION_PARAMETERS dcp;

    dcp.AdapterOrdinal = D3DADAPTER_DEFAULT;
    m_pD3DDevice->GetCreationParameters(&dcp);

    D3DDISPLAYMODE dm;
    dm.Width = dm.Height = 0;

    m_pD3DDevice->GetDirect3D(&pD3D);
    if(pD3D) {   
		// get the current screen dimensions
        pD3D->GetAdapterDisplayMode(dcp.AdapterOrdinal, &dm);
        SAFERELEASE(pD3D);
    }
	else {
		return NULL;
	}
	
	// Grab the ARBG surface.
    m_pD3DDevice->CreateImageSurface(dm.Width,dm.Height,D3DFMT_A8R8G8B8,&pSurface);
	m_pD3DDevice->GetFrontBuffer(pSurface);

    // Setup the dib header.
    BITMAPINFOHEADER bmih;
    bmih.biSize = sizeof(bmih);
    bmih.biWidth = dm.Width;
    bmih.biHeight = dm.Height;
    bmih.biPlanes = 1;
    bmih.biBitCount = 24;
    bmih.biCompression = BI_RGB;
    bmih.biSizeImage = dm.Width * dm.Height * 3;
    bmih.biXPelsPerMeter = 0;
    bmih.biYPelsPerMeter = 0;
    bmih.biClrUsed = 0;
    bmih.biClrImportant = 0;

   	pbyteDibBuffer = (PBYTE)calloc((bmih.biSizeImage+sizeof(BITMAPINFOHEADER)+1),1);
    if(!pbyteDibBuffer) return NULL;

	// Lock the surface.
    D3DLOCKED_RECT LockedRect;
    pSurface->LockRect(&LockedRect,NULL,D3DLOCK_READONLY);
	
	// Copy the bitmap info header into the dib buffer.
    memcpy(pbyteDibBuffer,&bmih,sizeof(BITMAPINFOHEADER));

    PDWORD lpSrc;
    PBYTE lpDest = pbyteDibBuffer+sizeof(BITMAPINFOHEADER);

    for(int y = dm.Height - 1; y >= 0; y--) 
	{
        lpSrc = (PDWORD)(LockedRect.pBits) + y * dm.Width;
		for(int x = 0; x < (signed)dm.Width; x++) 
		{
			// Store the pixels
            *(DWORD *)(lpDest) = *lpSrc;
            lpSrc++;
            lpDest += 3;
        }
    }

    // we can unlock and release the surface
    pSurface->UnlockRect();
    SAFERELEASE(pSurface);

	return pbyteDibBuffer;
}
Exemple #23
0
//-----------------------------------------------------------------------------
// Name: XBUtil_DumpSurface()
// Desc: Writes the contents of a surface (32-bit only) to a .tga file. This
//       could be a backbuffer, texture, or any other 32-bit surface.
//-----------------------------------------------------------------------------
HRESULT XBUtil_DumpSurface( LPDIRECT3DSURFACE8 pSurface, const CHAR* strFileName,
                            BOOL bSurfaceIsTiled )
{
    // Get the surface description. Make sure it's a 32-bit format
    D3DSURFACE_DESC desc;
    pSurface->GetDesc( &desc );
    if( desc.Size != ( desc.Width * desc.Height * sizeof(DWORD) ) )
        return E_NOTIMPL;

    // Lock the surface
    D3DLOCKED_RECT lock;
    if( FAILED( pSurface->LockRect( &lock, 0, bSurfaceIsTiled ? D3DLOCK_TILED : 0 ) ) )
        return E_FAIL;

    // Allocate memory for storing the surface bits
    VOID* pBits = (VOID*)new DWORD[desc.Width*desc.Height];

    // Unswizzle the bits, if necessary
    if( XGIsSwizzledFormat( desc.Format ) )
        XGUnswizzleRect( lock.pBits, desc.Width, desc.Height, NULL,
                         pBits, lock.Pitch, NULL, sizeof(DWORD) );
    else
        memcpy( pBits, lock.pBits, desc.Size );
    
    // Unlock the surface
    pSurface->UnlockRect();

    // Setup the TGA file header
    struct TargaHeader
    {
        BYTE IDLength;
        BYTE ColormapType;
        BYTE ImageType;
        BYTE ColormapSpecification[5];
        WORD XOrigin;
        WORD YOrigin;
        WORD ImageWidth;
        WORD ImageHeight;
        BYTE PixelDepth;
        BYTE ImageDescriptor;
    } tgaHeader;

    ZeroMemory( &tgaHeader, sizeof(tgaHeader) );
    tgaHeader.IDLength        = 0;
    tgaHeader.ImageType       = 2;
    tgaHeader.ImageWidth      = (WORD)desc.Width;
    tgaHeader.ImageHeight     = (WORD)desc.Height;
    tgaHeader.PixelDepth      = 32;
    tgaHeader.ImageDescriptor = 0x28;

    // Create a new file
    FILE* file = fopen( strFileName, "wb" );
    if( NULL == file )
    {
        pSurface->UnlockRect();
        return E_FAIL;
    }

    // Write the Targa header and the surface pixels to the file
    fwrite( &tgaHeader, sizeof(TargaHeader), 1, file );
    fwrite( pBits, sizeof(BYTE), desc.Size, file );
    fclose( file );

    // Cleanup and return
    delete[] pBits;

    return S_OK;
}