aboutsummaryrefslogtreecommitdiff
path: root/src/opengl/shaders.cpp
blob: 41d5a90d2eabf317b298eb4cd2fd0bb4b2aefa0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "shaders.hpp"

/**
 * Default Ray Marching Shader
 * Any change is forbidden :P
 */
std::string VertexShader="\
#version 330 core \n\
layout(location = 0) in vec3 position; \n\
uniform mat4 projection; \n\
uniform mat4 model; \n\
void main(){ \n\
  gl_Position =  projection * model * vec4(position,1); \n\
}";


/**
 * Read shaders and handle #include directive
 * @param shader_name
 * @return string containing shader source code
 */
std::string ReadShader(std::string shader_name){
	std::string shader_path=std::string(SHADERS_RESOURCES) + "/" + shader_name;
	std::ifstream shader_file;
	shader_file.open(shader_path);
	if(!shader_file.is_open()) {
		std::cout << "Failed to open: " << shader_path << std::endl;
		exit(EXIT_FAILURE);
	}
	std::string line;
	std::stringstream src;
	while(getline(shader_file, line)){
		if(line.find("#include")!=std::string::npos){
			int from=line.find("\"")+1;
			if(from !=std::string::npos){
				int until=line.size()-from-1;
				src << ReadShader(line.substr(from,until)) << std::endl;
				continue;
			}
		}
		src << line << std::endl;
	}
	return(src.str());
}


GLuint CompileShader(std::string shader_name){

  // Create ids
  GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
  GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

  // Compile vertex shader
  char const * vsrc_c = VertexShader.c_str();
  glShaderSource(VertexShaderID, 1, &vsrc_c, NULL);
  glCompileShader(VertexShaderID);

  // Compile fragment shader
  std::string fsrc_cpp=ReadShader(shader_name);
  char const * fsrc_c = fsrc_cpp.c_str();
  glShaderSource(FragmentShaderID, 1, &fsrc_c, NULL);
  glCompileShader(FragmentShaderID);

  // Link programs
  GLuint ProgramID = glCreateProgram();
  glAttachShader(ProgramID, VertexShaderID);
  glAttachShader(ProgramID, FragmentShaderID);
  glLinkProgram(ProgramID);

  // Cleaning
  glDetachShader(ProgramID, VertexShaderID);
  glDetachShader(ProgramID, FragmentShaderID);
  glDeleteShader(VertexShaderID);
  glDeleteShader(FragmentShaderID);

  return ProgramID;
}