4

I want to use a 1d texture (color ramp) to texture a simple triangle.

enter image description here

My fragment shader looks like this:

#version 420

uniform sampler1D           colorRamp;
in float height;

out vec4 FragColor;

void main()
{
   FragColor = texture(colorRamp, height).rgba;
}

My vertex shader looks like this:

#version 420

layout(location = 0) in vec3 position;

out float height;

void main()
{
    height = (position.y + 0.75f) / (2 * 0.75f);
    gl_Position = vec4( position, 1.0);
}

When drawing the triangle I proceed this way (I removed error checking form code for better readability):

glUseProgram(program_);

GLuint samplerLocation = glGetUniformLocation(program_, name.toCString());
glUniform1i(samplerLocation, currentTextureUnit_);

glActiveTexture( GL_TEXTURE0 + currentTextureUnit_ );
glBindTexture(GL_TEXTURE_1D, textureId);

Unfortunately my triangle is only black. Any ideas how to solve this issue?

I am pretty sure that the assigned texture is filled with proper data since I read it back with glGetTexImage and checked it. Do I need to call other functions to bind and activited the texture? I have almost the same code for 2d textures which is working.

When I change the shader code this way:

#version 420

uniform sampler1D           colorRamp;
in float height;

out vec4 FragColor;

void main()
{
   FragColor = vec4(height, height, height, 1.0); // change!
}

I get this output: enter image description here

I prepared some demo source code that reproduces the error. The source can be found here. It generates the following output:

enter image description here

The 1d texture is created this way - with only red pixels:

static GLuint Create1DTexture()
{
    GLuint textureId_;

    // generate the specified number of texture objects 
    glGenTextures(1, &textureId_);
    assert(glGetError() == GL_NO_ERROR);

    // bind texture
    glBindTexture(GL_TEXTURE_1D, textureId_);
    assert(glGetError() == GL_NO_ERROR);

    // tells OpenGL how the data that is going to be uploaded is aligned
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    assert(glGetError() == GL_NO_ERROR);

    float data[] =
    {
        1.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 0.0f, 1.0f
    };

    glTexImage1D(
        GL_TEXTURE_1D,      // Specifies the target texture. Must be GL_TEXTURE_1D or GL_PROXY_TEXTURE_1D.
        0,                  // Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
        GL_RGBA32F,
        3*sizeof(float)*4,
        0,                  // border: This value must be 0.
        GL_RGBA,
        GL_FLOAT,
        data
    );
    assert(glGetError() == GL_NO_ERROR);

    // texture sampling/filtering operation.
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    assert(glGetError() == GL_NO_ERROR);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    assert(glGetError() == GL_NO_ERROR);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    assert(glGetError() == GL_NO_ERROR);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    assert(glGetError() == GL_NO_ERROR);

    glBindTexture(GL_TEXTURE_1D, 0);
    assert(glGetError() == GL_NO_ERROR);

    return textureId_;
}

Texture binding is done this way:

GLuint samplerLocation = glGetUniformLocation(rc.ToonHandle, "ColorRamp");
glUniform1i(samplerLocation, 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_1D, rc.texure1d);
Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
  • 1
    Show the vertex shader too. Is it setting `height` properly? Are you sure you're passing in normalized height? Also I suggest using `.rgba`, it's clearer that you're talking about textures/colours. – Bartek Banachewicz Aug 28 '14 at 15:21
  • 2
    There are too many things that you could be doing wrong. Is the texture complete? Are you sure about the coordinates? Have you tried "painting height" by f.i. assigning a different shade of red between its 0 and 1 value, and like green outside that range? What does `GL_KHR_debug` report? – peppe Aug 28 '14 at 15:34
  • @BartekBanachewicz I changed the postiong accoring to your suggestions! – Vertexwahn Aug 28 '14 at 15:35
  • @peppe GL_KHR_debug does only report a Notification that seems not related to this problem (it reports that a vertex buffer was created in video memory). – Vertexwahn Aug 28 '14 at 15:40
  • I provided a "minimal" demo that reproduces the error. The demo uses GL 3.x but I thnik there is no big difference to GL 4.x. – Vertexwahn Aug 28 '14 at 20:56

1 Answers1

2

Found the bug:

glTexImage1D(
  GL_TEXTURE_1D,    // Specifies the target texture. Must be GL_TEXTURE_1D or GL_PROXY_TEXTURE_1D.
  0,          // Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
  GL_RGBA32F,
  3/*3*sizeof(float)*4*/,  // bug fix!!!!
  0,          // border: This value must be 0.
  GL_RGBA,
  GL_FLOAT,
  data
);
Andreas Haferburg
  • 5,189
  • 3
  • 37
  • 63
Vertexwahn
  • 7,709
  • 6
  • 64
  • 90
  • 1
    Yes, the fourth parameter is the width of the texture in pixels. It seems you have mistaken it with the size in bytes. – glampert Aug 29 '14 at 01:10
  • In my real application this error does not occur - I use sampler objects in the real application and it seems that 1d texture does not work with all types of sampler objects. – Vertexwahn Aug 29 '14 at 06:47