Mahmoud Kanbar
Mahmoud Kanbar

Reputation: 73

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

Upvotes: -1

Views: 348

Answers (2)

Mahmoud Kanbar
Mahmoud Kanbar

Reputation: 73

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.

Upvotes: 0

Ty Staszak
Ty Staszak

Reputation: 115

OpenGL can be finicky with versions and contexts sometimes, and the best course of action is to make sure everything is updated (especially your GPU drivers). If your computer supports it, I'd recommend using OpenGL version 4.3, or even 4.6. Your vertex shader is compiled but not your fragment, which is very odd, considering that they use the same format. This is a very non-answer and less of here's what to do, more of here's what to make sure. All of these things factor into one another, so the problem might be not where the error is.

Upvotes: 1

Related Questions