[solved] OpenGL example - ok running remotely, but ...

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

DougS
Just popping in
Just popping in
Posts: 14
Joined: Thu Mar 03, 2011 23:45

[solved] OpenGL example - ok running remotely, but ...

Postby DougS » Fri Mar 04, 2011 04:15

update: Solved; needed reshape,display callbacks, and usual glut event processing (see post below).

I've managed to build the CEGUI 0.75 from source (on a puppy linux 4.31 devx system), and get the Samples running (all the ones I've tried, at any rate).

After going through the "Using CEGUI with GLUT" tutorial (with modifications from various CEGUI Beginner's Guides) I have manged to get the (glut teapot) gui_loop.cpp example running and displaying TextDemo.layout nicely with TaharezLook.scheme over the teapot; the CEGUI window movable, all responding beautifully!

However, this was run from a remote ssh (tunneling; not using direct rendering) ... When I ran it from the system itself (no tunneling, no ssh, but run locally), I was quite surprised to see the glut teapot - but no CEGUI window. (No error messages or other indications anything was amiss either.) CEGUI.log and code snippets follow.

CEGUI.log excerpt

Code: Select all

04/03/2011 03:31:57 (Std)       ********************************************************************************
04/03/2011 03:31:57 (Std)       * -------- START OF ESSENTIAL SECTION TO BE POSTED ON THE FORUM       -------- *
04/03/2011 03:31:57 (Std)       ********************************************************************************
04/03/2011 03:31:57 (Std)       ---- Version 0.7.5 (Build: Feb 25 2011 GNU/Linux g++ 4.2.2 32 bit) ----
04/03/2011 03:31:57 (Std)       ---- Renderer module is: CEGUI::OpenGLRenderer - Official OpenGL based 2nd generation renderer
module.  TextureTarget support is not available :(  No glBlendFuncSeparate(EXT) support. ----
04/03/2011 03:31:57 (Std)       ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI --
--
04/03/2011 03:31:57 (Std)       ---- Image Codec module is: FreeImageCodec - FreeImage based image codec ----
04/03/2011 03:31:57 (Std)       ---- Scripting module is: None ----
04/03/2011 03:31:57 (Std)       ********************************************************************************
04/03/2011 03:31:57 (Std)       * -------- END OF ESSENTIAL SECTION TO BE POSTED ON THE FORUM         -------- *
04/03/2011 03:31:57 (Std)       ********************************************************************************



gui_loop.cpp program adapted from tutorial example
http://www.cegui.org.uk/wiki/index.php/Using_CEGUI_with_GLUT

Code: Select all

#include <cstdlib>
#include <GL/freeglut.h>
#include "CEGUI.h"
#include "CEGUIOpenGL.h"
#include "CEGUIOpenGLRenderer.h"

using namespace CEGUI;

/*****************************************************************************/
/*** same as: http://www.cegui.org.uk/wiki/index.php/Using_CEGUI_with_GLUT ***/


(skipping functions that are identical to ones in Using_CEGUI_with_GLUT example)

Code: Select all

/*** end same as http://www.cegui.org.uk/wiki/index.php/Using_CEGUI_with_GLUT ***/
/********************************************************************************/

// A barebones GLUT application
int main( int argc, char **argv)
{
        // Create our OpenGL Window
        glutInit(&argc,argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
        glutInitWindowSize(640, 480);
        window_id = glutCreateWindow("GLUT Loop");

        // Bootstrap CEGUI::System with an OpenGLRenderer object that uses the
        // current GL viewport, the DefaultResourceProvider, and the default
        // ImageCodec.
        CEGUI::OpenGLRenderer& myRenderer = CEGUI::OpenGLRenderer::bootstrapSystem();

        // set the default resource groups to be used

        // initialise the required dirs for the DefaultResourceProvider
        CEGUI::DefaultResourceProvider* rp =
                static_cast<CEGUI::DefaultResourceProvider*>
                (CEGUI::System::getSingleton().getResourceProvider());

        const char* dataPathPrefix = "./datafiles";
        char resourcePath[PATH_MAX];

        // for each resource type, set a resource group directory
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "schemes/");
        rp->setResourceGroupDirectory("schemes", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "imagesets/");
        rp->setResourceGroupDirectory("imagesets", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "fonts/");
        rp->setResourceGroupDirectory("fonts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "layouts/");
        rp->setResourceGroupDirectory("layouts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "looknfeel/");
        rp->setResourceGroupDirectory("looknfeels", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "lua_scripts/");
        rp->setResourceGroupDirectory("lua_scripts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "xml_schemas/");
        rp->setResourceGroupDirectory("schemas", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "animations/");
        rp->setResourceGroupDirectory("animations", resourcePath);

        CEGUI::Imageset::setDefaultResourceGroup("imagesets");
        CEGUI::Font::setDefaultResourceGroup("fonts");
        CEGUI::Scheme::setDefaultResourceGroup("schemes");
        CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
        CEGUI::WindowManager::setDefaultResourceGroup("layouts");
        CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
        CEGUI::AnimationManager::setDefaultResourceGroup("animations");

        // setup default group for validation schemas
        CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
        if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
                parser->setProperty("SchemaDefaultResourceGroup", "schemas");

        // create (load) the TaharezLook scheme file
        // (this auto-loads the TaharezLook looknfeel and imageset files)
        CEGUI::SchemeManager::getSingleton().create( "TaharezLook.scheme" );

        // create (load) a font.
        CEGUI::FontManager::getSingleton().create( "DejaVuSans-10.font" );

        Window* myRoot = WindowManager::getSingleton().loadWindowLayout( "TextDemo.layout");

        System::getSingleton().setGUISheet( myRoot );

        // Set some input handlers
        glutKeyboardFunc(myKeyboardFunc);              // key pressed
        glutKeyboardUpFunc(myKeyboardUpFunc);          // key released
        glutSpecialFunc(mySpecialFunc);                // special key pressed
        glutSpecialUpFunc(mySpecialUpFunc);            // special key released
        glutMouseFunc(myMouseFunc);                    // any mouse button press or release
        glutPassiveMotionFunc(myPassiveMotionFunc);    // mouse movement with no buttons held
        glutMotionFunc(myMotionFunc);                  // mouse movement with any button held

        // clearing this queue actually makes sure it's created(!) // ??
        myRenderer.getDefaultRenderingRoot().clearGeometry(CEGUI::RQ_OVERLAY);

        myRenderer.enableExtraStateSettings(true); // ??

        while( keep_running )
        {
                glutMainLoopEvent();
                render();
                glFlush();
                CEGUI::System::getSingleton().renderGUI();
                glutSwapBuffers();
        }

        glutDestroyWindow(window_id); // Exit gracefully
        return 0;
}

void render()
{
        glLoadIdentity();
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glutWireTeapot( 0.5 );
}


I have that user headspace error feeling. I'm betting someone here will quickly spot what I've done wrong.

(Once I get this going it might be nice to update the Using_CEGUI_with_GLUT tutorial with the missing/changed v0.75 bits.)

Cheers,

Doug
Last edited by DougS on Sat Mar 05, 2011 21:43, edited 1 time in total.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: OpenGL example - ok running remotely, but ...

Postby CrazyEddie » Fri Mar 04, 2011 08:38

Another odd issue :)

I tested out the tutorial along with the modified / updated bits that you posted and for me it's working ok (Gentoo Linux). Presumably there are no errors in the log? Just to confirm one thing: the regular CEGUI samples (no teapot!) run ok locally? Or also only remotely?

Not sure what to suggest at the moment, except usual debugging stuff of minimising the code until something works then add stuff back in, though in this case the code is fine (IMO) :?

CE.

DougS
Just popping in
Just popping in
Posts: 14
Joined: Thu Mar 03, 2011 23:45

Re: OpenGL example - ok running remotely, but ...

Postby DougS » Fri Mar 04, 2011 09:12

Just to confirm one thing: the regular CEGUI samples (no teapot!) run ok locally? Or also only remotely?


Hello, and thanks for such a quick response! To confirm: the CEGUI Samples (like CEGUI-0.7.5/Samples/TextDemo/ ...) work nicely both locally and remotely.

It is just my "Using CEGUI with GLUT" attempt that runs remotely, but not (correctly) locally.

Presumably there are no errors in the log?


No errors in the log that I could see. Log looks the same whether run remotely or locally.

Well, actually, I do see this one "Error" line, but it appears regardless (remotely or locally, working or not), and from what I gather from skimming other forum posts, it probably isn't an issue:

Code: Select all

04/03/2011 08:54:13 (Error)     Window::allocateRenderingWindow - Failed to create a suitable TextureTarget for use by Window 'TextDemo'


My guess is that my problem has something to do with the direct rendering, perhaps some optimisation or something that happens when directly rendering but doesn't happen when rendering remotely. (The CEIGUI Samples do seem to run faster locally than remotely, as expected.)

Since the Samples are working, that bodes well for narrowing it down and nailing it, I think.

( Also, I wanted to say thanks for the mingw builds! Very helpful, especially since I had been looking for some of those (supporting) dlls included there, too, for my -no-cygwin Win32 builds.)

Cheers,

Doug

DougS
Just popping in
Just popping in
Posts: 14
Joined: Thu Mar 03, 2011 23:45

Re: OpenGL example - ok running remotely, but ...

Postby DougS » Sat Mar 05, 2011 21:41

Solved! :D

Short answer: I needed the usual OpenGL reshape and display callbacks, and I needed to have done things the traditional glut way.

So, instead of rolling our own glut event processing loop, we just set up a reshape and display function as is usually done in glut:

Code: Select all

        glutReshapeFunc (myReshapeFunc);
        glutDisplayFunc (drawFrame);
        glutMainLoop();


Which is what the Samples do. The reshape callback was lifted from OpenGL Sample code:

Code: Select all

void myReshapeFunc(int w, int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 50.0);
    glMatrixMode(GL_MODELVIEW);
    CEGUI::System::getSingleton().
        notifyDisplaySizeChanged(CEGUI::Size((float)w,(float)h));
}


The display (rendering) callback, similarly:

Code: Select all

int d_lastFrameTime = 0;
bool d_quitFlag = false;

void drawFrame(void)
{
    CEGUI::System& guiSystem = CEGUI::System::getSingleton();

    // do time based updates
    int thisTime = glutGet(GLUT_ELAPSED_TIME);
    float elapsed = static_cast<float>(thisTime - d_lastFrameTime);
    d_lastFrameTime = thisTime;
    // inject the time pulse
    guiSystem.injectTimePulse(elapsed / 1000.0f);

    // do rendering for this frame.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    // draw your stuff here ...
    glColor4f(1.0f,0.0f,0.0f,1.0f);
    glTranslatef( 0,0,-5 );
    glutWireTeapot( 2.0 ); // (No milk in my tea, thank you.)

    // now CEGUI draws ...
    guiSystem.renderGUI();

    glutPostRedisplay();
    glutSwapBuffers();

    if (d_quitFlag)
    {
        CEGUI::OpenGLRenderer::destroySystem();
        exit(0);
    }
}


Nice jaunt through CEGUI source Ive had the past few days. CEIGUI source seems to be well-written, nicely documented, and adhering to modern C++ standards. So that should improve my own C++ coding...

DougS
Just popping in
Just popping in
Posts: 14
Joined: Thu Mar 03, 2011 23:45

Re: [solved] OpenGL example - ok running remotely, but ...

Postby DougS » Mon Mar 07, 2011 05:42

Once I get this going it might be nice to update the Using_CEGUI_with_GLUT tutorial with the missing/changed v0.7.5 bits.


I should clean up my minimal glut example version and update the glut example here on cegui's wiki. I found a another issue with key injection: was missing a key-down injection, and it was doing injectChar on some characters that might not have been printable. (Resulting in Return and Backspace keys not getting properly handled.) Here's what I did to fix mine.

Code: Select all

void myKeyboardFunc(unsigned char key, int x, int y)
{
        fakeCtrlAltShift();

        int scancode = mapNormal(key);
        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyDown(scancode);
        }

        if (isprint(key)) CEGUI::System::getSingleton().injectChar(key);

        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyUp(scancode);
        }
}


Also got the CELayoutEditor up and running today, and am making layouts wonderfully.

DougS
Just popping in
Just popping in
Posts: 14
Joined: Thu Mar 03, 2011 23:45

Re: [solved] OpenGL example - ok running remotely, but ...

Postby DougS » Tue Mar 08, 2011 03:56

I should clean up my minimal glut example version and update the glut example here on cegui's wiki.


Alas, not allowed into the wiki with my forum account.

Here's the minimal CEGUI OpenGL example. When you run it, you should see a glut teapot, with a nice CEGUI window on top.

The C++ source first ...

Code: Select all

// cegui_opengl.cpp - base-bones, OpenGL (glut) -only complete example
//   Adapted from http://www.cegui.org.uk/wiki/index.php/Using_CEGUI_with_GLUT & CEGUI Samples.
//   Usage:  ./cegui_opengl [datafiles-dir]
//       datafiles-dir - where the cegui data files are located (defaults to ./mySkin)

#include <cstdlib>
#include <GL/freeglut.h>
#include "CEGUI.h"
#include "CEGUIOpenGL.h"
#include "CEGUIOpenGLRenderer.h"
#include <ctype.h>

// Track the status of modifiers
bool ctrl_held = false;
bool alt_held = false;
bool shift_held = false;

// Some "glue" functions to go between OpenGL keyboard/mouse inputs, and what CEGUI needs

void fakeCtrlAltShift()
{
        int status = glutGetModifiers();
        if (status & GLUT_ACTIVE_CTRL)
        {
                if (!ctrl_held)
                {
                        ctrl_held = true;
                        CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftControl);
                }
        }
        else
        {
                if (ctrl_held)
                {
                        ctrl_held = false;
                        CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftControl);
                }
        }
        if (status & GLUT_ACTIVE_ALT)
        {
                if (!alt_held)
                {
                        alt_held = true;
                        CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftAlt);
                }
        }
        else
        {
                if (alt_held)
                {
                        alt_held = false;
                        CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftAlt);
                }
        }
        if (status & GLUT_ACTIVE_SHIFT)
        {
                if (!shift_held)
                {
                        shift_held = true;
                        CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftShift);
                }
        }
        else
        {
                if (shift_held)
                {
                        shift_held = false;
                        CEGUI::System::getSingleton().injectKeyUp(CEGUI::Key::LeftShift);
                }
        }
}

