'/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////  GDK_GL 2 - DEVELOPMENT EDITION .01 -  //////////////////////////////////////////////////
'/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
'////////////////////////////////////  By John Onyon a.k.a Unseen Machine  ///////////////////////////////////////////////////
'/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

'REM $INCLUDE:'UnseenGDK\GL\GDK_GL.bi'

'REM $INCLUDE:'UnseenGDK\GL\Models\Models.bi'



'// .MDL (Quake) Models \\

SUB MDL_TYPE_DEFS

 TYPE MDL_Vec3
  X AS SINGLE
  Y AS SINGLE
  Z AS SINGLE
 END TYPE

 TYPE MDL_Vertex
  V1 AS _UNSIGNED _BYTE
  V2 AS _UNSIGNED _BYTE
  V3 AS _UNSIGNED _BYTE
  NormalIndex AS _UNSIGNED _BYTE
 END TYPE

 TYPE MDL_TexCoord
  OnSeam AS LONG
  S AS LONG
  T AS LONG
 END TYPE

 TYPE MDL_Triangle
  FacesFront AS LONG
  Vertex1 AS LONG
  Vertex2 AS LONG
  Vertex3 AS LONG
 END TYPE

 TYPE MDL_SimpleFrame
  BBoxMin AS MDL_Vertex
  BBoxMax AS MDL_Vertex
  Name AS STRING * 16
 END TYPE

 TYPE MDL_Frame
  Type AS LONG
  Frame AS MDL_SimpleFrame
 END TYPE

 TYPE MDL_GroupFrame
  Type AS LONG
  Min AS MDL_Vertex
  Max AS MDL_Vertex
 END TYPE

 TYPE MDL_Skin
  Group AS LONG
 END TYPE

 TYPE MDL_GroupSkin
  Group AS LONG
  nb AS LONG
 END TYPE

 TYPE MDL_Header
  Ident AS LONG '// MUST BE 1330660425
  Version AS LONG '// MUST BE 6
  Scale AS MDL_Vec3
  Translate AS MDL_Vec3
  BoundingRadius AS SINGLE
  EyePosistion AS MDL_Vec3
  Num_Skins AS LONG
  SkinWidth AS LONG
  SkinHeight AS LONG
  Num_Verts AS LONG '// Num verts in a single frame
  Num_Tris AS LONG
  Num_Frames AS LONG
  SyncType AS LONG
  Flags AS LONG
  Size AS LONG
 END TYPE

 TYPE MDL_VertexF
  X AS SINGLE
  Y AS SINGLE
  Z AS SINGLE
 END TYPE

END SUB

'########################################################################################################################

