Баяковский.Начальный курс OpenGL (1124482), страница 13
Текст из файла (страница 13)
Çàìåòèì òîëüêî,÷òî, î÷èùàÿ áóôåðû 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íÿåì íàøè ñòðóêòóðû äàííûõ, òî ìîæåì åùå ïîâûñèòü ýôôåêòèâíîñòü ðèñîâàíèÿ òî÷åê. Íàïðèìåð:struct c i t y _ l i s t{};int num_cities ; /*float * p o s i t i o n ; /*char ** name ;/*float s i z e ;/*÷èñëî ã î ð î ä î â â ñïèñêå */êîîðäèíàòû ã î ð î ä à */óêàçàòåëü íà íàçâàíèÿ ã î ð î ä î â */ðàçìåð òî÷êè , îáîçíà÷àþùåé ã î ð î ä */Òåïåðü ãîðîäà ðàçíûõ ðàçìåðîâ õðàíÿòñÿ â ðàçíûõ ñïèñêàõ.Ïîëîæåíèÿ òî÷åê õðàíÿòñÿ îòäåëüíî â äèíàìè÷åñêîì ìàññèâå.Ïîñëå ðåîðãàíèçàöèè ìû èñêëþ÷àåì íåîáõîäèìîñòü â óñëîâíîìîïåðàòîðå âíóòðèglBegin/glEnd è ïîëó÷àåì âîçìîæíîñòü èñïîëü-çîâàòü ìàññèâû âåðøèí äëÿ îïòèìèçàöèè.
 ðåçóëüòàòå íàøàôóíêöèÿ âûãëÿäèò ñëåäóþùèì îáðàçîì:void d r a w _ c i t i e s ( struct c i t y _ l i s t{*list )int i ;/* ðèñóåì òî÷êè */g l P o i n t S i z e ( l i s t −>s i z e ) ;g l V e r t e x P o i n t e r ( 2 , GL_FLOAT, 0 ,l i s t −>num_cities ,l i s t −>p o s i t i o n ) ;glDrawArrays ( GL_POINTS, 0 , l i s t −>num_cities ) ;/* ðèñóåì íàçâàíèå ã î ð î ä à */for ( i =0; i < l i s t −>num_cities ; i ++){}}DrawText ( c i t y l i s t [ i ] . l o n g i t u d e ,ci ty li st [ i ] . latitudec i t y l i s t [ i ] .
name ) ;Ãëàâà 9. Îïòèìèçàöèÿ ïðîãðàìì1209.2. Îïòèìèçàöèÿ âûçîâîâ OpenGL9.2.1. Ïåðåäà÷à äàííûõ â OpenGL äàííîì ðàçäåëå ðàññìîòðèì ñïîñîáû ìèíèìèçàöèè âðåìåíèíà ïåðåäà÷ó äàííûõ î ïðèìèòèâàõ â OpenGL.Èñïîëüçóéòå ñâÿçàííûå ïðèìèòèâûÑâÿçàííûåïðèìèòèâû,òàêèåêàêGL_LINES,GL_LINE_LOOP, GL_TRIANGLE_STRIP, GL_TRIANGLE_FANè GL_QUAD_STRIP òðåáóþò äëÿ îïðåäåëåíèÿ ìåíüøå âåðøèí,÷åìîòäåëüíûåëèíèÿèëèìíîãîóãîëüíèê.Ýòîóìåíüøàåòêîëè÷åñòâî äàííûõ, ïåðåäàâàåìûõ OpenGL.Èñïîëüçóéòå ìàññèâû âåðøèíÍà áîëüøèíñòâå àðõèòåêòóð çàìåíà ìíîæåñòâåííûõ âûçîâîâglVertex/glColor/glNormalíà ìåõàíèçì ìàññèâîâ âåðøèí ìîæåòáûòü î÷åíü âûèãðûøíîé.Èñïîëüçóéòå èíäåêñèðîâàííûå ïðèìèòèâû íåêîòîðûõ ñëó÷àÿõ äàæå ïðè èñïîëüçîâàíèè ñâÿçàííûõïðèìèòèâîâGL_TRIANGLE_STRIP (GL_QUAD_STRIP)âåðøè-íû äóáëèðóþòñÿ.