Contains all the information required to render a set of vertices. This includes a list of VertexBuffers.
This class contains
Inheritance: DisposableObject
示例#1
0
        /// <summary>
        /// Class level dispose method
        /// </summary>
        /// <remarks>
        /// When implementing this method in an inherited class the following template should be used;
        /// protected override void dispose( bool disposeManagedResources )
        /// {
        ///     if ( !isDisposed )
        ///     {
        ///         if ( disposeManagedResources )
        ///         {
        ///             // Dispose managed resources.
        ///         }
        ///
        ///         // There are no unmanaged resources to release, but
        ///         // if we add them, they need to be released here.
        ///     }
        ///
        ///     // If it is available, make the call to the
        ///     // base class's Dispose(Boolean) method
        ///     base.dispose( disposeManagedResources );
        /// }
        /// </remarks>
        /// <param name="disposeManagedResources">True if Unmanaged resources should be released.</param>
        protected override void dispose(bool disposeManagedResources)
        {
            if (!IsDisposed)
            {
                if (disposeManagedResources)
                {
                    // Dispose managed resources.
                    if (this.renderOperation != null)
                    {
                        if (!this.renderOperation.IsDisposed)
                        {
                            this.renderOperation.Dispose();
                        }

                        this.renderOperation = null;
                    }

                    if (this.material != null)
                    {
                        if (!this.material.IsDisposed)
                        {
                            this.material.Dispose();
                        }

                        this.material = null;
                    }
                }

                // There are no unmanaged resources to release, but
                // if we add them, they need to be released here.
            }

            base.dispose(disposeManagedResources);
        }
 /// <summary>
 ///		Gets the render operation for this shadow renderable.
 /// </summary>
 /// <param name="op"></param>
 public void GetRenderOperation(RenderOperation op)
 {
     // TODO: Ensure all other places throughout the engine set these properly
     op.indexData     = renderOp.indexData;
     op.useIndices    = true;
     op.operationType = OperationType.TriangleList;
     op.vertexData    = renderOp.vertexData;
 }
        public override void GetRenderOperation(RenderOperation op)
        {
            // LineLists never use indices
            op.useIndices = false;
            op.indexData = null;

            // set the operation type
            op.operationType = OperationType.LineList;

            // set the vertex data correctly
            op.vertexData = vertexData;
        }
        public override void GetRenderOperation(RenderOperation op)
        {
            // LineLists never use indices
            op.useIndices = false;
            op.indexData  = null;

            // set the operation type
            op.operationType = OperationType.LineList;

            // set the vertex data correctly
            op.vertexData = vertexData;
        }
 public override void GetRenderOperation(RenderOperation op)
 {
     ValidateBrush();
     op.useIndices = true;
     op.operationType = OperationType.TriangleList;
     if (rebuildVertex)
     {
         buildVertexData();
         rebuildVertex = false;
     }
     op.vertexData = vertexData;
     if (rebuildIndex)
     {
         buildIndexData();
         rebuildIndex = false;
     }
     op.indexData = indexData;
 }
 /// <summary>
 ///    Gets the render operation required to send this object to the frame buffer.
 /// </summary>
 public void GetRenderOperation(RenderOperation op)
 {
 }
示例#7
0
		/// <summary>
		/// Class level dispose method
		/// </summary>
		/// <remarks>
		/// When implementing this method in an inherited class the following template should be used;
		/// protected override void dispose( bool disposeManagedResources )
		/// {
		/// 	if ( !isDisposed )
		/// 	{
		/// 		if ( disposeManagedResources )
		/// 		{
		/// 			// Dispose managed resources.
		/// 		}
		///
		/// 		// There are no unmanaged resources to release, but
		/// 		// if we add them, they need to be released here.
		/// 	}
		///
		/// 	// If it is available, make the call to the
		/// 	// base class's Dispose(Boolean) method
		/// 	base.dispose( disposeManagedResources );
		/// }
		/// </remarks>
		/// <param name="disposeManagedResources">True if Unmanaged resources should be released.</param>
		protected override void dispose( bool disposeManagedResources )
		{
			if ( !IsDisposed )
			{
				if ( disposeManagedResources )
				{
					// Dispose managed resources.
					if ( renderOperation != null )
					{
                        if (!this.renderOperation.IsDisposed)
                            this.renderOperation.Dispose();

						renderOperation = null;
					}

                    if (indexData != null)
                    {
                        if (!indexData.IsDisposed)
                            indexData.Dispose();

                        indexData = null;
                    }

                    if (vertexData != null)
                    {
                        if (!vertexData.IsDisposed)
                            vertexData.Dispose();

                        vertexData = null;
                    }
				}

				// There are no unmanaged resources to release, but
				// if we add them, they need to be released here.
			}

            base.dispose(disposeManagedResources);
		}
        public override void GetRenderOperation(RenderOperation op)
        {
            Debug.Assert(inBoundary);
            Debug.Assert(renderOp.vertexData != null, "attempting to render heightField with no vertexData");
            Debug.Assert(renderOp.indexData != null, "attempting to render heightField with no indexData");

            op.useIndices = this.renderOp.useIndices;
            op.operationType = this.renderOp.operationType;
            op.vertexData = this.renderOp.vertexData;
            op.indexData = this.renderOp.indexData;
        }
示例#9
0
 /// Gets all the patches within an AABB in world coordinates as GeometryData structs
 public virtual void GetRenderOpsInBox( AxisAlignedBox box, ArrayList opList)
 {
     if ( MathUtil.Intersects(box, bounds ) != Intersection.None )
     {
         RenderOperation rend = new RenderOperation();
         renderable.GetRenderOperation( rend );
         opList.Add( rend );
     }
 }
        public TerrainPage(Vector3 location, Page page)
        {
            this.location = location;
            pageCoord = new PageCoord(location, TerrainManager.Instance.PageSize);

            terrainMaterial = TerrainManager.Instance.TerrainMaterialConfig.NewTerrainMaterial(pageCoord.X, pageCoord.Z);

            currentPage = page;
            Debug.Assert(location == currentPage.Location, "creating TerrainPage with page at different location");
            numTiles = currentPage.NumTiles;
            patchSize = TerrainManager.Instance.PageSize / numTiles;

            // set up the page height maps for this page of terrain
            subPageSize = TerrainManager.Instance.SubPageSize;
            int subPagesPerPage = TerrainManager.Instance.PageSize / subPageSize;

            pageHeightMap = new PageHeightMap(subPagesPerPage, TerrainManager.Instance.PageSize,
                TerrainManager.Instance.MaxMetersPerSample, TerrainManager.Instance.MinMetersPerSample);

            pageHeightMap.Location = location;

            // create and position a scene node for this terrain page
            string nodeName = String.Format("TerrainPage[{0},{1}]", (int)(location.x / TerrainManager.oneMeter),
                (int)(location.z / TerrainManager.oneMeter));

            // DEBUG - Console.WriteLine("Creating {0}", name);
            sceneNode = TerrainManager.Instance.WorldRootSceneNode.CreateChildSceneNode(nodeName);

            sceneNode.Position = location;

            sceneNode.AttachObject(this);

            // create the render operation
            renderOp = new RenderOperation();
            renderOp.operationType = OperationType.TriangleList;
            renderOp.useIndices = true;

            CreatePatches();

            SetCastShadows();

            UpdateBounds();

            TerrainManager.Instance.ShadowConfig.ShadowTechniqueChange += ShadowTechniqueChangeHandler;
        }
