source code generator fo OBJ

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

source code generator fo OBJ

Postby JohnB » Dec 15, 2005 3:53

2007 02 10

Updated scgOBJ.bas to compile with FreeBASIC v0.17

2006 01 08

Updated scgOBJ.bas, minor change, added min error checking.

Update Cube.bas, correct object rotation order, yaw, pitch, roll.

The following source code is for a converter I am working on. The Converter converts an ASC wavefront OBJ file to Freebasic OpenGL code. Only limited testing has been done on the code. If you find errors in the conversion, please point me to the OBJ file. Going out of town for the holidays, so I am posting this code a little early, not enough testing.

Compile scgOBJ , fbc scgOBJ.bas -e
Run scgOBJ, enter the file name for the cube, Cube.OBJ, this will generate Cube.bi.
Compile and run Cube.bas

Happy Holidays
JohnB


The converter.
scgOBJ.bas

Code: Select all

'
' My THANKS to the Creators of FreeBASIC !!!
'
' and following
'
' Pete's QBasic Site for QB Express
' Imortis Inglorian  for How To Program A Simple Text Parser In FB/QB
' Delphi OpenGL project for example of Wavefront .OBJ Model Loader
' R. Steven Glanville for Anim8or  and A8Viewer
'
' source code generator, scan and generate GL code for wavefront obj
' FreeBASIC - v0.15b - Win98se
'
' update to FreeBASIC - v0.17 - WinXP SP1
' remove option explicit and option base 0
' changed functions to Sub's
' changed '$ include to # include
' change array from (100) to (0 To 100)
' change allocate to callocate ------------ cha0s, thanks for the help
'
'#DEFINE VERSION "' Generated by scgOBJ.bas - version 0.5 - 20060106 - JohnB"
#DEFINE VERSION "' Generated by scgOBJ_017.bas - version 0.5 - 20070210 - JohnB"
'
'
'


#include "GL/gl.bi"

type TypeColor         ' R G B
   R as glFloat
   G as glFloat
   B as glFloat
end type

type TypeCoord         ' X, Y, Z coordinates
   X as glFloat
   Y as glFloat
   Z as glFloat
end type

type TypeTexCoord      ' texture coordinates
   U as glFloat
   V as glFloat
end type


type TypeFaceVertex
   v  as integer      ' vertex geometric
   vt as integer      ' vertex texture
   vn as integer      ' vertex normal
end type

type TypeFace
   fvIndex as integer      ' index to the first face vertices
   fvFaces as integer      ' number of face vertices in face
end type

type TypeGroup
   GName          as string
   GFaces         as integer         ' Number of faces in group
   GFirstFacePtr  as TypeFace ptr      ' Pointer to first face in group
   GMaterialIndex as integer         ' index to Material
end type

type TypeMaterial      ' material Structure
   MaterialName as string
   Ambient      as TypeColor
   Diffuse      as TypeColor
   Specular     as TypeColor
   Shininess    as glFloat
   Texture      as glUint     
end type

type TypeModel
   ModelName     as string
   MaterialFile  as string
   Vertices      as integer
   Normals       as integer
   TexCoords     as integer
   Groups        as integer
   Materials     as integer
   Faces         as integer
   FaceVertices  as integer
   VertexPtr     as TypeCoord ptr
   NormalPtr     as TypeCoord ptr
   TexCoordPtr   as TypeTexCoord ptr
   MaterialPtr   as TypeMaterial ptr
   GroupPtr      as TypeGroup ptr
   FacePtr       as TypeFace ptr
   FaceVertexPtr as TypeFaceVertex ptr
end type

' temp pointers
Dim temp_VertexPtr     as TypeCoord Ptr
Dim temp_TexCoordPtr   as TypeTexCoord Ptr
Dim temp_NormalPtr     as TypeCoord Ptr       
Dim temp_MaterialPtr   as TypeMaterial Ptr
Dim temp_GroupPtr      as TypeGroup Ptr
Dim temp_FacePtr       as TypeFace Ptr
Dim temp_FirstFacePtr  as TypeFace Ptr
Dim temp_FaceVertexPtr as TypeFaceVertex Ptr

Dim Shared Parsed(0 To 100) as String

Sub Parse(ToParse as String)
   Dim CurrentPosition as Integer
   Dim CurrentCharacter as String
   Dim WordCount as Integer      : WordCount = 0
   Dim WordSize as Integer         : WordSize = 0
   For CurrentPosition = 1 to Len(ToParse)
      CurrentCharacter = MID$(ToParse,CurrentPosition,1)
      Select Case CurrentCharacter
         Case " "
            If WordSize <> 0 Then
               Parsed(WordCount + 1) = MID$(ToParse, CurrentPosition - WordSize, WordSize)
               WordCount = WordCount + 1
            End if
            WordSize = 0
         Case Else
            WordSize = WordSize + 1
      End Select
      If CurrentPosition = Len(ToParse) And WordSize <> 0 Then
         WordSize = WordSize - 1
         WordCount = WordCount + 1
         Parsed(WordCount) = MID$(ToParse, CurrentPosition - WordSize, WordSize + 1)
      End If
   Next CurrentPosition
   Parsed(0) = MKI$(WordCount)
End Sub

