GLUT

2009-05-18 6 views
37

के बिना ओपनजीएल शुरू करना प्रत्येक परिचय और नमूना जो मुझे मिल सकता है, वह ओएलजीएल "प्रारंभ करने" के लिए जीएलयूटी या कुछ अन्य ढांचे का उपयोग करता है। क्या जीएल और जीएलयू में उपलब्ध है के साथ ओपनजीएल शुरू करने का कोई तरीका है? यदि नहीं, तो जीएलयूटी क्या कर रहा है जो इसके बिना संभव नहीं है?GLUT

+1

कोई भी उल्लेख किया [EGL] (http://www.khronos.org/egl)? ओपनजीएल जैसे ऑपरेटिंग सिस्टम और एपीआई के बीच इंटरऑप के लिए यह ख्रोनोस मानक है, जिसका उद्देश्य ऐसी चीजों को एकजुट करना है। आईडीके, हालांकि आज इसका समर्थन कितना व्यापक है। – Kos

+0

जो केवल विंडोज़ है। – rotoglup

+0

यूप, लेकिन यह अभी भी निर्देशक है। :-) धन्यवाद! –

उत्तर

33

जैसा कि ल्यूक ने नोट किया था, संदर्भ बनाने और बांधने के लिए कोड प्रत्येक विंडोिंग प्लेटफ़ॉर्म के लिए विशिष्ट है।

यहाँ कुछ कार्यों आप विशिष्ट प्लेटफार्मों पर ओपन आरंभ करने के मामले में आरंभ करने के लिए कर रहे हैं:

विंडोज (एक ट्यूटोरियल here है)

  • wglCreateContext (HDC)

मैक ओएस एक्स - ओएस एक्स अनिवार्य रूप से तीन विकल्प हैं: कार्बन, कोको, और अंतर्निहित कोर ग्राफिक्स परत

  • The entire guide for Mac OS X OpenGL development
  • Carbon: aglCreateContext
  • Cocoa: बनाएँ (या उपवर्ग) एक NSOpenGLView। वे अपना स्वयं का संदर्भ बनाते हैं, और आप इसे वर्तमान बनाने के तरीके को खोजने के लिए अपने विधि प्रलेखन को पढ़ सकते हैं।
  • CoreGraphicsLayer: CGLCreateContext

लिनक्स

  • glx: glXCreateContext
+0

धन्यवाद, ये सहायक हैं। अब मुझे एहसास है कि मेरी समस्या विंडोज के लिए विशिष्ट है ओपनजीएल की बजाय कोड के पक्ष (यानी ओपनजीएल को शीर्ष पर काम करने की कोशिश कर रहा है - या साथ में? - जीडीआई +) –

+1

आप NSOpenGLView को उपclass नहीं करते हैं, आप एनएसवी व्यू को उपclass करते हैं और अधिक लचीलापन के लिए NSOpenGLContext और NSPixelFormat का उपयोग करते हैं (और आप बहुत सरल चीजों के लिए केवल NSOpenGLView का उपयोग करें)। – mk12

+2

इसके अलावा, ध्यान दें कि कार्बन काफी मृत अंत है (कोई 64 बिट समर्थन नहीं), और सीजीएल खिड़की नहीं बना सकता है, इसलिए ओएस एक्स के लिए कोको विंडोज़, मेनू इत्यादि के लिए एनएसजीएल और पूर्णस्क्रीन अनुप्रयोगों के लिए सीजीएल का उपयोग किया जाता है। – mk12

5

आप जो कर रहे हैं वह एक ओपनजीएल संदर्भ के साथ एक विंडो शुरू कर रहा है। इसके लिए ऑपरेटिंग सिस्टम को कुछ कॉल की आवश्यकता है। ओपनजीएल को केवल gl.h और glu.h के साथ प्रारंभ करना संभव नहीं है। GLUT (या SDL, SMFL, आदि) क्या यह आपके लिए एक अच्छा मंच स्वतंत्र तरीके से काम करता है। आप मूल कॉल के साथ प्रारंभिक भी कर सकते हैं।

2

आप GLUT source code को पकड़ सकते हैं और जो भी प्लेटफ़ॉर्म आप से संबंधित हैं, उसके लिए इनिट कोड देखें।

-2

का तरीका यहां बताया भरमार का उपयोग किए बिना ओपन (यह मानते हुए विंडोज़) प्रारंभ करने में एक बुनियादी और अच्छी शुरूआत है:

Init OpenGL without GLUT

के रूप में ल्यूक ने कहा, यदि आप न भरमार उपयोग करना चाहते हैं, तो आप के बारे में विशेष जानकारी की जरूरत है ऑपरेटिंग सिस्टम जिस पर आप विकास कर रहे हैं। जीएलयूटी का उपयोग करके आपके कोड को बंदरगाह में आसान बना दिया जाएगा।

