Exemplo n.º 1
0
        /// <summary>
        /// Sets the new submesh.
        /// </summary>
        /// <param name="context">The render context.</param>
        /// <param name="submesh">The submesh.</param>
        /// <param name="effectPassBinding">The effect pass binding.</param>
        /// <param name="effectPassParameterBindings">
        /// The effect parameter bindings containing per-pass parameter bindings.
        /// (Can also contain other parameter binding, e.g. per-instance, which are ignored.
        /// </param>
        /// <remarks>
        /// The current batch is automatically flushed when the submesh is changed.
        /// </remarks>
        public void SetSubmesh(RenderContext context, Submesh submesh, EffectPassBinding effectPassBinding,
                               EffectParameterBindingCollection effectPassParameterBindings)
        {
            Flush();

            _renderContext               = context;
            _submesh                     = submesh;
            _effectPassBinding           = effectPassBinding;
            _effectPassParameterBindings = effectPassParameterBindings;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Releases all resources used by an instance of the <see cref="RenderBatch{TVertex,TIndex}"/> class.
        /// </summary>
        public void Dispose()
        {
            if (IsDisposed)
            {
                return;
            }

            _renderContext               = null;
            _submesh                     = null;
            _effectPassBinding           = new EffectPassBinding();
            _effectPassParameterBindings = null;

            _instanceVertexBuffer.Dispose();
            IsDisposed = true;
        }
Exemplo n.º 3
0
    private void Draw(ref EffectPassBinding passBinding, RenderContext context, int index, int count, RenderOrder order)
    {
      var jobs = _jobs.Array;
      var cameraNode = context.CameraNode;
      var cameraPose = cameraNode.PoseWorld;

      var graphicsDevice = context.GraphicsService.GraphicsDevice;

      // Flag: true if the box vertex/index buffers are not set in the graphics device.
      bool setBoxBuffers = true;

      foreach (var pass in passBinding)
      {
        for (int i = index; i < index + count; i++)
        {
          var materialInstanceBinding = jobs[i].MaterialInstanceBinding;
          var decalNode = jobs[i].DecalNode;
          var decalPose = decalNode.PoseWorld;

          // Update and apply local, per-instance and per-pass bindings.
          foreach (var binding in materialInstanceBinding.ParameterBindings)
          {
            if (binding.Description.Hint == EffectParameterHint.PerPass)
              binding.Update(context);

            binding.Apply(context);
          }

          pass.Apply();

          bool drawWithQuad = false;
          if (!ClipAtNearPlane)
          {
            // ----- Check if near plane intersects the decal box.

            // First make a simple AABB check in world space.
            if (GeometryHelper.HaveContact(_cameraNearPlaneAabbWorld, decalNode.Aabb))
            {
              // Make exact check of decal box against camera near plane AABB in camera space.
              var decalBoxExtent = new Vector3(1, 1, 1);
              decalBoxExtent *= decalNode.ScaleLocal;
              var decalBoxCenter = new Vector3(0, 0, -decalNode.ScaleLocal.Z / 2);

              // Get pose of decal box in view space.
              var decalBoxPose = new Pose(
                cameraPose.ToLocalPosition(decalPose.Position + decalPose.Orientation * decalBoxCenter),
                cameraPose.Orientation.Transposed * decalPose.Orientation);

              // Aabb of camera near plane in view space.
              var projection = cameraNode.Camera.Projection;
              var cameraNearPlaneAabb = new Aabb(
                new Vector3(projection.Left, projection.Bottom, -projection.Near),
                new Vector3(projection.Right, projection.Top, -projection.Near));

              drawWithQuad = GeometryHelper.HaveContact(cameraNearPlaneAabb, decalBoxExtent, decalBoxPose, true);
            }
          }

          if (!drawWithQuad)
          {
            // Draw a box primitive.

            if (setBoxBuffers)
            {
              graphicsDevice.SetVertexBuffer(_vertexBuffer);
              graphicsDevice.Indices = _indexBuffer;
              setBoxBuffers = false;
            }


            graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, NumberOfPrimitives);
#else
            graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, NumberOfVertices, 0, NumberOfPrimitives);

          }
          else
          {
            // Draw a quad at the near plane because the camera is inside the box. 
            // The quad vertices must be given decal space!

            var projection = cameraNode.Camera.Projection;
            Vector3 scale = decalNode.ScaleWorld;
            Pose cameraToDecalPose = decalPose.Inverse * cameraPose;

            Vector4 scissor = GraphicsHelper.GetBounds(cameraNode, decalNode);
            // Use a bias to avoid that this quad is clipped by the near plane.
            const float bias = 1.0001f;
            float left = InterpolationHelper.Lerp(projection.Left, projection.Right, scissor.X) * bias;
            float top = InterpolationHelper.Lerp(projection.Top, projection.Bottom, scissor.Y) * bias;
            float right = InterpolationHelper.Lerp(projection.Left, projection.Right, scissor.Z) * bias;
            float bottom = InterpolationHelper.Lerp(projection.Top, projection.Bottom, scissor.W) * bias;
            float z = -projection.Near * bias;
            _quadVertices[0] = cameraToDecalPose.ToWorldPosition(new Vector3(left, top, z));
            _quadVertices[0].X /= scale.X;
            _quadVertices[0].Y /= scale.Y;
            _quadVertices[0].Z /= scale.Z;
            _quadVertices[1] = cameraToDecalPose.ToWorldPosition(new Vector3(right, top, z));
            _quadVertices[1].X /= scale.X;
            _quadVertices[1].Y /= scale.Y;
            _quadVertices[1].Z /= scale.Z;
            _quadVertices[2] = cameraToDecalPose.ToWorldPosition(new Vector3(left, bottom, z));
            _quadVertices[2].X /= scale.X;
            _quadVertices[2].Y /= scale.Y;
            _quadVertices[2].Z /= scale.Z;
            _quadVertices[3] = cameraToDecalPose.ToWorldPosition(new Vector3(right, bottom, z));
            _quadVertices[3].X /= scale.X;
            _quadVertices[3].Y /= scale.Y;
            _quadVertices[3].Z /= scale.Z;

            graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _quadVertices, 0, 2, VertexPosition.VertexDeclaration);

            // Remember that the device vertex/index buffers are not set anymore.
            setBoxBuffers = true;
          }
        }
      }
    }