Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.09.14;
Скачать: CL | DM;

Вниз

блендинг текстур по маске   Найти похожие ветки 

 
korvin88   (2006-07-19 19:30) [0]

Всем привет!

Вопрос практический - как совместить две текстуры на одном полигоне, имея битовую маску их совмещения? Т.е. там, где маска белая, должна быть одна текстура, а там, где черная - другая. API - OpenGL.


 
DeadMeat ©   (2006-07-19 19:49) [1]

http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm
Правда пример на терраин, но сам принцип думаю понятен.


 
korvin88   (2006-07-20 04:06) [2]

Нет, не то. Там они не используют маску, а просто блендят текстуры. Мне же нужно именно по маске.


 
tButton ©   (2006-07-20 07:49) [3]

пройтись по текстурам
а потом результат положить на полигон
если маска не динамическая, то такой ваиант наиболее быстродейственнен

а вообще можно сначала положить одну текстуру
а маску сделать альфаканалом второй текстуры
и положить вторую текстуру сверьху


 
korvin88   (2006-07-20 08:36) [4]

tButton
Как именно сделать и то и другое? И что значит динамическая маска? Типа динамически изменяется со временем? У меня просто много разных масок и нужно выводить много полигонов с разными текстурами, смешанными по этим разным маскам. Т.е. изменять текстуры (приделывать к ним альфу и т.д.) не катит.


 
DeadMeat ©   (2006-07-20 08:47) [5]


> Нет, не то. Там они не используют маску, а просто блендят
> текстуры. Мне же нужно именно по маске.

Вообщето они не просто блендят текстуры, а именно блендят их по маске. Я по этому примеру делал текстурирование своего терраина. Правда есть конечно и ограничение на количество. Зато шустро.

Если надо много, то gr32 и ей подобные в помощь. Но это уже не аппаратно.
Либо как в ссылке, но многопроходным рендерингом.

Больше не знаю...
Есть конечно еще и шейдеры. Там тоже просто реализуется, но насчет быстродействия, судя по моим экспериментам, при количестве текстур больше 4-5 на один полик, тормоза выше чем через комбайнер. Хотя шейдер простой как пятка.. Пришлось оптимизировать по дальности отрисовки.


 
tButton ©   (2006-07-20 08:48) [6]

1 вариант.
есть: текстура 1, текстура 2, маска для смешивания
мешаешь обе текстуры по маске результат кладёшь в третью текстуру
эту третью текстуру кладёшь на полигон

2 вариант
есть: текстура 1, текстура 2, маска для смешивания
кладёшь на полигон текстуру 1
делаешь маску альфа-каналом для второй текстуры (или её дубликата)
кладёшь вторую текстуру на полигон поверх первой


 
korvin88   (2006-07-20 10:03) [7]

tButton
Второй вариант пока отпадает - работать, конечно, будет, только медленно. Мне же маски нужно будет часто менять.

Степень подробности первого варианта поражает :))). Самое интересное место - мешаешь обе текстуры по маске. Хотелось бы узнать, как именно это сделать? То, что потом результат нужно будет вывести на экран, можно было не говорить :).


 
tButton ©   (2006-07-20 12:44) [8]

а что не понятно?
проходишься по пикселям
result.R = sprite1.R * mask + sprite2.R * (mask - 1);
result.G = sprite1.G * mask + sprite2.G * (mask - 1);
result.B = sprite1.B * mask + sprite2.B * (mask - 1);
где
sprite#.R - красная составляющая цвета пикселя
sprite#.G - зелёная составляющая цвета пикселя
sprite#.B - синяя составляющая цвета пикселя
mask - значение маски для данного пикселя выраженое в значении 0..1
и так для каждого пикселя.


 
korvin88   (2006-07-20 13:38) [9]

tButton
Делать это в realtime?!?! Тогда уж лучше каждый раз приделывать к текстуре нужную альфу :)). Предложенный тобой способ, может, конечно, и правильный, теоретически... Но блин, меня ведь в первую очередь интересует практическая реализация такого эффекта. То, что их цвета нужно смешать по подобному закону, я уже давно понял. Но как именно это сделать??? Только шейдеры, или можно обойтись расширениями? Какими? И как?

