feat: support create texture from memory
This commit is contained in:
parent
2fa346783a
commit
4b9f4b11f9
|
|
@ -33,6 +33,8 @@ struct KGE_API BinaryData
|
|||
|
||||
BinaryData();
|
||||
|
||||
BinaryData(void* buffer, uint32_t size);
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
|
|
@ -42,6 +44,12 @@ inline BinaryData::BinaryData()
|
|||
{
|
||||
}
|
||||
|
||||
inline BinaryData::BinaryData(void* buffer, uint32_t size)
|
||||
: buffer(buffer)
|
||||
, size(size)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool BinaryData::IsValid() const
|
||||
{
|
||||
return buffer != nullptr && size != 0;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ public:
|
|||
HRESULT CreateBitmapDecoderFromResource(_Out_ ComPtr<IWICBitmapDecoder>& decoder, _In_ void* data,
|
||||
DWORD data_size) override;
|
||||
|
||||
HRESULT CreateBitmapSourceFromMemory(_Out_ ComPtr<IWICBitmapSource>& source, _In_ UINT width, _In_ UINT height,
|
||||
_In_ UINT cbStride, _In_ UINT cbBufferSize, _In_ BYTE* buffer,
|
||||
_In_ REFWICPixelFormatGUID cPixelFormat);
|
||||
|
||||
HRESULT CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& text_format, _In_ LPCWSTR family,
|
||||
_In_ ComPtr<IDWriteFontCollection> collection, DWRITE_FONT_WEIGHT weight,
|
||||
DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size) override;
|
||||
|
|
@ -401,6 +405,23 @@ void D2DDeviceResources::ResetTextRenderingParams(HMONITOR monitor)
|
|||
}
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateBitmapSourceFromMemory(_Out_ ComPtr<IWICBitmapSource>& source, _In_ UINT width,
|
||||
_In_ UINT height, _In_ UINT cbStride, _In_ UINT cbBufferSize,
|
||||
_In_ BYTE* buffer, _In_ REFWICPixelFormatGUID cPixelFormat)
|
||||
{
|
||||
if (!imaging_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
ComPtr<IWICBitmap> output;
|
||||
|
||||
HRESULT hr = imaging_factory_->CreateBitmapFromMemory(width, height, cPixelFormat, cbStride, cbBufferSize, buffer, &output);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
source = output;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateBitmapConverter(_Out_ ComPtr<IWICFormatConverter>& converter,
|
||||
_In_opt_ ComPtr<IWICBitmapSource> source,
|
||||
_In_ REFWICPixelFormatGUID format, WICBitmapDitherType dither,
|
||||
|
|
|
|||
|
|
@ -35,12 +35,16 @@ KGE_API ID2DDeviceResources : public IUnknown
|
|||
public:
|
||||
virtual HRESULT Initialize(_In_ ComPtr<IDXGIDevice> dxgi_device, _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain) = 0;
|
||||
|
||||
virtual HRESULT CreateBitmapSourceFromMemory(_Out_ ComPtr<IWICBitmapSource> & source, _In_ UINT width,
|
||||
_In_ UINT height, _In_ UINT cbStride, _In_ UINT cbBufferSize,
|
||||
_In_ BYTE * buffer, _In_ REFWICPixelFormatGUID cPixelFormat) = 0;
|
||||
|
||||
virtual HRESULT CreateBitmapConverter(_Out_ ComPtr<IWICFormatConverter> & converter,
|
||||
_In_opt_ ComPtr<IWICBitmapSource> source, _In_ REFWICPixelFormatGUID format,
|
||||
WICBitmapDitherType dither, _In_opt_ ComPtr<IWICPalette> palette,
|
||||
double alpha_threshold_percent, WICBitmapPaletteType palette_translate) = 0;
|
||||
|
||||
virtual HRESULT CreateBitmapFromConverter(_Out_ ComPtr<ID2D1Bitmap> & bitmap,
|
||||
virtual HRESULT CreateBitmapFromConverter(_Out_ ComPtr<ID2D1Bitmap> & bitmap,
|
||||
_In_opt_ const D2D1_BITMAP_PROPERTIES* properties,
|
||||
_In_ ComPtr<IWICFormatConverter> converter) = 0;
|
||||
|
||||
|
|
@ -56,11 +60,11 @@ public:
|
|||
virtual HRESULT CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout> & text_layout, _In_ LPCWSTR text, UINT32 length,
|
||||
_In_ ComPtr<IDWriteTextFormat> text_format) = 0;
|
||||
|
||||
virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
|
||||
virtual HRESULT CreateFontCollectionFromFiles(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
|
||||
const Vector<String>& file_paths) = 0;
|
||||
|
||||
virtual HRESULT CreateFontCollectionFromBinaryData(_Out_ ComPtr<IDWriteFontCollection> & font_collection,
|
||||
const Vector<BinaryData>& data) = 0;
|
||||
const Vector<BinaryData>& data) = 0;
|
||||
|
||||
virtual HRESULT GetFontFamilyNames(_Out_ Vector<String> & family_names,
|
||||
_In_ ComPtr<IDWriteFontCollection> font_collection) = 0;
|
||||
|
|
@ -124,9 +128,8 @@ protected:
|
|||
ComPtr<IDWriteFactory> dwrite_factory_;
|
||||
};
|
||||
|
||||
|
||||
extern ComPtr<ID2DDeviceResources> GetD2DDeviceResources();
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace directx
|
||||
} // namespace graphics
|
||||
} // namespace kiwano
|
||||
|
|
|
|||
|
|
@ -37,6 +37,21 @@ namespace kiwano
|
|||
|
||||
using namespace kiwano::graphics::directx;
|
||||
|
||||
inline const GUID& ConvertPixelFormat(PixelFormat format, UINT& stride)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case PixelFormat::Bpp32RGB:
|
||||
stride = 3;
|
||||
return GUID_WICPixelFormat32bppRGB;
|
||||
case PixelFormat::Bpp32RGBA:
|
||||
stride = 4;
|
||||
return GUID_WICPixelFormat32bppRGB;
|
||||
default:
|
||||
return GUID_WICPixelFormatDontCare;
|
||||
}
|
||||
}
|
||||
|
||||
Renderer& Renderer::GetInstance()
|
||||
{
|
||||
return RendererImpl::GetInstance();
|
||||
|
|
@ -300,6 +315,55 @@ void RendererImpl::CreateTexture(Texture& texture, const BinaryData& data)
|
|||
KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture failed");
|
||||
}
|
||||
|
||||
void RendererImpl::CreateTexture(Texture& texture, const PixelSize& size, const BinaryData& data, PixelFormat format)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (!d2d_res_)
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = data.IsValid() ? S_OK : E_FAIL;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
UINT stride = 0;
|
||||
const auto& wicFormat = ConvertPixelFormat(format, stride);
|
||||
|
||||
ComPtr<IWICBitmapSource> source;
|
||||
hr = d2d_res_->CreateBitmapSourceFromMemory(source, UINT(size.x), UINT(size.y), UINT(size.x) * stride,
|
||||
UINT(data.size), reinterpret_cast<BYTE*>(data.buffer),
|
||||
wicFormat);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IWICFormatConverter> converter;
|
||||
hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA,
|
||||
WICBitmapDitherTypeNone, nullptr, 0.f,
|
||||
WICBitmapPaletteTypeMedianCut);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<ID2D1Bitmap> bitmap;
|
||||
hr = d2d_res_->CreateBitmapFromConverter(bitmap, nullptr, converter);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
NativePtr::Set(texture, bitmap);
|
||||
|
||||
texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height });
|
||||
texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KGE_SET_STATUS_IF_FAILED(hr, texture, "Load texture from memory failed");
|
||||
}
|
||||
|
||||
void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
void CreateTexture(Texture& texture, const BinaryData& data) override;
|
||||
|
||||
void CreateTexture(Texture& texture, const PixelSize& size, const BinaryData& data, PixelFormat format);
|
||||
|
||||
void CreateGifImage(GifImage& gif, const String& file_path) override;
|
||||
|
||||
void CreateGifImage(GifImage& gif, const BinaryData& data) override;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,14 @@ public:
|
|||
/// @param[in] data 图片二进制数据
|
||||
virtual void CreateTexture(Texture& texture, const BinaryData& data) = 0;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 从内存加载位图纹理资源
|
||||
/// @param[out] texture 纹理
|
||||
/// @param[in] size 位图大小
|
||||
/// @param[in] data 位图二进制数据
|
||||
/// @param[in] format 像素格式
|
||||
virtual void CreateTexture(Texture& texture, const PixelSize& size, const BinaryData& data, PixelFormat format) = 0;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 创建GIF图像内部资源
|
||||
/// @param[out] gif GIF图像
|
||||
|
|
|
|||
|
|
@ -62,6 +62,16 @@ TexturePtr Texture::Preload(const Resource& res)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
TexturePtr Texture::Preload(const PixelSize& size, const BinaryData& data, PixelFormat format)
|
||||
{
|
||||
TexturePtr ptr = MakePtr<Texture>();
|
||||
if (ptr)
|
||||
{
|
||||
Renderer::GetInstance().CreateTexture(*ptr, size, data, format);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Texture::Texture(const String& file_path)
|
||||
: Texture()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,6 +47,17 @@ enum class InterpolationMode
|
|||
/// @brief 像素大小
|
||||
typedef math::Vec2T<uint32_t> PixelSize;
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 像素格式
|
||||
* @details 像素格式指定了从内存加载位图时内存以何种方式排列
|
||||
*/
|
||||
enum class PixelFormat
|
||||
{
|
||||
Bpp32RGB,
|
||||
Bpp32RGBA,
|
||||
};
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 纹理
|
||||
|
|
@ -62,6 +73,10 @@ public:
|
|||
/// @brief 预加载图片资源
|
||||
static TexturePtr Preload(const Resource& res);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 从内存加载位图纹理
|
||||
static TexturePtr Preload(const PixelSize& size, const BinaryData& data, PixelFormat format);
|
||||
|
||||
Texture();
|
||||
|
||||
/// \~chinese
|
||||
|
|
|
|||
Loading…
Reference in New Issue