GWEN/GWork Irrlicht Renderer

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

GWEN/GWork Irrlicht Renderer

Post by kklouzal »

Hey guys! I'm sharing my Irrlicht Renderer for GWEN/GWork!
*UPDATE*
BillyQuith has graciously integrated my renderer into GWork
https://github.com/billyquith/GWork
GWEN has been abandoned by the developer and subsequently a fork called GWork has taken it's place.
GWork is in active development providing a more stable version of the original GWEN project.
It holds true to the idea of a "GUI Without Extravagant Nonsense" even more so than previous iterations.

The renderer is complete except for the font related functions which will be written once Irrlicht supports TT-Fonts.
For now it uses the built-in default GUI font and text rendering so you'll need to have Irrlicht compiled with GUI enabled.
Image
Image

Demo code is posted below:

Code: Select all

#include <irrlicht.h>
 
#include "gwork/gwork.h"
#include "gwork/Skins/Simple.h"
#include "gwork/Skins/TexturedBase.h"
#include "gwork/Test/Test.h"
#include "gwork/Input/Irrlicht.h"
#include "gwork/Renderers/Irrlicht.h"
#include <Gwork/Platform.h>
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
class MyEventReceiver : public IEventReceiver {
public:
    MyEventReceiver(Gwk::IInputEventListener* el) : input() {
        input.Initialize(el);
    }
 
    virtual bool OnEvent(const SEvent& event) {
        return input.HandleEvents(event);
    }
 
private:
    Gwk::Input::Irrlicht input;
};
 
int main() {
    IrrlichtDevice *device = createDevice(video::EDT_OPENGL, dimension2d<u32>(1004, 650), 32, false, false, false, NULL);
 
    if (!device) { return 1; }
    device->setWindowCaption(L"Gwork - Irrlicht Sample");
 
    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();
 
    //
    // Create a Gwork Irrlicht Renderer
    //
    Gwk::Platform::RelativeToExecutablePaths paths(GWORK_RESOURCE_DIR);
    Gwk::Renderer::IrrlichtResourceLoader loader(driver, paths);
    Gwk::Renderer::Irrlicht* pRenderer = new Gwk::Renderer::Irrlicht(device, loader);
    //
    // Create a Gwork skin
    //
    Gwk::Skin::TexturedBase* pSkin = new Gwk::Skin::TexturedBase(pRenderer);
    pSkin->Init("DefaultSkin.png");
    pSkin->SetDefaultFont("OpenSans.ttf", 11);
    //
    // Create a Canvas (it's root, on which all other Gwork panels are created)
    //
    Gwk::Controls::Canvas* pCanvas = new Gwk::Controls::Canvas(pSkin);
    pCanvas->SetSize(998, 650 - 24);
    pCanvas->SetDrawBackground(true);
    pCanvas->SetBackgroundColor(Gwk::Color(150, 0, 0, 255));
    //  Texture caching doesn't seem to work properly.
    //  Cached textures never get updated.
    //pCanvas->EnableCacheToTexture();
    //
    // Create our unittest control (which is a Window with controls in it)
    //
    auto pUnit = new TestFrame(pCanvas);
    pUnit->SetPos(10, 10);
 
    MyEventReceiver* eventReceiver = new MyEventReceiver(pCanvas);
    device->setEventReceiver(eventReceiver);
 
    int lastFPS = -1;
    while (device->run()) {
        driver->beginScene(true, true, SColor(255, 100, 101, 140));
        smgr->drawAll();
        //
        //  Draw the canvas
        //
        pCanvas->RenderCanvas();
        //
        driver->endScene();
        int fps = driver->getFPS();
        if (lastFPS != fps) {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += "] FPS:";
            str += fps;
 
            device->setWindowCaption(str.c_str());
            lastFPS = fps;
        }
    }
 
    delete eventReceiver;
    delete pCanvas;
    delete pSkin;
    delete pRenderer;
    device->drop();
    return 0;
}
Any issues directly related to the Irrlicht Renderer can be brought up here: https://github.com/kklouzal/GWork/issues
Any other issues with GWork can be brought up here: https://github.com/billyquith/GWork/issues
Last edited by kklouzal on Thu Jan 11, 2018 11:50 am, edited 13 times in total.
Dream Big Or Go Home.
Help Me Help You.
Neirdan
Posts: 39
Joined: Tue Aug 14, 2012 10:29 pm

Re: GWEN Irrlicht Renderer

Post by Neirdan »

I tried a google search and ended up with gwen stefani stuff, what exactly is GWEN?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: GWEN Irrlicht Renderer

Post by mongoose7 »

Instead of "gwen stefani", you could try "gwen renderer", the famous female soccer player.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

GWEN (Graphical user interface Without Extravagant Nonsense)

You can create gorgeous GUI's in a very simple fashion with little impact to performance. This is the type of GUI I would expect to have in Irrlicht by default.

https://github.com/garrynewman/GWEN
Dream Big Or Go Home.
Help Me Help You.
airc
Posts: 25
Joined: Wed Jan 08, 2014 8:17 am

Re: GWEN Irrlicht Renderer

Post by airc »

there are alot of errors during compilation !, i use CodeBlocks !.
do i need to set up some directory before the compilation ?
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

This is JUST the renderer for GWEN so you'll need to download GWEN and include it in your project :)
Dream Big Or Go Home.
Help Me Help You.
airc
Posts: 25
Joined: Wed Jan 08, 2014 8:17 am

Re: GWEN Irrlicht Renderer

Post by airc »

i am talking about GWEN it self .
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

GWEN uses premake4 to create project files then you can compile the library itself.
Dream Big Or Go Home.
Help Me Help You.
beasthacker
Posts: 15
Joined: Fri Jul 25, 2014 3:51 pm

Re: GWEN Irrlicht Renderer

Post by beasthacker »

Been a lurker on this forum for quite a while. Finally created an account so that I could say thank you! I've been wrestling with various GUI solutions for Irrlicht for weeks with pretty bad results overall (particularly for the amount of time wasted). Even spent a few days trying to write my own layer 'on top' of Irrlicht but that has its own issues.

I got lucky and stumbled across GWEN today and within a few hours already have things up and running thanks to you. You really made my day!

As far as TTF is concerned I'm using CGUITTFFont code that I found on this forum for TTF support. You can get it at http://irrlicht.sourceforge.net/forum/v ... =6&t=37296.

I'm using the TTF Font class currently with GWEN and so far it seems to be working fine! I loaded the TTF Font into the GUI Environment skin and then set 'Text' member to the skin's font instead of the default one:

** NOTE: I renamed the member named 'Text' to 'Font' for clarity sake

Code: Select all

Font = Device->getGUIEnvironment()->getSkin()->getFont(); // was named 'Text' in above example
 
I also implemented the MeasureText method as follows:

Code: Select all

virtual Gwen::Point MeasureText(Gwen::Font* pFont, const Gwen::String & text)
            {
                using namespace irr;
                using namespace core;
 
                // Get size of string from Irrlicht (hopefully correct for TTF stuff)
                std::wstring wText(text.begin(), text.end());
                dimension2d<u32> irrDimension = Font->getDimension(wText.c_str());
 
                Gwen::Point NewPoint;
                NewPoint.x = irrDimension.Width;
                NewPoint.y = irrDimension.Height;
 
                return NewPoint;
            }
After this the text isn't clipping so far so I thought it would be useful as a starting point for others.

The only issues I've had so far is that letters being typed in are appearing twice almost like insane repeat rate. Also I'm not getting space bar input even though you are inserting it in the event switch?

I haven't spent much time on the issues though so I'll let you know if I can fix them. If you have any ideas let me know.

Thanks a bunch for your help. Hopefully you can get TTF going soon yourself. :D

UPDATE:
Simple fix for the repeated character insertions.
Add the following to the 'default' switch for the Key Input Events in Gwen::Input::Irrlicht::HandleEvents() method.

Code: Select all

default:
                            {
                                // Do a quick check to see if key is being pressed/released for this event.
                                // This will prevent the double insertions of characters
                                if (IrrEvent.KeyInput.PressedDown)
                                {
                                    return m_Canvas->InputCharacter((Gwen::UnicodeChar)IrrEvent.KeyInput.Char);
                                }
                            }
