1

I'm attempting to texture a model of a wooden table with a wood bitmap i've found and resized, however the issue I have encountered is that each quad making up the surface of the table is clearly visible when the texture is applied. How do I make it look like one smooth texture?

void Table::DrawTableTop()
{
    glPushMatrix();
    //draw tabletop

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texid);

    glBegin(GL_QUADS);
    glMaterialfv(GL_FRONT, GL_SPECULAR, static_cast<GLfloat*>(specular));
    glMaterialf(GL_FRONT, GL_SHININESS, static_cast<GLfloat>(shininess));

    float unitx = 1.0f / (float)(xsize * 2 + 1);
    float unity = 1.0f / (float)(zsize * 2 + 1);

    for (int i = -xsize; i <= xsize; i++)
    {
        for (int j = -zsize; j <= zsize; j++)
        {
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, static_cast<GLfloat*>(wDiffuse));
            //top
            glNormal3f(0.0f, 1.0f, 0.0f);
            if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 + 1), unity * static_cast<float>(j + 10));
            glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j) + scale[2]);
            if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 + 1), unity * static_cast<float>(j + 10 + 1));
            glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j));
            if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20), unity * static_cast<float>(j + 10 + 1));
            glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j));
            if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 ), unity * static_cast<float>(j + 10));
            glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j) + scale[2]);
        }
    }

    glEnd();

    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);

    glPopMatrix();

The values of xsize and zsize are 20 and 10, respectively

I would like the texture to appear as if it was loaded on to one large quad, but obviously using multiple quads for improved lighting etc..

This is what the textured image looks like:

zombunny
  • 37
  • 5
  • *"... each quad ... is clearly visible when the texture is applied. How do I make it look like one smooth texture?"* - So the texture is not seamless? – Rabbid76 May 01 '19 at 21:08
  • I added an image link to better show what I mean into the post – zombunny May 01 '19 at 21:10
  • Texture coordinates have to be in range [0, 1] (0, 0) is the lower left and (1, 1) is the upper right of the texture. See [How do opengl texture coordinates work?](https://stackoverflow.com/questions/5532595/how-do-opengl-texture-coordinates-work). – Rabbid76 May 01 '19 at 21:14
  • As far as I can tell my texture coordinates are in that range – zombunny May 01 '19 at 21:17

2 Answers2

1

You messed up with the second texture coordinate. You set it to j + 20 when the vertex position has + scale[0], and to j + 20 + 1 when the vertex position does not have + scale[0]. As a result all your strips are 'inverted'.

To fix it use:

if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 + 1), unity * static_cast<float>(j + 10 + 1));
glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j) + scale[2]);
if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 + 1), unity * static_cast<float>(j + 10));
glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j));
if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20), unity * static_cast<float>(j + 10));
glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j));
if (tex) glTexCoord2f(unitx * static_cast<float>(i + 20 ), unity * static_cast<float>(j + 10 + 1));
glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j) + scale[2]);

However, a better way, is to extract the vertex position calculation as follows:

struct Vertex {
    float texcoord[2];
    float position[3];
};

Vertex vertex_at(float scale[3], float unitx, float unity, int i, int j)
{
    Vertex ret;
    ret.texcoord[0] = unitx*(i + 20);
    ret.texcoord[1] = unity*(j + 10);
    ret.position[0] = scale[0]*i;
    ret.position[1] = 0;
    ret.position[2] = scale[2]*j;
    return ret;
}

And use it like that:

for (int i = -xsize; i <= xsize; i++)
{
    for (int j = -zsize; j <= zsize; j++)
    {
        glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, static_cast<GLfloat*>(wDiffuse));
        //top
        glNormal3f(0.0f, 1.0f, 0.0f);
        Vertex v[4] = {
            vertex_at(scale, unitx, unity, i + 1, j + 1),
            vertex_at(scale, unitx, unity, i + 1, j),
            vertex_at(scale, unitx, unity, i, j),
            vertex_at(scale, unitx, unity, i, j + 1),
        };
        for(int k = 0; k < 4; ++k) {
            if (tex) glTexCoord2fv(v[k].texcoord);
            glVertex3fv(v[k].position);
        }
    }
}

This way it's easier to follow what's hapenning, and you are one step closer to using VAOs: just bundle all those Vertex structs into a buffer and set up the attrib pointers.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
1

The textures on the tiles are flipped along the y-axis. Change the texture coordinates:

if (tex) 
    glTexCoord2f(
        unitx * static_cast<float>(i + 20 + 1),
        unity * static_cast<float>(j + 10 + 1));
glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j) + scale[2]);

if (tex) 
    glTexCoord2f(
        unitx * static_cast<float>(i + 20 + 1),
        unity * static_cast<float>(j + 10));
glVertex3f(scale[0] * static_cast<float>(i) + scale[0], 0, scale[2] * static_cast<float>(j));

if (tex)
    glTexCoord2f(
        unitx * static_cast<float>(i + 20),
        unity * static_cast<float>(j + 10));
glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j));

if (tex)
    glTexCoord2f(
        unitx * static_cast<float>(i + 20 ),
        unity * static_cast<float>(j + 10 + 1));
glVertex3f(scale[0] * static_cast<float>(i), 0, scale[2] * static_cast<float>(j) + scale[2]);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174