[B3D] Quake III BSP Loader

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

ZaP

Betreff: [B3D] Quake III BSP Loader

BeitragFr, Jun 06, 2008 13:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi!

An dieser Stelle möchte ich meinen BSP Loader veröffentlichen, da ich an einem Punkt angelangt bin, bei dem ich meine den Loader ersteinmal so zu lassen, wie er jetzt ist.

ToDo:

- Face Type 3 und 4 zum Mesh hinzufügen
- besonders bei Face Type 3 (Curves & Patches) noch was machen, da diese die Lightmaps wesentlich beeinflussen
- BSP Tree(?)

Hier noch ein paar BSP maps zu rumspielen: http://rapidshare.de/files/396...r.zip.html (21.1 MB)

Ich hoffe, dass jemand Interesse hat und den Loader evtl. weiterentwickelt.

Naja, zu guter letzt der Code:

Code: [AUSKLAPPEN]

;
;
;      ZaP's Q3 BSP loader
;
;
Global vert_count = 0
Global face_count = 0
Global lmap_count = 0
Global surf_count = 0
Global text_count = 0
Global MISSING_TEXTURE_PATH$ = "textures/system/miss.png"


Const HEADER_LENGHT      = 3
Const AL_MAX_LUMPS      = 17      ;indeed 18! lumps
Const AL_MAX_TEXTURES   = 255
Const TW_MAX_VERTS      = 65535
Const AL_MAX_FACES      = 65535
Const AL_MAX_LMAPS      = 1023
Const AL_MAX_SURFS      = 255

SeedRnd MilliSecs()

Graphics3D 800,600,32,2
SetBuffer BackBuffer()
Local c = CreateCamera()
;CameraClsMode c,0,1
MoveEntity c,0,10,-100
CameraRange c,0.01,15000

Dim header(HEADER_LENGHT)


Dim lump_offset(AL_MAX_LUMPS)
Dim lump_lenght(AL_MAX_LUMPS)

Dim texture_name$(AL_MAX_TEXTURES)
Dim texture_flags(AL_MAX_TEXTURES)
Dim texture_content(AL_MAX_TEXTURES)
Dim texture_handle(AL_MAX_TEXTURES)

Dim plane_normal#(2,32768)
Dim plane_dist#(32768)

Dim brush_brushside(65536)
Dim brush_n_brushsides(65536)
Dim brush_texture(65536)

Dim brushside_plane(65536)
Dim brushside_texture(65536)

Dim vert_coord_x#(TW_MAX_VERTS)
Dim vert_coord_y#(TW_MAX_VERTS)
Dim vert_coord_z#(TW_MAX_VERTS)
Dim vert_text_coord_x#(TW_MAX_VERTS)
Dim vert_lmap_coord_x#(TW_MAX_VERTS)
Dim vert_text_coord_y#(TW_MAX_VERTS)
Dim vert_lmap_coord_y#(TW_MAX_VERTS)

Dim face_texture(AL_MAX_FACES)
Dim face_vertex(AL_MAX_FACES)
Dim face_n_vertex(AL_MAX_FACES)
Dim face_meshvert(AL_MAX_FACES)
Dim face_n_meshvert(AL_MAX_FACES)
Dim face_type(AL_MAX_FACES)
Dim face_lm(AL_MAX_FACES)
Dim face_patch_dims_x(AL_MAX_FACES)
Dim face_patch_dims_y(AL_MAX_FACES)


Dim lmap_r%(AL_MAX_LMAPS,AL_MAX_LMAPS)
Dim lmap_g%(AL_MAX_LMAPS,AL_MAX_LMAPS)
Dim lmap_b%(AL_MAX_LMAPS,AL_MAX_LMAPS)
Dim lmap_handle(AL_MAX_LMAPS)

Dim meshvert_offset(TW_MAX_VERTS)
Dim surface_tex(AL_MAX_SURFS)

Dim argb(0)

Local mesh

