AxiomRenderer.cs :  » Game » RealmForge » CrayzEdsGui » Renderers » AxiomEngine » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » RealmForge 
RealmForge » CrayzEdsGui » Renderers » AxiomEngine » AxiomRenderer.cs
#region LGPL License

/*************************************************************************
    Crazy Eddie's GUI System (http://crayzedsgui.sourceforge.net)
    Copyright (C)2004 Paul D Turner (crayzed@users.sourceforge.net)
  
  C# Port developed by Chris McGuirk (leedgitar@latenitegames.com)
  Compatible with the Axiom 3D Engine (http://axiomengine.sf.net)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*************************************************************************/

#endregion LGPL License

#region Using directives

using System;
using System.Collections;
using System.Text;

using Axiom.Core;
using Axiom.Graphics;
using Axiom.MathLib;

using CrayzEdsGui.Base;

#endregion

namespace CrayzEdsGui.Renderers.AxiomEngine{

  /// <summary>
  ///    Custom GUI renderer for the Axiom 3D Engine (http://axiomengine.sf.net).
  /// </summary>
  ///  Last synced on: 30th Oct 2004 by Paul Turner
  ///  C++ Master Sync Info:
  ///    ogrerenderer.cpp    v1.21
  ///    ogrerenderer.h      v1.11
  public class AxiomRenderer : CrayzEdsGui.Base.Renderer 
  {
    #region Constants

    /// <summary>
    ///    Number of vertices per quad.
    /// </summary>
    const int VertexPerQuad      = 6;
    /// <summary>
    ///    Number of vertices for a triangle.
    /// </summary>
    const int VertexPerTriangle    = 3;
    /// <summary>
    ///    Capacity of the allocated vertex buffer.
    /// </summary>
    const int VertexBufferCapacity  = 4096;

    #endregion Constants

    #region Fields

    protected Rect displayArea;
    /// <summary>
    ///    ArrayList that holds the quads that get queued.
    /// </summary>
    protected  ArrayList  quadList = new ArrayList();

    /// <summary>
    /// Single allocated ColorEx object used in color conversions.
    /// Done this way to save on possible mass creation of heap objects.
    /// </summary>
    protected Axiom.Core.ColorEx converterColourEx = new Axiom.Core.ColorEx();

    /// <summary>
    ///    Stores the texture unit state.
    /// </summary>
    protected TextureUnitState unitState;
    /// <summary>
    ///    Reusable array of 6 vertices to use for preparing vertex data
    ///    for a quad, then writing to an Axiom HardwareVertexBuffer in 
    ///    a single WriteData call.
    /// </summary>
    protected QuadVertex[] quadVertices;

    // AXIOM specific data

    /// <summary>
    ///    Reference to the core engine object.
    /// </summary>
    protected Axiom.Core.Root engine;
    /// <summary>
    ///    Reference to the current RenderSystem being used by Axiom.
    /// </summary>
    protected Axiom.Graphics.RenderSystem renderSystem;
    /// <summary>
    ///    ID of the queue that we are hooked into.
    /// </summary>
    protected Axiom.Core.RenderQueueGroupID queueID;
    /// <summary>
    ///    Currently set texture.
    /// </summary>
    protected Axiom.Core.Texture currentTexture;
    /// <summary>
    ///    Ogre render operation we use to do our stuff.
    /// </summary>
    protected Axiom.Graphics.RenderOperation renderOp = new Axiom.Graphics.RenderOperation();
    /// <summary>
    ///    Vertex buffer to queue sprite rendering.
    /// </summary>
    protected Axiom.Graphics.HardwareVertexBuffer buffer;
    /// <summary>
    ///    True if we render after everything else in our queue.
    /// </summary>
    protected bool postQueue;
    /// <summary>
    ///    Index into buffer where next vertex should be put.
    /// </summary>
    protected int bufferPos;
    /// <summary>
    ///    True when data in quad list is sorted.
    /// </summary>
    protected bool isSorted;
    /// <summary>
    ///    List used to track textures.
    /// </summary>
    protected ArrayList textureList = new ArrayList();
    /// <summary>
    ///    Used to compare quads based on their z value for sorting.
    /// </summary>
    protected QuadInfoComparer quadComparer = new QuadInfoComparer();
    /// <summary>
    ///    Offset required for proper texel mapping.
    /// </summary>
    protected Point texelOffset;
    /// <summary>
    ///    Reference to the currently set SceneManager
    /// </summary>
    protected Axiom.Core.SceneManager  sceneManager = null;

