RenderInterfaceOgre3D.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * This source file is part of libRocket, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://www.librocket.com
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #include "RenderInterfaceOgre3D.h"
  28. #include <Ogre/Ogre.h>
  29. struct RocketOgre3DVertex
  30. {
  31. float x, y, z;
  32. Ogre::uint32 diffuse;
  33. float u, v;
  34. };
  35. // The structure created for each texture loaded by Rocket for Ogre.
  36. struct RocketOgre3DTexture
  37. {
  38. RocketOgre3DTexture(Ogre::TexturePtr texture) : texture(texture)
  39. {
  40. }
  41. Ogre::TexturePtr texture;
  42. };
  43. // The structure created for each set of geometry that Rocket compiles. It stores the vertex and index buffers and the
  44. // texture associated with the geometry, if one was specified.
  45. struct RocketOgre3DCompiledGeometry
  46. {
  47. Ogre::RenderOperation render_operation;
  48. RocketOgre3DTexture* texture;
  49. };
  50. RenderInterfaceOgre3D::RenderInterfaceOgre3D(unsigned int window_width, unsigned int window_height)
  51. {
  52. render_system = Ogre::Root::getSingleton().getRenderSystem();
  53. // Configure the colour blending mode.
  54. colour_blend_mode.blendType = Ogre::LBT_COLOUR;
  55. colour_blend_mode.source1 = Ogre::LBS_DIFFUSE;
  56. colour_blend_mode.source2 = Ogre::LBS_TEXTURE;
  57. colour_blend_mode.operation = Ogre::LBX_MODULATE;
  58. // Configure the alpha blending mode.
  59. alpha_blend_mode.blendType = Ogre::LBT_ALPHA;
  60. alpha_blend_mode.source1 = Ogre::LBS_DIFFUSE;
  61. alpha_blend_mode.source2 = Ogre::LBS_TEXTURE;
  62. alpha_blend_mode.operation = Ogre::LBX_MODULATE;
  63. scissor_enable = false;
  64. scissor_left = 0;
  65. scissor_top = 0;
  66. scissor_right = (int) window_width;
  67. scissor_bottom = (int) window_height;
  68. }
  69. RenderInterfaceOgre3D::~RenderInterfaceOgre3D()
  70. {
  71. }
  72. // Called by Rocket when it wants to render geometry that it does not wish to optimise.
  73. void RenderInterfaceOgre3D::RenderGeometry(Rocket::Core::Vertex* ROCKET_UNUSED_PARAMETER(vertices), int ROCKET_UNUSED_PARAMETER(num_vertices), int* ROCKET_UNUSED_PARAMETER(indices), int ROCKET_UNUSED_PARAMETER(num_indices), Rocket::Core::TextureHandle ROCKET_UNUSED_PARAMETER(texture), const Rocket::Core::Vector2f& ROCKET_UNUSED_PARAMETER(translation))
  74. {
  75. ROCKET_UNUSED(vertices);
  76. ROCKET_UNUSED(num_vertices);
  77. ROCKET_UNUSED(indices);
  78. ROCKET_UNUSED(num_indices);
  79. ROCKET_UNUSED(texture);
  80. ROCKET_UNUSED(translation);
  81. // We've chosen to not support non-compiled geometry in the Ogre3D renderer.
  82. }
  83. // Called by Rocket when it wants to compile geometry it believes will be static for the forseeable future.
  84. Rocket::Core::CompiledGeometryHandle RenderInterfaceOgre3D::CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture)
  85. {
  86. RocketOgre3DCompiledGeometry* geometry = new RocketOgre3DCompiledGeometry();
  87. geometry->texture = texture == NULL ? NULL : (RocketOgre3DTexture*) texture;
  88. geometry->render_operation.vertexData = new Ogre::VertexData();
  89. geometry->render_operation.vertexData->vertexStart = 0;
  90. geometry->render_operation.vertexData->vertexCount = num_vertices;
  91. geometry->render_operation.indexData = new Ogre::IndexData();
  92. geometry->render_operation.indexData->indexStart = 0;
  93. geometry->render_operation.indexData->indexCount = num_indices;
  94. geometry->render_operation.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
  95. // Set up the vertex declaration.
  96. Ogre::VertexDeclaration* vertex_declaration = geometry->render_operation.vertexData->vertexDeclaration;
  97. size_t element_offset = 0;
  98. vertex_declaration->addElement(0, element_offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
  99. element_offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
  100. vertex_declaration->addElement(0, element_offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
  101. element_offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
  102. vertex_declaration->addElement(0, element_offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
  103. // Create the vertex buffer.
  104. Ogre::HardwareVertexBufferSharedPtr vertex_buffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertex_declaration->getVertexSize(0), num_vertices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  105. geometry->render_operation.vertexData->vertexBufferBinding->setBinding(0, vertex_buffer);
  106. // Fill the vertex buffer.
  107. RocketOgre3DVertex* ogre_vertices = (RocketOgre3DVertex*) vertex_buffer->lock(0, vertex_buffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_NORMAL);
  108. for (int i = 0; i < num_vertices; ++i)
  109. {
  110. ogre_vertices[i].x = vertices[i].position.x;
  111. ogre_vertices[i].y = vertices[i].position.y;
  112. ogre_vertices[i].z = 0;
  113. Ogre::ColourValue diffuse(vertices[i].colour.red / 255.0f, vertices[i].colour.green / 255.0f, vertices[i].colour.blue / 255.0f, vertices[i].colour.alpha / 255.0f);
  114. render_system->convertColourValue(diffuse, &ogre_vertices[i].diffuse);
  115. ogre_vertices[i].u = vertices[i].tex_coord[0];
  116. ogre_vertices[i].v = vertices[i].tex_coord[1];
  117. }
  118. vertex_buffer->unlock();
  119. // Create the index buffer.
  120. Ogre::HardwareIndexBufferSharedPtr index_buffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_32BIT, num_indices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
  121. geometry->render_operation.indexData->indexBuffer = index_buffer;
  122. geometry->render_operation.useIndexes = true;
  123. // Fill the index buffer.
  124. void* ogre_indices = index_buffer->lock(0, index_buffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_NORMAL);
  125. memcpy(ogre_indices, indices, sizeof(unsigned int) * num_indices);
  126. index_buffer->unlock();
  127. return reinterpret_cast<Rocket::Core::CompiledGeometryHandle>(geometry);
  128. }
  129. // Called by Rocket when it wants to render application-compiled geometry.
  130. void RenderInterfaceOgre3D::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation)
  131. {
  132. Ogre::Matrix4 transform;
  133. transform.makeTrans(translation.x, translation.y, 0);
  134. render_system->_setWorldMatrix(transform);
  135. render_system = Ogre::Root::getSingleton().getRenderSystem();
  136. RocketOgre3DCompiledGeometry* ogre3d_geometry = (RocketOgre3DCompiledGeometry*) geometry;
  137. if (ogre3d_geometry->texture != NULL)
  138. {
  139. render_system->_setTexture(0, true, ogre3d_geometry->texture->texture);
  140. // Ogre can change the blending modes when textures are disabled - so in case the last render had no texture,
  141. // we need to re-specify them.
  142. render_system->_setTextureBlendMode(0, colour_blend_mode);
  143. render_system->_setTextureBlendMode(0, alpha_blend_mode);
  144. }
  145. else
  146. render_system->_disableTextureUnit(0);
  147. render_system->_render(ogre3d_geometry->render_operation);
  148. }
  149. // Called by Rocket when it wants to release application-compiled geometry.
  150. void RenderInterfaceOgre3D::ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry)
  151. {
  152. RocketOgre3DCompiledGeometry* ogre3d_geometry = reinterpret_cast<RocketOgre3DCompiledGeometry*>(geometry);
  153. delete ogre3d_geometry->render_operation.vertexData;
  154. delete ogre3d_geometry->render_operation.indexData;
  155. delete ogre3d_geometry;
  156. }
  157. // Called by Rocket when it wants to enable or disable scissoring to clip content.
  158. void RenderInterfaceOgre3D::EnableScissorRegion(bool enable)
  159. {
  160. scissor_enable = enable;
  161. if (!scissor_enable)
  162. render_system->setScissorTest(false);
  163. else
  164. render_system->setScissorTest(true, scissor_left, scissor_top, scissor_right, scissor_bottom);
  165. }
  166. // Called by Rocket when it wants to change the scissor region.
  167. void RenderInterfaceOgre3D::SetScissorRegion(int x, int y, int width, int height)
  168. {
  169. scissor_left = x;
  170. scissor_top = y;
  171. scissor_right = x + width;
  172. scissor_bottom = y + height;
  173. if (scissor_enable)
  174. render_system->setScissorTest(true, scissor_left, scissor_top, scissor_right, scissor_bottom);
  175. }
  176. // Called by Rocket when a texture is required by the library.
  177. bool RenderInterfaceOgre3D::LoadTexture(Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source)
  178. {
  179. Ogre::TextureManager* texture_manager = Ogre::TextureManager::getSingletonPtr();
  180. Ogre::TexturePtr ogre_texture = texture_manager->getByName(Ogre::String(source.CString()));
  181. if (ogre_texture.isNull())
  182. {
  183. ogre_texture = texture_manager->load(Ogre::String(source.CString()),
  184. "Rocket",
  185. Ogre::TEX_TYPE_2D,
  186. 0);
  187. }
  188. if (ogre_texture.isNull())
  189. return false;
  190. texture_dimensions.x = ogre_texture->getWidth();
  191. texture_dimensions.y = ogre_texture->getHeight();
  192. texture_handle = reinterpret_cast<Rocket::Core::TextureHandle>(new RocketOgre3DTexture(ogre_texture));
  193. return true;
  194. }
  195. // Called by Rocket when a texture is required to be built from an internally-generated sequence of pixels.
  196. bool RenderInterfaceOgre3D::GenerateTexture(Rocket::Core::TextureHandle& texture_handle, const Rocket::Core::byte* source, const Rocket::Core::Vector2i& source_dimensions)
  197. {
  198. static int texture_id = 1;
  199. Ogre::TexturePtr ogre_texture = Ogre::TextureManager::getSingleton().loadRawData(Rocket::Core::String(16, "%d", texture_id++).CString(),
  200. "Rocket",
  201. Ogre::DataStreamPtr(new Ogre::MemoryDataStream((void*) source, source_dimensions.x * source_dimensions.y * sizeof(unsigned int))),
  202. source_dimensions.x,
  203. source_dimensions.y,
  204. Ogre::PF_A8B8G8R8,
  205. Ogre::TEX_TYPE_2D,
  206. 0);
  207. if (ogre_texture.isNull())
  208. return false;
  209. texture_handle = reinterpret_cast<Rocket::Core::TextureHandle>(new RocketOgre3DTexture(ogre_texture));
  210. return true;
  211. }
  212. // Called by Rocket when a loaded texture is no longer required.
  213. void RenderInterfaceOgre3D::ReleaseTexture(Rocket::Core::TextureHandle texture)
  214. {
  215. delete ((RocketOgre3DTexture*) texture);
  216. }
  217. // Returns the native horizontal texel offset for the renderer.
  218. float RenderInterfaceOgre3D::GetHorizontalTexelOffset()
  219. {
  220. return -render_system->getHorizontalTexelOffset();
  221. }
  222. // Returns the native vertical texel offset for the renderer.
  223. float RenderInterfaceOgre3D::GetVerticalTexelOffset()
  224. {
  225. return -render_system->getVerticalTexelOffset();
  226. }