Именно для этого я и указываю, что юзаю OpenGL. Тут, по идее, нужен блендинг, но у меня не получается его правильно настроить. Я вывожу маску - отлично. Вывожу поверх нее полигон с текстурой травы и glBlendFunc(GL_DST_COLOR,GL_ZERO) - вроде пока нормально (там где маска белая - появляется трава). Но затем пытаюсь вывести еще один полигон, с текстурой камня и glBlendFunc(GL_SRC_COLOR,GL_ONE ) - и все, уже облом (трава и камень резко меняют цвет, накладываясь друг на друга). Если юзать не битовую маску, а с альфой, то можно добиться, что камень выводится еще нормально, но трава, что ни делай, смешана с текстурой камня :((. Уже задолбался с этим :(. Я явно что-то делаю не так и почти наверняка существуют правила, как делать подобные вещи верным образом. Я вот и хочу узнать у вас, как это делается, т.к. по логике вещей, я явно не первый, кто с этим сталкивается. Искренне надеюсь на вашу помощь.


 
Trimp ©   (2006-07-20 14:12) [10]


> Делать это в realtime?!?! Тогда уж лучше каждый раз приделывать
> к текстуре нужную альфу :)). Предложенный тобой способ,
> может, конечно, и правильный, теоретически... Но блин, меня
> ведь в первую очередь интересует практическая реализация
> такого эффекта. То, что их цвета нужно смешать по подобному
> закону, я уже давно понял. Но как именно это сделать???


Это можно сделать через расширение ARB_texture_env_combine.
Описание тут http://steps3d.narod.ru/tutorials/tutorial-4.html


 
korvin88   (2006-07-20 15:24) [11]

Trimp
Гы... це я (как ты, наверное, уже понял) :))). В общем, ты мне это уже советовал :))). Просто тогда на геймдеве я рано порадовался - в реализацию закрался глюк (см. пост выше) и я решил уточнить вопрос здесь.
Мне действительно интересно, можно ли отладить вариант с блендингом.


 
a22 ©   (2006-07-20 17:34) [12]

если собираешься менять маску - делай шейдером. шейдер в 3 строки, не такой уж тяжелый, а быстрее все равно никак не сделаешь


 
korvin88   (2006-07-20 18:05) [13]

a22
Я шейдеры раньше вообще не изучал. Но раз так, то видимо, придется. Если не трудно, то подкинь сам шейдер, чтобы я мог в нем разобраться, а также какую-нить простую доку для начинающих по использованию шейдеров в Delphi/OpenGL.


 
tButton ©   (2006-07-21 08:44) [14]


> Делать это в realtime?!?!

а сделать это один раз в начале никак?


 
korvin88   (2006-07-21 11:45) [15]

tButton
Обьясняю подробно:
У меня есть ландшафт, нужно его затайлить. То место, где, например, трава граничит с камнем, нужно затекстурить по определенной маске - часть травой, а часть - камнем. Масок у меня много (16 штук). Текстур тоже (минимум - 5). Мне нужно, чтобы ландшафт рисовался, а следовательно, и текстуры блендились по маске в реальном времени (желательно с приемлимым FPS :))). Ты, насколько я понимаю, предлагаешь мне еще на этапе инициализации из базовых 16 черно-белых масок и 5 текстур сгенерировать все возможные комбинации совмещения этих текстур и забить все это в оперативу, чтобы потом рисовать по мере надобности???
Я, конечно, не спец в этом деле, но, imho, очень сильно пострадает время загрузки, а также на все это потребуется много памяти.


 
a22 ©   (2006-07-21 12:10) [16]

во многих играх тайлы были заранее нарисованы. оперативка дешевле новой видеокарты


 
tButton ©   (2006-07-21 14:25) [17]


> сгенерировать все возможные комбинации совмещения этих текстур
> и забить все это в оперативу, чтобы потом рисовать по мере
> надобности???

не все, а только те которые используются
и получится у тебя 16*5 80 текстур
не так уж много для современного железа

> во многих играх тайлы были заранее нарисованы.

угум-с

> оперативка дешевле новой видеокарты

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


 
korvin88   (2006-07-21 17:41) [18]

