Непонятка с glColor3b

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
Dimqin
незнакомец
Сообщения: 4
Зарегистрирован: 11.10.2019 10:36:09

Непонятка с glColor3b

Сообщение Dimqin »

Использую штатный компонент OpenGL.
Споткнулся на самом примитивном.
Есть процедура

Код: Выделить всё

procedure RedGreenBlue(Lite: TColor; out Red, Green, Blue: Byte);
begin
  Red := byte(Lite); 
  Green :=  byte(Lite shr 8);
  Blue :=  byte(Lite shr 16);
end;
Вызываю ее для преобразования стандартного TColor цвета

Код: Выделить всё

var
   Red, Green, Blue: Byte;
begin
...
    RedGreenBlue(clGreen, Red, Green, Blue);//
    glBegin(GL_QUADS);      // 
    glColor3f(Red/255, Green/255, Blue/255);     // 
    ...
В этом случае зеленый цвет нормальный.
А вот, если применить

Код: Выделить всё

    glColor3b(Red-128, Green-128, Blue-128);
то заливка черная, т.е. цвет не формируется. Задаю clBlue или clRed, или задаю просто числа (разбиваю число $0000FF или $FF0000) - работают все варианты. Задаю вручную $008000 - не работает.
Кто-нибудь сталкивался?
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>А вот, если применить
А ты чего хотел этим добиться?
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

glColor3b конвертирует числа из [-128,127] в [-1,1], см. секцию 2.13 в спеке OpenGL 1.1:
2022-10-04_21-47-15.png
2022-10-04_21-46-35.png
Cоответственно, вызов glColor3b(-128, 0, -128) эквивалентен передаче тройки (-1.0, 0.00392156862, -1.0). Предполагаю, что ожидаемый результат даст glColor3b(Red div 2, Green div 2, Blue div 2). Но мне непонятно почему просто не использовать glColor3ub?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Seenkao
энтузиаст
Сообщения: 568
Зарегистрирован: 01.04.2020 02:37:12
Контактная информация:

Сообщение Seenkao »

Дож писал(а):вызов glColor3b(-128, 0, -128)
это так не работает. Числа идут только положительные. От 0 до 255 для байта и от 0 до 1 для Single/Double.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Seenkao писал(а):это так не работает. Числа идут только положительные.
Как "это работает" написано в спецификации. Для тех, кому лень самостоятельно залезть спецификацию прежде чем объяснять как оно работает, я процитирую её здесь (OpenGL 1.1 Specification, таблица 2.2):
2022-10-06_14-04-40.png
И вот ещё:

Код: Выделить всё

D:\data\opensource\fpc\packages\opengl>grep -R "\<glColor3b\>" .
./src/gl.pp:  glColor3b: procedure(red, green, blue: GLbyte); extdecl;
./src/gl.pp:  @glColor3b := nil;
./src/gl.pp:    @glColor3b := GetGLProcAddress(LibGL, 'glColor3b');

D:\data\opensource\fpc\packages\opengl>grep -R "\<GLbyte\>" .
./src/gl.pp:  GLbyte     = ShortInt;      PGLbyte     = ^GLbyte;
./src/gl.pp:  TGLbyte     = GLbyte;
./src/gl.pp:  glColor3b: procedure(red, green, blue: GLbyte); extdecl;
./src/gl.pp:  glColor4b: procedure(red, green, blue, alpha: GLbyte); extdecl;
./src/gl.pp:  glNormal3b: procedure(nx, ny, nz: GLbyte); extdecl;
./src/glext.pp:  glSecondaryColor3bEXT: procedure(components: GLbyte); extdecl;
./src/glext.pp:  glSecondaryColor3bvEXT: procedure(components: GLbyte); extdecl;
./src/glext.pp:  glNormalStream3b: procedure(stream: GLenum; coords: GLbyte); extdecl;
./src/glext.pp:  glNormalStream3bv: procedure(stream: GLenum; coords: GLbyte); extdecl;
./src/glext.pp:  glSecondaryColor3b: procedure(red: GLbyte; green: GLbyte; blue: GLbyte); extdecl;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Seenkao
энтузиаст
Сообщения: 568
Зарегистрирован: 01.04.2020 02:37:12
Контактная информация:

