View in color | License | Download script | History | Other scripts by: luce80 |
19-Mar 13:03 UTC
[0.057] 22.61k
[0.057] 22.61k
nehe-lesson05-sdl.rREBOL [
Title: "NeHe Lesson 5 SDL"
file: %nehe-lesson05-sdl.r
author: "Marco Antoniazzi"
email: [luce80 AT libero DOT it]
date: 21-09-2012
version: 1.0.0
needs: [
%opengl-glu-glut-h.r
%sdl-h.r
]
Purpose: "Example use of %opengl-glu-glut-h.r and %sdl-h.r"
History: [
0.0.1 [11-08-2012 "First version"]
1.0.0 [21-09-2012 "Minor fixes"]
]
Category: [graphics]
library: [
level: 'intermediate
platform: [win linux]
type: 'how-to
domain: [graphics]
tested-under: [View 2.7.8.3.1 2.7.8.4.3]
support: none
license: none
see-also: [http://nehe.gamedev.net %nehe-lesson05.r]
]
]
{
* This code was created by Jeff Molofee '99
* (ported to Linux/SDL by Ti Leggett '01)
*
* If you've found this code useful, please let me know.
*
* Visit Jeff at http:;nehe.gamedev.net/
*
* or for port-specific comments, questions, bugreports etc.
* email to %leggett--eecs--tulane--edu
}
;REBOL-NOTE: load libraries and their headers
modul: any [
attempt [load %opengl-glu-glut-h.r]
if not error? try [close open tcp://www.google.com:80] [ ;online?
flash "Downloading OpenGL library header..."
modul: load http://www.rebol.org/download-a-script.r?script-name=opengl-glu-glut-h.r ;load-thru does not work (!?)
save %opengl-glu-glut-h.r modul
unview
modul
]
]
if not modul [alert "Unable to download or find opengl-glu-glut-h.r, quitting" quit]
clear back back tail modul ; remove example code
do modul
modul: any [
attempt [load %sdl-h.r]
if not error? try [close open tcp://www.google.com:80] [ ;online?
flash "Downloading SDL library header..."
modul: load http://www.rebol.org/download-a-script.r?script-name=sdl-h.r ;load-thru does not work (!?)
save %sdl-h.r modul
unview
modul
]
]
if not modul [alert "Unable to download or find sdl-h.r, quitting" quit]
clear back back tail modul ; remove example code
do modul
{ screen width, height, and bit depth }
SCREEN_WIDTH: 640
SCREEN_HEIGHT: 480
SCREEN_BPP: 16
{ Setup our booleans }
;TRUE: 1
;FALSE: 0
{ This is our SDL surface }
surface: none ;SDL_Surface *
{ function to release/destroy our resources and restoring the old desktop }
Quit*: func [returnCode ]
[
SDL_VideoQuit
{ clean up the window }
;SDL_Quit
;REBOL-NOTE: free SDL library
free SDL-lib
{ and exit appropriately }
;quit/return returnCode
halt
]
{ function to reset our viewport after a window resize }
resizeWindow: func [width height /local ratio]
[
{ Height / width ratio }
ratio: 0.0
{ Protect against a divide by zero }
if ( height = 0 ) [height: 1]
ratio: width / height
{ Setup our viewport. }
glViewport 0 0 width height
{ change to the projection matrix and set our viewing volume. }
glMatrixMode GL_PROJECTION
glLoadIdentity
{ Set our perspective }
gluPerspective 45.0 ratio 0.1 100.0
{ Make sure we're changing the model view and not the projection }
glMatrixMode GL_MODELVIEW
{ Reset The View }
glLoadIdentity
TRUE
]
{ function to handle key press events }
handleKeyPress: func [ keysym ]
[
switch ( keysym ) reduce
[
SDLK_ESCAPE [
{ ESC key was pressed }
Quit* 0
]
SDLK_F1 [
{ F1 key was pressed
* this toggles fullscreen mode
}
SDL_WM_ToggleFullScreen surface
]
]
]
{ general OpenGL initialization function }
initGL: func []
[
{ Enable smooth shading }
glShadeModel GL_SMOOTH
{ Set the background black }
glClearColor 0.0 0.0 0.0 0.0
{ Depth buffer setup }
glClearDepth 1.0
{ Enables Depth Testing }
glEnable GL_DEPTH_TEST
{ The Type Of Depth Test To Do }
glDepthFunc GL_LEQUAL
{ Really Nice Perspective Calculations }
glHint GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST
TRUE
]
rtri: rquad: 0.0
{ These are to calculate our fps }
T0: 0
Frames: 0
{ Here goes our drawing code }
drawGLScene: func [/local t seconds fps]
[
{ Clear The Screen And The Depth Buffer }
glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
glEnable GL_DEPTH_TEST
glLoadIdentity
glTranslatef -1.5 0.0 -6.0 ; Move Left And Into The Screen
glRotatef rtri 0.0 1.0 0.0 ; Rotate The Pyramid On It's Y Axis
glBegin GL_TRIANGLES ; Start Drawing The Pyramid
gl-color Red ; Red
glVertex3f 0.0 1.0 0.0 ; Top Of Triangle (Front)
gl-color Green ; Green
glVertex3f -1.0 -1.0 1.0 ; Left Of Triangle (Front)
gl-color Blue ; Blue
glVertex3f 1.0 -1.0 1.0 ; Right Of Triangle (Front)
gl-color Red ; Red
glVertex3f 0.0 1.0 0.0 ; Top Of Triangle (Right)
gl-color Blue ; Blue
glVertex3f 1.0 -1.0 1.0 ; Left Of Triangle (Right)
gl-color Green ; Green
glVertex3f 1.0 -1.0 -1.0 ; Right Of Triangle (Right)
gl-color Red ; Red
glVertex3f 0.0 1.0 0.0 ; Top Of Triangle (Back)
gl-color Green ; Green
glVertex3f 1.0 -1.0 -1.0 ; Left Of Triangle (Back)
gl-color Blue ; Blue
glVertex3f -1.0 -1.0 -1.0 ; Right Of Triangle (Back)
gl-color Red ; Red
glVertex3f 0.0 1.0 0.0 ; Top Of Triangle (Left)
gl-color Blue ; Blue
glVertex3f -1.0 -1.0 -1.0 ; Left Of Triangle (Left)
gl-color Green ; Green
glVertex3f -1.0 -1.0 1.0 ; Right Of Triangle (Left)
glEnd ; Done Drawing The Pyramid
glLoadIdentity
glTranslatef 1.5 0.0 -7.0 ; Move Right And Into The Screen
glRotatef rquad 1.0 1.0 1.0 ; Rotate The Cube On X, Y & Z
glBegin GL_QUADS ; Start Drawing The Cube
gl-color Green ; Set The Color To Green
glVertex3f 1.0 1.0 -1.0 ; Top Right Of The Quad (Top)
glVertex3f -1.0 1.0 -1.0 ; Top Left Of The Quad (Top)
glVertex3f -1.0 1.0 1.0 ; Bottom Left Of The Quad (Top)
glVertex3f 1.0 1.0 1.0 ; Bottom Right Of The Quad (Top
gl-color Orange ; Set The Color To Orange
glVertex3f 1.0 -1.0 1.0 ; Top Right Of The Quad (Bottom)
glVertex3f -1.0 -1.0 1.0 ; Top Left Of The Quad (Bottom)
glVertex3f -1.0 -1.0 -1.0 ; Bottom Left Of The Quad (Bottom)
glVertex3f 1.0 -1.0 -1.0 ; Bottom Right Of The Quad (Bottom)
gl-color Red ; Set The Color To Red
glVertex3f 1.0 1.0 1.0 ; Top Right Of The Quad (Front)
glVertex3f -1.0 1.0 1.0 ; Top Left Of The Quad (Front)
glVertex3f -1.0 -1.0 1.0 ; Bottom Left Of The Quad (Front)
glVertex3f 1.0 -1.0 1.0 ; Bottom Right Of The Quad (Front)
gl-color Yellow ; Set The Color To Yellow
glVertex3f 1.0 -1.0 -1.0 ; Bottom Left Of The Quad (Back)
glVertex3f -1.0 -1.0 -1.0 ; Bottom Right Of The Quad (Back)
glVertex3f -1.0 1.0 -1.0 ; Top Right Of The Quad (Back)
glVertex3f 1.0 1.0 -1.0 ; Top Left Of The Quad (Back)
gl-color Blue ; Set The Color To Blue
glVertex3f -1.0 1.0 1.0 ; Top Right Of The Quad (Left)
glVertex3f -1.0 1.0 -1.0 ; Top Left Of The Quad (Left)
glVertex3f -1.0 -1.0 -1.0 ; Bottom Left Of The Quad (Left)
glVertex3f -1.0 -1.0 1.0 ; Bottom Right Of The Quad (Left)
gl-color Violet ; Set The Color To Violet
glVertex3f 1.0 1.0 -1.0 ; Top Right Of The Quad (Right)
glVertex3f 1.0 1.0 1.0 ; Top Left Of The Quad (Right)
glVertex3f 1.0 -1.0 1.0 ; Bottom Left Of The Quad (Right)
glVertex3f 1.0 -1.0 -1.0 ; Bottom Right Of The Quad (Right)
glEnd ; Done Drawing The Quad
rtri: rtri + 0.2 ; Increase The Rotation Variable For The Triangle
rquad: rquad - 0.15 ; Decrease The Rotation Variable For The Quad
{ Draw it to the screen }
SDL_GL_SwapBuffers
{ Gather our frames per second }
Frames: Frames + 1
t: SDL_GetTicks
if (t - T0) >= 5000 [
seconds: (t - T0) / 1000.0
fps: Frames / seconds
print [Frames "frames in" seconds "seconds =" fps "FPS"]
T0: t
Frames: 0
]
TRUE
]
;REBOL-NOTE: make various structs to access SDL_Event(s), note the last underscore used to distinguish them
;from enumerated constants since REBOL is case insensitive
event-active: make struct! SDL_ActiveEvent_ none
event-resize: make struct! SDL_ResizeEvent_ none
event-key: make struct! SDL_KeyboardEvent_ none
assign-struct: func [dst [struct!] src [struct!]] [change third dst third src]
main: func [/local videoFlags done event videoInfo isActive]
[
{ Flags to pass to SDL_SetVideoMode }
videoFlags: 0
{ main loop variable }
done: false
{ used to collect events }
event: make struct! SDL_Event none
{ this holds some info about our display }
videoInfo: 0 ;const SDL_VideoInfo *
{ whether or not the window is active }
isActive: TRUE
{ initialize SDL }
if ( SDL_Init SDL_INIT_VIDEO ) < 0
[
print ["Video initialization failed:" SDL_GetError ]
Quit* 1
]
{ Fetch the video info }
videoInfo: SDL_GetVideoInfo
if 0 = videoInfo
[
print ["Video query failed:" SDL_GetError ]
Quit* 1
]
;REBOL-NOTE: copy data to a rebol struct!
videoInfo: addr-to-struct videoInfo SDL_VideoInfo
{ the flags to pass to SDL_SetVideoMode }
videoFlags: SDL_OPENGL { Enable OpenGL in SDL }
videoFlags: videoFlags or SDL_GL_DOUBLEBUFFER { Enable double buffering }
videoFlags: videoFlags or SDL_HWPALETTE { Store the palette in hardware }
videoFlags: videoFlags or SDL_RESIZABLE { Enable window resizing }
{ This checks to see if surfaces can be stored in memory }
either ( videoInfo/Bits and SDL_hw_available ) <> 0
[videoFlags: videoFlags or SDL_HWSURFACE]
[videoFlags: videoFlags or SDL_SWSURFACE]
{ This checks if hardware blits can be done }
if ( videoInfo/Bits and SDL_blit_hw ) <> 0
[videoFlags: videoFlags or SDL_HWACCEL]
{ Sets up OpenGL double buffering }
SDL_GL_SetAttribute SDL_GL_DOUBLEBUFFER 1
{ get a SDL surface }
surface: SDL_SetVideoMode SCREEN_WIDTH SCREEN_HEIGHT SCREEN_BPP videoFlags
{ Verify there is a surface }
if ( 0 = surface )
[
print ["Video mode set failed:" SDL_GetError ]
Quit* 1
]
{ initialize OpenGL }
initGL
{ Resize the initial window }
resizeWindow SCREEN_WIDTH SCREEN_HEIGHT
drawGLScene ;REBOL-NOTE: start drawing immediatly
print "Place mouse cursor inside window to activate it"
{ wait for events }
while [ not done ]
[
{ handle the events in the queue }
while [ 0 <> SDL_PollEvent event ]
[
switch ( to-integer event/type ) reduce
[
SDL_ACTIVEEVENT [
{ Something's happend with our focus
* If we lost focus or we are iconified, we
* shouldn't draw the screen
}
assign-struct event-active event ;REBOL-NOTE: translate data to a Rebol struct!
either ( 0 = to-integer event-active/gain )
[isActive: FALSE]
[isActive: TRUE]
]
SDL_VIDEORESIZE [
{ handle resize event }
assign-struct event-resize event
surface: SDL_SetVideoMode event-resize/w event-resize/h SCREEN_BPP videoFlags
if ( 0 = surface )
[
print ["Could not get a surface after resize:" SDL_GetError ]
Quit* 1
]
resizeWindow event-resize/w event-resize/h
]
SDL_KEYDOWN [
{ handle key presses }
assign-struct event-key event
handleKeyPress event-key/keysym-sym
]
SDL_QUIT [
{ handle quit requests }
done: true
]
]
]
{ draw the scene }
if ( isActive ) [drawGLScene ]
]
{ clean ourselves up and exit }
Quit* 0
{ Should never get here }
0
]
main Notes
|