示例#11
0
		/// <summary>
		///		Internal utility method for rendering a single object.
		/// </summary>
		/// <param name="renderable">The renderable to issue to the pipeline.</param>
		/// <param name="pass">The pass which is being used.</param>
		/// <param name="doLightIteration">If true, this method will issue the renderable to
		/// the pipeline possibly multiple times, if the pass indicates it should be
		/// done once per light.</param>
		/// <param name="manualLightList">Only applicable if 'doLightIteration' is false, this
		/// method allows you to pass in a previously determined set of lights
		/// which will be used for a single render of this object.</param>
		protected virtual void RenderSingleObject( IRenderable renderable,
												   Pass pass,
												   bool doLightIteration,
												   LightList manualLightList )
		{
			ushort numMatrices = 0;

			// grab the current scene detail level
			PolygonMode camPolyMode = this.cameraInProgress.PolygonMode;

			// get the world matrices and the count
			renderable.GetWorldTransforms( this.xform );
			numMatrices = renderable.NumWorldTransforms;

			// set the world matrices in the render system
			if ( numMatrices > 1 )
			{
				this.targetRenderSystem.SetWorldMatrices( this.xform, numMatrices );
			}
			else
			{
				this.targetRenderSystem.WorldMatrix = this.xform[ 0 ];
			}

			// issue view/projection changes (if any)
			this.UseRenderableViewProjection( renderable );

			if ( !this.suppressRenderStateChanges )
			{
				bool passSurfaceAndLightParams = true;
				if ( pass.IsProgrammable )
				{
					// Tell auto params object about the renderable change
					this.autoParamDataSource.Renderable = renderable;
					pass.UpdateAutoParamsNoLights( this.autoParamDataSource );
					if ( pass.HasVertexProgram )
					{
						passSurfaceAndLightParams = pass.VertexProgram.PassSurfaceAndLightStates;
					}
				}

				// issue texture units that depend on updated view matrix
				// reflective env mapping is one case
				for ( int i = 0; i < pass.TextureUnitStageCount; i++ )
				{
					TextureUnitState texUnit = pass.GetTextureUnitState( i );

					if ( texUnit.HasViewRelativeTexCoordGen )
					{
					    targetRenderSystem.SetTextureUnitSettings( i, texUnit );
					    //this.targetRenderSystem.SetTextureUnit( i, texUnit, !pass.HasFragmentProgram );
					}
				}

				// Normalize normals
				bool thisNormalize = renderable.NormalizeNormals;

				if ( thisNormalize != normalizeNormals )
				{
					this.targetRenderSystem.NormalizeNormals = thisNormalize;
					normalizeNormals = thisNormalize;
				}

				// Set up the solid / wireframe override
				PolygonMode requestedMode = pass.PolygonMode;
				if ( renderable.PolygonModeOverrideable == true )
				{
					// check camera detial only when render detail is overridable
					if ( requestedMode > camPolyMode )
					{
						// only downgrade detail; if cam says wireframe we don't go up to solid
						requestedMode = camPolyMode;
					}
				}

				if ( requestedMode != this.lastPolyMode )
				{
					this.targetRenderSystem.PolygonMode = requestedMode;
					this.lastPolyMode = requestedMode;
				}

				// TODO: Add ClipPlanes to RenderSystem.cs
				// This is removed in OGRE 1.6.0... no need to port - J. Price
				//targetRenderSystem.ClipPlanes = renderable.ClipPlanes;

				// get the renderables render operation
				op = renderable.RenderOperation;
				// TODO: Add srcRenderable to RenderOperation.cs
				//op.srcRenderable = renderable;

				if ( doLightIteration )
				{
					// Here's where we issue the rendering operation to the render system
					// Note that we may do this once per light, therefore it's in a loop
					// and the light parameters are updated once per traversal through the
					// loop
					LightList rendLightList = renderable.Lights;
					bool iteratePerLight = pass.IteratePerLight;
					int numIterations = iteratePerLight ? rendLightList.Count : 1;
					LightList lightListToUse = null;

					for ( int i = 0; i < numIterations; i++ )
					{
						// determine light list to use
						if ( iteratePerLight )
						{
							localLightList.Clear();

							// check whether we need to filter this one out
							if ( pass.RunOnlyOncePerLightType && pass.OnlyLightType != rendLightList[ i ].Type )
							{
								// skip this one
								continue;
							}

							localLightList.Add( rendLightList[ i ] );
							lightListToUse = localLightList;
						}
						else
						{
							// use complete light list
							lightListToUse = rendLightList;
						}

						if ( pass.IsProgrammable )
						{
							// Update any automatic gpu params for lights
							// Other bits of information will have to be looked up
							this.autoParamDataSource.SetCurrentLightList( lightListToUse );
							pass.UpdateAutoParamsLightsOnly( this.autoParamDataSource );

						    UpdateGpuProgramParameters( pass );
						}

						// Do we need to update light states?
						// Only do this if fixed-function vertex lighting applies
						if ( pass.LightingEnabled && passSurfaceAndLightParams )
						{
							this.targetRenderSystem.UseLights( lightListToUse, pass.MaxSimultaneousLights );
						}
                        this.targetRenderSystem.CurrentPassIterationCount = pass.IterationCount;
						// issue the render op
						this.targetRenderSystem.Render( op );
					} // iterate per light
				}
				else
				{
					// do we need to update GPU program parameters?
					if ( pass.IsProgrammable )
					{
						// do we have a manual light list
						if ( manualLightList != null )
						{
							// Update any automatic gpu params for lights
							// Other bits of information will have to be looked up
							this.autoParamDataSource.SetCurrentLightList( manualLightList );
							pass.UpdateAutoParamsLightsOnly( this.autoParamDataSource );
						}

					    UpdateGpuProgramParameters( pass );
					}

					// Use manual lights if present, and not using vertex programs
					if ( manualLightList != null && pass.LightingEnabled && passSurfaceAndLightParams )
					{
						this.targetRenderSystem.UseLights( manualLightList, pass.MaxSimultaneousLights );
					}
                    this.targetRenderSystem.CurrentPassIterationCount = pass.IterationCount;
					// issue the render op
					this.targetRenderSystem.Render( op );
				}
			}
			else
			{
				// suppressRenderStateChanges
				// Just render
                this.targetRenderSystem.CurrentPassIterationCount = 1;
				this.targetRenderSystem.Render( op );
			}

			// Reset view / projection changes if any
			this.ResetViewProjectionMode();
		}
