MD2 Loader + Animation - Texturing

BlitzMax Forums/BlitzMax OpenGL Programming/MD2 Loader + Animation - Texturing

Hi guys,

I have been working on a translation of a Java MD2 loader, found on the net, into a Blitzmax version.
It works great besides the texturing part. Being a newbie in opengl I thought it was time to ask for help.

I am posting my code below. If you manage to texture the model correctly please post an updated version of the code so that we can all benefit from it.


You can move the camera around the animated model using the arrow keys. You will have to find a MD2 model and update the model path aswell as the texture path in the code in the New Method of the MD2 type.

Thanks for your help
bye
Nennig

Global ScreenWidth:Int=1024
Global ScreenHeight:Int=768
Global ScreenDepth:Int=32

bglCreateContext(ScreenWidth,ScreenHeight,ScreenDepth,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER)


Type Face
	Field vertIndex:Int[3]
	Field uvIndex:Int[3]
End Type


Type animFrame
	Field name:String
	Field vertices:Float[]
End Type


Type MD2

Field myCamera:TCamera 
Field name:String
Field magic:Int
Field version:Int
Field skinWitdh:Int
Field skinHeight:Int
Field frameSize:Int
Field numSkins:Int
Field numVertices:Int
Field numTexCoords:Int
Field numTriangles:Int
Field numGLcommands:Int
Field numFrames:Int
Field offsetSkins:Int
Field offsetTexCoords:Int
Field offsetTriangles:Int
Field offsetFrames:Int
Field offsetGLcommands:Int
Field offsetEnd:Int


Field uvs:Float[]
Field faces:Face[]
Field normals:Float[]
Field interpolatedFrame:animFrame
Field frames:animFrame[]

Field startFrame:Int=0
Field endFrame:Int=0

Field curAnimFrame:Int=0
Field nextAnimFrame:Int=1

Field lastAnimTime:Long=0

Field fps:Int=30
Field animate=False



Function LoadGLTexture(filename:String)
	Local TextureImage:TPixmap
	TextureImage:TPixmap=LoadPixmap(filename)							
	

	
	If TextureImage <> Null											
		glGenTextures(1, Varptr texture)								
		glBindTexture(GL_TEXTURE_2D, texture)
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage.width, TextureImage.height, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage.pixels)
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
	EndIf
	Return texture													
End Function


