Exemplo n.º 1
0
// TexturedSquare
TexturedSquare::TexturedSquare(LPDIRECT3DDEVICE9 device, const D3DXVECTOR3& vect, const D3DXVECTOR3& shift, float size, 
                               std::vector<LPCWSTR> mipmapFilenames, int wid, bool useTex)
: TexturedObject(device, useTex) {

    std::vector<TEXTURE_VERTEX_WITH_NORMAL> vertices;
    D3DXVECTOR3 normal = vect;
    D3DXVec3Normalize(&normal, &normal);

    const int n = 10;
    const float min = -size / 2;
    const float max = size / 2;
    const float step = size / n;

    for (float u = min; u < max - step; u += step)
    {
        for (float v = min; v < max - step; v += step)
        {
            D3DXVECTOR3 u1, u2, u3, u4;
            if (normal.y != 0) {
                u1 = { u + shift.x, -(normal.x * u + normal.z * v) / normal.y + shift.y, v + shift.z };
                u2 = { u + step + shift.x, -(normal.x * (u + step) + normal.z * v) / normal.y + shift.y, v + shift.z };
                u3 = { u + shift.x, -(normal.x * u + normal.z * (v + step)) / normal.y + shift.y, v + step + shift.z };
                u4 = { u + step + shift.x, -(normal.x * (u + step) + normal.z * (v + step)) / normal.y + shift.y, v + step + shift.z };
            }
            else if (normal.z != 0) {
                u1 = { u + shift.x, v + shift.y, -(normal.x * u + normal.y * v) / normal.z + shift.z };
                u2 = { u + step + shift.x, v + shift.y, -(normal.x * (u + step) + normal.y * v) / normal.z + shift.z };
                u3 = { u + shift.x, v + step + shift.y, -(normal.x * u + normal.y * (v + step)) / normal.z + shift.z };
                u4 = { u + step + shift.x, v + step + shift.y, -(normal.x * (u + step) + normal.y * (v + step)) / normal.z + shift.z };
            }
            else if (normal.x != 0) {
                u1 = { -(normal.y * u + normal.z * v) / normal.x + shift.x, u + shift.y, v + shift.z };
                u2 = { -(normal.y * (u + step) + normal.z * v) / normal.x + shift.x, u + step + shift.y, v + shift.z };
                u3 = { -(normal.y * u + normal.z * (v + step)) / normal.x + shift.x, u + shift.y, v + step + shift.z };
                u4 = { -(normal.y * (u + step) + normal.z * (v + step)) / normal.x + shift.x, u + step + shift.y, v + step + shift.z };
            }

            TEXTURE_VERTEX_WITH_NORMAL v1 = { u1.x, u1.y, u1.z, normal, u / size + 0.5f, v / size + 0.5f};
            TEXTURE_VERTEX_WITH_NORMAL v2 = { u2.x, u2.y, u2.z, normal, (u + step) / size + 0.5f, v / size + 0.5f };
            TEXTURE_VERTEX_WITH_NORMAL v3 = { u3.x, u3.y, u3.z, normal, u / size + 0.5f, (v + step) / size + 0.5f };
            TEXTURE_VERTEX_WITH_NORMAL v4 = { u4.x, u4.y, u4.z, normal, (u + step) / size + 0.5f, (v + step) / size + 0.5f };

            vertices.push_back(v1);
            vertices.push_back(v2);
            vertices.push_back(v3);

            vertices.push_back(v3);
            vertices.push_back(v2);
            vertices.push_back(v4);
        }
    }
    const UINT width = wid;
    const UINT height = wid;
    IDirect3DTexture9* prevTexture = NULL;

    D3DXCreateTexture(d3dDevice, width, height, mipmapFilenames.size(), 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &this->pTexture);
    D3DXCreateTexture(d3dDevice, width, height, mipmapFilenames.size(), 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &prevTexture);

    for (int i = 0; i < (int) mipmapFilenames.size(); ++i)
    {
        IDirect3DSurface9 *pSurf;
        prevTexture->GetSurfaceLevel(i, &pSurf);
        D3DXLoadSurfaceFromFile(pSurf, NULL, NULL, mipmapFilenames[i], NULL, D3DX_DEFAULT, 0, NULL);
        pSurf->Release();
    }

    d3dDevice->UpdateTexture(prevTexture, pTexture);
    prevTexture->Release();

    setVertices(vertices);
}
		void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
		{
			bool textureUpdate = (Texture != texture) ? true : false;
			bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;

			if (textureUpdate || depthStencilUpdate)
			{
				// Set color attachments.

				if (textureUpdate)
				{
					if (texture.size() > Driver->ActiveRenderTarget.size())
					{
						core::stringc message = "This GPU supports up to ";
						message += Driver->ActiveRenderTarget.size();
						message += " textures per render target.";

						os::Printer::log(message.c_str(), ELL_WARNING);
					}

					const u32 size = core::min_(texture.size(), static_cast<u32>(Driver->ActiveRenderTarget.size()));

					for (u32 i = 0; i < Surface.size(); ++i)
					{
						if (Surface[i])
							Surface[i]->Release();
					}

					Surface.set_used(size);

					for (u32 i = 0; i < Texture.size(); ++i)
					{
						if (Texture[i])
							Texture[i]->drop();
					}

					Texture.set_used(size);

					for (u32 i = 0; i < size; ++i)
					{
						CD3D9Texture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(texture[i]) : 0;

						IDirect3DTexture9* textureID = 0;

						if (currentTexture)
						{
							if (currentTexture->getType() == ETT_2D)
								textureID = currentTexture->getDX9Texture();
							else
								os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
						}

						if (textureID)
						{
							Texture[i] = texture[i];
							Texture[i]->grab();

							IDirect3DSurface9* currentSurface = 0;
							textureID->GetSurfaceLevel(0, &currentSurface);

							Surface[i] = currentSurface;
						}
						else
						{
							Surface[i] = 0;
							Texture[i] = 0;
						}
					}
				}

				// Set depth and stencil attachments.

				if (depthStencilUpdate)
				{
					if (DepthStencilSurface)
					{
						DepthStencilSurface->Release();
						DepthStencilSurface = 0;
					}

					if (DepthStencil)
					{
						DepthStencil->drop();
						DepthStencil = 0;

						DepthStencilSurface = 0;
					}

					CD3D9Texture* currentTexture = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(depthStencil) : 0;

					IDirect3DTexture9* textureID = 0;

					if (currentTexture)
					{
						if (currentTexture->getType() == ETT_2D)
							textureID = currentTexture->getDX9Texture();
						else
							os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
					}

					if (textureID)
					{
						const ECOLOR_FORMAT textureFormat = (depthStencil) ? depthStencil->getColorFormat() : ECF_UNKNOWN;

						if (IImage::isDepthFormat(textureFormat))
						{
							DepthStencil = depthStencil;
							DepthStencil->grab();

							IDirect3DSurface9* currentSurface = 0;
							textureID->GetSurfaceLevel(0, &currentSurface);

							DepthStencilSurface = currentSurface;
						}
					}
				}

				// Set size required for a viewport.

				bool sizeDetected = false;

				for (u32 i = 0; i < Texture.size(); ++i)
				{
					if (Texture[i])
					{
						Size = Texture[i]->getSize();
						sizeDetected = true;

						break;
					}
				}

				if (!sizeDetected)
				{
					if (DepthStencil)
						Size = DepthStencil->getSize();
					else
						Size = Driver->getScreenSize();
				}
			}
		}
