1.4.5. demos/sdl/sdl-1.01.05

Start felix section to demos/sdl/sdl-1.01.05-0.flx[1 /1 ]
     1: #line 4296 "./lpsrc/flx_sdl.pak"
     2: // REQUIRES OpenGL and GLU
     3: /*
     4:  * This code was created by Jeff Molofee '99
     5:  * (ported to Linux/SDL by Ti Leggett '01)
     6:  *
     7:  * If you've found this code useful, please let me know.
     8:  *
     9:  * Visit Jeff at http://nehe.gamedev.net/
    10:  *
    11:  * or for port-specific comments, questions, bugreports etc.
    12:  * email to leggett@eecs.tulane.edu
    13:  */
    14: 
    15: #import <flx.flxh>
    16: include "SDL/SDL";
    17: include "SDL/SDL_keyboard";
    18: include "SDL/SDL_keysym";
    19: include "SDL/SDL_video";
    20: include "SDL/SDL_events";
    21: include "SDL/SDL_timer";
    22: include "SDL/SDL_mutex";
    23: include "SDL/SDL_opengl";
    24: 
    25: include "flx_faio";
    26: include "flx_faio_sdl";
    27: 
    28: open C_hack;
    29: open Carray;
    30: open MixedInt;
    31: open Uint32;
    32: open Uint8;
    33: open Float;
    34: 
    35: open SDL_h;
    36: open SDL_video_h;
    37: open SDL_keyboard_h;
    38: open SDL_events_h;
    39: open SDL_keysym_h;
    40: open SDL_timer_h;
    41: open SDL_mutex_h;
    42: 
    43: // This is the Felix asynchronous event source
    44: open SDL_events;
    45: 
    46: open SDL_opengl_h;
    47: 
    48: /* screen width, height, and bit depth */
    49: val SCREEN_WIDTH  = 640;
    50: val SCREEN_HEIGHT = 480;
    51: val SCREEN_BPP = 16;
    52: 
    53: /* function to reset our viewport after a window resize */
    54: proc resizeWindow( wwidth : int, hheight :int)
    55: {
    56:   var height = hheight;
    57:   var width = wwidth;
    58: 
    59:   /* Protect against a divide by zero */
    60:   if height == 0 do height = 1; done;
    61:   var ratio = double_of width / double_of height;
    62: 
    63:   block_sdl_events event_lock;
    64:   /* Setup our viewport. */
    65:   glViewport( 0, 0, width, height );
    66: 
    67:   /* change to the projection matrix and set our viewing volume. */
    68:   glMatrixMode( GL_PROJECTION );
    69:   glLoadIdentity( );
    70: 
    71:   /* Set our perspective */
    72:   gluPerspective( 45.0, ratio, 0.1, 100.0 );
    73: 
    74:   /* Make sure we're chaning the model view and not the projection */
    75:   glMatrixMode( GL_MODELVIEW );
    76: 
    77:   /* Reset The View */
    78:   glLoadIdentity( );
    79:   unblock_sdl_events event_lock;
    80: }
    81: 
    82: /* function to load in bitmap as a GL texture */
    83: proc LoadGLTextures( )
    84: {
    85:   /* Create storage space for the texture */
    86:   var TextureImage = SDL_LoadBMP(enconst c"media/textures/sdl208.bmp");
    87:   if isNULL TextureImage do
    88:     print "Can't load texture file media/textures/sdl208.bmp";
    89:     Quit 1;
    90:   done;
    91: 
    92:   /* Create The Texture */
    93:     glGenTextures( 3, texture );
    94: 
    95:   /* Typical Texture Generation Using Data From The Bitmap */
    96:   glBindTexture( GL_TEXTURE_2D, texture.[0] );
    97: 
    98:     /* Generate The Texture */
    99:   glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage.->w,
   100:     TextureImage.->h, 0, GL_RGB,
   101:     GL_UNSIGNED_BYTE, TextureImage.->pixels
   102:   );
   103: 
   104:   /* Linear Filtering */
   105:   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   106:     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
   107: 
   108:   glBindTexture( GL_TEXTURE_2D, texture.[1] );
   109: 
   110:   /* Linear Filtering */
   111:     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
   112:     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
   113: 
   114:     /* Generate The Texture */
   115:   glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage.->w,
   116:     TextureImage.->h, 0, cast[uint] GL_RGB,
   117:     GL_UNSIGNED_BYTE, TextureImage.->pixels
   118:   );
   119: 
   120:   glBindTexture( GL_TEXTURE_2D, texture.[2] );
   121: 
   122:   /* Linear Filtering */
   123:     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
   124:     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST );
   125: 
   126:   /* Generate The MipMapped Texture ( NEW ) */
   127:   ignore(gluBuild2DMipmaps(
   128:     GL_TEXTURE_2D, 3,
   129:     TextureImage.->w, TextureImage.->h,
   130:     GL_RGB, GL_UNSIGNED_BYTE,
   131:     cast[caddress] TextureImage.->pixels
   132:   ));
   133: 
   134:   /* Free up any memory we may have used */
   135:     SDL_FreeSurface( TextureImage );
   136: }
   137: 
   138: /* general OpenGL initialization function */
   139: proc initGL()
   140: {
   141:   /* Enable Texture Mapping ( NEW ) */
   142:   glEnable( GL_TEXTURE_2D );
   143: 
   144:   /* Enable smooth shading */
   145:   glShadeModel( GL_SMOOTH );
   146: 
   147:   /* Set the background black */
   148:   glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
   149: 
   150:   /* Depth buffer setup */
   151:   glClearDepth( 1.0 );
   152: 
   153:   /* Enables Depth Testing */
   154:   glEnable( GL_DEPTH_TEST );
   155: 
   156:   /* The Type Of Depth Test To Do */
   157:   glDepthFunc( GL_LEQUAL );
   158: 
   159:   /* Really Nice Perspective Calculations */
   160:   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   161: 
   162:   /* Setup The Ambient Light */
   163:   glLightfv( GL_LIGHT1, GL_AMBIENT, enconst (carray LightAmbient) );
   164: 
   165:   /* Setup The Diffuse Light */
   166:   glLightfv( GL_LIGHT1, GL_DIFFUSE, enconst (carray LightDiffuse) );
   167: 
   168:   /* Position The Light */
   169:   glLightfv( GL_LIGHT1, GL_POSITION, enconst (carray LightPosition) );
   170: 
   171:   /* Enable Light One */
   172:   glEnable( GL_LIGHT1 );
   173: 
   174:   /* Full Brightness, 50% Alpha ( NEW ) */
   175:   glColor4f( 1.0f, 1.0f, 1.0f, 0.5f);
   176: 
   177:   /* Blending Function For Translucency Based On Source Alpha Value  */
   178:   glBlendFunc( GL_SRC_ALPHA, GL_ONE );
   179: }
   180: 
   181: /* These are to calculate our fps */
   182: var T0     = 0;
   183: var Frames = 0;
   184: 
   185: var xrot = 0.0f; /* X Rotation ( NEW ) */
   186: var yrot = 0.0f; /* Y Rotation ( NEW ) */
   187: var z = -5.0f;   /* Depth Into The Screen */
   188: 
   189: var xspeed = 0.0f;
   190: var yspeed = 0.0f;
   191: 
   192: proc rotate()
   193: {
   194:   xrot += xspeed; /* Add xspeed To xrot */
   195:   yrot += yspeed; /* Add yspeed To yrot */
   196: }
   197: 
   198: 
   199: var light = false; /* Whether or not lighting is on */
   200: var blend = false; /* Whether or not blending is on */
   201: 
   202: 
   203: /* Ambient Light Values ( NEW ) */
   204: var LightAmbient =  0.5f, 0.5f, 0.5f, 1.0f;
   205: 
   206: /* Diffuse Light Values ( NEW ) */
   207: var LightDiffuse  = 1.0f, 1.0f, 1.0f, 1.0f;
   208: 
   209: /* Light Position ( NEW ) */
   210: var LightPosition = 0.0f, 0.0f, 2.0f, 1.0f;
   211: 
   212: var filter = 0;
   213: 
   214: var f_texture : uint ^ 3; /* Storage For 3 Textures ( NEW ) */
   215: var texture : carray[uint] = carray f_texture;
   216: 
   217: 
   218: /* Here goes our drawing code */
   219: proc drawGLScene(drawing:1->0)
   220: {
   221:   block_sdl_events event_lock;
   222:   drawing();
   223:   unblock_sdl_events event_lock;
   224: 
   225:   /* Gather our frames per second */
   226:   Frames++;
   227:   {
   228:     var t = SDL_GetTicks();
   229:     if t - T0 >= 5000 do
   230:       val seconds = double_of (t - T0) / 1000.0;
   231:       val fps = double_of Frames / seconds;
   232:       print Frames; print " frames in "; print seconds;
   233:       print " seconds = "; print fps; print " FPS"; endl;
   234:       T0 = t;
   235:       Frames = 0;
   236:     done;
   237:   };
   238:   rotate();
   239: }
   240: 
   241: /* whether or not the window is active */
   242: var isActive = true;
   243: 
   244: if SDL_Init(SDL_INIT_AUDIO \| SDL_INIT_VIDEO) < 0 do
   245:   print "Unable to init SDL"; endl;
   246:   System::exit(1);
   247: done;
   248: 
   249: var event_lock = SDL_CreateMutex();
   250: 
   251: 
   252: proc Quit(n:int)
   253: {
   254:   SDL_Quit;
   255:   System::exit 0;
   256: }
   257: 
   258: /* Fetch the video info */
   259: var videoInfo = SDL_GetVideoInfo();
   260: 
   261: if isNULL videoInfo do
   262:   print "Video query failed"; endl;
   263:   Quit 1;
   264: done;
   265: 
   266: /* the flags to pass to SDL_SetVideoMode */
   267: var
   268:   videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
   269:   videoFlags |= cast[uint] SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
   270:   videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
   271:   videoFlags |= SDL_RESIZABLE;       /* Enable window resizing */
   272: 
   273: /* This checks to see if surfaces can be stored in memory */
   274: if  videoInfo.->hw_available != 0 do
   275:     videoFlags |= SDL_HWSURFACE;
   276: else
   277:     videoFlags |= SDL_SWSURFACE;
   278: done;
   279: 
   280: /* This checks if hardware blits can be done */
   281: if videoInfo.->blit_hw != 0 do
   282:     videoFlags |= SDL_HWACCEL;
   283: done;
   284: 
   285: /* Sets up OpenGL double buffering */
   286: ignore$ SDL_GL_SetAttribute( cast[SDL_GLattr] SDL_GL_DOUBLEBUFFER, 1 );
   287: 
   288: /* get a SDL surface */
   289: var surface = SDL_SetVideoMode
   290:   (SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, videoFlags )
   291: ;
   292: 
   293: /* Verify there is a surface */
   294: if isNULL surface do
   295:   print "Video mode set failed"; endl;
   296:   Quit 1;
   297: done;
   298: 
   299: /* initialize OpenGL */
   300: initGL();
   301: LoadGLTextures();
   302: 
   303: /* resize the initial window */
   304: resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
   305: 
   306: // SDL Event dispatcher
   307: proc handle_active (e:SDL_ActiveEvent)
   308: {
   309:    isActive = e.gain != 0;
   310: }
   311: 
   312: proc handle_resize(e:SDL_ResizeEvent)
   313: {
   314:   block_sdl_events event_lock;
   315:   surface = SDL_SetVideoMode(
   316:     e.w,
   317:     e.h,
   318:     16, videoFlags
   319:   );
   320:   if isNULL surface do
   321:     print "Could not get a surface after resize"; endl;
   322:   done;
   323:   resizeWindow( e.w, e.h );
   324:   unblock_sdl_events event_lock;
   325: }
   326: 
   327: /* function to handle key press events */
   328: proc handle_key( keysym : SDL_keysym)
   329: {
   330:   match keysym.sym with
   331:   | ?k when k == SDLK_ESCAPE => { Quit 0; }
   332:   | ?k when k ==  SDLK_F1 =>
   333:         { ignore$ SDL_WM_ToggleFullScreen( surface ); }
   334:   | ?k when k == SDLK_b =>
   335:     {
   336:       blend = not blend;
   337:       if blend do
   338:             glEnable( GL_BLEND );
   339:             glDisable( GL_DEPTH_TEST );
   340:       else
   341:             glDisable( GL_BLEND );
   342:             glEnable( GL_DEPTH_TEST );
   343:       done;
   344:     }
   345:   | ?k when k == SDLK_f =>
   346:     {
   347:         filter = ( filter + 1) % 3;
   348:       print "Filter "; print filter; endl;
   349:     }
   350:   | ?k when k == SDLK_l =>
   351:     {
   352:         light = not light;
   353:         if not light do
   354:             glDisable( GL_LIGHTING );
   355:          else
   356:             glEnable( GL_LIGHTING );
   357:         done;
   358:     }
   359:   | ?k when k == SDLK_PAGEUP =>
   360:     {
   361:         z = z - 0.02f;
   362:     }
   363: 
   364:   | ?k when k == SDLK_PAGEDOWN =>
   365:     {
   366:         z = z + 0.02f;
   367:     }
   368: 
   369:   | ?k when k == SDLK_UP =>
   370:     {
   371:       xspeed = xspeed - 0.01f;
   372:     }
   373: 
   374:   | ?k when k == SDLK_DOWN =>
   375:     {
   376:       xspeed = xspeed + 0.01f;
   377:     }
   378: 
   379:   | ?k when k == SDLK_RIGHT =>
   380:     {
   381:       yspeed = yspeed + 0.01f;
   382:     }
   383: 
   384:   | ?k when k == SDLK_LEFT =>
   385:     {
   386:       yspeed = yspeed - 0.01f;
   387:     }
   388: 
   389:   | _ => {}
   390:   endmatch;
   391: }
   392: 
   393: /* draw the scene */
   394: proc draw(drawing: 1->0) {
   395:   if isActive call drawGLScene( drawing );
   396: }
   397: 
   398: proc keychan(x:schannel[SDL_keysym])
   399: {
   400:   whilst true do
   401:     var &k : SDL_keysym <- read x;
   402:     handle_key k;
   403:   done;
   404: }
   405: 
   406: proc activechan(x:schannel[SDL_ActiveEvent])
   407: {
   408:   whilst true do
   409:     var &k : SDL_ActiveEvent <- read x;
   410:     handle_active k;
   411:   done;
   412: }
   413: 
   414: proc resizechan(x:schannel[SDL_ResizeEvent])
   415: {
   416:   whilst true do
   417:     var &k : SDL_ResizeEvent <- read x;
   418:     handle_resize k;
   419:   done;
   420: }
   421: 
   422: proc drawchan(x:schannel[int], drawing:1->0)
   423: {
   424:   whilst true do
   425:     var &k : int <- read x;
   426:     draw drawing;
   427:   done;
   428: }
   429: 
   430: proc execute(x:schannel[int], something:1->0)
   431: {
   432:   whilst true do
   433:     var &k : int <- read x;
   434:     something();
   435:   done;
   436: }
   437: 
   438: val clock = Faio::mk_alarm_clock();
   439: proc poll_event(e: &SDL_Event)
   440: {
   441: tryagain:>
   442:   //print "Polling event"; endl;
   443:   var result = SDL_PollEvent(unref e);
   444:   if result > 0 do
   445:     //print "Got event"; endl;
   446:     return;
   447:   done;
   448:   Faio::sleep$ clock, 0.1;
   449:   goto tryagain;
   450: }
   451: 
   452: proc dispatch_event(
   453:   keyboard:schannel[SDL_keysym],
   454:   active:schannel[SDL_ActiveEvent],
   455:   resize:schannel[SDL_ResizeEvent]
   456: )
   457: {
   458:   whilst true do
   459:     //var &e : SDL_Event <- get_sdl_event event_lock;
   460:     var e : SDL_Event;
   461:     poll_event(&e);
   462:     match e.type_ with
   463:     | ?et when et == SDL_ACTIVEEVENT =>
   464:       { write (active, e.active); }
   465: 
   466:     | ?et when et == SDL_VIDEORESIZE =>
   467:       { write (resize, e.resize); }
   468: 
   469:     | ?et when et == SDL_KEYDOWN =>
   470:       { write (keyboard, e.key.keysym); }
   471: 
   472:     | ?et when et == SDL_QUIT =>
   473:       { Quit 0; }
   474: 
   475:     | _ => {}
   476:     endmatch;
   477:   done;
   478: }
   479: 
   480: /* write ticks at the desired framerate */
   481: proc framerate (x:schannel[int], framerate:double)
   482: {
   483:   whilst true do
   484:     Faio::sleep$ clock, framerate;
   485:     write (x,1);
   486:   done;
   487: }
   488: 
   489: /* LINEAR CONTROL MODEL: CANNOT DEADLOCK
   490:   ~~> async/sync connection
   491:   --> sync/sync connection
   492: 
   493:   SDL_event ~~> dispatcher
   494:                 --> resize handler
   495:                 --> active handler
   496:                 --> key handler
   497:   timer ~~> framerate --> draw
   498: */
   499: 
   500: /* make our communication channels */
   501: var keyboard = mk_schannel[SDL_keysym] ();
   502: var active = mk_schannel[SDL_ActiveEvent] ();
   503: var resize = mk_schannel[SDL_ResizeEvent] ();
   504: var clicks = mk_schannel[int] ();
   505: var rotation = mk_schannel[int] ();
   506: 
   507: /* start up the fthreads and plug them together */
   508: spawn_fthread { dispatch_event (keyboard, active, resize); };
   509: spawn_fthread { resizechan resize; };
   510: spawn_fthread { activechan active; };
   511: spawn_fthread { keychan keyboard; };
   512: 
   513: spawn_fthread { drawchan (clicks, the Drawing); };
   514: spawn_fthread { framerate (clicks, 0.05); };
   515: spawn_fthread { execute (rotation, the rotate); };
   516: spawn_fthread { framerate (rotation, 0.01); };
   517: 
   518: 
   519: // main thread hangs
   520: 
   521: /* Here goes our drawing code */
   522: proc Drawing()
   523: {
   524:   /* Clear The Screen And The Depth Buffer */
   525:   glClear( GL_COLOR_BUFFER_BIT \| GL_DEPTH_BUFFER_BIT );
   526: 
   527:   /* Reset the view */
   528:   glLoadIdentity( );
   529: 
   530:   /* Translate Into/Out Of The Screen By z */
   531:   glTranslatef( 0.0f, 0.0f, z );
   532: 
   533:   glRotatef( xrot, 1.0f, 0.0f, 0.0f); /* Rotate On The X Axis By xrot */
   534:   glRotatef( yrot, 0.0f, 1.0f, 0.0f); /* Rotate On The Y Axis By yrot */
   535: 
   536:   /* Select A Texture Based On filter */
   537:   glBindTexture( GL_TEXTURE_2D, texture.[filter] );
   538: 
   539:   /* Start Drawing Quads */
   540:   glBegin( GL_QUADS );
   541:     /* Front Face */
   542:     /* Normal Pointing Towards Viewer */
   543:     glNormal3f( 0.0f, 0.0f, 1.0f );
   544:     /* Point 1 (Front) */
   545:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f,  1.0f );
   546:     /* Point 2 (Front) */
   547:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  1.0f, -1.0f,  1.0f );
   548:     /* Point 3 (Front) */
   549:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f(  1.0f,  1.0f,  1.0f );
   550:     /* Point 4 (Front) */
   551:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f,  1.0f,  1.0f );
   552: 
   553:     /* Back Face */
   554:     /* Normal Pointing Away From Viewer */
   555:     glNormal3f( 0.0f, 0.0f, -1.0f);
   556:     /* Point 1 (Back) */
   557:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );
   558:     /* Point 2 (Back) */
   559:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f,  1.0f, -1.0f );
   560:     /* Point 3 (Back) */
   561:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f(  1.0f,  1.0f, -1.0f );
   562:     /* Point 4 (Back) */
   563:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  1.0f, -1.0f, -1.0f );
   564: 
   565:     /* Top Face */
   566:     /* Normal Pointing Up */
   567:     glNormal3f( 0.0f, 1.0f, 0.0f );
   568:     /* Point 1 (Top) */
   569:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f,  1.0f, -1.0f );
   570:     /* Point 2 (Top) */
   571:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f,  1.0f,  1.0f );
   572:     /* Point 3 (Top) */
   573:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f(  1.0f,  1.0f,  1.0f );
   574:     /* Point 4 (Top) */
   575:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f(  1.0f,  1.0f, -1.0f );
   576: 
   577:     /* Bottom Face */
   578:     /* Normal Pointing Down */
   579:     glNormal3f( 0.0f, -1.0f, 0.0f );
   580:     /* Point 1 (Bottom) */
   581:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );
   582:     /* Point 2 (Bottom) */
   583:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f(  1.0f, -1.0f, -1.0f );
   584:     /* Point 3 (Bottom) */
   585:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f(  1.0f, -1.0f,  1.0f );
   586:     /* Point 4 (Bottom) */
   587:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f,  1.0f );
   588: 
   589:     /* Right face */
   590:     /* Normal Pointing Right */
   591:     glNormal3f( 1.0f, 0.0f, 0.0f);
   592:     /* Point 1 (Right) */
   593:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f, -1.0f, -1.0f );
   594:     /* Point 2 (Right) */
   595:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f,  1.0f, -1.0f );
   596:     /* Point 3 (Right) */
   597:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f,  1.0f,  1.0f );
   598:     /* Point 4 (Right) */
   599:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, -1.0f,  1.0f );
   600: 
   601:     /* Left Face*/
   602:     /* Normal Pointing Left */
   603:     glNormal3f( -1.0f, 0.0f, 0.0f );
   604:     /* Point 1 (Left) */
   605:     glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );
   606:     /* Point 2 (Left) */
   607:     glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f,  1.0f );
   608:     /* Point 3 (Left) */
   609:     glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f,  1.0f,  1.0f );
   610:     /* Point 4 (Left) */
   611:     glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f,  1.0f, -1.0f );
   612:   glEnd();
   613: 
   614:   /* Draw it to the screen */
   615:   SDL_GL_SwapBuffers( );
   616: 
   617: }
End felix section to demos/sdl/sdl-1.01.05-0.flx[1]