Russian Qt Forum

Qt => OpenGL => Тема начата: spirits25 от Май 13, 2013, 11:06



Название: [РЕШЕНО] Регулирование прозрачности объекта
Отправлено: spirits25 от Май 13, 2013, 11:06
Всем привет, это опять я=)

Проблема на этот раз такая, не могу изменить прозрачность объекта QGLSceneNode, не меняя цвета его текстуры. Как-то криво написал, сейчас объясню.

Если я выставляю прозрачность при создании объекта (что уже не очень хороший вариант), например так:
Код:
    // ссылка на мою текстуру (обычное png изображение)
    QUrl url;
    url.setPath(filepath);
    url.setScheme(QLatin1String("file"));
    tex->setUrl(url);

    // создаю материал, устанавливаю текстуру
    QGLMaterial *mat1 = new QGLMaterial;
    mat1->setColor(QColor(0,0,0,100));
    mat1->setTexture(tex, 0);

    // добавляю материал в QGLSceneNode
    tempNode->palette()->addMaterial(mat1);
То материал становится чёрным, с прозрачностью альфа = 100. То есть я не могу сохранить цвет текстуры.

Но в идеале хотелось бы менять прозрачность уже готового к отображению объекта, то есть после builder.finalizedSceneNode();

Спасибо за любые советы и поправления.


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 13, 2013, 14:44
Может быть перед отрисовкой
Код:
myNode->draw(painter);
можно как-нибудь указать прозрачность для QGLPainter *painter ?

P.S.: добавление строки в код
Код:
painter->setColor(QColor(0, 0, 0, 100));
myNode->draw(painter);
ничего не изменил.. а ведь именно такой вариант (без изменения цвета, только прозрачности) был бы для меня идеальным..


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 14, 2013, 10:12
Стандартный подход - рисовать объекты в Z порядке (от дальних к ближним) используя glBlend c параметрами альфа - гуглите напр OpenGL transparency   


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 14, 2013, 10:24
Стандартный подход - рисовать объекты в Z порядке (от дальних к ближним) используя glBlend c параметрами альфа - гуглите напр OpenGL transparency   

Мне нужно динамически, например ползунком, поменять уровень прозрачности (от 0 до 100%). В glBlend ведь просто указываются эти параметры, без числового значения прозрачности?


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 14, 2013, 10:27
Мне нужно динамически, например ползунком, поменять уровень прозрачности (от 0 до 100%). В glBlend ведь просто указываются эти параметры, без числового значения прозрачности?
Да, но при этом учиьывается текущая альфа
Код
C++ (Qt)
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 14, 2013, 10:49
Да, но при этом учиьывается текущая альфа

Это у меня всё работает. А как мне её изменить, эту текущую альфу? У моих объектов прозрачность или 100% или 0% (текстура png местами прозрачна), а как сделать произвольное значение прозрачности?


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 14, 2013, 12:13
Это у меня всё работает. А как мне её изменить, эту текущую альфу? У моих объектов прозрачность или 100% или 0% (текстура png местами прозрачна), а как сделать произвольное значение прозрачности?
Без текстур: просто альфа компонента в цвете материала или (если материал выключен - в цвете glColor).

С текстурами: прозрачная текстура (альфа в имедже) значит что сквозь нее будет виден исходный (нетекстурированный) материал.

Ну и комбинируете как надо


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 14, 2013, 12:49
Без текстур: просто альфа компонента в цвете материала или (если материал выключен - в цвете glColor).

С текстурами: прозрачная текстура (альфа в имедже) значит что сквозь нее будет виден исходный (нетекстурированный) материал.

Ну и комбинируете как надо

