Пример #1
0
static bool convert_compressed(LPDIRECT3DTEXTURE9 dest, LPDIRECT3DTEXTURE9 src,
   int x, int y, int width, int height) {
#ifdef ALLEGRO_CFG_D3DX9
   bool ok = true;
   LPDIRECT3DSURFACE9 dest_texture_surface = NULL;
   LPDIRECT3DSURFACE9 src_texture_surface = NULL;

   if (dest->GetSurfaceLevel(0, &dest_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("convert_compressed: GetSurfaceLevel failed on dest.\n");
      ok = false;
   }

   if (ok && src->GetSurfaceLevel(0, &src_texture_surface) != D3D_OK) {
      ALLEGRO_ERROR("convert_compressed: GetSurfaceLevel failed on src.\n");
      ok = false;
   }

   RECT rect;
   rect.left = x;
   rect.top = y;
   rect.right = x + width;
   rect.bottom = y + height;

   if (ok && _al_imp_D3DXLoadSurfaceFromSurface &&
       _al_imp_D3DXLoadSurfaceFromSurface(dest_texture_surface,
                                          NULL,
                                          &rect,
                                          src_texture_surface,
                                          NULL,
                                          &rect,
                                          D3DX_FILTER_NONE,
                                          0) != D3D_OK) {
      ALLEGRO_ERROR("convert_compressed: D3DXLoadSurfaceFromSurface failed.\n");
      ok = false;
   }

   int i;
   if (src_texture_surface) {
       if ((i = src_texture_surface->Release()) != 0) {
          ALLEGRO_DEBUG("convert_compressed (src) ref count == %d\n", i);
       }
   }
   if (dest_texture_surface) {
       if ((i = dest_texture_surface->Release()) != 0) {
          // This can be non-zero
          ALLEGRO_DEBUG("convert_compressed (dest) ref count == %d\n", i);
       }
   }
   return ok;
#else
   (void)dest;
   (void)src;
   (void)x;
   (void)y;
   (void)width;
   (void)height;
   return false;
#endif
}
Пример #2
0
void InitStateDX9(void)
{
	// 取得Direct3D 9裝置
	LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9();

	// 關閉打光
	device->SetRenderState(D3DRS_LIGHTING, FALSE);
	// 使用trilinear
	device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
	//
	device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	//
	device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);

	device->GetRenderTarget(0, &g_pMainFrameBuffer);
	device->GetDepthStencilSurface(&g_pMainDepthBuffer);

	int width, height;
	GutGetWindowSize(width, height);

	g_iFrameBufferWidth = width * 2;
	g_iFrameBufferHeight = height * 2;

	device->CreateTexture(g_iFrameBufferWidth, g_iFrameBufferHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pTexture, NULL);
	device->CreateDepthStencilSurface(g_iFrameBufferWidth, g_iFrameBufferHeight, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pDepthStencil, NULL);
	g_pTexture->GetSurfaceLevel(0, &g_pFrameBuffer);
}
Пример #3
0
int RendererD3D::InitializeTextureFromBits(byte* pImageBits, int width, int height)
{
	HRESULT result;

	LPDIRECT3DSURFACE9 surface=NULL;
	LPDIRECT3DTEXTURE9 texture = NULL;
	
	result = D3DXCreateTexture( m_pd3dDevice, width, height, D3DX_DEFAULT, 0, D3DFMT_R8G8B8,D3DPOOL_MANAGED, &texture);

	texture->GetSurfaceLevel(0, &surface);

	RECT rect;
	rect.top = 0;
	rect.left = 0;
	rect.bottom = height;
	rect.right = width;

	result = D3DXLoadSurfaceFromMemory(surface,NULL,NULL,pImageBits,D3DFMT_R8G8B8, width*3*sizeof(byte),NULL,&rect,D3DX_DEFAULT,0);

	surface->Release();

	assert(result == D3D_OK);

	m_textureList.push_back(texture);
	return (m_textureList.size()-1);
}	
Пример #4
0
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D(HWND hWnd)
{
	//创建Direct3D对象, 该对象用于创建Direct3D设备对象
	if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
		return E_FAIL;

	//设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

	//创建Direct3D设备对象
	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, &g_pd3dDevice)))
	{
		return E_FAIL;
	}

	//禁用照明效果
	g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

	HRESULT hr = g_pd3dDevice->CreateTexture(256, 256, 1, D3DUSAGE_RENDERTARGET,
		D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pRenderTex, NULL);
	if (FAILED(hr))
	{
		return E_FAIL;
	}
	g_pRenderTex->GetSurfaceLevel(0, &g_pRenderSur);

	hr = g_pd3dDevice->CreateTexture(256, 256, 1, D3DUSAGE_RENDERTARGET,
		D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pRender2Tex, NULL);
	if (FAILED(hr))
	{
		return E_FAIL;
	}
	g_pRender2Tex->GetSurfaceLevel(0, &g_pRender2Sur);

	return S_OK;
}
Пример #5
0
//*************************************************************************************************************
void BlurTexture(LPDIRECT3DTEXTURE9 tex)
{
	LPDIRECT3DSURFACE9 surface = NULL;
	LPDIRECT3DSURFACE9 blursurface = NULL;
	LPDIRECT3DTEXTURE9 blurtex = NULL;

	D3DXVECTOR4 texelsize(1.0f / SHADOWMAP_SIZE, 0, 0, 0);
	D3DSURFACE_DESC desc;

	tex->GetLevelDesc(0, &desc);

	if( desc.Format == D3DFMT_A8R8G8B8 )
		blurtex = blurARGB8; // for convolution
	else
		blurtex = blurRGBA32F; // for others

	blurtex->GetSurfaceLevel(0, &blursurface);
	tex->GetSurfaceLevel(0, &surface);

	device->SetRenderTarget(0, blursurface);
	device->SetTexture(0, tex);
	device->SetVertexDeclaration(vertexdecl);

	boxblur5x5->SetVector("texelSize", &texelsize);

	boxblur5x5->Begin(NULL, 0);
	boxblur5x5->BeginPass(0);
	{
		device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float));
		std::swap(texelsize.x, texelsize.y);

		boxblur5x5->SetVector("texelSize", &texelsize);
		boxblur5x5->CommitChanges();

		device->SetRenderTarget(0, surface);
		device->SetTexture(0, blurtex);
		device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &vertices[0], 6 * sizeof(float));
	}
	boxblur5x5->EndPass();
	boxblur5x5->End();

	surface->Release();
	blursurface->Release();
}
Пример #6
0
HRESULT InitScene()
{
	HRESULT hr;
	LPD3DXBUFFER errors = NULL;

	D3DVERTEXELEMENT9 decl[] =
	{
		{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
		{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()
	};

	SetWindowText(hwnd, TITLE);

	MYVALID(CreateColorTex(device, 0xff77FF70, &texture));
	MYVALID(D3DXLoadMeshFromXA("../media/meshes/knot.X", D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &mesh));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/intensity.png", &intensity));

	MYVALID(device->CreateTexture(screenwidth, screenheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &colortarget, NULL));
	MYVALID(device->CreateTexture(screenwidth, screenheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &normaltarget, NULL));
	MYVALID(device->CreateTexture(screenwidth, screenheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &edgetarget, NULL));
	MYVALID(device->CreateVertexDeclaration(decl, &vertexdecl));

	edgetarget->GetSurfaceLevel(0, &edgesurface);
	colortarget->GetSurfaceLevel(0, &colorsurface);
	normaltarget->GetSurfaceLevel(0, &normalsurface);

	MYVALID(device->CreateTexture(512, 512, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &text, NULL));
	MYVALID(DXCreateEffect("../media/shaders/celshading.fx", device, &effect));

	DXRenderText(HELP_TEXT, text, 512, 512);

	D3DXVECTOR3 eye(0.5f, 0.5f, -1.5f);
	D3DXVECTOR3 look(0, 0, 0);
	D3DXVECTOR3 up(0, 1, 0);

	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 3, (float)screenwidth / (float)screenheight, 0.1f, 10);
	D3DXMatrixLookAtLH(&view, &eye, &look, &up);
	D3DXMatrixIdentity(&world);

	return S_OK;
}
Пример #7
0
void SetD3DResourcePrivateData(LPDIRECT3DRESOURCE9 res, const char* FName)
{
#if R3D_SET_DEBUG_D3D_NAMES

	DWORD sz = strlen(FName);
	res->SetPrivateData(WKPDID_D3DDebugObjectName, FName, sz, 0);

	void* p = 0;

	res->QueryInterface(IID_IDirect3DTexture9, &p);
	if(p)
	{
		LPDIRECT3DTEXTURE9 t = (LPDIRECT3DTEXTURE9)p;
		int mipsCount = t->GetLevelCount();

		for (int i = 0; i < mipsCount; ++i)
		{
			LPDIRECT3DSURFACE9 surf; 
			t->GetSurfaceLevel(i, &surf);
			surf->SetPrivateData(WKPDID_D3DDebugObjectName, FName, sz, 0);
			surf->Release();
		}

		t->Release();
		return;
	}

	p = 0;
	res->QueryInterface(IID_IDirect3DCubeTexture9, &p);
	if(p)
	{
		LPDIRECT3DCUBETEXTURE9 t = (LPDIRECT3DCUBETEXTURE9)p;
		int mipsCount = t->GetLevelCount();

		for (int i = 0; i < mipsCount; ++i)
		{
			for (int j = D3DCUBEMAP_FACE_POSITIVE_X; j <= D3DCUBEMAP_FACE_NEGATIVE_Z; ++j)
			{
				LPDIRECT3DSURFACE9 surf; 
				t->GetCubeMapSurface((D3DCUBEMAP_FACES)j, i, &surf);
				surf->SetPrivateData(WKPDID_D3DDebugObjectName, FName, sz, 0);
				surf->Release();
			}
		}

		t->Release();

		return;
	}

#endif
}
Пример #8
0
void AmjuGLDX9::SetTexture(
  AmjuGL::TextureHandle* th, 
  AmjuGL::TextureType tt, 
  AmjuGL::TextureDepth td,  
  int width, 
  int height, 
  uint8* data)
{
  AMJU_CALL_STACK;

  HRESULT res = D3DXCreateTexture(
    dd, //LPDIRECT3DDEVICE9 pDevice,
    width, //UINT Width,
    height, //UINT Height,
    0, //  Mip Levels: 0 means create all
    D3DUSAGE_DYNAMIC, //DWORD Usage,
    (td == AmjuGL::AMJU_RGB ? D3DFMT_R8G8B8 : D3DFMT_A8R8G8B8), //D3DFORMAT Format,
    D3DPOOL_DEFAULT, // Pool,
    reinterpret_cast<LPDIRECT3DTEXTURE9*>(th) //LPDIRECT3DTEXTURE9 * ppTexture
  );

  LPDIRECT3DTEXTURE9 pTex = reinterpret_cast<LPDIRECT3DTEXTURE9>(*th);

  D3DLOCKED_RECT lockedRect;
  pTex->LockRect(0, &lockedRect, NULL, 0);

  switch (td)
  {
  case AmjuGL::AMJU_RGB:
    CopyRGBTexture((uint8*)lockedRect.pBits, lockedRect.Pitch, data, width, height); 
    break;
  case AmjuGL::AMJU_RGBA:
    CopyRGBATexture((uint8*)lockedRect.pBits, lockedRect.Pitch, data, width, height); 
    break;
  }

  pTex->UnlockRect(0);

  // TODO Create data for each mipmap level.
  // NB We want the same functionality as screenshot shrinking.
  IDirect3DSurface9 * pSurfaceLevel;
  for (unsigned int iLevel = 0; iLevel < pTex->GetLevelCount(); iLevel++)
  {
    pTex->GetSurfaceLevel(iLevel, &pSurfaceLevel);

    // TODO Write this mip map
    
    pSurfaceLevel->Release();
  }
}
Пример #9
0
int surface_create(int width, int height, bool depthbuffer, bool, bool)
{
  LPDIRECT3DTEXTURE9 texture = NULL;
  d3ddev->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
  enigma::Surface* surface = new enigma::Surface();
  enigma::DX9Texture* gmTexture = new enigma::DX9Texture(texture);
  const int texid = enigma::textures.size();
  enigma::textures.push_back(gmTexture);
  //d3ddev->CreateRenderTarget(width, height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 2, false, &surface->surf, NULL);
  texture->GetSurfaceLevel(0,&surface->surf);
  surface->texture = texid; surface->width = width; surface->height = height;
  enigma::surfaces.push_back(surface);
  return enigma::surfaces.size() - 1;
}
Пример #10
0
HRESULT VertexObject::CreateTextureFromSurface(LPDIRECT3DSURFACE9 pSurface, RECT* pSrcRect, RECT* pDestRect, LPDIRECT3DTEXTURE9* ppTexture)
{
	int width, height;
	RECT Src;
	D3DSURFACE_DESC surfDesc;
	pSurface->GetDesc(&surfDesc);

	if( !pSrcRect )
	{
		width = surfDesc.Width;
		height = surfDesc.Height;
		Src.left = Src.top = 0;
		Src.right = width;
		Src.bottom = height;
	}
	else
	{
		width = pSrcRect->right - pSrcRect->left; // + 1;
		height = pSrcRect->bottom - pSrcRect->top; // + 1;
		Src = *pSrcRect;
	}

	D3DXCreateTexture(DDevice, width, height, 
	1, 0, surfDesc.Format, D3DPOOL_DEFAULT, ppTexture) ;

	// Retrieve the surface image of the texture.
	LPDIRECT3DSURFACE9 pTexSurface;
	LPDIRECT3DTEXTURE9 pTexture = *ppTexture;
	pTexture->GetLevelDesc(0, &surfDesc);
	pTexture->GetSurfaceLevel(0, &pTexSurface);

	// Create a clean surface to clear the texture with.
	LPDIRECT3DSURFACE9 pCleanSurface;
	D3DLOCKED_RECT lockRect;
	DDevice->CreateOffscreenPlainSurface(
	surfDesc.Width, surfDesc.Height, surfDesc.Format, D3DPOOL_DEFAULT, &pCleanSurface, NULL);
	pCleanSurface->LockRect(&lockRect, NULL, 0) ;
	memset((BYTE*)lockRect.pBits, 0, surfDesc.Height * lockRect.Pitch);
	pCleanSurface->UnlockRect() ;

	DDevice->UpdateSurface(pCleanSurface, NULL, pTexSurface, NULL);
	pCleanSurface->Release();

	// Copy the image to the texture.
	POINT destPoint = { 0, 0 };
	DDevice->UpdateSurface(pSurface, &Src, pTexSurface, &destPoint);
	pTexSurface->Release();

	return S_OK;
}
//-- SetRenderTarget ----------------------------------------------------------
//
//-----------------------------------------------------------------------------
void Renderer::SetRenderTarget( LPDIRECT3DTEXTURE9 texture )
{
	IDirect3DSurface9* surface;
	texture->GetSurfaceLevel( 0, &surface );

	m_pD3DDevice->SetRenderTarget( 0, surface );
	m_pD3DDevice->SetDepthStencilSurface( g_depthBuffer );
	m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0, 1.0f, 0 );

	surface->Release();

	//	m_renderTargetWidth = texture->Width();
	//	m_renderTargetHeight = texture->Height();

} // SetRenderTarget
Пример #12
0
	virtual const char* lock_framebuffer( void *& buffer, unsigned & pitch )
	{
		if ( retry_count && !restore_objects() ) return "Lock failed";

		lptex->GetLevelDesc(0, &d3dsd);
		if ( lptex->GetSurfaceLevel(0, &lpsurface) != D3D_OK )
			return "Lock failed";

		if ( lpsurface->LockRect(&d3dlr, 0, flags.lock) != D3D_OK )
			return "Lock failed";
		buffer = d3dlr.pBits;
		pitch = d3dlr.Pitch;

		return buffer != 0 ? 0 : "Lock failed";
	}
