Rendering artefact using OpenGL and IwGx/font rendering

Home / Forums / Marmalade Archive / IwGxFont / Rendering artefact using OpenGL and IwGx/font rendering
7 replies [Last post]
by: Danny Chapman
Status: Offline
Joined: 2011-11-03
Points: 2630

My app uses OpenGL to render almost everything when in game, but I would like to be able to render/overlay text as well. I can do this with no problems in the simulator - basically doing this:

1. Render all OpenGL, including clearing depth and colour buffers. This involves setting up the full-screen viewport, clearing depth and colour, rendering a skybox (without z test/writes), then rendering 3D geometry (and finally some 2D textures on the top for the UI).

2. Flush my OpenGL (not sure if this would be expected to be needed):

  glFlush();

3. Clear the depth buffer, even though I don't see why the font rendering should need it (if I don't, my OpenGL rendering is corrupted, though I don't know why):

    IwGxClear(IW_GX_DEPTH_BUFFER_F); // Or use glClear

4. Render the text using:

  CIwGxFont* font = (CIwGxFont*) IwGetResManager()->GetResNamed("font_large", IW_GX_RESTYPE_FONT);
  IwGxFontSetFont(font);
  CIwColour origColour = IwGxFontGetCol();
  IwGxFontSetCol(0xffa0a0a0);
  IwGxLightingOn();
  uint16 fontHeight = font->GetHeight();
  IwGxFontSetRect(CIwRect(0,(int16)IwGxGetScreenHeight() - fontHeight*5/4,(int16)IwGxGetScreenWidth(),fontHeight));
  IwGxFontSetAlignmentHor(IW_GX_FONT_ALIGN_CENTRE);
  // fill in txt here
  IwGxFontDrawText(txt);
  // tidy up
  IwGxFontSetCol(origColour);
  IwGxLightingOff();

3. Call

    IwGxFlush();
    IwGxSwapBuffers();

In the simulator, this works fine. However, under Android the top left of the display does not render my OpenGL correctly - in this region the depth buffer seems to be modified by the font rendering so that the terrain does not render over the skybox - see here:

http://www.rowlhouse.co.uk/PicaSim/IwGxFontBug.jpg

In this region sometimes the 3D geometry shows through, and sometimes, as in this picture, you get z-fighting so partial rendering of the 3D geometry.

I've also tried pretty much every modification to this I can think of - trying to use suggestions in the docs (rather incomplete) and the Marmalade FAQ http://www.drmop.com/index.php/marmalade-sdk-faq/ Many of these alternatives (including splitting up the font rendering so that it uses IwGxFontPrepareText before my OpoenGL calls to prepare the text, and then renders afterwards) work correctly on the simulator, but none so far work correctly on device.

I'm using in the icf file:
[GX]
Rasterisation=HW
Transform=HW

but haven't had any success with Transform=SW either.

Any ideas? I'm on the brink of giving up on this and writing my own text rendering system in OpenGL...

by: Danny Chapman
Status: Offline
Joined: 2011-11-03
Points: 2630
The "fix" for this is to

The "fix" for this is to disable OpenGL depth writes and tests prior to doing the font rendering.

It doesn't explain why IwGx renders in that corner.

It is also very unsatisfactory how IwGx interacts so badly with direct OpenGL calls, and provides no nice ways to help the app code keep IwGx in sync with OpenGL.

It's also a bug, presumably, that the rendering is so very different on Android and Windows. Doesn't give me much confidence it will work on iOS etc.

I wrote a more complete reply but these terrible boards lost it.

by: Brandon Moro
Status: Offline
Joined: 2012-06-23
Points: 160
I'm having a similar issue ..

I'm having a similar issue ... I too am trying to get IwGxFont rendering on top of my straight GL2.0 rendering code. Once I identified and fixed the GL state setting issues, it works properly in the simulator, but on the iPhone I get what looks like a black quad over the majority of the scene, obscuring my GL rendering. I see the font render properly, along with the corner-hopping Marmalade icon ... but my GL rendering only appears along the margins (even full screen quads).

Any help here would be appreciated ... like you, I'd prefer not to write my own font rendering code again, but it looks like I'm heading in that direction.

by: Danny Chapman
Status: Offline
Joined: 2011-11-03
Points: 2630
Here's what I do:

Here's what I do:

1. I do all my OpenGL rendering, excluding the swap buffers.

2. I prepare to call my IwGx overlay code by doing:

