Hello there. I’m totally new to OpenGL so I hope to be as clear as possible. I’m currently following the Learn OpenGL guide and I’ve reached the Shaders chapter (I don’t know why but I can’t add links because otherwise I can’t post the topic). I decided to make my own version of the Shader class that you can find at the end of the chapter. Jumping directly to the .cpp file, this is my own version:
#include "./shader.hpp"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
customlib::Shader::Shader(const char* vertexPath, const char* fragmentPath)
{
const char* vertexShaderSource;
const char* fragmentShaderSource;
customlib::Shader::m_ReadShaderFiles(&vertexShaderSource, &fragmentShaderSource, vertexPath, fragmentPath);
uint32_t vertexID;
uint32_t fragmentID;
customlib::Shader::m_CompileShader(vertexID, GL_VERTEX_SHADER, vertexShaderSource);
customlib::Shader::m_CompileShader(fragmentID, GL_FRAGMENT_SHADER, fragmentShaderSource);
customlib::Shader::m_GenerateShaderProgram(ID, vertexID, fragmentID);
glDeleteShader(vertexID);
glDeleteShader(fragmentID);
}
void customlib::Shader::Use() { glUseProgram(ID); }
void customlib::Shader::SetUniformBool(const char* name, bool value) const
{
int uniformReference = glGetUniformLocation(ID, name);
glUniform1i(uniformReference, (int)value);
}
void customlib::Shader::SetUniformInt(const char* name, int value) const
{
int uniformReference = glGetUniformLocation(ID, name);
glUniform1i(uniformReference, value);
}
void customlib::Shader::SetUniformFloat(const char* name, float value) const
{
int uniformReference = glGetUniformLocation(ID, name);
glUniform1f(uniformReference, value);
}
uint32_t customlib::Shader::GetID() { return ID; }
void customlib::Shader::m_ReadShaderFiles(const char** outVertShaderSource, const char** outFragShaderSource, const char* vertexPath, const char* fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
// Vertex Shader // Fragment Shader
vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath);
std::stringstream vShaderStream; std::stringstream fShaderStream;
vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf();
vShaderFile.close(); fShaderFile.close();
vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
*outVertShaderSource = vertexCode.c_str();
*outFragShaderSource = fragmentCode.c_str();
}
void customlib::Shader::m_CompileShader(uint32_t& shaderID, GLenum shaderType, const char* shaderSource)
{
shaderID = glCreateShader(shaderType);
glShaderSource(shaderID, 1, &shaderSource, NULL);
glCompileShader(shaderID);
int compileStatus;
char infoLog[512];
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compileStatus);
if (!compileStatus)
{
glGetShaderInfoLog(shaderID, 512, NULL, infoLog);
std::cout << "ERROR::SHADER_ID::" << shaderID << "::COMPILATION_FAILED\n" << infoLog << std::endl;
}
}
void customlib::Shader::m_GenerateShaderProgram(uint32_t& shaderProgramID, uint32_t vertex, uint32_t fragment)
{
shaderProgramID = glCreateProgram();
glAttachShader(shaderProgramID, vertex);
glAttachShader(shaderProgramID, fragment);
glLinkProgram(shaderProgramID);
int linkStatus;
char linkInfoLog[512];
glGetProgramiv(shaderProgramID, GL_LINK_STATUS, &linkStatus);
if (!linkStatus)
{
glGetProgramInfoLog(shaderProgramID, 512, NULL, linkInfoLog);
std::cout << "ERROR::SHADER_PROGRAM::" << shaderProgramID << "::LINKING_FAILED\n" << linkInfoLog << std::endl;
}
}
(where obviously customlib is my namespace).
I guess that the problem is probably related to the <fstream> and <sstream> libraries, because I get this error like 25% of the time randomly:
This is really weird because I also made my code to print what the ifstream read and there were no syntax errors. I don’t know why this happens, it’s just so random and annoying. Most of the times I have to excecute my project like 3 times before getting no error, without changing a single thing in my code
This is my fragment shader by the way:
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
void main()
{
FragColor = vec4(ourColor, 1.0);
}