tButton
Вот тут ты не прав. Что значит, "только те, которые используются"? Теоретически, использоваться могут все комбинации. А следовательно, их общее число будет около 400 (навскидку). Забиндинные текстуры, насколько я знаю, действительно хранятся в видеопамяти. Нагрузка на нее будет определятся размерами тайлов. Их можно сделать небольшим, так что первая проблема не так важна, разве что если только в видеокарте не стоит ограничение на кол-во используемых текстур :))). Гораздо больше меня смущает этап загрузки всего этого дела - 100-процентно получится медленно и печально :((.

В общем, резюмирую: такие варианты для тайлинга, как
1)заготовить хренову тучу текстур заранее.
2)сгенерить эту самую тучу на этапе инициализации.
и т.п., я буду использовать только тогда, когда израсходую все остальные методы. А следовательно, с нетерпением жду ответа от a22 по поводу того шейдера в 3 строки (уж больно заманчиво звучит :))).


 
korvin88   (2006-07-22 13:35) [19]

All
Up! Ну что? У кого-нить есть идеи? Может все-таки операцию, которую предложил tButton можно провернуть и без шейдеров, только с помощью расширений? У меня пока не получается :(. Ну хоть смысл простого блендинга понял - и то польза :).

В общем тут получается, что при обычном блендинге нельзя смешать одновременно 3 текстуры (ну, 2 типа земли и маску). Сначала нужно смешать 2 (одну землю и маску). Потом добавить еще одну (вторую землю). Так вот последняя добавленная влияет на уже готовую и правильно затекстуренную часть результирующего тайла :((. И никак от этого не избавишься :(. В голову лезет пока только использовать дополнительный буффер цвета и потом обьединять его с основным. Но нутром чую, что идея -бред :))).


 
OSokin ©   (2006-07-22 21:01) [20]

Я знаю, как это делается с GDI! RTFM MaskBlt и юзай с обоими рисунками! Как еще - спрашивай у antonn"а :)


 
DeadMeat ©   (2006-07-22 22:06) [21]

Так я и не понял, почему способ из ссылки не подходит.


 
A22 ©   (2006-07-22 22:29) [22]

sampler2D TexBase0 : register(s0);
sampler2D TexBase1 : register(s1);
sampler2D TexMask  : register(s2);

void ps_main(in float2 iTex0 : TEXCOORD0, out float4 output : COLOR)
{
   float4 c0 = tex2D(TexBase0, iTex0);
   float4 c1 = tex2D(TexBase1, iTex0);
   output = (c1 - c0)*tex2D(TexMask, iTex0).r + c0;
}

это на HLSL, я работал только с DirectX. но думаю, разницы особой нет. Шейдер берет 3 текстуры и смешивает две первые по маске (третья текстура). ничего особо умного, по сути то же, что предлагали считать на процессоре, но переписанное для видюхи.

2 tButton
насчет текстур и памяти - где они будут лежать от пула зависит :)


 
korvin88   (2006-07-23 04:27) [23]

OSokin
Нет, мне нужен именно OpenGL. Если antonn что-нибудь знает, то пусть отпишется :).

DeadMeat
Может я, конечно, чего-то не понимаю, но там у них маскирование не используется. Маска - это не те данные, которые указывают, где на карте располагается трава, а где земля. Маска - это те данные, которые указывают на то, как в каждом конкретном тайле смешиваются эти текстуры.

Вот маска (приблизительно):
0000000000000000
0000000000000000
0000000000000000
0000000100000000
0011001101111000
1111111111111111
1111111111111111
1111111111111111

Единицы - белый цвет, нули - черный. Каждый тайл должен рисоваться с 3 параметрами - текстура для белого цвета, текстура для черного и маска. Если цвет маски серый (0.5), то должна получится смесь соответствующих текстур. В примере из статьи они для каждого вертекса указывают "coverage factor", т.е (насколько я понял), с какой прозрачностью нужно нарисовать там ту, или иную текстуру. Я пытаюсь реализовать совсем другой метод.

A22
Спасибо, попробую разобраться :).


 
DeadMeat ©   (2006-07-23 13:05) [24]

