diff --git a/EU07.cpp b/EU07.cpp index ed6e4982..55a819df 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -298,15 +298,16 @@ int main(int argc, char *argv[]) ::SendMessage( Hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast( icon ) ); #endif - if ((false == GfxRenderer.Init(window)) - || (false == UILayer.init(window))) - return -1; + try { + if ((false == GfxRenderer.Init(window)) + || (false == UILayer.init(window))) + return -1; - input::Keyboard.init(); - input::Gamepad.init(); + input::Keyboard.init(); + input::Gamepad.init(); + + Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów - Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów - try { if( false == World.Init( window ) ) { ErrorLog( "Failed to init TWorld" ); return -1; diff --git a/Globals.cpp b/Globals.cpp index cd33b0e9..8ce70756 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -150,6 +150,7 @@ double Global::fFpsRadiusMax = 3000.0; // maksymalny promień renderowania int Global::iFpsRadiusMax = 225; // maksymalny promień renderowania double Global::fRadiusFactor = 1.1; // współczynnik jednorazowej zmiany promienia scenerii bool Global::bOldSmudge = false; // Używanie starej smugi +Global::shadowtune_t Global::shadowtune = { 8192, 200.0f, 150.0f, 100.0f }; // parametry testowe (do testowania scenerii i obiektów) bool Global::bWireFrame = false; @@ -536,6 +537,14 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> Global::ScaleSpecularValues; } + else if (token == "shadowtune") + { + Parser.getTokens(4, false); + Parser >> Global::shadowtune.map_size; + Parser >> Global::shadowtune.width; + Parser >> Global::shadowtune.depth; + Parser >> Global::shadowtune.distance; + } else if (token == "smoothtraction") { // podwójna jasność ambient diff --git a/Globals.h b/Globals.h index 51f9753a..ac6d445f 100644 --- a/Globals.h +++ b/Globals.h @@ -283,6 +283,14 @@ class Global static bool bHideConsole; // hunter-271211: ukrywanie konsoli static bool bOldSmudge; // Używanie starej smugi + static struct shadowtune_t + { + unsigned int map_size; + float width; + float depth; + float distance; + } shadowtune; + static TWorld *pWorld; // wskaźnik na świat do usuwania pojazdów static TAnimModel *pTerrainCompact; // obiekt terenu do ewentualnego zapisania w pliku static std::string asTerrainModel; // nazwa obiektu terenu do zapisania w pliku diff --git a/renderer.cpp b/renderer.cpp index 0eedf0db..6389697b 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -113,11 +113,14 @@ opengl_renderer::Init( GLFWwindow *Window ) { glGenTextures(1, &depth_tex); glBindTexture(GL_TEXTURE_2D, depth_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, - 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + Global::shadowtune.map_size, Global::shadowtune.map_size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, depth_tex); @@ -174,12 +177,13 @@ opengl_renderer::Render() { if( World.InitPerformed() ) { glDebug("rendering shadow map"); glDisable(GL_FRAMEBUFFER_SRGB); - glViewport(0, 0, 1024, 1024); + glViewport(0, 0, Global::shadowtune.map_size, Global::shadowtune.map_size); - glm::mat4 depthproj = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.1f, 100.0f); + glm::mat4 depthproj = glm::ortho(-Global::shadowtune.width, Global::shadowtune.width, + -Global::shadowtune.width, Global::shadowtune.width, 0.0f, Global::shadowtune.depth); glm::vec3 playerpos = glm::vec3(World.Camera.Pos.x, World.Camera.Pos.y, World.Camera.Pos.z); - glm::vec3 shadoweye = playerpos - Global::daylight.direction * 50.0f; - Global::SetCameraPosition(Math3D::vector3(shadoweye)); + glm::vec3 shadoweye = playerpos - Global::daylight.direction * Global::shadowtune.distance; + Global::SetCameraPosition(Math3D::vector3(0.0f, 0.0f, 0.0f)); glm::mat4 depthcam = glm::lookAt(shadoweye, playerpos, glm::vec3(0.0f, 1.0f, 0.0f)); @@ -187,7 +191,7 @@ opengl_renderer::Render() { glMatrixMode(GL_PROJECTION); glLoadMatrixf(glm::value_ptr(depthproj)); glMatrixMode(GL_MODELVIEW); - glMultMatrixf(glm::value_ptr(glm::mat4(glm::mat3(depthcam)))); + glMultMatrixf(glm::value_ptr(depthcam)); glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo); glClear(GL_DEPTH_BUFFER_BIT); @@ -209,7 +213,7 @@ opengl_renderer::Render() { glm::dmat4 worldcamera; World.Camera.SetMatrix( worldcamera ); m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera); - ::glMultMatrixd(glm::value_ptr(glm::dmat4(glm::dmat3(worldcamera)))); + ::glMultMatrixd(glm::value_ptr(worldcamera)); shader.bind(); active_shader = &shader; glDebug("rendering environment"); glDisable(GL_FRAMEBUFFER_SRGB); @@ -217,7 +221,8 @@ opengl_renderer::Render() { glDebug("rendering world"); glEnable(GL_FRAMEBUFFER_SRGB); - shader.set_lightview(depthproj * depthcam); //to jest źle. nie uwzględnia przesunięcia to wiadomo, ale obrót też jest źle + Global::SetCameraPosition(Math3D::vector3(0.0f, 0.0f, 0.0f)); + shader.set_lightview(depthproj * depthcam * glm::inverse(glm::mat4(worldcamera))); Render( &World.Ground ); glDebug("rendering cab"); diff --git a/shaders/blinnphong.frag b/shaders/blinnphong.frag index cd4245e8..0786134c 100644 --- a/shaders/blinnphong.frag +++ b/shaders/blinnphong.frag @@ -28,7 +28,7 @@ in vec4 f_light_pos; out vec4 color; uniform sampler2D tex; -uniform sampler2D shadowmap; +uniform sampler2DShadow shadowmap; uniform vec3 ambient; uniform vec3 emission; @@ -39,13 +39,57 @@ uniform float specular; uniform light_s lights[8]; uniform uint lights_count; +vec2 poissonDisk[16] = vec2[]( + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ), + vec2( -0.91588581, 0.45771432 ), + vec2( -0.81544232, -0.87912464 ), + vec2( -0.38277543, 0.27676845 ), + vec2( 0.97484398, 0.75648379 ), + vec2( 0.44323325, -0.97511554 ), + vec2( 0.53742981, -0.47373420 ), + vec2( -0.26496911, -0.41893023 ), + vec2( 0.79197514, 0.19090188 ), + vec2( -0.24188840, 0.99706507 ), + vec2( -0.81409955, 0.91437590 ), + vec2( 0.19984126, 0.78641367 ), + vec2( 0.14383161, -0.14100790 ) +); + +float random(vec3 seed, int i) +{ + vec4 seed4 = vec4(seed,i); + float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673)); + return fract(sin(dot_product) * 43758.5453); +} + float calc_shadow() { - vec3 coords = f_light_pos.xyz / f_light_pos.w; + vec3 coords = f_light_pos.xyz;// / f_light_pos.w; coords = coords * 0.5 + 0.5; - float closest_depth = texture(shadowmap, coords.xy).r; - float current_depth = coords.z; - float shadow = (current_depth - 0.1) > closest_depth ? 0.0 : 1.0; + float bias = 0.005; + + //PCF + //float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias)); + + //PCF + stratified poisson sampling + //float shadow = 1.0; + //for (int i=0;i<4;i++) + //{ + // int index = int(16.0*random(gl_FragCoord.xyy, i))%16; + // shadow -= 0.25*(1.0-texture(shadowmap, vec3(coords.xy + poissonDisk[index]/5000.0, coords.z - bias))); + //} + + //PCF + PCF + float shadow = 0.0; + vec2 texel = 1.0 / textureSize(shadowmap, 0); + for (float y = -1.5; y <= 1.5; y += 1.0) + for (float x = -1.5; x <= 1.5; x += 1.0) + shadow += texture(shadowmap, coords.xyz + vec3(vec2(x, y) * texel, -bias)); + shadow /= 16.0; + return shadow; }