Axiom.Graphics.ShadowRenderable.GetRenderOperationForUpdate C# (CSharp) Méthode

GetRenderOperationForUpdate() public méthode

Gets the internal render operation for setup.
public GetRenderOperationForUpdate ( ) : RenderOperation
Résultat RenderOperation
		public RenderOperation GetRenderOperationForUpdate()
		{
			return renderOperation;
		}

Usage Example

        /// <summary>
        ///		Generates the indexes required to render a shadow volume into the
        ///		index buffer which is passed in, and updates shadow renderables to use it.
        /// </summary>
        /// <param name="edgeData">The edge information to use.</param>
        /// <param name="indexBuffer">The buffer into which to write data into; current
        ///	contents are assumed to be discardable.</param>
        /// <param name="light">The light, mainly for type info as silhouette calculations
        /// should already have been done in <see cref="UpdateEdgeListLightFacing"/></param>
        /// <param name="shadowRenderables">A list of shadow renderables which has
        /// already been constructed but will need populating with details of
        /// the index ranges to be used.</param>
        /// <param name="flags">Additional controller flags, see <see cref="ShadowRenderableFlags"/>.</param>
        protected virtual void GenerateShadowVolume(EdgeData edgeData, HardwareIndexBuffer indexBuffer, Light light,
                                                    ShadowRenderableList shadowRenderables, int flags)
        {
            // Edge groups should be 1:1 with shadow renderables
            Debug.Assert(edgeData.edgeGroups.Count == shadowRenderables.Count);

            LightType lightType = light.Type;

            bool extrudeToInfinity = (flags & (int)ShadowRenderableFlags.ExtrudeToInfinity) > 0;

            // Lock index buffer for writing
            IntPtr idxPtr = indexBuffer.Lock(BufferLocking.Discard);

            int indexStart = 0;

            unsafe {
                // TODO: Will currently cause an overflow for 32 bit indices, revisit
                short *pIdx  = (short *)idxPtr.ToPointer();
                int    count = 0;

                // Iterate over the groups and form renderables for each based on their
                // lightFacing
                for (int groupCount = 0; groupCount < edgeData.edgeGroups.Count; groupCount++)
                {
                    EdgeData.EdgeGroup eg = (EdgeData.EdgeGroup)edgeData.edgeGroups[groupCount];
                    ShadowRenderable   si = (ShadowRenderable)shadowRenderables[groupCount];

                    RenderOperation lightShadOp = null;

                    // Initialise the index bounds for this shadow renderable
                    RenderOperation shadOp = si.GetRenderOperationForUpdate();
                    shadOp.indexData.indexCount = 0;
                    shadOp.indexData.indexStart = indexStart;

                    // original number of verts (without extruded copy)
                    int  originalVertexCount = eg.vertexData.vertexCount;
                    bool firstDarkCapTri     = true;
                    int  darkCapStart        = 0;

                    for (int edgeCount = 0; edgeCount < eg.edges.Count; edgeCount++)
                    {
                        EdgeData.Edge edge = (EdgeData.Edge)eg.edges[edgeCount];

                        EdgeData.Triangle t1 = (EdgeData.Triangle)edgeData.triangles[edge.triIndex[0]];
                        EdgeData.Triangle t2 =
                            edge.isDegenerate ? (EdgeData.Triangle)edgeData.triangles[edge.triIndex[0]] : (EdgeData.Triangle)edgeData.triangles[edge.triIndex[1]];

                        if (t1.lightFacing && (edge.isDegenerate || !t2.lightFacing))
                        {
                            /* Silhouette edge, first tri facing the light
                             * Also covers degenerate tris where only tri 1 is valid
                             * Remember verts run anticlockwise along the edge from
                             * tri 0 so to point shadow volume tris outward, light cap
                             * indexes have to be backwards
                             *
                             * We emit 2 tris if light is a point light, 1 if light
                             * is directional, because directional lights cause all
                             * points to converge to a single point at infinity.
                             *
                             * First side tri = near1, near0, far0
                             * Second tri = far0, far1, near1
                             *
                             * 'far' indexes are 'near' index + originalVertexCount
                             * because 'far' verts are in the second half of the
                             * buffer
                             */
                            pIdx[count++] = (short)edge.vertIndex[1];
                            pIdx[count++] = (short)edge.vertIndex[0];
                            pIdx[count++] = (short)(edge.vertIndex[0] + originalVertexCount);
                            shadOp.indexData.indexCount += 3;

                            if (!(lightType == LightType.Directional && extrudeToInfinity))
                            {
                                // additional tri to make quad
                                pIdx[count++] = (short)(edge.vertIndex[0] + originalVertexCount);
                                pIdx[count++] = (short)(edge.vertIndex[1] + originalVertexCount);
                                pIdx[count++] = (short)edge.vertIndex[1];
                                shadOp.indexData.indexCount += 3;
                            }

                            // Do dark cap tri
                            // Use McGuire et al method, a triangle fan covering all silhouette
                            // edges and one point (taken from the initial tri)
                            if ((flags & (int)ShadowRenderableFlags.IncludeDarkCap) > 0)
                            {
                                if (firstDarkCapTri)
                                {
                                    darkCapStart    = edge.vertIndex[0] + originalVertexCount;
                                    firstDarkCapTri = false;
                                }
                                else
                                {
                                    pIdx[count++] = (short)darkCapStart;
                                    pIdx[count++] = (short)(edge.vertIndex[1] + originalVertexCount);
                                    pIdx[count++] = (short)(edge.vertIndex[0] + originalVertexCount);
                                    shadOp.indexData.indexCount += 3;
                                }
                            }
                        }
                        else if (!t1.lightFacing && (edge.isDegenerate || t2.lightFacing))
                        {
                            // Silhouette edge, second tri facing the light
                            // Note edge indexes inverse of when t1 is light facing
                            pIdx[count++] = (short)edge.vertIndex[0];
                            pIdx[count++] = (short)edge.vertIndex[1];
                            pIdx[count++] = (short)(edge.vertIndex[1] + originalVertexCount);
                            shadOp.indexData.indexCount += 3;

                            if (!(lightType == LightType.Directional && extrudeToInfinity))
                            {
                                // additional tri to make quad
                                pIdx[count++] = (short)(edge.vertIndex[1] + originalVertexCount);
                                pIdx[count++] = (short)(edge.vertIndex[0] + originalVertexCount);
                                pIdx[count++] = (short)edge.vertIndex[0];
                                shadOp.indexData.indexCount += 3;
                            }

                            // Do dark cap tri
                            // Use McGuire et al method, a triangle fan covering all silhouette
                            // edges and one point (taken from the initial tri)
                            if ((flags & (int)ShadowRenderableFlags.IncludeDarkCap) > 0)
                            {
                                if (firstDarkCapTri)
                                {
                                    darkCapStart    = edge.vertIndex[1] + originalVertexCount;
                                    firstDarkCapTri = false;
                                }
                                else
                                {
                                    pIdx[count++] = (short)darkCapStart;
                                    pIdx[count++] = (short)(edge.vertIndex[0] + originalVertexCount);
                                    pIdx[count++] = (short)(edge.vertIndex[1] + originalVertexCount);
                                    shadOp.indexData.indexCount += 3;
                                }
                            }
                        }
                    }

                    // Do light cap
                    if ((flags & (int)ShadowRenderableFlags.IncludeLightCap) > 0)
                    {
                        ShadowRenderable lightCapRend = null;

                        if (si.IsLightCapSeperate)
                        {
                            // separate light cap
                            lightCapRend = si.LightCapRenderable;
                            lightShadOp  = lightCapRend.GetRenderOperationForUpdate();
                            lightShadOp.indexData.indexCount = 0;
                            // start indexes after the current total
                            // NB we don't update the total here since that's done below
                            lightShadOp.indexData.indexStart =
                                indexStart + shadOp.indexData.indexCount;
                        }

                        for (int triCount = 0; triCount < edgeData.triangles.Count; triCount++)
                        {
                            EdgeData.Triangle t = (EdgeData.Triangle)edgeData.triangles[triCount];

                            // Light facing, and vertex set matches
                            if (t.lightFacing && t.vertexSet == eg.vertexSet)
                            {
                                pIdx[count++] = (short)t.vertIndex[0];
                                pIdx[count++] = (short)t.vertIndex[1];
                                pIdx[count++] = (short)t.vertIndex[2];

                                if (lightShadOp != null)
                                {
                                    lightShadOp.indexData.indexCount += 3;
                                }
                                else
                                {
                                    shadOp.indexData.indexCount += 3;
                                }
                            }
                        }
                    }

                    // update next indexStart (all renderables sharing the buffer)
                    indexStart += shadOp.indexData.indexCount;

                    // add on the light cap too
                    if (lightShadOp != null)
                    {
                        indexStart += lightShadOp.indexData.indexCount;
                    }
                }
            }

            // Unlock index buffer
            indexBuffer.Unlock();

            Debug.Assert(indexStart <= indexBuffer.IndexCount, "Index buffer overrun while generating shadow volume!");
        }