diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 629951f2b..86f4c05b0 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -1,3 +1,5 @@ +// See http://www.ozone3d.net/tutorials/glsl_texturing_p04.php for ref + #ifdef UBO_DISABLED uniform mat4 ViewMatrix; uniform mat4 ProjectionMatrix; @@ -15,7 +17,7 @@ layout (std140) uniform MatrixesData }; #endif -uniform samplerCube tex; +uniform sampler2D tex; #if __VERSION__ >= 130 in vec3 nor; @@ -25,17 +27,18 @@ varying vec3 nor; #define FragColor gl_FragColor #endif +vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); +vec3 getLightFactor(float specMapValue); void main() { - vec3 fpos = gl_FragCoord.xyz / vec3(screen, 1.); - vec4 xpos = 2.0 * vec4(fpos, 1.0) - 1.0; - xpos = InverseProjectionMatrix * xpos; + vec3 texc = gl_FragCoord.xyz / vec3(screen, 1.); + vec3 u = getPosFromUVDepth(texc, InverseProjectionMatrix).xyz; + vec3 r = reflect(u, nor); - xpos.xyz /= xpos.w; - vec3 viewSampleDir = reflect(xpos.xyz, nor); - // Convert sampleDir in world space (where tex was generated) - vec4 sampleDir = transpose(InverseViewMatrix) * vec4(viewSampleDir, 0.); - vec4 detail0 = texture(tex, sampleDir.xyz); + float m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0)); + r.y = - r.y; + vec4 detail0 = texture(tex, r.xy / m + .5); + vec3 LightFactor = getLightFactor(1.); - FragColor = vec4(detail0.xyz, 1.); + FragColor = vec4(detail0.xyz * LightFactor, 1.); } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 0d7919d04..c5ea60aff 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2383,3 +2383,24 @@ void IrrDriver::clearLights() m_lights.clear(); } + +// ---------------------------------------------------------------------------- + +GLuint IrrDriver::getRenderTargetTexture(TypeRTT which) +{ + return m_rtts->getRenderTarget(which); +} + +// ---------------------------------------------------------------------------- + +FrameBuffer& IrrDriver::getFBO(TypeFBO which) +{ + return m_rtts->getFBO(which); +} + +// ---------------------------------------------------------------------------- + +GLuint IrrDriver::getDepthStencilTexture() +{ + return m_rtts->getDepthStencilTexture(); +} \ No newline at end of file diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 395bc90b8..151d17f68 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -36,6 +36,15 @@ #include #include "IrrlichtDevice.h" #include "ISkinnedMesh.h" +//#include "graphics/rtts.hpp" +#include "graphics/shaders.hpp" +#include "graphics/wind.hpp" +#include "io/file_manager.hpp" +#include "utils/aligned_array.hpp" +#include "utils/no_copy.hpp" +#include "utils/ptr_vector.hpp" +#include "utils/vec3.hpp" + namespace irr { namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh; @@ -45,17 +54,9 @@ namespace irr } using namespace irr; +class RTT; +class FrameBuffer; class ShadowImportanceProvider; - -#include "graphics/rtts.hpp" -#include "graphics/shaders.hpp" -#include "graphics/wind.hpp" -#include "io/file_manager.hpp" -#include "utils/aligned_array.hpp" -#include "utils/no_copy.hpp" -#include "utils/ptr_vector.hpp" -#include "utils/vec3.hpp" - class AbstractKart; class Camera; class PerCameraNode; @@ -74,6 +75,35 @@ enum STKRenderingPass PASS_COUNT, }; +enum TypeFBO +{ + FBO_SSAO, + FBO_NORMAL_AND_DEPTHS, + FBO_COMBINED_TMP1_TMP2, + FBO_COLORS, + FBO_LOG_LUMINANCE, + FBO_MLAA_COLORS, + FBO_TMP1_WITH_DS, + FBO_TMP2_WITH_DS, + FBO_TMP4, + FBO_LINEAR_DEPTH, + FBO_HALF1, + FBO_HALF2, + FBO_QUARTER1, + FBO_QUARTER2, + FBO_EIGHTH1, + FBO_EIGHTH2, + FBO_DISPLACE, + FBO_BLOOM_1024, + FBO_BLOOM_512, + FBO_TMP_512, + FBO_BLOOM_256, + FBO_TMP_256, + FBO_BLOOM_128, + FBO_TMP_128, + FBO_COUNT +}; + enum QueryPerf { Q_SOLID_PASS1, @@ -91,6 +121,57 @@ enum QueryPerf Q_LAST }; +enum TypeRTT +{ + RTT_TMP1 = 0, + RTT_TMP2, + RTT_TMP3, + RTT_TMP4, + RTT_LINEAR_DEPTH, + RTT_NORMAL_AND_DEPTH, + RTT_COLOR, + RTT_LOG_LUMINANCE, + + RTT_HALF1, + RTT_HALF2, + + RTT_QUARTER1, + RTT_QUARTER2, + // RTT_QUARTER3, + // RTT_QUARTER4, + + RTT_EIGHTH1, + RTT_EIGHTH2, + + // RTT_SIXTEENTH1, + // RTT_SIXTEENTH2, + + RTT_SSAO, + + // RTT_COLLAPSE, + // RTT_COLLAPSEH, + // RTT_COLLAPSEV, + // RTT_COLLAPSEH2, + // RTT_COLLAPSEV2, + // RTT_WARPH, + // RTT_WARPV, + + // RTT_HALF_SOFT, + + RTT_DISPLACE, + RTT_MLAA_COLORS, + + RTT_BLOOM_1024, + RTT_BLOOM_512, + RTT_TMP_512, + RTT_BLOOM_256, + RTT_TMP_256, + RTT_BLOOM_128, + RTT_TMP_128, + + RTT_COUNT +}; + /** * \brief class that creates the irrLicht device and offers higher-level * ways to manage the 3D scene @@ -477,9 +558,9 @@ public: return (m_shaders == NULL ? NULL : m_shaders->m_callbacks[num]); } // ------------------------------------------------------------------------ - inline GLuint getRenderTargetTexture(TypeRTT which) { return m_rtts->getRenderTarget(which); } - inline FrameBuffer& getFBO(TypeFBO which) { return m_rtts->getFBO(which); } - inline GLuint getDepthStencilTexture() { return m_rtts->getDepthStencilTexture(); } + GLuint getRenderTargetTexture(TypeRTT which); + FrameBuffer& getFBO(TypeFBO which); + GLuint getDepthStencilTexture(); // ------------------------------------------------------------------------ inline bool isGLSL() const { return m_glsl; } // ------------------------------------------------------------------------ diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 69ff4bbc7..699246d11 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -18,6 +18,7 @@ #define HEADER_RTTS_HPP #include "graphics/glwrap.hpp" +#include "graphics/irr_driver.hpp" #include "utils/ptr_vector.hpp" #include "utils/leak_check.hpp" @@ -29,86 +30,6 @@ namespace irr { using irr::video::ITexture; -enum TypeRTT -{ - RTT_TMP1 = 0, - RTT_TMP2, - RTT_TMP3, - RTT_TMP4, - RTT_LINEAR_DEPTH, - RTT_NORMAL_AND_DEPTH, - RTT_COLOR, - RTT_LOG_LUMINANCE, - - RTT_HALF1, - RTT_HALF2, - - RTT_QUARTER1, - RTT_QUARTER2, -// RTT_QUARTER3, -// RTT_QUARTER4, - - RTT_EIGHTH1, - RTT_EIGHTH2, - -// RTT_SIXTEENTH1, -// RTT_SIXTEENTH2, - - RTT_SSAO, - -// RTT_COLLAPSE, -// RTT_COLLAPSEH, -// RTT_COLLAPSEV, -// RTT_COLLAPSEH2, -// RTT_COLLAPSEV2, -// RTT_WARPH, -// RTT_WARPV, - -// RTT_HALF_SOFT, - - RTT_DISPLACE, - RTT_MLAA_COLORS, - - RTT_BLOOM_1024, - RTT_BLOOM_512, - RTT_TMP_512, - RTT_BLOOM_256, - RTT_TMP_256, - RTT_BLOOM_128, - RTT_TMP_128, - - RTT_COUNT -}; - - -enum TypeFBO -{ - FBO_SSAO, - FBO_NORMAL_AND_DEPTHS, - FBO_COMBINED_TMP1_TMP2, - FBO_COLORS, - FBO_LOG_LUMINANCE, - FBO_MLAA_COLORS, - FBO_TMP1_WITH_DS, - FBO_TMP2_WITH_DS, - FBO_TMP4, - FBO_LINEAR_DEPTH, - FBO_HALF1, - FBO_HALF2, - FBO_QUARTER1, - FBO_QUARTER2, - FBO_EIGHTH1, - FBO_EIGHTH2, - FBO_DISPLACE, - FBO_BLOOM_1024, - FBO_BLOOM_512, - FBO_TMP_512, - FBO_BLOOM_256, - FBO_TMP_256, - FBO_BLOOM_128, - FBO_TMP_128, - FBO_COUNT -}; class RTT { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index ad21aa710..594748b2b 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1187,6 +1187,8 @@ namespace MeshShader { Program = LoadProgram( GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getLightFactor.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); @@ -1202,7 +1204,7 @@ namespace MeshShader glUseProgram(0); } - void SphereMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const core::vector2df& screen) + void SphereMapShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix) { if (UserConfigParams::m_ubo_disabled) bypassUBO(Program); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 641544a61..747178013 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -254,7 +254,7 @@ public: static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix, const core::vector2df& screen); + static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &InverseModelMatrix); }; class SplattingShader diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index d772e2d4c..fff186f39 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -309,31 +309,13 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelMatrix, const c GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0 + MeshShader::SphereMapShader::TU_tex); - if (!irr_driver->SkyboxCubeMap) - { - glBindTexture(GL_TEXTURE_CUBE_MAP, irr_driver->FakeSkybox); - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; - glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - else - { - glBindTexture(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } + compressTexture(mesh.textures[0], true); + setTexture(MeshShader::SphereMapShader::TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::SphereMapShader::setUniforms(ModelMatrix, InverseModelMatrix, - core::vector2df(float(UserConfigParams::m_width), - float(UserConfigParams::m_height))); + MeshShader::SphereMapShader::setUniforms(ModelMatrix, InverseModelMatrix); assert(mesh.vao_second_pass); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - if (!irr_driver->SkyboxCubeMap) - { - GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; - glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } } void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index cfc59616f..cc7822947 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -2316,8 +2316,8 @@ void Kart::updateFlying() */ void Kart::loadData(RaceManager::KartType type, bool is_animated_model) { - - m_node = m_kart_model->attachModel(is_animated_model); + bool always_animated = (type == RaceManager::KT_PLAYER && race_manager->getNumPlayers() == 1); + m_node = m_kart_model->attachModel(is_animated_model, always_animated); #ifdef DEBUG m_node->setName( (getIdent()+"(lod-node)").c_str() ); diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 87daa1928..9870fb957 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -325,7 +325,7 @@ KartModel* KartModel::makeCopy() /** Attach the kart model and wheels to the scene node. * \return the node with the model attached */ -scene::ISceneNode* KartModel::attachModel(bool animated_models) +scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_animated) { assert(!m_is_master); @@ -342,10 +342,22 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models) // as animated mesh are not cheap to render use frustum box culling node->setAutomaticCulling(scene::EAC_FRUSTUM_BOX); - lod_node->add(20, node, true); - scene::ISceneNode* static_model = attachModel(false); - lod_node->add(100, static_model, true); - m_animated_node = static_cast(node); + if (always_animated) + { + // give a huge LOD distance for the player's kart. the reason is that it should + // use its animations for the shadow pass too, where the camera can be quite far + lod_node->add(10000, node, true); + scene::ISceneNode* static_model = attachModel(false, false); + lod_node->add(10001, static_model, true); + m_animated_node = static_cast(node); + } + else + { + lod_node->add(20, node, true); + scene::ISceneNode* static_model = attachModel(false, false); + lod_node->add(100, static_model, true); + m_animated_node = static_cast(node); + } attachHat(); @@ -363,7 +375,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models) // Become the owner of the wheels for(unsigned int i=0; i<4; i++) { - if(!m_wheel_model[i]) continue; + if (!m_wheel_model[i] || !m_wheel_node[i]) continue; m_wheel_node[i]->setParent(lod_node); } diff --git a/src/karts/kart_model.hpp b/src/karts/kart_model.hpp index 9ea00d42b..3be914685 100644 --- a/src/karts/kart_model.hpp +++ b/src/karts/kart_model.hpp @@ -237,7 +237,7 @@ public: float wheel_radius); void finishedRace(); scene::ISceneNode* - attachModel(bool animatedModels); + attachModel(bool animatedModels, bool always_animated); // ------------------------------------------------------------------------ /** Returns the animated mesh of this kart model. */ scene::IAnimatedMesh* diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index d251c56e4..f5d2e3749 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -330,7 +330,7 @@ void FeatureUnlockedCutScene::init() KartModel *kart_model = m_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy(); m_all_kart_models.push_back(kart_model); - m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true); + m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true, false); kart_model->setAnimation(KartModel::AF_DEFAULT); float susp[4]={0,0,0,0}; kart_model->update(0.0f, 0.0f, 0.0f, susp, 0.0f); diff --git a/src/states_screens/grand_prix_lose.cpp b/src/states_screens/grand_prix_lose.cpp index 06149ec1e..8f855108a 100644 --- a/src/states_screens/grand_prix_lose.cpp +++ b/src/states_screens/grand_prix_lose.cpp @@ -243,7 +243,7 @@ void GrandPrixLose::setKarts(std::vector ident_arg) { KartModel* kart_model = kart->getKartModelCopy(); m_all_kart_models.push_back(kart_model); - scene::ISceneNode* kart_main_node = kart_model->attachModel(false); + scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); core::vector3df kart_pos(m_kart_x + n*DISTANCE_BETWEEN_KARTS, m_kart_y, diff --git a/src/states_screens/grand_prix_win.cpp b/src/states_screens/grand_prix_win.cpp index 93b83dea6..64a96799c 100644 --- a/src/states_screens/grand_prix_win.cpp +++ b/src/states_screens/grand_prix_win.cpp @@ -355,7 +355,7 @@ void GrandPrixWin::setKarts(const std::string idents_arg[3]) KartModel* kart_model = kp->getKartModelCopy(); m_all_kart_models.push_back(kart_model); - scene::ISceneNode* kart_main_node = kart_model->attachModel(false); + scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); m_kart_x[i] = KARTS_X + i*KARTS_DELTA_X; m_kart_y[i] = INITIAL_Y + KARTS_DELTA_Y;