Here's a tweaked version of the included example:
Strict
Import ".\libode.a"
Import ".\libodemax.a"
Incbin "wcrate.jpg"
Incbin "ground.bmp"
Global ScreenWidth:Float = 800
Global ScreenHeight:Float = 600
Global ScreenDepth:Int = 32
Global FullScreen:Int = 1
Global Texname,texname2
Global lastspace
Global light:Int=True ' Lighting ON/OFF
Global blend:Int ' Blending ON/OFF
Global xrot:Float ' X Rotation
Global yrot:Float ' Y Rotation
Global lookupdown:Float=0.0
Global heading:Float=0.0
Global xpos:Float=0.0
Global zpos:Float=0.0
Global LightAmbient:Float[]=[0.8, 0.8, 0.8, 1.0] ' Ambient Light
Global LightDiffuse:Float[]=[1.0, 1.0, 1.0, 1.0] ' Diffuse Light
Global LightPosition:Float[]=[0.0, 2.0, 1.0, 1.0] ' Light Position
Global FPS,lfc,fc ' frame counter since app start
Global s:String=""
Global OdeEntList:tList = CreateList()
Global selectbuffer:Int[512],hits
Global SelectedName,lastselected:odeent
Global viewport:Int[4]
Global world,space,plane,boxbody,boxgeom,mass:Int[1024],boxsize:Float=0.1
Global lms:Int=MilliSecs()
Const MaxOdeEnts=50
include "ode-defs.bmx"
'
' Setup display
Local ScreenFlags = BGL_BACKBUFFER | BGL_DEPTHBUFFER
If FullScreen
ScreenFlags = ScreenFlags | BGL_FULLSCREEN
EndIf
bglCreateContext(ScreenWidth,ScreenHeight,ScreenDepth,0,ScreenFlags)
bglSetSwapInterval(1)
InitGl()
'
' Create ODE world
world=dworldcreate()
dWorldSetGravity (world, 0,-9.81,0)
space = dHashSpaceCreate (0);
plane=dCreatePlane (space,0,1,0,0);
'
' Create ODE boxes
For Local i:Float=1 To MaxOdeEnts/2
OdeEnt.createBox(world,space,i, 0.1,(i Mod 4-2)/4, (i / 4), -1)
Next
For Local i:Float=1 To MaxOdeEnts/2 ' 2 loops name param must be created sequentially
OdeEnt.createBox(world,space,i+MaxOdeEnts/2, 0.1,(i Mod 4-2.5)/4, (i / 4), -1.25)
Next
OMinitcontacts(world)
While Not KeyHit( KEY_ESCAPE )
'
' Update ODE
omEmptyContactGroup()
dSpaceCollide (space,Null, Byte Ptr omnearCallback);
dWorldStep (world,0.01)
'
' Render and stuff
glEnable(GL_TEXTURE_2D)
DisplayLoop()
glDisable(GL_TEXTURE_2D)
glColor3f 1.0,1.0,1.0
Local y=0
If MilliSecs()>lms+1000 Then
lms=MilliSecs()
FPS=(fc-lfc)
lfc=fc
EndIf
s = "#FPS: "+FPS
s:+"##Use mouse to look around"
s:+"#WASD/Arrow Keys to move"
s:+"#Left click to select#"
If lastselected
s:+"#Selection: "+lastselected.name+"#"
EndIf
Local f=Instr(s,"#",1)
Repeat
Local l:String= Left(s,f-1)
s= Right(s,Len(s)-f)
bglDrawText(l,10,y)
y:+12
f=Instr(s,"#",1)
Until f=0
FlushMem
bglSwapBuffers
fc:+1
Wend
End
'
' transfers the objects matrix into opengl ready to render
Function SetTransformMat(geom:Int)
Local R:Float Ptr
Local pos:Float Ptr
Local matrix:Float[16];
pos =Float Ptr dGeomGetPosition (geom);
R = Float Ptr dGeomGetRotation (geom);
matrix[0]=R[0]; matrix[1]=R[4]; matrix[2]=R[8]; matrix[3]=0;
matrix[4]=R[1]; matrix[5]=R[5]; matrix[6]=R[9]; matrix[7]=0;
matrix[8]=R[2]; matrix[9]=R[6]; matrix[10]=R[10]; matrix[11]=0;
matrix[12]=pos[0]; matrix[13]=pos[1]; matrix[14]=pos[2]; matrix[15]=1;
glMultMatrixf (matrix);
EndFunction
Function InitGl()
'''''' initial setup of gl
Local tex:TPixmap=LoadPixmap("incbin::wcrate.jpg")
texname=bglTexFromPixmap(tex)
texname2=bglTexFromPixmap(LoadPixmap("incbin::ground.bmp"))
glBindTexture GL_TEXTURE_2D, Texname2
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST
glBindTexture GL_TEXTURE_2D, Texname
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST
glEnable GL_TEXTURE_2D
glBlendFunc GL_SRC_ALPHA, GL_ONE
glClearColor(0.4, 0.4, 0.4, 0.0)
glClearDepth 1.0
glDepthFunc GL_LESS
glEnable GL_DEPTH_TEST
glShadeModel(GL_SMOOTH)
glViewport(0,0,ScreenWidth,ScreenHeight)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0,Float(ScreenWidth)/Float(ScreenHeight),0.1,100.0)
glMatrixMode(GL_MODELVIEW)
glLightfv GL_LIGHT0, GL_AMBIENT, Float Ptr LightAmbient
glLightfv GL_LIGHT0, GL_DIFFUSE, Float Ptr LightDiffuse
glLightfv GL_LIGHT0, GL_POSITION, Float Ptr LightPosition
glEnable GL_LIGHT0
End Function
Function DisplayLoop()
Local x_m:Float; Local y_m:Float; Local z_m:Float; Local u_m:Float ; Local v_m:Float
Local xtrans:Float; Local ztrans:Float; Local ytrans:Float
Local sceneroty:Float
Local loop_m:Int
'
' Blend mode
If KeyHit(KEY_B)
blend = Not blend
EndIf
If blend = 0 Then
glDisable GL_BLEND
glEnable GL_DEPTH_TEST
Else
glEnable GL_BLEND
glDisable GL_DEPTH_TEST
End If
'
' Lighting
If KeyHit(KEY_L)
light = Not light
EndIf
If light=0
glDisable(GL_LIGHTING)
Else
glEnable(GL_LIGHTING)
EndIf
'
' Movement
If KeyDown(KEY_UP) Or KeyDown(KEY_W)
xpos = xpos - Float(Sin(heading)) * 0.01
zpos = zpos - Float(Cos(heading)) * 0.01
End If
If KeyDown(KEY_DOWN) Or KeyDown(KEY_S)
xpos = xpos + Float(Sin(heading)) * 0.01
zpos = zpos + Float(Cos(heading)) * 0.01
End If
If KeyDown(KEY_LEFT) Or KeyDown(KEY_A)
xpos = xpos - Float(Sin(heading+90)) * 0.01
zpos = zpos - Float(Cos(heading+90)) * 0.01
EndIf
If KeyDown(KEY_RIGHT) Or KeyDown(KEY_D)
xpos = xpos + Float(Sin(heading+90)) * 0.01
zpos = zpos + Float(Cos(heading+90)) * 0.01
EndIf
yrot = heading
xtrans=-xpos
ztrans=-zpos
ytrans= - 0.5
sceneroty = 360.0 - yrot
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
lookupdown=lookupdown+(MouseY()-(ScreenHeight/2.0))/8
heading=heading-(MouseX()-(Screenwidth/2.0))/8
MoveMouse screenwidth/2,screenheight/2
'
' ---- Picking ----
'
glSelectBuffer(512,Varptr selectBuffer[0]);
glRenderMode(GL_SELECT)
glInitNames();
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(ScreenWidth/2.0, ScreenHeight/2.0, 1, 1, viewport);
gluPerspective(45.0,Float(ScreenWidth)/Float(ScreenHeight),0.1,100.0)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity
glRotatef lookupdown, 1.0, 0, 0
glRotatef sceneroty, 0, 1.0, 0
glTranslatef xtrans, ytrans, ztrans
glBindTexture GL_TEXTURE_2D, Texname2
Local i=1
For Local e:odeent=EachIn OdeEntlist
glPushName(i)
i:+1
glPushMatrix()
SetTransformMat(e.geom)
drawbox([e.size,e.size,e.size])
glPopName()
glPopMatrix()
Next
glFlush();
hits=glRenderMode(GL_RENDER);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glColor4f 1.0,1.0,1.0,1.0
If hits>0 Then processhits(hits,Varptr selectBuffer[0])
'
' ---- End of picking ----
'
'
' Render code
glLoadIdentity
glRotatef lookupdown, 1.0, 0, 0
glRotatef sceneroty, 0, 1.0, 0
glTranslatef xtrans, ytrans, ztrans
glBindTexture GL_TEXTURE_2D, Texname2
glColor4f 1.0,1.0,1.0,1.0
'
' ground - not rendered in pick selection render
glDisable(GL_LIGHTING)
glBegin(GL_QUADS)
glNormal3f( 0.0, -1.0, 0.0)';// Normal Pointing Up
glTexCoord2f(0.0, 0.0); glVertex3f(-10, 0, -10)';// Point 1 (Top)
glTexCoord2f(0.0, 10); glVertex3f(-10, 0, 10)';// Point 2 (Top)
glTexCoord2f(10, 10); glVertex3f( 10, 0, 10)';// Point 3 (Top)
glTexCoord2f(10, 0.0); glVertex3f( 10, 0, -10)';// Point 4 (Top)
glEnd()
glEnable(GL_LIGHTING)
glBindTexture GL_TEXTURE_2D, Texname
'
' boxes
Local se:odeent
glBindTexture GL_TEXTURE_2D, Texname
For Local e:odeent=EachIn OdeEntlist
glPushMatrix()
SetTransformMat(e.geom)
If selectedname=e.name Then
glDisable(GL_LIGHTING)
glColor4f 1.0,0.0,0.0,1.0
se=e
ElseIf e.state
glDisable(GL_LIGHTING)
glColor4f 0.0,1.0,0.0,1.0
Else
glColor4f 1.0,1.0,1.0,1.0
EndIf
drawbox([e.size,e.size,e.size])
If selectedname=e.name Or e.state=True Then
glEnable(GL_LIGHTING)
EndIf
glPopMatrix()
Next
'
' Change selection
If MouseHit(1) And lastspace Then
If lastselected
lastselected.state=False
EndIf
If se
se.state=Not se.state
lastselected=se
lastspace=False
Local fx:Float = Sin(heading)* -1000.0
Local fy:Float = 0.0
Local fz:Float = Cos(heading)* -1000.0
dbodyaddforce(se.body,fx,fy,fz)
EndIf
EndIf
If Not MouseHit(1) Then lastspace=True
selectedname=0
End Function
Function DrawBox(sides:Float[])
Local lx:Float = sides[0]*0.5;
Local ly:Float = sides[1]*0.5;
Local lz:Float = sides[2]*0.5;
glBegin(GL_QUADS);
' Front Face
glNormal3f( 0.0, 0.0, 1.0) ' Normal Pointing Towards Viewer
glTexCoord2f(0.0, 0.0); glVertex3f(-lx, -ly, lz) ' Point 1 (Front)
glTexCoord2f(1.0, 0.0); glVertex3f( lx, -ly, lz) ' Point 2 (Front)
glTexCoord2f(1.0, 1.0); glVertex3f( lx, ly, lz) ' Point 3 (Front)
glTexCoord2f(0.0, 1.0); glVertex3f(-lx, ly, lz) ' Point 4 (Front)
' Back Face
glNormal3f( 0.0, 0.0,-1.0) ' Normal Pointing Away From Viewer
glTexCoord2f(1.0, 0.0); glVertex3f(-lx, -ly, -lz) ' Point 1 (Back)
glTexCoord2f(1.0, 1.0); glVertex3f(-lx, ly, -lz) ' Point 2 (Back)
glTexCoord2f(0.0, 1.0); glVertex3f( lx, ly, -lz) ' Point 3 (Back)
glTexCoord2f(0.0, 0.0); glVertex3f( lx, -ly, -lz) ' Point 4 (Back)
' Top Face
glNormal3f( 0.0, 1.0, 0.0) ' Normal Pointing Up
glTexCoord2f(0.0, 1.0); glVertex3f(-lx, ly, -lz) ' Point 1 (Top)
glTexCoord2f(0.0, 0.0); glVertex3f(-lx, ly, lz) ' Point 2 (Top)
glTexCoord2f(1.0, 0.0); glVertex3f( lx, ly, lz) ' Point 3 (Top)
glTexCoord2f(1.0, 1.0); glVertex3f( lx, ly, -lz) ' Point 4 (Top)
' Bottom Face
glNormal3f( 0.0,-1.0, 0.0) ' Normal Pointing Down
glTexCoord2f(1.0, 1.0); glVertex3f(-lx, -ly, -lz) ' Point 1 (Bottom)
glTexCoord2f(0.0, 1.0); glVertex3f( lx, -ly, -lz) ' Point 2 (Bottom)
glTexCoord2f(0.0, 0.0); glVertex3f( lx, -ly, lz) ' Point 3 (Bottom)
glTexCoord2f(1.0, 0.0); glVertex3f(-lx, -ly, lz) ' Point 4 (Bottom)
' Right face
glNormal3f( 1.0, 0.0, 0.0) ' Normal Pointing Right
glTexCoord2f(1.0, 0.0); glVertex3f( lx, -ly, -lz) ' Point 1 (Right)
glTexCoord2f(1.0, 1.0); glVertex3f( lx, ly, -lz) ' Point 2 (Right)
glTexCoord2f(0.0, 1.0); glVertex3f( lx, ly, lz) ' Point 3 (Right)
glTexCoord2f(0.0, 0.0); glVertex3f( lx, -ly, lz) ' Point 4 (Right)
' Left Face
glNormal3f(-1.0, 0.0, 0.0) ' Normal Pointing Left
glTexCoord2f(0.0, 0.0); glVertex3f(-lx, -ly, -lz) ' Point 1 (Left)
glTexCoord2f(1.0, 0.0); glVertex3f(-lx, -ly, lz) ' Point 2 (Left)
glTexCoord2f(1.0, 1.0); glVertex3f(-lx, ly, lz) ' Point 3 (Left)
glTexCoord2f(0.0, 1.0); glVertex3f(-lx, ly, -lz) ' Point 4 (Left)
glEnd() ' Done Drawing Quads
EndFunction
Function processhits:String(hits:Int,sb:Int Ptr)
Local low:Float
Local ply:Int=Var (sb+3)
low=Var (sb+1)
For Local x=0 To hits-1
Local p=Var sb
sb:+1
Local d1:Float=Var sb
sb:+1
Local d2:Float=Var sb
sb:+1
If ((d1+d2)/2) < low Then
low=((d1+d2)/2)
ply=Var sb
End If
For Local n=1 To p
sb:+1
Next
Next
selectedname=ply
End FunctionIt should work in debug mode now :) and clicking on a box will push it away from the camera.
Still, you should not run it in windowed mode, unless you use this fix:
http://www.blitzbasic.com/Community/posts.php?topic=43206 or the view will be twirling like mad.