UpdateAutoParamsNoLights() 공개 메소드

Update any automatic parameters (except lights) on this pass.
public UpdateAutoParamsNoLights ( AutoParamDataSource source ) : void
source AutoParamDataSource
리턴 void
예제 #1
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();
		}
        /// <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, List<Light> manualLightList)
        {
            targetRenderSystem.BeginProfileEvent(ColorEx.Red, "RenderSingleObject: Material = " + renderable.Material.Name);

            ushort numMatrices = 0;

            // grab the current scene detail level
            SceneDetailLevel camDetailLevel = cameraInProgress.SceneDetail;

            // 			// update auto params if this is a programmable pass
            // 			if(pass.IsProgrammable) {
            // 				autoParamDataSource.Renderable = renderable;
            // 				pass.UpdateAutoParamsNoLights(autoParamDataSource);
            // 			}

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

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

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

            if (!suppressRenderStateChanges) {
                bool passSurfaceAndLightParams = true;
                if (pass.IsProgrammable) {
                    // Tell auto params object about the renderable change
                    autoParamDataSource.Renderable = renderable;
                    // Tell auto params object about the world matrices, eliminated query from renderable again
                    autoParamDataSource.SetWorldMatrices(xform, numMatrices);
                    pass.UpdateAutoParamsNoLights(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.NumTextureUnitStages; i++) {
                    TextureUnitState texUnit = pass.GetTextureUnitState(i);

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

                // Normalize normals
                bool thisNormalize = renderable.NormalizeNormals;

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

                // Set up the solid / wireframe override
                SceneDetailLevel requestedDetail = renderable.RenderDetail;
                if (requestedDetail != lastDetailLevel || requestedDetail != camDetailLevel) {
                    if (requestedDetail > camDetailLevel) {
                        // only downgrade detail; if cam says wireframe we don't go up to solid
                        requestedDetail = camDetailLevel;
                    }
                    targetRenderSystem.RasterizationMode = requestedDetail;
                    lastDetailLevel = requestedDetail;

                }

                // TODO: Add ClipPlanes to RenderSystem.cs
                //targetRenderSystem.ClipPlanes = renderable.ClipPlanes;

                // get the renderables render operation
                renderable.GetRenderOperation(op);
                // 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
                    doLightMeter.Enter();
                    if (MeterManager.Collecting) {
                        string s = string.Format("Rendering material '{0}'", renderable.Material.Name);
                        if (renderable is SubEntity) {
                            SubEntity subEntity = (SubEntity)renderable;
                            s += string.Format(", SubMesh '{0}', Entity '{1}'", subEntity.SubMesh.Name, subEntity.Parent.Name);
                        }
                        MeterManager.AddInfoEvent(s);
                    }

                    List<Light> rendLightList = renderable.Lights;
                    bool iteratePerLight = pass.RunOncePerLight;
                    int startLight = pass.StartLight;
                    int lightsLeft = iteratePerLight ? rendLightList.Count - startLight : 1;
                    List<Light> lightListToUse = null;
                    int lightIndex = startLight;

                    while (lightsLeft > 0) {
                        // determine light list to use
                        if(iteratePerLight) {
                            localLightList.Clear();
                            int lightsPerIteration = pass.LightsPerIteration;
                            int numShadowTextureLights = 0;
                            int lightsConsidered = 0;
                            for (int i=0; i<lightsPerIteration && lightIndex < rendLightList.Count; i++,lightIndex++,lightsLeft--) {
                                // check whether we need to filter this one out
                                lightsConsidered++;
                                if(pass.RunOnlyForOneLightType && pass.OnlyLightType != rendLightList[lightIndex].Type)
                                    // skip this one
                                    continue;
                                localLightList.Add(rendLightList[lightIndex]);
                                // potentially need to update content_type shadow texunit
                                // corresponding to this light
                                if (IsShadowTechniqueTextureBased && lightIndex < shadowTextures.Count) {
                                    // link the numShadowTextureLights'th shadow texture unit
                                    int tuindex = pass.GetTextureUnitWithContentTypeIndex(
                                        TextureContentType.Shadow, numShadowTextureLights);
                                    if (tuindex < pass.NumTextureUnitStages) {
                                        TextureUnitState tu = pass.GetTextureUnitState(tuindex);
                                        tu.SetTexturePtr(shadowTextures[lightIndex]);
                                        Camera cam = shadowTextures[lightIndex].GetBuffer().GetRenderTarget().GetViewport(0).Camera;
                                        if (!pass.HasVertexProgram)
                                            tu.SetProjectiveTexturing(true, cam);
                                        autoParamDataSource.SetTextureProjector(cam, numShadowTextureLights);
                                        ++numShadowTextureLights;
                                        // Have to set TU on rendersystem right now, although
                                        // autoparams will be set later
                                        targetRenderSystem.SetTextureUnit(tuindex, tu, !pass.HasFragmentProgram);
                                    }
                                }
                            }
                            // Did we run out of lights before slots? e.g. 5 lights, 2 per iteration
                            if (lightsPerIteration != lightsConsidered)
                                lightsLeft = 0;
                            lightListToUse = localLightList;
                        }
                        else {
                            if (startLight != 0) {
                                if (startLight >= rendLightList.Count) {
                                    lightsLeft = 0;
                                    break;
                                }
                                else {
                                    localLightList.Clear();
                                    for (int i=startLight; i<rendLightList.Count; i++)
                                        localLightList.Add(rendLightList[i]);
                                    lightListToUse = localLightList;
                                }
                            }
                            else
                                // use complete light list
                                lightListToUse = rendLightList;
                            lightsLeft = 0;
                        }

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

                            // note: parameters must be bound after auto params are updated
                            setGpuParmsMeter.Enter();
                            if(pass.HasVertexProgram) {
                                if (MeterManager.Collecting)
                                    MeterManager.AddInfoEvent("Vertex Program " + pass.VertexProgramName);
                                targetRenderSystem.BindGpuProgramParameters(GpuProgramType.Vertex, pass.VertexProgramParameters);
                            }
                            if(pass.HasFragmentProgram) {
                                if (MeterManager.Collecting)
                                    MeterManager.AddInfoEvent("Fragment Program " + pass.FragmentProgramName);
                                targetRenderSystem.BindGpuProgramParameters(GpuProgramType.Fragment, pass.FragmentProgramParameters);
                            }
                            setGpuParmsMeter.Exit();
                        }

                        // Do we need to update light states?
                        // Only do this if fixed-function vertex lighting applies
                        if(pass.LightingEnabled && passSurfaceAndLightParams) {
                            //useLightsMeter.Enter();
                            targetRenderSystem.UseLights(lightListToUse, pass.MaxLights);
                            //useLightsMeter.Exit();
                        }
                        // issue the render op
                        renderOpMeter.Enter();
                        targetRenderSystem.Render(op);
                        renderOpMeter.Exit();
                    } // iterate per light
                    doLightMeter.Exit();
                }
                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
                            autoParamDataSource.SetCurrentLightList(manualLightList);
                            pass.UpdateAutoParamsLightsOnly(autoParamDataSource);
                        }

                        // note: parameters must be bound after auto params are updated
                        if(pass.HasVertexProgram) {
                            targetRenderSystem.BindGpuProgramParameters(GpuProgramType.Vertex, pass.VertexProgramParameters);
                        }

                        if(pass.HasFragmentProgram) {
                             targetRenderSystem.BindGpuProgramParameters(GpuProgramType.Fragment, pass.FragmentProgramParameters);
                        }
                    }

                    // Use manual lights if present, and not using vertex programs
                    if(manualLightList != null && pass.LightingEnabled && passSurfaceAndLightParams) {
                        targetRenderSystem.UseLights(manualLightList, pass.MaxLights);
                    }

                    // issue the render op
                    renderOpMeter.Enter();
                    targetRenderSystem.Render(op);
                    renderOpMeter.Exit();
                }
            }
            else { // suppressRenderStateChanges
                // Just render
                renderOpMeter.Enter();
                targetRenderSystem.Render(op);
                renderOpMeter.Exit();
            }

            // Reset view / projection changes if any
            ResetViewProjMode();

            targetRenderSystem.EndProfileEvent();
        }