3D Space movement in OpenGL

User projects written in or related to FreeBASIC.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

3D Space movement in OpenGL

Post by axipher »

Hey everyone, I've noticed that there aren't any commercial games out there that are great space shooters without being super graphic intensive, so I set out to explore space in OpenGL.

Let me first say I used aleofjax's example of "6 DOF in OGL" in this thread:

http://www.freebasic.net/forum/posting. ... ly&t=12588

And just modified the control slightly and expanded on it to implement a ship object which I'm adding drawing routines for in a future release. So far the model loader loaders .dxf's quite nicely. I also added a much larger star field and didn't include the custom star model I have so I also used aleofjax's method for showing stars in my first attempts. My space universe now uses a basic triangular pyramid. I am currently working on adding bullets but I am having a very hard time with them. Right now the bullet is a red cube and Left-Clicking fires it off, but the vectors for it are far from working properly, maybe someone can give me a hint. I have finally added the beginnings of a pause menu which once completed will also double as the main menu. I need to now figure out the easiest way to implement printing. I have now added spherical planets with textures. Its coming along in the direction I want to and a lot faster than I thought it would. Please give any advice of constructive criticism you can.

I put the source below of the last working version without textures. I d this for some people to easily try the code quickly. The updated version will be in the ZIP file with a binary and the source. This ZIP file is accessible through the link at the end of the post.

TO-DO:
- Pause Menu
- Bullet Vector
- Larger basic polygon for planets
- Map file for planets (stars will remain random)
- Main Menu (after pause menu)
- Printing

The controls are as follows:

W/S = Forward/Reverse Thrust
Left SHIFT + W = Boosted Thrust Forward
A/D = Strafe Left/Right
R/F = Rise/Fall
Q/E = Rotate Counter-Clockwise/Clockwise
SPACE = Movement Brake
CONTROL = Rotation Brake
Mouse X/Y = Turn camera
Mouse Left-Click = Fire Bullet
P = Pause/Unpause
ESC = Quit

3d_space_scr.bas Download ZIP file for latest, this version is last standalone version without images!!!

Code: Select all

/' Axipher 2009
W = Accelerate
S = Deccelerate
Mouse = Angel
A/D = Strafe
R/F = Up/Down
space = Brake
Insert = reset
'/



' Randomize the randim number generator based on the timer
randomize timer



' TRUE/FALSE
const FALSE = 0
const TRUE  = -1



' Define
#define starcolour 1.0,0.75,0.0,1.0



' Files to include
#include once "fbgfx.bi"
#include once "gl\gl.bi"
#include once "gl\glu.bi"
#include once "gl\glfw.bi"
#include once "draw_gl_.bi"



enum object_type
  star = 1
  projectile = 2
  ship = 4
end enum

enum state_data
  normal = 0
  paused = 1
  mainmenu = 2
  credits = 3
end enum



' Some constants
const PI = 4 * atn(1)
const RAD = PI/180
const SHIP_ACC = 0.1
const SHIP_DBL_ACC = SHIP_ACC * 2
const SHIP_STRAFE = 0.1
const SHIP_RISE = 0.1
const SHIP_ROT = 0.1
const SHIP_DEC = 0.995
const SHIP_BRAKE = 0.97
const BULLET_SPEED = 10



' A few shared variables
dim shared as integer sx,sy,sf,sx2,sy2,keypressed,cursorvis,glx1,glx2,gly1,gly2
dim as double mouse_sensitivity = 0.6,mouse_threshold = 5
dim as double nextframe = timer + 1
dim shared as integer state



type mousedata
  as integer x,ox,dx,px
  as double cx
  as integer y,oy,dy,py
  as double cy
  as integer b,w,pb,pw
  
  declare constructor()
  
  declare sub update(vis as integer = 0)
end type

constructor mousedata()

end constructor

sub mousedata.update(vis as integer = 0)
  if state = normal then
    ox = x
    oy = y
    
    getmouse x,y,w,b
    
    dx = (x - ox)
    dy = (y - oy)
    
    cx = x - sx2
    cy = y - sy2
  
    setmouse sx2,sy2,0
  elseif state = paused then
    getmouse px,py,pw,pb
    setmouse ,,1
  end if
end sub



type vect6d
  u as single
  v as single
  w as single
  x as single
  y as single
  z as single
end type



type vector3d
  as double x,ux
  as double y,uy
  as double z,uz
  
  declare constructor()
  
  declare property x2() as double
  declare property y2() as double
  declare property z2() as double
end type

constructor vector3d()

end constructor

property vector3d.x2() as double
return (x + ux)
end property

property vector3d.y2() as double
return (y + uy)
end property

property vector3d.z2() as double
return (z + uz)
end property



type quaternion
  w as single
  x as single
  y as single
  z as single
  
  declare sub normalize()
  declare function conj() as quaternion
end type       

sub quaternion.normalize()
  dim as single mag = sqr(w*w+x*x+y*y+z*z)
  w /= mag
  x /= mag
  y /= mag
  z /= mag
end sub

function quaternion.conj() as quaternion
  return type<quaternion>( w, -x, -y, -z )
end function

Operator * (lhs as quaternion, rhs as quaternion) as quaternion
return type<quaternion>( lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z, _
lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y, _
lhs.w * rhs.y - lhs.x * rhs.z + lhs.y * rhs.w + lhs.z * rhs.x, _
lhs.w * rhs.z + lhs.x * rhs.y - lhs.y * rhs.x + lhs.z * rhs.w )
end Operator



type camera
  'position
  x as single
  y as single
  z as single
  
  'look vector
  lx as single
  ly as single
  lz as single
  
  'up vector
  ux as single
  uy as single
  uz as single
  
  'right vector
  rx as single
  ry as single
  rz as single
  
  FOV as single
  aspect as single
  nearClip as single
  farClip as single
  
  declare sub roll( a as single )
  declare sub pitch( a as single )
  declare sub yaw( a as single )
  declare sub advance( d as single )
  declare sub strafe( d as single )
  declare sub rise( d as single )
end type

sub camera.advance( d as single )
  dim as single xt, yt, zt
  xt = (lx - x) * d
  yt = (ly - y) * d
  zt = (lz - z) * d
  x += xt
  y += yt
  z += zt
  ux += xt
  uy += yt
  uz += zt
  rx += xt
  ry += yt
  rz += zt
  lx += xt
  ly += yt
  lz += zt
end sub

sub camera.strafe( d as single )
  dim as single xt, yt, zt
  xt = (rx - x) * d
  yt = (ry - y) * d
  zt = (rz - z) * d
  x += xt
  y += yt
  z += zt
  ux += xt
  uy += yt
  uz += zt
  rx += xt
  ry += yt
  rz += zt
  lx += xt
  ly += yt
  lz += zt
end sub

sub camera.rise( d as single )
  dim as single xt, yt, zt
  xt = (ux - x) * d
  yt = (uy - y) * d
  zt = (uz - z) * d
  x += xt
  y += yt
  z += zt
  ux += xt
  uy += yt
  uz += zt
  rx += xt
  ry += yt
  rz += zt
  lx += xt
  ly += yt
  lz += zt
end sub

sub camera.roll( a as single )
  dim as quaternion qUp = type<quaternion>(0, ux - x, uy - y, uz - z)
  dim as quaternion qRight = type<quaternion>(0, rx - x, ry - y, rz - z)
  dim as quaternion qRot = type<quaternion>(cos(a * rad/2), (lx - x) * sin(a * rad/2), (ly - y) * sin(a * rad/2), (lz - z) * sin(a * rad/2))
  
  dim as quaternion W = qRot * qUp * qRot.conj()
  ux = W.x + x
  uy = W.y + y
  uz = W.z + z
  W = qRot * qRight * qRot.conj()
  rx = W.x + x
  ry = W.y + y
  rz = W.z + z
end sub

sub camera.pitch( a as single )
  dim as quaternion qUp = type<quaternion>(0, ux - x, uy - y, uz - z)
  dim as quaternion qLook = type<quaternion>(0, lx - x, ly - y, lz - z)
  dim as quaternion qRot = type<quaternion>(cos(a * rad/2), (rx - x) * sin(a * rad/2), (ry - y) * sin(a * rad/2), (rz - z) * sin(a * rad/2))
  
  dim as quaternion W = qRot * qUp * qRot.conj()
  ux = W.x + x
  uy = W.y + y
  uz = W.z + z
  W = qRot * qLook * qRot.conj()
  lx = W.x + x
  ly = W.y + y
  lz = W.z + z
end sub

sub camera.yaw( a as single )
  dim as quaternion qRight = type<quaternion>(0, rx - x, ry - y, rz - z)
  dim as quaternion qLook = type<quaternion>(0, lx - x, ly - y, lz - z)
  dim as quaternion qRot = type<quaternion>(cos(a * rad/2), (ux - x) * sin(a * rad/2), (uy - y) * sin(a * rad/2), (uz - z) * sin(a * rad/2))
  
  dim as quaternion W = qRot * qRight * qRot.conj()
  rx = W.x + x
  ry = W.y + y
  rz = W.z + z
  W = qRot * qLook * qRot.conj()
  lx = W.x + x
  ly = W.y + y
  lz = W.z + z
end sub



type object
  as vector3d d,l,v
  as object_type ot
  as double scale
  as integer alive
  
  declare constructor()
  
  declare sub update()
  declare sub draw()
end type

constructor object()
d.x = 0
d.y = 0
d.z = 0
l.x = 0
l.y = 0
l.z = 0
v.x = 0
v.y = 0
v.z = 0
ot = star
scale = 1
end constructor

sub object.update()
  if alive then
    d.x += v.x
    d.y += v.y
    d.z += v.z
  end if
end sub

sub object.draw()
  if alive then
    select case ot
    case star
      draw_gl_star(d.x,d.y,d.z,scale)
    case projectile
      draw_gl_projectile(d.x,d.y,d.z)
    case ship
      draw_gl_ship
    end select
  end if
end sub

type button
  as integer x,y,sx,sy
  as double glx,gly,glsx,glsy
  as string label
  as double r,g,b,t
  
  declare constructor()
  declare constructor(_glx as double,_gly as double,_glsx as double,_glsy as double)
  
  declare sub draw(m as mousedata)
end type

constructor button()
  
end constructor

constructor button(_glx as double,_gly as double,_glsx as double,_glsy as double)
  glx = _glx
  gly = _gly
  glsx = _glsx
  glsy = _glsy
  x = sx2 + ((glx / glx2) * sx2)
  y = sy2 + ((gly / gly2) * sy2)
  sx = ((glsx / glx2) * sx2)
  sy = ((glsy / gly2) * sy2)
  r = 0
  g = 1
  b = 0
end constructor

sub button.draw(m as mousedata)
  if m.px >= x andalso m.px <= (x + sx) andalso m.py >= y andalso m.py <= (y + sy) then
    t = 0.9
  else
    t = 0.5
  end if
  glcolor4f r,g,b,t
  glbegin gl_quads
  glvertex3f glx,gly,1
  glvertex3f glx + glsx,gly,1
  glvertex3f glx + glsx,gly + glsy,1
  glvertex3f glx,gly + glsy,1
  glend
end sub



' Open a console window
dim as integer cns
cns = freefile
open cons for output as #cns

' Get current screen resolution
screeninfo sx,sy
sf = fb.gfx_opengl or fb.gfx_multisample or fb.gfx_fullscreen
'sf = fb.gfx_opengl or fb.gfx_multisample
'sx = 1024
'sy = 600

' Calculate mid points
sx2 = sx / 2
sy2 = sy / 2

' Calculate 2D OpenGL coords
glx1 = -1.0 * (sx2 / sy2)
glx2 = 1.0 * (sx2 / sy2)
gly1 = -1.0
gly2 = 1.0

' Initialize the screen
'screenres sx,sy,32,,fb.gfx_fullscreen or fb.gfx_opengl or fb.gfx_multisample
screenres sx,sy,32,,sf

' Variable for mouse data
dim as mousedata mouse

' Objects for ship and one projectile
dim as object t1,b1

' Variable for the camera
dim shared as camera cam,pmenu

' Store the timer in a variable
dim as double lastFrame = timer

' Variables for calculations
dim as double xv, yv, zv, p, r, y

' Initialize the camera
cam.x = 0
cam.y = 0
cam.z = 0

cam.lx = 0
cam.ly = 0
cam.lz = -1

cam.ux = 0
cam.uy = 1
cam.uz = 0

cam.rx = 1
cam.ry = 0
cam.rz = 0

cam.FOV = 45
cam.Aspect = sx/sy
cam.nearClip = .01
cam.farClip = 30000

' Set ship location to 0,0,0 and looking into the screen
t1.d.x = 0
t1.d.y = 0
t1.d.z = 0
t1.l.x = 0
t1.l.y = 0
t1.l.z = 1
t1.v.x = 0
t1.v.y = 0
t1.v.z = 0

declare sub init_3D_gl()
declare sub init_2D_gl()

init_3D_gl

' Make a list of stars
dim as integer starcount = 5000
dim as object ptr starsptr
starsptr = allocate(sizeof(object) * starcount)
for i as integer = 0 to starcount - 1
  starsptr[i].d.x = (rnd * 3000) + (rnd * 2000) + (rnd * 1000) - 3000
  starsptr[i].d.y = (rnd * 3000) + (rnd * 2000) + (rnd * 1000) - 3000
  starsptr[i].d.z = (rnd * 3000) + (rnd * 2000) + (rnd * 1000) - 3000
  starsptr[i].ot = star
  starsptr[i].scale = 10
  starsptr[i].alive = true
next

' make a button object
dim as button but1
but1 = button(glx1 + 0.02,gly1 + 0.02,0.5,0.2)

' Init mouse
mouse.update

' Main loop
do
  ' Update mouse data
  mouse.update
  
  ' Frame limiter
  'Sleep (1000 / 30) - ((Timer - lastFrame) / 1000), 1
  'lastFrame = Timer
  'sleep 1,1
  while timer < nextframe
    sleep 1,1
  wend
  nextframe = timer + (1 / 60)
  
  ' Reset keypressed
  if multikey(fb.sc_p) = 0 then keypressed = false
  
  if state = paused then
    
    ' Pause game
    if multikey(fb.sc_p) and keypressed = false then
      state = normal
      cursorvis = false
      keypressed = true
      setmouse sx2,sy2,0
    end if    
  end if
  
  if state = normal then
    
    ' Pause game
    if multikey(fb.sc_p) and keypressed = false then
      state = paused
      cursorvis = true
      keypressed = true
    end if
    
    windowtitle "Normal"
    
    ' A/D strafe left and right based on current direction
    if multikey(fb.sc_a) and multikey(fb.sc_d) = 0 then
      xv += (cam.rx - cam.x) * SHIP_STRAFE
      yv += (cam.ry - cam.y) * SHIP_STRAFE
      zv += (cam.rz - cam.z) * SHIP_STRAFE
    end if
    if multikey(fb.sc_d) and multikey(fb.sc_a) = 0 then
      xv -= (cam.rx - cam.x) * SHIP_STRAFE
      yv -= (cam.ry - cam.y) * SHIP_STRAFE
      zv -= (cam.rz - cam.z) * SHIP_STRAFE
    end if
    
    ' R/F move up and down based on current direction
    if multikey(fb.sc_r) and multikey(fb.sc_f) = 0 then
      xv -= (cam.ux - cam.x) * SHIP_RISE
      yv -= (cam.uy - cam.y) * SHIP_RISE
      zv -= (cam.uz - cam.z) * SHIP_RISE
    end if
    if multikey(fb.sc_f) and multikey(fb.sc_r) = 0 then
      xv += (cam.ux - cam.x) * SHIP_RISE
      yv += (cam.uy - cam.y) * SHIP_RISE
      zv += (cam.uz - cam.z) * SHIP_RISE
    end if
    
    ' W/S move forward or back depending on current direction
    if multikey(fb.sc_w) and multikey(fb.sc_s) = 0 then
      if multikey(fb.sc_lshift) then
        xv += (cam.lx - cam.x) * SHIP_DBL_ACC
        yv += (cam.ly - cam.y) * SHIP_DBL_ACC
        zv += (cam.lz - cam.z) * SHIP_DBL_ACC
      else
        xv += (cam.lx - cam.x) * SHIP_ACC
        yv += (cam.ly - cam.y) * SHIP_ACC
        zv += (cam.lz - cam.z) * SHIP_ACC
      end if
    end if
    if multikey(fb.sc_s) and multikey(fb.sc_w) = 0 then
      xv -= (cam.lx - cam.x) * SHIP_ACC
      yv -= (cam.ly - cam.y) * SHIP_ACC
      zv -= (cam.lz - cam.z) * SHIP_ACC
    end if
    
    ' Q/E to roll
    if multikey(fb.sc_q) and multikey(fb.sc_e) = 0 then
      r -= 2 * SHIP_ROT
    end if
    if multikey(fb.sc_e) and multikey(fb.sc_q) = 0 then
      r += 2 * SHIP_ROT
    end if
    if multikey(fb.sc_q) = 0 and multikey(fb.sc_e) = 0 then
      r *= 0.9
    end if
    
    ' Braking
    if multikey(fb.sc_space) then
      xv *= ship_brake
      yv *= ship_brake
      zv *= ship_brake
    end if
    
    ' Slow down rotation
    if multikey(fb.sc_CONTROL) then
      r *= ship_brake
      p *= ship_brake
      y *= ship_brake
    end if
    
    ' Mouse determines direction of acceleration to be affected by thrust
    ' Allowed to rotate fully without thrusting
    if abs(mouse.cx ) > mouse_threshold or abs(mouse.cy) > mouse_threshold then
      p += (mouse.cy * mouse_sensitivity) / 8 * SHIP_ROT
      y += (mouse.cx * mouse_sensitivity) / 8 * SHIP_ROT
    else
      p *= 0.9
      y *= 0.9
    end if
    
    ' Debug reset
    if multikey(fb.sc_insert) then
      xv = 0
      yv = 0
      zv = 0
      r = 0
      p = 0
      y = 0
      cam.x = 0
      cam.y = 0
      cam.z = 0
      cam.lx = 0
      cam.ly = 0
      cam.lz = -1
      cam.ux = 0
      cam.uy = 1
      cam.uz = 0
      cam.rx = 1
      cam.ry = 0
      cam.rz = 0
      cam.roll(r)
      cam.pitch(p)
      cam.yaw(y)
      t1.d.x = 0
      t1.d.y = 0
      t1.d.z = 0
      t1.l.x = 0
      t1.l.y = 0
      t1.l.z = -1
      t1.v.x = 0
      t1.v.y = 0
      t1.v.z = 0
    end if
    
    ' Natural decellearation
    xv *= ship_dec
    yv *= ship_dec
    zv *= ship_dec
    r *= ship_dec
    p *= ship_dec
    y *= ship_dec
    
    ' Adjust Camera
    cam.x += xv
    cam.y += yv
    cam.z += zv
    cam.lx += xv
    cam.ly += yv
    cam.lz += zv
    cam.rx += xv
    cam.ry += yv
    cam.rz += zv
    cam.ux += xv
    cam.uy += yv
    cam.uz += zv
    cam.roll(r)
    cam.pitch(p)
    cam.yaw(y)
    
    ' Clamp ship to camera
    t1.d.x = cam.x
    t1.d.y = cam.y
    t1.d.z = cam.z
    t1.l.x = cam.lx
    t1.l.y = cam.ly
    t1.l.z = cam.lz
    t1.v.x = cam.lx
    t1.v.y = cam.ly
    t1.v.z = cam.lz
    
    ' Fire projectile
    if mouse.b and 1 then
      b1 = object()
      b1.ot = projectile
      b1.d.x = cam.x
      b1.d.y = cam.y
      b1.d.z = cam.z
      b1.v.x = (cam.lx - cam.x) * BULLET_SPEED
      b1.v.y = (cam.ly - cam.y) * BULLET_SPEED
      b1.v.z = (cam.lz - cam.z) * BULLET_SPEED
      b1.alive = true
      b1.update
    else
      b1.update
    end if
    
  end if
  
  ' Reset OpenGL buffers
  glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
  glLoadIdentity
  
  ' Apply camera settings
  gluLookAt cam.x, cam.y, cam.z, cam.lx, cam.ly, cam.lz, cam.x - cam.ux, cam.y - cam.uy, cam.z - cam.uz
  
  'stars(i).x, stars(i).y + 0.5, stars(i).z + 0.5
  'stars(i).x - 0.5, stars(i).y - 0.5, stars(i).z - 0.5
  'stars(i).x + 0.5, stars(i).y - 0.5, stars(i).z - 0.5
  'stars(i).x, stars(i).y - 0.5, stars(i).z + 0.5
  
  ' Draw stars
  for i as integer = 0 to starcount - 1
    starsptr[i].draw
  next
  
  ' Draw bullet
  b1.draw
  
  ' Draw a 3D cartesian grid
'  glcolor3f 1,0,0
'  glbegin gl_lines
'  glvertex3f -1000,0,0
'  glvertex3f 1000,0,0
'  glEnd
'  glcolor3f 0,1,0
'  glbegin gl_lines
'  glvertex3f 0,-1000,0
'  glvertex3f 0,1000,0
'  glEnd
'  glcolor3f 0,0,1
'  glbegin gl_lines
'  glvertex3f 0,0,-1000
'  glvertex3f 0,0,1000
'  glEnd


  
  if state = paused then    
    windowtitle "Paused"
    
    init_2D_gl
    
    glcolor4f 0,0,0,0.5
    
    glbegin gl_quads
    glvertex3f glx1,gly1,1
    glvertex3f glx2,gly1,1
    glvertex3f glx2,gly2,1
    glvertex3f glx1,gly2,1
    glend
    
    glcolor4f 0.0, 1.0, 0.0, 0.9
    
    glbegin gl_line_strip
    glvertex3f glx1 + 0.01,gly1 + 0.01,1
    glvertex3f glx2 - 0.01,gly1 + 0.01,1
    glvertex3f glx2 - 0.01,gly2 - 0.01,1
    glvertex3f glx1 + 0.01,gly2 - 0.01,1
    glvertex3f glx1 + 0.01,gly1 + 0.01,1
    glend
    
    but1.draw(mouse)
    
    init_3D_gl
    
  end if
  
  ' Copy OpenGL buffer to screen
  flip
loop until multikey(fb.sc_escape)

deallocate(starsptr)

sub init_2D_gl()
  glViewport 0,0,sx,sy
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  glOrtho glx1, glx2, gly2, gly1, -5.0, 5.0
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glShadeModel GL_SMOOTH
  glClearColor 0.0, 0.0, 0.0, 1.0
  glClearDepth 1.0
  glClearAccum 0.0, 0.0, 0.0, 1.0
  glClear GL_ACCUM_BUFFER_BIT

  glEnable GL_DEPTH_TEST
  glDepthFunc GL_LEQUAL
  glEnable GL_BLEND
  glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
  glLineWidth 2.0
end sub

sub init_3D_gl()
  ' Initialize OpenGL
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective cam.fov, cam.aspect, cam.nearClip, cam.farClip
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glTexEnvf GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE
  glClearDepth 1.0
  glEnable GL_DEPTH_TEST
  glDepthFunc GL_LEQUAL
  glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
  glShadeModel GL_SMOOTH
  glClearColor 0.0, 0.0, 0.0, 1.0
  
  glPointSize 5
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  glLineWidth(5)
  glEnable(GL_LINE_SMOOTH)
end sub
draw_gl_.bi Download ZIP file for latest, this version is last standalone version without images!!!

Code: Select all

' draw_gl_... primitivessub draw_gl_cube(sidelength as double = 1,r as double = 1,g as double = 1,b as double = 1)

sub draw_gl_cube(sidelength as double = 1,r as double = 1,g as double = 1,b as double = 1)
  glBegin GL_QUADS
  glColor3f r, g, b
  glNormal3f 0.0, 0.0, 1.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / 2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / 2.0
  glNormal3f 1.0, 0.0, 0.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / -2.0
  glNormal3f 0.0, 0.0, -1.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / -2.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / -2.0
  glNormal3f -1.0, 0.0, 0.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / 2.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / 2.0
  glNormal3f 0.0, 1.0, 0.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / 2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / 2.0, sideLength / -2.0
  glNormal3f 0.0, -1.0, 0.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / 2.0
  glVertex3f sideLength / 2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / -2.0
  glVertex3f sideLength / -2.0, sideLength / -2.0, sideLength / 2.0
  glEnd
end sub

sub draw_gl_star(x as double,y as double,z as double,s as double)
  glbegin GL_TRIANGLES
  glcolor4f starcolour
  glVertex3f x, y + (0.5 * s), z
  glVertex3f x - (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  glVertex3f x + (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  
  glVertex3f x, y + (0.5 * s), z
  glVertex3f x - (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  glVertex3f x, y - (0.5 * s), z + (0.5 * s)
  
  glVertex3f x, y + (0.5 * s), z
  glVertex3f x + (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  glVertex3f x, y - (0.5 * s), z + (0.5 * s)
  
  glVertex3f x - (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  glVertex3f x + (0.5 * s), y - (0.5 * s), z - (0.5 * s)
  glVertex3f x, y - (0.5 * s), z + (0.5 * s)
  glend
end sub

sub draw_gl_projectile(x as double,y as double,z as double)
  glTranslatef x,y,z
  draw_gl_cube(.25,1,0,0)
  glTranslatef -x,-y,-z
end sub

sub draw_gl_ship
  
  end sub
http://www.mediafire.com/download.php?ktw2kmm2mgw
Last edited by axipher on Mar 24, 2009 4:10, edited 5 times in total.
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Post by relsoft »

I get a red screen of death.

As for the bullet vector, it's easy to calculate actually. All you have to do is find your forward vector, up vector, and right vector and you're set.

Say player is the player's pos and target is the target pos.

Code: Select all

forward = target - player
up = playerup
right = vector_cross(forward, right)
now:

Code: Select all

normalize(forward)
bulletvelocity = forward

UP and Right are used to draw(orient) bullet model in world space.

If it's just billboarded, you could just extract the modelview matrix and use it to draw your billboard like this:

Code: Select all

	glGetfloatv ( GL_MODELVIEW_MATRIX, @mat(0) )

	vright.x = mat(0)
	vright.y = mat(4)
	vright.z = mat(8)
	vup.x = mat(1)
	vup.y = mat(5)
	vup.z = mat(9)
	'billboard it
    point0.x = (-vRight.x - vUp.x) * QUAD_SCALE
	point0.y = (-vRight.y - vUp.y) * QUAD_SCALE
	point0.z = (-vRight.z - vUp.z) * QUAD_SCALE

    point1.x = ( vRight.x - vUp.x) * QUAD_SCALE
	point1.y = ( vRight.y - vUp.y) * QUAD_SCALE
	point1.z = ( vRight.z - vUp.z) * QUAD_SCALE

    point2.x = ( vRight.x + vUp.x) * QUAD_SCALE
	point2.y = ( vRight.y + vUp.y) * QUAD_SCALE
	point2.z = ( vRight.z + vUp.z) * QUAD_SCALE

    point3.x = (-vRight.x + vUp.x) * QUAD_SCALE
	point3.y = (-vRight.y + vUp.y) * QUAD_SCALE
	point3.z = (-vRight.z + vUp.z) * QUAD_SCALE

axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

The red is the bullet, just left-click and it will fire the bullet and should be normal, the bullets are buggy in general. As for the code, the movement is currently all based on vectors form the camera including distance, look vector, up vector, and right vector.
Dr_D
Posts: 2453
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

I added a v3d_normalize function, and modified the bullet launching code a bit. It should be ok now. Looking good, btw! :)

Code: Select all

/' Axipher 2009
W = Accelerate
S = Deccelerate
Mouse = Angel
A/D = Strafe
R/F = Up/Down
Space = Brake
Insert = Reset
'/



' Randomize the randim number generator based on the timer
randomize timer



' TRUE/FALSE
const FALSE = 0
const TRUE  = -1



' Files to include
#include once "fbgfx.bi"
#include once "gl\gl.bi"
#include once "gl\glu.bi"
#include once "gl\glfw.bi"
#include once "cube.bi"
#include once "draw_gl_.bi"



enum object_type
   star = 1
   projectile = 2
   ship = 4
end enum



' Some constants
const PI = 4 * atn(1)
const RAD = PI/180
const SHIP_ACC = 0.1
const SHIP_DBL_ACC = SHIP_ACC * 2
const SHIP_STRAFE = 0.1
const SHIP_RISE = 0.1
const SHIP_ROT = 0.1
const SHIP_DEC = 0.995
const SHIP_BRAKE = 0.97
const BULLET_SPEED = 1



' A few shared variables
dim shared as integer sx,sy,sx2,sy2
dim as double mouse_sensitivity = 0.6,mouse_threshold = 5



type mousedata
   as integer x,ox,dx
   as double cx
   as integer y,oy,dy
   as double cy
   as integer b
   
   declare constructor()
   
   declare sub update(vis as integer = 0)
end type

constructor mousedata()
   
end constructor

sub mousedata.update(vis as integer = 0)
   ox = x
   oy = y
   
   getmouse x,y,,b
   
   dx = (x - ox)
   dy = (y - oy)
   
   cx = x - sx2
   cy = y - sy2
   
   setmouse sx2,sy2,vis
end sub



Type vect6d
   u As Single
   v As Single
   w As Single
   x As Single
   y As Single
   z As Single
End Type



type vector3d
   as double x,ux
   as double y,uy
   as double z,uz
   
   declare constructor()
   
   declare property x2() as double
   declare property y2() as double
   declare property z2() as double
end type

constructor vector3d()
   
end constructor

property vector3d.x2() as double
   return (x + ux)
end property

property vector3d.y2() as double
   return (y + uy)
end property

property vector3d.z2() as double
   return (z + uz)
end property

sub v3d_normalize( byref v as vector3d )
    dim as double dist
    dist = sqr( v.x^2 + v.y^2 + v.z^2 )
    if dist = 0 then dist = 1
    v.x/=dist
    v.y/=dist
    v.z/=dist
end sub

Type quaternion
   w As Single
   x As Single
   y As Single
   z As Single
   
   Declare Sub normalize()
   Declare Function conj() As quaternion
End Type       
   
Sub quaternion.normalize()
   Dim As Single mag = Sqr(w*w+x*x+y*y+z*z)
   w /= mag
   x /= mag
   y /= mag
   z /= mag
End Sub

Function quaternion.conj() As quaternion
   Return Type<quaternion>( w, -x, -y, -z )
End Function

Operator * (lhs As quaternion, rhs As quaternion) As quaternion
   Return Type<quaternion>( lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z, _
                            lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y, _
                            lhs.w * rhs.y - lhs.x * rhs.z + lhs.y * rhs.w + lhs.z * rhs.x, _
                            lhs.w * rhs.z + lhs.x * rhs.y - lhs.y * rhs.x + lhs.z * rhs.w )
End Operator
       


Type camera
   'position
   x As Single
   y As Single
   z As Single
   
   'look vector
   lx As Single
   ly As Single
   lz As Single
   
   'up vector
   ux As Single
   uy As Single
   uz As Single
   
   'right vector
   rx As Single
   ry As Single
   rz As Single
   
   FOV As Single
   aspect As Single
   nearClip As Single
   farClip As Single
   
   Declare Sub roll( a As Single )
   Declare Sub pitch( a As Single )
   Declare Sub yaw( a As Single )
   Declare Sub advance( d As Single )
   Declare Sub strafe( d As Single )
   Declare Sub rise( d As Single )
End Type

Sub camera.advance( d As Single )
   Dim As Single xt, yt, zt
   xt = (lx - x) * d
   yt = (ly - y) * d
   zt = (lz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.strafe( d As Single )
   Dim As Single xt, yt, zt
   xt = (rx - x) * d
   yt = (ry - y) * d
   zt = (rz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.rise( d As Single )
   Dim As Single xt, yt, zt
   xt = (ux - x) * d
   yt = (uy - y) * d
   zt = (uz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.roll( a As Single )
   Dim As quaternion qUp = Type<quaternion>(0, ux - x, uy - y, uz - z)
   Dim As quaternion qRight = Type<quaternion>(0, rx - x, ry - y, rz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (lx - x) * Sin(a * rad/2), (ly - y) * Sin(a * rad/2), (lz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qUp * qRot.conj()
      ux = W.x + x
      uy = W.y + y
      uz = W.z + z
   W = qRot * qRight * qRot.conj()
      rx = W.x + x
      ry = W.y + y
      rz = W.z + z
End Sub

Sub camera.pitch( a As Single )
   Dim As quaternion qUp = Type<quaternion>(0, ux - x, uy - y, uz - z)
   Dim As quaternion qLook = Type<quaternion>(0, lx - x, ly - y, lz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (rx - x) * Sin(a * rad/2), (ry - y) * Sin(a * rad/2), (rz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qUp * qRot.conj()
      ux = W.x + x
      uy = W.y + y
      uz = W.z + z
   W = qRot * qLook * qRot.conj()
      lx = W.x + x
      ly = W.y + y
      lz = W.z + z
End Sub

Sub camera.yaw( a As Single )
   Dim As quaternion qRight = Type<quaternion>(0, rx - x, ry - y, rz - z)
   Dim As quaternion qLook = Type<quaternion>(0, lx - x, ly - y, lz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (ux - x) * Sin(a * rad/2), (uy - y) * Sin(a * rad/2), (uz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qRight * qRot.conj()
      rx = W.x + x
      ry = W.y + y
      rz = W.z + z
   W = qRot * qLook * qRot.conj()
      lx = W.x + x
      ly = W.y + y
      lz = W.z + z
End Sub



type object
   as vector3d d,l,v
   as object_type ot
   as double scale
   
   declare constructor()
   
   declare sub update()
   declare sub draw()
end type

constructor object()
   d.x = 0
   d.y = 0
   d.z = 0
   l.x = 0
   l.y = 0
   l.z = 0
   v.x = 0
   v.y = 0
   v.z = 0
   ot = star
   scale = 1
end constructor

sub object.update()
   d.x += v.x
   d.y += v.y
   d.z += v.z
end sub

sub object.draw()
    glPushMatrix()
   select case ot
   case star
      draw_gl_star(d.x,d.y,d.z,scale)
   case projectile
      draw_gl_projectile(d.x,d.y,d.z)
   case ship
      draw_gl_ship
   end select
   glPopMatrix()
end sub



' Open a console window
dim as integer cns
cns = freefile
open cons for output as #cns

' Get current screen resolution
screeninfo sx,sy
sx = 640
sy = 480

' Calculatemid points
sx2 = sx / 2
sy2 = sy / 2

' Initialize the screen
'screenres sx,sy,32,,fb.gfx_fullscreen or fb.gfx_opengl or fb.gfx_multisample
screenres sx,sy,32,,fb.gfx_opengl or fb.gfx_multisample

' Variable for mouse data
dim as mousedata mouse

' Objects for ship and one projectile
dim as object t1,b1

' Variable for the camera
Dim As camera cam

' Store the timer in a variable
Dim As double lastFrame = Timer

' Variables for calculations
Dim As double xv, yv, zv, p, r, y

' Initialize the camera
cam.x = 0
cam.y = 0
cam.z = 0

cam.lx = 0
cam.ly = 0
cam.lz = -1

cam.ux = 0
cam.uy = 1
cam.uz = 0

cam.rx = 1
cam.ry = 0
cam.rz = 0

cam.FOV = 45
cam.Aspect = sx/sy
cam.nearClip = .01
cam.farClip = 10000

' Set ship location to 0,0,0 and looking into the screen
t1.d.x = 0
t1.d.y = 0
t1.d.z = 0
t1.l.x = 0
t1.l.y = 0
t1.l.z = 1
t1.v.x = 0
t1.v.y = 0
t1.v.z = 0

' Initialize OpenGL
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective cam.fov, cam.aspect, cam.nearClip, cam.farClip
glMatrixMode GL_MODELVIEW
glLoadIdentity

glTexEnvf GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
glShadeModel GL_SMOOTH
glClearColor 0.0, 0.0, 0.0, 1.0

glPointSize 5
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glLineWidth(5)
glEnable(GL_LINE_SMOOTH)

' Make a cube
Dim As GLUint star = Cube(1)

' Make a list of cube locations
Dim As Integer starcount = 10000
Dim As vect6d stars(starcount)
For i As Integer = 0 To starcount - 1
    stars(i).u = Rnd * 1000
    stars(i).v = Rnd * 1000
    stars(i).w = Rnd * 1000
    stars(i).x = (Rnd * 1000) - 500
    stars(i).y = (Rnd * 1000) - 500
    stars(i).z = (Rnd * 1000) - 500
Next

' Init mouse
mouse.update

' Main loop
do
   ' Update mouse data
   mouse.update
   
   ' Frame limiter
   Sleep (1000 / 60) - ((Timer - lastFrame) / 1000), 1
   lastFrame = Timer
   
   ' A/D strafe left and right based on current direction
   if multikey(fb.sc_a) and multikey(fb.sc_d) = 0 then
      xv += (cam.rx - cam.x) * SHIP_STRAFE
      yv += (cam.ry - cam.y) * SHIP_STRAFE
      zv += (cam.rz - cam.z) * SHIP_STRAFE
   end if
   if multikey(fb.sc_d) and multikey(fb.sc_a) = 0 then
      xv -= (cam.rx - cam.x) * SHIP_STRAFE
      yv -= (cam.ry - cam.y) * SHIP_STRAFE
      zv -= (cam.rz - cam.z) * SHIP_STRAFE
   end if
   
   ' R/F move up and down based on current direction
   if multikey(fb.sc_r) and multikey(fb.sc_f) = 0 then
      xv -= (cam.ux - cam.x) * SHIP_RISE
      yv -= (cam.uy - cam.y) * SHIP_RISE
      zv -= (cam.uz - cam.z) * SHIP_RISE
   end if
   if multikey(fb.sc_f) and multikey(fb.sc_r) = 0 then
      xv += (cam.ux - cam.x) * SHIP_RISE
      yv += (cam.uy - cam.y) * SHIP_RISE
      zv += (cam.uz - cam.z) * SHIP_RISE
   end if
   
   ' W/S move forward or back depending on current direction
   if multikey(fb.sc_w) and multikey(fb.sc_s) = 0 then
      if multikey(fb.sc_lshift) then
         xv += (cam.lx - cam.x) * SHIP_DBL_ACC
         yv += (cam.ly - cam.y) * SHIP_DBL_ACC
         zv += (cam.lz - cam.z) * SHIP_DBL_ACC
      else
         xv += (cam.lx - cam.x) * SHIP_ACC
         yv += (cam.ly - cam.y) * SHIP_ACC
         zv += (cam.lz - cam.z) * SHIP_ACC
      end if
   end if
   if multikey(fb.sc_s) and multikey(fb.sc_w) = 0 then
      xv -= (cam.lx - cam.x) * SHIP_ACC
      yv -= (cam.ly - cam.y) * SHIP_ACC
      zv -= (cam.lz - cam.z) * SHIP_ACC
   end if
   
   ' Q/E to roll
   if multikey(fb.sc_q) and multikey(fb.sc_e) = 0 then
      r -= 2 * SHIP_ROT
   end if
   if multikey(fb.sc_e) and multikey(fb.sc_q) = 0 then
      r += 2 * SHIP_ROT
   end if
   if multikey(fb.sc_q) = 0 and multikey(fb.sc_e) = 0 then
      r *= 0.9
   end if
   
   ' Braking
   if multikey(fb.sc_space) then
      xv *= ship_brake
      yv *= ship_brake
      zv *= ship_brake
   end if
   
   ' Slow down rotation
   if multikey(fb.sc_CONTROL) then
      r *= ship_brake
      p *= ship_brake
      y *= ship_brake
   end if
   
   ' Mouse determines direction of acceleration to be affected by thrust
   ' Allowed to rotate fully without thrusting
   if abs(mouse.cx ) > mouse_threshold or abs(mouse.cy) > mouse_threshold then
      p += (mouse.cy * mouse_sensitivity) / 8 * SHIP_ROT
      y += (mouse.cx * mouse_sensitivity) / 8 * SHIP_ROT
   else
      p *= 0.9
      y *= 0.9
   end if
   
   ' Debug reset
   if multikey(fb.sc_insert) then
      xv = 0
      yv = 0
      zv = 0
      r = 0
      p = 0
      y = 0
      cam.x = 0
      cam.y = 0
      cam.z = 0
      cam.lx = 0
      cam.ly = 0
      cam.lz = -1
      cam.ux = 0
      cam.uy = 1
      cam.uz = 0
      cam.rx = 1
      cam.ry = 0
      cam.rz = 0
      cam.roll(r)
      cam.pitch(p)
      cam.yaw(y)
      t1.d.x = 0
      t1.d.y = 0
      t1.d.z = 0
      t1.l.x = 0
      t1.l.y = 0
      t1.l.z = -1
      t1.v.x = 0
      t1.v.y = 0
      t1.v.z = 0
   end if
   
   ' Natural decellearation
   xv *= ship_dec
   yv *= ship_dec
   zv *= ship_dec
   r *= ship_dec
   p *= ship_dec
   y *= ship_dec
   
   ' Adjust Camera
   cam.x += xv
   cam.y += yv
   cam.z += zv
   cam.lx += xv
   cam.ly += yv
   cam.lz += zv
   cam.rx += xv
   cam.ry += yv
   cam.rz += zv
   cam.ux += xv
   cam.uy += yv
   cam.uz += zv
   cam.roll(r)
   cam.pitch(p)
   cam.yaw(y)
   
   ' Clamp ship to camera
   t1.d.x = cam.x
   t1.d.y = cam.y
   t1.d.z = cam.z
   t1.l.x = cam.lx
   t1.l.y = cam.ly
   t1.l.z = cam.lz
   t1.v.x = cam.lx
   t1.v.y = cam.ly
   t1.v.z = cam.lz
   
   ' Fire projectile
   if mouse.b and 1 then
      b1 = object()
      b1.ot = projectile
      b1.d.x = t1.d.x + ((t1.l.x) * 1)
      b1.d.y = t1.d.y + ((t1.l.y) * 1)
      b1.d.z = t1.d.z + ((t1.l.z) * 1)
      
      'copy t1.l to the temp var
      dim as vector3d temp = t1.l
      
      'normalize the vector... make it unit length
      v3d_normalize(temp)
    
      'scale temp with bullet_speed and copy to b1.v
      'now it's ready to go. :)
      b1.v.x = temp.x * BULLET_SPEED
      b1.v.y = temp.y * BULLET_SPEED
      b1.v.z = temp.z * BULLET_SPEED
'      ? #cns, t1.l.x
   else
      b1.update
   end if
   
   ' Reset OpenGL buffers
   glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
   glLoadIdentity
   
   ' Apply camera settings
   gluLookAt cam.x, cam.y, cam.z, cam.lx, cam.ly, cam.lz, cam.x - cam.ux, cam.y - cam.uy, cam.z - cam.uz
   
   ' Draw stars
   For i As Integer = 0 To starcount - 1
     glPushMatrix
         'glRotatef stars(i).u, 1, 0, 0
         'glRotatef stars(i).v, 0, 1, 0
         'glRotatef stars(i).w, 0, 0, 1
         glTranslatef stars(i).x, stars(i).y, stars(i).z
         glCallList star
     glPopMatrix
   Next
   
   ' Draw bullet
   b1.draw
   
   ' Draw a 3D cartesian grid
'   glcolor3f 1,0,0
'   glbegin gl_lines
'   glvertex3f -1000,0,0
'   glvertex3f 1000,0,0
'   glEnd
'   glcolor3f 0,1,0
'   glbegin gl_lines
'   glvertex3f 0,-1000,0
'   glvertex3f 0,1000,0
'   glEnd
'   glcolor3f 0,0,1
'   glbegin gl_lines
'   glvertex3f 0,0,-1000
'   glvertex3f 0,0,1000
'   glEnd
   
   ' Copy OpenGL buffer to screen
   flip
loop until multikey(fb.sc_escape)

glDeleteLists star, 1
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

Hey, thanks for trying, it works a little better now, until you move around then it doesn't fire properly :(
Dr_D
Posts: 2453
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

hmm... ok. try this. i didn't test it with movement. :p

Code: Select all

/' Axipher 2009
W = Accelerate
S = Deccelerate
Mouse = Angel
A/D = Strafe
R/F = Up/Down
Space = Brake
Insert = Reset
'/



' Randomize the randim number generator based on the timer
Randomize Timer



' TRUE/FALSE
Const FALSE = 0
Const TRUE  = -1



' Files to include
#include once "fbgfx.bi"
#include once "gl\gl.bi"
#include once "gl\glu.bi"
#include once "gl\glfw.bi"
#include once "cube.bi"
#include once "draw_gl_.bi"



enum object_type
   star = 1
   projectile = 2
   ship = 4
End enum



' Some constants
Const PI = 4 * Atn(1)
Const RAD = PI/180
Const SHIP_ACC = 0.1
Const SHIP_DBL_ACC = SHIP_ACC * 2
Const SHIP_STRAFE = 0.1
Const SHIP_RISE = 0.1
Const SHIP_ROT = 0.1
Const SHIP_DEC = 0.995
Const SHIP_BRAKE = 0.97
Const BULLET_SPEED = 1



' A few shared variables
Dim Shared As Integer sx,sy,sx2,sy2
Dim As Double mouse_sensitivity = 0.6,mouse_threshold = 5



Type mousedata
   As Integer x,ox,dx
   As Double cx
   As Integer y,oy,dy
   As Double cy
   As Integer b
   
   Declare Constructor()
   
   Declare Sub update(vis As Integer = 0)
End Type

Constructor mousedata()
   
End Constructor

Sub mousedata.update(vis As Integer = 0)
   ox = x
   oy = y
   
   getmouse x,y,,b
   
   dx = (x - ox)
   dy = (y - oy)
   
   cx = x - sx2
   cy = y - sy2
   
   setmouse sx2,sy2,vis
End Sub



Type vect6d
   u As Single
   v As Single
   w As Single
   x As Single
   y As Single
   z As Single
End Type



Type vector3d
   As Double x,ux
   As Double y,uy
   As Double z,uz
   
   Declare Constructor()
   
   Declare Property x2() As Double
   Declare Property y2() As Double
   Declare Property z2() As Double
End Type

Constructor vector3d()
   
End Constructor

Property vector3d.x2() As Double
   Return (x + ux)
End Property

Property vector3d.y2() As Double
   Return (y + uy)
End Property

Property vector3d.z2() As Double
   Return (z + uz)
End Property

Sub v3d_normalize( Byref v As vector3d )
    Dim As Double dist
    dist = Sqr( v.x^2 + v.y^2 + v.z^2 )
    If dist = 0 Then dist = 1
    v.x/=dist
    v.y/=dist
    v.z/=dist
End Sub

Type quaternion
   w As Single
   x As Single
   y As Single
   z As Single
   
   Declare Sub normalize()
   Declare Function conj() As quaternion
End Type       
   
Sub quaternion.normalize()
   Dim As Single mag = Sqr(w*w+x*x+y*y+z*z)
   w /= mag
   x /= mag
   y /= mag
   z /= mag
End Sub

Function quaternion.conj() As quaternion
   Return Type<quaternion>( w, -x, -y, -z )
End Function

Operator * (lhs As quaternion, rhs As quaternion) As quaternion
   Return Type<quaternion>( lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z, _
                            lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y, _
                            lhs.w * rhs.y - lhs.x * rhs.z + lhs.y * rhs.w + lhs.z * rhs.x, _
                            lhs.w * rhs.z + lhs.x * rhs.y - lhs.y * rhs.x + lhs.z * rhs.w )
End Operator
       


Type camera
   'position
   x As Single
   y As Single
   z As Single
   
   'look vector
   lx As Single
   ly As Single
   lz As Single
   
   'up vector
   ux As Single
   uy As Single
   uz As Single
   
   'right vector
   rx As Single
   ry As Single
   rz As Single
   
   FOV As Single
   aspect As Single
   nearClip As Single
   farClip As Single
   
   Declare Sub roll( a As Single )
   Declare Sub pitch( a As Single )
   Declare Sub yaw( a As Single )
   Declare Sub advance( d As Single )
   Declare Sub strafe( d As Single )
   Declare Sub rise( d As Single )
End Type

Sub camera.advance( d As Single )
   Dim As Single xt, yt, zt
   xt = (lx - x) * d
   yt = (ly - y) * d
   zt = (lz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.strafe( d As Single )
   Dim As Single xt, yt, zt
   xt = (rx - x) * d
   yt = (ry - y) * d
   zt = (rz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.rise( d As Single )
   Dim As Single xt, yt, zt
   xt = (ux - x) * d
   yt = (uy - y) * d
   zt = (uz - z) * d
   x += xt
   y += yt
   z += zt
   ux += xt
   uy += yt
   uz += zt
   rx += xt
   ry += yt
   rz += zt
   lx += xt
   ly += yt
   lz += zt
End Sub

Sub camera.roll( a As Single )
   Dim As quaternion qUp = Type<quaternion>(0, ux - x, uy - y, uz - z)
   Dim As quaternion qRight = Type<quaternion>(0, rx - x, ry - y, rz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (lx - x) * Sin(a * rad/2), (ly - y) * Sin(a * rad/2), (lz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qUp * qRot.conj()
      ux = W.x + x
      uy = W.y + y
      uz = W.z + z
   W = qRot * qRight * qRot.conj()
      rx = W.x + x
      ry = W.y + y
      rz = W.z + z
End Sub

Sub camera.pitch( a As Single )
   Dim As quaternion qUp = Type<quaternion>(0, ux - x, uy - y, uz - z)
   Dim As quaternion qLook = Type<quaternion>(0, lx - x, ly - y, lz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (rx - x) * Sin(a * rad/2), (ry - y) * Sin(a * rad/2), (rz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qUp * qRot.conj()
      ux = W.x + x
      uy = W.y + y
      uz = W.z + z
   W = qRot * qLook * qRot.conj()
      lx = W.x + x
      ly = W.y + y
      lz = W.z + z
End Sub

Sub camera.yaw( a As Single )
   Dim As quaternion qRight = Type<quaternion>(0, rx - x, ry - y, rz - z)
   Dim As quaternion qLook = Type<quaternion>(0, lx - x, ly - y, lz - z)
   Dim As quaternion qRot = Type<quaternion>(Cos(a * rad/2), (ux - x) * Sin(a * rad/2), (uy - y) * Sin(a * rad/2), (uz - z) * Sin(a * rad/2))
   
   Dim As quaternion W = qRot * qRight * qRot.conj()
      rx = W.x + x
      ry = W.y + y
      rz = W.z + z
   W = qRot * qLook * qRot.conj()
      lx = W.x + x
      ly = W.y + y
      lz = W.z + z
End Sub



Type object
   As vector3d d,l,v
   As object_type ot
   As Double scale
   
   Declare Constructor()
   
   Declare Sub update()
   Declare Sub Draw()
End Type

Constructor object()
   d.x = 0
   d.y = 0
   d.z = 0
   l.x = 0
   l.y = 0
   l.z = 0
   v.x = 0
   v.y = 0
   v.z = 0
   ot = star
   scale = 1
End Constructor

Sub object.update()
   d.x += v.x
   d.y += v.y
   d.z += v.z
End Sub

Sub object.draw()
    glPushMatrix()
   Select Case ot
   Case star
      draw_gl_star(d.x,d.y,d.z,scale)
   Case projectile
      draw_gl_projectile(d.x,d.y,d.z)
   Case ship
      draw_gl_ship
   End Select
   glPopMatrix()
End Sub



' Open a console window
Dim As Integer cns
cns = Freefile
Open cons For Output As #cns

' Get current screen resolution
screeninfo sx,sy
sx = 640
sy = 480

' Calculatemid points
sx2 = sx / 2
sy2 = sy / 2

' Initialize the screen
'screenres sx,sy,32,,fb.gfx_fullscreen or fb.gfx_opengl or fb.gfx_multisample
screenres sx,sy,32,,fb.gfx_opengl Or fb.gfx_multisample

' Variable for mouse data
Dim As mousedata mouse

' Objects for ship and one projectile
Dim As object t1,b1

' Variable for the camera
Dim As camera cam

' Store the timer in a variable
Dim As Double lastFrame = Timer

' Variables for calculations
Dim As Double xv, yv, zv, p, r, y

' Initialize the camera
cam.x = 0
cam.y = 0
cam.z = 0

cam.lx = 0
cam.ly = 0
cam.lz = -1

cam.ux = 0
cam.uy = 1
cam.uz = 0

cam.rx = 1
cam.ry = 0
cam.rz = 0

cam.FOV = 45
cam.Aspect = sx/sy
cam.nearClip = .01
cam.farClip = 10000

' Set ship location to 0,0,0 and looking into the screen
t1.d.x = 0
t1.d.y = 0
t1.d.z = 0
t1.l.x = 0
t1.l.y = 0
t1.l.z = 1
t1.v.x = 0
t1.v.y = 0
t1.v.z = 0

' Initialize OpenGL
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective cam.fov, cam.aspect, cam.nearClip, cam.farClip
glMatrixMode GL_MODELVIEW
glLoadIdentity

glTexEnvf GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
glShadeModel GL_SMOOTH
glClearColor 0.0, 0.0, 0.0, 1.0

glPointSize 5
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glLineWidth(5)
glEnable(GL_LINE_SMOOTH)

' Make a cube
Dim As GLUint star = Cube(1)

' Make a list of cube locations
Dim As Integer starcount = 10000
Dim As vect6d stars(starcount)
For i As Integer = 0 To starcount - 1
    stars(i).u = Rnd * 1000
    stars(i).v = Rnd * 1000
    stars(i).w = Rnd * 1000
    stars(i).x = (Rnd * 1000) - 500
    stars(i).y = (Rnd * 1000) - 500
    stars(i).z = (Rnd * 1000) - 500
Next

' Init mouse
mouse.update

' Main loop
Do
   ' Update mouse data
   mouse.update
   
   ' Frame limiter
   Sleep (1000 / 60) - ((Timer - lastFrame) / 1000), 1
   lastFrame = Timer
   
   ' A/D strafe left and right based on current direction
   If multikey(fb.sc_a) And multikey(fb.sc_d) = 0 Then
      xv += (cam.rx - cam.x) * SHIP_STRAFE
      yv += (cam.ry - cam.y) * SHIP_STRAFE
      zv += (cam.rz - cam.z) * SHIP_STRAFE
   End If
   If multikey(fb.sc_d) And multikey(fb.sc_a) = 0 Then
      xv -= (cam.rx - cam.x) * SHIP_STRAFE
      yv -= (cam.ry - cam.y) * SHIP_STRAFE
      zv -= (cam.rz - cam.z) * SHIP_STRAFE
   End If
   
   ' R/F move up and down based on current direction
   If multikey(fb.sc_r) And multikey(fb.sc_f) = 0 Then
      xv -= (cam.ux - cam.x) * SHIP_RISE
      yv -= (cam.uy - cam.y) * SHIP_RISE
      zv -= (cam.uz - cam.z) * SHIP_RISE
   End If
   If multikey(fb.sc_f) And multikey(fb.sc_r) = 0 Then
      xv += (cam.ux - cam.x) * SHIP_RISE
      yv += (cam.uy - cam.y) * SHIP_RISE
      zv += (cam.uz - cam.z) * SHIP_RISE
   End If
   
   ' W/S move forward or back depending on current direction
   If multikey(fb.sc_w) And multikey(fb.sc_s) = 0 Then
      If multikey(fb.sc_lshift) Then
         xv += (cam.lx - cam.x) * SHIP_DBL_ACC
         yv += (cam.ly - cam.y) * SHIP_DBL_ACC
         zv += (cam.lz - cam.z) * SHIP_DBL_ACC
      Else
         xv += (cam.lx - cam.x) * SHIP_ACC
         yv += (cam.ly - cam.y) * SHIP_ACC
         zv += (cam.lz - cam.z) * SHIP_ACC
      End If
   End If
   If multikey(fb.sc_s) And multikey(fb.sc_w) = 0 Then
      xv -= (cam.lx - cam.x) * SHIP_ACC
      yv -= (cam.ly - cam.y) * SHIP_ACC
      zv -= (cam.lz - cam.z) * SHIP_ACC
   End If
   
   ' Q/E to roll
   If multikey(fb.sc_q) And multikey(fb.sc_e) = 0 Then
      r -= 2 * SHIP_ROT
   End If
   If multikey(fb.sc_e) And multikey(fb.sc_q) = 0 Then
      r += 2 * SHIP_ROT
   End If
   If multikey(fb.sc_q) = 0 And multikey(fb.sc_e) = 0 Then
      r *= 0.9
   End If
   
   ' Braking
   If multikey(fb.sc_space) Then
      xv *= ship_brake
      yv *= ship_brake
      zv *= ship_brake
   End If
   
   ' Slow down rotation
   If multikey(fb.sc_CONTROL) Then
      r *= ship_brake
      p *= ship_brake
      y *= ship_brake
   End If
   
   ' Mouse determines direction of acceleration to be affected by thrust
   ' Allowed to rotate fully without thrusting
   If Abs(mouse.cx ) > mouse_threshold Or Abs(mouse.cy) > mouse_threshold Then
      p += (mouse.cy * mouse_sensitivity) / 8 * SHIP_ROT
      y += (mouse.cx * mouse_sensitivity) / 8 * SHIP_ROT
   Else
      p *= 0.9
      y *= 0.9
   End If
   
   ' Debug reset
   If multikey(fb.sc_insert) Then
      xv = 0
      yv = 0
      zv = 0
      r = 0
      p = 0
      y = 0
      cam.x = 0
      cam.y = 0
      cam.z = 0
      cam.lx = 0
      cam.ly = 0
      cam.lz = -1
      cam.ux = 0
      cam.uy = 1
      cam.uz = 0
      cam.rx = 1
      cam.ry = 0
      cam.rz = 0
      cam.roll(r)
      cam.pitch(p)
      cam.yaw(y)
      t1.d.x = 0
      t1.d.y = 0
      t1.d.z = 0
      t1.l.x = 0
      t1.l.y = 0
      t1.l.z = -1
      t1.v.x = 0
      t1.v.y = 0
      t1.v.z = 0
   End If
   
   ' Natural decellearation
   xv *= ship_dec
   yv *= ship_dec
   zv *= ship_dec
   r *= ship_dec
   p *= ship_dec
   y *= ship_dec
   
   ' Adjust Camera
   cam.x += xv
   cam.y += yv
   cam.z += zv
   cam.lx += xv
   cam.ly += yv
   cam.lz += zv
   cam.rx += xv
   cam.ry += yv
   cam.rz += zv
   cam.ux += xv
   cam.uy += yv
   cam.uz += zv
   cam.roll(r)
   cam.pitch(p)
   cam.yaw(y)
   
   ' Clamp ship to camera
   t1.d.x = cam.x
   t1.d.y = cam.y
   t1.d.z = cam.z
   t1.l.x = cam.lx
   t1.l.y = cam.ly
   t1.l.z = cam.lz
   t1.v.x = cam.lx
   t1.v.y = cam.ly
   t1.v.z = cam.lz

   
   ' Fire projectile
   If mouse.b And 1 Then
      b1 = object()
      b1.ot = projectile
      
      Dim As vector3d temp
      temp.x = t1.l.x - t1.d.x
      temp.y = t1.l.y - t1.d.y
      temp.z = t1.l.z - t1.d.z

      'normalize the vector... make it unit length
      v3d_normalize(temp)
   
      b1.d.x = t1.d.x + temp.x
      b1.d.y = t1.d.y + temp.y
      b1.d.z = t1.d.z + temp.z

      'scale temp with bullet_speed and copy to b1.v
      'now it's ready to go. :)
      b1.v.x = temp.x * BULLET_SPEED
      b1.v.y = temp.y * BULLET_SPEED
      b1.v.z = temp.z * BULLET_SPEED
'      ? #cns, t1.l.x
   Else
      b1.update
   End If
   
   ' Reset OpenGL buffers
   glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
   glLoadIdentity
   
   ' Apply camera settings
   gluLookAt cam.x, cam.y, cam.z, cam.lx, cam.ly, cam.lz, cam.x - cam.ux, cam.y - cam.uy, cam.z - cam.uz
   
   ' Draw stars
   For i As Integer = 0 To starcount - 1
     glPushMatrix
         'glRotatef stars(i).u, 1, 0, 0
         'glRotatef stars(i).v, 0, 1, 0
         'glRotatef stars(i).w, 0, 0, 1
         glTranslatef stars(i).x, stars(i).y, stars(i).z
         glCallList star
     glPopMatrix
   Next
   
   ' Draw bullet
   b1.draw
   
   ' Draw a 3D cartesian grid
'   glcolor3f 1,0,0
'   glbegin gl_lines
'   glvertex3f -1000,0,0
'   glvertex3f 1000,0,0
'   glEnd
'   glcolor3f 0,1,0
'   glbegin gl_lines
'   glvertex3f 0,-1000,0
'   glvertex3f 0,1000,0
'   glEnd
'   glcolor3f 0,0,1
'   glbegin gl_lines
'   glvertex3f 0,0,-1000
'   glvertex3f 0,0,1000
'   glEnd
   
   ' Copy OpenGL buffer to screen
   flip
Loop Until multikey(fb.sc_escape)

glDeleteLists star, 1

As an alternative, this is a straight vector based approach. This code is old, but I've kept it semi-updated. Hopefully, it will be of some assistance. ;)

Code: Select all

#include "GL/gl.bi"
#include "GL/glu.bi"
#include "fbgfx.bi"
randomize timer

type vec3f
    X   as single
    Y   as single
    Z   as single
end type

type vec4f
    X   as single
    Y   as single
    Z   as single
    W   as single
end type

type Entities
    Position    as vec3f
    LookAt      as vec3f
    DVector     as vec3f
    UVector     as vec3f
    RVector     as vec3f
    Radius      as single
    Colr(3)     as single
    Emission(3) as single
    Orbit(1)    as single   
end type

type projectiles
    position    as vec3f
    direction   as vec3f
end type

declare sub Rot_X( byref Entity as Entities, byref Angle as single )
declare sub Rot_Y( byref Entity as Entities, byref Angle as single )
declare sub Rot_Z( byref Entity as Entities, byref Angle as single )
declare function Vector_Cross ( byref v1 as vec3f, byref v2 as vec3f ) as vec3f
declare function Vector_Magnitude( byref v as vec3f ) as single
declare sub Vector_Normalize ( byref v as vec3f )

dim as integer i,i2,button,tempx,tempy 
dim as single tDist
dim as Entities Cam, Ball(1 to 25)
dim projectile as projectiles
dim as single bullet_speed = 5
dim as vec3f Factor
dim as vec4f Light_Position =>(0,0,0,1)

'Initialize the camera's vectors for a right-handed system,
'and give it an initial position...
Cam.Position.X = 0
Cam.Position.Y = 0
Cam.Position.Z = 150

Cam.DVector.X = 0
Cam.DVector.Y = 0
Cam.DVector.Z = -1

Cam.UVector.X = 0
Cam.UVector.Y = 1
Cam.UVector.Z = 0

Cam.RVector.X = 1
Cam.RVector.Y = 0
Cam.RVector.Z = 0

for i = 2 to ubound(Ball)
    Ball(i).Position.X =-200+(rnd*400)
    Ball(i).Position.Z =-200+(rnd*400)
    Ball(i).Radius = 5+ rnd*10
    Ball(i).Orbit(1) = rnd+.1
    for i2 = 0 to 3
        Ball(i).Colr(i2) = rnd
        Ball(i).Emission(i2) = 0
    next
next


Ball(1).Radius = 20
Ball(1).Colr(0) = 1
Ball(1).Colr(1) = .5
Ball(1).Colr(2) = .015
Ball(1).Colr(3) = 1
Ball(1).Emission(0)= 1
Ball(1).Emission(1)= .5
Ball(1).Emission(2)= 0.15
Ball(1).Emission(3)= 1

screenres 640,480,32,2,FB.GFX_OPENGL or FB.GFX_HIGH_PRIORITY

const MidX = 640\2, MidY = 480\2, False = 0, True = not False

glViewport( 0, 0, 640, 480 )
glMatrixMode( GL_PROJECTION )
glLoadIdentity()
gluPerspective( 45.0, 640.0/480.0, 1, 1000 )
glMatrixMode( GL_MODELVIEW )
glLoadIdentity()

glShadeModel( GL_SMOOTH )
glClearColor( 0.0, 0.0, 0.0, 1.0 )
glClearDepth( 1.0 )
glEnable( GL_DEPTH_TEST )
glEnable( GL_COLOR_MATERIAL )
glEnable( Gl_LIGHTING )
glEnable( GL_LIGHT0 )
glDepthFunc( GL_LEQUAL )
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST )


dim as gluQuadricObj ptr Sphere  = gluNewQuadric()


do
    glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT )
    getmouse(TempX, TempY,, Button)
    Factor.Y = (MidX-TempX)/500
    Factor.X = (MidY-TempY)/500
    setmouse(MidX, MidY, 0)
    Factor.Z = -Cam.RVector.Y*.25 'comment for free rotation, uncomment = spring effect
    
    Rot_X( Cam, Factor.X )
    Rot_Y( Cam, Factor.Y )
    Rot_Z( Cam, Factor.Z )
    
    if multikey(FB.SC_W) then
        Cam.Position.X += Cam.DVector.X*2
        Cam.Position.Y += Cam.DVector.Y*2
        Cam.Position.Z += Cam.DVector.Z*2
    end if
    
    if multikey(FB.SC_S) then
        Cam.Position.X -= Cam.DVector.X*2
        Cam.Position.Y -= Cam.DVector.Y*2
        Cam.Position.Z -= Cam.DVector.Z*2
    end if
    
    if multikey(FB.SC_D) then
        Cam.Position.X += Cam.RVector.X*2
        Cam.Position.Y += Cam.RVector.Y*2
        Cam.Position.Z += Cam.RVector.Z*2
    end if
    
    if multikey(FB.SC_A) then
        Cam.Position.X -= Cam.RVector.X*2
        Cam.Position.Y -= Cam.RVector.Y*2
        Cam.Position.Z -= Cam.RVector.Z*2
    end if
    
    if button and FB.BUTTON_LEFT then
        projectile.direction = cam.dVector
        projectile.position.x = cam.position.x + projectile.direction.x*2
        projectile.position.y = cam.position.y + projectile.direction.y*2
        projectile.position.z = cam.position.z + projectile.direction.z*2
    end if
    
    projectile.position.x += projectile.direction.x*bullet_speed
    projectile.position.y += projectile.direction.y*bullet_speed
    projectile.position.z += projectile.direction.z*bullet_speed

    glMatrixMode( GL_MODELVIEW )
    glLoadIdentity()
    
    Cam.LookAt.X = Cam.Position.X + Cam.DVector.X
    Cam.LookAt.Y = Cam.Position.Y + Cam.DVector.Y
    Cam.LookAt.Z = Cam.Position.Z + Cam.DVector.Z
    
    gluLookat( Cam.Position.X, Cam.Position.Y, Cam.Position.Z, Cam.LookAt.X, Cam.LookAt.Y, Cam.LookAt.Z, Cam.UVector.X, Cam.UVector.Y, Cam.UVector.Z )
    
    glLightFv( GL_LIGHT0, GL_POSITION, @light_Position.x )
    
    gluQuadricDrawStyle( Sphere, GLU_LINE )
    gluQuadricNormals( Sphere, GLU_FLAT )
    gluQuadricOrientation( Sphere, GLU_INSIDE )
    glColor3f( 0,0,.25 )
    gluSphere( Sphere, 500, 32, 32 )
    
    gluQuadricDrawStyle( Sphere, GLU_FILL )
    gluQuadricNormals( Sphere, GLU_SMOOTH )
    gluQuadricOrientation( Sphere, GLU_OUTSIDE )
    for i = 1 to ubound(Ball)
        Ball(i).Orbit(0) +=Ball(i).Orbit(1)
        if Ball(i).Orbit(0)>=360 then Ball(i).Orbit(0) = 0
        glPushMatrix()
        glRotateF ( Ball(i).Orbit(0), 0, 1, 0 )
        glTranslateF( Ball(i).Position.X, Ball(i).Position.y, Ball(i).Position.Z )
        glColor4FV( @Ball(i).Colr(0) )
        glMaterialFv( GL_FRONT, GL_EMISSION, @Ball(i).Emission(0) )
        gluSphere( Sphere, Ball(i).Radius, 16, 16 )
        glPopMatrix()
    next
    
    glPushMatrix()
    glTranslateF( projectile.Position.X, projectile.Position.y, projectile.Position.Z )
    glColor4F( 1,1,1,1 )
    gluSphere( Sphere, 2, 16, 16 )
    glPopMatrix()

    flip
    sleep 1,1
loop while inkey$ <> chr$(27)

gluDeleteQuadric( Sphere )


function Vector_Cross ( byref v1 as vec3f, byref v2 as vec3f ) as vec3f
    dim v as vec3f
    v.x = (v1.y * v2.z) - (v2.y * v1.z)
    v.y = (v1.z * v2.x) - (v2.z * v1.x)
    v.z = (v1.x * v2.y) - (v2.x * v1.y)
    return v
end function

function Vector_Magnitude( byref V as vec3f ) as single
    dim Mag as single
    Mag = sqr(v.x ^2 + v.y ^2 + v.z ^2)
    if Mag = 0 then Mag = 1
    return Mag
end function

sub Vector_Normalize ( byref v as vec3f )
    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 Rot_X( byref Entity as Entities, byref Angle as single )
    dim tDir as vec3f, tSin as single, tCos as single
    
    tCos = cos(Angle)
    tSin = sin(Angle)
    
    'multiply the Direction Vector by the Cosine of the angle
    'multiply the Up Vector by the Sine of the angle,
    'Then, add them together.
    'Since the Up Vector is already Perpendicular,
    'this operation rotates the Direction Vector about the Right Vector.
    'It's the equivelant of rotating an object's "nose" up & down.
    tDir.X = Entity.DVector.X*tCOS+Entity.UVector.X*tSin
    tDir.Y = Entity.DVector.Y*tCOS+Entity.UVector.Y*tSin
    tDir.Z = Entity.DVector.Z*tCOS+Entity.UVector.Z*tSin
    
    'Make sure the temp vector is unit length by normalizing.
    Vector_Normalize tDir
    
    'Now, the temp vector is ready to copy over the Direction Vector variables...
    Entity.DVector.X = tDir.X
    Entity.DVector.Y = tDir.Y
    Entity.DVector.Z = tDir.Z   
    
    'Since we rotated the Direction Vector Up/Down,
    'The Direction Vector, and the Up Vector are no longer Orthographic.
    'We fix this by taking the cross product of the Direction vector,
    'and the Right vector to get a new Perpendicular vector,
    'which is the inverse of our new Up vector.
    Entity.UVector = Vector_Cross( Entity.DVector, Entity.RVector )
    
    'As stated before, take the inverse...
    Entity.UVector.X =-Entity.UVector.X
    Entity.UVector.Y =-Entity.UVector.Y
    Entity.UVector.Z =-Entity.UVector.Z
end sub



sub Rot_Y( byref Entity as Entities, byref Angle as single )
    dim tDir as vec3f, tCos as single, tSin as single
    
    tCos = cos(Angle)
    tSin = sin(Angle)
    
    'Here, we basically just...
    'multiply the Direction Vector by the Cosine of the angle
    'multiply the Right Vector by the Sine of the angle,
    'Then, subtract the Right Vector from the Direction Vector.
    'Since the Right Vector is already Perpendicular,
    'this operation rotates the Direction Vector about the Up Vector.
    'It's the equivelant of rotating an object's "nose" left & right.
    tDir.X = Entity.DVector.X*tCOS-Entity.RVector.X*tSin
    tDir.Y = Entity.DVector.Y*tCOS-Entity.RVector.Y*tSin
    tDir.Z = Entity.DVector.Z*tCOS-Entity.RVector.Z*tSin
    
    'Make the temp vector unit length by normalizing...
    Vector_Normalize tDir
    
    'Now, the temp vector is ready to copy to the actual Direction Vector variable...
    Entity.DVector.X = tDir.X
    Entity.DVector.Y = tDir.Y
    Entity.DVector.Z = tDir.Z
    
    'Since we rotated the Direction Vector left/right,
    'The Direction Vector, and the Right Vector are no longer orthographic.
    'We fix this by taking the cross product of the Direction vector,
    'and the Up vector to get a new Perpendicular vector,
    'which is our new Right vector.
    Entity.RVector = Vector_Cross( Entity.DVector, Entity.UVector )
end sub



sub Rot_Z( byref Entity as Entities, byref Angle as single )
    dim tRight as vec3f, tCos as single, tSin as single
    tCos = cos(Angle)
    tSin = sin(Angle)
    
    
    'Here, we basically just...
    'multiply the Right Vector by the Cosine of the angle
    'multiply the Up Vector by the Sine of the angle,
    'Then, add them together.
    'Since the Up Vector is already Perpendicular,
    'this operation rotates the Right Vector about the Direction Vector.
    'It's the equivelant of an object rolling around a line going from the tail, to the nose.
    tRight.X = Entity.RVector.X*tCOS+Entity.UVector.X*tSin
    tRight.Y = Entity.RVector.Y*tCOS+Entity.UVector.Y*tSin
    tRight.Z = Entity.RVector.Z*tCOS+Entity.UVector.Z*tSin
    
    'Make the temp vector unit length by normalizing...
    Vector_Normalize tRight
    
    'Copy it over the Right Vector...
    Entity.RVector.X = tRight.X
    Entity.RVector.Y = tRight.Y
    Entity.RVector.Z = tRight.Z
    
    'Same function as the end of the Rot_X sub. ;)
    Entity.UVector = Vector_Cross( Entity.DVector, Entity.RVector )
    Entity.UVector.X =-Entity.UVector.X
    Entity.UVector.Y =-Entity.UVector.Y
    Entity.UVector.Z =-Entity.UVector.Z
end sub

axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

for the sphere/lighting demo with working bullet, I'll tear it apart tomorrow, and your second attempt works while moving, but sometimes it shoots backwards and it shoots based on the movement of the ship, not the direction the camera is facing, I'll check out tomorrow as well.
Dr_D
Posts: 2453
Joined: May 27, 2005 4:59
Contact:

Post by Dr_D »

Actually, it shoots along the axis the camera is facing... unless I misunderstand the intention. If the ship(camera) is moving faster than the bullet itself, it will appear to be shooting backwards because you actually move faster than the projectile. Try shooting while moving straight forward, then stopping. The projectile will catch up and pass you along the same vector. :p
aleofjax
Posts: 117
Joined: Oct 18, 2007 8:10

Post by aleofjax »

Okay, it's been, what, two months since I posted that demo, right? I haven't had much time on the computer for a while, before and after that demo. That was the only thing that I managed to get accomplished in the time that I had -- and I had to squeeze to get that puppy out! To think that the one thing that I put out there, my only chance to show off, would be picked up by someone else, and then used in his/i] program.

axifer, I can't tell you how much that means to me. Thank You! ^_^

I should be seeing more computer time for the forseeable future, so I'm going to take a look what you're working on. I think our interests may coincide, I'll get back to you soon.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

@aleofjax: I remembered your demo from a while back when I was just starting in OpenGL, I just found time recently to start working on something and liked the idea of a 3D space shooter so I set out to make one, I couldn't get rotations to work properly, so i used yours. If your interested in collaborating I'm all up for it, once I get projectiles working properly, I can start working on adding other models such as planets, asteroids, ships, stations, and a HUD.
aleofjax
Posts: 117
Joined: Oct 18, 2007 8:10

Post by aleofjax »

Kudos for the good commenting and descriptive variable names! That's about as organized as I'd like to be. Just what kind of space shooter are you planning on making with this? Asteroids? Star Control? The Last Starfighter? If you'll be using planets and space stations, I suppose that means gravity and a pretty massive scale. I'm down with some physics, but I'll warn you: angular velocities make me dizzy!

You might consider setting up your movement controls to affect the ship, then clamp the camera to the ship instead of the other way around. It would make it easier to select other cameras (chase cam, cockpit, etc..).

As for the bullet, counldn't you just add the camera's velocity to the bullet's trajectory?
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

About the switching controls to ship instead of camera, that's desired, I just based it on your code to get it to work haha. And it's gooing to be more in the style of Dark Star One, 3D space shooter with asteroids you can go inside of, planets, and space stations, so very big scale. I would like to get the skybox around everything and max velocity working as well. Lots to do for this project.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

Just a quick update, not much has changed, using triangles now instead of cubes, half-way to implementing a pause menu, runs super smooth on my machine at 60 FPS
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

Well I've got the bullet behaving a little better now, still not the best. I've also started to implement a pause menu, which was way easier then I made it out to be, please try it out and let me know how it is. I'll update the attachment as well for those too lazy to compile.
axipher
Posts: 891
Joined: Dec 27, 2005 16:37
Location: Sudbury,Ontario

Post by axipher »

Well I'm pounding out the updates in my spare time. Now the planets are nice spheres, more circular, and texture mapped. Things are moving along quite nicely. Any comments appreciated.
Post Reply