' file: fbGFXTest.bi
#include once "fbgfx.bi"
#include once "GL/glu.bi"
#include once "AntTweakBar.bi"
using fb

' a GUI button callback
sub ButtonCallback TW_CALL(clientData as any ptr)
  dim as integer ptr pClicks = cptr(integer ptr,clientData)
  *pClicks+=1
  WindowTitle "ButtonCallback: " & *pClicks
end sub


' step 1: create OpenGL context (FBGFX, GLUT, GWFW, ...)
ScreenRes 640,480, 32,, FB.GFX_OPENGL

' step 2: init AntTweakBar
TwInit(TW_OPENGL,0)

' step 3: set current window size
' (GLUT,GWFW, ... do it inside the resize callback's also)
dim as integer w,h:ScreenInfo w,h
TwWindowSize(w,h)

' step 4: create one or more TweakBar's
dim as TwBar ptr bar = TwNewBar("bar")
TwDefine(!"GLOBAL help='This example shows how to integrate AntTweakBar\nwith FreeBASIC and OpenGL.' ")
dim as single bkgcolor(...) = {0,0,0,1}
TwAddVarRW(bar, "bkgcolor", TW_TYPE_COLOR4F, @bkgcolor(0), " label='background color' help='change the color' ")
dim as uinteger Frames
TwAddVarRO(bar, "frames", TW_TYPE_UINT32, @frames, " label='number of frames'  help='frame counter.' ")
dim as double fps=60
TwAddVarRO(bar, "fps", TW_TYPE_DOUBLE, @fps, " label='frames per second' precision=2 help='FPS a TweakBar double.' ")
dim as integer nClicks
TwAddVarRO(bar, "nclicks", TW_TYPE_INT32, @nClicks, " label='button clicks' help='a TweakBar integer.'")
TwAddButton(bar,"button1",@ButtonCallback,@nClicks," label='press the button ->' help='a TweakBar Button.' ")

glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(40, w/h, 1, 100)
gluLookAt(0,5,3, 0,0,0, 0,1,0)

' step 5: redirect mouse and keyboard events to AntTweakBar
dim as EVENT e

dim as double t1 = timer

while e.type<>EVENT_WINDOW_CLOSE
  if ScreenEvent(@e) then
    select case e.type
    case EVENT_KEY_PRESS
      dim as integer key,modifier
      If (e.scancode = SC_ESCAPE) Then
        e.type=EVENT_WINDOW_CLOSE ' good for fullscreen
      end if
      select case e.scancode
      case SC_ENTER     : key = TW_KEY_RETURN
      case SC_BACKSPACE : key = TW_KEY_BACKSPACE
      case SC_TAB       : key = TW_KEY_TAB
      'case SC_CLEAR     : key = TW_KEY_CLEAR
      'case SC_PAUSE     : key = TW_KEY_PAUSE
      case SC_ESCAPE    : key = TW_KEY_ESCAPE
      case SC_SPACE     : key = TW_KEY_SPACE
      case SC_DELETE    : key = TW_KEY_DELETE
      case SC_UP        : key = TW_KEY_UP
      case SC_DOWN      : key = TW_KEY_DOWN
      case SC_RIGHT     : key = TW_KEY_RIGHT
      case SC_LEFT      : key = TW_KEY_LEFT
      case SC_INSERT    : key = TW_KEY_INSERT
      case SC_HOME      : key = TW_KEY_HOME
      case SC_END       : key = TW_KEY_END
      case SC_PAGEUP    : key = TW_KEY_PAGE_UP
      case SC_PAGEDOWN  : key = TW_KEY_PAGE_DOWN
      case SC_F1        : key = TW_KEY_F1
      case SC_F2        : key = TW_KEY_F2
      case SC_F3        : key = TW_KEY_F3
      case SC_F4        : key = TW_KEY_F4
      case SC_F5        : key = TW_KEY_F5
      case SC_F6        : key = TW_KEY_F6
      case SC_F7        : key = TW_KEY_F7
      case SC_F8        : key = TW_KEY_F8
      case SC_F9        : key = TW_KEY_F9
      case SC_F10       : key = TW_KEY_F10
      case SC_F11       : key = TW_KEY_F11
      case SC_F12       : key = TW_KEY_F12
      case SC_RSHIFT    : modifier = TW_KMOD_SHIFT
      case SC_LSHIFT    : modifier = TW_KMOD_SHIFT
      case SC_CONTROL   : modifier = TW_KMOD_CTRL
      case SC_ALT       : modifier = TW_KMOD_ALT
      case SC_LWIN      : modifier = TW_KMOD_META
      case SC_RWIN      : modifier = TW_KMOD_META
      case SC_MENU      : modifier = TW_KMOD_META
      case else         : key = e.ascii
      end select
      TwKeyPressed(key,modifier)
    case EVENT_MOUSE_MOVE
      TwMouseMotion(e.x,e.y)

    case EVENT_MOUSE_BUTTON_PRESS,EVENT_MOUSE_BUTTON_RELEASE
      dim as integer button,action
      ' set twbar action
      if e.type = EVENT_MOUSE_BUTTON_PRESS then
        action = TW_MOUSE_PRESSED
      else
        action = TW_MOUSE_RELEASED
      end if
      ' set twbar button
      select case e.button
      case BUTTON_LEFT   : button or=TW_MOUSE_LEFT
      case BUTTON_MIDDLE : button or=TW_MOUSE_MIDDLE
      case BUTTON_RIGHT  : button or=TW_MOUSE_RIGHT
      end select
      TwMouseButton(action,button)

    case EVENT_MOUSE_WHEEL
      TwMouseWheel(e.z)
    end select
  end if
  if (frames mod 100)=0 then
    dim as double t2 = Timer()
    fps=100.0/(t2-t1)
    t1 =t2
  end if
  frames+=1
  ' if values (frames,fps, ...) are changed refresh the bar
  TwRefreshBar(bar)

  glClearColor(bkgcolor(0),bkgcolor(1),bkgcolor(2),bkgcolor(3))
  glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  ' ...
  ' render scene
  ' ...
 
  ' draw GUI
  TwDraw()
 
  ' swapbuffers
  Flip
  sleep 10
wend

' step 6: relase all resources
TwTerminate()

End