Esempio n. 1
0
        private bool LoadFaceLump(Q3BSPDirEntry dir, BinaryReader fileReader)
        {
            int faceCount = dir.Length / Q3BSPConstants.sizeFace;

            faces       = new Q3BSPFace[faceCount];
            facesToDraw = new bool[faceCount];
            for (int i = 0; i < faceCount; i++)
            {
                faces[i] = Q3BSPFace.FromStream(fileReader);
            }

            bspLogger.WriteLine("No of faces: " + faceCount);
            return(true);
        }
Esempio n. 2
0
        int IComparer.Compare(object x, object y)
        {
            Q3BSPFace face1 = (Q3BSPFace)x;
            Q3BSPFace face2 = (Q3BSPFace)y;

            if (face1.TextureIndex != face2.TextureIndex)
            {
                return(face1.TextureIndex - face2.TextureIndex);
            }
            else
            {
                return(face1.LightMapIndex - face2.LightMapIndex);
            }
        }
Esempio n. 3
0
        public void InitializeStatic(GraphicsDevice graphics)
        {
            List <short>   indexList              = new List <short>();
            List <short[]> indexBufferList        = new List <short[]>();
            List <Vector2> textureAndLightMapList = new List <Vector2>();
            int            lastTextureIndex       = 0;
            int            lastLightMapIndex      = 0;

            Q3BSPFace[] tempFaces = new Q3BSPFace[faces.Length];
            faces.CopyTo(tempFaces, 0);

            System.Array.Sort(tempFaces, new Q3BSPFaceComparer());

            foreach (Q3BSPFace face in tempFaces)
            {
                // The current index buffer is done and needs to be refreshed.
                if ((face.TextureIndex != lastTextureIndex || face.LightMapIndex != lastLightMapIndex) && ((indexList.Count != 0 || indexList.Count > int.MaxValue)))
                {
                    indexBufferList.Add(indexList.ToArray());
                    textureAndLightMapList.Add(new Vector2(lastTextureIndex, lastLightMapIndex));
                    indexList.Clear();
                }

                if (face.FaceType == Q3BSPFaceType.Patch)
                {
                    Q3BSPVertex[] patchVertices  = patches[face.PatchIndex].GetVertices();
                    short[]       patchIndices   = patches[face.PatchIndex].GetIndices();
                    Q3BSPVertex[] newVertexArray = new Q3BSPVertex[vertices.Length + patchVertices.Length];

                    vertices.CopyTo(newVertexArray, 0);
                    patchVertices.CopyTo(newVertexArray, vertices.Length);

                    foreach (short index in patchIndices)
                    {
                        indexList.Add((short)(vertices.Length + index));
                    }

                    vertices = newVertexArray;
                }

                for (int i = 0; i < face.MeshVertexCount; ++i)
                {
                    indexList.Add((short)(face.StartVertex + meshVertices[face.StartMeshVertex + i]));
                }

                lastTextureIndex  = face.TextureIndex;
                lastLightMapIndex = face.LightMapIndex;
            }

            // Add the last index buffer
            indexBufferList.Add(indexList.ToArray());
            textureAndLightMapList.Add(new Vector2(lastTextureIndex, lastLightMapIndex));
            indexList.Clear();

            // Set the vertex and index buffers
            vertexBuffer = new VertexBuffer(graphics, typeof(Q3BSPVertex), vertices.Length, BufferUsage.WriteOnly);
            vertexBuffer.SetData <Q3BSPVertex>(vertices);

            indexBuffers       = new IndexBuffer[indexBufferList.Count];
            indexBufferLengths = new int[indexBufferList.Count];
            for (int i = 0; i < indexBuffers.Length; i++)
            {
                indexBuffers[i] = new IndexBuffer(graphics, typeof(short), indexBufferList[i].Length, BufferUsage.WriteOnly);
                indexBuffers[i].SetData <short>(indexBufferList[i]);
                indexBufferLengths[i] = indexBufferList[i].Length;
            }

            // Set the texture and lightmap array
            textureAndLightMapIndices = textureAndLightMapList.ToArray();
        }
