c++openglglslfstreamsstream

OpenGL error(#97) No program main found even though the shader is correct and successfully read from a file


I was building my own shader based on the https://learnopengl.com/ tutorial.
The problem was that I have the following error when linking the shader program

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

the shader class I built is

#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);
    }
};

as you can see there is no logical error I've made up there, and the fragmentCode && vertexCode strings were the same in the shaders files I made
where vertex is

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

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

And the fragment is

#version 330

out vec4 finalColor;

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

Solution

  • The error was in fragmentStream << fragmentStream.rdbuf(); and that's why there is a warning in my FRAGMENT SHADER LOG, and this line must be replaced by this fragmentStream << fragmentFile.rdbuf(); This is my fault, I was using very similar names in this class, and unfortunately both stringstream and ifstream classes have rdbuf() function.