Advertisement
Guest User

Untitled

a guest
Oct 1st, 2016
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
BlitzMax 28.27 KB | None | 0 0
  1. SuperStrict
  2. Framework sidesign.minib3d 'https://github.com/si-design/minib3d
  3. Import brl.Stream
  4. Import brl.linkedlist
  5. Import brl.standardio
  6. Import brl.bmploader
  7. Import brl.pngloader
  8.  
  9. 'Data sizes
  10. Const B_BYTE:Int = 1
  11. Const B_SHORT:Int = 2
  12. Const B_INT:Int = 4
  13. Const B_FLOAT:Int = 4
  14.  
  15. SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER
  16. Graphics3D(DesktopWidth() * 0.7, DesktopHeight() * 0.7, 0, 2)
  17. ClearTextureFilters()
  18.  
  19. Global camera:TCamera = CreateCamera()
  20. MoveEntity(camera, 0, 0, -10)
  21.  
  22. 'AmbientLight(255, 255, 255)
  23. 'Local light:TLight = CreateLight(1)
  24. 'RotateEntity(light, 45, 45, 0)
  25.  
  26. TQPalette.LoadPalette("palette.lmp")
  27. Global myBSP:TQBSP
  28. Global levelMesh:TMesh
  29. Global levelMeshAlpha:TMesh
  30.  
  31. 'Debug make a mesh
  32. Function GenerateBSPMesh(mesh:TMesh var, alphaMesh:TMesh var, myBSP:TQBSP)
  33.     If mesh Then FreeEntity(mesh)
  34.     If alphaMesh Then FreeEntity(alphaMesh)
  35.     'Local mesh:TMesh = CreateMesh()
  36.     'Local surf:TSurface[1024 * 10]
  37.    
  38.     GCCollect()
  39.    
  40.     mesh = CreateMesh()
  41.     alphaMesh = CreateMesh()
  42.    
  43.     Local face:TQFace
  44.     Local ledge:TQLedge
  45.     Local edge:TQEdge
  46.     Local plane:TQPlane
  47.     Local texInfo:TQSurface
  48.     Local vert:TQVertex
  49.     Local fNr:Int
  50.     Local eNr:Int
  51.     Local surf:TSurface
  52.     Local vertCount:Int
  53.     Local newVertCount:Int
  54.    
  55.     Local s:Float
  56.     Local t:Float
  57.    
  58.     For Local model:TQModel = EachIn myBSP.Models 'Go through models
  59.         For fNr = model.Face_ID Until model.Face_ID + model.Face_Num 'Go through faces
  60.             'Debug progress
  61.             'If fNr Mod 100 <= 0 Then Print "Generating: " + fNr + "/" + model.Face_Num
  62.             face = myBSP.Faces[fNr] 'Get current face
  63.             texInfo = myBSP.texInfo[face.TexInfo_ID]
  64.             plane = myBSP.PLANES[face.Plane_ID]
  65.            
  66.             If myBSP.MipTexs[texInfo.Texture_ID].Name.StartsWith("trigger") Then Continue
  67.            
  68.             'ERROR if we're using too many vertices
  69.             If face.Surface And face.Surface.CountVertices() > (10000 * 3) - 1 Then Print "TOO MANY VERTICES!!";End
  70.            
  71.             'If we don't have a surface to work with, create one
  72.             If Not face.Surface Then
  73.                 If myBSP.MipTexs[texInfo.Texture_ID].Name.StartsWith("*") Then
  74.                     face.Surface = CreateSurface(alphaMesh, Null)
  75.                 Else
  76.                     face.Surface = CreateSurface(mesh, Null)
  77.                 EndIf
  78.             EndIf
  79.            
  80.             surf = face.Surface
  81.            
  82.             'Get verts
  83.             newVertCount = 0
  84.             vertCount = surf.CountVertices()
  85.             For eNr = face.Ledge_ID Until face.Ledge_ID + face.Ledge_Num 'Go through edges
  86.                 ledge = myBSP.Ledges[eNr] 'Get ledge
  87.                 edge = myBSP.Edges[Abs(ledge.edge)] 'Get edge via ledge
  88.                
  89.                 If ledge.edge < 0 Then
  90.                     vert = myBSP.Vertices[edge.Vertex0]
  91.                 Else
  92.                     vert = myBSP.Vertices[edge.Vertex1]
  93.                 EndIf
  94.                
  95.                 AddVertex(surf, -vert.Y * 0.2, vert.Z * 0.2, vert.X * 0.2)
  96.                
  97.                 'Calculate UV
  98.                 s = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorS.X, texInfo.VectorS.Y, texInfo.VectorS.Z) + texInfo.DistS
  99.                 t = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorT.X, texInfo.VectorT.Y, texInfo.VectorT.Z) + texInfo.DistT
  100.                 'Based on texture size
  101.                 s:/myBSP.MipTexs[texInfo.Texture_ID].width
  102.                 t:/myBSP.MipTexs[texInfo.Texture_ID].Height
  103.                
  104.                 'Test UV for lightmap
  105.                 VertexTexCoords(surf, vertCount, (face.LightS - face.LightMinUV.x) / face.LightDist.x, (face.LightT - face.LightMinUV.y) / face.LightDist.y)
  106.                
  107.                 'VertexTexCoords(surf, vertCount, s, t) 'Real texture UV
  108.                 VertexNormal(surf, vertCount, plane.Normal.Z, plane.Normal.Y, plane.Normal.X)
  109.                
  110.                 vertCount:+1
  111.                 newVertCount:+1
  112.             Next
  113.            
  114.             'Make Tris
  115.             For Local i:Int = vertCount - newVertCount Until vertCount - 2
  116.                 AddTriangle(surf, vertCount - newVertCount, i + 1, i + 2)
  117.             Next
  118.            
  119.             'PaintSurface(surf, myBSP.MipTexs[texInfo.Texture_ID].Brush)
  120.             If face.LightBrush Then PaintSurface(surf, face.LightBrush)
  121.         Next
  122.     Next
  123.    
  124.     EntityFX(mesh, 1 + 2)
  125.     EntityFX(alphaMesh, 1 + 2)
  126.    
  127.     'Return mesh
  128.     GCCollect()
  129. EndFunction
  130.  
  131. 'Print mesh.CountSurfaces()
  132.  
  133. Function RequestBSP()
  134.     Local filter:String = "BSP Files:bsp;All Files:*"
  135.     Local file:String = RequestFile("Select BSP file to load", filter:String)
  136.    
  137.     If file Then
  138.         PositionEntity(camera, -2, 2.5, -10)
  139.         RotateEntity(camera, 0, 0, 0)
  140.        
  141.         myBSP = TQBSP.LoadFile(file)
  142.         GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  143.     EndIf
  144.    
  145.     FlushKeys()
  146.     FlushMouse()
  147. EndFunction
  148.  
  149. If FileSize(AppDir + "/dm1.bsp") > 0 Then
  150.     myBSP = TQBSP.LoadFile(AppDir + "/dm1.bsp")
  151.     GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  152.    
  153.     PositionEntity(camera, -250, 30, 70)
  154.     RotateEntity(camera, 15, 180 + 25, 0)
  155. Else
  156.     RequestBSP()
  157. EndIf
  158.  
  159. 'Main loop
  160. While Not AppTerminate() And Not KeyDown(KEY_ESCAPE)
  161.     'Cls()
  162.     'If KeyHit(KEY_O) Then Wireframe(False)
  163.     If KeyDown(KEY_P) Then Wireframe(True)
  164.    
  165.     If KeyDown(KEY_LEFT) Then TurnEntity(camera, 0, 2, 0)
  166.     If KeyDown(KEY_RIGHT) Then TurnEntity(camera, 0, -2, 0)
  167.     If KeyDown(KEY_UP) Then TurnEntity(camera, -2, 0, 0)
  168.     If KeyDown(KEY_DOWN) Then TurnEntity(camera, 2, 0, 0)
  169.    
  170.     If KeyDown(KEY_W) Then MoveEntity(camera, 0, 0, 1.5)
  171.     If KeyDown(KEY_S) Then MoveEntity(camera, 0, 0, -1.5)
  172.     If KeyDown(KEY_A) Then MoveEntity(camera, -1.5, 0, 0)
  173.     If KeyDown(KEY_D) Then MoveEntity(camera, 1.5, 0, 0)
  174.    
  175.     If KeyDown(KEY_SPACE) Then MoveEntity(camera, 0, 1, 0)
  176.     If KeyDown(KEY_LCONTROL) Then MoveEntity(camera, 0, -1, 0)
  177.    
  178.     If KeyHit(KEY_TAB) Then RequestBSP()
  179.    
  180.     If myBSP Then myBSP.Update()
  181.     RenderWorld()
  182.    
  183.     BeginMax2D()
  184.     DrawText("TAB: Open BSP", 0, 0)
  185.     EndMax2D()
  186.    
  187.     Flip(1)
  188. Wend
  189. End
  190.  
  191. Type TQBSP
  192.     Field File:String
  193.     Field Stream:TStream
  194.    
  195.     Field Header:TQHeader
  196.    
  197.     Field PLANES:TQPlane[]
  198.     Field Vertices:TQVertex[]
  199.     Field Nodes:TList = CreateList()
  200.     Field TexInfo:TQSurface[]
  201.     Field MipTexHeader:TQMipHeader
  202.     Field MipTexs:TQMipTex[]
  203.     Field AnimatedMipTexs:TQMipTex[]
  204.     Field Faces:TQFace[]
  205.     Field ClipNodes:TList = CreateList()
  206.     Field Leaves:TList = CreateList()
  207.     Field Edges:TQEdge[]
  208.     Field Ledges:TQLedge[]
  209.     Field Models:TQModel[]
  210.     'Field LightMap:Byte[]
  211.    
  212.     Field StartMS:Int
  213.    
  214.     Function LoadFile:TQBSP(url:String)
  215.         Local nB:TQBSP = New TQBSP
  216.         nB.File = url
  217.        
  218.         If nB.Process() Then
  219.             Return nB
  220.         Else
  221.             nB.StreamError("Map ~q" + nB.file + "~q NOT loaded")
  222.             Return Null
  223.         EndIf
  224.     EndFunction
  225.    
  226.     Method Update()
  227.         For Local m:TQMipTex = EachIn Self.AnimatedMipTexs
  228.             PositionTexture(GetBrushTexture(m.Brush), (MilliSecs() - StartMS) * 0.00005, -(MilliSecs() - StartMS) * 0.0001)
  229.             RotateTexture(GetBrushTexture(m.Brush), (MilliSecs() - StartMS) * 0.0005)
  230.         Next
  231.     EndMethod
  232.    
  233.     Method StreamError(MSG:String)
  234.         If Stream Then CloseStream(Stream)
  235.         DebugLog "Read error: " + MSG
  236.     EndMethod
  237.    
  238.     Method Process:Int()
  239.         Stream = OpenStream(File)
  240.         If Not Stream Then
  241.             StreamError("Unable to read file ~q" + file + "~q")
  242.             Return False
  243.         EndIf
  244.        
  245.         Local num:Int 'For counting stuff
  246.         Local i:Int 'For loops
  247.        
  248.         'Read header
  249.         Self.Header = TQHeader.Read(Stream)
  250.        
  251.         'Read planes
  252.         num = Self.Header.PLANES.Count(TQPlane.Size())
  253.         DebugLog "Planes: " + num
  254.         Self.PLANES = New TQPlane[num]
  255.         Self.Header.PLANES.JumpTo(Stream)
  256.         For i = 0 Until num
  257.             'ListAddLast(Self.PLANES, TQPlane.Read(Stream))
  258.             Self.PLANES[i] = TQPlane.Read(Stream)
  259.         Next
  260.        
  261.         'Read vertices
  262.         num = Self.Header.Vertices.Count(TQVertex.Size())
  263.         DebugLog "Vertices: " + num
  264.         Self.Vertices = New TQVertex[num]
  265.         Self.Header.Vertices.JumpTo(Stream)
  266.         For i = 0 Until num
  267.             'ListAddLast(Self.Vertices, TQVertex.Read(Stream))
  268.             Self.Vertices[i] = TQVertex.Read(Stream)
  269.         Next
  270.        
  271.         'Read nodes
  272.         'num = Self.Header.Nodes.Count(TQNode.Size())
  273.         'DebugLog "Nodes: " + num
  274.         'Self.Header.Nodes.JumpTo(Stream)
  275.         'For i = 0 Until num
  276.         '   ListAddLast(Self.Nodes, TQNode.Read(Stream))
  277.         'Next
  278.        
  279.         'Read texture info
  280.         num = Self.Header.TexInfo.Count(TQSurface.Size())
  281.         DebugLog "TexInfo: " + num
  282.         Self.TexInfo = New TQSurface[num]
  283.         Self.Header.TexInfo.JumpTo(Stream)
  284.         For i = 0 Until num
  285.             Self.TexInfo[i] = TQSurface.Read(Stream)
  286.         Next
  287.        
  288.         'Read mipmap header
  289.         Self.Header.MipTex.JumpTo(Stream)
  290.         Self.MipTexHeader = TQMipHeader.Read(Stream)
  291.         num = Self.MipTexHeader._count
  292.         DebugLog "MipMap Texs: " + num
  293.        
  294.         'Read miptexs from mipmap header
  295.         'CreateDir(AppDir + "/tex/", True) 'Debug for exporting
  296.        
  297.         MipTexs = New TQMipTex[num]
  298.         For i = 0 Until num
  299.             Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i])
  300.             Self.MipTexs[i] = TQMipTex.Read(Stream)
  301.            
  302.             If Self.MipTexs[i].width > 1 And Self.MipTexs[i].Height > 1 Then
  303.                 Local pix:TPixmap = CreatePixmap(Self.MipTexs[i].width, Self.MipTexs[i].Height, PF_RGB888)
  304.                 Local x:Int
  305.                 Local y:Int
  306.                 Local colorID:Byte
  307.                 Local palColor:TQColor32
  308.                
  309.                 Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i] + Self.MipTexs[i].Offset1)
  310.                 For Local bI:Int = 0 Until pix.width * pix.Height
  311.                     colorID = ReadByte(Stream)
  312.                     palColor = TQPalette.colors[colorID]
  313.                    
  314.                     pix.WritePixel(x, y, GenRGB(palColor.r, palColor.g, palColor.b))
  315.                    
  316.                     x:+1
  317.                     If x >= pix.width Then
  318.                         x = 0
  319.                         y:+1
  320.                     EndIf
  321.                 Next
  322.                
  323.                 If pix Then
  324.                     Self.MipTexs[i].Brush = LoadBrushPixmap(pix, 0)
  325.                     If Self.MipTexs[i].Name.StartsWith("*") Then
  326.                         BrushAlpha(Self.MipTexs[i].Brush, 0.65)
  327.                         BrushBlend(Self.MipTexs[i].Brush, 1)
  328.                         AnimatedMipTexs = AnimatedMipTexs[..AnimatedMipTexs.Length + 1]
  329.                         AnimatedMipTexs[AnimatedMipTexs.Length - 1] = Self.MipTexs[i]
  330.                     EndIf
  331.                 EndIf
  332.             EndIf
  333.         Next
  334.        
  335.         'Read faces
  336.         num = Self.Header.Faces.Count(TQFace.Size())
  337.         DebugLog "Faces: " + num
  338.         Self.Faces = New TQFace[num]
  339.         Self.Header.Faces.JumpTo(Stream)
  340.         For i = 0 Until num
  341.             Self.Faces[i] = TQFace.Read(Stream)
  342.         Next
  343.        
  344.         'Read lightmaps
  345.         'Self.Header.LightMaps.JumpTo(Stream)
  346.         'LightMap = New Byte[Self.Header.LightMaps.Size]
  347.         'For i:Int = 0 Until LightMap.Length
  348.         '   LightMap[i] = ReadByte(Stream)
  349.         'Next
  350.         'Stream.ReadBytes(LightMap, LightMap.Length)
  351.        
  352.         'Read clipnodes
  353.         'num = Self.Header.ClipNodes.Count(TQClipNode.Size())
  354.         'DebugLog "ClipNodes: " + num
  355.         'Self.Header.ClipNodes.JumpTo(Stream)
  356.         'For i = 0 Until num
  357.         '   ListAddLast(Self.ClipNodes, TQClipNode.Read(Stream))
  358.         'Next
  359.        
  360.         'Read leaves
  361.         'num = Self.Header.Leaves.Count(TQDLeaf.Size())
  362.         'DebugLog "Leaves: " + num
  363.         'Self.Header.Leaves.JumpTo(Stream)
  364.         'For i = 0 Until num
  365.         '   ListAddLast(Self.Leaves, TQDLeaf.Read(Stream))
  366.         'Next
  367.        
  368.         'Read edges
  369.         num = Self.Header.Edges.Count(TQEdge.Size())
  370.         DebugLog "Edges: " + num
  371.         Self.Edges = New TQEdge[num]
  372.         Self.Header.Edges.JumpTo(Stream)
  373.         For i = 0 Until num
  374.             'ListAddLast(Self.Edges, TQEdge.Read(Stream))
  375.             Self.Edges[i] = TQEdge.Read(Stream)
  376.         Next
  377.        
  378.         'Read ledges
  379.         num = Self.Header.Ledges.Count(TQLedge.Size())
  380.         DebugLog "Ledges: " + num
  381.         Self.Ledges = New TQLedge[num]
  382.         Self.Header.Ledges.JumpTo(Stream)
  383.         For i = 0 Until num
  384.             'ListAddLast(Self.Ledges, TQLedge.Read(Stream))
  385.             Self.Ledges[i] = TQLedge.Read(Stream)
  386.         Next
  387.        
  388.         'Read models
  389.         num = Self.Header.Models.Count(TQModel.Size())
  390.         DebugLog "Models: " + num
  391.         Self.Models = New TQModel[num]
  392.         Self.Header.Models.JumpTo(Stream)
  393.         For i = 0 Until num
  394.             'ListAddLast(Self.Models, TQModel.Read(Stream))
  395.             Self.Models[i] = TQModel.Read(Stream)
  396.         Next
  397.        
  398.         'Read lightmaps from faces
  399.         For i = 0 Until Self.Faces.Length
  400.             Self.Faces[i].GetLightmap(Self)
  401.         Next
  402.        
  403.         StartMS = MilliSecs()
  404.        
  405.         CloseStream(Stream)
  406.         Return True
  407.     EndMethod
  408. EndType
  409.  
  410. 'http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm
  411. 'char 8bit = negative byte
  412. 'u_char 8bit = byte
  413. 'short 16bit = negative short
  414. 'u_short 16bit = short
  415. 'long 32bit = int
  416. 'u_long 32bit = longer int
  417. 'float 32bit = float
  418. 'scalar_t 32bit = float
  419.  
  420. Type TQHeader
  421.     Field Version:Int
  422.     Field Entities:TQEntry
  423.     Field PLANES:TQEntry
  424.     Field MipTex:TQEntry
  425.     Field Vertices:TQEntry
  426.     Field VisiList:TQEntry
  427.     Field Nodes:TQEntry
  428.     Field TexInfo:TQEntry
  429.     Field Faces:TQEntry
  430.     Field LightMaps:TQEntry
  431.     Field ClipNodes:TQEntry
  432.     Field Leaves:TQEntry
  433.     Field LFace:TQEntry
  434.     Field Edges:TQEntry
  435.     Field Ledges:TQEntry
  436.     Field Models:TQEntry
  437.    
  438.     Function Read:TQHeader(Stream:TStream)
  439.         Local nH:TQHeader = New TQHeader
  440.        
  441.         nH.Version = ReadInt(Stream)
  442.         If nH.Version = "29" Then
  443.             DebugLog "BSP version: " + nH.Version + " (correct)"
  444.         Else
  445.             DebugLog "BSP version: " + nH.Version + " (incorrect)"
  446.         EndIf
  447.        
  448.         nH.Entities = TQEntry.Read(Stream)
  449.         nH.PLANES = TQEntry.Read(Stream)
  450.        
  451.         nH.MipTex = TQEntry.Read(Stream)
  452.         nH.Vertices = TQEntry.Read(Stream)
  453.        
  454.         nH.VisiList = TQEntry.Read(Stream)
  455.         nH.Nodes = TQEntry.Read(Stream)
  456.        
  457.         nH.TexInfo = TQEntry.Read(Stream)
  458.        
  459.         nH.Faces = TQEntry.Read(Stream)
  460.        
  461.         nH.LightMaps = TQEntry.Read(Stream)
  462.         nH.ClipNodes = TQEntry.Read(Stream)
  463.        
  464.         nH.Leaves = TQEntry.Read(Stream)
  465.        
  466.         nH.LFace = TQEntry.Read(Stream)
  467.         nH.Edges = TQEntry.Read(Stream)
  468.        
  469.         nH.Ledges = TQEntry.Read(Stream)
  470.         nH.Models = TQEntry.Read(Stream)
  471.        
  472.         Return nH
  473.     EndFunction
  474. EndType
  475.  
  476. Type TQModel
  477.     Field Bound:TQBoundBox
  478.     Field Origin:TQVec3
  479.     Field Node_ID0:Int
  480.     Field Node_ID1:Int
  481.     Field Node_ID2:Int
  482.     Field Node_ID3:Int
  483.     Field NumLeafs:Int
  484.     Field Face_ID:Int
  485.     Field Face_Num:Int
  486.    
  487.     Function Read:TQModel(Stream:TStream)
  488.         Local nM:TQModel = New TQModel
  489.         nM.Bound = TQBoundBox.Read(Stream)
  490.         nM.Origin = TQVec3.Read(Stream)
  491.         nM.Node_ID0 = ReadInt(Stream)
  492.         nM.Node_ID1 = ReadInt(Stream)
  493.         nM.Node_ID2 = ReadInt(Stream)
  494.         nM.Node_ID3 = ReadInt(Stream)
  495.         nM.NumLeafs = ReadInt(Stream)
  496.         nM.Face_ID = ReadInt(Stream)
  497.         nM.Face_Num = ReadInt(Stream)
  498.         Return nM
  499.     EndFunction
  500.    
  501.     Function Size:Int()
  502.         Return (B_INT * 7) + TQBoundBox.Size() + TQVec3.Size()
  503.     EndFunction
  504. EndType
  505.  
  506. Type TQVertex
  507.     Field X:Float
  508.     Field Y:Float
  509.     Field Z:Float
  510.    
  511.     Function Read:TQVertex(Stream:TStream)
  512.         Local nV:TQVertex = New TQVertex
  513.         nV.X = ReadFloat(Stream)
  514.         nV.Y = ReadFloat(Stream)
  515.         nV.Z = ReadFloat(Stream)
  516.        
  517.         Return nV
  518.     EndFunction
  519.    
  520.     Function Size:Int()
  521.         Return B_FLOAT * 3
  522.     EndFunction
  523. EndType
  524.  
  525. Type TQSurface
  526.     Field VectorS:TQVec3
  527.     Field DistS:Float
  528.     Field VectorT:TQVec3
  529.     Field DistT:Float
  530.     Field Texture_ID:Int
  531.    
  532.     Field Animated:Int
  533.    
  534.     Function Read:TQSurface(Stream:TStream)
  535.         Local nS:TQSurface = New TQSurface
  536.         nS.VectorS = TQVec3.Read(Stream)
  537.         nS.DistS = ReadFloat(Stream)
  538.         nS.VectorT = TQVec3.Read(Stream)
  539.         nS.DistT = ReadFloat(Stream)
  540.         nS.Texture_ID = ReadInt(Stream)
  541.         nS.Animated = ReadInt(Stream)
  542.         Return nS
  543.     EndFunction
  544.    
  545.     Function Size:Int()
  546.         Return (B_FLOAT * 2) + (B_INT * 2) + (TQVec3.Size() * 2)
  547.     EndFunction
  548. EndType
  549.  
  550. Type TQEdge
  551.     Field Vertex0:Short
  552.     Field Vertex1:Short
  553.    
  554.     Function Read:TQEdge(Stream:TStream)
  555.         Local nE:TQEdge = New TQEdge
  556.         nE.Vertex0 = ReadShort(Stream)
  557.         nE.Vertex1 = ReadShort(Stream)
  558.         Return nE
  559.     EndFunction
  560.    
  561.     Function Size:Int()
  562.         Return B_SHORT * 2
  563.     EndFunction
  564. EndType
  565.  
  566. Type TQLedge
  567.     Field Edge:Int
  568.    
  569.     Function Read:TQLedge(Stream:TStream)
  570.         Local nL:TQLedge = New TQLedge
  571.         nL.Edge = ReadInt(Stream)
  572.         Return nL
  573.     EndFunction
  574.    
  575.     Function Size:Int()
  576.         Return B_INT
  577.     EndFunction
  578. EndType
  579.  
  580. Type TQFace
  581.     Field Plane_ID:Short
  582.    
  583.     Field Side:Short
  584.     Field Ledge_ID:Int
  585.    
  586.     Field Ledge_Num:Short
  587.     Field TexInfo_ID:Short
  588.    
  589.     Field TypeLight:Byte
  590.     Field BaseLight:Byte
  591.     Field Light:Byte[2]
  592.     Field LightMap:Int
  593.    
  594.     Field Surface:TSurface
  595.    
  596.     Field LightBrush:TBrush
  597.     Field LightDist:TQVec2
  598.     Field LightMinUV:TQVec2
  599.     Field LightMaxUV:TQVec2
  600.     Field LightS:Float
  601.     Field LightT:Float
  602.    
  603.     Function Read:TQFace(Stream:TStream)
  604.         Local nF:TQFace = New TQFace
  605.         nF.Plane_ID = ReadShort(Stream)
  606.         nF.Side = ReadShort(Stream)
  607.         nF.Ledge_ID = ReadInt(Stream)
  608.         nF.Ledge_Num = ReadShort(Stream)
  609.         nF.TexInfo_ID = ReadShort(Stream)
  610.         nF.TypeLight = ReadByte(Stream)
  611.         nF.BaseLight = ReadByte(Stream)
  612.         nF.Light[0] = ReadByte(Stream)
  613.         nF.Light[1] = ReadByte(Stream)
  614.         nF.LightMap = ReadInt(Stream)
  615.         Return nF
  616.     EndFunction
  617.    
  618.     Method GetLightmap(bsp:TQBSP)
  619.         bsp.Stream.Seek(bsp.Header.LightMaps.Offset + Self.LightMap)
  620.        
  621.         Local plane:TQPlane = bsp.PLANES[Self.Plane_ID]
  622.        
  623.         'Get the vertex data from all edges
  624.         LightMinUV = New TQVec2
  625.         LightMaxUV = New TQVec2
  626.         LightDist = New TQVec2
  627.        
  628.         Local ledge:TQLedge
  629.         Local edge:TQEdge
  630.         Local vert:TQVertex
  631.         Local texInfo:TQSurface = bsp.texInfo[Self.TexInfo_ID]
  632.         For Local eNr:Int = Self.Ledge_ID Until Self.Ledge_ID + Self.Ledge_Num 'Go through edges
  633.             ledge = bsp.Ledges[eNr] 'Get ledge
  634.             edge = bsp.Edges[Abs(ledge.edge)] 'Get edge via ledge
  635.            
  636.             If ledge.edge < 0 Then
  637.                 vert = bsp.Vertices[edge.Vertex0]
  638.             Else
  639.                 vert = bsp.Vertices[edge.Vertex1]
  640.             EndIf
  641.            
  642.             LightS = DotProduct(vert.x, vert.y, vert.Z, texInfo.VectorS.x, texInfo.VectorS.y, texInfo.VectorS.Z) + texInfo.DistS
  643.             LightT = DotProduct(vert.x, vert.y, vert.Z, texInfo.VectorT.x, texInfo.VectorT.y, texInfo.VectorT.Z) + texInfo.DistT
  644.            
  645.             If (eNr = Self.Ledge_ID) Then
  646.                 'Starting point
  647.                 LightMinUV.x = LightS
  648.                 LightMinUV.y = LightT
  649.                 LightMaxUV.x = LightS
  650.                 LightMaxUV.y = LightT
  651.             Else
  652.                 'Is this a new minimum?
  653.                 If LightS < LightMinUV.x Then LightMinUV.x = LightS
  654.                 If LightT < LightMinUV.y Then LightMinUV.y = LightT
  655.                
  656.                 'Is this a new maximum
  657.                 If LightS > LightMaxUV.x Then LightMaxUV.x = LightS
  658.                 If LightT > LightMaxUV.y Then LightMaxUV.y = LightT
  659.             End If
  660.         Next
  661.        
  662.         'Get distances
  663.         LightDist.x = LightMaxUV.x - LightMinUV.x
  664.         LightDist.y = LightMaxUV.y - LightMinUV.y
  665.        
  666.         Local pix:TPixmap = CreatePixmap(Floor(LightDist.x / 16.0) + 1, Floor(LightDist.y / 16.0) + 1, PF_RGB888)
  667.        
  668.         If pix.width <= 0 Or pix.Height <= 0 Then
  669.             pix = Null
  670.             Return
  671.         EndIf
  672.         'Print pix.width + "/" + pix.Height
  673.         Local x:Int
  674.         Local y:Int
  675.         Local color:Byte
  676.         For y = 0 Until pix.Height
  677.         For x = 0 Until pix.width
  678.             color = bsp.Stream.ReadByte()' - Self.BaseLight
  679.             pix.WritePixel(x, y, GenRGB(color,color,color))
  680.         Next
  681.         Next
  682.        
  683.         If FileType(AppDir + "/lightmaps") = FILETYPE_DIR Then SavePixmapPNG(pix, AppDir + "/lightmaps/" + Plane_ID + ".png", 0)
  684.        
  685.         Self.LightBrush = LoadBrushPixmap(pix, 0)
  686.     EndMethod
  687.    
  688.     Function Size:Int()
  689.         Return (B_SHORT * 4) + (B_INT * 2) + (B_BYTE * 4)
  690.     EndFunction
  691. EndType
  692.  
  693. Type TQMipHeader
  694.     Field NumTex:Int
  695.     Field Offset:Int[]
  696.    
  697.     Field _count:Int
  698.    
  699.     Function Read:TQMipHeader(Stream:TStream)
  700.         Local nM:TQMipHeader = New TQMipHeader
  701.         nM.NumTex = ReadInt(Stream)
  702.        
  703.         'Should I even read this?
  704.         nM.Offset = New Int[nM.NumTex]
  705.         For Local i:Int = 0 Until nM.NumTex
  706.             nM.Offset[i] = ReadInt(Stream)
  707.             nM._count:+1
  708.         Next
  709.         Return nM
  710.     EndFunction
  711. EndType
  712.  
  713. Type TQMipTex
  714.     Field Name:String
  715.     Field width:Int
  716.     Field Height:Int
  717.     Field Offset1:Int
  718.     Field Offset2:Int
  719.     Field Offset4:Int
  720.     Field Offset8:Int
  721.    
  722.     Field Texture:TTexture
  723.     Field Brush:TBrush
  724.    
  725.     Function Read:TQMipTex(Stream:TStream)
  726.         Local nM:TQMipTex = New TQMipTex
  727.         For Local i:Int = 0 Until 16
  728.             nM.Name:+Chr(ReadByte(Stream))
  729.         Next
  730.         nM.width = ReadInt(Stream)
  731.         nM.Height = ReadInt(Stream)
  732.         nM.Offset1 = ReadInt(Stream)
  733.         nM.Offset2 = ReadInt(Stream)
  734.         nM.Offset4 = ReadInt(Stream)
  735.         nM.Offset8 = ReadInt(Stream)
  736.         Return nM
  737.     EndFunction
  738.    
  739.     Function Size:Int()
  740.         Return (B_BYTE * 16) + (B_INT * 6)
  741.     EndFunction
  742. EndType
  743.  
  744. Type TQEntry
  745.     Field Offset:Int
  746.     Field Size:Int
  747.    
  748.     Function Read:TQEntry(Stream:TStream)
  749.         Local nE:TQEntry = New TQEntry
  750.         nE.Offset = ReadInt(Stream)
  751.         nE.Size = ReadInt(Stream)
  752.         Return nE
  753.     EndFunction
  754.    
  755.     Method Count:Int(typeSize:Int)
  756.         Return Size / typeSize
  757.     EndMethod
  758.    
  759.     Method JumpTo(Stream:TStream)
  760.         Stream.Seek(Self.Offset)
  761.     EndMethod
  762. EndType
  763.  
  764. Type TQNode
  765.     Field Plane_ID:Int
  766.    
  767.     Field Front:Short
  768.    
  769.     Field Back:Short
  770.    
  771.     Field Box:TQBBoxShort
  772.     Field Face_ID:Short
  773.     Field Face_Num:Short
  774.    
  775.     Function Read:TQNode(Stream:TStream)
  776.         Local nN:TQNode = New TQNode
  777.         nN.Plane_ID = ReadInt(Stream)
  778.         nN.Front = ReadShort(Stream)
  779.         nN.Back = ReadShort(Stream)
  780.         nN.Box = TQBBoxShort.Read(Stream)
  781.         nN.Face_ID = ReadShort(Stream)
  782.         nN.Face_Num = ReadShort(Stream)
  783.         Return nN
  784.     EndFunction
  785. EndType
  786.  
  787. Type TQDLeaf
  788.     Field Typ:Int
  789.     Field VisList:Int
  790.    
  791.     Field Bound:TQBBoxShort
  792.     Field LFace_ID:Short
  793.    
  794.     Field LFace_Num:Short
  795.     Field SndWater:Byte
  796.     Field SndSky:Byte
  797.     Field SndSlime:Byte
  798.     Field SndLava:Byte
  799.    
  800.     Function Read:TQDLeaf(Stream:TStream)
  801.         Local nD:TQDLeaf = New TQDLeaf
  802.         nD.Typ = ReadInt(Stream)
  803.         nD.VisList = ReadInt(Stream)
  804.        
  805.         nD.Bound = TQBBoxShort.Read(Stream)
  806.         nD.LFace_ID = ReadShort(Stream)
  807.        
  808.         nD.LFace_Num = ReadShort(Stream)
  809.         nD.SndWater = ReadByte(Stream)
  810.         nD.SndSky = ReadByte(Stream)
  811.         nD.SndSlime = ReadByte(Stream)
  812.         nD.SndLava = ReadByte(Stream)
  813.         Return nD
  814.     EndFunction
  815. EndType
  816.  
  817. Type TQPlane
  818.     Field Normal:TQVec3
  819.    
  820.     Field Dist:Float
  821.    
  822.     Field Typ:Int
  823.    
  824.     Function Read:TQPlane(Stream:TStream)
  825.         Local nP:TQPlane = New TQPlane
  826.         nP.Normal = TQVec3.Read(Stream)
  827.         nP.Dist = ReadFloat(Stream)
  828.         nP.Typ = ReadInt(Stream)
  829.         Return nP
  830.     EndFunction
  831.    
  832.     Function Size:Int()
  833.         Return B_FLOAT + B_INT + TQVec3.Size()
  834.     EndFunction
  835. EndType
  836.  
  837. Type TQClipNode
  838.     Field PlaneNum:Int
  839.     Field Front:Short
  840.    
  841.     Field Back:Short
  842.    
  843.     Function Read:TQClipNode(Stream:TStream)
  844.         Local nC:TQClipNode = New TQClipNode
  845.         nC.PlaneNum = ReadInt(Stream)
  846.         nC.Front = ReadShort(Stream)
  847.         nC.Back = ReadShort(Stream)
  848.         Return nC
  849.     EndFunction
  850. EndType
  851.  
  852. Type TQPalette
  853.     Global colors:TQColor32[]
  854.    
  855.     Function LoadPalette(url:String)
  856.         Local Stream:TStream = OpenStream(url, True, False)
  857.         If Not Stream Then Print("Unable to load palette ~q" + url + "~q")
  858.         colors = New TQColor32[Stream.Size() / 3]
  859.        
  860.         For Local i:Int = 0 Until colors.Length
  861.             colors[i] = New TQColor32
  862.             colors[i].r = Stream.ReadByte()
  863.             colors[i].g = Stream.ReadByte()
  864.             colors[i].b = Stream.ReadByte()
  865.         Next
  866.        
  867.         'debug save palette
  868.         Rem
  869.         Local pix:TPixmap = CreatePixmap(colors.Length, 8, PF_RGB888)
  870.         For Local i:Int = 0 Until colors.Length
  871.             For Local y:Int = 0 Until pix.Height
  872.                 pix.WritePixel(i, y, GenRGB(colors[i].r, colors[i].g, colors[i].b))
  873.             Next
  874.         Next
  875.         SavePixmapPNG(pix, AppDir + "/palette.png", 9)
  876.         endrem
  877.        
  878.         CloseStream(Stream)
  879.         DebugLog "Palette: " + url + " @ " + colors.Length + " colors"
  880.     EndFunction
  881.    
  882. EndType
  883.  
  884. Type TQColor32
  885.     Field r:Byte
  886.     Field g:Byte
  887.     Field b:Byte
  888. EndType
  889.  
  890. 'Basic types
  891. Type TQVec3
  892.     Field X:Float
  893.     Field Y:Float
  894.     Field Z:Float
  895.    
  896.     Function Read:TQVec3(Stream:TStream)
  897.         Local nV:TQVec3 = New TQVec3
  898.         nV.X = ReadFloat(Stream)
  899.         nV.Y = ReadFloat(Stream)
  900.         nV.Z = ReadFloat(Stream)
  901.         Return nV
  902.     EndFunction
  903.    
  904.     Function Size:Int()
  905.         Return B_FLOAT * 3
  906.     EndFunction
  907. EndType
  908.  
  909. Type TQVec2
  910.     Field X:Float
  911.     Field Y:Float
  912.    
  913.     Function Read:TQVec2(Stream:TStream)
  914.         Local nV:TQVec2 = New TQVec2
  915.         nV.X = ReadFloat(Stream)
  916.         nV.Y = ReadFloat(Stream)
  917.         Return nV
  918.     EndFunction
  919.    
  920.     Function Size:Int()
  921.         Return B_FLOAT * 2
  922.     EndFunction
  923. EndType
  924.  
  925. Type TQBoundBox
  926.     Field Minimum:TQVec3
  927.     Field Maximum:TQVec3
  928.    
  929.     Function Read:TQBoundBox(Stream:TStream)
  930.         Local nB:TQBoundBox = New TQBoundBox
  931.         nB.Minimum = TQVec3.Read(Stream)
  932.         nB.Maximum = TQVec3.Read(Stream)
  933.         Return nB
  934.     EndFunction
  935.    
  936.     Function Size:Int()
  937.             Return TQVec3.Size() * 2
  938.     EndFunction
  939. EndType
  940.  
  941. Type TQBBoxShort
  942.     Field Minimum:Short
  943.     Field Maximum:Short
  944.    
  945.     Function Read:TQBBoxShort(Stream:TStream)
  946.         Local nB:TQBBoxShort = New TQBBoxShort
  947.         nB.Minimum = ReadShort(Stream)
  948.         nB.Maximum = ReadShort(Stream)
  949.         Return nB
  950.     EndFunction
  951.    
  952.     Function Size:Int()
  953.         Return B_SHORT * 2
  954.     EndFunction
  955. EndType
  956.  
  957. 'Common
  958. Function CrossProduct:TQVec3(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  959.     Local CProd:TQVec3 = New TQVec3
  960.     CProd.x = (y1 * z2) - (z1 * y2)
  961.     CProd.y = (z1 * x2) - (x1 * z2)
  962.     CProd.z = (x1 * y2) - (y1 * x2)
  963.     Return CProd
  964. End Function
  965. Function DotProduct:Float(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  966.     Return ((x1 * x2) + (y1 * y2) + (z1 * z2))
  967. EndFunction
  968.  
  969. Function GenRGB:Int(r:Byte, g:Byte, b:Byte, a:Byte = 255)
  970.     Return (a Shl 24) | (r Shl 16) | (g Shl 8) | b
  971. EndFunction
  972.    
  973. Function GetRGB:Int(argb:Int, a:byte Var, r:byte Var, g:byte Var, b:byte Var)
  974.     a=(argb Shr 24) & $ff
  975.     r=(argb Shr 16) & $ff
  976.     g=(argb Shr 8) & $ff
  977.     b=argb & $ff
  978. EndFunction
  979.  
  980. 'Custom brushes
  981. Function LoadBrushPixmap:TBrush(pixmapin:TPixmap, Flags:Int = 1, u_scale:Float = 1.0, v_scale:Float = 1.0)
  982.     Return PixTBrush.LoadBrushPixmap(pixmapin, Flags, u_scale, v_scale)
  983. EndFunction
  984.  
  985. Function LoadTexturePixmap:TTexture(pixmapin:TPixmap,flags:Int=1)
  986.     Return PixTTexture.LoadTexturePixmap(pixmapin, Flags)
  987. EndFunction
  988.  
  989. Type PixTBrush Extends TBrush
  990.  
  991.     Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags:Int=1,u_scale:Float=1.0,v_scale:Float=1.0)
  992.    
  993.         Local brush:TBrush=New TBrush
  994.        
  995.         brush.tex[0]=PixTTexture.LoadTexturePixmap:TTexture(pixmapin,flags)
  996.         brush.no_texs=1
  997.        
  998.         'brush.tex[0].u_scale#=u_scale#
  999.         'brush.tex[0].v_scale#=v_scale#
  1000.        
  1001.         pixmapin = Null
  1002.                
  1003.         Return brush
  1004.        
  1005.     EndFunction
  1006. EndType
  1007.  
  1008. Type PixTTexture Extends TTexture
  1009.  
  1010.     Function LoadTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int=1,tex:TTexture=Null)
  1011.    
  1012.         Return LoadAnimTexturePixMap:TTexture(pixmapin,flags,0,0,0,1,tex)
  1013.        
  1014.     End Function
  1015.  
  1016.     Function LoadAnimTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int,frame_width:Int,frame_height:Int,first_frame:Int,frame_count:Int,tex:TTexture=Null)
  1017.    
  1018.         Local pixmapFileName:String="pixmap"+MilliSecs()+Rnd()
  1019.        
  1020.         If flags&128 Then Return LoadCubeMapTexture(pixmapFileName$,flags,tex)
  1021.    
  1022.         If tex=Null Then tex:TTexture=New TTexture
  1023.        
  1024.         tex.file:String=pixmapFileName
  1025.         tex.file_abs:String=pixmapFileName
  1026.        
  1027.         ' set tex.flags before TexInList
  1028.         tex.flags=flags
  1029.         tex.FilterFlags()
  1030.        
  1031.         ' check to see if texture with same properties exists already, if so return existing texture
  1032.         Local old_tex:TTexture
  1033.         old_tex=tex.TexInList()
  1034.         If old_tex<>Null And old_tex<>tex
  1035.             Return old_tex
  1036.         Else
  1037.             If old_tex<>tex
  1038.                 ListAddLast(tex_list,tex)
  1039.             EndIf
  1040.         EndIf
  1041.    
  1042.         ' load pixmap
  1043.         tex.pixmap = CopyPixmap(pixmapin)
  1044.        
  1045.         ' check to see if pixmap contain alpha layer, set alpha_present to true if so (do this before converting)
  1046.         Local alpha_present:Int=False
  1047.         If tex.pixmap.format=PF_RGBA8888 Or tex.pixmap.format=PF_BGRA8888 Or tex.pixmap.format=PF_A8 Then alpha_present=True
  1048.    
  1049.         ' convert pixmap to appropriate format
  1050.         If tex.pixmap.format<>PF_RGBA8888
  1051.             tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
  1052.         EndIf
  1053.        
  1054.         ' if alpha flag is true and pixmap doesn't contain alpha info, apply alpha based on color values
  1055.         If tex.flags&2 And alpha_present=False
  1056.             tex.pixmap=ApplyAlpha(tex.pixmap)
  1057.         EndIf      
  1058.    
  1059.         ' if mask flag is true, mask pixmap
  1060.         If tex.flags&4
  1061.             tex.pixmap=MaskPixmap(tex.pixmap,0,0,0)
  1062.         EndIf
  1063.        
  1064.         ' ---
  1065.        
  1066.         ' if tex not anim tex, get frame width and height
  1067.         If frame_width=0 And frame_height=0
  1068.             frame_width=tex.pixmap.width
  1069.             frame_height=tex.pixmap.height
  1070.         EndIf
  1071.    
  1072.         ' ---
  1073.        
  1074.         tex.no_frames=frame_count
  1075.         tex.gltex=tex.gltex[..tex.no_frames]
  1076.    
  1077.         ' ---
  1078.        
  1079.         ' pixmap -> tex
  1080.    
  1081.         Local xframes:Int=tex.pixmap.width/frame_width
  1082.         Local yframes:Int=tex.pixmap.height/frame_height
  1083.            
  1084.         Local startx:Int=first_frame Mod xframes
  1085.         Local starty:Int=(first_frame/yframes) Mod yframes
  1086.            
  1087.         Local x:Int=startx
  1088.         Local y:Int=starty
  1089.    
  1090.         Local pixmap:TPixmap
  1091.    
  1092.         For Local i:Int=0 To tex.no_frames-1
  1093.    
  1094.             ' get static pixmap window. when resize pixmap is called new pixmap will be returned.
  1095.             pixmap=tex.pixmap.Window(x*frame_width,y*frame_height,frame_width,frame_height)
  1096.             x=x+1
  1097.             If x>=xframes
  1098.                 x=0
  1099.                 y=y+1
  1100.             EndIf
  1101.        
  1102.             ' ---
  1103.        
  1104.             pixmap=AdjustPixmap(pixmap)
  1105.             tex.width=pixmap.width
  1106.             tex.height=pixmap.height
  1107.             Local width:Int=pixmap.width
  1108.             Local height:Int=pixmap.height
  1109.    
  1110.             Local name:Int
  1111.             glGenTextures 1,Varptr name
  1112.             glBindtexture GL_TEXTURE_2D,name
  1113.    
  1114.             Local mipmap:Int
  1115.             If tex.flags&8 Then mipmap=True
  1116.             Local mip_level:Int=0
  1117.             Repeat
  1118.                 glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
  1119.                 glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
  1120.                 If Not mipmap Then Exit
  1121.                 If width=1 And height=1 Exit
  1122.                 If width>1 width:/2
  1123.                 If height>1 height:/2
  1124.    
  1125.                 pixmap=ResizePixmap(pixmap,width,height)
  1126.                 mip_level:+1
  1127.             Forever
  1128.             tex.no_mipmaps=mip_level
  1129.    
  1130.             tex.gltex[i]=name
  1131.    
  1132.         Next
  1133.                
  1134.         tex.pixmap = Null
  1135.                
  1136.         Return tex
  1137.        
  1138.     End Function
  1139. EndType
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement