示例#1
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();
            }
        }
示例#2
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);
                }
            }
        }