Конференция "Игры" » Проблема с прозрачностью.
 
  • AlexanderMS © (11.08.07 16:00) [0]
    Суть в следующем: есть текстура. И нужно, чтобы объект с этой текстурой полностью был прозрачным в том месте, где цвет у текстуры равен фиолетовому (255, 0, 255) (условно).

    Вот так я готовлю текстуру в виде RGBA:

       for I := 0 to ImageSize - 1 do
         begin
           if (Texture^[I * 3] = TransparentColor[0])
           and (Texture^[I * 3 + 1] = TransparentColor[1])
           and (Texture^[I * 3 + 2] = TransparentColor[2])
             then
               begin
                 ResultTexture^[I * 4] := 255;
                 ResultTexture^[I * 4 + 1] := 255;
                 ResultTexture^[I * 4 + 2] := 255;
                 ResultTexture^[I * 4 + 3] := 0;

               end
             else
               begin
                 ResultTexture^[I * 4] := Texture^[I * 3 + 2];
                 ResultTexture^[I * 4 + 1] := Texture^[I * 3 + 1];
                 ResultTexture^[I * 4 + 2] := Texture^[I * 3];
                 ResultTexture^[I * 4 + 3] := 255;
               end;
          end;



    При рисовании прозрачности нет, а цвет - синий вместо "прозрачного".

    На форумах я встречал следующий код:

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);



    Но у меня при его использовании всё, что "рисуется" после кода - не видно вообще.
    Пробовал по-другому, и при
    glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR)

    прозрачность была, но и остальной цвет "был полупрозрачным", что не устраивает. Как сделать правильно?
  • ElectriC © (11.08.07 16:50) [1]
    Делай текстуру с алфа-каналом (например в Photoshop'e), сохраняй в PNG или TGA(-большой размер файла).
    Затем:
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    P.S. Aлфа-канал - т.б. прозрачность:))
  • @!!ex © (11.08.07 21:47) [2]
    > [1] ElectriC ©   (11.08.07 16:50)

    Проблема скорее не в самой прозрачности, а в сортировке отрисовки объекта.

    <TELEPATOR ON>
    У тебя сейчас так:
    РИсуешь некоторую сцену, потом орисуешь прозрачный объект, сквоь него нормально просвечивает сцена в местах прозрачности, потом рисуешь еще объекты и они уже скзвоь прозрачный объект не просвечивают?
    <TELEPATOR OFF>


    > [0] AlexanderMS ©   (11.08.07 16:00)

    Прозрачность не так проста, как кажеться.
    Почитай про то, как работают конвееры на видухе.
    Это очень полезная инфа.
    1) Поймешь почему прозрачность не всегда прозрачна.(тот самый случай, когда мы рисуем прозрачный объект, а потом пытаемся за ним что-то нарисовать и оно рисуется так, как будто объект не прозрачен)
    2) Шейдеры будет писать просто.
  • rts111 © (12.08.07 00:34) [3]
    Включи альфа-тест, будет тебе прозрачность:

    glEnable( GL_ALPHA_TEST );
    glAlphaFunc( GL_GREATER , 0 );
  • @!!ex © (12.08.07 12:05) [4]
    Это ,конечно ,решение.
    Но тоько в следующий раз у него возникнет надобность сделать полупрозрачный полик, и опять будет искать ответ, почему не прозрачный...
    Пускай уж лучше один раз разберется со всем...
  • AlexanderMS © (12.08.07 19:05) [5]
    Альфа тест включил, куда только не ставил код, ничего не работает. А от драйверов видеокарты прозрачность зависит? У моей всего 2 расширения поддерживается.
  • rts111 © (12.08.07 19:54) [6]
    Нужно подготовить текстуру, как ты описал в [1] посте.

    Когда инициализируешь текстуру нужно ставить GL_NEAREST, а например не GL_LINEAR:
    glTexParameterf( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST );
    glTexParameterf( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST );

    Так как тоже альфа интерполируется и получается уже не равна нулю.

    Если все же GL_LINEAR, то в glAlphaFunc сравнивай не с нулем,
    а с значением чуть больше нуля, например 0.1:

    glEnable( GL_ALPHA_TEST );
    glAlphaFunc( GL_GREATER , 0.1 );

    В твоем примере  GL_BLEND вообще включать не надо.
  • AlexanderMS © (13.08.07 18:22) [7]
    Что только не пробовал, прозрачности нет. Сделал, как в [6] - абсолютно всё прозрачно, и что не нужно, тоже. Тест везде пробовал включать. Всё, что после включения теста - не видно.
    Пробовал менять параметры - или ничего не рисуется, или
    на том месте, где должна быть прозрачность, - собственный цвет объекта, не просвечиваемый.
  • @!!ex © (13.08.07 19:01) [8]
    Короч объясняю что за функции перечислены выше.
    glEnable(GL_BLEND); - включает смешивание
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - задает закон смешивания


    Как раз включает ту самую прозрачность.
    Это очень крутая прозрачность, это даже не столько прозрачность, сколько смешивание, кторое можно использовать как прозрачность.
    В данном конкретном случае смешиваются цвета (берется цвет точки, цвет текстуры и они друг на друга накладывются) причем не с полной интенсивность, а с интенсивностью равной Alpha.
    Пример:
    На экране нарисован пиксель синего цвета.
    Мы рисуем красный, но с Альфой 0.5, в итоге красный не закроет синий полность, а всего лишь на половину, тоесть синий будет проглядывать через красный.

    На самом деле в твоем случае Смешивание(Blending) не нужен, поскольку у тебя всего два состояния: рисовать пиксель(если цвет отличаеться фиолетовго) и не рисовать пиксель(где цвет фиолетовый).
    ДЛя этого и служит Альфа Тест.
    Он берет Альфу и сравниает ее по заданному закону, если сравнение не проходит, то пиксель не рисуется, вот и все.
    glEnable( GL_ALPHA_TEST ); - включает тест
    glAlphaFunc( GL_GREATER , 0.1 ); - задает закон сравнения.


    Первый апарметр задает знак сравнения:
    Тебе нужны GL_GREATER GL_LESS GL_EQAL GL_NOTEQAL.
    Второй параметр задает значения для сравнения.
    Соответственно Больше 0.1, Меньше 0.1, Равно 0.1, Не равно 0.1.

    Попробуй использовать
    glAlphaFunc( GL_NOTEQAL , 0 );

  • AlexanderMS © (13.08.07 20:21) [9]
    @!!ex ©   (13.08.07 19:01) [8]
    Спасибо за подробную информацию.
    Но не получается. Делаю так.

    Включаю альфа-тест перед прорисовкой. Пробовал все варианты сравнения. Рисую всё. В последную очередь - объекты с прозрачностью. И вот так выглядит:
    http://alexanderms.narod.ru/ALPHA.jpg
  • @!!ex © (13.08.07 20:51) [10]
    А у меня все ок.
    Посмотри пример:
    http://afera-net.narod.ru/Alpha_Test.rar

    Если пример правлиьно заработает у тебя, я скажу где твой косяк.
  • @!!ex © (13.08.07 20:52) [11]
    Хотя че ждать. И так понятно.
    Косяк в том,ч то текстуру создаешь GL_DECAL, А надо GL_MODULATE
  • AlexanderMS © (14.08.07 06:52) [12]
    Спасибо за пример. Он работает. А в моей альфа не работает.

     
    glBindTexture(GL_TEXTURE_2D, Planet.TurnTexID);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     glTexImage2d(GL_TEXTURE_2D, 0, GL_RGBA, TurnTextureWidth, TurnTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, Planet.TurnTexture);

  • @!!ex © (14.08.07 08:18) [13]
    Ну тогда даже не знаю. Разбирайся. Рабочий пример у тебя есть.
  • grisme © (14.08.07 17:47) [14]
    у меня компилится так:
    procedure gl_engine_texture_compile_alpha(var tex:GLUInt; tb:TBMPImage; GL_FILTER: GLUInt);
    begin
           glGenTextures(1, tex);
           glBindTexture(GL_TEXTURE_2D, tex);
           glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_FILTER);
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_FILTER);
           gluBuild2DMipmaps(GL_TEXTURE_2D, 4, tb.width, tb.height, GL_RGBA, GL_UNSIGNED_BYTE, @tb.pdata[0]);
    end;



    Бленд перед рендером делаю таким:
           
    glEnable(GL_BLEND);
           glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  • AlexanderMS © (14.08.07 19:23) [15]
    Большое всем спасибо. Я думал, что
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    относится к настраиваемой текстуре, а оказывается, ко всем. Поставил перед прорисовкой - OK. Столько ломал голову над этим... :(
 
Конференция "Игры" » Проблема с прозрачностью.
Есть новые Нет новых   [134431   +10][b:0][p:0.003]