GLSL texture tearing problem

Hi there !

Since I have changed my GPU for something… a bit more powerful, I decided to learn new stuff, using opengl 3.x (actually 3.0).

Therefore I did a small utility for myself for matrix related operation and so on and it goes pretty well…

Then comes the moment of my “first” texture shader and here comes the problem (see attached file).
I have on my cube 4 good faces and 2 which are ‘teared’.

Here are the shaders:
vertex:


#version 130

in vec3 in_Vertex;
in vec3 in_Color;
in vec2 in_UVcoord;

out vec3 vert_Color;
out vec2 vert_UVcoord;

uniform mat4 un_Transform;
uniform mat4 un_Perspective;

void main()
{
    gl_Position = un_Perspective * un_Transform * vec4(in_Vertex, 1.0);
    vert_Color = in_Color;
	vert_UVcoord = in_UVcoord;
}

fragment:


#version 130

in vec3 vert_Color;
in vec2 vert_UVcoord;

uniform float un_Intensity;
uniform sampler2D un_Texture;

void main()
{
	vec3 color2 = normalize(vert_Color + vec3(un_Intensity));
    gl_FragColor = texture(un_Texture,vert_UVcoord);
}

The most weird thing is that if I set the UV_coord var interpolation to noperpective, it runs well and I don’t understand why… I have also noted that if the teared face is strictly parallel to the screen, it isn’t teared and displays well.

here is the init code of the elements (C++):


[...] <- headers

typedef struct{
    vec3 position;
    vec3 color;
    vec2 UV_coord;
} vertex;

void defineVertex(vertex* v,vec3 position,vec3 color,vec2 UV_coord){
    v->position = position;
    v->color = color;
    v->UV_coord = UV_coord;
}

