Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (PDF) (1124368), страница 12
Текст из файла (страница 12)
Ïðè çíà÷åíèè ïàðàìåòðà mode, ðàâíîì GL_NICEST,òî÷êè ðèñóþòñÿ êàê îêðóæíîñòè;GL_POLYGON_SMOOTH_HINT óïðàâëåíèåêà÷å-ñòâîì âûâîäà ñòîðîí ìíîãîóãîëüíèêà.Ïàðàìåòð mode èíòåðïðåòèðóåòñÿ ñëåäóþùèì îáðàçîì:GL_FASTESTGL_NICEST èñïîëüçóåòñÿ íàèáîëåå áûñòðûé àëãîðèòì; èñïîëüçóåòñÿ àëãîðèòì, îáåñïå÷èâàþùèé ëó÷-øåå êà÷åñòâî;GL_DONT_CARE âûáîð àëãîðèòìà çàâèñèò îò ðåàëèçà-öèè.Âàæíî çàìåòèòü, ÷òî êîìàíäîéglHint()ïðîãðàììèñò ìîæåòòîëüêî îïðåäåëèòü ñâîè ïîæåëàíèÿ îòíîñèòåëüíî òîãî èëè èíîãî àñïåêòà ðàñòåðèçàöèè ïðèìèòèâîâ. Êîíêðåòíàÿ ðåàëèçàöèÿOpenGL âïðàâå èãíîðèðîâàòü äàííûå óñòàíîâêè.glHint() íåëüçÿ âûçûâàòü ìåæäó îïåglBegin()/glEnd().Îáðàòèòå âíèìàíèå, ÷òîðàòîðíûìè ñêîáêàìèÃëàâà 7.
Îïåðàöèè ñ ïèêñåëÿìè987.5. Êîíòðîëüíûå âîïðîñû1) Êàêèå áóôåðû èçîáðàæåíèé èñïîëüçóþòñÿ â OpenGL è äëÿ÷åãî?2) Äëÿ ÷åãî èñïîëüçóåòñÿ êîìàíäàglBlendFunc?3) Ïî÷åìó äëÿ êîððåêòíîãî âûâîäà ïðîçðà÷íûõ îáúåêòîâ òðåáóåòñÿ ñîáëþäåíèå óñëîâèé óïîðÿäî÷åííîãî âûâîäà ïðèìèòèâîâ ñ ïðîçðà÷íîñòüþ?4) Äëÿ ÷åãî èñïîëüçóåòñÿ áóôåð-íàêîïèòåëü? Ïðèâåäèòå ïðèìåð ðàáîòû ñ íèì.5) Êàê â OpenGL ìîæíî íàëîæèòü ìàñêó íà ðåçóëüòèðóþùååèçîáðàæåíèå?6) Îáúÿñíèòå, äëÿ ÷åãî ïðèìåíÿòñÿ êîìàíäà7) Êàêîâ ýôôåêò âûïîëíåíèÿ êîìàíäûglHint(GL_FOG_HINT, GL_DONT_CARE)?glHint() .×àñòü IIÏðèåìû ðàáîòû ñ OpenGL99Ãëàâà 8.Ãðàôè÷åñêèå àëãîðèòìûíà îñíîâå OpenGL ýòîé ãëàâå ìû ðàññìîòðèì êàê ñ ïîìîùüþ OpenGL ñîçäàâàòü íåêîòîðûå èíòåðåñíûå âèçóàëüíûå ýôôåêòû, íåïîñðåäñòâåííàÿ ïîääåðæêà êîòîðûõ îòñóòñòâóåò â ñòàíäàðòå áèáëèîòåêè.8.1.
Óñòðàíåíèå ñòóïåí÷àòîñòèÍà÷íåì ñ çàäà÷è óñòðàíåíèÿ ñòóïåí÷àòîñòè (antialiasing). Ýôôåêò ñòóïåí÷àòîñòè (aliasing) âîçíèêàåò â ðåçóëüòàòå ïîãðåøíîñòåé ðàñòåðèçàöèè ïðèìèòèâîâ â áóôåðå êàäðà èç-çà êîíå÷íîãî(è êàê ïðàâèëî, íåáîëüøîãî) ðàçðåøåíèÿ áóôåðà. Åñòü íåñêîëüêîïîäõîäîâ ê ðåøåíèþ äàííîé ïðîáëåìû. Íàïðèìåð, ìîæíî ïðèìåíÿòü ôèëüòðàöèþ ïîëó÷åííîãî èçîáðàæåíèÿ. Òàêæå ýòîò ýôôåêò ìîæíî óñòðàíÿòü íà ýòàïå ðàñòåðèçàöèè, ñãëàæèâàÿ îáðàçêàæäîãî ïðèìèòèâà.
Çäåñü ìû ðàññìîòðèì ïðèåì, ïîçâîëÿþùèéóñòðàíÿòü ïîäîáíûå àðòåôàêòû äëÿ âñåé ñöåíû öåëèêîì.Äëÿ êàæäîãî êàäðà íåîáõîäèìî íàðèñîâàòü ñöåíó íåñêîëüêî101Ãëàâà 8. Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGL102ðàç, íà êàæäîì ïðîõîäå íåìíîãî ñìåùàÿ êàìåðó îòíîñèòåëüíîíà÷àëüíîãî ïîëîæåíèÿ. Ïîëîæåíèÿ êàìåð, íàïðèìåð, ìîãóò îáðàçîâûâàòü îêðóæíîñòü. Åñëè ñäâèã êàìåðû îòíîñèòåëüíî ìàë,òî ïîãðåøíîñòè äèñêðåòèçàöèè ïðîÿâÿòñÿ ïî-ðàçíîìó, è, óñðåäíÿÿ ïîëó÷åííûå èçîáðàæåíèÿ, ìû ïîëó÷èì ñãëàæåííîå èçîáðàæåíèå.Ïðîùå âñåãî ñäâèãàòü ïîëîæåíèå íàáëþäàòåëÿ, íî ïåðåä ýòèìíóæíî âû÷èñëèòü ðàçìåð ñäâèãà òàê, ÷òîáû ïðèâåäåííîå ê êîîðäèíàòàì ýêðàíà çíà÷åíèå íå ïðåâûøàëî, ñêàæåì, ïîëîâèíû ðàçìåðà ïèêñåëÿ.Âñå ïîëó÷åííûå èçîáðàæåíèÿ ñîõðàíÿåì â áóôåðå-íàêîïèòåëå ñ êîýôôèöèåíòîì1/n,ãäån ÷èñëîïðîõîäîâ äëÿ êàæäîãîêàäðà.
×åì áîëüøå òàêèõ ïðîõîäîâ òåì íèæå ïðîèçâîäèòåëüíîñòü, íî ëó÷øå ðåçóëüòàò.for ( i =0; i <samples_count;++ i )// îáû÷íî samples_count ëåæèò â ïðåäåëàõ îò 5 äî 10{ShiftCamera ( i ) ; // ñäâèãàåì êàìåðóRenderScene ( ) ;i f ( i ==0)// íà ïåðâîé èòåðàöèè çàãðóæàåì èçîáðàæåíèåglAccum (GL_LOAD, 1 / ( float ) samples_count ) ;else// äîáàâëÿåì ê óæå ñóùåñòâóþùåìó}glAccum (GL_ACCUM, 1 / ( float ) samples_count ) ;// Ïèøåì òî, ÷òî ïîëó÷èëîñü , íàçàä â èñõîäíûé áóôåðglAccum (GL_RETURN, 1 . 0 ) ;Ñëåäóåò îòìåòèòü, ÷òî óñòðàíåíèå ñòóïåí÷àòîñòè ñðàçó äëÿâñåé ñöåíû, êàê ïðàâèëî, ñâÿçàíî ñ ñåðüåçíûì ïàäåíèåì ïðîèçâîäèòåëüíîñòè âèçóàëèçàöèè, òàê êàê âñÿ ñöåíà ðèñóåòñÿ íåñêîëüêîðàç. Ñîâðåìåííûå óñêîðèòåëè îáû÷íî àïïàðàòíî ðåàëèçóþò äðóãèå ìåòîäû.8.2. Ïîñòðîåíèå òåíåé1038.2.
Ïîñòðîåíèå òåíåé OpenGL íåò âñòðîåííîé ïîääåðæêè ïîñòðîåíèÿ òåíåé íàóðîâíå áàçîâûõ êîìàíä.  çíà÷èòåëüíîé ñòåïåíè ýòî îáúÿñíÿåòñÿ òåì, ÷òî ñóùåñòâóåò ìíîæåñòâî àëãîðèòìîâ èõ ïîñòðîåíèÿ,êîòîðûå ìîãóò áûòü ðåàëèçîâàíû ÷åðåç ôóíêöèè OpenGL. Ïðèñóòñòâèå òåíåé ñèëüíî âëèÿåò íà ðåàëèñòè÷íîñòü òðåõìåðíîãîèçîáðàæåíèÿ, ïîýòîìó ðàññìîòðèì îäèí èç ïîäõîäîâ ê èõ ïîñòðîåíèþ.Áîëüøèíñòâî àëãîðèòìîâ, ïðåäíàçíà÷åííûõ äëÿ ïîñòðîåíèÿòåíåé, èñïîëüçóþò ìîäèôèöèðîâàííûå ïðèíöèïû ïåðñïåêòèâíîéïðîåêöèè. Çäåñü ðàññìàòðèâàåòñÿ îäèí èç ñàìûõ ïðîñòûõ ìåòîäîâ. Ñ åãî ïîìîùüþ ìîæíî ïîëó÷àòü òåíè, îòáðàñûâàåìûå òðåõìåðíûì îáúåêòîì íà ïëîñêîñòü.Îáùèé ïîäõîä òàêîâ: äëÿ âñåõ òî÷åê îáúåêòà íàõîäèòñÿ èõïðîåêöèÿ ïàðàëëåëüíî âåêòîðó, ñîåäèíÿþùåìó äàííóþ òî÷êó èòî÷êó, â êîòîðîé íàõîäèòñÿ èñòî÷íèê ñâåòà, íà íåêóþ çàäàííóþïëîñêîñòü.
Òåì ñàìûì ïîëó÷àåì íîâûé îáúåêò, öåëèêîì ëåæàùèé â çàäàííîé ïëîñêîñòè. Ýòîò îáúåêò è ÿâëÿåòñÿ òåíüþ èñõîäíîãî.Ðàññìîòðèì ìàòåìàòè÷åñêèå îñíîâû äàííîãî ìåòîäà.Ïóñòü:P òî÷êà â òðåõìåðíîì ïðîñòðàíñòâå, êîòîðàÿ îòáðàñûâàåòòåíü.L ïîëîæåíèå èñòî÷íèêà ñâåòà, êîòîðûé îñâåùàåò äàííóþ òî÷êó.S = a(L − P ) − P òî÷êà,P , ãäå a ïàðàìåòð.â êîòîðóþ îòáðàñûâàåò òåíü òî÷êàÏðåäïîëîæèì, ÷òî òåíü ïàäàåò íà ïëîñêîñòüñëó÷àåa = zp /(zl − zp ).Ñëåäîâàòåëüíî,z = 0. ýòîìÃëàâà 8. Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGL104xs = (xp zl − zl zp )/(zl − zp )ys = (yp zl − yl zp )/(zl − zp )zs =0Ââåäåì îäíîðîäíûå êîîðäèíàòû:xsyszsws0Îòñþäà êîîðäèíàòûS= x0s /ws0= ys0 /ws0=0= z l − zpìîãóò áûòü ïîëó÷åíû ñ èñïîëüçîâàíè-åì óìíîæåíèÿ ìàòðèö ñëåäóþùèì îáðàçîì:x0s ys0 0 ws0 = xs ys zszl0 0zl1 −xl −yl000 00 00 10 zlÄëÿ òîãî, ÷òîáû àëãîðèòì ìîã ðàññ÷èòûâàòü òåíü, ïàäàþùóþíà ïðîèçâîëüíóþ ïëîñêîñòü, ðàññìîòðèì ïðîèçâîëüíóþ òî÷êó íàëèíèè ìåæäóaP + bL,SP , ïðåäñòàâëåííóþ â îäíîðîäíûõ êîîðäèíàòàõ:a è b ñêàëÿðíûå ïàðàìåòðû.èãäåÑëåäóþùàÿ ìàòðèöà çàäàåò ïëîñêîñòü ÷åðåç êîîðäèíàòû ååíîðìàëè: xn yn G= zn dÒî÷êà, â êîòîðîé ëó÷, ïðîâåäåííûé îò èñòî÷íèêà ñâåòà ÷åðåçäàííóþ òî÷êóðàìèaèb,P , ïåðåñåêàåò ïëîñêîñòü G, îïðåäåëÿåòñÿ ïàðàìåò-óäîâëåòâîðÿþùèìè ñëåäóþùåìó óðàâíåíèþ:8.2.
Ïîñòðîåíèå òåíåé105(aP + bL)G = 0Îòñþäà ïîëó÷àåì:a(P G) + b(LG) = 0. Ýòîìó óðàâíåíèþ óäî-âëåòâîðÿþòa = (LG), b = −(P G)Ñëåäîâàòåëüíî, êîîðäèíàòû èñêîìîé òî÷êè(P G)L.S = (LG)P −Ïîëüçóÿñü àññîöèàòèâíîñòüþ ìàòðè÷íîãî ïðîèçâåäåíèÿ,ïîëó÷èìS = P [(LG)I − GL]ãäåI åäèíè÷íàÿ ìàòðèöà.(LG)I − GL èñïîëüçóåòñÿÌàòðèöà(8.1)äëÿ ïîëó÷åíèÿ òåíåé íàïðîèçâîëüíîé ïëîñêîñòè.Ðàññìîòðèì íåêîòîðûå àñïåêòû ïðàêòè÷åñêîé ðåàëèçàöèèäàííîãî ìåòîäà ñ ïîìîùüþ OpenGL.Ïðåäïîëîæèì, ÷òî ìàòðèöàíàìè èç ôîðìóëûoorShadow(LG)I − GL.áûëà ðàíåå ïîëó÷åíàÑëåäóþùèé êîä ñ åå ïîìîùüþñòðîèò òåíè äëÿ çàäàííîé ïëîñêîñòè:/* Âèçóàëèçèðóåì ñöåíó â îáû÷íîì ðåæèìå */RenderGeometry ( ) ;/* Äåëàåì òåíè ïîëóïðîçðà÷íûìè ñ èñïîëüçîâàíèåìñìåøèâàíèÿ öâåòîâ ( b l e n d i n g ) */glEnable (GL_BLEND) ;glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ;g l D i s a b l e (GL_LIGHTING ) ;glColor4f (0.0 , 0.0 , 0.0 , 0.5);glPushMatrix ( ) ;/* Ïðîåöèðóåì òåíü */glMultMatrixf ( ( GLfloat * ) floorShadow ) ;/* Âèçóàëèçèðóåì ñöåíó â ïðîåêöèè */106Ãëàâà 8.
Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGLRenderGeometry ( ) ;glPopMatrix ( ) ;glEnable (GL_LIGHTING ) ;g l D i s a b l e (GL_BLEND) ;Ìàòðèöà oorShadow ìîæåò áûòü ïîëó÷åíà èç óðàâíåíèÿ 8.1ñ ïîìîùüþ ñëåäóþùåé ôóíêöèè:/* ïàðàìåòðû :p l a n e − êîýôôèöèåíòû óðàâíåíèÿ ïëîñêîñòèl i g h t p o s − êîîðäèíàòû èñòî÷íèêà ñâåòàâîçâðàùàåò : m a t r i x − ðåçóëüòèðóþùàÿ ìàòðèöà*/void shadowmatrix ( GLfloat matrix [ 4 ] [ 4 ] ,{GLfloat plane [ 4 ] ,GLfloat l i g h t p o s [ 4 ] )GLfloat dot ;dot = plane [ 0 ]plane [ 1 ]plane [ 2 ]plane [ 3 ]****lightpos [0] +lightpos [1] +lightpos [2] +lightpos [ 3 ] ;matrix [ 0 ] [ 0 ]matrix [ 1 ] [ 0 ]matrix [ 2 ] [ 0 ]matrix [ 3 ] [ 0 ]====dot0. f0.
f0. f−−−−lightpos [0]lightpos [0]lightpos [0]lightpos [0]****plane [ 0 ] ;plane [ 1 ] ;plane [ 2 ] ;plane [ 3 ] ;matrix [ 0 ] [ 1 ]matrix [ 1 ] [ 1 ]matrix [ 2 ] [ 1 ]matrix [ 3 ] [ 1 ]====0. fdot0. f0. f−−−−lightpos [1]lightpos [1]lightpos [1]lightpos [1]****plane [ 0 ] ;plane [ 1 ] ;plane [ 2 ] ;plane [ 3 ] ;matrix [ 0 ] [ 2 ]matrix [ 1 ] [ 2 ]matrix [ 2 ] [ 2 ]matrix [ 3 ] [ 2 ]====0.
f0. fdot0. f−−−−lightpos [2]lightpos [2]lightpos [2]lightpos [2]****plane [ 0 ] ;plane [ 1 ] ;plane [ 2 ] ;plane [ 3 ] ;8.2. Ïîñòðîåíèå òåíåé}matrix [ 0 ] [ 3 ]matrix [ 1 ] [ 3 ]matrix [ 2 ] [ 3 ]matrix [ 3 ] [ 3 ]====0. f0. f0. fdot107−−−−lightpos [3]lightpos [3]lightpos [3]lightpos [3]****plane [ 0 ] ;plane [ 1 ] ;plane [ 2 ] ;plane [ 3 ] ;Çàìåòèì, ÷òî òåíè, ïîñòðîåííûå òàêèì îáðàçîì, èìåþò ðÿäíåäîñòàòêîâ:Îïèñàííûé àëãîðèòì ïðåäïîëàãàåò, ÷òî ïëîñêîñòè áåñêîíå÷íû, è íå îòðåçàåò òåíè ïî ãðàíèöå. Íàïðèìåð, åñëè íåêîòîðûé îáúåêò îòáðàñûâàåò òåíü íà ñòîë, îíà íå áóäåò îòñåêàòüñÿ ïî ãðàíèöå, è, òåì áîëåå, ¾çàâîðà÷èâàòüñÿ¿ íà áîêîâóþ ïîâåðõíîñòü ñòîëà. íåêîòîðûõ ìåñòàõ òåíåé ìîæåò íàáëþäàòüñÿ ýôôåêò¾äâîéíîãî ñìåøèâàíèÿ¿ (reblending), ò.å.
òåìíûå ïÿòíà âòåõ ó÷àñòêàõ, ãäå ñïðîåöèðîâàííûå òðåóãîëüíèêè ïåðåêðûâàþò äðóã äðóãà.Ñ óâåëè÷åíèåì ÷èñëà ïîâåðõíîñòåé ñëîæíîñòü àëãîðèòìàðåçêî óâåëè÷èâàåòñÿ, ò.ê. äëÿ êàæäîé ïîâåðõíîñòè íóæíîçàíîâî ñòðîèòü âñþ ñöåíó, äàæå åñëè ïðîáëåìà îòñå÷åíèÿòåíåé ïî ãðàíèöå áóäåò ðåøåíà.Òåíè îáû÷íî èìåþò ðàçìûòûå ãðàíèöû, à â ïðèâåäåííîìàëãîðèòìå îíè âñåãäà èìåþò ðåçêèå êðàÿ. ×àñòè÷íî èçáåæàòü ýòîãî ïîçâîëÿåò ðàñ÷åò òåíåé èç íåñêîëüêèõ èñòî÷íèêîâ ñâåòà, ðàñïîëîæåííûõ ðÿäîì è ïîñëåäóþùåå ñìåøèâàíèå ðåçóëüòàòîâ.Èìååòñÿ ðåøåíèå ïåðâîé è âòîðîé ïðîáëåìû. Äëÿ ýòîãî èñïîëüçóåòñÿ áóôåð ìàñêè (ñì. ï.
7.2).Èòàê, çàäà÷à îòñå÷ü âûâîä ãåîìåòðèè (òåíè) ïî ãðàíèöåíåêîòîðîé ïðîèçâîëüíîé îáëàñòè è èçáåæàòü ¾äâîéíîãî ñìåøè-Ãëàâà 8. Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGL108âàíèÿ¿. Îáùèé àëãîðèòì ðåøåíèÿ ñ èñïîëüçîâàíèåì áóôåðà ìàñêè òàêîâ:1) î÷èùàåì áóôåð ìàñêè çíà÷åíèåì 0;2) îòîáðàæàåìçàäàííóþîáëàñòüîòñå÷åíèÿ,óñòàíàâëèâàÿçíà÷åíèÿ â áóôåðå ìàñêè â 1;3) ðèñóåì òåíè â òåõ îáëàñòÿõ, ãäå â áóôåðå ìàñêè óñòàíîâëåíû çíà÷åíèÿ; åñëè òåñò ïðîõîäèò, óñòàíàâëèâàåì â ýòèîáëàñòè çíà÷åíèå 2.Òåïåðü ðàññìîòðèì ýòè ýòàïû áîëåå ïîäðîáíî.1./* î÷èùàåì áóôåð ìàñêè*/g l C l e a r S t e n c i l (0 x0 )g l C l e a r (GL_STENCIL_BUFFER_BIT) ;/* âêëþ÷àåì òåñò */glEnable (GL_STENCIL_TEST) ;2./* óñëîâèå â ñ å ã ä à âûïîëíåíî èçíà÷åíèå â áóôåðå áóäåò ðàâíî 1 */g l S t e n c i l F u n c (GL_ALWAYS, 0x1 , 0 x f f f f f f f f ) ;/* â ëþáîì ñëó÷àå çàìåíÿåì çíà÷åíèå â áóôåðå ìàñêè*/g l S t e n c i l O p (GL_REPLACE, GL_REPLACE, GL_REPLACE) ;/* âûâîäèì ãåîìåòðèþ , ïî êîòîðîéçàòåì áóäåò îòñå÷åíà òåíü*/RenderPlane ( ) ;3./* óñëîâèå âûïîëíåíî è òåñò äàåò èñòèíó òîëüêîåñëè çíà÷åíèå â áóôåðå ìàñêè ðàâíî 1 */8.3.