summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-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
8 files changed, 161 insertions, 1 deletions
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;