Пример #1
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
		}