毛皮质地在兔子上显得粗糙

时间:2014-03-18 07:38:02

标签: qt opengl graphics 3d texture-mapping

我编写了这段代码,将纹理应用于以ply格式提供的兔子模型。兔子用纹理绘制,但不像看起来像毛皮,纹理看起来像粗点。

void GLRenderer::paintGL()
{
    // Set light
    GLfloat light_position[] = { lightPositionX, lightPositionY, lightPositionZ, 0.0 };
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Enabling texture
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    bindTexture(QImage("fur4.bmp"));

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    glEnable(GL_NORMALIZE);
    glLoadIdentity();

    glBegin(GL_TRIANGLES);

        for( int i = 0 ; i < objPLYParser.g_vpX.size() ; i+=3 )
        {
                float vector1[3], vector2[3], vCross[3], normalizationValue;
                vector1[0] = objPLYParser.g_vpX[i] - objPLYParser.g_vpX[i+1];
                vector1[1] = objPLYParser.g_vpY[i] - objPLYParser.g_vpY[i+1];
                vector1[2] = objPLYParser.g_vpZ[i] - objPLYParser.g_vpZ[i+1];

                vector2[0] = objPLYParser.g_vpX[i] - objPLYParser.g_vpX[i+2];
                vector2[1] = objPLYParser.g_vpY[i] - objPLYParser.g_vpY[i+2];
                vector2[2] = objPLYParser.g_vpZ[i] - objPLYParser.g_vpZ[i+2];

                // Cross product
                vCross[0] = vector1[1] * vector2[2] - vector2[1] * vector1[2];
                vCross[1] = vector2[0] * vector1[2] - vector1[0] * vector2[2];
                vCross[2] = vector1[0] * vector2[1] - vector2[0] * vector1[1];

                // Value to do normalization with
                normalizationValue = sqrt( vCross[0]*vCross[0] + vCross[1]*vCross[1] + vCross[2]*vCross[2] );

                 float normal[3];
                 normal[0] = vCross[0]/normalizationValue;
                 normal[1] = vCross[1]/normalizationValue;
                 normal[2] = vCross[2]/normalizationValue;

                 glNormal3f(normal[0],normal[1],normal[2]);

            glTexCoord2f(0.0, 0.0);
            glVertex3f(objPLYParser.g_vpX[i],objPLYParser.g_vpY[i],objPLYParser.g_vpZ[i]);

            glTexCoord2f( 1.0,0.0);
            glVertex3f(objPLYParser.g_vpX[i+1],objPLYParser.g_vpY[i+1],objPLYParser.g_vpZ[i+1]);

            glTexCoord2f(1.0, 1.0);
            glVertex3f(objPLYParser.g_vpX[i+2],objPLYParser.g_vpY[i+2],objPLYParser.g_vpZ[i+2]);
        }


    glEnd();
    glDisable(GL_TEXTURE_2D);
}

我试过的纹理文件:

enter image description here

enter image description here

我得到的输出:

enter image description here

enter image description here

有什么建议我可能在这里做错了吗?

2 个答案:

答案 0 :(得分:9)

在这些方面:

glTexCoord2f(0.0, 0.0);
...

glTexCoord2f( 1.0,0.0);
...

glTexCoord2f(1.0, 1.0);
...

您提供纹理坐标,将整个纹理的一半映射到每个单独的三角形。你所看到的是整个皮毛纹理在网格上密集地铺设。

您需要提供更好的纹理坐标。

答案 1 :(得分:4)

首先,您可以使用简单的对象空间映射,例如,您可以使用(x * scale,(y + z)* scale)纹理坐标的(x,y,z)顶点。然后,您可以调整比例