//=========================================================================================================================
void TextureManager::WriteTGAToFile(LPCWSTR filename, ID3D11ShaderResourceView* textureSRV)
{
    // https://directxtex.codeplex.com/wikipage?title=CaptureTexture

    ID3D11Texture2D *textureInterface = 0;
    ID3D11Resource *textureResource;
    textureSRV->GetResource(&textureResource);
    textureResource->QueryInterface<ID3D11Texture2D>(&textureInterface);

    HRESULT result;
    //ScratchImage image;
    ScratchImage image;
    result = CaptureTexture(mD3DSystem->GetDevice11(), mD3DSystem->GetDeviceContext(), textureInterface, image);

    if (SUCCEEDED(result))
    {
        result = SaveToTGAFile(*image.GetImages(), filename);

        if (FAILED(result))
        {
            ZShadeMessageCenter::MsgBoxError(NULL, "Failed to save TGA texture !!");
        }
    }

    SAFE_RELEASE(textureInterface);
    SAFE_RELEASE(textureResource);
}
//===============================================================================================================================
void TextureManager::WritePNGToFile(LPCWSTR filename, ID3D11ShaderResourceView* textureSRV)
{
    ID3D11Texture2D *textureInterface = 0;
    ID3D11Resource *textureResource;
    textureSRV->GetResource(&textureResource);
    textureResource->QueryInterface<ID3D11Texture2D>(&textureInterface);

    HRESULT result;
    result = SaveWICTextureToFile(mD3DSystem->GetDeviceContext(), textureInterface, GUID_ContainerFormatPng, filename);

    if (FAILED(result))
    {
        ScratchImage image;
        result = CaptureTexture(mD3DSystem->GetDevice11(), mD3DSystem->GetDeviceContext(), textureInterface, image);

        if (SUCCEEDED(result))
        {
            result = SaveToWICFile(image.GetImages(), image.GetImageCount(), WIC_FLAGS_NONE, GUID_ContainerFormatPng, filename);

            if (FAILED(result))
            {
                ZShadeMessageCenter::MsgBoxError(NULL, "Failed to save PNG texture !!");
            }
        }
    }

    SAFE_RELEASE(textureInterface);
    SAFE_RELEASE(textureResource);
}
Beispiel #3
0
//-------------------------------------------------------------------------------------
// Compression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Compress( const Image& srcImage, DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& image )
{
    if ( IsCompressed(srcImage.format) || !IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    // Image size must be a multiple of 4 (degenerate cases for mipmaps are allowed)
    bool degenerate = false;

    size_t width = srcImage.width;
    if ( (width % 4) != 0 )
    {
        if ( width != 1 && width != 2 )
            return E_INVALIDARG;

        degenerate = true;
    }

    size_t height = srcImage.height;
    if ( (height % 4) != 0 )
    {
        if ( height != 1 && height != 2 )
            return E_INVALIDARG;

        degenerate = true;
    }

    // Create compressed image
    HRESULT hr = image.Initialize2D( format, width, height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Compress single image
    if ( (compress & TEX_COMPRESS_PARALLEL) && !degenerate )
    {
#ifndef _OPENMP
        return E_NOTIMPL;
#else
        hr = _CompressBC_Parallel( srcImage, *img, _GetBCFlags( compress ), alphaRef );
#endif // _OPENMP
    }
    else
    {
        hr = _CompressBC( srcImage, *img, _GetBCFlags( compress ), alphaRef, degenerate );
    }

    if ( FAILED(hr) )
        image.Release();

    return hr;
}
Beispiel #4
0
//-------------------------------------------------------------------------------------
// Resize image
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Resize( const Image& srcImage, size_t width, size_t height, DWORD filter, ScratchImage& image )
{
    if ( width == 0 || height == 0 )
        return E_INVALIDARG;

#ifdef _M_X64
    if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) )
        return E_INVALIDARG;

    if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    if ( !srcImage.pixels )
        return E_POINTER;

    if ( IsCompressed( srcImage.format ) )
    {
        // We don't support resizing compressed images
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    HRESULT hr = image.Initialize2D( srcImage.format, width, height, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
        return E_POINTER;

    if ( _UseWICFiltering( srcImage.format, filter ) )
    {
        WICPixelFormatGUID pfGUID;
        if ( _DXGIToWIC( srcImage.format, pfGUID, true ) )
        {
            // Case 1: Source format is supported by Windows Imaging Component
            hr = _PerformResizeUsingWIC( srcImage, filter, pfGUID, *rimage );
        }
        else
        {
            // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
            hr = _PerformResizeViaF32( srcImage, filter, *rimage );
        }
    }
    else
    {
        hr = _PerformResizeUsingCustomFilters( srcImage, filter, *rimage );
    }

    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
//===============================================================================================================================
HRESULT TextureManager::LoadDDSTextureFromFile(LPCWSTR tex_filename, ID3D11ShaderResourceView** srv)
{
    HRESULT hr;

    TexMetadata imageMetadata;
    ScratchImage* image = new ScratchImage();

    hr = LoadFromDDSFile(tex_filename, DDS_FLAGS_NONE, &imageMetadata, *image);

    hr = CreateShaderResourceView(mD3DSystem->GetDevice11(), image->GetImages(), image->GetImageCount(), imageMetadata, srv);

    return hr;
}
void SaveTextureAsDDS(ID3D11Resource* texture, const wchar* filePath)
{
    ID3D11DevicePtr device;
    texture->GetDevice(&device);

    ID3D11DeviceContextPtr context;
    device->GetImmediateContext(&context);

    ScratchImage scratchImage;
    DXCall(CaptureTexture(device, context, texture, scratchImage));
    DXCall(SaveToDDSFile(scratchImage.GetImages(), scratchImage.GetImageCount(),
                         scratchImage.GetMetadata(), DDS_FLAGS_FORCE_DX10_EXT, filePath));
}
void SaveTextureAsPNG(ID3D11Resource* texture, const wchar* filePath)
{
    ID3D11DevicePtr device;
    texture->GetDevice(&device);

    ID3D11DeviceContextPtr context;
    device->GetImmediateContext(&context);

    ScratchImage scratchImage;
    DXCall(CaptureTexture(device, context, texture, scratchImage));

    DXCall(SaveToWICFile(scratchImage.GetImages(), scratchImage.GetImageCount(), WIC_FLAGS_NONE,
                         GetWICCodec(WIC_CODEC_PNG), filePath));
}
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::Decompress(
    const Image& cImage,
    DXGI_FORMAT format,
    ScratchImage& image)
{
    if (!IsCompressed(cImage.format) || IsCompressed(format))
        return E_INVALIDARG;

    if (format == DXGI_FORMAT_UNKNOWN)
    {
        // Pick a default decompressed format based on BC input format
        format = DefaultDecompress(cImage.format);
        if (format == DXGI_FORMAT_UNKNOWN)
        {
            // Input is not a compressed format
            return E_INVALIDARG;
        }
    }
    else
    {
        if (!IsValid(format))
            return E_INVALIDARG;

        if (IsTypeless(format) || IsPlanar(format) || IsPalettized(format))
            return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
    }

    // Create decompressed image
    HRESULT hr = image.Initialize2D(format, cImage.width, cImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *img = image.GetImage(0, 0, 0);
    if (!img)
    {
        image.Release();
        return E_POINTER;
    }

    // Decompress single image
    hr = DecompressBC(cImage, *img);
    if (FAILED(hr))
        image.Release();

    return hr;
}
//-------------------------------------------------------------------------------------
// Compression
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::Compress(
    const Image& srcImage,
    DXGI_FORMAT format,
    DWORD compress,
    float threshold,
    ScratchImage& image)
{
    if (IsCompressed(srcImage.format) || !IsCompressed(format))
        return E_INVALIDARG;

    if (IsTypeless(format)
        || IsTypeless(srcImage.format) || IsPlanar(srcImage.format) || IsPalettized(srcImage.format))
        return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);

    // Create compressed image
    HRESULT hr = image.Initialize2D(format, srcImage.width, srcImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *img = image.GetImage(0, 0, 0);
    if (!img)
    {
        image.Release();
        return E_POINTER;
    }

    // Compress single image
    if (compress & TEX_COMPRESS_PARALLEL)
    {
#ifndef _OPENMP
        return E_NOTIMPL;
#else
        hr = CompressBC_Parallel(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), threshold);
#endif // _OPENMP
    }
    else
    {
        hr = CompressBC(srcImage, *img, GetBCFlags(compress), GetSRGBFlags(compress), threshold);
    }

    if (FAILED(hr))
        image.Release();

    return hr;
}
Beispiel #10
0
//-------------------------------------------------------------------------------------
// Converts to/from a premultiplied alpha version of the texture
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::PremultiplyAlpha(
    const Image& srcImage,
    DWORD flags,
    ScratchImage& image)
{
    if (!srcImage.pixels)
        return E_POINTER;

    if (IsCompressed(srcImage.format)
        || IsPlanar(srcImage.format)
        || IsPalettized(srcImage.format)
        || IsTypeless(srcImage.format)
        || !HasAlpha(srcImage.format))
        return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);

    if ((srcImage.width > UINT32_MAX) || (srcImage.height > UINT32_MAX))
        return E_INVALIDARG;

    HRESULT hr = image.Initialize2D(srcImage.format, srcImage.width, srcImage.height, 1, 1);
    if (FAILED(hr))
        return hr;

    const Image *rimage = image.GetImage(0, 0, 0);
    if (!rimage)
    {
        image.Release();
        return E_POINTER;
    }

    if (flags & TEX_PMALPHA_REVERSE)
    {
        hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? DemultiplyAlpha(srcImage, *rimage) : DemultiplyAlphaLinear(srcImage, flags, *rimage);
    }
    else
    {
        hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(srcImage, *rimage) : PremultiplyAlphaLinear(srcImage, flags, *rimage);
    }
    if (FAILED(hr))
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
Beispiel #11
0
// Executes the basic game loop.
void Game::Tick()
{
    m_timer.Tick([&]()
    {
        Update(m_timer);
    });

    Render();

    if (m_screenshot)
    {
        OutputDebugStringA("Saving screenshot...\n");

        auto commandQ = m_deviceResources->GetCommandQueue();

        DX::ThrowIfFailed(
            SaveDDSTextureToFile(commandQ, m_screenshot.Get(),
                                 L"screenshot.dds",
                                 D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT)
            );

        DX::ThrowIfFailed(
            SaveWICTextureToFile(commandQ, m_screenshot.Get(),
                GUID_ContainerFormatJpeg, L"screenshot.jpg",
                D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT)
            );

        ScratchImage image;
        DX::ThrowIfFailed(CaptureTexture(commandQ, m_screenshot.Get(), false, image,
                                         D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT));

        DX::ThrowIfFailed(SaveToDDSFile(image.GetImages(), image.GetImageCount(), image.GetMetadata(), DDS_FLAGS_NONE, L"screenshot2.dds"));
        DX::ThrowIfFailed(SaveToWICFile(*image.GetImage(0, 0, 0), WIC_FLAGS_NONE, GUID_ContainerFormatJpeg, L"screenshot2.jpg"));

        m_screenshot.Reset();
    }

    ++m_frame;
}
Beispiel #12
0
//-------------------------------------------------------------------------------------
// Converts to a premultiplied alpha version of the texture
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image& srcImage, ScratchImage& image )
{
    if ( !srcImage.pixels )
        return E_POINTER;

    if ( IsCompressed(srcImage.format)
         || IsVideo(srcImage.format)
         || IsTypeless(srcImage.format)
         || !HasAlpha(srcImage.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

#ifdef _M_X64
    if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    HRESULT hr = image.Initialize2D( srcImage.format, srcImage.width, srcImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
    {
        image.Release();
        return E_POINTER;
    }

    hr = _PremultiplyAlpha( srcImage, *rimage );
    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
//-------------------------------------------------------------------------------------
// Decompression
//-------------------------------------------------------------------------------------
HRESULT Decompress( const Image& cImage, DXGI_FORMAT format, ScratchImage& image )
{
    if ( IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        // Pick a default decompressed format based on BC input format
        format = _DefaultDecompress( cImage.format );
        if ( format == DXGI_FORMAT_UNKNOWN )
        {
            // Input is not a compressed format
            return E_INVALIDARG;
        }
    }
    else if ( !IsCompressed(cImage.format) || !IsValid(format) )
        return E_INVALIDARG;

    // Create decompressed image
    HRESULT hr = image.Initialize2D( format, cImage.width, cImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *img = image.GetImage( 0, 0, 0 );
    if ( !img )
    {
        image.Release();
        return E_POINTER;
    }

    // Decompress single image
    hr = _DecompressBC( cImage, *img );
    if ( FAILED(hr) )
        image.Release();

    return hr;
}
//-------------------------------------------------------------------------------------
// Do conversion, flip/rotate using WIC, conversion cycle
//-------------------------------------------------------------------------------------
static HRESULT _PerformFlipRotateViaF32( _In_ const Image& srcImage, _In_ DWORD flags, _In_ const Image& destImage )
{
    if ( !srcImage.pixels || !destImage.pixels )
        return E_POINTER;

    assert( srcImage.format != DXGI_FORMAT_R32G32B32A32_FLOAT );
    assert( srcImage.format == destImage.format );

    ScratchImage temp;
    HRESULT hr = _ConvertToR32G32B32A32( srcImage, temp );
    if ( FAILED(hr) )
        return hr;

    const Image *tsrc = temp.GetImage( 0, 0, 0 );
    if ( !tsrc )
        return E_POINTER;

    ScratchImage rtemp;
    hr = rtemp.Initialize2D( DXGI_FORMAT_R32G32B32A32_FLOAT, destImage.width, destImage.height, 1, 1 );
    if ( FAILED(hr) )
        return hr;

    const Image *tdest = rtemp.GetImage( 0, 0, 0 );
    if ( !tdest )
        return E_POINTER;

    hr = _PerformFlipRotateUsingWIC( *tsrc, flags, GUID_WICPixelFormat128bppRGBAFloat, *tdest );
    if ( FAILED(hr) )
        return hr;

    temp.Release();

    hr = _ConvertFromR32G32B32A32( *tdest, destImage );
    if ( FAILED(hr) )
        return hr;

    return S_OK;
}
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                  DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( !IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    // Image size must be a multiple of 4 (degenerate cases for mipmaps are allowed)
    size_t width = srcImages[0].width;
    if ( (width % 4) != 0 )
    {
        if ( width != 1 && width != 2 )
            return E_INVALIDARG;
    }

    size_t height = srcImages[0].height;
    if ( (height % 4) != 0 )
    {
        if ( height != 1 && height != 2 )
            return E_INVALIDARG;
    }

    cImages.Release();

    TexMetadata mdata2 = metadata;
    mdata2.format = format;
    HRESULT hr = cImages.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != cImages.GetImageCount() )
    {
        cImages.Release();
        return E_FAIL;
    }

    const Image* dest = cImages.GetImages();
    if ( !dest  )
    {
        cImages.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        assert( dest[ index ].format == format );

        const Image& src = srcImages[ index ];

        height = src.height;
        width = src.width;
        if ( width != dest[ index ].width || height != dest[ index ].height )
        {
            cImages.Release();
            return E_FAIL;
        }

        bool degenerate = ((height < 4) || (width < 4)) != 0;

        if ( (compress & TEX_COMPRESS_PARALLEL) && !degenerate)
        {
#ifndef _OPENMP
            return E_NOTIMPL;
#else
            if ( compress & TEX_COMPRESS_PARALLEL )
            {
                hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), alphaRef );
                if ( FAILED(hr) )
                {
                    cImages.Release();
                    return  hr;
                }
            }
#endif // _OPENMP
        }
        else
        {
            hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), alphaRef, degenerate );
            if ( FAILED(hr) )
            {
                cImages.Release();
                return hr;
            }
        }
    }

    return S_OK;
}
Beispiel #16
0
//-------------------------------------------------------------------------------------
// Converts to a premultiplied alpha version of the texture (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT PremultiplyAlpha( const Image* srcImages, size_t nimages, const TexMetadata& metadata, ScratchImage& result )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed(metadata.format)
         || IsVideo(metadata.format)
         || IsTypeless(metadata.format)
         || !HasAlpha(metadata.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

#ifdef _M_X64
    if ( (metadata.width > 0xFFFFFFFF) || (metadata.height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    if ( metadata.IsPMAlpha() )
    {
        // Already premultiplied
        return E_FAIL;
    }

    TexMetadata mdata2 = metadata;
    mdata2.SetAlphaMode(TEX_ALPHA_MODE_PREMULTIPLIED);
    HRESULT hr = result.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != result.GetImageCount() )
    {
        result.Release();
        return E_FAIL;
    }

    const Image* dest = result.GetImages();
    if ( !dest )
    {
        result.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        const Image& src = srcImages[ index ];
        if ( src.format != metadata.format )
        {
            result.Release();
            return E_FAIL;
        }

#ifdef _M_X64
        if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) )
            return E_FAIL;
#endif
        const Image& dst = dest[ index ];
        assert( dst.format == metadata.format );

        if ( src.width != dst.width || src.height != dst.height )
        {
            result.Release();
            return E_FAIL;
        }

        hr = _PremultiplyAlpha( src, dst );
        if ( FAILED(hr) )
        {
            result.Release();
            return hr;
        }
    }

    return S_OK;
}
Beispiel #17
0
//-------------------------------------------------------------------------------------
// Converts to/from a premultiplied alpha version of the texture (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT DirectX::PremultiplyAlpha(
    const Image* srcImages,
    size_t nimages,
    const TexMetadata& metadata,
    DWORD flags,
    ScratchImage& result)
{
    if (!srcImages || !nimages)
        return E_INVALIDARG;

    if (IsCompressed(metadata.format)
        || IsPlanar(metadata.format)
        || IsPalettized(metadata.format)
        || IsTypeless(metadata.format)
        || !HasAlpha(metadata.format))
        return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);

    if ((metadata.width > UINT32_MAX) || (metadata.height > UINT32_MAX))
        return E_INVALIDARG;

    if (metadata.IsPMAlpha() != ((flags & TEX_PMALPHA_REVERSE) != 0))
        return E_FAIL;

    TexMetadata mdata2 = metadata;
    mdata2.SetAlphaMode((flags & TEX_PMALPHA_REVERSE) ? TEX_ALPHA_MODE_STRAIGHT : TEX_ALPHA_MODE_PREMULTIPLIED);
    HRESULT hr = result.Initialize(mdata2);
    if (FAILED(hr))
        return hr;

    if (nimages != result.GetImageCount())
    {
        result.Release();
        return E_FAIL;
    }

    const Image* dest = result.GetImages();
    if (!dest)
    {
        result.Release();
        return E_POINTER;
    }

    for (size_t index = 0; index < nimages; ++index)
    {
        const Image& src = srcImages[index];
        if (src.format != metadata.format)
        {
            result.Release();
            return E_FAIL;
        }

        if ((src.width > UINT32_MAX) || (src.height > UINT32_MAX))
            return E_FAIL;

        const Image& dst = dest[index];
        assert(dst.format == metadata.format);

        if (src.width != dst.width || src.height != dst.height)
        {
            result.Release();
            return E_FAIL;
        }

        if (flags & TEX_PMALPHA_REVERSE)
        {
            hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? DemultiplyAlpha(src, dst) : DemultiplyAlphaLinear(src, flags, dst);
        }
        else
        {
            hr = (flags & TEX_PMALPHA_IGNORE_SRGB) ? PremultiplyAlpha_(src, dst) : PremultiplyAlphaLinear(src, flags, dst);
        }
        if (FAILED(hr))
        {
            result.Release();
            return hr;
        }
    }

    return S_OK;
}
Beispiel #18
0
void DDEngine::ModelObject::loadGeometry(std::vector<Mesh>& meshes)
{
	Importer importer;
	const aiScene* scene = importer.ReadFile(modelPath,
		aiProcess_Triangulate |
		aiProcess_ConvertToLeftHanded |
		aiProcess_FlipUVs |
		aiProcess_SortByPType |
		aiProcess_OptimizeMeshes |
		aiProcess_OptimizeGraph |
		aiProcess_FixInfacingNormals |
		aiProcess_CalcTangentSpace
		);

	if (!scene) {
		Win32Utils::showMessage("Error during loading object.", importer.GetErrorString());
		return;
	}

	const aiVector3D nullVec(0.0f, 0.0f, 0.0f);

	for (size_t i = 0; i < scene->mNumMeshes; i++) {
		const aiMesh* mesh = scene->mMeshes[i];
		Mesh ddeMesh;

		for (size_t j = 0; j < mesh->mNumVertices; j++) {

			const aiVector3D* pos = &(mesh->mVertices[j]);
			const aiVector3D* nor = mesh->HasNormals() ? &(mesh->mNormals[j]) : &nullVec;
			const aiVector3D* tan = mesh->HasTangentsAndBitangents() ? &(mesh->mTangents[j]) : &nullVec;
			const aiVector3D* tex = mesh->HasTextureCoords(0) ? &(mesh->mTextureCoords[0][j]) : &nullVec;

			#define VB(x, y, z, u, v, nx, ny, nz, tx, ty, tz, tw) ddeMesh.VB(VertexPositionNormalTangentTexture(XMFLOAT3(x, y, z), XMFLOAT3(nx, ny, nz), XMFLOAT4(tx, ty, tz, tw), XMFLOAT2(u, v)))

			VB(
				pos->x, pos->y, pos->z,
				tex->x, tex->y,
				nor->x, nor->y, nor->z,
				tan->x, tan->y, tan->z, 0.0f
			);

			ddeMesh.materialIndex = mesh->mMaterialIndex;

		}

		for (size_t j = 0; j < mesh->mNumFaces; j++) {

			const aiFace& face = mesh->mFaces[j];

			switch (face.mNumIndices) {
				case 1: ddeMesh.topology = PrimitiveTopology::POINT_LIST; break;
				case 2: ddeMesh.topology = PrimitiveTopology::LINE_LIST; break;
				case 3: ddeMesh.topology = PrimitiveTopology::TRIANGLE_LIST; break;
				default: ddeMesh.topology = PrimitiveTopology::UNDEFINED; break;
			}

			for (size_t index = 0; index < face.mNumIndices; index++) {
				ddeMesh.IB(face.mIndices[index]);
			}

		}

		meshes.push_back(ddeMesh);
	}

	for (size_t i = 0; i < scene->mNumMaterials; i++) {
		const aiMaterial* material = scene->mMaterials[i];
		Material ddeMaterial;
		ddeMaterial.index = i;

		if (material->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
			aiString Path;

			if (material->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
				Texture tex;
				tex.type = Texture::TextureType::DIFFUSE;

				ShaderResourceView* texture = nullptr;

				std::string path = Path.data;
				std::size_t ext = path.find(".tga");
				ScratchImage image;
				HRESULT hr = -1;

				std::string currentPath = FileUtils::getPath(modelPath) + "/";
				tex.path = currentPath + path;

				if (ext != std::string::npos) {
					hr = LoadFromTGAFile(StringUtils::toWstring(currentPath + path).c_str(), nullptr, image);
				}
				else {
					texture = TextureUtils::createTexture(currentPath + path, *Ctx);
				}

				if (SUCCEEDED(hr)) {
					hr = CreateShaderResourceView(Ctx->device, image.GetImages(), image.GetImageCount(), image.GetMetadata(), &texture);
				}

				if (texture) {
					tex.texture = texture;
					ddeMaterial.textureArray[Texture::TextureType::DIFFUSE] = texture;
					ddeMaterial.textures.push_back(tex);
				}
			}
		
		}

		materials.push_back(ddeMaterial);

	}

}
Beispiel #19
0
//-------------------------------------------------------------------------------------
// CaptureTexture
bool Test05()
{
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;
    HRESULT hr = CreateDevice(device.GetAddressOf(), context.GetAddressOf());
    if (FAILED(hr))
    {
        printe("Failed creating device (HRESULT %08X)\n", hr);
        return false;
    }

    bool success = true;

    size_t ncount = 0;
    size_t npass = 0;

    for (size_t index = 0; index < _countof(g_TestMedia); ++index)
    {
        if (g_TestMedia[index].options & FLAGS_NOT_SUPPORTED)
        {
            continue;
        }

        wchar_t szPath[MAX_PATH] = {};
        DWORD ret = ExpandEnvironmentStringsW(g_TestMedia[index].fname, szPath, MAX_PATH);
        if (!ret || ret > MAX_PATH)
        {
            printe("ERROR: ExpandEnvironmentStrings FAILED\n");
            return false;
        }

#ifdef _DEBUG
        OutputDebugString(szPath);
        OutputDebugStringA("\n");
#endif
        // Form dest path
        wchar_t ext[_MAX_EXT];
        wchar_t fname[_MAX_FNAME];
        _wsplitpath_s(szPath, nullptr, 0, nullptr, 0, fname, _MAX_FNAME, ext, _MAX_EXT);

        wchar_t tempDir[MAX_PATH] = {};
        ret = ExpandEnvironmentStringsW(TEMP_PATH L"d3d11", tempDir, MAX_PATH);
        if (!ret || ret > MAX_PATH)
        {
            printe("ERROR: ExpandEnvironmentStrings FAILED\n");
            return false;
        }

        CreateDirectoryW(tempDir, nullptr);

        wchar_t szDestPath[MAX_PATH] = {};
        _wmakepath_s(szDestPath, MAX_PATH, nullptr, tempDir, fname, L".dds");

        TexMetadata metadata;
        ScratchImage image;

        if (_wcsicmp(ext, L".dds") == 0)
        {
            hr = LoadFromDDSFile(szPath, DDS_FLAGS_NONE, &metadata, image);
        }
        else
        {
            hr = LoadFromWICFile(szPath, WIC_FLAGS_NONE, &metadata, image);
        }

        bool forceNoMips = false;
        const TexMetadata* check = &g_TestMedia[index].metadata;
        if (FAILED(hr))
        {
            success = false;
            printe("Failed getting data from (HRESULT %08X):\n%ls\n", hr, szPath);
        }
        else if (memcmp(&metadata, check, sizeof(TexMetadata)) != 0)
        {
            success = false;
            printe("Metadata error in:\n%ls\n", szPath);
            printmeta(&metadata);
            printmetachk(check);
        }
        else
        {
            bool pass = true;

            if (g_TestMedia[index].options & FLAGS_YUV)
            {
                if (!IsSupportedTexture(device.Get(), metadata))
                {
                    // Can't create video textures with mips on most hardware
                    metadata.mipLevels = 1;
                    forceNoMips = true;

                    if (!IsSupportedTexture(device.Get(), metadata))
                    {
                        print("WARNING: Format %u is not supported by this hardware\n", metadata.format);
                        continue;
                    }
                }
            }

            {
                ComPtr<ID3D11Resource> pResource;
                hr = CreateTexture(device.Get(), image.GetImages(), image.GetImageCount(), metadata, pResource.GetAddressOf());
                if (FAILED(hr))
                {
                    success = false;
                    printe("Failed creating texture from (HRESULT %08X):\n%ls\n", hr, szPath);
                }
                else
                {
                    ScratchImage image2;
                    hr = CaptureTexture(device.Get(), context.Get(), pResource.Get(), image2);

                    if (FAILED(hr))
                    {
                        success = false;
                        printe("Failed capturing texture from (HRESULT %08X):\n%ls\n", hr, szPath);
                    }
                    else
                    {
                        const TexMetadata& mdata2 = image2.GetMetadata();

                        if (memcmp(&mdata2, &metadata, sizeof(TexMetadata)) != 0)
                        {
                            success = false;
                            printe("Metadata error in:\n%ls\n", szDestPath);
                            printmeta(&mdata2);
                            printmetachk(check);
                        }
                        else if (!forceNoMips && image.GetImageCount() != image2.GetImageCount())
                        {
                            success = false;
                            printe("Image count in captured texture (%zu) doesn't match source (%zu) in:\n%ls\n", image2.GetImageCount(), image.GetImageCount(), szDestPath);
                        }
                        else
                        {
                            hr = SaveToDDSFile(image2.GetImages(), image2.GetImageCount(), image2.GetMetadata(), DDS_FLAGS_NONE, szDestPath);
                            if (FAILED(hr))
                            {
                                success = false;
                                pass = false;
                                printe("Failed writing DDS to (HRESULT %08X):\n%ls\n", hr, szDestPath);
                            }

                            if (!IsPlanar(metadata.format))
                            {
                                float mse, mseV[4];
                                hr = ComputeMSE(*image.GetImage(0, 0, 0), *image2.GetImage(0, 0, 0), mse, mseV);
                                if (FAILED(hr))
                                {
                                    success = false;
                                    pass = false;
                                    printe("Failed comparing captured image (HRESULT %08X):\n%ls\n", hr, szPath);
                                }
                                else if (fabs(mse) > 0.000001f)
                                {
                                    success = false;
                                    pass = false;
                                    printe("Failed comparing captured image MSE = %f (%f %f %f %f)... 0.f:\n%ls\n",
                                        mse, mseV[0], mseV[1], mseV[2], mseV[3], szPath);
                                }
                            }
                        }
                    }
                }
            }

            // Staging resource tests
            {
                ComPtr<ID3D11Resource> pStaging;
                hr = CreateTextureEx(device.Get(), image.GetImages(), image.GetImageCount(), metadata,
                    D3D11_USAGE_STAGING, 0, D3D11_CPU_ACCESS_READ, 0, false, pStaging.GetAddressOf());
                if (FAILED(hr))
                {
                    success = false;
                    pass = false;
                    printe("Failed creating test staging texture (HRESULT %08X):\n%ls\n", hr, szPath);
                }
                else
                {
                    ScratchImage image2;
                    hr = CaptureTexture(device.Get(), context.Get(), pStaging.Get(), image2);

                    if (FAILED(hr))
                    {
                        success = false;
                        printe("Failed capturing texture from staging texture (HRESULT %08X):\n%ls\n", hr, szPath);
                    }
                    else
                    {
                        const TexMetadata& mdata2 = image2.GetMetadata();

                        if (memcmp(&mdata2, &metadata, sizeof(TexMetadata)) != 0)
                        {
                            success = false;
                            printe("Metadata error in:\n%ls\n", szDestPath);
                            printmeta(&mdata2);
                            printmetachk(check);
                        }
                        else if (!forceNoMips && image.GetImageCount() != image2.GetImageCount())
                        {
                            success = false;
                            printe("Image count in captured texture staging texture (%zu) doesn't match source (%zu) in:\n%ls\n", image2.GetImageCount(), image.GetImageCount(), szDestPath);
                        }
                        else
                        {
                            wchar_t tname[MAX_PATH] = {};
                            wcscpy_s(tname, fname);
                            wcscat_s(tname, L"_staging");

                            wchar_t szDestPath2[MAX_PATH] = {};
                            _wmakepath_s(szDestPath2, MAX_PATH, nullptr, tempDir, tname, L".dds");

                            hr = SaveToDDSFile(image2.GetImages(), image2.GetImageCount(), image2.GetMetadata(), DDS_FLAGS_NONE, szDestPath2);
                            if (FAILED(hr))
                            {
                                success = false;
                                pass = false;
                                printe("Failed writing DDS to (HRESULT %08X):\n%ls\n", hr, szDestPath2);
                            }

                            if (!IsPlanar(metadata.format))
                            {
                                float mse, mseV[4];
                                hr = ComputeMSE(*image.GetImage(0, 0, 0), *image2.GetImage(0, 0, 0), mse, mseV);
                                if (FAILED(hr))
                                {
                                    success = false;
                                    pass = false;
                                    printe("Failed comparing captured image (HRESULT %08X):\n%ls\n", hr, szPath);
                                }
                                else if (fabs(mse) > 0.000001f)
                                {
                                    success = false;
                                    pass = false;
                                    printe("Failed comparing captured image MSE = %f (%f %f %f %f)... 0.f:\n%ls\n",
                                        mse, mseV[0], mseV[1], mseV[2], mseV[3], szPath);
                                }
                            }
                        }
                    }
                }
            }

            // CaptureTexture of an MSAA resource is tested elsewhere

            if (pass)
                ++npass;
        }

        ++ncount;
    }

    print("%zu images tested, %zu images passed ", ncount, npass);

    return success;
}
//-------------------------------------------------------------------------------------
// Flip/rotate image
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT FlipRotate( const Image& srcImage, DWORD flags, ScratchImage& image )
{
    if ( !srcImage.pixels )
        return E_POINTER;

    if ( !flags )
        return E_INVALIDARG;

#ifdef _AMD64_
    if ( (srcImage.width > 0xFFFFFFFF) || (srcImage.height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    if ( IsCompressed( srcImage.format ) )
    {
        // We don't support flip/rotate operations on compressed images
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" );
    static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" );
    static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" );

    // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags
    switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) )
    {
    case 0:
    case TEX_FR_ROTATE90:
    case TEX_FR_ROTATE180:
    case TEX_FR_ROTATE270:
        break;

    default:
        return E_INVALIDARG;
    }

    size_t nwidth = srcImage.width;
    size_t nheight = srcImage.height;

    if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270))
    {
        nwidth = srcImage.height;
        nheight = srcImage.width;
    }

    HRESULT hr = image.Initialize2D( srcImage.format, nwidth, nheight, 1, 1 );
    if ( FAILED(hr) )
        return hr;
   
    const Image *rimage = image.GetImage( 0, 0, 0 );
    if ( !rimage )
        return E_POINTER;

    WICPixelFormatGUID pfGUID;
    if ( _DXGIToWIC( srcImage.format, pfGUID ) )
    {
        // Case 1: Source format is supported by Windows Imaging Component
        hr = _PerformFlipRotateUsingWIC( srcImage, flags, pfGUID, *rimage );
    }
    else
    {
        // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
        hr = _PerformFlipRotateViaF32( srcImage, flags, *rimage );
    }

    if ( FAILED(hr) )
    {
        image.Release();
        return hr;
    }

    return S_OK;
}
_Use_decl_annotations_
HRESULT Compress( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                  DXGI_FORMAT format, DWORD compress, float alphaRef, ScratchImage& cImages )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed(metadata.format) || !IsCompressed(format) )
        return E_INVALIDARG;

    if ( IsTypeless(format)
         || IsTypeless(metadata.format) || IsPlanar(metadata.format) || IsPalettized(metadata.format) )
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );

    cImages.Release();

    TexMetadata mdata2 = metadata;
    mdata2.format = format;
    HRESULT hr = cImages.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != cImages.GetImageCount() )
    {
        cImages.Release();
        return E_FAIL;
    }

    const Image* dest = cImages.GetImages();
    if ( !dest  )
    {
        cImages.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        assert( dest[ index ].format == format );

        const Image& src = srcImages[ index ];

        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
        {
            cImages.Release();
            return E_FAIL;
        }

        if ( (compress & TEX_COMPRESS_PARALLEL) )
        {
#ifndef _OPENMP
            return E_NOTIMPL;
#else
            if ( compress & TEX_COMPRESS_PARALLEL )
            {
                hr = _CompressBC_Parallel( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
                if ( FAILED(hr) )
                {
                    cImages.Release();
                    return  hr;
                }
            }
#endif // _OPENMP
        }
        else
        {
            hr = _CompressBC( src, dest[ index ], _GetBCFlags( compress ), _GetSRGBFlags( compress ), alphaRef );
            if ( FAILED(hr) )
            {
                cImages.Release();
                return hr;
            }
        }
    }

    return S_OK;
}
CMP_ERROR WINAPI GPU_DirectX::Decompress(
    const CMP_Texture* pSourceTexture,
    CMP_Texture* pDestTexture
    )
{
    HRESULT hr;

    TexMetadata mdata;

    memset(&mdata, 0, sizeof(TexMetadata));
    mdata.height    = pSourceTexture->dwHeight;
    mdata.width     = pSourceTexture->dwWidth;
    mdata.depth = 1;
    mdata.arraySize = 1;
    mdata.mipLevels = 1;
    mdata.dimension = TEX_DIMENSION_TEXTURE2D;
    mdata.format = CMP2DXGIFormat(pSourceTexture->format);

/***  Use this for debugging DDS file loads
    LPWSTR lpImageSrc = L"";
    ScratchImage image;
    hr = LoadFromDDSFile(lpImageSrc, DDS_FLAGS_NONE, &mdata, image);
    if (FAILED(hr))
    {
        wchar_t buff[2048] = { 0 };
        swprintf_s(buff, "Failed to load texture file\n\nFilename = %ls\nHRESULT %08X", lpImageSrc, hr);
        return 0;
    }
***/

    if (FAILED(InitDevice(mdata, pDestTexture->format)))
    {
        CleanupDevice();
        return CMP_ERR_UNABLE_TO_INIT_DECOMPRESSLIB;
    }

    if (mdata.dimension == TEX_DIMENSION_TEXTURE3D)
    {
            wchar_t buff[2048] = { 0 };
            swprintf_s(buff, L"Arrays of volume textures are not supported\n\nArray size %Iu", mdata.arraySize);
            return CMP_ERR_GENERIC;
    }
    else
    {
        m_iMaxIndex = static_cast<UINT>(mdata.arraySize);
    }

    switch (mdata.format)
    {
        case DXGI_FORMAT_BC6H_TYPELESS:
        case DXGI_FORMAT_BC6H_UF16:
        case DXGI_FORMAT_BC6H_SF16:
        case DXGI_FORMAT_BC7_TYPELESS:
        case DXGI_FORMAT_BC7_UNORM:
        case DXGI_FORMAT_BC7_UNORM_SRGB:
            if (m_featureLevel < D3D_FEATURE_LEVEL_11_0)
            {
                wchar_t buff[2048] = { 0 };
                swprintf_s(buff, L"BC6H/BC7 requires DirectX 11 hardware\n\nDXGI Format %d\nFeature Level %d", 
                                 pSourceTexture->format, m_featureLevel);
                return CMP_ERR_GENERIC;
            }
            break;

        default:
        {
            UINT flags = 0;
            hr = m_pd3dDevice->CheckFormatSupport(mdata.format, &flags);
            if (FAILED(hr) || !(flags & (D3D11_FORMAT_SUPPORT_TEXTURE1D | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D)))
            {
                wchar_t buff[2048] = { 0 };
                swprintf_s(buff, L"Format not supported by DirectX hardware\n\nDXGI Format %d\nFeature Level %d\nHRESULT = %08X", mdata.format, m_featureLevel, hr);
                return CMP_ERR_GENERIC;
            }
        }
        break;
    }

    // Special case to make sure Texture cubes remain arrays
    mdata.miscFlags &= ~TEX_MISC_TEXTURECUBE;

    Image srcImage;

    // Set size to 4 pixel boundaries
    // Should check format is compressed for none compressed cases
    // where 4 pixel bound is not required.
    srcImage.width             = ((pSourceTexture->dwWidth  + 3) / 4) * 4;
    srcImage.height            = ((pSourceTexture->dwHeight + 3) / 4) * 4;
    srcImage.format            = mdata.format;
    srcImage.pixels            = pSourceTexture->pData;

    ComputePitch(mdata.format, srcImage.width, srcImage.height, srcImage.rowPitch, srcImage.slicePitch, 0);


    hr = CreateShaderResourceView(m_pd3dDevice, &srcImage, 1, mdata, &m_pSRV);
    if (FAILED(hr))
    {
         return CMP_ERR_GENERIC;
    }

#ifdef SHOW_WINDOW
    // Activate the window: Use for debugging!
    ShowWindow(m_hWnd, SW_SHOW);
#endif
    //  Wait in Main message loop, until render is complete!!
    //  then exit

    MSG msg = { 0 };

    while (WM_QUIT != msg.message)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            Render();
            break;
        }
    }

    m_pRenderTargetView->GetResource(&m_pResource);
    ScratchImage sratchimage;
    CaptureTexture(m_pd3dDevice, m_pImmediateContext,m_pResource, sratchimage);

    size_t pxsize    = sratchimage.GetPixelsSize();

    // Check the size matches our output
    if (pxsize == pDestTexture->dwDataSize)
    {
        uint8_t *pxdata = sratchimage.GetPixels();
        memcpy(pDestTexture->pData, pxdata, pDestTexture->dwDataSize);
    }

    CleanupDevice();

    return CMP_OK; // msg.wParam;
}
HRESULT Decompress( const Image* cImages, size_t nimages, const TexMetadata& metadata,
                    DXGI_FORMAT format, ScratchImage& images )
{
    if ( !cImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed(format) || IsTypeless(format) )
        return E_INVALIDARG;

    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        // Pick a default decompressed format based on BC input format
        format = _DefaultDecompress( cImages[0].format );
        if ( format == DXGI_FORMAT_UNKNOWN )
        {
            // Input is not a compressed format
            return E_FAIL;
        }
    }
    else if ( !IsValid(format) )
        return E_INVALIDARG;

    images.Release();

    TexMetadata mdata2 = metadata;
    mdata2.format = format;
    HRESULT hr = images.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != images.GetImageCount() )
    {
        images.Release();
        return E_FAIL;
    }

    const Image* dest = images.GetImages();
    if ( !dest )
    {
        images.Release();
        return E_POINTER;
    }

    for( size_t index=0; index < nimages; ++index )
    {
        assert( dest[ index ].format == format );

        const Image& src = cImages[ index ];
        if ( !IsCompressed( src.format ) )
        {
            images.Release();
            return E_FAIL;
        }

        if ( src.width != dest[ index ].width || src.height != dest[ index ].height )
        {
            images.Release();
            return E_FAIL;
        }

        hr = _DecompressBC( src, dest[ index ] );
        if ( FAILED(hr) )
        {
            images.Release();
            return hr;
        }
    }

    return S_OK;
}
Beispiel #24
0
//-------------------------------------------------------------------------------------
// Resize image (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT Resize( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                size_t width, size_t height, DWORD filter, ScratchImage& result )
{
    if ( !srcImages || !nimages || width == 0 || height == 0 )
        return E_INVALIDARG;

#ifdef _M_X64
    if ( (width > 0xFFFFFFFF) || (height > 0xFFFFFFFF) )
        return E_INVALIDARG;
#endif

    TexMetadata mdata2 = metadata;
    mdata2.width = width;
    mdata2.height = height;
    mdata2.mipLevels = 1;
    HRESULT hr = result.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    bool usewic = _UseWICFiltering( metadata.format, filter );

    WICPixelFormatGUID pfGUID = {0};
    bool wicpf = ( usewic ) ? _DXGIToWIC( metadata.format, pfGUID, true ) : false;

    switch ( metadata.dimension )
    {
    case TEX_DIMENSION_TEXTURE1D:
    case TEX_DIMENSION_TEXTURE2D:
        assert( metadata.depth == 1 );

        for( size_t item = 0; item < metadata.arraySize; ++item )
        {
            size_t srcIndex = metadata.ComputeIndex( 0, item, 0 );
            if ( srcIndex >= nimages )
            {
                result.Release();
                return E_FAIL;
            }

            const Image* srcimg = &srcImages[ srcIndex ];
            const Image* destimg = result.GetImage( 0, item, 0 );
            if ( !srcimg || !destimg )
            {
                result.Release();
                return E_POINTER;
            }

            if ( srcimg->format != metadata.format )
            {
                result.Release();
                return E_FAIL;
            }

#ifdef _M_X64
            if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) )
            {
                result.Release();
                return E_FAIL;
            }
#endif

            if ( usewic )
            {
                if ( wicpf )
                {
                    // Case 1: Source format is supported by Windows Imaging Component
                    hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg );
                }
                else
                {
                    // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
                    hr = _PerformResizeViaF32( *srcimg, filter, *destimg );
                }
            }
            else
            {
                // Case 3: not using WIC resizing
                hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg );
            }

            if ( FAILED(hr) )
            {
                result.Release();
                return hr;
            }
        }
        break;

    case TEX_DIMENSION_TEXTURE3D:
        assert( metadata.arraySize == 1 );

        for( size_t slice = 0; slice < metadata.depth; ++slice )
        {
            size_t srcIndex = metadata.ComputeIndex( 0, 0, slice );
            if ( srcIndex >= nimages )
            {
                result.Release();
                return E_FAIL;
            }

            const Image* srcimg = &srcImages[ srcIndex ];
            const Image* destimg = result.GetImage( 0, 0, slice );
            if ( !srcimg || !destimg )
            {
                result.Release();
                return E_POINTER;
            }

            if ( srcimg->format != metadata.format )
            {
                result.Release();
                return E_FAIL;
            }

#ifdef _M_X64
            if ( (srcimg->width > 0xFFFFFFFF) || (srcimg->height > 0xFFFFFFFF) )
            {
                result.Release();
                return E_FAIL;
            }
#endif

            if ( usewic )
            {
                if ( wicpf )
                {
                    // Case 1: Source format is supported by Windows Imaging Component
                    hr = _PerformResizeUsingWIC( *srcimg, filter, pfGUID, *destimg );
                }
                else
                {
                    // Case 2: Source format is not supported by WIC, so we have to convert, resize, and convert back
                    hr = _PerformResizeViaF32( *srcimg, filter, *destimg );
                }
            }
            else
            {
                // Case 3: not using WIC resizing
                hr = _PerformResizeUsingCustomFilters( *srcimg, filter, *destimg );
            }

            if ( FAILED(hr) )
            {
                result.Release();
                return hr;
            }
        }
        break;

    default:
        result.Release();
        return E_FAIL;
    }

    return S_OK;
}
//-------------------------------------------------------------------------------------
// Flip/rotate image (complex)
//-------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT FlipRotate( const Image* srcImages, size_t nimages, const TexMetadata& metadata,
                    DWORD flags, ScratchImage& result )
{
    if ( !srcImages || !nimages )
        return E_INVALIDARG;

    if ( IsCompressed( metadata.format ) )
    {
        // We don't support flip/rotate operations on compressed images
        return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    static_assert( TEX_FR_ROTATE0 == WICBitmapTransformRotate0, "TEX_FR_ROTATE0 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE90 == WICBitmapTransformRotate90, "TEX_FR_ROTATE90 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE180 == WICBitmapTransformRotate180, "TEX_FR_ROTATE180 no longer matches WIC" );
    static_assert( TEX_FR_ROTATE270 == WICBitmapTransformRotate270, "TEX_FR_ROTATE270 no longer matches WIC" );
    static_assert( TEX_FR_FLIP_HORIZONTAL == WICBitmapTransformFlipHorizontal, "TEX_FR_FLIP_HORIZONTAL no longer matches WIC" );
    static_assert( TEX_FR_FLIP_VERTICAL == WICBitmapTransformFlipVertical, "TEX_FR_FLIP_VERTICAL no longer matches WIC" );

    // Only supports 90, 180, 270, or no rotation flags... not a combination of rotation flags
    switch ( flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE180|TEX_FR_ROTATE270) )
    {
    case 0:
    case TEX_FR_ROTATE90:
    case TEX_FR_ROTATE180:
    case TEX_FR_ROTATE270:
        break;

    default:
        return E_INVALIDARG;
    }

    TexMetadata mdata2 = metadata;

    bool flipwh = false;
    if (flags & (TEX_FR_ROTATE90|TEX_FR_ROTATE270))
    {
        flipwh = true;
        mdata2.width = metadata.height;
        mdata2.height = metadata.width;
    }

    HRESULT hr = result.Initialize( mdata2 );
    if ( FAILED(hr) )
        return hr;

    if ( nimages != result.GetImageCount() )
    {
        result.Release();
        return E_FAIL;
    }

    const Image* dest = result.GetImages();
    if ( !dest )
    {
        result.Release();
        return E_POINTER;
    }

    WICPixelFormatGUID pfGUID;
    bool wicpf = _DXGIToWIC( metadata.format, pfGUID );

    for( size_t index=0; index < nimages; ++index )
    {
        const Image& src = srcImages[ index ];
        if ( src.format != metadata.format )
        {
            result.Release();
            return E_FAIL;
        }

#ifdef _AMD64_
        if ( (src.width > 0xFFFFFFFF) || (src.height > 0xFFFFFFFF) )
            return E_FAIL;
#endif

        const Image& dst = dest[ index ];
        assert( dst.format == metadata.format );

        if ( flipwh )
        {
            if ( src.width != dst.height || src.height != dst.width )
            {
                result.Release();
                return E_FAIL;
            }
        }
        else
        {
            if ( src.width != dst.width || src.height != dst.height )
            {
                result.Release();
                return E_FAIL;
            }
        }

        if (wicpf)
        {
            // Case 1: Source format is supported by Windows Imaging Component
            hr = _PerformFlipRotateUsingWIC( src, flags, pfGUID, dst );
        }
        else
        {
            // Case 2: Source format is not supported by WIC, so we have to convert, flip/rotate, and convert back
            hr = _PerformFlipRotateViaF32( src, flags, dst );
        }

        if ( FAILED(hr) )
        {
            result.Release();
            return hr;
        }
    }

    return S_OK;
}
Beispiel #26
0
//-------------------------------------------------------------------------------------
// CreateTexture
bool Test02()
{
    ComPtr<ID3D11Device> device;
    HRESULT hr = CreateDevice(device.GetAddressOf(), nullptr);
    if (FAILED(hr))
    {
        printe("Failed creating device (HRESULT %08X)\n", hr);
        return false;
    }

    bool success = true;

    size_t ncount = 0;
    size_t npass = 0;

    for (size_t index = 0; index < _countof(g_TestMedia); ++index)
    {
        if (g_TestMedia[index].options & FLAGS_NOT_SUPPORTED)
        {
            continue;
        }

        wchar_t szPath[MAX_PATH] = {};
        DWORD ret = ExpandEnvironmentStringsW(g_TestMedia[index].fname, szPath, MAX_PATH);
        if (!ret || ret > MAX_PATH)
        {
            printe("ERROR: ExpandEnvironmentStrings FAILED\n");
            return false;
        }

#ifdef _DEBUG
        OutputDebugString(szPath);
        OutputDebugStringA("\n");
#endif

        wchar_t ext[_MAX_EXT];
        _wsplitpath_s(szPath, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT);

        TexMetadata metadata;
        ScratchImage image;

        if (_wcsicmp(ext, L".dds") == 0)
        {
            hr = LoadFromDDSFile(szPath, DDS_FLAGS_NONE, &metadata, image);
        }
        else
        {
            hr = LoadFromWICFile(szPath, WIC_FLAGS_NONE, &metadata, image);
        }

        const TexMetadata* check = &g_TestMedia[index].metadata;
        if (FAILED(hr))
        {
            success = false;
            printe("Failed getting data from (HRESULT %08X):\n%ls\n", hr, szPath);
        }
        else if (memcmp(&metadata, check, sizeof(TexMetadata)) != 0)
        {
            success = false;
            printe("Metadata error in:\n%ls\n", szPath);
            printmeta(&metadata);
            printmetachk(check);
        }
        else
        {
            if (g_TestMedia[index].options & FLAGS_YUV)
            {
                if (!IsSupportedTexture(device.Get(), metadata))
                {
                    // Can't create video textures with mips on most hardware
                    metadata.mipLevels = 1;

                    if (!IsSupportedTexture(device.Get(), metadata))
                    {
                        print("WARNING: Format %u is not supported by this hardware\n", metadata.format);
                        continue;
                    }
                }
            }

            ComPtr<ID3D11Resource> pResource;
            hr = CreateTexture(device.Get(), image.GetImages(), image.GetImageCount(), metadata, pResource.GetAddressOf());
            if (FAILED(hr))
            {
                success = false;
                printe("Failed creating texture from (HRESULT %08X):\n%ls\n", hr, szPath);
            }
            else
            {
                hr = CreateTextureEx(device.Get(), image.GetImages(), image.GetImageCount(), metadata,
                    D3D11_USAGE_IMMUTABLE, D3D11_BIND_SHADER_RESOURCE, 0, 0,
                    true, pResource.ReleaseAndGetAddressOf());
                if (FAILED(hr))
                {
                    success = false;
                    printe("Failed creating texture ex from (HRESULT %08X):\n%ls\n", hr, szPath);
                }
                else
                {
                    ++npass;
                }
            }
        }

        ++ncount;
    }

    print("%zu images tested, %zu images passed ", ncount, npass);

    return success;
}
Beispiel #27
0
int WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow )
{
    UNREFERENCED_PARAMETER( hPrevInstance );
    UNREFERENCED_PARAMETER( lpCmdLine );

    if ( !*lpCmdLine )
    {
        MessageBox( NULL, L"Usage: ddsview <filename>", L"DDSView", MB_OK | MB_ICONEXCLAMATION );
        return 0;
    }

    TexMetadata mdata;
    HRESULT hr = GetMetadataFromDDSFile( lpCmdLine, DDS_FLAGS_NONE, mdata );
    if ( FAILED(hr) )
    {
        WCHAR buff[2048];
        swprintf_s( buff, L"Failed to open texture file\n\nFilename = %ls\nHRESULT %08X", lpCmdLine, hr );
        MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
        return 0;
    }

    if( FAILED( InitWindow( hInstance, nCmdShow, mdata ) ) )
        return 0;

    SetWindowTextW( g_hWnd, lpCmdLine );

    if( FAILED( InitDevice( mdata ) ) )
    {
        CleanupDevice();
        return 0;
    }

    if (mdata.dimension == TEX_DIMENSION_TEXTURE3D)
    {
        if ( mdata.arraySize > 1 )
        {
            WCHAR buff[2048];
            swprintf_s( buff, L"Arrays of volume textures are not supported\n\nFilename = %ls\nArray size %Iu", lpCmdLine, mdata.arraySize );
            MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
            return 0;
        }

        g_iMaxIndex = static_cast<UINT>( mdata.depth );
    }
    else
    {
        g_iMaxIndex = static_cast<UINT>( mdata.arraySize );
    }

    switch( mdata.format )
    {
    case DXGI_FORMAT_BC6H_TYPELESS:
    case DXGI_FORMAT_BC6H_UF16:
    case DXGI_FORMAT_BC6H_SF16:
    case DXGI_FORMAT_BC7_TYPELESS:
    case DXGI_FORMAT_BC7_UNORM:
    case DXGI_FORMAT_BC7_UNORM_SRGB:
        if ( g_featureLevel < D3D_FEATURE_LEVEL_11_0 )
        {
            WCHAR buff[2048];
            swprintf_s( buff, L"BC6H/BC7 requires DirectX 11 hardware\n\nFilename = %ls\nDXGI Format %d\nFeature Level %d", lpCmdLine, mdata.format, g_featureLevel );
            MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
            return 0;
        }
        break;

    default:
        {
            UINT flags = 0;
            hr = g_pd3dDevice->CheckFormatSupport ( mdata.format, &flags );
            if ( FAILED(hr) || !(flags & (D3D11_FORMAT_SUPPORT_TEXTURE1D|D3D11_FORMAT_SUPPORT_TEXTURE2D|D3D11_FORMAT_SUPPORT_TEXTURE3D)) )
            {
                WCHAR buff[2048];
                swprintf_s( buff, L"Format not supported by DirectX hardware\n\nFilename = %ls\nDXGI Format %d\nFeature Level %d\nHRESULT = %08X", lpCmdLine, mdata.format, g_featureLevel, hr );
                MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
                return 0;
            }
        }
        break;
    }

    ScratchImage image;
    hr = LoadFromDDSFile( lpCmdLine, DDS_FLAGS_NONE, &mdata, image );
    if ( FAILED(hr) )
    {
        WCHAR buff[2048];
        swprintf_s( buff, L"Failed to load texture file\n\nFilename = %ls\nHRESULT %08X", lpCmdLine, hr );
        MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
        return 0;
    }

    // Special case to make sure Texture cubes remain arrays
    mdata.miscFlags &= ~TEX_MISC_TEXTURECUBE;

    hr = CreateShaderResourceView( g_pd3dDevice, image.GetImages(), image.GetImageCount(), mdata, &g_pSRV );
    if ( FAILED(hr) )
    {
        WCHAR buff[2048];
        swprintf_s( buff, L"Failed creating texture from file\n\nFilename = %ls\nHRESULT = %08X", lpCmdLine, hr );
        MessageBox( NULL, buff, L"DDSView", MB_OK | MB_ICONEXCLAMATION );
        return 0;
    }

    // Main message loop
    MSG msg = {0};
    while( WM_QUIT != msg.message )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            Render();
        }
    }

    CleanupDevice();

    return ( int )msg.wParam;
}
Beispiel #28
0
//-------------------------------------------------------------------------------------
// rendertest
bool Test04()
{
    ComPtr<ID3D11Device> device;
    HRESULT hr = SetupRenderTest(device.GetAddressOf(), nullptr);
    if (FAILED(hr))
    {
        printe("Failed creating device (HRESULT %08X)\n", hr);
        return false;
    }

    bool success = true;

    size_t ncount = 0;
    size_t npass = 0;

    for (size_t index = 0; index < _countof(g_TestMedia); ++index)
    {
        if (g_TestMedia[index].options & (FLAGS_YUV | FLAGS_NOT_SUPPORTED))
        {
            // Skip video textures which need special options to render
            continue;
        }

        wchar_t szPath[MAX_PATH] = {};
        DWORD ret = ExpandEnvironmentStringsW(g_TestMedia[index].fname, szPath, MAX_PATH);
        if (!ret || ret > MAX_PATH)
        {
            printe("ERROR: ExpandEnvironmentStrings FAILED\n");
            return false;
        }

#ifdef _DEBUG
        OutputDebugString(szPath);
        OutputDebugStringA("\n");
#endif

        wchar_t ext[_MAX_EXT];
        _wsplitpath_s(szPath, nullptr, 0, nullptr, 0, nullptr, 0, ext, _MAX_EXT);

        TexMetadata metadata;
        ScratchImage image;

        if (_wcsicmp(ext, L".dds") == 0)
        {
            hr = LoadFromDDSFile(szPath, DDS_FLAGS_NONE, &metadata, image);
        }
        else
        {
            hr = LoadFromWICFile(szPath, WIC_FLAGS_NONE, &metadata, image);
        }

        const TexMetadata* check = &g_TestMedia[index].metadata;
        if (FAILED(hr))
        {
            success = false;
            printe("Failed getting data from (HRESULT %08X):\n%ls\n", hr, szPath);
        }
        else if (memcmp(&metadata, check, sizeof(TexMetadata)) != 0)
        {
            success = false;
            printe("Metadata error in:\n%ls\n", szPath);
            printmeta(&metadata);
            printmetachk(check);
        }
        else
        {
            ComPtr<ID3D11ShaderResourceView> pSRV;
            hr = CreateShaderResourceView(device.Get(), image.GetImages(), image.GetImageCount(), metadata, pSRV.GetAddressOf());
            if (FAILED(hr))
            {
                success = false;
                printe("Failed creating SRV from (HRESULT %08X):\n%ls\n", hr, szPath);
            }
            else
            {
                print("Viewing %ls\n", szPath);

                RenderTest(metadata, pSRV.Get());

                ++npass;
            }
        }

        ++ncount;
    }

    print("%zu images tested, %zu images passed ", ncount, npass);

    CleanupRenderTest();

    return success;
}