Files
XCEngine/tests/OpenGL/OpenGLShader.cpp
ssdfasd 170df5506b Add OpenGLShader class
- Created OpenGLShader class for shader compilation
- Supports compiling from file or source code
- Provides uniform setting methods (SetInt, SetFloat, SetVec3, SetMat4)
- Integrated with GLAD for OpenGL function loading
2026-03-16 16:09:09 +08:00

131 lines
3.5 KiB
C++

#define GLFW_INCLUDE_NONE
#include "OpenGLShader.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <fstream>
#include <sstream>
#include <iostream>
namespace XCEngine {
namespace RHI {
OpenGLShader::OpenGLShader()
: m_program(0) {
}
OpenGLShader::~OpenGLShader() {
Shutdown();
}
bool OpenGLShader::CompileFromFile(const char* vertexPath, const char* fragmentPath) {
std::string vertexCode, fragmentCode;
std::ifstream vShaderFile(vertexPath), fShaderFile(fragmentPath);
if (!vShaderFile.is_open() || !fShaderFile.is_open()) {
return false;
}
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
return Compile(vertexCode.c_str(), fragmentCode.c_str());
}
bool OpenGLShader::Compile(const char* vertexSource, const char* fragmentSource) {
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vertexSource, NULL);
glCompileShader(vertex);
if (!CheckCompileErrors(vertex, "VERTEX")) {
return false;
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fragmentSource, NULL);
glCompileShader(fragment);
if (!CheckCompileErrors(fragment, "FRAGMENT")) {
return false;
}
m_program = glCreateProgram();
glAttachShader(m_program, vertex);
glAttachShader(m_program, fragment);
glLinkProgram(m_program);
if (!CheckLinkErrors(m_program)) {
return false;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
return true;
}
void OpenGLShader::Shutdown() {
if (m_program) {
glDeleteProgram(m_program);
m_program = 0;
}
}
void OpenGLShader::Use() const {
glUseProgram(m_program);
}
void OpenGLShader::SetInt(const std::string& name, int value) const {
glUniform1i(glGetUniformLocation(m_program, name.c_str()), value);
}
void OpenGLShader::SetFloat(const std::string& name, float value) const {
glUniform1f(glGetUniformLocation(m_program, name.c_str()), value);
}
void OpenGLShader::SetVec3(const std::string& name, float x, float y, float z) const {
glUniform3f(glGetUniformLocation(m_program, name.c_str()), x, y, z);
}
void OpenGLShader::SetVec3(const std::string& name, const float* values) const {
glUniform3fv(glGetUniformLocation(m_program, name.c_str()), 1, values);
}
void OpenGLShader::SetMat4(const std::string& name, const float* value) const {
glUniformMatrix4fv(glGetUniformLocation(m_program, name.c_str()), 1, GL_FALSE, value);
}
bool OpenGLShader::CheckCompileErrors(unsigned int shader, const char* type) {
int success;
char infoLog[1024];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR: " << type << "\n" << infoLog << std::endl;
return false;
}
return true;
}
bool OpenGLShader::CheckLinkErrors(unsigned int program) {
int success;
char infoLog[1024];
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(program, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR\n" << infoLog << std::endl;
return false;
}
return true;
}
} // namespace RHI
} // namespace XCEngine