/
ArtemNech
/
simpleOpenGL
Обзор
Документация
Войти
/
ArtemNech
/
simpleOpenGL
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
backend/ogl_sys/drawing-sets/shaderprogram.h
202 строки
6 KB
Artem Nechitaylenko
Старый телевизор добавлен
21 май 2026, 08:11
21 май 2026, 08:11
e78c117
Код
Авторство
О чём код?
#ifndef OPENGL_HANDLES_H #define OPENGL_HANDLES_H #include "glad.h" #include <glm/glm.hpp> #include <iostream> // ============================================ // ShaderProgram // ============================================ class ShaderProgram { GLuint m_id; std::vector<std::string> m_errors; private: // methods GLuint compileShader(const std::string& source, GLenum type) { GLuint shader = glCreateShader(type); const char* src = source.c_str(); glShaderSource(shader, 1, &src, nullptr); glCompileShader(shader); GLint success; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if (!success) { char infoLog[512]; glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::COMPILATION_FAILED\n" << infoLog << std::endl; std::cout << "Source: " << source << std::endl; /*const char* typeName = (type == GL_VERTEX_SHADER) ? "Vertex" : "Fragment"; std::string err = (std::string)typeName + ": " + infoLog; m_errors.push_back(err);*/ glDeleteShader(shader); return 0; } return shader; } public: ShaderProgram() { m_id = glCreateProgram(); } ~ShaderProgram() { if (m_id) glDeleteProgram(m_id); } ShaderProgram(const ShaderProgram&) = delete; ShaderProgram& operator=(const ShaderProgram&) = delete; ShaderProgram(ShaderProgram&& other) noexcept : m_id(other.m_id) { other.m_id = 0; } void bind() const { glUseProgram(m_id); } void unbind() const { glUseProgram(0); } [[nodiscard]] GLuint get() const { return m_id; } [[nodiscard]] bool isValid() const { return m_id != 0; } std::vector<std::string>& errors() { return m_errors; } void setUniform(const char* name, const glm::mat4& mat) const { glUniformMatrix4fv(glGetUniformLocation(m_id, name), 1, GL_FALSE, (const GLfloat*)&mat[0][0]); } void setUniform(const char* name, float value) const { glUniform1f(glGetUniformLocation(m_id, name), (GLfloat)value); } void setUniform(const char* name, int value) const { glUniform1i(glGetUniformLocation(m_id, name), value); } void setUniform(const char* name, const glm::vec2& vec) const { glUniform2fv(glGetUniformLocation(m_id, name), 1, (const GLfloat*)&vec[0]); } void setUniform(const char* name, const glm::vec3& vec) const { glUniform3fv(glGetUniformLocation(m_id, name), 1, (const GLfloat*)&vec[0]); } void setUniform(const char* name, const glm::vec4& vec) const { glUniform4fv(glGetUniformLocation(m_id, name), 1, (const GLfloat*)&vec[0]); } // Компиляция из строк bool compile(const std::string& vertexSource, const std::string& fragmentSource) { m_errors.clear(); // Компилируем вершинный шейдер GLuint vertexShader = compileShader(vertexSource, GL_VERTEX_SHADER); if (vertexShader == 0) return false; // Компилируем фрагментный шейдер GLuint fragmentShader = compileShader(fragmentSource, GL_FRAGMENT_SHADER); if (fragmentShader == 0) { char infoLog[512]; glGetProgramInfoLog(m_id, 512, nullptr, infoLog); std::string err = infoLog; m_errors.push_back(err); glDeleteShader(vertexShader); return false; } // Прикрепляем шейдеры к программе glAttachShader(m_id, vertexShader); glAttachShader(m_id, fragmentShader); // Линкуем glLinkProgram(m_id); // Проверяем линковку GLint success; glGetProgramiv(m_id, GL_LINK_STATUS, &success); if (!success) { char infoLog[512]; glGetProgramInfoLog(m_id, 512, nullptr, infoLog); //std::cerr << "Program linking failed:\n" << infoLog << std::endl; std::string err = infoLog; m_errors.push_back(err); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return false; } // Очищаем шейдеры (они уже прикреплены) glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return success; } }; // ============================================ // Buffer // ============================================ enum BufferType { Vertex = GL_ARRAY_BUFFER, Index = GL_ELEMENT_ARRAY_BUFFER }; enum BufferUsage { Static = GL_STATIC_DRAW, Dynamic = GL_DYNAMIC_DRAW, Stream = GL_STREAM_DRAW }; class Buffer { GLuint m_id; BufferType m_type; public: explicit Buffer(BufferType type) : m_id(0), m_type(type) { glGenBuffers(1, &m_id); } GLuint id() { return m_id; } ~Buffer() { if (m_id) glDeleteBuffers(1, &m_id); } Buffer(const Buffer&) = delete; Buffer& operator=(const Buffer&) = delete; Buffer(Buffer&& other) noexcept : m_id(other.m_id), m_type(other.m_type) { other.m_id = 0; } void bind() const { glBindBuffer(static_cast<GLenum>(m_type), m_id); } void unbind() const { glBindBuffer(static_cast<GLenum>(m_type), 0); } void data(const void* vertices, size_t size, BufferUsage usage) { glBufferData(static_cast<GLenum>(m_type), (GLsizeiptr)size, vertices, static_cast<GLenum>(usage)); } }; // ============================================ // VertexArray // ============================================ class VertexArray { GLuint m_id; public: VertexArray() : m_id(0) { glGenVertexArrays(1, &m_id); } GLuint id() {return m_id; } ~VertexArray() { if (m_id) glDeleteVertexArrays(1, &m_id); } VertexArray(const VertexArray&) = delete; VertexArray& operator=(const VertexArray&) = delete; VertexArray(VertexArray&& other) noexcept : m_id(other.m_id) { other.m_id = 0; } void bind() const { glBindVertexArray(m_id); } static void unbind() { glBindVertexArray(0); } void addAttribute(const Buffer& buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, size_t offset) const { bind(); buffer.bind(); glVertexAttribPointer(index, size, type, normalized, stride, (void*)offset); glEnableVertexAttribArray(index); } }; #endif // OPENGL_HANDLES_H