# Issues with coplanar surfaces on MBX

**URL:** <https://forums.imgtec.com/t/issues-with-coplanar-surfaces-on-mbx/336>\
**Category:** PowerVR Insider\
**Created:** [April 27, 2009, 1:22am UTC](https://forums.imgtec.com/t/issues-with-coplanar-surfaces-on-mbx/336 "2009-04-27T01:22:39Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![iswhite](https://avatars.discourse-cdn.com/v4/letter/i/ccd318/32.png) [@iswhite](https://forums.imgtec.com/u/iswhite)\
**Post date:** [April 27, 2009, 1:22am UTC](https://forums.imgtec.com/t/issues-with-coplanar-surfaces-on-mbx/336/1 "2009-04-27T01:22:39Z")

</div>

Hello,

  

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

&nbsp;
  

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

&nbsp;
  

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.&nbsp;&nbsp; I'm using a 24-bit depth buffer and rgb565 for color.&nbsp;My drawing code can be found below.&nbsp; The code&nbsp;draws a&nbsp;blue rectangle inside&nbsp;a larger red one and rotates it slowly.&nbsp; On the 2530 there is flickering between the red and blue rectangles whenever the rectangle is not facing the screen directly.&nbsp; On the PC there is no flickering.&nbsp; I hope someone can point out to me if I'm doing something wrong or if there is&nbsp;is some fundamental difference between the PC and the MBX.
  

&nbsp;
  

&nbsp;

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

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

&nbsp;glMatrixMode(GL\_PROJECTION);  
&nbsp;glLoadIdentity();

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

&nbsp;glMatrixMode(GL\_MODELVIEW);  
&nbsp;glLoadIdentity();

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

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

&nbsp;static const GLushort indices[4] = { 0, 2 , 3, 1 };  
&nbsp;glEnableClientState( GL\_VERTEX\_ARRAY );  
&nbsp;glVertexPointer( 2, GL\_SHORT, 0, vertices );  
&nbsp;glDrawElements( GL\_TRIANGLE\_FAN, 4, GL\_UNSIGNED\_SHORT, indices );  
&nbsp;glDisableClientState( GL\_VERTEX\_ARRAY );  
}

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

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

&nbsp;glPushMatrix();

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

&nbsp;// Draw depth buffer face  
&nbsp;glEnable( GL\_DEPTH\_TEST );  
&nbsp;glDepthFunc( GL\_LESS );  
&nbsp;glColorMask( GL\_FALSE, GL\_FALSE, GL\_FALSE, GL\_FALSE );&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glDepthMask( GL\_TRUE ); 

&nbsp;glEnable( GL\_POLYGON\_OFFSET\_FILL );&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPolygonOffset (factor, unit );

&nbsp;DrawRectangle( x, y, width, height );  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPolygonOffset( 0.0f, 0.0f );  
&nbsp;glDisable( GL\_POLYGON\_OFFSET\_FILL );  
&nbsp;&nbsp;&nbsp;  
&nbsp;glColorMask( GL\_TRUE, GL\_TRUE, GL\_TRUE, GL\_TRUE );  
&nbsp;glDepthMask( GL\_FALSE );

&nbsp;

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

&nbsp;

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

&nbsp;glDepthMask( GL\_TRUE );  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPopMatrix();  
}

&nbsp;

...

&nbsp;

  
&nbsp;SetPerspective();

&nbsp;glEnable( GL\_DEPTH\_TEST) ;  
&nbsp;glDisable( GL\_LIGHTING );  
&nbsp;glDisable( GL\_CULL\_FACE );  
&nbsp;glDisable( GL\_TEXTURE\_2D );

