Отображение текстуры с использованием одномерной текстуры с OpenGL 4.x

Я хочу использовать 1d-текстуру (цветовую шкалу) для текстурирования простого треугольника.

введите здесь описание изображения

Мой фрагментный шейдер выглядит так:

#version 420

uniform sampler1D           colorRamp;
in float height;

out vec4 FragColor;

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

Мой вершинный шейдер выглядит так:

#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);
}

При рисовании треугольника я поступаю следующим образом (код формы проверки ошибок я удалил для лучшей читабельности):

glUseProgram(program_);

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

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

К сожалению, мой треугольник только черный. Любые идеи, как решить эту проблему?

Я почти уверен, что назначенная текстура заполнена правильными данными, так как я прочитал ее с помощью glGetTexImage и проверил. Нужно ли вызывать другие функции для привязки и активации текстуры? У меня есть почти такой же код для 2D-текстур, который работает.

Когда я изменяю код шейдера таким образом:

#version 420

uniform sampler1D           colorRamp;
in float height;

out vec4 FragColor;

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

Я получаю такой вывод: введите здесь описание изображения

Я подготовил демо исходный код, который воспроизводит ошибку. Источник можно найти здесь. Он генерирует следующий вывод:

введите здесь описание изображения

Текстура 1d создается таким образом — только с красными пикселями:

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_;
}

Привязка текстуры делается так:

GLuint samplerLocation = glGetUniformLocation(rc.ToonHandle, "ColorRamp");
glUniform1i(samplerLocation, 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_1D, rc.texure1d);

person Vertexwahn    schedule 28.08.2014    source источник
comment
Покажите также вершинный шейдер. Правильно ли он устанавливает height? Вы уверены, что проходите по нормализованной высоте? Также я предлагаю использовать .rgba, так понятнее, что вы говорите о текстурах/цветах.   -  person Bartek Banachewicz    schedule 28.08.2014
comment
Слишком много вещей, которые вы можете делать неправильно. Текстура готова? Вы уверены в координатах? Вы пробовали рисовать высоту от f.i. назначение другого оттенка красного между его значением 0 и 1 и, например, зеленого за пределами этого диапазона? Что сообщает GL_KHR_debug?   -  person peppe    schedule 28.08.2014
comment
@BartekBanachewicz Я изменил позицию в соответствии с вашими предложениями!   -  person Vertexwahn    schedule 28.08.2014
comment
@peppe GL_KHR_debug сообщает только об уведомлении, которое кажется не связанным с этой проблемой (оно сообщает, что в видеопамяти был создан буфер вершин).   -  person Vertexwahn    schedule 28.08.2014
comment
Я предоставил минимальную демонстрацию, которая воспроизводит ошибку. Демо использует GL 3.x, но я думаю, что нет большой разницы с GL 4.x.   -  person Vertexwahn    schedule 29.08.2014


Ответы (1)


Нашел ошибку:

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
);
person Vertexwahn    schedule 28.08.2014
comment
Да, четвертый параметр — это ширина текстуры в пикселях. Кажется, вы ошиблись с размером в байтах. - person glampert; 29.08.2014
comment
В моем реальном приложении этой ошибки не возникает - я использую объекты сэмплера в реальном приложении и кажется, что 1d текстура не работает со всеми типами объектов сэмплера. - person Vertexwahn; 29.08.2014