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(); } }
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); } } }