Method New()
	myCamera = New TCamera
	hBMP=LoadGLTexture("blade_red.bmp")
	filename:String="tris.md2"
	glEnable(GL_TEXTURE_2D)	
	glClearColor(0.0, 2.0, 0.0, 0.0)
	glClearDepth 1.0
	glDepthFunc(GL_LESS)
	glEnable(GL_DEPTH_TEST)
	glFrontFace(GL_CW)
	glShadeModel(GL_SMOOTH)
	glViewport(0,1,ScreenWidth,ScreenHeight)
	glMatriXMode(GL_PROJECTION)
	glLoadIdentitY()
	gluPerspective(45.0,Float(ScreenWidth)/Float(ScreenHeight),1.0,1000.0)
	gluLookAt(mYCamera.Eye.X,mYCamera.Eye.Y,mYCamera.Eye.Z,mYCamera.Target.X,mYCamera.Target.Y,mYCamera.Target.Z,mYCamera.Up.X,mYCamera.Up.Y,mYCamera.Up.Z)
	glMatriXMode(GL_MODELVIEW)
	
	
	fichier=OpenFile(filename)
	taille= FileSize(fichier)
	magic=Readint(fichier)
	version=Readint(fichier)
	skinWitdh=Readint(fichier)
	skinHeight=Readint(fichier)
	framSize=Readint(fichier)
	numSkins=Readint(fichier)
	numVertices=Readint(fichier)
	numTexCoords=Readint(fichier)
	numTriangles=Readint(fichier)
	numGLcommands=Readint(fichier)
	numFrames=Readint(fichier)
	offsetSkins=Readint(fichier)
	offsetTexCoords=Readint(fichier)
	offsetTriangles=Readint(fichier)
	offsetFrames=Readint(fichier)
	offsetGLcommands=Readint(fichier)
	offsetEnd=Readint(fichier)
			
	
	uvs= New Float[numTexCoords*2]
	SeekStream (fichier, offsetTexCoords)
	For i=0 To numTexCoords-1
		uvs[i*2]=ReadShort(fichier)/ skinWitdh
		uvs[(i*2)+1]=1-ReadShort(fichier)/ skinHeight

	Next 
	
	
	SeekStream (fichier, offsetTriangles)
	faces=New Face[numTriangles]
	For i=0 To numTriangles-1
		faces[i]= New Face
		curFace:Face=faces[i]
		curFace.vertIndex[2] = ReadShort(fichier)
		curFace.vertIndex[1] = ReadShort(fichier)
		curFace.vertIndex[0] = ReadShort(fichier)
		curFace.uvIndex[2] = ReadShort(fichier)
		curFace.uvIndex[1] = ReadShort(fichier)
		curFace.uvIndex[0] = ReadShort(fichier)
	Next

	frames = New animFrame[numFrames]
	interpolatedFrame = New animFrame
	interpolatedFrame.vertices = New Float[numVertices*3]
	SeekStream(fichier, offsetFrames)
	Local scale:Float [3]
	Local translate:Float[3]
	Local curFrame:animFrame
	Local tempx:Int
	Local tempy:Int
	Local tempz:Int
	Local dummy:Int
	
	For i=0 To numFrames-1
            
                frames[i] = New animFrame
                frames[i].vertices = New Float[numVertices * 3]
                curFrame = frames[i]                                
                                                
                scale[0] = ReadFloat(fichier)
		       scale[1] = ReadFloat(fichier)
		       scale[2] = ReadFloat(fichier)
		       translate[0] = ReadFloat(fichier)
		       translate[1] = ReadFloat(fichier)
		       translate[2] = ReadFloat(fichier)
		       curFrame.name = ReadString(fichier,16)
                                
                For v= 0 To numVertices-1
                                
                    tempx = ReadByte(fichier)
                    tempy = ReadByte(fichier)
                    tempz = ReadByte(fichier)
                    dummy = ReadByte(fichier)
                    curFrame.vertices[(v*3)] = tempx * scale[0] + translate[0]
                    curFrame.vertices[(v*3)+2] = -1 * (tempy * scale[1] + translate[1])
                    curFrame.vertices[(v*3)+1] = tempz * scale[2] + translate[2] 
	
		    	Next
	Next		
	CloseStream(fichier)	
	
End Method

Method Render()
		glClearColor(0.0, 0.1, 0.6, 0.0)
		glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
		glLoadIdentitY()
		glTranslatef(0.0,0.0,155.0)
		gluLookAt(mYCamera.Eye.X,mYCamera.Eye.Y,mYCamera.Eye.Z,mYCamera.Target.X,mYCamera.Target.Y,mYCamera.Target.Z,mYCamera.Up.X,mYCamera.Up.Y,mYCamera.Up.Z)
		bglDrawText("Eye.X " + mYCamera.Eye.X,10,24)
		bglDrawText("Eye.Y " + mYCamera.Eye.Y,10,44)
		bglDrawText("Eye.Z " + mYCamera.Eye.Z,10,64)
		
		bglDrawText("Target.X " + mYCamera.Target.X,260,24)
		bglDrawText("Target.Y " + mYCamera.Target.Y,260,44)
		bglDrawText("Target.Z " + mYCamera.Target.Z,260,64)

        frame:animFrame = frames[startFrame]
		        
        If (animate=True) Then
      
            createInterpolatedFrame()
            frame = interpolatedFrame

      	End If 
	   
	    glBegin GL_TRIANGLES
	     
        For  i = 0 To faces.length-1 
           
         curFace:Face = faces[i]
            
         For v= 0 To  2
			
		glTexCoord2f(uvs[(curFace.uvIndex[v]*2)], uvs[(curFace.uvIndex[v]*2)+1])
         glVertex3f(frame.vertices[(curFace.vertIndex[v]*3)], frame.vertices[(curFace.vertIndex[v]*3)+1], frame.vertices[(curFace.vertIndex[v]*3)+2])               
      				
		Next 
        Next
		glEnd
		
		
