Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' Wavefront .obj viewer
- ' Data structures
- '
- ' Data is stored as a list of vertices, containing
- struc SOBJ_polyVertex
- dim vertexIndex
- dim normIndex
- endstruc
- struc SOBJ_poly
- dim firstVertex, vertexCount ' Indicates a section of the polyVertex array that makes up the current polygon
- endstruc
- struc SOBJ_model
- dim vertexCount, &vertex# ()() ' Actual X, Y, Z vertices
- dim normCount, &norm#()() ' Actual X, Y, Z normals
- dim polyVertexCount, SOBJ_polyVertex &polyVertex () ' Indices of vertices arranged into polygons
- dim polyCount, SOBJ_poly &poly () ' Polygon data
- endstruc
- ' Variables.
- ' Passed as parameters to subroutines
- dim SOBJ_model &theModel, SOBJ_poly &thePoly, theFile, theDir$, theFileName$, SOBJ_polyVertex &thePolyVertex
- dim &theVec#()
- ' Working variables
- dim i, i2, tempToken$, tempChar$, y
- ' Subroutines
- goto Start
- LoadChar:
- tempChar$ = ReadChar (theFile) ' Read character
- if tempChar$ >= "A" and tempChar$ <= "Z" then ' Convert to lowercase
- tempChar$ = Chr$ (Asc(tempChar$) - Asc("A") + Asc ("a"))
- endif
- return
- InternalLoadToken:
- ' Load a text token from file "theFile"
- ' Same as LoadToken below, but doesn't strip comments
- tempToken$ = ""
- if tempChar$ = "" then return endif
- ' Skip whitespace and format characters (except for chr$(13))
- while tempChar$ <> "" and tempChar$ <> chr$(13) and tempChar$ <= " "
- gosub LoadChar
- wend
- if tempChar$ = "" then
- return
- endif
- ' Determine token type from first character
- tempToken$ = tempChar$
- if tempChar$ >= "a" and tempChar$ <= "z" then ' Word
- ' Read character string
- gosub LoadChar
- while tempChar$ >= "a" and tempChar$ <= "z"
- tempToken$ = tempToken$ + tempChar$
- gosub LoadChar
- wend
- return
- endif
- if tempChar$ >= "0" and tempChar$ <= "9" or tempChar$ = "-" or tempChar$ = "+" or tempChar$ = "." then ' Number
- ' Read number
- gosub LoadChar
- while tempChar$ >= "0" and tempChar$ <= "9" or tempChar$ = "-" or tempChar$ = "+" or tempChar$ = "." or tempChar$ = "e"
- tempToken$ = tempToken$ + tempChar$
- gosub LoadChar
- wend
- return
- endif
- ' Treat everything else as a single character symbol
- gosub LoadChar
- return
- LoadToken:
- ' Load a text token from file "theFile"
- ' Expects: theFile = An open file handle
- ' Returns: tempToken$ = "" If end of file reached
- ' tempToken$ = chr$(13) If end of line reached
- ' tempToken$ =
- ' Load a token
- gosub InternalLoadToken
- ' Skip comments
- if tempToken$ = "#" then
- gosub InternalLoadToken
- while tempToken$ <> chr$(13) and tempToken$ <> ""
- gosub InternalLoadToken
- wend
- endif
- return
- OpenObjFile:
- theFile = OpenFileRead (theDir$ + theFileName$)
- tempChar$ = " "
- if FileError () <> "" then
- printr "Error opening " + theDir$ + theFileName$
- printr FileError ()
- end
- endif
- return
- LoadObj:
- ' Expects: theDir$ = Directory containing file(s)
- ' theFileName$ = Obj file to load
- ' File is scanned in 2 passes.
- ' First pass counts the elements of each type.
- ' Second loads them
- ' Open file
- gosub OpenObjFile
- ' Allocate model
- alloc theModel
- dim nonorm = 0
- ' First pass: Count
- printr "Count vertices, polys, normals..."
- ' for i2 = 0 to thePoly.vertexCount - 1
- ' &thePolyVertex = &theModel.polyVertex (thePoly.firstVertex + i2)
- '
- ' theModel.vertex# (thePolyVertex.vertexIndex) + 1
- '
- ' next
- gosub LoadToken
- while tempToken$ <> ""
- y = 1: gosub DisplayCounters
- if tempToken$ = "v" then
- ' Count vertex
- theModel.vertexCount = theModel.vertexCount + 1
- if nonorm = 1 then
- theModel.normCount = theModel.normCount + 1
- endif
- endif
- if tempToken$ = "vn" then
- ' Count normal
- theModel.normCount = theModel.normCount + 1
- endif
- if themodel.normCount = 0 then
- themodel.normcount = themodel.vertexcount
- nonorm = 1
- endif
- if tempToken$ = "f" then
- ' Count polygon
- theModel.polyCount = theModel.vertexCount + 1
- ' Count polygon corners
- gosub LoadToken
- while tempToken$ <> "" and tempToken$ <> chr$(13)
- theModel.polyVertexCount = theModel.polyVertexCount + 1
- while tempChar$ <> "" and tempChar$ > " " ' Skip to whitespace
- gosub LoadChar
- wend
- gosub LoadToken
- wend
- endif
- ' Skip to end of line
- while tempToken$ <> chr$(13)
- gosub LoadToken
- wend
- ' Next token
- gosub LoadToken
- wend
- gosub DisplayCounters
- ' Allocate vertices and polygons
- alloc theModel.vertex#, theModel.vertexCount - 1, 2
- alloc theModel.norm#, theModel.normCount - 1, 2
- alloc theModel.poly, theModel.polyCount - 1
- alloc theModel.polyVertex, theModel.polyVertexCount - 1
- ' Reset counters
- theModel.vertexCount = 0
- theModel.normCount = 0
- theModel.polyCount = 0
- theModel.polyVertexCount = 0
- ' Second pass. Load data
- printr "Load model..."
- CloseFile (theFile)
- gosub OpenObjFile
- gosub LoadToken
- while tempToken$ <> ""
- y = 3: gosub DisplayCounters
- if tempToken$ = "v" then ' Vector found
- ' Load in each coordinate
- y = 1: gosub LoadToken
- for i = 0 to 2
- if tempToken$ <> "" and tempToken$ <> chr$(13) then
- if nonorm = 0 then
- theModel.vertex# (theModel.vertexCount) (i) = val (tempToken$)
- else
- theModel.vertex# (theModel.vertexCount) (i) = val (tempToken$)
- theModel.norm# (theModel.normCount) (i) = val (tempToken$)
- endif
- gosub LoadToken
- endif
- next
- theModel.vertexCount = theModel.vertexCount + 1
- else
- if tempToken$ = "vn" then ' Normal found
- ' Load in coordinates
- gosub LoadToken
- for i = 0 to 2
- if tempToken$ <> "" and tempToken$ <> chr$(13) then
- theModel.norm# (theModel.normCount) (i) = val (tempToken$)
- gosub LoadToken
- endif
- next
- theModel.normCount = theModel.normCount + 1
- else
- if tempToken$ = "f" then ' Face found
- ' Record start of polygon vertices
- &thePoly = &theModel.poly (theModel.polyCount)
- theModel.polyCount = theModel.polyCount + 1
- thePoly.firstVertex = theModel.polyVertexCount
- ' Read vertices
- gosub LoadToken
- while tempToken$ <> "" and tempToken$ <> chr$(13)
- theModel.polyVertex (theModel.polyVertexCount).vertexIndex = val (tempToken$) - 1 ' Note: In the file the index is 1 origin. We are using 0 origin, so must subtract 1
- ' Vertex data stored in 3 parts, separated by slashes
- ' Look for second part
- gosub LoadToken
- if tempToken$ = "/" then
- gosub LoadToken
- ' Second part is texture coordinates which we haven't implemented yet
- ' So skip it
- if tempToken$ <> "" and tempToken$ <> chr$(13) and tempToken$ <> "/" then
- gosub LoadToken
- endif
- ' Third part is normal
- if tempToken$ = "/" then
- gosub LoadToken
- if tempToken$ <> "" and tempToken$ <> chr$(13) then
- theModel.polyVertex (theModel.polyVertexCount).normIndex = val (tempToken$) - 1
- endif
- endif
- endif
- while tempChar$ <> "" and tempChar$ > " " ' Skip to whitespace
- gosub LoadChar
- wend
- gosub LoadToken
- theModel.polyVertexCount = theModel.polyVertexCount + 1
- wend
- ' Complete polygon definition
- thePoly.vertexCount = theModel.polyVertexCount - thePoly.firstVertex
- endif
- endif
- endif
- ' Skip to end of line
- while tempToken$ <> chr$(13)
- gosub LoadToken
- wend
- ' Next token
- gosub LoadToken
- wend
- gosub DisplayCounters
- CloseFile (theFile)
- return
- DisplayCounters:
- ' Output vertex and poly counts. (To show we're actually doing something...!)
- locate 0, y: printr theModel.vertexCount + ", " + theModel.normCount + ", " + theModel.polyCount + ", " + theModel.polyVertexCount
- return
- DrawObj:
- ' Render obj model
- ' Expects: theModel = Points to model to render
- 'glpushmatrix()
- for i = 0 to theModel.polyCount - 1
- &thePoly = &theModel.poly (i)
- glpushmatrix()
- glBegin (GL_TRIANGLE_FAN)
- for i2 = 0 to thePoly.vertexCount - 1
- &thePolyVertex = &theModel.polyVertex (thePoly.firstVertex + i2)
- ' printr "drawing"
- 'if nonorm = 0 then 'create norms (if none are present then it will attempt to create one)
- 'glNormal3fv (theModel.norm# (thePolyVertex.normIndex)) 'commented it out because it kept on crashing
- 'else
- 'printr "nonorm = 1"
- 'glnormal3fv (theModel.vertex# (thePolyVertex.vertexIndex))
- 'endif
- glVertex3fv (theModel.vertex# (thePolyVertex.vertexIndex))
- next
- glEnd ()
- next
- glpopmatrix ()
- return
- ' Main program
- Start:
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- ' Test by loading a sample model
- dim SOBJ_model &model, xang#, yang#, zoom#, list, key$, saveFileName$
- 'ResizeText (60, 30)
- theDir$ = "Files\"
- theFileName$ = "level001.obj"
- gosub LoadObj
- 'Models can have several thousand vertices and polygons, which can cause our
- 'virtual machine based language to chug a little bit.
- ' Therefore we render the frame once into a display list, which will usually speed things up dramatically
- printr "Create display list..."
- list = glGenLists (1)
- glNewList (list, gl_compile)
- gosub DrawObj
- glEndList ()
- &model = &theModel
- ' Lighting
- glEnable (GL_LIGHTING)
- glEnable (GL_LIGHT0)
- glEnable (GL_COLOR_MATERIAL)
- dim camX#, camY#, camZ#, camAng# ' Camera position and direction
- dim keydowne=0
- dim camAngY#, camY2#
- dim camAngX#, camX2#
- dim pausemenu = 0
- dim mouseX, mouseY, mouseXPrev, mouseYPrev
- Dim Angle#(2)
- dim isrunning=1
- dim jumplimit = 5 'max hight reached while jumping
- dim camheight = camy2#
- 'dim BGM_Model& model = LoadBGM("Files\", "lvl4.bgm")
- dim isjumping = 0
- dim jumpup =0
- dim jumpdown=0
- dim heightbeforechange = camy2#
- 'dim i
- 'camstartcord
- camX# = 0
- camY# = 3
- camZ# = 0
- '`1gluPerspective (60, (1.0*WindowWidth()) / WindowHeight(), 0.1, 100)
- 'glMatrixMode (GL_MODELVIEW)
- while isrunning=1
- camheight = camy#
- ' Draw scene
- ' Clear the screen
- glClear (GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT)
- ' Clear the depth buffer (Z buffer)
- ' and the colour buffer (pixels)
- 'Position camera
- glLoadIdentity ()
- glRotatef(Angle#(2), 0, 0, 1)
- glRotatef(Angle#(1), 1, 0, 0)
- glRotatef(Angle#(0), 0, 1, 0)
- glTranslatef (-camX#, -camY#, -camZ#)
- glCallList (list)
- 'glTranslatef(0, -1, -5)
- 'glCallList (list)'DrawBGM(model)
- SwapBuffers ()
- ' Move camera
- while SyncTimer (10)
- Angle#(0) = Angle#(0) + Mouse_XD()*60.0
- Angle#(1) = Angle#(1) + Mouse_YD()*60.0
- if keydown ("p") then
- endif
- 'endif
- if KeyDown ("W") then
- if pausemenu = 0 then
- camX# = camX# + Cosd(Angle#(0)-90) * .2
- camZ# = camZ# + Sind(Angle#(0)-90) * .2
- endif
- endif
- if KeyDown ("S") then
- if pausemenu = 0 then
- camX# = camX# - Cosd(Angle#(0)-90) * .2
- camZ# = camZ# - Sind(Angle#(0)-90) * .2
- endif
- endif
- if KeyDown("A") Then
- if pausemenu = 0 then
- camX# = camX# - Cosd(Angle#(0)) * .2
- camZ# = camZ# - Sind(Angle#(0)) * .2
- Endif
- endif
- if KeyDown("D") Then
- if pausemenu = 0 then
- camX# = camX# + Cosd(Angle#(0)) * .2
- camZ# = camZ# + Sind(Angle#(0)) * .2
- Endif
- endif
- if isjumping = 0then
- if KeyDown("E") then
- camY# = camY# + 0.105
- keydowne = 1
- isjumping = 1
- jumpup = 1
- endif
- endif
- if isjumping =1 then
- if camheight < jumplimit then
- if jumpup =1 then
- camy# = camy# + 0.0575
- endif
- endif
- endif
- if isjumping = 1 then
- if camheight >= jumplimit then
- jumpup = 0
- jumpdown=1
- endif
- endif
- if isjumping = 1 then
- if jumpdown = 1 then
- if heightbeforechange = camy# then
- jumpdown = 0
- isjumping = 0
- endif
- endif
- endif
- if camy#<=3 then
- isjumping = 0
- jumpdown = 0
- endif
- if isjumping = 1 then
- if jumpdown = 1 then
- camy# = camy# - 0.075
- endif
- endif
- heightbeforechange = camy#
- wend
- wend
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement