From 04ad0732633449167c478bdb84a8aa28351a2cea Mon Sep 17 00:00:00 2001 From: Linloir <3145078758@qq.com> Date: Mon, 12 Dec 2022 21:23:57 +0800 Subject: [PATCH] Implement shader and mesh classes --- FinalProject/mesh.cpp | 46 +++++++++++++++ FinalProject/mesh.h | 7 ++- FinalProject/shader.cpp | 120 ++++++++++++++++++++++++++++++++++++++++ FinalProject/shader.h | 51 ++++++++--------- 4 files changed, 194 insertions(+), 30 deletions(-) diff --git a/FinalProject/mesh.cpp b/FinalProject/mesh.cpp index 6f70f09..986cf26 100644 --- a/FinalProject/mesh.cpp +++ b/FinalProject/mesh.cpp @@ -1 +1,47 @@ #pragma once + +#include "mesh.h" +#include "utils.h" +#include "logger.h" + +Mesh::Mesh(const std::vector& vertices, const std::vector& indices, const std::vector& textures) { + _vertices = vertices; + _indices = indices; + _textures = textures; + + setupMesh(); +} + +Mesh::Mesh(const std::vector& vertices, const std::vector& textures) { + _vertices = vertices; + _textures = textures; + + setupMesh(); +} + +void Mesh::render(const ShaderProgram& shader) const { + unsigned int diffuseNr = 1; + unsigned int specularNr = 1; + for (unsigned int i = 0; i < _textures.size(); i++) { + OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding + // retrieve texture number (the N in diffuse_textureN) + std::string number; + std::string name = _textures[i].type() == TextureType::DIFFUSE ? "texture_diffuse" : "texture_specular"; + if (_textures[i].type() == TextureType::DIFFUSE) + number = std::to_string(diffuseNr++); + else if (_textures[i].type() == TextureType::SPECULAR) + number = std::to_string(specularNr++); + + OPENGL_EXTRA_FUNCTIONS->glUniform1i(OPENGL_EXTRA_FUNCTIONS->glGetUniformLocation(shader.programId(), (name + number).c_str()), i); + _textures[i].bind(); + } + OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0); + + _vao.setActive(); + glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0); + _vao.setInactive(); +} + +void Mesh::setupMesh() { + _vao = VertexArrayObject(_vertices, _indices); +} diff --git a/FinalProject/mesh.h b/FinalProject/mesh.h index dd9628c..995630e 100644 --- a/FinalProject/mesh.h +++ b/FinalProject/mesh.h @@ -16,8 +16,8 @@ private: VertexArrayObject _vao; public: - Mesh(std::vector vertices, std::vector indices, std::vector textures); - Mesh(std::vector vertices, std::vector textures); + Mesh(const std::vector& vertices, const std::vector& indices, const std::vector& textures); + Mesh(const std::vector& vertices, const std::vector& textures); public: inline std::vector vertices() const { return _vertices; } @@ -28,4 +28,7 @@ public: public: void render(const ShaderProgram& shader) const ; + +private: + void setupMesh(); }; \ No newline at end of file diff --git a/FinalProject/shader.cpp b/FinalProject/shader.cpp index 6f70f09..b43038b 100644 --- a/FinalProject/shader.cpp +++ b/FinalProject/shader.cpp @@ -1 +1,121 @@ #pragma once + +#include + +#include "shader.h" +#include "utils.h" +#include "logger.h" + +inline void Shader::dispose() { + OPENGL_EXTRA_FUNCTIONS->glDeleteShader(_shaderId); + _shaderId = 0; +} + +VertexShader::VertexShader(const std::string& source){ + _shaderId = OPENGL_EXTRA_FUNCTIONS->glCreateShader(GL_VERTEX_SHADER); + compile(source); +} + +void VertexShader::compile(const std::string& source) { + const char* sourcePtr = source.c_str(); + OPENGL_EXTRA_FUNCTIONS->glShaderSource(_shaderId, 1, &sourcePtr, nullptr); + OPENGL_EXTRA_FUNCTIONS->glCompileShader(_shaderId); +} + +FragmentShader::FragmentShader(const std::string& source){ + _shaderId = OPENGL_EXTRA_FUNCTIONS->glCreateShader(GL_FRAGMENT_SHADER); + compile(source); +} + +void FragmentShader::compile(const std::string& source) { + const char* sourcePtr = source.c_str(); + OPENGL_EXTRA_FUNCTIONS->glShaderSource(_shaderId, 1, &sourcePtr, nullptr); + OPENGL_EXTRA_FUNCTIONS->glCompileShader(_shaderId); +} + +GeometryShader::GeometryShader(const std::string& source) { + _shaderId = OPENGL_EXTRA_FUNCTIONS->glCreateShader(GL_GEOMETRY_SHADER); + compile(source); +} + +void GeometryShader::compile(const std::string& source) { + const char* sourcePtr = source.c_str(); + OPENGL_EXTRA_FUNCTIONS->glShaderSource(_shaderId, 1, &sourcePtr, nullptr); + OPENGL_EXTRA_FUNCTIONS->glCompileShader(_shaderId); +} + +ShaderProgram::ShaderProgram() { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); +} + +ShaderProgram::ShaderProgram(VertexShader vertexShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, vertexShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + vertexShader.dispose(); +} + +ShaderProgram::ShaderProgram(FragmentShader fragmentShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, fragmentShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + fragmentShader.dispose(); +} + +ShaderProgram::ShaderProgram(GeometryShader geometryShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, geometryShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + geometryShader.dispose(); +} + +ShaderProgram::ShaderProgram(VertexShader vertexShader, FragmentShader fragmentShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, vertexShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, fragmentShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + vertexShader.dispose(); + fragmentShader.dispose(); +} + +ShaderProgram::ShaderProgram(VertexShader vertexShader, GeometryShader geometryShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, vertexShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, geometryShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + vertexShader.dispose(); + geometryShader.dispose(); +} + +ShaderProgram::ShaderProgram(FragmentShader fragmentShader, GeometryShader geometryShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, fragmentShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, geometryShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + fragmentShader.dispose(); + geometryShader.dispose(); +} + +ShaderProgram::ShaderProgram(VertexShader vertexShader, FragmentShader fragmentShader, GeometryShader geometryShader) { + _programId = OPENGL_EXTRA_FUNCTIONS->glCreateProgram(); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, vertexShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, fragmentShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glAttachShader(_programId, geometryShader.shaderId()); + OPENGL_EXTRA_FUNCTIONS->glLinkProgram(_programId); + vertexShader.dispose(); + fragmentShader.dispose(); + geometryShader.dispose(); +} + +inline void ShaderProgram::setActive() { + OPENGL_EXTRA_FUNCTIONS->glUseProgram(_programId); +} + +inline void ShaderProgram::setInactive() { + OPENGL_EXTRA_FUNCTIONS->glUseProgram(0); +} + +inline void ShaderProgram::dispose() { + OPENGL_EXTRA_FUNCTIONS->glDeleteProgram(_programId); + _programId = 0; +} \ No newline at end of file diff --git a/FinalProject/shader.h b/FinalProject/shader.h index 32c5630..e27e588 100644 --- a/FinalProject/shader.h +++ b/FinalProject/shader.h @@ -2,56 +2,52 @@ #include #include -#include +#include class Shader { -private: - int _shaderId = -1; +protected: + unsigned int _shaderId = -1; public: - Shader(); + Shader() {} + + inline unsigned int shaderId() const { return _shaderId; } + inline void dispose(); protected: - virtual void compile(std::string sourceFilePath) = 0; - void dispose(); - -public: - bool operator == (const Shader& other) const; + virtual void compile(const std::string& sourceFilePath) = 0; }; class VertexShader : public Shader { public: - VertexShader(); - VertexShader(std::string sourceFilePath); + VertexShader() {} + VertexShader(const std::string& sourceFilePath); protected: - virtual void compile(std::string sourceFilePath) override; + virtual void compile(const std::string& sourceFilePath) override; }; class FragmentShader : public Shader { public: - FragmentShader(); - FragmentShader(std::string sourceFilePath); + FragmentShader() {} + FragmentShader(const std::string& sourceFilePath); protected: - virtual void compile(std::string sourceFilePath) override; + virtual void compile(const std::string& sourceFilePath) override; }; class GeometryShader : public Shader { public: - GeometryShader(); - GeometryShader(std::string sourceFilePath); + GeometryShader() {} + GeometryShader(const std::string& sourceFilePath); protected: - virtual void compile(std::string sourceFilePath) override; + virtual void compile(const std::string& sourceFilePath) override; }; class ShaderProgram { private: - VertexShader _vertexShader; - FragmentShader _fragmentShader; - GeometryShader _geometryShader; - unsigned int _programId = -1; + unsigned int _programId = 0; public: ShaderProgram(); @@ -62,13 +58,12 @@ public: ShaderProgram(VertexShader vertexShader, GeometryShader geometryShader); ShaderProgram(FragmentShader fragmentShader, GeometryShader geometryShader); ShaderProgram(VertexShader vertexShader, FragmentShader fragmentShader, GeometryShader geometryShader); - ~ShaderProgram(); public: - bool operator == (const Shader& other); - - template - void setUniform(std::string name, const std::vector& values); - inline void setActive(); + inline void setInactive(); + + inline unsigned int programId() const { return _programId; } + + inline void dispose(); };