End Method

Method setFrameRange(startFrame:Int,endFrame:Int)
    
        self.startFrame = startFrame
        self.endFrame = endFrame
       
        If (startFrame < 0) Then startFrame = 0
        If (startFrame > frames.length) Then startFrame = frames.length
        If (endFrame < 0) Then endFrame = 0
        If (endFrame > frames.length) Then endFrame = frames.length
       
        curAnimFrame = startFrame
        nextAnimFrame = startFrame+1

End Method
    
Method setFPS(fps:Int)
           
        self.fps = fps
End Method   


Method toggleAnim(enable:Int)
    
	self.animate = enable
    
End Method    



Method resetAnim()
        curAnimFrame = startFrame
        nextAnimFrame = startFrame+1
        lastAnimTime = 0
End Method

Method createInterpolatedFrame()
              
        curTime:Long = MilliSecs()
        elapsedTime:Long = curTime - lastAnimTime
               
	    t:Float = elapsedTime / (1000.0 / self.fps)
        
        nextAnimFrame = (curAnimFrame + 1) Mod endFrame
        If (nextAnimFrame > endFrame) Then  nextAnimFrame = startFrame
        	
        If(elapsedTime > (1000.0 / fps)) Then
	       curAnimFrame = nextAnimFrame                                  
           lastAnimTime = curTime
	    End If
	        
         For v = 0 To frames[curAnimFrame].vertices.length -1 
        
         interpolatedFrame.vertices[v] = (frames[curAnimFrame].vertices[v] + t * (frames[nextAnimFrame].vertices[v] - frames[curAnimFrame].vertices[v]))
        	
    		Next 

End Method

End Type

Type TCamera 
	
	Field Eye:Vector3 = New Vector3
	Field Target:Vector3 = New Vector3
	Field Dir:Vector3 = New Vector3
	Field Up:Vector3 = New Vector3
	Field VRight:Vector3= New Vector3
	
	Method New()
		
		Eye.X=0.0
		Eye.Y=10.0
		Eye.Z=-22.0
		Target.X=0.0
		Target.Y=0.0
		Target.Z=100.0
		Up.X=0.0
		Up.Y=1.0
		Up.Z=0.0
		VRight.X=0.0
		VRight.Y=0.0
		VRight.Z=0.0
		
	End Method
	
	Method Move(speed:Float)
		
		Dir=Target.Sub(Eye)
		Eye.X:+Dir.X *speed
		Eye.Z:+Dir.Z *speed
		
		Target.X:+Dir.X *speed
		Target.Z:+Dir.Z *speed
		
	End Method		
	
	Method Rotate(speed:Float)
			
		Dir=Target.Sub(Eye)
		s:Float=DegreeToRadian(speed)
		Target.Z=(Eye.Z+Sin(s)*Dir.X + Cos(s)*Dir.Z)
		Target.X=(Eye.X+Cos(s)*Dir.X - Sin(s)*Dir.Z)
	End Method


	Function  DegreeToRadian:Float(degree:Float)
			 out:Float= degree * (3.1415926/180)
			 Return out	
	End Function
	

End Type


Type Vector3
	Field X:Float										
	Field Y:Float										
	Field Z:Float		
	
	Method Sub:Vector3(v:Vector3)
		result:Vector3=New Vector3
		result.X=X-v.X ; result.Y=Y-v.Y ; result.Z=Z-v.Z
		Return result
	End Method
	
	Method New()
		X=0.0 ; Y=0.0 ; Z=0.0
	End Method

