[SOLVED] Ogre 1.9 RC1 + Android + libRocket Topic is solved

Discussion of issues specific to mobile platforms such as iOS, Android, Symbian and Meego.
Post Reply
technique
Halfling
Posts: 91
Joined: Fri Oct 22, 2010 10:46 pm
x 8

[SOLVED] Ogre 1.9 RC1 + Android + libRocket

Post by technique »

I currently try to use Ogre 1.9 + LibRocket on Android. After adjusting much of the Ogre LibRocket Demo Sample my App is full up and running but i didnt see anything of the libRocket GUI (but all resources are loaded correctly and rocket doenst post any error debug msgs). Since im using GLES2 and the RTSS i thought this might be the problem.

I had to adjust a few things in the libRocket Ogre Sample like the 16 bit index buffer conversion and a few other small things (found a few hints about that in the www). LibRocket seems to start correctly parsing and using all needed RML files and do not promt an error message anymore.

I read about a lot Apps using libRocket as GUI System on Android + Ogre but there is no tutorial out there showing how to do that. Since im not quite familar with the OgreRenderSystem or RTSS i m not sure if its possible using libRocket (the librocket ogre sample way) with RTSS enabled?
But since GLES2 did not have the fixed function pipeline ability - i thought i need the RTSS ffp emulation to use libRocket!

Did anyone point me in the right direction how to get this working?

Thanks for reading this!
Last edited by technique on Mon Nov 18, 2013 6:26 pm, edited 2 times in total.
Image
Kingdoms Defender offers Tower Defense action with breathtaking 3-D graphics for your mobile Android device.

Give it a try:
Free-Version:
http://play.google.com/store/apps/detai ... ender_free

Full-Version:
http://play.google.com/store/apps/detai ... msdefender
technique
Halfling
Posts: 91
Joined: Fri Oct 22, 2010 10:46 pm
x 8

Re: Ogre 1.9 RC + Android + libRocket

Post by technique »

Solved. I was helped by ulyk. I'll probably will write a small tutorial how i did it! but this will take a few time!
Image
Kingdoms Defender offers Tower Defense action with breathtaking 3-D graphics for your mobile Android device.

Give it a try:
Free-Version:
http://play.google.com/store/apps/detai ... ender_free

Full-Version:
http://play.google.com/store/apps/detai ... msdefender
mega28
Gnoblar
Posts: 4
Joined: Fri Jun 14, 2013 12:43 am

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by mega28 »

Still willing to write the tutorial ? Provide a working sample perhaps ?
technique
Halfling
Posts: 91
Joined: Fri Oct 22, 2010 10:46 pm
x 8

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by technique »

Oh yeah but i m currently very busy - ill post some source code soon!
Image
Kingdoms Defender offers Tower Defense action with breathtaking 3-D graphics for your mobile Android device.

Give it a try:
Free-Version:
http://play.google.com/store/apps/detai ... ender_free

Full-Version:
http://play.google.com/store/apps/detai ... msdefender
rhaith
Kobold
Posts: 27
Joined: Mon Nov 23, 2009 4:35 am
x 2

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by rhaith »

To those interested I had this problem too and solved it. I wrote a small article on it with source code to download to get libRocket working on android and iOS.

http://www.manicnorth.com/devblog/1/
RigoCL
Greenskin
Posts: 114
Joined: Mon Oct 14, 2013 1:41 am
Location: Chile
x 3

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by RigoCL »

Great double work rhaith, pretty sure lots of Android/libRocket lovers will appreciate your article and source... I took a fast look into that and found the 1x1 pure white texture very tricky, meaning very smart fast solution.
Integrated: Ogre3D + dotScene (Blender loader) + MyGUI (UI) + RakNet (Client/Server) + Leap Motion (The future is here!) + StereoManager (3D Anaglyph red-cyan)
WIP: StereoManager (Real 3D) + CCS (Camera Control System) + Sound, experimenting with Android.
j1230xz
Gnoblar
Posts: 21
Joined: Mon May 13, 2013 3:21 pm

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by j1230xz »

I am trying to implement your solution right now. Hope it works.... thank you like million times :)

