I've been running into a problem with Mesa, both 3.0 and 3.1, where small
triangles (less than ~1/4 pixel across) aren't rendered.  When I use
OpenGL instead, the image looks fine.

Randy Frank suggested I give this a try with trispd.c to see if I could
duplicate the problem.  His suggestion worked:

I've included the modified trispd.c.  It no longer does texturing, (or
filtering or persp. corr'n.).

More importantly, however, it uses individual triangles instead of
triangle strips to fill the screen.

Try running the program as:
  trispd -size 0.3
and then
  trispd -size 0.2

The first picture should look fine, but the second has NO triangles drawn.

If curious, I narrowed the cutoff down further:  at a size of 0.2237 it's
fine, at 0.2235 it's empty, and at 0.2236 it fills a few pixels if the
starting X and Y coords are not exactly 1.0 (see the code for comments).

Again, when I linked with OpenGL, I was unable to find any cutoff for
minimum pixel size.  I managed to go down to 0.01 before my patience gave
out.

I suspect this part of the actual rasterization code has not changed
significantly between 3.0 and 3.1 since my first test case looks the same 
between these version.  Since I am still using 3.0 for the public version
of our code, if this is an easy fix and can be propogated back to 3.0 I
would love to hear about it.

Thanks!

------------------------------------------ - - - - - - - - - - - - - - -
Jeremy Meredith                           |   email: [EMAIL PROTECTED]
Lawrence Livermore National Laboratory    |   phone: (925) 422-1197
P.O. Box 808  L-98                        |   fax  : (925) 422-3389
Livermore, CA 94550                       |   loc  : bldg 132N room 1025
/*
 * File modified by Jeremy Meredith ([EMAIL PROTECTED]) --
 * derived from trispd.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <GL/glut.h>


static float Width = 140.0;
static float Height = 140.0;
static float Size = 5;


static void Idle( void )
{
   glutPostRedisplay();
}


static void Display( void )
{
   float x, y;
   float xStep;
   float yStep;
   int i;
   float red[3] = { 1.0, 0.0, 0.0 };
   float blue[3] = { 0.0, 0.0, 1.0 };

   /* Set `Size' to mean pixel width, not area */
   xStep = yStep = Size;

   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

   /*
    * The offset (.0001 or .00001) in the x and y start is just to 
    * prevent the values from lying perfectly on f.p. number boundaries.
    * It is not necessary to show the problem.
    */
   for (y=1.0001; y<Height-yStep; y+=yStep) {
       glBegin(GL_TRIANGLES);
       for (x=1.0001; x<Width-xStep; x+=xStep) {

           /* Do this as individual triangles, not a strip */
           glColor3fv(red);
           glVertex2f(x, y);
           glColor3fv(blue);
           glVertex2f(x, y+yStep);
           glColor3fv(red);
           glVertex2f(x+xStep, y);

           glColor3fv(blue);
           glVertex2f(x, y+yStep);
           glColor3fv(red);
           glVertex2f(x+xStep, y);
           glColor3fv(blue);
           glVertex2f(x+xStep, y+yStep);
       }
       glEnd();
   }
   
   glutSwapBuffers();
   printf("drawn\n");
}


static void Reshape( int width, int height )
{
   Width = width;
   Height = height;
   glViewport( 0, 0, width, height );
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
   glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}


static void Key( unsigned char key, int x, int y )
{
   (void) x;
   (void) y;
   switch (key) {
      case 27:
         exit(0);
         break;
   }
   glutPostRedisplay();
}


static void Init( int argc, char *argv[] )
{
   GLint shade;
   GLint rBits, gBits, bBits;

   int i;
   for (i=1; i<argc; i++) {
      if (strcmp(argv[i],"-dither")==0)
         glDisable(GL_DITHER);
      else if (strcmp(argv[i],"+dither")==0)
         glEnable(GL_DITHER);
      else if (strcmp(argv[i],"+smooth")==0)
         glShadeModel(GL_SMOOTH);
      else if (strcmp(argv[i],"+flat")==0)
         glShadeModel(GL_FLAT);
      else if (strcmp(argv[i],"+depth")==0)
         glEnable(GL_DEPTH_TEST);
      else if (strcmp(argv[i],"-depth")==0)
         glDisable(GL_DEPTH_TEST);
      else if (strcmp(argv[i],"-size")==0) {
         Size = atof(argv[i+1]);
         i++;
      }
      else
         printf("Unknown option: %s\n", argv[i]);
   }

   glGetIntegerv(GL_SHADE_MODEL, &shade);

   printf("Dither: %s\n", glIsEnabled(GL_DITHER) ? "on" : "off");
   printf("ShadeModel: %s\n", (shade==GL_FLAT) ? "flat" : "smooth");
   printf("DepthTest: %s\n", glIsEnabled(GL_DEPTH_TEST) ? "on" : "off");
   printf("Size: %f pixels\n", Size);

   glGetIntegerv(GL_RED_BITS, &rBits);
   glGetIntegerv(GL_GREEN_BITS, &gBits);
   glGetIntegerv(GL_BLUE_BITS, &bBits);
   printf("RedBits: %d  GreenBits: %d  BlueBits: %d\n", rBits, gBits, bBits);
}


static void Help( const char *program )
{
   printf("%s options:\n", program);
   printf("  +/-dither      enable/disable dithering\n");
   printf("  +/-depth       enable/disable depth test\n");
   printf("  +flat          flat shading\n");
   printf("  +smooth        smooth shading\n");
   printf("  -size pixels   specify pixels/triangle\n");
}


int main( int argc, char *argv[] )
{
   printf("For options:  %s -help\n", argv[0]);
   glutInit( &argc, argv );
   glutInitWindowSize( (int) Width, (int) Height );
   glutInitWindowPosition( 0, 0 );

   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );

   glutCreateWindow( argv[0] );

   if (argc==2 && strcmp(argv[1],"-help")==0) {
      Help(argv[0]);
      return 0;
   }

   Init( argc, argv );

   glutReshapeFunc( Reshape );
   glutKeyboardFunc( Key );
   glutDisplayFunc( Display );
   glutIdleFunc( Idle );

   glutMainLoop();
   return 0;
}

Reply via email to