summaryrefslogtreecommitdiff
path: root/graphics/asymptote/shaders.cc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/shaders.cc
Initial commit
Diffstat (limited to 'graphics/asymptote/shaders.cc')
-rw-r--r--graphics/asymptote/shaders.cc109
1 files changed, 109 insertions, 0 deletions
diff --git a/graphics/asymptote/shaders.cc b/graphics/asymptote/shaders.cc
new file mode 100644
index 0000000000..1067068772
--- /dev/null
+++ b/graphics/asymptote/shaders.cc
@@ -0,0 +1,109 @@
+// shader handling
+// Author: Supakorn "Jamie" Rassameemasmuang
+
+#include "common.h"
+
+#ifdef HAVE_GL
+
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <string>
+#include <iostream>
+
+#include "shaders.h"
+
+GLuint compileAndLinkShader(std::vector<ShaderfileModePair> const& shaders,
+ size_t NLights, size_t NMaterials,
+ std::vector<std::string> const& defineflags)
+{
+ GLuint mainShader = glCreateProgram();
+ std::vector<GLuint> compiledShaders;
+
+ size_t n=shaders.size();
+ for(size_t i=0; i < n; ++i) {
+ GLint newshader=createShaderFile(shaders[i].first,shaders[i].second,
+ NLights,NMaterials,defineflags);
+ glAttachShader(mainShader,newshader);
+ compiledShaders.push_back(newshader);
+ }
+
+ glLinkProgram(mainShader);
+
+ for(size_t i=0; i < n; ++i) {
+ glDetachShader(mainShader,compiledShaders[i]);
+ glDeleteShader(compiledShaders[i]);
+ }
+
+ return mainShader;
+}
+
+GLuint createShaders(GLchar const* src, int shaderType,
+ std::string const& filename)
+{
+ GLuint shader=glCreateShader(shaderType);
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+
+ if(status != GL_TRUE) {
+ GLint length;
+
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+
+ std::vector<GLchar> msg(length);
+
+ glGetShaderInfoLog(shader, length, &length, msg.data());
+
+ size_t n=msg.size();
+ for(size_t i=0; i < n; ++i) {
+ std::cerr << msg[i];
+ }
+
+ std::cerr << std::endl << "GL Compile error" << std::endl;
+ std::cerr << src << std::endl;
+ throw 1;
+ }
+ return shader;
+}
+
+GLuint createShaderFile(std::string file, int shaderType, size_t Nlights,
+ size_t Nmaterials,
+ std::vector<std::string> const& defineflags)
+{
+ std::ifstream shaderFile;
+ shaderFile.open(file.c_str());
+ std::stringstream shaderSrc;
+
+#ifdef __APPLE__
+#define GLSL_VERSION "410"
+#else
+#define GLSL_VERSION "130"
+#endif
+
+ shaderSrc << "#version " << GLSL_VERSION << "\r\n";
+ shaderSrc << "#extension GL_ARB_uniform_buffer_object : enable"
+ << "\r\n";
+ shaderSrc << "#extension GL_ARB_shading_language_packing : enable"
+ << "\r\n";
+
+ size_t n=defineflags.size();
+ for(size_t i=0; i < n; ++i) {
+ shaderSrc << "#define " << defineflags[i] << "\r\n";
+ }
+
+ shaderSrc << "const int Nlights=" << Nlights << ";\r\n";
+ shaderSrc << "const int Nmaterials=" << Nmaterials << ";\r\n";
+
+ if(shaderFile) {
+ shaderSrc << shaderFile.rdbuf();
+ shaderFile.close();
+ } else {
+ throw 1;
+ }
+
+ return createShaders(shaderSrc.str().data(), shaderType, file);
+}
+#endif