Skarred
Skarred

Reputation: 31

Passing array data through textures in opengl

So i'm trying to pass a bunch of vectors to the fragment shader and apparently i should do it with a 1d texture. But if i try to access the passed vectors, the values are not what i expect.

How should i index the texture() function?

Passing the texture:

std::vector<vec3> triangles;
//triangles is already filled by this point
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, texture);        
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB16F, Object::triangles.size(), 0, GL_RGB, GL_FLOAT, &Object::triangles[0]);

GLint textureLoc =  glGetUniformLocation( getId(), "triangles" );
glUniform1f(textureLoc, 0);

setUniform((int)Object::triangles.size(), "triCount");

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//draw a rectangle from -1,-1 to 1,1

fragment shader code:

uniform sampler1D triangles;
uniform int triCount;

struct Triangle{
            vec3 a,b,c;
            vec3 normal;
};

void main(){
  for(int i = 0;i < triCount;i++){//for each triangle
    Triangle triangle;
    //set the points of the triangle
    triangle.a = vec3(texture(triangles,i));
    triangle.b = vec3(texture(triangles,i++));
    triangle.c = vec3(texture(triangles,i++));
    //set the normal vector of the triangle
    triangle.normal = vec3(texture(triangles,i++));

    //then i do stuff with the current triangle and return a color 
  }
}

The array contains 3 points and a normal vector of a bunch of triangles, that's why i read from the texture this way.

edit: glGetTexImage confirmed that the passed texture is correct.

Upvotes: 1

Views: 1378

Answers (1)

Rabbid76
Rabbid76

Reputation: 210918

When using texture, the texture coordinates are floating point values ​​in the range [0.0, 1.0]. Use texelFetch to perform a lookup of a single Texel from texture with integral texture coordinates in the range [0, width):

triangle.a      = texelFetch(triangles, i*4,   0).xyz;
triangle.b      = texelFetch(triangles, i*4+1, 0).xyz;
triangle.c      = texelFetch(triangles, i*4+2, 0).xyz;
triangle.normal = texelFetch(triangles, i*4+3, 0).xyz;

Be aware, that the computation of the Texel indices in your shader code is incorrect.


Alternatively, you can calculate the texture coordinate by dividing the index by the width of the texture. The size of a texture can be get by textureSize:

float width = float(textureSize(triangles, 0));
triangle.a      = texture(triangles, (float(i*4)+0.5) / width).xyz;
triangle.b      = texture(triangles, (float(i*4)+1.5) / width).xyz;
triangle.c      = texture(triangles, (float(i*4)+2.5) / width).xyz;
triangle.normal = texture(triangles, (float(i*4)+3.5) / width).xyz;

Upvotes: 3

Related Questions