;mesh = LoadQ3BSP("maps/cyl.bsp")
;mesh = LoadQ3BSP("maps/test1.bsp")
;mesh = LoadQ3BSP("maps/acid3tourney3.bsp")
mesh = LoadQ3BSP("maps/q3dm17.bsp")
;mesh = LoadQ3BSP("maps/menu.bsp")
;mesh = LoadQ3BSP("maps/dm_plant.bsp")
;mesh = LoadQ3BSP("maps/dm_prison.bsp")
;mesh = LoadQ3BSP("maps/doortest.bsp")
;mesh = LoadQ3BSP("maps/out.bsp")


ScaleMesh mesh,0.1,0.1,0.1


CameraClsColor c,100,100,100

timer = CreateTimer(60)

Repeat
   
   WaitTimer(timer)
   
   Cls
   
   x = KeyDown(200)-KeyDown(208)
   y = KeyDown(203)-KeyDown(205)
   spd = KeyDown(17)-KeyDown(31)
   lr = KeyDown(32)-KeyDown(30)
   TurnEntity c,x*2,0,0
   TurnEntity c,0,y*2,0,1
   
   MoveEntity c,lr,0,spd
   
   RenderWorld
   
   
   AppTitle "Tris: "+TrisRendered()
   
   Flip 0

Until KeyHit(1)
End

