4
votes

I've got some difficulty debugging my program. I'm trying use an array as a lookup table to offset the vertex location in my vertex shader, but I can't even tell if I'm linking my array correctly. The offset factor always ends up zero (flattening my vectors, rather than giving them a shape), so either I'm accessing the texture1D coordinates wrong or the array isn't binding right to the texture.

Frankly, I don't know which coordinates I should be using to get the values from a 1D texture... but I've tried all the combinations.

Here I setup the array and bind it to the shader:

//FISH
GLfloat fish_coords[100];
for (int i = 0; i < 50; i++){fish_coords[i] = 0;}
for (int i = 50; i < 100; i++){fish_coords[i] = 1;}
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glGenTextures(1, &fishtexture);  
glBindTexture(GL_TEXTURE_1D, fishtexture);
glTexImage1D(GL_TEXTURE_1D, 0, 1, 128,0,GL_RGBA, GL_UNSIGNED_BYTE, &fish_coords);

switch(shadow_selection){
case 0: 
    vertexShader = "fish.vert";
    fragmentShader = "fish.frag";
    setShaders();

    GLint loc1;
    loc1 = glGetUniformLocation(shaderProgram,"fish_coords");
    glUniform1i(loc1,0);    

And my vertex shader:

uniform float spec_factor;
uniform sampler1D fish_coords;

varying vec3 lightDir,normal;

void main()
{

    vec4 v_pos;
    vec3 ldir;

    gl_TexCoord[0] = gl_MultiTexCoord0;

    v_pos = gl_ModelViewMatrix * gl_Vertex;
    ldir = vec3(gl_LightSource[0].position-v_pos);
    lightDir = normalize(ldir);
    normal = normalize(gl_NormalMatrix * gl_Normal);

    vec4 offset;
    offset = texture1D(fish_coords, gl_TexCoord[0].r);

    vec4 fish_shape;
    fish_shape.xz = gl_Vertex.xz;
    fish_shape.y = gl_Vertex.y * offset.x;
    fish_shape.w = 1;

    gl_Position = gl_ModelViewProjectionMatrix * fish_shape;
}
2
The quick answer is: That's not how you load a texture. Bind selects a texture by id that you want to operate on. You allocate ids with glGenTextures, bind them, load them (eg with glTexImage1D) and then use them.Ben Jackson
ah, I thought lookup tables were a kind of hack with the textures so that's why I wasn't doing that. thanks.jakev
Ok, so with that changed... I'm not getting any closer.jakev

2 Answers

3
votes

There are two problems in your texture loading code:

1.- The default MIN filter uses mipmaps, so with that setup the texture incomplete. Set the MIN/MAG filters after binding the texture to GL_NEAREST. 2.- Your texture data is floats, but you say to GL they are unsigned bytes, change that to GL_FLOAT.

After this changes your texture should appear.

1
votes

There is a GLSL command that allows you to access single texels of a texture, without no texture filtering: texelFetch Instead of using normalized coordinates (0-1), it uses integers, so texelFetch(32, 32) would fetch the the texel 32 texel to the right and 32 texels down.

It looks like you are writing pretty old school GLSL though, so I don't know how applicable it is.

Warning: If you are compiling your GLSL programs on an Nvidia card, with the Nvidia drivers, it will compile like it was CG, which has a funny caveat. Interestingly enough, if you try to access an index of an sufficiently large array (you are using an texture as an array, so that should not be a problem for you) using an hardcoded value for the index, it will compile. However, if you use an dynamic index (variable) to access an field of the same array, it will not compile. The reason is that Nvidias compiler optimizes out all the indexes not being used (since you are using a hardcoded value, the compiler thinks that it can throw away the other array values)!

This gave me quite an headache some years ago.

Incidentally, I see that you're trying to render a school of fishes or something, it looks interesting, any place where you have a demo?