示例#12
0
		/// <summary>
		/// Class level dispose method
		/// </summary>
		/// <remarks>
		/// When implementing this method in an inherited class the following template should be used;
		/// protected override void dispose( bool disposeManagedResources )
		/// {
		/// 	if ( !isDisposed )
		/// 	{
		/// 		if ( disposeManagedResources )
		/// 		{
		/// 			// Dispose managed resources.
		/// 		}
		///
		/// 		// There are no unmanaged resources to release, but
		/// 		// if we add them, they need to be released here.
		/// 	}
		///
		/// 	// If it is available, make the call to the
		/// 	// base class's Dispose(Boolean) method
		/// 	base.dispose( disposeManagedResources );
		/// }
		/// </remarks>
		/// <param name="disposeManagedResources">True if Unmanaged resources should be released.</param>
		protected virtual void dispose( bool disposeManagedResources )
		{
			if ( !isDisposed )
			{
				if ( disposeManagedResources )
				{
					// Dispose managed resources.
					if ( renderOperation != null )
					{
						renderOperation.vertexData = null;
						renderOperation.indexData = null;
						renderOperation = null;
					}
				}

				// There are no unmanaged resources to release, but
				// if we add them, they need to be released here.
			}
			isDisposed = true;
		}
示例#13
0
		/// <summary>
		/// Render something to the active viewport.
		/// </summary>
		/// <remarks>
		/// Low-level rendering interface to perform rendering
		/// operations. Unlikely to be used directly by client
		/// applications, since the <see cref="SceneManager"/> and various support
		/// classes will be responsible for calling this method.
		/// Can only be called between BeginScene and EndScene
		/// </remarks>
		/// <param name="op">
		/// A rendering operation instance, which contains details of the operation to be performed.
		/// </param>
		public override void Render(RenderOperation op)
		{
			//StateManager.RasterizerState.FillMode = XFG.FillMode.Solid;
			StateManager.CommitState(_device);
#if SILVERLIGHT
			StateManager.ResetState(_device);
#endif

			Effect effectToUse;

			if (useSkinnedEffect)
			{
				var boneMatrices = new Matrix[Root.Instance.SceneManager.AutoParamData.WorldMatrixCount];
				for (var i = 0; i < Root.Instance.SceneManager.AutoParamData.WorldMatrixCount; i++)
				{
#if!(XBOX || XBOX360)
					boneMatrices[i] =
						XnaHelper.Convert(Root.Instance.SceneManager.AutoParamData.WorldMatrixArray[i]);
#else
					Axiom.Math.Matrix4 matrix = Root.Instance.SceneManager.AutoParamData.WorldMatrixArray[i];
					boneMatrices[i] = XnaHelper.Convert( matrix  );
#endif
				}
				skinnedEffect.SetBoneTransforms(boneMatrices);
				effectToUse = skinnedEffect;
			}
			else
			{
				basicEffect.VertexColorEnabled =
					op.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Diffuse) != null;

				basicEffect.TextureEnabled =
					op.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.TexCoords) != null;

				effectToUse = basicEffect;
			}

			var ve = op.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.Normal);
			if (ve != null) //this operation has Normals
			{
				basicEffect.LightingEnabled = false; //turn off lighting
			}

			basicEffect.LightingEnabled = (ve != null);

			//Debug.WriteLine(" Vertices=" + op.vertexData.vertexCount +
			//                " Normals=" + (ve != null) +
			//                " Lighting=" + basicEffect.LightingEnabled +
			//                " DL0=" + basicEffect.DirectionalLight0.Enabled +
			//                " Fog=" + basicEffect.FogEnabled +
			//                " " + effectToUse);

			// effectToUse.CurrentTechnique.Passes[0].Apply();
			//DualTextureEffect dualTextureEffect;

			// don't even bother if there are no vertices to render, causes problems on some cards (FireGL 8800));)
			if (op.vertexData.vertexCount == 0)
			{
				return;
			}

			// class base implementation first
			base.Render(op);


			/*---------------shaders generator part------*/