int main(int argc, char** argv){

[...] // context init and so on

    gltProgram shader; // even if it is a custom class, I hope you'll understand the inteface :)
    bool shader_ok = true;
    if( (shader_ok = shader.create()) )
    if( (shader_ok = shader.vertexShader.load("Shaders\\couleurs.vert",GL_VERTEX_SHADER)) )
    if( (shader_ok = shader.fragmentShader.load("Shaders\\couleurs.frag",GL_FRAGMENT_SHADER)) ){
        shader.bindAttribLocation(0,"in_Vertex");
        shader.bindAttribLocation(1,"in_Color");   //Not in use in the shader
        shader.bindAttribLocation(2,"in_UVcoord");
        shader_ok = shader.link();
    }
    if( !shader_ok ){
        fprintf(log,"Echec du chargement
");
        App.Close();
        return -1;
    }

    gltUniform intensity(&shader,"un_Intensity");
    gltUniform transform(&shader,"un_Transform");
    gltUniform perspective(&shader,"un_Perspective");
    gltUniform texture(&shader,"un_Texture");

    vertex vertices[8]; // vertices definition
    defineVertex(&vertices[0],vec3(-0.5,-0.5,0.5),vec3(1,0,0),vec2(0,0));
    defineVertex(&vertices[1],vec3(0.5,-0.5,0.5),vec3(0,1,0),vec2(1,0));
    defineVertex(&vertices[2],vec3(0.5,-0.5,-0.5),vec3(0,0,1),vec2(1,0));
    defineVertex(&vertices[3],vec3(-0.5,-0.5,-0.5),vec3(0,0,0),vec2(0,0));
    defineVertex(&vertices[4],vec3(-0.5,0.5,0.5),vec3(1,0,1),vec2(0,1));
    defineVertex(&vertices[5],vec3(0.5,0.5,0.5),vec3(0,1,1),vec2(1,1));
    defineVertex(&vertices[6],vec3(0.5,0.5,-0.5),vec3(1,1,0),vec2(1,1));
    defineVertex(&vertices[7],vec3(-0.5,0.5,-0.5),vec3(1,1,1),vec2(0,1));

    //Defining the index table
    uvec3 elements[] = { uvec3(0,1,4),
                         uvec3(4,1,5),
                         uvec3(1,2,5),
                         uvec3(2,6,5),
                         uvec3(2,3,6),
                         uvec3(3,7,6),
                         uvec3(3,0,7),
                         uvec3(0,4,7),
                         uvec3(4,5,7),
                         uvec3(5,6,7),
                         uvec3(3,2,0),
                         uvec3(2,1,0)};

    //Defining the texture (quite a tough one, indeed :))
    vec3 texture_data[] = { vec3(0,0,0),
                            vec3(1,1,1),
                            vec3(1,1,1),
                            vec3(0,0,0) };

    //loading a 4x4 matrix with equivalent matrix to gluperspective(angle,window ratio,near clipping,far clipping)
    mat4 pers = mat4::perspective( 90, OGL_WIN_RATIO, 0.001, 100 ); //OGL_WIN_RATIO set to 1 as it is a square window

    GLuint tex; //Texture init
    glGenTextures(1,&tex);
    glBindTexture(GL_TEXTURE_2D,tex);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,2,2,0,GL_RGB,GL_FLOAT,texture_data);

    glActiveTexture(GL_TEXTURE0);
    glUniform1i(texture.Id(),0);

    glEnable(GL_DEPTH_TEST);
    glClearColor(1,0,1,0);


    [...]//Loop start, drawing step:

        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1); //Not in use in the shader
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(0, vec3::size, vec3::type, GL_FALSE, sizeof(vertex), &(vertices[0].position));
        glVertexAttribPointer(1, vec3::size, vec3::type, GL_FALSE, sizeof(vertex), &(vertices[0].color));       //Not in use in the shader
        glVertexAttribPointer(2, vec2::size, vec2::type, GL_FALSE, sizeof(vertex), &(vertices[0].UV_coord));
        glUseProgram(shader.Id());

        float fluctuate = pow(sin(ck.GetElapsedTime()/1000.0),2);
        float pfluctuate = (1+fluctuate)*0.5;

        //Make the cube dance, cosmetic only
        mat4 trans(1);
        trans.translate3D(0,0,-2);
        trans.scale3D(pfluctuate,pfluctuate,1);
        trans.rotate3D(90,1,-1,0);
        trans.rotate3D(ck.GetElapsedTime()/24.0,1,0,0);
        trans.rotate3D(ck.GetElapsedTime()/8.0,0,1,0);
        trans.rotate3D(ck.GetElapsedTime()/40.0,1,0,0);

        glUniform1f(intensity.Id(),fluctuate);
        glUniformMatrix4fv(transform.Id(),1,GL_FALSE,(GLfloat*)trans.data);
        glUniformMatrix4fv(perspective.Id(),1,GL_FALSE,(GLfloat*)pers.data);

        glDrawElements(GL_TRIANGLES, 12*3, GL_UNSIGNED_INT, elements);
        glUseProgram(0);
        glDisableVertexAttribArray(2);
        glDisableVertexAttribArray(1); //Not in use in the shader
        glDisableVertexAttribArray(0);

    [...]//Loop end

    return 0;
}

If you’ve got any idea, I suspected vertex order issue, but it doesn’t seem to be de problem…
Thanks anyway.

Zeiph.

Simply your uv coords are bad. For example, for your last triangle (uvec3(2,1,0)), you have twice (1,0) as texcoord.

Is it mandatory to have two differents UV coord on the same edge?

I didn’t speak about edge, but about face. If you have twice the same coordinate in the same triangle, then you’ll have distorsion, such you are facing.

If you can’t make the same vertex have the same coordinate when expressed from different faces, then duplicate your vertex or displace your texture coordinates so that the whole model will use a single texture (instead of 6 times the same texture or 6 textures). This generally happen when constructing a cube (you will have the same problems with normals for example).

Ok so this is no probleme in the program but in the model…

Thanks a lot.