    #endregion Fields

    #region Constructors

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    /// <param name="queueID">Value that specifies where the GUI should appear in the Axiom rendering output.</param>
    /// <param name="postQueue">
    ///    Set to true to have GUI rendered after render queue <paramref name="queueID"/>, 
    ///    or false to have the GUI rendered before render queue <paramref name="queueID"/>.
    /// </param>
    /// <param name="maxQuads">Obsolete.  Set to 0.</param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID, bool postQueue, int maxQuads)
    {
      ConstructorImpl(window, queueID, postQueue);

      // hook into axiom rendering system
      SetTargetSceneManager(SceneType.Generic);
    }

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window)
    {
      ConstructorImpl(window, RenderQueueGroupID.Overlay, false);

      // hook into axiom rendering system
      SetTargetSceneManager(SceneType.Generic);
    }

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    /// <param name="queueID">
    ///    Value that specifies where the GUI should appear in the Axiom rendering output.  The GUI
    ///    will be rendererd prior to the specified render queue group.
    /// </param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID)
    {
      ConstructorImpl(window, queueID, false);

      // hook into axiom rendering system
      SetTargetSceneManager(SceneType.Generic);
    }

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    /// <param name="queueID">Value that specifies where the GUI should appear in the Axiom rendering output.</param>
    /// <param name="postQueue">
    ///    Set to true to have GUI rendered after render queue <paramref name="queueID"/>, 
    ///    or false to have the GUI rendered before render queue <paramref name="queueID"/>.
    /// </param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID, bool postQueue)
    {
      ConstructorImpl(window, queueID, postQueue);

      // hook into axiom rendering system
      SetTargetSceneManager(SceneType.Generic);
    }

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    /// <param name="queueID">Value that specifies where the GUI should appear in the Axiom rendering output.</param>
    /// <param name="postQueue">
    ///    Set to true to have GUI rendered after render queue <paramref name="queueID"/>, 
    ///    or false to have the GUI rendered before render queue <paramref name="queueID"/>.
    /// </param>
    /// <param name="sceneType">SceneType value indicating the SceneManager that the GUI sould attach to.</param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID, bool postQueue, Axiom.Core.SceneType sceneType)
    {
      ConstructorImpl(window, queueID, postQueue);

      // hook into axiom rendering system
      SetTargetSceneManager(sceneType);
    }

    /// <summary>
    ///    Constructor for renderer class that uses Axiom (tm) for rendering.
    /// </summary>
    /// <param name="window">Pre-created Axiom render window.</param>
    /// <param name="queueID">Value that specifies where the GUI should appear in the Axiom rendering output.</param>
    /// <param name="postQueue">
    ///    Set to true to have GUI rendered after render queue <paramref name="queueID"/>, 
    ///    or false to have the GUI rendered before render queue <paramref name="queueID"/>.
    /// </param>
    /// <param name="sceneManager">SceneManager that the GUI sould attach to.</param>
    public AxiomRenderer(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID, bool postQueue, Axiom.Core.SceneManager sceneManager)
    {
      ConstructorImpl(window, queueID, postQueue);

      // hook into axiom rendering system
      SetTargetSceneManager(sceneManager);
    }

    #endregion Constructors

    #region Renderer Implementation

    #region Properties

    public override float Height {
      get {
        return displayArea.Height;
      }
    }

    public override int HorizontalScreenDPI {
      get {
        return 96;
      }
    }


    public override int MaxTextureSize {
      get {
        // TODO: Use proper value
        return 2048;
      }
    }


    public override Rect Rect {
      get {
        return displayArea;
      }
    }

    public override Size Size {
      get {
        return displayArea.Size;
      }
    }

