Search code examples
algorithmopenglgraphicsdirectxtexture-mapping

Texture coordinates for triangle fans


I am trying to "fill" a surface of some geometry that I drew. I am using GL_TRIANGLE_FAN primitive. (for example : 1 hub (center) point and 12 other points). I have calculated texture coordinates for each vertex in the interval 0-1. But as a result I get this **image** , its a little bit confused. I desire to get result like that image . Please help, what is wrong here? How can I calculate correct texture coordinates in such Triangulation ( GL_TRIANGLE_FAN ) in the image red dots is my points

*Code - Snippet :

 assert(("CROSS type intersection needs only 5 vertices : center point and "
         "rest points in anticlockwise order", (lp->size() > 5) && (lp->size() < 5)));
 osg::Vec3 vAlong_1,vAlong_2;
 vAlong_1 = (*lp)[1] - (*lp)[4];
 vAlong_2 = (*lp)[1] - (*lp)[2];
 eps = ((*lp)[2] - (*lp)[4]).length() * 0.2 / 2;
 vAlong_1.normalize();
 vAlong_2.normalize();

 _edgeCoords->push_back((*lp)[0]);
 _edgeCoords->push_back((*lp)[1]);
 if (CMF::euclidDistance((*lp)[0],(*lp)[1]) <= CMF::euclidDistance((*lp)[0],(*lp)[2])) {
    float cosAlpha = -(vAlong_1 * vAlong_2);
    float extraLength = ((*lp)[2] - (*lp)[1]).length() * cosAlpha;
     _edgeCoords->push_back((*lp)[1] + vAlong_1 * (eps + extraLength));
     _edgeCoords->push_back((*lp)[2] + vAlong_1 * eps);
 } else {
     float cosAlpha = (vAlong_1 * vAlong_2);
     float extraLength = ((*lp)[2] - (*lp)[1]).length() * cosAlpha;
     _edgeCoords->push_back((*lp)[1] + vAlong_1 * eps);
     _edgeCoords->push_back((*lp)[2] + vAlong_1 * (eps + extraLength));
 }
_edgeCoords->push_back((*lp)[2]);
if (CMF::euclidDistance((*lp)[0],(*lp)[2]) <= CMF::euclidDistance((*lp)[0],(*lp)[3])) {
   float cosAlpha = -(vAlong_1 * vAlong_2);
   float extraLength = ((*lp)[3] - (*lp)[2]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[2] - vAlong_2 * (eps + extraLength));
    _edgeCoords->push_back((*lp)[3] - vAlong_2 * eps);
} else {
    float cosAlpha = (vAlong_1 * vAlong_2);
    float extraLength = ((*lp)[3] - (*lp)[2]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[2] - vAlong_2 * eps);
    _edgeCoords->push_back((*lp)[3] - vAlong_2 * (eps + extraLength));
}
_edgeCoords->push_back((*lp)[3]);
if (CMF::euclidDistance((*lp)[0],(*lp)[3]) <= CMF::euclidDistance((*lp)[0],(*lp)[4])) {
   float cosAlpha = -(vAlong_1 * vAlong_2);
   float extraLength = ((*lp)[4] - (*lp)[3]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[3] - vAlong_1 * (eps + extraLength));
    _edgeCoords->push_back((*lp)[4] - vAlong_1 * eps);
} else {
    float cosAlpha = (vAlong_1 * vAlong_2);
    float extraLength = ((*lp)[4] - (*lp)[3]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[3] - vAlong_1 * eps);
    _edgeCoords->push_back((*lp)[4] - vAlong_1 * (eps + extraLength));
}
_edgeCoords->push_back((*lp)[4]);
if (CMF::euclidDistance((*lp)[0],(*lp)[1]) <= CMF::euclidDistance((*lp)[0],(*lp)[4])) {
   float cosAlpha = -(vAlong_1 * vAlong_2);
   float extraLength = ((*lp)[4] - (*lp)[1]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[4] + vAlong_2 * eps);
    _edgeCoords->push_back((*lp)[1] + vAlong_2 * (eps + extraLength));
} else {
    float cosAlpha = (vAlong_1 * vAlong_2);
    float extraLength = ((*lp)[4] - (*lp)[1]).length() * cosAlpha;
    _edgeCoords->push_back((*lp)[4] + vAlong_2 * (eps + extraLength));
    _edgeCoords->push_back((*lp)[1] + vAlong_2 * eps);
}
_edgeCoords->push_back((*lp)[1]);

_tCoords->push_back(osg::Vec2(0.5,0.5));
_tCoords->push_back(osg::Vec2(0.666,0.666));
_tCoords->push_back(osg::Vec2(0.666,1.0));
_tCoords->push_back(osg::Vec2(0.333,1.0));
_tCoords->push_back(osg::Vec2(0.333,0.666));
_tCoords->push_back(osg::Vec2(0.0,0.666));
_tCoords->push_back(osg::Vec2(0.0,0.333));
_tCoords->push_back(osg::Vec2(0.333,0.333));
_tCoords->push_back(osg::Vec2(0.333,0.0));
_tCoords->push_back(osg::Vec2(0.666,0.0));
_tCoords->push_back(osg::Vec2(0.666,0.333));
_tCoords->push_back(osg::Vec2(1.0,0.333));
_tCoords->push_back(osg::Vec2(1.0,0.666));
_tCoords->push_back(osg::Vec2(0.666,0.666));

Solution

  • Try keeping the 2d positions always equal to the texture coordinates for each vertex. That will ensure your geometry appears as an undistorted cutout of your texture. You can then rescale and center the mesh as you like without distorting the texture by applying transforms to the vertex positions.

    One way to do this would be to create a function that pushes a single vertex, accepting the 2d coordinates of the vertex and any transforms you want to apply. The function would then push the 2d coordinates as texcoords, then transform them and push the result as positions.