Собсна говоря это не просто Covarage factor.
Там ведь число в пределах 0..255. Это не так, что вот 0 это трава, а 255 это земля и ничего более. Между ними как раз и идет градация. 127 - это будет среднее между травой и землей. Да и там просто показан пример. Принцип можно из него понять и сделать как надо. Маска ведь черно белая, как ни крути. В начале (к примеру) кладется трава. И там, где на маске, скажем 255 - идет трава. Но если маску сгладить и сделать не сразу 255, а к примеру градиентом от 0 до 255, плавным, то и на полике будет плавный переход. Это и есть блендинг по вашей маске. И как раз используя расширения. А точнее комбайнер. Есть и ограничение, на 4 текстуры одновременно, но что мешает подставлять нужные текстуры в нужный момент?

Хотя конечно я могу и ошибаться, пускай спецы меня поправят. Я давно уже OGLом не занимался. Времени нет.


 
korvin88   (2006-07-23 13:52) [25]

DeadMeat
Все верно - это один из вариантов затайлить ландшафт. Но я делаю по другому. У меня маска определена для каждого тайла, а не вертекса.

Раскажу, пожалуй, зачем я это все придумал:

Какой самый простой и тупой способ красиво затайлить ландшафт? Правильно - подготовить заранее все текстуры тайлов со всеми переходами и рисовать их по мере надобности. Но вот проблема - а что если у нас 5 базовых текстур (трава, земля, снег, песок и дорога)? Тогда, как я уже говорил несколькими постами выше, нам нужно порядка 400 текстур с переходами (трава-земля 16 видов, трава-снег 16 видов и т.д.). Тут я и подумал - почему бы это дело не оптимизировать и хранить только базовые текстуры и 16 черно-белых масок переходов, а остальные блендить на основе этих масок в realtime. Такая вот была исходная мысль.


 
DeadMeat ©   (2006-07-23 22:26) [26]

Я чего сказать та хочу... Блендинг по маске мона сделать комбайнером без проблем. Хоть какой. Просто главное его правильно применить. В примере как раз это и показано. Просто вчитаться надо.
Там на всю поверхность кладется одна текстура, потом по маске, кладется другая. И получается, что маска это Coverage factor, которая показывает, где трава, а где земля. В маске это черные и белые участки. Можно еще и альфа канал подключить. Тогда одной маской можно сразу три текстуры сблендить. Но на самом деле это и есть нужный Вам (как я понял) бленд текстур по маске. Разве не так?


 
XProger ©   (2006-07-24 00:10) [27]

GLSL fragment program
uniform sampler2D mask;
uniform sampler2D tex1;
uniform sampler2D tex2;

void main(void)
{
  vec2 tc = gl_TexCoord[0].st;
  gl_FragColor = mix(texture2D(tex1, tc), texture2D(tex2, tc), texture2D(mask, tc));
}


tButton дал верное решение твоей задачи, советую не воротить носом...


 
korvin88   (2006-07-24 15:07) [28]

DeadMeat
Нет, не так, блин :). По видимому, тут без иллюстраций не обойтись. Маска у меня кладется на [b]каждый[/b] тайл. [b]Совместно[/b] с двумя текстурами. И цвет маски определяет прозрачность текселей (так, кажется, это называется) на этих текстурах, а не прозрачность самих текстур.

Короче, вот:

[b]Пример №1[/b] (как тут по человечески заливать изображения и давать ссылки я не знаю, так что сорри :))
У нас есть:
маска смешивания - http://www.gamedev.ru/images/?id=13117
текстура №1 (для белого цвета) - http://www.gamedev.ru/images/?id=13118
текстура №2 (для черного цвета) - http://www.gamedev.ru/images/?id=13119
После смешивания мы должны наложить на квад - http://www.gamedev.ru/images/?id=13120

Для полного понимания идем дальше :)))
[b]Пример №2[/b]
У нас есть:
маска смешивания - http://www.gamedev.ru/images/?id=13121
текстура №1 (для белого цвета) - http://www.gamedev.ru/images/?id=13122
текстура №2 (для черного цвета) - http://www.gamedev.ru/images/?id=13123
И какую текстуру мы должны получить в итоге??? Правильно - http://www.gamedev.ru/images/?id=13124

Надеюсь, теперь все понятно? :)) Таким образом мы для каждого квада создаем по мере надобности текстуру прямо в процессе рендеринга (на основе базовых текстур и масок). Если ты мне подскажешь, как на комбайнерах из статьи сделать такой эффект, буду тебе очень благодарен.

XProger
Я и не ворочу, просто он дал мне теорию (с которой я полностью согласен), а у меня проблемы именно с практической реализацией. За шейдер спасибо. Изучать я собирался GLSL, так что твой пример мне как раз кстати :).


 
korvin88   (2006-07-24 15:19) [29]

Правка:
Пардон, в примере 2 очепятка :)). Черному цвету соответствует текстура №1 (песок), а белому - №2 (снег).


 
DeadMeat ©   (2006-07-24 15:46) [30]

Можете меня повесить на тупость, но так я и не понял, в чем разница.
Щас времени нету это дело поднимать на чистом OGL (давно это было), поэтому простой пример на GLScene, использующий те же комбайнеры:
http://slil.ru/22949959
312 kb

Это не то?


 
DeadMeat ©   (2006-07-24 15:47) [31]


> повесить за тупость


 
DeadMeat ©   (2006-07-24 15:53) [32]

Дико извиняюсь... Не то закачал.
Вот:
http://slil.ru/22949983


 
antonn ©   (2006-07-24 16:07) [33]

korvin88   (23.07.06 4:27) [23]
Нет, мне нужен именно OpenGL. Если antonn что-нибудь знает, то пусть отпишется :).

по ОГЛ ниче не знаю :)
для битмапов(есть простор для оптимизации):
procedure CopyTransparentMask(_B_in,_B_out,_B_mask:Tbitmap; _x,_y:integer);
const  MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type  PRGBArray = ^TRGBArray;
     TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
var x, y: Integer; RowOut,RowIn,RowMask: PRGBArray;
   _r,_b,_g:integer;
begin
if (_x+_B_in.Width)>_B_out.Width then exit; if _x<0 then exit;
if (_y+_B_in.Height)>_B_out.Height then exit; if _y<0 then exit;
 _B_in.PixelFormat:=pf24bit; //!!
 _B_out.PixelFormat:=pf24bit; //!!
 _B_mask.PixelFormat:=pf24bit; //!!
 for y:=0 to _B_in.Height-1 do begin
    RowOut:= _B_out.ScanLine[y+_y];
    RowIn:= _B_in.ScanLine[y];
    RowMask:= _B_mask.ScanLine[y];
   for x:=0 to _B_in.Width-1 do
    if not((RowIn[x].rgbtRed=rc1)and(RowIn[x].rgbtGreen=gc1)and(RowIn[x].rgbtBlue=bc1))  then begin
         _r:= trunc(RowOut[x+_x].rgbtRed+((((RowIn[x].rgbtRed)-RowOut[x+_x].rgbtRed)/100)*(RowMask[x].rgbtRed*100/255)));
        if _r>255 then _r:=255 else if _r<0 then _r:=0;
         _g:= trunc(RowOut[x+_x].rgbtGreen+(((RowIn[x].rgbtGreen-RowOut[x+_x].rgbtGreen)/100)*(RowMask[x].rgbtGreen*100/255)));
        if _g>255 then _g:=255 else if _g<0 then _g:=0;
         _b:= trunc(RowOut[x+_x].rgbtBlue+(((RowIn[x].rgbtBlue-RowOut[x+_x].rgbtBlue)/100)*(RowMask[x].rgbtBlue*100/255)));
        if _b>255 then _b:=255 else if _b<0 then _b:=0;
         RowOut[x+_x].rgbtRed:=_r;
         RowOut[x+_x].rgbtGreen:=_g;
         RowOut[x+_x].rgbtBlue:=_b;
   end;
 end
end;


 
korvin88   (2006-07-24 16:34) [34]

DeadMeat
Ты прав, признаю. Комбайнеры мне помогут. Спасибо :). Действительно, в этом примере, если Tex0 - первая текстура, Tex2 - вторая, а Tex1 - битовая маска, а код комбайнера


Tex0:=Tex0;
Tex1:=Tex1;
Tex2:=Tex2;
Tex2:=Interpolate (Tex0, Tex2, Tex1);


то получается именно то, что надо (теперь хоть ясно, что с чем интерполировать :)).

