Баяковский.Начальный курс OpenGL (1124482), страница 16
Текст из файла (страница 16)
OPENGL-ïðèëîæåíèÿ ñ ïîìîùüþ GLUT142Windows\System ñîîòâåòñòâåííî. Òàêæå â ýòèõ êàòàëîãàõ íàäîïðîâåðèòü íàëè÷èå ôàéëîâ gl.h, glu.h, opengl32.lib, glu32.lib,opengl32.dll, glu32.dll, êîòîðûå îáû÷íî âõîäÿò â ñîñòàâ BorlandC++ è Windows.Ïðè ýòîì íàäî ó÷èòûâàòü, ÷òî îðèãèíàëüíûå (äëÿ MicrosoftVisual C++) âåðñèè ôàéëà glut32.lib c Borland C++ Builder6 ðàáîòàòü íå áóäóò, è ñëåäóåò èñïîëüçîâàòü òîëüêî ñîâìåñòèìóþ âåðñèþ.
×òîáû ñîçäàòü òàêóþ âåðñèþ, íàäî èñïîëüçîâàòüñòàíäàðòíóþ ïðîãðàììó 'implib', êîòîðàÿ íàõîäèòñÿ â êàòàëîãåBorland\BDS\4.0\Bin. Äëÿ ýòîãî â êîìàíäíîé ñòðîêå íàäî âûïîëíèòü êîìàíäóimplib glut32.libglut32.dllêîòîðàÿ ñîçäàåò íóæíûé lib-ôàéë èç ñîîòâåòñòâóþùåãî dll-ôàéëà.Äëÿ ñîçäàíèÿ ïðèëîæåíèÿ íàäî âûïîëíèòü ñëåäóþùèå äåéñòâèÿ:Ñîçäàíèå ïðîåêòà: äëÿ ýòîãî íàäî âûáðàòü FileOtherConsole Application, OK. New ïîÿâèâøåìñÿ îêíå âûáðàòü Source Type ¾Ñ++¿, ¾ConsoleApplication¿, ñáðîñèòü îïöèè ¾Use VCL¿, ¾Multi Threaded¿.Íàæàòü ÎÊ.Òåêñò ïðîãðàììû ìîæíî ëèáî ðàçìåñòèòü â ñîçäàííîìòåêñòîâîì ôàéëå, ëèáî óäàëèòü åãî èç ïðîåêòà (ProjectRemove From Project) è äîáàâèòü ôàéë ñ ðàñøèðåíèåì *.cèëè *.cpp â ïðîåêò (âûáðàâ ProjectAdd To Project).Ñîõðàíèòå ñîçäàííûé ïðîåêò â æåëàåìîì êàòàëîãå (âûáðàâFileSave All).Ïîäêëþ÷èòü ê ïðîåêòó áèáëèîòåêó GLUT.
Äëÿ ýòîãî íàäîâûáðàòü ProjectAdd To Project è äîáàâèòü ôàéë glut32.lib10.5. GLUT â ñðåäå BORLAND C++ BUILDER 2006Äëÿ êîìïèëÿöèè âûáðàòü Projectíèÿ RunRun.143Build . . . , äëÿ âûïîëíå-Êîãäà ïðîãðàììà ãîòîâà, ðåêîìåíäóåòñÿ ïåðåêîìïèëèðîâàòüåå â ðåæèìå ¾Release¿ äëÿ îïòèìèçàöèè ïî áûñòðîäåéñòâèþ èîáúåìó.
Äëÿ ýòîãî íàäî âûáðàòü ProjectBuild Congurations èâ ñïèñêå ¾Conguration name¿ âûáðàòü ¾Release Build¿.Ãëàâà 11.Èñïîëüçîâàíèå OpenGL âMFC è VCLÄàëåå áóäåì ðàññìàòðèâàòü ïðèíöèïû ïîñòðîåíèå îêîííîãîïðèëîæåíèÿ Windows ñ ïîääåðæêîé OpenGL ïðè ïîìîùè âîçìîæíîñòåé áèáëèîòåê MFC (Microsoft Foundation Classes) è VCL(Visual Component Library).Ïîñêîëüêó Windows ÿâëÿåòñÿ ìíîãîîêîííîé îïåðàöèîííîéñèñòåìîé, îñíîâíàÿ çàäà÷à ïðèëîæåíèÿ íà ýòàïå èíèöèàëèçàöèè ¾ïðèâÿçàòü¿ êîìàíäû OpenGL ê êîíêðåòíîìó îêíó è ñîçäàòü äëÿ ýòîãî îêíà âñå âñïîìîãàòåëüíûå áóôåðû (áóôåð êàäðà,áóôåð ãëóáèíû è ò.ï.). Ñàìà áèáëèîòåêà íå ñîäåðæèò ñðåäñòâ äëÿýòîãî, ïîýòîìó êàæäàÿ îïåðàöèîííàÿ ñèñòåìà, ïîääåðæèâàþùàÿOpenGL, ïðåäîñòàâëÿåò ñâîè. Áèáëèîòåêà GLUT ïðåäñòàâëÿåò óíèôèöèðîâàííûé èíòåðôåéñ äëÿ äîñòóïà ê ýòîé ôóíêöèîíàëüíîñòè, îäíàêî ïëàòîé çà óíèôèêàöèþ ÿâëÿåòñÿ äîñòàòî÷íîñêðîìíûå âîçìîæíîñòè ïîñòðîåíèÿ ãðàôè÷åñêîãî èíòåðôåéñàïîëüçîâàòåëÿ, ðåàëèçîâàííûå â GLUT.
Äëÿ ñîçäàíèÿ ïðèëîæåíèé ñ ðàçâèòûì èíòåðôåéñîì íåîáõîäèìî ïðèìåíÿòü ñðåäñòâàêîíêðåòíîé îïåðàöèîííîé ñèñòåìû äëÿ ðàáîòû ñ OpenGL.Äëÿ èíèöèàëèçàöèè è ðàáîòû ñ OpenGL â Windows íåîáõî145146Ãëàâà 11. Èñïîëüçîâàíèå OPENGL â MFC è VCLäèìî âûïîëíèòü ñëåäóþùèå øàãè:1) èíèöèàëèçàöèÿ (ïðè ñîçäàíèè îêíà);à) ïîëó÷åíèå è óñòàíîâêà êîíòåêñòà ãðàôè÷åñêîãî óñòðîéñòâà (ñì. ï.11.1);á) óñòàíîâêà ïèêñåëüíîãî ôîðìàòà (ï.11.2);â) ïîëó÷åíèå è óñòàíîâêà êîíòåêñòà ðèñîâàíèÿ (ï.11.3);2) ðèñîâàíèå ñ ïîìîùüþ OpenGL â îêíå;3) îñâîáîæäåíèå êîíòåêñòîâ (ïðè óäàëåíèè îêíà).11.1. Êîíòåêñò óñòðîéñòâàÊîíòåêñò óñòðîéñòâà (device context) âàæíûé ýëåìåíò ãðàôèêè â ñðåäå ÎÑ Windows. Êîíòåêñò óñòðîéñòâà óêàçûâàåò ìåñòîîòîáðàæåíèÿ ãðàôè÷åñêèõ êîìàíä.
Êîíòåêñòîì ìîæåò áûòü îêíîïðîãðàììû íà ýêðàíå, ïðèíòåð, èëè äðóãîå óñòðîéñòâî, ïîääåðæèâàþùåå ãðàôè÷åñêèé âûâîä.Èäåíòèôèêàòîð êîíòåêñòà óñòðîéñòâà ýòî ÷èñëîâîå çíà÷åíèå, çíàíèå êîòîðîãî ïîçâîëÿåò íàïðàâèòü ãðàôè÷åñêèé âûâîäâ íóæíûé êîíòåêñò. Ïåðåä íà÷àëîì ðèñîâàíèÿ íåîáõîäèìî ïîëó÷èòü ýòî ÷èñëîâîå çíà÷åíèå, à ïîñëå ðèñîâàíèÿ íóæíî êîíòåêñò îñâîáîäèòü, ò.å. âåðíóòü èñïîëüçóåìûå ðåñóðñû â ñèñòåìó.Íåñîáëþäåíèå ýòîãî ïðàâèëà ÷ðåâàòî òàêèìè ïîñëåäñòâèÿìè êàêóòå÷êè ïàìÿòè è ïðåêðàùåíèå íîðìàëüíîé ðàáîòû ïðîãðàììû.Ïîñêîëüêó íàøåé çàäà÷åé ÿâëÿåòñÿ ðèñîâàíèå â îêíå, êîí-hDC ìîæíî ïîëó÷èòü ïî èäåíòèôèêàòîðó îêíàhWnd:HWND hWnd = <êîä ïîëó÷åíèå èäåíòèôèêàòîðà îêíà >;HDC hDC = GetDC(hWnd ) ;òåêñò óñòðîéñòâàÄëÿ îñâîáîæäåíèÿ êîíòåêñòà èñïîëüçóåòñÿ êîìàíäàReleaseDC (hWnd, hDC ) ;ReleaseDC:11.2.
Óñòàíîâêà ôîðìàòà ïèêñåëåé14711.2. Óñòàíîâêà ôîðìàòà ïèêñåëåéÏîñëå ïîëó÷åíèÿ êîíòåêñòà óñòðîéñòâ íóæíî óñòàíîâèòü ôîðìàò ïèêñåëåé (pixel format) êîíòåêñòà. Ýòî íóæíî äëÿ òîãî, ÷òîáû ñîîáùèòü îïåðàöèîííîé ñèñòåìå, êàêèå ðåñóðñû íåîáõîäèìîâûäåëèòü äëÿ äàííîãî êîíòåêñòà. Ôîðìàò ïèêñåëåé óêàçûâàåò,êàêèå âîçìîæíîñòè OpenGL ìû áóäåì èñïîëüçîâàòü: äâîéíîéáóôåð, áóôåð ìàñêè, áóôåð ãëóáèíû, ôîðìàò öâåòà è ò.ä.×òîáû óñòàíîâèòü ôîðìàò ïèêñåëÿ, íóæíî çàïîëíèòü ñòðóêòóðóPIXELFORMATDESCRIPTORè ïåðåäàòü åå â òåêóùèé êîí-òåêñò:PIXELFORMATDESCRIPTOR pfd ;// îáíóëÿåì â ñ å òîëüêî ÷òî ñîçäàííîé ñòðóêòóðû ;ZeroMemory(&pfd , sizeof ( pfd ) ) ;// çàïîëíÿåì ñòðóêòóðópfd .
n S i z e = sizeof ( pfd ) ;pfd . nVersion = 1 ;// ôëàãè ïîêàçûâàþò , ÷òî ìû áóäåì èñïîëüçîâàòü// äóáëèðóþùóþ áóôåðèçàöèþ OpenGL â ýòîì îêíåPfd . dwFlags = PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER;pfd . iPixelType = PFD_TYPE_RGBA;// ïîëíîöâåòíûé áóôåð öâåòà (8 áèò íà êàíàë )pfd . c C o l o r B i t s = 2 4 ;// çàïðàøèâàåì 16 áèò íà ïèêñåëü äëÿ áóôåðà ãëóáèíûpfd . cDepthBits = 1 6 ;pfd . iLayerType = PFD_MAIN_PLANE;int iFormat = ChoosePixelFormat (hDC, &pfd ) ;SetPixelFormat (hDC, iFormat , &pfd ) ;Ðàññìîòðèì ïîäðîáíåå ôóíêöèè, êîòîðûå èñïîëüçóþòñÿ äëÿóñòàíîâêè ôîðìàòà ïèêñåëÿ:int ChoosePixelFormat (HDC hdc ,CONST PIXELFORMATDESCRIPTOR *ppfd ) ;Ãëàâà 11. Èñïîëüçîâàíèå OPENGL â MFC è VCL148Ýòà ôóíêöèÿ ïîçâîëÿåò ïî êîíòåêñòó ãðàôè÷åñêîãî óñòðîéñòâà íàéòè ïèêñåëüíûé ôîðìàò, ìàêñèìàëüíî óäîâëåòâîðÿþùèéíàøèì òðåáîâàíèÿì, è âîçâðàùàåò åãî äåñêðèïòîð. Íàïðèìåð,åñëè çàïðîøåí 24-áèòíûé áóôåð öâåòà, à êîíòåêñò ãðàôè÷åñêîãîóñòðîéñòâà ïðåäîñòàâëÿåò òîëüêî 8-áèòíûé áóôåð, òî ôóíêöèÿâîçâðàòèò ôîðìàò ïèêñåëÿ ñ 8-áèòíûì áóôåðîì.ÔóíêöèÿSetPixelFormat óñòàíàâëèâàåò ôîðìàò ïèêñåëÿ â êîí-òåêñò ãðàôè÷åñêîãî óñòðîéñòâà:BOOL SetPixelFormat (HDC hdc , int iPixelFormat ,CONST PIXELFORMATDESCRIPTOR *ppfd ) ;Ïîñêîëüêó ìû èñïîëüçóåì êîíòåêñò ãðàôè÷åñêîãî óñòðîéñòâàñ äâîéíûì áóôåðîì, OpenGL-ðèñîâàíèå â êîíòåêñò ïðîèñõîäèòâ íåâèäèìîå íà ýêðàíå ìåñòî â ïàìÿòè.
Ýòî íåîáõîäèìî äëÿïðåäîòâðàùåíèÿ ìåðöàíèÿ. Äëÿ òîãî, ÷òîáû èçîáðàæåíèå ïîÿâèëîñü íà ýêðàíå, íóæíî âûçâàòü ñëåäóþùóþ ôóíêöèþ:SwapBuffers ( hDC ) ;11.3. Êîíòåêñò ðèñîâàíèÿ (render context)Êîíòåêñò ðèñîâàíèÿ îïðåäåëÿåò â êàêîé êîíòåêñò óñòðîéñòâàáóäóò íàïðàâëÿòüñÿ êîìàíäû OpenGL. Íàïðèìåð, åñëè â ïðîãðàììå åñòü íåñêîëüêî îêîí OpenGL, òî ïåðåä âûçîâîì êîìàíäOpenGL íåîáõîäèìî óêàçàòü îêíî, â êîòîðîå áóäóò íàïðàâëåíûýòè êîìàíäû. Ñ êîíòåêñòîì ðèñîâàíèÿ àññîöèèðîâàíî òåêóùååñîñòîÿíèå OpenGL, òåêñòóðû, äèñïëåéíûå ñïèñêè è ò.ï.Ñîçäàíèå êîíòåêñòà ðèñîâàíèÿhRC:HGLRC hRC;hRC = wglCreateContext (hDC ) ;Ïåðåä èñïîëüçîâàíèåì êîíòåêñòà íåîáõîäèìî ñäåëàòü åãî òåêóùèì:11.4. Êëàññ GLRC149wglMakeCurrent (hDC, hRC ) ;Äàëåå ìîæíî ñâîáîäíî èñïîëüçîâàòü êîìàíäû OpenGL, íå çàáûâàÿ âûçûâàòüSwapBuersïîñëå îêîí÷àíèÿ ðèñîâàíèÿ êàäðà.Ïîñëå èñïîëüçîâàíèÿ êîíòåêñòà ðèñîâàíèÿ åãî íóæíî îñâîáîäèòü (îáû÷íî ïåðåä îñâîáîæäåíèåì ñîîòâåòñòâóþùåãî êîíòåêñòàóñòðîéñòâà):wglDeleteContext (hRC ) ;11.4.
Êëàññ GLRC ï.Á.5 ïðèâåäåí ïðèìåð êëàññàGLRC,ðåàëèçóþùèé ïåðå-÷èñëåííûå îïåðàöèè. Öèêë èíèöèàëèçàöèè è ðèñîâàíèÿ ñ èñïîëüçîâàíèåì ýòîãî êëàññà âûãëÿäèò ñëåäóþùèì îáðàçîì:GLRC* m_pGLRC;...// 1 . èíèöèàëèçàöèÿ îêíàm_pGLRC = new GLRC(hWnd ) ;bool r e s = m_pGLRC−>Create ( ) ;if (! res )Error ( "Íåâîçìîæíî ñîçäàòü êîíòåêñò OpenGL" ) ;..// 2 .
ðèñîâàíèå// ( îáû÷íî â îáðàáîò÷èêàõ ñîáûòèÿ WM_PAINT)bool r e s = m_pGLRC−>MakeCurrent ( ) ;if (! res )Error ( "Íåâîçìîæíî ñäåëàòü êîíòåêñò òåêóùèì" ) ;// êîìàíäû OpenGLg l C l e a r (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)...// çàâåðøåíèå êàäðàm_pGLRC−>SwapBuffers ( ) ;Ãëàâà 11. Èñïîëüçîâàíèå OPENGL â MFC è VCL150// 3 . óíè÷òîæåíèå îêíà//( îáû÷íî â îáðàáîò÷èêàõ ñîáûòèÿ WM_DESTROY)m_pGLRC−>Destroy ( ) ;delete m_pGLRC;11.5. Èñïîëüçîâàíèå OpenGL c MFCÅñëè ïðè ñîçäàíèè Windows-ïðèëîæåíèÿ èñïîëüçóåòñÿ áèáëèîòåêà MFC, òî íåîáõîäèìî âñòðîèòü èíèöèàëèçàöèþ, îñâîáîæäåíèå êîíòåêñòîâ è ðèñîâàíèå OpenGL â ðàçëè÷íûå îáðàáîò÷èêèóíàñëåäîâàííûõ êëàññîâ MFC. Äàííàÿ êíèãà íå ÿâëÿåòñÿ ðóêîâîäñòâîì ïî ïðîãðàììèðîâàíèþ ñ èñïîëüçîâàíèåì MFC, ïîýòîìóîãðàíè÷èìñÿ ñîâåòàìè ïî èñïîëüçîâàíèþ OpenGL ñ ýòîé áèáëèîòåêîé:Êîä èíèöèàëèçàöèè è ðèñîâàíèÿ òåïåðü äîëæåí íàõîäèòüñÿâ ìåòîäàõ (èëè âûçûâàòüñÿ èç ýòèõ ìåòîäîâ) êëàññà, óíàñëåäîâàííîãî îò êëàññàCWndíàïðÿìóþ èëè êîñâåííî.Äëÿ èíèöèàëèçàöèè OpenGL ëó÷øå âñåãî èñïîëüçîâàòü ìåòîäèëèOnCreate, äëÿ ðèñîâàíèÿ OnPaint, OnUpdate, OnDrawOnTimer (ýòî çàâèñèò îò ðàçíûõ ôàêòîðîâ, íàïðèìåð,îò êàêîãî èìåííî êëàññà óíàñëåäîâàí êëàññ OpenGL-îêíàè ÷òî èìåííî èçîáðàæàåòñÿ).Äëÿ ïðåäîòâðàùåíèÿ ìåðöàíèÿ íåîáõîäèìî ïåðåãðóçèòüWM_ERASEBKGND, èíà÷å Windowsáóäåò çàëèâàòü ôîí îêíà ïåðåä âûçîâîì îáðàáîò÷èêà OnPaint.îáðàáîò÷èê ñîîáùåíèÿOnDestroy,OnSize.Äëÿ îñâîáîæäåíèÿ ïîäîéäåò îáðàáîò÷èêîáðàáîòêè èçìåíåíèé ðàçìåðà îêíà à äëÿÏîëó÷èòü èäåíòèôèêàòîð îêíà ìîæíî ñ ïîìîùüþ ìåòîäàCWnd::GetSafeHwnd.11.5.
Èñïîëüçîâàíèå OPENGL C MFC151Ïðèìåð êëàññà îêíà, ðèñîâàíèå â êîòîðîå îñóùåñòâëÿåòñÿïðè ïîìîùè OpenGL.class OpenGLWindow : public CWnd{public :OpenGLWindow ( ) ;// îòêðûòûå ÷ëåíû êëàññà...private :// çàêðûòûå ÷ëåíû êëàññà...// ñèãíàòóðû ýòèõ ìåòîäîâ îïðåäåëåíû çàðàíåå MFC// è äîëæíû âûãëÿäåòü èìåííî òàêafx_msgafx_msgafx_msgafx_msgint OnCreate (LPCREATESTRUCT l p C r e a t e S t r u c t ) ;BOOL OnEraseBkgnd (CDC* pDC ) ;void OnPaint ( ) ;void OnDestroy ( ) ;// îáúÿâëåíèå êàðòû ñîîáùåíèé WindowsDECLARE_MESSAGE_MAP( )// êëàññ äëÿ õðàíåíèÿ êîíòåêñòîâ OpenGL};GLRC* m_pGLRC;Ðåàëèçàöèÿ ìåòîäîâ:// êîíñòðóêòîðOpenGLWindow : : OpenGLWindow ( ): m_pGLRC(NULL){}// çàïîëíåíèå êàðòû ñîîáùåíèéBEGIN_MESSAGE_MAP(OpenGLWindow , CWnd)// ñòàíäàðòíûå ìàêðîñû MFCON_WM_CREATE( )ON_WM_PAINT( )152Ãëàâà 11.
Èñïîëüçîâàíèå OPENGL â MFC è VCLON_WM_DESTROY( )ON_WM_ERASEBKGND( )END_MESSAGE_MAP( )// â ýòîì ìåòîäå ðåàëèçóåì èíèöèàëèçàöèþafx_msg int OpenGLWindow : : OnCreate (LPCREATESTRUCT l p C r e a t e S t r u c t ){m_pGLRC = new GLRC( GetSafeHwnd ( ) ) ;bool r e s = m_pGLRC−>Create ( ) ;if (! res )return FALSE ;}return CWnd : : OnCreate ( l p C r e a t e S t r u c t ) ;// çàïðåùàåì çàëèâêó ôîíàafx_msg BOOL OpenGLWindow : : OnEraseBkgnd (CDC* pDC){return FALSE ;}// ç ä å ñ ü ðèñóåìafx_msg void OpenGLWindow : : OnPaint ( ){CWnd : : OnPaint ( ) ;// äåëàåì òåêóùèìm_glRC−>MakeCurrent ( ) ;g l C l e a r (GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT) ;// ðèñóåì òî, ÷òî õîòèì íàðèñîâàòü<ìåòîäû ðèñîâàíèÿ OpenGL>11.6.