OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: MOGRE SpriteManager2d
View page
Source of version: 4
(current)
{img src="img/wiki_up/MOGRESpriteManager2d.png" alt="thumb|" width="350" imalign="right"} This is a slightly modified port of ((SpriteManager2d)), which provides an __easy way to draw 2D objects__ to the screen. It was done by user ((User:Smiley80|Smiley80)). {img src="img/wiki_up/Forum_icon_question2.gif" alt="Forum_icon_question2.gif"} For questions, bug reports etc. use this [http://www.ogre3d.org/addonforums/viewtopic.php?f=8&t=10336|forum thread]. {maketoc} !Features * Render two dimensional images * It also can write text - use a font textures and set the uv-coordinates appropriately * ... !Usage * Initialization (after you created the SceneManager). __Note:__ This sets the properties to their default values. {CODE(wrap="1", colors="c#")}SpriteManager.Initialize(sceneMgr);{CODE} * In the program's main loop (e.g. the FrameStarted eventhandler). __Note:__ The sprite buffer is cleared after each rendering (sprites.Clear() in Render()), so you have to enqueue the sprites you want to draw each frame. {CODE(wrap="1", colors="c#")}SpriteManager.EnqueueTexture(textureName, x1, y1, x2, y2, alpha);{CODE} * Shutdown (before root.Dispose()). {CODE(wrap="1", colors="c#")}SpriteManager.Shutdown();{CODE} !!Properties * TargetQueue specifies before or after which RenderQueue the rendering should happen (default is RenderQueueGroupID.RENDER_QUEUE_OVERLAY). * AfterQueue indicates that the rendering should happen after the specified RenderQueue (default is false). * MinimalHardwareBufferSize specifies an the initial and minimum size of the HardwareBuffer. This prevents the HardwareBuffer from being constantly destroyed and recreated when the number sprites increases (if the number of sprites * 6 is below or equal the value of MinimalHardwareBufferSize) (default is 120). !!EnqueueTexture in depth {CODE(wrap="1", colors="c#")}EnqueueTexture(textureName, x1, y1, x2, y2, tx1, ty1, tx2, ty2, alpha){CODE} * textureName is the filename of the texture you want to draw. The method ensure that the texture is loaded, so it doesn't have to be done beforehand. * (x1; y1) is the coordinate of the top-left corner and (x2; y2) is the coodinate of the bottom-right corner of the sprite. The values of x and y range are in screen space (-1 to 1). If you want to use screen coordinates in pixel, you have to convert them using the following formulas: For x-coordinates: {CODE(wrap="1", colors="c#")}((float)x / screen-width) * 2 - 1{CODE} For y-coordinates: {CODE(wrap="1", colors="c#")}-(((float)y / screen-height) * 2 - 1){CODE} __Example__: Assuming the screen resolution is 1280x960, the position should be at (320; 240) and the size of the sprite is 640x480: x1 = 320, y1 = 240 => x1 = -0.5, y1 = 0.5 ; x2 = 960, y2 = 720 => x1 = 0.5, y2 = -0.5 * tx1, ty1, tx2, ty2 are the uv-coordinates of the texture (0 to 1). The default is "0, 0, 1, 1" which draws the whole texture. * alpha is the alpha value (D'oh) which ranges from 0 to 1. Where 0 is fully transparent and 1 is fully opaque. !!Performance Issues Enqueuing a lot of sprites (100+) each frame leads to a significant framerate drop. In such case remove sprites.Clear() from Render(), enqueue the sprites only once and add a method, which allows you to remove a sprite manually. !See also * ((-Overlay|Overlay)) * ((-Billboard|Billboard)) * ((MOGRE MovableText by Billboards)) - shows text, clamped to a SceneNode * ((MOGRE MovableText)) - add text to {LEX()}SceneNode{LEX}s * ((Simple text in MOGRE)) - shows text independent of a SceneNode * ((Easy Debug Text for MOGRE)) - shows a text, which can be updated * ((OgreSprites)) - similar, but without use of ''Billboard'' * ((ManualObject 2D)) * ((-GUI|GUI)) - several gui systems !SpriteManager.cs {CODE(wrap="1", colors="c#")} namespace Example { using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Mogre; public static class SpriteManager { #region Fields private static HardwareVertexBufferSharedPtr hardwareBuffer; private static RenderOperation renderOp; private static SceneManager sceneMan; private static LinkedList<Sprite> sprites; #endregion Fields #region Properties public static bool AfterQueue { get; set; } public static int MinimalHardwareBufferSize { get; set; } public static RenderQueueGroupID TargetQueue { get; set; } #endregion Properties #region Methods public static void EnqueueTexture(string textureName, float x1, float y1, float x2, float y2, float alpha) { EnqueueTexture(textureName, x1, y1, x2, y2, 0, 0, 1, 1, alpha); } public static void EnqueueTexture(string textureName, float x1, float y1, float x2, float y2, float tx1, float ty1, float tx2, float ty2, float alpha) { float z = -1.0f; Sprite spr = new Sprite(); spr.Alpha = alpha; spr.Pos = new Vector3[6]; spr.UV = new Vector2[6]; spr.Pos[0] = new Vector3(x1, y2, z); spr.UV[0] = new Vector2(tx1, ty2); spr.Pos[1] = new Vector3(x2, y1, z); spr.UV[1] = new Vector2(tx2, ty1); spr.Pos[2] = new Vector3(x1, y1, z); spr.UV[2] = new Vector2(tx1, ty1); spr.Pos[3] = new Vector3(x1, y2, z); spr.UV[3] = new Vector2(tx1, ty2); spr.Pos[4] = new Vector3(x2, y1, z); spr.UV[4] = new Vector2(tx2, ty1); spr.Pos[5] = new Vector3(x2, y2, z); spr.UV[5] = new Vector2(tx2, ty2); TexturePtr tp = TextureManager.Singleton.GetByName(textureName); if (tp == null || !tp.IsLoaded) { tp = TextureManager.Singleton.Load(textureName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME); } spr.TexHandle = tp.Handle; tp.Dispose(); if (!sprites.Contains(spr)) { sprites.AddLast(spr); } } public static void Initialize(SceneManager sceneManager) { sceneMan = sceneManager; TargetQueue = RenderQueueGroupID.RENDER_QUEUE_OVERLAY; AfterQueue = false; MinimalHardwareBufferSize = 120; sprites = new LinkedList<Sprite>(); sceneMan.RenderQueueStarted += RenderQueueStarted; sceneMan.RenderQueueEnded += RenderQueueEnded; } public static void Shutdown() { if (hardwareBuffer != null) { HardwareBuffer_Destroy(); } sceneMan.RenderQueueStarted -= RenderQueueStarted; sceneMan.RenderQueueEnded -= RenderQueueEnded; } private static void HardwareBuffer_Create(int size) { VertexDeclaration vd; renderOp = new RenderOperation(); renderOp.vertexData = new VertexData(); renderOp.vertexData.vertexStart = 0; vd = renderOp.vertexData.vertexDeclaration; vd.AddElement( 0, 0, VertexElementType.VET_FLOAT3, VertexElementSemantic.VES_POSITION); vd.AddElement( 0, VertexElement.GetTypeSize(VertexElementType.VET_FLOAT3), VertexElementType.VET_FLOAT2, VertexElementSemantic.VES_TEXTURE_COORDINATES); hardwareBuffer = HardwareBufferManager.Singleton.CreateVertexBuffer( vd.GetVertexSize(0), (uint)size, HardwareBuffer.Usage.HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, true); renderOp.vertexData.vertexBufferBinding.SetBinding(0, hardwareBuffer); renderOp.operationType = RenderOperation.OperationTypes.OT_TRIANGLE_LIST; renderOp.useIndexes = false; } private static void HardwareBuffer_Destroy() { hardwareBuffer.Dispose(); renderOp.vertexData.Dispose(); renderOp.Dispose(); } private static void Render() { if (sprites.Count == 0) { return; } RenderSystem rs = Root.Singleton.RenderSystem; Chunk thisChunk = new Chunk(); List<Chunk> chunks = new List<Chunk>(); int newSize; newSize = sprites.Count * 6; if (newSize < MinimalHardwareBufferSize) { newSize = MinimalHardwareBufferSize; } // grow hardware buffer if needed if (hardwareBuffer == null || hardwareBuffer.NumVertices < newSize) { if (hardwareBuffer != null) { HardwareBuffer_Destroy(); } HardwareBuffer_Create(newSize); } // write quads to the hardware buffer, and remember chunks unsafe { Vertex* buffer = (Vertex*)hardwareBuffer.Lock(HardwareBuffer.LockOptions.HBL_DISCARD); LinkedListNode<Sprite> node = sprites.First; Sprite currSpr; while (node != null) { currSpr = node.Value; thisChunk.Alpha = currSpr.Alpha; thisChunk.TexHandle = currSpr.TexHandle; for (int i = 0; i < 6; i++) { *buffer++ = new Vertex( currSpr.Pos[i], currSpr.UV[i]); } thisChunk.VertexCount += 6; node = node.Next; if (node == null || thisChunk.TexHandle != node.Value.TexHandle || thisChunk.Alpha != node.Value.Alpha) { chunks.Add(thisChunk); thisChunk.VertexCount = 0; } } } hardwareBuffer.Unlock(); // set up... RenderSystem_Setup(); // do the real render! // do the real render! TexturePtr tp = null; renderOp.vertexData.vertexStart = 0; foreach (Chunk currChunk in chunks) { renderOp.vertexData.vertexCount = currChunk.VertexCount; tp = TextureManager.Singleton.GetByHandle(currChunk.TexHandle); rs._setTexture(0, true, tp.Name); rs._setTextureUnitFiltering( 0, FilterOptions.FO_LINEAR, FilterOptions.FO_LINEAR, FilterOptions.FO_POINT); // set alpha LayerBlendModeEx_NativePtr alphaBlendMode = LayerBlendModeEx_NativePtr.Create(); alphaBlendMode.alphaArg1 = 0; alphaBlendMode.alphaArg2 = currChunk.Alpha; alphaBlendMode.source1 = LayerBlendSource.LBS_TEXTURE; alphaBlendMode.source2 = LayerBlendSource.LBS_MANUAL; alphaBlendMode.blendType = LayerBlendType.LBT_ALPHA; alphaBlendMode.operation = LayerBlendOperationEx.LBX_MODULATE; alphaBlendMode.factor = currChunk.Alpha; rs._setTextureBlendMode(0, alphaBlendMode); rs._render(renderOp); renderOp.vertexData.vertexStart += currChunk.VertexCount; alphaBlendMode.DestroyNativePtr(); } if (tp != null) { tp.Dispose(); } // sprites go home! sprites.Clear(); } private static void RenderQueueEnded(byte queueGroupId, string invocation, out bool repeatThisInvocation) { repeatThisInvocation = false; // shut up compiler if (AfterQueue && queueGroupId == (byte)TargetQueue) { Render(); } } private static void RenderQueueStarted(byte queueGroupId, string invocation, out bool skipThisInvocation) { skipThisInvocation = false; // shut up compiler if (!AfterQueue && queueGroupId == (byte)TargetQueue) { Render(); } } private static void RenderSystem_Setup() { RenderSystem rs = Root.Singleton.RenderSystem; LayerBlendModeEx_NativePtr colorBlendMode = LayerBlendModeEx_NativePtr.Create(); colorBlendMode.blendType = LayerBlendType.LBT_COLOUR; colorBlendMode.source1 = LayerBlendSource.LBS_TEXTURE; colorBlendMode.operation = LayerBlendOperationEx.LBX_SOURCE1; TextureUnitState.UVWAddressingMode uvwAddressMode; uvwAddressMode.u = TextureUnitState.TextureAddressingMode.TAM_CLAMP; uvwAddressMode.v = TextureUnitState.TextureAddressingMode.TAM_CLAMP; uvwAddressMode.w = TextureUnitState.TextureAddressingMode.TAM_CLAMP; rs._setWorldMatrix(Matrix4.IDENTITY); rs._setViewMatrix(Matrix4.IDENTITY); rs._setProjectionMatrix(Matrix4.IDENTITY); rs._setTextureMatrix(0, Matrix4.IDENTITY); rs._setTextureCoordSet(0, 0); rs._setTextureCoordCalculation(0, TexCoordCalcMethod.TEXCALC_NONE); rs._setTextureBlendMode(0, colorBlendMode); rs._setTextureAddressingMode(0, uvwAddressMode); rs._disableTextureUnitsFrom(1); rs.SetLightingEnabled(false); rs._setFog(FogMode.FOG_NONE); rs._setCullingMode(CullingMode.CULL_NONE); rs._setDepthBufferParams(false, false); rs._setColourBufferWriteEnabled(true, true, true, false); rs.SetShadingType(ShadeOptions.SO_GOURAUD); rs._setPolygonMode(PolygonMode.PM_SOLID); rs.UnbindGpuProgram(GpuProgramType.GPT_FRAGMENT_PROGRAM); rs.UnbindGpuProgram(GpuProgramType.GPT_VERTEX_PROGRAM); rs._setSeparateSceneBlending( SceneBlendFactor.SBF_SOURCE_ALPHA, SceneBlendFactor.SBF_ONE_MINUS_SOURCE_ALPHA, SceneBlendFactor.SBF_ONE, SceneBlendFactor.SBF_ONE); rs._setAlphaRejectSettings(CompareFunction.CMPF_ALWAYS_PASS, 0, true); colorBlendMode.DestroyNativePtr(); } #endregion Methods #region Nested Types internal struct Chunk { #region Properties public float Alpha { get; set; } public uint TexHandle { get; set; } public uint VertexCount { get; set; } #endregion Properties } internal struct Sprite { #region Properties public float Alpha { get; set; } public Vector3[] Pos { get; set; } public uint TexHandle { get; set; } public Vector2[] UV { get; set; } #endregion Properties #region Methods public static bool operator !=(Sprite left, Sprite right) { return !left.Equals(right); } public static bool operator ==(Sprite left, Sprite right) { return left.Equals(right); } public override bool Equals(object obj) { if (obj is Sprite) { return this.Equals((Sprite)obj); // use Equals method below } else { return false; } } public bool Equals(Sprite other) { bool equal = this.TexHandle == other.TexHandle && this.Alpha == other.Alpha; if (!equal) { return false; } for (int i = 0; i < 6; i++) { if (this.Pos[i] != other.Pos[i]) { return false; } if (this.UV[i] != other.UV[i]) { return false; } } return true; } public override int GetHashCode() { return this.Alpha.GetHashCode() ^ this.Pos.GetHashCode() ^ this.UV.GetHashCode() ^ this.TexHandle.GetHashCode(); } #endregion Methods } [StructLayout(LayoutKind.Explicit)] internal struct Vertex { [FieldOffset(0)] public Vector3 Pos; [FieldOffset(12)] public Vector2 UV; #region Constructors public Vertex(Vector3 pos, Vector2 uv) { this.Pos = pos; this.UV = uv; } #endregion Constructors } #endregion Nested Types } }{CODE}
Search by Tags
Search Wiki by Freetags
Latest Changes
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
...more
Search
Find
Advanced
Search Help
Online Users
266 online users