#if AXIOM_FF_EMULATION

			if ( Root.Instance.RenderSystem.ConfigOptions[ "Use Content Pipeline" ].Value != "Yes" )
			{

				if ( !VertexShaderIsSet || !PixelShaderIsSet )
				{
					FixedFunctionEmulation.VertexBufferDeclaration vbd = new FixedFunctionEmulation.VertexBufferDeclaration();
					List<FixedFunctionEmulation.VertexBufferElement> lvbe = new List<FixedFunctionEmulation.VertexBufferElement>( op.vertexData.vertexDeclaration.ElementCount );

					int textureLayer = 0;
					for ( int i = 0; i < op.vertexData.vertexDeclaration.ElementCount; i++ )
					{
						FixedFunctionEmulation.VertexBufferElement element = new FixedFunctionEmulation.VertexBufferElement();

						element.VertexElementIndex = (ushort)op.vertexData.vertexDeclaration[ i ].Index;
						element.VertexElementSemantic = op.vertexData.vertexDeclaration[ i ].Semantic;
						element.VertexElementType = op.vertexData.vertexDeclaration[ i ].Type;

						//uncomment this to see the texture shadow
						//the problem is that some texcoords are given but texture is not set
						//
						/*if (//op.vertexData.vertexDeclaration[i].Type == VertexElementType.Float1 &&
							op.vertexData.vertexDeclaration[ i ].Semantic == VertexElementSemantic.TexCoords )
						{
							if ( !texStageDesc[ textureLayer ].Enabled )
							{

								texStageDesc[ textureLayer ].layerBlendMode = new LayerBlendModeEx();
								texStageDesc[ textureLayer ].layerBlendMode.blendType = LayerBlendType.Color;
								texStageDesc[ textureLayer ].layerBlendMode.operation = LayerBlendOperationEx.Modulate;
								texStageDesc[ textureLayer ].layerBlendMode.source1 = LayerBlendSource.Texture;
								texStageDesc[ textureLayer ].layerBlendMode.source2 = LayerBlendSource.Current;

								texStageDesc[ textureLayer ].Enabled = true;
								//texStageDesc[ textureLayer ].autoTexCoordType = TexCoordCalcMethod.ProjectiveTexture;
								texStageDesc[ textureLayer ].coordIndex = textureLayer;
								switch ( op.vertexData.vertexDeclaration[ i ].Type )
								{
									case VertexElementType.Float1:
										texStageDesc[ textureLayer ].texType = TextureType.OneD;
										break;
									case VertexElementType.Float2:
										texStageDesc[ textureLayer ].texType = TextureType.TwoD;
										break;
									case VertexElementType.Float3:
										texStageDesc[ textureLayer ].texType = TextureType.ThreeD;
										break;
								}
								//texStageDesc[textureLayer].layerBlendMode = new LayerBlendModeEx();
							}
							textureLayer++;
						}*/

						lvbe.Add( element );
					}
					vbd.VertexBufferElements = lvbe;


					for ( int i = 0; i < Config.MaxTextureLayers; i++ )
					{
						FixedFunctionEmulation.TextureLayerState tls = new FixedFunctionEmulation.TextureLayerState();

						if ( texStageDesc[ i ].Enabled )
						//if (texStageDesc[i].tex != null)
						{
							tls.TextureType = texStageDesc[ i ].texType;
							tls.TexCoordCalcMethod = texStageDesc[ i ].autoTexCoordType;
							tls.CoordIndex = texStageDesc[ i ].coordIndex;
							tls.LayerBlendMode = texStageDesc[ i ].layerBlendMode;
							//TextureLayerStateList

							_fixedFunctionState.TextureLayerStates.Add( tls );
						}

						FixedFunctionEmulation.GeneralFixedFunctionState gff;
						gff = _fixedFunctionState.GeneralFixedFunctionState;

						gff.EnableLighting = _ffProgramParameters.LightingEnabled;
						gff.FogMode = _ffProgramParameters.FogMode;
						_fixedFunctionState.GeneralFixedFunctionState = gff;

						//lights
						foreach ( Light l in _ffProgramParameters.Lights )
							_fixedFunctionState.Lights.Add( l.Type );


						_fixedFunctionProgram = (FixedFunctionEmulation.HLSLFixedFunctionProgram)_shaderManager.GetShaderPrograms( "hlsl", vbd, _fixedFunctionState );

						_fixedFunctionProgram.FragmentProgramUsage.Program.DefaultParameters.NamedParamCount.ToString();


						_fixedFunctionProgram.SetFixedFunctionProgramParameters( _ffProgramParameters );

						//Bind Vertex Program
						if ( !VertexShaderIsSet )
						{
							BindGpuProgram( _fixedFunctionProgram.VertexProgramUsage.Program.BindingDelegate );
							BindGpuProgramParameters( GpuProgramType.Vertex, _fixedFunctionProgram.VertexProgramUsage.Params );
							needToUnmapVS = true;
						}
						// Bind Fragment Program 
						if ( !PixelShaderIsSet )
						{
							BindGpuProgram( _fixedFunctionProgram.FragmentProgramUsage.Program.BindingDelegate );
							BindGpuProgramParameters( GpuProgramType.Fragment, _fixedFunctionProgram.FragmentProgramUsage.Params );
							needToUnmapFS = true;
						}

						//clear parameters lists for next frame
						_fixedFunctionState.Lights.Clear();
						_fixedFunctionState.TextureLayerStates.Clear();
						//_fixedFunctionState.MaterialEnabled = false; 
						//_ffProgramParameters.FogMode = FogMode.None;


					}
				}
			}
			/*---------------------------------------------------------------------------------------------------------*/
#endif
			var vertDecl = (XnaVertexDeclaration)op.vertexData.vertexDeclaration;
			// set the vertex declaration and buffer binding 
			//_device.VertexDeclaration = vertDecl.XnaVertexDecl;
			_setVertexBufferBinding(op.vertexData.vertexBufferBinding);

			PrimitiveType primType = 0;
			switch (op.operationType)
			{
				case OperationType.PointList:
					primType = PrimitiveType.LineList; /* XNA 4.0 doesn't support PointList so using LineList instead */
					primCount = op.useIndices ? op.indexData.indexCount : op.vertexData.vertexCount;
					break;
				case OperationType.LineList:
					primType = PrimitiveType.LineList;
					primCount = (op.useIndices ? op.indexData.indexCount : op.vertexData.vertexCount) / 2;
					break;
				case OperationType.LineStrip:
					primType = PrimitiveType.LineStrip;
					primCount = (op.useIndices ? op.indexData.indexCount : op.vertexData.vertexCount) - 1;
					break;
				case OperationType.TriangleList:
					primType = PrimitiveType.TriangleList;
					primCount = (op.useIndices ? op.indexData.indexCount : op.vertexData.vertexCount) / 3;
					break;
				case OperationType.TriangleStrip:
					primType = PrimitiveType.TriangleStrip;
					primCount = (op.useIndices ? op.indexData.indexCount : op.vertexData.vertexCount) - 2;
					break;
				case OperationType.TriangleFan:
					throw new Exception("XNA 4.0 doesn't support TriangleFan");
			} // switch(primType)

			try
			{
				// are we gonna use indices?
				if (op.useIndices)
				{
					var idxBuffer = (XnaHardwareIndexBuffer)op.indexData.indexBuffer;
					_device.Indices = idxBuffer.XnaIndexBuffer;
					foreach (var pass in effectToUse.CurrentTechnique.Passes)
					{
						pass.Apply();                      
						_device.DrawIndexedPrimitives(primType, op.vertexData.vertexStart, 0, op.vertexData.vertexCount,
													   op.indexData.indexStart, primCount);
					}
				}
				else
				{
					// draw vertices without indices
					foreach (var pass in effectToUse.CurrentTechnique.Passes)
					{
						pass.Apply();
						_device.DrawPrimitives(primType, op.vertexData.vertexStart, primCount);
					}
				}
			}
			catch (InvalidOperationException ioe)
			{
				LogManager.Instance.Write("Failed to draw RenderOperation : ", LogManager.BuildExceptionString(ioe));
			}
			//crap hack, set the sources back to null to allow accessing vertices and indices buffers
			_device.SetVertexBuffer(null);
			_device.Indices = null;
			_device.Textures[0] = null;