    public override int VerticalScreenDPI {
      get {
        return 96;
      }
    }

    public override float Width {
      get {
        return displayArea.Width;
      }
    }

    #endregion Properties

    #region Methods

    public override void AddQuad(Rect destRect, float z, CrayzEdsGui.Base.Texture texture, Rect textureRect, ColorRect colors) {
      // if not queueing, render directly (as in, right now!)
      if(!isQueueingEnabled) {
        RenderQuadDirect(destRect, z, texture, textureRect, colors);
      }
      else {
        isSorted = false;

        QuadInfo quad = new QuadInfo();

        // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
        quad.position.left  = destRect.left;
        quad.position.right  = destRect.right;
        quad.position.top  = displayArea.Height - destRect.top;
        quad.position.bottom = displayArea.Height - destRect.bottom;
        quad.position.Offset(texelOffset);

        // convert quad co-ordinates for a -1 to 1 co-ordinate system.
        quad.position.left  /= displayArea.Width * 0.5f;
        quad.position.right  /= displayArea.Width * 0.5f;
        quad.position.top  /= displayArea.Height * 0.5f;
        quad.position.bottom /= displayArea.Height * 0.5f;
        quad.position.Offset(new Point(-1.0f, -1.0f));

        quad.z = -1 + z;
        quad.texture = ((AxiomTexture)texture).Texture;
        quad.texPosition = textureRect;

        // convert colors here to save re-doing when frame does not change.
        // Note that top / bottom are switched
        quad.topLeftColor   = ColorToAxiomColor(colors.bottomLeft);
        quad.topRightColor   = ColorToAxiomColor(colors.bottomRight);
        quad.bottomLeftColor   = ColorToAxiomColor(colors.topLeft);
        quad.bottomRightColor = ColorToAxiomColor(colors.topRight);

        quadList.Add(quad);
      }
    }

    /// <summary>
    ///    Clears the queue.
    /// </summary>
    public override void ClearRenderList() {
      // Leed said: Should be false?
      // CE Says: Nope!  With the list empty, it is considered as sorted.
      quadList.Clear();
      isSorted = true;
    }

    /// <summary>
    ///    Creates an empty texture.
    /// </summary>
    /// <returns></returns>
    public override CrayzEdsGui.Base.Texture CreateTexture() {
      AxiomTexture tex = new AxiomTexture(this);
      textureList.Add(tex);
      return tex;
    }

    public override CrayzEdsGui.Base.Texture CreateTexture(float size) {
      AxiomTexture tex = (AxiomTexture)CreateTexture();
      tex.SetAxiomTextureSize((int)size);
      return tex;
    }

    /// <summary>
    ///    Loads a texture from file.
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public override CrayzEdsGui.Base.Texture CreateTexture(string fileName) {
      AxiomTexture tex = (AxiomTexture)CreateTexture();
      tex.LoadFromFile(fileName);

      return tex;
    }

    public override void DestroyAllTextures() {

    }

    public override void DestroyTexture(CrayzEdsGui.Base.Texture texture) {

    }

