首页 > 解决方案 > 顶点着色器接收输入但不生成输出

问题描述

我有这个顶点着色器,它只是传递给定的位置并将 UV 和颜色传递给片段着色器:

#version 330 core                                                   
layout (location = 0) in vec2 in_pos;                            
layout (location = 1) in vec2 in_texUV;                             
layout (location = 2) in vec4 in_color;                             
out vec2 ex_texUV;                                                  
out vec4 ex_color;                                                  
                                                                              
uniform mat4 projection;                                            
                                                                    
void main()                                                         
{                                                                   
    gl_Position = vec4(in_pos, 0.0, 1.0) * projection;           
    ex_texUV    = in_texUV;                                         
    ex_color    = in_color;                                         
}

编辑:片段着色器显示在这里,所有制服都正确设置:

#version 330 core                                               
in vec2 in_texUV;                                               
in vec4 in_color;                                               
out vec4 out_color;                                             
                                                                
uniform vec2 screenSize;                                        
uniform vec3 transparentColour;                                 
uniform sampler2D sprite;                                       
                                                                
uniform sampler2D palette;                                      
uniform int paletteLines[0x100];                                
                                                                
void main()                                                     
{                                                               
    if (in_color.a == 0.0) {                                    
        vec4 coord = gl_FragCoord - 0.5;                        
        vec2 screenPos;                                         
        screenPos.x = coord.x * screenSize.x;                   
        screenPos.y = coord.y * screenSize.y;                   
                                                                
        int id = paletteLines[int(screenPos.y)];                
                                                                
        int index = int(texture2D(sprite, in_texUV).r * 255);   
                                                                
        if (index == 0)                                         
            discard;                                            
                                                                
        vec2 palvec;                                            
        palvec.x = index;                                       
        palvec.y = id;                                          
                                                                
        out_color = texture(palette, palvec);                   
    }                                                           
}

(投影变量设置正确,使用 NVIDIA Nsight 显示。

顶点和片段着色器都被编辑为简单的传递(甚至将片段着色器设置为常量vec4(1.0, 1.0, 1.0, 1.0)),但它总是什么都不显示。

为了设置着色器,我首先将 VAO 和 VBO 设置为从以下列表中传递DrawVertex

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(2, &GFXVBO);
glBindBuffer(GL_ARRAY_BUFFER, GFXVBO);
glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE, sizeof(DrawVertex), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_SHORT, GL_FALSE, sizeof(DrawVertex), (void *)(sizeof(short) * 2));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(DrawVertex), (void *)(sizeof(short) * 4));
glEnableVertexAttribArray(2);

然后使用下面的代码进行绘制(保证VAO和VBO绑定,gfxShader只是使用程序的助手):

gfxShader.use();

// [setup the program, change uniforms as necessary]

// lastRenderCount is how many to render
// gfxPolyList is the list of DrawVertex
glBufferData(GL_ARRAY_BUFFER, lastRenderCount * sizeof(DrawVertex), gfxPolyList, GL_DYNAMIC_DRAW);

glDrawArrays(GL_TRIANGLES, 0, lastRenderCount);

gfxShader.stop();

然而,尽管如此,尽管RenderDoc 显示输入正在被传递,输出根本没有显示任何内容。最重要的是,NVIDIA Nsight 表示没有绘制任何片段。我哪里会出错?

对于上下文,这里是 struct DrawVertex

struct DrawVertex {
    short x;
    short y;
    short u;
    short v;

    Color color = 0; //0xRRGGBBAA
};

标签: c++openglglsl

解决方案


gl_Position = vec4(in_pos, 0.0, 1.0) * projection;

这是错误的。矩阵乘法不可交换。应该:

gl_Position = projection * vec4(in_pos, 0.0, 1.0);

如果你不相信我,试试这个:

glm::mat4 proj = {
    1.0f, 0.0f, 3.0f, 5.0f,
    0.0f, 1.0f, 3.0f, 6.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 3.0f, 1.0f
};
glm::vec4 vec = { 0.0f, 1.0f, 0.0f, 1.0f };
glm::vec4 result1 = proj * vec;
glm::vec4 result2 = vec * proj;
std::cout << "result1: " << result1.x << result1.y << result1.z << result1.w << '\n';
std::cout << "result2: " << result2.x << result2.y << result2.z << result2.w << '\n';

// Output:
result1: 0167
result2: 5701

https://learnopengl.com/Getting-started/Transformations

编辑:您的片段着色器仅在以下情况下运行in_color.a == 0.0?你确定这是正确的吗?也许您打算!=改用。


推荐阅读