Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];

Вниз

Цветовые маски в DirectDraw   Найти похожие ветки 

 
Ермак ©   (2003-12-05 13:09) [0]

Добрый день, мастера!

Ерунда какая-то, однако...
Директ Дро дает в PixelFormat следующие RGB-маски:
TrueColor
RedMask = 00FF0000
GreenMask = 0000FF00
BlueMask = 000000FF
HighColor
RedMask = 0000F800
GreenMask = 000007E0
BlueMask = 0000001F

То есть, цвета якобы идут в прямом формате - RGB. При прямой же работе с поверхностью обнаруживается, что писать цвета надо в обратном формате - BGR. Это глюк, или так и должно быть?

Версия ДХ - 8 или старше, чипсет - Intel i740.


 
Sapersky ©   (2003-12-05 14:05) [1]

Может, пишешь не вполне правильно?


 
Ermak   (2003-12-05 15:24) [2]

Нет, с написанием все верно.
Вот код:
ptr[0] := $F8;
ptr[1] := $00;
где ptr - pByteArray - указывает на начало видеопамяти при LockSurface. По идее должна появиться красная точка в углу экрана, а появляется синяя! Т.е. схема BGR. То же самое в 24бит режиме. Я вывожу данные прямо из BMP (где они, как известно в BGR) на экран - и все ОК! А маски выдаются такие, как я привел, якобы RGB. Поскольку надо обеспечить совместимость с разными режимами, нужно учитывать маски. В том-то и вопрос: если они всегда в перевернутом виде даются - то нет проблем, а вот если это глюк на моем чипсете?


 
Sapersky ©   (2003-12-06 14:18) [3]

Хм, ну не знаю. Может, правда глюки с драйверами или ещё чем. Надо протестировать на другой видеокарте...
Насколько помню, у меня тоже с порядком записи были проблемы. Сейчас для задания цвета пользуюсь следующей процедурой и она вроде бы работает везде:

procedure SetImagePixel(Var pb : PByte; Color : TRGBQuad; Const PixelFormat : TPixelFormat);
// pb - указатель на текущий пиксель поверхность (сдвигается здесь же), Color - исходный цвет
Var rr, gg, bb : Byte;
begin
With PixelFormat do begin
 If BytesPP=2 then begin // в случае 16-битного цвета преобразуем
   rr:=Color.rgbRed   shr RShift;
   gg:=Color.rgbGreen shr GShift;
   bb:=Color.rgbBlue  shr BShift;
   PWord(pb)^:=(rr shl LoRBit) or (gg shl LoGBit) or (bb shl LoBBit);
 end else
   PDWord(pb)^:=(Color.rgbRed shl LoRBit) or (Color.rgbGreen shl LoGBit) or
                (Color.rgbBlue shl LoBBit);

 Inc(pb,BytesPP); // сдвигаем указатель
end;
end;

RShift, GShift, BShift - разница в количестве бит для 24/32-битного режима (8 бит на цвет) и цветовой составляющей данного режима (например, для режима 5-6-5 будет 3-2-3).
Преобразование получается не совсем точное, для цветового ключа, например, лучше использовать:
rr:=Color.rgbRed   * MaxRValue div 255;
gg:=Color.rgbGreen * MaxGValue div 255;
bb:=Color.rgbBlue  * MaxBValue div 255;
MaxRValue, MaxGValue, MaxBValue - максимальные значения для цветовой составляющей.
LoRBit, LoGBit, LoBBit - номера младшего (крайнего слева) бита цветовой составляющей.
Всё это получается из масок следующим образом:

procedure GetSurfPixelFormat(surf : IDirectDrawSurface7; Var PFormat : TPixelFormat);
Var rc,gc,bc,ac : Byte;

 function Bit_LowerNum(value : DWord): Byte;
 Var n,m : DWord;
 begin
 Result:=0; m:=1;
 For n:=0 to 31 do begin
   If (value and m)=m then begin Result:=n; Exit; end;
   m:=m shl 1;
 end;
 end;

 function Bit_OnesCount(value : DWord): Byte;
 Var n,m : DWord;
 begin
 Result:=0; m:=1;
 For n:=0 to 31 do begin
   If (value and m)=m then Inc(Result); m:=m shl 1;
 end;
 end;

begin
With PFormat do begin
 ZeroMemory(@DDPFormat,SizeOf(TDDPixelFormat));
 DDPFormat.dwSize:=SizeOf(TDDPixelFormat);
 surf.GetPixelFormat(DDPFormat);
 BytesPP:=DDPFormat.dwRGBBitCount div 8;
 LoRBit:=Bit_LowerNum(DDPFormat.dwRBitMask);
 LoGBit:=Bit_LowerNum(DDPFormat.dwGBitMask);
 LoBBit:=Bit_LowerNum(DDPFormat.dwBBitMask);
 LoABit:=Bit_LowerNum(DDPFormat.dwRGBAlphaBitMask);
 rc:=Bit_OnesCount(DDPFormat.dwRBitMask);
 gc:=Bit_OnesCount(DDPFormat.dwGBitMask);
 bc:=Bit_OnesCount(DDPFormat.dwBBitMask);
 ac:=Bit_OnesCount(DDPFormat.dwRGBAlphaBitMask);
 MaxRValue:=(1 shl rc)-1; MaxGValue:=(1 shl gc)-1;
 MaxBValue:=(1 shl bc)-1; MaxAValue:=(1 shl ac)-1;
 RShift:=8-rc; GShift:=8-gc; BShift:=8-bc; AShift:=8-ac;
end;
end;

Вроде нигде ничего не переворачивается (RGB на BGR и т.п.)? Или я просто этого не замечаю :)

Хотя, например, YUV следует явно писать (выяснено экспериментальным путём) в обратном порядке (т.е. если формат UYVY, то пишется Y1-V-Y0-U).

Вообще можно использовать GetDC/BitBlt и забыть о форматах пикселей. Притом что у меня по тестам это получается быстрее - видимо, моя процедура сильно кривая :( Или слишком универсальная - понимает практически все форматы, в т.ч. YUV.


 
Ермак ©   (2003-12-06 14:51) [4]

Спасибо Sapersky, попробую!

Я тоже написал свою процедуру, которая по DX Pixel Format автоматически приводит к 16-бит формату, но выяснилась вышеописанная ерунда...

Еще раз спасибо!!!



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.038 c
3-1078406893
WebErr
2004-03-04 16:28
2004.04.04
Сложности сортировки


11-1059376323
С@ня
2003-07-28 11:12
2004.04.04
Буфер


1-1079535736
{bas}
2004-03-17 18:02
2004.04.04
Copy array


1-1079441862
zac
2004-03-16 15:57
2004.04.04
Как удалить нарисованное?


1-1079110010
Димка
2004-03-12 19:46
2004.04.04
как закрыто приложение?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский