'based on ' mouse.bas' by  Don (don67geo@yahoo.com) 
'  modified and translated opengl mouse.c into hotbasic source. 
' 
$typecheck ON
$INCLUDE <RapidQ2.inc>
$INCLUDE <GL\QGL.inc>

DECLARE SUB FormCreate
DECLARE SUB FormKeyDown (Key AS Word, KeyShift AS INTEGER)
DECLARE SUB FormMouseDown (Button%, X%, Y%, Shift%)
DECLARE SUB FormMouseMove (X%, Y%, Shift%)
DECLARE SUB FormMouseUp(Button%, X%, Y%, Shift%)
DECLARE SUB FormSize
DECLARE sub meshbuilder
DECLARE sub meshframe(state as integer, ox as integer, nx as integer, oy as integer, ny as integer)
DECLARE sub setrendermode
DECLARE sub setvisual(iw as integer, ih as integer)


$define PAN    1
$define ROTATE 2
$define ZOOM   3

defint mx,my,dx,dy
dim trans(3) as single
dim rotat(2) as single

DEFINT state = 0

DIM GL AS QGL
'-- user interface here 
create Form as QFORM
  caption       = "OpenGL Mouse Demo"
  center
  width         = 256
  height        = 256
  onpaint       = meshbuilder
  onmouseup     = FormMouseUp
  onmousedown   = FormMouseDown
  onmousemove   = FormMouseMove
  onshow        = FormCreate
  onkeydown     = FormKeyDown
  onresize      = FormSize
end create

Form.showmodal
end


sub meshframe(state as integer, ox as integer, nx as integer, oy as integer, ny as integer)
    dx = ox - nx
    dy = ny - oy
    select case state
      case PAN:    trans(0) = trans(0) - dx / 100.0
                   trans(1) = trans(1) - dy / 100.0
      case ROTATE: rotat(0) = rotat(0) + (dy * 18.0) / 20.0
                   rotat(1) = rotat(1) - (dx * 18.0) / 20.0
      case ZOOM:   trans(2) = trans(2) - (dx + dy) / 20.0
    end select
end sub

sub setrendermode
    glEnable(GL_DEPTH_TEST)
end sub

sub setvisual(iw as integer, ih as integer)
    defdbl aspect = iw/ih
    glViewport(0, 0, iw, ih)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity
    gluPerspective(60.0,aspect,0.001,200.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity
    glTranslatef(0.0, 0.0, -3.0)
end sub

sub meshbuilder
    ' rotate a triangle around 
    glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT)
    glPushMatrix
    glTranslatef(trans(0), trans(1), trans(2))
    glRotatef(rotat(0), 1.0, 0.0, 0.0)
    glRotatef(rotat(1), 0.0, 1.0, 0.0)
    glClearColor(0.18,0.18,0.38,0.0)

    glBegin(GL_TRIANGLES)

    glIndexi(1): glColor3f(1.0, 0.0, 0.0): glVertex3i(0, 1, 0)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(-1, -1, 1)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(1, -1, 1)
    
    glIndexi(1): glColor3f(1.0, 0.0, 0.0): glVertex3i(0, 1, 0)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(1, -1, 1)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(1, -1, -1)

    glIndexi(1): glColor3f(1.0, 0.0, 0.0): glVertex3i(0, 1, 0)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(1, -1, -1)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(-1, -1, -1)
    
    glIndexi(1): glColor3f(1.0, 0.0, 0.0): glVertex3i(0, 1, 0)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(-1, -1, -1)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(-1, -1, 1)
    
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(1, -1, 1)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(-1, -1, 1)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(-1, -1, -1)
    
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(-1, -1, -1)
    glIndexi(3): glColor3f(0.0, 0.0, 1.0): glVertex3i(1, -1, -1)
    glIndexi(2): glColor3f(0.0, 1.0, 0.0): glVertex3i(1, -1, 1)
    glEnd

    glPopMatrix
    GL.Flip
end sub


SUB FormCreate
    GL.Init(Form)
   setrendermode
END SUB

SUB FormMouseDown (Button%, X%, Y%, Shift%) 
  if Button% = 0 then state = ROTATE  'or state 
  if Button%= 1 then state = ZOOM 'or state 
  mx = X%'Screen.mouseX 
  my = Y%'Screen.mouseY 
END SUB

SUB FormMouseUp(Button%, X%, Y%, Shift%)
   state = 0
END SUB


SUB FormMouseMove (X%, Y%, Shift%)
     meshframe(state, mx, X%, my, Y%)
     mx = X%
     my = y%
     meshbuilder
     GL.Flip
END SUB

SUB FormKeyDown (Key AS Word, KeyShift AS INTEGER) 
  if key = 27 then 
    GL.Close
    Form.close
  end if
  if KeyShift THEN state = STATE XOR PAN
END SUB


SUB FormSize
  GL.Resize(form.clientWidth, form.clientHeight)
  setvisual(GL.width, GL.height)
  meshbuilder
END SUB