Пример #13
0
bool CAnimationSpooler::SetColorKey(LPDIRECT3DTEXTURE9 pTexture, LPDIRECT3DSURFACE9 pSurface, int iTexSize, COLORREF clrColorKey)
{
   ASSERT(pTexture);
   ASSERT(pSurface);

   if( clrColorKey == CLR_INVALID ) return true;

   // Get colorkey's red, green, and blue components
   // and put the colorkey in the texture's native format
   DWORD r = GetRValue(clrColorKey);
   DWORD g = GetGValue(clrColorKey);
   DWORD b = GetBValue(clrColorKey);
   DWORD dwColorKey = D3DCOLOR_ARGB(255,r,g,b);

   HRESULT Hr;
   LPDIRECT3DTEXTURE9 pTex = NULL;
   Hr = m_p3DDevice->CreateTexture(iTexSize, iTexSize, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTex, NULL);
   if( FAILED(Hr) ) return false;
   CSafeRelease<IDirect3DTexture9> RefTex = pTex;
   LPDIRECT3DSURFACE9 pTexSurf = NULL;
   Hr = pTex->GetSurfaceLevel(0, &pTexSurf);
   if( FAILED(Hr) ) return false;
   CSafeRelease<IDirect3DSurface9> RefTexSurf = pTexSurf;
   Hr = m_p3DDevice->GetRenderTargetData(pSurface, pTexSurf);
   if( FAILED(Hr) ) return false;

   // Lock the texture and scan through each pixel, replacing the colorkey pixels
   D3DLOCKED_RECT d3dlr;
   Hr = pTex->LockRect(0, &d3dlr, 0, 0);
   if( FAILED(Hr) ) return false;
   DWORD* pBits = static_cast<DWORD*>(d3dlr.pBits);
   for( int y = 0; y < iTexSize; y++ ) {
      for( int x = 0; x < iTexSize; x++ ) {
         if( pBits[x] == dwColorKey ) pBits[x] = 0x00000000;
         else pBits[x] |= 0xff000000;
      }
      pBits += d3dlr.Pitch / sizeof(DWORD);
   }
   pTex->UnlockRect(0);

   // Copy modified data back
   POINT pt = { 0, 0 };
   RECT rcDest = { 0, 0, iTexSize, iTexSize };
   Hr = m_p3DDevice->UpdateSurface(pTexSurf, &rcDest, pSurface, &pt);

   return true;
}
Пример #14
0
void cTexture::BltToTextureSurface(LPDIRECT3DTEXTURE9 pTempTex )
{

	SafeRelease( m_pTexture );

	D3DSURFACE_DESC TexDesc;

	pTempTex->GetLevelDesc( 0, &TexDesc );
	DWORD NumLevels = pTempTex->GetLevelCount();
	
	D3DXCreateTexture( 
		Graphics()->GetDevice(),
		TexDesc.Width,
		TexDesc.Height,
		NumLevels,
		0,
		TexDesc.Format,
		D3DPOOL_MANAGED,
		&m_pTexture );

	LPDIRECT3DSURFACE9 pSrcSurf = 0;
	LPDIRECT3DSURFACE9 pDestSurf = 0;

	for( int i = 0 ; i < NumLevels ; i++ )
	{
		m_pTexture->GetSurfaceLevel( i, &pDestSurf );
		pTempTex->GetSurfaceLevel( i, &pSrcSurf );

		D3DXLoadSurfaceFromSurface( 
			pDestSurf,
			0,
			0,
			pSrcSurf,
			0,
			0,
			D3DX_FILTER_NONE,
			0 );

		pDestSurf->Release();
		pSrcSurf->Release();
	}

}
Пример #15
0
	virtual void clear()
	{
		if ( retry_count && !restore_objects() ) return;

		lptex->GetLevelDesc(0, &d3dsd);
		lptex->GetSurfaceLevel(0, &lpsurface);

		if ( lpsurface )
		{
			lpdev->ColorFill( lpsurface, NULL, D3DCOLOR_XRGB(0x00, 0x00, 0x00) );
			lpsurface->Release();
			lpsurface = 0;
		}

		for ( unsigned i = 0; i < 3; i++ )
		{
			lpdev->Clear( 0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0x00, 0x00, 0x00), 1.0f, 0 );
			lpdev->Present( 0, 0, 0, 0 );
		}
	}