// Map ASCII to Scan Codes
int mapNormal(unsigned char c)
{
        int scancode;
        switch(c)
        {
                case 97:
                case 65:
                        scancode = CEGUI::Key::A;
                        break;
                case 98:
                case 66:
                        scancode = CEGUI::Key::B;
                        break;
                case 99:
                case 67:
                        scancode = CEGUI::Key::C;
                        break;
                case 100:
                case 68:
                        scancode = CEGUI::Key::D;
                        break;
                case 101:
                case 69:
                        scancode = CEGUI::Key::E;
                        break;
                case 102:
                case 70:
                        scancode = CEGUI::Key::F;
                        break;
                case 103:
                case 71:
                        scancode = CEGUI::Key::G;
                        break;
                case 104:
                case 72:
                        scancode = CEGUI::Key::H;
                        break;
                case 105:
                case 73:
                        scancode = CEGUI::Key::I;
                        break;
                case 106:
                case 74:
                        scancode = CEGUI::Key::J;
                        break;
                case 107:
                case 75:
                        scancode = CEGUI::Key::K;
                        break;
                case 108:
                case 76:
                        scancode = CEGUI::Key::L;
                        break;
                case 109:
                case 77:
                        scancode = CEGUI::Key::M;
                        break;
                case 110:
                case 78:
                        scancode = CEGUI::Key::N;
                        break;
                case 111:
                case 79:
                        scancode = CEGUI::Key::O;
                        break;
                case 112:
                case 80:
                        scancode = CEGUI::Key::P;
                        break;
                case 113:
                case 81:
                        scancode = CEGUI::Key::Q;
                        break;
                case 114:
                case 82:
                        scancode = CEGUI::Key::R;
                        break;
                case 115:
                case 83:
                        scancode = CEGUI::Key::S;
                        break;
                case 116:
                case 84:
                        scancode = CEGUI::Key::T;
                        break;
                case 117:
                case 85:
                        scancode = CEGUI::Key::U;
                        break;
                case 118:
                case 86:
                        scancode = CEGUI::Key::V;
                        break;
                case 119:
                case 87:
                        scancode = CEGUI::Key::W;
                        break;
                case 120:
                case 88:
                        scancode = CEGUI::Key::X;
                        break;
                case 121:
                case 89:
                        scancode = CEGUI::Key::Y;
                        break;
                case 122:
                case 90:
                        scancode = CEGUI::Key::Z;
                        break;
                case 27:
                        scancode = CEGUI::Key::Escape;
                        break;
                case 49:
                        scancode = CEGUI::Key::One;
                        break;
                case 50:
                        scancode = CEGUI::Key::Two;
                        break;
                case 51:
                        scancode = CEGUI::Key::Three;
                        break;
                case 52:
                        scancode = CEGUI::Key::Four;
                        break;
                case 53:
                        scancode = CEGUI::Key::Five;
                        break;
                case 54:
                        scancode = CEGUI::Key::Six;
                        break;
                case 55:
                        scancode = CEGUI::Key::Seven;
                        break;
                case 56:
                        scancode = CEGUI::Key::Eight;
                        break;
                case 57:
                        scancode = CEGUI::Key::Nine;
                        break;
                case 48:
                        scancode = CEGUI::Key::Zero;
                        break;
                case 45:
                        scancode = CEGUI::Key::Minus;
                        break;
                case 61:
                        scancode = CEGUI::Key::Equals;
                        break;
                case 8:
                        scancode = CEGUI::Key::Backspace;
                        break;
                case 9:
                        scancode = CEGUI::Key::Tab;
                        break;
                case 91:
                        scancode = CEGUI::Key::LeftBracket;
                        break;
                case 93:
                        scancode = CEGUI::Key::RightBracket;
                        break;
                case 13:
                        scancode = CEGUI::Key::Return;
                        break;
                case 59:
                        scancode = CEGUI::Key::Semicolon;
                        break;
                case 39:
                        scancode = CEGUI::Key::Apostrophe;
                        break;
                case 96:
                        scancode = CEGUI::Key::Grave;
                        break;
                case 92:
                        scancode = CEGUI::Key::Backslash;
                        break;
                case 44:
                        scancode = CEGUI::Key::Comma;
                        break;
                case 46:
                        scancode = CEGUI::Key::Period;
                        break;
                case 47:
                        scancode = CEGUI::Key::Slash;
                        break;
                case 42:
                        scancode = CEGUI::Key::Multiply;
                        break;
                case 32:
                        scancode = CEGUI::Key::Space;
                        break;
                case 64:
                        scancode = CEGUI::Key::At;
                        break;
                case 58:
                        scancode = CEGUI::Key::Colon;
                        break;
                case 95:
                        scancode = CEGUI::Key::Underline;
                        break;
                case 127:
                        scancode = CEGUI::Key::Delete;
                        break;
                default:
                        scancode = 0;
        }
        return scancode;
}