Function LoadQ3BSP(path$)
   
   Local stream = ReadFile(path$)
   If Not stream Then DebugLog "WARNING: "+path$:Return
   
   ;read the IBSP header
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   
   Local header$ = ReadChar(stream,4)
   Local version = ReadInt(stream)
   
   If Not header$ = "IBSP" Then DebugLog "not a valid Q3BSP file":Return
   If Not version = $2E Then DebugLog "wrong version number (should be 46)":Return
   
   ;get each lump
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   
   For nlump = 0 To 17
      lump_offset(nlump) = ReadInt(stream)
      lump_lenght(nlump) = ReadInt(stream)
   Next
   
   ;first lump -> entities
   
   SeekFile(stream,lump_offset(0))
   Local BSP_ENTITIES$ = ReadChar(stream,lump_lenght(0))
   
   DebugLog BSP_ENTITIES$
   
   ;second lump, textures
   
   SeekFile(stream,lump_offset(1))
   
   For i=0 To (lump_lenght(1)-72) / 72
      texture_name$(i) = ReadChar(stream,64)
      texture_flags(i) = ReadInt(stream)
      texture_content(i) = ReadInt(stream)
      LoadBSPTextures()
      text_count = text_count + 1
   Next
   
   
   
   ;ninth lump -> brushes
   
   SeekFile(stream,lump_offset(8))
   
   For i=0 To lump_lenght(8) / 12
      brush_brushside(i) = ReadInt(stream)
      brush_n_brushsides(i) = ReadInt(stream)
      brush_texture(i) = ReadInt(stream)
   Next
   
   ;tenth lump -> brushsides
   
   SeekFile(stream,lump_offset(9))
   
   For i=0 To lump_lenght(9) / 8
      brushside_plane(i) = ReadInt(stream)
      brushside_texture(i) = ReadInt(stream)
   Next
   
   ;eleventh lump .. vertices
   
   DebugLog "################# VERTS #################"
   
   SeekFile(stream,lump_offset(10))
   
   For i=0 To (lump_lenght(10)) / 44
      
      vert_coord_x#(i) = ReadFloat(stream)
      vert_coord_y#(i) = ReadFloat(stream)
      vert_coord_z#(i) = ReadFloat(stream)
      
      vert_text_coord_x#(i) = ReadFloat(stream)
      vert_text_coord_y#(i) = ReadFloat(stream)
      vert_lmap_coord_x#(i) = ReadFloat(stream)
      vert_lmap_coord_y#(i) = ReadFloat(stream)
      
      
      
      ;skip the rest
      SeekFile(stream,FilePos(stream)+16)
      
      vert_count = vert_count + 1
      
      If vert_count > TW_MAX_VERTS
         RuntimeError "MAX_TW_VERTS"
      EndIf
      
   Next
   
   ;twelve.. meshverts
   
   DebugLog "################# MESHVERTS #################"
   
   SeekFile(stream,lump_offset(11))
   
   For i=0 To (lump_lenght(11)) / 4
      
      meshvert_offset(i) = ReadInt(stream)
   ;   If meshvert_offset(i) > 127 Then meshvert_offset(i) = 127
      
   Next
      
   ;forteenth lump -> faces
   
   DebugLog "################# FACES #################"
   
   SeekFile(stream,lump_offset(13))
   
   For i=0 To (lump_lenght(13)-104) / 104
      
      face_texture(i) = ReadInt(stream)
      ReadInt(stream) ;skip
      face_type(i) = ReadInt(stream)
      face_vertex(i) = ReadInt(stream)
      face_n_vertex(i) = ReadInt(stream)
      face_meshvert(i) = ReadInt(stream)
      face_n_meshvert(i) = ReadInt(stream)
      face_lm(i) = ReadInt(stream)
      
      If face_lm(i) < 0 Then face_lm(i) = 0
      
      SeekFile(stream,FilePos(stream)+64)
      
      face_patch_dims_x(i) = ReadInt(stream)
      face_patch_dims_y(i) = ReadInt(stream)
      
      face_count = face_count + 1
      
   Next
   
   
   ;lightmaps
   
   SeekFile(stream,lump_offset(14))
   
   lmap_count = (lump_lenght(14)) / 49152
   
   For i=0 To lmap_count
      
      For y=0 To 127
         For x=0 To 127
            lmap_r(x,y) = ReadByte(stream)
            lmap_g(x,y) = ReadByte(stream)
            lmap_b(x,y) = ReadByte(stream)
         Next
      Next
      
      lmap_handle(i) = CreateTexture(128,128)
      SetBuffer TextureBuffer(lmap_handle(i))
      
      LockBuffer
      
      For x=0 To 127
         For y=0 To 127
            rgb = lmap_r(x,y)*$10000 + lmap_g(x,y)*$100 + lmap_b(x,y)
            WritePixelFast x,y,rgb,TextureBuffer(lmap_handle(i))
         Next
      Next
      
      UnlockBuffer
      
   Next   
   
   ;free the memory
   Dim lmap_r(0,0)
   Dim lmap_g(0,0)
   Dim lmap_b(0,0)
   
   
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   AppTitle "done. creating mesh..."
   
   Local mesh = BSP_AssembleMesh()
   
   
   CloseFile(stream)
   
   AppTitle "ready."
   
   Return mesh
   
End Function


Function ReadChar$(stream, lenght)
   
   Local char$
   Local c
   
   For i=1 To lenght
      c = ReadByte(stream)
      If c > 31
         char$ = char$ + Chr(c)
      EndIf
   Next
   
   Return char$
   
End Function


Function LoadBSPTextures()
   
   ;cache all textures the map is including
   
   For i=0 To 255
      Local tname$ = texture_name$(i)
      If tname$ <> ""
         texture_handle(i) = LoadTexture(tname$)
         If Not texture_handle(i) Then texture_handle(i) = LoadTexture(MISSING_TEXTURE_PATH$)
      EndIf
   Next
   
End Function