#if AXIOM_FF_EMULATION
	/*---------------shaders generator part------*/
			if ( needToUnmapVS )
			{
				UnbindGpuProgram( GpuProgramType.Vertex );
			}

			if ( needToUnmapFS )
			{
				UnbindGpuProgram( GpuProgramType.Fragment );
			}
			/*--------------------------------------------*/
#endif
		}
示例#14
0
 /// <summary>
 ///    Returns the geometry to use during rendering.
 /// </summary>
 /// <param name="op"></param>
 public override void GetRenderOperation(Axiom.Graphics.RenderOperation op)
 {
     op.vertexData    = renderOp.vertexData;
     op.operationType = renderOp.operationType;
     op.useIndices    = renderOp.useIndices;
 }
示例#15
0
		/// <summary>
		///		Overloaded method.
		/// </summary>
		/// <param name="op"></param>
		/// <returns></returns>
		public void GetRenderOperation( RenderOperation op )
		{
			// call overloaded method with lod index of 0 by default
			GetRenderOperation( op, 0 );
		}
示例#16
0
		public void ManualRender( RenderOperation op,
								  Pass pass,
								  Viewport vp,
								  Matrix4 worldMatrix,
								  Matrix4 viewMatrix,
								  Matrix4 projMatrix )
		{
			this.ManualRender( op, pass, vp, worldMatrix, viewMatrix, projMatrix, false );
		}
        /// <summary>
        /// generates renderOps from billboards.  nulls billboards when done.
        /// </summary>
        public void FinishRebuild()
        {
            foreach (string textureName in billboards.Keys)
            {
                foreach (int alpha in billboards[textureName].Keys)
                {
                    List<float[]>bbList = billboards[textureName][alpha];

                    RenderOperation renderOp = new RenderOperation();
                    renderOp.operationType = OperationType.TriangleList;
                    renderOp.useIndices = false;

                    VertexData vertexData = new VertexData();

                    vertexData.vertexCount = 6 * bbList.Count;
                    vertexData.vertexStart = 0;

                    // free the original vertex declaration to avoid a leak
                    HardwareBufferManager.Instance.DestroyVertexDeclaration(vertexData.vertexDeclaration);

                    // use common vertex declaration
                    vertexData.vertexDeclaration = TreeGroup.BillboardVertexDeclaration;

                    // create the hardware vertex buffer and set up the buffer binding
                    HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                        vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                        BufferUsage.StaticWriteOnly, false);

                    vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

                    renderOp.vertexData = vertexData;

                    // lock the vertex buffer
                    IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

                    int bufferOff = 0;

                    unsafe
                    {
                        float* buffer = (float*)ipBuf.ToPointer();
                        foreach (float[] src in bbList)
                        {
                            buffer[bufferOff++] = src[0];
                            buffer[bufferOff++] = src[1];
                            buffer[bufferOff++] = src[2];
                            buffer[bufferOff++] = src[3];
                            buffer[bufferOff++] = src[4];

                            buffer[bufferOff++] = src[5];
                            buffer[bufferOff++] = src[6];
                            buffer[bufferOff++] = src[7];
                            buffer[bufferOff++] = src[8];
                            buffer[bufferOff++] = src[9];

                            buffer[bufferOff++] = src[10];
                            buffer[bufferOff++] = src[11];
                            buffer[bufferOff++] = src[12];
                            buffer[bufferOff++] = src[13];
                            buffer[bufferOff++] = src[14];

                            buffer[bufferOff++] = src[10];
                            buffer[bufferOff++] = src[11];
                            buffer[bufferOff++] = src[12];
                            buffer[bufferOff++] = src[13];
                            buffer[bufferOff++] = src[14];

                            buffer[bufferOff++] = src[15];
                            buffer[bufferOff++] = src[16];
                            buffer[bufferOff++] = src[17];
                            buffer[bufferOff++] = src[18];
                            buffer[bufferOff++] = src[19];

                            buffer[bufferOff++] = src[0];
                            buffer[bufferOff++] = src[1];
                            buffer[bufferOff++] = src[2];
                            buffer[bufferOff++] = src[3];
                            buffer[bufferOff++] = src[4];
                        }
                    }
                    hvBuffer.Unlock();

                    TreeBillboardRenderOp op = new TreeBillboardRenderOp(textureName, alpha, renderOp);

                    renderOps.Add(op);
                }
            }

            billboards = null;
        }
 public override void GetRenderOperation(RenderOperation op)
 {
     op.vertexData    = vertexData;
     op.useIndices    = false;
     op.operationType = OperationType.TriangleStrip;
 }
 public void GetRenderOperation(RenderOperation op)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="op"></param>
 public abstract void GetRenderOperation(RenderOperation op);
 public TreeBillboardRenderOp(string textureName, int alpha, RenderOperation renderOp)
 {
     this.textureName = textureName;
     this.alpha = alpha;
     this.renderOp = renderOp;
 }
        public void BoundaryChange()
        {
            Debug.Assert(inBoundary);
            DisposeBuffers();
            renderOp = null;

            BuildBuffers();
        }