Да, без текстур просто. С текстурой - альфа канал в изображении. А мне нужно сделать весь материал, например, на 40% прозрачным. Чтобы объект с текстурой был полупрозрачным. И менять эту прозрачность. Вот именно это я не могу сделать.


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 14, 2013, 15:00
Да, без текстур просто. С текстурой - альфа канал в изображении. А мне нужно сделать весь материал, например, на 40% прозрачным. Чтобы объект с текстурой был полупрозрачным. И менять эту прозрачность. Вот именно это я не могу сделать.
Для начала отключите шейдера - тогда должно получаться простой установкой альфы (цвета материала) + glBlend. Во всяком случае у меня получается  :)


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 15, 2013, 10:19
Для начала отключите шейдера - тогда должно получаться простой установкой альфы (цвета материала) + glBlend. Во всяком случае у меня получается  :)
Всё равно я не пойму, как указать альфу без цвета материала? У меня есть текстура, если я указываю через setColor, то все цвета текстуры заменяются.. Можете отрывками кода показать как отключаете шейдера и устанавливаете альфа-канал?

Спасибо.


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 16, 2013, 07:29
Всё равно я не пойму, как указать альфу без цвета материала? У меня есть текстура, если я указываю через setColor, то все цвета текстуры заменяются.. Можете отрывками кода показать как отключаете шейдера и устанавливаете альфа-канал?
В аттаче измененный файл для стандартного примера "textures"


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 16, 2013, 16:32
В аттаче измененный файл для стандартного примера "textures"

Здесь прозрачность выставляется через
Код:
GLfloat color[4] = { 1, 1, 1, 0.2};
glColor4fv(color);
А шейдера отключаются через program. Я правильно это всё понял?

И ещё, это на моменте создания объекта? или при перерисовке уже созданного тоже получится таким способом поменять прозрачность?

~~~~~~~~~~~~~~~~~~~~~~~~~~
Пересмотрел код ещё пару раз - мне нужно во время создания объекта, когда у меня доступны вертексы и текстурные координаты сделать с ними
Код:
    program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
    program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
    program->setAttributeArray
        (PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());
    program->setAttributeArray
        (PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
так?


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Май 16, 2013, 20:49
Это все на момент рисования (а не создания) причем важен порядок отрисовки. Напр если Вы перенесете код рисования белого квадрата после рисования куба - эффект исчезнет. Геометрию и текстуры заряжаете как обычно. Шейдер имеет право делать что хочет, поэтому оключать его не то чтобы "обязательно", а для "чистоты эксперимента"


Название: Re: Регулирование прозрачности объекта
Отправлено: Disa от Май 17, 2013, 11:12
Прочитал по диагонали, как обычно :) Но вроде есть чего добавить. Намучился я в свое время с этим альфа-блендингом.

1). Alpha blending работает фактический в конце конвеера, то есть на сам блендинг фраг.шейдер влиять не должен.
Цитировать
Blending is the stage of OpenGL rendering pipeline that takes the fragment color outputs from the Fragment Shader and combines them with the colors in the color buffers that these outputs map to. Blending parameters can allow the source and destination colors for each output to be combined in various ways.

2). Как было сказано, для его включения нужно делать:
Код
C++ (Qt)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

или передавать какие-то другие константы для приемника/источника

3). Желательно быть уверенным в том, что включено рисование задних граней:
Код
C++ (Qt)
glDisable(GL_CULL_FACE)

4). Нужно отсортировавать (самостоятельно) все объекты, нужно ли сортировать ВСЕ треугольники. Сортировать нужно в зависимости от расстояния от камеры до объекта. В случае многих объектом - естественно мб напряг с перформансом. Рисуем от дальних к ближнем.

5). Крутить значение прозрачности выходной текстуры, можно передавая в шейдер in переменную (или attribute для вершинного шейдера, в виде одного float, назовем alpha) и для out vec4 fragColor, пишем fragColor = vec4(texture2D( Texture1, uv), alpha);


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 17, 2013, 11:57
5). Крутить значение прозрачности выходной текстуры, можно передавая в шейдер in переменную (или attribute для вершинного шейдера, в виде одного float, назовем alpha) и для out vec4 fragColor, пишем fragColor = vec4(texture2D( Texture1, uv), alpha);

что такое vec4? или можно немного кода (контекста) для этого пункта?