One question though (im relatively new to ogre). I did not see where you load the shaders? I guess only the program file should be loaded in Ogre somehow?
j1230xz
Gnoblar
Posts: 21
Joined: Mon May 13, 2013 3:21 pm

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by j1230xz »

Works perfectly. Tested on Android, ios, linux

Thanks
technique
Halfling
Posts: 91
Joined: Fri Oct 22, 2010 10:46 pm
x 8

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by technique »

Thank you rhaith - i didnt find the time to write a tutorial!

If you want to use the Android AssetManager for your Resources you have to create your own Rocket::Core::FileInterface.
Here is my implementation (free to use):

Code: Select all

#ifndef ANDROIDFILEINTERFACE_H
#define ANDROIDFILEINTERFACE_H

// ANDROID
#include <android/asset_manager.h>
#include <android/log.h>

// ROCKET
#include <Rocket/Core/FileInterface.h>

// STL
#include <map>

#define APPNAME "TEST"

struct AndroidFilePointer
{
	AAsset* asset;
	int offset;
};

class AndroidFileInterface : public Rocket::Core::FileInterface
{
public:
	AndroidFileInterface(AAssetManager* assetMgr)
	{
		mAssetMgr = assetMgr;
	}

	// Opens a file.
	virtual Rocket::Core::FileHandle Open(const Rocket::Core::String& path)
	{
		//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, (Rocket::Core::String("Rocket::Core::FileHandle Open: ") + path).CString());
		AAsset* asset = AAssetManager_open(mAssetMgr, path.CString(), AASSET_MODE_BUFFER);
		if(asset)
		{
			AndroidFilePointer* afp = new AndroidFilePointer();
			afp->asset = asset;
			afp->offset = 0;
			Rocket::Core::FileHandle membuf = (Rocket::Core::FileHandle) afp;
			return membuf;
		}
		return NULL;
	}

	// Closes a previously opened file.
	virtual void Close(Rocket::Core::FileHandle file)
	{
		//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Rocket::Core::FileHandle Close");
		if(file)
		{
			AndroidFilePointer* afp = (AndroidFilePointer*) file;
			AAsset* asset = afp->asset;
			AAsset_close(asset);
			delete afp;
		}
	}

	// Reads data from a previously opened file.
	virtual size_t Read(void* buffer, size_t size, Rocket::Core::FileHandle file) {
		//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Rocket::Core::FileHandle Read %d ...", size);
		if(!file) return 0;
		AndroidFilePointer* afp = (AndroidFilePointer*) file;
		AAsset* asset = afp->asset;
		off_t length = AAsset_getLength(asset);
		char const* assetBuffer = (char*) AAsset_getBuffer(asset);
		if((afp->offset + size) <= length)
		{
			memcpy(buffer, assetBuffer + afp->offset, size);
			afp->offset += size;
			//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "... (afp->offset + size) <= length: read %d", size);
			return size;
		}
		else
		{
			int s = (length - afp->offset);
			memcpy(buffer, assetBuffer + afp->offset, s);
			afp->offset += s;
			//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "... (afp->offset + size) > length: read %d", s);
			return s;
		}
	}

	// Seeks to a point in a previously opened file.
	virtual bool Seek(Rocket::Core::FileHandle file, long offset, int origin) {
		AndroidFilePointer* afp = (AndroidFilePointer*) file;
		AAsset* asset = afp->asset;
		off_t length = AAsset_getLength(asset);

		//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Rocket::Core::FileHandle Seek origin: %d offset %d, afp_offset %d...", origin, offset, afp->offset);

		if(SEEK_SET == origin)
		{
			off_t pointer = offset;
			//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "... SEEK_SET == origin %d", pointer);
			if(pointer > length)
				return false;
			if(pointer < 0)
				return false;

			afp->offset = pointer;
			return true;
		}
		else if(SEEK_CUR == origin)
		{
			off_t pointer = afp->offset + offset;
			//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "... SEEK_CUR == origin %d", pointer);
			if(pointer > length)
				return false;
			if(pointer < 0)
				return false;

			afp->offset = pointer;
			return true;
		}
		else
		{
			off_t pointer = length + offset;
			//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "... SEEK_END == origin %d", pointer);
			if(pointer > length)
				return false;
			if(pointer < 0)
				return false;

			afp->offset = pointer;
			return true;
		}
	}