示例#23
0
		protected override void dispose( bool disposeManagedResources )
		{
			if ( !IsDisposed )
			{
				if ( disposeManagedResources )
				{
					if ( SceneManagerDestroyed != null )
					{
						SceneManagerDestroyed( this );
					}

					ClearScene();
					RemoveAllCameras();

					if ( op != null )
					{
						if ( !op.IsDisposed )
						{
							op.Dispose();
						}

						op = null;
					}

					if ( this.autoParamDataSource != null )
					{
						if ( !this.autoParamDataSource.IsDisposed )
						{
							this.autoParamDataSource.Dispose();
						}

						this.autoParamDataSource = null;
					}

					if ( this.rootSceneNode != null )
					{
						if ( !this.rootSceneNode.IsDisposed )
						{
							this.rootSceneNode.Dispose();
						}

						this.rootSceneNode = null;
					}
				}
			}

			base.dispose( disposeManagedResources );
		}
        private void BuildBuffers()
        {
            //
            // Build the vertex buffer
            //

            List<Vector2> points = boundary.Points;
            List<int[]> indices = boundary.Triangles;

            VertexData vertexData = new VertexData();

            vertexData.vertexCount = boundary.Points.Count;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;
            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, 0);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            float minx = boundary.Bounds.Minimum.x;
            float minz = boundary.Bounds.Minimum.z;

            unsafe
            {
                float* buffer = (float*)ipBuf.ToPointer();

                for (int v = 0; v < vertexData.vertexCount; v++)
                {

                    // Position
                    buffer[bufferOff++] = points[v].x;
                    buffer[bufferOff++] = height;
                    buffer[bufferOff++] = points[v].y;

                    // normals
                    buffer[bufferOff++] = 0;
                    buffer[bufferOff++] = 1;
                    buffer[bufferOff++] = 0;

                    // Texture
                    float tmpu = ( points[v].x - minx ) / (128 * TerrainManager.oneMeter);
                    float tmpv = ( points[v].y - minz )/ (128 * TerrainManager.oneMeter);

                    buffer[bufferOff++] = tmpu;
                    buffer[bufferOff++] = tmpv;
                }
            }
            hvBuffer.Unlock();

            //
            // build the index buffer
            //
            IndexData indexData = new IndexData();

            int numIndices = indices.Count * 3;

            indexData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(
                IndexType.Size16, numIndices, BufferUsage.StaticWriteOnly);

            IntPtr indexBufferPtr = indexData.indexBuffer.Lock(0, indexData.indexBuffer.Size, BufferLocking.Discard);

            unsafe
            {
                ushort* indexBuffer = (ushort*)indexBufferPtr.ToPointer();
                for (int i = 0; i < indices.Count; i++)
                {
                    indexBuffer[i * 3] = (ushort)indices[i][0];
                    indexBuffer[i * 3 + 1] = (ushort)indices[i][1];
                    indexBuffer[i * 3 + 2] = (ushort)indices[i][2];
                }
            }

            indexData.indexBuffer.Unlock();

            indexData.indexCount = numIndices;
            indexData.indexStart = 0;

            renderOp = new RenderOperation();

            renderOp.vertexData = vertexData;
            renderOp.indexData = indexData;
            renderOp.operationType = OperationType.TriangleList;
            renderOp.useIndices = true;
        }
 public override void GetRenderOperation(RenderOperation op)
 {
     op.vertexData = vertexData;
     op.useIndices = false;
     op.operationType = OperationType.TriangleStrip;
 }
示例#26
0
文件: Node.cs 项目: WolfgangSt/axiom
			protected override void dispose( bool disposeManagedResources )
			{
				if ( !IsDisposed )
				{
					if ( disposeManagedResources )
					{

						// Dispose managed resources.
						if ( renderOperation != null )
						{
							renderOperation.vertexData = null;
							renderOperation.indexData = null;
							renderOperation = null;
						}
					}
				}
				base.dispose( disposeManagedResources );
			}
示例#27
0
		public override void Render( RenderOperation op )
		{
			GLES2Config.GlCheckError( this );

			base.Render( op );

			var bufferData = 0;

			var decl = op.vertexData.vertexDeclaration.Elements;
			var gles2decl = op.vertexData.vertexDeclaration as GLES2VertexDeclaration;

			// Use a little shorthand
#if !AXIOM_NO_GLES2_VAO_SUPPORT
			bool useVAO = ( null != gles2decl && gles2decl.IsInitialized() );
#else
			bool useVAO = false;
#endif
	
			if ( useVAO )
				SetVertexDeclaration( op.vertexData.vertexDeclaration, op.vertexData.vertexBufferBinding );

			foreach ( var elem in decl )
			{
				var elemIndex = elem.Index;
				var elemSource = elem.Source;
				var elemType = elem.Type;

				if ( !op.vertexData.vertexBufferBinding.IsBufferBound( elemSource ) )
				{
					continue; //skip unbound elements
				}
				GLES2Config.GlCheckError( this );

				HardwareVertexBuffer vertexBuffer = op.vertexData.vertexBufferBinding.GetBuffer( elemSource );

				this.BindGLBuffer( GLenum.ArrayBuffer, ( vertexBuffer as GLES2HardwareVertexBuffer ).GLBufferID );

				if ( !useVAO || ( useVAO && null != gles2decl && !gles2decl.IsInitialized ) )
				{
					bufferData = elem.Offset;

					VertexElementSemantic sem = elem.Semantic;
					var typeCount = VertexElement.GetTypeCount( elemType );
					bool normalized = false;
					int attrib = 0;

					if ( op.vertexData.vertexStart != 0 )
					{
						bufferData = bufferData + op.vertexData.vertexStart & vertexBuffer.VertexSize;
					}

					if ( Capabilities.HasCapability( Graphics.Capabilities.SeperateShaderObjects ) )
					{
						GLSLESProgramPipeline programPipeline = GLSLESProgramPipelineManager.Instance.ActiveProgramPipeline;

						if ( !programPipeline.IsAttributeValid( sem, elemIndex ) )
						{
							continue;
						}

						attrib = programPipeline.GetAttributeIndex( sem, elemIndex );
					}
					else
					{
						GLSLESLinkProgram linkProgram = GLSLESLinkProgramManager.Instance.ActiveLinkProgram;
						if ( null == linkProgram || !linkProgram.IsAttributeValid( sem, elemIndex ) )
						{
							continue;
						}

						attrib = linkProgram.GetAttributeIndex( sem, elemIndex );
					}

					switch ( elem.Type )
					{
						case VertexElementType.Color:
						case VertexElementType.Color_ARGB:
						case VertexElementType.Color_ABGR:
							//Because GL takes these as a sequence of single unsigned bytes, count needs to be 4
							//VertexElement.GetTypeCount treams them as 1 (RGBA)
							//Also need to normalize the fixed-point data
							typeCount = 4;
							normalized = true;
							break;
						default:
							break;
					}

					GL.VertexAttribPointer( attrib, typeCount, GLES2HardwareBufferManager.GetGLType( elemType ), normalized, vertexBuffer.VertexSize, ref bufferData );
					GLES2Config.GlCheckError( this );

					GL.EnableVertexAttribArray( attrib );
					GLES2Config.GlCheckError( this );

					this.renderAttribsBound.Add( attrib );
				}
			}
			//Find the correct type to render
			GLenum primType = GLenum.TriangleFan;

			switch ( op.operationType )
			{
				case OperationType.PointList:
					primType = GLenum.Points;
					break;
				case OperationType.LineList:
					primType = GLenum.Lines;
					break;
				case OperationType.LineStrip:
					primType = GLenum.LineStrip;
					break;
				case OperationType.TriangleList:
					primType = GLenum.Triangles;
					break;
				case OperationType.TriangleStrip:
					primType = GLenum.TriangleStrip;
					break;
				case OperationType.TriangleFan:
					primType = GLenum.TriangleFan;
					break;
			}

			if ( op.useIndices )
			{
				// If we are using VAO's then only bind the buffer the first time through. Otherwise, always bind.
				if (!useVAO || ( useVAO && null != gles2decl && !gles2decl.IsInitialized ) )
					this.BindGLBuffer( GLenum.ElementArrayBuffer, ((GLES2HardwareIndexBuffer )op.indexData.indexBuffer).BufferID );

				bufferData = op.indexData.indexStart * op.indexData.indexBuffer.IndexSize;

				GLenum indexType = ( op.indexData.indexBuffer.Type == IndexType.Size16 ) ? GLenum.UnsignedShort : GLenum.UnsignedInt;

				do
				{
					//Update derived depth bias
					if ( derivedDepthBias && currentPassIterationCount > 0 )
					{
						this.SetDepthBias( derivedDepthBiasBase + derivedDepthBiasMultiplier * currentPassIterationNum, derivedDepthBiasSlopeScale );
					}
					GLES2Config.GlCheckError( this );
				
					GL.DrawElements( ( this.polygonMode == GLenum.PolygonOffsetFill ) ? primType : this.polygonMode, op.indexData.indexCount, indexType, ref bufferData );
					GLES2Config.GlCheckError( this, false );
				} while ( UpdatePassIterationRenderState() );
			}
			else
			{
				do
				{
					//Update derived depth bias
					if ( derivedDepthBias && currentPassIterationNum > 0 )
					{
						this.SetDepthBias( derivedDepthBiasBase + derivedDepthBiasMultiplier * currentPassIterationNum, derivedDepthBiasSlopeScale );
					}
					GLES2Config.GlCheckError( this );

					//GL.DrawArrays( ( this.polygonMode == GLenum.PolygonOffsetFill ) ? primType : this.polygonMode, 0, op.vertexData.vertexCount );
					GL.DrawArrays( All.Triangles, 0, op.vertexData.vertexCount );
					GLES2Config.GlCheckError( this, false );
				} while ( UpdatePassIterationRenderState() );
			}

			//Unbind all attributes
			foreach ( var ai in this.renderAttribsBound )
			{
				GL.DisableVertexAttribArray( ai );
				GLES2Config.GlCheckError( this );
			}

			this.renderAttribsBound.Clear();
		}
 /// <summary>
 ///		Gets the render operation for this shadow renderable.
 /// </summary>
 /// <param name="op"></param>
 public void GetRenderOperation(RenderOperation op)
 {
     // TODO: Ensure all other places throughout the engine set these properly
     op.indexData = renderOp.indexData;
     op.useIndices = true;
     op.operationType = OperationType.TriangleList;
     op.vertexData = renderOp.vertexData;
 }