Exemplo n.º 3
0
void D3D9RenderTarget::BuildRenderTarget()
{
	XTRACE_FUNCTION;

	ASSERT( m_Params.Width );
	ASSERT( m_Params.Height );

	STATIC_HASHED_STRING( Render );
	CATPRINTF( sRender, 1, "Building render target...\n" );

	uint ColorUsage = D3DUSAGE_RENDERTARGET;
	if( m_Params.AutoGenMipMaps )
	{
		ColorUsage |= D3DUSAGE_AUTOGENMIPMAP;
	}

	uint DepthStencilUsage = D3DUSAGE_DEPTHSTENCIL;

	if( m_Params.ColorFormat != ERTF_None )
	{
		CATPRINTF( sRender, 1, "Trying to create color texture with format %d\n", m_Params.ColorFormat );

		const ERenderTargetFormat SupportedFormat = m_Renderer->GetBestSupportedRenderTargetFormat( m_Params.ColorFormat );
		CATPRINTF( sRender, 1, "Creating color texture with format %d...\n", SupportedFormat );

		IDirect3DTexture9* ColorTexture;
		HRESULT hr = m_D3DDevice->CreateTexture(
			m_Params.Width,
			m_Params.Height,
			1,
			ColorUsage,
			GetD3DFormat( SupportedFormat ),
			D3DPOOL_DEFAULT,
			&ColorTexture,
			NULL );
		ASSERT( hr == D3D_OK );
		m_ColorTexture = new D3D9Texture( m_D3DDevice, ColorTexture );
		ColorTexture->GetSurfaceLevel( 0, &m_ColorSurface );
	}

	if( m_Params.DepthStencilFormat != ERTF_None )
	{
		if( m_Params.DepthStencilFormat != ERTF_UseDefault )
		{
			CATPRINTF( sRender, 1, "Trying to create depth/stencil texture with format %d\n", m_Params.DepthStencilFormat );

			const ERenderTargetFormat SupportedFormat = m_Renderer->GetBestSupportedRenderTargetFormat( m_Params.DepthStencilFormat );
			CATPRINTF( sRender, 1, "Creating depth/stencil texture with format %d...\n", SupportedFormat );

			IDirect3DTexture9* DepthStencilTexture;
			HRESULT hr = m_D3DDevice->CreateTexture(
				m_Params.Width,
				m_Params.Height,
				1,
				DepthStencilUsage,
				GetD3DFormat( SupportedFormat ),
				D3DPOOL_DEFAULT,
				&DepthStencilTexture, NULL );
			ASSERT( hr == D3D_OK );
			m_DepthStencilTexture = new D3D9Texture( m_D3DDevice, DepthStencilTexture );
			DepthStencilTexture->GetSurfaceLevel( 0, &m_DepthStencilSurface );
		}
		else
		{
			m_DepthStencilSurface = ( IDirect3DSurface9* )( m_Renderer->GetDefaultRenderTarget()->GetDepthStencilRenderTargetHandle() );
			m_DepthStencilSurface->AddRef();
		}
	}

	CATPRINTF( sRender, 1, "Render target built.\n" );
}
Exemplo n.º 4
0
//---------------------------------------------------------------------
void DrawFrame()
{
	HRESULT hr;

	// Update flash movie if necessarily
	unsigned int numDirtyRects; const RECT* dirtyRects;
	if (g_flashPlayer->IsNeedUpdate(NULL, &dirtyRects, &numDirtyRects))
	{
		IDirect3DTexture9* pTexToUpdate = g_texturesRotation[g_currentTexture];
		if (++g_currentTexture == num_textures_in_rotation)
			g_currentTexture = 0;

		IDirect3DSurface9* pSrcSurface;
		hr = pTexToUpdate->GetSurfaceLevel(0, &pSrcSurface);
		assert(SUCCEEDED(hr));

		HDC surfaceDC;
		hr = pSrcSurface->GetDC(&surfaceDC);
		assert(SUCCEEDED(hr));

		// Draw flash frame
		g_flashPlayer->DrawFrame(surfaceDC);

		hr = pSrcSurface->ReleaseDC(surfaceDC);
		assert(SUCCEEDED(hr));

		// Update our GUI texture
		IDirect3DSurface9* pDestSurface;
		hr = g_textureGUI->GetSurfaceLevel(0, &pDestSurface);
		assert(SUCCEEDED(hr));

		for (unsigned int i = 0; i < numDirtyRects; ++i)
		{
			POINT destPoint = { dirtyRects[i].left, dirtyRects[i].top };
			hr = g_device->UpdateSurface(pSrcSurface, dirtyRects + i, pDestSurface, &destPoint);
			assert(SUCCEEDED(hr));
		}

		pDestSurface->Release();
		pSrcSurface->Release();
	}

	//---------------------------------------------------------------------
	struct TLVERTEX
	{
		float x;
		float y;
		float z;
		float rhw;
		D3DCOLOR color;
		float u;
		float v;
	};

	const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;

	float halfInvWindowWidth = 1.0f / g_windowWidth * 0.5f;
	float halfInvWindowHeight = 1.0f / g_windowHeight * 0.5f;

	// Create quad vertices
	TLVERTEX vertices[4];
	vertices[0].x = 0; vertices[0].y = 0;
	vertices[0].z = 0.0f; vertices[0].rhw = 1.0f;
	vertices[0].color = 0xFFFFFFFF;
	vertices[0].u = halfInvWindowWidth; vertices[0].v = halfInvWindowHeight;

	vertices[1].x = (float)g_windowWidth; vertices[1].y = 0;
	vertices[1].z = 0.0f; vertices[1].rhw = 1.0f;
	vertices[1].color = 0xFFFFFFFF;
	vertices[1].u = 1.0f + halfInvWindowWidth; vertices[1].v = halfInvWindowHeight;

	vertices[2].x = (float)g_windowWidth; vertices[2].y = (float)g_windowHeight;
	vertices[2].z = 0.0f; vertices[2].rhw = 1.0f;
	vertices[2].color = 0xFFFFFFFF;
	vertices[2].u = 1.0f + halfInvWindowWidth; vertices[2].v = 1.0f + halfInvWindowHeight;

	vertices[3].x = 0; vertices[3].y = (float)g_windowHeight;
	vertices[3].z = 0.0f; vertices[3].rhw = 1.0f;
	vertices[3].color = 0xFFFFFFFF;
	vertices[3].u = halfInvWindowWidth; vertices[3].v = 1.0f + halfInvWindowHeight;

	// Begin frame
	hr = g_device->BeginScene();
	assert(SUCCEEDED(hr));
	hr = g_device->Clear(0, NULL, D3DCLEAR_TARGET, 0xFF000000, 1.0f, 0);
	assert(SUCCEEDED(hr));

	// Draw the quad
	hr = g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	assert(SUCCEEDED(hr));

	hr = g_device->SetRenderState(D3DRS_FOGENABLE, false);
	assert(SUCCEEDED(hr));
	hr = g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	assert(SUCCEEDED(hr));

	// Use alpha channel in texture for alpha
	hr = g_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	assert(SUCCEEDED(hr));
	hr = g_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	assert(SUCCEEDED(hr));

	hr = g_device->SetTexture(0, g_textureGUI);
	assert(SUCCEEDED(hr));

	hr = g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	assert(SUCCEEDED(hr));
	hr = g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	assert(SUCCEEDED(hr));

	hr = g_device->SetFVF(D3DFVF_TLVERTEX);
	assert(SUCCEEDED(hr));
	hr = g_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertices, sizeof(TLVERTEX));
	assert(SUCCEEDED(hr));

	hr = g_device->EndScene();
	assert(SUCCEEDED(hr));
	hr = g_device->Present(NULL, NULL, NULL, NULL);
	assert(SUCCEEDED(hr));
}
/*
==================
Creates a texture
==================
*/
IDirect3DTexture9 *DirectXTextureBuilder::createTexture(BYTE *pImage,
        int pBlockWidth,
        int pBlockHeight,
        int pSrcBpp,
        D3DFORMAT pSrcFormat,
        D3DFORMAT pDstFormat) {
	HRESULT mHr;

	IDirect3DTexture9 *mNewTexture;

	// ----- Texture creation -----

	LPDIRECT3DDEVICE9 d3ddeviceptr = _render->_wrappedRenderer->GetDevice();  //Here we break encapsulation with frienship to access internal ptr!!!
	mHr = D3DXCreateTexture(d3ddeviceptr,
	                        pBlockWidth,
	                        pBlockHeight,
	                        1,
	                        0,
	                        pDstFormat,
	                        D3DPOOL_MANAGED,
	                        &mNewTexture);

	if (FAILED(mHr)) {
		g_debug->header("Error creating the texture", 2);
		exit(0);  // TODO: Free objects?
	}

	// ----- D3D Surface creation -----

	IDirect3DSurface9 *_surface;

	// The surfaces points to the texture
	mHr = mNewTexture->GetSurfaceLevel(0, &_surface);
	if (FAILED(mHr)) {
		g_debug->header("Error creating the surface", 2);
		exit(0);  // TODO: free objects
	}

	// ----- Add the source image into the surface -----

	// Source image
	RECT mSrcRect;
	mSrcRect.left       = 0;
	mSrcRect.top        = 0;
	mSrcRect.right      = pBlockWidth;
	mSrcRect.bottom     = pBlockHeight;

	mHr = D3DXLoadSurfaceFromMemory(_surface,
	                                0,
	                                0,
	                                pImage,
	                                pSrcFormat,
	                                pBlockWidth * pSrcBpp,
	                                0,
	                                &mSrcRect,
	                                D3DX_FILTER_NONE,
	                                0);

	if (FAILED(mHr)) {
		g_debug->header("Error loading the block to the surface", 2);
		exit(0);  // TODO: free objects
	}

	// Free memory
	_surface->Release();

	return mNewTexture;
}
Exemplo n.º 6
0
/**
*
* Sets up the radiant light surface and texture.
* Since this surface exists in the scratch pool, it does not need to be restored when the device is lost.
*
* @author Jade Abbott
* @return True if creation was successful.
*
*/
bool
CRadialMenu::CreateRadiance()
{
	assert(m_pRenderer);

	CSurfaceManager& rSurfaceManager = m_pRenderer->GetSurfaceManager();

	IDirect3DTexture9* pTexture = 0;
	if (FAILED(rSurfaceManager.CreateTexture(m_uiDiameter,
											 m_uiDiameter,
											 D3DFMT_A8R8G8B8,
											 D3DPOOL_MANAGED,
											 &pTexture)))
	{
		return false;
	}

	// Get the texture's surface.
	IDirect3DSurface9* pSurface = 0;
	if (FAILED(pTexture->GetSurfaceLevel(0, &pSurface)))
	{
		pTexture->Release();
		return false;
	}

	const float kfRadius = m_uiDiameter * 0.5f;
	const float kfRadiusFraction = 1.0f / kfRadius;

	D3DLOCKED_RECT surfaceRect;
	HRESULT hr = pSurface->LockRect(&surfaceRect, 0, 0);
	if (SUCCEEDED(hr))
	{
		D3DCOLOR* pPixels = reinterpret_cast<D3DCOLOR*>(surfaceRect.pBits);
		unsigned int uiNumPixelsWide = surfaceRect.Pitch / 4;	// Includes dirty region.

		// set the colour and alpha for every texel.
		for (unsigned int uiWidth = 0; uiWidth < m_uiDiameter; ++uiWidth)
		{
			for (unsigned int uiHeight = 0; uiHeight < m_uiDiameter; ++uiHeight)
			{
				D3DXVECTOR2 vecRelativePixelPos(static_cast<float>(uiWidth) - kfRadius,
												static_cast<float>(uiHeight) - kfRadius);	// This texel's position relative to the centre of the image.

				float fTexelAlpha = D3DXVec2Length(&vecRelativePixelPos) * kfRadiusFraction;	// Scalar value between 0.0f and 1.0f (capped at 1.0f).
				fTexelAlpha = 1.0f - (fTexelAlpha * fTexelAlpha);	// Squaring the value makes the radiant light stand out more.

				pPixels[(uiHeight * uiNumPixelsWide) + uiWidth] = D3DCOLOR_ARGB(fTexelAlpha <= 0.0f ? 0 : static_cast<unsigned char>(fTexelAlpha * MathUtility::kMaxUC), 192, 128, 32);
			}
		}

		pSurface->UnlockRect();
	}
	else
	{
		assert(false);
		pSurface->Release();
		pTexture->Release();
		return false;
	}

	// Release the surface (texture has it's own reference).
	pSurface->Release();

	// Save the texture to the texture manager.
	CTextureManager& rTextureManager = m_pRenderer->GetTextureManager();

	if (m_iRadiantTextureID != Utility::INVALID_ID)
	{
		rTextureManager.RemoveTexture(m_iRadiantTextureID);
	}

	m_iRadiantTextureID = m_pRenderer->GetTextureManager().LoadTextureMemory(pTexture);

	if (m_iRadiantTextureID == Utility::INVALID_ID)
	{
		pTexture->Release();
		return false;
	}

	return true;
}
Exemplo n.º 7
0
bool Surface::swap()
{
    if (mSwapChain)
    {
        IDirect3DTexture9 *flipTexture = mFlipTexture;
        flipTexture->AddRef();

        IDirect3DSurface9 *renderTarget = mRenderTarget;
        renderTarget->AddRef();

        EGLint oldWidth = mWidth;
        EGLint oldHeight = mHeight;

        checkForWindowResize();

        IDirect3DDevice9 *device = mDisplay->getDevice();

        IDirect3DSurface9 *textureSurface;
        flipTexture->GetSurfaceLevel(0, &textureSurface);

        mDisplay->endScene();
        device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
        renderTarget->Release();

        applyFlipState(device);
        device->SetTexture(0, flipTexture);

        float xscale = (float)mWidth / oldWidth;
        float yscale = (float)mHeight / oldHeight;

        // Render the texture upside down into the back buffer
        // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
        float quad[4][6] = {{     0 - 0.5f,       0 - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f       },
                            {mWidth - 0.5f,       0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f       },
                            {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
                            {     0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f,   1.0f-yscale}};   // x, y, z, rhw, u, v

        mDisplay->startScene();
        device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));

        flipTexture->Release();
        textureSurface->Release();

        restoreState(device);

        mDisplay->endScene();
        HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval());

        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
        {
            return error(EGL_BAD_ALLOC, false);
        }

        if (result == D3DERR_DEVICELOST)
        {
            return error(EGL_CONTEXT_LOST, false);
        }

        ASSERT(SUCCEEDED(result));

    }

    return true;
}