Just found an odd bug/something but using InputKey() with Gwen::Key::Space doesn't actually insert a space into textfields? Maybe InputKey is more for modifier keys? Not sure if thats a bug or not. Anyways to fix you can add the following to the irr::KEY_SPACE case in HandleEvents() that will explicitly enter the 'space character' into the text fields. This solves the space bar issue!

Code: Select all

case irr::KEY_SPACE:
                            {
                                if (IrrEvent.KeyInput.PressedDown)
                                    return m_Canvas->InputCharacter((Gwen::UnicodeChar)IrrEvent.KeyInput.Char);//(Gwen::UnicodeChar)0x20); also works
                            }
Again, thanks a ton for the great addition! I've got the Unit Tests for GWEN working perfectly and rendering on top of my Irrlicht scene. This really is an awesome library :lol:
Last edited by beasthacker on Fri Aug 15, 2014 4:16 pm, edited 1 time in total.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

Ah you made my day! I'm glad someone has found a use for this. I appreciate the addition to get TT fonts working however I'll wait to update the code here until the next version of Irrlicht since from what I've herd they will have TT integrated with 1.9. I've been tirelessly binding GWEN to Lua over the past week and once that's done I'll have it here as well.

As a side note, the renderer is still incomplete. You are able to use GWEN to draw and interact with all their controls however there are a few areas where optimization could be added in, specifically with the DrawPixel() and DrawLinedRect() functions. It would be faster to use Irrlicht's provided draw functions to accomplish those tasks however when using them the objects don't draw onto the screen in the correct locations. The second and most vital optimization would be the caching to texture features, I don't believe GWEN takes care of this for you and needs to be implemented into the renderer. I don't know enough about how to even get started on that so maybe someone will come along and get it working :)
Dream Big Or Go Home.
Help Me Help You.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

I fixed a bad memory leak in the renderer today, it was eating up 1mb of ram per second, whoops!

The OP has been updated with new code :)
Dream Big Or Go Home.
Help Me Help You.
beasthacker
Posts: 15
Joined: Fri Jul 25, 2014 3:51 pm

Re: GWEN Irrlicht Renderer

Post by beasthacker »

Nice catch. I haven't messed with the renderer really except measureText().

By the way, the solution I'm using for TTF in irrlicht uses FreeType lib and is a subclass of IGUIFont. I don't know how 1.9 will change but if it still uses IGUIFont interface then you shouldn't have to change any of the Gwen text rendering code when you update. The Gwen renderer is identical, the only difference is that i set the IGUIFont 'Text' member in renderer to the special TTF Font class linked above. Just FYI, I wasn't sure if I explained it clearly above. Wouldn't want you to miss out on TTF if you don't have to wait :D

Also, I think it's worth noting for Gwen users that if you are using Irrlicht and Gwen together on platforms besides Microsoft Windows, cursors won't show up correctly. (Resize cursors, I-Bars, etc). Look in gwen source at Platform.h and you can see that none has been implemented besides Windows (and maybe allegro?) for different cursors.

What I did for a quick fix was set up some new defines in Gwen source so that I could include my own implementation for the Platform.h interface in my project if I'm not building on Windows.

Its not done but here's the start for an Irrlicht Gwen Platform implementation that can use Irrlicht sprite bank cursors. I also included Mac OSX specific cursor control in this file at least temporarily but figured I would leave it in if other people are building for Mac.

GwenIrrlichtPlatform.h

Code: Select all

#pragma once
#ifndef GwenIrrlichtPlatform_h
#define GwenIrrlichtPlatform_h
 
namespace Gwen
{
    namespace Platform
    {
        
        static Gwen::String         clipboardString;
        extern irr::IrrlichtDevice *device;
    }
}
 
#endif


GwenIrrlichtPlatform.cpp (NOTE: If building on Mac OSX, compile as Objective C++ in XCode settings for the file)

Code: Select all

#include <Gwen/Macros.h>
#include <Gwen/Platform.h>
#include <Gwen/Structures.h>
 
#include <irrlicht.h>
 
