Advertisement
Guest User

Untitled

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