aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2020-07-09 13:02:31 +0200
committerLoic Guegan <manzerbredes@mailbox.org>2020-07-09 13:02:31 +0200
commit12829892b262a0c7fcccba9198e5b6b31b2a8015 (patch)
tree908152ccc4fd1f4ee2c16b4bb8e0bee215ebdae7
parentaac94e911b0bab8db5cdb5efb8d4d8f2d4072610 (diff)
Cleaning codeHEADmaster
-rw-r--r--resources/shaders/algorithms/normal.frag24
-rw-r--r--resources/shaders/algorithms/ray_marching.glsl5
-rw-r--r--resources/shaders/algorithms/raymarching.frag26
-rw-r--r--resources/shaders/julia.frag48
-rw-r--r--resources/shaders/main.frag (renamed from resources/shaders/main.glsl)46
-rw-r--r--resources/shaders/objects/sphere.frag7
-rw-r--r--resources/shaders/objects/sphere.glsl4
-rw-r--r--src/opengl/shaders.cpp164
-rw-r--r--src/rms.cpp9
9 files changed, 165 insertions, 168 deletions
diff --git a/resources/shaders/algorithms/normal.frag b/resources/shaders/algorithms/normal.frag
new file mode 100644
index 0000000..0f61544
--- /dev/null
+++ b/resources/shaders/algorithms/normal.frag
@@ -0,0 +1,24 @@
+// Requirements:
+// #define NORMAL_ACCURACY 0.01
+// GetDist: (vec3 position) => float
+// GetDist should return the closest object point distance from position (in the whole scene)
+
+/**
+ * Compute the normal of an object at a given surface point
+ * this can be usefull for lighting etc..
+ * This function exploit the fact that the gradient on a given surface point in 3D space
+ * given the normal direction (source: https://fr.wikipedia.org/wiki/Gradient#Dimension_3_:_gradient_normal_%C3%A0_une_surface_en_un_point,_plan_tangent)
+ *
+ *
+ */
+vec3 GetNormal(vec3 point_position) {
+ float point_distance = GetDist(point_position);
+ vec2 epsilon = vec2(NORMAL_ACCURACY, 0); // Just a convenient way to use NORMAL_ACCURACY and 0
+ // Compute the gradient
+ vec3 gradient = point_distance - vec3(
+ GetDist(point_position-epsilon.xyy),
+ GetDist(point_position-epsilon.yxy),
+ GetDist(point_position-epsilon.yyx));
+
+ return normalize(gradient);
+} \ No newline at end of file
diff --git a/resources/shaders/algorithms/ray_marching.glsl b/resources/shaders/algorithms/ray_marching.glsl
deleted file mode 100644
index d984c0e..0000000
--- a/resources/shaders/algorithms/ray_marching.glsl
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-RayMarching(vec3 ro, vec3 rd){
-
-} \ No newline at end of file
diff --git a/resources/shaders/algorithms/raymarching.frag b/resources/shaders/algorithms/raymarching.frag
new file mode 100644
index 0000000..b8de515
--- /dev/null
+++ b/resources/shaders/algorithms/raymarching.frag
@@ -0,0 +1,26 @@
+// Requirements:
+// #define MAX_STEPS 100
+// #define MAX_DIST 100.
+// GetDist: (vec3 position) => float
+// GetDist should return the closest object point distance from position (in the whole scene)
+
+/**
+ * Ray Marching algorithm
+ * Please take a look at: https://www.youtube.com/watch?v=PGtv-dBi2wE&t=1367s
+ * This function return the distance reached by the ray:
+ * - If dist<MAX_DIST we hit something
+ */
+float RayMarch(vec3 ray_origin, vec3 ray_direction) {
+ float dist_origin=0.; // Ray start at the origin
+ for(int i=0; i<MAX_STEPS; i++) { // If we take to much time to converge (i>=MAX_STEPS)
+ // We move the ray:
+ vec3 ray_position = ray_origin + ray_direction*dist_origin;
+ // We find the next closest point:
+ float closest_point = GetDist(ray_position);
+ // Increase the ray distance
+ dist_origin += closest_point;
+ // Check if we went to far or we are too close from a point (we hit a surface)
+ if(dist_origin>MAX_DIST || closest_point<SURF_DIST) break;
+ }
+ return dist_origin;
+} \ No newline at end of file
diff --git a/resources/shaders/julia.frag b/resources/shaders/julia.frag
new file mode 100644
index 0000000..12d923b
--- /dev/null
+++ b/resources/shaders/julia.frag
@@ -0,0 +1,48 @@
+// ----- Vertex Shader -----
+#version 410 core
+
+layout(location = 0) in vec3 position;
+uniform mat4 projection;
+uniform mat4 model;
+
+void main(){
+ gl_Position = projection * model * vec4(position,1);
+}
+
+// ----- Fragment Shader -----
+
+#version 410 core
+
+uniform vec2 resolution;
+uniform float time;
+
+out vec3 color;
+
+#define ACCURACY 1000
+#define LIMIT 1000
+
+vec2 cmult(vec2 z1,vec2 z2){
+ return(vec2(z1.x*z2.x-z1.y*z2.y,z1.x*z2.y+z1.y*z2.x));
+}
+
+vec2 IsDiverging(vec2 coord){
+ vec2 z=vec2(coord.x,coord.y);
+ int i;
+ for(i=0;i<ACCURACY;i++){
+ z=cmult(z,z)+vec2(-0.3,0.5);
+ if(length(z) > LIMIT)
+ break;
+
+ }
+ return(z);
+}
+
+
+void main()
+{
+ vec2 coord=gl_FragCoord.xy/resolution.xy;
+ coord-=0.5;
+ coord/=(time/10);
+ float d=length(IsDiverging(coord));
+ color=vec3(LIMIT/(d*2),0,0);
+}
diff --git a/resources/shaders/main.glsl b/resources/shaders/main.frag
index 2888d56..590b849 100644
--- a/resources/shaders/main.glsl
+++ b/resources/shaders/main.frag
@@ -1,16 +1,3 @@
-// ----- Vertex Shader -----
-#version 330 core
-
-layout(location = 0) in vec3 position;
-uniform mat4 projection;
-uniform mat4 model;
-
-void main(){
- gl_Position = projection * model * vec4(position,1);
-}
-
-// ----- Fragment Shader -----
-
#version 330 core
uniform vec2 resolution;
@@ -18,45 +5,24 @@ uniform float time;
out vec3 color;
-
#define MAX_STEPS 100
#define MAX_DIST 100.
#define SURF_DIST .01
+#define NORMAL_ACCURACY 0.01
+#include "objects/sphere.frag"
float GetDist(vec3 p) {
- vec4 s = vec4(0, 1, 6, 1);
-
- float sphereDist = length(p-s.xyz)-s.w;
+ float sphereDist = SphereSDF(p,vec3(0, 1, 6),1);
float planeDist = p.y;
float d = min(sphereDist, planeDist);
return d;
}
-float RayMarch(vec3 ro, vec3 rd) {
- float dO=0.;
-
- for(int i=0; i<MAX_STEPS; i++) {
- vec3 p = ro + rd*dO;
- float dS = GetDist(p);
- dO += dS;
- if(dO>MAX_DIST || dS<SURF_DIST) break;
- }
-
- return dO;
-}
+#include "algorithms/raymarching.frag"
+#include "algorithms/normal.frag"
+
-vec3 GetNormal(vec3 p) {
- float d = GetDist(p);
- vec2 e = vec2(.01, 0);
-
- vec3 n = d - vec3(
- GetDist(p-e.xyy),
- GetDist(p-e.yxy),
- GetDist(p-e.yyx));
-
- return normalize(n);
-}
float GetLight(vec3 p) {
vec3 lightPos = vec3(0, 5, 6);
diff --git a/resources/shaders/objects/sphere.frag b/resources/shaders/objects/sphere.frag
new file mode 100644
index 0000000..e69deaa
--- /dev/null
+++ b/resources/shaders/objects/sphere.frag
@@ -0,0 +1,7 @@
+/**
+ * Compute the Signed Distance Function (SDF)
+ * of a sphere.
+ */
+float SphereSDF(vec3 ray_position, vec3 sphere_position, float radius){
+ return(length(ray_position - sphere_position)-radius);
+} \ No newline at end of file
diff --git a/resources/shaders/objects/sphere.glsl b/resources/shaders/objects/sphere.glsl
deleted file mode 100644
index a3d25eb..0000000
--- a/resources/shaders/objects/sphere.glsl
+++ /dev/null
@@ -1,4 +0,0 @@
-
-float Sphere(vec3 ray_position, vec3 sphere_position){
-
-} \ No newline at end of file
diff --git a/src/opengl/shaders.cpp b/src/opengl/shaders.cpp
index 34d4e8f..41d5a90 100644
--- a/src/opengl/shaders.cpp
+++ b/src/opengl/shaders.cpp
@@ -1,42 +1,63 @@
#include "shaders.hpp"
-GLuint CompileShader(std::string shader_name){
- std::ifstream shader_file;
- shader_file.open(std::string(SHADERS_RESOURCES) + "/" + shader_name);
- if(!shader_file.is_open()) {
- std::cout << "Failed to open: " << shader_name << std::endl;
- exit(EXIT_FAILURE);
- }
+/**
+ * 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());
+}
- std::string line;
- char type='\0';
- std::stringstream ss[2];
- while(getline(shader_file, line)) {
- if(line.find("- Vertex Shader -") != std::string::npos){
- type='v';
- } else if(line.find("- Fragment Shader -") != std::string::npos){
- type='f';
- }
- if(type=='v')
- ss[0] << line << std::endl;
- else if(type=='f')
- ss[1] << line << std::endl;
- }
+GLuint CompileShader(std::string shader_name){
// Create ids
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Compile vertex shader
- std::string vsrc=ss[0].str();
- char const * vsrc_c = vsrc.c_str();
+ char const * vsrc_c = VertexShader.c_str();
glShaderSource(VertexShaderID, 1, &vsrc_c, NULL);
glCompileShader(VertexShaderID);
// Compile fragment shader
- std::string fsrc=ss[1].str();
- char const * fsrc_c = fsrc.c_str();
+ std::string fsrc_cpp=ReadShader(shader_name);
+ char const * fsrc_c = fsrc_cpp.c_str();
glShaderSource(FragmentShaderID, 1, &fsrc_c, NULL);
glCompileShader(FragmentShaderID);
@@ -54,96 +75,3 @@ GLuint CompileShader(std::string shader_name){
return ProgramID;
}
-
-
-GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
-
- // Create the shaders
- GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
- GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
-
- // Read the Vertex Shader code from the file
- std::string VertexShaderCode;
- std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
- if(VertexShaderStream.is_open()){
- std::stringstream sstr;
- sstr << VertexShaderStream.rdbuf();
- VertexShaderCode = sstr.str();
- VertexShaderStream.close();
- }else{
- printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
- getchar();
- return 0;
- }
-
- // Read the Fragment Shader code from the file
- std::string FragmentShaderCode;
- std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
- if(FragmentShaderStream.is_open()){
- std::stringstream sstr;
- sstr << FragmentShaderStream.rdbuf();
- FragmentShaderCode = sstr.str();
- FragmentShaderStream.close();
- }
-
- GLint Result = GL_FALSE;
- int InfoLogLength;
-
-
- // Compile Vertex Shader
- printf("Compiling shader : %s\n", vertex_file_path);
- char const * VertexSourcePointer = VertexShaderCode.c_str();
- glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
- glCompileShader(VertexShaderID);
-
- // Check Vertex Shader
- glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
- glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
- if ( InfoLogLength > 0 ){
- std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
- glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
- printf("%s\n", &VertexShaderErrorMessage[0]);
- }
-
-
-
- // Compile Fragment Shader
- printf("Compiling shader : %s\n", fragment_file_path);
- char const * FragmentSourcePointer = FragmentShaderCode.c_str();
- glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
- glCompileShader(FragmentShaderID);
-
- // Check Fragment Shader
- glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
- glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
- if ( InfoLogLength > 0 ){
- std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
- glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
- printf("%s\n", &FragmentShaderErrorMessage[0]);
- }
-
- // Link the program
- printf("Linking program\n");
- GLuint ProgramID = glCreateProgram();
- glAttachShader(ProgramID, VertexShaderID);
- glAttachShader(ProgramID, FragmentShaderID);
- glLinkProgram(ProgramID);
-
- // Check the program
- glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
- glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
- if ( InfoLogLength > 0 ){
- std::vector<char> ProgramErrorMessage(InfoLogLength+1);
- glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
- printf("%s\n", &ProgramErrorMessage[0]);
- }
-
-
- glDetachShader(ProgramID, VertexShaderID);
- glDetachShader(ProgramID, FragmentShaderID);
-
- glDeleteShader(VertexShaderID);
- glDeleteShader(FragmentShaderID);
-
- return ProgramID;
-}
diff --git a/src/rms.cpp b/src/rms.cpp
index b7cf93b..a9bb166 100644
--- a/src/rms.cpp
+++ b/src/rms.cpp
@@ -8,6 +8,12 @@ void OnWindowResize(GLFWwindow* window, int width, int height){
AppContext->renderer.AjustViewport(width,height);
}
+void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
+{
+ if (key == GLFW_KEY_R && action == GLFW_PRESS)
+ AppContext->renderer.RefreshShader();
+}
+
int main(int argc, char *argv[])
{
GLFWwindow* window;
@@ -29,7 +35,7 @@ int main(int argc, char *argv[])
// Init Renderer/OpenGL
APP_CONTEXT InitContext={
- Renderer(WIDTH,HEIGHT,"main.glsl"),
+ Renderer(WIDTH,HEIGHT,"main.frag"),
HUD(window)
};
AppContext=&InitContext;
@@ -37,6 +43,7 @@ int main(int argc, char *argv[])
glfwSetWindowSizeCallback(window, OnWindowResize);
+ glfwSetKeyCallback(window, key_callback);
/* Loop until the user closes the window */
double InitTime = glfwGetTime();