PrepareForIwGx(false);

DisableDepthMask disableDepthMask;
DisableDepthTest disableDepthTest;

3. I call my IwGx overlay, which does things like:

CIwGxFont* font = GetFont(gs);
IwGxFontSetFont(font);

CIwColour origColour = IwGxFontGetCol();

IwGxFontSetCol(0xffa0a0a0);
IwGxLightingOn();
uint16 fontHeight = font->GetHeight();
IwGxFontSetRect(CIwRect(0,(int16)IwGxGetScreenHeight() - fontHeight*5/4,(int16)IwGxGetScreenWidth(),fontHeight));
IwGxFontSetAlignmentHor(IW_GX_FONT_ALIGN_CENTRE);

IwGxFontDrawText("Blah");

IwGxFontSetCol(origColour);
IwGxLightingOff();

4. Then flush and clean up:

IwGxFlush();
IwGxSwapBuffers();

RecoverFromIwGx(false);

I'd like to see your "state setting issues" solution. I found this to be a matter of poking around in the dark (no documentation, and of course, absolutely no help from marmalade staff here when I asked). I came up with the following awful hackery (for OpenGL 1):

tatic GLfloat UITextureMatrix[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};

void RecoverFromIwGx(bool clear)
{
// Marmalade clobbers some of these
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glMatrixMode( GL_TEXTURE );
glLoadIdentity();

glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glMatrixMode( GL_TEXTURE );
glGetFloatv(GL_TEXTURE_MATRIX, UITextureMatrix);
glLoadIdentity();

glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glShadeModel(GL_SMOOTH);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

float col = 0.0f;
glClearColor(col, col, col, 1.0);
if (clear)
{
IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F);
IwGxFlush();
IwGxSwapBuffers();
}
}

void PrepareForIwGx(bool clear)
{
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glShadeModel(GL_FLAT);

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glMultMatrixf(UITextureMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

float col = 1.0f;
glClearColor(col, col, col, 1.0f);
if (clear)
{
IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F);
IwGxFlush();
IwGxSwapBuffers();
}
}

I hope some of this is useful. With all this (and numerous other workarounds - for example to fix up the portrait/landscape difference (BUG) with iOS and Android etc) things work for me on Android, iOS and Windows.

by: Brandon Moro
Status: Offline
Joined: 2012-06-23
Points: 160
Thanks for the code, that is

Thanks for the code, that is mostly what I was doing. My GL code is GLES2, so some of that stuff doesn't apply and I'm still having my odd black square on iOS only (not in simulator).

As for the GL state setting, I just wrote a function that prints out all of GL's current state (glIsEnabled(), etc), and did a run where I printed that out before and after IwGxFont rendering to see what states it shifted (and then added code to get them back to my expected values).

by: Brandon Moro
Status: Offline
Joined: 2012-06-23
Points: 160
so, to close this up, I

so, to close this up, I eventually tracked down my remaining issue ... it actually wasn't a GL issue, but a floating point issue. It would seem that using IwGx must at some point affect floating point precision / operation, as by only changing my render loop, some totally unrelated floating point code started producing NaNs.

It was my bad, code ended up using a floating point variable that wasn't initialized until just afterwards ... but consistently, using IwGL that worked fine (producing a 0.0f), and using IwGx it would produce a NaN.

by: Danny Chapman
Status: Offline
Joined: 2011-11-03
Points: 2630
I still have problems with

I still have problems with this actually - with my workarounds as described above I can mix GL calls with Gx/font rendering and all is well. However, if I suspend/resume the app then I get the weird depth buffer/masking problems as described above.

This happens even if I suspend/resume during the font end - when I'm only using IwUI. It seems to resume OK, but when it runs the game I get the problem. I also have a problem with flipped lighting, as reported (and ignored) previously - on HTC Desire. Neither happens in the simulator (x86 or ARM) or on iOS.

by: AlexeyStotskiy
Status: Offline
Joined: 2012-08-03
Points: 20
Hi, guys, may you share some

Hi, guys, may you share some full working solution's example?

Latest Posts

Latest Comments

Top Contributors

  • Chris D : 27,010
  • MonRoyals : 26,970
  • Salman : 26,720
  • Jez Hammond : 20,130
  • pjan : 11,150
  • gjw : 10,350
  • Paolo Oliverio : 9,640
  • Beaker_2 : 8,390
  • Kite : 8,210
  • bluescrn : 7,810