Сообщение Seenkao »

не веришь, твои проблемы. Мучайся дальше.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

не веришь
А с чего это вдруг я должен вам верить? Вы мой батюшка? Нет, вы не мой батюшка, вы форумный невежда, который говорит ерунду, сам не приводит никаких аргументов, и, видимо, даже не в состоянии вдумчиво прочитать куски спецификаций, которые прямо противоречат вашим же бредням.
Seenkao
энтузиаст
Сообщения: 568
Зарегистрирован: 01.04.2020 02:37:12
Контактная информация:

Сообщение Seenkao »

Дож писал(а):вы форумный невежда, который говорит ерунду, сам не приводит никаких аргументов, и, видимо, даже не в состоянии вдумчиво прочитать куски спецификаций, которые прямо противоречат вашим же бредням.
Ещё один умник, который головой не хочет думать, но оскорбить надо обязательно (у вас там ПМС начался?), да ещё и проверить не может.

Мне не надо ни каких доказательств приводить, я работаю с OpenGL уже давно.

Читай "OpenGL суперкнига". Раз тут только можешь только оскорбления кидать.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

OpenGL суперкнига (третье издание, ISBN 5-8459-0998-8), стр. 75:
2022-10-06_19-45-48.png
Тут сказано, что суффикс b указывает на знаковое число, это согласуется со спецификацией, и не согласуется с тем, что пишете вы.
Мне не надо ни каких доказательств приводить, я работаю с <Икс> уже давно.
Невежды любят так говорить :)
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Seenkao
энтузиаст
Сообщения: 568
Зарегистрирован: 01.04.2020 02:37:12
Контактная информация:

Сообщение Seenkao »

Дож писал(а):Тут сказано, что суффикс b указывает на знаковое число
Дож писал(а): эквивалентен передаче тройки (-1.0, 0.00392156862, -1.0).
я мог быть и не прав насчёт байтов, но советую заглянуть на страницу 276.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Читаю что написано на странице 276:
2022-10-06_20-38-05.png
Здесь описано что происходит для целых чисел от 0 до их максимального значения, но не написано что происходит с целыми числами меньше нуля.

Так что же на самом деле произойдёт если вызвать glColor3b(-128, 0, -128); ? Варианты ответов:
1. Ошибка компиляции из-за неправильного типа
2. OpenGL вернёт ошибку в рантайме при проверке операндов
3. Undefined Behavior (например, драйвер форматирует диск)
4. Клампинг по [0,255] и приведение к (0.0, 0.0, 0.0)
5. Линейное маппирование из [-128,127] в [0.0,1.0], что даёт (0, 0.50196078431, 0) (этот вариант, видимо, предполагает топикстартер)
6. В точности так, как сказано в спецификации: если подставить в формулу для GLbyte, то получится (-1.0, 0.00392156862, -1.0)

Я свой вариант ответа уже привёл и обосновал.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

"И тут влез я со своим самоваром!" :wink:
Сори, но чем glColor3f ( и glColor4f ) не угодили? Реально ведь (ИМХО) проще всего. (Все равно ведь весь ОpenGl работает с вещественными числами )
(Прокутил код своей ОpenGl/ОpenVR технодемки ничего другого не нашел. Хотя насколько я помню пробовал множество вариантов - но видимо другие варианты glColor не прижились )
А если хочется пересчета из целочисленных форматов пишешь что-то вроде этого.

Код: Выделить всё

 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 glColor4f( Red(Color)/255,Green(Color)/255 ,Blue(Color)/255,1-TRSet/100);
Ответить