Sub ParseFaceVertex(s as String , ByRef v as integer, ByRef vt as integer, ByRef vn as integer)
   Dim as integer fvtype = 0
   Dim as integer start   = 1
   Dim as integer current
   v = -1 : vt = -1 : vn = -1
   If instr(s, "/")  <> 0 Then fvtype = 1
   If instr(s, "//") <> 0 Then fvtype = 2
   Select Case fvtype
      Case 0                                       ' type v
         v = Val(s)
      Case 1                                       ' type v/vt/vn                     
         current = instr(s, "/")
         v = Val(MID$(s, start, current - start))
         start = current + 1
         current = instr(start, s, "/")
         vt = Val(MID$(s, start, current - start))
         start = current + 1
         vn = Val(MID$(s, start, Len(s) - start + 1))
      Case 2                                       ' type v//vn
         current = instr(s, "//")
         v = Val(MID$(s, start, current - start))
         start = current + 2
         vn = Val(MID$(s, start, Len(s) - start + 1))
   End Select   
End Sub

Sub InitModel(M as TypeModel)
   ' strings
   M.ModelName     = ""
   M.MaterialFile  = ""
   ' integers
   M.Vertices      = 0
   M.Normals       = 0
   M.TexCoords     = 0
   M.Materials     = 0
   M.Groups        = 0
   M.Faces         = 0
   M.FaceVertices  = 0
      ' pointers
   M.VertexPtr     = 0
   M.NormalPtr     = 0
   M.TexCoordPtr   = 0
   M.MaterialPtr   = 0
   M.GroupPtr      = 0
   M.FacePtr       = 0
   M.FaceVertexPtr = 0
End Sub

Dim as TypeModel M
Dim as Integer i, j, f, im, iv, ivt, ivn, ifv, iface, ig
Dim as String ln, model
Dim as Integer UnProcessed_Type = 0
Dim as glFloat default_Ambient(4)   = {0.2, 0.2, 0.2, 1.0}
Dim as glFloat default_Diffuse(4)   = {1.0, 1.0, 1.0, 1.0}
Dim as glFloat default_Specular(4)  = {0.6, 0.6, 0.6, 1.0}
Dim as glFloat default_Shininess(1) = {300.0}
Dim as Integer debug_flag

'------------- degug help flag --------------
debug_flag = 0
'--------------------------------------------

