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.
beasthacker
Posts: 15
Joined: Fri Jul 25, 2014 3:51 pm

Re: GWEN Irrlicht Renderer

Post by beasthacker »

Alright I've got a few images to show you guys Gwen running in Irrlicht. All of the images are using my dark / orange theme except one where I use the default Gwen theme. I whipped these up real quickly so there isn't a lot going on except a simple grid scene node but hopefully it will give everyone some idea of what's available.

People may be wondering why they would want to switch to Gwen from Irrlicht's default GUI. In a single word: "Events". No more Macro'd Unique ID keys for every single tiny GUI element you want to get events for. No more ungodly large event switch statements. Just setup your Gwen classes and all the GUI events take custom method callbacks that are much easier, cleaner and allow for data that is not predetermined at compile time. It has all the basic GUI widgets covered (more than I took screenshots of) and is easily customizable by editing the pre-existing PSD theme or creating your own. The downside of Gwen is that there is a lack of documentation so you'll probably be reading Gwen's sourcecode as you get started. The Unit Test source code is a good place to start to learn how to start your GUI in Gwen.

Unit Tests running over Irrlicht scene
Image

Checkboxes
Image

Collapsible List
Image

Color Picker
Image

Menus
Image

Image

Multi line Labels that wrap correctly
Image

Progress bars
Image

Tabs
Image

Text Input (Default Skin).
Image

You may notice dark text in a few areas. This is because Gwen will use a dark text color by default on some controls that aren't controlled by the theme yet. This won't be an issue in your own code as you can manually set the text color to something lighter.

Hopefully these can hangout on imgur without issues until we have a better place to upload them.

Here is the Gwen Theme file I'm using. I had to convert it to PNG to upload to imgur. In the future I'll get the PSD up so people can alter the colors if they want. Its not perfect yet but figured I'd share the work in progress anyways.

Dark-Orange Theme (recolor of Default)
Image

Also I am using a framerate limiter in my project so the FPS on the bottom may be inaccurate. All images were taken in OSX 10.9 with Irrlicht 1.8 build.

NOTE: These images are using TTF Fonts. I used the CGUITTFont class available at http://irrlicht.sourceforge.net/forum/v ... =6&t=37296. If you wish to use TTF before 1.9 release you can set the Font ('Text') member of the Irrlicht Gwen Renderer to use a CGUITTFont instance instead of the default font.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

I fixed an issue with void FreeTexture() today which would cause a crash on some machines when Irrlicht was running the DirectX 9 driver. The issue was that I was calling ->drop() on a reference counted pointer which Irrlicht automatically cleans up during device->drop(). I also did some code cleanup which involved removing a lot of variables which were being initialized for no good reason and could just be put into the function call they were being passed to. The renderer is now also const-correct, I see some small FPS increase on my end from all this.

I also went ahead and uncommented DrawLinedRect and DrawPixel as they appear to be working properly now. If anyone else is using this please test and see then report back here if it is!

:)
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 »

Both DrawPixel and DrawLinedRect are uncommented for me and I haven't noticed any issues with it. This is on Mac OSX 10.9 and Open GL Renderer for my current build.

I also experienced the crash issue on OpenGL with freeTexture() before. Instead of removing the call to ThisTex->drop() in FreeTexture(), I added in NewTex->grab() after getTexture() call in LoadTexture(). I haven't read Irrlicht source regarding textures being dropped when the device is dropped but generally from my understanding it's better to retain/grab objects that we would use in the renderer and then release/drop them when we're done. This way if something happens and the texture is drop()-ed by Irrlicht, etc the object won't be deallocated until FreeTexture() is called.

Without reading the source I don't know if this scenario is ever possible but from my experience this way is preferable. If you have any reason why this is a bad idea I'd love to know.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

I'm pretty sure you don't need to ->grab() the texture after ->getTexture() since it is reference counted inside the IReferenceCounted class. Check this post as I was pulling my hair out trying to figure out why it was crashing. http://irrlicht.sourceforge.net/forum/v ... 71#p289019

The crash was occurring in IReferenceCounted.h at line 134 which was a call to 'delete'
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 »

grab() will increment the reference count number. When the number reaches zero it is deallocated.

