From 548c2b03f8184497a5306f4b4412e3120eaef211 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 8 Jun 2014 15:40:35 +0300 Subject: Add shaderprogram class. --- src/render/shaders/shader.h | 3 +++ src/render/shaders/shaderprogram.cpp | 49 +++++++++++++++++++++++++++++++++ src/render/shaders/shaderprogram.h | 48 +++++++++++++++++++++++++++++++++ src/render/shaders/shadersmanager.cpp | 51 +++++++++++++++++++++++++++++++++++ src/render/shaders/shadersmanager.h | 7 ++++- 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 src/render/shaders/shaderprogram.cpp create mode 100644 src/render/shaders/shaderprogram.h (limited to 'src/render/shaders') diff --git a/src/render/shaders/shader.h b/src/render/shaders/shader.h index 6ee964704..adcc29702 100644 --- a/src/render/shaders/shader.h +++ b/src/render/shaders/shader.h @@ -34,6 +34,9 @@ class Shader final : public Resource A_DELETE_COPY(Shader) + unsigned int getShaderId() const + { return mShaderId; } + protected: unsigned int mShaderId; }; diff --git a/src/render/shaders/shaderprogram.cpp b/src/render/shaders/shaderprogram.cpp new file mode 100644 index 000000000..7d79e5cb9 --- /dev/null +++ b/src/render/shaders/shaderprogram.cpp @@ -0,0 +1,49 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef USE_OPENGL + +#include "render/shaders/shaderprogram.h" + +#include "render/mgl.h" + +#include "render/shaders/shader.h" + +ShaderProgram::ShaderProgram(const unsigned int id, + Shader *const vertex, + Shader *const fragment) : + Resource(), + mProgramId(id), + mVertex(vertex), + mFragment(fragment) +{ +} + +ShaderProgram::~ShaderProgram() +{ + if (mProgramId) + mglDeleteProgram(mProgramId); + if (mVertex) + mVertex->decRef(); + if (mFragment) + mFragment->decRef(); +} + +#endif // USE_OPENGL diff --git a/src/render/shaders/shaderprogram.h b/src/render/shaders/shaderprogram.h new file mode 100644 index 000000000..bb01a4802 --- /dev/null +++ b/src/render/shaders/shaderprogram.h @@ -0,0 +1,48 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef RENDER_SHADERPROGRAM_H +#define RENDER_SHADERPROGRAM_H + +#ifdef USE_OPENGL + +#include "resources/resource.h" + +class Shader; + +class ShaderProgram final : public Resource +{ + public: + ShaderProgram(const unsigned int id, + Shader *const vertex, + Shader *const fragment); + + ~ShaderProgram(); + + A_DELETE_COPY(ShaderProgram) + + protected: + unsigned int mProgramId; + Shader *mVertex; + Shader *mFragment; +}; + +#endif // USE_OPENGL +#endif // RENDER_SHADERPROGRAM_H diff --git a/src/render/shaders/shadersmanager.cpp b/src/render/shaders/shadersmanager.cpp index 85c5bf64e..e457ba473 100644 --- a/src/render/shaders/shadersmanager.cpp +++ b/src/render/shaders/shadersmanager.cpp @@ -28,6 +28,9 @@ #include "render/mgl.h" #include "render/shaders/shader.h" +#include "render/shaders/shaderprogram.h" + +#include "resources/resourcemanager.h" #include "utils/files.h" @@ -59,4 +62,52 @@ Shader *ShadersManager::createShader(const unsigned int type, return nullptr; } +ShaderProgram *ShadersManager::createProgram(const std::string &vertex, + const std::string &fragment) +{ + ResourceManager *const resman = ResourceManager::getInstance(); + Shader *const vertexShader = static_cast( + resman->getShader(GL_VERTEX_SHADER, vertex)); + if (!vertexShader) + return nullptr; + + Shader *const fragmentShader = static_cast( + resman->getShader(GL_FRAGMENT_SHADER, fragment)); + + if (!fragmentShader) + { + vertexShader->decRef(); + return nullptr; + } + + GLuint programId = mglCreateProgram(); + if (!programId) + { + vertexShader->decRef(); + fragmentShader->decRef(); + return nullptr; + } + + mglAttachShader(programId, vertexShader->getShaderId()); + mglAttachShader(programId, fragmentShader->getShaderId()); + mglLinkProgram(programId); + GLint isLinked = 0; + mglGetProgramiv(programId, GL_LINK_STATUS, &isLinked); + if (isLinked == GL_TRUE) + return new ShaderProgram(programId, vertexShader, fragmentShader); + + GLint len = 0; + mglGetProgramiv(programId, GL_INFO_LOG_LENGTH, &len); + char *buf = new char[len + 1]; + mglGetProgramInfoLog(programId, len, &len, buf); + buf[len] = 0; + logger->log("Program '%s, %s' compilation error: %s", + vertexShader->getIdPath().c_str(), + fragmentShader->getIdPath().c_str(), + buf); + delete [] buf; + mglDeleteProgram(programId); + return nullptr; +} + #endif diff --git a/src/render/shaders/shadersmanager.h b/src/render/shaders/shadersmanager.h index 0ad8556c8..ba7d26438 100644 --- a/src/render/shaders/shadersmanager.h +++ b/src/render/shaders/shadersmanager.h @@ -27,13 +27,18 @@ #include "localconsts.h" -struct Shader; +class Shader; +class ShaderProgram; class ShadersManager final { public: Shader *createShader(const unsigned int type, const std::string &fileName) A_WARN_UNUSED; + + ShaderProgram *createProgram(const std::string &vertex, + const std::string &fragment) + A_WARN_UNUSED; }; extern ShadersManager shaders; -- cgit v1.2.3-60-g2f50