'a lot of this code has been borrowed from rel's opengl tutorials DEFINT A - Z randomize timer const PI = 3.141593 const SCR_WIDTH = 640 const SCR_HEIGHT = 480 const BITSPP = 32 const maxseg = 2000 'option explicit '$include: "\sdl\sdl.bi" '$include: "\gl\gl.bi" '$include: "\gl\glu.bi" DECLARE SUB Init_GL_SDL(SDLscreen as SDL_Surface ptr) Declare Sub SDL_GetEvents(EscapeVal as Integer) Declare Sub draw_scene() Declare Sub Draw_Cube() declare sub genmap () declare sub rotpnt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!) declare function u! (an!) dim vpage as SDL_Surface ptr dim Finished as integer dim shared cs(360) as single, sn(360) as single dim shared rx!, ry!, rz!, camx!, camy!, camz! dim shared segangle(maxseg) as single dim shared segdata(maxseg, 9) as single 'xyz increment on the z axis, xyz increment on the x axis, xyz increment on the z axis dim shared fp, fps, fpsr!, tim# dim shared nearseg, nearsub dim shared mapscale!, viewdist,radius! dim shared tilt!, campitch!, lethrottle!, methrottle!, yheight! dim shared pathvector(6) as single 'this contains the nxyz values from the draw routine to compare vs camera 'angle to turn the camera angle to follow perpendicular to track position dim shared event as SDL_Event, keys as Uint8 ptr const maxpoly = 20 type pointtype x as single y as single z as single end type type polytype pnt(3) as pointtype col(3) as single end type type tiletype npolies as integer polies(maxpoly) as polytype end type dim shared tileinfo(1) as tiletype read npolies tileinfo(0).npolies = npolies for i = 0 to npolies - 1 for a = 0 to 2 read tileinfo(0).polies(i).pnt(a).x read tileinfo(0).polies(i).pnt(a).y read tileinfo(0).polies(i).pnt(a).z next for a = 0 to 2 read tileinfo(0).polies(i).col(a) next next radius! = 10 mapscale! = 5 viewdist = 80 'yheight! = .1 camy! = yheight! camz! = -10 tim# = timer + 1 genmap maxspeed! = 4 nearseg = 0 tilt! = 0 for i = 0 to 360 cs(i) = cos(3.141592 / 180 * i) sn(i) = sin(3.141592 / 180 * i) next genmap Init_GL_SDL vpage Finished = 0 do SDL_GetEvents(Finished) draw_scene SDL_GL_SwapBuffers SDL_PumpEvents tilt! = tilt! - 5 * lethrottle! if tilt! > 20 then tilt! = 20 if tilt! < -20 then tilt! = -20 tilt! = tilt! * .9 ry! = u!(ry! + lethrottle! * 3) rotpnt 0, 0, 1, 0, ry!, 0, nx!, ny!, nz! rotpnt nx!, ny!, nz!, campitch!, 0, 0, nx!, ny!, nz! camx! = camx! + nx! * speed! camy! = camy! + ny! * speed! camz! = camz! - nz! * speed! speed! = speed! + methrottle! * .1 if speed! > maxspeed! then speed! = maxspeed! speed! = speed! * .99 closer = nearseg dist! = 500 for iter = -5 to 5 a = nearseg + iter if a < 0 then a = 0 if a > maxseg then a = maxseg ax! = camx! - segdata(a, 0) * mapscale! ay! = camy! - segdata(a, 1) * mapscale! az! = camz! - segdata(a, 2) * mapscale! d1! = sqr(ax! * ax! + ay! * ay! + az! * az!) if d1! < dist! then dist! = d1! closer = a end if next nearseg = closer ax! = camx! - segdata(nearseg, 0) * mapscale! ay! = camy! - segdata(nearseg, 1) * mapscale! az! = camz! - segdata(nearseg, 2) * mapscale! d1! = sqr(ax! * ax! + ay! * ay! + az! * az!) closeness! = .9 maxd! = radius! * closeness! * 2 if d1! > maxd! then bx! = ax! * maxd! / d1! + segdata(nearseg, 0) * mapscale! by! = ay! * maxd! / d1! + segdata(nearseg, 1) * mapscale! bz! = az! * maxd! / d1! + segdata(nearseg, 2) * mapscale! camx! = camx! + (bx! - camx!) * closeness! camy! = camy! + (by! - camy!) * closeness! camz! = camz! + (bz! - camz!) * closeness! end if loop until Finished SDL_Quit end data 40 data -1, 0, 1 data -1, 0, 0 data 0, 0, 1 data 0.5, 0.5, 0.5 data 0, 0, 0 data 0, 0, 1 data -1, 0, 0 data 1, 1, 1 data -2, 0, 1 data -2, 0, 0 data -1, 0, 1 data 0.5, 0.5, 0.5 data -1, 0, 0 data -1, 0, 1 data -2, 0, 0 data 0.5, 0.5, 0.5 data -3, 0, 1 data -3, 0, 0 data -2, 0, 1 data 0.5, 0.5, 0.5 data -2, 0, 0 data -2, 0, 1 data -3, 0, 0 data 0.5, 0.5, 0.5 data -4, 0, 1 data -4, 0, 0 data -3, 0, 1 data 0.5, 0.5, 0.5 data -3, 0, 0 data -3, 0, 1 data -4, 0, 0 data 0.5, 0.5, 0.5 data -5, 0, 1 data -5, 0, 0 data -4, 0, 1 data 0.5, 0.5, 0.5 data -4, 0, 0 data -4, 0, 1 data -5, 0, 0 data 0.5, 0.5, 0.5 data -6, 0, 1 data -6, 0, 0 data -5, 0, 1 data 0.5, 0.5, 0.5 data -5, 0, 0 data -5, 0, 1 data -6, 0, 0 data 0.5, 0.5, 0.5 data -7, 0, 1 data -7, 0, 0 data -6, 0, 1 data 0.5, 0.5, 0.5 data -6, 0, 0 data -6, 0, 1 data -7, 0, 0 data 0.5, 0.5, 0.5 data -8, 0, 1 data -8, 0, 0 data -7, 0, 1 data 0.5, 0.5, 0.5 data -7, 0, 0 data -7, 0, 1 data -8, 0, 0 data 0.5, 0.5, 0.5 data -9, 0, 1 data -9, 0, 0 data -8, 0, 1 data 0.5, 0.5, 0.5 data -8, 0, 0 data -8, 0, 1 data -9, 0, 0 data 0.5, 0.5, 0.5 data -10, 1, 1 data -10, 1, 0 data -9, 0, 1 data 0.3, 0.3, 0.3 data -9, 0, 0 data -9, 0, 1 data -10, 1, 0 data 0.3, 0.3, 0.3 '-- data 1, 0, 1 data 1, 0, 0 data 0, 0, 1 data 0.5, 0.5, 0.5 data 0, 0, 0 data 0, 0, 1 data 1, 0, 0 data 1, 1, 1 data 2, 0, 1 data 2, 0, 0 data 1, 0, 1 data 0.5, 0.5, 0.5 data 1, 0, 0 data 1, 0, 1 data 2, 0, 0 data 0.5, 0.5, 0.5 data 3, 0, 1 data 3, 0, 0 data 2, 0, 1 data 0.5, 0.5, 0.5 data 2, 0, 0 data 2, 0, 1 data 3, 0, 0 data 0.5, 0.5, 0.5 data 4, 0, 1 data 4, 0, 0 data 3, 0, 1 data 0.5, 0.5, 0.5 data 3, 0, 0 data 3, 0, 1 data 4, 0, 0 data 0.5, 0.5, 0.5 data 5, 0, 1 data 5, 0, 0 data 4, 0, 1 data 0.5, 0.5, 0.5 data 4, 0, 0 data 4, 0, 1 data 5, 0, 0 data 0.5, 0.5, 0.5 data 6, 0, 1 data 6, 0, 0 data 5, 0, 1 data 0.5, 0.5, 0.5 data 5, 0, 0 data 5, 0, 1 data 6, 0, 0 data 0.5, 0.5, 0.5 data 7, 0, 1 data 7, 0, 0 data 6, 0, 1 data 0.5, 0.5, 0.5 data 6, 0, 0 data 6, 0, 1 data 7, 0, 0 data 0.5, 0.5, 0.5 data 8, 0, 1 data 8, 0, 0 data 7, 0, 1 data 0.5, 0.5, 0.5 data 7, 0, 0 data 7, 0, 1 data 8, 0, 0 data 0.5, 0.5, 0.5 data 9, 0, 1 data 9, 0, 0 data 8, 0, 1 data 0.5, 0.5, 0.5 data 8, 0, 0 data 8, 0, 1 data 9, 0, 0 data 0.5, 0.5, 0.5 data 10, 1, 1 data 10, 1, 0 data 9, 0, 1 data 0.3, 0.3, 0.3 data 9, 0, 0 data 9, 0, 1 data 10, 1, 0 data 0.3, 0.3, 0.3 SUB Init_GL_SDL(SDLscreen as SDL_Surface ptr) dim Result as unsigned integer 'checker value for SDL initialization dim SDL_flags as integer 'Flags for SDL screen 'OpenGL params for gluerspective dim FOVy as double 'Feild of view angle in Y dim Aspect as double 'Aspect of screen dim znear as double 'z-near clip distance dim zfar as double 'z-far clip distance 'Let's set up our sdl flags variable SDL_flags = SDL_HWSURFACE 'use Hardware surface SDL_flags = SDL_flags or SDL_DOUBLEBUF 'doublebuffer to prevent flicker SDL_flags = SDL_flags or SDL_OPENGL 'activate OpenGL SDL_flags = SDL_flags or SDL_FULLSCREEN 'FullScreen(REM for windowed) 'Init everything for SDL(video,audio, key, joy, etc) result = SDL_Init(SDL_INIT_EVERYTHING) if result <> 0 then 'error? end 1 'then quit end if 'Set 640*480*32 'SCR_WIDTH/HEIGHT/BITSPP are CONSTANTS declared at the main module SDLscreen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, BITSPP, SDL_flags) if SDLscreen = 0 then SDL_Quit end 1 end if SDL_WM_SetCaption "glflattest", "" 'Make caption if windowed 'Set OpenGL ViewPort to screen dimensions glViewport 0, 0, SCR_WIDTH, SCR_HEIGHT 'Set current Mode to projection(ie: 3d) glMatrixMode GL_PROJECTION 'Load identity matrix to projection matrix glLoadIdentity 'Set gluPerspective params FOVy = 80/2 '45 deg fovy Aspect = SCR_WIDTH / SCR_HEIGHT 'aspect = x/y znear = 1 'Near clip zfar = 2000 'far clip 'use glu Perspective to set our 3d frustum dimension up gluPerspective FOVy, aspect, znear, zfar 'Modelview mode 'ie. Matrix that does things to anything we draw 'as in lines, points, tris, etc. glMatrixMode GL_MODELVIEW 'load identity(clean) matrix to modelview glLoadIdentity glShadeModel GL_SMOOTH 'set shading to smooth(try GL_FLAT) glClearColor 0.0, 0.0, 0.0, 0.0 'set Clear color to BLACK glClearDepth 1.0 'Set Depth buffer to 1(z-Buffer) glEnable GL_DEPTH_TEST 'Enable Depth Testing so that our z-buffer works 'compare each incoming pixel z value with the z value present in the depth buffer 'LEQUAL means than pixel is drawn if the incoming z value is less than 'or equal to the stored z value glDepthFunc GL_LEQUAL 'have one or more material parameters track the current color 'Material is your 3d model glEnable GL_COLOR_MATERIAL 'Tell openGL that we want the best possible perspective transform glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST END SUB '******************************************************************************************* 'Check for events from SDL 'Params: Escapeval is a byref integer that allows us to ' quit out mainloop and quit the proggie Sub SDL_GetEvents(EscapeVal as Integer) 'SDL event is type in the SDL inc directory 'poll events SDL_PollEvent ( @event ) keys = SDL_GetKeyState(null) methrottle! = 0 lethrottle! = 0 if keys[SDLK_ESCAPE] then EscapeVal = 1 if keys[SDLK_W] then lethrottle! = lethrottle! - .5 if keys[SDLK_L] then lethrottle! = lethrottle! - .5 if keys[SDLK_S] then lethrottle! = lethrottle! + .5 if keys[SDLK_O] then lethrottle! = lethrottle! + .5 if keys[SDLK_I] then methrottle! = methrottle! + .5 if keys[SDLK_E] then methrottle! = methrottle! + .5 if keys[SDLK_D] then methrottle! = methrottle! - .5 if keys[SDLK_K] then methrottle! = methrottle! - .5 'if keys[SDLK_LEFT] then movingleft = 1 'if keys[SDLK_RIGHT] then movingright = 1 ' 'if k$ = "w" then 'if k$ = "l" then lethrottle! = lethrottle! + .5 'if k$ = "s" then lethrottle! = lethrottle! - .5 'if k$ = "o" then lethrottle! = lethrottle! - .5 'if k$ = "j" then 'if k$ = "f" then 'if k$ = "u" then 'if k$ = "r" then 'if k$ = "i" then methrottle! = methrottle! + .5 'if k$ = "e" then methrottle! = methrottle! + .5 'if k$ = "d" then methrottle! = methrottle! - .5 'if k$ = "k" then methrottle! = methrottle! - .5 End Sub '******************************************************************************************* 'Draw to our open GL screen Sub draw_scene() static theta as integer 'Rotation degrees dim xtrans as single 'xtranslation dim ytrans as single 'ytranslation dim ztrans as single 'ztranslation dim scalefactor as single 'Scaling factor 'clear the screen 'GL_COLOR_BUFFER_BIT = to black(remember glClearColor?) 'GL_DEPTH_BUFFER_BIT set depth buffer to 1 (remember glClearDepth?) glClear GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT 'Push matrix to the matrix stack so that we start fresh glPushMatrix 'Reset the matrix to identity glLoadIdentity 'Our translation factor 'Try to change these arguments xtrans = 0.0 ytrans = 0.0 ztrans = -10 glTranslatef xtrans, ytrans, ztrans 'Our scale factor Scalefactor = 1.0 'glScalef scalefactor, scalefactor, scalefactor 'Scales our modelview matrix 3x in the x, y, z axes 'try to change its arguments to different values glScalef scalefactor, scalefactor, scalefactor 'glRotatef angle, x, y, z rotates your model 'angle = Specifies the angle of rotation, in degrees 'x, y, z = Specify the x, y, and z coordinates of a vector 'So to rotate your 3d object theta degrees in the x axis you would write: 'we will meke use of some other values for x,y ans z coords in later tutes glRotatef u!(5 + tiltb! / 10), 1, 0, 0 'glRotatef theta, 0, 1, 0 'rotate in the y axis 'tiltb! = tilt! 'glRotatef u!(tiltb!), 0, 0, 1 Draw_Cube glPopMatrix Theta = theta + 1 'Force completion of drawing glFlush end sub '******************************************************************************************* 'Draw's our a normalized cube. Taken andmodified from NeHe's tutorials(Im lazy so what? ;*)) 'NEW!!!!!! Sub Draw_Cube() endseg = nearseg + viewdist if endseg > maxseg - 1 then endseg = maxseg - 1 startseg = nearseg - viewdist if startseg < 1 then startseg = 1 dim pnts(3, 3) as single pullx! = 0 pully! = 0 pullz! = 0 a! = tilt! tiltb! = u!(a!) for i = endseg to startseg step -1 if i = nearseg then closer = 0 dist! = 500 end if nx! = segdata(i, 0) ny! = segdata(i, 1) nz! = segdata(i, 2) x! = nearsub xl! = nx! * mapscale! - camx! yl! = ny! * mapscale! - camy! zl! = nz! * mapscale! - camz! xl! = xl! + x! * segdata(i, 3) + y! * segdata(i, 6) yl! = yl! + x! * segdata(i, 4) + y! * segdata(i, 7) zl! = zl! + x! * segdata(i, 5) + y! * segdata(i, 8) rotpnt xl!, yl!, zl!, rx!, ry!, 0, nx!, ny!, nz! 'rotpnt nx!, ny!, nz!, 0, 0, tiltb!, nx!, ny!, nz! if i = nearseg then d1! = sqr(xl! * xl! + yl! * yl! + zl! * zl!) if d1! < dist! then dist! = d1! closer = a end if pathvector(4) = ny! campitch! = u!(segangle(i)) end if npolies = tileinfo(0).npolies for ply = 0 to npolies - 1 for pnt = 0 to 2 iz = i + tileinfo(0).polies(ply).pnt(pnt).z nx! = segdata(iz, 0) ny! = segdata(iz, 1) nz! = segdata(iz, 2) x! = tileinfo(0).polies(ply).pnt(pnt).x y! = tileinfo(0).polies(ply).pnt(pnt).y xl! = nx! * mapscale! - camx! yl! = ny! * mapscale! - camy! - 1 zl! = nz! * mapscale! - camz! xl! = xl! - x! * segdata(iz, 3) + y! * segdata(iz, 6) yl! = yl! - x! * segdata(iz, 4) + y! * segdata(iz, 7) zl! = zl! - x! * segdata(iz, 5) + y! * segdata(iz, 8) rotpnt xl!, yl!, zl!, rx!, ry!, 0, nx!, ny!, nz! rotpnt nx!, ny!, nz!, 0, 0, tiltb!, nx!, ny!, nz! pnts(pnt, 0) = nx! pnts(pnt, 1) = ny! pnts(pnt, 2) = nz! next if nz! < 15 - zback then r! = cos((i mod 8) / 8 * 3.14159 * 2) * .15 + .85 glBegin GL_TRIANGLES glColor3f tileinfo(0).polies(ply).col(0) * r!, tileinfo(0).polies(ply).col(1) * r!, tileinfo(0).polies(ply).col(2) * r! glVertex3f pnts(0,0), pnts(0,1), pnts(0,2) glVertex3f pnts(1,0), pnts(1,1), pnts(1,2) glVertex3f pnts(2,0), pnts(2,1), pnts(2,2) glEnd glBegin GL_LINES glColor3f tileinfo(0).polies(ply).col(0) * .75 * r!, tileinfo(0).polies(ply).col(1) * .75 * r!, tileinfo(0).polies(ply).col(2) * .75 * r! glVertex3f pnts(0,0), pnts(0,1), pnts(0,2) glVertex3f pnts(1,0), pnts(1,1), pnts(1,2) glVertex3f pnts(1,0), pnts(1,1), pnts(1,2) glVertex3f pnts(2,0), pnts(2,1), pnts(2,2) glVertex3f pnts(2,0), pnts(2,1), pnts(2,2) glVertex3f pnts(0,0), pnts(0,1), pnts(0,2) glEnd else startseg = i end if next next nearsub = closer if pathvector(4) + yheight! > 0 then camy! = camy! + (pathvector(4) + yheight!)' * .8 End Sub sub genmap () bx! = 0 by! = 0 bz! = 0 yawness = 10 pitchness = 2 yawan! = 180 pitchan! = 0 y! = 0 i = 0 do yaw! = rnd * yawness - yawness / 2 pitch! = rnd * pitchness - pitchness / 2 if i > maxseg - 3 then yaw! = 0 if i < 3 then yaw! = 0 if i > maxseg - 3 then pitch! = 0 if i < 3 then pitch! = 0 l = int(5) * 2 for a = 0 to l yawan! = u!(yawan! + yaw!) opitch! = pitchan! pitchan! = u!(pitchan! + pitch!) if opitch! > 340 and pitchan! <= 340 then pitchan! = opitch! if opitch! < 20 and pitchan! >= 20 then pitchan! = opitch! 'if pitchan! 'bx! = bx! + .5 * cos(3.14159 / 180 * yawan!) 'by! = by! + .5 * sin(3.14159 / 180 * yawan!) 'y! = y! + .5 * sin(3.14159 / 180 * pitchan!) i = i + 1 if i > maxseg then exit do rotpnt 2, 0, 0, 0, yawan!, 0, nx!, ny!, nz! rotpnt nx!, ny!, nz!, pitchan!, 0, 0, nx!, ny!, nz! segdata(i, 3) = nx! segdata(i, 4) = ny! segdata(i, 5) = nz! rotpnt 0, 2, 0, 0, yawan!, 0, nx!, ny!, nz! rotpnt nx!, ny!, nz!, pitchan!, 0, 0, nx!, ny!, nz! segdata(i, 6) = nx! segdata(i, 7) = ny! segdata(i, 8) = nz! rotpnt 0, 0, 1, 0, yawan!, 0, nx!, ny!, nz! rotpnt nx!, ny!, nz!, pitchan!, 0, 0, nx!, ny!, nz! segdata(i, 0) = bx! + nx! segdata(i, 1) = by! + ny! segdata(i, 2) = bz! + nz! bx! = bx! + nx! by! = by! + ny! bz! = bz! + nz! segangle(i) = -pitchan! 'segangle(i, 1) = yawan! next loop end sub sub rotpnt (x1!, y1!, z1!, rotx!, roty!, rotz!, nx!, ny!, nz!) rx = rotx! ry = roty! rz = rotz! 'x nx1! = x1! ny1! = z1! * sn(rx) + y1! * cs(rx) nz1! = z1! * cs(rx) - y1! * sn(rx) 'y nx2! = nx1! * cs(ry) - nz1! * sn(ry) ny2! = ny1! nz2! = nx1! * sn(ry) + nz1! * cs(ry) 'z nx3! = nx2! * cs(rz) - ny2! * sn(rz) ny3! = nx2! * sn(rz) + ny2! * cs(rz) nz3! = nz2! nx! = nx3! ny! = ny3! nz! = nz3! end sub function u! (an!) while an! > 359: an! = an! - 360: wend while an! < 0: an! = an! + 360: wend u! = an! end function