SUB GDK_GL_MDL_LOAD_COLORS (CLR() AS LONG)
 RESTORE MDLColors
 FOR i% = 0 TO 767 STEP 3
  READ R%, G%, B%
  CLR(ClrCnt%) = _RGB32(R%, G%, B%)
  ClrCnt% = ClrCnt% + 1
 NEXT
 MDLColors:
 DATA 0,0,0,15,15,15,31,31,31,47,47,47,63,63,63,75,75,75,91,91,91,107,107,107,123,123,123,139,139,139,155,155,155,171,171,171,187,187,187,203,203,203,219,219,219,235,235,235,15,11,7,23,15,11,31,23,11,39,27,15,47,35,19,55,43,23,63,47,23,75,55,27,83,59,27,91,67,31,99,75,31,107,83,31,115,87,31,123,95,35,131,103,35,143,111,35,11,11,15,19,19,27,27,27,39,39,39,51,47,47,63,55,55,75,63,63,87,71,71,103,79,79,115,91,91,127,99,99,139,107,107,151,115,115,163,123,123,175,131,131,187,139,139,203,0,0,0,7,7,0,11,11,0,19,19,0,27,27,0,35,35,0,43,43,7,47,47,7,55,55,7,63,63,7,71,71,7,75,75,11,83,83,11,91,91,11,99,99,11,107,107,15,7,0,0,15,0,0,23,0,0,31,0,0,39,0,0,47,0,0,55,0,0,63,0,0,71,0,0,79,0,0,87,0,0,95,0,0,103,0,0,111,0,0,119,0,0,127,0,0,19,19,0,27,27,0,35,35,0,47,43,0,55,47,0,67,55,0,75,59,7,87,67,7,95,71,7,107,75,11,119,83,15,131,87,19,139,91,19,151,95,27,163,99,31,175,103,35,35,19,7,47,23,11,59,31,15,75,35,19,87,43,23,99,47,31,115,55,35,127,59,43,143,67,51,159,79,51,175,99,47,191,119,47,207,143,43,223,171,39,239,203,31,255,243,27,11,7,0,27,19,0,43,35,15,55,43,19,71,51,27,83,55,35,99,63,43,111,71,51,127,83,63,139,95,71,155,107,83,167,123,95,183,135,107,195,147,123,211,163,139,227,179,151,171,139,163,159,127,151,147,115,135,139,103,123,127,91,111,119,83,99,107,75,87,95,63,75,87,55,67,75,47,55,67,39,47,55,31,35,43,23,27,35,19,19,23,11,11,15,7,7,187,115,159,175,107,143,163,95,131,151,87,119,139,79,107,127,75,95,115,67,83,107,59,75,95,51,63,83,43,55,71,35,43,59,31,35,47,23,27,35,19,19,23,11,11,15,7,7,219,195,187,203,179,167,191,163,155,175,151,139,163,135,123,151,123,111,135,111,95,123,99,83,107,87,71,95,75,59,83,63,51,67,51,39,55,43,31,39,31,23,27,19,15,15,11,7,111,131,123,103,123,111,95,115,103,87,107,95,79,99,87,71,91,79,63,83,71,55,75,63,47,67,55,43,59,47,35,51,39,31,43,31,23,35,23,15,27,19,11,19,11,7,11,7,255,243,27,239,223,23,219,203,19,203,183,15,187,167,15,171,151,11,155,131,7,139,115,7,123,99,7,107,83,0,91,71,0,75,55,0,59,43,0,43,31,0,27,15,0,11,7,0,0,0,255,11,11,239,19,19,223,27,27,207,35,35,191,43,43,175,47,47,159,47,47,143,47,47,127,47,47,111,47,47,95,43,43,79,35,35,63,27,27,47,19,19,31,11,11,15,43,0,0,59,0,0,75,7,0,95,7,0,111,15,0,127,23,7,147,31,7,163,39,11,183,51,15,195,75,27,207,99,43,219,127,59,227,151,79,231,171,95,239,191,119,247,211,139,167,123,59,183,155,55,199,195,55,231,227,87,127,191,255,171,231,255,215,255,255,103,0,0,139,0,0,179,0,0,215,0,0,255,0,0,255,243,147,255,247,199,255,255,255,159,91,83,
END SUB

'########################################################################################################################

