Question

im learning to use openGL and iv been told that because my wheel arches are concave i have to tessellate them. So here is my code for the front wheel arch...

GLdouble car[7][2] = { {-1.93,0.3}, {-1.95,0.4}, {-2.2,0.6}, {-2.6,0.6}, {-2.82,0.4}, {-2.8,0.3}, {-2.78,0.0} };
GLUtesselator *tess = gluNewTess(); // create a tessellator

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);

glBegin(GL_POLYGON);

glTexCoord2f( 0.0 , 0.0 ); glVertex2f(-1.0 , 0.0 );
glTexCoord2f(-0.97, 0.0 ); glVertex2f(-1.97, 0.0 );

// Wheel arch
gluTessBeginContour(tess);
{
    gluTessVertex(tess, car[0], car[0]);
    gluTessVertex(tess, car[1], car[1]);
    gluTessVertex(tess, car[2], car[2]);
    gluTessVertex(tess, car[3], car[3]);
    gluTessVertex(tess, car[4], car[4]);
    gluTessVertex(tess, car[5], car[5]);
    gluTessVertex(tess, car[6], car[6]);
}
gluTessEndContour(tess);

And the car looks like this:

car

{i know the texturing is wrong atm too) but as you can see the front wheel arch hasnt changed even with the tessellation, so i guess im tessellating wrong.. or need to tessellate more of it.. or something? if someone could please help me with this massive problem im having with the wheel arches and rectify it i would be eternally gratefully as i have been struggling to get past this point for a while. thanks :)

The whole drawBody function code can be found here: http://pastebin.com/s9RpzMsd

Update: Thanks for all the help: my object now looks like this thanks to the tessellation help. Now just to texture :)

car better

Update 2: Ok so I used the same code roughly as PeterT suggested and this is what it ended up (had to make changes for it to compile. Point it out if its wrong)

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);

GLUtesselator *tess = gluNewTess(); // create a tessellator

gluTessCallback(tess, GLU_TESS_VERTEX,
               (void (__stdcall *)  ()) &putvertex);
gluTessCallback(tess, GLU_TESS_BEGIN,
               (void (__stdcall *)  ()) &glBegin);
gluTessCallback(tess, GLU_TESS_END,
               (void (__stdcall *)  ()) &glEnd);


gluTessBeginPolygon(tess, NULL);
gluTessBeginContour(tess);
    for(int i=0; i<29;i++)
        gluTessVertex(tess, car[i], car[i]);
        //call gluTessVertex for EVERY vertex in the polygon here 
    gluTessEndContour(tess);
gluTessEndPolygon(tess);
glDisable(GL_TEXTURE_2D);

With the putvertex code being:

void CALLBACK putvertex(GLdouble *verts)
{
//filled according to you texture coordinates:
GLdouble scalefacx = 1.0;
GLdouble scalefacy = 1.0;
GLdouble offsetx = -1.0;
GLdouble offsety = 0.0;
glVertex2dv(verts);
glTexCoord2d(verts[0]*scalefacx - offsetx,verts[1]*scalefacy - offsety);
}

It then looks like this:

car texture

Have i gone wrong somewhere? :/

Thanks for all your help, the final image looks like this:

car finished

Again thanks for all your help! Especially PeterT :)

Was it helpful?

Solution

You can't just tessellate part of the polygyon and it'll work, you need to tessellate the whole polygon, something like this:

   //fix for windows C++:
   #ifndef CALLBACK
   #define CALLBACK
   #endif

   tobj = gluNewTess();
   gluTessCallback(tobj, GLU_TESS_VERTEX,
                   (GLvoid (CALLBACK*) ()) &glVertex3dv);
   gluTessCallback(tobj, GLU_TESS_BEGIN,
                   (GLvoid (CALLBACK*) ()) &glBegin);
   gluTessCallback(tobj, GLU_TESS_END,
                   (GLvoid (CALLBACK*) ()) &glEnd);

   gluTessBeginPolygon(tobj, NULL);
      gluTessBeginContour(tobj);
         for(int i=0; i<7;i++)
           gluTessVertex(tobj, car[i], car[i]);
         //call gluTessVertex for EVERY vertex in the polygon here 
      gluTessEndContour(tobj);
   gluTessEndPolygon(tobj);

Also, you need to specify all 3 components of the vertices as GLdouble. So it would be something like this (still missing some vertices of course):

GLdouble car[7][3] = { {-1.93,0.3,0.0}, {-1.95,0.4,0.0}, {-2.2,0.6,0.0}, {-2.6,0.6,0.0}, {-2.82,0.4,0.0}, {-2.8,0.3,0.0}, {-2.78,0.0,0.0} };

In order to give every vertex a texture coordinate, you need to write your own function that takes a void *(which will contain a pointer to the x,y,z coordinates of the vertex) and calls glVertex and glTexCoord.

Also you should avoid doing tesselation every frame, so you should either save the calls between gluTessBeginPolygon and gluTessEndPolygon in a Display list, or better yet have your GLU_TESS_VERTEX function save the vertices in a VBO.

You might also have to define the GLU_TESS_COMBINE callback, look here and here for details and more sample code.

edit2: Actually texturing is not quite so easy. This is some old deprecated code, that probably still works for you but is very unreliable especially if you use shaders. For a more modern version, look at this Thread. You should remove the glTexCoord2d() calls and this has to go into the draw function:

//adjust these values to the object/texture size
GLfloat scalex = 1.0;
GLfloat scaley = 1.0;
GLfloat offsetx= 0.0;
GLfloat offsety= 0.0;

//GLdouble gens[4] = {1.0,0.0,0.0,0.0};
//GLdouble gent[4] = {0.0,1.0,0.0,0.0};
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

glTexGend(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGend(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
//glTexGendv(GL_S,GL_OBJECT_PLANE,gens);
//glTexGendv(GL_T,GL_OBJECT_PLANE,gent);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(scalex,scaley,1.0f);
glTranslatef(offsetx,offsety,0.0);

//do the normal rendering
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
...

Also, remember that tessellating every frame is still not a good idea for anything but small tests, rather using it together with display list or VBOs as stated previously would be more effective.

OTHER TIPS

gluTesselator will not make one single convex polygon from a concave polygon, because that's mathematically impossible. It emits multiple primitive groups (GL_POLYGON, GL_TRIANGLE, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN), and that's what you need to pass to OpenGL. Add tesselator callbacks to glBegin and glEnd as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top