Function BSP_AssembleMesh()
   
   Local mesh = CreateMesh()
   Local vert_index
   
   
   ;load default surface with texture-not-found brush
   
   
   For i=0 To face_count
      
      texname$ = texture_name$(face_texture(i))+".jpg"
      
      newsurf = 1
      
      
      For t=1 To surf_count
         If surface_tex(t-1) = face_texture(i)
            s = GetSurface(mesh,t)
            brush = GetSurfaceBrush(s)
            newsurf = 0
            Exit
         EndIf
      Next
      
      If newsurf
         brush = LoadBrush(texname$)
         If Not brush Then brusht = LoadTexture(MISSING_TEXTURE_PATH$):brush=CreateBrush():BrushTexture brush,brusht,0,0
         s = CreateSurface(mesh,brush)
         surf_count = surf_count + 1
         surface_tex(surf_count) = face_texture(i)
      EndIf
      
      If face_type(i) = 1
         
         
         index = face_vertex(i)
         
         
         For e=face_meshvert(i) To face_meshvert(i)+face_n_meshvert(i)-1 Step 3
            
            indexb = index+meshvert_offset(e)
            indexc = index+meshvert_offset(e+1)
            indexd = index+meshvert_offset(e+2)
            
            v0 = AddVertex(s,vert_coord_x#(indexb),vert_coord_z#(indexb),vert_coord_y#(indexb),vert_text_coord_x#(indexb),vert_text_coord_y#(indexb))
            v1 = AddVertex(s,vert_coord_x#(indexc),vert_coord_z#(indexc),vert_coord_y#(indexc),vert_text_coord_x#(indexc),vert_text_coord_y#(indexc))
            v2 = AddVertex(s,vert_coord_x#(indexd),vert_coord_z#(indexd),vert_coord_y#(indexd),vert_text_coord_x#(indexd),vert_text_coord_y#(indexd))
            
            VertexTexCoords s,v0,vert_lmap_coord_x#(indexb),vert_lmap_coord_y#(indexb),1,1
            VertexTexCoords s,v1,vert_lmap_coord_x#(indexc),vert_lmap_coord_y#(indexc),1,1
            VertexTexCoords s,v2,vert_lmap_coord_x#(indexd),vert_lmap_coord_y#(indexd),1,1
            
            AddTriangle(s,v0,v1,v2)
            
         Next
         
         
         ;------- LMAPS -------
         
         TextureBlend lmap_handle(face_lm(i)),5
         TextureCoords lmap_handle(face_lm(i)),1
         BrushTexture brush,lmap_handle(face_lm(i)),0,1
         PaintSurface s,brush
         
      EndIf
      
      If face_type(i) = 3
         
         index = face_vertex(i)
         
         For e = face_meshvert(i) To face_meshvert(i) + face_n_meshvert(i)-1 Step 3
            
            indexb = index+meshvert_offset(e)
            indexc = index+meshvert_offset(e+1)
            indexd = index+meshvert_offset(e+2)
            
            v0 = AddVertex(s,vert_coord_x#(indexb),vert_coord_z#(indexb),vert_coord_y#(indexb))
            v1 = AddVertex(s,vert_coord_x#(indexc),vert_coord_z#(indexc),vert_coord_y#(indexc))
            v2 = AddVertex(s,vert_coord_x#(indexd),vert_coord_z#(indexd),vert_coord_y#(indexd))
            
            AddTriangle(s,v0,v1,v2)
            
         Next
         
      EndIf
      
      If face_type(i) = 2
         
         lod = 6
         
         index = face_vertex(i)
         num = face_n_vertex(i)
         
         dimx = face_patch_dims_x(i)
         dimy = face_patch_dims_y(i)
         
         
         For e = index To index+num Step 3
            v0 = AddVertex(s,vert_coord_x#(e),vert_coord_z#(e),vert_coord_y#(e))
            v1 = AddVertex(s,vert_coord_x#(e+1),vert_coord_z#(e+1),vert_coord_y#(e+1))
            v2 = AddVertex(s,vert_coord_x#(e+2),vert_coord_z#(e+2),vert_coord_y#(e+2))
            
            AddTriangle(s,v0,v1,v2)
         Next
         
      EndIf
      
   Next
   
   DebugLog "### Mesh assembly completed:"
   DebugLog "Surface count = "+CountSurfaces(mesh)
   DebugLog "Triangle count = "+CountTriangles(mesh)
   DebugLog "Vertex count = "+CountVertices(mesh)
   
   
   Return mesh
   
End Function

Starfare: Worklog, Website (download)

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group