// Map Special GLUT Keys to Scan Codes
int mapSpecial(int c)
{
        int scancode;
        switch(c)
        {
                case 1:
                        scancode = CEGUI::Key::F1;
                        break;
                case 2:
                        scancode = CEGUI::Key::F2;
                        break;
                case 3:
                        scancode = CEGUI::Key::F3;
                        break;
                case 4:
                        scancode = CEGUI::Key::F4;
                        break;
                case 5:
                        scancode = CEGUI::Key::F5;
                        break;
                case 6:
                        scancode = CEGUI::Key::F6;
                        break;
                case 7:
                        scancode = CEGUI::Key::F7;
                        break;
                case 8:
                        scancode = CEGUI::Key::F8;
                        break;
                case 9:
                        scancode = CEGUI::Key::F9;
                        break;
                case 10:
                        scancode = CEGUI::Key::F10;
                        break;
                case 11:
                        scancode = CEGUI::Key::F11;
                        break;
                case 12:
                        scancode = CEGUI::Key::F12;
                        break;
                case 104:
                        scancode = CEGUI::Key::PageUp;
                        break;
                case 105:
                        scancode = CEGUI::Key::PageDown;
                        break;
                case 106:
                        scancode = CEGUI::Key::Home;
                        break;
                case 107:
                        scancode = CEGUI::Key::End;
                        break;
                case 100:
                        scancode = CEGUI::Key::ArrowLeft;
                        break;
                case 101:
                        scancode = CEGUI::Key::ArrowUp;
                        break;
                case 102:
                        scancode = CEGUI::Key::ArrowRight;
                        break;
                case 103:
                        scancode = CEGUI::Key::ArrowDown;
                        break;
                case 108:
                        scancode = CEGUI::Key::Insert;
                        break;
                default:
                        scancode = 0;
        }
        return scancode;
}