Пример #16
0
	virtual void OnDistorting()
	{
		IDirect3DSurface9* targetSurface = nullptr;
		IDirect3DSurface9* texSurface = nullptr;
		HRESULT hr = S_OK;

		hr = texture->GetSurfaceLevel( 0, &texSurface );
		assert(SUCCEEDED(hr));

		hr = device->GetRenderTarget( 0, &targetSurface );
		assert(SUCCEEDED(hr));

		hr = device->StretchRect( targetSurface, NULL, texSurface, NULL, D3DTEXF_NONE);
		assert(SUCCEEDED(hr));
		
		ES_SAFE_RELEASE( texSurface );
		ES_SAFE_RELEASE( targetSurface );

		renderer->SetBackground( texture );
	}
Пример #17
0
HRESULT CDxtexDoc::LoadAlphaBmp(CString& strPath)
{
    HRESULT hr;
    LPDIRECT3DTEXTURE9 pmiptex;
    LPDIRECT3DSURFACE9 psurf;

    if (IsCubeMap())
        return E_FAIL;

    pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;
    hr = pmiptex->GetSurfaceLevel(0, &psurf);
    if (FAILED(hr))
        return hr;

    hr = LoadAlphaIntoSurface(strPath, psurf);
    ReleasePpo(&psurf);
    if (FAILED(hr))
        return hr;
    
    UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
    return S_OK;
}
Пример #18
0
bool CGUIFontTTFDX::CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2)
{
  FT_Bitmap bitmap = bitGlyph->bitmap;

  LPDIRECT3DTEXTURE9 texture = ((CDXTexture *)m_texture)->GetTextureObject();
  LPDIRECT3DSURFACE9 target;
  if (m_speedupTexture)
    m_speedupTexture->GetSurfaceLevel(0, &target);
  else
    texture->GetSurfaceLevel(0, &target);

  RECT sourcerect = { 0, 0, bitmap.width, bitmap.rows };
  RECT targetrect = { x1, y1, x2, y2 };

  HRESULT hr = D3DXLoadSurfaceFromMemory( target, NULL, &targetrect,
                                          bitmap.buffer, D3DFMT_LIN_A8, bitmap.pitch, NULL, &sourcerect,
                                          D3DX_FILTER_NONE, 0x00000000);

  SAFE_RELEASE(target);

  if (FAILED(hr))
  {
    CLog::Log(LOGERROR, __FUNCTION__": Failed to copy the new character (0x%08X)", hr);
    return false;
  }

  if (m_speedupTexture)
  {
    // Upload to GPU - the automatic dirty region tracking takes care of the rect.
    HRESULT hr = g_Windowing.Get3DDevice()->UpdateTexture(m_speedupTexture->Get(), texture);
    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Failed to upload from sysmem to vidmem (0x%08X)", hr);
      return false;
    }
  }
  return TRUE;
}
Пример #19
0
CBaseTexture* CGUIFontTTFDX::ReallocTexture(unsigned int& newHeight)
{
  assert(newHeight != 0);
  assert(m_textureWidth != 0);
  if(m_textureHeight == 0)
  {
    delete m_texture;
    m_texture = NULL;
    delete m_speedupTexture;
    m_speedupTexture = NULL;
  }
  m_staticCache.Flush();
  m_dynamicCache.Flush();

  CDXTexture* pNewTexture = new CDXTexture(m_textureWidth, newHeight, XB_FMT_A8);
  pNewTexture->CreateTextureObject();
  LPDIRECT3DTEXTURE9 newTexture = pNewTexture->GetTextureObject();

  if (newTexture == NULL)
  {
    CLog::Log(LOGERROR, __FUNCTION__" - failed to create the new texture h=%d w=%d", m_textureWidth, newHeight);
    SAFE_DELETE(pNewTexture);
    return NULL;
  }

  // Use a speedup texture in system memory when main texture in default pool+dynamic
  // Otherwise the texture would have to be copied from vid mem to sys mem, which is too slow for subs while playing video.
  CD3DTexture* newSpeedupTexture = NULL;
  if (g_Windowing.DefaultD3DPool() == D3DPOOL_DEFAULT && g_Windowing.DefaultD3DUsage() == D3DUSAGE_DYNAMIC)
  {
    newSpeedupTexture = new CD3DTexture();

    if (!newSpeedupTexture->Create(m_textureWidth, newHeight, 1, 0, D3DFMT_A8, D3DPOOL_SYSTEMMEM))
    {
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      return NULL;
    }
  }

  LPDIRECT3DSURFACE9 pSource, pTarget;
  // There might be data to copy from the previous texture
  if ((newSpeedupTexture && m_speedupTexture) || (newTexture && m_texture))
  {
    if (m_speedupTexture && newSpeedupTexture)
    {
      m_speedupTexture->GetSurfaceLevel(0, &pSource);
      newSpeedupTexture->GetSurfaceLevel(0, &pTarget);
    }
    else
    {
      ((CDXTexture *)m_texture)->GetTextureObject()->GetSurfaceLevel(0, &pSource);
      newTexture->GetSurfaceLevel(0, &pTarget);
    }

    D3DLOCKED_RECT srclr, dstlr;
    if(FAILED(pSource->LockRect( &srclr, NULL, 0 ))
    || FAILED(pTarget->LockRect( &dstlr, NULL, 0 )))
    {
      CLog::Log(LOGERROR, __FUNCTION__" - failed to lock surfaces");
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      pSource->Release();
      pTarget->Release();
      return NULL;
    }

    unsigned char *dst = (unsigned char *)dstlr.pBits;
    unsigned char *src = (unsigned char *)srclr.pBits;
    unsigned int dstPitch = dstlr.Pitch;
    unsigned int srcPitch = srclr.Pitch;
    unsigned int minPitch = std::min(srcPitch, dstPitch);

    if (srcPitch == dstPitch)
    {
      memcpy(dst, src, srcPitch * m_textureHeight);
    }
    else
    {
      for (unsigned int y = 0; y < m_textureHeight; y++)
      {
        memcpy(dst, src, minPitch);
        src += srcPitch;
        dst += dstPitch;
      }
    }
    pSource->UnlockRect();
    pTarget->UnlockRect();

    pSource->Release();
    pTarget->Release();
  }

  // Upload from speedup texture to main texture
  if (newSpeedupTexture && m_speedupTexture)
  {
    LPDIRECT3DSURFACE9 pSource, pTarget;
    newSpeedupTexture->GetSurfaceLevel(0, &pSource);
    newTexture->GetSurfaceLevel(0, &pTarget);
    const RECT rect = { 0, 0, m_textureWidth, m_textureHeight };
    const POINT point = { 0, 0 };

    HRESULT hr = g_Windowing.Get3DDevice()->UpdateSurface(pSource, &rect, pTarget, &point);
    SAFE_RELEASE(pSource);
    SAFE_RELEASE(pTarget);

    if (FAILED(hr))
    {
      CLog::Log(LOGERROR, __FUNCTION__": Failed to upload from sysmem to vidmem (0x%08X)", hr);
      SAFE_DELETE(newSpeedupTexture);
      SAFE_DELETE(pNewTexture);
      return NULL;
    }
  }

  SAFE_DELETE(m_texture);
  SAFE_DELETE(m_speedupTexture);
  m_textureHeight = newHeight;
  m_textureScaleY = 1.0f / m_textureHeight;
  m_speedupTexture = newSpeedupTexture;

  return pNewTexture;
}
Пример #20
0
INT CrenderTarget::CreateRenderSurface()
{
	HRESULT hr=-1;

	DWORD				dMip = 1;
	LPDIRECT3DSURFACE9	pSfC = NULL;
	LPDIRECT3DSURFACE9	pSfD = NULL;
	D3DSURFACE_DESC		dscC;
	D3DSURFACE_DESC		dscD;

	D3DCAPS9			m_Caps;

	m_pDev->GetRenderTarget(0,&pSfC);
	m_pDev->GetDepthStencilSurface(&pSfD);

    pSfC->GetDesc(&dscC);
	pSfD->GetDesc(&dscD);

	m_pDev->GetDeviceCaps(&m_Caps);

	pSfC->Release();
	pSfD->Release();

	if(m_iW<0)
		m_iW = dscC.Width;
	
	if(m_iH<0)
		m_iH = dscC.Height;


	m_dC = dscC.Format;
	m_dD = dscD.Format;

	if(LCX_TARGET_HDR16 == m_nType)
		m_dC = D3DFMT_A16B16G16R16F;

	if(LCX_TARGET_HDR32 == m_nType)
		m_dC = D3DFMT_A32B32G32R32F;


	
	hr = D3DXCreateRenderToSurface(m_pDev
							, m_iW
							, m_iH
							, (D3DFORMAT)m_dC
							, TRUE
							, (D3DFORMAT)m_dD
							, &m_pRts);

	if(FAILED(hr))
		return -1;

	hr = D3DXCreateTexture(m_pDev
							, m_iW
							, m_iH
							, dMip
							, D3DUSAGE_RENDERTARGET
							, (D3DFORMAT)m_dC
							, D3DPOOL_DEFAULT
							, &m_pTxP);

	if(FAILED(hr))
        return -1;

	hr = m_pTxP->GetSurfaceLevel(0, &m_pSfc);

	if(FAILED(hr))
		return -1;

	// Clear 0x0
	m_pDev->ColorFill(m_pSfc, NULL, 0x0);
	

	return hr;
}
Пример #21
0
// 使用DirectX 9來繪圖
void RenderFrameDX9(void)
{
	LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9();
	Vector4 vPlane(0.0f, 0.0f, 1.0f, -g_mirror_z);

	// 開始下繪圖指令
	device->BeginScene(); 

	{
		LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup;
		device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release();
		device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release();

		LPDIRECT3DSURFACE9 pSurface;
		g_pTexture->GetSurfaceLevel(0, &pSurface); 

		device->SetRenderTarget(0, pSurface);
		device->SetDepthStencilSurface(g_pDepthStencil);

		device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 200, 255), 1.0f, 0);

		RenderModelDX9(true, &vPlane);

		pSurface->Release();
		device->SetRenderTarget(0, pFrameBufferBackup);
		device->SetDepthStencilSurface(pDepthBufferBackup);
	}

	// 把上一個步驟的結果當成貼圖來使用
	{
		// 消除畫面
		device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0);

		RenderModelDX9(false, NULL);

		Matrix4x4 identMat; identMat.Identity();
		device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &identMat);

		sModelMaterial_DX9 material;
		material.m_pTextures[0] = g_pTexture;
		material.Submit();

		device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

		device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
		device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
		device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

		Matrix4x4 uv_offset_matrix;
		uv_offset_matrix.Scale_Replace(0.5f, -0.5f, 1.0f);
		uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f);

		Matrix4x4 inv_view_matrix = g_Control.GetViewMatrix();
		inv_view_matrix.FastInvert();

		Matrix4x4 texture_matrix = inv_view_matrix * g_mirror_view_matrix * g_projection_matrix * uv_offset_matrix;

		device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix);
		device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
		// D3DTTFF_PROJECTED告知direct3d裝置texcoord需要除以w
		device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
		float v[12];
		for ( int i=0; i<4; i++ )
		{
			g_Quad[i].m_Position.StoreXYZ(&v[i*3]);
		}
		// 畫出矩形
		device->SetFVF(D3DFVF_XYZ);
		//device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Quad, sizeof(Vertex_V));
		device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, 12);

	}

	// 宣告所有的繪圖指令都下完了
	device->EndScene(); 

	// 把背景backbuffer的畫面呈現出來
	device->Present( NULL, NULL, NULL, NULL );
}
Пример #22
0
void C3DCanvas::SaveToFile(const char* sFileName, int nImageSize)
{
	string sFile = sFileName;
	string sExt = CParaFile::GetFileExtension(sFileName);

	D3DXIMAGE_FILEFORMAT FileFormat = D3DXIFF_PNG;

	if(sExt == "dds")
	{
		FileFormat = D3DXIFF_DDS;
	}
	else if(sExt == "jpg")
	{
		FileFormat = D3DXIFF_JPG;
	}
	else // if(sExt == "png")
	{
		sFile = CParaFile::ChangeFileExtension(sFile, "png");
	}

	if(nImageSize<=0 || nImageSize>= m_nTextureWidth)
	{
		if( SUCCEEDED(D3DXSaveTextureToFile(sFile.c_str(), FileFormat, m_canvasTexture->GetTexture(), NULL )) )
		{
			OUTPUT_LOG("canvas portrait %d taken for %s", m_nTextureWidth, sFile.c_str());
		}
	}
	else
	{
		// if the size is somewhere in the middle.
		/*int nMipLevel = 0;
		int nWidth = m_nTextureWidth;
		while (nImageSize <nWidth)
		{
			nMipLevel++;
			nWidth = nWidth / 2;
		}*/
		LPDIRECT3DTEXTURE9 pTex = m_canvasTexture->GetTexture();
		if(pTex)
		{
			LPDIRECT3DSURFACE9 pSur = NULL;
			pTex->GetSurfaceLevel(0, &pSur);

			if(pSur)
			{
				LPDIRECT3DDEVICE9 pd3dDevice = CGlobals::GetRenderDevice();
				D3DFORMAT colorFormat = D3DFMT_A8R8G8B8;
				LPDIRECT3DTEXTURE9 pTextureDest = NULL;
				LPDIRECT3DSURFACE9 pSurDest = NULL;
				if(FAILED(pd3dDevice->CreateTexture((int)nImageSize, (int)nImageSize, 1, D3DUSAGE_RENDERTARGET, colorFormat, D3DPOOL_DEFAULT, &pTextureDest , NULL)))
				{
					SAFE_RELEASE(pSur);
					return;
				}
				if(FAILED(pTextureDest->GetSurfaceLevel(0, &pSurDest)))
				{
					SAFE_RELEASE(pTextureDest);
					SAFE_RELEASE(pSur);
					return;
				}
				
				// Copy scene to lower resolution render target texture
				if( SUCCEEDED(pd3dDevice->StretchRect( pSur, NULL, pSurDest, NULL, D3DTEXF_LINEAR )) ) 
				{
					if(SUCCEEDED(D3DXSaveSurfaceToFile(sFile.c_str(), FileFormat, pSurDest, NULL,NULL )))
					{
						OUTPUT_LOG("canvas portrait %d taken for %s",nImageSize, sFile.c_str());
					}
				}
				SAFE_RELEASE(pSur);
				SAFE_RELEASE(pSurDest);
				SAFE_RELEASE(pTextureDest);
			}
		}

	}
}
Пример #23
0
bool DirectXTextureManager::loadTileSetFromTexture(	Game *game, 
													wstring dir,
													wstring sourceImageFileName,
													int tileWidth,
													int tileHeight,
													int spacing,
													int margin)
{
	// CONVERT THE FILE NAME INTO A WINDOW LONG CHAR wchar_t (LPCWSTR)
	wstring sourcePath = dir + sourceImageFileName;

	LPDIRECT3DTEXTURE9 textureToDivide;
	LPDIRECT3DSURFACE9 surfaceToDivide;

	unsigned int result = fillTexture(sourcePath, &textureToDivide);
	textureToDivide->GetSurfaceLevel(0, &surfaceToDivide);
	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-margin)/(tileWidth+spacing);
	int rows = (textureHeight-margin)/(tileHeight+spacing);
	DirectXGraphics *dxg = (DirectXGraphics*)graphics;

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

	// THE TILE SET IMAGE LOADED SUCCESSFULLY, SO LET'S CUT IT UP
	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 + spacing)) + margin;
			sourceRect.right = tileWidth + (sourceRect.left) - 1;
			sourceRect.top = (row * (tileHeight + spacing)) + margin;
			sourceRect.bottom = tileHeight + (sourceRect.top) - 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;
				
			// LET'S PUT THE SURFACE IN AN IMAGE FILE
			D3DXSaveSurfaceToFileW(textureFilename.c_str(), D3DXIFF_PNG, extractedSurface, NULL, NULL); 
			D3DXIMAGE_INFO info;
			HRESULT result = D3DXGetImageInfoFromFile(textureFilename.c_str(), &info);
			if (result != S_OK) return false;

			// AND THEN LOAD IT BACK IN AS A TEXTURE
			result = D3DXCreateTextureFromFileEx(	graphicsDevice,		// GPU
													textureFilename.c_str(),			// BITMAP FILE PATH/NAME
													tileWidth,			// BITMAP IMAGE WIDTH
													tileHeight,		// BITMAP IMAGE HEIGHT
													1,					// MIP-MAP LEVELS (1 FOR NO CHAIN)
													D3DPOOL_DEFAULT,	// THE TYPE OF SURFACE (STANDARD)
													D3DFMT_UNKNOWN,		// SURFACE FORMAT (DEFAULT)
													D3DPOOL_DEFAULT,	// MEMORY CLASS FOR THE TEXTURE
													D3DX_DEFAULT,		// IMAGE FILTER
													D3DX_DEFAULT,		// MIP FILTER
													NULL,			// COLOR KEY
													&info,				// BITMAP FILE INFO
													NULL,				// COLOR PALETTE
													&extractedTexture );	// THE TEXTURE WE ARE CREATING AND LOADING					
			if (result != S_OK) return false;

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

			// AND ADD IT TO THE TEXTURES
			textures[textureFilename] = extractedTexture;
		}
	}
	return true;
}
Пример #24
0
/*===========================================================
					  Render To Texture
===========================================================*/
bool RendrToTexture(mytex* &tex,D3DPOOL pool,int &x_delta,int &y_delta,int nowx,int nowy,imgbase *img)
{
	bool rlt = true;
	LPDIRECT3DTEXTURE9 pRenderTexture = NULL; // 目标纹理
	LPDIRECT3DSURFACE9 pRenderSurface = NULL,pBackBuffer = NULL;
	// pRenderSurface是pRenderTexture 对应的Surface		// pBackBuffer用于保存原来的Render Target

	//注意这里的第三个参数必须为D3DUSAGE_RENDERTARGET      //第四个参数决定纹理的格式,不同的场景会要求不同的格式
	g_pd3dD->CreateTexture(drect.right,drect.bottom,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&pRenderTexture,NULL);

	//获得pRenderTexture对应的Surface
	pRenderTexture->GetSurfaceLevel(0,&pRenderSurface);

	//这里保存下原来的Render target,在做完RTT后再恢复
	g_pd3dD->GetRenderTarget(0,&pBackBuffer);
	if( SUCCEEDED( g_pd3dD->BeginScene() ) )
	{
		//设置我们的纹理为render target
		g_pd3dD->SetRenderTarget(0, pRenderSurface);
		g_pd3dD->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DXCOLOR(0.0f,0.00f,0.00f,1.00f), 1.0f, 0);

		//绘制tex
		img->rtt_draw_func();

		//重新将render target设置为帧缓存
		g_pd3dD->SetRenderTarget(0, pBackBuffer);
		g_pd3dD->EndScene();
		pBackBuffer->Release();
	}
	else
	{
		SAFE_RELEASE(pRenderSurface);
		SAFE_RELEASE(pRenderTexture);
		return false;
	}


	//获取rendertarget内的值
	LPDIRECT3DTEXTURE9 RenderTarget_Tex;
	LPDIRECT3DSURFACE9 RenderTarget_Surface;
	g_pd3dD->CreateTexture(drect.right,drect.bottom,1,0,D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &RenderTarget_Tex, NULL);
	RenderTarget_Tex->GetSurfaceLevel(0,&RenderTarget_Surface);
	if (g_pd3dD->GetRenderTargetData(pRenderSurface, RenderTarget_Surface) == D3D_OK)
	{
		D3DLOCKED_RECT lockbits;
		if (RenderTarget_Tex->LockRect(0,&lockbits, NULL, 0) == D3D_OK)
		{
			BYTE* bits=(BYTE*)(lockbits.pBits);
			int line_Offset = lockbits.Pitch;	//每行字节数
			BYTE* bits_head = bits;

			int left = 0x7fffffff , right = -1, top = 0x7fffffff, bottom = -1;
			for( int y=0; y<drect.bottom; y++ )
			{
				for( int x=0; x<drect.right; x++ )
				{
					if(bits[3]!=0)	//如果alpha不为0
					{
						if(x<left) left=x;
						if(x>right) right=x;
						if(y<top) top=y;
						if(y>bottom) bottom=y;
					}
					bits += 4;
				}
			}
			bits = bits_head;

			int dwidth = right-left ,dheight = bottom-top;
			int bytenum = dwidth*dheight*4;
			BYTE* dest_bits = new BYTE[bytenum];
			BYTE* dest_head = dest_bits;
			//定义初始pos 
			bits += top*line_Offset + left*4;
			//复制目标块
			for( int y=0; y<dheight; y++ )
			{
				for( int x=0; x<dwidth; x++ )
				{
					dest_bits[0] = bits[0];
					dest_bits[1] = bits[1];
					dest_bits[2] = bits[2];
					dest_bits[3] = bits[3];

					bits += 4;
					dest_bits +=4;
				}
				bits += line_Offset - dwidth*4;
			}

			RenderTarget_Tex->UnlockRect(0);

			D3DLOCKED_RECT lockmapbits;
			if (g_pd3dD->CreateTexture(dwidth, dheight, 1, 0, D3DFMT_A8R8G8B8, pool, &(tex->tex), NULL) == D3D_OK)
			{
				tex->tex->LockRect(0, &lockmapbits, NULL, 0);
				//直接复制内存块
				CopyMemory(lockmapbits.pBits,dest_head,bytenum);
				tex->tex->UnlockRect(0);
			}
			else {rlt = false;}

			//rendertarget的宽高以及相对于draw之前的偏移量
			tex->width = dwidth;
			tex->height = dheight;
			x_delta = left - nowx;
			y_delta = top - nowy;
		}
		else {rlt = false;}
	}
	else {rlt = false;}

	/*/保存纹理到图片
	if(FAILED(D3DXSaveTextureToFileW(L"rt.png",D3DXIFF_PNG,tex->tex,0)))
		RenderTarget_Tex = 0;//*/

	SAFE_RELEASE(RenderTarget_Tex);
	SAFE_RELEASE(RenderTarget_Surface);
	SAFE_RELEASE(pRenderSurface);
	SAFE_RELEASE(pRenderTexture);
	
	return rlt;
}
void RenderWithIrregularPCF(
	const D3DXMATRIX& viewproj,
	const D3DXVECTOR3& eye,
	const D3DXMATRIX& lightview,
	const D3DXMATRIX& lightproj,
	const D3DXVECTOR4& lightpos,
	const D3DXVECTOR4& clipplanes,
	const D3DXVECTOR4& texelsize)
{
	LPDIRECT3DSURFACE9 oldsurface		= NULL;
	LPDIRECT3DSURFACE9 shadowsurface	= NULL;
	D3DXVECTOR4 noisesize(16.0f, 16.0f, 0, 1);

	// STEP 1: render shadow map
	shadowmap->GetSurfaceLevel(0, &shadowsurface);

	device->GetRenderTarget(0, &oldsurface);
	device->SetRenderTarget(0, shadowsurface);
	device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
	//device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

	shadowsurface->Release();

	pcfirreg->SetTechnique("shadowmap");
	pcfirreg->SetMatrix("lightView", &lightview);
	pcfirreg->SetMatrix("lightProj", &lightproj);
	pcfirreg->SetVector("clipPlanes", &clipplanes);

	pcfirreg->Begin(NULL, 0);
	pcfirreg->BeginPass(0);
	{
		RenderScene(pcfirreg, 1); // caster
		RenderScene(pcfirreg, 3); // caster & receiver
	}
	pcfirreg->EndPass();
	pcfirreg->End();

	// STEP 2: render scene
	//device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	device->SetRenderTarget(0, oldsurface);
	device->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0xff6694ed, 1.0f, 0);
	device->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);

	oldsurface->Release();

	device->SetTexture(1, shadowmap);
	device->SetTexture(2, noise);

	pcfirreg->SetTechnique("irregular_light");
	//pcfirreg->SetTechnique("irregular_screen");
	pcfirreg->SetMatrix("matViewProj", &viewproj);
	pcfirreg->SetMatrix("lightView", &lightview);
	pcfirreg->SetMatrix("lightProj", &lightproj);
	pcfirreg->SetVector("clipPlanes", &clipplanes);
	pcfirreg->SetVector("lightPos", &lightpos);
	pcfirreg->SetVector("eyePos", (D3DXVECTOR4*)&eye);
	pcfirreg->SetVector("texelSize", &texelsize);
	pcfirreg->SetVector("noiseSize", &noisesize);

	pcfirreg->Begin(NULL, 0);
	pcfirreg->BeginPass(0);
	{
		RenderScene(pcfirreg, 2); // receiver
		RenderScene(pcfirreg, 3); // caster & receiver
	}
	pcfirreg->EndPass();
	pcfirreg->End();

	device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
}
Пример #26
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;
}
Пример #27
0
// Draw a textured quad on the back-buffer
bool CDirect3D::D3DSwapBuffers(void)
{
    HRESULT hr;
    UINT uPasses;

	if (backbuffer_clear_countdown > 0) {
		backbuffer_clear_countdown--;
		pD3DDevice9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	}

#if DOSBOXMENU_TYPE == DOSBOXMENU_SDLDRAW
    // If the SDL drawn menus are visible, copy the SDL surface to the Direct3D surface to keep them visible on-screen
    if (mainMenu.isVisible() && mainMenu.menuBox.h != 0 && dwY >= mainMenu.menuBox.h)
	UpdateRectFromSDLSurface(0, 0, mainMenu.menuBox.w, mainMenu.menuBox.h);
#endif

    // begin rendering
    pD3DDevice9->BeginScene();

#if C_D3DSHADERS
    /* PS 2.0 path */
    if(psActive) {

	if(preProcess) {

	    // Set preprocess matrices
	    if(FAILED(psEffect->SetMatrices(m_matPreProj, m_matPreView, m_matPreWorld))) {
		LOG_MSG("D3D:Set matrices failed.");
		return false;
	    }

	    // Save render target
	    LPDIRECT3DSURFACE9 lpRenderTarget;
	    pD3DDevice9->GetRenderTarget(0, &lpRenderTarget);
	    LPDIRECT3DTEXTURE9 lpWorkTexture = lpWorkTexture1;
pass2:
	    // Change the render target
	    LPDIRECT3DSURFACE9 lpNewRenderTarget;
	    lpWorkTexture->GetSurfaceLevel(0, &lpNewRenderTarget);

	    if(FAILED(pD3DDevice9->SetRenderTarget(0, lpNewRenderTarget))) {
		LOG_MSG("D3D:Failed to set render target");
		return false;
	    }

	    SAFE_RELEASE(lpNewRenderTarget);

	    uPasses = 0;
	    if(FAILED(psEffect->Begin((lpWorkTexture==lpWorkTexture1) ?
		    (ScalingEffect::Preprocess1):(ScalingEffect::Preprocess2), &uPasses))) {
		LOG_MSG("D3D:Failed to begin PS");
		return false;
	    }

	    for(UINT uPass=0;uPass<uPasses;uPass++) {
		hr=psEffect->BeginPass(uPass);
		if(FAILED(hr)) {
		    LOG_MSG("D3D:Failed to begin pass %d", uPass);
		    return false;
		}

		// Render the vertex buffer contents
		pD3DDevice9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
		psEffect->EndPass();
	    }

	    if(FAILED(psEffect->End())) {
		LOG_MSG("D3D:Failed to end effect");
		return false;
	    }

#if DEBUG_PS
	    // Save rendertarget data
	    LPDIRECT3DSURFACE9 lpTexRenderTarget;
	    lpWorkTexture->GetSurfaceLevel(0, &lpTexRenderTarget);
	    lpDebugTexture->GetSurfaceLevel(0, &lpNewRenderTarget);
	    if(FAILED(hr=pD3DDevice9->GetRenderTargetData(lpTexRenderTarget, lpNewRenderTarget))) {
		LOG_MSG("D3D:Unable to get render target data: 0x%x", hr);
		SAFE_RELEASE(lpTexRenderTarget);
		SAFE_RELEASE(lpNewRenderTarget);
	    } else {
		SAFE_RELEASE(lpTexRenderTarget);
		SAFE_RELEASE(lpNewRenderTarget);
		LOG_MSG("D3D:Got render target data, writing debug file (%dx%d)", dwTexWidth, dwTexHeight);
		if(lpDebugTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_READONLY) == D3D_OK) {
		    FILE * debug = fopen(((lpWorkTexture==lpWorkTexture1)?"pass1.raw":"pass2.raw"), "wb");
		    if(debug == NULL) {
			LOG_MSG("D3D:Unable to create file!");
		    } else {
			for(int i = 0; i < dwTexHeight; i++) {
			    Bit8u * ptr = (Bit8u*)d3dlr.pBits;
			    for(int j = 0; j < dwTexWidth; j++) {
				fwrite(ptr, 3, sizeof(char), debug);
				ptr += 4;
			    }
			    d3dlr.pBits = (Bit8u*)d3dlr.pBits + d3dlr.Pitch;
			}
			fclose(debug);
		    }
		    lpDebugTexture->UnlockRect(0);
		}
		d3dlr.pBits = NULL;
	    }
#endif

	    if((psEffect->hasPreprocess2()) && (lpWorkTexture == lpWorkTexture1)) {
		lpWorkTexture = lpWorkTexture2;
		goto pass2;
	    }

	    // Reset the rendertarget
	    pD3DDevice9->SetRenderTarget(0, lpRenderTarget);
	    SAFE_RELEASE(lpRenderTarget);

	    // Set matrices for final pass
	    if(FAILED(psEffect->SetMatrices(m_matProj, m_matView, m_matWorld))) {
		LOG_MSG("D3D:Set matrices failed.");
		return false;
	    }
	}

	uPasses = 0;

	if(FAILED(psEffect->Begin(ScalingEffect::Combine, &uPasses))) {
	    LOG_MSG("D3D:Failed to begin PS");
	    return false;
	}

	for(UINT uPass=0;uPass<uPasses;uPass++) {
	    hr=psEffect->BeginPass(uPass);
	    if(FAILED(hr)) {
		LOG_MSG("D3D:Failed to begin pass %d", uPass);
		return false;
	    }

	    // Render the vertex buffer contents
	    pD3DDevice9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
	    psEffect->EndPass();
	}

	if(FAILED(psEffect->End())) {
	    LOG_MSG("D3D:Failed to end effect");
	    return false;
	}

    } else
