| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- /*
- * This source file is part of libRocket, the HTML/CSS Interface Middleware
- *
- * For the latest information, see http://www.librocket.com
- *
- * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
- #include "RenderInterfaceOgre3D.h"
- #include <Ogre/Ogre.h>
- struct RocketOgre3DVertex
- {
- float x, y, z;
- Ogre::uint32 diffuse;
- float u, v;
- };
- // The structure created for each texture loaded by Rocket for Ogre.
- struct RocketOgre3DTexture
- {
- RocketOgre3DTexture(Ogre::TexturePtr texture) : texture(texture)
- {
- }
- Ogre::TexturePtr texture;
- };
- // The structure created for each set of geometry that Rocket compiles. It stores the vertex and index buffers and the
- // texture associated with the geometry, if one was specified.
- struct RocketOgre3DCompiledGeometry
- {
- Ogre::RenderOperation render_operation;
- RocketOgre3DTexture* texture;
- };
- RenderInterfaceOgre3D::RenderInterfaceOgre3D(unsigned int window_width, unsigned int window_height)
- {
- render_system = Ogre::Root::getSingleton().getRenderSystem();
- // Configure the colour blending mode.
- colour_blend_mode.blendType = Ogre::LBT_COLOUR;
- colour_blend_mode.source1 = Ogre::LBS_DIFFUSE;
- colour_blend_mode.source2 = Ogre::LBS_TEXTURE;
- colour_blend_mode.operation = Ogre::LBX_MODULATE;
- // Configure the alpha blending mode.
- alpha_blend_mode.blendType = Ogre::LBT_ALPHA;
- alpha_blend_mode.source1 = Ogre::LBS_DIFFUSE;
- alpha_blend_mode.source2 = Ogre::LBS_TEXTURE;
- alpha_blend_mode.operation = Ogre::LBX_MODULATE;
- scissor_enable = false;
- scissor_left = 0;
- scissor_top = 0;
- scissor_right = (int) window_width;
- scissor_bottom = (int) window_height;
- }
- RenderInterfaceOgre3D::~RenderInterfaceOgre3D()
- {
- }
- // Called by Rocket when it wants to render geometry that it does not wish to optimise.
- 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))
- {
- ROCKET_UNUSED(vertices);
- ROCKET_UNUSED(num_vertices);
- ROCKET_UNUSED(indices);
- ROCKET_UNUSED(num_indices);
- ROCKET_UNUSED(texture);
- ROCKET_UNUSED(translation);
- // We've chosen to not support non-compiled geometry in the Ogre3D renderer.
- }
- // Called by Rocket when it wants to compile geometry it believes will be static for the forseeable future.
- Rocket::Core::CompiledGeometryHandle RenderInterfaceOgre3D::CompileGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rocket::Core::TextureHandle texture)
- {
- RocketOgre3DCompiledGeometry* geometry = new RocketOgre3DCompiledGeometry();
- geometry->texture = texture == NULL ? NULL : (RocketOgre3DTexture*) texture;
- geometry->render_operation.vertexData = new Ogre::VertexData();
- geometry->render_operation.vertexData->vertexStart = 0;
- geometry->render_operation.vertexData->vertexCount = num_vertices;
- geometry->render_operation.indexData = new Ogre::IndexData();
- geometry->render_operation.indexData->indexStart = 0;
- geometry->render_operation.indexData->indexCount = num_indices;
- geometry->render_operation.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- // Set up the vertex declaration.
- Ogre::VertexDeclaration* vertex_declaration = geometry->render_operation.vertexData->vertexDeclaration;
- size_t element_offset = 0;
- vertex_declaration->addElement(0, element_offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
- element_offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
- vertex_declaration->addElement(0, element_offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
- element_offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
- vertex_declaration->addElement(0, element_offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
- // Create the vertex buffer.
- Ogre::HardwareVertexBufferSharedPtr vertex_buffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertex_declaration->getVertexSize(0), num_vertices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
- geometry->render_operation.vertexData->vertexBufferBinding->setBinding(0, vertex_buffer);
- // Fill the vertex buffer.
- RocketOgre3DVertex* ogre_vertices = (RocketOgre3DVertex*) vertex_buffer->lock(0, vertex_buffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_NORMAL);
- for (int i = 0; i < num_vertices; ++i)
- {
- ogre_vertices[i].x = vertices[i].position.x;
- ogre_vertices[i].y = vertices[i].position.y;
- ogre_vertices[i].z = 0;
- 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);
- render_system->convertColourValue(diffuse, &ogre_vertices[i].diffuse);
- ogre_vertices[i].u = vertices[i].tex_coord[0];
- ogre_vertices[i].v = vertices[i].tex_coord[1];
- }
- vertex_buffer->unlock();
- // Create the index buffer.
- Ogre::HardwareIndexBufferSharedPtr index_buffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(Ogre::HardwareIndexBuffer::IT_32BIT, num_indices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
- geometry->render_operation.indexData->indexBuffer = index_buffer;
- geometry->render_operation.useIndexes = true;
- // Fill the index buffer.
- void* ogre_indices = index_buffer->lock(0, index_buffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_NORMAL);
- memcpy(ogre_indices, indices, sizeof(unsigned int) * num_indices);
- index_buffer->unlock();
- return reinterpret_cast<Rocket::Core::CompiledGeometryHandle>(geometry);
- }
- // Called by Rocket when it wants to render application-compiled geometry.
- void RenderInterfaceOgre3D::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation)
- {
- Ogre::Matrix4 transform;
- transform.makeTrans(translation.x, translation.y, 0);
- render_system->_setWorldMatrix(transform);
- render_system = Ogre::Root::getSingleton().getRenderSystem();
- RocketOgre3DCompiledGeometry* ogre3d_geometry = (RocketOgre3DCompiledGeometry*) geometry;
- if (ogre3d_geometry->texture != NULL)
- {
- render_system->_setTexture(0, true, ogre3d_geometry->texture->texture);
- // Ogre can change the blending modes when textures are disabled - so in case the last render had no texture,
- // we need to re-specify them.
- render_system->_setTextureBlendMode(0, colour_blend_mode);
- render_system->_setTextureBlendMode(0, alpha_blend_mode);
- }
- else
- render_system->_disableTextureUnit(0);
- render_system->_render(ogre3d_geometry->render_operation);
- }
- // Called by Rocket when it wants to release application-compiled geometry.
- void RenderInterfaceOgre3D::ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry)
- {
- RocketOgre3DCompiledGeometry* ogre3d_geometry = reinterpret_cast<RocketOgre3DCompiledGeometry*>(geometry);
- delete ogre3d_geometry->render_operation.vertexData;
- delete ogre3d_geometry->render_operation.indexData;
- delete ogre3d_geometry;
- }
- // Called by Rocket when it wants to enable or disable scissoring to clip content.
- void RenderInterfaceOgre3D::EnableScissorRegion(bool enable)
- {
- scissor_enable = enable;
- if (!scissor_enable)
- render_system->setScissorTest(false);
- else
- render_system->setScissorTest(true, scissor_left, scissor_top, scissor_right, scissor_bottom);
- }
- // Called by Rocket when it wants to change the scissor region.
- void RenderInterfaceOgre3D::SetScissorRegion(int x, int y, int width, int height)
- {
- scissor_left = x;
- scissor_top = y;
- scissor_right = x + width;
- scissor_bottom = y + height;
- if (scissor_enable)
- render_system->setScissorTest(true, scissor_left, scissor_top, scissor_right, scissor_bottom);
- }
- // Called by Rocket when a texture is required by the library.
- bool RenderInterfaceOgre3D::LoadTexture(Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source)
- {
- Ogre::TextureManager* texture_manager = Ogre::TextureManager::getSingletonPtr();
- Ogre::TexturePtr ogre_texture = texture_manager->getByName(Ogre::String(source.CString()));
- if (ogre_texture.isNull())
- {
- ogre_texture = texture_manager->load(Ogre::String(source.CString()),
- "Rocket",
- Ogre::TEX_TYPE_2D,
- 0);
- }
- if (ogre_texture.isNull())
- return false;
- texture_dimensions.x = ogre_texture->getWidth();
- texture_dimensions.y = ogre_texture->getHeight();
- texture_handle = reinterpret_cast<Rocket::Core::TextureHandle>(new RocketOgre3DTexture(ogre_texture));
- return true;
- }
- // Called by Rocket when a texture is required to be built from an internally-generated sequence of pixels.
- bool RenderInterfaceOgre3D::GenerateTexture(Rocket::Core::TextureHandle& texture_handle, const Rocket::Core::byte* source, const Rocket::Core::Vector2i& source_dimensions)
- {
- static int texture_id = 1;
- Ogre::TexturePtr ogre_texture = Ogre::TextureManager::getSingleton().loadRawData(Rocket::Core::String(16, "%d", texture_id++).CString(),
- "Rocket",
- Ogre::DataStreamPtr(new Ogre::MemoryDataStream((void*) source, source_dimensions.x * source_dimensions.y * sizeof(unsigned int))),
- source_dimensions.x,
- source_dimensions.y,
- Ogre::PF_A8B8G8R8,
- Ogre::TEX_TYPE_2D,
- 0);
- if (ogre_texture.isNull())
- return false;
- texture_handle = reinterpret_cast<Rocket::Core::TextureHandle>(new RocketOgre3DTexture(ogre_texture));
- return true;
- }
- // Called by Rocket when a loaded texture is no longer required.
- void RenderInterfaceOgre3D::ReleaseTexture(Rocket::Core::TextureHandle texture)
- {
- delete ((RocketOgre3DTexture*) texture);
- }
- // Returns the native horizontal texel offset for the renderer.
- float RenderInterfaceOgre3D::GetHorizontalTexelOffset()
- {
- return -render_system->getHorizontalTexelOffset();
- }
- // Returns the native vertical texel offset for the renderer.
- float RenderInterfaceOgre3D::GetVerticalTexelOffset()
- {
- return -render_system->getVerticalTexelOffset();
- }
|