    public override void DoRender() {
      SortQuads();
      InitRenderStates();

      // clear this in case we think it's untouched from last frame
      currentTexture = null;

      // always start with a clear buffer
      bufferPos = 0;

      // iterate over each quad in the list
      for(int i = 0; i < quadList.Count; ++i) {
        QuadInfo quad = (QuadInfo)quadList[i];

        // flush and set texture if needed
        if(currentTexture != quad.texture) {
          // render any remaining quads for the current texture
          RenderVBuffer();

          // set the new texture
          renderSystem.SetTexture(0, true, quad.texture.Name);
          currentTexture = quad.texture;
        }

        // setup Vertex 1...
        quadVertices[bufferPos].x    = quad.position.left;
        quadVertices[bufferPos].y    = quad.position.bottom;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse = quad.topLeftColor;
        quadVertices[bufferPos].tu    = quad.texPosition.left;
        quadVertices[bufferPos].tv    = quad.texPosition.bottom;
        ++bufferPos;

        // setup Vertex 2...
        quadVertices[bufferPos].x    = quad.position.right;
        quadVertices[bufferPos].y    = quad.position.bottom;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse  = quad.topRightColor;
        quadVertices[bufferPos].tu    = quad.texPosition.right;
        quadVertices[bufferPos].tv    = quad.texPosition.bottom;
        ++bufferPos;

        // setup Vertex 3...
        quadVertices[bufferPos].x    = quad.position.left;
        quadVertices[bufferPos].y    = quad.position.top;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse = quad.bottomLeftColor;
        quadVertices[bufferPos].tu    = quad.texPosition.left;
        quadVertices[bufferPos].tv    = quad.texPosition.top;
        ++bufferPos;

        // setup Vertex 4...
        quadVertices[bufferPos].x    = quad.position.right;
        quadVertices[bufferPos].y    = quad.position.bottom;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse = quad.topRightColor;
        quadVertices[bufferPos].tu    = quad.texPosition.right;
        quadVertices[bufferPos].tv    = quad.texPosition.bottom;
        ++bufferPos;

        // setup Vertex 5...
        quadVertices[bufferPos].x    = quad.position.right;
        quadVertices[bufferPos].y    = quad.position.top;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse = quad.bottomRightColor;
        quadVertices[bufferPos].tu    = quad.texPosition.right;
        quadVertices[bufferPos].tv    = quad.texPosition.top;
        ++bufferPos;

        // setup Vertex 6...
        quadVertices[bufferPos].x    = quad.position.left;
        quadVertices[bufferPos].y    = quad.position.top;
        quadVertices[bufferPos].z    = quad.z;
        quadVertices[bufferPos].diffuse = quad.bottomLeftColor;
        quadVertices[bufferPos].tu    = quad.texPosition.left;
        quadVertices[bufferPos].tv    = quad.texPosition.top;
        ++bufferPos;

        // if there is not enough room in the buffer for another sprite, render what we have
        if(bufferPos >= (VertexBufferCapacity - VertexPerQuad)) {
          RenderVBuffer();
        }
      }

      // send any remaining data to be rendered
      RenderVBuffer();
    }

    #endregion Methods

    #endregion Renderer Implementation

    #region Implementation Methods
    /// <summary>
    /// Implementation method that does most of the work of the constructor
    /// </summary>
    protected void ConstructorImpl(Axiom.Graphics.RenderWindow window, Axiom.Core.RenderQueueGroupID queueID, bool postQueue)
    {
      this.queueID = queueID;
      this.postQueue = postQueue;
      this.isQueueingEnabled = true;
      this.isSorted = true;

      engine = Axiom.Core.Root.Instance;
      renderSystem = engine.RenderSystem;

      renderOp.vertexData = new VertexData();
      renderOp.vertexData.vertexStart = 0;

      // setup vertex declaration for the vertex format we use
      VertexDeclaration decl = renderOp.vertexData.vertexDeclaration;
      int offset = 0;

      decl.AddElement(0, offset, VertexElementType.Float3, VertexElementSemantic.Position);
      offset += VertexElement.GetTypeSize(VertexElementType.Float3);
      decl.AddElement(0, offset, VertexElementType.Color, VertexElementSemantic.Diffuse);
      offset += VertexElement.GetTypeSize(VertexElementType.Color);
      decl.AddElement(0, offset, VertexElementType.Float2, VertexElementSemantic.TexCoords);

      // create the hardware vertex buffer
      buffer = HardwareBufferManager.Instance.CreateVertexBuffer(
        decl.GetVertexSize(0), VertexBufferCapacity, BufferUsage.DynamicWriteOnly, false);

      // bind the fresh vertex buffer
      renderOp.vertexData.vertexBufferBinding.SetBinding(0, buffer);

      quadVertices = new QuadVertex[VertexBufferCapacity];

      // complete render operation basic initialization
      renderOp.operationType = OperationType.TriangleList;
      renderOp.useIndices = false;

      // discover display settings and setup the displayArea rect
      displayArea.left = 0;
      displayArea.top = 0;
      displayArea.right = window.Width;
      displayArea.bottom = window.Height;

      // initialize required texel offset
      texelOffset = new Point(renderSystem.HorizontalTexelOffset, renderSystem.VerticalTexelOffset);

      // Set up the texture unit state
      unitState = new TextureUnitState( new Pass( null, 0 ) );
      unitState.ColorBlendMode.blendType = LayerBlendType.Color;
      unitState.ColorBlendMode.source1 = LayerBlendSource.Texture;
      unitState.ColorBlendMode.source2 = LayerBlendSource.Diffuse;
      unitState.ColorBlendMode.operation = LayerBlendOperationEx.Modulate;

      unitState.AlphaBlendMode.blendType = LayerBlendType.Alpha;
      unitState.AlphaBlendMode.source1 = LayerBlendSource.Texture;
      unitState.AlphaBlendMode.source2 = LayerBlendSource.Diffuse;
      unitState.AlphaBlendMode.operation = LayerBlendOperationEx.Modulate;
    }