End Type


Global myModel:MD2= New MD2
myModel.setFrameRange(0,198)
myModel.toggleAnim(1)
myModel.setFPS(10)

While Not KeyHit( KEY_ESCAPE )
	If KeyDown(KEY_DOWN) Then myModel.mYCamera.Move(+0.01)
	If KeyDown(KEY_UP) Then myModel.mYCamera.Move(-0.01)
	If KeyDown(KEY_LEFT) Then myModel.mYCamera.Rotate(10)
	If KeyDown(KEY_RIGHT) Then myModel.mYCamera.Rotate(-10)
	myModel.Render()
	bglSwapBuffers
	FlushMem
Wend




Hi all,

After being obsessed one full day at work with this texture problem, I finallly figured out the solution.

Find yourself an MD2 model and enjoy it in Blitzmax!

Nennig




Global ScreenWidth:Int=1024
Global ScreenHeight:Int=768
Global ScreenDepth:Int=32

Global Framecounter_framerate
Global Checkimage:Byte[256,256,3]
Global texname:Int[20]


bglCreateContext(ScreenWidth,ScreenHeight,ScreenDepth,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER)


Type Face
	Field vertIndex:Int[3]
	Field uvIndex:Int[3]
End Type


Type animFrame
	Field name:String
	Field vertices:Float[]
End Type


Type MD2

Field myCamera:TCamera 
Field name:String
Field magic:Int
Field version:Int
Field skinWitdh:Int
Field skinHeight:Int
Field frameSize:Int
Field numSkins:Int
Field numVertices:Int
Field numTexCoords:Int
Field numTriangles:Int
Field numGLcommands:Int
Field numFrames:Int
Field offsetSkins:Int
Field offsetTexCoords:Int
Field offsetTriangles:Int
Field offsetFrames:Int
Field offsetGLcommands:Int
Field offsetEnd:Int


Field uvs:Float[]
Field faces:Face[]
Field normals:Float[]
Field interpolatedFrame:animFrame
Field frames:animFrame[]

Field startFrame:Int=0
Field endFrame:Int=0

Field curAnimFrame:Int=0
Field nextAnimFrame:Int=1

Field lastAnimTime:Long=0

Field fps:Int=30
Field animate=False



Function LoadGLTexture(filename:String)
	Local PointeurImg:Byte Ptr
	Local TexWidth
	Local TexHeight
	tex01:TPixmap=LoadPixmap(filename)
	TexWidth=tex01.Width
	TexHeight=tex01.Height
	PointeurImg=PixmapPixelPtr(tex01,0,0)
	pp=0
	For y=TexHeight-1 To 0 Step -1
		For x=0 To TexWidth-1
			Checkimage[y,x,0]=PointeurImg[pp]
			Checkimage[y,x,1]=PointeurImg[pp+1]
			Checkimage[y,x,2]=PointeurImg[pp+2]
			pp=pp+3
		Next
	Next
	tex01=Null
	glEnable(GL_TEXTURE_2D)
	glGenTextures 2, Varptr Texname[0]

	glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST
	glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST
	glTexImage2D GL_TEXTURE_2D, 0, 3, TexWidth, TexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Checkimage
	
	


End Function


