На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела "Программирование графики"
1) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с чтением, сохранением, обработкой, созданием, отрисовкой графической информации (в том числе - 3D [OpenGL, Direct3D] и анимации [в т.ч. VFW, DirectShow, OpenDML]).
Флэш обсуждают здесь!.

2) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе.

3) Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно.



Ваше мнение о модераторах: user posted imageBarazuk, user posted imageOpenGL, user posted imageMikle
Модераторы: OpenGL, Mikle
  
> OpenGL и неправильный расчёт альфы , Наложение белого на белый даёт серый
    Добрый день. Сел писать графику на OpenGL < 3.0, то есть без шейдеров, VAO и прочего. Думал, что легче будет, да и хотел бы гарантировать, что программа запустится на любом железе, вплоть до древнего хлама. Ну и наткнулся на проблему. Когда рисуется квадрат с текстурой белого полупрозрачного цвета (т.е. альфа у каждого пикселя = 0.5) поверх белого непрозрачного квадрата, то получается серый.

    Настройки каждой текстуры:
    ExpandedWrap disabled
          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);


    И рисование:
    ExpandedWrap disabled
          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, но рисуется поверх полупрозрачного квадрата) оно рисует нормально. Как быть? Пока что вижу только способ переписать всё с шейдерами, а если на какой-то машине не запуститься, то запускать альтернативу, которая будет плохо рисовать всякие туманы и контуры (что в принципе приемлемо, но хотелось бы знать, в чём причина).

    На изображении на самом деле рисуется изображение с равномерным градиентом от белого к прозрачному.
    Прикреплённая картинка
    Прикреплённая картинка
      Всё правильно работает.
      Через толстое-толстое стекло ты смотришь на белый квадрат. Какого цвета он будет?
      Тот же квадрат перед тобой, а за ним стекло. Теперь какой цвет?
      Раньше так писали
      ExpandedWrap disabled
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        Цитата business user @
        Какого цвета он будет?

        Белый.
        Цитата business user @
        Теперь какой цвет?

        Тоже белый, разве нет? Почему он должен быть не белым? Я смотрю на белую стену сквозь тонкое белое стекло, сквозь толстое белое, без стекла - всё равно всё будет белым?

        цвет = альфа текстуры * цвет текстуры + (1 - альфа текстуры) * цвет в буфере
        В нашем случае: цвет = А * белый + (1 - А) * белый = 1 * белый = белый

        И там стоял glBlendFunc где-то в инициализации, в фрагменты, что я показал, он не вошёл. Но я поставил его ещё пару раз в цикл на всякий случай, результат тот же. Я просто не понимаю логику OpenGL.
          Я OpenGL не знаю, но в Direct3D будет белый, значит и здесь должно быть так же.
          Могу предположить: текстура белого полупрозрачного квадрата, случайно, не из PNG грузится, который premultipled? Если да, до должно быть как-то так:
          ExpandedWrap disabled
            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
            Цитата Mikle @
            текстура белого полупрозрачного квадрата, случайно, не из PNG грузится, который premultipled

            Точно! Проверил побайтово получившуюся картинку, посмотрел на PixelFormat, и таки да, она premultiplied. Не думал, что LockBits может вернуть не тот PixelFormat, что в картинке, и даже не тот, что ей передают... Кажется, пора искать какую-то библиотеку по открытию изображений.

            Добавлено: хотя если представить, что Bitmap при загрузке из файла на самом деле загрузку откладывает, а настоящий формат оно узнаёт только когда его в явном виде просят вытянуть изображение побайтово, то это обретает смысл.
            Сообщение отредактировано: k.sovailo -
              Цитата k.sovailo @
              Кажется, пора искать какую-то библиотеку по открытию изображений.

              premultipled по структуре ни чем не отличается от обычного ARGB, разница в том, как его нужно использовать.
              Нужно искать не "какую-то библиотеку по открытию изображений", а программу для сохранения изображений, которая не делает, как фотошоп, все PNG принудительно premultipled.
                Mikle, кстати да, именно фотошоп я и использовал. Я знаю, что такое premultiplied, мне просто надоела ситуация, когда GDI+ (сейчас все изображения загружаются через него) постоянно выдаёт не то, что я прошу.
                  Цитата k.sovailo @
                  просто надоела ситуация, когда GDI+ (сейчас все изображения загружаются через него) постоянно выдаёт не то, что я прошу.

                  Ещё раз - файл premultiplied ни чем не отличается от не premultiplied. Само слово "premultiplied" - это свойство изображения, а не файла. Либо поменяй glBlendFunc как я писал выше, чтобы пользоваться premultiplied, либо, если надо именно обычную альфу, сохраняй с помощью GDI+ или с помощь какого-нибудь Paint.net. Фотошоп при сохранении в PNG меняет не просто формат, он меняет сами данные - умножает цвет на альфу.
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0488 ]   [ 18 queries used ]   [ Generated: 28.03.24, 12:38 GMT ]