    /// <summary>
    ///    Converts between Axiom and GUI color formats.
    /// </summary>
    /// <param name="color"></param>
    /// <returns></returns>
    protected int ColorToRgba(int color) {
      // TODO: Possible removal of this?
      // nothing right now
      return color;
    }

    /// <summary>
    /// Convert a GUI color value to something that the active Axiom
    /// render system is expecting.
    /// </summary>
    /// <param name="color"></param>
    /// <returns></returns>
    protected int ColorToAxiomColor(Color color) {
      converterColourEx.a = color.a;
      converterColourEx.r = color.r;
      converterColourEx.g = color.g;
      converterColourEx.b = color.b;

      return renderSystem.ConvertColor(converterColourEx);
    }

    /// <summary>
    ///    Helper method for configuring render states.
    /// </summary>
    protected void InitRenderStates() {
      // setup the matrices
      renderSystem.WorldMatrix = Matrix4.Identity;
      renderSystem.ViewMatrix = Matrix4.Identity;
      renderSystem.ProjectionMatrix = Matrix4.Identity;

      // render settings
      renderSystem.LightingEnabled = false;
      renderSystem.SetDepthBufferParams(false, false);
      renderSystem.CullingMode = CullingMode.None;
      renderSystem.SetFog(FogMode.None, ColorEx.White, 0, 0, 0);
      renderSystem.SetColorBufferWriteEnabled(true, true, true, true);
      renderSystem.UnbindGpuProgram(GpuProgramType.Fragment);
      renderSystem.UnbindGpuProgram(GpuProgramType.Vertex);

      // texture settings
      renderSystem.SetTextureCoordCalculation( 0, TexCoordCalcMethod.None );
      renderSystem.SetTextureCoordSet( 0, 0 );
      renderSystem.SetTextureUnitFiltering(0, FilterOptions.Linear, FilterOptions.Linear, FilterOptions.Point);
      renderSystem.SetTextureAddressingMode(0, TextureAddressing.Clamp);
      renderSystem.SetTextureMatrix(0, Matrix4.Identity);
      renderSystem.SetAlphaRejectSettings(0, CompareFunction.AlwaysPass, 0);
      renderSystem.SetTextureBlendMode( 0, unitState.ColorBlendMode );
      renderSystem.SetTextureBlendMode( 0, unitState.AlphaBlendMode );

      // HACK: Add DisableTextureUnitsFrom(stage) to Axiom
      for(int i = 1; i < 6; i++) {
        renderSystem.SetTexture(i, false, "");
      }

      // enable alpha blending
      renderSystem.SetSceneBlending(SceneBlendFactor.SourceAlpha, SceneBlendFactor.OneMinusSourceAlpha);
    }

    /// <summary>
    ///    Renders whatever is in the vertex buffer.
    /// </summary>
    protected void RenderVBuffer() {
      // we only need to do anything if there is actually quads in the buffer
      if(bufferPos != 0) {
        // write the data to the buffer
        buffer.WriteData(0, 24 * bufferPos, quadVertices, true);

        // tell render operation how many quads to draw
        renderOp.vertexData.vertexCount = bufferPos;
        renderSystem.Render(renderOp);

        // reset buffer
        bufferPos = 0;
      }
    }

