// 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, ¤tSurface); 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, ¤tSurface); 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(); } } }
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" ); }
//--------------------------------------------------------------------- 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; }
/** * * 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; }
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; }