Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.233.150] |
|
Сообщ.
#1
,
|
|
|
Добрый день. Сел писать графику на OpenGL < 3.0, то есть без шейдеров, VAO и прочего. Думал, что легче будет, да и хотел бы гарантировать, что программа запустится на любом железе, вплоть до древнего хлама. Ну и наткнулся на проблему. Когда рисуется квадрат с текстурой белого полупрозрачного цвета (т.е. альфа у каждого пикселя = 0.5) поверх белого непрозрачного квадрата, то получается серый.
Настройки каждой текстуры: glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, *texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmapdata.Width, bitmapdata.Height, 0, GL_BGRA, GL_UNSIGNED_BYTE, bitmapdata.Scan0); И рисование: unsigned int len = drawlist.legth(); GlBlendEquation glBlendEquation = (GlBlendEquation)glutGetProcAddress("glBlendEquation"); glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < len; i++) { glBlendEquation(0x8006);//GL_FUNC_ADD glBindTexture(GL_TEXTURE_2D, drawlist[i].texture); glBegin(GL_QUADS); glBlendEquation(0x8006);//На всякий случай после begin glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1.0f, 1.0f, 1.0f, drawlist[i].alpha); glTexCoord2f(0.0f, 0.0f); glVertex2fv(&drawlist[i].points[0]); glTexCoord2f(1.0f, 0.0f); glVertex2fv(&drawlist[i].points[2]); glTexCoord2f(1.0f, 1.0f); glVertex2fv(&drawlist[i].points[4]); glTexCoord2f(0.0f, 1.0f); glVertex2fv(&drawlist[i].points[6]); glEnd(); } glBindTexture(GL_TEXTURE_2D, 0); glFlush(); glutSwapBuffers(); Я подумал, что в glBlendEquation оказался GL_MAX, поэтому и сделал костыль, но не помогло. При этом картинки с общей альфой (т.е. альфа каждого пикселя 255, но рисуется поверх полупрозрачного квадрата) оно рисует нормально. Как быть? Пока что вижу только способ переписать всё с шейдерами, а если на какой-то машине не запуститься, то запускать альтернативу, которая будет плохо рисовать всякие туманы и контуры (что в принципе приемлемо, но хотелось бы знать, в чём причина). На изображении на самом деле рисуется изображение с равномерным градиентом от белого к прозрачному. Прикреплённая картинка
|
Сообщ.
#2
,
|
|
|
Всё правильно работает.
Через толстое-толстое стекло ты смотришь на белый квадрат. Какого цвета он будет? Тот же квадрат перед тобой, а за ним стекло. Теперь какой цвет? Раньше так писали glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
Сообщ.
#3
,
|
|
|
Цитата business user @ Какого цвета он будет? Белый. Цитата business user @ Теперь какой цвет? Тоже белый, разве нет? Почему он должен быть не белым? Я смотрю на белую стену сквозь тонкое белое стекло, сквозь толстое белое, без стекла - всё равно всё будет белым? цвет = альфа текстуры * цвет текстуры + (1 - альфа текстуры) * цвет в буфере В нашем случае: цвет = А * белый + (1 - А) * белый = 1 * белый = белый И там стоял glBlendFunc где-то в инициализации, в фрагменты, что я показал, он не вошёл. Но я поставил его ещё пару раз в цикл на всякий случай, результат тот же. Я просто не понимаю логику OpenGL. |
Сообщ.
#4
,
|
|
|
Я OpenGL не знаю, но в Direct3D будет белый, значит и здесь должно быть так же.
Могу предположить: текстура белого полупрозрачного квадрата, случайно, не из PNG грузится, который premultipled? Если да, до должно быть как-то так: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); |
Сообщ.
#5
,
|
|
|
Цитата Mikle @ текстура белого полупрозрачного квадрата, случайно, не из PNG грузится, который premultipled Точно! Проверил побайтово получившуюся картинку, посмотрел на PixelFormat, и таки да, она premultiplied. Не думал, что LockBits может вернуть не тот PixelFormat, что в картинке, и даже не тот, что ей передают... Кажется, пора искать какую-то библиотеку по открытию изображений. Добавлено: хотя если представить, что Bitmap при загрузке из файла на самом деле загрузку откладывает, а настоящий формат оно узнаёт только когда его в явном виде просят вытянуть изображение побайтово, то это обретает смысл. |
Сообщ.
#6
,
|
|
|
Цитата k.sovailo @ Кажется, пора искать какую-то библиотеку по открытию изображений. premultipled по структуре ни чем не отличается от обычного ARGB, разница в том, как его нужно использовать. Нужно искать не "какую-то библиотеку по открытию изображений", а программу для сохранения изображений, которая не делает, как фотошоп, все PNG принудительно premultipled. |
Сообщ.
#7
,
|
|
|
Mikle, кстати да, именно фотошоп я и использовал. Я знаю, что такое premultiplied, мне просто надоела ситуация, когда GDI+ (сейчас все изображения загружаются через него) постоянно выдаёт не то, что я прошу.
|
Сообщ.
#8
,
|
|
|
Цитата k.sovailo @ просто надоела ситуация, когда GDI+ (сейчас все изображения загружаются через него) постоянно выдаёт не то, что я прошу. Ещё раз - файл premultiplied ни чем не отличается от не premultiplied. Само слово "premultiplied" - это свойство изображения, а не файла. Либо поменяй glBlendFunc как я писал выше, чтобы пользоваться premultiplied, либо, если надо именно обычную альфу, сохраняй с помощью GDI+ или с помощь какого-нибудь Paint.net. Фотошоп при сохранении в PNG меняет не просто формат, он меняет сами данные - умножает цвет на альфу. |