Дело за малым - сделать такое самому :))). Но вот в этом мне поможет скорее не твой пример про ландшафт (там тоже комбайнеры, но принцип, я все же считаю, немного другой), а статья, которуй мне посоветовал Trimp.

Еще раз, спасибо.

P.S.
DeadMeat
Первый пример тоже рабочий (именно по нему я ответ писал), просто текстуры нужно было свои в папку кинуть :). Так даже удобнее :)).

antonn
Нет, нет. Это простой блендинг вручную. Мне нужен был аппартный, средствами OpenGL.


 
DeadMeat ©   (2006-07-24 16:36) [35]

korvin88
Собсна пжалста..


> Первый пример тоже рабочий (именно по нему я ответ писал),
>  просто текстуры нужно было свои в папку кинуть :). Так
> даже удобнее :)).

Ну в этом можно кликом загружать свои. Поэтому решил перезалить.
Там в подсказке записан формат команд. Но это так... для примера. Просто удобная обертка над комбайнером в виде "шейдера".


 
korvin88   (2006-07-25 14:13) [36]

Блииин, опять ничего не выходит :((((. Вроде разобрался по статье, что с чем интерполировать. Прикинул также по примеру DeadMeat"а, как нужно делать. Сделал. И нифига не работает - результат такой-же, какого я всегда добивался при обычном блендинге! Т.е. вторая текстура банально влияет на уже наложенную :((. Вот код:


Procedure DrawMaskedPolygon(PMask,PTex1,PTex2 : GLUint; x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 : GLfloat);
begin
 glPushAttrib(GL_ALL_ATTRIB_BITS);
   //биндим текстуру травы (для белого цвета)
   glActiveTextureARB(GL_TEXTURE0_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D,PTex1);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE        );

   //биндим маску
   glActiveTextureARB(GL_TEXTURE1_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D,PMask);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE       );

   //биндим текстуру земли (для черного цвета)
   glActiveTextureARB(GL_TEXTURE2_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D,PTex2);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB    );
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB ,GL_INTERPOLATE_ARB);

   //устанавливаем по порядку Arg0, Arg1 и Arg2 для формулы интерполяции Arg0*Arg2+Arg1*(1-Arg2)
   //самое тонкое место... может, ошибка здесь???
   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB ,GL_PREVIOUS_ARB);
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR   );

   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB ,GL_TEXTURE     );
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR   );

   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB ,GL_PREVIOUS_ARB);
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_COLOR   );

   //собственно, выводим сам квад
   glBegin(GL_TRIANGLE_STRIP);
     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,co,cz);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,co,cz);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,co,cz);
     glVertex3f          (x1,y1,z1);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,cz,cz);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,cz,cz);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,cz,cz);
     glVertex3f          (x2,y2,z2);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,co,co);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,co,co);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,co,co);
     glVertex3f          (x3,y3,z3);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,cz,co);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,cz,co);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,cz,co);
     glVertex3f          (x4,y4,z4);
   glEnd ;
 glPopAttrib ;
end ;


Может, я опять неправильно понял, как это дело использовать? Помогите, пожалуйста, разобраться.


 
Trimp ©   (2006-07-25 15:20) [37]

//самое тонкое место... может, ошибка здесь???
Здесь

glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB ,GL_PREVIOUS_ARB);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR   );

glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB ,GL_TEXTURE     );
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR   );

glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB ,GL_PREVIOUS_ARB);
glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA   );


 
Trimp ©   (2006-07-25 15:31) [38]

Замечание

Вместо

//биндим маску
  glActiveTextureARB(GL_TEXTURE1_ARB    );
  glEnable          (GL_TEXTURE_2D      );
  glBindTexture     (GL_TEXTURE_2D,PMask);
  glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE       );

лучше

  glActiveTextureARB(GL_TEXTURE1_ARB    );
  glEnable          (GL_TEXTURE_2D      );
  glBindTexture     (GL_TEXTURE_2D, PMask);
  glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB    );
  glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB
,GL_REPLACE);

  glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB
,GL_REPLACE);

  glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB ,GL_PREVIOUS_ARB);
  glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR   );

  glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB ,GL_TEXTURE);
  glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_ARB,GL_SRC_ALPHA   );