void myKeyboardFunc(unsigned char key, int x, int y)
{
        fakeCtrlAltShift();

        int scancode = mapNormal(key);
        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyDown(scancode);
        }

        if (isprint(key)) CEGUI::System::getSingleton().injectChar(key);

        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyUp(scancode);
        }
}

void myKeyboardUpFunc(unsigned char key, int x, int y)
{
        fakeCtrlAltShift();
        int scancode = mapNormal(key);
        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyUp(scancode);
        }
}

void mySpecialFunc(int key, int x, int y)
{
        fakeCtrlAltShift();
        int scancode = mapSpecial(key);
        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyDown(scancode);
        }
}

void mySpecialUpFunc(int key, int x, int y)
{
        fakeCtrlAltShift();
        int scancode = mapSpecial(key);
        if (scancode)
        {
                CEGUI::System::getSingleton().injectKeyUp(scancode);
        }
}

void myMouseFunc(int button, int state, int x, int y)
{
        if (state == 0)     // State 0 = Button Pressed
        {
                switch (button)
                {
                        case 0:     // glut's left mouse button
                                CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
                                break;
                        case 1:     // glut's middle mouse button
                                CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
                                break;
                        case 2:     // glut's right mouse button
                                CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
                                break;
                        case 3:     // glut's mouse wheel up
                                CEGUI::System::getSingleton().injectMouseWheelChange(2.0);
                                break;
                        case 4:     // glut's mouse wheen down
                                CEGUI::System::getSingleton().injectMouseWheelChange(-2.0);
                                break;
                }
        }
        else if (state == 1)    // State 1 = Button Released
        {
                switch (button)
                {
                        case 0:     // glut's left mouse button
                                CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
                                break;
                        case 1:     // glut's middle mouse button
                                CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
                                break;
                        case 2:     // glut's right mouse button
                                CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
                                break;
                }
        }
}