    /// <summary>
    ///    Sorts quad list according to texture.
    /// </summary>
    protected void SortQuads() {
      if(!isSorted) {
        quadList.Sort(quadComparer);
      }
    }

    /// <summary>
    ///    Adds a quad directly to the display (not queued).
    /// </summary>
    /// <param name="destRect"></param>
    /// <param name="z"></param>
    /// <param name="texture"></param>
    /// <param name="texRect"></param>
    /// <param name="colors"></param>
    protected void RenderQuadDirect(Rect destRect, float z, CrayzEdsGui.Base.Texture texture, Rect texRect, ColorRect colors) {
      // bring in the -1 to 1 range
      z = -1 + z;

      Rect finalRect = new Rect();

      // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
      finalRect.left  = destRect.left;
      finalRect.right  = destRect.right;
      finalRect.top  = displayArea.Height - destRect.top;
      finalRect.bottom = displayArea.Height - destRect.bottom;
      finalRect.Offset(texelOffset);

      // convert quad co-ordinates for a -1 to 1 co-ordinate system.
      finalRect.left  /= displayArea.Width * 0.5f;
      finalRect.right  /= displayArea.Width * 0.5f;
      finalRect.top  /= displayArea.Height * 0.5f;
      finalRect.bottom /= displayArea.Height * 0.5f;
      finalRect.Offset(new Point(-1.0f, -1.0f));

      // convert colors for axiom, note that top / bottom are switched.
      int  topLeftColor   = ColorToAxiomColor(colors.bottomLeft);
      int topRightColor   = ColorToAxiomColor(colors.bottomRight);
      int bottomLeftColor   = ColorToAxiomColor(colors.topLeft);
      int bottomRightColor = ColorToAxiomColor(colors.topRight);

      InitRenderStates();
      renderSystem.SetTexture(0, true, ((AxiomTexture)texture).Texture.Name);

      // setup Vertex 1...
      quadVertices[0].x    = finalRect.left;
      quadVertices[0].y    = finalRect.bottom;
      quadVertices[0].z    = z;
      quadVertices[0].diffuse = topLeftColor;
      quadVertices[0].tu    = texRect.left;
      quadVertices[0].tv    = texRect.bottom;

      // setup Vertex 2...
      quadVertices[1].x    = finalRect.right;
      quadVertices[1].y    = finalRect.bottom;
      quadVertices[1].z    = z;
      quadVertices[1].diffuse  = topRightColor;
      quadVertices[1].tu    = texRect.right;
      quadVertices[1].tv    = texRect.bottom;

      // setup Vertex 3...
      quadVertices[2].x    = finalRect.left;
      quadVertices[2].y    = finalRect.top;
      quadVertices[2].z    = z;
      quadVertices[2].diffuse = bottomLeftColor;
      quadVertices[2].tu    = texRect.left;
      quadVertices[2].tv    = texRect.top;

      // setup Vertex 4...
      quadVertices[3].x    = finalRect.right;
      quadVertices[3].y    = finalRect.bottom;
      quadVertices[3].z    = z;
      quadVertices[3].diffuse = topRightColor;
      quadVertices[3].tu    = texRect.right;
      quadVertices[3].tv    = texRect.bottom;

      // setup Vertex 5...
      quadVertices[4].x    = finalRect.right;
      quadVertices[4].y    = finalRect.top;
      quadVertices[4].z    = z;
      quadVertices[4].diffuse = bottomRightColor;
      quadVertices[4].tu    = texRect.right;
      quadVertices[4].tv    = texRect.top;

      // setup Vertex 6...
      quadVertices[5].x    = finalRect.left;
      quadVertices[5].y    = finalRect.top;
      quadVertices[5].z    = z;
      quadVertices[5].diffuse = bottomLeftColor;
      quadVertices[5].tu    = texRect.left;
      quadVertices[5].tv    = texRect.top;

      // size of the struct * 6
      int length = 24 * 6;

      // blast the array into the buffer
      buffer.WriteData(0, length, quadVertices, true);
      bufferPos = VertexPerQuad;

      // finally, render it!
      RenderVBuffer();
    }

