Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование игр, графики и искусственного интеллекта > Пишем движок


Автор: gepard 5.6.2005, 05:51
Часть II - Карта прозрачности.

Что такое карта прозрачности? Это чёрно-белый рисунок, который указывает на то, какие части поверхности должны иметь определённую степень прозрачности. Надо знать, что прозрачности в OpenGL, как таковой - нет. Это просто ещё одна компонента цвета, которая отображает яркость. По другому тут не скажешь. понимание этого определения достигается путём долгих экспериментов. Ладно, без офтопика...

Как всё устроено.
Всё просто... У нас есть две картинки... Конечно, если вы можете грузить картинки с альфа каналом, то вы без проблем будете обходиться и одной картинкой, главное чтобы вы могли отделить альфа канал от RGB-канала. Сначала мы отображаем поверхность, затем отключаем тест глубины, включаем смешивание, и устанавливаем на выход(GL_DST_COLOR) чёрный цвет(GL_ZERO)(т.е. всё что будет на альфа-карте чёрным цветом - будет отображаться на поверхности, а всё что белым - нет, эта область будет прозрачна), затем накладываем на неё альфа-карту и отображаем поверхность. Это мы нарисовали нашу поверхность, прозрачную там где нам надо. Теперь ещё ведь и наложить саму текстуру следует: устанавливаем в получаемом цвете буфера и источнике единицу(GL_ONE), затем накладываем RGB-картинку, после чего опять рисуем поверхность. После всего этого мы вновь включаем тест глубины и отключаем смешивание цветов.

Чтобы осознать как всё происходит надо понимать, как это работает. Вспомните свою основную функцию прорисовки в OpenGL... Какие функции там есть?
glClear(), glLoadIdentity(), gluLookAt()... По сути эта функция - это один кадр вашего проекта. Теперь понимаете? В данной функции вы указываете то, как надо отобразить объекты, при чём в это время ничего не происходит, до тех пор, конечно, пока функция не закончится. Потому что по её окончанию, результат будет выведен на экран. Когда мы рисовали поверхности, накладывая на них различные картинки - мы не создавала тем самым несколько поверхностей. Мы их просто рисовали в буфере ОДНОГО кадра. Теперь о смешивании... Функция glBlendFunc()... Если объяснить на пальцах, то мы делаем так: рисуем в буфер кадра всё, что чёрное, а белое отбрасываем... Отбрасываем по средствам смешивания... Ниже я приведу код и вы, я думаю, догоните в чём замес.

Код
Код

...//код перед
glDisable(GL_DEPTH_TEST);//Отключаем тест глубины
glBlendFunc(GL_DST_COLOR, GL_ZERO);//Записываем в буфер кадра только цвета соответствующие чёрным оттенкам альфа-карты
glEnable(GL_BLEND);//Включаем режим смешивания

skin->transparencyMap->setTexture();//Устанавливаем текстуру альфа-карты

glBegin(GL_POLYGON);//Рисуем полигоны
    for (j = 0; j < polygon[i].vertexCount; j++)//Идём по всем вершинам
    {
        glTexCoord2f(/*UV координаты альфа-карты*/);
        glVertex3f(/*коордианты вершины*/);
    }
glEnd();

glBlendFunc(GL_ONE, GL_ONE);//Рисуем всё, в буфер кадра, куда пишется только места с оттенком чёрного цвета. Тут надо въехать, что наш кадр как бы делится на два "подкадра": сначала мы рисуем первую половину, праллельно тем самым задавая параметры рисования второй половины.

skin->texture->setTexture();//Устанавливаем отображени самой текстуры - RGB-картинки

glBegin(GL_POLYGON);//Рисуем полигоны
    for (j = 0; j < polygon[i].vertexCount; j++)//По всем вершинам идём
    {
    glTexCoord2f(/*UV координаты RGB-картинки*/);
    glVertex3f(/*коордианты вершины*/);
    }
glEnd();

glDisable(GL_BLEND);//Отключаем смешивание
glEnable(GL_DEPTH_TEST);//Включаем тест глубины.
...//код дальше


Маленькая важность отображения объектов, на последок.
Дело в том, что, когда мы рисуем такие поверхности, мы отключаем тест глубины, а следовательно, объекты, которые были нарисованы раньше - будут "перекрыты" объектами в отображении которых есть отключение теста глубины, вне зависимости от того, кто расположен ближе к "зрителю". Таким образом можно сделать несложное умозаключение: сначала надо отображать те поверхности(объекты и т.п.), которые используют в своём отображении отключение теста глубины, а потом - все остальные.

