OpenGL:在圆柱体周围包裹纹理

时间:2016-06-21 06:47:47

标签: c opengl textures

我正在尝试将纹理添加到圆柱体中以便很好地绘制石头。我开始使用圆柱体,然后绘制我找到here的石头纹理但是得到了一些奇怪的结果。这是我正在使用的功能:

try
{
    if (urlfuerdoppelclick != null)
        if (urlfuerdoppelclick.Length > 0)
        {
            eintraege = eintraege + " marker" + i.ToString() + ".addListener";
            eintraege = eintraege + " ('dblclick',";
            eintraege = eintraege + "   function () ";
            eintraege = eintraege + "    { ";
            eintraege = eintraege + "      window.open(\"" + urlfuerdoppelclick 
+ "\"); ";
            eintraege = eintraege + "    } ";
            eintraege = eintraege + " ); ";
        }
}
catch { };
try
{
    if (voninnen != null)
        if (voninnen.Length > 0)
        {
            eintraege = eintraege + " marker" + i.ToString() + ".addListener";
            eintraege = eintraege + " ('click',";
            eintraege = eintraege + "   function () ";
            eintraege = eintraege + "    { ";
            eintraege = eintraege + "      window.open(\"" + voninnen + "\"); ";
            eintraege = eintraege + "    } ";
            eintraege = eintraege + " ); ";
        };
}
catch (Exception e) { };

我收到的输出是

enter image description here

我仍然是OpenGL的新手,更具体的是纹理,所以我的理解非常有限。我的思考过程是我将纹理映射到用于制作圆柱体的每个void draw_well(double x, double y, double z, double dx, double dy, double dz, double th) { // Set specular color to white float white[] = {1,1,1,1}; float black[] = {0,0,0,1}; glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shinyvec); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,black); glPushMatrix(); // Offset glTranslated(x,y,z); glRotated(th,0,1,0); glScaled(dx,dy,dz); // Enable textures glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glBindTexture(GL_TEXTURE_2D,texture[0]); // Stone texture glBegin(GL_QUAD_STRIP); for (int i = 0; i <= 359; i++) { glNormal3d(Cos(i), 1, Sin(i)); glTexCoord2f(0,0); glVertex3f(Cos(i), -1, Sin(i)); glTexCoord2f(0,1); glVertex3f(Cos(i), 1, Sin(i)); glTexCoord2f(1,1); glVertex3f(Cos(i + 1), 1, Sin(i + 1)); glTexCoord2f(1,0); glVertex3f(Cos(i + 1), -1, Sin(i + 1)); } glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); } // Later down in the display function draw_well(0, 0, 0, 1, 1, 1, 0); ,但显然我做错了。关于导致这种奇怪输出的原因以及如何解决它的任何解释都将非常感激。

1 个答案:

答案 0 :(得分:2)

您的抽奖例程可能存在三个主要问题。四条带索引,纹理坐标重复过多以及可能错误地使用trig函数;

三角函数函数通常接受表示以弧度而非度数表示的角度的值。仔细检查您正在使用的Sin和Cos函数的参数。

Quadstrip 索引不正确。索引应该是这样的......

enter image description here

注意四边形是如何以时钟方式定义的,但是对角线顶点是按顺序定义的。您将四边形定义为v0,v1,v3,v2而不是v0,v1,v2,v3,因此交换四个顶点的最后两个顶点。这也导致了不正确共享顶点的另一个错误。你在每个垂直边缘重复它们,因为你在一个循环中绘制相同的顶点集(i + 1),就像你在下一个循环中所做的那样(即因为我现在已经增加了1)。

纹理坐标对于每个四边形在0,1范围内,这意味着您要定义一个360度分割的圆柱体,并且该纹理在圆柱体周围重复360次。我假设纹理应该1:1映射到圆柱体而不重复?

以下是使用您提供的内容的一些示例代码。我已将段数减少到64,如果您仍希望有360,则相应地修改numberOfSegments

float pi = 3.141592654f;

unsigned int numberOfSegments = 64;
float angleIncrement = (2.0f * pi) / static_cast<float>(numberOfSegments);
float textureCoordinateIncrement = 1.0f / static_cast<float>(numberOfSegments);

glBegin(GL_QUAD_STRIP);
for (unsigned int i = 0; i <= numberOfSegments; ++i)
{
    float c = cos(angleIncrement * i);
    float s = sin(angleIncrement * i);

    glTexCoord2f( textureCoordinateIncrement * i, 0); glVertex3f( c, -1.0f, s);
    glTexCoord2f( textureCoordinateIncrement * i, 1.0f); glVertex3f( c, 1.0f, s);
}
glEnd();

N.BYou正在使用旧版本的OpenGL(使用glBegin / glVertex等)。