+1

यह नमूना ग्लूट का उपयोग करता है? –

-1

जीएल एक एपीआई है, और जीएलयू जीएल के शीर्ष पर एक उपयोगिता पुस्तकालय है। यह पूरी तरह से ऑपरेटिंग सिस्टम स्वतंत्र है।

ओपनजीएल प्रारंभिकरण और एक्सटेंशन लाने प्लेटफार्म निर्भर संचालन हैं। इसलिए आप अकेले ओपनजीएल के साथ कुछ भी नहीं कर सकते हैं।

जीएलयूटी तेजी से अपर्याप्त और बहुत खराब पुस्तकालय है, और केवल यही है कि यह ओपनजीएल संदर्भ शुरू करता है और आपको चलने के लिए कुछ आदिम माउस/कीबोर्ड इनपुट मॉड्यूल प्रदान करता है।

Win32 ओपनजीएल संदर्भ को शुरू करने के लिए टूल प्रदान करता है। लिनक्स के लिए आप जीएलएक्स देख सकते हैं। इसके अलावा, अगर आप इसे करने का एक सिस्टम स्वतंत्र तरीका चाहते हैं, तो आप एसडीएल देख सकते हैं। विभिन्न प्रोग्रामिंग भाषाओं के लिए ऐसी सुविधाएं हो सकती हैं जो आपको एक मंच स्वतंत्र डेस्कटॉप एपीआई प्रदान करती हैं।

-1

आप गैलेक्सी बलों V2 के स्रोत की जाँच कर सकते हैं, http://www.galaxy-forces.com/

यह बिना ओपन के लिए कक्षाओं को लागू करता है विंडोज, मैक पर जीएलयूटी या अन्य पुस्तकालयों का उपयोग करना, और लिनक्स। मूल मंच कोड, सभी सार्वजनिक डोमेन का उपयोग करना।

2

GLX न्यूनतम runnable उदाहरण

here से अनुकूलित।

कीबोर्ड इनपुट के साथ भी सौदे करता है।

संकलित साथ:

gcc glx.c -lGLU -lGL -lX11 

Ubuntu 14.04 में परीक्षण किया गया।

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <sys/time.h> 
#define GL_GLEXT_PROTOTYPES 
#define GLX_GLXEXT_PROTOTYPES 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <GL/glx.h> 

struct MyWin { 
    Display *display; 
    Window win; 
    int displayed; 
    int width; 
    int height; 
}; 

const int WIN_XPOS = 256; 
const int WIN_YPOS = 64; 
const int WIN_XRES = 320; 
const int WIN_YRES = 320; 
const int NUM_SAMPLES = 4; 

struct MyWin Win; 

double elapsedMsec(const struct timeval *start, const struct timeval *stop) { 
    return ((stop->tv_sec - start->tv_sec) * 1000.0 + 
      (stop->tv_usec - start->tv_usec)/1000.0); 
} 

void displayCB() { 
    glClear(GL_COLOR_BUFFER_BIT); 
    glLoadIdentity(); 
    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 
    glBegin(GL_TRIANGLES); 
    glColor3f(1.0f, 0.0f, 0.0f); 
    glVertex3f(0.0f, 1.0f, 0.0f); 
    glVertex3f(-1.0f, -1.0f, 0.0f); 
    glVertex3f(1.0f, -1.0f, 0.0f); 
    glEnd(); 
    glFlush(); 
    glXSwapBuffers(Win.display, Win.win); 
} 

void keyboardCB(KeySym sym, unsigned char key, int x, int y, 
     int *setting_change) { 
    switch (tolower(key)) { 
     case 27: 
      exit(EXIT_SUCCESS); 
      break; 
     case 'k': 
      printf("You hit the 'k' key\n"); 
      break; 
     case 0: 
      switch (sym) { 
       case XK_Left : 
        printf("You hit the Left Arrow key\n"); 
        break; 
       case XK_Right : 
        printf("You hit the Right Arrow key\n"); 
        break; 
      } 
      break; 
    } 
} 

void reshapeCB(int width, int height) { 
    Win.width = width; 
    Win.height = height; 
    glViewport(0, 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); 
    glMatrixMode(GL_MODELVIEW); 
} 