SUB GDK_GL_MDL_LOAD_NORMALS (Normals() AS MDL_VertexF)
 RESTORE MDL_norms:
 FOR i% = 0 TO 161
  READ Normals(i%).X, Normals(i%).Y, Normals(i%).Z
 NEXT
 MDL_norms:
 DATA -0.525731,0.000000,0.850651,-0.442863,0.238856,0.864188,-0.295242,0.000000,0.955423,-0.309017,0.500000,0.809017,-0.162460,0.262866,0.951056,0.000000,0.000000,1.000000,0.000000,0.850651,0.525731,-0.147621,0.716567,0.681718,0.147621,0.716567,0.681718,0.000000,0.525731,0.850651,0.309017,0.500000,0.809017,0.525731,0.000000,0.850651,0.295242,0.000000,0.955423,0.442863,0.238856,0.864188,0.162460,0.262866,0.951056,-0.681718,0.147621,0.716567,-0.809017,0.309017,0.500000,-0.587785,0.425325,0.688191,-0.850651,0.525731,0.000000,-0.864188,0.442863,0.238856,-0.716567,0.681718,0.147621,-0.688191,0.587785,0.425325,-0.500000,0.809017,0.309017,-0.238856,0.864188,0.442863,-0.425325,0.688191,0.587785,-0.716567,0.681718,-0.147621,-0.500000,0.809017,-0.309017,-0.525731,0.850651,0.000000,0.000000,0.850651,-0.525731,-0.238856,0.864188,-0.442863,0.000000,0.955423,-0.295242,-0.262866,0.951056,-0.162460,0.000000,1.000000,0.000000,0.000000,0.955423,0.295242,-0.262866,0.951056,0.162460,0.238856,0.864188,0.442863,0.262866,0.951056,0.162460,0.500000,0.809017,0.309017,0.238856,0.864188,-0.442863,0.262866,0.951056,-0.162460,0.500000,0.809017,-0.309017,0.850651,0.525731,0.000000,0.716567,0.681718,0.147621,0.716567,0.681718,-0.147621,0.525731,0.850651,0.000000,0.425325,0.688191,0.587785,0.864188,0.442863,0.238856,0.688191,0.587785,0.425325,0.809017,0.309017,0.500000,0.681718,0.147621,0.716567,0.587785,0.425325,0.688191,0.955423,0.295242,0.000000,1.000000,0.000000,0.000000,0.951056,0.162460,0.262866,0.850651,-0.525731,0.000000,0.955423,-0.295242,0.000000,0.864188,-0.442863,0.238856,0.951056,-0.162460,0.262866,0.809017,-0.309017,0.500000,0.681718,-0.147621,0.716567,0.850651,0.000000,0.525731,0.864188,0.442863,-0.238856,0.809017,0.309017,-0.500000,0.951056,0.162460,-0.262866,0.525731,0.000000,-0.850651,0.681718,0.147621,-0.716567,0.681718,-0.147621,-0.716567,0.850651,0.000000,-0.525731,0.809017,-0.309017,-0.500000,0.864188,-0.442863,-0.238856,0.951056,-0.162460,-0.262866,0.147621,0.716567,-0.681718,0.309017,0.500000,-0.809017,0.425325,0.688191,-0.587785,0.442863,0.238856,-0.864188,0.587785,0.425325,-0.688191,0.688191,0.587785,-0.425325,-0.147621,0.716567,-0.681718,-0.309017,0.500000,-0.809017,0.000000,0.525731,-0.850651,-0.525731,0.000000,-0.850651,-0.442863,0.238856,-0.864188,-0.295242,0.000000,-0.955423,-0.162460,0.262866,-0.951056,0.000000,0.000000,-1.000000,0.295242,0.000000,-0.955423,0.162460,0.262866,-0.951056,-0.442863,-0.238856,-0.864188,-0.309017,-0.500000,-0.809017,-0.162460,-0.262866,-0.951056,0.000000,-0.850651,-0.525731,-0.147621,-0.716567,-0.681718,0.147621,-0.716567,-0.681718,0.000000,-0.525731,-0.850651,0.309017,-0.500000,-0.809017,0.442863,-0.238856,-0.864188,0.162460,-0.262866,-0.951056,0.238856,-0.864188,-0.442863,0.500000,-0.809017,-0.309017,0.425325,-0.688191,-0.587785,0.716567,-0.681718,-0.147621,0.688191,-0.587785,-0.425325,0.587785,-0.425325,-0.688191,0.000000,-0.955423,-0.295242,0.000000,-1.000000,0.000000,0.262866,-0.951056,-0.162460,0.000000,-0.850651,0.525731,0.000000,-0.955423,0.295242,0.238856,-0.864188,0.442863,0.262866,-0.951056,0.162460,0.500000,-0.809017,0.309017,0.716567,-0.681718,0.147621,0.525731,-0.850651,0.000000,-0.238856,-0.864188,-0.442863,-0.500000,-0.809017,-0.309017,-0.262866,-0.951056,-0.162460,-0.850651,-0.525731,0.000000,-0.716567,-0.681718,-0.147621,-0.716567,-0.681718,0.147621,-0.525731,-0.850651,0.000000,-0.500000,-0.809017,0.309017,-0.238856,-0.864188,0.442863,-0.262866,-0.951056,0.162460,-0.864188,-0.442863,0.238856,-0.809017,-0.309017,0.500000,-0.688191,-0.587785,0.425325,-0.681718,-0.147621,0.716567,-0.442863,-0.238856,0.864188,-0.587785,-0.425325,0.688191,-0.309017,-0.500000,0.809017,-0.147621,-0.716567,0.681718,-0.425325,-0.688191,0.587785,-0.162460,-0.262866,0.951056,0.442863,-0.238856,0.864188,0.162460,-0.262866,0.951056,0.309017,-0.500000,0.809017,0.147621,-0.716567,0.681718,0.000000,-0.525731,0.850651,0.425325,-0.688191,0.587785,0.587785,-0.425325,0.688191,0.688191,-0.587785,0.425325,-0.955423,0.295242,0.000000,-0.951056,0.162460,0.262866,-1.000000,0.000000,0.000000,-0.850651,0.000000,0.525731,-0.955423,-0.295242,0.000000,-0.951056,-0.162460,0.262866,-0.864188,0.442863,-0.238856,-0.951056,0.162460,-0.262866,-0.809017,0.309017,-0.500000,-0.864188,-0.442863,-0.238856,-0.951056,-0.162460,-0.262866,-0.809017,-0.309017,-0.500000,-0.681718,0.147621,-0.716567,-0.681718,-0.147621,-0.716567,-0.850651,0.000000,-0.525731,-0.688191,0.587785,-0.425325,-0.587785,0.425325,-0.688191,-0.425325,0.688191,-0.587785,-0.425325,-0.688191,-0.587785,-0.587785,-0.425325,-0.688191,-0.688191,-0.587785,-0.425325