	// Returns the current position of the file pointer.
	virtual size_t Tell(Rocket::Core::FileHandle file)
	{
		AndroidFilePointer* afp = (AndroidFilePointer*) file;
		//__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Rocket::Core::FileHandle Tell Offset %d", afp->offset);
		return afp->offset;
	}

private:
	 AAssetManager* mAssetMgr;
};

#endif

You can use this just with these two lines:

Code: Select all

	mAndroidFileInterface = new AndroidFileInterface(mAssetMgr);
	Rocket::Core::SetFileInterface(mAndroidFileInterface);
Last edited by technique on Wed Jan 29, 2014 9:23 pm, edited 1 time in total.
Image
Kingdoms Defender offers Tower Defense action with breathtaking 3-D graphics for your mobile Android device.

Give it a try:
Free-Version:
http://play.google.com/store/apps/detai ... ender_free

Full-Version:
http://play.google.com/store/apps/detai ... msdefender
User avatar
Argosse
Gnoblar
Posts: 17
Joined: Wed Apr 27, 2011 9:43 pm

Re: [SOLVED] Ogre 1.9 RC1 + Android + libRocket

Post by Argosse »

Would you post your full RenderInterfaceOgre3D.cpp? And the functions you use to initialise libRocket? Ive got everything loaded but nothing displays.
technique
Halfling
Posts: 91
Joined: Fri Oct 22, 2010 10:46 pm
x 8

Re: [SOLVED] Ogre 1.9 RC1 + Android + libRocket

Post by technique »