/* Try to find a framebuffer config that matches 
* the specified pixel requirements. 
*/ 
GLXFBConfig chooseFBConfig(Display *display, int screen) { 
    static const int Visual_attribs[] = { 
     GLX_X_RENDERABLE , True, 
     GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, 
     GLX_RENDER_TYPE , GLX_RGBA_BIT, 
     GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, 
     GLX_RED_SIZE  , 8, 
     GLX_GREEN_SIZE , 8, 
     GLX_BLUE_SIZE  , 8, 
     GLX_ALPHA_SIZE , 8, 
     GLX_DEPTH_SIZE , 24, 
     GLX_STENCIL_SIZE , 8, 
     GLX_DOUBLEBUFFER , True, 
     GLX_SAMPLE_BUFFERS, 1, 
     GLX_SAMPLES  , 4, 
     None 
    }; 
    int attribs [ 100 ] ; 
    memcpy(attribs, Visual_attribs, sizeof(Visual_attribs)); 
    GLXFBConfig ret = 0; 
    int fbcount; 
    GLXFBConfig *fbc = glXChooseFBConfig(display, screen, attribs, &fbcount); 
    if (fbc) { 
     if (fbcount >= 1) 
      ret = fbc[0]; 
     XFree(fbc); 
    } 
    return ret; 
} 

GLXContext createContext(Display *display, int screen, 
     GLXFBConfig fbconfig, XVisualInfo *visinfo, Window window) { 
#define GLX_CONTEXT_MAJOR_VERSION_ARB  0x2091 
#define GLX_CONTEXT_MINOR_VERSION_ARB  0x2092 
    typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, 
      GLXFBConfig, GLXContext, int, const int*); 
    /* Verify GL driver supports glXCreateContextAttribsARB() */ 
    /* Create an old-style GLX context first, to get the correct function ptr. */ 
    glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; 
    GLXContext ctx_old = glXCreateContext(display, visinfo, 0, True); 
    if (!ctx_old) { 
     printf("Could not even allocate an old-style GL context!\n"); 
     exit(EXIT_FAILURE); 
    } 
    glXMakeCurrent (display, window, ctx_old) ; 
    /* Verify that GLX implementation supports the new context create call */ 
    if (strstr(glXQueryExtensionsString(display, screen), 
       "GLX_ARB_create_context") != 0) 
     glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) 
      glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB"); 
    if (!glXCreateContextAttribsARB) { 
     printf("Can't create new-style GL context\n"); 
     exit(EXIT_FAILURE); 
    } 
    /* Got the pointer. Nuke old context. */ 
    glXMakeCurrent(display, None, 0); 
    glXDestroyContext(display, ctx_old); 

    /* Try to allocate a GL 4.2 COMPATIBILITY context */ 
    static int Context_attribs[] = { 
     GLX_CONTEXT_MAJOR_VERSION_ARB, 4, 
     GLX_CONTEXT_MINOR_VERSION_ARB, 2, 
     GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 
     /*GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, */ 
     /*GLX_CONTEXT_FLAGS_ARB  , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, */ 
     /*GLX_CONTEXT_FLAGS_ARB  , GLX_CONTEXT_DEBUG_BIT_ARB, */ 
     None 
    }; 
    GLXContext context = glXCreateContextAttribsARB(display, fbconfig, 0, 
      True, Context_attribs); 
    /* Forcably wait on any resulting X errors */ 
    XSync(display, False); 
    if (!context) { 
     printf("Failed to allocate a GL 4.2 context\n"); 
     exit(EXIT_FAILURE); 
    } 
    printf("Created GL 4.2 context\n"); 
    return context; 
} 

void createWindow() { 
    /* Init X and GLX */ 
    Win.displayed = 0; 
    Display *display = Win.display = XOpenDisplay(":0.0"); 
    if (!display) 
     printf("Cannot open X display\n"); 
    int screen = DefaultScreen(display); 
    Window root_win = RootWindow(display, screen); 
    if (!glXQueryExtension(display, 0, 0)) 
     printf("X Server doesn't support GLX extension\n"); 
    /* Pick an FBconfig and visual */ 
    GLXFBConfig fbconfig = chooseFBConfig(display, screen); 
    if (!fbconfig) { 
     printf("Failed to get GLXFBConfig\n"); 
     exit(EXIT_FAILURE); 
    } 
    XVisualInfo *visinfo = glXGetVisualFromFBConfig(display, fbconfig); 
    if (!visinfo) { 
     printf("Failed to get XVisualInfo\n"); 
     exit(EXIT_FAILURE); 
    } 
    printf("X Visual ID = 0x%.2x\n", (int)visinfo->visualid); 
    /* Create the X window */ 
    XSetWindowAttributes winAttr ; 
    winAttr.event_mask = StructureNotifyMask | KeyPressMask ; 
    winAttr.background_pixmap = None ; 
    winAttr.background_pixel = 0 ; 
    winAttr.border_pixel  = 0 ; 
    winAttr.colormap = XCreateColormap(display, root_win, 
      visinfo->visual, AllocNone); 
    unsigned int mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; 
    Window win = Win.win = XCreateWindow (display, root_win, 
      WIN_XPOS, WIN_YPOS, 
      WIN_XRES, WIN_YRES, 0, 
      visinfo->depth, InputOutput, 
      visinfo->visual, mask, &winAttr) ; 
    XStoreName(Win.display, win, "My GLX Window"); 
    /* Create an OpenGL context and attach it to our X window */ 
    GLXContext context = createContext(display, screen, fbconfig, visinfo, win); 
    if (! glXMakeCurrent(display, win, context)) 
     printf("glXMakeCurrent failed.\n"); 
    if (! glXIsDirect (display, glXGetCurrentContext())) 
     printf("Indirect GLX rendering context obtained\n"); 
    /* Display the window */ 
    XMapWindow(display, win); 
    if (! glXMakeCurrent(display, win, context)) 
     printf("glXMakeCurrent failed.\n"); 
    printf("Window Size = %d x %d\n", WIN_XRES, WIN_YRES); 
    printf("Window Samples = %d\n", NUM_SAMPLES); 
} 