Your issue was because something like this happened:
1. Driver->getTexture() -- Texture created and reference count is one.
2. Driver calls drop() on the texture at some point -- Reference counter is zero and destructor is called, etc
3. Irrlicht renderer calls drop() on the same object which was already released or about to be. Either call to invalid pointer or something else bizarre like trying to delete random pointer!

My method would work like this:
1. Driver->getTexture() - Texture created with reference count of one.
2. We call grab() in LoadTexture() -- Reference count is now two
3. Driver calls drop() on texture at some point -- Reference count is back to one (not deallocated like usual)
4. We keep the still valid texture around as long as required then call drop() during FreeTexture() -- reference count goes to zero and is deallocated, etc.

Your issue was caused because you didn't call grab() but drop() was called twice (once by you and driver). Of course removing drop() also works although if it is possible that a scenario arises where the driver drop()s a Texture before we call FreeTexture() there may be an invalid pointer hanging around which isn't good.

I don't know how likely that is but if we grab() it ourselves then we can rest assured that it won't be deallocated until FreeTexture() is called. Even if something funky happens with the driver.

Probably not a huge deal but something to be aware of.

Also I'm doing some testing with Texture cache so stay tuned!
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

Okay I understand now. I think the real solution here would be to not use grab() or drop() but instead call Driver->removeTexture() hehe. I'm looking very forward to seeing what you do with ICacheToTexture! Even if you don't get it working it would at least give me a basis to try and implement it myself :)

I'm also thinking about forking the git repo for gwen to fix/improve things myself. I've submitted 9 but reports so far and none of them have been answered! but that's Garry Newman for you.... :>
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 created the GIT repo and uploaded my version of GWEN that I've been using which has a couple bug fixes as well as the Irrlicht renderer and my lua bindings. All future updates to the code here in this post will be uploaded there. https://github.com/kklouzal/GWEN

The Irrlicht renderer I've got there has the texture caching support however controls that are set to cache to a texture are drawing completely black. I'll look into it more later but I'm still looking forward to anyone elses input on how it should be done!
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 »

Hey. I'm not at the office today but I was checking out your Texture caching implementation.

For the most part its pretty similar to what I came up with, set/reset render target during start/finish methods and add new render target texture during the create method.

I am also having issues with black or no controls. You'll need to clear the render target during setup to SColor(0,0,0,0) to get rid of it (if i remember correctly). From what I can tell from Gwen's source the setupCacheTexture() method is only called when the control will redraw itself and its children so we shouldn't have to worry about clearing anything important hopefully.

Even though I got rid of black controls in my code, the Gwen controls don't appear to be drawing to the render target.

I haven't tested it yet but my theory is that maybe the Controls are being drawn at their normal Origin instead of 0,0 for the new render target? I was going to do a test with a new boolean flag in the Renderer that will be flipped when a Control is being drawn to the Cache and then ensure that the base control is drawn at 0,0 origin in the cache render target. The normal render methods are called between calls to setupCacheTexture and finishCacheTexture so maybe we need to prevent the usual transformation of controls and instead draw them in local space in the cache render target?

Also another thing that I realized was that the Device->addRenderTarget() method documentation says that the resolution of the new render target should be base 2. In my code I do a little bit shifting to get the next largest base 2 number for the height and width of the new render target.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

Well I tried something, I set the size of the render target to be the size of the entire Irrlicht window, then I made the texture draw in the upper left corner so it covered the entire window, no control showed up anywhere on the texture. During setup I also cleared the texture to white, black, and red, still no control showed up anywhere. For whatever reason I don't think the individual control's render/draw function is being called, I'm going to look into this a little further..

EDIT: No, their draw functions from the renderer itself are being called and their being called into the correct locations(I did some print debugging). So I don't know here, maybe were not setting up the render to texture properly.

EDIT EDIT: So I decided to throw a call to draw2DLine() into the FinishCacheTexture function right before we reset the render target, I drew it from the upper left screen coordinate to the bottom right and I noticed something strange, first of all the line showed up and it drew from the top left corner of the texture down to the bottom right, so Irrlicht is trying to draw the entire screen region into whatever size render texture we specify, and here is the most important part, it starts drawing it from the upper left corner of the screen into the upper left corner of the texture, so we need a function to offset the rendering bounds or something. I know this because I actually drug the control that was being cached up to the top left corner of the screen and it magically appeared onto the texture!
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 »

It sounds like you verified that they are being drawn which is great! Now just to get them in the right location. I don't have the code in front of me but here's some pseudo code to show my original idea:

Code: Select all

 
 
// In Gwen::Renderer::Irrlicht add a new member
public:
    bool IsDrawingToCache;
 
// In Gwen::Renderer::IrrlichtCTT::SetupCacheTexture()
Renderer->IsDrawingToCache = true;
 
// Then reset in Gwen::Renderer::IrrlichtCTT::FinishCacheTexture()
Renderer->IsDrawingToCache = false;
 
// In Gwen::Renderer::Irrlicht::DrawTexturedRect()
if (IsDrawingToCache == false)
{
    Translate(pTargetRect)
}
else
{
    // Do Nothing? Don't know off the top of my head but this may work?
    // Or Translate to local coordinates instead.
}
 
// Just thought of this but we could just make our own custom Translate method instead and call that in all the renderer methods?
// Then we won't have a bunch of if/else in our rendering code and instead keep it all in the new method?
 
Gwen::Renderer::Irrlicht::TranslateForRender(Gwen::Rect rect)
{
    if (!IsDrawingToCache)
        Translate(rect);
 }
 
Also FYI in my IrrlichtCTT class I made the 'Renderer' member of type Gwen::Renderer::Irrlicht instead of Gwen::Renderer::Base because Irrlicht renderer is required for it to work anyways :D
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

Getting rid of Translate() would solve the issue as the controls draw in the upper left corner when Translate() isn't called. I thought about doing what you propose but I feel like there might be a better way to approach this.
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 »

I'm curious now :o

I'll just lay out my concern for you though. I personally think that we should avoid changing Gwen's source where we can implement it in the renderer. (Not saying my idea is the best way by any means). That way anyone can use the Original Gwen source, another Fork or their own version (like me currently) without having to worry about the Irrlicht renderer/cache stuff breaking. I don't know what your idea is but I thought I'd mention it :D

Also I'm using the Color picker for cache testing because it should cache by default and is quite expensive (300+fps for other Controls goes down to 70fps for color picker!). Its probably a good one to use for performance testing once we get to that point.
beasthacker
Posts: 15
Joined: Fri Jul 25, 2014 3:51 pm

Re: GWEN Irrlicht Renderer

Post by beasthacker »

Oh and one more quick thing for you while we're on the topic of the texture caching.

From my look at gwen's source I have a sneaking suspicion that resizable controls will not renderer correctly with texture caching. Because the render target texture is created with the bounds of the Control and is only done once (AFAIK) if we have a Control like a docked sidebar that resizes or a window, etc. the cache may get clipped if it is resized larger than the original cache texture!

I'll have to do some testing but I thought it was worth mentioning. Although I suppose you just can disable caching in these cases manually. We could also do a check to see if bounds changed on the control and then create a new resized render target if that happens but I'm not sure if that's a good solution either.
kklouzal
Posts: 343
Joined: Sun Mar 28, 2010 8:14 pm
Location: USA - Arizona

Re: GWEN Irrlicht Renderer

Post by kklouzal »

All controls have texture caching disabled by default, but I suspect this issue your talking about may be what the Update method is for. Also, I just commented out all the Translate() functions in the renderer and tested, it didn't fix this issue, it just made the controls draw improperly. Back to the drawing board!
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 »

That's what I was thinking. Problem is that UpdateControlCacheTexture() is never called in Gwen source. Did a search and came up with nothing. Also I haven't seen anyone actually implement it in their own texture caching.

Color picker was setup to cache by default but I it may have been setup that way in the unit tests rather than the gwen source (i don't remember ha). But it is still has the highest performance impact of all the control's I've tested.

Can you tell me how they are being drawn improperly?

Also you should check out GetRenderOffset() in Renderer base. That is what is set when Gwen is drawing controls to cache. It may shed some light on the issue. I know Translate() uses the render offset value as well. That should give you a place to start looking at least. Sorry I can't be of more use without the source in front of me.


I'll be back at the office in a few hours and do some tests of my own. Let me know if you have any luck in the meantime! :D
Post Reply