#endif
    {
	// Normal path
	pD3DDevice9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
    }

    // end rendering
    pD3DDevice9->EndScene();

    if(GCC_UNLIKELY(hr=pD3DDevice9->Present(NULL, NULL, NULL, NULL)) != D3D_OK) {
	switch(hr) {
	    case D3DERR_DEVICELOST:
        LOG_MSG("D3D:Driver device lost");
        if (!deviceLost) {
            deviceLost = true;
            void RENDER_CallBack(GFX_CallBackFunctions_t f);
            RENDER_CallBack(GFX_CallBackRedraw);
        }
		return false;
		break;
	    case D3DERR_DRIVERINTERNALERROR:
		LOG_MSG("D3D:Driver internal error");
		return false;
		break;
	    case D3DERR_INVALIDCALL:
	    default:
		LOG_MSG("D3D:Invalid call");
		return false;
		break;
	}
    }

    return true;
}
Пример #28
0
// Should be scale free.
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture)
{
	u8* srcAddr = Memory::GetPointer(xfbAddr);
	if (!srcAddr)
	{
		WARN_LOG(VIDEO, "Tried to decode from invalid memory address");
		return;
	}

	int srcFmtWidth = srcWidth / 2;
	XFBReadBuffer &ReadBuffer = XReadBuffers[xfreadBuffers];
	if (ReadBuffer.Width != srcFmtWidth || ReadBuffer.Height != srcHeight)
	{
		ReadBuffer.Release();
		ReadBuffer.Width = srcFmtWidth;
		ReadBuffer.Height = srcHeight;
		ReadBuffer.XFBMEMTexture = D3D::CreateTexture2D(srcFmtWidth, srcHeight, D3DFMT_A8R8G8B8, 1, D3DPOOL_SYSTEMMEM);
		ReadBuffer.XFBTexture = D3D::CreateTexture2D(srcFmtWidth, srcHeight, D3DFMT_A8R8G8B8);
		ReadBuffer.XFBMEMTexture->GetSurfaceLevel(0, &ReadBuffer.ReadSurface);
		ReadBuffer.XFBTexture->GetSurfaceLevel(0, &ReadBuffer.WriteSurface);
	}
	D3D::ReplaceTexture2D(ReadBuffer.XFBMEMTexture, srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false);
	RECT srcr{ 0, 0, srcFmtWidth, srcHeight };
	POINT dstp{ 0, 0 };
	D3D::dev->UpdateSurface(ReadBuffer.ReadSurface, &srcr, ReadBuffer.WriteSurface, &dstp);
	g_renderer->ResetAPIState(); // reset any game specific settings
	
	LPDIRECT3DSURFACE9 Rendersurf = nullptr;
	destTexture->GetSurfaceLevel(0,&Rendersurf);
	D3D::dev->SetDepthStencilSurface(nullptr);
	D3D::dev->SetRenderTarget(0, Rendersurf);

	D3DVIEWPORT9 vp;

	// Stretch picture with increased internal resolution
	vp.X = 0;
	vp.Y = 0;
	vp.Width  = srcWidth;
	vp.Height = srcHeight;
	vp.MinZ = 0.0f;
	vp.MaxZ = 1.0f;
	D3D::dev->SetViewport(&vp);
	RECT destrect;
	destrect.bottom = srcHeight;
	destrect.left = 0;
	destrect.right = srcWidth;
	destrect.top = 0;
	
	RECT sourcerect;
	sourcerect.bottom = srcHeight;
	sourcerect.left = 0;
	sourcerect.right = srcFmtWidth;
	sourcerect.top = 0;

	D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
	D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
		
	TextureConversionShaderLegacy::SetShaderParameters(
		(float)srcFmtWidth,
		(float)srcHeight,
		0.0f,
		0.0f,
		1.0f,
		1.0f,
		(float)srcFmtWidth,
		(float)srcHeight);
	D3D::dev->SetPixelShaderConstantF(C_COLORMATRIX, PixelShaderManager::GetBuffer(), 2);
	D3D::drawShadedTexQuad(
		ReadBuffer.XFBTexture,
		&sourcerect,
		1,
		1,
		srcWidth,
		srcHeight,
		s_yuyvToRgbProgram,
		VertexShaderCache::GetSimpleVertexShader(0));


	D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
	D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
	D3D::SetTexture(0,nullptr);
	D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
	D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());	
	g_renderer->RestoreAPIState();
	Rendersurf->Release();
	xfreadBuffers = (xfreadBuffers + 1) % NUM_XFBREAD_BUFFER;
}
Пример #29
0
/*
	Renders all tiles and sprites. Note that these objects can
	be rotated.
*/
void DirectXGraphics::renderWorldRenderList()
{
	worldRenderList->resetIterator();
	RenderItem itemToRender;
	LPDIRECT3DTEXTURE9 texture;
	RECT *rect = NULL;
	GameGUI *gui = game->getGUI();
	Viewport *viewport = gui->getViewport();

	// GO THROUGH EACH ITEM IN THE LIST
	while (worldRenderList->hasNext())
	{
		float translationX;
		float translationY;
		if (rect != NULL)
			delete rect;
		rect = NULL;
		itemToRender = worldRenderList->next();
		
		// LET'S GET THE TEXTURE WE WANT TO RENDER
		int id = itemToRender.id;
		if (id >= 0)
		{
			texture = ((DirectXTextureManager*)worldTextureManager)->getTexture(id);
			D3DXVECTOR3 position = D3DXVECTOR3(	(FLOAT)(itemToRender.x),
											(FLOAT)(itemToRender.y),
												0);

			position.x += viewport->getViewportOffsetX();
			position.y += viewport->getViewportOffsetY();

			// ADJUST FOR THE GUI OFFSET
			if ((position.x < viewport->getViewportOffsetX())
				||  (position.y < viewport->getViewportOffsetY()))
			{
				IDirect3DSurface9 *surface;
				UINT level = 0;
				HRESULT result = texture->GetSurfaceLevel(level, &surface);
				D3DSURFACE_DESC surfaceDescription;
				surface->GetDesc(&surfaceDescription);
				rect = new RECT();
				rect->left = 0;
				rect->top = 0;
				rect->right = surfaceDescription.Width;
				rect->bottom = surfaceDescription.Height;
				if (position.x < viewport->getViewportOffsetX())
				{
					int xDiff = viewport->getViewportOffsetX() - (int)position.x;
					rect->left = xDiff;
					position.x += xDiff;
				}
				if (position.y < viewport->getViewportOffsetY())
				{
					int yDiff = viewport->getViewportOffsetY() - (int)position.y;
					rect->top = yDiff;
					position.y += yDiff;
				}	
			}			

			// LET'S PUT THE STANDARD ROTATION MATRIX ASIDE
			// FOR A SECOND. IT WILL BE USED FOR RENDERING THE
			// GUI, BUT WE'LL WANT A CUSTOM ONE FOR WORLD OBJECTS
			D3DXMATRIX defaultTransform;
			D3DXMatrixIdentity(&defaultTransform);
				
			// TO RENDER A PROPERLY ROTATED OBJECT TO THE WORLD,
			// FIRST WE NEED TO MOVE IT TO THE ORIGIN, CENTERED
			// ABOUT THE ORIGIN SO WE SET UP THIS MATRIX
			// TO DO THIS
			D3DXMATRIX translationToOrigin;
			D3DXMatrixIdentity(&translationToOrigin);
		    translationToOrigin._41 = -(itemToRender.width/2);
			translationToOrigin._42 = -(itemToRender.height/2);
	
			// THEN WE NEED A MATRIX TO DO THE ROTATION
			D3DXMATRIX rotationAboutOrigin;
			D3DXMatrixIdentity(&rotationAboutOrigin);
	
			// THE PROBLEM ANGLES ARE 0, 90, 180, and 270
			float cosTheta = cos(itemToRender.rotationInRadians);
			float sinTheta = sin(itemToRender.rotationInRadians);
			if (cosTheta != cosTheta)
				cosTheta = 0;
			if (sinTheta != sinTheta)
				sinTheta = 0;
			rotationAboutOrigin._11 = cosTheta;
			rotationAboutOrigin._21 = -sinTheta;
			rotationAboutOrigin._12 = sinTheta;
			rotationAboutOrigin._22 = cosTheta;
	
			// AND THEN WE NEED A MATRIX TO ROTATE THE OBJECT
			// TO THE LOCATION WE WANT IT RENDERED
			D3DXMATRIX translationBackToCenter;
			D3DXMatrixIdentity(&translationBackToCenter);
			translationBackToCenter._41 = ((position.x) + (itemToRender.width/2));
			translationBackToCenter._42 = ((position.y) + (itemToRender.height/2));
	
			// THE COMBINED MATRIX COMBINES THESE 3 OPERATIONS
			// INTO A SINGLE MATRIX
			D3DXMATRIX combinedMatrix = translationToOrigin;
			combinedMatrix *= rotationAboutOrigin;
			combinedMatrix *= translationBackToCenter;
	
			// NOW LET'S USE THE COMBINED MATRIX TO POSITION AND ROTATE THE ITEM
			spriteHandler->SetTransform(&combinedMatrix);
		
			// RENDER THE OPAQUE ITEMS
			if (itemToRender.a == 255)
			{
				if (FAILED(spriteHandler->Draw(
					texture, 
					rect,
			        NULL,
					NULL,
					DEFAULT_ALPHA_COLOR)))
				{
					game->getText()->writeDebugOutput("\nspriteHandler->Draw: FAILED");
				}
				// RENDER THE ITEMS WITH CUSTOM TRANSPARENCY
				else
				{
					if (itemToRender.a < 0)
						itemToRender.a = 0;
					else if (itemToRender.a > 255)
						itemToRender.a = 255;
					if (FAILED(spriteHandler->Draw(
						texture,
						rect,
						NULL,
						NULL,
						D3DCOLOR_ARGB(itemToRender.a, 255, 255, 255))))
					{
						game->getText()->writeDebugOutput("\nspriteHandler->Draw: FAILED");
					}
				}
			}
		}
	}

	// NOW EMPTY THE LIST, WE'RE ALL DONE WITH IT
	worldRenderList->clear();
	if (rect != NULL)
		delete rect;
	
	// AND RESTORE THE MATRIX USED FOR RENDERING THE GUI
	D3DXMATRIX identityMatrix;
	D3DXMatrixIdentity(&identityMatrix);
	spriteHandler->SetTransform(&identityMatrix);
}
Пример #30
0
// 使用DirectX 9來繪圖
void RenderFrameDX9(void)
{
	LPDIRECT3DDEVICE9 device = GutGetGraphicsDeviceDX9();
	LPDIRECT3DTEXTURE9 pBlurredTexture = NULL;

	Matrix4x4 light_projection_matrix;
	Matrix4x4 light_view_matrix;

	Matrix4x4 view_matrix = g_Control.GetViewMatrix();
	Matrix4x4 world_matrix = g_Control.GetObjectMatrix();

	// 開始下繪圖指令
	device->BeginScene(); 
	{
		// 保存主framebuffer
		LPDIRECT3DSURFACE9 pFrameBufferBackup, pDepthBufferBackup;
		device->GetRenderTarget(0, &pFrameBufferBackup); pFrameBufferBackup->Release();
		device->GetDepthStencilSurface(&pDepthBufferBackup); pDepthBufferBackup->Release();
		// 取出動態貼圖中的surface
		LPDIRECT3DSURFACE9 pSurface;
		g_pTexture->GetSurfaceLevel(0, &pSurface); 
		// 把繪圖結果輸出到動態貼圖中
		device->SetRenderTarget(0, pSurface);
		device->SetDepthStencilSurface(g_pDepthStencil);
		// 清除畫面
		device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(255, 255, 255, 255), 1.0f, 0);
		// 設定光源位置
		Vector4 vLightPos = g_Light.m_Position;
		Vector4 vLightUp(0.0f, 1.0f, 0.0f);
		Vector4 vLightLookat(0.0f, 0.0f, 0.0f);

		light_projection_matrix = GutMatrixPerspectiveRH_DirectX(60.0f, 1.0f, 0.1f, 100.0f);
		light_view_matrix = GutMatrixLookAtRH(vLightPos, vLightLookat, vLightUp);
		// 把鏡頭放到光源位置來畫陰影
		device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *)&light_projection_matrix);
		device->SetTransform(D3DTS_VIEW, (D3DMATRIX *)&light_view_matrix);
		device->SetTransform(D3DTS_WORLD, (D3DMATRIX *)&world_matrix);

		// 把所有反射關閉,讓模型在畫面上呈現黑色。
		D3DCOLORVALUE zero = {0.0f, 0.0f, 0.0f, 1.0f};

		sModelMaterial_DX9 material;
		material.m_Material.Ambient = zero;
		material.m_Material.Emissive = zero;
		material.m_Material.Diffuse = zero;
		material.m_Material.Specular = zero;
		material.m_bCullFace = false;

		material.Submit();

		SetupLightingDX9();
		// 畫出模型
		g_Model_DX9.Render(0);
		// 告知direct3d9裝置rendertarget使用完畢
		pSurface->Release();
		// 還原主framebuffer
		device->SetRenderTarget(0, pFrameBufferBackup);
		device->SetDepthStencilSurface(pDepthBufferBackup);
	}

	// 把影子柔化
	{
		pBlurredTexture = BlurTexture(g_pTexture);
	}

	// 把上一個步驟的結果當成貼圖來使用
	{
		// 消除畫面
		device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 150, 255), 1.0f, 0);
		// 設定轉換矩陣
		device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX *) &g_projection_matrix);
		device->SetTransform(D3DTS_VIEW, (D3DMATRIX *) &view_matrix);
		device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &world_matrix);
		// 設定光源
		SetupLightingDX9();

		device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
		device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

		device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
		device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);

		// 畫出茶壼
		g_Model_DX9.Render();

		sModelMaterial_DX9 material;
		material.m_pTextures[0] = pBlurredTexture;
		material.Submit();
		// 計算貼圖矩陣
		Matrix4x4 inv_view_matrix = g_Control.GetCameraMatrix();
		Matrix4x4 uv_offset_matrix;
		uv_offset_matrix.Identity();
		uv_offset_matrix.Scale(0.5f, -0.5f, 0.5f);
		uv_offset_matrix[3].Set(0.5f, 0.5f, 0.5f, 1.0f);

		Matrix4x4 texture_matrix = inv_view_matrix * light_view_matrix * light_projection_matrix * uv_offset_matrix;
		Matrix4x4 indent_matrix = Matrix4x4::IdentityMatrix();
		// 設定轉換矩陣
		device->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &texture_matrix);
		device->SetTransform(D3DTS_WORLD, (D3DMATRIX *) &indent_matrix);
		// 開啟自動產生貼圖座標功能
		device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
		device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);

		device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
		device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

		device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
		device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

		// 畫出地表
		g_Terrain_DX9.Render(0);

		device->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
		device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
	}

	// 宣告所有的繪圖指令都下完了
	device->EndScene(); 

	// 把背景backbuffer的畫面呈現出來
	device->Present( NULL, NULL, NULL, NULL );
}