Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/bensch/lesson01.c @ 1775

Last change on this file since 1775 was 1775, checked in by bensch, 22 years ago

orxonox/branches/bensch: added some test files.

File size: 9.6 KB
RevLine 
[1775]1/*
2 * This code was created by Jeff Molofee '99
3 * (ported to Linux/GLX by Mihael Vrbanec '00)
4 *
5 * If you've found this code useful, please let me know.
6 *
7 * Visit Jeff at http://nehe.gamedev.net/
8 *
9 * or for port-specific comments, questions, bugreports etc.
10 * email to Mihael.Vrbanec@stud.uni-karlsruhe.de
11 */
12 
13#include <stdio.h>
14#include <GL/glx.h>
15#include <GL/gl.h>
16#include <GL/glu.h>
17#include <X11/extensions/xf86vmode.h>
18#include <X11/keysym.h>
19
20/* stuff about our window grouped together */
21typedef struct {
22    Display *dpy;
23    int screen;
24    Window win;
25    GLXContext ctx;
26    XSetWindowAttributes attr;
27    Bool fs;
28    Bool doubleBuffered;
29    XF86VidModeModeInfo deskMode;
30    int x, y;
31    unsigned int width, height;
32    unsigned int depth;   
33} GLWindow;
34
35/* attributes for a single buffered visual in RGBA format with at least
36 * 4 bits per color and a 16 bit depth buffer */
37static int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 4, 
38    GLX_GREEN_SIZE, 4, 
39    GLX_BLUE_SIZE, 4, 
40    GLX_DEPTH_SIZE, 16,
41    None};
42
43/* attributes for a double buffered visual in RGBA format with at least
44 * 4 bits per color and a 16 bit depth buffer */
45static int attrListDbl[] = { GLX_RGBA, GLX_DOUBLEBUFFER, 
46    GLX_RED_SIZE, 4, 
47    GLX_GREEN_SIZE, 4, 
48    GLX_BLUE_SIZE, 4, 
49    GLX_DEPTH_SIZE, 16,
50    None };
51
52GLWindow GLWin;
53
54/* function called when our window is resized (should only happen in window mode) */
55void resizeGLScene(unsigned int width, unsigned int height)
56{
57    if (height == 0)    /* Prevent A Divide By Zero If The Window Is Too Small */
58        height = 1;
59    glViewport(0, 0, width, height);    /* Reset The Current Viewport And Perspective Transformation */
60    glMatrixMode(GL_PROJECTION);
61    glLoadIdentity();
62    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
63    glMatrixMode(GL_MODELVIEW);
64}
65
66/* general OpenGL initialization function */
67int initGL(GLvoid)
68{
69    glShadeModel(GL_SMOOTH);
70    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
71    glClearDepth(1.0f);
72    glEnable(GL_DEPTH_TEST);
73    glDepthFunc(GL_LEQUAL);
74    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
75    /* we use resizeGLScene once to set up our initial perspective */
76    resizeGLScene(GLWin.width, GLWin.height);
77    glFlush();
78    return True;
79}
80
81/* Here goes our drawing code */
82int drawGLScene(GLvoid)
83{
84    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
85    glLoadIdentity();
86    if (GLWin.doubleBuffered)
87    {
88        glXSwapBuffers(GLWin.dpy, GLWin.win);
89    }
90    return True;   
91}
92
93/* function to release/destroy our resources and restoring the old desktop */
94GLvoid killGLWindow(GLvoid)
95{
96    if (GLWin.ctx)
97    {
98        if (!glXMakeCurrent(GLWin.dpy, None, NULL))
99        {
100            printf("Could not release drawing context.\n");
101        }
102        glXDestroyContext(GLWin.dpy, GLWin.ctx);
103        GLWin.ctx = NULL;
104    }
105    /* switch back to original desktop resolution if we were in fs */
106    if (GLWin.fs)
107    {
108        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, &GLWin.deskMode);
109        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
110    }
111    XCloseDisplay(GLWin.dpy);
112}
113
114/* this function creates our window and sets it up properly */
115/* FIXME: bits is currently unused */
116Bool createGLWindow(char* title, int width, int height, int bits,
117                    Bool fullscreenflag)
118{
119    XVisualInfo *vi;
120    Colormap cmap;
121    int dpyWidth, dpyHeight;
122    int i;
123    int glxMajorVersion, glxMinorVersion;
124    int vidModeMajorVersion, vidModeMinorVersion;
125    XF86VidModeModeInfo **modes;
126    int modeNum;
127    int bestMode;
128    Atom wmDelete;
129    Window winDummy;
130    unsigned int borderDummy;
131   
132    GLWin.fs = fullscreenflag;
133    /* set best mode to current */
134    bestMode = 0;
135    /* get a connection */
136    GLWin.dpy = XOpenDisplay(0);
137    GLWin.screen = DefaultScreen(GLWin.dpy);
138    XF86VidModeQueryVersion(GLWin.dpy, &vidModeMajorVersion,
139        &vidModeMinorVersion);
140    printf("XF86VidModeExtension-Version %d.%d\n", vidModeMajorVersion,
141        vidModeMinorVersion);
142    XF86VidModeGetAllModeLines(GLWin.dpy, GLWin.screen, &modeNum, &modes);
143    /* save desktop-resolution before switching modes */
144    GLWin.deskMode = *modes[0];
145    /* look for mode with requested resolution */
146    for (i = 0; i < modeNum; i++)
147    {
148        if ((modes[i]->hdisplay == width) && (modes[i]->vdisplay == height))
149        {
150            bestMode = i;
151        }
152    }
153    /* get an appropriate visual */
154    vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
155    if (vi == NULL)
156    {
157        vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
158        GLWin.doubleBuffered = False;
159        printf("Only Singlebuffered Visual!\n");
160    }
161    else
162    {
163        GLWin.doubleBuffered = True;
164        printf("Got Doublebuffered Visual!\n");
165    }
166    glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
167    printf("glX-Version %d.%d\n", glxMajorVersion, glxMinorVersion);
168    /* create a GLX context */
169    GLWin.ctx = glXCreateContext(GLWin.dpy, vi, 0, GL_TRUE);
170    /* create a color map */
171    cmap = XCreateColormap(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
172        vi->visual, AllocNone);
173    GLWin.attr.colormap = cmap;
174    GLWin.attr.border_pixel = 0;
175
176    if (GLWin.fs)
177    {
178        XF86VidModeSwitchToMode(GLWin.dpy, GLWin.screen, modes[bestMode]);
179        XF86VidModeSetViewPort(GLWin.dpy, GLWin.screen, 0, 0);
180        dpyWidth = modes[bestMode]->hdisplay;
181        dpyHeight = modes[bestMode]->vdisplay;
182        printf("Resolution %dx%d\n", dpyWidth, dpyHeight);
183        XFree(modes);
184   
185        /* create a fullscreen window */
186        GLWin.attr.override_redirect = True;
187        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
188            StructureNotifyMask;
189        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
190            0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual,
191            CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
192            &GLWin.attr);
193        XWarpPointer(GLWin.dpy, None, GLWin.win, 0, 0, 0, 0, 0, 0);
194                XMapRaised(GLWin.dpy, GLWin.win);
195        XGrabKeyboard(GLWin.dpy, GLWin.win, True, GrabModeAsync,
196            GrabModeAsync, CurrentTime);
197        XGrabPointer(GLWin.dpy, GLWin.win, True, ButtonPressMask,
198            GrabModeAsync, GrabModeAsync, GLWin.win, None, CurrentTime);
199    }
200    else
201    {
202        /* create a window in window mode*/
203        GLWin.attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask |
204            StructureNotifyMask;
205        GLWin.win = XCreateWindow(GLWin.dpy, RootWindow(GLWin.dpy, vi->screen),
206            0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
207            CWBorderPixel | CWColormap | CWEventMask, &GLWin.attr);
208        /* only set window title and handle wm_delete_events if in windowed mode */
209        wmDelete = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
210        XSetWMProtocols(GLWin.dpy, GLWin.win, &wmDelete, 1);
211        XSetStandardProperties(GLWin.dpy, GLWin.win, title,
212            title, None, NULL, 0, NULL);
213        XMapRaised(GLWin.dpy, GLWin.win);
214    }       
215    /* connect the glx-context to the window */
216    glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
217    XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
218        &GLWin.width, &GLWin.height, &borderDummy, &GLWin.depth);
219    printf("Depth %d\n", GLWin.depth);
220    if (glXIsDirect(GLWin.dpy, GLWin.ctx)) 
221        printf("Congrats, you have Direct Rendering!\n");
222    else
223        printf("Sorry, no Direct Rendering possible!\n");
224    initGL();
225    return True;   
226}
227
228int main(int argc, char **argv)
229{
230    XEvent event;
231    Bool done;
232   
233    done = False;
234    /* default to fullscreen */
235    GLWin.fs = True;
236    createGLWindow("NeHe's OpenGL Framework", 640, 480, 24, GLWin.fs);
237
238    /* wait for events*/ 
239    while (!done)
240    {
241        /* handle the events in the queue */
242        while (XPending(GLWin.dpy) > 0)
243        {
244            XNextEvent(GLWin.dpy, &event);
245            switch (event.type)
246            {
247                case Expose:
248                        if (event.xexpose.count != 0)
249                            break;
250                    drawGLScene();
251                        break;
252            case ConfigureNotify:
253            /* call resizeGLScene only if our window-size changed */
254                if ((event.xconfigure.width != GLWin.width) || 
255                    (event.xconfigure.height != GLWin.height))
256                {
257                    GLWin.width = event.xconfigure.width;
258                    GLWin.height = event.xconfigure.height;
259                        printf("Resize event\n");
260                    resizeGLScene(event.xconfigure.width,
261                        event.xconfigure.height);
262                }
263                break;
264            /* exit in case of a mouse button press */
265            case ButtonPress:     
266                done = True;
267                break;
268            case KeyPress:
269                if (XLookupKeysym(&event.xkey, 0) == XK_Escape)
270                {
271                    done = True;
272                }
273                if (XLookupKeysym(&event.xkey,0) == XK_F1)
274                {
275                    killGLWindow();
276                    GLWin.fs = !GLWin.fs;
277                    createGLWindow("NeHe's OpenGL Framework", 640, 480, 24, GLWin.fs);
278                }
279                break;
280            case ClientMessage:   
281                if (*XGetAtomName(GLWin.dpy, event.xclient.message_type) == 
282                    *"WM_PROTOCOLS")
283                {
284                    printf("Exiting sanely...\n");
285                    done = True;
286                }
287                break;
288            default:
289                break;
290            }
291        }
292        drawGLScene();
293    }
294    killGLWindow();
295    exit (0);
296}
Note: See TracBrowser for help on using the repository browser.