コード例 #1
0
ファイル: Texture2d.cpp プロジェクト: foolhuang/Helium
//PMDTODO: Implement this
/// @copydoc Resource::SerializePersistentResourceData()
void Texture2d::SerializePersistentResourceData( Serializer& s )
{
    uint32_t baseLevelWidth = 0;
    uint32_t baseLevelHeight = 0;
    uint32_t mipCount = 0;
    int32_t pixelFormatIndex = RENDERER_PIXEL_FORMAT_INVALID;

    RTexture2d* pTexture2d = static_cast< RTexture2d* >( m_spTexture.Get() );
    if( pTexture2d )
    {
        baseLevelWidth = pTexture2d->GetWidth();
        baseLevelHeight = pTexture2d->GetHeight();
        mipCount = pTexture2d->GetMipCount();
        pixelFormatIndex = pTexture2d->GetPixelFormat();
    }

    s << baseLevelWidth;
    s << baseLevelHeight;
    s << mipCount;
    s << pixelFormatIndex;

    if( s.GetMode() == Serializer::MODE_LOAD )
    {
        m_spTexture.Release();

        Renderer* pRenderer = Renderer::GetStaticInstance();
        if( pRenderer &&
            baseLevelWidth != 0 &&
            baseLevelHeight != 0 &&
            mipCount != 0 &&
            static_cast< uint32_t >( pixelFormatIndex ) < static_cast< uint32_t >( RENDERER_PIXEL_FORMAT_MAX ) )
        {
            m_spTexture = pRenderer->CreateTexture2d(
                baseLevelWidth,
                baseLevelHeight,
                mipCount,
                static_cast< ERendererPixelFormat >( pixelFormatIndex ),
                RENDERER_BUFFER_USAGE_STATIC );
            if( !m_spTexture )
            {
                HELIUM_TRACE(
                    TraceLevels::Error,
                    ( TXT( "Texture2d::SerializePersistentResourceData(): Failed to create texture render " )
                    TXT( "resource (width: %" ) TPRIu32 TXT( "; height: %" ) TPRIu32 TXT( "; mip count: %" )
                    TPRIu32 TXT( "; pixel format index: %" ) TPRId32 TXT( ").\n" ) ),
                    baseLevelWidth,
                    baseLevelHeight,
                    mipCount,
                    pixelFormatIndex );
            }
        }
    }
}
コード例 #2
0
/// Reinitialize any resources dependent on graphics configuration settings.
///
/// This can be called during runtime when the graphics configuration settings change to reconstruct states and
/// other resources that are dependent on certain graphics configuration settings (i.e. default texture filtering
/// mode).  Existing resources that are reinitialized will have their reference counts decremented and will be
/// cleared out of this manager.  If no renderer is initialized, resources will remain null.
///
/// @see Initialize(), Shutdown()
void RenderResourceManager::PostConfigUpdate()
{
    // Release resources that are dependent on configuration settings.
    RSamplerStatePtr* pLinearSamplerStates = m_samplerStates[ TEXTURE_FILTER_LINEAR ];
    for( size_t addressModeIndex = 0; addressModeIndex < RENDERER_TEXTURE_ADDRESS_MODE_MAX; ++addressModeIndex )
    {
        pLinearSamplerStates[ addressModeIndex ].Release();
    }

    m_spShadowDepthTexture.Release();
    m_spSceneTexture.Release();

    // Get the renderer and graphics configuration.
    Renderer* pRenderer = Renderer::GetStaticInstance();
    if( !pRenderer )
    {
        return;
    }

    Config& rConfig = Config::GetStaticInstance();
    StrongPtr< GraphicsConfig > spGraphicsConfig(
        rConfig.GetConfigObject< GraphicsConfig >( Name( TXT( "GraphicsConfig" ) ) ) );
    if( !spGraphicsConfig )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "RenderResourceManager::PostConfigUpdate(): Initialization failed; missing GraphicsConfig.\n" ) );

        return;
    }

    // Create the standard linear-filtering sampler states.
    RSamplerState::Description samplerStateDesc;
    samplerStateDesc.addressModeW = RENDERER_TEXTURE_ADDRESS_MODE_CLAMP;
    samplerStateDesc.mipLodBias = 0;
    samplerStateDesc.maxAnisotropy = spGraphicsConfig->GetMaxAnisotropy();

    GraphicsConfig::ETextureFilter textureFiltering = spGraphicsConfig->GetTextureFiltering();
    switch( textureFiltering )
    {
    case GraphicsConfig::ETextureFilter::TRILINEAR:
        {
            samplerStateDesc.filter = RENDERER_TEXTURE_FILTER_MIN_LINEAR_MAG_LINEAR_MIP_LINEAR;
            break;
        }

    case GraphicsConfig::ETextureFilter::ANISOTROPIC:
        {
            samplerStateDesc.filter = RENDERER_TEXTURE_FILTER_ANISOTROPIC;
            break;
        }

    case GraphicsConfig::ETextureFilter::BILINEAR:
    default:
        {
            samplerStateDesc.filter = RENDERER_TEXTURE_FILTER_MIN_LINEAR_MAG_LINEAR_MIP_POINT;
            break;
        }
    }

    for( size_t addressModeIndex = 0; addressModeIndex < RENDERER_TEXTURE_ADDRESS_MODE_MAX; ++addressModeIndex )
    {
        ERendererTextureAddressMode addressMode = static_cast< ERendererTextureAddressMode >( addressModeIndex );
        samplerStateDesc.addressModeU = addressMode;
        samplerStateDesc.addressModeV = addressMode;
        samplerStateDesc.addressModeW = addressMode;

        pLinearSamplerStates[ addressModeIndex ] = pRenderer->CreateSamplerState( samplerStateDesc );
        HELIUM_ASSERT( pLinearSamplerStates[ addressModeIndex ] );
    }

    // Create the scene color target and shadow buffer depth textures.  Due to restrictions with render target
    // settings on certain platforms (namely when using Direct3D), these must be the same size.
    // XXX WDI: Implement support for the NULL FOURCC format for Direct3D to avoid this restriction when possible.
    uint32_t bufferWidth = pRenderer->GetMainContextWidth();
    uint32_t bufferHeight = pRenderer->GetMainContextHeight();

    GraphicsConfig::EShadowMode shadowMode = GraphicsConfig::EShadowMode::NONE;
    uint32_t shadowBufferUsableSize = 0;

    if( pRenderer->SupportsAnyFeature( RENDERER_FEATURE_FLAG_DEPTH_TEXTURE ) )
    {
        shadowMode = spGraphicsConfig->GetShadowMode();
        if( shadowMode != GraphicsConfig::EShadowMode::INVALID && shadowMode != GraphicsConfig::EShadowMode::NONE )
        {
            shadowBufferUsableSize = spGraphicsConfig->GetShadowBufferSize();
            if( shadowBufferUsableSize != 0 )
            {
                if( bufferWidth < shadowBufferUsableSize )
                {
                    bufferWidth = shadowBufferUsableSize;
                }

                if( bufferHeight < shadowBufferUsableSize )
                {
                    bufferHeight = shadowBufferUsableSize;
                }

                m_spShadowDepthTexture = pRenderer->CreateTexture2d(
                    bufferWidth,
                    bufferHeight,
                    1,
                    RENDERER_PIXEL_FORMAT_DEPTH,
                    RENDERER_BUFFER_USAGE_DEPTH_STENCIL );
                if( !m_spShadowDepthTexture )
                {
                    HELIUM_TRACE(
                        TRACE_ERROR,
                        ( TXT( "Failed to create shadow depth texture of size %" ) TPRIu32 TXT( "x%" ) TPRIu32
                        TXT( ".\n" ) ),
                        bufferWidth,
                        bufferHeight );

                    shadowMode = GraphicsConfig::EShadowMode::NONE;
                    shadowBufferUsableSize = 0;
                }
            }
        }
    }

    m_shadowMode = shadowMode;
    m_shadowDepthTextureUsableSize = shadowBufferUsableSize;

    m_spSceneTexture = pRenderer->CreateTexture2d(
        bufferWidth,
        bufferHeight,
        1,
        RENDERER_PIXEL_FORMAT_R16G16B16A16_FLOAT,
        RENDERER_BUFFER_USAGE_RENDER_TARGET );
    if( !m_spSceneTexture )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "Failed to create scene render texture of size %" ) TPRIu32 TXT( "x%" ) TPRIu32 TXT( ".\n" ),
            bufferWidth,
            bufferHeight );
    }
}
コード例 #3
0
/// Reconstruct render resources based on the maximum render viewport size.
///
/// @param[in] width   Maximum viewport width, in pixels.
/// @param[in] height  Maximum viewport height, in pixels.
void RenderResourceManager::UpdateMaxViewportSize( uint32_t width, uint32_t height )
{
	if ( width == m_viewportWidthMax && height == m_viewportHeightMax )
	{
		return;
	}

	m_spDepthStencilSurface.Release();
	m_spShadowDepthTexture.Release();
	m_spSceneTexture.Release();

	Renderer* pRenderer = Renderer::GetInstance();
	if ( !pRenderer )
	{
		m_viewportWidthMax = 0;
		m_viewportHeightMax = 0;
		m_shadowMode = GraphicsConfig::EShadowMode::NONE;
		m_shadowDepthTextureUsableSize = 0;

		return;
	}

	// Don't create any surfaces for zero-sized viewports.
	if ( width == 0 || height == 0 )
	{
		m_viewportWidthMax = 0;
		m_viewportHeightMax = 0;

		return;
	}

	// Due to restrictions with render target settings on certain platforms (namely when using Direct3D), the scene
	// texture, depth-stencil surface, and shadow depth texture must all be the same size.
	// XXX WDI: Implement support for the NULL FOURCC format for Direct3D to avoid this restriction when possible.
	uint32_t bufferWidth = Max( width, m_shadowDepthTextureUsableSize );
	uint32_t bufferHeight = Max( height, m_shadowDepthTextureUsableSize );

	m_spSceneTexture = pRenderer->CreateTexture2d(
		bufferWidth,
		bufferHeight,
		1,
		RENDERER_PIXEL_FORMAT_R16G16B16A16_FLOAT,
		RENDERER_BUFFER_USAGE_RENDER_TARGET );
	if ( !m_spSceneTexture )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			"Failed to create scene render texture of size %" PRIu32 "x%" PRIu32 ".\n",
			bufferWidth,
			bufferHeight );
	}

	m_spDepthStencilSurface = pRenderer->CreateDepthStencilSurface(
		bufferWidth,
		bufferHeight,
		RENDERER_SURFACE_FORMAT_DEPTH_STENCIL,
		0 );
	if ( !m_spDepthStencilSurface )
	{
		HELIUM_TRACE(
			TraceLevels::Error,
			"Failed to create scene depth-stencil surface of size %" PRIu32 "x%" PRIu32 ".\n",
			bufferWidth,
			bufferHeight );
	}

	if ( m_shadowMode != GraphicsConfig::EShadowMode::NONE && m_shadowMode != GraphicsConfig::EShadowMode::INVALID &&
		m_shadowDepthTextureUsableSize != 0 )
	{
		m_spShadowDepthTexture = pRenderer->CreateTexture2d(
			bufferWidth,
			bufferHeight,
			1,
			RENDERER_PIXEL_FORMAT_DEPTH,
			RENDERER_BUFFER_USAGE_DEPTH_STENCIL );
		if ( !m_spShadowDepthTexture )
		{
			HELIUM_TRACE(
				TraceLevels::Error,
				"Failed to create shadow depth texture of size %" PRIu32 "x%" PRIu32 ".\n",
				bufferWidth,
				bufferHeight );
		}
	}
}
コード例 #4
0
ファイル: Font.cpp プロジェクト: kevindqc/Helium
/// @copydoc Asset::BeginPrecacheResourceData()
bool Font::BeginPrecacheResourceData()
{
    uint_fast8_t textureCount = m_persistentResourceData.m_textureCount;
    HELIUM_ASSERT( m_persistentResourceData.m_pspTextures || textureCount == 0 );

    // If we have don't have a renderer, we don't need to load the texture sheets.
    Renderer* pRenderer = Renderer::GetStaticInstance();
    if( !pRenderer )
    {
        for( uint_fast8_t textureIndex = 0; textureIndex < textureCount; ++textureIndex )
        {
            m_persistentResourceData.m_pspTextures[ textureIndex ].Release();
            SetInvalid( m_persistentResourceData.m_pTextureLoadIds[ textureIndex ] );
        }

        return true;
    }

    // Allocate and begin loading texture resources.
    ERendererPixelFormat format =
        ( m_textureCompression == ECompression::COLOR_COMPRESSED ? RENDERER_PIXEL_FORMAT_BC1 : RENDERER_PIXEL_FORMAT_R8 );
    size_t blockRowCount = RendererUtil::PixelToBlockRowCount( m_textureSheetHeight, format );

    uint16_t textureSheetWidth = Max< uint16_t >( m_textureSheetWidth, 1 );
    uint16_t textureSheetHeight = Max< uint16_t >( m_textureSheetHeight, 1 );

    for( uint_fast8_t textureIndex = 0; textureIndex < textureCount; ++textureIndex )
    {
        RTexture2d* pTexture = NULL;

        size_t loadId;
        SetInvalid( loadId );

        size_t textureSize = GetSubDataSize( textureIndex );
        if( IsInvalid( textureSize ) )
        {
            HELIUM_TRACE(
                TraceLevels::Error,
                ( TXT( "Font::BeginPrecacheResourceData(): Unable to locate cached texture data for texture sheet %" )
                  PRIuFAST8 TXT( " of font \"%s\".\n" ) ),
                textureIndex,
                *GetPath().ToString() );
        }
        else
        {
            pTexture = pRenderer->CreateTexture2d(
                textureSheetWidth,
                textureSheetHeight,
                1,
                format,
                RENDERER_BUFFER_USAGE_STATIC );
            if( !pTexture )
            {
                HELIUM_TRACE(
                    TraceLevels::Error,
                    ( TXT( "Font::BeginPrecacheResourceData(): Failed to allocate %" ) PRIu16 TXT( "x%") PRIu16
                      TXT( " texture for texture sheet %" ) PRIuFAST8 TXT( " of font \"%s\".\n" ) ),
                    textureSheetWidth,
                    textureSheetHeight,
                    textureIndex,
                    *GetPath().ToString() );
            }
            else
            {
                size_t pitch = 0;
                void* pMappedData = pTexture->Map( 0, pitch );
                HELIUM_ASSERT( pMappedData );

                textureSize = Min( textureSize, pitch * blockRowCount );

                loadId = BeginLoadSubData( pMappedData, textureIndex, textureSize );
                if( IsInvalid( loadId ) )
                {
                    HELIUM_TRACE(
                        TraceLevels::Error,
                        ( TXT( "Font::BeginPrecacheResourceData(): Failed to begin loading texture sheet %" ) PRIuFAST8
                          TXT( " of font \"%s\".\n" ) ),
                        textureIndex,
                        *GetPath().ToString() );

                    pTexture->Unmap( 0 );
                }
            }
        }

        m_persistentResourceData.m_pspTextures[ textureIndex ] = pTexture;
        m_persistentResourceData.m_pTextureLoadIds[ textureIndex ] = loadId;
    }

    return true;
}