Method New()
	myCamera = New TCamera
	LoadGLTexture("blade_red.png")
	filename:String="tris.md2"
	glClearColor(0.0, 2.0, 0.0, 0.0)
	glClearDepth 1.0
	glDepthFunc(GL_LESS)
	glEnable(GL_DEPTH_TEST)
	glFrontFace(GL_CW)
	glShadeModel(GL_SMOOTH)
	glViewport(0,1,ScreenWidth,ScreenHeight)
	glMatriXMode(GL_PROJECTION)
	glLoadIdentitY()
	gluPerspective(45.0,Float(ScreenWidth)/Float(ScreenHeight),1.0,1000.0)
	gluLookAt(mYCamera.Eye.X,mYCamera.Eye.Y,mYCamera.Eye.Z,mYCamera.Target.X,mYCamera.Target.Y,mYCamera.Target.Z,mYCamera.Up.X,mYCamera.Up.Y,mYCamera.Up.Z)
	glMatriXMode(GL_MODELVIEW)
		
	
	fichier=OpenFile(filename)
	taille= FileSize(fichier)
	magic=Readint(fichier)
	version=Readint(fichier)
	skinWitdh=Readint(fichier)
	skinHeight=Readint(fichier)
	framSize=Readint(fichier)
	numSkins=Readint(fichier)
	numVertices=Readint(fichier)
	numTexCoords=Readint(fichier)
	numTriangles=Readint(fichier)
	numGLcommands=Readint(fichier)
	numFrames=Readint(fichier)
	offsetSkins=Readint(fichier)
	offsetTexCoords=Readint(fichier)
	offsetTriangles=Readint(fichier)
	offsetFrames=Readint(fichier)
	offsetGLcommands=Readint(fichier)
	offsetEnd=Readint(fichier)
			
	
	uvs= New Float[numTexCoords*2]
	SeekStream (fichier, offsetTexCoords)
	For i=0 To numTexCoords-1
		uvs[i*2]=Float ReadShort(fichier)/ skinWitdh
		uvs[(i*2)+1]=1- Float ReadShort(fichier)/ skinHeight
	Next 
		
	SeekStream (fichier, offsetTriangles)
	faces=New Face[numTriangles]
	For i=0 To numTriangles-1
		faces[i]= New Face
		curFace:Face=faces[i]
		curFace.vertIndex[2] = ReadShort(fichier)
		curFace.vertIndex[1] = ReadShort(fichier)
		curFace.vertIndex[0] = ReadShort(fichier)
		curFace.uvIndex[2] = ReadShort(fichier)
		curFace.uvIndex[1] = ReadShort(fichier)
		curFace.uvIndex[0] = ReadShort(fichier)
	Next

	frames = New animFrame[numFrames]
	interpolatedFrame = New animFrame
	interpolatedFrame.vertices = New Float[numVertices*3]
	SeekStream(fichier, offsetFrames)
	Local scale:Float [3]
	Local translate:Float[3]
	Local curFrame:animFrame
	Local tempx:Int
	Local tempy:Int
	Local tempz:Int
	Local dummy:Int
	
	For i=0 To numFrames-1
            
                frames[i] = New animFrame
                frames[i].vertices = New Float[numVertices * 3]
                curFrame = frames[i]                                
                                                
                scale[0] = ReadFloat(fichier)
		       scale[1] = ReadFloat(fichier)
		       scale[2] = ReadFloat(fichier)
		       translate[0] = ReadFloat(fichier)
		       translate[1] = ReadFloat(fichier)
		       translate[2] = ReadFloat(fichier)
		       curFrame.name = ReadString(fichier,16)
                                
                For v= 0 To numVertices-1
                                
                    tempx = ReadByte(fichier)
                    tempy = ReadByte(fichier)
                    tempz = ReadByte(fichier)
                    dummy = ReadByte(fichier)
                    curFrame.vertices[(v*3)] = tempx * scale[0] + translate[0]
                    curFrame.vertices[(v*3)+2] = -1 * (tempy * scale[1] + translate[1])
                    curFrame.vertices[(v*3)+1] = tempz * scale[2] + translate[2] 
	
		    	Next
	Next		
	CloseStream(fichier)	
	
End Method

