1
\$\begingroup\$

I'm trying to write a shader which renders a multitextured geometry wihout rerendering the geometry with each texture.

In my test I'm not using textures, I just convert the texture index to a color (0: red, 1: blue, 2: green). I'm rendering 3 planes with 3 different "texture index" attributes. The vertex shader just passes that float to the fragment shader where I convert it to an integer (and use this interger as an array indexer in the main shader).

So a vertex consists 4 floats (0-2: position, 3: texture index). Everything is fine until I'm trying to use that "texture index".

Here's the VertexShader:

#version 130
uniform mat4 proj;
uniform mat4 view;
uniform mat4 world;

in vec3 in_position;
in float in_fl;

smooth out float FL;

void main(void)
{
    FL = in_fl;

    gl_Position = proj * view * world * vec4(in_position, 1);
}

FragmentShader:

#version 130

out vec4 out_frag_color;
smooth in float FL;

void main(void)
{
    int i = int(FL);

    if(i == 0)
        out_frag_color = vec4(1,0,0,1);
    else if(i == 1)
        out_frag_color = vec4(0,0,1,1);
    else if(i == 2)
        out_frag_color = vec4(0,1,0,1);
    else   
        out_frag_color = vec4(1,1,1,1);
}

And the result (the numbers are the "texture index" of the plane): Problems, problems... Tested on an Intel HD 4000 GPU and an nVidia GTS 250, same result. As you can see 0 is OK, but 2.0 is sometimes 2 (green), sometimes 1 (blue), why? If I pass that "i" to a sampler2D array, nothing shows up on the screen, because "i" is out of the array bounds.

The rendering is done using OpenGL 3.0, with a VAO, an ArrayBuffer and an ElementArrayBuffer.

This is how I setup the attrib pointers:

GL.EnableVertexAttribArray(0); //pos
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, sizeof(float) * 4, 0);

GL.EnableVertexAttribArray(1); //tetxure index
GL.VertexAttribPointer(1, 1, VertexAttribPointerType.Float, true, sizeof(float) * 4, sizeof(float) * 3);

I've tried using VertexAttribPointerType.Int and int attributes, Also I've tried setting the "FL" varaible in the vertex shader, with 0, the result is red which is good, but if I use 1 or 2 the result is again a mess.

So what do you think? It's a rounding problem? Or how should I render the geometry with multiple textures wihout rerendering the geometry with each texture?

\$\endgroup\$
  • \$\begingroup\$ I'm trying to write a shader which renders a multitextured geometry without rerendering the geometry with each texture What are you trying to achieve, did you look into multitexturing ? you only render the geometry once with multiple textures. Explaining what are you trying to achieve is better than describing your solution \$\endgroup\$ – concept3d Oct 11 '14 at 20:05
  • \$\begingroup\$ Sorry, I tried to explain what I'm trying to achieve, I just don't know how.. (English is not my native language, but I think you already know it) So I'm trying to render a model with multiple textures (each vertex has an attribute which is the texture index) but I don't want to re render the whole model with each texture. \$\endgroup\$ – robot9706 Oct 11 '14 at 20:10
  • \$\begingroup\$ Well, it's ok english isn't my native language either. Anyway for multitexturing you need to pass multiple textures and then blend them, rather than giving each vertex an index attribute. \$\endgroup\$ – concept3d Oct 11 '14 at 20:18
  • \$\begingroup\$ I know what multitexturing does, but I don't want to blend the textures. Every polygon has it's own texture and I'm trying to render the model with one draw call. \$\endgroup\$ – robot9706 Oct 11 '14 at 20:22
  • 2
    \$\begingroup\$ Visually, it looks like z-fighting... it looks like the "2.0" diamond is being drawn twice with same coordinates and depth, and randomly either the blue or green gets drawn first and wins. \$\endgroup\$ – david van brink Oct 11 '14 at 20:48
2
\$\begingroup\$

I managed to find out what my problem was. The "smooth" keyword.

Vertex shader:

...
in float in_fl;

flat out int FL;

void main(void)
{
    FL = int(in_fl);
...

Fragment shader:

...
    flat in int FL;
...

So now I have a red, a blue and a green square, as I wanted.

Anyway thanks for any help.

\$\endgroup\$
  • \$\begingroup\$ This seems surprising. opengl.org/wiki/Type_Qualifier_(GLSL) says "SMOOTH: ​ The value will be interpolated in a perspective-correct fashion. This is the default if no qualifier is present." \$\endgroup\$ – david van brink Oct 13 '14 at 4:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.