Sure - dont worry about the reload texture methods in my implementation. You might need them to Resume your app correctly (have a look here -> http://www.ogre3d.org/forums/viewtopic.php?f=21&t=79435)

Code: Select all

/*
 * 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.h>
#include <android/log.h>
#define APPNAME "TEST"

struct RocketOgre3DVertex
{
	float x, y, z;
	Ogre::uint32 diffuse;
	float u, v;
};



// 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();

	Ogre::TextureManager* texture_manager = Ogre::TextureManager::getSingletonPtr();
	mBlankTexture = texture_manager->load("blank.png",
											"Rocket",
											Ogre::TEX_TYPE_2D,
											0);

	// 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;

	mWindowWidth = window_width;
	mWindowHeight = window_height;

	CreateShader();
}

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(vertices), int ROCKET_UNUSED(num_vertices), int* ROCKET_UNUSED(indices), int ROCKET_UNUSED(num_indices), Rocket::Core::TextureHandle ROCKET_UNUSED(texture), const Rocket::Core::Vector2f& 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_16BIT, num_indices, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);
	geometry->render_operation.indexData->indexBuffer = index_buffer;
	geometry->render_operation.useIndexes = true;

	// Fill the index buffer.
	uint16_t* ogre_indices = (uint16_t*) index_buffer->lock(0, index_buffer->getSizeInBytes(), Ogre::HardwareBuffer::HBL_NORMAL);
	for (int i = 0; i < num_indices; ++i)
	{
		ogre_indices[i] = indices[i];
	}
	index_buffer->unlock();;


	return reinterpret_cast<Rocket::Core::CompiledGeometryHandle>(geometry);
}

void RenderInterfaceOgre3D::CreateShader()
{
	mVertexProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram("SimpleTexturingNoLightsVP",
																				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
																				"glsles",
																				Ogre::GPT_VERTEX_PROGRAM);
	mVertexProgram->setSourceFile( "SimpleTexturingNoLightsVP.glsles" );
	mVertexProgram->load();
	mVertexProgramParams = mVertexProgram->createParameters();

	mFragmentProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram("SimpleTexturingNoLightsFP",
																				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
																				"glsles",
																				Ogre::GPT_FRAGMENT_PROGRAM);
	mFragmentProgram->setSourceFile( "SimpleTexturingNoLightsFP.glsles" );
	mFragmentProgram->load();
	mFragmentProgramParams = mFragmentProgram->createParameters();
}


// Called by Rocket when it wants to render application-compiled geometry.
void RenderInterfaceOgre3D::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation)
{
	render_system = Ogre::Root::getSingleton().getRenderSystem();
	Ogre::Matrix4 transform;
	transform.makeTrans(translation.x, translation.y, 0);
	render_system->_setWorldMatrix(transform);

	Ogre::Matrix4 projection_matrix;
	BuildProjectionMatrix(projection_matrix);
	mVertexProgramParams->setNamedConstant("worldViewProj", projection_matrix * transform);
	render_system->bindGpuProgramParameters(Ogre::GPT_VERTEX_PROGRAM, mVertexProgramParams, Ogre::GPV_ALL);

	RocketOgre3DCompiledGeometry* ogre3d_geometry = (RocketOgre3DCompiledGeometry*) geometry;

	if (ogre3d_geometry->texture != NULL)
	{
		render_system->_setTexture(0, true, ogre3d_geometry->texture->texture);	// Disable depth bias.
		render_system->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_POINT);

		// 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->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_POINT);	// Disable depth bias.
		render_system->_setTexture( 0, true, mBlankTexture);

		//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)
{

	int pos = source.RFind("/");
	pos++;
	Rocket::Core::String fileName(source.Substring(pos));

	__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "TEXTURE LOAD %s", fileName.CString());
	Ogre::TextureManager* texture_manager = Ogre::TextureManager::getSingletonPtr();
	Ogre::TexturePtr ogre_texture = texture_manager->getByName(Ogre::String(fileName.CString()));
	if (ogre_texture.isNull())
	{
		ogre_texture = texture_manager->load(Ogre::String(fileName.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;
}

void RenderInterfaceOgre3D::reloadFontTexture()
{
	for(int i = 0; i < mBackupFontTextures.size(); i++)
	{
		FontTextureBackup* t = mBackupFontTextures.at(i);

		Ogre::TextureManager::getSingleton().remove(t->mRocketTexture->texture->getName());

		Ogre::DataStreamPtr stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream((void*) mBackupFontTextures.at(i)->mSource,
				mBackupFontTextures.at(i)->mSourceDimensions.x * mBackupFontTextures.at(i)->mSourceDimensions.y * sizeof(unsigned int)));

		__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "RELOAD TEXTURE %c", t->mName.CString());

		Ogre::TexturePtr ogre_texture = Ogre::TextureManager::getSingleton().loadRawData(mBackupFontTextures.at(i)->mName.CString(),
																						 "Rocket",
																						 stream,
																						 (unsigned short)(mBackupFontTextures.at(i)->mSourceDimensions.x),
																						 (unsigned short)(mBackupFontTextures.at(i)->mSourceDimensions.y),
																						 Ogre::PF_A8B8G8R8,
																						 Ogre::TEX_TYPE_2D,
																						 0);

		t->mRocketTexture->texture = ogre_texture;


		/*
		Ogre::TextureManager::getSingleton().remove(mBackupFontTextures.at(i)->mName.CString());

		Ogre::DataStreamPtr stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream((void*) mBackupFontTextures.at(i)->mSource,
				mBackupFontTextures.at(i)->mSourceDimensions.x * mBackupFontTextures.at(i)->mSourceDimensions.y * sizeof(unsigned int)));


																						 */
	}
}

