$TYPECHECK ON $INCLUDE <RapidQ2.inc> $INCLUDE <GL\QGL.inc> dim debug as qdebug '----------------------------------------------- 'sample HeNe #19,'' This code was created by Jeff Molofee '99 '' ported by JohnK '----------------------------------------------- DECLARE SUB drawGLScene DECLARE Sub MakeQuad DECLARE sub Form_Key_Press(keysym AS Word, KeyShift AS INTEGER) DECLARE sub ResetParticle( byval num as integer, byval clr as integer, byval xDir as single, byval yDir as single, byval zDir as single ) DECLARE sub initfx DECLARE sub sizeit DECLARE sub wipeoff '' Max number of particles CONST MAX_PARTICLES = 250 DEFINT rainbow = TRUE '' Toggle rainbow effect DEFSNG slowdown = -1.0 '' Slow Down Particles DEFSNG xspeed '' Base X Speed (To Allow Keyboard Direction Of Tail) DEFSNG yspeed '' Base Y Speed (To Allow Keyboard Direction Of Tail) DEFSNG zoom = -10.0 '' Used To Zoom Out DEFINT col = 0 '' Current Color Selection DEFINT delay '' Rainbow Effect Delay '' Create our particle structure type particle active as integer '' Active (Yes/No) life as single '' Particle Life fade as single '' Fade Speed r as single '' Red Value g as single '' Green Value b as single '' Blue Value x as single '' X Position y as single '' Y Position z as single '' Z Position xi as single '' X Direction yi as single '' Y Direction zi as single '' Z Direction xg as single '' X Gravity yg as single '' Y Gravity zg as single '' Z Gravity end type '' Rainbow of colors DEFSNG colors(0 to 35) = { _ 1.0, 0.5, 0.5, _ 1.0, 0.75, 0.5, _ 1.0, 1.0, 0.5, _ 0.75, 1.0, 0.5, _ 0.5, 1.0, 0.5, _ 0.5, 1.0, 0.75, _ 0.5, 1.0, 1.0, _ 0.5, 0.75, 1.0, _ 0.5, 0.5, 1.0, _ 0.75, 0.5, 1.0, _ 1.0, 0.5, 1.0, _ 1.0, 0.5, 0.75} '' Our beloved array of particles dim particles(0 to MAX_PARTICLES-1) as particle 'create our wrapper DIM GL AS QGL DIM myTexture AS GLuint :myTexture = 0 DIM TheQuad as glInt create tmx as QTimer interval = 1 enabled = 0 onTimer = drawGLScene end create ' user interface create fx as QFORM caption = "RQGL Demo" top = 16 left = 26 width = 640 height = 480 onPaint = drawGLScene onResize = sizeit onClick = wipeoff onKeyDown = Form_Key_Press onShow = initfx end create ' main program fx.ShowModal end 'user procedures sub initfx DIM clr as integer DIM i as integer dim xi as single , yi as single , zi as single GL.Init(fx) '' Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit myTexture = GL.CreateTextureFromFile("particle.bmp") IF myTexture = 0 THEN Showmessage "failed texture": fx.Close GL.Front = .1 GL.Back = 200 '' Enable smooth shading glShadeModel( GL_SMOOTH ) '' Set the background black glClearColor( 0.2, 0.2, 0.2, 0.0 ) '' Depth buffer setup glClearDepth( 1.0 ) '' Enables Depth Testing glDisable( GL_DEPTH_TEST ) '' Enable Blending glEnable( GL_BLEND ) '' Type Of Blending To Perform glBlendFunc( GL_SRC_ALPHA, GL_ONE ) '' Really Nice Perspective Calculations glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) '' Really Nice Point Smoothing glHint( GL_POINT_SMOOTH_HINT, GL_NICEST ) '' Enable Texture Mapping glEnable( GL_TEXTURE_2D ) '' Select Our Texture ' glBindTexture( GL_TEXTURE_2D, myTexture ) '' Reset all the particles for i = 0 to MAX_PARTICLES-1 clr = ( i + 1 ) \ ( MAX_PARTICLES \ 12 ) xi = ( ( rnd * 50 ) - 26.0 ) * 10.0 yi = ( ( rnd * 50 ) - 25.0 ) * 10.0 zi = yi ResetParticle( i, clr, xi, yi, zi ) next i MakeQuad tmx.enabled = true end sub sub sizeit GL.Resize(fx.clientWidth, fx.clientHeight) glMatrixMode( GL_MODELVIEW ) '' Reset The View glLoadIdentity end sub sub wipeoff '' Clean up our textures glDeleteTextures( 1, myTexture) GL.Close fx.close end sub '' function to reset one particle to initial state '' NOTE: I added this function to replace doing the same thing in several '' places and to also make it easy to move the pressing of numpad keys '' 2, 4, 6, and 8 into handleKeyPress function. sub ResetParticle( byval num as integer, byval clr as integer, byval xDir as single, byval yDir as single, byval zDir as single ) '' Make the particels active particles(num).active = TRUE '' Give the particles life particles(num).life = 1.0 '' Random Fade Speed particles(num).fade = ( rnd * 100 ) / 1000.0 + 0.003 '' Select Red Rainbow Color particles(num).r = colors(clr * 3 + 0) '' Select Green Rainbow Color particles(num).g = colors(clr * 3 + 1) '' Select Blue Rainbow Color particles(num).b = colors(clr * 3+ 2) '' Set the position on the X axis particles(num).x = 0.0 '' Set the position on the Y axis particles(num).y = 0.0 '' Set the position on the Z axis particles(num).z = 0.0 '' Random Speed On X Axis particles(num).xi = xDir '' Random Speed On Y Axi particles(num).yi = yDir '' Random Speed On Z Axis particles(num).zi = zDir '' Set Horizontal Pull To Zero particles(num).xg = 0.0 '' Set Vertical Pull Downward particles(num).yg = -0.8 '' Set Pull On Z Axis To Zero particles(num).zg = 0.0 end sub '' function to handle key press events sub Form_Key_Press(keysym AS Word, KeyShift AS INTEGER) dim i as integer 'showmessage str$(keysym) select case keysym case 27 '' ESC key was pressed wipeoff case 112 '' F1 key toggles fullscreen mode IF GL.FullScreen = False THEN fx.BorderStyle = bsNone fx.top=0: fx.Left = 0 SizeIt GL.FullScreen = True ELSE fx.BorderStyle = bsSizeable fx.top=10: fx.Left = 10 GL.FullScreen = False END IF case 187 '' + speeds up the particles if ( slowdown > 1.0 ) then slowdown -= 0.1 case 189 '' - slows down the particles if ( slowdown < 4.0 ) then slowdown += 0.1 case 33 '' PageUp key was pressed '' this zooms into the scene zoom = zoom + 0.5 case 34 '' this zooms out of the scene zoom = zoom -0.5 case 38 '' up arrow increases the particles' y movement if ( yspeed < 200.0 ) then _ yspeed += 4 case 40 '' dn arrow decreases the particles' y movement if ( yspeed > -200.0 ) then _ yspeed -= 4 case 39 '' Right arrow key was pressed '' this increases the particles' x movement if ( xspeed < 200.0 ) then _ xspeed += 4 case 37 '' Left arrow key was pressed '' this decreases the particles' x movement if ( xspeed > -200.0 ) then _ xspeed -= 4 case 71 '' 'g' increase particles' y gravity for i = 0 to MAX_PARTICLES-1 if ( particles(i).yg < 1.5 ) then particles(i).yg = particles(i).yg +0.5 next i case 89 '' y decreases the particles' y gravity for i = 0 to MAX_PARTICLES-1 if ( particles(i).xg > -1.5 ) then particles(i).xg = particles(i).xg -0.5 next i case 88 '' x increases the particles' x gravity for i = 0 to MAX_PARTICLES-1 if ( particles(i).xg < 1.5 ) then particles(i).xg = particles(i).xg + 0.5 next i case 13 '' Return key was pressed '' this toggles the rainbow color effect rainbow = not rainbow delay = 5 case 32 '' Spacebar was pressed '' this turns off rainbow-ing and manually cycles through colors rainbow = FALSE delay = 0 col = ( col + 1 ) mod 12 end select IF KeyShift THEN '' Tab key was pressed '' this resets the particles and makes them re-explode for i = 0 to MAX_PARTICLES-1 DEFINT clr = ( i + 1 ) \ ( MAX_PARTICLES \ 12 ) DEFSNG xi, yi, zi xi = ( ( rnd * 50 ) - 26.0 ) * 10.0 yi = ( ( rnd * 50 ) - 25.0 ) * 10.0 zi = yi ResetParticle( i, clr, xi, yi, zi ) next i END IF end sub '' Here goes our drawing code SUB drawGLScene dim i as integer dim x as single , y as single , z as single dim xi as single , yi as single , zi as single '' Clear The Screen And The Depth Buffer glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT ) glLoadIdentity '' Modify each of the particles for i = 0 to MAX_PARTICLES-1 if ( particles(i).active ) then x = particles(i).x ' Grab Our Particle X Position y = particles(i).y ' Grab Our Particle Y Position z = particles(i).z + zoom ' Particle Z Position + Zoom '' Draw The Particle Using Our RGB Values, '' Fade The Particle Based On It's Life glColor4f( particles(i).r, _ particles(i).g, _ particles(i).b, _ particles(i).life ) glLoadIdentity glTranslatef(x, y, z) glCallList(theQuad) '' Move On The X Axis By X Speed particles(i).x = particles(i).x + particles(i).xi / ( slowdown * 1000 ) '' Move On The Y Axis By Y Speed particles(i).y = particles(i).y + particles(i).yi / ( slowdown * 1000 ) '' Move On The Z Axis By Z Speed particles(i).z = particles(i).z + particles(i).zi / ( slowdown * 1000 ) '' Take Pull On X Axis Into Account particles(i).xi = particles(i).xi + particles(i).xg '' Take Pull On Y Axis Into Account particles(i).yi = particles(i).yi + particles(i).yg '' Take Pull On Z Axis Into Account particles(i).zi = particles(i).zi + particles(i).zg '' Reduce Particles Life By 'Fade' particles(i).life = particles(i).life - particles(i).fade '' If the particle dies, revive it if ( particles(i).life < 0.0 ) then xi = xspeed + ( ( rnd * 60 ) - 32.0 ) yi = yspeed + ( ( rnd * 60 ) - 30.0 ) zi = ( ( rnd * 60 ) - 30.0 ) ResetParticle( i, col, xi, yi, zi ) end if end if next i '' Draw it to the screen GL.Flip '' Gather our frames per second fx.Caption = "Frame Rate = " + str$(GL.FrameRate) END SUB Sub MakeQuad TheQuad = glGenLists( 1 ) glNewList( TheQuad, GL_COMPILE) '' Build Quad From A Triangle Strip glBegin( GL_TRIANGLE_STRIP ) '' Top Right glTexCoord2d( 1, 1 ) glVertex3f( 0.5, + 0.5, -10 ) '' Top Left glTexCoord2d( 0, 1 ) glVertex3f( -0.5, + 0.5, -10 ) '' Bottom Right glTexCoord2d( 1, 0 ) glVertex3f( 0.5, - 0.5, -10 ) '' Bottom Left glTexCoord2d( 0, 0 ) glVertex3f( -0.5, - 0.5, -10 ) glEnd glEndList end sub