void processXEvents(Atom wm_protocols, Atom wm_delete_window) { 
    int setting_change = 0; 
    while (XEventsQueued(Win.display, QueuedAfterFlush)) { 
     XEvent event; 
     XNextEvent(Win.display, &event); 
     if(event.xany.window != Win.win) 
      continue; 
     switch (event.type) { 
      case MapNotify: 
       { 
        Win.displayed = 1; 
        break; 
       } 
      case ConfigureNotify: 
       { 
        XConfigureEvent cevent = event.xconfigure; 
        reshapeCB(cevent.width, cevent.height); 
        break; 
       } 
      case KeyPress: 
       { 
        char chr; 
        KeySym symbol; 
        XComposeStatus status; 
        XLookupString(&event.xkey, &chr, 1, &symbol, &status); 
        keyboardCB(symbol, chr, event.xkey.x, event.xkey.y, 
          &setting_change); 
        break; 
       } 
      case ClientMessage: 
       { 
        if (event.xclient.message_type == wm_protocols && 
          (Atom)event.xclient.data.l[0] == wm_delete_window) { 
         exit(EXIT_SUCCESS); 
        } 
        break; 
       } 
     } 
    } 
} 

void mainLoop() { 
    /* Register to receive window close events (the "X" window manager button) */ 
    Atom wm_protocols  = XInternAtom(Win.display, "WM_PROTOCOLS" , False); 
    Atom wm_delete_window = XInternAtom(Win.display, "WM_DELETE_WINDOW", False); 
    XSetWMProtocols(Win.display, Win.win, &wm_delete_window, True); 

    while (1) { 
     /* Redraw window (after it's mapped) */ 
     if (Win.displayed) 
      displayCB(); 

     /* Update frame rate */ 
     struct timeval last_xcheck = {0, 0}; 
     struct timeval now; 
     gettimeofday(&now, 0); 

     /* Check X events every 1/10 second */ 
     if (elapsedMsec(&last_xcheck, &now) > 100) { 
      processXEvents(wm_protocols, wm_delete_window); 
      last_xcheck = now; 
     } 
    } 
} 

int main(int argc, char *argv[]) { 
    Win.width = WIN_XRES; 
    Win.height = WIN_YRES; 
    createWindow(); 

    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glShadeModel(GL_FLAT); 

    printf("Valid keys: Left, Right, k, ESC\n"); 
    printf("Press ESC to quit\n"); 
    mainLoop(); 
    return EXIT_SUCCESS; 
} 

हमेशा FreeGlut के स्रोत को खोलने को देखने के लिए कि यह कैसे प्रत्येक भरमार समारोह लागू करता है सकते हैं, लेकिन GLX की तुलना में कम स्तर के लिए जा रहा संभावना कट्टर है।

EGL

GLX करने के लिए एक Khronos मानकीकृत विकल्प है, वर्तमान में सबसे अधिक बार OpenGL ES के साथ प्रयोग किया तरह लग रहा है।

https://cgit.freedesktop.org/mesa/demos/tree/src/egl मीसा के कार्यान्वयन का उपयोग उदाहरण दिए गए हैं, लेकिन मैं अभी तक उन्हें काम करने में कामयाब नहीं किया है:

git checkout mesa-demos-8.1.0 
./autogen.sh 
./configure 
make 

साथ विफल:

/work/git/mesa-demos/src/egl/opengl/demo1.c:26: undefined reference to `eglGetScreensMESA' 

लेकिन Ubuntu 14.04 mesa-utils-extra पैकेज में es2gears है, तो एक रास्ता होना चाहिए।

यह भी देखें: What is EGL And How Can I Use It