Method Render()
		glClearColor(0.0, 0.1, 0.6, 0.0)
		glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
		glLoadIdentitY()
		glTranslatef(0.0,0.0,155.0)
		gluLookAt(mYCamera.Eye.X,mYCamera.Eye.Y,mYCamera.Eye.Z,mYCamera.Target.X,mYCamera.Target.Y,mYCamera.Target.Z,mYCamera.Up.X,mYCamera.Up.Y,mYCamera.Up.Z)
		bglDrawText("Eye.X " + mYCamera.Eye.X,10,24)
		bglDrawText("Eye.Y " + mYCamera.Eye.Y,10,44)
		bglDrawText("Eye.Z " + mYCamera.Eye.Z,10,64)
		
		bglDrawText("Target.X " + mYCamera.Target.X,260,24)
		bglDrawText("Target.Y " + mYCamera.Target.Y,260,44)
		bglDrawText("Target.Z " + mYCamera.Target.Z,260,64)
		
		bglDrawText("FPS : "+Framecounter_framerate,10,100)
		bglDrawText("CurFrame : "+curAnimFrame,10,120)
        frame:animFrame = frames[startFrame]
		        
        If (animate=True) Then
      
            createInterpolatedFrame()
            frame = interpolatedFrame

      	End If 
	   
	    glBegin GL_TRIANGLES
  		glBindTexture GL_TEXTURE_2D,Texname[0]
	    	For  i = 0 To faces.length-1 
           
         	curFace:Face = faces[i]
            
         	For v= 0 To  2
			
				glTexCoord2f(uvs[(curFace.uvIndex[v]*2)], uvs[(curFace.uvIndex[v]*2)+1])
         		glVertex3f(frame.vertices[(curFace.vertIndex[v]*3)], frame.vertices[(curFace.vertIndex[v]*3)+1], frame.vertices[(curFace.vertIndex[v]*3)+2])               
      				
			Next 
        	Next
		glEnd
		

		
End Method

Method setFrameRange(startFrame:Int,endFrame:Int)
    
        self.startFrame = startFrame
        self.endFrame = endFrame
       
  		If (startFrame < 0) Then startFrame = 0
       
 	If (startFrame > frames.length) Then startFrame = frames.length
       If (endFrame < 0) Then endFrame = 0
  
      If (endFrame > frames.length) Then endFrame = frames.length
       
        curAnimFrame = startFrame
        nextAnimFrame = startFrame+1

End Method
    
Method setFPS(fps:Int)
           
        self.fps = fps
End Method   


Method toggleAnim(enable:Int)
    
	self.animate = enable
    
End Method    



Method resetAnim()
        curAnimFrame = startFrame
        nextAnimFrame = startFrame+1
        lastAnimTime = 0
End Method

Method createInterpolatedFrame()
              
        curTime:Long = MilliSecs()
        elapsedTime:Long = curTime - lastAnimTime
               
	    t:Float = elapsedTime / (1000.0 / self.fps)
        
        nextAnimFrame = (curAnimFrame + 1)' Mod endFrame
        If (nextAnimFrame > endFrame) Then  nextAnimFrame = startFrame
        	
        If(elapsedTime > (1000.0 / fps)) Then
	       curAnimFrame = nextAnimFrame                                  
           lastAnimTime = curTime
	    End If
	        
         For v = 0 To frames[curAnimFrame].vertices.length -1 
        
         interpolatedFrame.vertices[v] = (frames[curAnimFrame].vertices[v] + t * (frames[nextAnimFrame].vertices[v] - frames[curAnimFrame].vertices[v]))
        	
    		Next 

End Method

End Type