P.S. Ознакомься получше со статьёй.


 
korvin88   (2006-07-25 18:10) [39]

Trimp
Мда... пришлось повозиться, но оно в итоге заработало, наконец, как надо :).

All
Спасибо большое, всем, кто потратил на меня свое время :))).


 
Trimp ©   (2006-07-25 18:21) [40]

В чём ошибка то была?


 
korvin88   (2006-07-25 19:02) [41]

Trimp
Чья? Моя? В ДНК, надо полагать, раз так долго все это рожал :))). Но и ты тоже немного ошибся в последнем примере. Перепутал параметры - они должны относиться к маске, т.е. к первой текстуре, а не нулевой :). Это меня долго смущало. Плюс ко всему я никак не мог допереть, что маску легче сделать с альфой (возможно даже, без альфы - никак). Ну и баги по мелочи. Ну сейчас хоть работает :)). Если интересно, то вот правильная процедура (пока не оптимизировал - наверняка это все можно свести к более простой форме).


Procedure DrawMaskedPolygon(PMask,PTex1,PTex2 : GLUint; x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4 : GLfloat);
begin
 glPushAttrib(GL_ALL_ATTRIB_BITS);
   glActiveTextureARB(GL_TEXTURE0_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D,PTex2);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE ,GL_COMBINE_ARB    );
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB  ,GL_REPLACE        );
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_REPLACE        );

   glActiveTextureARB(GL_TEXTURE1_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D, PMask);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE ,GL_COMBINE_ARB    );
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB  ,GL_INTERPOLATE_ARB);
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_REPLACE        );

   glActiveTextureARB(GL_TEXTURE2_ARB    );
   glEnable          (GL_TEXTURE_2D      );
   glBindTexture     (GL_TEXTURE_2D,PTex1);
   glTexEnvi         (GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE ,GL_COMBINE_ARB    );
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB  ,GL_INTERPOLATE_ARB);
   glTexEnvi         (GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_REPLACE        );

   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB   ,GL_PREVIOUS_ARB);
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB  ,GL_SRC_COLOR   );

   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB   ,GL_TEXTURE     );
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB  ,GL_SRC_COLOR   );
   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB ,GL_TEXTURE     );
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_ARB,GL_SRC_ALPHA   );

   glTexEnvi (GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB   ,GL_PREVIOUS_ARB);
   glTexEnvi (GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB  ,GL_SRC_ALPHA   );

   glBegin(GL_TRIANGLE_STRIP);
     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,co,cz);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,co,cz);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,co,cz);
     glVertex3f          (x1,y1,z1);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,cz,cz);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,cz,cz);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,cz,cz);
     glVertex3f          (x2,y2,z2);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,co,co);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,co,co);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,co,co);
     glVertex3f          (x3,y3,z3);

     glNormal3f          (0,1,0   );
     glMultiTexCoord2fARB(GL_TEXTURE0_ARB,cz,co);
     glMultiTexCoord2fARB(GL_TEXTURE1_ARB,cz,co);
     glMultiTexCoord2fARB(GL_TEXTURE2_ARB,cz,co);
     glVertex3f          (x4,y4,z4);
   glEnd ;
 glPopAttrib ;
end ;


Еще раз, спасибо! :))


 
Trimp ©   (2006-07-25 19:16) [42]

Всё понял.  


> что маску легче сделать с альфой

Про это забыл написать.

Удачи! :))


 
имя   (2007-03-14 08:11) [43]

Удалено модератором


 
имя   (2007-03-21 20:25) [44]

Удалено модератором



Страницы: 1 2 вся ветка

Текущий архив: 2008.09.14;
Скачать: CL | DM;

Наверх




Память: 0.63 MB
Время: 0.022 c
2-1217826999
deadteachers
2008-08-04 09:16
2008.09.14
Связи между БД


2-1217593979
l_v
2008-08-01 16:32
2008.09.14
NetShareAdd


3-1205917843
pavel_guzhanov
2008-03-19 12:10
2008.09.14
rf сделать в запросе два варианта записи в одно поле?


2-1217389405
Viod
2008-07-30 07:43
2008.09.14
Работа с TTreeView


2-1217687765
BlueDragon
2008-08-02 18:36
2008.09.14
Поиск скрытых файлов