summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-06-08 15:40:35 +0300
committerAndrei Karas <akaras@inbox.ru>2014-06-08 15:40:35 +0300
commit548c2b03f8184497a5306f4b4412e3120eaef211 (patch)
treea3813d15d21c320be53650e1e195b68842f12197
parent0f500fab826a57f8aae8a3e2062a90ee9e80a199 (diff)
downloadmv-548c2b03f8184497a5306f4b4412e3120eaef211.tar.gz
mv-548c2b03f8184497a5306f4b4412e3120eaef211.tar.bz2
mv-548c2b03f8184497a5306f4b4412e3120eaef211.tar.xz
mv-548c2b03f8184497a5306f4b4412e3120eaef211.zip
Add shaderprogram class.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/graphicsmanager.cpp1
-rw-r--r--src/render/mgl.cpp1
-rw-r--r--src/render/mgl.h1
-rw-r--r--src/render/mgltypes.h2
-rw-r--r--src/render/shaders/shader.h3
-rw-r--r--src/render/shaders/shaderprogram.cpp49
-rw-r--r--src/render/shaders/shaderprogram.h48
-rw-r--r--src/render/shaders/shadersmanager.cpp51
-rw-r--r--src/render/shaders/shadersmanager.h7
-rw-r--r--src/resources/resourcemanager.cpp27
-rw-r--r--src/resources/resourcemanager.h3
13 files changed, 196 insertions, 1 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6f9081b1f..ec19ed7d2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -939,6 +939,8 @@ SET(SRCS
render/surfacegraphics.h
render/shaders/shader.cpp
render/shaders/shader.h
+ render/shaders/shaderprogram.cpp
+ render/shaders/shaderprogram.h
render/shaders/shadersmanager.cpp
render/shaders/shadersmanager.h
text.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index c2aef8836..7a894c5ff 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1056,6 +1056,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
render/surfacegraphics.h \
render/shaders/shader.cpp \
render/shaders/shader.h \
+ render/shaders/shaderprogram.cpp \
+ render/shaders/shaderprogram.h \
render/shaders/shadersmanager.cpp \
render/shaders/shadersmanager.h \
text.cpp \
diff --git a/src/graphicsmanager.cpp b/src/graphicsmanager.cpp
index 299255abe..4fa4744a6 100644
--- a/src/graphicsmanager.cpp
+++ b/src/graphicsmanager.cpp
@@ -985,6 +985,7 @@ void GraphicsManager::initOpenGLFunctions()
assignFunction(glShaderSource, "glShaderSource");
assignFunction(glCompileShader, "glCompileShader");
assignFunction(glLinkProgram, "glLinkProgram");
+ assignFunction(glGetProgramInfoLog, "glGetProgramInfoLog");
assignFunction(glDeleteProgram, "glDeleteProgram");
assignFunction(glCreateProgram, "glCreateProgram");
assignFunction(glAttachShader, "glAttachShader");
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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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<Shader*>(
+ resman->getShader(GL_VERTEX_SHADER, vertex));
+ if (!vertexShader)
+ return nullptr;
+
+ Shader *const fragmentShader = static_cast<Shader*>(
+ 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;
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 8bce250fb..9fd445ffc 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -44,6 +44,7 @@
#include "utils/sdlcheckutils.h"
#include "render/shaders/shader.h"
+#include "render/shaders/shaderprogram.h"
#include "render/shaders/shadersmanager.h"
#include <SDL_image.h>
@@ -732,6 +733,32 @@ Resource *ResourceManager::getShader(const unsigned int type,
ShaderLoader rl = { name, type };
return get("shader_" + name, &ShaderLoader::load, &rl);
}
+
+struct ShaderProgramLoader final
+{
+ const std::string vertex;
+ const std::string fragment;
+
+ static Resource *load(const void *const v)
+ {
+ if (!v)
+ return nullptr;
+
+ const ShaderProgramLoader *const rl
+ = static_cast<const ShaderProgramLoader *const>(v);
+ ShaderProgram *const resource = shaders.createProgram(
+ rl->vertex, rl->fragment);
+ return resource;
+ }
+};
+
+Resource *ResourceManager::getShaderProgram(const std::string &vertex,
+ const std::string &fragment)
+{
+ ShaderProgramLoader rl = { vertex, fragment };
+ return get("program_" + vertex + " + " + fragment,
+ &ShaderProgramLoader::load, &rl);
+}
#endif
struct WalkLayerLoader final
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index f7d901f09..88bae02db 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -178,6 +178,9 @@ class ResourceManager final
Resource *getShader(const unsigned int type,
const std::string &name) A_WARN_UNUSED;
+
+ Resource *getShaderProgram(const std::string &vertex,
+ const std::string &fragment) A_WARN_UNUSED;
#endif
WalkLayer *getWalkLayer(const std::string &name, Map *const map);