Issues with coplanar surfaces on MBX

Hello,


I'm trying to draw 2D primitives on a 3D plane using OpenGL ES 1.1.  Basically, I want rectangular planes that can move in a 3D space acting like regular 3D objects.  On these surfaces i want to use the 3D hardware to draw 2D rectangular primitivies such as text, images, and solid colored rectangles. 
 

The major issue here is z-fighting due to the coplanar surfaces of drawing 2D primitives on top of one another.  To resolve this issue I've come up with the strategy to initially draw the 3D surface as rectangle only on the z-buffer, offset slightly using glPolygonOffset.  Then all the 2D primitives are drawn with a back to front ordering with the glDepthMask disabled but with depth testing on.  

 

This strategy works fine with the Imagination's PC implementation of 1.1 on Windows XP, however it fails to work our TI OMAP 2530 hardware running Windows CE 5.0.   I'm using a 24-bit depth buffer and rgb565 for color. My drawing code can be found below.  The code draws a blue rectangle inside a larger red one and rotates it slowly.  On the 2530 there is flickering between the red and blue rectangles whenever the rectangle is not facing the screen directly.  On the PC there is no flickering.  I hope someone can point out to me if I'm doing something wrong or if there is is some fundamental difference between the PC and the MBX.

 

 
void SetPerspective(void)
{
 const float PI = 3.141592f;
 float  fovy = 70.0f;
 float  aspect = (float)800/480;
 float       fW,fH;
 float  znear = 2.0f;
 float       zfar  = 10.0f;
 fH = (float)tan((double)fovy * PI / 360.0f)*znear;
 fW = fH * aspect;
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glFrustumf(-fW, fW, -fH, fH, znear, zfar);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glTranslatef(0.0f, 0.0f, -5.0f);
}
void DrawRectangle(int x, int y, int width, int height)
{
 GLshort vertices[8];
 vertices[0] = x;
 vertices[1] = y;
 vertices[2] = x + width;
 vertices[3] = y;
 vertices[4] = x;
 vertices[5] = y + height;
 vertices[6] = x + width;
 vertices[7] = y + height;
 static const GLushort indices[4] = { 0, 2 , 3, 1 };
 glEnableClientState( GL_VERTEX_ARRAY );
 glVertexPointer( 2, GL_SHORT, 0, vertices );
 glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, indices );
 glDisableClientState( GL_VERTEX_ARRAY );
}
void Draw()
{
 float factor = 1.1f;
 float unit = 4.0f;
 int x = -2;
 int y = -2;
 int width = 4;
 int height = 4;
 glPushMatrix();
 angle += 1.0f;
 if( angle >= 360.0f ) {
     angle = 0.0f;
 }
 glRotatef( angle, 0.0f, 1.0f, 0.0f );
 // Draw depth buffer face
 glEnable( GL_DEPTH_TEST );
 glDepthFunc( GL_LESS );
 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );    
 glDepthMask( GL_TRUE );
 glEnable( GL_POLYGON_OFFSET_FILL );    
 glPolygonOffset (factor, unit );
 DrawRectangle( x, y, width, height );
    
 glPolygonOffset( 0.0f, 0.0f );
 glDisable( GL_POLYGON_OFFSET_FILL );
   
 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
 glDepthMask( GL_FALSE );
 
 // Draw red rectangle    
 glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
 DrawRectangle( x, y, width, height );
 
 // Draw blue rectangle    
 glColor4f( 0.0f, 0.0f, 1.0f, 0.0f );
 DrawRectangle( x+1, y+1, width-2, height-2 );
 glDepthMask( GL_TRUE );
    
 glPopMatrix();
}
 
...
 

 SetPerspective();
 glEnable( GL_DEPTH_TEST) ;
 glDisable( GL_LIGHTING );
 glDisable( GL_CULL_FACE );
 glDisable( GL_TEXTURE_2D );
 bool quit = false;
 while( !quit ) {
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
     Draw();
     eglSwapBuffers( g_EglDisplay, g_EglSurface );
 
  ...
 
[/CODE]
 
 
 
[CODE]
 

void SetPerspective(void)
{
 const float PI = 3.141592f;
 float  fovy = 70.0f;
 float  aspect = (float)800/480;
 float       fW,fH;
 float  znear = 2.0f;
 float       zfar  = 10.0f;

 fH = (float)tan((double)fovy * PI / 360.0f)*znear;
 fW = fH * aspect;

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();

 glFrustumf(-fW, fW, -fH, fH, znear, zfar);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();

 glTranslatef(0.0f, 0.0f, -5.0f);
}

void DrawRectangle(int x, int y, int width, int height)
{
 GLshort vertices[8];
 vertices[0] = x;
 vertices[1] = y;
 vertices[2] = x + width;
 vertices[3] = y;
 vertices[4] = x;
 vertices[5] = y + height;
 vertices[6] = x + width;
 vertices[7] = y + height;

 static const GLushort indices[4] = { 0, 2 , 3, 1 };
 glEnableClientState( GL_VERTEX_ARRAY );
 glVertexPointer( 2, GL_SHORT, 0, vertices );
 glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, indices );
 glDisableClientState( GL_VERTEX_ARRAY );
}

void Draw()
{
 float factor = 1.1f;
 float unit = 4.0f;

 int x = -2;
 int y = -2;
 int width = 4;
 int height = 4;

 glPushMatrix();

 angle += 1.0f;
 if( angle >= 360.0f ) {
     angle = 0.0f;
 }
 glRotatef( angle, 0.0f, 1.0f, 0.0f );

 // Draw depth buffer face
 glEnable( GL_DEPTH_TEST );
 glDepthFunc( GL_LESS );
 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );    
 glDepthMask( GL_TRUE );

 glEnable( GL_POLYGON_OFFSET_FILL );    
 glPolygonOffset (factor, unit );

 DrawRectangle( x, y, width, height );
    
 glPolygonOffset( 0.0f, 0.0f );
 glDisable( GL_POLYGON_OFFSET_FILL );
   
 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
 glDepthMask( GL_FALSE );

 

 // Draw red rectangle    
 glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
 DrawRectangle( x, y, width, height );

 

 // Draw blue rectangle    
 glColor4f( 0.0f, 0.0f, 1.0f, 0.0f );
 DrawRectangle( x+1, y+1, width-2, height-2 );

 glDepthMask( GL_TRUE );
    
 glPopMatrix();
}

 

...

 


 SetPerspective();

 glEnable( GL_DEPTH_TEST) ;
 glDisable( GL_LIGHTING );
 glDisable( GL_CULL_FACE );
 glDisable( GL_TEXTURE_2D );

 bool quit = false;
 while( !quit ) {
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

     Draw();
     eglSwapBuffers( g_EglDisplay, g_EglSurface );

 

  ...

 

[/CODE]

 

 

 
Hello,

 

Sadly the answer is that polygon offset is not supported on MBX hardware. I have to reckon that The PCEmulation libraries should emulate this properly and it should fail in the same way.

You could try disabling writing to the depth buffer and submit the polygons somewhat ordered (draw all the opaque polygons first if you are going to try this).

Another alternative is to render the 2D primitives into a texture. This might be a good solution if the 2D content does not change very often.

 

Best regards.

 

Carlos.
That is unfortunate.  The problem with a back to front rendering is where two 3d planes intersect, then they should occlude each other.

 

I think I'll see if I can't find someway to imitate glPolygonOffset on the application side.

 

Thanks for the response,

Ian