31 October 2012

Tutorial 2: Specifying GUI (part 1)

In this tutorial we build upon Tutorial 1 to create a more complex graphical user interface using the Tinia framework.

Familiarity with basic OpenGL and C++ with object orientation is assumed.

The program created in this tutorial will run both as a desktop program and as a server/client program.

The program consists of three files: The Job class definition and two main files. One main file will be created for the desktop program, and one for the web program. We will only highlight changes from Tutorial 1, so it's a good idea to brush up on that tutorial before reading this one.

GUI through Tinia


The ExposedModel class has the method setGUILayout which is used to specify how we want our GUI to look.

In the eyes of the model, a GUI is just a tree of widget types defined in the namespace tinia::model::gui. Every GUI starts with a root element. A root element can be any widget type, but it's usually one of the container widgets HorizontalLayout, VerticalLayout, Grid or TabLayout.

Altering Tutorial 1

We'd like to modify Tutorial 1 such that it only contains an OpenGL canvas. First we need to specify the root element, which we choose to be a VerticalLayout. We make our GUI in the constructor of Tutorial2Job. All GUI elements in the model are represented as pointers, so we do this as well.

The creation of the VerticalLayout is really simple:
    auto layout = new tinia::model::gui::VerticalLayout();
An OpenGL canvas is represented by a Canvas element. The constructor takes the key to the Viewer as the first value.
    auto canvas = new tinia::model::gui::Canvas("myViewer");
In the previous tutorial we relied on the fact that Tinia defaults the boundingbox key to "boundingbox", but it's good practice to specify this manually to the Canvas. This is done with the following line
    canvas->boundingBoxKey("boundingbox");
Once we've made our new Canvas it's just the simple matter of adding it to the VerticalLayout
    layout->addChild(canvas);
Finally we set our layout as the GUI to the model. Notice how the second argument is tinia::model::gui::ALL which indicates that the GUI can be used for all types of devices (desktops, mobile devices, tablets):
    m_model->setGUILayout(layout, tinia::model::gui::ALL);
The rest of the program is left unchanged. The whole Tutorial2_Job.hpp is then
#pragma once
#include <tinia/tinia.hpp>
#include <GL/glew.h>
namespace tinia { namespace tutorial {
class Tutorial2Job : public tinia::jobcontroller::OpenGLJob {
public:
    Tutorial2Job();
    bool renderFrame( const std::string &session,
                      const std::string &key,
                      unsigned int fbo,
                      const size_t width,
                      const size_t height );
};
Tutorial2Job::Tutorial2Job()
{
    m_model->addElement( "myViewer", tinia::model::Viewer() );
    m_model->addElement("boundingbox", "0 0 0 1 1 1");
    auto layout = new tinia::model::gui::VerticalLayout();
    auto canvas = new tinia::model::gui::Canvas("myViewer");
    canvas->boundingBoxKey("boundingbox");
    layout->addChild(canvas);
    m_model->setGUILayout(layout, tinia::model::gui::ALL);
}
bool Tutorial2Job::renderFrame( const std::string &session,
                                const std::string &key,
                                unsigned int fbo,
                                const size_t width,
                                const size_t height )
{
    tinia::model::Viewer viewer;
    m_model->getElementValue("myViewer", viewer);
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(viewer.modelviewMatrix.data());
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(viewer.projectionMatrix.data());
    glClearColor(0, 0, 0 ,0 );
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, width, height);
    glBegin(GL_TRIANGLES);
    glColor3f(1, 0, 0);
    glVertex2f(0, 0);
    glVertex2f(1, 0);
    glVertex2f(1, 1);
    glEnd();
    return true;
}
} // of tutorial
} // of tinia

Ownership of the GUI


The observant reader might have noticed that we don't delete the GUI pointers we've made in the tutorial. By design, the ExposedModel takes ownership of the GUI pointers and deletes them upon destruction.

Running the desktop program


Starting the program should show something similar to this:


Running the web program

If you've successfully installed Tinia you should be able to run the web program as tutorial2_web through the mod_trell web interface.

The program should look something like this:


No comments:

Post a Comment