void myPassiveMotionFunc(int x, int y)
{
        CEGUI::System::getSingleton().injectMousePosition(x,y);
}

void myMotionFunc(int x, int y)
{
        CEGUI::System::getSingleton().injectMousePosition(x,y);
}


void myReshapeFunc(int w, int h)
{
   // (typical OpenGL sequence for display size change)
        glViewport (0, 0, (GLsizei) w, (GLsizei) h);
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 50.0);
        glMatrixMode(GL_MODELVIEW);

   // Inform gui of size ...
        CEGUI::System::getSingleton().
                notifyDisplaySizeChanged(CEGUI::Size((float)w,(float)h));
}


bool d_quitFlag = false;

bool quit(const CEGUI::EventArgs&)
{
        d_quitFlag = true;
        return true; // event was handled
}

// we'll need to listen for quit events to respond to the 'quit' button
void subscribeEvent(const CEGUI::String& widget, const CEGUI::String& event,
                const CEGUI::Event::Subscriber& method)
{
        CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();
        if (winMgr.isWindowPresent(widget))
        {
                CEGUI::Window* window = winMgr.getWindow(widget);
                window->subscribeEvent(event, method);
        }
}

// dump any text typed into the edit box to stdout
void dumpEditBoxText ()
{
   CEGUI::MultiLineEditbox * multiLineEditbox =
      static_cast<CEGUI::MultiLineEditbox*>
      (CEGUI::WindowManager::getSingletonPtr()->
       getWindow( "OuterWin/Edit1" ));
   printf("text=%s\n", multiLineEditbox->getText().c_str() );
}