示例#29
0
        public override void Render( RenderOperation op )
        {
            // Exit immediately if there is nothing to render
            // This caused a problem on FireGL 8800
            if ( op.vertexData.vertexCount == 0 )
            {
                return;
            }

            base.Render( op );

            // To think about: possibly remove setVertexDeclaration and 
            // setVertexBufferBinding from RenderSystem since the sequence is
            // a bit too D3D9-specific?
            VertexDeclaration = op.vertexData.vertexDeclaration;
            // TODO: the false parameter has to be carried inside op as var
            SetVertexBufferBinding(op.vertexData.vertexBufferBinding, op.numberOfInstances, false, op.useIndices);

            // Determine rendering operation
            var primType = PrimitiveType.TriangleList;
            var lprimCount = op.vertexData.vertexCount;
            var cnt = op.useIndices && primType != PrimitiveType.PointList ? op.indexData.indexCount : op.vertexData.vertexCount;

            switch ( op.operationType )
            {
                case OperationType.TriangleList:
                    primType = PrimitiveType.TriangleList;
                    lprimCount = cnt / 3;
                    break;
                case OperationType.TriangleStrip:
                    primType = PrimitiveType.TriangleStrip;
                    lprimCount = cnt - 2;
                    break;
                case OperationType.TriangleFan:
                    primType = PrimitiveType.TriangleFan;
                    lprimCount = cnt - 2;
                    break;
                case OperationType.PointList:
                    primType = PrimitiveType.PointList;
                    lprimCount = cnt;
                    break;
                case OperationType.LineList:
                    primType = PrimitiveType.LineList;
                    lprimCount = cnt / 2;
                    break;
                case OperationType.LineStrip:
                    primType = PrimitiveType.LineStrip;
                    lprimCount = cnt - 1;
                    break;
            } // switch(primType)

            if (lprimCount == 0)
                return;


            if (op.useIndices)
            {
                var d3DIdxBuf = (D3DHardwareIndexBuffer)op.indexData.indexBuffer;
                ActiveD3D9Device.Indices = d3DIdxBuf.D3DIndexBuffer;
                do
                {
                    // Update derived depth bias
                    if (derivedDepthBias && currentPassIterationNum > 0)
                    {
                        SetDepthBias(derivedDepthBiasBase +
                            derivedDepthBiasMultiplier * currentPassIterationNum,
                            derivedDepthBiasSlopeScale);
                    }

                    // draw the indexed primitives
                    ActiveD3D9Device.DrawIndexedPrimitives(primType, 
                        op.vertexData.vertexStart, 
                        0, 
                        op.vertexData.vertexCount, 
                        op.indexData.indexStart, 
                        lprimCount);
                } while (UpdatePassIterationRenderState());
            }
            else
            {
                // nfz: gpu_iterate
                do
                {
                    // Update derived depth bias
                    if (derivedDepthBias && currentPassIterationNum > 0)
                    {
                        SetDepthBias(derivedDepthBiasBase +
                            derivedDepthBiasMultiplier * currentPassIterationNum,
                            derivedDepthBiasSlopeScale);
                    }
                    // Unindexed, a little simpler!
                    ActiveD3D9Device.DrawPrimitives(primType, op.vertexData.vertexStart, lprimCount);
                } while (UpdatePassIterationRenderState());
            }
        }
