wissen.leben | WWU Münster 


Basic tgt Example

Overview

This tutorial will explain the default design for tgt applications. tgt provides abstraction from the underlying toolkit used for window management and user interaction. When keeping to the application layout descibed here, one will produce program code than can be compiled as a GLUT, a SDL or a Qt application.

More complex programs will lay down one of these toolkits (Qt most likely), dissociate form the design paradicms explained here and lose the toolkit compability to make extensive use of the features of the chosen toolkit. Functions provided by classes as GuiApplication will then be reimplemented within the application.

But as long as the application layout introduced in this tutorial suffis, we recommend to keep to this scheme for tgt programs.

Structure of standard tgt Applications

Our application is based on five tgt classes: GuiApplication, GLCavas, EventHandler, Painter and EventListener. The first three will be used as implemented in tgt, the latter two will be base classes the user derives from to override some methods. The first three form a framework to support the functions the classes derived from the latter two will provide. Our first example will not handle the event classes, they will be introduced in the events tutorial.

Example

includes

One could include tgt header files by just using
#include <tgt/tgt.h>

As this would include all header files of tgt, we disadvise to use it that way. It might be used quick and dirty for testing purposes or so. We recommend to include the header files needed in your program seperately.

#include <tgt/guiapplication.h>
#include <tgt/quadric.h>
#include <tgt/toolkitfactory.h>
#include <tgt/painter.h>

Painter

The tgt::Painter class represents the object acutally rendering something. The user derives his own class from tgt::Painter overriding the paint(), init() and sizeChanged() methods.

class MyPainter : public Painter {
public:
    MyPainter(GLCanvas* canvas) : Painter(canvas) {}
    virtual void paint();
    virtual void sizeChanged(const ivec2& size);
    virtual void init();
};

void MyPainter::paint() {
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    getCamera()->look();
    glColor3f(1.f, 0.f, 0.f);
    Sphere sphere(1.f, 64, 32);
    sphere.render();
}

void MyPainter::sizeChanged(const ivec2& size) {
    glViewport(0, 0, size.x, size.y);
}

void MyPainter::init() {
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    getCamera()->setPosition(vec3(0.f,0.f,2.f));
}

In our example, we derive class MyPainter from tgt::Painter. paint() is the method that will be called whenever the canvas is redisplaied. If not explizitly disabled, front- and backbuffer will be swapped automatically after execution of paint() method (in single buffer mode, glFlush() would be called). Our paint method simply clears the canvas and paints a red sphere.

The init()-method is called when the associated canvas gets initialized and in meant to prepares our OpenGL context. In our example, we also position our camera object in addition to setting up the OpenGl context.

The sizeChanged() method gets executed when the size of the canvas the painter belongs to changes. This gives to the painter the opportunity to adapt it’s rendering to the new size. in our case, we simply adapt the viewport. In further examples, we will also adapt to the new aspect ratio within this method.

main-Method

int main(int argc, char** argv) {
    GuiApplication* tgtApp = ToolkitFactory::createApplication(argc, argv);

    GLCanvas* canvas = ToolkitFactory::createCanvas("tgt Example: Minimal");
    tgtApp->addCanvas(canvas);

    tgtApp->init();

    Camera camera;
    canvas->setCamera(&camera);
    MyPainter painter(canvas);
    canvas->setPainter(&painter);

    tgtApp->run();

    delete canvas;
    delete tgtApp;

    return 0;
}

The tgt::ToolkitFactory provides methodes to create objects which depend on a certain toolkit. Which toolkit to use can be chosen at compile time.

We have one GuiApplication object and at least one GLCanvas object – both represented by toolkit-specific child classes – which together form the base of our application.

The GuiApplication object takes care of the program run. It manages which tgt features to use and initializes many of them, if they need to. It also manages the canvases, and it provides the main loop our tgt program runs.

A GLCanvas represents a area on the screen where OpenGL content is rendered. In most cases, a canvas is a window. Every Canvas has it’s own OpenGL context.

Note: SDL toolkit supports only one canvas at a time.

In our main method, we simply create a GuiApplication and a GLCanvas and register the Canvas at the Application. Then we create a camera and a MyPainter object and associate both with our canvas. Then we enter our programs main loop.

Note: GLUT-Applications will not return from the mainloop. The last three lines of code of the main method will not be executed when our program is compiled and executed as a GLUT application.

The camera object provides a comfortable way to manipulate and apply a view matrix. We will have a closer look to the camera object within the navigation tutorial.

Complete source code


samples/minimal.cpp
#include "tgt/guiapplication.h"
#include "tgt/quadric.h"
#include "tgt/toolkitfactory.h"
#include "tgt/painter.h"

using namespace tgt;

class MyPainter : public Painter {
public:
    MyPainter(GLCanvas* canvas)
      : Painter(canvas)
    {}

    virtual void paint();
    virtual void sizeChanged(const ivec2& size);
    virtual void init();
};

void MyPainter::paint() {
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    getCamera()->look();

    glColor3f(1.f, 0.f, 0.f);

    Sphere sphere(1.f, 64, 32);
    sphere.render();
}

void MyPainter::sizeChanged(const ivec2& size) {
    glViewport(0, 0, size.x, size.y);
}

void MyPainter::init() {
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    getCamera()->setPosition(vec3(0.f,0.f,2.f));
}

int main(int argc, char** argv) {
    std::cout
        << "tgt Sample Program: minimal" << std::endl
        << std::endl
        << "A minimal example displaying a simple red sphere on black ground to show how tgt" << std::endl
        << "is used." << std::endl
        << std::endl;

    // build a tgt app with the desired gui toolkit
    GuiApplication* tgtApp = ToolkitFactory::createApplication(argc, argv);

    GLCanvas* canvas = ToolkitFactory::createCanvas("tgt Example: Minimal");
    tgtApp->addCanvas(canvas);

    tgtApp->init();

    Camera camera;
    canvas->setCamera(&camera);
    MyPainter painter(canvas);
    canvas->setPainter(&painter);

    tgtApp->run();

    delete canvas;
    delete tgtApp;

    return 0;
}

Impressum | © 2009 Arbeitsgruppe VisCG | Edit this page
Arbeitsgruppe Visualisierung und Computergrafik
Einsteinstraße 62 · 48149 Münster
Tel.: +49 (251) 83-32700 · Fax: +49 (251) 83-33755