&nbsp;bool quit = false;  
&nbsp;while( !quit ) {  
&nbsp;&nbsp;&nbsp;&nbsp; glClear( GL\_COLOR\_BUFFER\_BIT | GL\_DEPTH\_BUFFER\_BIT );

&nbsp;&nbsp;&nbsp;&nbsp; Draw();  
&nbsp;&nbsp;&nbsp;&nbsp; eglSwapBuffers( g\_EglDisplay, g\_EglSurface );

&nbsp;

&nbsp; ...

&nbsp;

[/CODE]

&nbsp;

&nbsp;

&nbsp;
[CODE]  

&nbsp;
  

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

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

&nbsp;glMatrixMode(GL\_PROJECTION);  
&nbsp;glLoadIdentity();
  

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

&nbsp;glMatrixMode(GL\_MODELVIEW);  
&nbsp;glLoadIdentity();
  

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

  

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

&nbsp;static const GLushort indices[4] = { 0, 2 , 3, 1 };  
&nbsp;glEnableClientState( GL\_VERTEX\_ARRAY );  
&nbsp;glVertexPointer( 2, GL\_SHORT, 0, vertices );  
&nbsp;glDrawElements( GL\_TRIANGLE\_FAN, 4, GL\_UNSIGNED\_SHORT, indices );  
&nbsp;glDisableClientState( GL\_VERTEX\_ARRAY );  
}
  

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

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

&nbsp;glPushMatrix();
  

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

&nbsp;// Draw depth buffer face  
&nbsp;glEnable( GL\_DEPTH\_TEST );  
&nbsp;glDepthFunc( GL\_LESS );  
&nbsp;glColorMask( GL\_FALSE, GL\_FALSE, GL\_FALSE, GL\_FALSE );&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glDepthMask( GL\_TRUE ); 
  

&nbsp;glEnable( GL\_POLYGON\_OFFSET\_FILL );&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPolygonOffset (factor, unit );
  

&nbsp;DrawRectangle( x, y, width, height );  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPolygonOffset( 0.0f, 0.0f );  
&nbsp;glDisable( GL\_POLYGON\_OFFSET\_FILL );  
&nbsp;&nbsp;&nbsp;  
&nbsp;glColorMask( GL\_TRUE, GL\_TRUE, GL\_TRUE, GL\_TRUE );  
&nbsp;glDepthMask( GL\_FALSE );
  

&nbsp;
  

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

&nbsp;
  

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

&nbsp;glDepthMask( GL\_TRUE );  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;glPopMatrix();  
}
  

&nbsp;
  

...
  

&nbsp;
  

  
&nbsp;SetPerspective();
  

&nbsp;glEnable( GL\_DEPTH\_TEST) ;  
&nbsp;glDisable( GL\_LIGHTING );  
&nbsp;glDisable( GL\_CULL\_FACE );  
&nbsp;glDisable( GL\_TEXTURE\_2D );
  

&nbsp;bool quit = false;  
&nbsp;while( !quit ) {  
&nbsp;&nbsp;&nbsp;&nbsp; glClear( GL\_COLOR\_BUFFER\_BIT | GL\_DEPTH\_BUFFER\_BIT );
  

&nbsp;&nbsp;&nbsp;&nbsp; Draw();  
&nbsp;&nbsp;&nbsp;&nbsp; eglSwapBuffers( g\_EglDisplay, g\_EglSurface );
  

&nbsp;
  

&nbsp; ...
  

&nbsp;
  

[/CODE]
  

&nbsp;
  

&nbsp;
  

&nbsp;

---

<div class="post-metadata">

**Author:** ![CarlosSarria](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.imgtec.com/carlossarria/32/263_2.png) [@CarlosSarria](https://forums.imgtec.com/u/CarlosSarria)\
**Post date:** [April 28, 2009, 1:30pm UTC](https://forums.imgtec.com/t/issues-with-coplanar-surfaces-on-mbx/336/2 "2009-04-28T13:30:05Z")

</div>

Hello,
  

&nbsp;
  

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&nbsp;it should&nbsp;fail in the same way. 
  

You could try&nbsp;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.
  

&nbsp;
  

Best regards.
  

&nbsp;
  

Carlos.

---

<div class="post-metadata">

**Author:** ![iswhite](https://avatars.discourse-cdn.com/v4/letter/i/ccd318/32.png) [@iswhite](https://forums.imgtec.com/u/iswhite)\
**Post date:** [April 29, 2009, 11:18pm UTC](https://forums.imgtec.com/t/issues-with-coplanar-surfaces-on-mbx/336/3 "2009-04-29T23:18:29Z")

</div>

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

&nbsp;
  

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

&nbsp;
  

Thanks for the response,
  

Ian
  

&nbsp;
