Beispiel #1
0
// interface functions
void MFTexture_CreatePlatformSpecific(MFTexture *pTexture, bool generateMipChain)
{
	MFTextureTemplateData *pTemplate = pTexture->pTemplateData;

	// create texture
	D3DFORMAT platformFormat = (D3DFORMAT)MFTexture_GetPlatformFormatID(pTemplate->imageFormat, MFDD_XBOX);

#if defined(XB_XGTEXTURES)
	pTexture->pTexture = &pTexture->texture;
	XGSetTextureHeader(pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, 1, 0, platformFormat, 0, pTexture->pTexture, 0, 0);
	pTexture->pTexture->Register(pTemplate->pSurfaces[0].pImageData);

	if(pTemplate->imageFormat >= TexFmt_XB_A8R8G8B8s && pTemplate->imageFormat <= TexFmt_XB_R4G4B4A4s)
	{
		XGSwizzleRect(pTemplate->pSurfaces[0].pImageData, 0, NULL, pTemplate->pSurfaces[0].pImageData, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, NULL, pTemplate->pSurfaces[0].bitsPerPixel/8);
	}
#else

	HRESULT hr;
	hr = D3DXCreateTexture(pd3dDevice, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, generateMipChain ? 0 : 1, 0, platformFormat, 0, &pTexture->pTexture);

	MFDebug_Assert(hr != D3DERR_NOTAVAILABLE, MFStr("LoadTexture failed: D3DERR_NOTAVAILABLE, 0x%08X", hr));
	MFDebug_Assert(hr != D3DERR_OUTOFVIDEOMEMORY, MFStr("LoadTexture failed: D3DERR_OUTOFVIDEOMEMORY, 0x%08X", hr));
	MFDebug_Assert(hr != D3DERR_INVALIDCALL, MFStr("LoadTexture failed: D3DERR_INVALIDCALL, 0x%08X", hr));
	MFDebug_Assert(hr != D3DXERR_INVALIDDATA, MFStr("LoadTexture failed: D3DXERR_INVALIDDATA, 0x%08X", hr));

	MFDebug_Assert(hr == D3D_OK, MFStr("Failed to create texture '%s'.", pTexture->name));

	// copy image data
	D3DLOCKED_RECT rect;
	pTexture->pTexture->LockRect(0, &rect, NULL, 0);

	if(pTemplate->imageFormat >= TexFmt_XB_A8R8G8B8s && pTemplate->imageFormat <= TexFmt_XB_R4G4B4A4s)
	{
		XGSwizzleRect(pTemplate->pSurfaces[0].pImageData, 0, NULL, rect.pBits, pTemplate->pSurfaces[0].width, pTemplate->pSurfaces[0].height, NULL, pTemplate->pSurfaces[0].bitsPerPixel/8);
	}
	else
	{
		MFCopyMemory(rect.pBits, pTemplate->pSurfaces[0].pImageData, pTemplate->pSurfaces[0].bufferLength);
	}

	pTexture->pTexture->UnlockRect(0);

	// filter mip levels
	if(generateMipChain)
		D3DXFilterTexture(pTexture->pTexture, NULL, 0, D3DX_DEFAULT);
#endif
}
Beispiel #2
0
void RageDisplay_D3D::UpdateTexture( 
	unsigned uTexHandle, 
	RageSurface* img,
	int xoffset, int yoffset, int width, int height )
{
	IDirect3DTexture9* pTex = (IDirect3DTexture9*)uTexHandle;
	ASSERT( pTex != NULL );
	
	RECT rect; 
	rect.left = xoffset;
	rect.top = yoffset;
	rect.right = width - xoffset;
	rect.bottom = height - yoffset;

	D3DLOCKED_RECT lr;
	pTex->LockRect( 0, &lr, &rect, 0 );
	
	D3DSURFACE_DESC desc;
	pTex->GetLevelDesc(0, &desc);
	ASSERT( xoffset+width <= int(desc.Width) );
	ASSERT( yoffset+height <= int(desc.Height) );

	//
	// Copy bits
	//
#if defined(XBOX)
	// Xbox textures need to be swizzled
	XGSwizzleRect(
		img->pixels,	// pSource, 
		img->pitch,		// Pitch,
		NULL,	// pRect,
		lr.pBits,	// pDest,
		img->w,	// Width,
		img->h,	// Height,
		NULL,	// pPoint,
		img->format->BytesPerPixel ); //BytesPerPixel
#else
	int texpixfmt;
	for(texpixfmt = 0; texpixfmt < NUM_PIX_FORMATS; ++texpixfmt)
		if(D3DFORMATS[texpixfmt] == desc.Format) break;
	ASSERT( texpixfmt != NUM_PIX_FORMATS );

	RageSurface *Texture = CreateSurfaceFromPixfmt(RagePixelFormat(texpixfmt), lr.pBits, width, height, lr.Pitch);
	ASSERT( Texture );
	RageSurfaceUtils::Blit( img, Texture, width, height );

	delete Texture;
#endif

	pTex->UnlockRect( 0 );
}
Beispiel #3
0
//-----------------------------------------------------------------------------
// Name: XBUtil_SwizzleTexture2D()
// Desc: Swizzles a 2D texture before it gets unlocked. Note: this operation
//       can be very slow.
//-----------------------------------------------------------------------------
VOID XBUtil_SwizzleTexture2D( D3DLOCKED_RECT* pLock, const D3DSURFACE_DESC* pDesc )
{
    DWORD dwPixelSize   = XGBytesPerPixelFromFormat( pDesc->Format );
    DWORD dwTextureSize = pDesc->Width * pDesc->Height * dwPixelSize;

    BYTE* pSrcBits = new BYTE[ dwTextureSize ];
    memcpy( pSrcBits, pLock->pBits, dwTextureSize );
    
    XGSwizzleRect( pSrcBits, 0, NULL, pLock->pBits,
                  pDesc->Width, pDesc->Height, 
                  NULL, dwPixelSize );

    SAFE_DELETE_ARRAY( pSrcBits );
}
Beispiel #4
0
void Font::RenderToTexture(CSurface &texture, const string &str, dword height, dword style, D3DXCOLOR color, int maxWidth, bool fade)
{
    xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data;
    if (m_pFont == NULL)
        return;

    m_pFont->SetTextHeight(height);
    m_pFont->SetTextStyle(style);
    m_pFont->SetTextColor(color);

    dword dwMaxWidth = (maxWidth <= 0) ? 1000 : maxWidth;

    // get the exact width and height required to display the string
    dword dwRequiredWidth = GetRequiredWidth(str, height, style);
    dword dwRequiredHeight = GetRequiredHeight(str, height, style);;

    // calculate the texture width and height needed to display the font
    dword dwTextureWidth  = dwRequiredWidth * 2;
    dword dwTextureHeight = dwRequiredHeight * 2;
    {
        // because the textures are swizzled we make sure
        // the dimensions are a power of two
        for(dword wmask = 1; dwTextureWidth &(dwTextureWidth - 1); wmask = (wmask << 1 ) + 1)
            dwTextureWidth = (dwTextureWidth + wmask) & ~wmask;

        for(dword hmask = 1; dwTextureHeight &(dwTextureHeight - 1); hmask = (hmask << 1) + 1)
            dwTextureHeight = ( dwTextureHeight + hmask ) & ~hmask;

        // also enforce a minimum pitch of 64 bytes
        dwTextureWidth = max(64 / XGBytesPerPixelFromFormat(D3DFMT_A8R8G8B8), dwTextureWidth);
    }

    // create an temporary image surface to render to
    D3DSurface *pTempSurface;
    d3d->d3d_render_device->CreateImageSurface(dwTextureWidth, dwTextureHeight, D3DFMT_LIN_A8R8G8B8, &pTempSurface);

    // clear the temporary surface
    {
        D3DLOCKED_RECT tmpLr;
        pTempSurface->LockRect(&tmpLr, NULL, 0);
        memset(tmpLr.pBits, 0, dwTextureWidth * dwTextureHeight * XGBytesPerPixelFromFormat(D3DFMT_A8R8G8B8));
        pTempSurface->UnlockRect();
    }

    // render the text to the temporary surface
    word *wcBuf = StringToWChar(str);
    m_pFont->TextOut(pTempSurface, wcBuf, -1, 0, 0);
    delete [] wcBuf;

    // create the texture that will be drawn to the screen
    texture.Destroy();
    texture.Create(dwTextureWidth, dwTextureHeight);

    // copy from the temporary surface to the final texture
    {
        D3DLOCKED_RECT tmpLr;
        D3DLOCKED_RECT txtLr;

        pTempSurface->LockRect(&tmpLr, NULL, 0);
        texture.GetTexture()->LockRect(0, &txtLr, NULL, 0);

        if (fade)
        {
            // draw the last 35 pixels of the string fading out to max width or texture width
            dword dwMinFadeDistance = min(static_cast<dword>(dwTextureWidth * 0.35), 35);
            dword dwFadeStart               = min(dwTextureWidth, dwMaxWidth - dwMinFadeDistance);
            dword dwFadeEnd                 = min(dwTextureWidth, dwMaxWidth);
            dword dwFadeDistance    = dwFadeEnd - dwFadeStart;

            for (dword h = 0; h < dwTextureHeight; h++)
            {
                for (dword w = 0; w < dwFadeDistance; w++)
                {
                    dword *pColor = reinterpret_cast<dword *>(tmpLr.pBits);
                    dword offset = (h * dwTextureWidth) + (dwFadeStart + w);

                    D3DXCOLOR color = D3DXCOLOR(pColor[offset]);
                    color.a = color.a * (1.0f - static_cast<float>(w) / static_cast<float>(dwFadeDistance));
                    pColor[offset] = color;
                }
            }
        }

        // dont draw anything > than max width
        for (dword h = 0; h < dwTextureHeight; h++)
        {
            for (dword w = min(dwTextureWidth, dwMaxWidth); w < dwTextureWidth; w++)
            {
                dword *pColor = reinterpret_cast<dword *>(tmpLr.pBits);
                dword offset = (h * dwTextureWidth) + w;

                D3DXCOLOR color = D3DXCOLOR(pColor[offset]);
                color.a = 0.0;
                pColor[offset] = color;
            }
        }

        // copy and swizzle the linear surface to the swizzled texture
        XGSwizzleRect(tmpLr.pBits, tmpLr.Pitch, NULL, txtLr.pBits, dwTextureWidth, dwTextureHeight, NULL, 4);

        texture.GetTexture()->UnlockRect(0);
        pTempSurface->UnlockRect();
    }

    pTempSurface->Release();
}
Beispiel #5
0
//-----------------------------------------------------------------------------
// Name: XBUtil_CreateNormalizationCubeMap()
// Desc: Creates a cubemap and fills it with normalized RGBA vectors
//-----------------------------------------------------------------------------
HRESULT XBUtil_CreateNormalizationCubeMap( LPDIRECT3DDEVICE8 pd3dDevice, 
                                           DWORD dwSize, 
                                           LPDIRECT3DCUBETEXTURE8* ppCubeMap )
{
    HRESULT hr;

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

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

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

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

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

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

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

    // Free temp space
    SAFE_DELETE_ARRAY( pSourceBits );

    return S_OK;
}