Спасибо за помощь.


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Май 17, 2013, 12:19
Это все на момент рисования (а не создания) причем важен порядок отрисовки. Напр если Вы перенесете код рисования белого квадрата после рисования куба - эффект исчезнет. Геометрию и текстуры заряжаете как обычно. Шейдер имеет право делать что хочет, поэтому оключать его не то чтобы "обязательно", а для "чистоты эксперимента"

Я отрисовываю так:
Код:
    backNode->draw(painter);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    GLfloat color[4] = { 1, 1, 1, 0.2};
    glColor4fv(color);
   
    frontNode->draw(painter);
   
    glDisable(GL_BLEND);
при этом ничего не меняется. backNode и frontNode - готовые к отображению объекты QGLSceneNode, поэтому на данном этапе я не могу сделать
Код:
    program->setAttributeArray
        (PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());
    program->setAttributeArray
        (PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
, так как vertices и texCoords у меня были в момент создания объектов и после метода QGLBuilder::finalizedSceneNode() они больше не нужны.


Название: Re: Регулирование прозрачности объекта
Отправлено: Disa от Май 17, 2013, 13:18
Домой вечером доберусь, постараюсь накидать рабочий код


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Июнь 03, 2013, 15:51
Домой вечером доберусь, постараюсь накидать рабочий код
Жду помощи=)


Название: Re: Регулирование прозрачности объекта
Отправлено: Igors от Июнь 03, 2013, 16:24
Я отрисовываю так:
Код:
    backNode->draw(painter);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    GLfloat color[4] = { 1, 1, 1, 0.2};
    glColor4fv(color);
    
    frontNode->draw(painter);
    
    glDisable(GL_BLEND);
при этом ничего не меняется. backNode и frontNode - готовые к отображению объекты QGLSceneNode, поэтому на данном этапе я не могу сделать
Код:
    program->setAttributeArray
        (PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());
    program->setAttributeArray
        (PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
, так как vertices и texCoords у меня были в момент создания объектов и после метода QGLBuilder::finalizedSceneNode() они больше не нужны.
Мне в принципе нечего добавить. Если в примере работает а у Вас нет, значит что-то мешает. Попробуйте на простых объектах - напр 2 прямоугольника, один далеко, др близко. Убедитесь что выставленные glColor и glBlend не перекрываются в frontNode->draw(painter). Да, ну и менять ATTRIBUTE конечно не нужно


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Июнь 03, 2013, 16:31
Мне в принципе нечего добавить. Если в примере работает а у Вас нет, значит что-то мешает. Попробуйте на простых объектах - напр 2 прямоугольника, один далеко, др близко. Убедитесь что выставленные glColor и glBlend не перекрываются в frontNode->draw(painter). Да, ну и менять ATTRIBUTE конечно не нужно
дело в том, что у меня объекты QGLSceneNode и отрисовываются они по другому. Или это не должно влиять, схема одна должна быть?


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Июнь 03, 2013, 16:49
А для того стандартного примера qtbase/examples/opengl/textures прозрачность работает лишь при добавлении
Код:
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    GLfloat color[4] = { 1, 1, 1, 0.23 };
    glColor4fv(color);
Всё остальное Вы добавляли для наглядности, как я понял. Видимо всё таки чего-то я в упор не вижу=)


Название: Re: Регулирование прозрачности объекта
Отправлено: spirits25 от Июнь 04, 2013, 11:31
Решил, подсмотрев тут http://gitorious.org/qt-quick3d/qt-quick3d/blobs/9dd2f1b8a26f054ed61ff9151e226213fa1ebc94/src/plugins/sceneformats/obj/qglobjscenehandler.cpp , а именно с 416 строки идёт следующее:
Код:
        } else if (keyword == "d") {
            // "Dissolve factor" of the material, which is its opacity.
            if (material) {
                qreal alpha = objReadFloat(line, &posn);
                QColor ambient = material->ambientColor();
                QColor diffuse = material->diffuseColor();
                ambient.setAlphaF(alpha);
                diffuse.setAlphaF(alpha);
                material->setAmbientColor(ambient);
                material->setDiffuseColor(diffuse);
            }

Всем спасибо за помощь, особенно Igors! Надеюсь кому-нибудь эта тема сбережёт время=)