Благодарю за внимание.

©Gepard aka [ss]3L33T@

Автор: chipset 5.6.2005, 06:12
В ФАК Ю! smile

Автор: gepard 5.6.2005, 06:13
smile

Автор: p0s0l 9.6.2005, 22:22
gepard, если не сложно, можешь выложить простенький .exe-пример, показывающий результат применения этих карт прозрачностей ?


Автор: gepard 10.6.2005, 07:51
См. аттач.
Серый куб под плоскостью, к которой применена карта прозрачности.

Автор: p0s0l 10.6.2005, 18:24
Хм... Я думал пример пояснит одну вещь, но так и не прояснил... Скорее всего, задаю глупый вопрос: smile
Когда используется карта прозрачности ?... Чем она лучше простой текстуры с альфа-каналом ?
Единственное преимущество я вижу лишь в том, что карта прозрачности может иметь другое разрешение, нежели сама текстура, скорее всего, применяется более меньшего разрешения, типа сделать дырку в земле... Но это ценой двойной прорисовки...
Может напишешь в статье, когда она используется, зачем и чем лучше - для таких как я... немного отставших от времени smile ?

Автор: gepard 11.6.2005, 05:30
А разниы никакой и нет. Я же писал об этом в статье. Что мол можете и текстуру с альфа каналом юзать

Автор: p0s0l 11.6.2005, 12:21
Понятно... Ну раз разницы нет, тогда зачем она нужна ? smile Ты так и не написал, в каких случаях удобно это использовать... Я вижу 2 недостатка:
- два прохода
- отключение Z-теста

Когда же текстура с альфа-каналом, Z-тест отключать не надо, и рисуется за один проход...

PS: Не совсем понятно это:
Цитата(gepard @ 5.6.2005, 05:51)
Таким образом можно сделать несложное умозаключение: сначала надо отображать те поверхности(объекты и т.п.), которые используют в своём отображении отключение теста глубины, а потом - все остальные.
Хотя судя по примеру, который ты выложил - прозрачная поверхность рисуется позже чем непрозрачный куб, т.к. если опуститься ниже (кнопкой E), то "прицел"(прозрачная поверхность) всё равно будет поверх куба, хотя от камеры находится за кубом...


Автор: gepard 12.6.2005, 07:15
Цитата(p0s0l @ 11.6.2005, 12:21)
Хотя судя по примеру, который ты выложил - прозрачная поверхность рисуется позже чем непрозрачный куб, т.к. если опуститься ниже (кнопкой E), то "прицел"(прозрачная поверхность) всё равно будет поверх куба, хотя от камеры находится за кубом...

Верно.

Цитата(p0s0l @ 11.6.2005, 12:21)
Когда же текстура с альфа-каналом, Z-тест отключать не надо, и рисуется за один проход...

Продемонстрируй.

Автор: p0s0l 12.6.2005, 11:27
Ну... Примерно так, надо только объединить две текстуры в одну с альфа-каналом...
Код
...//код перед    
//glDisable(GL_DEPTH_TEST);//Отключаем тест глубины    
// тут 2 варианта, первый аналог того, что делал gepard
// второй вариант мне больше нравиться, но нужно немного по-другому делать альфу-карту
// 1)
glBlendFunc(GL_ONE, GL_SRC_ALPHA); // или можно попробовать glBlendFunc(GL_DST_ALPHA, GL_SRC_ALPHA);
// 2)
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);

glEnable(GL_BLEND);//Включаем режим смешивания    
skin->texture->setTextureWithAlphaChannel();//Устанавливаем отображени самой текстуры - RGBA-картинки (с альфа-каналом)
glBegin(GL_POLYGON);//Рисуем полигоны    
    for (j = 0; j < polygon[i].vertexCount; j++)//По всем вершинам идём    
    {    
    glTexCoord2f(/*UV координаты RGBA-картинки*/);    
    glVertex3f(/*коордианты вершины*/);    
    }    
glEnd();    
glDisable(GL_BLEND);//Отключаем смешивание    
//glEnable(GL_DEPTH_TEST);//Включаем тест глубины.    
...//код дальше
Ну и рисовать прозрачные полигоны нужно в конце, после непрозрачных...


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)