    #endregion Implementation Methods

    #region AxiomRenderer Specific Methods
    /// <summary>
    ///    Sets or changes the scene manager that the GUI system should be attached to.
    /// </summary>
    /// <param name="sceneType">SceneType value indicating the new SceneManager to be used.</param>
    public void SetTargetSceneManager(Axiom.Core.SceneType sceneType)
    {
      SetTargetSceneManager(engine.SceneManagers.GetSceneManager(sceneType));
    }

    /// <summary>
    ///    Sets or changes the scene manager that the GUI system should be attached to.
    /// </summary>
    /// <param name="sceneManager">The new SceneManager to be used.</param>
    public void SetTargetSceneManager(Axiom.Core.SceneManager sceneManager)
    {
      // unhook from current scene manager.
      if(this.sceneManager != null) {
        this.sceneManager.QueueStarted -= new RenderQueueEvent(SceneManager_QueueStarted);
        this.sceneManager.QueueEnded -= new RenderQueueEvent(SceneManager_QueueEnded);
        this.sceneManager = null;
      }

      // hook new scene manager if that is not NULL
      if (sceneManager != null) {
        this.sceneManager = sceneManager;
        this.sceneManager.QueueStarted += new RenderQueueEvent(SceneManager_QueueStarted);
        this.sceneManager.QueueEnded += new RenderQueueEvent(SceneManager_QueueEnded);
      }
      
    }

    /// <summary>
    ///    Sets the render queue and pre/post settings indicating where the GUI should appear
    ///    within the rendering output.
    /// </summary>
    /// <param name="queueID">Value that specifies where the GUI should appear in the Axiom rendering output.</param>
    /// <param name="postQueue">
    ///    Set to true to have GUI rendered after render queue <paramref name="queueID"/>, 
    ///    or false to have the GUI rendered before render queue <paramref name="queueID"/>.
    /// </param>
    public void SetTargetRenderQueue(Axiom.Core.RenderQueueGroupID queueID, bool postQueue)
    {
      this.queueID = queueID;
      this.postQueue = postQueue;
    }

    /// <summary>
    ///    Create a texture from an existing Axiom.Core.Texture object.
    /// </summary>
    /// <param name="texture">Axiom.Core.Texture object to be used as the basis for the new Texture</param>
    /// <returns>The newly created Texture object</returns>
    public CrayzEdsGui.Base.Texture CreateTexture(Axiom.Core.Texture texture) 
    {
      AxiomTexture tex = (AxiomTexture)CreateTexture();
      tex.Texture = texture;
      return tex;
    }

    #endregion

    private bool SceneManager_QueueStarted(RenderQueueGroupID priority) 
    {
      if(!postQueue && (queueID == priority)) {
        GuiSystem.Instance.RenderGui();
      }

      return false;
    }

    private bool SceneManager_QueueEnded(RenderQueueGroupID priority) {
      if(postQueue && (queueID == priority)) {
        GuiSystem.Instance.RenderGui();
      }

      return false;
    }
  }

  /// <summary>
  ///    Structure used for vertices.
  /// </summary>
  public struct QuadVertex {
    public float x, y, z;
    public int diffuse;
    public float tu, tv;
  }

  /// <summary>
  ///    Structure holding details about a quad to be drawn.
  /// </summary>
  public struct QuadInfo {
    public Axiom.Core.Texture texture;
    public Rect position;
    public float z;
    public Rect texPosition;
    public int  topLeftColor;
    public int  topRightColor;
    public int  bottomLeftColor;
    public int  bottomRightColor;
  }

  public class QuadInfoComparer : IComparer {
    #region IComparer Members

    public int Compare(object x, object y) {
      QuadInfo a = (QuadInfo)x;
      QuadInfo b = (QuadInfo)y;

      if(a.z > b.z) {
        return -1;
      }
      else if(a.z < b.z) {
        return 1;
      }

      // equal
      return 0;
    }

    #endregion

  }

}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.