// 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::DataStreamPtr stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream((void*) source, source_dimensions.x * source_dimensions.y * sizeof(unsigned int)));

	Rocket::Core::String name = Rocket::Core::String(16, "%d", texture_id++);

	Ogre::TexturePtr ogre_texture = Ogre::TextureManager::getSingleton().loadRawData(name.CString(),
																					 "Rocket",
																					 stream,
																					 (unsigned short)(source_dimensions.x),
																					 (unsigned short)(source_dimensions.y),
																					 Ogre::PF_A8B8G8R8,
																					 Ogre::TEX_TYPE_2D,
																					 0);

	if (ogre_texture.isNull())
	{
		__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "TEXTURE GENERATE FAILED");
		return false;
	}

	FontTextureBackup* backup = new FontTextureBackup();
	backup->mSource = (Rocket::Core::byte*) malloc(source_dimensions.x * source_dimensions.y * sizeof(unsigned int));
	memcpy(backup->mSource, source, source_dimensions.x * source_dimensions.y * sizeof(unsigned int));
	backup->mName = name;
	backup->mSourceDimensions = source_dimensions;
	backup->mRocketTexture = new RocketOgre3DTexture(ogre_texture);
	mBackupFontTextures.push_back(backup);

	__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "TEXTURE GENERATE DONE %d", mBackupFontTextures.size());
	texture_handle = reinterpret_cast<Rocket::Core::TextureHandle>(backup->mRocketTexture);
	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();
}

// Builds an OpenGL-style orthographic projection matrix.
void RenderInterfaceOgre3D::BuildProjectionMatrix(Ogre::Matrix4& projection_matrix)
{
	float z_near = -1;
	float z_far = 1;

	projection_matrix = Ogre::Matrix4::ZERO;

	// Set up matrices.
	projection_matrix[0][0] = 2.0f / (float) mWindowWidth;
	projection_matrix[0][3]= -1.0000000f;
	projection_matrix[1][1]= -2.0f / (float) mWindowHeight;
	projection_matrix[1][3]= 1.0000000f;
	projection_matrix[2][2]= -2.0f / (z_far - z_near);
	projection_matrix[3][3]= 1.0000000f;
}

Image
Kingdoms Defender offers Tower Defense action with breathtaking 3-D graphics for your mobile Android device.

Give it a try:
Free-Version:
http://play.google.com/store/apps/detai ... ender_free

Full-Version:
http://play.google.com/store/apps/detai ... msdefender
sabotage3d
Gnoblar
Posts: 15
Joined: Sun Jul 20, 2014 10:01 pm

Re: [SOLVED] Ogre 1.9 RC1 + Android + libRocket

Post by sabotage3d »

Hey guys,
Any chance someone to share a really simple working code. I was trying your samples under IOS and I am running into series of crashes, which are hard to debug. If someone can upload a really simple button template would be great.

Thanks in advance,
Alex
rraallvv
Gnoblar
Posts: 7
Joined: Sat Jul 27, 2013 9:10 am

Re: [SOLVED] Ogre 1.9 RC + Android + libRocket

Post by rraallvv »

rhaith wrote:To those interested I had this problem too and solved it. I wrote a small article on it with source code to download to get libRocket working on android and iOS.

http://www.manicnorth.com/devblog/1/
The page was removed, I've found this other post (presumably from the same author)

http://manicnorth.com/librocket/

This is what I did:

- I added the files rocket_fp.glsl, rocket_fp.glsles, rocket_vp.glsl, rocket_vp.glsles, and rocket.program to the .blend file, as scripts, each with the same name that the unpacked file, and them packed them in the blend file.
- Replaced the files RenderInterfaceOgre3D.cpp and RenderInterfaceOgre3D.h in Ogre's source
- I'm not using UIManager.cpp and UIManager.h but the render listener that came with Ogre, i.e. RocketRenderListener.cpp and RocketRenderListener.h.

The problem is that the shaders are not loaded in RenderInterfaceOgre3D.cpp, and the app crashes:

Code: Select all

Ogre::GpuProgramPtr vpShader = Ogre::HighLevelGpuProgramManager::getSingletonPtr()->getByName( "RocketVP" ); // <-- this fails
Ogre::GpuProgramPtr fpShader = Ogre::HighLevelGpuProgramManager::getSingletonPtr()->getByName( "RocketFP" ); // <-- this too

// ....

Ogre::GpuProgramParametersSharedPtr params = vpShader->getDefaultParameters(); // <-- this crashes
Also I don't know whether that is the proper way to add the shaders to the project; just by adding them as text scripts.

Any help or comment is appreciated.
gavrus
Gnoblar
Posts: 3
Joined: Fri Sep 23, 2016 5:54 pm

Re: [SOLVED] Ogre 1.9 RC1 + Android + libRocket

Post by gavrus »

Post Reply