/// <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 }