opengl ट्यूटोरियल
शुरुआत ओपेंग्ल से हुई
खोज…
टिप्पणियों
ओपनजीएल 2 डी और 3 डी ग्राफिक्स ग्राफिक्स ग्राफिक्स का प्रतिपादन करने के लिए एक खुला मानक है। OpenGL को प्लेटफ़ॉर्म के एक शानदार सरणी में लागू किया गया है, जिससे OpenGL को लक्षित करने वाले ऐप्स बेहद लचीले हो जाते हैं।
संस्करण
संस्करण | रिलीज़ की तारीख |
---|---|
1.1 | 1997/03/04 |
1.2 | 1998/03/16 |
1.2.1 | 1998/10/14 |
1.3 | 2001/08/14 |
1.4 | 2002/07/24 |
1.5 | 2003/07/29 |
2.0 | 2004/09/07 |
2.1 | 2006-07-02 |
3.0 | 2008-08-11 |
3.1 | 2009-03-24 |
3.2 | 2009-08-03 |
3.3 | 2010-03-11 |
4.0 | 2010-03-11 |
4.1 | 2010-07-26 |
4.2 | 2011-08-08 |
4.3 | 2012-08-06 |
4.4 | 2013-07-22 |
4.5 | 2014-08-11 |
OpenGL को प्राप्त करना
ओपनजीएल के बारे में सबसे आम गलतफहमियों में से एक यह है कि यह एक पुस्तकालय था जिसे तीसरे पक्ष के स्रोतों से स्थापित किया जा सकता था। इस ग़लतफ़हमी के कारण "OpenGL स्थापित करने का तरीका" या "OpenGL SDK डाउनलोड करने के तरीके" के रूप में कई प्रश्न सामने आते हैं।
यह नहीं है कि OpenGL कंप्यूटर सिस्टम में कैसे रास्ता खोजता है। ओपनजीएल अपने आप में विशिष्टताओं का एक समूह है, जिस पर एक कार्यान्वयन का पालन करना चाहिए। तो यह कार्यान्वयन है जो मायने रखता है। और कुछ समय के लिए, ओपनजीएल कार्यान्वयन जीपीयू ड्राइवरों का हिस्सा हैं। यह भविष्य में बदल सकता है , जब नए GPU प्रोग्रामिंग इंटरफ़ेस OpenGL को लाइब्रेरी के रूप में लागू करने की अनुमति देता है, लेकिन अब यह ग्राफिक्स ड्राइवरों के लिए एक प्रोग्रामिंग एपीआई है।
जब ओपनजीएल को पहली बार एपीआई जारी किया गया, तो उसने किसी तरह से एबीआई (एप्लीकेशन बाइनरी इंटरफेस) अनुबंध में विंडोज, सोलारिस और लिनक्स (एलएसबी -4 डेस्कटॉप) को शामिल किया, इसके अलावा यह मूल सूर्य मैट्रिक्स है। Apple ने वास्तव में MacOS X में OpenGL को इतनी गहराई से एकीकृत किया, कि उपलब्ध OpenGL संस्करण को MacOS X के संस्करण से कसकर जोड़ा गया। इसका उल्लेखनीय प्रभाव है, इन ऑपरेटिंग सिस्टमों के लिए सिस्टम प्रोग्रामिंग वातावरण (यानी कंपाइलर और लिंकर टूलचैन जो मूल रूप से इन सिस्टमों को लक्षित करता है) को भी OpenGL API परिभाषाएँ देनी चाहिए । यह वास्तव में ओपनजीएल के लिए एसडीके स्थापित करने के लिए आवश्यक नहीं है। एक समर्पित एसडीके स्थापित करने की आवश्यकता के बिना इन ऑपरेटिंग सिस्टम पर ओपनजीएल प्रोग्राम करना तकनीकी रूप से संभव है, यह मानते हुए कि लक्षित एबीआई के बाद एक बिल्ड वातावरण स्थापित किया गया है।
इन सख्त ABI नियमों का एक साइड इफेक्ट यह है कि बाइंडिंग इंटरफ़ेस के माध्यम से खुलने वाला OpenGL संस्करण एक सामान्य कॉमन डिनोमिनेटर है जो लक्ष्य प्लेटफ़ॉर्म पर चलने वाले प्रोग्राम उपलब्ध होने की उम्मीद कर सकता है। इसलिए आधुनिक ओपनगेल सुविधाओं को विस्तार तंत्र के माध्यम से एक्सेस किया जाना है, जो अलग से गहराई में वर्णित है।
लिनक्स
लिनक्स में, सिस्टम के विभिन्न पहलुओं के लिए विकास पैकेजों का संकलन करना काफी आम है, ताकि इन्हें व्यक्तिगत रूप से अपडेट किया जा सके। अधिकांश लिनक्स वितरण में ओपनजीएल के लिए विकास फाइलें एक समर्पित पैकेज में निहित होती हैं, जो आमतौर पर डेस्कटॉप एप्लिकेशन डेवलपमेंट मेटा-पैकेज के लिए एक निर्भरता होती है। इसलिए लिनक्स के लिए OpenGL विकास फ़ाइलों को स्थापित करना आमतौर पर डेस्कटॉप विकास मेटा पैकेज / एस * की स्थापना के साथ ध्यान रखा जाता है। *
माइक्रोसॉफ़्ट विंडोज़
एपीआई बाइंडिंग लाइब्रेरी opengl32.dll
( opengl32.dll
के दोनों 32 बिट और 64 बिट संस्करणों के लिए ऐसा नाम) को विंडोज एनटी -4 और विंडोज 95 बी (दोनों सीए 1997) के बाद से हर विंडोज संस्करण के साथ डिफ़ॉल्ट रूप से भेज दिया गया है। हालाँकि यह DLL एक वास्तविक OpenGL कार्यान्वयन प्रदान नहीं करता है (एक सॉफ़्टवेयर फ़ॉलबैक के अलावा जिसका एकमात्र उद्देश्य प्रोग्राम के लिए सुरक्षा नेट के रूप में कार्य करना है यदि कोई अन्य OpenGL कार्यान्वयन स्थापित नहीं है)। यह DLL विंडोज से संबंधित है और इसे परिवर्तित या स्थानांतरित नहीं किया जाना चाहिए ! आधुनिक OpenGL संस्करण तथाकथित opengl32.dll
क्लाइंट ड्राइवर (ICD) के हिस्से के रूप में भेजे जाते हैं और डिफ़ॉल्ट opengl32.dll
माध्यम से एक्सेस किए जाते हैं जो विंडोज के हर संस्करण के साथ पहले से इंस्टॉल आता है। Microsoft द्वारा आंतरिक रूप से यह निर्णय लिया गया था, हालाँकि, Windows अद्यतन के माध्यम से स्थापित ग्राफिक्स ड्राइवर एक OpenGL ICD को स्थापित / अद्यतन नहीं करेगा। जैसा कि स्वचालित रूप से इंस्टॉल किए गए ड्राइवरों के साथ विंडोज के नए इंस्टॉलेशन में आधुनिक ओपनजीएल सुविधाओं के लिए समर्थन की कमी है। आधुनिक सुविधाओं के साथ एक ओएनजीसीएल आईसीडी प्राप्त करने के लिए, ग्राफिक्स ड्राइवरों को जीपीयू विक्रेता की वेबसाइट से सीधे डाउनलोड किया जाना चाहिए और मैन्युअल रूप से स्थापित किया जाना चाहिए।
विकास के संबंध में कोई अतिरिक्त कदम नहीं उठाना चाहिए। सभी सी / सी ++ कंपाइलर हेडर और लिंकर स्टब (opengl32.lib) के साथ विंडोज एबीआई विनिर्देशों जहाज का पालन करते हैं, जो कि ओपनजीएल के उपयोग को बनाने और निष्पादन योग्य बनाने के लिए आवश्यक है।
विंडोज पर मैनुअल ओपनजीएल सेटअप
पूर्ण उदाहरण कोड अंत में शामिल है
OpenGL के लिए विंडोज घटक
WGL
WGL (स्पष्ट लचीलापन देता है हो सकता है), "विंडोज जीएल" के लिए खड़ा है में "विंडोज और ओपन के बीच एक अंतरफलक के रूप में" - ओपन के साथ संवाद करने के लिए Windows एपीआई से कार्यों का एक सेट। WGL फ़ंक्शन में एक wgl उपसर्ग होता है और इसके टोकन में WGL_ उपसर्ग होता है।
Microsoft सिस्टम पर समर्थित डिफ़ॉल्ट OpenGL संस्करण 1.1 है। यह एक बहुत पुराना संस्करण है (हाल ही में एक 4.5 है)। सबसे हाल के संस्करणों को प्राप्त करने का तरीका अपने ग्राफिक्स ड्राइवरों को अपडेट करना है, लेकिन आपके ग्राफिक्स कार्ड को उन नए संस्करणों का समर्थन करना चाहिए।
डब्ल्यूजीएल कार्यों की पूरी सूची यहां पाई जा सकती है ।
ग्राफिक्स डिवाइस इंटरफ़ेस (GDI)
GDI (आज GDI + के लिए अद्यतन किया गया) एक 2D ड्राइंग इंटरफ़ेस है जो आपको विंडोज़ में एक विंडो पर आकर्षित करने की अनुमति देता है। ओपनजीएल को इनिशियलाइज़ करने के लिए आपको GDI की आवश्यकता है और इसके साथ बातचीत करने की अनुमति दें (लेकिन वास्तव में GDI का उपयोग नहीं करेंगे)।
GDI में, प्रत्येक विंडो में एक उपकरण संदर्भ (DC) होता है जिसका उपयोग फ़ंक्शन को कॉल करते समय ड्राइंग लक्ष्य को पहचानने के लिए किया जाता है (आप इसे एक पैरामीटर के रूप में पास करते हैं)। हालाँकि, OpenGL अपने स्वयं के प्रतिपादन संदर्भ (RC) का उपयोग करता है। इसलिए, RC बनाने के लिए DC का उपयोग किया जाएगा।
बुनियादी ढांचा
एक खिड़की का निर्माण
तो ओपनजीएल में चीजें करने के लिए, हमें RC की आवश्यकता है, और RC प्राप्त करने के लिए, हमें DC की आवश्यकता है, और DC प्राप्त करने के लिए हमें एक विंडो की आवश्यकता है। विंडोज एपीआई का उपयोग करके एक विंडो बनाने के लिए कई चरणों की आवश्यकता होती है। यह एक बुनियादी दिनचर्या है, इसलिए अधिक विस्तृत विवरण के लिए, आपको अन्य प्रलेखन से परामर्श करना चाहिए, क्योंकि यह विंडोज एपीआई का उपयोग करने के बारे में नहीं है।
यह एक Windows सेटअप है, इसलिए Windows.h
को शामिल किया जाना चाहिए, और कार्यक्रम का प्रवेश बिंदु अपने मापदंडों के साथ WinMain
प्रक्रिया होना चाहिए। कार्यक्रम को opengl32.dll
और gdi32.dll
(चाहे आप 64 या 32 बिट सिस्टम पर हों) से जुड़ा होना चाहिए।
पहले हमें WNDCLASS
संरचना का उपयोग करके अपनी खिड़की का वर्णन करना होगा। इसमें उस विंडो के बारे में जानकारी है जिसे हम बनाना चाहते हैं:
/* REGISTER WINDOW */
WNDCLASS window_class;
// Clear all structure fields to zero first
ZeroMemory(&window_class, sizeof(window_class));
// Define fields we need (others will be zero)
window_class.style = CS_OWNDC;
window_class.lpfnWndProc = window_procedure; // To be introduced later
window_class.hInstance = instance_handle;
window_class.lpszClassName = TEXT("OPENGL_WINDOW");
// Give our class to Windows
RegisterClass(&window_class);
/* *************** */
प्रत्येक फ़ील्ड के अर्थ की सटीक व्याख्या के लिए (और फ़ील्ड की पूरी सूची के लिए), MSDN डोक्यूमिनेशन से परामर्श करें।
फिर, हम CreateWindowEx
का उपयोग करके एक विंडो बना सकते हैं। विंडो बनने के बाद, हम इसके DC का अधिग्रहण कर सकते हैं:
/* CREATE WINDOW */
HWND window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
TEXT("OPENGL_WINDOW"),
TEXT("OpenGL window"),
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL,
NULL,
instance_handle,
NULL);
HDC dc = GetDC(window_handle);
ShowWindow(window_handle, SW_SHOW);
/* ************* */
अंत में, हमें एक संदेश लूप बनाने की आवश्यकता है जो ओएस से खिड़की की घटनाओं को प्राप्त करता है:
/* EVENT PUMP */
MSG msg;
while (true) {
if (PeekMessage(&msg, window_handle, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// draw(); <- there goes your drawing
SwapBuffers(dc); // To be mentioned later
}
/* ********** */
पिक्सेल प्रारूप
OpenGL को हमारी खिड़की के बारे में कुछ जानकारी जानने की आवश्यकता होती है, जैसे कि रंग बिटनेस, बफरिंग विधि, और इसी तरह। इसके लिए, हम एक पिक्सेल प्रारूप का उपयोग करते हैं। हालाँकि, हम केवल OS को सुझाव दे सकते हैं कि हमें किस तरह के पिक्सेल प्रारूप की आवश्यकता है, और OS सबसे अधिक समान सपोर्ट करेगा, इस पर हमारा सीधा नियंत्रण नहीं है। इसीलिए इसे केवल वर्णनकर्ता कहा जाता है।
/* PIXEL FORMAT */
PIXELFORMATDESCRIPTOR descriptor;
// Clear all structure fields to zero first
ZeroMemory(&descriptor, sizeof(descriptor));
// Describe our pixel format
descriptor.nSize = sizeof(descriptor);
descriptor.nVersion = 1;
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER | PFD_SWAP_LAYER_BUFFERS;
descriptor.iPixelType = PFD_TYPE_RGBA;
descriptor.cColorBits = 32;
descriptor.cRedBits = 8;
descriptor.cGreenBits = 8;
descriptor.cBlueBits = 8;
descriptor.cAlphaBits = 8;
descriptor.cDepthBits = 32;
descriptor.cStencilBits = 8;
// Ask for a similar supported format and set it
int pixel_format = ChoosePixelFormat(dc, &descriptor);
SetPixelFormat(dc, pixel_format, &descriptor);
/* *********************** */
हमने dwFlags
फ़ील्ड में डबल बफरिंग सक्षम की है, इसलिए हमें ड्राइंग के बाद चीजों को देखने के लिए SwapBuffers
को कॉल करना होगा।
प्रसंग का प्रतिपादन
उसके बाद, हम बस अपना प्रतिपादन संदर्भ बना सकते हैं:
/* RENDERING CONTEXT */
HGLRC rc = wglCreateContext(dc);
wglMakeCurrent(dc, rc);
/* ***************** */
ध्यान दें कि एक समय में केवल एक धागा RC का उपयोग कर सकता है। यदि आप इसे बाद में किसी अन्य थ्रेड से उपयोग करना चाहते हैं, तो आपको इसे फिर से सक्रिय करने के लिए wglMakeCurrent
को कॉल करना होगा (यह इसे उस थ्रेड पर निष्क्रिय कर देगा जो वर्तमान में सक्रिय है, और इसी तरह)।
OpenGL फ़ंक्शंस प्राप्त करना
OpenGL फ़ंक्शन फ़ंक्शन पॉइंटर्स का उपयोग करके प्राप्त किए जाते हैं। सामान्य प्रक्रिया है:
- किसी तरह फ़ंक्शन पॉइंटर प्रकार (अनिवार्य रूप से फ़ंक्शन प्रोटोटाइप) प्राप्त करें
- प्रत्येक फ़ंक्शन को घोषित करें जिसका हम उपयोग करना चाहते हैं (इसके फ़ंक्शन पॉइंटर प्रकार के साथ)
- वास्तविक फ़ंक्शन प्राप्त करें
उदाहरण के लिए, ग्लोबिन पर विचार करें:
// We need to somehow find something that contains something like this,
// as we can't know all the OpenGL function prototypes
typedef void (APIENTRY *PFNGLBEGINPROC)(GLenum);
// After that, we need to declare the function in order to use it
PFNGLBEGINPROC glBegin;
// And finally, we need to somehow make it an actual function
("पीएफएन" का अर्थ है "सूचक कार्य करने के लिए", फिर एक ओपनगैल फ़ंक्शन के नाम का अनुसरण करता है, और अंत में "पीआरसी" - जो कि सामान्य ओपनगैल फ़ंक्शन सूचक प्रकार नाम है।)
यहां बताया गया है कि यह विंडोज पर कैसे किया जाता है। जैसा कि पहले बताया गया है, Microsoft केवल OpenGL 1.1 को शिप करता है। सबसे पहले, उस संस्करण के लिए फ़ंक्शन पॉइंटर प्रकार GL/gl.h
को शामिल करके पाया जा सकता है। उसके बाद, हम उन सभी फ़ंक्शंस की घोषणा करते हैं जिन्हें हम ऊपर दिखाए गए अनुसार उपयोग करने का इरादा रखते हैं (हेडर फ़ाइल में ऐसा करने और उन्हें "बाहरी" घोषित करने से हम उन्हें एक बार लोड करने के बाद उन सभी का उपयोग करने की अनुमति देंगे, बस इसे शामिल करके)। अंत में, OpenGL 1.1 कार्यों को लोड करना DLL को खोलकर किया जाता है:
HMODULE gl_module = LoadLibrary(TEXT("opengl32.dll"));
/* Load all the functions here */
glBegin = (PFNGLBEGINPROC)GetProcAddress("glBegin");
// ...
/* *************************** */
FreeLibrary(gl_module);
हालाँकि, हम शायद OpenGL 1.1 से थोड़ा अधिक चाहते हैं। लेकिन विंडोज हमें फ़ंक्शन प्रोटोटाइप या उससे ऊपर की चीज़ों के लिए निर्यात किए गए फ़ंक्शन नहीं देता है। प्रोटोटाइप को ओपन रजिस्ट्री से अधिग्रहित किया जाना चाहिए। हमारे लिए ब्याज की तीन फ़ाइलें हैं: GL/glext.h
, GL/glcorearb.h
, और GL/wglext.h
।
विंडोज द्वारा प्रदान की गई GL/gl.h
को पूरा करने के लिए, हमें GL/glext.h
आवश्यकता है। इसमें शामिल है (जैसा कि रजिस्ट्री द्वारा वर्णित है) "ओपनजीएल 1.2 और ऊपर संगतता प्रोफाइल और एक्सटेंशन इंटरफेस" (प्रोफाइल और एक्सटेंशन के बारे में बाद में, जहां हम देखेंगे कि यह वास्तव में उन दो फ़ाइलों का उपयोग करने के लिए एक अच्छा विचार नहीं है )।
वास्तविक कार्यों को wglGetProcAddress
द्वारा प्राप्त करने की आवश्यकता है (इस आदमी के लिए DLL खोलने की कोई आवश्यकता नहीं है, वे वहां नहीं हैं, बस फ़ंक्शन का उपयोग करें)। इसके साथ, हम OpenGL 1.2 और इसके बाद के संस्करण (लेकिन नहीं) से सभी कार्यों को प्राप्त कर सकते हैं। ध्यान दें कि, इसे ठीक से काम करने के लिए, OpenGL रेंडरिंग संदर्भ को चालू और बनाया जाना चाहिए । तो, उदाहरण के लिए, glClear
:
// Include the header from the OpenGL registry for function pointer types
// Declare the functions, just like before
PFNGLCLEARPROC glClear;
// ...
// Get the function
glClear = (PFNGLCLEARPROC)wglGetProcAddress("glClear");
हम वास्तव में एक रैपर get_proc
प्रक्रिया का निर्माण कर सकते हैं जो wglGetProcAddress
और GetProcAddress
दोनों का उपयोग करती है:
// Get function pointer
void* get_proc(const char *proc_name)
{
void *proc = (void*)wglGetProcAddress(proc_name);
if (!proc) proc = (void*)GetProcAddress(gl_module, proc_name); // gl_module must be somewhere in reach
return proc;
}
तो लपेटने के लिए, हम इस तरह से फ़ंक्शन पॉइंटर घोषणाओं से भरा एक हेडर फाइल बनाएंगे:
extern PFNGLCLEARCOLORPROC glClearColor;
extern PFNGLCLEARDEPTHPROC glClearDepth;
extern PFNGLCLEARPROC glClear;
extern PFNGLCLEARBUFFERIVPROC glClearBufferiv;
extern PFNGLCLEARBUFFERFVPROC glClearBufferfv;
// And so on...
फिर हम load_gl_functions
जैसी प्रक्रिया बना सकते हैं, जिसे हम केवल एक बार कॉल करते हैं, और इस तरह काम करते हैं:
glClearColor = (PFNGLCLEARCOLORPROC)get_proc("glClearColor");
glClearDepth = (PFNGLCLEARDEPTHPROC)get_proc("glClearDepth");
glClear = (PFNGLCLEARPROC)get_proc("glClear");
glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)get_proc("glClearBufferiv");
glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)get_proc("glClearBufferfv");
और तुम सब सेट हो! बस फ़ंक्शन पॉइंटर्स और जीएल दूर हेडर शामिल करें।
बेहतर सेटअप
ओपनजीएल प्रोफाइल
OpenGL 20 से अधिक वर्षों के लिए विकास में रहा है, और डेवलपर्स हमेशा पीछे की संगतता (बीसी) के बारे में सख्त थे। इसकी वजह से एक नया फीचर जोड़ना बहुत कठिन है। इस प्रकार, 2008 में, इसे दो "प्रोफाइल" में अलग कर दिया गया। कोर और संगतता । कोर प्रोफाइल प्रदर्शन सुधार और कुछ नई सुविधाओं के पक्ष में ई.पू. को तोड़ता है। यह पूरी तरह से कुछ विरासत सुविधाओं को भी हटा देता है। संगतता प्रोफ़ाइल 1.0 से नीचे सभी संस्करणों के साथ बीसी को बनाए रखती है, और इस पर कुछ नई सुविधाएँ उपलब्ध नहीं हैं। यह केवल पुराने, विरासत प्रणालियों के लिए उपयोग किया जाना है, सभी नए अनुप्रयोगों को मूल प्रोफ़ाइल का उपयोग करना चाहिए।
उस वजह से, हमारे मूल सेटअप के साथ एक समस्या है - यह केवल उस संदर्भ को प्रदान करता है जो ओपनगैल 1.0 के साथ संगत है। पिक्सेल प्रारूप भी सीमित है। एक्सटेंशन का उपयोग करके एक बेहतर दृष्टिकोण है।
OpenGL एक्सटेंशन
ओपनजीएल की मूल कार्यक्षमता के अतिरिक्त किसी भी विस्तार को कहा जाता है। आम तौर पर, वे या तो कुछ चीजों को कानूनी बना सकते हैं जो पहले नहीं थे, पैरामीटर मान सीमा बढ़ाएँ, GLSL का विस्तार करें, और यहां तक कि पूरी तरह से नई कार्यक्षमता जोड़ें।
एक्सटेंशन के तीन प्रमुख समूह हैं: विक्रेता, EXT और ARB। विक्रेता एक्सटेंशन विशिष्ट विक्रेता से आते हैं, और उनके पास विक्रेता विशिष्ट चिह्न होते हैं, जैसे AMD या NV। EXT एक्सटेंशन एक साथ काम करने वाले कई विक्रेताओं द्वारा बनाए जाते हैं। कुछ समय बाद, वे एआरबी एक्सटेंशन बन सकते हैं, जो सभी आधिकारिक तौर पर समर्थित हैं और एआरबी द्वारा अनुमोदित हैं।
फ़ंक्शन पॉइंटर प्रकार और सभी एक्सटेंशन के फ़ंक्शन प्रोटोटाइप को प्राप्त करने के लिए और जैसा कि पहले उल्लेख किया गया है, सभी फ़ंक्शन पॉइंटर OpenGL 1.2 और उससे अधिक से टाइप करते हैं , एक को OpenGL रजिस्ट्री से हेडर फ़ाइलों को डाउनलोड करना होगा। जैसा कि चर्चा है, नए अनुप्रयोगों के लिए कोर प्रोफाइल का उपयोग करना बेहतर है, इसलिए GL/gl.h
और GL/glext.h
GL/glcorearb.h
बजाय GL/glcorearb.h
को शामिल करना बेहतर होगा (यदि आप GL/glcorearb.h
का उपयोग कर रहे हैं तो डॉन 't में GL/gl.h
शामिल GL/gl.h
)।
WGL के लिए GL/wglext.h
में एक्सटेंशन भी हैं। उदाहरण के लिए, सभी समर्थित एक्सटेंशनों की सूची प्राप्त करने का कार्य वास्तव में एक एक्सटेंशन है, wglGetExtensionsStringARB
(यह सभी समर्थित एक्सटेंशनों की अंतरिक्ष से अलग सूची के साथ एक बड़ा स्ट्रिंग देता है)।
एक्सटेंशन प्राप्त करना wglGetProcAddress
माध्यम से भी नियंत्रित किया जाता है, इसलिए हम पहले की तरह अपने रैपर का उपयोग कर सकते हैं।
उन्नत पिक्सेल प्रारूप और संदर्भ निर्माण
WGL_ARB_pixel_format
एक्सटेंशन हमें उन्नत पिक्सेल प्रारूप निर्माण की अनुमति देता है। पहले के विपरीत, हम एक संरचना का उपयोग नहीं करते हैं। इसके बजाय, हम वांछित विशेषताओं की सूची पास करते हैं।
int pixel_format_arb;
UINT pixel_formats_found;
int pixel_attributes[] = {
WGL_SUPPORT_OPENGL_ARB, 1,
WGL_DRAW_TO_WINDOW_ARB, 1,
WGL_DRAW_TO_BITMAP_ARB, 1,
WGL_DOUBLE_BUFFER_ARB, 1,
WGL_SWAP_LAYER_BUFFERS_ARB, 1,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 32,
WGL_STENCIL_BITS_ARB, 8,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
0
};
BOOL result = wglChoosePixelFormatARB(dc, pixel_attributes, NULL, 1, &pixel_format_arb, &pixel_formats_found);
इसी तरह, WGL_ARB_create_context
एक्सटेंशन हमें उन्नत संदर्भ निर्माण की अनुमति देता है:
GLint context_attributes[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
HGLRC new_rc = wglCreateContextAttribsARB(dc, 0, context_attributes);
मापदंडों और कार्यों की एक सटीक व्याख्या के लिए, OpenGL विनिर्देश से परामर्श करें।
हमने उनके साथ शुरुआत क्यों नहीं की? खैर, ऐसा इसलिए है क्योंकि एक्सटेंशन हमें ऐसा करने की अनुमति देते हैं, और एक्सटेंशन प्राप्त करने के लिए हमें wglGetProcAddress
आवश्यकता wglGetProcAddress
, लेकिन यह केवल एक सक्रिय वैध संदर्भ के साथ काम करता है। इसलिए संक्षेप में, इससे पहले कि हम जो संदर्भ बनाना चाहते हैं, हमें पहले से ही कुछ संदर्भ सक्रिय करने की आवश्यकता है, और इसे आमतौर पर एक डमी संदर्भ के रूप में संदर्भित किया जाता है।
हालाँकि, Windows एक से अधिक बार विंडो के पिक्सेल प्रारूप को सेट करने की अनुमति नहीं देता है। इस वजह से, नई चीजों को लागू करने के लिए खिड़की को नष्ट करने और फिर से बनाने की आवश्यकता है:
wglMakeCurrent(dc, NULL);
wglDeleteContext(rc);
ReleaseDC(window_handle, dc);
DestroyWindow(window_handle);
// Recreate the window...
पूर्ण उदाहरण कोड:
/* We want the core profile, so we include GL/glcorearb.h. When including that, then
GL/gl.h should not be included.
If using compatibility profile, the GL/gl.h and GL/glext.h need to be included.
GL/wglext.h gives WGL extensions.
Note that Windows.h needs to be included before them. */
#include <cstdio>
#include <Windows.h>
#include <GL/glcorearb.h>
#include <GL/wglext.h>
LRESULT CALLBACK window_procedure(HWND, UINT, WPARAM, LPARAM);
void* get_proc(const char*);
/* gl_module is for opening the DLL, and the quit flag is here to prevent
quitting when recreating the window (see the window_procedure function) */
HMODULE gl_module;
bool quit = false;
/* OpenGL function declarations. In practice, we would put these in a
separate header file and add "extern" in front, so that we can use them
anywhere after loading them only once. */
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
PFNGLGETSTRINGPROC glGetString;
int WINAPI WinMain(HINSTANCE instance_handle, HINSTANCE prev_instance_handle, PSTR cmd_line, int cmd_show) {
/* REGISTER WINDOW */
WNDCLASS window_class;
// Clear all structure fields to zero first
ZeroMemory(&window_class, sizeof(window_class));
// Define fields we need (others will be zero)
window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
window_class.lpfnWndProc = window_procedure;
window_class.hInstance = instance_handle;
window_class.lpszClassName = TEXT("OPENGL_WINDOW");
// Give our class to Windows
RegisterClass(&window_class);
/* *************** */
/* CREATE WINDOW */
HWND window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
TEXT("OPENGL_WINDOW"),
TEXT("OpenGL window"),
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL,
NULL,
instance_handle,
NULL);
HDC dc = GetDC(window_handle);
ShowWindow(window_handle, SW_SHOW);
/* ************* */
/* PIXEL FORMAT */
PIXELFORMATDESCRIPTOR descriptor;
// Clear all structure fields to zero first
ZeroMemory(&descriptor, sizeof(descriptor));
// Describe our pixel format
descriptor.nSize = sizeof(descriptor);
descriptor.nVersion = 1;
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER | PFD_SWAP_LAYER_BUFFERS;
descriptor.iPixelType = PFD_TYPE_RGBA;
descriptor.cColorBits = 32;
descriptor.cRedBits = 8;
descriptor.cGreenBits = 8;
descriptor.cBlueBits = 8;
descriptor.cAlphaBits = 8;
descriptor.cDepthBits = 32;
descriptor.cStencilBits = 8;
// Ask for a similar supported format and set it
int pixel_format = ChoosePixelFormat(dc, &descriptor);
SetPixelFormat(dc, pixel_format, &descriptor);
/* *********************** */
/* RENDERING CONTEXT */
HGLRC rc = wglCreateContext(dc);
wglMakeCurrent(dc, rc);
/* ***************** */
/* LOAD FUNCTIONS (should probably be put in a separate procedure) */
gl_module = LoadLibrary(TEXT("opengl32.dll"));
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)get_proc("wglGetExtensionsStringARB");
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)get_proc("wglChoosePixelFormatARB");
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)get_proc("wglCreateContextAttribsARB");
glGetString = (PFNGLGETSTRINGPROC)get_proc("glGetString");
FreeLibrary(gl_module);
/* ************** */
/* PRINT VERSION */
const GLubyte *version = glGetString(GL_VERSION);
printf("%s\n", version);
fflush(stdout);
/* ******* */
/* NEW PIXEL FORMAT*/
int pixel_format_arb;
UINT pixel_formats_found;
int pixel_attributes[] = {
WGL_SUPPORT_OPENGL_ARB, 1,
WGL_DRAW_TO_WINDOW_ARB, 1,
WGL_DRAW_TO_BITMAP_ARB, 1,
WGL_DOUBLE_BUFFER_ARB, 1,
WGL_SWAP_LAYER_BUFFERS_ARB, 1,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 32,
WGL_STENCIL_BITS_ARB, 8,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
0
};
BOOL result = wglChoosePixelFormatARB(dc, pixel_attributes, NULL, 1, &pixel_format_arb, &pixel_formats_found);
if (!result) {
printf("Could not find pixel format\n");
fflush(stdout);
return 0;
}
/* **************** */
/* RECREATE WINDOW */
wglMakeCurrent(dc, NULL);
wglDeleteContext(rc);
ReleaseDC(window_handle, dc);
DestroyWindow(window_handle);
window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
TEXT("OPENGL_WINDOW"),
TEXT("OpenGL window"),
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL,
NULL,
instance_handle,
NULL);
dc = GetDC(window_handle);
ShowWindow(window_handle, SW_SHOW);
/* *************** */
/* NEW CONTEXT */
GLint context_attributes[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
rc = wglCreateContextAttribsARB(dc, 0, context_attributes);
wglMakeCurrent(dc, rc);
/* *********** */
/* EVENT PUMP */
MSG msg;
while (true) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// draw(); <- there goes your drawing
SwapBuffers(dc);
}
/* ********** */
return 0;
}
// Procedure that processes window events
LRESULT CALLBACK window_procedure(HWND window_handle, UINT message, WPARAM param_w, LPARAM param_l)
{
/* When destroying the dummy window, WM_DESTROY message is going to be sent,
but we don't want to quit the application then, and that is controlled by
the quit flag. */
switch(message) {
case WM_DESTROY:
if (!quit) quit = true;
else PostQuitMessage(0);
return 0;
}
return DefWindowProc(window_handle, message, param_w, param_l);
}
/* A procedure for getting OpenGL functions and OpenGL or WGL extensions.
When looking for OpenGL 1.2 and above, or extensions, it uses wglGetProcAddress,
otherwise it falls back to GetProcAddress. */
void* get_proc(const char *proc_name)
{
void *proc = (void*)wglGetProcAddress(proc_name);
if (!proc) proc = (void*)GetProcAddress(gl_module, proc_name);
return proc;
}
g++ GLExample.cpp -lopengl32 -lgdi32
साथ संकलित किया गया, जिसमें MinGW / Cygwin या cl GLExample.cpp opengl32.lib gdi32.lib user32.lib
संकलक के लिए cl GLExample.cpp opengl32.lib gdi32.lib user32.lib
। हालाँकि, सुनिश्चित करें कि OpenGL रजिस्ट्री से हेडर शामिल पथ में हैं। यदि नहीं, तो का उपयोग -I
के लिए झंडा g++
या /I
के लिए cl
आदेश संकलक कि वे कहाँ हैं बताने के लिए।
C ++ और कोको के साथ OpenGL 4.1 बनाना
नोट: इस उदाहरण में कुछ ऑब्जेक्टिव-सी होंगे .. हम इस उदाहरण में C ++ के लिए एक आवरण बनाएंगे, इसलिए इसके बारे में ज्यादा चिंता न करें।
सबसे पहले Xcode शुरू करें और एक प्रोजेक्ट बनाएं।
Info.plist फ़ाइल को छोड़कर सभी स्रोतों को हटा दें। (आपका ऐप इसके बिना काम नहीं करेगा)
4 नए सोर्स-फाइल्स बनाएँ: एक ऑब्जेक्टिव-सी ++ फाइल और हैडर (मैंने अपना MacApp कहा है) A C ++ क्लास (मैंने मेरा (एप्लीकेशन कहा है))
शीर्ष बाईं ओर (प्रोजेक्ट नाम के साथ) इस पर क्लिक करें और लिंक किए गए ढांचे और पुस्तकालयों को जोड़ें। जोड़ें: OpenGL.Framework AppKit.Framework GLKit.Framework
आपकी परियोजना शायद इस तरह दिखाई देगी:
NSApplication एक मुख्य वर्ग है जिसका आप MacOS ऐप बनाते समय उपयोग करते हैं। यह आपको खिड़कियों को पंजीकृत करने और घटनाओं को पकड़ने की अनुमति देता है।
हम NSApplication में अपनी (अपनी) विंडो रजिस्टर करना चाहते हैं। पहला यह है कि से विरासत में मिली एक उद्देश्य-सी वर्ग अपने उद्देश्य-c ++ शीर्ष लेख में बनाने NSWindow और औजार NSApplicationDelegate NSWindow सी ++ आवेदन, एक ओपन देखें और ड्रा पाश के लिए एक टाइमर के लिए सूचक की जरूरत है
//Mac_App_H
#import <Cocoa/Cocoa.h>
#import "Application.hpp"
#import <memory>
NSApplication* application;
@interface MacApp : NSWindow <NSApplicationDelegate>{
std::shared_ptr<Application> appInstance;
}
@property (nonatomic, retain) NSOpenGLView* glView;
-(void) drawLoop:(NSTimer*) timer;
@end
हम इसे मुख्य से बुलाते हैं
int main(int argc, const char * argv[]) {
MacApp* app;
application = [NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
//create a window with the size of 600 by 600
app = [[MacApp alloc] initWithContentRect:NSMakeRect(0, 0, 600, 600) styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:YES];
[application setDelegate:app];
[application run];
}
हमारी खिड़की का कार्यान्वयन वास्तव में काफी आसान है सबसे पहले हम अपने चमक को संश्लेषित करने की घोषणा करते हैं और एक वैश्विक उद्देश्य-सी बूलियन जोड़ते हैं जब खिड़की बंद होनी चाहिए।
#import "MacApp.h"
@implementation MacApp
@synthesize glView;
BOOL shouldStop = NO;
अब निर्माणकर्ता के लिए। मेरी प्राथमिकता initWithContentRect का उपयोग करना है।
-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag{
if(self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag]){
//sets the title of the window (Declared in Plist)
[self setTitle:[[NSProcessInfo processInfo] processName]];
//This is pretty important.. OS X starts always with a context that only supports openGL 2.1
//This will ditch the classic OpenGL and initialises openGL 4.1
NSOpenGLPixelFormatAttribute pixelFormatAttributes[] ={
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize , 24 ,
NSOpenGLPFAAlphaSize , 8 ,
NSOpenGLPFADoubleBuffer ,
NSOpenGLPFAAccelerated ,
NSOpenGLPFANoRecovery ,
0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]initWithAttributes:pixelFormatAttributes];
//Initialize the view
glView = [[NSOpenGLView alloc]initWithFrame:contentRect pixelFormat:format];
//Set context and attach it to the window
[[glView openGLContext]makeCurrentContext];
//finishing off
[self setContentView:glView];
[glView prepareOpenGL];
[self makeKeyAndOrderFront:self];
[self setAcceptsMouseMovedEvents:YES];
[self makeKeyWindow];
[self setOpaque:YES];
//Start the c++ code
appInstance = std::shared_ptr<Application>(new Application());
}
return self;
}
ठीक है ... अब हमारे पास वास्तव में एक रन करने योग्य ऐप है .. आप एक काली स्क्रीन या झिलमिलाहट देख सकते हैं।
आइए एक भयानक त्रिकोण बनाना शुरू करें। (c ++ में)
मेरा आवेदन हैडर
#ifndef Application_hpp
#define Application_hpp
#include <iostream>
#include <OpenGL/gl3.h>
class Application{
private:
GLuint program;
GLuint vao;
public:
Application();
void update();
~Application();
};
#endif /* Application_hpp */
कार्यान्वयन:
Application::Application(){
static const char * vs_source[] =
{
"#version 410 core \n"
" \n"
"void main(void) \n"
"{ \n"
" const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0), \n"
" vec4(-0.25, -0.25, 0.5, 1.0), \n"
" vec4( 0.25, 0.25, 0.5, 1.0)); \n"
" \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
};
static const char * fs_source[] =
{
"#version 410 core \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = vec4(0.0, 0.8, 1.0, 1.0); \n"
"} \n"
};
program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
void Application::update(){
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);
glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
Application::~Application(){
glDeleteVertexArrays(1, &vao);
glDeleteProgram(program);
}
अब हमें केवल बार-बार अपडेट कॉल करने की आवश्यकता है (यदि आप कुछ स्थानांतरित करना चाहते हैं) अपने उद्देश्य-सी वर्ग में लागू करें
-(void) drawLoop:(NSTimer*) timer{
if(shouldStop){
[self close];
return;
}
if([self isVisible]){
appInstance->update();
[glView update];
[[glView openGLContext] flushBuffer];
}
}
और इस विधि को अपने उद्देश्य-ग वर्ग के कार्यान्वयन में जोड़ें:
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
[NSTimer scheduledTimerWithTimeInterval:0.000001 target:self selector:@selector(drawLoop:) userInfo:nil repeats:YES];
}
यह आपके सी ++ वर्ग के अपडेट फ़ंक्शन को बार-बार कॉल करेगा (प्रत्येक 0.000001 सेकंड सटीक होने के लिए)
समाप्त करने के लिए हम विंडो को बंद करते हैं जब क्लोज बटन दबाया जाता है:
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication{
return YES;
}
- (void)applicationWillTerminate:(NSNotification *)aNotification{
shouldStop = YES;
}
बधाई हो, अब आपके पास किसी भी तीसरे पक्ष के ढांचे के बिना ओपनजीएल त्रिकोण के साथ एक भयानक खिड़की है।
प्लेटफ़ॉर्म OpenGL संदर्भ निर्माण (SDL2 का उपयोग करके)
OpenGL संदर्भ वाली विंडो बनाना ( GLEW के माध्यम से एक्सटेंशन लोड करना ):
#define GLEW_STATIC #include <GL/glew.h> #include <SDL2/SDL.h> int main(int argc, char* argv[]) { SDL_Init(SDL_INIT_VIDEO); /* Initialises Video Subsystem in SDL */ /* Setting up OpenGL version and profile details for context creation */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); /* A 800x600 window. Pretty! */ SDL_Window* window = SDL_CreateWindow ( "SDL Context", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_OPENGL ); /* Creating OpenGL Context */ SDL_GLContext gl_context = SDL_GL_CreateContext(window); /* Loading Extensions */ glewExperimental = GL_TRUE; glewInit(); /* The following code is for error checking. * If OpenGL has initialised properly, this should print 1. * Remove it in production code. */ GLuint vertex_buffer; glGenBuffers(1, &vertex_buffer); printf("%u\n", vertex_buffer); /* Error checking ends here */ /* Main Loop */ SDL_Event window_event; while(1) { if (SDL_PollEvent(&window_event)) { if (window_event.type == SDL_QUIT) { /* If user is exiting the application */ break; } } /* Swap the front and back buffer for flicker-free rendering */ SDL_GL_SwapWindow(window); } /* Freeing Memory */ glDeleteBuffers(1, &vertex_buffer); SDL_GL_DeleteContext(gl_context); SDL_Quit(); return 0; }
MacOS (Xcode, GLFW और GLEW) पर आधुनिक OpenGL 4.1 सेटअप करें
1. GLFW स्थापित करें
पहला कदम एक OpenGL विंडो बनाना है। GLFW एक ओपन सोर्स, बहु मंच ओपन के साथ खिड़कियां बनाने के लिए पुस्तकालय है, GLFW पहले से फ़ाइलों को डाउनलोड स्थापित करने के लिए www.glfw.org
GLFW फ़ोल्डर निकालें और इसकी सामग्री इस तरह दिखाई देगी
GLFW बनाने के लिए CMake को डाउनलोड और इंस्टॉल करें। गोटो www.cmake.org/download/ , CMake डाउनलोड करें और मैक ओएस एक्स के लिए इंस्टॉल करें
यदि Xcode इंस्टॉल नहीं है। Mac App Store से Xcode डाउनलोड और इंस्टॉल करें।
एक नया फ़ोल्डर बनाएँ GLFW फ़ोल्डर के अंदर बनाएँ
सीएमके खोलें, GLFW फ़ोल्डर का चयन करने के लिए ब्राउज़ स्रोत बटन पर क्लिक करें (सुनिश्चित करें कि CMakeLists.txt) उस फ़ोल्डर के अंदर स्थित है। उसके बाद, ब्राउज़ बिल्ड बटन पर क्लिक करें और पिछले चरण में नव निर्मित बिल्ड फ़ोल्डर का चयन करें।
अब कॉन्फ़िगर बटन पर क्लिक करें और डिफ़ॉल्ट डिफ़ॉल्ट कंपाइलर विकल्प के साथ जनरेटर के रूप में Xcode का चयन करें , और संपन्न पर क्लिक करें।
BUILD_SHARED_LIBS विकल्प पर टिक करें और फिर फिर से कॉन्फ़िगर बटन पर क्लिक करें और अंत में जनरेट बटन पर क्लिक करें।
पीढ़ी के बाद सीएमके को इस तरह दिखना चाहिए
अब फाइंडर और गोटो / यूएसआर खोलें, यदि पहले से ही नहीं है तो एक फ़ोल्डर नाम स्थानीय बनाएं। स्थानीय फ़ोल्डर खोलें और बनाने के दो फ़ोल्डर्स शामिल हैं और lib अगर पहले से ही वहाँ नहीं।
अब GLFW फ़ोल्डर खोलें और गोटो बिल्ड (जहां सीएमके ने फाइलें बनाई थीं)। Xcode में GLFW.xcodeproj फ़ाइल खोलें।
इंस्टॉल का चयन करें > मेरा मैक और फिर रन (प्ले आकार का बटन) पर क्लिक करें।
अब इसे सफलतापूर्वक स्थापित किया गया है (चेतावनियों को अनदेखा करें)।
यह सुनिश्चित करने के लिए कि ओपन फाइंडर और गोटो / यूएसआर / लोकल / लेबर फोल्डर और तीन GLFW लाइब्रेरी फाइल्स पहले से ही वहां मौजूद होंगी (यदि नहीं तो GLFW फोल्डर के अंदर बिल्ड फोल्डर खोलें और src / Debug पर जाकर सभी फाइलों को / usr / लोकल / लीब पर कॉपी करें )
ओपन फाइंडर और गोटो / यूएसआर / लोकल / शामिल हैं और एक GLFW फोल्डर वहां पहले से मौजूद होगा जिसमें glfw3.h और glfw3native.h के नाम से इसके अंदर दो हेडर फाइलें होंगी।
2. GLEW स्थापित करें
GLEW एक क्रॉस-प्लेटफ़ॉर्म लाइब्रेरी है जो OpenGL एक्सटेंशन को क्वेरी और लोड करने में मदद करता है। यह निर्धारित करने के लिए रन-टाइम मैकेनिज्म प्रदान करता है कि टारगेट प्लेटफ़ॉर्म पर OpenGL एक्सटेंशन का समर्थन किया जाता है। यह केवल आधुनिक ओपनजीएल (ओपनजीएल संस्करण 3.2 और अधिक से अधिक जो रनटाइम पर निर्धारित किए जाने वाले कार्यों की आवश्यकता है) के लिए है। सबसे पहले इसकी फाइल्स को glew.sourceforge.net से डाउनलोड करें
GLFW फ़ोल्डर निकालें और इसकी सामग्री इस तरह दिखाई देगी।
अब टर्मिनल खोलें, GLEW फ़ोल्डर में नेविगेट करें और निम्न कमांड टाइप करें
make
sudo make install
make clean
अब GLEW सफलतापूर्वक स्थापित हो गया है। यह सुनिश्चित करने के लिए कि इसकी स्थापना, ओपन फाइंडर, / usr / लोकल / शामिल पर जाएं और एक GL फ़ोल्डर पहले से ही मौजूद होगा जिसमें glew.h , glxew.h और wglew.h नाम से इसके अंदर तीन हेडर फाइलें होंगी।
खोजक खोलें और / usr / स्थानीय / lib और GLEW लाइब्रेरी फ़ाइलों पर जाएं पहले से ही वहां मौजूद होंगे
3. टेस्ट और रन
अब हमने GLFW और GLEW को सफलतापूर्वक स्थापित कर दिया है। इसका समय कोड है। Xcode खोलें और एक नया Xcode प्रोजेक्ट बनाएं। कमांड लाइन टूल चुनें और फिर आगे बढ़ें और भाषा के रूप में C ++ चुनें।
Xcode एक नया कमांड लाइन प्रोजेक्ट बनाएगा।
प्रोजेक्ट नाम पर क्लिक करें, और निर्माण पथ टैब के तहत मूलभूत से सभी में , खोज पथ अनुभाग के तहत, / usr / स्थानीय जोड़ें / हैडर खोज पथ में शामिल करें और लाइब्रेरी खोज पथ में / usr / स्थानीय / देय जोड़ें
प्रोजेक्ट के नाम पर क्लिक करें, और बिल्ड चरणों के तहत और बाइनरी लाइब्रेरी के साथ लिंक के तहत OpenGL.framework जोड़ें और / usr / स्थानीय / lib से हाल ही में बनाए गए GLFW और GLEW पुस्तकालयों को भी जोड़ें
अब हम C ++ और Xcode का उपयोग करके macOS पर मॉडर्न ओपन GL 4.1 में कोड करने के लिए तैयार हैं। निम्न कोड ब्लैंक स्क्रीन आउटपुट के साथ GLFW का उपयोग करके एक OpenGL विंडो बनाएगा।
#include <GL/glew.h>
#include <GLFW/glfw3.h>
// Define main function
int main()
{
// Initialize GLFW
glfwInit();
// Define version and compatibility settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create OpenGL window and context
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
// Check for window creation failure
if (!window)
{
// Terminate GLFW
glfwTerminate();
return 0;
}
// Initialize GLEW
glewExperimental = GL_TRUE; glewInit();
// Event loop
while(!glfwWindowShouldClose(window))
{
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
// Terminate GLFW
glfwTerminate(); return 0;
}
जावा और LWJGL 3.0 के साथ Opengl प्रसंग बनाएँ
इस उदाहरण कोड में हम LWJGL 3.0+ का उपयोग करके एक रिक्त Opengl विंडो बनाएंगे, इसमें आपके IDE में प्रोजेक्ट बनाने के चरण शामिल नहीं हैं
- एक विंडो नाम बनाएँ WindowManager जिसमें स्क्रीन पर एक opengl संदर्भ विंडो बनाने के लिए सभी बॉयलर प्लेट कोड होंगे
WindowManager.java
import org.lwjgl.glfw.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
/**
* Class Containing code related to inflating Opengl Window
*/
public class Displaymanager {
private static long window;
public static void createDisplay(){
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");
// Configure our window
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
int WIDTH = 300;
int HEIGHT = 300;
// Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in our rendering loop
});
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
window,
(vidmode.width() - WIDTH) / 2,
(vidmode.height() - HEIGHT) / 2
);
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
// Make the window visible
glfwShowWindow(window);
}
public static boolean isCloseRequested(){
return glfwWindowShouldClose(window);
}
public static void updateDisplay(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
public static void destroyDisplay(){
// Terminate GLFW and free the error callback
cleanUp();
glfwTerminate();
glfwSetErrorCallback(null).free();
}
private static void cleanUp() {
// Free the window callbacks and destroy the window
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
}
}
- अगला एक वर्ग बनाएं जिसमें मुख्य रेंडरिंग लूप शामिल हो, जो बनाए गए सभी उपरोक्त फ़ंक्शन को कॉल करेगा
OpenGlMain.java
import org.lwjgl.opengl.GL;
import renderEngine.Displaymanager;
import static org.lwjgl.opengl.GL11.glClearColor;
/**
* Class to test the opengl Window
*/
public class OpenGlMain {
public static void main(String[] args) {
Displaymanager.createDisplay();
// This line is critical for LWJGL's interoperation with GLFW's
// OpenGL context, or any context that is managed externally.
// LWJGL detects the context that is current in the current thread,
// creates the GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();
while (!Displaymanager.isCloseRequested()){
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Displaymanager.updateDisplay();
}
Displaymanager.destroyDisplay();
}
}
आगे विस्तार के लिए चेकआउट आधिकारिक LWJGL गाइड