Frage

jede Einführung und Probe, die ich finden kann, scheint GLUT oder einen anderen Rahmen zu verwenden, um „initialisieren“ OpenGL. Gibt es eine Möglichkeit OpenGL zur Initialisierung mit genau dem, was in GL und GLU verfügbar ist? Wenn nicht, dann was GLUT ist, das zu tun ist nicht möglich, ohne es?

War es hilfreich?

Lösung

Wie luke erwähnt, ist der Code zu erstellen und den Kontext zu binden spezifisch für jede Windowing-Plattform.

Hier sind einige Funktionen, die Sie im Hinblick auf die Initialisierung von OpenGL auf bestimmten Plattformen zu erhalten begonnen:

Fenster (ein Tutorial ist hier )

  • wglCreateContext (hDC)

Mac OS X - O X hat im Wesentlichen drei Möglichkeiten: Kohlenstoff, Kakao, und die darunter liegenden Core Graphics Layer-

Linux

Andere Tipps

Was Sie tun, ist ein Fenster mit einem OpenGL-Kontext zu initialisieren. Dies erfordert einige Anrufe an das Betriebssystem. Es ist nicht möglich, OpenGL zu initialisieren mit nur gl.h und glu.h. GLUT (oder SDL , SMFL , usw.) macht das in einer netten Plattform unabhängige Art und Weise für Sie arbeiten. Sie können auch die Initialisierung mit nativer Anrufe tun.

Sie könnten die greifen GLUT Quellcode und finden Sie in der Init-Code für was auch immer Plattform, die Sie beschäftigen sich mit.

GLX minimal runnable Beispiel

Angepasst von hier .

befasst sich auch mit Tastatureingaben.

Kompilieren mit:

gcc glx.c -lGLU -lGL -lX11

Getestet in 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;
}

Man könnte immer die Quelle der freeglut zu sehen, wie es jede Schwemme Funktion implementiert, aber gehe niedrigeres Niveau als GLX ist wahrscheinlich Hardcore.

EGL

Sieht aus wie ein Khronos standardisierte Alternative zu GLX, die derzeit am häufigsten mit OpenGL ES verwendet.

https://cgit.freedesktop.org/mesa/demos/tree / src / egl enthält Beispiele Mesa-Implementierung verwendet, aber ich habe noch nicht geschafft, sie funktioniert:

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

schlägt mit:

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

Aber Ubuntu 14.04 hat in dem es2gears Paket mesa-utils-extra, so muss es eine Möglichkeit sein.

Siehe auch: Was ist EGL und wie kann ich verwenden es

GL ist eine API, und GLU ist eine Utility-Bibliothek auf der GL. Es ist völlig unabhängig vom Betriebssystem.

OpenGL Initialisierung und Erweiterung fetching sind plattformabhängige Operationen. Daher können Sie allein mit OpenGL über nichts tun.

GLUT ist schnell unzureichend und schrecklich schlechte Bibliothek und über nur es tut, ist, dass es den OpenGL-Kontext initialisiert und bietet einige primitive Maus / Tastatur-Eingabemodule Sie laufend zu erhalten.

Win32 bietet Tools als auch OpenGL-Kontext zu initialisieren. Für Linux können Sie GLX überprüfen. Auch, wenn Sie ein System unabhängige Art und Weise, es zu tun mögen, dann können Sie SDL überprüfen. Für verschiedene Programmiersprachen kann es Dienstprogramme, die Ihnen eine Plattform unabhängigen Desktop-API zur Verfügung stellen.

Sie können die Quelle der Galaxy Forces V2 überprüfen, http://www.galaxy-forces.com/

Es implementiert Klassen für OpenGL ohne GLUT oder andere Bibliotheken auf Windows, Mac und Linux. Mit nativen Plattform-Code, alle öffentlichen Bereich.

Hier ist eine grundlegende und eine gute Einführung, wie Sie initialisieren OpenGL (vorausgesetzt, Fenster) ohne GLUT mit:

Init OpenGL ohne GLUT

Wie Luke sagte, wenn Sie nicht wollen GLUT verwenden Sie spezifische Informationen über das Betriebssystem benötigen Sie entwickeln. Mit GLUT wird Ihren Code einfacher zu portieren machen.

GLUT ist für gewöhnlich großes Werkzeug für eine OpenGL lernen, ohne dass die Details von Sachen Windowing. Sie können ohne unnötigen Details OpenGL leicht lernen. Nein, es ist keine Funktionen für ein Fenster erstellen und das Fenster in OpenGL zu verwalten. Es ist möglich, aber Sie müssen die Funktionen vom Betriebssystem verwenden Sie zur Verfügung gestellt verwenden. ZB Windows oder Linux, die für Anfänger besonders Windows ist ein echter Alptraum ist, wenn Sie OpenGL neu sind dann GLUT ist der Weg zu gehen.

Der Basic-Code für

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top