Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (PDF) (1124368), страница 13
Текст из файла (страница 13)
Çåðêàëüíûå îòðàæåíèÿ109g l S t e n c i l F u n c (GL_EQUAL, 0x1 , 0 x f f f f f f f f ) ;/* çíà÷åíèå â áóôåðå ðàâíî 2 , åñëè òåíü óæå âûâåäåíà */g l S t e n c i l O p (GL_KEEP, GL_KEEP, GL_INCR) ;/* âûâîäèì òåíè */RenderShadow ( ) ;Ñòðîãî ãîâîðÿ, äàæå ïðè ïðèìåíåíèè ìàñêèðîâàíèÿ îñòàþòñÿ íåêîòîðûå ïðîáëåìû, ñâÿçàííûå ñ ðàáîòîé z-áóôåðà.  ÷àñòíîñòè, íåêîòîðûå ó÷àñòêè òåíåé ìîãóò ñòàòü íåâèäèìûìè. Äëÿðåøåíèÿ ýòîé ïðîáëåìû ìîæíî íåìíîãî ïðèïîäíÿòü òåíè íàäïëîñêîñòüþ c ïîìîùüþ ìîäèôèêàöèè óðàâíåíèÿ, îïèñûâàþùåãîïëîñêîñòü. Îïèñàíèå äðóãèõ ìåòîäîâ âûõîäèò çà ðàìêè äàííîãîïîñîáèÿ.8.3.
Çåðêàëüíûå îòðàæåíèÿ ýòîì ðàçäåëå ìû ðàññìîòðèì àëãîðèòì ïîñòðîåíèÿ îòðàæåíèé îò ïëîñêèõ îáúåêòîâ. Òàêèå îòðàæåíèÿ ïðèäàþò áîëüøóþ äîñòîâåðíîñòü ïîñòðîåííîìó èçîáðàæåíèþ è èõ îòíîñèòåëüíî ëåãêî ðåàëèçîâàòü.Àëãîðèòì èñïîëüçóåò èíòóèòèâíîå ïðåäñòàâëåíèå ïîëíîé ñöåíû ñ çåðêàëîì êàê ñîñòàâëåííîé èç äâóõ: ¾íàñòîÿùåé¿ è ¾âèðòóàëüíîé¿ íàõîäÿùåéñÿ çà çåðêàëîì. Ñëåäîâàòåëüíî, ïðîöåññðèñîâàíèÿ îòðàæåíèé ñîñòîèò èç äâóõ ÷àñòåé: 1) âèçóàëèçàöèèîáû÷íîé ñöåíû è 2) ïîñòðîåíèÿ è âèçóàëèçàöèè âèðòóàëüíîé.Äëÿ êàæäîãî îáúåêòà ¾íàñòîÿùåé¿ ñöåíû ñòðîèòñÿ åãî îòðàæåííûé äâîéíèê, êîòîðûé íàáëþäàòåëü è óâèäèò â çåðêàëå.Äëÿ èëëþñòðàöèè ðàññìîòðèì êîìíàòó ñ çåðêàëîì íà ñòåíå.Êîìíàòà è îáúåêòû, íàõîäÿùèåñÿ â íåé, âûãëÿäÿò â çåðêàëå òàê,êàê åñëè áû çåðêàëî áûëî îêíîì, à çà íèì áûëà áû åùå îäíà òàêàÿ æå êîìíàòà ñ òåì æå îáúåêòàìè, íî ñèììåòðè÷íî îòðàæåííûìè îòíîñèòåëüíî ïëîñêîñòè, ïðîâåäåííîé ÷åðåç ïîâåðõíîñòüÃëàâà 8. Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGL110Ðèñ.
8.1. Çåðêàëüíîå îòðàæåíèåçåðêàëà.Óïðîùåííûé âàðèàíò àëãîðèòìà ñîçäàíèÿ ïëîñêîãî îòðàæåíèÿ ñîñòîèò èç ñëåäóþùèõ øàãîâ:1) Ðèñóåì ñöåíó êàê îáû÷íî, íî áåç îáúåêòîâ-çåðêàë.2) Èñïîëüçóÿ áóôåð ìàñêè, îãðàíè÷èâàåì äàëüíåéøèé âûâîäïðîåêöèåé çåðêàëà íà ýêðàí.3) Âèçóàëèçèðóåì ñöåíó, îòðàæåííóþ îòíîñèòåëüíî ïëîñêîñòèçåðêàëà. Ïðè ýòîì áóôåð ìàñêè ïîçâîëèò îãðàíè÷èòü âûâîäôîðìîé ïðîåêöèè îáúåêòà-çåðêàëà.Ýòà ïîñëåäîâàòåëüíîñòü äåéñòâèé ïîçâîëèò ïîëó÷èòü óáåäèòåëüíûé ýôôåêò îòðàæåíèÿ.Ðàññìîòðèì ýòàïû áîëåå ïîäðîáíî.Ñíà÷àëà íåîáõîäèìî íàðèñîâàòü ñöåíó êàê îáû÷íî. Íå áóäåì îñòàíàâëèâàòüñÿ íà ýòîì ýòàïå ïîäðîáíî. Çàìåòèì òîëüêî,÷òî, î÷èùàÿ áóôåðû OpenGL íåïîñðåäñòâåííî ïåðåä ðèñîâàíèåì, íóæíî íå çàáûòü î÷èñòèòü áóôåð ìàñêè:8.3. Çåðêàëüíûå îòðàæåíèÿ111g l C l e a r (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) ;Âî âðåìÿ âèçóàëèçàöèè ñöåíû ëó÷øå íå ðèñîâàòü îáúåêòû,êîòîðûå çàòåì ñòàíóò çåðêàëüíûìè.Íà âòîðîì ýòàïå íåîáõîäèìî îãðàíè÷èòü äàëüíåéøèé âûâîäïðîåêöèåé çåðêàëüíîãî îáúåêòà íà ýêðàí.Äëÿ ýòîãî íàñòðàèâàåì áóôåð ìàñêè è ðèñóåì çåðêàëîglEnable (GL_STENCIL_TEST) ;/* óñëîâèå â ñ å ã ä à âûïîëíåíî è çíà÷åíèå â áóôåðåáóäåò ðàâíî 1 */g l S t e n c i l F u n c (GL_ALWAYS, 1 , 0 ) ;g l S t e n c i l O p (GL_KEEP, GL_KEEP, GL_REPLACE) ;RenderMirrorObject ( ) ; ðåçóëüòàòå ìû ïîëó÷èëè:â áóôåðå êàäðà êîððåêòíî íàðèñîâàííàÿ ñöåíà, çà èñêëþ÷åíèåì îáëàñòè çåðêàëà;â îáëàñòè çåðêàëà (òàì, ãäå ìû õîòèì âèäåòü îòðàæåíèå)çíà÷åíèå áóôåðà ìàñêè ðàâíî 1.Íà òðåòüåì ýòàïå íóæíî íàðèñîâàòü ñöåíó, îòðàæåííóþ îòíîñèòåëüíî ïëîñêîñòè çåðêàëüíîãî îáúåêòà.Ñíà÷àëà íàñòðàèâàåì ìàòðèöó îòðàæåíèÿ.
Ìàòðèöà îòðàæåíèÿ äîëæíà çåðêàëüíî îòðàæàòü âñþ ãåîìåòðèþ îòíîñèòåëüíîïëîñêîñòè, â êîòîðîé ëåæèò îáúåêò-çåðêàëî. Åå ìîæíî ïîëó÷èòü,íàïðèìåð, ñ ïîìîùüþ òàêîé ôóíêöèè (ïîïðîáóéòå ïîëó÷èòü ýòóìàòðèöó ñàìîñòîÿòåëüíî â êà÷åñòâå óïðàæíåíèÿ):void r e f l e c t i o n m a t r i x ( GLfloat r e f l e c t i o n _ m a t r i x [ 4 ] [ 4 ] ,{GLfloat plane_point [ 3 ] ,G l f l o a t plane_normal [ 3 ] )GLfloat * p ;112Ãëàâà 8. Ãðàôè÷åñêèå àëãîðèòìû íà îñíîâå OPENGLGLfloat * v ;float pv ;GLfloat * p = ( G l f l o a t * ) plane_point ;G l f l o a t * v = ( G l f l o a t * ) plane_normal ;float pv = p [ 0 ] * v [0]+ p [ 1 ] * v [1]+ p [ 2 ] * v [ 2 ] ;}reflection_matrixreflection_matrixreflection_matrixreflection_matrix[0][0][1][0][2][0][3][0]====1 − 2 * v[0] * v [0];− 2 * v[0] * v [1];− 2 * v[0] * v [2];2 * pv * v [ 0 ] ;reflection_matrixreflection_matrixreflection_matrixreflection_matrix[0][1][1][1][2][1][3][1]====− 2 * v[0] * v [1];1− 2 * v [ 1 ] * v [ 1 ] ;− 2 * v[1] * v [2];2 * pv * v [ 1 ] ;reflection_matrixreflection_matrixreflection_matrixreflection_matrix[0][2][1][2][2][2][3][2]====− 2 * v[0] * v [2];− 2 * v[1] * v [2];1 − 2 * v[2] * v [2];2 * pv * v [ 2 ] ;reflection_matrixreflection_matrixreflection_matrixreflection_matrix[0][3][1][3][2][3][3][3]====0;0;0;1;Íàñòðàèâàåì áóôåð ìàñêè íà ðèñîâàíèå òîëüêî â îáëàñòÿõ,ãäå çíà÷åíèå áóôåðà ðàâíî 1:/* óñëîâèå âûïîëíåíî è òåñò äàåò èñòèíóòîëüêî åñëè çíà÷åíèå â áóôåðå ìàñêè ðàâíî 1 */g l S t e n c i l F u n c (GL_EQUAL, 0x1 , 0 x f f f f f f f f ) ;/* íè÷åãî íå ìåíÿåì â áóôåðå */g l S t e n c i l O p (GL_KEEP, GL_KEEP, GL_KEEP) ;è ðèñóåì ñöåíó åùå ðàç (áåç çåðêàëüíûõ îáúåêòîâ)8.4.
Êîíòðîëüíûå âîïðîñû113glPushMatrix ( ) ;glMultMatrixf ( ( float * ) r e f l e c t i o n _ m a t r i x ) ;RenderScene ( ) ;glPopMatrix ( ) ;Íàêîíåö, îòêëþ÷àåì ìàñêèðîâàíèå:g l D i s a b l e (GL_STENCIL_TEST) ;Ïîñëå ýòîãî ìîæíî îïöèîíàëüíî åùå ðàç âûâåñòè çåðêàëüíûéîáúåêò, íàïðèìåð, ñ àëüôà-ñìåøåíèåì äëÿ ñîçäàíèÿ ýôôåêòàçàìóòíåíèÿ çåðêàëà è ò.ä.Îáðàòèòå âíèìàíèå, ÷òî îïèñàííûé ìåòîä êîððåêòíî ðàáîòàåò, òîëüêî åñëè çà çåðêàëüíûì îáúåêòîì íåò äðóãèõ îáúåêòîâñöåíû. Ïîýòîìó ñóùåñòâóåò íåñêîëüêî ìîäèôèêàöèé ýòîãî àëãîðèòìà, îòëè÷àþùèõñÿ ïîñëåäîâàòåëüíîñòüþ äåéñòâèé è èìåþùèõ ðàçíûå îãðàíè÷åíèÿ íà ãåîìåòðèþ.8.4.
Êîíòðîëüíûå âîïðîñû ðåçóëüòàòå ÷åãî âîçíèêàåò ýôôåêò ñòóïåí÷àòîñòè èçîáðàæåíèÿ? Îïèøèòå àëãîðèòì óñòðàíåíèÿ ñòóïåí÷àòîñòè.Ïî÷åìó â OpenGL íåò âñòðîåííîé ïîääåðæêè ïîñòðîåíèÿòåíåé?Êðàòêî îïèøèòå ïðåäëîæåííûé ìåòîä âèçóàëèçàöèè çåðêàëüíûõ îáúåêòîâ. Ïî÷åìó îí íå ðàáîòàåò, åñëè çà çåðêàëîìíàõîäÿòñÿ äðóãèå îáúåêòû ñöåíû? ×òî áóäåò îòðàæàòüñÿ âýòîì ñëó÷àå? Ïîäóìàéòå, êàê îáîéòè ýòî îãðàíè÷åíèå?Ãëàâà 9.Îïòèìèçàöèÿ ïðîãðàìì9.1. Îðãàíèçàöèÿ ïðèëîæåíèÿÍà ïåðâûé âçãëÿä ìîæåò ïîêàçàòüñÿ, ÷òî ïðîèçâîäèòåëüíîñòüãðàôè÷åñêèõ ïðèëîæåíèé, îñíîâàííûõ íà OpenGL, îïðåäåëÿåòñÿâ ïåðâóþ î÷åðåäü ïðîèçâîäèòåëüíîñòüþ ðåàëèçàöèè ñàìîé áèáëèîòåêè.
Ýòî âåðíî, îäíàêî îðãàíèçàöèÿ âñåãî ïðèëîæåíèÿ òàêæå î÷åíü âàæíà.9.1.1. Âûñîêîóðîâíåâàÿ îïòèìèçàöèÿÎáû÷íî îò ïðîãðàììû ïîä OpenGL òðåáóåòñÿ âèçóàëèçàöèÿâûñîêîãî êà÷åñòâà íà èíòåðàêòèâíûõ ñêîðîñòÿõ. Íî êàê ïðàâèëî,è òî è äðóãîå ñðàçó ïîëó÷èòü íå óäàåòñÿ. Ñëåäîâàòåëüíî, íåîáõîäèì ïîèñê êîìïðîìèññà ìåæäó êà÷åñòâîì è ïðîèçâîäèòåëüíîñòüþ. Ñóùåñòâóåò ìíîæåñòâî ðàçëè÷íûõ ïîäõîäîâ, íî èõ ïîäðîáíîå îïèñàíèå âûõîäèò çà ïðåäåëû ýòîãî ïîñîáèÿ. Ïðèâåäåì ëèøüíåñêîëüêî ïðèìåðîâ.Ìîæíî îòîáðàæàòü ãåîìåòðèþ ñöåíû ñ íèçêèì êà÷åñòâîìâî âðåìÿ àíèìàöèè, à â ìîìåíòû îñòàíîâîê ïîêàçûâàòü åå ñ115Ãëàâà 9. Îïòèìèçàöèÿ ïðîãðàìì116íàèëó÷øèì êà÷åñòâîì. Âî âðåìÿ èíòåðàêòèâíîãî âðàùåíèÿ(íàïðèìåð, ïðè íàæàòîé êëàâèøå ìûøè) âèçóàëèçèðîâàòüìîäåëü ñ óìåíüøåííûì êîëè÷åñòâîì ïðèìèòèâîâ.
Ïðè ðèñîâàíèè ñòàòè÷íîãî èçîáðàæåíèÿ îòîáðàæàòü ìîäåëü ïîë-íîñòüþ.Àíàëîãè÷íî, îáúåêòû, êîòîðûå ðàñïîëàãàþòñÿ äàëåêî îòíàáëþäàòåëÿ, ìîãóò áûòü ïðåäñòàâëåíû ìîäåëÿìè ïîíèæåííîé ñëîæíîñòè. Ýòî çíà÷èòåëüíî ñíèçèò íàãðóçêó íàâñå ñòóïåíè êîíâåéåðà OpenGL. Îáúåêòû, êîòîðûå íàõîäÿòñÿ ïîëíîñòüþ âíå ïîëÿ âèäèìîñòè, ìîãóò áûòü ýôôåêòèâíî îòñå÷åíû áåç ïåðåäà÷è íà êîíâåéåð OpenGL ñ ïîìîùüþ ïðîâåðêè ïîïàäàíèÿ îãðàíè÷èâàþùèõ èõ ïðîñòûõîáúåìîâ (ñôåð èëè êóáîâ) â ïèðàìèäó çðåíèÿ.9.1.2. Íèçêîóðîâíåâàÿ îïòèìèçàöèÿÎáúåêòû, îòîáðàæàåìûå ñ ïîìîùüþ OpenGL, õðàíÿòñÿ âíåêîòîðûõ ñòðóêòóðàõ äàííûõ. Îäíè òèïû òàêèõ ñòðóêòóð áîëåå ýôôåêòèâíû â èñïîëüçîâàíèè, ÷åì äðóãèå, ÷òî îïðåäåëÿåòñêîðîñòü âèçóàëèçàöèè.Æåëàòåëüíî, ÷òîáû èñïîëüçîâàëèñü ñòðóêòóðû äàííûõ, êîòîðûå ìîãóò áûòü áûñòðî è ýôôåêòèâíî ïåðåäàíû íà êîíâåéåðOpenGL.
Íàïðèìåð, åñëè ìû õîòèì îòîáðàçèòü ìàññèâ òðåóãîëüíèêîâ, òî èñïîëüçîâàíèå óêàçàòåëÿ íà ýòîò ìàññèâ çíà÷èòåëüíîáîëåå ýôôåêòèâíî, ÷åì ïåðåäà÷à åãî OpenGL ïîýëåìåíòíî.Ïðèìåð. Ïðåäïîëîæèì, ÷òî ìû ïèøåì ïðèëîæåíèå, êîòîðîåðåàëèçóåò ðèñîâàíèå êàðòû ìåñòíîñòè. Îäèí èç êîìïîíåíòîâ áàçû äàííûõ ñïèñîê ãîðîäîâ ñ èõ øèðèíîé, äîëãîòîé è íàçâàíèåì. Ñîîòâåòñòâóþùàÿ ñòðóêòóðà äàííûõ ìîæåò áûòü òàêîé:struct c i t y{float l a t i t u t e , l o n g i t u d e ;char * name ;/* ïîëîæåíèå ã î ð î ä à *//* íàçâàíèå */9.1.
Îðãàíèçàöèÿ ïðèëîæåíèÿint l a r g e _ f l a g ;};117/* 0 = ìàëåíüêèé , 1 = áîëüøîé */Ñïèñîê ãîðîäîâ ìîæåò õðàíèòüñÿ êàê ìàññèâ òàêèõ ñòðóêòóð.Äîïóñòèì, ìû ïèøåì ôóíêöèþ, êîòîðàÿ ðèñóåò ãîðîäà íà êàðòåâ âèäå òî÷åê ðàçíîãî ðàçìåðà ñ ïîäïèñÿìè:void d r a w _ c i t i e s ( int n , struct c i t y c i t y l i s t [ ] ){int i ;for ( i =0; i < n ; i ++){if ( c i t y l i s t [ i ] . large_flag )elseglPointSize ( 4.0 ) ;glPointSize ( 2.0 ) ;g l B e g i n ( GL_POINTS ) ;glVertex2f ( c i t y l i s t [ i ] . longitude ,ci ty li st [ i ] . latitude );glEnd ( ) ;/* ðèñóåì íàçâàíèå ã î ð î ä à */}}DrawText ( c i t y l i s t [ i ] .
l o n g i t u d e ,c i t y l i s t [ i ] . latitude ,c i t y l i s t [ i ] . name ) ;Ýòà ðåàëèçàöèÿ íåóäà÷íà ïî ñëåäóþùèì ïðè÷èíàì: glPointSizeglBeginâûçûâàåòñÿ äëÿ êàæäîé èòåðàöèè öèêëà;ìåæäóèglEndðèñóåòñÿ òîëüêî îäíà òî÷êà;âåðøèíû îïðåäåëÿþòñÿ â íåîïòèìàëüíîì ôîðìàòå.Íèæå ïðèâåäåíî áîëåå ðàöèîíàëüíîå ðåøåíèå:void d r a w _ c i t i e s ( int n , struct c i t y c i t y l i s t [ ] ){Ãëàâà 9.
Îïòèìèçàöèÿ ïðîãðàìì118int i ;/* ñíà÷àëà ðèñóåì ìàëåíüêèå òî÷êè */glPointSize ( 2.0 ) ;g l B e g i n ( GL_POINTS ) ;for ( i =0; i < n ; i ++){i f ( c i t y l i s t [ i ] . l a r g e _ f l a g ==0) {glVertex2f ( c i t y l i s t [ i ] . longitude ,ci ty li st [ i ] . latitude );}}glEnd ( ) ;/* áîëüøèå òî÷êè ðèñóåì âî âòîðóþ î÷åðåäü */glPointSize ( 4.0 ) ;g l B e g i n ( GL_POINTS ) ;for ( i =0; i < n ; i ++){i f ( c i t y l i s t [ i ] . l a r g e _ f l a g ==1){glVertex2f ( c i t y l i s t [ i ] . longitude ,ci ty li st [ i ] .
latitude );}}glEnd ( ) ;/* çàòåì ðèñóåì íàçâàíèÿ ã î ð î ä î â */}for ( i =0; i < n ; i ++){DrawText ( c i t y l i s t [ i ] . l o n g i t u d e ,c i t y l i s t [ i ] . latitude ,c i t y l i s t [ i ] . name ) ;} òàêîé ðåàëèçàöèè ìû âûçûâàåìëè÷èâàåì ÷èñëî âåðøèí ìåæäóglBeginglPointSizeè glEnd.äâàæäû è óâå-Îäíàêî îñòàþòñÿ åùå ïóòè äëÿ îïòèìèçàöèè. Åñëè ìû ïîìå-9.1. Îðãàíèçàöèÿ ïðèëîæåíèÿ119íÿåì íàøè ñòðóêòóðû äàííûõ, òî ìîæåì åùå ïîâûñèòü ýôôåêòèâíîñòü ðèñîâàíèÿ òî÷åê.