END SUB

'##########################################################################################################################

FUNCTION MDL_Load (Model AS MODEL, File$)
 '// Figure out model type from extension and set ID flag
 FileName$ = LTRIM$(RTRIM$(FileName$))
 Ext$ = RIGHT$(FileName$, LEN(FileName$) - INSTR(FileName$, ".")) '// get file type i.e .mdl, .md2, .3ds etc

 DIM infile AS LONG

 IF UCASE$(Ext$) = "MDL" THEN '// quake 1

  DIM TmpMdl AS MDL_Header
  DIM PixelByte AS _UNSIGNED _BYTE

  '// OPEN FILE AND GET HEADER INFO
  infile = FREEFILE
  OPEN FileName$ FOR BINARY ACCESS READ AS #infile
  GET #infile, 1, TmpMdl '// Get header info
  IF TmpMdl.Ident = 1330660425 AND TmpMdl.Version = 6 THEN '// make sure its compatible

   Model.NumFrames = TmpMdl.Num_Frames

   Model.ID = MDL '// set model id flag
   Model.HeaderPntr = _MEMNEW(LEN(TmpMdl)) '// allocate memory
   _MEMPUT Model.HeaderPntr, Model.HeaderPntr.OFFSET, TmpMdl '// put header data into memory

   '// calculate size of required memory block
   DIM TMPMDLSKIN AS MDL_Skin, TMPTEXCOORD AS MDL_TexCoord, TMPTRI AS MDL_Triangle, TMPFRAME AS MDL_Frame, TMPVERT AS MDL_Vertex

   SkinSize& = TmpMdl.Num_Skins * LEN(TMPMDLSKIN)
   TexCoordSize& = TmpMdl.Num_Verts * LEN(TMPTEXCOORD)
   TriSize& = TmpMdl.Num_Tris * LEN(TMPTRI)
   FramesSize& = TmpMdl.Num_Frames * LEN(TMPFRAME)
   VertsSize& = (TmpMdl.Num_Frames * TmpMdl.Num_Verts) * LEN(TMPVERT)
   MemBlockSize& = SkinSize& + TexCoordSize& + TriSize& + FramesSize& + VertsSize&

   '// Allocate memory
   Model.DataPntr = _MEMNEW(MemBlockSize&)

   '// Load data
   BytePos& = 1 + LEN(TmpMdl)
   MemOffset& = 0

   '// load skins
   DIM MDL_CLRS(255) AS LONG
   GDK_GL_MDL_LOAD_COLORS MDL_CLRS()

   FOR I% = 0 TO TmpMdl.Num_Skins - 1
    Model.Skin = _NEWIMAGE(TmpMdl.SkinWidth, TmpMdl.SkinHeight, 32)
    GET #infile, BytePos&, TMPMDLSKIN '//load skin data
    _MEMPUT Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TMPMDLSKIN '//store in memory block
    BytePos& = BytePos& + LEN(TMPMDLSKIN)
    MemOffset& = MemOffset& + LEN(TMPMDLSKIN)
    _DEST Model.Skin
    FOR PixelCnty% = 0 TO TmpMdl.SkinHeight - 1
     FOR PixelCntx% = 0 TO TmpMdl.SkinWidth - 1
      GET #infile, BytePos&, PixelByte
      BytePos& = BytePos& + 1
      PSET (PixelCntx%, PixelCnty%), MDL_CLRS(INT(PixelByte))
     NEXT
    NEXT
    _DEST 0
   NEXT
   Model.Skin = GDK_GL_MAKE_TEXTURE(Model.Skin)

   '// load texture coord data
   FOR I% = 0 TO TmpMdl.Num_Verts - 1
    GET #infile, BytePos&, TMPTEXCOORD
    _MEMPUT Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TMPTEXCOORD
    MemOffset& = MemOffset& + LEN(TMPTEXCOORD)
    BytePos& = BytePos& + LEN(TMPTEXCOORD)
   NEXT

   '// load triangle data
   FOR I% = 0 TO TmpMdl.Num_Tris - 1
    GET #infile, BytePos&, TMPTRI
    _MEMPUT Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TMPTRI
    MemOffset& = MemOffset& + LEN(TMPTRI)
    BytePos& = BytePos& + LEN(TMPTRI)
   NEXT

   '// load frame data
   FOR I% = 0 TO TmpMdl.Num_Frames - 1
    GET #infile, BytePos&, TMPFRAME
    BytePos& = BytePos& + LEN(TMPFRAME)
    FOR j% = 0 TO TmpMdl.Num_Verts - 1
     GET #infile, BytePos&, TMPVERT
     _MEMPUT Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TMPVERT
     MemOffset& = MemOffset& + LEN(TMPVERT)
     BytePos& = BytePos& + LEN(TMPVERT)
    NEXT
   NEXT

   '// If it got here then alls good
   CLOSE #infile
   MDL_Load = -1
   EXIT FUNCTION

  ELSE
   '//error
   MDL_Load = 0
   EXIT FUNCTION
  END IF

 END IF

