为什么GLSL着色器程序无法正确链接?

问题描述 投票:0回答:1

由于未知原因,GLSL 着色器程序无法正确链接,日志为空。着色器编译正确。

尝试做:

CompileShaders("Data/Shaders/ui", 0b01, MainUiShader);

...给出错误:

ERROR: Cant link shaders

这是带有函数的标题:

void CompileShader(std::string ShaderFile, GLenum ShaderType, GLuint ShaderVariable) {
    LoadFile(ShaderFile);
    ShaderVariable = glCreateShader(ShaderType);
    const char* ShaderSource = TempData0.c_str();
    glShaderSource(ShaderVariable, 1, &ShaderSource, NULL);
    glCompileShader(ShaderVariable);

    glGetShaderiv(ShaderVariable, GL_COMPILE_STATUS, &TempValue);
    if (!TempValue)
    {glGetShaderInfoLog(ShaderVariable, 4096, NULL, Log);
            std::cout << "ERROR: shader compilation fail\n";
            std::cout << Log << std::endl;}
    else {std::cout << "Shader compiled\n";}}

void CompileShaders(std::string ShaderFile, int8_t ShaderTypes, GLuint ShaderVariable) 
{
    ShaderVariable = glCreateProgram();
    if ((0b01 & ShaderTypes) > 0) {
        CompileShader(ShaderFile.append(".vsh"), GL_VERTEX_SHADER, Stemp[0]);
        glAttachShader(ShaderVariable, Stemp[0]);
        std::cout << ShaderFile;
        ShaderFile = ShaderFile.substr(0, ShaderFile.size() - 4);}
        CompileShader(ShaderFile.append(".fsh"), GL_FRAGMENT_SHADER, Stemp[2]);
        glAttachShader(ShaderVariable, Stemp[2]);
        std::cout << ShaderFile;

    glLinkProgram(ShaderVariable);
    glGetProgramiv(ShaderVariable, GL_LINK_STATUS, &TempValue);
    if (!TempValue) {
        std::cout << "ERROR: Cant link shaders";
        glGetProgramInfoLog(ShaderVariable, 512, NULL, Log);
        std::cout<<Log;
    }
}

主要代码如下:

#include "main.h"
int main()
{
//GLFWInitialization:
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    ResetWindow();

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

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

    CompileShaders("Data/Shaders/ui", 0b00, MainUiShader);

    while (Window) {
        if (glfwWindowShouldClose(Window)) { glfwTerminate(); return 0; }
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBindVertexArray(VAO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_DYNAMIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
            (void*)0);
        glEnableVertexAttribArray(0);

        glUseProgram(MainUiShader);

        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(Window);
        glfwPollEvents();
    }
    
}

ui.fsh:

#version 330 core

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}

ui.vsh:

#version 330 core

layout (location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(position.x + 0.5, position.y, position.z, 1.0);
}

(所有变量定义正确,OpenGL初始化正确,但如果你需要什么我可以发送它,或者我可以发送完整的项目)。

所以我开始根据指南编写这段代码,它可以绘制1个三角形。这个三角形应该是橙色的,但它是黑色的,因为片段着色器由于这个问题而无法工作,我不知道为什么会发生这种情况。

c++ opengl glsl glfw
1个回答
2
投票

这个问题与 OpenGL 无关,而是与将变量传递给方法的方式有关。着色器的句柄通过值传递给CompileShader

方法。此方法内的更改不会反映给调用者,这意味着 
Stemp[0]
Stemp[2]
 永远不会设置。由于未设置它们,因此无效的着色器对象将附加到着色器程序并且链接失败。

您可以更改代码以传递类似于以下内容的引用:

void CompileShader(std::string ShaderFile, GLenum ShaderType, GLuint& ShaderVariable)
,如果您希望从外部看到对 ShaderVariable 的更改。

请注意,您的

CompileShaders

 方法也存在同样的问题。

© www.soinside.com 2019 - 2024. All rights reserved.