private void ApplyStencilTest(StencilTest stencilTest) { if (_renderState.StencilTest.Enabled != stencilTest.Enabled) { Enable(EnableCap.StencilTest, stencilTest.Enabled); _renderState.StencilTest.Enabled = stencilTest.Enabled; } if (stencilTest.Enabled) { ApplyStencil(StencilFace.Front, _renderState.StencilTest.FrontFace, stencilTest.FrontFace); ApplyStencil(StencilFace.Back, _renderState.StencilTest.BackFace, stencilTest.BackFace); } }
public void Set(Context context, IList <Vector3D> positions) { // // This method expects that the positions are ordered in a repeated pattern of // below terrain, above terrain pairs. // // Wall mesh // Mesh wallMesh = new Mesh(); wallMesh.PrimitiveType = PrimitiveType.TriangleStrip; // // Positions // int numberOfLineSegments = (positions.Count / 2) - 1; int numberOfVertices = 2 + numberOfLineSegments + numberOfLineSegments; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); IList <Vector3D> tempPositions = positionsAttribute.Values; wallMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Vertex array // _wallVA = context.CreateVertexArray(wallMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); // // Line mesh // Mesh lineMesh = new Mesh(); lineMesh.PrimitiveType = PrimitiveType.LineStrip; // // Positions // positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); tempPositions = positionsAttribute.Values; lineMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Indices // int numIndices = 4 * numberOfLineSegments; ushort[] indices = new ushort[numIndices]; int baseIndex = 1; for (int i = 0; i < numIndices; i += 4, baseIndex += 2) { indices[i] = (ushort)baseIndex; indices[i + 1] = (ushort)(baseIndex - 1); indices[i + 2] = (ushort)(baseIndex + 1); indices[i + 3] = (ushort)(baseIndex + 2); } IndexBuffer indexBuffer = Device.CreateIndexBuffer(BufferHint.StaticDraw, numIndices * sizeof(ushort)); indexBuffer.CopyFromSystemMemory(indices); // // Vertex array // _lineVA = context.CreateVertexArray(lineMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); _lineVA.IndexBuffer = indexBuffer; // // State // _wallDrawState = new DrawState(); _wallDrawState.RenderState.FacetCulling.Enabled = false; _wallDrawState.RenderState.DepthTest.Enabled = false; _wallDrawState.RenderState.DepthMask = false; _wallDrawState.VertexArray = _lineVA; _wallDrawState.ShaderProgram = _wallSP; _shadowVolumePassOne = new DrawState(); _shadowVolumePassOne.VertexArray = _lineVA; _shadowVolumePassOne.ShaderProgram = _shadowVolumeSP; _shadowVolumePassOne.RenderState.FacetCulling.Enabled = false; _shadowVolumePassOne.RenderState.DepthMask = false; _shadowVolumePassOne.RenderState.ColorMask = new ColorMask(false, false, false, false); StencilTest stOne = _shadowVolumePassOne.RenderState.StencilTest; stOne.Enabled = true; stOne.FrontFace.DepthFailStencilPassOperation = StencilOperation.Decrement; stOne.BackFace.DepthFailStencilPassOperation = StencilOperation.Increment; _shadowVolumePassTwo = new DrawState(); _shadowVolumePassTwo.VertexArray = _lineVA; _shadowVolumePassTwo.ShaderProgram = _shadowVolumeSP; _shadowVolumePassTwo.RenderState.DepthMask = false; StencilTest stTwo = _shadowVolumePassTwo.RenderState.StencilTest; stTwo.Enabled = true; stTwo.FrontFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.Function = StencilTestFunction.NotEqual; stTwo.BackFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.Function = StencilTestFunction.NotEqual; }