Type TCamera 
	
	Field Eye:Vector3 = New Vector3
	Field Target:Vector3 = New Vector3
	Field Dir:Vector3 = New Vector3
	Field Up:Vector3 = New Vector3
	Field VRight:Vector3= New Vector3
	
	Method New()
		
		Eye.X=0.0
		Eye.Y=10.0
		Eye.Z=-22.0
		Target.X=0.0
		Target.Y=0.0
		Target.Z=100.0
		Up.X=0.0
		Up.Y=1.0
		Up.Z=0.0
		VRight.X=0.0
		VRight.Y=0.0
		VRight.Z=0.0
		
	End Method
	
	Method Move(speed:Float)
		
		Dir=Target.Sub(Eye)
		Eye.X:+Dir.X *speed
		Eye.Z:+Dir.Z *speed
		
		Target.X:+Dir.X *speed
		Target.Z:+Dir.Z *speed
		
	End Method		
	
	Method Rotate(speed:Float)
			
		Dir=Target.Sub(Eye)
		s:Float=DegreeToRadian(speed)
		Target.Z=(Eye.Z+Sin(s)*Dir.X + Cos(s)*Dir.Z)
		Target.X=(Eye.X+Cos(s)*Dir.X - Sin(s)*Dir.Z)
	End Method


	Function  DegreeToRadian:Float(degree:Float)
			 out:Float= degree * (3.1415926/180)
			 Return out	
	End Function
	

End Type


Type Vector3
	Field X:Float										
	Field Y:Float										
	Field Z:Float		
	
	Method Sub:Vector3(v:Vector3)
		result:Vector3=New Vector3
		result.X=X-v.X ; result.Y=Y-v.Y ; result.Z=Z-v.Z
		Return result
	End Method
	
	Method New()
		X=0.0 ; Y=0.0 ; Z=0.0
	End Method

End Type


Global myModel:MD2= New MD2
myModel.setFrameRange(40,45)
myModel.toggleAnim(1)
myModel.setFPS(2)

While Not KeyHit( KEY_ESCAPE )
	If KeyDown(KEY_DOWN) Then myModel.mYCamera.Move(+0.01)
	If KeyDown(KEY_UP) Then myModel.mYCamera.Move(-0.01)
	If KeyDown(KEY_LEFT) Then myModel.mYCamera.Rotate(10)
	If KeyDown(KEY_RIGHT) Then myModel.mYCamera.Rotate(-10)
		 	
	Framecounter_counter=Framecounter_counter+1
	If Framecounter_time=0 Then Framecounter_time=MilliSecs()
	If Framecounter_time+1001 <MilliSecs() Then
		Framecounter_framerate=Framecounter_counter
		Framecounter_counter=0
		Framecounter_time=MilliSecs()
	EndIf
	
		
	myModel.Render()
	bglSwapBuffers
	FlushMem
Wend









Just a screenshot....



This doesn't look half bad..
I'm gonna take try to take a look at this later.. :)

I did and post a minor change in the code above to the setFrameRange method. So that you can play only a selected portion of the frames of your model.

Hope you find it useful.

Nennig

Nice work!

Ahh. An (almost) direct port of my java MD2 code.
Thanks dude. Now I won't have to do it :)

I still think it's the easiest most readable MD2 loader/player ever ;)

How cool... welcome Ozak!

Thanks :)

Actually the fancy hardcoded pixel flipping trick is not needed.

Just replace


For i=0 To numTexCoords-1
	uvs[i*2]=Float ReadShort(fichier)/ skinWitdh
	uvs[(i*2)+1]=1-Float ReadShort(fichier)/ skinHeight
Next 


with


For i=0 To numTexCoords-1
	uvs[i*2]=Float ReadShort(fichier)/ skinWitdh
	uvs[(i*2)+1]=Float ReadShort(fichier)/ skinHeight
Next 



I'll post a seperate MD2 Model file loader/drawer that can just be included as well as a simple texture helper later if I get the time:)

Hello ozak,

Thanks to you. I had very much fun translating your code :-)
Thanks for the code update as well.

No problem :)
I posted the simple Texture helper btw.
It works well with the MD2 sample. I'm hoping to seperate the MD2 loader/drawer into a seperate class file as well as including normal generation + collision + faster drawing using vertex buffers soon :)