96 lines
2.6 KiB
C++
96 lines
2.6 KiB
C++
|
#include "Shader.h"
|
||
|
#include <fstream>
|
||
|
#include <sstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
Shader::~Shader()
|
||
|
{
|
||
|
if (m_ProgramID)
|
||
|
glDeleteProgram(m_ProgramID);
|
||
|
}
|
||
|
|
||
|
bool Shader::Load(const std::string& vertexPath, const std::string& fragmentPath)
|
||
|
{
|
||
|
// 1) Create shader objects
|
||
|
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||
|
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||
|
|
||
|
// 2) Load sources
|
||
|
std::string vertSource = LoadSourceFromFile(vertexPath);
|
||
|
std::string fragSource = LoadSourceFromFile(fragmentPath);
|
||
|
if (vertSource.empty() || fragSource.empty())
|
||
|
{
|
||
|
std::cerr << "[Shader] Failed to read shader files." << std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// 3) Compile vertex shader
|
||
|
{
|
||
|
const char* src = vertSource.c_str();
|
||
|
glShaderSource(vertexShader, 1, &src, nullptr);
|
||
|
glCompileShader(vertexShader);
|
||
|
if (!CompileShader(vertexShader, vertexPath))
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// 4) Compile fragment shader
|
||
|
{
|
||
|
const char* src = fragSource.c_str();
|
||
|
glShaderSource(fragmentShader, 1, &src, nullptr);
|
||
|
glCompileShader(fragmentShader);
|
||
|
if (!CompileShader(fragmentShader, fragmentPath))
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// 5) Create program and link
|
||
|
m_ProgramID = glCreateProgram();
|
||
|
glAttachShader(m_ProgramID, vertexShader);
|
||
|
glAttachShader(m_ProgramID, fragmentShader);
|
||
|
glLinkProgram(m_ProgramID);
|
||
|
|
||
|
// Check link status
|
||
|
GLint success;
|
||
|
glGetProgramiv(m_ProgramID, GL_LINK_STATUS, &success);
|
||
|
if (!success)
|
||
|
{
|
||
|
char infoLog[1024];
|
||
|
glGetProgramInfoLog(m_ProgramID, 1024, nullptr, infoLog);
|
||
|
std::cerr << "[Shader] Program linking failed:\n" << infoLog << std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Cleanup shader objects after linking
|
||
|
glDeleteShader(vertexShader);
|
||
|
glDeleteShader(fragmentShader);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool Shader::CompileShader(GLuint shaderID, const std::string& filePath)
|
||
|
{
|
||
|
GLint success;
|
||
|
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
|
||
|
if (!success)
|
||
|
{
|
||
|
char infoLog[1024];
|
||
|
glGetShaderInfoLog(shaderID, 1024, nullptr, infoLog);
|
||
|
std::cerr << "[Shader] Compilation error in " << filePath << ":\n"
|
||
|
<< infoLog << std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
std::string Shader::LoadSourceFromFile(const std::string& filePath)
|
||
|
{
|
||
|
std::ifstream file(filePath);
|
||
|
if (!file.is_open())
|
||
|
{
|
||
|
std::cerr << "[Shader] Could not open file: " << filePath << std::endl;
|
||
|
return "";
|
||
|
}
|
||
|
std::stringstream buffer;
|
||
|
buffer << file.rdbuf();
|
||
|
return buffer.str();
|
||
|
}
|