Esempio n. 4
0
        /// <param name="shaderPath">Path to the directory that contains all compiled .shaders. Is relative to the Content.BasePath directory. Do not include a leading '/'.</param>
        public bool InitializeLevel(GraphicsDevice graphics, ContentManager content, string shaderPath, string quakePath)
        {
            bool bSuccess = true;

            lightMapManager = new Q3BSPLightMapManager();
            bSuccess        = lightMapManager.GenerateLightMaps(lightMapData, graphics);

            if (bSuccess)
            {
                shaderManager            = new Q3BSPShaderManager();
                shaderManager.ShaderPath = shaderPath;
                shaderManager.QuakePath  = quakePath;
                bSuccess = shaderManager.LoadTextures(textureData, graphics, content);
            }

            if (bSuccess && shaderManager.SkyMaterial != null)
            {
                skybox = new Q3BSPSkybox(skyboxSize, skyboxTessellation, graphics, shaderManager);
            }

            if (bSuccess)
            {
                shaderManager.LightMapManager = lightMapManager;
            }

            levelInitialized = bSuccess;

            if (renderType == Q3BSPRenderType.StaticBuffer)
            {
                InitializeStatic(graphics);
            }

            else if (renderType == Q3BSPRenderType.BSPCulling)
            {
                Q3BSPFace[] tempFaces = new Q3BSPFace[faces.Length];
                faces.CopyTo(tempFaces, 0);

                System.Array.Sort(tempFaces, new Q3BSPFaceComparer());

                int indexCount        = 0;
                int lastTextureIndex  = 0;
                int lastLightMapIndex = 0;
                this.maximumNumberOfIndicesToDraw = 0;

                foreach (Q3BSPFace face in tempFaces)
                {
                    // The current index buffer is done and needs to be refreshed.
                    if ((face.TextureIndex != lastTextureIndex || face.LightMapIndex != lastLightMapIndex))
                    {
                        if (face.TextureIndex == 4)
                        {
                            indexCount += 0;
                        }
                        if (indexCount > maximumNumberOfIndicesToDraw)
                        {
                            maximumNumberOfIndicesToDraw = indexCount;
                        }
                        indexCount = 0;
                    }

                    lastTextureIndex  = face.TextureIndex;
                    lastLightMapIndex = face.LightMapIndex;
                    indexCount       += face.MeshVertexCount;
                }

                if (indexCount > maximumNumberOfIndicesToDraw)
                {
                    maximumNumberOfIndicesToDraw = indexCount;
                }
            }

            bspLogger.WriteLine("Level initialized: " + levelInitialized.ToString());
            return(levelInitialized);
        }
Esempio n. 5
0
        public void RenderLevelBSP(Vector3 cameraPosition, Matrix viewMatrix, Matrix projMatrix, GameTime gameTime, GraphicsDevice graphics)
        {
            int cameraLeaf    = GetCameraLeaf(cameraPosition);
            int cameraCluster = leafs[cameraLeaf].Cluster;

            CurrentCluster = cameraCluster;
            CurrentLeaf    = cameraLeaf;

            if (0 > cameraCluster)
            {
                cameraCluster = lastGoodCluster;
            }
            lastGoodCluster = cameraCluster;

            ResetFacesToDraw();

            BoundingFrustum frustum      = new BoundingFrustum(viewMatrix * projMatrix);
            ArrayList       visibleFaces = new ArrayList();

            foreach (Q3BSPLeaf leaf in leafs)
            {
                if (!visData.FastIsClusterVisible(cameraCluster, leaf.Cluster))
                {
                    continue;
                }

                //// Culls visible leafs. Unsure as to why.
                //if (!frustum.Intersects(leaf.Bounds))
                //{
                //    continue;
                //}

                for (int i = 0; i < leaf.LeafFaceCount; i++)
                {
                    int       faceIndex = leafFaces[leaf.StartLeafFace + i];
                    Q3BSPFace face      = faces[faceIndex];
                    if (face.FaceType != Q3BSPFaceType.Billboard && !facesToDraw[faceIndex])
                    {
                        facesToDraw[faceIndex] = true;
                        visibleFaces.Add(face);
                    }
                }
            }

            if (0 >= visibleFaces.Count)
            {
                return;
            }

            Q3BSPFaceComparer fc = new Q3BSPFaceComparer();

            visibleFaces.Sort(fc);

            graphics.VertexDeclaration = vertexDeclaration;
            Matrix matrixWorldViewProjection = viewMatrix * projMatrix;
            Effect effect;

            int[] indexArray = new int[maximumNumberOfIndicesToDraw];

            int lastTextureIndex      = 0;
            int lastLightMapIndex     = 0;
            int accumulatedIndexCount = 0;

            graphics.RenderState.DepthBufferEnable = true;

            foreach (Q3BSPFace face in visibleFaces)
            {
                if (face.FaceType == Q3BSPFaceType.Patch)
                {
                    effect = shaderManager.GetEffect(face.TextureIndex, face.LightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                    effect.Begin();
                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Begin();
                        patches[face.PatchIndex].Draw(graphics);
                        pass.End();
                    }
                    effect.End();

                    continue;
                }

                if ((face.TextureIndex != lastTextureIndex || face.LightMapIndex != lastLightMapIndex) && accumulatedIndexCount > 0)
                {
                    if (shaderManager.IsMaterialDrawable(lastTextureIndex))
                    {
                        effect = shaderManager.GetEffect(lastTextureIndex, lastLightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                        effect.Begin();
                        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                        {
                            pass.Begin();
                            graphics.DrawUserIndexedPrimitives <Q3BSPVertex>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indexArray, 0, accumulatedIndexCount / 3);
                            pass.End();
                        }
                        effect.End();
                    }

                    //indexArray = new int[maximumNumberOfIndicesToDraw];
                    accumulatedIndexCount = 0;
                }

                lastTextureIndex  = face.TextureIndex;
                lastLightMapIndex = face.LightMapIndex;

                for (int i = 0; i < face.MeshVertexCount; ++i)
                {
                    indexArray[accumulatedIndexCount] = (face.StartVertex + meshVertices[face.StartMeshVertex + i]);
                    accumulatedIndexCount++;
                }
            }

            // Draw the final batch of faces
            if (indexArray.Length != 0 && shaderManager.IsMaterialDrawable(lastTextureIndex))
            {
                effect = shaderManager.GetEffect(lastTextureIndex, lastLightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                effect.Begin();
                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    graphics.DrawUserIndexedPrimitives <Q3BSPVertex>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indexArray, 0, accumulatedIndexCount / 3);
                    pass.End();
                }
                effect.End();
            }
        }
Esempio n. 6
0
        public void RenderLevelBSP(Vector3 cameraPosition, Matrix worldMatrix, Matrix viewMatrix, Matrix projMatrix, GameTime gameTime, GraphicsDevice graphics)
        {
            int cameraLeaf = GetCameraLeaf(Vector3.Transform(cameraPosition, Matrix.Invert(worldMatrix))); /* transform to world coords  */
            //int cameraLeaf = GetCameraLeaf(Vector3.Transform(cameraPosition, worldMatrix));
            //int cameraLeaf = GetCameraLeaf(cameraPosition); /* transform to world coords  */
            int cameraCluster = leafs[cameraLeaf].Cluster;

            CurrentCluster = cameraCluster;
            CurrentLeaf    = cameraLeaf;

            if (0 > cameraCluster)
            {
                cameraCluster = lastGoodCluster;
            }
            lastGoodCluster = cameraCluster;

            ResetFacesToDraw();
            BoundingFrustum frustum      = new BoundingFrustum(Matrix.Multiply(viewMatrix, projMatrix));
            ArrayList       visibleFaces = new ArrayList();

            VisibleLeafs = 0;
            Intersect    = false;
            foreach (Q3BSPLeaf leaf in leafs)
            {
                if (!visData.FastIsClusterVisible(cameraCluster, leaf.Cluster))
                {
                    continue;
                }

                //// Culls visible leafs. Unsure as to why.

                /*
                 * if (!frustum.Intersects(leaf.Bounds))
                 * {
                 *  continue;
                 * }
                 */
                /* oriented bounding boxes fix the upper problem */
                // create oriented bounding box in world space

                obb = new OrientedBoundingBox(leaf.Bounds, worldMatrix);
                if (!frustum.Intersects(obb.AABBWorld))
                {
                    continue;
                }
                else
                {
                    Intersect = true;
                }

                VisibleLeafs++;

                for (int i = 0; i < leaf.LeafFaceCount; i++)
                {
                    int       faceIndex = leafFaces[leaf.StartLeafFace + i];
                    Q3BSPFace face      = faces[faceIndex];
                    if (face.FaceType != Q3BSPFaceType.Billboard && !facesToDraw[faceIndex])
                    {
                        facesToDraw[faceIndex] = true;
                        visibleFaces.Add(face);
                    }
                }
            }

            if (0 >= visibleFaces.Count)
            {
                return;
            }

            Q3BSPFaceComparer fc = new Q3BSPFaceComparer();

            visibleFaces.Sort(fc);

            Matrix matrixWorldViewProjection = worldMatrix * viewMatrix * projMatrix;
            Effect effect;

            short[] indexArray = new short[maximumNumberOfIndicesToDraw];

            int lastTextureIndex      = 0;
            int lastLightMapIndex     = 0;
            int accumulatedIndexCount = 0;

            graphics.DepthStencilState = DepthStencilState.Default;

            foreach (Q3BSPFace face in visibleFaces)
            {
                if (face.FaceType == Q3BSPFaceType.Patch)
                {
                    effect = shaderManager.GetEffect(face.TextureIndex, face.LightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();
                        patches[face.PatchIndex].Draw(graphics);
                    }

                    continue;
                }

                if ((face.TextureIndex != lastTextureIndex || face.LightMapIndex != lastLightMapIndex) && accumulatedIndexCount > 0)
                {
                    if (shaderManager.IsMaterialDrawable(lastTextureIndex))
                    {
                        effect = shaderManager.GetEffect(lastTextureIndex, lastLightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                        {
                            pass.Apply();
                            graphics.DrawUserIndexedPrimitives <Q3BSPVertex>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indexArray, 0, accumulatedIndexCount / 3);
                        }
                    }

                    //indexArray = new int[maximumNumberOfIndicesToDraw];
                    accumulatedIndexCount = 0;
                }

                lastTextureIndex  = face.TextureIndex;
                lastLightMapIndex = face.LightMapIndex;

                for (int i = 0; i < face.MeshVertexCount; ++i)
                {
                    indexArray[accumulatedIndexCount] = (short)(face.StartVertex + meshVertices[face.StartMeshVertex + i]);
                    accumulatedIndexCount++;
                }
            }

            // Draw the final batch of faces
            if (indexArray.Length != 0 && shaderManager.IsMaterialDrawable(lastTextureIndex))
            {
                effect = shaderManager.GetEffect(lastTextureIndex, lastLightMapIndex, viewMatrix, matrixWorldViewProjection, gameTime);

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    graphics.DrawUserIndexedPrimitives <Q3BSPVertex>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indexArray, 0, accumulatedIndexCount / 3);
                }
            }
        }