-2

我正在根据https://learnopengl.com/教程构建自己的着色器。
问题是链接着色器程序时出现以下错误

VERTEX SHADER LOG

FRAGMENT SHADER LOG
WARNING: warning(#272) Implicit version number 110 not supported by GL3 forward compatible context

SHADER LINKING LOG
Vertex shader(s) failed to link, fragment shader(s) failed to link.
Vertex link error: INVALID_OPERATION.
ERROR: error(#97) No program main found
fragment link error: INVALID_OPERATION.
ERROR: error(#97) No program main found

我建立的着色器类是

#pragma once


#include <glew/glew.h>

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

class Shader
{
    private:

    unsigned int ID;

    void checkShaderCompile(unsigned int shaderID, std::string type)
    {
        char compileLog[1024];
        glGetShaderInfoLog(shaderID, 1024, NULL, compileLog);
        std::cout << type << " LOG" << std::endl;
        std::cout << compileLog << std::endl;
    }

    void checkProgramLink()
    {
        char linkLog[1024];
        glGetProgramInfoLog(ID, 1024, NULL, linkLog);
        std::cout << "SHADER LINKING LOG" << std::endl;
        std::cout << linkLog << std::endl;
    }

    std::string getVertexSource(const char* vertexPath)
    {
        std::string vertexSource;
        std::ifstream vertexFile;

        vertexFile.exceptions(std::ifstream::badbit | std::ifstream::failbit);

        try
        {
            vertexFile.open(vertexPath);

            std::stringstream vertexStream;
            vertexStream << vertexFile.rdbuf();

            vertexSource = vertexStream.str();
        }
        catch (std::ifstream::failure e)
        {
            std::cout << "CANNOT OPEN VERTEX SHADER" << std::endl;
        }

        return vertexSource;
    }

    std::string getFragmentSource(const char* fragmentPath)
    {
        std::string  fragmentSource;
        std::ifstream  fragmentFile;

        fragmentFile.exceptions(std::ifstream::badbit | std::ifstream::failbit);

        try
        {
            fragmentFile.open(fragmentPath);

            std::stringstream fragmentStream;
            fragmentStream << fragmentStream.rdbuf();

            fragmentSource = fragmentStream.str();
        }
        catch (std::ifstream::failure e)
        {
            std::cout << "CANNOT OPEN FRAGMENT SHADER" << std::endl;
        }

        return fragmentSource;
    }

    public:
    Shader(const char* vertexPath, const char* fragmentPath)
    {

        std::string vertexSource = getVertexSource(vertexPath);
        std::string fragmentSource = getFragmentSource(fragmentPath);

        const char* vertexCode = vertexSource.c_str();
        const char* fragmentCode = fragmentSource.c_str();

        //creating and compiling vertex shader
        unsigned int vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShaderID, 1, &vertexCode, NULL);
        glCompileShader(vertexShaderID);
        checkShaderCompile(vertexShaderID, "VERTEX SHADER");

        //creating and compiling frgment shader
        unsigned int fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShaderID, 1, &fragmentCode, NULL);
        glCompileShader(fragmentShaderID);
        checkShaderCompile(fragmentShaderID, "FRAGMENT SHADER");

        //creating and linking a shader program
        ID = glCreateProgram();
        glAttachShader(ID, vertexShaderID);
        glAttachShader(ID, fragmentShaderID);
        glLinkProgram(ID);
        checkProgramLink();


        glDeleteShader(vertexShaderID);
        glDeleteShader(fragmentShaderID);
    }

    void use()
    {
        glUseProgram(ID);
    }
};

如您所见,我在那里没有编造任何逻辑错误,并且我
在顶点所在的着色器文件中的 fragmentCode && vertexCode 字符串是相同的

#version 330
layout(location = 0) in vec3 vertexCoordinates;

void main()
{
    gl_Position = vec4(vertexCoordinates, 1.0);
}

片段是

#version 330

out vec4 finalColor;

void main()
{
    finalColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
4

2 回答 2

1

OpenGL 有时可能对版本和上下文很挑剔,最好的做法是确保所有内容都已更新(尤其是您的 GPU 驱动程序)。如果您的计算机支持它,我建议使用 OpenGL 版本 4.3,甚至 4.6。您的顶点着色器已编译,但您的片段未编译,考虑到它们使用相同的格式,这很奇怪。这是一个非常无意义的答案,更少的是要做什么,更多的是要确保的。所有这些因素相互影响,因此问题可能不在于错误所在。

于 2021-01-28T20:51:44.203 回答
0

错误出现了 fragmentStream << fragmentStream.rdbuf(); ,这就是为什么我的 FRAGMENT SHADER LOG 中有一个警告,并且必须用这个替换这一行 fragmentStream << fragmentFile.rdbuf(); 这是我的错,我在这个类中使用了非常相似的名称,不幸的是 stringstream 和 ifstream 类都有 rdbuf( ) 功能。

于 2021-01-28T21:24:51.967 回答