Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Maybe projection/clipping bug?

Help
mirtch
2006-06-14
2013-04-17
  • mirtch
    mirtch
    2006-06-14

    Hello HM,

    I use vincent for a map display app. So big question for me was: How to use the coordinates (long, lat) as fixed-point values without modifying their values before rendering. If I would use them through the floating point compatibility layer it wouldn't be too fast and the values would overflow through conversion. So I use them directly and adjust the scale accordingly.

    In my test app I render a line (street segment). If I move the camera towards the street it suddenly disappears.

    The commented lines are the opengl-es calls used with vincent. (Btw: If I run the app with the rasterioid from hybrid it looks as expected).

    Could it be some projection/clipping bug or is my scaling approach wrong? I already turned off the clipping for this line and then I saw that the first point got some confusing y-coordinate change. Thanks for help!

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

    float heading = 90.0;
    float lookupdown = 68;
    float xpos = 952568.0;
    float ypos = 4326122.0;
    float zpos = 91.0;

    #ifndef PI
    #define PI 3.141592653589
    #endif

    #ifndef DEG_RAD
    #define DEG_RAD(x) x * PI / 180.0
    #endif

    void display(void)
    {
       glLoadIdentity();
      
       glScalef(1/30.0, -1/30.0, 1/30.0);
       //glScalef(65536/30.0, -65536/30.0, 65536/30.0); OPENGL-ES
       float scenerot = 360.0 - heading;
       glRotatef(lookupdown, 1.0, 0.0, 0.0);
       glRotatef(scenerot, 0.0, 0.0, 1.0);
       glTranslatef(-xpos, -ypos, -zpos);
       //glTranslatex(-xpos, -ypos, -zpos); OPENGL-ES

       glClearColor(1.0, 1.0, 1.0, 0);
       glClear(GL_COLOR_BUFFER_BIT);
       glColor3f(0.0, 0.0, 1.0);

       float pPoints[4];
       //int pPoints[4]; OPENGL-ES

       // P1
       pPoints[0] = 952673.0;  // some longitude in metres (sinusoidal projection)
       pPoints[1] = 4326157.0; // some latitude in metres

       // P2
       pPoints[2] = 952856.0;
       pPoints[3] = 4326034.0;
      
      
       //glVertexPointer(2, GL_FIXED, 2*sizeof(GL_FIXED), pPoints); OPENGL-ES
       glVertexPointer(2, GL_FLOAT, 2*sizeof(GL_FLOAT), pPoints);
      
       glDrawArrays(GL_LINES, 0, 2);
       glutSwapBuffers();
    }

    void reshape(int w, int h)
    {
       glViewport(0, 0, (GLsizei)h, (GLsizei)w);
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(45.0, 400.0/240.0, 1, 100);
       glMatrixMode(GL_MODELVIEW);
    }

    void init()
    {
       glEnableClientState(GL_VERTEX_ARRAY); 
    }

    void keyboard(unsigned char key, int x, int y)
    {
      switch(key)
      {
          case 3: /* ctrl+c */
            exit(0);
            break;
          case 115: /* s */
            xpos -= (float)sin(DEG_RAD(heading)) * 10;
              ypos += (float)cos(DEG_RAD(heading)) * 10;
            break;
          case 119: /* w */
             xpos += (float)sin(DEG_RAD(heading)) * 10;
               ypos -= (float)cos(DEG_RAD(heading)) * 10;
             break;
       };
      glutPostRedisplay();
    }

    int main(int argc, char **argv)
    {
      glutInit(&argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      glutInitWindowSize(400, 240);
      glutCreateWindow(argv[0]);
     
      init();
     
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc(keyboard);
      glutMainLoop();
      return 0;
    }

    m.mirtschink

     
    • Just looking at the coordinates, this looks as if you'd always run into overflow situations. (e.g. glTranslatef(-xpos, -ypos, -zpos); with the values defined above).

      - HM

       
    • mirtch
      mirtch
      2006-06-14

      the commented lines i.e. glTranslatex(-xpos, -ypos, -zpos) i use with vincent so i could not detect some overflow through debugger

       
    • Where did you set the breakpoins when you say "I could not detect some overflow"? Did you really step through the actual coordinate transformation code?

      - HM

       
    • PS: Just so you understand: Vincent is implements "common light", i.e. the transformation is done using 16.16 fixed point representation. Hybrid uses a custom floating point implementation for this part, in order to qualify for "common".

      - HM

       
    • mirtch
      mirtch
      2006-06-16

      Hello Hans-Martin,

      Thanks for your reply!

      First I checked proper matrix generation (i.e. CreateTranslate, CreateRotate, CreateScale).

      Then I set bp at ContextRender::SelectArrayElement() after CalcCC(). I could not detect any overflows in both clipCoords and eyecoords.

      At least I skipped the clipping for the line as follows in ContextLines.cpp:

      ...
      array1[0] = &from;
      array1[1] = &to;

      size_t numVertices = ClipPrimitive(2, array1, array2, &result);

      result[0] = &from; // revert the clipping step
      result[1] = &to; // revert the clipping step

      if (numVertices >= 2) {
      ...

      And after this I saw that the line is shown correct. But if the y-coord of the clipcoords (after some more steps toward) changes from negative to positive then the point is warped and the culling mask completely changes.

      Hybrid uses in both profiles floating points? How they get that fast on ARM?

      regards,
      m.mirtschink

       
      • Do you have a negative w value before clipping?

        BTW, which timezone are you in? Send me an email and we can set up an IM session...

        - HM