示例#30
0
		/// <summary>
		/// Class level dispose method
		/// </summary>
		/// <remarks>
		/// When implementing this method in an inherited class the following template should be used;
		/// protected override void dispose( bool disposeManagedResources )
		/// {
		/// 	if ( !isDisposed )
		/// 	{
		/// 		if ( disposeManagedResources )
		/// 		{
		/// 			// Dispose managed resources.
		/// 		}
		///
		/// 		// There are no unmanaged resources to release, but
		/// 		// if we add them, they need to be released here.
		/// 	}
		///
		/// 	// If it is available, make the call to the
		/// 	// base class's Dispose(Boolean) method
		/// 	base.dispose( disposeManagedResources );
		/// }
		/// </remarks>
		/// <param name="disposeManagedResources">True if Unmanaged resources should be released.</param>
		protected override void dispose( bool disposeManagedResources )
		{
			if ( !IsDisposed )
			{
				if ( disposeManagedResources )
				{
					// Dispose managed resources.
					if ( renderOperation != null )
					{
                        if (!renderOperation.IsDisposed)
                            renderOperation.Dispose();

						renderOperation = null;
					}
				}

				// There are no unmanaged resources to release, but
				// if we add them, they need to be released here.
			}

            base.dispose(disposeManagedResources);
		}
        /// <summary>
        ///		Internal constructor, only allows creation of StitchRenderables within the scene manager.
        /// </summary>
        internal StitchRenderable(TerrainPatch terrainPatch, VertexData vertexData, IndexData indexData, 
			int numSamples, int southMetersPerSample, int eastMetersPerSample)
        {
            renderDetail = SceneDetailLevel.Solid;
            parent = terrainPatch;

            renderOp = new RenderOperation();
            renderOp.operationType = OperationType.TriangleList;
            renderOp.useIndices = true;
            renderOp.vertexData = vertexData;
            renderOp.indexData = indexData;

            isVisible = true;
            this.numSamples = numSamples;
            this.southMetersPerSample = southMetersPerSample;
            this.eastMetersPerSample = eastMetersPerSample;
        }
示例#32
0
		/// <summary>
		///    Fills a RenderOperation structure required to render this mesh.
		/// </summary>
		/// <param name="op">Reference to a RenderOperation structure to populate.</param>
		/// <param name="lodIndex">The index of the LOD to use.</param>
		public void GetRenderOperation( RenderOperation op, int lodIndex )
		{
			// meshes always use indices
			op.useIndices = true;

			// use lod face list if requested, else pass the normal face list
			if ( lodIndex > 0 && ( lodIndex - 1 ) < this.lodFaceList.Count )
			{
				// Use the set of indices defined for this LOD level
				op.indexData = this.lodFaceList[ lodIndex - 1 ];
			}
			else
			{
				op.indexData = this.indexData;
			}

			// set the operation type
			op.operationType = this.operationType;

			// set the vertex data correctly
			op.vertexData = this.useSharedVertices ? this.parent.SharedVertexData : this.vertexData;
		}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="op"></param>
        public void GetRenderOperation(RenderOperation op)
        {
            Debug.Assert(renderOp.vertexData != null, "attempting to render stitch with no vertexData");
            Debug.Assert(renderOp.indexData != null, "attempting to render stitch with no indexData");

            op.useIndices = this.renderOp.useIndices;
            op.operationType = this.renderOp.operationType;
            op.vertexData = this.renderOp.vertexData;
            op.indexData = this.renderOp.indexData;
        }
示例#34
0
		/// <summary>
		///		Manual rendering method, for advanced users only.
		/// </summary>
		/// <remarks>
		///		This method allows you to send rendering commands through the pipeline on
		///		demand, bypassing any normal world processing. You should only use this if you
		///		really know what you're doing; the engine does lots of things for you that you really should
		///		let it do. However, there are times where it may be useful to have this manual interface,
		///		for example overlaying something on top of the scene.
		///		<p/>
		///		Because this is an instant rendering method, timing is important. The best
		///		time to call it is from a RenderTarget event handler.
		///		<p/>
		///		Don't call this method a lot, it's designed for rare (1 or 2 times per frame) use.
		///		Calling it regularly per frame will cause frame rate drops!
		/// </remarks>
		/// <param name="op">A RenderOperation object describing the rendering op.</param>
		/// <param name="pass">The Pass to use for this render.</param>
		/// <param name="vp">Reference to the viewport to render to.</param>
		/// <param name="worldMatrix">The transform to apply from object to world space.</param>
		/// <param name="viewMatrix">The transform to apply from object to view space.</param>
		/// <param name="projMatrix">The transform to apply from view to screen space.</param>
		/// <param name="doBeginEndFrame">
		///		If true, BeginFrame() and EndFrame() are called, otherwise not.
		///		You should leave this as false if you are calling this within the main render loop.
		/// </param>
		public virtual void ManualRender( RenderOperation op,
										  Pass pass,
										  Viewport vp,
										  Matrix4 worldMatrix,
										  Matrix4 viewMatrix,
										  Matrix4 projMatrix,
										  bool doBeginEndFrame )
		{
			// configure all necessary parameters
			this.targetRenderSystem.Viewport = vp;
			this.targetRenderSystem.WorldMatrix = worldMatrix;
			this.targetRenderSystem.ViewMatrix = viewMatrix;
			this.targetRenderSystem.ProjectionMatrix = projMatrix;

			if ( doBeginEndFrame )
			{
				this.targetRenderSystem.BeginFrame();
			}

			// set the pass and render the object
			this.SetPass( pass );
			this.targetRenderSystem.Render( op );

			if ( doBeginEndFrame )
			{
				this.targetRenderSystem.EndFrame();
			}
		}
        /// <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!");
        }
示例#36
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="disposeManagedResources"></param>
		protected override void dispose( bool disposeManagedResources )
		{
			if ( !this.IsDisposed )
			{
				if ( disposeManagedResources )
				{
					this.ClearScene();
					this.RemoveAllCameras();

					if ( op != null )
					{
						if ( !op.IsDisposed )
							op.Dispose();

						op = null;
					}

					if ( this.autoParamDataSource != null )
					{
						if ( !this.autoParamDataSource.IsDisposed )
							this.autoParamDataSource.Dispose();

						this.autoParamDataSource = null;
					}

					if ( this.rootSceneNode != null )
					{
						if ( !this.rootSceneNode.IsDisposed )
							this.rootSceneNode.Dispose();

						this.rootSceneNode = null;
					}
				}
			}

			base.dispose( disposeManagedResources );
		}
        private void Init(int metersPerSample)
        {
            // set up the material
            normalMaterial = WorldManager.Instance.DefaultTerrainMaterial;

            material = normalMaterial;

            // create the render operation
            renderOp = new RenderOperation();
            renderOp.operationType = OperationType.TriangleList;
            renderOp.useIndices = true;

            location = tile.Location;

            // ask the world manager what LOD we should use
            this.metersPerSample = metersPerSample;

            targetMetersPerSample = metersPerSample;

            // figure out the number of actual samples we need in the tile based on the size
            // and level of detail
            numSamples = tile.Size / metersPerSample;

            // allocate the storage for the height map
            heightMap = new float[numSamples * numSamples];

            return;
        }