Я хотел бы использовать D2D для декодирования распространенных форматов изображений (.jpeg
, .png
) и записать их в мои текстуры OpenGL в формате, который я использую по умолчанию, то есть RGBA, 8 бит на канал.
Самый простой способ, казалось бы, просто применить декорированный CreateBitmapFromSource(IWIC_decoder_frame, ..., &IWIC_bitmap)
и прочитать IWICBitmap
...
Однако у меня были проблемы с этим:
- В: Как я могу прочитать GUID форматов пикселей WI C? Я случайно догадался, что числа в отладчике (
{6FDDC324-4E03-4BFE-B185-3D77768DC920}
) соответствуют GUID_WICPixelFormat24bpp3Channels
. - Но даже после понимания того, что в растровом формате WI C есть только 3 канала, размер возвращаемого байта после вызова
IWIC_bitmap_lock->GetDataPointer(&bitmap_buffer_size, &data_ptr)
, bitmap_buffer_size
был 854559
, в то время как я ожидал 3*width*height = 653*436*3 = 854124
. Я попытался записать растровое изображение на мою текстуру, но в результате получилось следующее:
(я также пытался использовать IWICFormatConverter
, но не знал, как создать цель рендеринга. Документация пропускает часть с //Create render target and D2D bitmap from IWICBitmapSource
.)
![enter image description here](https://i.stack.imgur.com/asWyT.jpg)
IWICBitmapDecoder *IWIC_decoder = NULL;
IWICBitmapFrameDecode *IWIC_decoder_frame = NULL;
HR(IWIC_imaging_factory->CreateDecoderFromFilename(
L"cat.jpg", // Image to be decoded
NULL, // Do not prefer a particular vendor
GENERIC_READ, // Desired read access to the file
WICDecodeMetadataCacheOnDemand, // Cache metadata when needed
&IWIC_decoder // Pointer to the decoder
));
// get frame
HR(IWIC_decoder->GetFrame(0, &IWIC_decoder_frame));
// get frame dimentions
u32 frame_width = 0;
u32 frame_height = 0;
HR(IWIC_decoder_frame->GetSize (&frame_width, &frame_height));
IWICBitmap *IWIC_bitmap = NULL;
IWICBitmapLock *IWIC_bitmap_lock = NULL;
WICRect IWIC_lock_rect = { 0, 0, (s32)frame_width, (s32)frame_height };
HR(IWIC_imaging_factory->CreateBitmapFromSource(IWIC_decoder_frame, WICBitmapCacheOnDemand, &IWIC_bitmap));
HR(IWIC_bitmap->Lock(&IWIC_lock_rect, WICBitmapLockRead, &IWIC_bitmap_lock));
WICPixelFormatGUID pixel_format;
HR(IWIC_bitmap->GetPixelFormat(&pixel_format));
UINT bitmap_buffer_size = 0;
u8 *reader = NULL;
// Retrieve a pointer to the pixel data.
HR(IWIC_bitmap_lock->GetDataPointer(&bitmap_buffer_size, &reader));
...
for(int row_index = 0; row_index < (y1 - y0); row_index++)
{
for(int column_index = 0; column_index < (x1 - x0); column_index++)
{
u32 *pixel = rect_start + column_index + row_index * TEXTURE_DIM;
u8 *writer = (u8 *)pixel;
*writer = *source;
writer++;source++;
*writer = *source;
writer++;source++;
*writer = *source;
writer++; source++;
*writer = 255;
writer++;
byte_size--;
if(byte_size < 0)
{
break;
}
}
}
Читает IWICBitmap
разумный способ справиться с этим? Или я должен использовать конвертер?