Code: Select all
'3 types of camera
'3rd person, and first person
'Keys:
'W,S = move forward
'A,D = Rotate view left, right
'X,C = Roll
'Q,Z = Rotate view up, down
'1,2,3 = change camera mode
'Alternate keys
'Arrows, Insert, home, end, etc
'Relsoft 2005
'Rel.Betterwebber.com
DEFINT A - Z
const PI = 3.141593 'PI for rotation
const RAD_FACTOR = PI / 180.0
const SCR_WIDTH = 640 'Width of the screen
const SCR_HEIGHT = 480 'height of the screen
const BITSPP = 32 '32 bits per pixel format
const CAM_SPEED = .25
const MAX_NPC = 60
enum CAMERA_MODE
E_FPC 'First person
E_TPC '3rd person for planes
E_TPC2 'Mariokart
end enum
option explicit 'Force declaration
Type Vector3d
x as single
y as single
z as single
End Type
Type CameraType
m_Position as vector3d
m_Target as vector3d
m_Up as vector3d
m_Roll as integer
m_mode as integer
End Type
Type PlayerType
m_Position as vector3d
m_Target as vector3d
m_Up as vector3d
m_Roll as integer
m_OldV as vector3d 'old look
m_NewV as vector3d 'New Look
End Type
Type NpcType
x as single
y as single
z as single
Theta as integer
Phi as integer
radius as single
rot_radius as single
r as single
g as single
b as single
End Type
'$include: "\sdl\sdl.bi" 'sdl function and constants declaration
'$include: "\gl\gl.bi" 'OpenGL funks and consts
'$include: "\gl\glu.bi" 'GL standard utility lib
'Declarations
DECLARE SUB Init_GL_SDL(SDLscreen as SDL_Surface ptr)
Declare Sub SDL_GetEvents(EscapeVal as Integer)
Declare Sub draw_scene()
declare sub draw_axis ()
declare sub draw_player_axis ()
Declare sub Render_grid(byval y as integer, byval scale as single)
declare sub vector_cross (v1 as vector3d, v2 as vector3d, vout as vector3d)
declare function vector_magnitude(v as vector3d) as single
declare sub vector_normalize (v as vector3d)
declare sub vector_add (v1 as vector3d, v2 as vector3d, vout as vector3d)
declare sub vector_sub (v1 as vector3d, v2 as vector3d, vout as vector3d)
declare sub player_set_position(Byref Player as PlayerType, _
byval px as single, byval py as single, byval pz as single,_
byval vx as single, byval vy as single, byval vz as single,_
byval ux as single, byval uy as single, byval uz as single)
declare Sub player_setview(Byref Player as PlayerType)
declare Sub player_setview_by_mouse(Byref Player as PlayerType)
declare Sub player_rotate_view (Byref Player as PlayerType, byval angle as single,_
byval x as single, byval y as single, byval z as single)
declare Sub player_move(Byref Player as PlayerType, byval speed as single)
declare Sub player_strafe(Byref Player as PlayerType, byval speed as single)
declare sub set_camera_FPC ( Player as PlayerType, Camera as CameraType )
declare sub set_camera_TPC ( Player as PlayerType, Camera as CameraType )
declare sub set_camera_TPC2 ( Player as PlayerType, Camera as CameraType )
declare Sub matrix_rotate_axis( m() as single, BYVAL angle AS SINGLE,_
BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE )
declare Sub matrix_transformVector( m() as single, BYREF v as Vector3d )
declare Sub player_rotate_view2 (Byref Camera as CameraType, byval angle as single,_
byval x as single, byval y as single, byval z as single)
declare sub npc_rotate_spherical(Npc as NpcType)
declare sub npc_init(Npc as NpcType)
declare sub npc_update (Npc() as NpcType)
'*******************************************************************************************
'Main code
'*******************************************************************************************
dim shared scaleValue as single
dim Shared Player as PlayerType
dim Shared Camera as CameraType
dim shared roll_angle as integer
dim shared current_camera as integer
dim shared Npc(Max_NPC) as NpcType
roll_angle = 0
randomize timer
dim vpage as SDL_Surface ptr 'The screen we want to draw to
dim Finished as integer 'Quit or not?
Init_GL_SDL vpage 'init GL SDL stuff
'Quadric stuff
'Intialize quadric pointers
'Share through modules
dim shared qobj_sphere as GLUquadricObj ptr
'Load quadric pointers
qobj_sphere = gluNewQuadric
'Sphere
gluQuadricDrawStyle qobj_sphere, GLU_LINE
gluQuadricNormals qobj_sphere, GLU_NONE
dim k as ubyte ptr
Dim Frames as integer
dim fps as single
dim t as single
dim stime as single
dim time_start as integer
dim i as integer
for i = 0 to Ubound(Npc)
npc_init ( Npc(i) )
Next i
player_set_position Player, 0, -7, 0, 0, -7, 1, 0, 1, 0
Player.m_Up.x = 0
Player.m_Up.y = 1
Player.m_Up.z = 0
Player.m_NewV.x = SCR_WIDTH \ 2
Player.m_NewV.y = SCR_HEIGHT \ 2
current_camera = E_TPC '3rd person
Camera.m_mode = E_TPC '3rd person
Finished = 0 'set finished to false
do
time_start = SDL_GetTicks()
SDL_GetEvents(Finished) 'handle events
Player.m_Roll = roll_angle
for i = 0 to Ubound(Npc)
npc_rotate_spherical ( Npc(i) )
Next i
Camera.m_mode = current_camera
'player_setview_by_mouse Player
player_setview Player
k = SDL_GetKeyState(0)
if k[SDLK_ESCAPE] then
finished = -1
end if
if k[SDLK_UP] then
player_move Player, CAM_SPEED
end if
if k[SDLK_DOWN] then
player_move Player, -CAM_SPEED
end if
if k[SDLK_RIGHT] then
player_strafe Player, CAM_SPEED
end if
if k[SDLK_LEFT] then
player_strafe Player, -CAM_SPEED
end if
if k[SDLK_W] then
player_move Player, CAM_SPEED
end if
if k[SDLK_S] then
player_move Player, -CAM_SPEED
end if
if k[SDLK_A] or k[SDLK_DELETE] then
Player.m_NewV.x = Player.m_NewV.x - 13
end if
if k[SDLK_D] or k[SDLK_INSERT] then
Player.m_NewV.x = Player.m_NewV.x + 13
end if
if k[SDLK_Q] or k[SDLK_PAGEUP] then
Player.m_NewV.y = Player.m_NewV.y - 13
end if
if k[SDLK_Z] or k[SDLK_PAGEDOWN] then
Player.m_NewV.y = Player.m_NewV.y + 13
end if
if k[SDLK_X] or k[SDLK_HOME] then
roll_angle = roll_angle + 1
End if
if k[SDLK_C] or k[SDLK_END] then
roll_angle = roll_angle - 1
End if
if k[SDLK_1] then
current_camera = E_FPC
End if
if k[SDLK_2] then
current_camera = E_TPC
End if
if k[SDLK_3] then
current_camera = E_TPC2
End if
frames = frames + 1
t = (SDL_GetTicks() * 0.001) - stime
SDL_WM_SetCaption "Pos x: " + str$(Player.m_Position.x) + _
"y: " + str$(Player.m_Position.y) + _
"z: " + str$(Player.m_Position.z) + _
" Target x: " + str$(Player.m_Target.x) + _
"y: " + str$(Player.m_Target.y) + _
"z: " + str$(Player.m_Target.z) + _
" Roll: " + str$(Player.m_Roll)_
, ""
if t > 4 then
'SDL_WM_SetCaption "Frames per sec:" + str$(Frames/t), ""
stime = (SDL_GetTicks() * 0.001)
frames = 0
end if
draw_scene 'Draw something
while(SDL_GetTicks() < time_start + 16): wend
SDL_GL_SwapBuffers 'Flip to screen
SDL_PumpEvents 'force an event queue update(input, etc)
loop until Finished
gluDeleteQuadric qObj_sphere
SDL_Quit 'quit SDL
end
'*******************************************************************************************
'SUBS/FUNKS
'*******************************************************************************************
'*******************************************************************************************
'Initializes GL+SDL
'Params: SDLscreen pointer to GL/SDL context to draw to
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_ShowCursor SDL_DISABLE
SDL_WM_SetCaption "Sdl Template", "" '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 = 500 '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 qui the proggie
Sub SDL_GetEvents(EscapeVal as Integer)
'SDL event is type in the SDL inc directory
dim event as SDL_Event
'poll events
while( SDL_PollEvent ( @event ) )
select case event.type
case SDL_KEYDOWN: 'if a key is pressed quit proggie
'EscapeVal = -1
case SDL_MOUSEBUTTONDOWN:
end select
wend
End Sub
'*******************************************************************************************
'Draw to our open GL screen
Sub draw_scene()
select case Camera.m_mode
case E_FPC
set_camera_FPC Player, Camera
case E_TPC
set_camera_TPC Player, Camera
case E_TPC2
set_camera_TPC2 Player, Camera
case else
end select
'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
glPushMatrix
glLoadIdentity
'// Give openGL our camera position, then camera view, then camera up vector
gluLookAt Camera.m_Position.x, Camera.m_Position.y, Camera.m_Position.z,_
Camera.m_Target.x, Camera.m_Target.y, Camera.m_Target.z,_
Camera.m_Up.x, Camera.m_Up.y, Camera.m_Up.z
Render_grid -8, 64
Render_grid 8, 64
npc_update Npc()
glColor3f 1.0, 1.0, 1.0
glTranslatef Player.m_Position.x, Player.m_Position.y, Player.m_Position.z
gluSphere qobj_sphere, 0.75, 25, 20 'draw sphere
glPopMatrix
glFlush
end sub
sub Render_grid(byval y as integer, byval scale as single)
dim grid_line as GLfloat
dim grid as integer
grid_line = -scale
glBegin GL_LINES
for grid = 0 to scale * 2
glColor3f 0.0, 1.0, 0.0
glVertex3f grid_line + Grid, y, -scale
glVertex3f grid_line + Grid, y, scale
glVertex3f -scale, y, grid_line + Grid
glVertex3f scale, y, grid_line + Grid
next grid
glEnd
end sub
'//*****************************************************************************************
'//*****************************************************************************************
'CAMERA STUFF
'//*****************************************************************************************
'//*****************************************************************************************
sub vector_cross (v1 as vector3d, v2 as vector3d, vout as vector3d)
vout.x = (v1.y * v2.z) - (v2.y * v1.z)
vout.y = (v1.z * v2.x) - (v2.z * v1.x)
vout.z = (v1.x * v2.y) - (v2.x * v1.y)
end sub
function vector_magnitude(v as vector3d) as single
dim mag as single
mag = sqr(v.x * v.x + v.y * v.y + v.z * v.z)
if mag = 0 then mag = 1
vector_magnitude = mag
end function
sub vector_normalize (v as vector3d)
dim mag as single
mag = vector_magnitude(v)
v.x = v.x / mag
v.y = v.y / mag
v.z = v.z / mag
end sub
sub vector_add (v1 as vector3d, v2 as vector3d, vout as vector3d)
vout.x = v1.x + v2.x
vout.y = v1.y + v2.y
vout.z = v1.z + v2.z
end sub
sub vector_sub (v1 as vector3d, v2 as vector3d, vout as vector3d)
vout.x = v1.x - v2.x
vout.y = v1.y - v2.y
vout.z = v1.z - v2.z
end sub
'
sub player_set_position(Byref Player as PlayerType, _
byval px as single, byval py as single, byval pz as single,_
byval vx as single, byval vy as single, byval vz as single,_
byval ux as single, byval uy as single, byval uz as single)
Player.m_Position.x = px
Player.m_Position.y = py
Player.m_Position.z = pz
Player.m_Target.x = vx
Player.m_Target.y = vy
Player.m_Target.z = vz
Player.m_Up.x = ux
Player.m_Up.y = uy
Player.m_Up.z = uz
end sub
Sub player_setview( Player as PlayerType)
const MID_X = SCR_WIDTH / 2
const MID_Y = SCR_HEIGHT / 2
dim d_x as integer, d_y as integer
dim angle_x as single
dim angle_y as single
dim angle_z as single
static old_roll as single
vector_normalize Player.m_Up
d_x = Player.m_NewV.x
d_y = Player.m_NewV.y
Player.m_OldV.x = Player.m_NewV.x
Player.m_OldV.y = Player.m_NewV.y
Player.m_NewV.x = MID_X
Player.m_NewV.y = MID_Y
angle_x = (MID_X - d_x) / 50.0
angle_y = (MID_Y - d_y) / 50.0
angle_z = old_roll - Player.m_Roll
dim mat(15) as single
dim v_right as vector3d
dim v_forward as vector3d
v_forward.x = Player.m_Target.x - Player.m_Position.x
v_forward.y = Player.m_Target.y - Player.m_Position.y
v_forward.z = Player.m_Target.z - Player.m_Position.z
'r = f x u
vector_cross v_forward , Player.m_Up, v_right
vector_normalize v_right
'rotate aound the right vector
if angle_y <> 0 then
matrix_rotate_axis mat(), angle_y * RAD_FACTOR, v_right.x, v_right.y, v_right.z
matrix_transformVector mat() , v_forward
matrix_transformVector mat() , Player.m_Up
end if
'up vector rotation
if angle_x <> 0 then
matrix_rotate_axis mat(), angle_x * RAD_FACTOR, Player.m_Up.x, Player.m_Up.y, Player.m_Up.z
matrix_transformVector mat() , v_forward
matrix_transformVector mat() , Player.m_Up
end if
'rotate around the forward vector
if angle_z <> 0 then
matrix_rotate_axis mat(), angle_z * RAD_FACTOR , v_forward.x, v_forward.y , v_forward.z
matrix_transformVector mat() , v_forward
matrix_transformVector mat() , Player.m_Up
end if
old_roll = Player.m_Roll
Player.m_Target.x = Player.m_Position.x + v_forward.x
Player.m_Target.y = Player.m_Position.y + v_forward.y
Player.m_Target.z = Player.m_Position.z + v_forward.z
end sub
Sub player_move(Byref Player as PlayerType, byval speed as single)
' Get our view vector (The direciton we are facing)
dim v_forward as vector3d
v_forward.x = Player.m_Target.x - Player.m_Position.x
v_forward.y = Player.m_Target.y - Player.m_Position.y
v_forward.z = Player.m_Target.z - Player.m_Position.z
vector_normalize v_forward
Player.m_Position.x = Player.m_Position.x + v_forward.x * speed
Player.m_Position.y = Player.m_Position.y + v_forward.y * speed
Player.m_Position.z = Player.m_Position.z + v_forward.z * speed
Player.m_Target.x = Player.m_Target.x + v_forward.x * speed
Player.m_Target.y = Player.m_Target.y + v_forward.y * speed
Player.m_Target.z = Player.m_Target.z + v_forward.z * speed
end sub
Sub player_strafe(Byref Player as PlayerType, byval speed as single)
' Get our view vector (The direciton we are facing)
dim v_forward as vector3d
dim v_right as vector3d
v_forward.x = Player.m_Target.x - Player.m_Position.x
v_forward.y = Player.m_Target.y - Player.m_Position.y
v_forward.z = Player.m_Target.z - Player.m_Position.z
'get the right vector so for moving left or right
'normalizing it to make our movements scalable
vector_cross v_forward , Player.m_Up, v_right
vector_normalize v_right
'strafe right or left depending on the value of the speed
Player.m_Position.x = Player.m_Position.x + v_right.x * speed
Player.m_Position.y = Player.m_Position.y + v_right.y * speed
Player.m_Position.z = Player.m_Position.z + v_right.z * speed
'unless you want to "lock" your target you should also update
'the target vector
'try to Rem the following lines just for kicks
'hint: this could be used for 3rd person cams
Player.m_Target.x = Player.m_Target.x + v_right.x * speed
Player.m_Target.y = Player.m_Target.y + v_right.y * speed
Player.m_Target.z = Player.m_Target.z + v_right.z * speed
end sub
sub set_camera_FPC ( Player as PlayerType, Camera as CameraType )
Camera.m_Position.x = Player.m_Position.x
Camera.m_Position.y = Player.m_Position.y
Camera.m_Position.z = Player.m_Position.z
Camera.m_Target.x = Player.m_Target.x
Camera.m_Target.y = Player.m_Target.y
Camera.m_Target.z = Player.m_Target.z
'set camera up
Camera.m_Up.x = Player.m_Up.x
Camera.m_Up.y = Player.m_Up.y
Camera.m_Up.z = Player.m_Up.z
end sub
'standard 3rd person cam (for wing commander type games)
sub set_camera_TPC ( Player as PlayerType, Camera as CameraType )
'get camera target by getting the players position
Camera.m_Target.x = Player.m_Position.x
Camera.m_Target.y = Player.m_Position.y
Camera.m_Target.z = Player.m_Position.z
'set camera up
Camera.m_Up.x = Player.m_Up.x
Camera.m_Up.y = Player.m_Up.y
Camera.m_Up.z = Player.m_Up.z
dim f as vector3d
dim r as vector3d
dim u as vector3d
'get forward vector
f.x = Player.m_Target.x - Player.m_Position.x
f.y = Player.m_Target.y - Player.m_Position.y
f.z = Player.m_Target.z - Player.m_Position.z
'up
u.x = Player.m_Up.x
u.y = Player.m_Up.y
u.z = Player.m_Up.z
'get right
vector_cross f , Player.m_Up, r
'normalize everything
vector_normalize f
vector_normalize r
vector_normalize u
'set the camera just behind the ball 8 units
Camera.m_Position.x = Player.m_Position.x - (f.x * 8)
Camera.m_Position.y = Player.m_Position.y - (f.y * 8)
Camera.m_Position.z = Player.m_Position.z - (f.z * 8)
end sub
'Mario kart, GTA style camera
sub set_camera_TPC2 ( Player as PlayerType, Camera as CameraType )
'get camera target by getting the players position
Camera.m_Target.x = Player.m_Position.x
Camera.m_Target.y = Player.m_Position.y
Camera.m_Target.z = Player.m_Position.z
'set camera up
Camera.m_Up.x = Player.m_Up.x
Camera.m_Up.y = Player.m_Up.y
Camera.m_Up.z = Player.m_Up.z
dim f as vector3d
dim r as vector3d
dim u as vector3d
'get forward vector
f.x = Player.m_Target.x - Player.m_Position.x
f.y = Player.m_Target.y - Player.m_Position.y
f.z = Player.m_Target.z - Player.m_Position.z
'up
u.x = Player.m_Up.x
u.y = Player.m_Up.y
u.z = Player.m_Up.z
'get right
vector_cross f , Player.m_Up, r
'normalize everything
vector_normalize f
vector_normalize r
vector_normalize u
dim mat(15) as single
'rotate forward pos on perpendicular axis to itself
matrix_rotate_axis mat(), -15 * RAD_FACTOR , r.x, r.y, r.z
matrix_transformVector mat() , f
'set the camera just behind the ball 8 units
Camera.m_Position.x = Player.m_Position.x - (f.x * 8)
Camera.m_Position.y = Player.m_Position.y - (f.y * 8)
Camera.m_Position.z = Player.m_Position.z - (f.z * 8)
end sub
'standard axis angle rotation
'derived from paul bourkes article
Sub matrix_rotate_axis( m() as single, BYVAL angle AS SINGLE,_
BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE )
dim sa as single
dim ca as single
sa = sin(angle)
ca = cos(angle)
dim recip_leng as single
recip_leng = 1 / sqr(x*x + y*y + z*z)
x = x * recip_leng
y = y * recip_leng
z = z * recip_leng
m(0) = ca + (1-ca) * x * x 'x1
m(1) = (1-ca) * x*y + sa*z 'x2
m(2) = (1-ca) * x*z - sa*y 'x3
m(3) = 0 'w1
m(4) = (1-ca) * y*x - sa*z 'y1
m(5) = ca + (1-ca) * y * y 'y2
m(6) = (1-ca) * y*z + sa*x 'y3
m(7) = 0 'w2
m(8) = (1-ca) * z*x + sa*y 'z1
m(9) = (1-ca) * y*z - sa*x 'z2
m(10) = ca + (1-ca) * z * z 'z3
m(11) = 0 'w3
m(12) = 0 'tx
m(13) = 0 'ty
m(14) = 0 'tz
m(15) = 1 'w4
End Sub
Sub matrix_transformVector( m() as single, BYREF v as Vector3d )
'transforms a vector with the matrix m
dim x as single
dim y as single
dim z as single
x = v.x
y = v.y
z = v.z
v.x = x * m(0) + y * m(4) + z * m(8)
v.y = x * m(1) + y * m(5) + z * m(9)
v.z = x * m(2) + y * m(6) + z * m(10)
End Sub
sub draw_axis ()
'draws the wopld axes
dim up as vector3d
dim fwd as vector3d
dim rite as vector3d
up.x = 0
up.y = 1
up.z = 0
fwd.x = 0
fwd.y = 0
fwd.z = 1
rite.x = 1
rite.y = 0
rite.z = 0
glBegin GL_LINES
glColor3f 0, 0, 1 'blue
glVertex3f 0, 0, 0
glVertex3f up.x, up.y*64, up.z
glColor3f 1, 0, 1 'purple
glVertex3f 0, 0, 0
glVertex3f fwd.x, fwd.y , fwd.z *64
glColor3f 1, 0, 0 'red
glVertex3f 0, 0, 0
glVertex3f rite.x *64, rite.y, rite.z
glEnd
end sub
sub npc_rotate_spherical(Npc as NpcType)
with Npc
.theta = (.theta + 3) mod 360
.phi = (.phi + 3) mod 360
end with
end sub
sub npc_init(Npc as NpcType)
with Npc
.theta = int(rnd * 360)
.phi = int(rnd * 360)
.x = -32 + int(rnd * 64)
.y = -4 + int(rnd * 8)
.z = -32 + int(rnd * 64)
.radius = .2 + int(rnd * 2)
.rot_radius = 1 + int(rnd * 5)
.r = rnd
.g = rnd
.b = rnd
end with
end sub
sub npc_update (Npc() as NpcType)
dim i as integer
dim dx as single
dim dy as single
dim dz as single
dim stheta as single
dim sphi as single
for i = 0 to Ubound(Npc)
With Npc(i)
sphi = .phi * PI / 180.0
stheta = .theta * PI / 180.0
dx = sin(sphi) * cos(stheta) * .rot_radius
dy = sin(sphi) * sin(stheta) * .rot_radius
dz = cos(sphi) * .rot_radius
glPushmatrix
glColor3f .r, .g, .b
glTranslatef .x + dx, .y + dy, .z + dz
gluSphere qobj_sphere, .radius, 25, 20 'draw sphere
glPopMatrix
end with
Next i
end sub