// The OpenGL rendering / draw callback ...

int d_lastFrameTime = 0;   // for cegui time pulse management

void drawFrame(void)
{
        CEGUI::System& guiSystem = CEGUI::System::getSingleton();

        // do time based updates
        int thisTime = glutGet(GLUT_ELAPSED_TIME);
        float elapsed = static_cast<float>(thisTime - d_lastFrameTime);
        d_lastFrameTime = thisTime;
        //  ... inject the time pulse
        guiSystem.injectTimePulse(elapsed / 1000.0f);

        // rendering for this frame.

   // prepare to render, typical OpenGL things
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        //
        // (draw your application OpenGL here, as usual)
        //
        glColor4f(1.0f,0.0f,0.0f,1.0f);
        glTranslatef( 0,0,-5 );
        glutWireTeapot( 2.0 ); 


        //
        // Now, CEGUI draws on top of that...
        //
        guiSystem.renderGUI();


   // (typical OpenGL double-buffering display sequence)
        glutPostRedisplay();
        glutSwapBuffers();


        // Here we check the 'quitting' state and cleanup as required.
        // this is probably not the best way to do this, but since we're
        // using glut, and glutMainLoop can never return, we need some
        // way of checking when to exit.  And this is it...
        if (d_quitFlag)
        {
      dumpEditBoxText();
                CEGUI::OpenGLRenderer::destroySystem();
                exit(0);
        }
}


int main( int argc, char **argv)
{
   // usual OpenGL / glut boilerplate
        glutInit(&argc,argv);
        glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
        glutInitWindowSize(640, 480);
   glutCreateWindow("CEGUI + OpenGL/GLUT example");


        // Bootstrap CEGUI::System with an OpenGLRenderer object that uses the
        // current GL viewport, the DefaultResourceProvider, and the default
        // ImageCodec.      CEGUI::OpenGLRenderer& myRenderer =
        CEGUI::OpenGLRenderer::bootstrapSystem();

        // Set the default resource groups to be used

        // initialise the required dirs for the DefaultResourceProvider
        CEGUI::DefaultResourceProvider* rp =
                static_cast<CEGUI::DefaultResourceProvider*>
                (CEGUI::System::getSingleton().getResourceProvider());

        // for each resource type, set a resource group directory
        const char* dataPathPrefix = (argc>1
      ? (const char *)argv[1]  // dir from command-line,
      : "./mySkin" );         // or,  default location
        char resourcePath[PATH_MAX];
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "schemes/");
        rp->setResourceGroupDirectory("schemes", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "imagesets/");
        rp->setResourceGroupDirectory("imagesets", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "fonts/");
        rp->setResourceGroupDirectory("fonts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "layouts/");
        rp->setResourceGroupDirectory("layouts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "looknfeel/");
        rp->setResourceGroupDirectory("looknfeels", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "lua_scripts/");
        rp->setResourceGroupDirectory("lua_scripts", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "xml_schemas/");
        rp->setResourceGroupDirectory("schemas", resourcePath);
        sprintf(resourcePath, "%s/%s", dataPathPrefix, "animations/");
        rp->setResourceGroupDirectory("animations", resourcePath);

        CEGUI::Imageset::setDefaultResourceGroup("imagesets");
        CEGUI::Font::setDefaultResourceGroup("fonts");
        CEGUI::Scheme::setDefaultResourceGroup("schemes");
        CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
        CEGUI::WindowManager::setDefaultResourceGroup("layouts");
        CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
        CEGUI::AnimationManager::setDefaultResourceGroup("animations");

        // setup default group for validation schemas
        CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
        if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
                parser->setProperty("SchemaDefaultResourceGroup", "schemas");

        // create (load) the scheme file
        // (this auto-loads the looknfeel and imageset files)
        CEGUI::SchemeManager::getSingleton().create( "WindowsLook.scheme" );

        // create (load) a font.
        CEGUI::FontManager::getSingleton().create( "Batang-48.font" );

        // .. and the layout xml specifying which widgets go where
        CEGUI::Window* myRoot =
                CEGUI::WindowManager::getSingleton().loadWindowLayout("MyDialog1.layout");
        CEGUI::System::getSingleton().setGUISheet( myRoot );

        // Quit button
        subscribeEvent("OuterWin/Quit",
                        CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&quit));

        // Set some glut handlers, as is customary for OpenGL applications
        glutKeyboardFunc(myKeyboardFunc);            // key pressed
        glutKeyboardUpFunc(myKeyboardUpFunc);        // key released
        glutSpecialFunc(mySpecialFunc);              // special key pressed
        glutSpecialUpFunc(mySpecialUpFunc);          // special key released
        glutMouseFunc(myMouseFunc);                  // any mouse button press or release
        glutPassiveMotionFunc(myPassiveMotionFunc);  // mouse movement with no buttons held
        glutMotionFunc(myMotionFunc);                // mouse movement with any button held
        glutReshapeFunc (myReshapeFunc);             // window dims set/changed
        glutDisplayFunc (drawFrame);                 // opengl + cegui rendering
        glutMainLoop();                              // glut event processing loop
        return 0;
}