InitModel(M)
Print
Input "Enter model name > ",M.ModelName
'M.ModelName = "galleon_uv.obj"     ' downloaded as galleon.3ds, converted to obj with AN8,UVMapper
Print
'
'   scan obj file
'
f = FreeFile
If Open(M.ModelName For Input as #f) <> 0 Then
   Print
   Print "File "; M.ModelName; " not found."
   Print
   End
End If
'
do until eof(f)
   Line Input #f, ln
   Parse(ln)
'   Print CVI(Parsed(0))
   If CVI(Parsed(0)) <> 0 Then
      Select Case Parsed(1)
         Case "mtllib"
            M.MaterialFile = Parsed(2)
         Case "v"
            M.Vertices += 1
         Case "vn"
            M.Normals += 1
         Case "vt"
            M.TexCoords += 1
         Case "g"
            M.Groups += 1
'         Case "usemtl"
         Case "f"
            M.Faces += 1
            M.FaceVertices += (CVI(Parsed(0)) - 1)
         Case Else
            If Left(Parsed(1),1) <> "#" Then
               UnProcessed_Type += 1
               print "UnProcessed Type > ", ln
            End If
      End Select
   End If
loop
close #f
'Print "v = ";M.Vertices; "  vn = ";M.Normals; "  vt = ";M.TexCoords
'Print "g = ";M.Groups; "  f = ";M.Faces; "  fv = ";M.FaceVertices
'Print "Press any key to continue."
'Sleep
'
'   scan mtl file
'
If M.MaterialFile <> "" Then
   f = FreeFile
   If Open(M.MaterialFile For Input as #f) = 0 Then
      do until eof(f)
         Line Input #f, ln
         Parse(ln)
         If CVI(Parsed(0)) <> 0 And Parsed(1) = "newmtl" Then M.Materials += 1
      loop
      close #f

'
'   create materials array
'
      If M.Materials <> 0 Then
         M.MaterialPtr = Callocate(Len(TypeMaterial) * M.Materials)      
         f = FreeFile
         Open M.MaterialFile For Input as #f
         im = -1   ' no materials
         do until eof(f)
            Line Input #f, ln
            Parse(ln)
            If CVI(Parsed(0)) <> 0 Then
               Select Case Parsed(1)
                  Case "newmtl"
                     im += 1 : temp_MaterialPtr = M.MaterialPtr + im
                     temp_MaterialPtr->MaterialName = Parsed(2)
                  Case "Ka"
                     temp_MaterialPtr->Ambient.R = Val(Parsed(2))
                     temp_MaterialPtr->Ambient.G = Val(Parsed(3))
                     temp_MaterialPtr->Ambient.B = Val(Parsed(4))
                  Case "Kd"
                     temp_MaterialPtr->Diffuse.R = Val(Parsed(2))
                     temp_MaterialPtr->Diffuse.G = Val(Parsed(3))
                     temp_MaterialPtr->Diffuse.B = Val(Parsed(4))
                  Case "Ks"
                     temp_MaterialPtr->Specular.R = Val(Parsed(2))
                     temp_MaterialPtr->Specular.G = Val(Parsed(3))
                     temp_MaterialPtr->Specular.B = Val(Parsed(4))
                  Case "Ns"
                     temp_MaterialPtr->Shininess = Val(Parsed(2))
               End Select
            End If
         loop
         close #f
      End If
   Else
      Print
      Print "Material file not found, "; M.MaterialFile
      Print
   End If
End If
'
'   create v, vt, vn, facevertex, face, group arrays
'
f = FreeFile
If M.Vertices > 0 Then
   M.VertexPtr = Callocate(Len(TypeCoord) * M.Vertices)
   If M.TexCoords > 0 Then M.TexCoordPtr = Callocate(Len(TypeTexCoord) * M.TexCoords)
   If M.Normals   > 0 Then M.NormalPtr   = Callocate(Len(TypeCoord) * M.Normals)
   If M.Groups > 0 Then M.GroupPtr = Callocate(Len(TypeGroup) * M.Groups)
   If M.Faces > 0 Then M.FacePtr = Callocate(Len(TypeFace) * M.Faces)
   If M.FaceVertices > 0 Then M.FaceVertexPtr = Callocate(Len(TypeFaceVertex) * M.FaceVertices)
   iv = -1 : ivt = -1 : ivn = -1 : ifv = -1 : iface = -1 : ig = -1
   temp_GroupPtr = M.GroupPtr : temp_FacePtr = M.FacePtr : temp_FaceVertexPtr = M.FaceVertexPtr
   Open M.ModelName For Input as #f
   do until eof(f)
      Line Input #f, ln
      Parse(ln)
      If CVI(Parsed(0)) <> 0 then
         Select Case Parsed(1)
            Case "mtllib"
            Case "v"
               iv +=1 : temp_VertexPtr = M.VertexPtr + iv
               temp_VertexPtr->X = Val(Parsed(2))
               temp_VertexPtr->Y = Val(Parsed(3))
               temp_VertexPtr->Z = Val(Parsed(4))
            Case "vn"
               ivn +=1 : temp_NormalPtr = M.NormalPtr + ivn
               temp_NormalPtr->X = Val(Parsed(2))
               temp_NormalPtr->Y = Val(Parsed(3))
               temp_NormalPtr->Z = Val(Parsed(4))
            Case "vt"
               ivt += 1 : temp_TexCoordPtr = M.TexCoordPtr + ivt
               temp_TexCoordPtr->U =  Val(Parsed(2))
               temp_TexCoordPtr->V =  Val(Parsed(3))
            Case "usemtl"
               If M.MaterialFile <> "" And M.Materials <> 0 Then
                  For i = 0 to M.Materials -1
                     temp_MaterialPtr = M.MaterialPtr + i
                     If Parsed(2) = temp_MaterialPtr->MaterialName Then
                         temp_GroupPtr->GMaterialIndex = i
                         Exit For
                     Endif
                  Next i
               End If
            Case "g"
               ig += 1 : temp_GroupPtr = M.GroupPtr + ig
               If CVI(Parsed(0)) > 1 Then
                  temp_GroupPtr->GName  = Parsed(2)
               Else
                  temp_GroupPtr->GName  = ""
               End If
               temp_GroupPtr->GFaces = 0
               temp_GroupPtr->GFirstFacePtr  = M.FacePtr + iface + 1
               temp_GroupPtr->GMaterialIndex = -1
            Case "f"
               iface += 1
               temp_GroupPtr->GFaces += 1
               temp_FacePtr = M.FacePtr + iface
               temp_FacePtr->fvIndex = ifv + 1
               temp_FacePtr->fvFaces = CVI(Parsed(0)) - 1
               For i = 0 to temp_FacePtr->fvFaces -1
                  ifv += 1 : temp_FaceVertexPtr = M.FaceVertexPtr + ifv
                  ParseFaceVertex(Parsed(i + 2), temp_FaceVertexPtr->v, temp_FaceVertexPtr->vt, temp_FaceVertexPtr->vn)
               Next i
            Case Else
               If Left(Parsed(1),1) <> "#" Then
                  UnProcessed_Type += 1
                  print "UnProcessed Type > ", ln
               End If
         End Select
      End If
   loop
   close #f
End If
Print "end of create loop"
'
' at this point, the wavefront obj data is store in the types, arrays etc
' the following code generates gl source code that can be used with FreeBASIC
'

'print
'print "TypeColor        ", Len(TypeColor)
'print "TypeCoord        ", Len(TypeCoord)
'print "TypeTexCoord     ", Len(TypeTexCoord)
'print "TypeMaterial     ", Len(TypeMaterial)
'print "TypeGroup        ", Len(TypeGroup)
'print "TypeFace         ", Len(TypeFace)
'print "TypeFaceVertex   ", Len(TypeFaceVertex)
'sleep

'print
'print "iv = "; iv+1; "  vt = "; ivt+1; "  ivn = "; ivn+1
'print "ifv = "; ifv+1; "  iface = "; iface+1; "  ig = "; ig+1
'print
'print "GroupPtr = "; M.GroupPtr;"   FacePtr = "; M.FacePtr;"   FaceVertexPtr = "; M.FaceVertexPtr
'print

'
' output to a file
'

f = FreeFile
Open Left(M.ModelName, instr(M.ModelName, ".")) + "bi"  For Output  AS #f

Print #f, "'"
Print #f, VERSION
Print #f, "'"
Print #f, "' model name       ", M.ModelName
Print #f, "' material file    ", M.MaterialFile
Print #f, "' materials        ", M.Materials
Print #f, "' verttices        ", M.Vertices
Print #f, "' tex coords       ", M.TexCoords
Print #f, "' normals          ", M.Normals
Print #f, "' groups           ", M.Groups
Print #f, "' faces            ", M.Faces
Print #f, "' face vertices    ", M.FaceVertices
Print #f, "' UnProcessed Type ", UnProcessed_Type
Print #f, "'"

'
' do we have data to create file
'
If M.Groups <> 0 And M.Faces <> 0 And M.Vertices <> 0 Then   
      
'
' find min max for x,y,z vertices
'
   Dim as glFloat vx_min, vx_max, vy_min, vy_max, vz_min, vz_max, vx_temp, vy_temp, vz_temp
'
   vx_min = M.VertexPtr->X : vx_max = vx_min
   vy_min = M.VertexPtr->Y : vy_max = vy_min
   vz_min = M.VertexPtr->Z : vz_max = vz_min
'
   For iv = 0 to M.Vertices -1
      vx_temp = (M.VertexPtr + iv)->X
      vy_temp = (M.VertexPtr + iv)->Y
      vz_temp = (M.VertexPtr + iv)->Z
   
      If vx_temp < vx_min Then vx_min = vx_temp
      If vx_temp > vx_max Then vx_max = vx_temp
   
      If vy_temp < vy_min Then vy_min = vy_temp
      If vy_temp > vy_max Then vy_max = vy_temp
   
      If vz_temp < vz_min Then vz_min = vz_temp
      If vz_temp > vz_max Then vz_max = vz_temp
   Next iv
   Print #f, "'"
   Print #f, "' vx min = "; vx_min; "    vx_max = "; vx_max
   Print #f, "' vy min = "; vy_min; "    vy_max = "; vy_max
   Print #f, "' vz min = "; vz_min; "    vz_max = "; vz_max
   Print #f, "'"
   Print #f,

'   
' generate code for Materials
'
   If M.Materials <> 0 Then
      Print #f, "'"
      Print #f, "' Generate Material Variables"
      Print #f, "'"
      For im = 0 to M.Materials - 1
         temp_MaterialPtr = M.MaterialPtr + im
      ' Ambient
         Print #f, "Dim as glFloat "; temp_MaterialPtr->MaterialName; "_Ambient(4) = {";
         Print #f, temp_MaterialPtr->Ambient.R; ",";temp_MaterialPtr->Ambient.G; ",";temp_MaterialPtr->Ambient.R; ", 1.0 }"
      ' Diffuse
         Print #f, "Dim as glFloat "; temp_MaterialPtr->MaterialName; "_Diffuse(4) = {";
         Print #f, temp_MaterialPtr->Diffuse.R; ",";temp_MaterialPtr->Diffuse.G; ",";temp_MaterialPtr->Diffuse.R; ", 1.0 }"
      ' Specular
         Print #f, "Dim as glFloat "; temp_MaterialPtr->MaterialName; "_Specular(4) = {";
         Print #f, temp_MaterialPtr->Specular.R; ",";temp_MaterialPtr->Specular.G; ",";temp_MaterialPtr->Specular.R; ", 1.0 }"
      ' Shininess
         Print #f, "Dim as glFloat "; temp_MaterialPtr->MaterialName; "_Shininess(1) = {" ;temp_MaterialPtr->Shininess; " }"
   '      Print #f, "'"   
      Next i
   Else
      ' add code for default Ambient, Diffuse, Specular and Shininess
      ' Ambient
      Print #f, "Dim as glFloat default_Ambient(4) = { 0.2, 0.2, 0.2, 1.0 }"
      ' Diffuse
      Print #f, "Dim as glFloat default_Diffuse(4) = { 1.0, 1.0, 1.0, 1.0 }"
      ' Specular
      Print #f, "Dim as glFloat default_Specular(4) = { 0.6, 0.6, 0.6, 1.0 }"
      ' Shininess
      Print #f, "Dim as glFloat default_Shininess(1) = { 300.0 }"
   End If
   
'
'   generate code for Group Faces, possible zero faces in group !!!
'
   If M.Groups <> 0 Then
      For ig = 0 to M.Groups - 1
         temp_GroupPtr = M.GroupPtr + ig
         Print #f, "'"
         Print #f, "' Group Name                    "; temp_GroupPtr->GName
         Print #f, "' Number of Faces in the Group  "; temp_GroupPtr->GFaces
         Print #f,
          If temp_GroupPtr->GFaces > 0 Then
            If (M.Materials > 0) And (temp_GroupPtr->GMaterialIndex <> -1) Then
               temp_MaterialPtr = M.MaterialPtr + temp_GroupPtr->GMaterialIndex
               Print #f, "' Material Name             "; temp_MaterialPtr->MaterialName
               Print #f, "'"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, @";   temp_MaterialPtr->MaterialName; "_Ambient(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, @";   temp_MaterialPtr->MaterialName; "_Diffuse(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @";  temp_MaterialPtr->MaterialName; "_Specular(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, @"; temp_MaterialPtr->MaterialName; "_Shininess(0))"
               Print #f,
            Else
               Print #f, "' No Material in obj file, using default material"
               Print #f, "'"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, @default_Ambient(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, @default_Diffuse(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @default_Specular(0))"
               Print #f, "glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, @default_Shininess(0))"
               Print #f,
            End If
            For iface = 0 to temp_GroupPtr->GFaces - 1
               temp_FacePtr = temp_GroupPtr->GFirstFacePtr + iface
               ifv = temp_FacePtr->fvIndex
               Select Case temp_FacePtr->fvFaces
                  Case 3
                     Print #f, "glBegin(GL_TRIANGLES)"
                  Case 4
                     Print #f, "glBegin(GL_QUADS)"
                  Case Else
                     Print #f, "glBegin(GL_POLYGON)"
               End Select
               For i = 0 to temp_FacePtr->fvFaces - 1
                  temp_FaceVertexPtr = M.FaceVertexPtr + ifv + i
                  iv =  temp_FaceVertexPtr->v
                  ivt = temp_FaceVertexPtr->vt
                  ivn = temp_FaceVertexPtr->vn
                  If ivt > 0 Then
                     Print #f, "glTexCoord2f( "; (M.TexCoordPtr + ivt -1)->U; ","; (M.TexCoordPtr + ivt -1)->V; " )"
                  End If
                  If ivn > 0 Then
                     Print #f, "glNormal3f( ";
                     Print #f,  (M.NormalPtr + ivn -1)->X; ","; (M.NormalPtr + ivn -1)->Y; ","; (M.NormalPtr + ivn -1)->Z; " )"
                  End If
                  If iv  > 0 Then
                     Print #f, "glVertex3f( ";
                     Print #f, (M.VertexPtr + iv -1)->X; ","; (M.VertexPtr + iv -1)->Y; ",";(M.VertexPtr + iv -1)->Z; " )"
                  End If
               Next i
               Print #f, "glEnd()"
               Print #f,
            Next iface
         End If
      Next ig
   End If

Else
   Print
   Print "See Data in Output file.
   Print
End If

If M.Vertices     > 0 Then DeAllocate(M.VertexPtr)
If M.TexCoords    > 0 Then DeAllocate(M.TexCoordPtr)
If M.Normals      > 0 Then DeAllocate(M.NormalPtr)
If M.Materials    > 0 Then DeAllocate(M.MaterialPtr)
If M.Groups       > 0 Then DeAllocate(M.GroupPtr)
If M.Faces        > 0 Then DeAllocate(M.FacePtr)
If M.FaceVertices > 0 Then DeAllocate(M.FaceVertexPtr)
Close #f
Print
Print "Output file is > "; Left(M.ModelName, instr(M.ModelName, ".")) + "bi"
Print "Press any key to continue."
Sleep
End




A simple cube.
Cube.obj

Code: Select all

# file generated by UVMapper
# NumVerts/NumTVerts/NumVNormals/NumFacets   8/24/30/6
# NumGroups/NumMaterials/NumRegions   1/0/0
# x/y/color/ppu   1024/768/0/50.00000000

v -30.00000000 -30.00000000 -30.00000000
v -30.00000000 -30.00000000  30.00000000
v -30.00000000  30.00000000 -30.00000000
v -30.00000000  30.00000000  30.00000000
v  30.00000000 -30.00000000 -30.00000000
v  30.00000000 -30.00000000  30.00000000
v  30.00000000  30.00000000 -30.00000000
v  30.00000000  30.00000000  30.00000000

vt  0.98000002  0.65000004
vt  0.75500000  0.65000004
vt  0.75500000  0.35000002
vt  0.98000002  0.35000002
vt  0.48999998  0.35000002
vt  0.48999998  0.65000004
vt  0.26499999  0.65000004
vt  0.26499999  0.35000002
vt  0.24499999  0.35000002
vt  0.24499999  0.65000004
vt  0.02000000  0.65000004
vt  0.02000000  0.35000002
vt  0.73500001  0.65000004
vt  0.50999999  0.65000004
vt  0.50999999  0.35000002
vt  0.73500001  0.35000002
vt  0.26499999  0.67500001
vt  0.48999998  0.67500001
vt  0.48999998  0.97500002
vt  0.26499999  0.97500002
vt  0.48999998  0.02500000
vt  0.48999998  0.32500002
vt  0.26499999  0.32500002
vt  0.26499999  0.02500000

vn  0.00000000  0.00000000 -1.00000000
vn  0.00000000  0.00000000  1.00000000
vn -1.00000000  0.00000000  0.00000000
vn  1.00000000  0.00000000  0.00000000
vn  0.00000000  1.00000000  0.00000000
vn  0.00000000 -1.00000000  0.00000000
vn  0.00000000  0.00000000 -1.00000000
vn  0.00000000 -1.00000000  0.00000000
vn -1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000  1.00000000
vn  0.00000000 -1.00000000  0.00000000
vn -1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000 -1.00000000
vn  0.00000000  1.00000000  0.00000000
vn -1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000  1.00000000
vn  0.00000000  1.00000000  0.00000000
vn -1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000 -1.00000000
vn  0.00000000 -1.00000000  0.00000000
vn  1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000  1.00000000
vn  0.00000000 -1.00000000  0.00000000
vn  1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000 -1.00000000
vn  0.00000000  1.00000000  0.00000000
vn  1.00000000  0.00000000  0.00000000
vn  0.00000000  0.00000000  1.00000000
vn  0.00000000  1.00000000  0.00000000
vn  1.00000000  0.00000000  0.00000000

g group1
f 3/1/13 7/2/25 5/3/19 1/4/7
f 6/5/22 8/6/28 4/7/16 2/8/10
f 2/9/12 4/10/18 3/11/15 1/12/9
f 7/13/27 8/14/30 6/15/24 5/16/21
f 4/17/17 8/18/29 7/19/26 3/20/14
f 5/21/20 6/22/23 2/23/11 1/24/8


The viewer.
Cube.bas

Code: Select all

'
' display cube
' FreeBASIC - v0.15b - Win98se
' cube.bas  - 20060106 - JohnB
'
'
' 20060106 - fixed object rotation, order needed to be yaw, pitch, roll
'
Option Explicit
Option Base 0

'$include: "SDL/SDL.bi"
'$include: "SDL/SDL_mouse.bi"
'$include: "GL/gl.bi"
'$include: "GL/glu.bi"
'
'SDL code
'
Dim result As unSigned Integer
Dim video As SDL_Surface Ptr
Dim event As SDL_Event

'Dim w   As Integer : w   = 800
'Dim h   As Integer : h   = 600
Dim w   As Integer : w   = 1024
Dim h   As Integer : h   = 768

Dim bpp As Integer : bpp = 32

dim passes as integer
dim time_start as integer
dim time_end as integer

result = SDL_Init(SDL_INIT_EVERYTHING)
If result <> 0 Then
   End 1
End If

SDL_GL_SetAttribute SDL_GL_DOUBLEBUFFER, 1

dim flags as uinteger : flags = SDL_FULLSCREEN Or SDL_OPENGL Or SDL_OPENGLBLIT Or SDL_HWSURFACE Or SDL_HWACCEL Or SDL_OPENGLBLIT
video = SDL_SetVideoMode(w, h, bpp, flags)
If video = 0 Then
   SDL_Quit
   End 1
End If

glViewport 0, 0, w, h
 
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 80/2, w / h, 1.0, 5000.0
   
glMatrixMode GL_MODELVIEW
glLoadIdentity

glShadeModel GL_SMOOTH
glClearColor 0.0, 0.0, 0.0, 1.0
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST

'
'lights
'   
Dim lightAmb(4) As Single : lightAmb(0) = 0.1 : lightAmb(1) = 0.1 : lightAmb(2) = 0.1 : lightAmb(3) = 1.0
Dim lightDif(4) As Single : lightDif(0) = 1.0 : lightDif(1) = 1.0 : lightDif(2) = 1.0 : lightDif(3) = 1.0
Dim lightSpec(4) As Single : lightSpec(0) = 0.2 : lightSpec(1) = 0.2 : lightSpec(2) = 0.2 : lightSpec(3) = 1.0
Dim lightPos(4) As Single : lightPos(0) = 120.0 : lightPos(1) = 120.0 : lightPos(2) = 120.0 : lightPos(3) = 1.0

glLightfv GL_LIGHT1, GL_AMBIENT, @lightAmb(0)
glLightfv GL_LIGHT1, GL_DIFFUSE, @lightDif(0)
glLightfv GL_LIGHT1, GL_SPECULAR, @lightSpec(0)
glLightfv GL_LIGHT1, GL_POSITION,@lightPos(0)
glEnable GL_LIGHT1
glEnable GL_LIGHTING


glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
glDisable(GL_TEXTURE_2D)

dim cube1 as uinteger
cube1 = glGenLists(1)
glNewList cube1, GL_COMPILE
'
' insert generated code here
' -----------------------------------------------------------------------------
'$include: "Cube.bi"
' -----------------------------------------------------------------------------
' end generated code
'
glEndList

dim done as integer : done = 0
dim z_start as single : z_start = -120.0

dim world_rotate_x as single : world_rotate_x = 0.0
dim world_rotate_y as single : world_rotate_y = 0.0

dim object_translate_x as single : object_translate_x = 0.0
dim object_translate_y as single : object_translate_y = 0.0
dim object_translate_z as single : object_translate_z = z_start

dim object_rotate_x as single : object_rotate_x = 0.0
dim object_rotate_y as single : object_rotate_y = 0.0
dim object_rotate_z as single : object_rotate_z = 0.0


SDL_EnableKeyRepeat(1, 1)
SDL_ShowCursor 0

passes = 0
time_start = timer

do while (done = 0)
   
   passes += 1
   
   glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
    glPushMatrix
   
   glRotatef(world_rotate_y, 0.0, 1.0, 0.0)
   glRotatef(world_rotate_x, 1.0, 0.0, 0.0)

   glTranslatef object_translate_x, object_translate_y, object_translate_z

   glRotatef(object_rotate_z, 0.0, 0.0, 1.0)
   glRotatef(object_rotate_x, 1.0, 0.0, 0.0)
   glRotatef(object_rotate_y, 0.0, 1.0, 0.0)

   glCallList cube1
   
   glPopMatrix           

     SDL_GL_SwapBuffers
   do while (SDL_PollEvent(@event))
       if (event.type = SDL_QUIT_) then done = 1
         if (event.type = SDL_KEYDOWN) then
         select case event.key.keysym.sym
            case SDLK_ESCAPE
               done = 1
            case SDLK_UP
               world_rotate_x += 0.1
            case SDLK_DOWN
               world_rotate_x -= 0.1
            case SDLK_LEFT
               world_rotate_y += 0.1
            case SDLK_RIGHT
               world_rotate_y -= 0.1
            case SDLK_PAGEUP
               object_translate_z += 1.0
            case SDLK_PAGEDOWN
               object_translate_z -= 1.0
            case SDLK_KP2
               object_rotate_x += 1.0
            case SDLK_KP8
               object_rotate_x -= 1.0
            case SDLK_KP6
               object_rotate_y += 1.0
            case SDLK_KP4
               object_rotate_y -= 1.0
            case SDLK_KP1
               object_rotate_z += 1.0
            case SDLK_KP3
               object_rotate_z -= 1.0
            case SDLK_r
               world_rotate_x = 0.0
               world_rotate_y = 0.0
               object_translate_z = z_start
               object_rotate_x = 0.0
               object_rotate_y = 0.0
               object_rotate_z = 0.0
            end select                       
        end if
     loop
loop

SDL_ShowCursor 1
SDL_Quit

time_end = timer
print "Passes = ", passes
print "FPS = ", passes/(time_end - time_start)
print

End
Last edited by JohnB on Feb 11, 2007 3:55, edited 2 times in total.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Other Credits

Postby JohnB » Dec 15, 2005 6:22

'
' Pete's QBasic Site for QB Express
' Imortis Inglorian for How To Program A Simple Text Parser In FB/QB
' Delphi OpenGL project for Wavefront .OBJ Model Loader
' R. Steven Glanville for Anim8or and A8Viewer
'

JohnB
Imortis
Moderator
Posts: 1744
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Postby Imortis » Dec 21, 2005 21:52

You found my tutorial helpful? Right on!
ShadowDust
Posts: 274
Joined: Oct 13, 2005 2:05
Contact:

Postby ShadowDust » Dec 25, 2005 5:37

*backspaces entire post* u know.... im just gonna be quiet... :D
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Update

Postby JohnB » Jan 09, 2006 6:02

Updated scgOBJ.bas and Cube.bas.

This is a request for information, need fps info on common model. If you have time, download galleon.3ds from 3D Cafe, convert to .obj, convert and run. I am interested in fps, please specify hardware.

Thanks

JohnB

P.S. I did .3ds to .obj conversion using Anim8or.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Feb 11, 2007 3:58

Updated scgOBJ.bas - 2007 02 10.

JohnB
antibyte
Posts: 11
Joined: Jun 13, 2007 17:46
Location: Germany

Re: Update

Postby antibyte » Jun 13, 2007 17:50

837 FPS on Nvidia GeForce 6800 GT (Linux)


JohnB wrote:Updated scgOBJ.bas and Cube.bas.

This is a request for information, need fps info on common model. If you have time, download galleon.3ds from 3D Cafe, convert to .obj, convert and run. I am interested in fps, please specify hardware.

Thanks

JohnB

P.S. I did .3ds to .obj conversion using Anim8or.
Imortis
Moderator
Posts: 1744
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Postby Imortis » Sep 11, 2007 23:44

I hate to be a thread necromancer here, but how would I use this with mtl files. Right now it skips them. Would an mtl be used as a texture in openGL?
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Postby JohnB » Sep 12, 2007 6:11

I could not get a good format description for mtl. I assume it is something like materials in povray.

The following is an example of texture mapping. Just create 2n x 2n bmp for a texture.

texcube2.bas

Code: Select all

'
' display textured cube
' FreeBASIC - v0.18 - Win98se/WinXP
' texcube2.bas  - 20070912 - JohnB
'
#include "SDL/SDL.bi"
#include "SDL/SDL_mouse.bi"
#include "GL/gl.bi"
#include "GL/glu.bi"

#include once "bmpload.bi"
declare function LoadGLTextures() as integer

'' Setup our booleans
const FALSE = 0
const TRUE  = not FALSE

'
'SDL code
'
Dim result As unSigned Integer
Dim video As SDL_Surface Ptr
Dim event As SDL_Event

'Dim w   As Integer : w   = 800
'Dim h   As Integer : h   = 600
Dim w   As Integer : w   = 1024
Dim h   As Integer : h   = 768

Dim bpp As Integer : bpp = 32

dim passes as integer
dim time_start as integer
dim time_end as integer

result = SDL_Init(SDL_INIT_EVERYTHING)
If result <> 0 Then
   End 1
End If

SDL_GL_SetAttribute SDL_GL_DOUBLEBUFFER, 1

dim flags as uinteger : flags = SDL_FULLSCREEN Or SDL_OPENGL Or SDL_OPENGLBLIT Or SDL_HWSURFACE Or SDL_HWACCEL Or SDL_OPENGLBLIT
video = SDL_SetVideoMode(w, h, bpp, flags)
If video = 0 Then
   SDL_Quit
   End 1
End If

glViewport 0, 0, w, h
 
glMatrixMode GL_PROJECTION
glLoadIdentity
gluPerspective 80/2, w / h, 1.0, 5000.0
   
glMatrixMode GL_MODELVIEW
glLoadIdentity

glShadeModel GL_SMOOTH
glClearColor 0.0, 0.0, 0.0, 1.0
glClearDepth 1.0
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST

'
'lights
'   
Dim lightAmb(4) As Single : lightAmb(0) = 0.1 : lightAmb(1) = 0.1 : lightAmb(2) = 0.1 : lightAmb(3) = 1.0
Dim lightDif(4) As Single : lightDif(0) = 1.0 : lightDif(1) = 1.0 : lightDif(2) = 1.0 : lightDif(3) = 1.0
Dim lightSpec(4) As Single : lightSpec(0) = 0.2 : lightSpec(1) = 0.2 : lightSpec(2) = 0.2 : lightSpec(3) = 1.0
Dim lightPos(4) As Single : lightPos(0) = 120.0 : lightPos(1) = 120.0 : lightPos(2) = 120.0 : lightPos(3) = 1.0

glLightfv GL_LIGHT1, GL_AMBIENT, @lightAmb(0)
glLightfv GL_LIGHT1, GL_DIFFUSE, @lightDif(0)
glLightfv GL_LIGHT1, GL_SPECULAR, @lightSpec(0)
glLightfv GL_LIGHT1, GL_POSITION,@lightPos(0)
glEnable GL_LIGHT1
glEnable GL_LIGHTING

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

'
' texture mapping
'

dim shared texture(0) as GLuint               '' Storage For One Texture ( NEW )
   '' Jump To Texture Loading Routine
   if (LoadGLTextures() = false) then
      end 1                                        '' If Texture Didn't Load Quit
   end if
glEnable GL_TEXTURE_2D                         '' Enable Texture Mapping ( NEW )



' generate list for cube
   dim cube1 as uinteger
   cube1 = glGenLists(1)
   glNewList cube1, GL_COMPILE
'
' insert generated code here
' -----------------------------------------------------------------------------
#include "cube.bi"
' -----------------------------------------------------------------------------
' end generated code
'
glEndList

dim done as integer : done = 0
dim z_start as single : z_start = -120.0

dim world_rotate_x as single : world_rotate_x = 0.0
dim world_rotate_y as single : world_rotate_y = 0.0

dim object_translate_x as single : object_translate_x = 0.0
dim object_translate_y as single : object_translate_y = 0.0
dim object_translate_z as single : object_translate_z = z_start

dim object_rotate_x as single : object_rotate_x = 0.0
dim object_rotate_y as single : object_rotate_y = 0.0
dim object_rotate_z as single : object_rotate_z = 0.0


SDL_EnableKeyRepeat(1, 1)
SDL_ShowCursor 0

passes = 0
time_start = timer

do while (done = 0)
   
   passes += 1
   
   glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
      glPushMatrix
   
   glRotatef(world_rotate_y, 0.0, 1.0, 0.0)
   glRotatef(world_rotate_x, 1.0, 0.0, 0.0)

   glTranslatef object_translate_x, object_translate_y, object_translate_z

   glRotatef(object_rotate_z, 0.0, 0.0, 1.0)
   glRotatef(object_rotate_x, 1.0, 0.0, 0.0)
   glRotatef(object_rotate_y, 0.0, 1.0, 0.0)

   ' bind texture to cube1
   glBindTexture GL_TEXTURE_2D, texture(0)
   glCallList cube1
   
   glPopMatrix           

   SDL_GL_SwapBuffers

   do while (SDL_PollEvent(@event))
      if (event.type = SDL_QUIT_) then done = 1
         if (event.type = SDL_KEYDOWN) then
         select case event.key.keysym.sym
            case SDLK_ESCAPE
               done = 1
            case SDLK_UP
               world_rotate_x += 0.1
            case SDLK_DOWN
               world_rotate_x -= 0.1
            case SDLK_LEFT
               world_rotate_y += 0.1
            case SDLK_RIGHT
               world_rotate_y -= 0.1
            case SDLK_PAGEUP
               object_translate_z += 1.0
            case SDLK_PAGEDOWN
               object_translate_z -= 1.0
            case SDLK_KP2,SDLK_s
               object_rotate_x += 1.0
            case SDLK_KP8,SDLK_w
               object_rotate_x -= 1.0
            case SDLK_KP6,SDLK_e
               object_rotate_y += 1.0
            case SDLK_KP4,SDLK_q
               object_rotate_y -= 1.0
            case SDLK_KP1,SDLK_a
               object_rotate_z += 1.0
            case SDLK_KP3,SDLK_d
               object_rotate_z -= 1.0
            case SDLK_r
               world_rotate_x = 0.0
               world_rotate_y = 0.0
               object_translate_z = z_start
               object_rotate_x = 0.0
               object_rotate_y = 0.0
               object_rotate_z = 0.0
         end select                       
       end if
   loop
loop
glDeleteTextures 1, @texture(0)
SDL_ShowCursor 1
SDL_Quit

time_end = timer
print "Passes = ", passes
print "FPS = ", passes/(time_end - time_start)
print

End


'' Load Bitmaps And Convert To Textures
function LoadGLTextures() as integer
  dim Status as integer = FALSE                     '' Status Indicator
  dim TextureImage(0) as BITMAP_RGBImageRec ptr     '' Create Storage Space For The Texture

  ' Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
  TextureImage(0) = LoadBMP("cube2.bmp")
  if TextureImage(0) then
    Status = TRUE                                   '' Set The Status To TRUE
    glGenTextures 1, @texture(0)                    '' Create The Texture
    ' Typical Texture Generation Using Data From The Bitmap
    glBindTexture GL_TEXTURE_2D, texture(0)
    glTexImage2D GL_TEXTURE_2D, 0, 3, TextureImage(0)->sizeX, TextureImage(0)->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage(0)->buffer
    glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
    glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
  end if

  if TextureImage(0) then                           '' If Texture Exists
    if TextureImage(0)->buffer then                 '' If Texture Image Exist
      deallocate(TextureImage(0)->buffer)           '' Free The Texture Image Memory
    end if
    deallocate(TextureImage(0))                     '' Free The Image Structure
  end if

  return Status                                     '' Return The Status
end function
Imortis
Moderator
Posts: 1744
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Postby Imortis » Sep 12, 2007 12:12

I am trying to make a simple 3D engine that will use obj files for it's graphics. I found a few models to convert with your code, but they have textures. I don't think they fit the openGL texture restrictions.

Thanks for the example. I am going to try to find something on the MTL format and see if I can make this fully functional.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 7 guests