Фрагментный шейдер игнорирует текстурные координаты - PullRequest
1 голос
/ 07 ноября 2019

Я изучаю OpenGL с помощью учебных пособий по learnopengl.com .

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

Кажется, что фрагментный шейдер игнорирует текстурные координаты , но странным образом закрашивает два моих треугольника цветом первого пикселя. Я попытался поместить значения мусора в координаты текстуры, и он всегда остается неизменным.

unsigned char texture_buffer[9*4] = // 3x3 texture RGBA ...
{   
    255,40,100,255,  100,200,200,255,  150,150,200,255,
    100,100,150,255, 200,200,100,255,  150,200,150,255,
    150,100,100,255, 200,100,200,255,  200,150,150,255
};
float positions_texcoords[] =
{   //    x              y            z               tex coords
        0.0f,           0.0f,       0.0f,           0.0f, 0.0f,
        0.5f,           0.0f,       0.0f,           1.0f, 0.0f,
        0.0f,           0.5f,       0.0f,           0.0f, 1.0f,
        0.5f,         0.5f,       0.0f,           1.0f, 1.0f,
        0.5f,         0.0f,       0.0f,           1.0f, 0.0f,
        0.0f,         0.5f,       0.0f,           0.0f, 1.0f
};

однократный вызов отрисовки:

    GLuint texture = 0;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0,
                 GL_RGBA, GL_UNSIGNED_BYTE, (void *)texture_buffer );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions_texcoords), 
                   positions_texcoords, GL_STATIC_DRAW);

        // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

        // texture coord attribute
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);


    glClearColor(0.3f, 0.0f, 0.1f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindTexture(GL_TEXTURE_2D, texture);

    glUseProgram(shader_program_id);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 6);


    SwapBuffers(window_dc);

вершинный шейдер:

#version 330 core
layout (location = 0) in vec3 in_pos;
layout (location = 1) in vec2 in_tex_coord;

out vec2 out_tex_coord;

void main()
{
    gl_Position = vec4(in_pos, 1.0);
    out_tex_coord = in_tex_coord;
}

фрагментный шейдер:

#version 330 core      
out vec4 FragColor;  

in vec2 in_tex_coord;
uniform sampler2D in_texture;

void main()
{
    FragColor = texture(in_texture, in_tex_coord);
} 

Буду признателен за любые предложения о том, что может происходить. Спасибо.

1 Ответ

2 голосов
/ 07 ноября 2019

Вывод этапа шейдера связан с вводом следующего этапа шейдера по его названию (кроме случаев, когда вы используете спецификатор макета). См. правила сопоставления интерфейса между этапами шейдера.

Имя входной переменной фрагментного шейдера должно совпадать с именем выходной переменной вершинного шейдера.

Посколькуимя выходных координат текстуры в вершинном шейдере равно out_tex_coord

out vec2 out_tex_coord;

имя соответствующего ввода в фрагментном шейдере также должно быть out_tex_coord:

in vec2 out_tex_coord;

void main()
{
    FragColor = texture(in_texture, out_tex_coord);
} 
...