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/mgl.cpp | 1 + src/render/mgl.h | 1 + src/render/mgltypes.h | 2 ++ 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 ++++- 8 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 src/render/shaders/shaderprogram.cpp create mode 100644 src/render/shaders/shaderprogram.h (limited to 'src/render') diff --git a/src/render/mgl.cpp b/src/render/mgl.cpp index 47d087325..d18763051 100644 --- a/src/render/mgl.cpp +++ b/src/render/mgl.cpp @@ -83,6 +83,7 @@ defName(glUniform2f); defName(glUniform3f); defName(glUniform4f); defName(glCheckFramebufferStatus); +defName(glGetProgramInfoLog); #ifdef WIN32 defName(wglGetExtensionsString); diff --git a/src/render/mgl.h b/src/render/mgl.h index 02122f88c..a72ef0331 100644 --- a/src/render/mgl.h +++ b/src/render/mgl.h @@ -86,6 +86,7 @@ defNameE(glUniform2f); defNameE(glUniform3f); defNameE(glUniform4f); defNameE(glCheckFramebufferStatus); +defNameE(glGetProgramInfoLog); #ifdef WIN32 defNameE(wglGetExtensionsString); diff --git a/src/render/mgltypes.h b/src/render/mgltypes.h index 497fa6afa..7e56941a9 100644 --- a/src/render/mgltypes.h +++ b/src/render/mgltypes.h @@ -121,6 +121,8 @@ typedef void (APIENTRY *glUniform3f_t) (GLint location, typedef void (APIENTRY *glUniform4f_t) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef GLenum (APIENTRY *glCheckFramebufferStatus_t) (GLenum target); +typedef void (APIENTRY *glGetProgramInfoLog_t) (GLuint program, + GLsizei maxLength, GLsizei *length, GLchar *infoLog); // callback typedef void (APIENTRY *GLDEBUGPROC_t) (GLenum source, GLenum type, GLuint id, 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