From 03fbdc260df9e57baf1c0a4273b865c3dc1a6957 Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Mon, 28 Apr 2014 18:42:23 +0200 Subject: [PATCH 01/69] Add a new option for high-definition textures. --- data/gui/custom_video_settings.stkgui | 8 ++++---- src/config/user_config.hpp | 3 +++ src/states_screens/dialogs/custom_video_settings.cpp | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/data/gui/custom_video_settings.stkgui b/data/gui/custom_video_settings.stkgui index ad2c62572..be3dc6a15 100644 --- a/data/gui/custom_video_settings.stkgui +++ b/data/gui/custom_video_settings.stkgui @@ -124,13 +124,13 @@ - + diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 7ebb7332d..f6c1cee2d 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -443,6 +443,9 @@ namespace UserConfigParams PARAM_PREFIX BoolUserConfigParam m_texture_compression PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression", &m_video_group, "Enable Texture Compression")); + PARAM_PREFIX BoolUserConfigParam m_high_definition_textures + PARAM_DEFAULT(BoolUserConfigParam(true, "enable_high_definition_textures", + &m_video_group, "Enable high definition textures")); PARAM_PREFIX BoolUserConfigParam m_ubo_disabled PARAM_DEFAULT(BoolUserConfigParam(false, "disable_ubo_support", &m_video_group, "Disable UBO support")); diff --git a/src/states_screens/dialogs/custom_video_settings.cpp b/src/states_screens/dialogs/custom_video_settings.cpp index 89bf7e3dd..0f5a85d8d 100644 --- a/src/states_screens/dialogs/custom_video_settings.cpp +++ b/src/states_screens/dialogs/custom_video_settings.cpp @@ -52,6 +52,7 @@ void CustomVideoSettingsDialog::beforeAddingWidgets() getWidget("anim_gfx")->setState( UserConfigParams::m_graphical_effects ); getWidget("weather_gfx")->setState( UserConfigParams::m_weather_effects ); getWidget("ubo")->setState(!UserConfigParams::m_ubo_disabled); + getWidget("hd-textures")->setState(UserConfigParams::m_high_definition_textures); SpinnerWidget* kart_anim = getWidget("steering_animations"); kart_anim->addLabel( _("Disabled") ); // 0 @@ -106,8 +107,10 @@ GUIEngine::EventPropagation CustomVideoSettingsDialog::processEvent(const std::s getWidget("anim_gfx")->getState(); UserConfigParams::m_weather_effects = getWidget("weather_gfx")->getState(); - UserConfigParams::m_ubo_disabled = + UserConfigParams::m_ubo_disabled = !getWidget("ubo")->getState(); + UserConfigParams::m_high_definition_textures = + getWidget("hd-textures")->getState(); UserConfigParams::m_motionblur = getWidget("motionblur")->getState(); From fac9cafa963426da8f54e006bd9d39a512ec374a Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Tue, 29 Apr 2014 18:57:36 +0200 Subject: [PATCH 02/69] Create the directory where resized textures will be cached. --- src/io/file_manager.cpp | 34 ++++++++++++++++++++++++++++++++++ src/io/file_manager.hpp | 5 +++++ 2 files changed, 39 insertions(+) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 75565da81..0f5867337 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -192,6 +192,7 @@ FileManager::FileManager() checkAndCreateConfigDir(); checkAndCreateAddonsDir(); checkAndCreateScreenshotDir(); + checkAndCreateCachedTexturesDir(); checkAndCreateGPDir(); #ifdef WIN32 @@ -596,6 +597,14 @@ std::string FileManager::getScreenshotDir() const return m_screenshot_dir; } // getScreenshotDir +//----------------------------------------------------------------------------- +/** Returns the directory in which resized textures should be cached. +*/ +std::string FileManager::getCachedTexturesDir() const +{ + return m_cached_textures_dir; +} // getCachedTexturesDir + //----------------------------------------------------------------------------- /** Returns the directory in which user-defined grand prix should be stored. */ @@ -852,6 +861,31 @@ void FileManager::checkAndCreateScreenshotDir() } // checkAndCreateScreenshotDir +// ---------------------------------------------------------------------------- +/** Creates the directories for cached textures. This will set +* m_cached_textures_dir with the appropriate path. +*/ +void FileManager::checkAndCreateCachedTexturesDir() +{ +#if defined(WIN32) || defined(__CYGWIN__) + m_cached_textures_dir = m_user_config_dir + "resized-textures/"; +#elif defined(__APPLE__) + m_cached_textures_dir = getenv("HOME"); + m_cached_textures_dir += "/Library/Application Support/SuperTuxKart/ResizedTextures/"; +#else + m_cached_textures_dir = checkAndCreateLinuxDir("XDG_CACHE_HOME", "supertuxkart", ".cache/", "."); + m_cached_textures_dir += "resized-textures/"; +#endif + + if (!checkAndCreateDirectory(m_cached_textures_dir)) + { + Log::error("FileManager", "Can not create cached textures directory '%s', " + "falling back to '.'.", m_cached_textures_dir.c_str()); + m_cached_textures_dir = "."; + } + +} // checkAndCreateCachedTexturesDir + // ---------------------------------------------------------------------------- /** Creates the directories for user-defined grand prix. This will set m_gp_dir * with the appropriate path. diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index edde400e9..6fa266b40 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -72,6 +72,9 @@ private: /** Directory to store screenshots in. */ std::string m_screenshot_dir; + /** Directory where resized textures are cached. */ + std::string m_cached_textures_dir; + /** Directory where user-defined grand prix are stored. */ std::string m_gp_dir; @@ -91,6 +94,7 @@ private: bool isDirectory(const std::string &path) const; void checkAndCreateAddonsDir(); void checkAndCreateScreenshotDir(); + void checkAndCreateCachedTexturesDir(); void checkAndCreateGPDir(); #if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__) std::string checkAndCreateLinuxDir(const char *env_name, @@ -110,6 +114,7 @@ public: XMLNode *createXMLTreeFromString(const std::string & content); std::string getScreenshotDir() const; + std::string getCachedTexturesDir() const; std::string getGPDir() const; bool checkAndCreateDirectoryP(const std::string &path); const std::string &getAddonsDir() const; From 7a3ba812d7c55152f55b9e0e6cf38c879dbd9dbc Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Thu, 1 May 2014 19:09:10 +0200 Subject: [PATCH 03/69] Use smaller textures when HD textures option is disabled. Generate them if they are not already in the cache directory. --- lib/irrlicht/include/IrrCompileConfig.h | 4 +- src/graphics/irr_driver.cpp | 70 +++++++++++++++++++++++++ src/graphics/irr_driver.hpp | 2 + src/tracks/track.cpp | 40 +++++++++++++- 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/lib/irrlicht/include/IrrCompileConfig.h b/lib/irrlicht/include/IrrCompileConfig.h index 0948fea18..42bdb516b 100644 --- a/lib/irrlicht/include/IrrCompileConfig.h +++ b/lib/irrlicht/include/IrrCompileConfig.h @@ -544,12 +544,12 @@ B3D, MS3D or X meshes */ #endif //! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files -//#define _IRR_COMPILE_WITH_BMP_WRITER_ +#define _IRR_COMPILE_WITH_BMP_WRITER_ #ifdef NO_IRR_COMPILE_WITH_BMP_WRITER_ #undef _IRR_COMPILE_WITH_BMP_WRITER_ #endif //! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files -//#define _IRR_COMPILE_WITH_JPG_WRITER_ +#define _IRR_COMPILE_WITH_JPG_WRITER_ #ifdef NO_IRR_COMPILE_WITH_JPG_WRITER_ #undef _IRR_COMPILE_WITH_JPG_WRITER_ #endif diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 503cfaa71..9cdd392ba 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1239,6 +1239,76 @@ void IrrDriver::unsetTextureErrorMessage() m_texture_error_message = ""; } // unsetTextureErrorMessage +// ---------------------------------------------------------------------------- +/** Retrieve all textures in the specified directory, generate a smaller +* version for each of them and save them in the cache. Smaller textures are +* generated only if they do not already exist or if their original version +* is newer than the cached one. +* \param dir Directory from where textures will be retrieve. +* \return Directory where smaller textures were cached. +*/ +std::string IrrDriver::generateSmallerTextures(const std::string& dir) +{ + std::set files; + file_manager->listFiles(files, dir, true); + + std::set::const_iterator it; + for (it = files.cbegin(); it != files.cend(); ++it) + { + std::string ext = StringUtils::toLowerCase(StringUtils::getExtension(*it)); + if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp") + { + getSmallerTexture(*it); + } + } // for it in files + + return file_manager->getCachedTexturesDir(); +} // generateSmallerTextures + +// ---------------------------------------------------------------------------- +/** Return the filename for the cached smaller version of the texture. Also, +* generate the smaller version of the texture if it does not already +* exist or if the original version is newer than the cached one. +* \param filename File name of the original texture. +* \return File name of the cached texture. +* +* \todo Regenerate the texture if the original version is newer than the +* cached one. +*/ +std::string IrrDriver::getSmallerTexture(const std::string& filename) +{ + // Retrieve the filename of the cached texture + std::string file = StringUtils::getBasename(filename); + std::string cached_file = + file_manager->getCachedTexturesDir() + file; + // If the cached texture does not exist, we generate it. + if (!file_manager->fileExists(cached_file)) + { + video::IVideoDriver* video_driver = irr_driver->getVideoDriver(); + video::IImage* img = + video_driver->createImageFromFile(filename.c_str()); + + if (img != NULL) + { + core::dimension2d dim = img->getDimension(); + core::dimension2d new_dim; // Dimension of the cached texture + const int scale_factor = 2; + // Resize the texture only if it can be done properly + if (dim.Width < scale_factor || dim.Height < scale_factor) + new_dim = dim; + else + new_dim = dim / scale_factor; + + video::IImage* scaled = + video_driver->createImage(img->getColorFormat(), new_dim); + img->copyToScaling(scaled); + + video_driver->writeImageToFile(scaled, cached_file.c_str()); + } // if img != NULL + } // if !file_manager->fileExists(cached_file) + return cached_file; +} // getSmallerTexture + // ---------------------------------------------------------------------------- /** Loads a texture from a file and returns the texture object. This is just * a convenient wrapper which loads the texture from a STK asset directory. diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 3d1d995ce..774083b79 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -290,6 +290,8 @@ public: void displayFPS(); bool OnEvent(const irr::SEvent &event); void setAmbientLight(const video::SColor &light); + std::string generateSmallerTextures(const std::string& dir); + std::string getSmallerTexture(const std::string& texture); video::ITexture *getTexture(FileManager::AssetType type, const std::string &filename, bool is_premul=false, diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index cf6068168..f48b09f23 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -829,7 +829,31 @@ bool Track::loadMainTrack(const XMLNode &root) std::string model_name; track_node->get("model", &model_name); std::string full_path = m_root+model_name; - scene::IMesh *mesh = irr_driver->getMesh(full_path); + + scene::IMesh *mesh; + // If the hd texture option is disabled, we generate smaller textures + // and configure the path to them before loading the mesh. + if (!UserConfigParams::m_high_definition_textures) + { + std::string cached_textures_dir = + irr_driver->generateSmallerTextures(m_root); + + irr::io::IAttributes* scene_params = + irr_driver->getSceneManager()->getParameters(); + // Before changing the texture path, we retrieve the older one to restore it later + std::string texture_default_path = + scene_params->getAttributeAsString(scene::B3D_TEXTURE_PATH).c_str(); + scene_params->setAttribute(scene::B3D_TEXTURE_PATH, cached_textures_dir.c_str()); + + mesh = irr_driver->getMesh(full_path); + + scene_params->setAttribute(scene::B3D_TEXTURE_PATH, texture_default_path.c_str()); + } + else // Load mesh with default (hd) textures + { + mesh = irr_driver->getMesh(full_path); + } + if(!mesh) { Log::fatal("track", @@ -1471,6 +1495,15 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) file_manager->pushTextureSearchPath(m_root); file_manager->pushModelSearchPath (m_root); + // If the hd texture option is disabled, we generate smaller textures + // and we also add the cache directory to the texture search path + if (!UserConfigParams::m_high_definition_textures) + { + std::string cached_textures_dir = + irr_driver->generateSmallerTextures(m_root); + file_manager->pushTextureSearchPath(cached_textures_dir); + } + // First read the temporary materials.xml file if it exists try { @@ -1663,7 +1696,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) World::getWorld()->setClearbackBufferColor(m_sky_color); } - + if (!UserConfigParams::m_high_definition_textures) + { + file_manager->popTextureSearchPath(); + } file_manager->popTextureSearchPath(); file_manager->popModelSearchPath (); From de5375ab9fd7a09d18242b9ea29b0bf186d7a1ce Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Sat, 3 May 2014 09:35:51 +0200 Subject: [PATCH 04/69] Add subdirectories in the cache directory to organize textures of each track. --- src/graphics/irr_driver.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 9cdd392ba..123c52474 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1279,8 +1279,13 @@ std::string IrrDriver::getSmallerTexture(const std::string& filename) { // Retrieve the filename of the cached texture std::string file = StringUtils::getBasename(filename); - std::string cached_file = - file_manager->getCachedTexturesDir() + file; + std::string parent_dir = StringUtils::getPath(filename); + if (StringUtils::hasSuffix(parent_dir, "/")) + parent_dir = parent_dir.substr(0, parent_dir.size() - 1); + parent_dir = StringUtils::getBasename(parent_dir); + std::string cached_file = file_manager->getCachedTexturesDir() + parent_dir + "/"; + file_manager->checkAndCreateDirectoryP(cached_file); + cached_file += file; // If the cached texture does not exist, we generate it. if (!file_manager->fileExists(cached_file)) { From b4b2e44a0824e5a203d3792179a39912d1a26fda Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Sat, 3 May 2014 10:04:17 +0200 Subject: [PATCH 05/69] Regenerate a cached texture when the original is newer. --- src/graphics/irr_driver.cpp | 4 +++- src/io/file_manager.cpp | 14 ++++++++++++++ src/io/file_manager.hpp | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 123c52474..9c0842064 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1286,8 +1286,10 @@ std::string IrrDriver::getSmallerTexture(const std::string& filename) std::string cached_file = file_manager->getCachedTexturesDir() + parent_dir + "/"; file_manager->checkAndCreateDirectoryP(cached_file); cached_file += file; + // If the cached texture does not exist, we generate it. - if (!file_manager->fileExists(cached_file)) + if (!file_manager->fileExists(cached_file) || + file_manager->fileIsNewer(filename, cached_file)) { video::IVideoDriver* video_driver = irr_driver->getVideoDriver(); video::IImage* img = diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 0f5867337..4aac8224b 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -1184,3 +1184,17 @@ bool FileManager::removeDirectory(const std::string &name) const #endif } // remove directory + +// ---------------------------------------------------------------------------- +/** Returns true if the first file is newer than the second. The comparison is +* based on the modification time of the two files. +*/ +bool FileManager::fileIsNewer(const std::string& f1, const std::string& f2) const +{ + struct stat stat1; + struct stat stat2; + stat(f1.c_str(), &stat1); + stat(f2.c_str(), &stat2); + return stat1.st_mtime > stat2.st_mtime; +} // fileIsNewer + diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index 6fa266b40..9739bbcad 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -142,6 +142,9 @@ public: void popModelSearchPath(); void popMusicSearchPath(); void redirectOutput(); + + bool fileIsNewer(const std::string& f1, const std::string& f2) const; + // ------------------------------------------------------------------------ /** Adds a directory to the music search path (or stack). */ From ab824f0ac38753331b5a9e6cd9d3b7c8dfda2ea4 Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Sat, 3 May 2014 14:39:09 +0200 Subject: [PATCH 06/69] Remove the use of cbegin and cend. (c++11 features) --- src/graphics/irr_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 703f72d2d..8ca8b0e03 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1254,7 +1254,7 @@ std::string IrrDriver::generateSmallerTextures(const std::string& dir) file_manager->listFiles(files, dir, true); std::set::const_iterator it; - for (it = files.cbegin(); it != files.cend(); ++it) + for (it = files.begin(); it != files.end(); ++it) { std::string ext = StringUtils::toLowerCase(StringUtils::getExtension(*it)); if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp") From 1070fd7395aac077c3b28e3abcaa87b9578ba593 Mon Sep 17 00:00:00 2001 From: Stephen Just Date: Wed, 7 May 2014 23:19:39 -0600 Subject: [PATCH 07/69] Fix segfault on Linux/Mesa For some reason, glGetString(GL_EXTENSIONS) is failing. This will need more investigation --- src/graphics/irr_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 1d61bfe14..911a591ec 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -444,7 +444,7 @@ void IrrDriver::initDevice() // Parse extensions hasVSLayer = false; const GLubyte *extensions = glGetString(GL_EXTENSIONS); - if (strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL) + if (extensions && strstr((const char*)extensions, "GL_AMD_vertex_shader_layer") != NULL) hasVSLayer = true; From af91b8b4ae3890ed8b75e2616f74b28802016db6 Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Thu, 8 May 2014 18:04:22 +0200 Subject: [PATCH 08/69] Extend caching abilities to compressed textures. Also, improve the structure of cache directories to fit new needs. --- src/graphics/glwrap.cpp | 101 +++++++++++++++++++++++++++++++++++- src/graphics/glwrap.hpp | 4 ++ src/graphics/irr_driver.cpp | 34 +++++++----- src/graphics/irr_driver.hpp | 3 ++ src/io/file_manager.cpp | 35 +++++++++++-- src/io/file_manager.hpp | 1 + 6 files changed, 160 insertions(+), 18 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index ef0733af5..10a371d82 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -68,6 +68,8 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; PFNGLBLENDCOLORPROC glBlendColor; +PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; +PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; #endif static bool is_gl_init = false; @@ -215,6 +217,8 @@ void initGL() glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex"); glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding"); glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor"); + glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D"); + glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage"); #ifdef DEBUG glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); #endif @@ -303,17 +307,32 @@ GLuint getDepthTexture(irr::video::ITexture *tex) } std::set AlreadyTransformedTexture; - void compressTexture(irr::video::ITexture *tex, bool srgb) { if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end()) return; AlreadyTransformedTexture.insert(tex); + + glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex)); + + std::string cached_file; + if (UserConfigParams::m_texture_compression) + { + // Try to retrieve the compressed texture in cache + std::string tex_name = irr_driver->getTextureName(tex); + if (!tex_name.empty()) { + cached_file = file_manager->getTextureCacheLocation(tex_name) + ".gltz"; + if (!file_manager->fileIsNewer(tex_name, cached_file)) { + if (loadCompressedTexture(cached_file)) + return; + } + } + } + size_t w = tex->getSize().Width, h = tex->getSize().Height; char *data = new char[w * h * 4]; memcpy(data, tex->lock(), w * h * 4); tex->unlock(); - glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex)); unsigned internalFormat, Format; if (tex->hasAlpha()) Format = GL_BGRA; @@ -337,6 +356,84 @@ void compressTexture(irr::video::ITexture *tex, bool srgb) glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, Format, GL_UNSIGNED_BYTE, (GLvoid *)data); glGenerateMipmap(GL_TEXTURE_2D); delete[] data; + + if (UserConfigParams::m_texture_compression && !cached_file.empty()) + { + // Save the compressed texture in the cache for later use. + saveCompressedTexture(cached_file); + } +} + +//----------------------------------------------------------------------------- +/** Try to load a compressed texture from the given file name. +* Data in the specified file need to have a specific format. See the +* saveCompressedTexture() function for a description of the format. +* \return true if the loading succeeded, false otherwise. +* \see saveCompressedTexture +*/ +bool loadCompressedTexture(const std::string& compressed_tex) +{ + std::ifstream ifs(compressed_tex, std::ios::in | std::ios::binary); + if (!ifs.is_open()) + return false; + + int internal_format; + int w, h; + int size = -1; + ifs.read((char*)&internal_format, sizeof(int)); + ifs.read((char*)&w, sizeof(int)); + ifs.read((char*)&h, sizeof(int)); + ifs.read((char*)&size, sizeof(int)); + + if (ifs.fail() || size == -1) + return false; + + char *data = new char[size]; + ifs.read(data, size); + if (!ifs.fail()) + { + glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format, + w, h, 0, size, (GLvoid*)data); + glGenerateMipmap(GL_TEXTURE_2D); + delete[] data; + ifs.close(); + return true; + } + delete[] data; + return false; +} + +//----------------------------------------------------------------------------- +/** Try to save the last texture sent to glTexImage2D in a file of the given +* file name. This function should only be used for textures sent to +* glTexImage2D with a compressed internal format as argument.
+* \note The following format is used to save the compressed texture:
+*
+* The first four elements are integers and the last one is stored +* on \c size bytes. +* \see loadCompressedTexture +*/ +void saveCompressedTexture(const std::string& compressed_tex) +{ + int internal_format, width, height, size; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internal_format); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint *)&width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint *)&height); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&size); + + char *data = new char[size]; + glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data); + std::ofstream ofs(compressed_tex, std::ios::out | std::ios::binary); + if (ofs.is_open()) + { + ofs.write((char*)&internal_format, sizeof(int)); + ofs.write((char*)&width, sizeof(int)); + ofs.write((char*)&height, sizeof(int)); + ofs.write((char*)&size, sizeof(int)); + ofs.write(data, size); + ofs.close(); + } + delete[] data; } void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index e00369c1e..6195448ed 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -85,6 +85,8 @@ extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; extern PFNGLBLENDCOLORPROC glBlendColor; +extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; +extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; #ifdef DEBUG extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; #endif @@ -160,6 +162,8 @@ GLint LoadProgram(Types ... args) GLuint getTextureGLuint(irr::video::ITexture *tex); GLuint getDepthTexture(irr::video::ITexture *tex); void compressTexture(irr::video::ITexture *tex, bool srgb); +bool loadCompressedTexture(const std::string& compressed_tex); +void saveCompressedTexture(const std::string& compressed_tex); void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height); void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 8ca8b0e03..4f79e9fba 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1245,7 +1245,8 @@ void IrrDriver::unsetTextureErrorMessage() * version for each of them and save them in the cache. Smaller textures are * generated only if they do not already exist or if their original version * is newer than the cached one. -* \param dir Directory from where textures will be retrieve. +* \param dir Directory from where textures will be retrieved. +* Must end with '/'. * \return Directory where smaller textures were cached. */ std::string IrrDriver::generateSmallerTextures(const std::string& dir) @@ -1263,7 +1264,7 @@ std::string IrrDriver::generateSmallerTextures(const std::string& dir) } } // for it in files - return file_manager->getCachedTexturesDir(); + return file_manager->getTextureCacheLocation(dir); } // generateSmallerTextures // ---------------------------------------------------------------------------- @@ -1272,21 +1273,11 @@ std::string IrrDriver::generateSmallerTextures(const std::string& dir) * exist or if the original version is newer than the cached one. * \param filename File name of the original texture. * \return File name of the cached texture. -* -* \todo Regenerate the texture if the original version is newer than the -* cached one. */ std::string IrrDriver::getSmallerTexture(const std::string& filename) { // Retrieve the filename of the cached texture - std::string file = StringUtils::getBasename(filename); - std::string parent_dir = StringUtils::getPath(filename); - if (StringUtils::hasSuffix(parent_dir, "/")) - parent_dir = parent_dir.substr(0, parent_dir.size() - 1); - parent_dir = StringUtils::getBasename(parent_dir); - std::string cached_file = file_manager->getCachedTexturesDir() + parent_dir + "/"; - file_manager->checkAndCreateDirectoryP(cached_file); - cached_file += file; + std::string cached_file = file_manager->getTextureCacheLocation(filename); // If the cached texture does not exist, we generate it. if (!file_manager->fileExists(cached_file) || @@ -1428,9 +1419,26 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename, Log::error("irr_driver", "Texture '%s' not found.", filename.c_str()); } + m_texturesFileName[out] = filename; + return out; } // getTexture +// ---------------------------------------------------------------------------- +/** Get the texture file name using a texture pointer. +* \param tex Pointer on the texture for which we want to find the file name. +* \return Filename of the texture if found, or an empty string otherwise. +*/ +std::string IrrDriver::getTextureName(video::ITexture* tex) +{ + std::map::iterator it; + it = m_texturesFileName.find(tex); + if (it != m_texturesFileName.end()) + return it->second; + else + return ""; +} // getTextureName + // ---------------------------------------------------------------------------- /** Appends a pointer to each texture used in this mesh to the vector. * \param mesh The mesh from which the textures are being determined. diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index e685d5789..e106c211c 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -133,6 +133,8 @@ private: float greenSHCoeff[9]; float redSHCoeff[9]; + /** Keep a trace of the origin file name of a texture. */ + std::map m_texturesFileName; /** Flag to indicate if a resolution change is pending (which will be * acted upon in the next update). None means no change, yes means @@ -311,6 +313,7 @@ public: bool is_premul=false, bool is_prediv=false, bool complain_if_not_found=true); + std::string getTextureName(video::ITexture* tex); void grabAllTextures(const scene::IMesh *mesh); void dropAllTextures(const scene::IMesh *mesh); scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL, diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 4aac8224b..e45b98008 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -868,13 +868,13 @@ void FileManager::checkAndCreateScreenshotDir() void FileManager::checkAndCreateCachedTexturesDir() { #if defined(WIN32) || defined(__CYGWIN__) - m_cached_textures_dir = m_user_config_dir + "resized-textures/"; + m_cached_textures_dir = m_user_config_dir + "cached-textures/"; #elif defined(__APPLE__) m_cached_textures_dir = getenv("HOME"); - m_cached_textures_dir += "/Library/Application Support/SuperTuxKart/ResizedTextures/"; + m_cached_textures_dir += "/Library/Application Support/SuperTuxKart/CachedTextures/"; #else m_cached_textures_dir = checkAndCreateLinuxDir("XDG_CACHE_HOME", "supertuxkart", ".cache/", "."); - m_cached_textures_dir += "resized-textures/"; + m_cached_textures_dir += "cached-textures/"; #endif if (!checkAndCreateDirectory(m_cached_textures_dir)) @@ -1010,6 +1010,35 @@ void FileManager::redirectOutput() Log::openOutputFiles(logoutfile); } // redirectOutput +//----------------------------------------------------------------------------- +/** Returns the theoretical location of the cached version of a texture +* depending of the current config. (This function also works for directories: +* in this case the returned directory will be the cache location for all +* textures that you will find in the specified directory. The specified +* directory must end with '/') +* \note The returned location is where the cached data should be read or +* written but the file itseft does not necessarity exist. However, the +* directory structure is automatically created if it does not exist. +*/ +std::string FileManager::getTextureCacheLocation(const std::string& filename) +{ + std::string file = StringUtils::getBasename(filename); + + std::string parent_dir = StringUtils::getPath(filename); + if (StringUtils::hasSuffix(parent_dir, "/")) + parent_dir = parent_dir.substr(0, parent_dir.size() - 1); + parent_dir = StringUtils::getBasename(parent_dir); + + std::string cache_subdir = UserConfigParams::m_high_definition_textures + ? "hd/" + : "resized/"; + std::string cached_file = + getCachedTexturesDir() + cache_subdir + parent_dir + "/"; + checkAndCreateDirectoryP(cached_file); + cached_file += file; + return cached_file; +} // getTextureCacheLocation + //----------------------------------------------------------------------------- /** Returns the directory for addon files. */ const std::string &FileManager::getAddonsDir() const diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index 9739bbcad..cd3914d14 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -116,6 +116,7 @@ public: std::string getScreenshotDir() const; std::string getCachedTexturesDir() const; std::string getGPDir() const; + std::string getTextureCacheLocation(const std::string& filename); bool checkAndCreateDirectoryP(const std::string &path); const std::string &getAddonsDir() const; std::string getAddonsFile(const std::string &name); From 326c707458134fda4da08767ff0aa7f4aa3b016b Mon Sep 17 00:00:00 2001 From: Guillaume P Date: Thu, 8 May 2014 20:20:35 +0200 Subject: [PATCH 09/69] Clear the reminder of the origin file name of textures in Track::cleanup(). --- src/graphics/irr_driver.cpp | 8 ++++++++ src/graphics/irr_driver.hpp | 1 + src/tracks/track.cpp | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 68b48042a..de05edbb8 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1438,6 +1438,14 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename, return out; } // getTexture +// ---------------------------------------------------------------------------- +/** Clear the texture-filename reminder. +*/ +void IrrDriver::clearTexturesFileName() +{ + m_texturesFileName.clear(); +} // clearTexturesFileName + // ---------------------------------------------------------------------------- /** Get the texture file name using a texture pointer. * \param tex Pointer on the texture for which we want to find the file name. diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index df7f21b66..79d1b0887 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -309,6 +309,7 @@ public: bool is_premul=false, bool is_prediv=false, bool complain_if_not_found=true); + void clearTexturesFileName(); std::string getTextureName(video::ITexture* tex); void grabAllTextures(const scene::IMesh *mesh); void dropAllTextures(const scene::IMesh *mesh); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index e7795ee1a..2010adb30 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -207,8 +207,10 @@ void Track::cleanup() ItemManager::destroy(); ParticleKindManager::get()->cleanUpTrackSpecificGfx(); - // Clear remainder of transformed textures + // Clear reminder of transformed textures resetTextureTable(); + // Clear reminder of the link between textures and file names. + irr_driver->clearTexturesFileName(); for(unsigned int i=0; i Date: Thu, 8 May 2014 20:40:22 +0200 Subject: [PATCH 10/69] Fix Travis CI build. --- src/graphics/glwrap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 8edcd8d0e..e08c1bafa 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -381,7 +381,7 @@ void compressTexture(irr::video::ITexture *tex, bool srgb) */ bool loadCompressedTexture(const std::string& compressed_tex) { - std::ifstream ifs(compressed_tex, std::ios::in | std::ios::binary); + std::ifstream ifs(compressed_tex.c_str(), std::ios::in | std::ios::binary); if (!ifs.is_open()) return false; @@ -431,7 +431,7 @@ void saveCompressedTexture(const std::string& compressed_tex) char *data = new char[size]; glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data); - std::ofstream ofs(compressed_tex, std::ios::out | std::ios::binary); + std::ofstream ofs(compressed_tex.c_str(), std::ios::out | std::ios::binary); if (ofs.is_open()) { ofs.write((char*)&internal_format, sizeof(int)); From 9ab068a72d15b15d07289c6d2c9c4011af44fb31 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 8 May 2014 20:40:39 -0400 Subject: [PATCH 11/69] Remove accidentally committed file --- src/states_screens/xx | 212 ------------------------------------------ 1 file changed, 212 deletions(-) delete mode 100644 src/states_screens/xx diff --git a/src/states_screens/xx b/src/states_screens/xx deleted file mode 100644 index bb522ef9e..000000000 --- a/src/states_screens/xx +++ /dev/null @@ -1,212 +0,0 @@ -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 1) // SuperTuxKart - a fun racing game with go-kart -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 2) // Copyright (C) 2013 Glenn De Jonghe -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 3) // -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 4) // This program is free software; you can redistribute it and/or -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 5) // modify it under the terms of the GNU General Public License -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 6) // as published by the Free Software Foundation; either version 3 -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 7) // of the License, or (at your option) any later version. -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 8) // -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 9) // This program is distributed in the hope that it will be useful, -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 10) // but WITHOUT ANY WARRANTY; without even the implied warranty of -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 11) // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 12) // GNU General Public License for more details. -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 13) // -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 14) // You should have received a copy of the GNU General Public License -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 15) // along with this program; if not, write to the Free Software -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 16) // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 17) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 18) #include "states_screens/dialogs/recovery_dialog.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 19) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 20) #include "audio/sfx_manager.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 21) #include "guiengine/engine.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 22) #include "states_screens/state_manager.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 23) #include "utils/translation.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 24) #include "utils/string_utils.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 25) #include "online/messages.hpp" -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 26) -4d6b110e (hiker 2014-02-26 12:52:16 +1100 27) #include -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 28) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 29) using namespace GUIEngine; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 30) using namespace irr; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 31) using namespace irr::gui; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 32) using namespace Online; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 33) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 34) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 35) /** Constructor for the recovery dialog. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 36) */ -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 37) RecoveryDialog::RecoveryDialog() : ModalDialog(0.8f,0.8f) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 38) { -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 39) m_recovery_request = NULL; -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 40) m_self_destroy = false; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 41) m_show_recovery_input = true; -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 42) m_show_recovery_info = false; -8e8f02a1 (hiker 2014-04-06 01:27:04 +1100 43) doInit(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 44) showRecoveryInput(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 45) } // RecoveryDialog -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 46) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 47) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 48) /** Destructor, destroys the recovery request. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 49) */ -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 50) RecoveryDialog::~RecoveryDialog() -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 51) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 52) delete m_recovery_request; -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 53) } //~RecoverDialog -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 54) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 55) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 56) /** Shows the input screen to get the account name and email address. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 57) */ -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 58) void RecoveryDialog::showRecoveryInput() -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 59) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 60) m_show_recovery_input = false; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 61) clearWindow(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 62) m_phase = Input; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 63) loadFromFile("online/recovery_input.stkgui"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 64) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 65) m_username_widget = getWidget("username"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 66) assert(m_username_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 67) m_username_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 68) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 69) m_email_widget = getWidget("email"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 70) assert(m_email_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 71) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 72) m_info_widget = getWidget("info"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 73) assert(m_info_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 74) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 75) m_options_widget = getWidget("options"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 76) assert(m_options_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 77) m_submit_widget = getWidget("submit"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 78) assert(m_submit_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 79) m_cancel_widget = getWidget("cancel"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 80) assert(m_cancel_widget != NULL); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 81) } // showRecoveryInput -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 82) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 83) // ----------------------------------------------------------------------------- -7cc83e14 (konstin 2014-03-29 11:33:43 +0100 84) /** Informs the user that an email will be sent. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 85) */ -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 86) void RecoveryDialog::showRecoveryInfo() -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 87) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 88) m_show_recovery_info = false; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 89) clearWindow(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 90) m_phase = Info; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 91) loadFromFile("online/recovery_info.stkgui"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 92) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 93) m_info_widget = getWidget("info"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 94) assert(m_info_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 95) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 96) m_options_widget = getWidget("options"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 97) assert(m_options_widget != NULL); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 98) m_cancel_widget = getWidget("cancel"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 99) assert(m_cancel_widget != NULL); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 100) } // showRecoveryInfo -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 101) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 102) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 103) /** Let esc act as cancel. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 104) */ -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 105) bool RecoveryDialog::onEscapePressed() -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 106) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 107) return m_cancel_widget->isActivated(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 108) } // onEscapePressed -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 109) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 110) // ----------------------------------------------------------------------------- -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 111) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 112) void RecoveryDialog::processInput() -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 113) { -4d6b110e (hiker 2014-02-26 12:52:16 +1100 114) const core::stringw username = m_username_widget->getText().trim(); -4d6b110e (hiker 2014-02-26 12:52:16 +1100 115) const core::stringw email = m_email_widget->getText().trim(); -7cc83e14 (konstin 2014-03-29 11:33:43 +0100 116) if (username.size() < 4 || username.size() > 30 || -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 117) email.size() < 4 || email.size() > 50 ) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 118) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 119) sfx_manager->quickSound("anvil"); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 120) m_info_widget->setErrorColor(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 121) m_info_widget->setText(_("Username and/or email address invalid."), -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 122) false); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 123) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 124) else -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 125) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 126) m_info_widget->setDefaultColor(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 127) m_options_widget->setDeactivated(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 128) m_recovery_request = new XMLRequest(); -cb959acb (hiker 2014-04-07 08:25:48 +1000 129) // This function also works when the current user is not logged in -cb959acb (hiker 2014-04-07 08:25:48 +1000 130) CurrentUser::setUserDetails(m_recovery_request, "recovery"); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 131) m_recovery_request->addParameter("username", username); -cb959acb (hiker 2014-04-07 08:25:48 +1000 132) m_recovery_request->addParameter("email", email ); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 133) m_recovery_request->queue(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 134) } -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 135) } // processInput -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 136) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 137) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 138) /** Handle a user event. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 139) */ -7cc83e14 (konstin 2014-03-29 11:33:43 +0100 140) GUIEngine::EventPropagation -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 141) RecoveryDialog::processEvent(const std::string& eventSource) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 142) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 143) std::string selection; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 144) if (eventSource == m_options_widget->m_properties[PROP_ID]) -7cc83e14 (konstin 2014-03-29 11:33:43 +0100 145) selection = -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 146) m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 147) else -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 148) selection = eventSource; -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 149) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 150) if (selection == m_cancel_widget->m_properties[PROP_ID]) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 151) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 152) m_self_destroy = true; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 153) return GUIEngine::EVENT_BLOCK; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 154) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 155) else if (selection == m_submit_widget->m_properties[PROP_ID]) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 156) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 157) processInput(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 158) return GUIEngine::EVENT_BLOCK; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 159) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 160) return GUIEngine::EVENT_LET; -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 161) } // processEvent -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 162) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 163) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 164) /** Called when the user pressed enter. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 165) */ -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 166) void RecoveryDialog::onEnterPressedInternal() -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 167) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 168) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 169) if (GUIEngine::isFocusedForPlayer(m_options_widget, PLAYER_ID_GAME_MASTER)) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 170) return; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 171) if (m_submit_widget->isActivated()) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 172) processInput(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 173) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 174) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 175) // ----------------------------------------------------------------------------- -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 176) /** This is called every frame and checks if an outstanding recovery request -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 177) * was finished. If so, it displays the results. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 178) * \param dt Time step size. -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 179) */ -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 180) void RecoveryDialog::onUpdate(float dt) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 181) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 182) if(m_recovery_request != NULL) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 183) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 184) if(m_recovery_request->isDone()) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 185) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 186) if(m_recovery_request->isSuccess()) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 187) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 188) m_show_recovery_info = true; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 189) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 190) else -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 191) { -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 192) sfx_manager->quickSound( "anvil" ); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 193) m_info_widget->setErrorColor(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 194) m_info_widget->setText(m_recovery_request->getInfo(), false); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 195) m_options_widget->setActivated(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 196) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 197) delete m_recovery_request; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 198) m_recovery_request = NULL; -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 199) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 200) else -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 201) { -99e7b565 (unitraxx 2013-09-14 01:07:22 +0000 202) m_info_widget->setText(Messages::validatingInfo(), false); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 203) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 204) } -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 205) // It's unsafe to delete from inside the event handler so we do it here -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 206) if (m_self_destroy) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 207) ModalDialog::dismiss(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 208) else if (m_show_recovery_input) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 209) showRecoveryInput(); -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 210) else if (m_show_recovery_info) -4091c4c9 (unitraxx 2013-07-27 20:55:10 +0000 211) showRecoveryInfo(); -6afc12c8 (hiker 2014-03-14 16:44:58 +1100 212) } // onUpdates From d78482ac67278620401d07aab6c907e2c950c89e Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 8 May 2014 20:50:34 -0400 Subject: [PATCH 12/69] Better react to small screens --- src/guiengine/engine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index fdcb13fe1..c1495fdf7 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1048,7 +1048,12 @@ namespace GUIEngine const int screen_width = irr_driver->getFrameSize().Width; const int screen_height = irr_driver->getFrameSize().Height; float scale = std::max(0, screen_width - 640)/564.0f; - if (screen_height < 700) scale = std::min(scale, 0.25f); // attempt to compensate for small screens + + // attempt to compensate for small screens + if (screen_width < 1200) scale = std::max(0, screen_width - 640) / 750.0f; + if (screen_width < 900 || screen_height < 700) scale = std::min(scale, 0.05f); + + Log::info("GUIEngine", "scale: %f", scale); float normal_text_scale = 0.7f + 0.2f*scale; float title_text_scale = 0.2f + 0.2f*scale; From 3e6ab6d7b638a597efab3d0491584e692968c27b Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 14:44:53 +0200 Subject: [PATCH 13/69] Factorize SSAO in its own code. --- src/graphics/irr_driver.hpp | 1 + src/graphics/render.cpp | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 72419f2b9..f66b36671 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -269,6 +269,7 @@ private: void computeCameraMatrix(scene::ICameraSceneNode * const camnode); void renderShadows(); void renderGlow(std::vector& glows); + void renderSSAO(); void renderLights(float dt); void renderDisplacement(); void doScreenShot(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 2bfdf7eee..9bf6701e0 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -231,6 +231,12 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector renderLights(dt); PROFILER_POP_CPU_MARKER(); + // Handle SSAO + PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); + if (UserConfigParams::m_ssao) + renderSSAO(); + PROFILER_POP_CPU_MARKER(); + PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); if (!UserConfigParams::m_dynamic_lights) { @@ -830,19 +836,19 @@ void IrrDriver::renderLights(float dt) m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff); } gl_driver->extGlDrawBuffers(1, bufs); - // Handle SSAO - if (UserConfigParams::m_ssao) - { - glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO)); - glClearColor(1., 1., 1., 1.); - glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); - m_post_processing->renderSSAO(); - // Blur it to reduce noise. - m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), - irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); - glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); - } +} + +void IrrDriver::renderSSAO() +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO)); + glClearColor(1., 1., 1., 1.); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); + m_post_processing->renderSSAO(); + // Blur it to reduce noise. + m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), + irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); + glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z) From 59f586c5ee2935ff732f080db593bde2f81a7cd7 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 14:54:42 +0200 Subject: [PATCH 14/69] Add some more gpu timer. --- src/graphics/irr_driver.hpp | 8 +- src/graphics/render.cpp | 195 +++++++++++++++++++----------------- 2 files changed, 108 insertions(+), 95 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index f66b36671..9f3fe4c63 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -77,9 +77,13 @@ enum STKRenderingPass enum QueryPerf { Q_SOLID_PASS1, - Q_SOLID_PASS2, - Q_LIGHT, Q_SHADOWS, + Q_LIGHT, + Q_SSAO, + Q_SOLID_PASS2, + Q_TRANSPARENT, + Q_PARTICLES, + Q_DISPLACEMENT, Q_LAST }; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 9bf6701e0..ce56ad7c9 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -216,26 +216,32 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox(); - PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); // Shadows - if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && - UserConfigParams::m_shadows && hasShadow) { - renderShadows(); + PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); + ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); + if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && + UserConfigParams::m_shadows && hasShadow) + renderShadows(); + PROFILER_POP_CPU_MARKER(); } - PROFILER_POP_CPU_MARKER(); - - PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); // Lights - renderLights(dt); - PROFILER_POP_CPU_MARKER(); + { + PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); + ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT)); + renderLights(dt); + PROFILER_POP_CPU_MARKER(); + } // Handle SSAO - PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); - if (UserConfigParams::m_ssao) - renderSSAO(); - PROFILER_POP_CPU_MARKER(); + { + PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); + ScopedGPUTimer Timer(getGPUTimer(Q_SSAO)); + if (UserConfigParams::m_ssao) + renderSSAO(); + PROFILER_POP_CPU_MARKER(); + } PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF); if (!UserConfigParams::m_dynamic_lights) @@ -274,18 +280,29 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector computeSunVisibility(); PROFILER_POP_CPU_MARKER(); - // We need to re-render camera due to the per-cam-node hack. - PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); - renderTransparent(); - PROFILER_POP_CPU_MARKER(); + // Render transparent + { + PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00); + ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT)); + renderTransparent(); + PROFILER_POP_CPU_MARKER(); + } - PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); - renderParticles(); - PROFILER_POP_CPU_MARKER(); + // Render particles + { + PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00); + ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES)); + renderParticles(); + PROFILER_POP_CPU_MARKER(); + } - PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF); - renderDisplacement(); - PROFILER_POP_CPU_MARKER(); + // Render displacement + { + PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF); + ScopedGPUTimer Timer(getGPUTimer(Q_DISPLACEMENT)); + renderDisplacement(); + PROFILER_POP_CPU_MARKER(); + } } // -------------------------------------------- @@ -638,13 +655,9 @@ void IrrDriver::renderShadows() glDrawBuffer(GL_NONE); glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); - { - ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); - m_scene_manager->drawAll(scene::ESNRP_SOLID); - } + m_scene_manager->drawAll(scene::ESNRP_SOLID); glDisable(GL_POLYGON_OFFSET_FILL); - glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } @@ -766,75 +779,71 @@ void IrrDriver::renderLights(float dt) const core::vector3df &campos = irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); + std::vector BucketedLN[15]; + for (unsigned int i = 0; i < lightcount; i++) { - ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT)); - - std::vector BucketedLN[15]; - for (unsigned int i = 0; i < lightcount; i++) + if (!m_lights[i]->isPointLight()) { - if (!m_lights[i]->isPointLight()) - { - m_lights[i]->render(); - if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows()) - m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex()); - else - m_post_processing->renderSunlight(); - continue; - } - const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos); - unsigned idx = (unsigned)(lightpos.getLength() / 10); - if (idx > 14) - idx = 14; - BucketedLN[idx].push_back(m_lights[i]); + m_lights[i]->render(); + if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows()) + m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex()); + else + m_post_processing->renderSunlight(); + continue; } - - unsigned lightnum = 0; - - for (unsigned i = 0; i < 15; i++) - { - for (unsigned j = 0; j < BucketedLN[i].size(); j++) - { - if (++lightnum >= MAXLIGHT) - { - LightNode* light_node = BucketedLN[i].at(j); - light_node->setEnergyMultiplier(0.0f); - } - else - { - LightNode* light_node = BucketedLN[i].at(j); - - float em = light_node->getEnergyMultiplier(); - if (em < 1.0f) - { - light_node->setEnergyMultiplier(std::min(1.0f, em + dt)); - } - - const core::vector3df &pos = light_node->getAbsolutePosition(); - PointLightsInfo[lightnum].posX = pos.X; - PointLightsInfo[lightnum].posY = pos.Y; - PointLightsInfo[lightnum].posZ = pos.Z; - - PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy(); - - const core::vector3df &col = light_node->getColor(); - PointLightsInfo[lightnum].red = col.X; - PointLightsInfo[lightnum].green = col.Y; - PointLightsInfo[lightnum].blue = col.Z; - } - } - if (lightnum > MAXLIGHT) - { - irr_driver->setLastLightBucketDistance(i * 10); - break; - } - } - - lightnum++; - - renderPointLights(MIN2(lightnum, MAXLIGHT)); - if (SkyboxCubeMap) - m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff); + const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos); + unsigned idx = (unsigned)(lightpos.getLength() / 10); + if (idx > 14) + idx = 14; + BucketedLN[idx].push_back(m_lights[i]); } + + unsigned lightnum = 0; + + for (unsigned i = 0; i < 15; i++) + { + for (unsigned j = 0; j < BucketedLN[i].size(); j++) + { + if (++lightnum >= MAXLIGHT) + { + LightNode* light_node = BucketedLN[i].at(j); + light_node->setEnergyMultiplier(0.0f); + } + else + { + LightNode* light_node = BucketedLN[i].at(j); + + float em = light_node->getEnergyMultiplier(); + if (em < 1.0f) + { + light_node->setEnergyMultiplier(std::min(1.0f, em + dt)); + } + + const core::vector3df &pos = light_node->getAbsolutePosition(); + PointLightsInfo[lightnum].posX = pos.X; + PointLightsInfo[lightnum].posY = pos.Y; + PointLightsInfo[lightnum].posZ = pos.Z; + + PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy(); + + const core::vector3df &col = light_node->getColor(); + PointLightsInfo[lightnum].red = col.X; + PointLightsInfo[lightnum].green = col.Y; + PointLightsInfo[lightnum].blue = col.Z; + } + } + if (lightnum > MAXLIGHT) + { + irr_driver->setLastLightBucketDistance(i * 10); + break; + } + } + + lightnum++; + + renderPointLights(MIN2(lightnum, MAXLIGHT)); + if (SkyboxCubeMap) + m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff); gl_driver->extGlDrawBuffers(1, bufs); } From 94c65434df7e6d0c80a04a99bfe6eabcc10057d0 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 15:07:07 +0200 Subject: [PATCH 15/69] Add some more perfs counter to post process --- src/graphics/irr_driver.hpp | 4 + src/graphics/post_processing.cpp | 133 ++++++++++++++++--------------- src/graphics/post_processing.hpp | 3 +- src/graphics/render.cpp | 14 ++-- 4 files changed, 81 insertions(+), 73 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 9f3fe4c63..d49354f6e 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -84,6 +84,10 @@ enum QueryPerf Q_TRANSPARENT, Q_PARTICLES, Q_DISPLACEMENT, + Q_GODRAYS, + Q_BLOOM, + Q_TONEMAP, + Q_MOTIONBLUR, Q_LAST }; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 959ac351b..fb1384069 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -624,10 +624,8 @@ void PostProcessing::applyMLAA() // ---------------------------------------------------------------------------- /** Render the post-processed scene */ -void PostProcessing::render() +void PostProcessing::render(scene::ICameraSceneNode * const camnode) { - if (!irr_driver->isGLSL()) return; - IVideoDriver * const drv = irr_driver->getVideoDriver(); MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver-> @@ -635,29 +633,25 @@ void PostProcessing::render() GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> getCallback(ES_GAUSSIAN3H); - const u32 cams = Camera::getNumCameras(); - for(u32 cam = 0; cam < cams; cam++) + GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS); + GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS); + // Each effect uses these as named, and sets them up for the next effect. + // This allows chaining effects where some may be disabled. + + // As the original color shouldn't be touched, the first effect can't be disabled. + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + if (UserConfigParams::m_dof) { - scene::ICameraSceneNode * const camnode = - Camera::getCamera(cam)->getCameraSceneNode(); - mocb->setCurrentCamera(cam); - GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS); - GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS); - // Each effect uses these as named, and sets them up for the next effect. - // This allows chaining effects where some may be disabled. - - // As the original color shouldn't be touched, the first effect can't be disabled. - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - - if (UserConfigParams::m_dof) - { - renderDoF(out_fbo, in_rtt); - std::swap(in_rtt, out_rtt); - std::swap(in_fbo, out_fbo); - } + renderDoF(out_fbo, in_rtt); + std::swap(in_rtt, out_rtt); + std::swap(in_fbo, out_fbo); + } + { PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); + ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS)); const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays) { @@ -665,7 +659,7 @@ void PostProcessing::render() // Grab the sky glBindFramebuffer(GL_FRAMEBUFFER, out_fbo); glClear(GL_COLOR_BUFFER_BIT); -// irr_driver->renderSkybox(); + irr_driver->renderSkybox(camnode); // Set the sun's color const SColor col = World::getWorld()->getTrack()->getSunColor(); @@ -700,8 +694,8 @@ void PostProcessing::render() trans.transformVect(ndc, pos); - const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y; - const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X; + const float texh = m_vertices[0].v1.TCoords.Y - m_vertices[0].v0.TCoords.Y; + const float texw = m_vertices[0].v3.TCoords.X - m_vertices[0].v0.TCoords.X; const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw; const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh; @@ -727,10 +721,13 @@ void PostProcessing::render() glDisable(GL_BLEND); } PROFILER_POP_CPU_MARKER(); + } - // Simulate camera defects from there + // Simulate camera defects from there + { PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00); + ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM)); if (UserConfigParams::m_bloom) { glClear(GL_STENCIL_BUFFER_BIT); @@ -784,53 +781,61 @@ void PostProcessing::render() renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_512)); glDisable(GL_BLEND); } // end if bloom - PROFILER_POP_CPU_MARKER(); - computeLogLuminance(in_rtt); + } + + //computeLogLuminance(in_rtt); + { + PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00); + ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP)); toneMap(out_fbo, in_rtt); std::swap(in_rtt, out_rtt); std::swap(in_fbo, out_fbo); + PROFILER_POP_CPU_MARKER(); + } + { + PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); + ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR)); if (UserConfigParams::m_motionblur && m_any_boost) // motion blur { - PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); - renderMotionBlur(cam, in_rtt, out_fbo); + renderMotionBlur(0, in_rtt, out_fbo); std::swap(in_fbo, out_fbo); std::swap(in_rtt, out_rtt); - PROFILER_POP_CPU_MARKER(); } + PROFILER_POP_CPU_MARKER(); + } - if (irr_driver->getNormals()) - { - glEnable(GL_FRAMEBUFFER_SRGB); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH)); - glDisable(GL_FRAMEBUFFER_SRGB); - } - else if (irr_driver->getSSAOViz()) - { - glEnable(GL_FRAMEBUFFER_SRGB); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO)); - glDisable(GL_FRAMEBUFFER_SRGB); - } - else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. - { - PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00); - glEnable(GL_FRAMEBUFFER_SRGB); - glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS)); - renderPassThrough(in_rtt); - glDisable(GL_FRAMEBUFFER_SRGB); - applyMLAA(); - blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height); - PROFILER_POP_CPU_MARKER(); - } - else - { - glEnable(GL_FRAMEBUFFER_SRGB); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - renderPassThrough(in_rtt); - glDisable(GL_FRAMEBUFFER_SRGB); - } + if (irr_driver->getNormals()) + { + glEnable(GL_FRAMEBUFFER_SRGB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH)); + glDisable(GL_FRAMEBUFFER_SRGB); + } + else if (irr_driver->getSSAOViz()) + { + glEnable(GL_FRAMEBUFFER_SRGB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO)); + glDisable(GL_FRAMEBUFFER_SRGB); + } + else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. + { + PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00); + glEnable(GL_FRAMEBUFFER_SRGB); + glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS)); + renderPassThrough(in_rtt); + glDisable(GL_FRAMEBUFFER_SRGB); + applyMLAA(); + blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height); + PROFILER_POP_CPU_MARKER(); + } + else + { + glEnable(GL_FRAMEBUFFER_SRGB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + renderPassThrough(in_rtt); + glDisable(GL_FRAMEBUFFER_SRGB); } } // render diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 359293524..d7975ffae 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -21,6 +21,7 @@ #include "IShaderConstantSetCallBack.h" #include "S3DVertex.h" #include "SMaterial.h" +#include "graphics/camera.hpp" #include @@ -92,7 +93,7 @@ public: void renderGlow(unsigned tex); /** Render the post-processed scene */ - void render(); + void render(scene::ICameraSceneNode * const camnode); /** Use motion blur for a short time */ void giveBoost(unsigned int cam_index); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index ce56ad7c9..58728a68c 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -142,6 +142,12 @@ void IrrDriver::renderGLSL(float dt) renderScene(camnode, glows, dt, track->hasShadows()); + // Render the post-processed scene + if (UserConfigParams::m_dynamic_lights) + m_post_processing->render(camnode); + else + glDisable(GL_FRAMEBUFFER_SRGB); + PROFILER_POP_CPU_MARKER(); // Note that drawAll must be called before rendering @@ -152,14 +158,6 @@ void IrrDriver::renderGLSL(float dt) World::getWorld()->getPhysics()->draw(); } // for igetNumKarts() - PROFILER_PUSH_CPU_MARKER("Postprocessing", 0xFF, 0xFF, 0x00); - // Render the post-processed scene - if (UserConfigParams::m_dynamic_lights) - m_post_processing->render(); - else - glDisable(GL_FRAMEBUFFER_SRGB); - PROFILER_POP_CPU_MARKER(); - glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); From c5e31c96b186598bfe27ba8fc47da6d9317c6150 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 15:11:18 +0200 Subject: [PATCH 16/69] Simplify mesh temporary. Until we move this code to the exporter. --- src/graphics/irr_driver.cpp | 3 ++- src/graphics/post_processing.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 911a591ec..2cfa74e09 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -841,7 +841,8 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename) filename.c_str()); return NULL; } - return am->getMesh(0); + scene::IMeshManipulator *mani = irr_driver->getVideoDriver()->getMeshManipulator(); + return mani->createMeshWelded(am->getMesh(0)); } // getMesh // ---------------------------------------------------------------------------- diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index fb1384069..310199600 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -786,12 +786,12 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode) //computeLogLuminance(in_rtt); { - PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00); +// PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP)); toneMap(out_fbo, in_rtt); std::swap(in_rtt, out_rtt); std::swap(in_fbo, out_fbo); - PROFILER_POP_CPU_MARKER(); +// PROFILER_POP_CPU_MARKER(); } { From bc2c355cd82af5eb0406b931fcb8e1885986e681 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 18:41:24 +0200 Subject: [PATCH 17/69] Shadows: Emit an error instead of sending wrong corners. --- src/graphics/render.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 58728a68c..5ebcbef30 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -610,6 +610,13 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode) float up = box.MaxEdge.Y; float down = box.MinEdge.Y; + // Prevent Matrix without extend + if (left == right || up == down) + { + Log::error("Shadows", "Shadows Near/Far plane have a 0 area"); + continue; + } + core::matrix4 tmp_matrix; tmp_matrix.buildProjectionMatrixOrthoLH(left, right, From 5b511fedd85069c5a056d8fd8833823ded7bac54 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 18:46:07 +0200 Subject: [PATCH 18/69] Lights: Culling was not using correct cam position --- src/graphics/irr_driver.hpp | 2 +- src/graphics/render.cpp | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index d49354f6e..26dc4c18a 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -278,7 +278,7 @@ private: void renderShadows(); void renderGlow(std::vector& glows); void renderSSAO(); - void renderLights(float dt); + void renderLights(scene::ICameraSceneNode * const camnode, float dt); void renderDisplacement(); void doScreenShot(); public: diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 5ebcbef30..8818c2c1c 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -228,7 +228,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector { PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT)); - renderLights(dt); + renderLights(camnode, dt); PROFILER_POP_CPU_MARKER(); } @@ -759,7 +759,7 @@ static void renderPointLights(unsigned count) glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); } -void IrrDriver::renderLights(float dt) +void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt) { for (unsigned i = 0; i < sun_ortho_matrix.size(); i++) @@ -781,8 +781,7 @@ void IrrDriver::renderLights(float dt) irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); const u32 lightcount = m_lights.size(); - const core::vector3df &campos = - irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); + const core::vector3df &campos = camnode->getAbsolutePosition(); std::vector BucketedLN[15]; for (unsigned int i = 0; i < lightcount; i++) From b4e9a0057472e960d807ac03a164b42dec3f6d16 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 18:54:06 +0200 Subject: [PATCH 19/69] Fix profiler --- src/graphics/post_processing.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 310199600..68ac865b0 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -781,17 +781,17 @@ void PostProcessing::render(scene::ICameraSceneNode * const camnode) renderPassThrough(irr_driver->getRenderTargetTexture(RTT_BLOOM_512)); glDisable(GL_BLEND); } // end if bloom - + PROFILER_POP_CPU_MARKER(); } //computeLogLuminance(in_rtt); { -// PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00); + PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00); ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP)); toneMap(out_fbo, in_rtt); std::swap(in_rtt, out_rtt); std::swap(in_fbo, out_fbo); -// PROFILER_POP_CPU_MARKER(); + PROFILER_POP_CPU_MARKER(); } { From cd6e7f3d906b7ea76352132e325372617520fe4c Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 19:32:52 +0200 Subject: [PATCH 20/69] Fix an assert. --- src/graphics/render.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8818c2c1c..0ea38494a 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -610,15 +610,16 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode) float up = box.MaxEdge.Y; float down = box.MinEdge.Y; + core::matrix4 tmp_matrix; + // Prevent Matrix without extend if (left == right || up == down) { Log::error("Shadows", "Shadows Near/Far plane have a 0 area"); + sun_ortho_matrix.push_back(tmp_matrix); continue; } - core::matrix4 tmp_matrix; - tmp_matrix.buildProjectionMatrixOrthoLH(left, right, up, down, 30, z); From 07f68db6c3dc2be448acfe65a459be91926f259d Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 9 May 2014 19:55:06 +0200 Subject: [PATCH 21/69] Fix wrong mouse poisition report. m_mouse_pos was always (0, -1) in some case, which makes profiling hard. --- src/guiengine/event_handler.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index acce1b1d9..cfcc0332c 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -159,8 +159,12 @@ bool EventHandler::OnEvent (const SEvent &event) event.EventType == EET_JOYSTICK_INPUT_EVENT) { // Remember the mouse position - m_mouse_pos.X = event.MouseInput.X; - m_mouse_pos.Y = event.MouseInput.Y; + if (event.EventType == EET_MOUSE_INPUT_EVENT && + event.MouseInput.Event == EMIE_MOUSE_MOVED) + { + m_mouse_pos.X = event.MouseInput.X; + m_mouse_pos.Y = event.MouseInput.Y; + } // Notify the profiler of mouse events if(UserConfigParams::m_profiler_enabled && From b72c1ad0c52612e2c3414583485907e1ee312129 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 02:28:02 +0200 Subject: [PATCH 22/69] Fix for disappearing objects. --- src/graphics/render.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 0ea38494a..88532c0e3 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -139,6 +139,7 @@ void IrrDriver::renderGLSL(float dt) #endif camera->activate(); rg->preRenderCallback(camera); // adjusts start referee + m_scene_manager->setActiveCamera(camnode); renderScene(camnode, glows, dt, track->hasShadows()); @@ -624,7 +625,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode) up, down, 30, z); m_suncam->setProjectionMatrix(tmp_matrix, true); - m_scene_manager->setActiveCamera(m_suncam); m_suncam->render(); sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW)); @@ -632,7 +632,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode) assert(sun_ortho_matrix.size() == 4); camnode->setNearValue(oldnear); camnode->setFarValue(oldfar); -// camnode->render(); float *tmp = new float[16 * 8]; From f7aa586eb2c644df70ff84864fb66494d4442338 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 02:41:45 +0200 Subject: [PATCH 23/69] Check if compression was successful before caching Fix a crash on radeon. --- src/graphics/glwrap.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index e08c1bafa..7ab7712e2 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -423,10 +423,13 @@ bool loadCompressedTexture(const std::string& compressed_tex) */ void saveCompressedTexture(const std::string& compressed_tex) { - int internal_format, width, height, size; + int internal_format, width, height, size, compressionSuccessful; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internal_format); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint *)&width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint *)&height); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, (GLint *)&compressionSuccessful); + if (!compressionSuccessful) + return; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&size); char *data = new char[size]; From a3f1e4bad1f494f62291bfe764628bb30aa0eb50 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 02:52:58 +0200 Subject: [PATCH 24/69] Explicitly use S3TC texture compression. --- src/graphics/glwrap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7ab7712e2..996760e02 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -357,9 +357,9 @@ void compressTexture(irr::video::ITexture *tex, bool srgb) else { if (srgb) - internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA : GL_COMPRESSED_SRGB; + internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; else - internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA : GL_COMPRESSED_RGB; + internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT; } glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, Format, GL_UNSIGNED_BYTE, (GLvoid *)data); glGenerateMipmap(GL_TEXTURE_2D); From 5d3b6bba4d524516b276358e834debd858d92908 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 20:00:52 +0200 Subject: [PATCH 25/69] Avoid shadow disappearance --- src/graphics/render.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 88532c0e3..380fc3915 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -219,9 +219,12 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector { PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS)); + // To avoid wrong culling, use the largest view possible + m_scene_manager->setActiveCamera(m_suncam); if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights && UserConfigParams::m_shadows && hasShadow) renderShadows(); + m_scene_manager->setActiveCamera(camnode); PROFILER_POP_CPU_MARKER(); } From 6bf67523b945dc6b5c38be3789268186e30ea4a3 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 20:16:27 +0200 Subject: [PATCH 26/69] Prettier gpu timing label. --- src/utils/profiler.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/utils/profiler.cpp b/src/utils/profiler.cpp index 6cde51c57..5a4003911 100644 --- a/src/utils/profiler.cpp +++ b/src/utils/profiler.cpp @@ -389,8 +389,23 @@ void Profiler::draw() if (hovered_gpu_marker != Q_LAST) { + static const char *Phase[Q_LAST] = + { + "Solid Pass 1", + "Shadows", + "Lights", + "SSAO", + "Solid Pass 2", + "Transparent", + "Particles", + "Displacement", + "Godrays", + "Bloom", + "Tonemap", + "Motion Blur" + }; std::ostringstream oss; - oss << "GPU marker " << hovered_gpu_marker << " : " << hovered_gpu_marker_elapsed << " us"; + oss << Phase[hovered_gpu_marker] << " : " << hovered_gpu_marker_elapsed << " us"; font->draw(oss.str().c_str(), GPU_MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00)); } } From 6936f30b36e6f000aac685c658ecae541e2587c5 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 20:49:30 +0200 Subject: [PATCH 27/69] Premultiply alpha for billboards. --- data/shaders/billboard.frag | 2 +- src/graphics/glwrap.cpp | 15 +++++++++++++-- src/graphics/glwrap.hpp | 2 +- src/graphics/stkbillboard.cpp | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/data/shaders/billboard.frag b/data/shaders/billboard.frag index 6df5ad558..0eb0af806 100644 --- a/data/shaders/billboard.frag +++ b/data/shaders/billboard.frag @@ -12,5 +12,5 @@ varying vec2 uv; void main(void) { vec4 color = texture(tex, uv); - FragColor = vec4(color.rgb * color.a, color.a); + FragColor = vec4(color.rgb, color.a); } diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 996760e02..aacb64ba2 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -315,7 +315,7 @@ void resetTextureTable() AlreadyTransformedTexture.clear(); } -void compressTexture(irr::video::ITexture *tex, bool srgb) +void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha) { if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end()) return; @@ -338,7 +338,7 @@ void compressTexture(irr::video::ITexture *tex, bool srgb) } size_t w = tex->getSize().Width, h = tex->getSize().Height; - char *data = new char[w * h * 4]; + unsigned char *data = new unsigned char[w * h * 4]; memcpy(data, tex->lock(), w * h * 4); tex->unlock(); unsigned internalFormat, Format; @@ -347,6 +347,17 @@ void compressTexture(irr::video::ITexture *tex, bool srgb) else Format = GL_BGR; + if (premul_alpha) + { + for (unsigned i = 0; i < w * h; i++) + { + float alpha = pow(data[4 * i + 3] / 255., 1. / 2.2); + data[4 * i] *= alpha; + data[4 * i + 1] *= alpha; + data[4 * i + 2] *= alpha; + } + } + if (!UserConfigParams::m_texture_compression) { if (srgb) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 5cec12f90..bd64792d7 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -181,7 +181,7 @@ public: GLuint getTextureGLuint(irr::video::ITexture *tex); GLuint getDepthTexture(irr::video::ITexture *tex); void resetTextureTable(); -void compressTexture(irr::video::ITexture *tex, bool srgb); +void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false); bool loadCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex); void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height); diff --git a/src/graphics/stkbillboard.cpp b/src/graphics/stkbillboard.cpp index 7b71977b5..4ce29f479 100644 --- a/src/graphics/stkbillboard.cpp +++ b/src/graphics/stkbillboard.cpp @@ -35,7 +35,7 @@ void STKBillboard::render() core::vector3df pos = getAbsolutePosition(); glBindVertexArray(billboardvao); video::ITexture *tex = Material.getTexture(0); - compressTexture(tex, true); + compressTexture(tex, true, true); GLuint texid = getTextureGLuint(tex); setTexture(0, texid, GL_LINEAR, GL_LINEAR); glUseProgram(MeshShader::BillboardShader::Program); From 648d076e00adb326c3869cd2b428018b37ffd616 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 10 May 2014 20:58:43 +0200 Subject: [PATCH 28/69] Premultiply alpha for particles too. --- data/shaders/particle.frag | 3 +-- src/graphics/glwrap.cpp | 4 +++- src/graphics/gpuparticles.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index f363e9cf1..56369e5d9 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -20,6 +20,5 @@ void main(void) EnvPos /= EnvPos.w; float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); vec4 color = texture(tex, tc) * vec4(pc, 1.0); - color.a *= alpha * smoothstep(1., 0.8, lf); - FragColor = vec4(color.rgb * color.a, color.a); + FragColor = color * alpha * smoothstep(1., 0.8, lf); } diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index aacb64ba2..da7bac15f 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -351,7 +351,9 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha) { for (unsigned i = 0; i < w * h; i++) { - float alpha = pow(data[4 * i + 3] / 255., 1. / 2.2); + float alpha = data[4 * i + 3]; + if (alpha > 0.) + alpha = pow(alpha / 255., 1. / 2.2); data[4 * i] *= alpha; data[4 * i + 1] *= alpha; data[4 * i + 2] *= alpha; diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 6dc648831..8b14bee60 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -360,7 +360,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); video::ITexture *tex = getMaterial(0).getTexture(0); - compressTexture(tex, true); + compressTexture(tex, true, true); texture = getTextureGLuint(getMaterial(0).getTexture(0)); } From 46a832a67f0d66acfc9f6515413ea327c41d6e72 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 00:52:19 +0200 Subject: [PATCH 29/69] Reenable physic debug mode --- src/graphics/glwrap.cpp | 26 ++++++++++++++++++++++++ src/graphics/glwrap.hpp | 3 +++ src/graphics/shaders.cpp | 34 ++++++++++++++++++++++++++++++++ src/graphics/shaders.hpp | 15 ++++++++++++++ src/physics/irr_debug_drawer.cpp | 3 +-- src/physics/irr_debug_drawer.hpp | 1 + 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index da7bac15f..d60215c25 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -521,6 +521,32 @@ unsigned GPUTimer::elapsedTimeus() return result / 1000; } +void draw3DLine(const core::vector3df& start, + const core::vector3df& end, irr::video::SColor color) +{ + if (!irr_driver->isGLSL()) { + irr_driver->getVideoDriver()->draw3DLine(start, end, color); + return; + } + + float vertex[6] = { + start.X, start.Y, start.Z, + end.X, end.Y, end.Z + }; + + glBindVertexArray(UtilShader::ColoredLine::vao); + glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(float), vertex); + + glUseProgram(UtilShader::ColoredLine::Program); + UtilShader::ColoredLine::setUniforms(color); + glDrawArrays(GL_LINES, 0, 2); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glGetError(); +} + static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height, float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, float tex_width, float tex_height) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index bd64792d7..df3827d0f 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -186,6 +186,9 @@ bool loadCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex); void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height); +void draw3DLine(const core::vector3df& start, + const core::vector3df& end, irr::video::SColor color); + void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, const irr::core::rect& sourceRect, const irr::core::rect* clipRect, const irr::video::SColor &color, bool useAlphaChannelOfTexture); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 28e441e46..4a3e9a126 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -364,6 +364,7 @@ void Shaders::loadShaders() UIShader::ColoredTextureRectShader::init(); UIShader::TextureRectShader::init(); UIShader::UniformColoredTextureRectShader::init(); + UtilShader::ColoredLine::init(); } Shaders::~Shaders() @@ -404,6 +405,39 @@ static void bypassUBO(GLint Program) glUniformMatrix4fv(IPM, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); } +namespace UtilShader +{ + GLuint ColoredLine::Program; + GLuint ColoredLine::uniform_color; + GLuint ColoredLine::vao; + GLuint ColoredLine::vbo; + + void ColoredLine::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/coloredquad.frag").c_str()); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + float vertex[6] = {}; + glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertex, GL_DYNAMIC_DRAW); + GLuint attrib_position = glGetAttribLocation(Program, "Position"); + glEnableVertexAttribArray(attrib_position); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + uniform_color = glGetUniformLocation(Program, "color"); + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); + } + + void ColoredLine::setUniforms(const irr::video::SColor &col) + { + glUniform4i(uniform_color, col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha()); + glUniformMatrix4fv(glGetUniformLocation(Program, "ModelMatrix"), 1, GL_FALSE, core::IdentityMatrix.pointer()); + } +} + namespace MeshShader { diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 8b0c0a54f..7efc11f4c 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -32,6 +32,21 @@ public: static GLuint cubevbo, cubeindexes; static GLuint ViewProjectionMatrixesUBO; }; + +namespace UtilShader +{ +class ColoredLine +{ +public: + static GLuint Program; + static GLuint uniform_color; + static GLuint vao, vbo; + + static void init(); + static void setUniforms(const irr::video::SColor &); +}; +} + namespace MeshShader { class ObjectPass1Shader diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index e835a05d9..ed3b169fa 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -58,8 +58,7 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, { video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255), (int)(color.getZ()*255) ); - irr_driver->getVideoDriver()->draw3DLine((const core::vector3df&)from, - (const core::vector3df&)to, c); + draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c); } /* EOF */ diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index 93fdbcbc9..1d6ca8720 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -20,6 +20,7 @@ #define HEADER_IRR_DEBUG_DRAWER_HPP #include "btBulletDynamicsCommon.h" +#include "graphics/glwrap.hpp" #include "utils/vec3.hpp" From 486d5c291f6f4a77b5962a40a0fb1b09a65d7445 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 19:26:14 -0400 Subject: [PATCH 30/69] Batch physics debug rendering --- src/graphics/irr_driver.cpp | 10 ++++++++++ src/graphics/render.cpp | 18 ++++++++++++++++++ src/modes/world.cpp | 6 ++++++ src/physics/irr_debug_drawer.cpp | 16 +++++++++++++++- src/physics/irr_debug_drawer.hpp | 8 ++++++++ src/physics/physics.hpp | 1 + 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 1fb87a56a..15cd402c0 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1952,6 +1952,16 @@ void IrrDriver::update(float dt) else renderFixed(dt); + + if (world != NULL && world->getPhysics() != NULL) + { + IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); + if (debug_drawer != NULL && debug_drawer->debugEnabled()) + { + debug_drawer->beginNextFrame(); + } + } + if (m_request_screenshot) doScreenShot(); // Enable this next print statement to get render information printed diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 380fc3915..fef45da0d 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -197,6 +197,24 @@ void IrrDriver::renderGLSL(float dt) drawDebugMeshes(); #endif + + if (world != NULL && world->getPhysics() != NULL) + { + IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); + if (debug_drawer != NULL && debug_drawer->debugEnabled()) + { + const std::map>& lines = debug_drawer->getLines(); + std::map>::const_iterator it; + for (it = lines.begin(); it != lines.end(); it++) + { + for (int i = 0; i < it->second.size(); i += 2) + { + draw3DLine((const core::vector3df&)it->second[0], (const core::vector3df&)it->second[1], it->first); + } + } + } + } + PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45); m_video_driver->endScene(); PROFILER_POP_CPU_MARKER(); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 1cedb6fe4..af3fab03c 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -621,8 +621,14 @@ void World::resetAllKarts() // Stil wait will all karts are in rest (and handle the case that a kart // fell through the ground, which can happen if a kart falls for a long // time, therefore having a high speed when hitting the ground. + int count = 0; while(!all_finished) { + if (count++ > 100) + { + Log::error("World", "Infitine loop waiting for all_finished?"); + break; + } m_physics->update(1.f/60.f); all_finished=true; for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++) diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index ed3b169fa..a6ec03460 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -58,7 +58,21 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, { video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255), (int)(color.getZ()*255) ); - draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c); + + m_lines[c].push_back(from); + m_lines[c].push_back(to); + + //draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c); +} + +// ----------------------------------------------------------------------------- + +void IrrDebugDrawer::beginNextFrame() +{ + for (std::map>::iterator it = m_lines.begin(); it != m_lines.end(); it++) + { + it->second.clear(); + } } /* EOF */ diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index 1d6ca8720..72a40932c 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -23,6 +23,8 @@ #include "graphics/glwrap.hpp" #include "utils/vec3.hpp" +#include +#include /** * \ingroup physics @@ -39,6 +41,9 @@ public: DM_NO_KARTS_GRAPHICS = 0x02 }; DebugModeType m_debug_mode; + + std::map> m_lines; + protected: virtual void setDebugMode(int debug_mode) {} /** Callback for bullet: if debug drawing should be done or not. @@ -66,6 +71,9 @@ public: bool debugEnabled() const {return m_debug_mode!=0;} void nextDebugMode(); void setDebugMode(DebugModeType mode); + + void beginNextFrame(); + const std::map>& getLines() const { return m_lines; } }; // IrrDebugDrawer #endif diff --git a/src/physics/physics.hpp b/src/physics/physics.hpp index 47b3e874f..96f5fc1b6 100644 --- a/src/physics/physics.hpp +++ b/src/physics/physics.hpp @@ -165,6 +165,7 @@ public: void setDebugMode(IrrDebugDrawer::DebugModeType mode) { m_debug_drawer->setDebugMode(mode); } /** Returns true if the debug drawer is enabled. */ bool isDebug() const {return m_debug_drawer->debugEnabled(); } + IrrDebugDrawer* getDebugDrawer() { return m_debug_drawer; } virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifold,int numManifolds, btTypedConstraint** constraints,int numConstraints, From bdabbedf285c7573c3ce69192cf78913410687f7 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 19:31:30 -0400 Subject: [PATCH 31/69] fix silly mistake in previous commit --- src/graphics/render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index fef45da0d..7b65a1ff3 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -209,7 +209,7 @@ void IrrDriver::renderGLSL(float dt) { for (int i = 0; i < it->second.size(); i += 2) { - draw3DLine((const core::vector3df&)it->second[0], (const core::vector3df&)it->second[1], it->first); + draw3DLine((const core::vector3df&)it->second[i], (const core::vector3df&)it->second[i + 1], it->first); } } } From 4e9f19900842ba25e1baa2cdb7f43ffa9681d4f8 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 19:50:24 -0400 Subject: [PATCH 32/69] Save raw floats and not vectors --- src/graphics/render.cpp | 10 ++++++---- src/physics/irr_debug_drawer.cpp | 12 ++++++++---- src/physics/irr_debug_drawer.hpp | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 7b65a1ff3..ec3233e62 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -203,13 +203,15 @@ void IrrDriver::renderGLSL(float dt) IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); if (debug_drawer != NULL && debug_drawer->debugEnabled()) { - const std::map>& lines = debug_drawer->getLines(); - std::map>::const_iterator it; + const std::map>& lines = debug_drawer->getLines(); + std::map>::const_iterator it; for (it = lines.begin(); it != lines.end(); it++) { - for (int i = 0; i < it->second.size(); i += 2) + for (int i = 0; i < it->second.size(); i += 6) { - draw3DLine((const core::vector3df&)it->second[i], (const core::vector3df&)it->second[i + 1], it->first); + draw3DLine(core::vector3df(it->second[i], it->second[i + 1], it->second[i + 2]), + core::vector3df(it->second[i + 3], it->second[i + 4], it->second[i + 5]), + it->first); } } } diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index a6ec03460..7f8de560e 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -59,9 +59,13 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255), (int)(color.getZ()*255) ); - m_lines[c].push_back(from); - m_lines[c].push_back(to); - + std::vector& v = m_lines[c]; + v.push_back(from.getX()); + v.push_back(from.getY()); + v.push_back(from.getZ()); + v.push_back(to.getX()); + v.push_back(to.getY()); + v.push_back(to.getZ()); //draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c); } @@ -69,7 +73,7 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, void IrrDebugDrawer::beginNextFrame() { - for (std::map>::iterator it = m_lines.begin(); it != m_lines.end(); it++) + for (std::map>::iterator it = m_lines.begin(); it != m_lines.end(); it++) { it->second.clear(); } diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index 72a40932c..6788be86c 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -42,7 +42,7 @@ public: }; DebugModeType m_debug_mode; - std::map> m_lines; + std::map> m_lines; protected: virtual void setDebugMode(int debug_mode) {} @@ -73,7 +73,7 @@ public: void setDebugMode(DebugModeType mode); void beginNextFrame(); - const std::map>& getLines() const { return m_lines; } + const std::map>& getLines() const { return m_lines; } }; // IrrDebugDrawer #endif From b286069108f5b0f771f8fe382b78d16b38190ea7 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 01:59:59 +0200 Subject: [PATCH 33/69] Use batched draw call to draw lines. --- src/graphics/glwrap.cpp | 2 -- src/graphics/render.cpp | 21 ++++++++++++++++----- src/graphics/shaders.cpp | 3 +-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index d60215c25..4dfd2f2bc 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -541,8 +541,6 @@ void draw3DLine(const core::vector3df& start, glUseProgram(UtilShader::ColoredLine::Program); UtilShader::ColoredLine::setUniforms(color); glDrawArrays(GL_LINES, 0, 2); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); glGetError(); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index ec3233e62..69592b111 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -52,6 +52,9 @@ STKInstancedSceneNode *InstancedBox = 0; +#define MAX2(a, b) ((a) > (b) ? (a) : (b)) +#define MIN2(a, b) ((a) > (b) ? (b) : (a)) + void IrrDriver::renderGLSL(float dt) { World *world = World::getWorld(); // Never NULL. @@ -207,11 +210,20 @@ void IrrDriver::renderGLSL(float dt) std::map>::const_iterator it; for (it = lines.begin(); it != lines.end(); it++) { - for (int i = 0; i < it->second.size(); i += 6) + for (int i = 0; i < it->second.size(); i += 6 * 1024) { - draw3DLine(core::vector3df(it->second[i], it->second[i + 1], it->second[i + 2]), + unsigned count = MIN2(it->second.size() - i, 6 * 1024); + glBindVertexArray(UtilShader::ColoredLine::vao); + glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, count, &(it->second.data()[i])); + + glUseProgram(UtilShader::ColoredLine::Program); + UtilShader::ColoredLine::setUniforms(it->first); + glDrawArrays(GL_LINES, 0, count / 6); + +/* draw3DLine(core::vector3df(it->second[i], it->second[i + 1], it->second[i + 2]), core::vector3df(it->second[i + 3], it->second[i + 4], it->second[i + 5]), - it->first); + it->first);*/ } } } @@ -755,8 +767,7 @@ void IrrDriver::renderGlow(std::vector& glows) } // ---------------------------------------------------------------------------- -#define MAX2(a, b) ((a) > (b) ? (a) : (b)) -#define MIN2(a, b) ((a) > (b) ? (b) : (a)) + static LightShader::PointLightInfo PointLightsInfo[MAXLIGHT]; static void renderPointLights(unsigned count) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 4a3e9a126..d804c00c2 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -421,8 +421,7 @@ namespace UtilShader glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - float vertex[6] = {}; - glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertex, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, 6 * 1024, 0, GL_DYNAMIC_DRAW); GLuint attrib_position = glGetAttribLocation(Program, "Position"); glEnableVertexAttribArray(attrib_position); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); From 325ec8e754833b94db159a27203262bef7e44faf Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 02:13:04 +0200 Subject: [PATCH 34/69] Fix wrong buffer size and factorize state changes. --- src/graphics/render.cpp | 14 +++++++++----- src/graphics/shaders.cpp | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 69592b111..4b42bd5a9 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -208,24 +208,28 @@ void IrrDriver::renderGLSL(float dt) { const std::map>& lines = debug_drawer->getLines(); std::map>::const_iterator it; + + + glUseProgram(UtilShader::ColoredLine::Program); + glBindVertexArray(UtilShader::ColoredLine::vao); + glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); for (it = lines.begin(); it != lines.end(); it++) { + UtilShader::ColoredLine::setUniforms(it->first); for (int i = 0; i < it->second.size(); i += 6 * 1024) { unsigned count = MIN2(it->second.size() - i, 6 * 1024); - glBindVertexArray(UtilShader::ColoredLine::vao); - glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, count, &(it->second.data()[i])); - glUseProgram(UtilShader::ColoredLine::Program); - UtilShader::ColoredLine::setUniforms(it->first); - glDrawArrays(GL_LINES, 0, count / 6); + glDrawArrays(GL_LINES, 0, count / 3); /* draw3DLine(core::vector3df(it->second[i], it->second[i + 1], it->second[i + 2]), core::vector3df(it->second[i + 3], it->second[i + 4], it->second[i + 5]), it->first);*/ } } + glUseProgram(0); + glBindVertexArray(0); } } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d804c00c2..3288c97ff 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -421,7 +421,7 @@ namespace UtilShader glBindVertexArray(vao); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, 6 * 1024, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW); GLuint attrib_position = glGetAttribLocation(Program, "Position"); glEnableVertexAttribArray(attrib_position); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); From e16c6af04a67efc2768ea6f49636348a38ed039f Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 02:24:17 +0200 Subject: [PATCH 35/69] Forget a sizeof(float). --- src/graphics/render.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 4b42bd5a9..43fab1831 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -216,16 +216,14 @@ void IrrDriver::renderGLSL(float dt) for (it = lines.begin(); it != lines.end(); it++) { UtilShader::ColoredLine::setUniforms(it->first); - for (int i = 0; i < it->second.size(); i += 6 * 1024) + const std::vector &vertex = it->second; + const float *tmp = vertex.data(); + for (int i = 0; i < vertex.size(); i += 1024 * 6) { - unsigned count = MIN2(it->second.size() - i, 6 * 1024); - glBufferSubData(GL_ARRAY_BUFFER, 0, count, &(it->second.data()[i])); + unsigned count = MIN2(vertex.size() - i, 1024 * 6); + glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); glDrawArrays(GL_LINES, 0, count / 3); - -/* draw3DLine(core::vector3df(it->second[i], it->second[i + 1], it->second[i + 2]), - core::vector3df(it->second[i + 3], it->second[i + 4], it->second[i + 5]), - it->first);*/ } } glUseProgram(0); From fbd33420c23a27ef0a59583e9b19f2cc97e1e68f Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 20:38:10 -0400 Subject: [PATCH 36/69] cull by distance, to improve performance --- src/physics/irr_debug_drawer.cpp | 9 +++++++++ src/physics/irr_debug_drawer.hpp | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index 7f8de560e..f5b4c8009 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -22,7 +22,9 @@ #include "karts/abstract_kart.hpp" #include "modes/world.hpp" +#include #include +#include IrrDebugDrawer::IrrDebugDrawer() { @@ -59,6 +61,10 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255), (int)(color.getZ()*255) ); + //World::getWorld()->getCa + + if (from.distance2(m_camera_pos) > 10000) return; + std::vector& v = m_lines[c]; v.push_back(from.getX()); v.push_back(from.getY()); @@ -77,6 +83,9 @@ void IrrDebugDrawer::beginNextFrame() { it->second.clear(); } + + scene::ICameraSceneNode* camera = irr_driver->getSceneManager()->getActiveCamera(); + m_camera_pos = camera->getPosition(); } /* EOF */ diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index 6788be86c..daece183f 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -44,6 +44,8 @@ public: std::map> m_lines; + Vec3 m_camera_pos; + protected: virtual void setDebugMode(int debug_mode) {} /** Callback for bullet: if debug drawing should be done or not. From c0a7c76886c7fc3703262422e5248e40f2e0bf45 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 20:43:43 -0400 Subject: [PATCH 37/69] Fix pre-c++2011 build, hopefully --- src/graphics/render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 43fab1831..300ce02ae 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -206,7 +206,7 @@ void IrrDriver::renderGLSL(float dt) IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); if (debug_drawer != NULL && debug_drawer->debugEnabled()) { - const std::map>& lines = debug_drawer->getLines(); + const std::map >& lines = debug_drawer->getLines(); std::map>::const_iterator it; From 522ad01a2738fb6f128b73978a0cf5c8f69cfc9b Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 20:46:56 -0400 Subject: [PATCH 38/69] More to fix pre-c++2011 build --- src/physics/irr_debug_drawer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index daece183f..f106ea5da 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -42,7 +42,7 @@ public: }; DebugModeType m_debug_mode; - std::map> m_lines; + std::map > m_lines; Vec3 m_camera_pos; From 7808fc8a0944726cc036d107cd71ee429bd8a8e9 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 20:50:18 -0400 Subject: [PATCH 39/69] Yet another fix to pre-c++2011 compilation..... --- src/physics/irr_debug_drawer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics/irr_debug_drawer.hpp b/src/physics/irr_debug_drawer.hpp index f106ea5da..b384f12bd 100644 --- a/src/physics/irr_debug_drawer.hpp +++ b/src/physics/irr_debug_drawer.hpp @@ -75,7 +75,7 @@ public: void setDebugMode(DebugModeType mode); void beginNextFrame(); - const std::map>& getLines() const { return m_lines; } + const std::map >& getLines() const { return m_lines; } }; // IrrDebugDrawer #endif From 00ea15b7bbf5dc051c77f61b886f44bf0aedb031 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 10 May 2014 20:53:51 -0400 Subject: [PATCH 40/69] Yet another fix to pre-c++2011 compilation..... (not trying to raise my commit count, I swear!!) --- src/physics/irr_debug_drawer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics/irr_debug_drawer.cpp b/src/physics/irr_debug_drawer.cpp index f5b4c8009..f5fd5ce6f 100644 --- a/src/physics/irr_debug_drawer.cpp +++ b/src/physics/irr_debug_drawer.cpp @@ -79,7 +79,7 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to, void IrrDebugDrawer::beginNextFrame() { - for (std::map>::iterator it = m_lines.begin(); it != m_lines.end(); it++) + for (std::map >::iterator it = m_lines.begin(); it != m_lines.end(); it++) { it->second.clear(); } From 518a5fd8ef4855984f0f0770ed04620aaee3c744 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sun, 11 May 2014 02:58:23 +0200 Subject: [PATCH 41/69] Fix pre-c++2011 + improved waterfall effect --- data/gfx/waterfall.xml | 18 ++++++++++-------- src/graphics/render.cpp | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/data/gfx/waterfall.xml b/data/gfx/waterfall.xml index 244427d64..c08fec91e 100644 --- a/data/gfx/waterfall.xml +++ b/data/gfx/waterfall.xml @@ -1,5 +1,5 @@ - + @@ -10,21 +10,23 @@ - + - + - + - + diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 300ce02ae..a999748a2 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -207,7 +207,7 @@ void IrrDriver::renderGLSL(float dt) if (debug_drawer != NULL && debug_drawer->debugEnabled()) { const std::map >& lines = debug_drawer->getLines(); - std::map>::const_iterator it; + std::map >::const_iterator it; glUseProgram(UtilShader::ColoredLine::Program); From e5410e23a2c92cacbd7060f7371f4c6f3acd18f8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 18:00:30 +0200 Subject: [PATCH 42/69] Use Alchemy SSAO --- data/shaders/ssao.frag | 79 ++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 110b0b51d..6179cb46c 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,3 +1,5 @@ +// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ + uniform sampler2D ntex; uniform sampler2D dtex; uniform sampler2D noise_texture; @@ -22,57 +24,60 @@ layout (std140) uniform MatrixesData in vec2 uv; out float AO; -const float strengh = 5.; -const float radius = 1.f; +const float sigma = 1.; +const float beta = 0.0001; +const float epsilon = .00001; +const float radius = .1; +const float k = 1.; #define SAMPLES 16 -const float invSamples = strengh / SAMPLES; - -vec3 rand(vec2 co) -{ - float noiseX = clamp(fract(sin(dot(co ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0; - float noiseY = clamp(fract(sin(dot(co ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0; - return vec3(noiseX, noiseY, length(texture(noise_texture, co * pow(3.14159265359, 2.)).xyz)); -} +const float invSamples = 1. / SAMPLES; vec3 DecodeNormal(vec2 n); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); +vec3 rand(vec2 co) +{ + float noiseX = clamp(fract(sin(dot(co ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0; + float noiseY = clamp(fract(sin(dot(co ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0; + return vec3(noiseX, noiseY, length(texture(noise_texture, co * pow(3.14159265359, 2.)).xyz)); +} + void main(void) { - vec4 cur = texture(ntex, uv); - float curdepth = texture(dtex, uv).x; + vec4 cur = texture(ntex, uv); + float curdepth = texture(dtex, uv).x; vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix); + if (FragPos.z < 0.) discard; - // get the normal of current fragment - vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); - // Workaround for nvidia and skyboxes - float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2 || curdepth > 0.9955) discard; - // Make a tangent as random as possible - vec3 randvect = rand(uv); - vec3 tangent = normalize(cross(norm, randvect)); - vec3 bitangent = cross(norm, tangent); + // get the normal of current fragment + vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + // Workaround for nvidia and skyboxes + float len = dot(vec3(1.0), abs(cur.xyz)); + if (len < 0.2 || curdepth > 0.9955) discard; - float bl = 0.0; + float randAngle = rand(uv).x; + vec2 Xaxis = vec2(cos(randAngle), sin(randAngle)); + Xaxis = normalize(Xaxis); + vec2 Yaxis = vec2(sin(randAngle), -cos(randAngle)); + Yaxis = normalize(Yaxis); - for(int i = 0; i < SAMPLES; ++i) { - vec3 sampleDir = samplePoints[i].x * tangent + samplePoints[i].y * bitangent + samplePoints[i].z * norm; - sampleDir *= samplePoints[i].w; - vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0); - vec4 sampleProj = ProjectionMatrix * samplePos; - sampleProj /= sampleProj.w; + float bl = 0.0; - bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); - // get the depth of the occluder fragment - float occluderFragmentDepth = texture(dtex, (sampleProj.xy * 0.5) + 0.5).x; - // Position of the occluder fragment in worldSpace - vec4 occluderPos = getPosFromUVDepth(vec3((sampleProj.xy * 0.5) + 0.5, occluderFragmentDepth), InverseProjectionMatrix); + for(int i = 0; i < SAMPLES; ++i) { + vec2 occluder_uv = samplePoints[i].x * Xaxis + samplePoints[i].y * Yaxis; + occluder_uv *= samplePoints[i].w * radius; + occluder_uv += uv; - bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); - bl += isOccluded ? samplePoints[i].z * smoothstep(5 * radius, 0, distance(samplePos, FragPos)) : 0.; - } + if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - AO = max(1.0 - bl * invSamples, 0.); + float occluderFragmentDepth = texture(dtex, occluder_uv).x; + vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); + + vec3 vi = (OccluderPos - FragPos).xyz; + bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon); + } + + AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.); } From 567974aeeda16d122605c24ce7376de733c8e968 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 18:09:48 +0200 Subject: [PATCH 43/69] Use dFdX/dFdY to compute normals in SSAO. --- data/shaders/ssao.frag | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 6179cb46c..9de77dd6b 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,4 +1,5 @@ // From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ +// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/ uniform sampler2D ntex; uniform sampler2D dtex; @@ -49,10 +50,11 @@ void main(void) vec4 cur = texture(ntex, uv); float curdepth = texture(dtex, uv).x; vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix); - if (FragPos.z < 0.) discard; // get the normal of current fragment - vec3 norm = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + vec3 ddx = dFdx(FragPos.xyz); + vec3 ddy = dFdy(FragPos.xyz); + vec3 norm = normalize(cross(ddy, ddx)); // Workaround for nvidia and skyboxes float len = dot(vec3(1.0), abs(cur.xyz)); if (len < 0.2 || curdepth > 0.9955) discard; From 41e02e08802dee06ab58104995703b4ec3696250 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 11 May 2014 18:20:30 +0200 Subject: [PATCH 44/69] Allow depth test on debug physic view --- src/graphics/render.cpp | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index a999748a2..22461f236 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -146,6 +146,43 @@ void IrrDriver::renderGLSL(float dt) renderScene(camnode, glows, dt, track->hasShadows()); + // Debug physic + // Note that drawAll must be called before rendering + // the bullet debug view, since otherwise the camera + // is not set up properly. This is only used for + // the bullet debug view. + if (UserConfigParams::m_artist_debug_mode) + World::getWorld()->getPhysics()->draw(); + if (world != NULL && world->getPhysics() != NULL) + { + IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); + if (debug_drawer != NULL && debug_drawer->debugEnabled()) + { + const std::map >& lines = debug_drawer->getLines(); + std::map >::const_iterator it; + + + glUseProgram(UtilShader::ColoredLine::Program); + glBindVertexArray(UtilShader::ColoredLine::vao); + glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); + for (it = lines.begin(); it != lines.end(); it++) + { + UtilShader::ColoredLine::setUniforms(it->first); + const std::vector &vertex = it->second; + const float *tmp = vertex.data(); + for (int i = 0; i < vertex.size(); i += 1024 * 6) + { + unsigned count = MIN2(vertex.size() - i, 1024 * 6); + glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); + + glDrawArrays(GL_LINES, 0, count / 3); + } + } + glUseProgram(0); + glBindVertexArray(0); + } + } + // Render the post-processed scene if (UserConfigParams::m_dynamic_lights) m_post_processing->render(camnode); @@ -153,13 +190,6 @@ void IrrDriver::renderGLSL(float dt) glDisable(GL_FRAMEBUFFER_SRGB); PROFILER_POP_CPU_MARKER(); - - // Note that drawAll must be called before rendering - // the bullet debug view, since otherwise the camera - // is not set up properly. This is only used for - // the bullet debug view. - if (UserConfigParams::m_artist_debug_mode) - World::getWorld()->getPhysics()->draw(); } // for igetNumKarts() glBindVertexArray(0); @@ -201,36 +231,6 @@ void IrrDriver::renderGLSL(float dt) #endif - if (world != NULL && world->getPhysics() != NULL) - { - IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer(); - if (debug_drawer != NULL && debug_drawer->debugEnabled()) - { - const std::map >& lines = debug_drawer->getLines(); - std::map >::const_iterator it; - - - glUseProgram(UtilShader::ColoredLine::Program); - glBindVertexArray(UtilShader::ColoredLine::vao); - glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo); - for (it = lines.begin(); it != lines.end(); it++) - { - UtilShader::ColoredLine::setUniforms(it->first); - const std::vector &vertex = it->second; - const float *tmp = vertex.data(); - for (int i = 0; i < vertex.size(); i += 1024 * 6) - { - unsigned count = MIN2(vertex.size() - i, 1024 * 6); - glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]); - - glDrawArrays(GL_LINES, 0, count / 3); - } - } - glUseProgram(0); - glBindVertexArray(0); - } - } - PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45); m_video_driver->endScene(); PROFILER_POP_CPU_MARKER(); From 11b7d20ad86161e85cb943d8fd208962dd40facf Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 00:03:42 +0200 Subject: [PATCH 45/69] Use the mipmap trick to speed up ssao. --- data/shaders/ssao.frag | 29 ++++++++++++----------------- src/graphics/post_processing.cpp | 8 ++++---- src/graphics/shaders.cpp | 3 +-- src/graphics/shaders.hpp | 2 +- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 9de77dd6b..7d5672396 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -26,9 +26,10 @@ in vec2 uv; out float AO; const float sigma = 1.; +const float tau = 7.; const float beta = 0.0001; const float epsilon = .00001; -const float radius = .1; +const float radius = 1.; const float k = 1.; #define SAMPLES 16 @@ -38,13 +39,6 @@ const float invSamples = 1. / SAMPLES; vec3 DecodeNormal(vec2 n); vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); -vec3 rand(vec2 co) -{ - float noiseX = clamp(fract(sin(dot(co ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0; - float noiseY = clamp(fract(sin(dot(co ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0; - return vec3(noiseX, noiseY, length(texture(noise_texture, co * pow(3.14159265359, 2.)).xyz)); -} - void main(void) { vec4 cur = texture(ntex, uv); @@ -59,22 +53,23 @@ void main(void) float len = dot(vec3(1.0), abs(cur.xyz)); if (len < 0.2 || curdepth > 0.9955) discard; - float randAngle = rand(uv).x; - vec2 Xaxis = vec2(cos(randAngle), sin(randAngle)); - Xaxis = normalize(Xaxis); - vec2 Yaxis = vec2(sin(randAngle), -cos(randAngle)); - Yaxis = normalize(Yaxis); - + int x = int(1024. * uv.x), y = int(1024. * uv.y); + float r = radius / FragPos.z; + float phi = 30. * (x ^ y) + 10. * x * y; float bl = 0.0; for(int i = 0; i < SAMPLES; ++i) { - vec2 occluder_uv = samplePoints[i].x * Xaxis + samplePoints[i].y * Yaxis; - occluder_uv *= samplePoints[i].w * radius; + float alpha = (i + .5) * invSamples; + float theta = 2. * 3.14 * tau * alpha + phi; + float h = r * alpha; + vec2 occluder_uv = h * vec2(cos(theta), sin(theta)); occluder_uv += uv; if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - float occluderFragmentDepth = texture(dtex, occluder_uv).x; + float m = round(log2(h) + 3.); + + float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); vec3 vi = (OccluderPos - FragPos).xyz; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 68ac865b0..8b4d3c61e 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -423,11 +423,11 @@ void PostProcessing::renderSSAO() glUseProgram(FullScreenShader::SSAOShader::Program); glBindVertexArray(FullScreenShader::SSAOShader::vao); - setTexture(0, irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), GL_LINEAR, GL_LINEAR); - setTexture(1, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR); - setTexture(2, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); + setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); - FullScreenShader::SSAOShader::setUniforms(0, 1, 2); + FullScreenShader::SSAOShader::setUniforms(0, 1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 3288c97ff..003eef762 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -2624,13 +2624,12 @@ namespace FullScreenShader }*/ } - void SSAOShader::setUniforms(unsigned TU_ntex, unsigned TU_dtex, unsigned TU_noise) + void SSAOShader::setUniforms(unsigned TU_dtex, unsigned TU_noise) { if (UserConfigParams::m_ubo_disabled) bypassUBO(Program); glUniform4fv(FullScreenShader::SSAOShader::uniform_samplePoints, 16, FullScreenShader::SSAOShader::SSAOSamples); - glUniform1i(FullScreenShader::SSAOShader::uniform_ntex, TU_ntex); glUniform1i(FullScreenShader::SSAOShader::uniform_dtex, TU_dtex); glUniform1i(FullScreenShader::SSAOShader::uniform_noise_texture, TU_noise); } diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 7efc11f4c..68fd37e4a 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -712,7 +712,7 @@ public: static float SSAOSamples[64]; static void init(); - static void setUniforms(unsigned TU_ntex, unsigned TU_dtex, unsigned TU_noise); + static void setUniforms(unsigned TU_dtex, unsigned TU_noise); }; class FogShader From f8544493b68c1b97ea59160fa1c96836b4eb1170 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 00:14:50 +0200 Subject: [PATCH 46/69] Improve SSAO perf --- data/shaders/ssao.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 7d5672396..9dac85bff 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -67,7 +67,7 @@ void main(void) if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - float m = round(log2(h) + 3.); + float m = round(log2(h)) + 7.; float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); From 7e1625da5e12b2a2953e6fd162790e9dd85845ff Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 00:30:36 +0200 Subject: [PATCH 47/69] Tweak SSAO params. --- data/shaders/ssao.frag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 9dac85bff..9bf6022a6 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -29,8 +29,8 @@ const float sigma = 1.; const float tau = 7.; const float beta = 0.0001; const float epsilon = .00001; -const float radius = 1.; -const float k = 1.; +const float radius = 2.; +const float k = 1.5; #define SAMPLES 16 @@ -67,7 +67,7 @@ void main(void) if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - float m = round(log2(h)) + 7.; + float m = round(log2(h)) + 6.; float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); From 4fcec02123e6efec078599988f21d86208b9c195 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 00:34:44 +0200 Subject: [PATCH 48/69] Remove ssao depth guard. --- data/shaders/ssao.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 9bf6022a6..837c46550 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -51,7 +51,7 @@ void main(void) vec3 norm = normalize(cross(ddy, ddx)); // Workaround for nvidia and skyboxes float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2 || curdepth > 0.9955) discard; + if (len < 0.2) discard; int x = int(1024. * uv.x), y = int(1024. * uv.y); float r = radius / FragPos.z; From 229b72f84a884433d6011102457c0ea082129f29 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 01:06:33 +0200 Subject: [PATCH 49/69] Render SSAO at fullscreen resolution. --- data/shaders/ssao.frag | 2 +- src/graphics/render.cpp | 4 ++-- src/graphics/rtts.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 837c46550..78de29b94 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -67,7 +67,7 @@ void main(void) if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - float m = round(log2(h)) + 6.; + float m = round(log2(h)) + 7.; float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 22461f236..5a0a57f2e 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -892,11 +892,11 @@ void IrrDriver::renderSSAO() glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO)); glClearColor(1., 1., 1., 1.); glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); + glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); m_post_processing->renderSSAO(); // Blur it to reduce noise. m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), - irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2); + irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 775c911eb..fd14fb5fe 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -86,7 +86,7 @@ RTT::RTT() RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT); RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE); - RenderTargetTextures[RTT_SSAO] = generateRTT(half, GL_R16F, GL_RED, GL_FLOAT); + RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT); RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_HALF1] = generateRTT(half, GL_RGBA16F, GL_BGRA, GL_FLOAT); From 23ba597a1c61017507a630ec42364bec2acd94b1 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 18:39:33 +0200 Subject: [PATCH 50/69] SSAO: Use int rounding --- data/shaders/ssao.frag | 164 +++++++++++++++++++++-------------------- 1 file changed, 84 insertions(+), 80 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 78de29b94..c093802bb 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,80 +1,84 @@ -// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ -// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/ - -uniform sampler2D ntex; -uniform sampler2D dtex; -uniform sampler2D noise_texture; -uniform vec4 samplePoints[16]; - -#ifdef UBO_DISABLED -uniform mat4 ViewMatrix; -uniform mat4 ProjectionMatrix; -uniform mat4 InverseViewMatrix; -uniform mat4 InverseProjectionMatrix; -#else -layout (std140) uniform MatrixesData -{ - mat4 ViewMatrix; - mat4 ProjectionMatrix; - mat4 InverseViewMatrix; - mat4 InverseProjectionMatrix; - mat4 ShadowViewProjMatrixes[4]; -}; -#endif - -in vec2 uv; -out float AO; - -const float sigma = 1.; -const float tau = 7.; -const float beta = 0.0001; -const float epsilon = .00001; -const float radius = 2.; -const float k = 1.5; - -#define SAMPLES 16 - -const float invSamples = 1. / SAMPLES; - -vec3 DecodeNormal(vec2 n); -vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); - -void main(void) -{ - vec4 cur = texture(ntex, uv); - float curdepth = texture(dtex, uv).x; - vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix); - - // get the normal of current fragment - vec3 ddx = dFdx(FragPos.xyz); - vec3 ddy = dFdy(FragPos.xyz); - vec3 norm = normalize(cross(ddy, ddx)); - // Workaround for nvidia and skyboxes - float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2) discard; - - int x = int(1024. * uv.x), y = int(1024. * uv.y); - float r = radius / FragPos.z; - float phi = 30. * (x ^ y) + 10. * x * y; - float bl = 0.0; - - for(int i = 0; i < SAMPLES; ++i) { - float alpha = (i + .5) * invSamples; - float theta = 2. * 3.14 * tau * alpha + phi; - float h = r * alpha; - vec2 occluder_uv = h * vec2(cos(theta), sin(theta)); - occluder_uv += uv; - - if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; - - float m = round(log2(h)) + 7.; - - float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; - vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); - - vec3 vi = (OccluderPos - FragPos).xyz; - bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon); - } - - AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.); -} +// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ +// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/ + +uniform sampler2D ntex; +uniform sampler2D dtex; +uniform sampler2D noise_texture; +uniform vec4 samplePoints[16]; +uniform vec2 screen = vec2(1680, 1050); + +#ifdef UBO_DISABLED +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; +uniform mat4 InverseViewMatrix; +uniform mat4 InverseProjectionMatrix; +#else +layout (std140) uniform MatrixesData +{ + mat4 ViewMatrix; + mat4 ProjectionMatrix; + mat4 InverseViewMatrix; + mat4 InverseProjectionMatrix; + mat4 ShadowViewProjMatrixes[4]; +}; +#endif + +in vec2 uv; +out float AO; + +const float sigma = 1.; +const float tau = 2.; +const float beta = 0.0001; +const float epsilon = .00001; +const float radius = 1.; +const float k = 1.; + +#define SAMPLES 16 + +const float invSamples = 1. / SAMPLES; + +vec3 DecodeNormal(vec2 n); +vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); + +void main(void) +{ + vec4 cur = texture(ntex, uv); + float curdepth = texture(dtex, uv).x; + vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix); + + // get the normal of current fragment + vec3 ddx = dFdx(FragPos.xyz); + vec3 ddy = dFdy(FragPos.xyz); + vec3 norm = normalize(cross(ddy, ddx)); + // Workaround for nvidia and skyboxes + float len = dot(vec3(1.0), abs(cur.xyz)); + if (len < 0.2) discard; + + int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y); + float r = radius / FragPos.z; + float phi = 30. * (x ^ y) + 10. * x * y; + float bl = 0.0; + + for(int i = 0; i < SAMPLES; ++i) { + float alpha = (i + .5) * invSamples; + float theta = 2. * 3.14 * tau * alpha + phi; + float h = r * alpha; + vec2 occluder_uv = h * vec2(cos(theta), sin(theta)) * screen; + occluder_uv += gl_FragCoord.xy; + + float m = round(log2(h)) + 7; + ivec2 ioccluder_uv = ivec2(occluder_uv); + occluder_uv = (ioccluder_uv >> int(m)) << int(m); + occluder_uv /= screen; + + if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; + + float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; + vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); + + vec3 vi = (OccluderPos - FragPos).xyz; + bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon); + } + + AO = max(pow(1.0 - 2. * sigma * bl * invSamples, k), 0.); +} \ No newline at end of file From e8b4926b0b528652b378ec9c4d6ffa742fd4309a Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 12 May 2014 18:31:43 +0200 Subject: [PATCH 51/69] Fixed #1313. In some cases STK was barely playable because of very low refresh rates (25-30Hz). This may be caused by last changes in display drivers. I remember that previously refresh rates for resolution were in order from the lowest to the greatest. Now I see it in reversed order. Irrlicht didn't check refresh rates and always set the last available for specified resolution. Now we use the highest available refresh rate. Perhaps we should use xrandr library instead of vidmode. It should be much smarter and maybe would solve some multimonitor issues. --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index e9877a3e3..95bd6095e 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -264,6 +264,7 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset) // enumerate video modes s32 modeCount; XF86VidModeModeInfo** modes; + float refresh_rate; XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); @@ -271,13 +272,37 @@ bool CIrrDeviceLinux::switchToFullscreen(bool reset) for (s32 i = 0; ihdisplay >= Width && modes[i]->vdisplay >= Height) + { + float pixels_per_second = modes[i]->dotclock * 1000.0; + float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal; + refresh_rate = pixels_per_second / pixels_per_frame; bestMode = i; + } + else if (bestMode!=-1 && + modes[i]->hdisplay == modes[bestMode]->hdisplay && + modes[i]->vdisplay == modes[bestMode]->vdisplay) + { + float pixels_per_second = modes[i]->dotclock * 1000.0; + float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal; + float refresh_rate_tmp = pixels_per_second / pixels_per_frame; + + if (refresh_rate_tmp > refresh_rate) + { + refresh_rate = refresh_rate_tmp; + bestMode = i; + } + } else if (bestMode!=-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height && modes[i]->hdisplay <= modes[bestMode]->hdisplay && modes[i]->vdisplay <= modes[bestMode]->vdisplay) + { + float pixels_per_second = modes[i]->dotclock * 1000.0; + float pixels_per_frame = modes[i]->htotal * modes[i]->vtotal; + refresh_rate = pixels_per_second / pixels_per_frame; bestMode = i; + } } if (bestMode != -1) { From 96babc81ad8d15404ae225ee00b4442079f35f1d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 12 May 2014 19:36:45 +0200 Subject: [PATCH 52/69] Reenable custom light radius --- data/shaders/pointlight.frag | 4 ++-- data/shaders/pointlight.vert | 8 +++++--- src/graphics/render.cpp | 5 ++++- src/graphics/shaders.cpp | 5 +++++ src/graphics/shaders.hpp | 4 ++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 23f9e7f17..54704c5f0 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -22,6 +22,7 @@ layout (std140) uniform MatrixesData flat in vec3 center; flat in float energy; flat in vec3 col; +flat in float radius; out vec4 Diffuse; out vec4 Specular; @@ -46,8 +47,7 @@ void main() vec3 light_col = col.xyz; float d = distance(light_pos, xpos.xyz); float att = energy * 20. / (1. + d * d); - float max_d = 5. * energy; - att *= (max_d - d) / max_d; + att *= (radius - d) / radius; if (att <= 0.) discard; // Light Direction diff --git a/data/shaders/pointlight.vert b/data/shaders/pointlight.vert index 8736831e5..6a8b9c683 100644 --- a/data/shaders/pointlight.vert +++ b/data/shaders/pointlight.vert @@ -17,10 +17,12 @@ layout (std140) uniform MatrixesData in vec3 Position; in float Energy; in vec3 Color; +in float Radius; flat out vec3 center; flat out float energy; flat out vec3 col; +flat out float radius; const float zNear = 1.; @@ -86,12 +88,11 @@ vec4 ComputeClipRegion(vec3 lightPosView, float lightRadius) void main(void) { - float radius = 5. * Energy; vec4 Center = ViewMatrix * vec4(Position, 1.); Center /= Center.w; vec2 ProjectedCornerPosition; - vec4 clip = ComputeClipRegion(Center.xyz, radius); + vec4 clip = ComputeClipRegion(Center.xyz, Radius); switch (gl_VertexID) { case 0: @@ -110,7 +111,7 @@ void main(void) // Work out nearest depth for quad Z // Clamp to near plane in case this light intersects the near plane... don't want our quad to be clipped - float quadDepth = max(zNear, Center.z - radius); + float quadDepth = max(zNear, Center.z - Radius); // Project quad depth into clip space vec4 quadClip = ProjectionMatrix * vec4(0., 0., quadDepth, 1.0f); @@ -119,4 +120,5 @@ void main(void) col = Color; center = Position; energy = Energy; + radius = Radius; } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 5a0a57f2e..8255a10f0 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -789,7 +789,7 @@ static void renderPointLights(unsigned count) setTexture(1, irr_driver->getDepthStencilTexture(), GL_NEAREST, GL_NEAREST); LightShader::PointLightShader ::setUniforms(core::vector2df(float(UserConfigParams::m_width), - float(UserConfigParams::m_height) ), + float(UserConfigParams::m_height) ), 200, 0, 1); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); @@ -870,6 +870,9 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt) PointLightsInfo[lightnum].red = col.X; PointLightsInfo[lightnum].green = col.Y; PointLightsInfo[lightnum].blue = col.Z; + + // Light radius + PointLightsInfo[lightnum].radius = 20 * light_node->getEffectiveEnergy(); } } if (lightnum > MAXLIGHT) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 003eef762..07575a2b8 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1825,6 +1825,7 @@ namespace LightShader GLuint PointLightShader::attrib_Position; GLuint PointLightShader::attrib_Color; GLuint PointLightShader::attrib_Energy; + GLuint PointLightShader::attrib_Radius; GLuint PointLightShader::uniform_ntex; GLuint PointLightShader::uniform_dtex; GLuint PointLightShader::uniform_spec; @@ -1843,6 +1844,7 @@ namespace LightShader attrib_Position = glGetAttribLocation(Program, "Position"); attrib_Color = glGetAttribLocation(Program, "Color"); attrib_Energy = glGetAttribLocation(Program, "Energy"); + attrib_Radius = glGetAttribLocation(Program, "Radius"); uniform_ntex = glGetUniformLocation(Program, "ntex"); uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_spec = glGetUniformLocation(Program, "spec"); @@ -1861,10 +1863,13 @@ namespace LightShader glVertexAttribPointer(attrib_Energy, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(3 * sizeof(float))); glEnableVertexAttribArray(attrib_Color); glVertexAttribPointer(attrib_Color, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(4 * sizeof(float))); + glEnableVertexAttribArray(attrib_Radius); + glVertexAttribPointer(attrib_Radius, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(7 * sizeof(float))); glVertexAttribDivisor(attrib_Position, 1); glVertexAttribDivisor(attrib_Energy, 1); glVertexAttribDivisor(attrib_Color, 1); + glVertexAttribDivisor(attrib_Radius, 1); } void PointLightShader::setUniforms(const core::vector2df &screen, unsigned spec, unsigned TU_ntex, unsigned TU_dtex) diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 68fd37e4a..aee792bd9 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -440,7 +440,7 @@ namespace LightShader float red; float green; float blue; - float padding; + float radius; }; @@ -448,7 +448,7 @@ namespace LightShader { public: static GLuint Program; - static GLuint attrib_Position, attrib_Energy, attrib_Color; + static GLuint attrib_Position, attrib_Energy, attrib_Color, attrib_Radius; static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen; static GLuint vbo; static GLuint vao; From 0b463f5222e07906e287e756d6cf86f3e82aa245 Mon Sep 17 00:00:00 2001 From: Deve Date: Mon, 12 May 2014 20:06:44 +0200 Subject: [PATCH 53/69] Allow to run xrandr instead of vidmode as an option --- CMakeLists.txt | 11 +++++++++++ cmake/FindXrandr.cmake | 18 ++++++++++++++++++ lib/irrlicht/CMakeLists.txt | 6 ++++++ 3 files changed, 35 insertions(+) create mode 100644 cmake/FindXrandr.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ba13be3fa..0e8c53b52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON) if(UNIX) option(USE_CPP2011 "Activate C++ 2011 mode (GCC only)" OFF) + option(USE_XRANDR "Use xrandr instead of vidmode" OFF) endif() if(MSVC) # Normally hide the option to build wiiuse on VS, since it depends @@ -117,6 +118,11 @@ if(USE_FRIBIDI) endif() endif() +# Xrandr +if(UNIX AND USE_XRANDR) + find_package(Xrandr REQUIRED) +endif() + if(UNIX) if(USE_CPP2011) add_definitions("-std=c++0x") @@ -278,6 +284,11 @@ if(USE_WIIUSE) endif() +# Xrandr +if(UNIX AND USE_XRANDR) + target_link_libraries(supertuxkart ${XRANDR_LIBRARIES}) +endif() + if(MSVC) target_link_libraries(supertuxkart iphlpapi.lib) add_custom_command(TARGET supertuxkart POST_BUILD diff --git a/cmake/FindXrandr.cmake b/cmake/FindXrandr.cmake new file mode 100644 index 000000000..820f82be7 --- /dev/null +++ b/cmake/FindXrandr.cmake @@ -0,0 +1,18 @@ +find_path(XRANDR_INCLUDE_DIR NAMES X11/extensions/Xrandr.h + PATH_SUFFIXES X11/extensions + DOC "The XRANDR include directory" +) + +find_library(XRANDR_LIBRARY NAMES Xrandr + DOC "The XRANDR library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XRANDR DEFAULT_MSG XRANDR_LIBRARY XRANDR_INCLUDE_DIR) + +if(XRANDR_FOUND) + set( XRANDR_LIBRARIES ${XRANDR_LIBRARY} ) + set( XRANDR_INCLUDE_DIRS ${XRANDR_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XRANDR_INCLUDE_DIR XRANDR_LIBRARY) diff --git a/lib/irrlicht/CMakeLists.txt b/lib/irrlicht/CMakeLists.txt index e1200309d..17b96e62e 100644 --- a/lib/irrlicht/CMakeLists.txt +++ b/lib/irrlicht/CMakeLists.txt @@ -21,6 +21,12 @@ else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include") endif() +# Xrandr +if(UNIX AND USE_XRANDR) + add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_) + add_definitions(-D_IRR_LINUX_X11_RANDR_) +endif() + set(IRRLICHT_SOURCES source/Irrlicht/CTRStencilShadow.cpp source/Irrlicht/CGUIListBox.cpp From 8e17ae90b6644f4b15b37da96898918556276544 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 20:12:59 +0200 Subject: [PATCH 54/69] Resolution independent ssao --- data/shaders/ssao.frag | 2 +- src/graphics/post_processing.cpp | 2 +- src/graphics/shaders.cpp | 11 +++++++---- src/graphics/shaders.hpp | 4 ++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index c093802bb..7693590e9 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -5,7 +5,7 @@ uniform sampler2D ntex; uniform sampler2D dtex; uniform sampler2D noise_texture; uniform vec4 samplePoints[16]; -uniform vec2 screen = vec2(1680, 1050); +uniform vec2 screen; #ifdef UBO_DISABLED uniform mat4 ViewMatrix; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 8b4d3c61e..fa285556e 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -427,7 +427,7 @@ void PostProcessing::renderSSAO() glGenerateMipmap(GL_TEXTURE_2D); setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); - FullScreenShader::SSAOShader::setUniforms(0, 1); + FullScreenShader::SSAOShader::setUniforms(core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 07575a2b8..84c736232 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -2497,6 +2497,7 @@ namespace FullScreenShader GLuint SSAOShader::uniform_dtex; GLuint SSAOShader::uniform_noise_texture; GLuint SSAOShader::uniform_samplePoints; + GLuint SSAOShader::uniform_screen; GLuint SSAOShader::vao; float SSAOShader::SSAOSamples[64]; @@ -2511,6 +2512,7 @@ namespace FullScreenShader uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_noise_texture = glGetUniformLocation(Program, "noise_texture"); uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); + uniform_screen = glGetUniformLocation(Program, "screen"); vao = createVAO(Program); GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); @@ -2629,14 +2631,15 @@ namespace FullScreenShader }*/ } - void SSAOShader::setUniforms(unsigned TU_dtex, unsigned TU_noise) + void SSAOShader::setUniforms(const core::vector2df &screen, unsigned TU_dtex, unsigned TU_noise) { if (UserConfigParams::m_ubo_disabled) bypassUBO(Program); - glUniform4fv(FullScreenShader::SSAOShader::uniform_samplePoints, 16, FullScreenShader::SSAOShader::SSAOSamples); + glUniform4fv(uniform_samplePoints, 16, SSAOSamples); + glUniform2f(uniform_screen, screen.X, screen.Y); - glUniform1i(FullScreenShader::SSAOShader::uniform_dtex, TU_dtex); - glUniform1i(FullScreenShader::SSAOShader::uniform_noise_texture, TU_noise); + glUniform1i(uniform_dtex, TU_dtex); + glUniform1i(uniform_noise_texture, TU_noise); } GLuint FogShader::Program; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index aee792bd9..36f74a430 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -707,12 +707,12 @@ class SSAOShader { public: static GLuint Program; - static GLuint uniform_ntex, uniform_dtex, uniform_noise_texture, uniform_samplePoints; + static GLuint uniform_ntex, uniform_dtex, uniform_noise_texture, uniform_samplePoints, uniform_screen; static GLuint vao; static float SSAOSamples[64]; static void init(); - static void setUniforms(unsigned TU_dtex, unsigned TU_noise); + static void setUniforms(const core::vector2df &screen, unsigned TU_dtex, unsigned TU_noise); }; class FogShader From 967d7a0316ecefb695e98173b1294913ec705687 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 20:16:37 +0200 Subject: [PATCH 55/69] Use mipmap nearest --- src/graphics/post_processing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index fa285556e..4b1a7b076 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -423,7 +423,7 @@ void PostProcessing::renderSSAO() glUseProgram(FullScreenShader::SSAOShader::Program); glBindVertexArray(FullScreenShader::SSAOShader::vao); - setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); + setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST); glGenerateMipmap(GL_TEXTURE_2D); setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); From bba9e3ca2c05f8cfcc2a82e4a065e7e06d046e28 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 20:49:47 +0200 Subject: [PATCH 56/69] Add a 17 tap blur filter and use it for SSAO --- data/shaders/gaussian17taph.frag | 38 ++++++++++++++++++++++++++++++++ data/shaders/gaussian17tapv.frag | 38 ++++++++++++++++++++++++++++++++ src/graphics/post_processing.cpp | 33 +++++++++++++++++++++++++++ src/graphics/post_processing.hpp | 1 + src/graphics/render.cpp | 2 +- src/graphics/shaders.cpp | 30 +++++++++++++++++++++++++ src/graphics/shaders.hpp | 20 +++++++++++++++++ 7 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 data/shaders/gaussian17taph.frag create mode 100644 data/shaders/gaussian17tapv.frag diff --git a/data/shaders/gaussian17taph.frag b/data/shaders/gaussian17taph.frag new file mode 100644 index 000000000..874d22a7f --- /dev/null +++ b/data/shaders/gaussian17taph.frag @@ -0,0 +1,38 @@ +// From http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + +uniform sampler2D tex; +uniform vec2 pixel; + + +in vec2 uv; +out vec4 FragColor; + +void main() +{ + + float X = uv.x; + float Y = uv.y; + + float offset[5] = { + 0., + 1.41176470588235, + 3.29411764705882, + 5.17647058823529, + 7.05882352941176 + }; + float weight[5] = { + 0.196380615234375, + 0.1888427734375, + 0.03631591796875, + 0.0020751953125, + 0.000015258789062 + }; + + vec4 sum = texture(tex, vec2(X, Y)) * weight[0]; + for (int i = 1; i < 5; i++) { + sum += texture(tex, vec2(X - offset[i] * pixel.x, Y)) * weight[i]; + sum += texture(tex, vec2(X + offset[i] * pixel.x, Y)) * weight[i]; + } + + FragColor = sum; +} diff --git a/data/shaders/gaussian17tapv.frag b/data/shaders/gaussian17tapv.frag new file mode 100644 index 000000000..00de4c4aa --- /dev/null +++ b/data/shaders/gaussian17tapv.frag @@ -0,0 +1,38 @@ +// From http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + +uniform sampler2D tex; +uniform vec2 pixel; + + +in vec2 uv; +out vec4 FragColor; + +void main() +{ + + float X = uv.x; + float Y = uv.y; + + float offset[5] = { + 0., + 1.41176470588235, + 3.29411764705882, + 5.17647058823529, + 7.05882352941176 + }; + float weight[5] = { + 0.196380615234375, + 0.1888427734375, + 0.03631591796875, + 0.0020751953125, + 0.000015258789062 + }; + + vec4 sum = texture(tex, vec2(X, Y)) * weight[0]; + for (int i = 1; i < 5; i++) { + sum += texture(tex, vec2(X, Y - offset[i] * pixel.y)) * weight[i]; + sum += texture(tex, vec2(X, Y + offset[i] * pixel.y)) * weight[i]; + } + + FragColor = sum; +} diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 4b1a7b076..354340e91 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -383,6 +383,39 @@ void PostProcessing::renderGaussian6Blur(GLuint in_fbo, GLuint in_tex, GLuint tm } } +void PostProcessing::renderGaussian17TapBlur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height) +{ + float inv_width = 1.f / width, inv_height = 1.f / height; + { + glBindFramebuffer(GL_FRAMEBUFFER, tmp_fbo); + glUseProgram(FullScreenShader::Gaussian17TapHShader::Program); + glBindVertexArray(FullScreenShader::Gaussian17TapHShader::vao); + + glUniform2f(FullScreenShader::Gaussian17TapHShader::uniform_pixel, inv_width, inv_height); + + setTexture(0, in_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glUniform1i(FullScreenShader::Gaussian17TapHShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + { + glBindFramebuffer(GL_FRAMEBUFFER, in_fbo); + glUseProgram(FullScreenShader::Gaussian17TapVShader::Program); + glBindVertexArray(FullScreenShader::Gaussian17TapVShader::vao); + + glUniform2f(FullScreenShader::Gaussian17TapVShader::uniform_pixel, inv_width, inv_height); + + setTexture(0, tmp_tex, GL_LINEAR, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glUniform1i(FullScreenShader::Gaussian17TapVShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } +} + void PostProcessing::renderPassThrough(GLuint tex) { diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index d7975ffae..d3bb77921 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -84,6 +84,7 @@ public: /** Blur the in texture */ void renderGaussian3Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t inv_width, size_t inv_height); void renderGaussian6Blur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height); + void renderGaussian17TapBlur(unsigned in_fbo, unsigned in_tex, unsigned tmp_fbo, unsigned tmp_tex, size_t width, size_t height); /** Render tex. Used for blit/texture resize */ void renderPassThrough(unsigned tex); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8255a10f0..154be4eb9 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -898,7 +898,7 @@ void IrrDriver::renderSSAO() glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); m_post_processing->renderSSAO(); // Blur it to reduce noise. - m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), + m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 84c736232..51df04a30 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -301,8 +301,10 @@ void Shaders::loadShaders() FullScreenShader::DepthOfFieldShader::init(); FullScreenShader::ColorLevelShader::init(); FullScreenShader::FogShader::init(); + FullScreenShader::Gaussian17TapHShader::init(); FullScreenShader::Gaussian3HBlurShader::init(); FullScreenShader::Gaussian3VBlurShader::init(); + FullScreenShader::Gaussian17TapVShader::init(); FullScreenShader::Gaussian6HBlurShader::init(); FullScreenShader::Gaussian6VBlurShader::init(); FullScreenShader::PenumbraHShader::init(); @@ -2349,6 +2351,20 @@ namespace FullScreenShader glUniform1i(uniform_shadowtex, TU_shadowtex); } + GLuint Gaussian17TapHShader::Program; + GLuint Gaussian17TapHShader::uniform_tex; + GLuint Gaussian17TapHShader::uniform_pixel; + GLuint Gaussian17TapHShader::vao; + void Gaussian17TapHShader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17taph.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + vao = createVAO(Program); + } + GLuint Gaussian6HBlurShader::Program; GLuint Gaussian6HBlurShader::uniform_tex; GLuint Gaussian6HBlurShader::uniform_pixel; @@ -2377,6 +2393,20 @@ namespace FullScreenShader vao = createVAO(Program); } + GLuint Gaussian17TapVShader::Program; + GLuint Gaussian17TapVShader::uniform_tex; + GLuint Gaussian17TapVShader::uniform_pixel; + GLuint Gaussian17TapVShader::vao; + void Gaussian17TapVShader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/gaussian17tapv.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + vao = createVAO(Program); + } + GLuint Gaussian6VBlurShader::Program; GLuint Gaussian6VBlurShader::uniform_tex; GLuint Gaussian6VBlurShader::uniform_pixel; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 36f74a430..f70fbaf20 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -610,6 +610,16 @@ public: static void setUniforms(const core::vector3df &direction, float r, float g, float b, unsigned TU_ntex, unsigned TU_dtex, unsigned TU_shadowtex); }; +class Gaussian17TapHShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + class Gaussian6HBlurShader { public: @@ -630,6 +640,16 @@ public: static void init(); }; +class Gaussian17TapVShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + class Gaussian6VBlurShader { public: From 26d48cdad099efc061db5a223b98c056aadf15bf Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 12 May 2014 23:59:17 +0200 Subject: [PATCH 57/69] SSAO: Stronger blur + tweak param Use another algorithm to have gaussian blur that lets us customise radius more easily. --- data/shaders/gaussian17taph.frag | 35 +++++++++++++------------------ data/shaders/gaussian17tapv.frag | 36 +++++++++++++------------------- data/shaders/ssao.frag | 4 ++-- src/graphics/render.cpp | 2 +- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/data/shaders/gaussian17taph.frag b/data/shaders/gaussian17taph.frag index 874d22a7f..f02a49dfc 100644 --- a/data/shaders/gaussian17taph.frag +++ b/data/shaders/gaussian17taph.frag @@ -1,37 +1,30 @@ -// From http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ +// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html uniform sampler2D tex; uniform vec2 pixel; - +uniform float sigma = 5.; in vec2 uv; out vec4 FragColor; void main() { - float X = uv.x; float Y = uv.y; - float offset[5] = { - 0., - 1.41176470588235, - 3.29411764705882, - 5.17647058823529, - 7.05882352941176 - }; - float weight[5] = { - 0.196380615234375, - 0.1888427734375, - 0.03631591796875, - 0.0020751953125, - 0.000015258789062 - }; - vec4 sum = texture(tex, vec2(X, Y)) * weight[0]; - for (int i = 1; i < 5; i++) { - sum += texture(tex, vec2(X - offset[i] * pixel.x, Y)) * weight[i]; - sum += texture(tex, vec2(X + offset[i] * pixel.x, Y)) * weight[i]; + float g0, g1, g2; + g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); + g1 = exp(-0.5 / (sigma * sigma)); + g2 = g1 * g1; + vec4 sum = texture(tex, vec2(X, Y)) * g0; + g0 *= g1; + g1 *= g2; + for (int i = 1; i < 9; i++) { + sum += texture(tex, vec2(X - i * pixel.x, Y)) * g0; + sum += texture(tex, vec2(X + i * pixel.x, Y)) * g0; + g0 *= g1; + g1 *= g2; } FragColor = sum; diff --git a/data/shaders/gaussian17tapv.frag b/data/shaders/gaussian17tapv.frag index 00de4c4aa..01e54a8a9 100644 --- a/data/shaders/gaussian17tapv.frag +++ b/data/shaders/gaussian17tapv.frag @@ -1,38 +1,32 @@ -// From http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ +// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html uniform sampler2D tex; uniform vec2 pixel; - +uniform float sigma = 5.; in vec2 uv; out vec4 FragColor; void main() { - float X = uv.x; float Y = uv.y; - float offset[5] = { - 0., - 1.41176470588235, - 3.29411764705882, - 5.17647058823529, - 7.05882352941176 - }; - float weight[5] = { - 0.196380615234375, - 0.1888427734375, - 0.03631591796875, - 0.0020751953125, - 0.000015258789062 - }; - vec4 sum = texture(tex, vec2(X, Y)) * weight[0]; - for (int i = 1; i < 5; i++) { - sum += texture(tex, vec2(X, Y - offset[i] * pixel.y)) * weight[i]; - sum += texture(tex, vec2(X, Y + offset[i] * pixel.y)) * weight[i]; + float g0, g1, g2; + g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma); + g1 = exp(-0.5 / (sigma * sigma)); + g2 = g1 * g1; + vec4 sum = texture(tex, vec2(X, Y)) * g0; + g0 *= g1; + g1 *= g2; + for (int i = 1; i < 9; i++) { + sum += texture(tex, vec2(X, Y - i * pixel.y)) * g0; + sum += texture(tex, vec2(X, Y + i * pixel.y)) * g0; + g0 *= g1; + g1 *= g2; } FragColor = sum; } + diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 7693590e9..5c0080ead 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -27,10 +27,10 @@ in vec2 uv; out float AO; const float sigma = 1.; -const float tau = 2.; +const float tau = 7.; const float beta = 0.0001; const float epsilon = .00001; -const float radius = 1.; +const float radius = 1.5; const float k = 1.; #define SAMPLES 16 diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 154be4eb9..42e7628c8 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -899,7 +899,7 @@ void IrrDriver::renderSSAO() m_post_processing->renderSSAO(); // Blur it to reduce noise. m_post_processing->renderGaussian17TapBlur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO), - irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height); + irr_driver->getFBO(FBO_TMP4), irr_driver->getRenderTargetTexture(RTT_TMP4), UserConfigParams::m_width, UserConfigParams::m_height ); glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); } From bcc46b149eadcd656a95c4b035ed0934bffdfe15 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Mon, 12 May 2014 19:03:40 -0400 Subject: [PATCH 58/69] Remove call to createMeshWelded, now handled in B3D exporter --- src/graphics/irr_driver.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 15cd402c0..9a2d40b1f 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -841,8 +841,7 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename) filename.c_str()); return NULL; } - scene::IMeshManipulator *mani = irr_driver->getVideoDriver()->getMeshManipulator(); - return mani->createMeshWelded(am->getMesh(0)); + return am->getMesh(0); } // getMesh // ---------------------------------------------------------------------------- @@ -1628,7 +1627,7 @@ void IrrDriver::displayFPS() if (UserConfigParams::m_artist_debug_mode) { - sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) KTris - LightDst : ~%d", + sprintf(buffer, "FPS: %i/%i/%i - Objects (P1:%d P2:%d T:%d) - LightDst : ~%d", min, fps, max, object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[SOLID_NORMAL_AND_DEPTH_PASS], object_count[TRANSPARENT_PASS], m_last_light_bucket_distance); object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0; object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0; From 20959f970a622737da4d00169230626539c00f83 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 13 May 2014 01:12:24 +0200 Subject: [PATCH 59/69] Avoid displacement related fbo bind in non advanced pipeline --- src/graphics/render.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 42e7628c8..13e71a5c8 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -331,6 +331,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector renderParticles(); PROFILER_POP_CPU_MARKER(); } + if (!UserConfigParams::m_dynamic_lights) + return; // Render displacement { From 59484ea09ae0057e45dd5932683f410bb1ba3f3f Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 13 May 2014 19:40:30 +0200 Subject: [PATCH 60/69] DS buffer is not linear and cant be mipmapped Use the method provided by SAO paper (ie convert to linear and then mipmap) --- data/shaders/linearizedepth.frag | 13 +++++++++ data/shaders/ssao.frag | 45 +++++++++++++++----------------- src/graphics/post_processing.cpp | 12 ++++++++- src/graphics/rtts.cpp | 2 ++ src/graphics/rtts.hpp | 2 ++ src/graphics/shaders.cpp | 24 +++++++++++++++++ src/graphics/shaders.hpp | 11 ++++++++ 7 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 data/shaders/linearizedepth.frag diff --git a/data/shaders/linearizedepth.frag b/data/shaders/linearizedepth.frag new file mode 100644 index 000000000..fdb456f48 --- /dev/null +++ b/data/shaders/linearizedepth.frag @@ -0,0 +1,13 @@ +uniform sampler2D tex; +uniform float zn; +uniform float zf; + +in vec2 uv; +out float Depth; + +void main() +{ + float d = texture(tex, uv).x; + float c0 = zn * zf, c1 = zn - zf, c2 = zf; + Depth = c0 / (d * c1 + c2); +} diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 5c0080ead..824b773d6 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,9 +1,7 @@ // From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ // and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/ -uniform sampler2D ntex; uniform sampler2D dtex; -uniform sampler2D noise_texture; uniform vec4 samplePoints[16]; uniform vec2 screen; @@ -37,24 +35,25 @@ const float k = 1.; const float invSamples = 1. / SAMPLES; -vec3 DecodeNormal(vec2 n); -vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); +vec3 getXcYcZc(int x, int y, float zC) +{ + // We use perspective symetric projection matrix hence P(0,2) = P(1, 2) = 0 + float xC= (1. - 2 * (float(x) + 0.5) / screen.x) * zC / ProjectionMatrix[0][0]; + float yC= (1. + 2 * (float(y) + 0.5) / screen.y) * zC / ProjectionMatrix[1][1]; + return vec3(xC, yC, zC); +} void main(void) { - vec4 cur = texture(ntex, uv); - float curdepth = texture(dtex, uv).x; - vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix); + float lineardepth = textureLod(dtex, uv, 0.).x; + int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y); + vec3 FragPos = getXcYcZc(x, y, lineardepth); // get the normal of current fragment - vec3 ddx = dFdx(FragPos.xyz); - vec3 ddy = dFdy(FragPos.xyz); - vec3 norm = normalize(cross(ddy, ddx)); - // Workaround for nvidia and skyboxes - float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2) discard; + vec3 ddx = dFdx(FragPos); + vec3 ddy = dFdy(FragPos); + vec3 norm = -normalize(cross(ddy, ddx)); - int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y); float r = radius / FragPos.z; float phi = 30. * (x ^ y) + 10. * x * y; float bl = 0.0; @@ -63,20 +62,18 @@ void main(void) float alpha = (i + .5) * invSamples; float theta = 2. * 3.14 * tau * alpha + phi; float h = r * alpha; - vec2 occluder_uv = h * vec2(cos(theta), sin(theta)) * screen; - occluder_uv += gl_FragCoord.xy; + vec2 offset = h * vec2(cos(theta), sin(theta)) * screen; - float m = round(log2(h)) + 7; - ivec2 ioccluder_uv = ivec2(occluder_uv); - occluder_uv = (ioccluder_uv >> int(m)) << int(m); - occluder_uv /= screen; + float m = round(log2(h) + 7); + ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset); + ioccluder_uv = (ioccluder_uv << int(m)) >> int(m); - if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue; + if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue; - float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x; - vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix); + float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / screen, m).x; + vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth); - vec3 vi = (OccluderPos - FragPos).xyz; + vec3 vi = OccluderPos - FragPos; bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 354340e91..54f3b6516 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -451,12 +451,22 @@ void PostProcessing::renderSSAO() glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); + // Generate linear depth buffer + glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_LINEAR_DEPTH)); + glUseProgram(FullScreenShader::LinearizeDepthShader::Program); + glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao); + setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR); + FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_SSAO)); + if (!noise_tex) noise_tex = irr_driver->getTexture(file_manager->getAsset("textures/noise.png").c_str()); glUseProgram(FullScreenShader::SSAOShader::Program); glBindVertexArray(FullScreenShader::SSAOShader::vao); - setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST); + + setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR); diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index fd14fb5fe..ae071b595 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -83,6 +83,7 @@ RTT::RTT() RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT); + RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT); RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT); RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT); RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE); @@ -118,6 +119,7 @@ RTT::RTT() FrameBuffers[FBO_TMP1_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture); FrameBuffers[FBO_TMP2_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP2], DepthStencilTexture); FrameBuffers[FBO_TMP4] = generateFBO(RenderTargetTextures[RTT_TMP4], DepthStencilTexture); + FrameBuffers[FBO_LINEAR_DEPTH] = generateFBO(RenderTargetTextures[RTT_LINEAR_DEPTH]); FrameBuffers[FBO_DISPLACE] = generateFBO(RenderTargetTextures[RTT_DISPLACE], DepthStencilTexture); FrameBuffers[FBO_HALF1] = generateFBO(RenderTargetTextures[RTT_HALF1]); FrameBuffers[FBO_HALF2] = generateFBO(RenderTargetTextures[RTT_HALF2]); diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index a8234bb76..6edab8556 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -31,6 +31,7 @@ enum TypeRTT RTT_TMP2, RTT_TMP3, RTT_TMP4, + RTT_LINEAR_DEPTH, RTT_NORMAL_AND_DEPTH, RTT_COLOR, RTT_LOG_LUMINANCE, @@ -87,6 +88,7 @@ enum TypeFBO FBO_TMP1_WITH_DS, FBO_TMP2_WITH_DS, FBO_TMP4, + FBO_LINEAR_DEPTH, FBO_HALF1, FBO_HALF2, FBO_QUARTER1, diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 51df04a30..883fe75b6 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -311,6 +311,7 @@ void Shaders::loadShaders() FullScreenShader::PenumbraVShader::init(); FullScreenShader::GlowShader::init(); FullScreenShader::PassThroughShader::init(); + FullScreenShader::LinearizeDepthShader::init(); FullScreenShader::SSAOShader::init(); FullScreenShader::SunLightShader::init(); FullScreenShader::DiffuseEnvMapShader::init(); @@ -2510,6 +2511,29 @@ namespace FullScreenShader vao = createVAO(Program); } + GLuint LinearizeDepthShader::Program; + GLuint LinearizeDepthShader::uniform_zn; + GLuint LinearizeDepthShader::uniform_zf; + GLuint LinearizeDepthShader::uniform_texture; + GLuint LinearizeDepthShader::vao; + void LinearizeDepthShader::init() + { + Program = LoadProgram( + GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/linearizedepth.frag").c_str()); + uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_zf = glGetUniformLocation(Program, "zf"); + uniform_zn = glGetUniformLocation(Program, "zn"); + vao = createVAO(Program); + } + + void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex) + { + glUniform1f(uniform_zn, zn); + glUniform1f(uniform_zf, zf); + glUniform1i(uniform_texture, TU_tex); + } + GLuint GlowShader::Program; GLuint GlowShader::uniform_tex; GLuint GlowShader::vao; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index f70fbaf20..3a3ec8e31 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -713,6 +713,17 @@ public: static void init(); }; +class LinearizeDepthShader +{ +public: + static GLuint Program; + static GLuint uniform_zn, uniform_zf, uniform_texture; + static GLuint vao; + + static void init(); + static void setUniforms(float zn, float zf, unsigned TU_tex); +}; + class GlowShader { public: From 5fd41a2f2cc10a868654f976fe3e3cc4faba2f04 Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 00:32:36 +0200 Subject: [PATCH 61/69] Light: Import distance properly. Also remove some silly default param for addlight that could make argument passing not obvious. --- src/graphics/irr_driver.cpp | 4 ++-- src/graphics/irr_driver.hpp | 4 ++-- src/graphics/light.cpp | 3 ++- src/graphics/light.hpp | 6 +++--- src/graphics/render.cpp | 2 +- src/graphics/sun.cpp | 2 +- src/states_screens/feature_unlocked.cpp | 2 +- src/tracks/track_object_presentation.cpp | 8 ++++---- src/tracks/track_object_presentation.hpp | 2 +- 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 9a2d40b1f..4c7854aee 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2305,7 +2305,7 @@ void IrrDriver::applyObjectPassShader() // ---------------------------------------------------------------------------- -scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, +scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, float radius, float r, float g, float b, bool sun, scene::ISceneNode* parent) { if (m_glsl) @@ -2314,7 +2314,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, LightNode *light = NULL; if (!sun) - light = new LightNode(m_scene_manager, parent, energy, r, g, b); + light = new LightNode(m_scene_manager, parent, energy, radius, r, g, b); else light = new SunNode(m_scene_manager, parent, r, g, b); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 08cd55b4b..04ebfbf1f 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -563,8 +563,8 @@ public: void applyObjectPassShader(); void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false); // ------------------------------------------------------------------------ - scene::ISceneNode *addLight(const core::vector3df &pos, float energy = 1., float r = 1.0f, - float g = 1.0f, float b = 1.0f, bool sun = false, scene::ISceneNode* parent = NULL); + scene::ISceneNode *addLight(const core::vector3df &pos, float energy, float radius, float r, + float g, float b, bool sun = false, scene::ISceneNode* parent = NULL); // ------------------------------------------------------------------------ void clearLights(); // ------------------------------------------------------------------------ diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index d534ad4cb..068809995 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -34,10 +34,11 @@ using namespace core; aabbox3df LightNode::box; -LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float r, float g, float b): +LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float d, float r, float g, float b): ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1) { m_energy = e; + m_radius = d; m_energy_multiplier = 1.0f; m_color[0] = r; m_color[1] = g; diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 1f17c5aad..62b3bd44f 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -40,7 +40,7 @@ class LightNode: public scene::ISceneNode #endif public: - LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float r, float g, float b); + LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float d, float r, float g, float b); virtual ~LightNode(); virtual void render() OVERRIDE; @@ -55,7 +55,7 @@ public: virtual u32 getMaterialCount() const OVERRIDE { return 1; } virtual bool isPointLight() { return true; } - //float getRadius() const { return m_radius; } + float getRadius() const { return m_radius; } float getEnergy() const { return m_energy; } float getEffectiveEnergy() const { return m_energy_multiplier * m_energy; } core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); } @@ -66,7 +66,7 @@ public: protected: static core::aabbox3df box; - //float m_radius; + float m_radius; float m_color[3]; float m_energy; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 13e71a5c8..bc993e985 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -874,7 +874,7 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt) PointLightsInfo[lightnum].blue = col.Z; // Light radius - PointLightsInfo[lightnum].radius = 20 * light_node->getEffectiveEnergy(); + PointLightsInfo[lightnum].radius = light_node->getRadius(); } } if (lightnum > MAXLIGHT) diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index dd20a74b4..3399cd668 100644 --- a/src/graphics/sun.cpp +++ b/src/graphics/sun.cpp @@ -35,7 +35,7 @@ using namespace scene; using namespace core; SunNode::SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b): - LightNode(mgr, parent, 0., r, g, b) + LightNode(mgr, parent, 0., 0., r, g, b) { m_color[0] = r; m_color[1] = g; diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 07b24c348..2b3a90cf2 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -302,7 +302,7 @@ void FeatureUnlockedCutScene::init() 120, 120)); const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f ); - m_light = irr_driver->addLight(sun_pos, 10000.0f, 1, 1, 1); + m_light = irr_driver->addLight(sun_pos, 10000.0f, 1., 1, 1, 1); #ifdef DEBUG m_light->setName("light"); #endif diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 02345c57f..c6d9f95e4 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -675,15 +675,15 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no xml_node.get("color", &m_color); const video::SColorf colorf(m_color); - //m_distance = 25.0f; - //xml_node.get("distance", &m_distance); - m_energy = 1.0f; xml_node.get("energy", &m_energy); + m_distance = 20. * m_energy; + xml_node.get("distance", &m_distance); + if (irr_driver->isGLSL()) { - m_node = irr_driver->addLight(m_init_xyz, m_energy, colorf.r, colorf.g, colorf.b, false, parent); + m_node = irr_driver->addLight(m_init_xyz, m_energy, m_distance, colorf.r, colorf.g, colorf.b, false, parent); } else { diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 561df9ff5..ba7bb95a5 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -307,7 +307,7 @@ class TrackObjectPresentationLight : public TrackObjectPresentationSceneNode { private: video::SColor m_color; - //float m_distance; + float m_distance; float m_energy; public: From 1073335f4dd81b71a38ccf05494c7529dcae41a5 Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 00:50:25 +0200 Subject: [PATCH 62/69] Fix sun light --- src/states_screens/feature_unlocked.cpp | 2 +- src/tracks/track.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 2b3a90cf2..d251c56e4 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -302,7 +302,7 @@ void FeatureUnlockedCutScene::init() 120, 120)); const core::vector3df &sun_pos = core::vector3df( 0, 200, 100.0f ); - m_light = irr_driver->addLight(sun_pos, 10000.0f, 1., 1, 1, 1); + m_light = irr_driver->addLight(sun_pos, 10000.0f, 1., 1, 1, 1, true); #ifdef DEBUG m_light->setName("light"); #endif diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 2010adb30..ae9fe5aab 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1719,7 +1719,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } const video::SColorf tmpf(m_sun_diffuse_color); - m_sun = irr_driver->addLight(m_sun_position, 0., tmpf.r, tmpf.g, tmpf.b, true); + m_sun = irr_driver->addLight(m_sun_position, 0., 0., tmpf.r, tmpf.g, tmpf.b, true); if (!irr_driver->isGLSL()) { From 0ccac5d316f0092527124a9414de5a7da6b03916 Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 00:59:51 +0200 Subject: [PATCH 63/69] Replace texture2D by texture in dof.frag --- data/shaders/dof.frag | 86 +++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/data/shaders/dof.frag b/data/shaders/dof.frag index 35259d26d..90938d68f 100644 --- a/data/shaders/dof.frag +++ b/data/shaders/dof.frag @@ -21,62 +21,58 @@ void main() vec2 offset = 10. / screen; - vec4 col = texture2D(tex, uv); + vec4 col = texture(tex, uv); vec4 colOriginal = col; // Weight from here http://artmartinsh.blogspot.fr/2010/02/glsl-lens-blur-filter-with-bokeh.html - col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.29,0.29) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.37,0.15) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur); - col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur); + col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur); + col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur); + col += texture(tex, uv + (vec2(0.29,0.29) * offset) * blur); + col += texture(tex, uv + (vec2(-0.37,0.15) * offset) * blur); + col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur); + col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur); + col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur); + col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur); + col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur); + col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur); + col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur); + col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur); + col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur); + col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur); + col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur); + col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur); - col += texture2D(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(0.15, 0.37) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(-0.37, 0.15) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(0.37, -0.15) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(-0.15, -0.37) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(-0.15, 0.37) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(0.37, 0.15) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(-0.37, -0.15) * offset) * blur * 0.9); + col += texture(tex, uv + (vec2(0.15, -0.37) * offset) * blur * 0.9); - col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7); - col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7); + col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.7); + col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur *0.7); - col += texture2D(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4); - col += texture2D(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(0.29, 0.29) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(0.4, 0.0) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(0.29, -0.29) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(0.0, -0.4) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(-0.29, 0.29) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(-0.4, 0.0) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(-0.29, -0.29) * offset) * blur * 0.4); + col += texture(tex, uv + (vec2(0.0, 0.4) * offset) * blur * 0.4); col = vec4(col.rgb / 41.0, col.a); depth = clamp((FragPos.z/280), 0., 1.); depth = (1 - depth); vec3 final = colOriginal.rgb * depth + col.rgb * (1 - depth); -/* - FragColor.xyz = vec3(depth); - FragColor.a = 1.0; - */ FragColor = vec4(final, 1.); } From 03ad82267ac57393e35476576f523ffd2634670f Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 13 May 2014 19:39:19 -0400 Subject: [PATCH 64/69] Fix OSX 10.7 compilation --- src/graphics/glwrap.cpp | 4 ++++ src/graphics/glwrap.hpp | 6 ++++++ src/network/protocols/connect_to_server.cpp | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 4dfd2f2bc..638f3f192 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -490,6 +490,7 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) if (!UserConfigParams::m_profiler_enabled) return; if (profiler.isFrozen()) return; +#ifdef GL_TIME_ELAPSED irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver(); if (!timer.initialised) { @@ -497,14 +498,17 @@ ScopedGPUTimer::ScopedGPUTimer(GPUTimer &timer) timer.initialised = true; } gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, timer.query); +#endif } ScopedGPUTimer::~ScopedGPUTimer() { if (!UserConfigParams::m_profiler_enabled) return; if (profiler.isFrozen()) return; +#ifdef GL_TIME_ELAPSED irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver *)irr_driver->getDevice()->getVideoDriver(); gl_driver->extGlEndQuery(GL_TIME_ELAPSED); +#endif } GPUTimer::GPUTimer() : initialised(false) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index df3827d0f..56fd99ee4 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -5,6 +5,12 @@ # include # include # define OGL32CTX +# ifdef GL_ARB_instanced_arrays +# define glVertexAttribDivisor glVertexAttribDivisorARB +# endif +# ifndef GL_TEXTURE_SWIZZLE_RGBA +# define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 +# endif #elif defined(ANDROID) # include #elif defined(WIN32) diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp index 0cc8d314f..bc4dda7fd 100644 --- a/src/network/protocols/connect_to_server.cpp +++ b/src/network/protocols/connect_to_server.cpp @@ -153,7 +153,7 @@ void ConnectToServer::asynchronousUpdate() if (m_server_address.ip == 0 || m_server_address.port == 0) { // server data not correct, hide address and stop m_state = HIDING_ADDRESS; - Log::error("ConnectToServer", "Server address is "ADDRESS_FORMAT, ADDRESS_ARGS(m_server_address.ip, m_server_address.port)); + Log::error("ConnectToServer", "Server address is " ADDRESS_FORMAT, ADDRESS_ARGS(m_server_address.ip, m_server_address.port)); m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); return; } From dd81f02fea0ddc3453da80ae094351d15af7df9a Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 01:51:40 +0200 Subject: [PATCH 65/69] Fix for #1324 --- src/graphics/render.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index bc993e985..617327452 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -341,6 +341,8 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector renderDisplacement(); PROFILER_POP_CPU_MARKER(); } + // Ensure that no object will be drawn after that by using invalid pass + irr_driver->setPhase(PASS_COUNT); } // -------------------------------------------- From 474bbb4373e2d2de9018049123742196434dd3bc Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 13 May 2014 20:00:16 -0400 Subject: [PATCH 66/69] Try to convert icon rendering to new helper function (for GL3 support) --- lib/irrlicht/include/IGUISkin.h | 5 +++++ lib/irrlicht/source/Irrlicht/CGUIButton.cpp | 15 ++++++++++----- lib/irrlicht/source/Irrlicht/CGUISkin.cpp | 7 +++++++ lib/irrlicht/source/Irrlicht/CGUISkin.h | 4 ++++ src/guiengine/skin.cpp | 9 +++++++++ src/guiengine/skin.hpp | 5 +++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/irrlicht/include/IGUISkin.h b/lib/irrlicht/include/IGUISkin.h index d3bf337df..53664f3da 100644 --- a/lib/irrlicht/include/IGUISkin.h +++ b/lib/irrlicht/include/IGUISkin.h @@ -12,6 +12,7 @@ namespace irr { +namespace video { class ITexture; } namespace gui { class IGUIFont; @@ -564,6 +565,10 @@ namespace gui //! get the type of this skin virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; } + + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) = 0; }; diff --git a/lib/irrlicht/source/Irrlicht/CGUIButton.cpp b/lib/irrlicht/source/Irrlicht/CGUIButton.cpp index 5a451cdbd..21be74646 100644 --- a/lib/irrlicht/source/Irrlicht/CGUIButton.cpp +++ b/lib/irrlicht/source/Irrlicht/CGUIButton.cpp @@ -249,11 +249,16 @@ void CGUIButton::draw() pos.X -= ImageRect.getWidth() / 2; pos.Y -= ImageRect.getHeight() / 2; - driver->draw2DImage(Image, - ScaleImage? AbsoluteRect : - core::recti(pos, ImageRect.getSize()), - ImageRect, &AbsoluteClippingRect, - 0, UseAlphaChannel); + skin->draw2DImage(Image, + ScaleImage ? AbsoluteRect : + core::recti(pos, ImageRect.getSize()), + ImageRect, &AbsoluteClippingRect, + 0, UseAlphaChannel); + //driver->draw2DImage(Image, + // ScaleImage? AbsoluteRect : + // core::recti(pos, ImageRect.getSize()), + // ImageRect, &AbsoluteClippingRect, + // 0, UseAlphaChannel); } } else diff --git a/lib/irrlicht/source/Irrlicht/CGUISkin.cpp b/lib/irrlicht/source/Irrlicht/CGUISkin.cpp index b0b2b39c3..df3238e5c 100644 --- a/lib/irrlicht/source/Irrlicht/CGUISkin.cpp +++ b/lib/irrlicht/source/Irrlicht/CGUISkin.cpp @@ -179,6 +179,13 @@ CGUISkin::~CGUISkin() } +void CGUISkin::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + Driver->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); +} + //! returns default color video::SColor CGUISkin::getColor(EGUI_DEFAULT_COLOR color) const { diff --git a/lib/irrlicht/source/Irrlicht/CGUISkin.h b/lib/irrlicht/source/Irrlicht/CGUISkin.h index 903d856d6..ebaab6d2a 100644 --- a/lib/irrlicht/source/Irrlicht/CGUISkin.h +++ b/lib/irrlicht/source/Irrlicht/CGUISkin.h @@ -224,6 +224,10 @@ namespace gui //! scripting languages, editors, debuggers or xml deserialization purposes. virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0); + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture); + private: video::SColor Colors[EGDC_COUNT]; diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index e0d015a90..6d2292573 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -2267,6 +2267,15 @@ void Skin::drawIcon (IGUIElement *element, EGUI_DEFAULT_ICON icon, // ----------------------------------------------------------------------------- +void Skin::draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture) +{ + ::draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); +} + +// ----------------------------------------------------------------------------- + video::SColor Skin::getColor (EGUI_DEFAULT_COLOR color) const { /* diff --git a/src/guiengine/skin.hpp b/src/guiengine/skin.hpp index 3c8eac393..f13a5066a 100644 --- a/src/guiengine/skin.hpp +++ b/src/guiengine/skin.hpp @@ -381,6 +381,11 @@ namespace GUIEngine const core::rect< s32 > &rect, const core::rect< s32 > *clip, core::rect* checkClientArea=0); + + virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, + const core::rect& sourceRect, const core::rect* clipRect, + const video::SColor* const colors, bool useAlphaChannelOfTexture); + virtual void drawIcon (gui::IGUIElement *element, gui::EGUI_DEFAULT_ICON icon, const core::position2di position, From 86c8b9f83d91cefda3248df5cb42c0757cbe8dd1 Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 02:12:18 +0200 Subject: [PATCH 67/69] Some tweaking to make ssao more apparent --- data/shaders/ssao.frag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 824b773d6..0289bb4c0 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -24,12 +24,12 @@ layout (std140) uniform MatrixesData in vec2 uv; out float AO; -const float sigma = 1.; +const float sigma = 2.; const float tau = 7.; const float beta = 0.0001; const float epsilon = .00001; const float radius = 1.5; -const float k = 1.; +const float k = 1.5; #define SAMPLES 16 @@ -64,7 +64,7 @@ void main(void) float h = r * alpha; vec2 offset = h * vec2(cos(theta), sin(theta)) * screen; - float m = round(log2(h) + 7); + float m = round(log2(h) + 6); ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset); ioccluder_uv = (ioccluder_uv << int(m)) >> int(m); From 1d4bcd5adee0ecb08a7e809cd2b419faa1000815 Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 02:27:17 +0200 Subject: [PATCH 68/69] SSAO: Increase beta constant to avoid error --- data/shaders/ssao.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 0289bb4c0..947401818 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -26,7 +26,7 @@ out float AO; const float sigma = 2.; const float tau = 7.; -const float beta = 0.0001; +const float beta = 0.001; const float epsilon = .00001; const float radius = 1.5; const float k = 1.5; From 229b461a6caa091345a0f7ff302c82fc78b4386d Mon Sep 17 00:00:00 2001 From: vlj Date: Wed, 14 May 2014 03:26:43 +0200 Subject: [PATCH 69/69] SSAO: Less abrupt transition --- data/shaders/ssao.frag | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 947401818..95daf0f89 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -24,11 +24,11 @@ layout (std140) uniform MatrixesData in vec2 uv; out float AO; -const float sigma = 2.; +const float sigma = 1.; const float tau = 7.; const float beta = 0.001; const float epsilon = .00001; -const float radius = 1.5; +const float radius = 1.; const float k = 1.5; #define SAMPLES 16 @@ -66,7 +66,6 @@ void main(void) float m = round(log2(h) + 6); ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset); - ioccluder_uv = (ioccluder_uv << int(m)) >> int(m); if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue;