| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #include "shader.h"
- #include <QFile>
- #include <QTextStream>
- #include <QDebug>
- namespace Render::GL {
- Shader::Shader() {
- // Defer OpenGL function initialization until a context is current
- }
- Shader::~Shader() {
- if (m_program != 0) {
- glDeleteProgram(m_program);
- }
- }
- bool Shader::loadFromFiles(const QString& vertexPath, const QString& fragmentPath) {
- QFile vertexFile(vertexPath);
- QFile fragmentFile(fragmentPath);
-
- if (!vertexFile.open(QIODevice::ReadOnly) || !fragmentFile.open(QIODevice::ReadOnly)) {
- qWarning() << "Failed to open shader files";
- return false;
- }
-
- QTextStream vertexStream(&vertexFile);
- QTextStream fragmentStream(&fragmentFile);
-
- QString vertexSource = vertexStream.readAll();
- QString fragmentSource = fragmentStream.readAll();
-
- return loadFromSource(vertexSource, fragmentSource);
- }
- bool Shader::loadFromSource(const QString& vertexSource, const QString& fragmentSource) {
- initializeOpenGLFunctions();
- GLuint vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER);
- GLuint fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER);
-
- if (vertexShader == 0 || fragmentShader == 0) {
- return false;
- }
-
- bool success = linkProgram(vertexShader, fragmentShader);
-
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
-
- return success;
- }
- void Shader::use() {
- initializeOpenGLFunctions();
- glUseProgram(m_program);
- }
- void Shader::release() {
- initializeOpenGLFunctions();
- glUseProgram(0);
- }
- void Shader::setUniform(const QString& name, float value) {
- GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
- if (location != -1) {
- glUniform1f(location, value);
- }
- }
- void Shader::setUniform(const QString& name, const QVector3D& value) {
- GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
- if (location != -1) {
- glUniform3f(location, value.x(), value.y(), value.z());
- }
- }
- void Shader::setUniform(const QString& name, const QMatrix4x4& value) {
- GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
- if (location != -1) {
- glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
- }
- }
- void Shader::setUniform(const QString& name, int value) {
- GLint location = glGetUniformLocation(m_program, name.toUtf8().constData());
- if (location != -1) {
- glUniform1i(location, value);
- }
- }
- void Shader::setUniform(const QString& name, bool value) {
- setUniform(name, static_cast<int>(value));
- }
- GLuint Shader::compileShader(const QString& source, GLenum type) {
- initializeOpenGLFunctions();
- GLuint shader = glCreateShader(type);
-
- QByteArray sourceBytes = source.toUtf8();
- const char* sourcePtr = sourceBytes.constData();
- glShaderSource(shader, 1, &sourcePtr, nullptr);
- glCompileShader(shader);
-
- GLint success;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
- if (!success) {
- GLchar infoLog[512];
- glGetShaderInfoLog(shader, 512, nullptr, infoLog);
- qWarning() << "Shader compilation failed:" << infoLog;
- glDeleteShader(shader);
- return 0;
- }
-
- return shader;
- }
- bool Shader::linkProgram(GLuint vertexShader, GLuint fragmentShader) {
- initializeOpenGLFunctions();
- m_program = glCreateProgram();
- glAttachShader(m_program, vertexShader);
- glAttachShader(m_program, fragmentShader);
- glLinkProgram(m_program);
-
- GLint success;
- glGetProgramiv(m_program, GL_LINK_STATUS, &success);
- if (!success) {
- GLchar infoLog[512];
- glGetProgramInfoLog(m_program, 512, nullptr, infoLog);
- qWarning() << "Shader linking failed:" << infoLog;
- glDeleteProgram(m_program);
- m_program = 0;
- return false;
- }
-
- return true;
- }
- } // namespace Render::GL
|