From f0b4f2d46e3bfb9c3bd36a857283e551f2d6d3fc Mon Sep 17 00:00:00 2001 From: Emmanuel Benoit Date: Sat, 30 Sep 2017 11:23:14 +0200 Subject: [PATCH] Raymarcher + automatic load --- Makefile | 4 +-- main.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ map.glsl | 4 +++ raymarcher.glsl | 23 +++++++++-------- 4 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 map.glsl diff --git a/Makefile b/Makefile index 5dab264..00327a3 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,7 @@ CPPFLAGS += -I. -Iimgui -Iglm \ -DREAL_BUILD -DGLM_ENABLE_EXPERIMENTAL LIBS += $(shell sdl2-config --libs) -lGL -lGLEW -ldl -FILEDUMPS = \ - fd-raymarch-header.glsl.h \ - fd-raymarcher.glsl.h +FILEDUMPS = IMGUI = imgui.o imgui_demo.o imgui_draw.o DEMO = \ diff --git a/main.cc b/main.cc index 6ad047d..6c41d4e 100644 --- a/main.cc +++ b/main.cc @@ -18,6 +18,8 @@ struct T_Main SDL_Window * window; SDL_GLContext gl; T_FilesWatcher watcher; + T_WatchedFiles shaderFiles; + GLuint prog; std::string loadError; bool done = false; @@ -29,11 +31,16 @@ struct T_Main void handleCapture( ); void makeUI( ); void render( ); + + void loadProgram( ); }; /*----------------------------------------------------------------------------*/ T_Main::T_Main( ) + : shaderFiles( watcher , [this] { + this->loadProgram( ); + } ) { SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ); @@ -52,6 +59,8 @@ T_Main::T_Main( ) gl = SDL_GL_CreateContext( window ); glewInit(); ImGui_ImplSdl_Init( window ); + + loadProgram( ); } void T_Main::mainLoop( ) @@ -148,6 +157,34 @@ void T_Main::render( ) // FIXME draw the fuck //project->render( ); + if ( prog != 0 ) { + glUseProgram( prog ); + + enum { + U_TIME = 0 , + U_RESOLUTION = 1 , + U_CAM_POS = 2 , + U_LOOK_AT = 3 , + U_CAM_UP = 4 , + U_NEAR_PLANE = 5 , + U_LIGHT_DIR = 6 , + U_RENDER = 7 , + }; + + auto const& dspSize( ImGui::GetIO( ).DisplaySize ); + glUniform1f( U_TIME , 0 ); + glUniform2f( U_RESOLUTION , dspSize.x , dspSize.y ); + + glUniform3f( U_CAM_POS , 0 , 0 , -15 ); + glUniform3f( U_LOOK_AT , 0 , 0 , 0 ); + glUniform3f( U_CAM_UP , 0 , 1 , 0 ); + glUniform1f( U_NEAR_PLANE , 1 ); + + glUniform3f( U_LIGHT_DIR , 0 , 1 , 1 ); + glUniform4f( U_RENDER , 128 , 0.9 , 0.001 , 100 ); + + glRectf( -1, -1 , 1 , 1 ); + } glUseProgram( 0 ); ImGui::Render( ); @@ -155,6 +192,35 @@ void T_Main::render( ) } +void T_Main::loadProgram( ) +{ + std::vector< std::string > errors; + + if ( prog != 0 ) { + glDeleteProgram( prog ); + prog = 0; + } + + shaderFiles.clear( ); + shaderFiles.watch( "raymarch-header.glsl" ); + shaderFiles.watch( "map.glsl" ); + shaderFiles.watch( "raymarcher.glsl" ); + + T_ShaderCode shader( 3 ); + shader.loadPart( 0 , "raymarch-header.glsl" , errors ); + shader.loadPart( 1 , "map.glsl" , errors ); + shader.loadPart( 2 , "raymarcher.glsl" , errors ); + + prog = shader.createProgram( GL_FRAGMENT_SHADER , errors ); + + if ( errors.size( ) != 0 ) { + for ( auto const& str : errors ) { + printf( "ERR: %s\n" , str.c_str( ) ); + } + } +} + + /*============================================================================*/ int main( int , char** ) diff --git a/map.glsl b/map.glsl new file mode 100644 index 0000000..a62fc36 --- /dev/null +++ b/map.glsl @@ -0,0 +1,4 @@ +vec2 map( vec3 pos ) +{ + return vec2( length( pos ) - 1. , 0. ); +} diff --git a/raymarcher.glsl b/raymarcher.glsl index 312aebf..9ef9cad 100644 --- a/raymarcher.glsl +++ b/raymarcher.glsl @@ -49,8 +49,6 @@ void main( ) { setCamFromUniforms( ); - int dispMode = ( u_DebugFeatures.x >> 3 ) & 3; - vec2 uv = ( gl_FragCoord.xy / u_Resolution ) * 2 - 1; vec3 camDir = normalize( lookAt - camPos ); vec3 side = normalize( cross( camUp , camDir ) ); @@ -62,14 +60,19 @@ void main( ) vec3 r = march( camPos , rayDir , int( u_Render.x ) , u_Render.y ); vec3 hitPos = camPos + rayDir * r.x; - vec3 bc = vec3( 1. ); - vec3 hvec = normalize( rayDir - u_LightDir ) , - norm = getNormal( hitPos ); - float ndotl = dot( norm , -normalize( u_LightDir ) ) , - ndoth = dot( norm , hvec ); - float si = pow( clamp( ndoth , 0 , 1 ) , 4 ) , - di = .6 + .3 * clamp( ndotl , 0 , 1 ); - bc = mix( bc * di , vec3( 1. ) , si ); + vec3 bc; + if ( r.y >= 0. ) { + bc = vec3( 1. , 1. , 0. ); + vec3 hvec = normalize( rayDir - u_LightDir ) , + norm = getNormal( hitPos ); + float ndotl = dot( norm , -normalize( u_LightDir ) ) , + ndoth = dot( norm , hvec ); + float si = pow( clamp( ndoth , 0 , 1 ) , 4 ) , + di = .6 + .3 * clamp( ndotl , 0 , 1 ); + bc = mix( bc * di , vec3( 1. ) , si ); + } else { + bc = vec3( 0. ); + } color = vec4( bc , 1 );