The layout xml file, mySkin/layouts/MyDialog1.layout , a minimal multi-line edit box with a "quit" button.

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>

<GUILayout >
    <Window Type="WindowsLook/FrameWindow" Name="OuterWin" >
        <Property Name="Font" Value="Batang-48" />
        <Property Name="Text" Value="My Dialog" />
        <Property Name="TitlebarFont" Value="Batang-48" />
        <Property Name="TitlebarEnabled" Value="True" />
        <Property Name="UnifiedAreaRect" Value="{{0.0568905,0},{0.0467909,0},{0.838693,0},{0.648898,0}}" />
        <Window Type="WindowsLook/MultiLineEditbox" Name="OuterWin/Edit1" >
            <Property Name="Font" Value="Batang-48" />
            <Property Name="Text" >
</Property>
            <Property Name="MaxTextLength" Value="1073741823" />
            <Property Name="UnifiedAreaRect" Value="{{0.0248588,0},{0.0549957,0},{0.977684,0},{0.762724,0}}" />
            <Property Name="TextParsingEnabled" Value="False" />
        </Window>
        <Window Type="WindowsLook/Button" Name="OuterWin/Quit" >
            <Property Name="Font" Value="Batang-48" />
            <Property Name="Text" Value="Quit" />
            <Property Name="UnifiedAreaRect" Value="{{0.391485,0},{0.817677,0},{0.641485,0},{0.964801,0}}" />
        </Window>
    </Window>
</GUILayout>


The font xml file, mySkin/fonts/Batang-48.font ...

Code: Select all

<?xml version="1.0" ?>
<Font Name="Batang-48" Filename="batang.ttf" Type="FreeType" Size="48" NativeHorzRes="1891" NativeVertRes="1418" AutoScaled="true"/>

(Didn't really seem to make it all the way to 48 pt there ... but I may not have something quite right.)

The rest of the files in in the mySkin/ folder are the same as are found in the datafiles/ folder used for the Samples in the CEGUI source:

Code: Select all

mySkin/imagesets/WindowsLook.imageset
mySkin/imagesets/WindowsLook.tga
mySkin/lua_scripts/demo8.lua
mySkin/layouts/MyDialog1.layout
mySkin/looknfeel/WindowsLook.looknfeel
mySkin/fonts/batang.ttf
mySkin/fonts/Batang-48.font
mySkin/animations/example.xml
mySkin/xml_schemas/CEGUIConfig.xsd
mySkin/xml_schemas/GUIScheme.xsd
mySkin/xml_schemas/Font.xsd
mySkin/xml_schemas/Falagard.xsd
mySkin/xml_schemas/Imageset.xsd
mySkin/xml_schemas/Animation.xsd
mySkin/xml_schemas/GUILayout.xsd
mySkin/schemes/WindowsLookWidgets.scheme
mySkin/schemes/WindowsLook.scheme


Lastly, the Makefile ...

Code: Select all

# minimal cegui opengl example

CFLAGS = -Wall -I/usr/X11R6/include/ \
         -I/usr/local/include/CEGUI \
         -I/usr/local/include/CEGUI/RendererModules/OpenGL \
        -g -ggdb

LIBS = -Wall -L/usr/X11R6/lib \
         -lX11 -lXi -lXmu -lglut -lGL -lGLU \
         -L/usr/local/lib -lCEGUIBase -lCEGUIOpenGLRenderer

cegui_opengl:   cegui_opengl.o
        g++ cegui_opengl.o $(LIBS) -o cegui_opengl

cegui_opengl.o: cegui_opengl.cpp
        g++ $(CFLAGS) -c cegui_opengl.cpp

.PHONY: clean
clean:
        rm -rf *.o cegui_opengl


Probably should update the wiki with this and include all files for this example as a (linux) standard tar.gz.

That should help OpenGL users to hit the ground running, for 0.7.5 at least.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: [solved] OpenGL example - ok running remotely, but ...

Postby CrazyEddie » Mon Mar 14, 2011 09:24

Doug_S wrote:Alas, not allowed into the wiki with my forum account.

What's the issue / error you get? I suspect it's probably related to the underscore in your username.

CE


Return to “Help”

Who is online

Users browsing this forum: No registered users and 8 guests