2

我正在学习使用 openGL,有人告诉我,因为我的轮拱是凹的,所以我必须对它们进行镶嵌。所以这是我的前轮拱代码......

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);

这辆车看起来像这样:

车

{我知道纹理也是错误的atm)但是你可以看到前轮拱即使有镶嵌也没有改变,所以我想我镶嵌错了..或者需要更多的镶嵌..还是什么?如果有人可以帮助我解决我在轮拱上遇到的这个巨大问题并纠正它,我将永远感激不尽,因为我一直在努力克服这一点。谢谢 :)

整个drawBody函数代码可以在这里找到:http: //pastebin.com/s9RpzMsd

更新:感谢所有帮助:感谢镶嵌帮助,我的对象现在看起来像这样。现在只是纹理:)

车更好

更新 2:好的,所以我使用了与 PeterT 建议的大致相同的代码,这就是它最终的结果(必须对其进行更改才能编译。指出它是否错误)

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);

putvertex 代码为:

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);
}

然后看起来像这样:

汽车质感

我在某个地方出错了吗?:/

感谢您的所有帮助,最终图像如下所示:

车完成

再次感谢您的帮助!尤其是彼得 :)

4

2 回答 2

2

您不能只对多边形的一部分进行细分,它会起作用,您需要对整个多边形进行细分,如下所示:

   //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);

此外,您需要将顶点的所有 3 个组件指定为GLdouble. 所以它会是这样的(当然仍然缺少一些顶点):

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} };

为了给每个顶点一个纹理坐标,您需要编写自己的函数,该函数接受 a void *(将包含指向顶点的 x、y、z 坐标的指针)并调用glVertexand glTexCoord

此外,您应该避免每帧都进行细分,因此您应该将调用保存在显示列表之间gluTessBeginPolygon和中,或者更好的是让您的函数将顶点保存在 VBO 中。gluTessEndPolygonGLU_TESS_VERTEX

您可能还必须定义GLU_TESS_COMBINE回调,查看此处此处了解详细信息和更多示例代码。

编辑2:实际上纹理并不是那么容易。这是一些不推荐使用的旧代码,可能仍然对您有用,但非常不可靠,尤其是在您使用着色器时。如需更现代的版本,请查看此 Thread。您应该删除glTexCoord2d()调用,这必须进入绘图函数:

//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);
...

此外,请记住,除了小测试之外,对每一帧进行细分仍然不是一个好主意,而是将它与前面所述的显示列表或 VBO 一起使用会更有效。

于 2012-01-09T08:04:32.897 回答
0

gluTesselator 不会从一个凹多边形生成一个凸多边形,因为这在数学上是不可能的。它发出多个原始组(GL_POLYGON、GL_TRIANGLE、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN),这就是您需要传递给 OpenGL 的内容。也将 tesselator 回调添加到 glBegin 和 glEnd。

于 2012-01-09T10:36:47.750 回答