END FUNCTION

'##########################################################################################################################

SUB MDL_Draw (Model AS MODEL, Frame%)


 '// Create tmpheader and load data
 DIM TmpMDL AS MDL_Header
 _MEMGET Model.HeaderPntr, Model.HeaderPntr.OFFSET, TmpMDL

 '// Animation basic error handler
 IF Frame% >= TmpMDL.Num_Frames OR Frame% < 1 THEN Frame% = 1

 '// GL arrays
 DIM VB_Vert(8, TmpMDL.Num_Tris - 1) AS SINGLE '// Vertex buffer
 DIM tc(5, TmpMDL.Num_Tris - 1) AS SINGLE '// Texture coordinate array
 DIM Norm(8, TmpMDL.Num_Tris - 1) AS SINGLE '// Normal index array

 '// dim temp arrays for model data
 DIM TmpSkin(TmpMDL.Num_Skins - 1) AS MDL_Skin
 DIM TmpTexCoord(TmpMDL.Num_Verts - 1) AS MDL_TexCoord
 DIM TmpTris(TmpMDL.Num_Tris - 1) AS MDL_Triangle
 DIM TmpFrames(TmpMDL.Num_Frames - 1) AS MDL_Frame
 DIM TmpVerts(TmpMDL.Num_Frames - 1, TmpMDL.Num_Verts - 1) AS MDL_Vertex

 '// load normal index -
 DIM MDL_NORMALS(162) AS MDL_VertexF
 GDK_GL_MDL_LOAD_NORMALS MDL_NORMALS()

 '// DEV NOTE - Need to figure out how to only load the relevant frame in memory!
 MemOffset& = LEN(TmpSkin(0))

 '// load texture coord data
 _MEMGET Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TmpTexCoord()
 MemOffset& = MemOffset& + LEN(TmpTexCoord(0)) * TmpMDL.Num_Verts

 '// load triangle data
 _MEMGET Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TmpTris()
 MemOffset& = MemOffset& + LEN(TmpTris(0)) * TmpMDL.Num_Tris

 '// load frame data
 FOR I% = 0 TO TmpMDL.Num_Frames - 1
  FOR j% = 0 TO TmpMDL.Num_Verts - 1
   _MEMGET Model.DataPntr, Model.DataPntr.OFFSET + MemOffset&, TmpVerts(I%, j%)
   MemOffset& = MemOffset& + LEN(TmpVerts(0, 0))
  NEXT
 NEXT

 '// Into gl buffer
 FOR j% = 0 TO TmpMDL.Num_Tris - 1

  VB_Vert(0, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex1).V1 * TmpMDL.Scale.X) + TmpMDL.Translate.X
  VB_Vert(1, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex1).V2 * TmpMDL.Scale.Y) + TmpMDL.Translate.Y
  VB_Vert(2, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex1).V3 * TmpMDL.Scale.Z) + TmpMDL.Translate.Z
  VB_Vert(3, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex2).V1 * TmpMDL.Scale.X) + TmpMDL.Translate.X
  VB_Vert(4, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex2).V2 * TmpMDL.Scale.Y) + TmpMDL.Translate.Y
  VB_Vert(5, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex2).V3 * TmpMDL.Scale.Z) + TmpMDL.Translate.Z
  VB_Vert(6, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex3).V1 * TmpMDL.Scale.X) + TmpMDL.Translate.X
  VB_Vert(7, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex3).V2 * TmpMDL.Scale.Y) + TmpMDL.Translate.Y
  VB_Vert(8, j%) = (TmpVerts(Frame%, TmpTris(j%).Vertex3).V3 * TmpMDL.Scale.Z) + TmpMDL.Translate.Z

  Norm(0, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex1).NormalIndex).X
  Norm(1, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex1).NormalIndex).Y
  Norm(2, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex1).NormalIndex).Z
  Norm(3, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex2).NormalIndex).X
  Norm(4, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex2).NormalIndex).Y
  Norm(5, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex2).NormalIndex).Z
  Norm(6, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex3).NormalIndex).X
  Norm(7, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex3).NormalIndex).Y
  Norm(8, j%) = MDL_NORMALS(TmpVerts(Frame%, TmpTris(j%).Vertex3).NormalIndex).Z

  IF TmpTris(j%).FacesFront THEN
   s1% = 0: s2% = 0: s3% = 0
  ELSE
   IF TmpTexCoord(TmpTris(j%).Vertex1).OnSeam THEN s1% = (TmpMDL.SkinWidth / 2) ELSE s1% = 0
   IF TmpTexCoord(TmpTris(j%).Vertex2).OnSeam THEN s2% = (TmpMDL.SkinWidth / 2) ELSE s2% = 0
   IF TmpTexCoord(TmpTris(j%).Vertex3).OnSeam THEN s3% = (TmpMDL.SkinWidth / 2) ELSE s3% = 0
  END IF

  tc(0, j%) = ((TmpTexCoord(TmpTris(j%).Vertex1).S + s1%) + .5) / TmpMDL.SkinWidth
  tc(1, j%) = (TmpTexCoord(TmpTris(j%).Vertex1).T + .5) / TmpMDL.SkinHeight
  tc(2, j%) = ((TmpTexCoord(TmpTris(j%).Vertex2).S + s2%) + .5) / TmpMDL.SkinWidth
  tc(3, j%) = (TmpTexCoord(TmpTris(j%).Vertex2).T + .5) / TmpMDL.SkinHeight
  tc(4, j%) = ((TmpTexCoord(TmpTris(j%).Vertex3).S + s3%) + .5) / TmpMDL.SkinWidth
  tc(5, j%) = (TmpTexCoord(TmpTris(j%).Vertex3).T + .5) / TmpMDL.SkinHeight

 NEXT

 '// Render
 _glEnableClientState _GL_VERTEX_ARRAY
 _glEnableClientState _GL_TEXTURE_COORD_ARRAY
 _glEnableClientState _GL_NORMAL_ARRAY
 _glBindTexture _GL_TEXTURE_2D, Model.Skin
 _glVertexPointer 3, _GL_FLOAT, 0, _OFFSET(VB_Vert())
 _glTexCoordPointer 2, _GL_FLOAT, 0, _OFFSET(tc())
 _glNormalPointer _GL_FLOAT, 0, _OFFSET(Norm())
 _glDrawArrays _GL_TRIANGLES, 0, TmpMDL.Num_Tris * 3
 _glDisableClientState _GL_VERTEX_ARRAY
 _glDisableClientState _GL_TEXTURE_COORD_ARRAY
 _glDisableClientState _GL_NORMAL_ARRAY

END SUB

'#########################################################################################################################


