Skip to content

Instantly share code, notes, and snippets.

@rgngl
Created June 16, 2013 21:54
Show Gist options
  • Save rgngl/5793585 to your computer and use it in GitHub Desktop.
Save rgngl/5793585 to your computer and use it in GitHub Desktop.
libRocket and GamePlay3D integration
#include "rocketgp3dtest.h"
// Declare our game instance
rocketgp3dtest game;
rocketgp3dtest::rocketgp3dtest()
: _scene(NULL)
{
}
void rocketgp3dtest::initialize()
{
// Load game scene from file
_scene = Scene::load("res/box.gpb");
// Set the aspect ratio for the scene's camera to match the current resolution
_scene->getActiveCamera()->setAspectRatio(getAspectRatio());
// Get light node
Node* lightNode = _scene->findNode("directionalLight");
Light* light = lightNode->getLight();
// Initialize box model
Node* boxNode = _scene->findNode("box");
Model* boxModel = boxNode->getModel();
Material* boxMaterial = boxModel->setMaterial("res/box.material");
boxMaterial->getParameter("u_ambientColor")->setValue(_scene->getAmbientColor());
boxMaterial->getParameter("u_lightColor")->setValue(light->getColor());
boxMaterial->getParameter("u_lightDirection")->setValue(lightNode->getForwardVectorView());
initializeRocket();
}
void rocketgp3dtest::initializeRocket()
{
Rocket::Core::SetFileInterface(&_fileInterface);
Rocket::Core::SetRenderInterface(&_renderInterface);
Rocket::Core::SetSystemInterface(&_systemInterface);
Rocket::Core::Initialise();
_rocketContext = Rocket::Core::CreateContext("main",
Rocket::Core::Vector2i(getWidth(), getHeight()));
Rocket::Core::String font_names[4];
font_names[0] = "Delicious-Roman.otf";
font_names[1] = "Delicious-Italic.otf";
font_names[2] = "Delicious-Bold.otf";
font_names[3] = "Delicious-BoldItalic.otf";
for (int i = 0; i < sizeof(font_names) / sizeof(Rocket::Core::String); i++)
{
Rocket::Core::FontDatabase::LoadFontFace(font_names[i]);
}
Rocket::Core::ElementDocument* document = _rocketContext->LoadDocument("test.rml");
document->Show();
document->RemoveReference();
}
void rocketgp3dtest::finalize()
{
SAFE_RELEASE(_scene);
_rocketContext->RemoveReference();
}
void rocketgp3dtest::update(float elapsedTime)
{
// Rotate model
_scene->findNode("box")->rotateY(MATH_DEG_TO_RAD((float)elapsedTime / 1000.0f * 180.0f));
_rocketContext->Update();
}
void rocketgp3dtest::render(float elapsedTime)
{
// Clear the color and depth buffers
clear(CLEAR_COLOR_DEPTH, Vector4::zero(), 1.0f, 0);
// Visit all the nodes in the scene for drawing
_scene->visit(this, &rocketgp3dtest::drawScene);
_rocketContext->Render();
}
bool rocketgp3dtest::drawScene(Node* node)
{
// If the node visited contains a model, draw it
Model* model = node->getModel();
if (model)
{
model->draw();
}
return true;
}
void rocketgp3dtest::keyEvent(Keyboard::KeyEvent evt, int key)
{
if (evt == Keyboard::KEY_PRESS)
{
switch (key)
{
case Keyboard::KEY_ESCAPE:
exit();
break;
}
}
}
void rocketgp3dtest::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
switch (evt)
{
case Touch::TOUCH_PRESS:
break;
case Touch::TOUCH_RELEASE:
break;
case Touch::TOUCH_MOVE:
break;
};
}
#ifndef TEMPLATEGAME_H_
#define TEMPLATEGAME_H_
#include "gameplay.h"
#include "RocketInterfaces.h"
#include <Rocket/Core.h>
using namespace gameplay;
/**
* Main game class.
*/
class rocketgp3dtest: public Game
{
public:
/**
* Constructor.
*/
rocketgp3dtest();
/**
* @see Game::keyEvent
*/
void keyEvent(Keyboard::KeyEvent evt, int key);
/**
* @see Game::touchEvent
*/
void touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
protected:
/**
* @see Game::initialize
*/
void initialize();
void initializeRocket();
/**
* @see Game::finalize
*/
void finalize();
/**
* @see Game::update
*/
void update(float elapsedTime);
/**
* @see Game::render
*/
void render(float elapsedTime);
private:
/**
* Draws the scene each frame.
*/
bool drawScene(Node* node);
Scene* _scene;
RocketGP3DFile _fileInterface;
RocketGP3DSystem _systemInterface;
RocketGP3Render _renderInterface;
Rocket::Core::Context *_rocketContext;
};
#endif
//
// RocketInterfaces.cpp
// rocketgp3dtest
//
// Created by Ustun Ergenoglu on 6/13/13.
//
//
#include "RocketInterfaces.h"
#include <string.h>
using namespace gameplay;
using namespace Rocket::Core;
#define GP3D_ROCKET_ASSETS_PREFIX "res/rocket/"
// ********** File Interface
FileHandle RocketGP3DFile::Open(const Rocket::Core::String &path)
{
std::string s(GP3D_ROCKET_ASSETS_PREFIX);
s.append(path.CString());
gameplay::Stream *stream = FileSystem::open(s.c_str());
return (FileHandle)stream;
}
void RocketGP3DFile::Close(Rocket::Core::FileHandle file)
{
gameplay::Stream *stream;
stream = (gameplay::Stream*)file;
stream->close();
delete stream;
}
size_t RocketGP3DFile::Read(void *buffer,
size_t size,
FileHandle file)
{
size_t s;
gameplay::Stream *stream;
stream = (gameplay::Stream*)file;
s = stream->read(buffer, 1, size);
return s;
}
bool RocketGP3DFile::Seek(FileHandle file,
long offset, int origin)
{
gameplay::Stream *stream;
stream = (gameplay::Stream*)file;
return stream->seek(offset, origin);
}
size_t RocketGP3DFile::Tell(FileHandle file)
{
gameplay::Stream *stream;
stream = (gameplay::Stream*)file;
return stream->position();
}
// ********** System Interface
float RocketGP3DSystem::GetElapsedTime()
{
return (float)Game::getAbsoluteTime();
}
// ********** Render Interface
void RocketGP3Render::RenderGeometry(Rocket::Core::Vertex *vertices,
int num_vert, int *ind, int num_ind,
Rocket::Core::TextureHandle texture,
const Rocket::Core::Vector2f &translation)
{
float width = Game::getInstance()->getWidth();
float height = Game::getInstance()->getHeight();
Model *model = createModel(vertices, num_vert, ind, num_ind, texture);
Matrix proj;
Matrix::createOrthographicOffCenter(0, width, height, 0, -1, 1, &proj);
proj.translate(translation.x, translation.y, 0.0f);
model->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(proj);
model->draw();
model->release();
}
CompiledGeometryHandle RocketGP3Render::CompileGeometry(Rocket::Core::Vertex *vertices,
int num_vert,
int *ind, int num_ind,
Rocket::Core::TextureHandle texture)
{
Model *model = createModel(vertices, num_vert, ind, num_ind, texture);
return (CompiledGeometryHandle)model;
}
void RocketGP3Render::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry,
const Rocket::Core::Vector2f &translation)
{
float width = Game::getInstance()->getWidth();
float height = Game::getInstance()->getHeight();
Matrix proj;
Matrix::createOrthographicOffCenter(0, width, height, 0, -1, 1, &proj);
proj.translate(translation.x, translation.y, 0.0f);
Model *model = (Model*)geometry;
model->getMaterial()->getParameter("u_worldViewProjectionMatrix")->setValue(proj);
model->draw();
}
void RocketGP3Render::ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry)
{
Model *model = (Model*)geometry;
model->release();
}
void RocketGP3Render::EnableScissorRegion(bool enable)
{
if (enable) {
glEnable(GL_SCISSOR_TEST);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
void RocketGP3Render::SetScissorRegion(int x, int y, int width, int height)
{
glScissor(x, y, width, height);
}
bool RocketGP3Render::LoadTexture(Rocket::Core::TextureHandle &texture_handle,
Rocket::Core::Vector2i &texture_dimensions,
const Rocket::Core::String &source)
{
std::string s(GP3D_ROCKET_ASSETS_PREFIX);
s.append(source.CString());
gameplay::Image *image = gameplay::Image::create(s.c_str());
gameplay::Texture *tex = gameplay::Texture::create(image);
texture_dimensions.x = tex->getWidth();
texture_dimensions.y = tex->getHeight();
texture_handle = (Rocket::Core::TextureHandle)gameplay::Texture::Sampler::create(tex);
SAFE_RELEASE(tex);
return (texture_handle != 0);
}
bool RocketGP3Render::GenerateTexture(Rocket::Core::TextureHandle &texture_handle,
const Rocket::Core::byte *source,
const Rocket::Core::Vector2i &source_dimensions)
{
//gameplay::Texture::create doesn't have a const qualifier for the data
//buffer. So, here's a workaround.
unsigned char *src = const_cast<unsigned char*>(source);
gameplay::Texture *tex = gameplay::Texture::create(gameplay::Texture::RGBA,
source_dimensions.x,
source_dimensions.y,
(unsigned char*)src, true);
texture_handle = (Rocket::Core::TextureHandle)gameplay::Texture::Sampler::create(tex);
SAFE_RELEASE(tex);
return (texture_handle != 0);
}
void RocketGP3Render::ReleaseTexture(Rocket::Core::TextureHandle texture_handle)
{
gameplay::Texture::Sampler *sampler = (gameplay::Texture::Sampler*)texture_handle;
sampler->release();
}
static Properties *materialProperties = NULL;
static Properties* getMaterialProperties()
{
if (!materialProperties) {
materialProperties = Properties::create("res/rocketui.material#rocketui");
}
materialProperties->rewind();
return materialProperties;
}
Model* RocketGP3Render::createModel(Rocket::Core::Vertex *vertices, int num_vert,
int *ind, int num_ind,
Rocket::Core::TextureHandle texture)
{
gameplay::Texture::Sampler *sampler = (gameplay::Texture::Sampler*)texture;
//Create mesh
VertexFormat::Element elements[3];
elements[0] = VertexFormat::Element(VertexFormat::POSITION, 2);
elements[1] = VertexFormat::Element(VertexFormat::COLOR, 4);
elements[2] = VertexFormat::Element(VertexFormat::TEXCOORD0, 2);
float *vertexData = new float[num_vert * 8];
for (int i = 0; i < num_vert; ++i) {
float *vd = vertexData + 8*i;
vd[0] = vertices[i].position.x;
vd[1] = vertices[i].position.y;
vd[2] = (float)vertices[i].colour.red / 255.0f;
vd[3] = (float)vertices[i].colour.green / 255.0f;
vd[4] = (float)vertices[i].colour.blue / 255.0f;
vd[5] = (float)vertices[i].colour.alpha / 255.0f;
vd[6] = vertices[i].tex_coord.x;
vd[7] = vertices[i].tex_coord.y;
}
VertexFormat format(elements, 3);
Mesh* mesh = Mesh::createMesh(format, num_vert);
mesh->setVertexData(vertexData);
MeshPart* part = mesh->addPart(Mesh::TRIANGLES,
Mesh::INDEX32, num_ind);
part->setIndexData(ind, 0, num_ind);
Model* model = Model::create(mesh);
mesh->release();
Properties *mp = getMaterialProperties();
Material *material = Material::create(getMaterialProperties());
material->getParameter("u_diffuseTexture")->setValue(sampler);
model->setMaterial(material);
material->release();
delete [] vertexData;
return model;
}
//
// RocketInterfaces.h
// rocketgp3dtest
//
// Created by Ustun Ergenoglu on 6/13/13.
//
//
#ifndef __rocketgp3dtest__RocketInterfaces__
#define __rocketgp3dtest__RocketInterfaces__
#include <Rocket/Core.h>
#include <gameplay.h>
class RocketGP3DFile : public Rocket::Core::FileInterface {
public:
Rocket::Core::FileHandle Open(const Rocket::Core::String& path);
// Closes a previously opened file.
void Close(Rocket::Core::FileHandle file);
// Reads data from a previously opened file.
size_t Read(void* buffer, size_t size, Rocket::Core::FileHandle file);
// Seeks to a point in a previously opened file.
bool Seek(Rocket::Core::FileHandle file, long offset, int origin);
// Returns the current position of the file pointer.
size_t Tell(Rocket::Core::FileHandle file);
};
class RocketGP3DSystem : public Rocket::Core::SystemInterface {
public:
float GetElapsedTime();
};
class RocketGP3Render : public Rocket::Core::RenderInterface {
public:
void RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices,
int* indices, int num_indices,
Rocket::Core::TextureHandle texture,
const Rocket::Core::Vector2f& translation);
// Called by Rocket when it wants to compile geometry it believes will be
// static for the forseeable future.
Rocket::Core::CompiledGeometryHandle
CompileGeometry(Rocket::Core::Vertex* vertices,
int num_vert, int* ind, int num_ind,
Rocket::Core::TextureHandle texture);
// Called by Rocket when it wants to render application-compiled geometry.
void RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry,
const Rocket::Core::Vector2f& translation);
// Called by Rocket when it wants to release application-compiled geometry.
void ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry);
// Called by Rocket when it wants to enable or disable scissoring to clip
// content.
void EnableScissorRegion(bool enable);
// Called by Rocket when it wants to change the scissor region.
void SetScissorRegion(int x, int y, int width, int height);
// Called by Rocket when a texture is required by the library.
bool LoadTexture(Rocket::Core::TextureHandle& texture_handle,
Rocket::Core::Vector2i& texture_dimensions,
const Rocket::Core::String& source);
// Called by Rocket when a texture is required to be built from an
// internally-generated sequence of pixels.
bool GenerateTexture(Rocket::Core::TextureHandle& texture_handle,
const Rocket::Core::byte* source,
const Rocket::Core::Vector2i& source_dimensions);
// Called by Rocket when a loaded texture is no longer required.
void ReleaseTexture(Rocket::Core::TextureHandle texture_handle);
private:
gameplay::Model* createModel(Rocket::Core::Vertex *vertices, int num_vert,
int *ind, int num_ind,
Rocket::Core::TextureHandle texture);
};
#endif /* defined(__rocketgp3dtest__RocketInterfaces__) */
#ifdef OPENGL_ES
precision highp float;
#endif
// Uniforms
uniform sampler2D u_diffuseTexture; // Diffuse texture
#if defined(MODULATE_COLOR)
uniform vec4 u_modulateColor; // Modulation color
#endif
#if defined(MODULATE_ALPHA)
uniform float u_modulateAlpha; // Modulation alpha
#endif
// Varyings
varying vec2 v_texCoord0; // Texture coordinate(u, v)
#if defined(VERTEX_COLOR)
varying vec3 v_color; // Input Vertex color ( r g b )
#endif
void main()
{
// Sample the texture for the color
gl_FragColor = texture2D(u_diffuseTexture, v_texCoord0);
#if defined(VERTEX_COLOR)
// gl_FragColor = gl_FragColor * vec4(v_color, 1.0);
#endif
// Global color modulation
#if defined(MODULATE_COLOR)
gl_FragColor *= u_modulateColor;
#endif
#if defined(MODULATE_ALPHA)
gl_FragColor.a *= u_modulateAlpha;
#endif
gl_FragColor.a = texture2D(u_diffuseTexture, v_texCoord0).a;
// gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
material rocketui
{
technique
{
pass
{
// shaders
vertexShader = res/shaders/rocketui.vert
fragmentShader = res/shaders/rocketui.frag
defines = VERTEX_COLOR
// render state
renderState
{
cullFace = false
depthWrite = false
depthTest = false
blend = true
blendSrc = SRC_ALPHA
blendDst = ONE_MINUS_SRC_ALPHA
}
}
}
}
// Attributes
attribute vec4 a_position; // Vertex Position (x, y, z, w)
attribute vec2 a_texCoord0; // Vertex Texture Coordinate (u, v)
#if defined(TEXCOORD1)
attribute vec2 a_texCoord1; // Second tex coord for multi-texturing
#endif
#if defined(SKINNING)
attribute vec4 a_blendWeights; // Vertex blend weight, up to 4 (0, 1, 2, 3)
attribute vec4 a_blendIndices; // Vertex blend index int u_matrixPalette (0, 1, 2, 3)
#endif
#if defined(VERTEX_COLOR)
attribute vec3 a_color; // Output Vertex Color
varying vec3 v_color; // Output Vertex Color
#endif
// Uniforms
uniform mat4 u_worldViewProjectionMatrix; // Matrix to transform a position to clip space
#if defined(TEXTURE_REPEAT)
uniform vec2 u_textureRepeat; // Texture repeat for tiling
#endif
#if defined(TEXTURE_OFFSET)
uniform vec2 u_textureOffset; // Texture offset
#endif
// Varyings
varying vec2 v_texCoord0; // Texture Coordinate
#include "skinning-none.vert"
void main()
{
// Get the vertex position
vec4 position = getPosition();
// Transform position to clip space.
gl_Position = u_worldViewProjectionMatrix * position;
// Texture transformation.
v_texCoord0 = a_texCoord0;
#if defined(TEXTURE_REPEAT)
v_texCoord0 *= u_textureRepeat;
#endif
#if defined(TEXTURE_OFFSET)
v_texCoord0 += u_textureOffset;
#endif
// Pass on vertex color to fragment shader
#if defined(VERTEX_COLOR)
v_color = a_color;
#endif
}
body
{
font-family: Delicious;
font-weight: normal;
font-style: normal;
font-size: 15;
color: white;
}
body.window
{
background-decorator: tiled-box;
background-top-left-image: invader.png 0px 0px 133px 140px;
background-top-right-image: invader.png 136px 0px 146px 140px;
background-top-image: invader.png stretch 134px 0px 135px 140px;
background-bottom-left-image: invader.png 0px 140px 11px 151px;
background-bottom-right-image: invader.png 136px 140px 146px 151px;
background-bottom-image: invader.png stretch 11px 140px 12px 151px;
background-left-image: invader.png stretch 0px 139px 10px 140px;
background-center-image: invader.png stretch 11px 139px 12px 140px;
padding: 10px 15px;
}
div
{
display: block;
}
div#title-bar span
{
padding-left: 85px;
padding-right: 25px;
padding-top: 17px;
padding-bottom: 48px;
font-size: 22;
font-weight: bold;
text-shadow: 2px 2px black;
background-decorator: tiled-horizontal;
background-left-image: test.png 147px 0px 229px 85px;
background-center-image: test.png stretch 229px 0px 230px 85px;
background-right-image: test.png 231px 0px 246px 85px;
}
div#title-bar
{
position: absolute;
top: -10px;
}
div#content
{
z-index: 1;
overflow: auto;
height: 100%;
}
scrollbarvertical
{
width: 27px;
}
scrollbarvertical slidertrack
{
background-decorator: tiled-vertical;
background-top-image: test.png 56px 199px 83px 201px;
background-center-image: test.png stretch 56px 201px 83px 202px;
background-bottom-image: test.png 56px 203px 83px 204px;
}
scrollbarvertical sliderbar
{
width: 23px;
background-decorator: tiled-vertical;
background-top-image: test.png 56px 152px 79px 175px;
background-center-image: test.png stretch 56px 175px 79px 175px;
background-bottom-image: test.png 56px 176px 79px 198px;
}
scrollbarvertical sliderarrowdec,
scrollbarvertical sliderarrowinc
{
width: 27px;
height: 24px;
}
scrollbarvertical sliderarrowdec
{
icon-decorator: image;
icon-image: test.png 0px 152px 27px 176px;
}
scrollbarvertical sliderarrowinc
{
icon-decorator: image;
icon-image: test.png 28px 152px 55px 176px;
}
<rml>
<head>
<link type="text/css" href="test.rcss"/>
<title>Window</title>
<style>
body
{
width: 80%;
height: 80%;
margin: auto;
}
</style>
</head>
<body class="window">
<div id="title-bar">
<span id="title">Dummy Title</span>
</div>
<div id="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
</body>
</rml>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment