片段着色器忽略纹理坐标

时间:2019-11-07 10:31:32

标签: opengl glsl textures

我正在通过learnopengl.com上的教程学习OpenGL。

我已经使用2个没有着色器的三角形将自己定义的3x3纹理绘制到正方形上。但是,使用着色器,我无法理解这种奇怪的行为:

片段着色器似乎忽略了纹理坐标,但奇怪的是用第一个像素的颜色绘制了我的两个三角形。我尝试将垃圾值放入纹理坐标中,并且始终保持不变。

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 个答案:

答案 0 :(得分:2)

着色器阶段的输出通过其名称链接到下一个着色器阶段的输入(使用布局限定符时除外)。参见interface matching rules between shader stages.

片段着色器输入变量的名称必须与顶点着色器输出变量的名称相同。

由于顶点着色器中输出的纹理坐标的名称为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);
} 
相关问题