#include <iostream>
#include <time.h>
 
// @NOTE: We're treating this file as an Objective C++ file for OSX compilation
// so that we can use NSCursor to change system cursor.
#ifdef __APPLE__
#import <AppKit/AppKit.h>
#endif // __APPLE__
 
#include "GwenIrrlichtPlatform.h"
 
namespace Gwen
{
    
    namespace Platform
    {
        irr::IrrlichtDevice *device = nullptr;
    }
    
    void Platform::Sleep(unsigned int iMS)
    {
        // @NOTE: Is this actually used for anything?
    }
    
    void Platform::SetCursor(unsigned char iCursor)
    {
#ifdef __APPLE__
        // Apple desktop specific implementation
        switch (iCursor)
        {
            case CursorType::Beam:
                [[NSCursor IBeamCursor] set];
                break;
                
            case CursorType::SizeAll:  // Roll over
            case CursorType::SizeNESW: // Roll over
            case CursorType::SizeNS:
                [[NSCursor resizeUpDownCursor] set];
                break;
                
            case CursorType::SizeWE:
                [[NSCursor resizeLeftRightCursor] set];
                break;
 
            // These aren't available to NSCursor
            // To use these you'd need to load system textures manually
            // or make your own :(
            /*
            case CursorType::SizeNWSE:
                irrCursor = ECI_SIZENWSE;
                break;
                
            case CursorType::SizeNESW:
                irrCursor = ECI_SIZENWSE;
                break;
            */
                
            case CursorType::Finger:
                [[NSCursor pointingHandCursor] set];
                break;
                
                // Roll over normal/default
            case CursorType::Normal:
            default:
                [[NSCursor arrowCursor] set];
                break;
        }
#else
        // General Irrlicht implementation using sprite banks for cursor
        using namespace irr::gui;
        
        if (device != nullptr)
        {
            // Set Irrlicht cursor
            ECURSOR_ICON    irrCursor = ECI_NORMAL;
            
            switch (iCursor)
            {
                case CursorType::Beam:
                    irrCursor = ECI_IBEAM;
                    break;
                    
                case CursorType::SizeNS:
                    irrCursor = ECI_SIZENS;
                    break;
                    
                case CursorType::SizeWE:
                    irrCursor = ECI_SIZEWE;
                    break;
                    
                case CursorType::SizeNWSE:
                    irrCursor = ECI_SIZENWSE;
                    break;
                    
                case CursorType::SizeNESW:
                    irrCursor = ECI_SIZENWSE;
                    break;
                    
                case CursorType::SizeAll:
                    irrCursor = ECI_SIZEALL;
                    break;
                    
                case CursorType::No:
                    irrCursor = ECI_NO;
                    break;
                    
                case CursorType::Wait:
                    irrCursor = ECI_WAIT;
                    break;
 
                    // Roll over normal/default
                case CursorType::Normal:
                default:
                    irrCursor = ECI_NORMAL;
                    break;
            }
            
            device->getCursorControl()->setActiveIcon(irrCursor);
        }
#endif
    }
    
    void Platform::GetCursorPos(Gwen::Point &p)
    {
        if (device)
        {
            p.x = device->getCursorControl()->getPosition().X;
            p.y = device->getCursorControl()->getPosition().Y;
        }
    }
    
    void Platform::GetDesktopSize(int &w, int &h)
    {
        if (device)
        {
            w = device->getVideoDriver()->getScreenSize().Width;
            h = device->getVideoDriver()->getScreenSize().Height;
        }
    }
    
    // Super basic clipboard
    Gwen::String Platform::GetClipboardText()
    {
        return clipboardString;
    }
    
    bool Platform::SetClipboardText(const String &str)
    {
        clipboardString = str;
        return true;
    }
    
    float Platform::GetTimeInSeconds()
    {
        // Laziness. Is irrlicht's clock any better?
        float fSeconds = (float)clock()/(float)CLOCKS_PER_SEC;
        return fSeconds;
    }
    
    // @TODO: Finish these up in a cross platform way if possible
    // Or at least do it for Mac/Linux as Windows platform will be used if possible with GWEN
    bool Platform::FileOpen(const String &Name, const String &StartPath, const String &Extension, Gwen::Event::Handler *pHandler, Event::Handler::FunctionWithInformation fnCallback)
    {
        return false;
    }
    
    bool Platform::FileSave(const String &Name, const String &StartPath, const String &Extension, Gwen::Event::Handler *pHandler, Event::Handler::FunctionWithInformation fnCallback)
    {
        return false;
    }
    
    bool Platform::FolderOpen(const String &Name, const String &StartPath, Gwen::Event::Handler *pHandler, Event::Handler::FunctionWithInformation fnCallback)
    {
        return false;
    }
    
    // @NOTE: @TODO: Haven't attempted/looked into these yet but
    // I think Irrlicht handles all this for us
    void* CreatePlatformWindow(int x, int y, int w, int h, const Gwen::String& strWindowTitle) { return nullptr; }
    void Platform::DestroyPlatformWindow(void* pPtr) { }
    void Platform::SetBoundsPlatformWindow(void* pPtr, int x, int y, int w, int h) { }
    void Platform::MessagePump(void* pWindow, Gwen::Controls::Canvas* ptarget) { }
    bool Platform::HasFocusPlatformWindow(void* pPtr) { return true; }
    void Platform::SetWindowMaximized(void* pPtr, bool bMaximized, Gwen::Point& pNewPos, Gwen::Point& pNewSize) { }
    void Platform::SetWindowMinimized(void* pPtr, bool bMinimized) { }
    
}
 
#endif // defined GWEN_PLATFORM_IRR
 
I haven't had a chance to test out the cursor sprite bank features in Irrlicht so if any body has more experience with them let me know if I screwed it up horribly. I'm planning on using sprite banks eventually so that our cursors will be uniform across platforms. The apple cursors work currently but not all of them are available in NSCursor (WFT Apple?) and will make things like resizable controls in Gwen a lot easier to use on Mac. My plan is to eventually remove the apple specific code or move it to its own gwen platform file if I can't get the Irrlicht one to perform all features in a cross platform manner.

I was going to upload my WIP black and orange theme for Gwen (drop in replacement PSD). I'm still pretty new to the form here so if there is a place I can upload a .PSD file to the forum that would be cool to share it with you guys.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

I think I'll fork the GWEN git repo since Garry Newman seems to have abandoned the project then we will have a place for all this stuff. Some screenshots would be nice if you have them, I too am using a custom 'charcoal glass' theme that looks pretty nice. I don't want to miss out on TTF fonts however I've not released my application yet so i'm banking on Irrlicht 1.9 release to come out before my project is ready. :P
Dream Big Or Go Home.
Help Me Help You.
beasthacker
Posts: 15
Joined: Fri Jul 25, 2014 3:51 pm

Re: GWEN Irrlicht Renderer

Post by beasthacker »

Sounds good to me. Not sure why Garry abandoned it, but from what I gather he's doing the C# thing currently with Unity for rust AFAIK.

You may be interested to check out an existing fork of Gwen at https://github.com/billyquith/GWork. This is actually the fork I'm using (didn't realize it wasn't the original when I first got it :roll:). Its been working good for me so far and may be a candidate for a fork if you prefer the formatting style, lack of dependency on Bootil and UTF8 everywhere. This fork also includes an SDL2 renderer and Allegro renderer for Gwen. The Allegro renderer also has the Texture caching implemented so it may be a good reference down the line regardless. It shouldn't make a big difference either way as the Irrlicht renderer portion works fine on both with maybe the only exception being measuring strings.

I can at least post Screens for the unit tests in some themes. I'll have to ask my boss about screenshots from my current project though. I could also probably whip something simple up just to show the GUI over 3D. If you have a place to upload them let me know. I may just put some imgurs on here temporarily so at least people checking out the post can get an idea of what Gwen is.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

The unit-tests are perfect. I'm kinda stuck using garry's fork after spending two weeks binding 72 of the control classes into lua, 30,000 lines of code later I'm not going to switch :P I'm happy to hear though this has helped someone in a commercial application!
Dream Big Or Go Home.
Help Me Help You.
Post Reply