From 52ebb9a300d8dd96ddfc539e7c00e8753fcbf9f8 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sat, 21 Dec 2013 14:36:40 +0000 Subject: [PATCH 001/412] Little value for the distance of animated kart. You won't notice the difference (expect that the christmas hat isn't displayed with the non animated version git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14742 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/karts/kart_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index d58ad51f2..881bb120c 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -342,7 +342,7 @@ 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(50, node, true); + lod_node->add(20, node, true); scene::ISceneNode* static_model = attachModel(false); lod_node->add(500, static_model, true); m_animated_node = static_cast(node); From 1a2d26b89412bc3e254302fb40dc78d7f015e2a7 Mon Sep 17 00:00:00 2001 From: deveee Date: Sat, 21 Dec 2013 17:04:46 +0000 Subject: [PATCH 002/412] - Fixed crash when goal is scored after time limit - Set time max value to 15 - playing one game 45 minutes doesn't have a sense - Remember time value in user config - Little beter look of soccer setup - Set goal-limit mode as default git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14743 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/gui/soccer_setup.stkgui | 33 +++++++++++----------- src/config/user_config.hpp | 3 ++ src/modes/soccer_world.cpp | 3 ++ src/states_screens/soccer_setup_screen.cpp | 13 ++++++--- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/data/gui/soccer_setup.stkgui b/data/gui/soccer_setup.stkgui index d0ef77a63..314e9d269 100644 --- a/data/gui/soccer_setup.stkgui +++ b/data/gui/soccer_setup.stkgui @@ -2,37 +2,36 @@ -
+
-
+
+ I18N="In soccer setup menu" text="Number of goals to win" text_align="left" /> - +
- - -
- +
- + I18N="In soccer setup menu" text="Maximum time (min.)" text_align="left" /> + + +
+ +
+ + - -
- - + - - - +
diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index df2798971..81d59034f 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -368,6 +368,9 @@ namespace UserConfigParams PARAM_PREFIX IntUserConfigParam m_num_goals PARAM_DEFAULT( IntUserConfigParam(3, "numgoals", &m_race_setup_group, "Default number of goals in soccer mode.") ); + PARAM_PREFIX IntUserConfigParam m_soccer_time_limit + PARAM_DEFAULT( IntUserConfigParam(3, "soccer-time-limit", + &m_race_setup_group, "Limit in soccer time mode.") ); PARAM_PREFIX IntUserConfigParam m_difficulty PARAM_DEFAULT( IntUserConfigParam(0, "difficulty", &m_race_setup_group, diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index 9d271485d..3ed770a72 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -162,6 +162,9 @@ void SoccerWorld::update(float dt) //----------------------------------------------------------------------------- void SoccerWorld::onCheckGoalTriggered(bool first_goal) { + if (isRaceOver()) + return; + if (m_can_score_points) { m_team_goals[first_goal ? 0 : 1]++; diff --git a/src/states_screens/soccer_setup_screen.cpp b/src/states_screens/soccer_setup_screen.cpp index 24a80ea62..604e06838 100644 --- a/src/states_screens/soccer_setup_screen.cpp +++ b/src/states_screens/soccer_setup_screen.cpp @@ -198,22 +198,26 @@ void SoccerSetupScreen::init() if (UserConfigParams::m_num_goals <= 0) UserConfigParams::m_num_goals = 3; + + if (UserConfigParams::m_soccer_time_limit <= 0) + UserConfigParams::m_soccer_time_limit = 3; SpinnerWidget* goalamount = getWidget("goalamount"); goalamount->setValue(UserConfigParams::m_num_goals); - goalamount->setDeactivated(); + goalamount->setActivated(); SpinnerWidget* timeAmount = getWidget("timeamount"); - timeAmount->setValue(timeAmount->getMin()); + timeAmount->setValue(UserConfigParams::m_soccer_time_limit); + timeAmount->setDeactivated(); CheckBoxWidget* timeEnabled = getWidget("time_enabled"); + timeEnabled->setState(false); // Set focus on "continue" - ButtonWidget* bt_continue = getWidget("continue"); + ButtonWidget* bt_continue = getWidget("continue"); bt_continue->setFocusForPlayer(PLAYER_ID_GAME_MASTER); // We need players to be able to choose their teams - //~ input_manager->getDeviceList()->setAssignMode(ASSIGN); input_manager->setMasterPlayerOnly(false); // This flag will cause that a 'fire' event will be mapped to 'select' (if @@ -231,6 +235,7 @@ void SoccerSetupScreen::tearDown() input_manager->getDeviceList()->mapFireToSelect(false); UserConfigParams::m_num_goals = getWidget("goalamount")->getValue(); + UserConfigParams::m_soccer_time_limit = getWidget("timeamount")->getValue(); // Remove all ModelViewWidgets we created manually PtrVector& children = central_div->getChildren(); From 43d919ec6aebf9649bd3d5ee6be04df76318ffd8 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sun, 22 Dec 2013 00:08:17 +0000 Subject: [PATCH 003/412] Reduced the LOD distance of the kart. The player won't notice since he is focused on the race git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14744 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/karts/kart_model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 881bb120c..bcb3f224a 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -344,7 +344,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models) lod_node->add(20, node, true); scene::ISceneNode* static_model = attachModel(false); - lod_node->add(500, static_model, true); + lod_node->add(100, static_model, true); m_animated_node = static_cast(node); attachHat(); From 07abdebbfa0c986d7abb7678d20aadcde6bf61cd Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 22 Dec 2013 03:03:07 +0000 Subject: [PATCH 007/412] Add range check for ssao + fix for nvidia git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14748 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index f5fd32f77..e6c496027 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -6,9 +6,8 @@ uniform mat4 invprojm; uniform mat4 projm; uniform vec4 samplePoints[16]; -const float strengh = 1.; -const float radius = 0.1f; -const float threshold = 0.1; +const float strengh = 4.; +const float radius = .1f; #define SAMPLES 16 @@ -33,7 +32,9 @@ void main(void) // get the normal of current fragment vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0)); - if (curdepth > 0.99) discard; + // Workaround for nvidia and skyboxes + float len = dot(vec3(1.0), abs(cur.xyz)); + if (len < 0.2 || curdepth > 0.999) discard; vec3 tangent = normalize(cross(norm, norm.yzx)); vec3 bitangent = cross(norm, tangent); @@ -47,9 +48,12 @@ void main(void) // get the depth of the occluder fragment float occluderFragmentDepth = decdepth(vec4(texture2D(depth, (sampleProj.xy * 0.5) + 0.5).xyz, 0.0)); + // Position of the occluder fragment in worldSpace + vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); + occluderPos /= occluderPos.w; float depthDifference = sampleProj.z - (2. * occluderFragmentDepth - 1.0); - bl += (abs(depthDifference) < threshold) ? step(0., depthDifference) : 0.0; + bl += (distance(occluderPos, FragPos) < radius) ? step(0., depthDifference) : 0.0; } // output the result From bc2eefe1dc28a69d6eba7ae4f60d98a7b8c6e07c Mon Sep 17 00:00:00 2001 From: deveee Date: Sun, 22 Dec 2013 16:14:26 +0000 Subject: [PATCH 009/412] Fixed displaying more than 2 karts in soccer setup screen git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14751 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/states_screens/soccer_setup_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/states_screens/soccer_setup_screen.cpp b/src/states_screens/soccer_setup_screen.cpp index 604e06838..20f2b61b1 100644 --- a/src/states_screens/soccer_setup_screen.cpp +++ b/src/states_screens/soccer_setup_screen.cpp @@ -468,7 +468,7 @@ void SoccerSetupScreen::updateKartViewsLayout() const int cur_col = cur_kart_per_team[team] % nb_columns; int nb_karts_in_this_row = (nb_karts_per_team[team] - cur_row*nb_columns) % nb_columns; - if(nb_karts_in_this_row == 0) + if(nb_karts_in_this_row == 0 || nb_karts_per_team[team] > 1) nb_karts_in_this_row = nb_columns; // TODO: not sure of the computation here... const int pos_x = center_x_per_team[team] + cur_col*kart_view_size - nb_karts_in_this_row*kart_view_size/2; cur_kart_per_team[team]++; From 8b76971a547c878d2fe496420eaf9322f24dc15d Mon Sep 17 00:00:00 2001 From: deveee Date: Sun, 22 Dec 2013 17:44:09 +0000 Subject: [PATCH 010/412] Minor changes in soccer setup gui git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14752 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/gui/soccer_setup.stkgui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/gui/soccer_setup.stkgui b/data/gui/soccer_setup.stkgui index 314e9d269..d876e93a7 100644 --- a/data/gui/soccer_setup.stkgui +++ b/data/gui/soccer_setup.stkgui @@ -2,7 +2,7 @@ -
+
@@ -34,7 +34,7 @@
- +
From 45db87de8a51822d14c49f8823ef34f751f2b85f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 16:59:55 +0000 Subject: [PATCH 011/412] Merge normals and depth RTT into a single one git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14754 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/fog.frag | 6 +----- data/shaders/grass.frag | 19 +--------------- data/shaders/normalmap.frag | 10 +-------- data/shaders/objectpass.frag | 20 +---------------- data/shaders/objectpass_ref.frag | 18 +--------------- data/shaders/objectpass_rimlit.frag | 19 +--------------- data/shaders/objectpass_spheremap.frag | 20 +---------------- data/shaders/pointlight.frag | 7 +----- data/shaders/splatting.frag | 21 +----------------- data/shaders/ssao.frag | 10 ++------- data/shaders/sunlight.frag | 7 +----- src/graphics/callbacks.cpp | 29 ------------------------- src/graphics/irr_driver.cpp | 3 +-- src/graphics/light.cpp | 3 +-- src/graphics/post_processing.cpp | 30 +++++++++++--------------- src/graphics/render.cpp | 3 +-- src/graphics/rtts.cpp | 9 +++----- src/graphics/rtts.hpp | 6 ++---- src/graphics/shadow_importance.cpp | 3 +-- src/graphics/sun.cpp | 3 +-- 20 files changed, 35 insertions(+), 211 deletions(-) diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag index f2ed93327..6ac828d43 100644 --- a/data/shaders/fog.frag +++ b/data/shaders/fog.frag @@ -9,13 +9,9 @@ uniform vec3 col; uniform vec3 campos; uniform mat4 ipvmat; -float decdepth(vec4 rgba) { - return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); -} - void main() { - float z = decdepth(vec4(texture2D(tex, gl_TexCoord[0].xy).xyz, 0.0)); + float z = texture2D(tex, gl_TexCoord[0].xy).a; vec3 tmp = vec3(gl_TexCoord[0].xy, z); tmp = tmp * 2.0 - 1.0; diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index cdf9601ac..109a87a01 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -1,30 +1,13 @@ #version 130 - uniform float far; uniform float objectid; uniform sampler2D tex; noperspective in vec3 nor; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { vec4 color = texture2D(tex, gl_TexCoord[0].st); - - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - - gl_FragData[0] = color; - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 19cd4c080..5d1f61b76 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -6,13 +6,6 @@ noperspective in vec3 tangent; noperspective in vec3 bitangent; noperspective in vec3 normal; -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { // normal in Tangent Space @@ -28,6 +21,5 @@ void main() gl_FragData[0] = texture2D (texture, gl_TexCoord[0].st); - gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, 1.0); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, 0.0); + gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag index 6c01dff40..9ae602623 100644 --- a/data/shaders/objectpass.frag +++ b/data/shaders/objectpass.frag @@ -1,29 +1,12 @@ #version 130 uniform sampler2D tex; uniform sampler2D lighttex; -uniform float far; uniform int hastex; uniform int haslightmap; -uniform float objectid; noperspective in vec3 nor; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { - - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - vec4 light = vec4(1.0); if (haslightmap != 0) { @@ -35,7 +18,6 @@ void main() { else gl_FragData[0] = gl_Color; - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag index 1256a6715..6c9bc83dc 100644 --- a/data/shaders/objectpass_ref.frag +++ b/data/shaders/objectpass_ref.frag @@ -1,27 +1,12 @@ #version 130 uniform sampler2D tex; -uniform float far; uniform int hastex; uniform float objectid; noperspective in vec3 nor; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - //if (hastex != 0) { vec4 col = texture2D(tex, gl_TexCoord[0].xy); @@ -33,7 +18,6 @@ void main() { // gl_FragData[0] = gl_Color; //} - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag index 49f7e9699..6bdb15754 100644 --- a/data/shaders/objectpass_rimlit.frag +++ b/data/shaders/objectpass_rimlit.frag @@ -1,6 +1,5 @@ #version 130 uniform sampler2D tex; -uniform float far; uniform int hastex; uniform float objectid; @@ -8,22 +7,7 @@ noperspective in vec3 nor; noperspective in vec3 eyenor; noperspective in vec3 viewpos; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { - - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - float rim = 1.0 - dot(eyenor, viewpos); rim = smoothstep(0.5, 1.5, rim) * 0.35; @@ -40,7 +24,6 @@ void main() { gl_FragData[0] = gl_Color + vec4(vec3(rim), 0.0); } - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 3a47f7794..c2a07952b 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -1,28 +1,11 @@ #version 130 uniform sampler2D tex; -uniform float far; -uniform float objectid; noperspective in vec3 eyenor; noperspective in vec3 viewpos; noperspective in vec3 nor; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { - - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - // Calculate the spherical UV const vec3 forward = vec3(0.0, 0.0, 1.0); @@ -38,6 +21,5 @@ void main() { gl_FragData[0] = detail0 * gl_Color; - gl_FragData[1] = vec4(nor, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(nor, gl_FragCoord.z); } diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 4908709d7..91ccf6b5e 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -1,5 +1,4 @@ uniform sampler2D ntex; -uniform sampler2D dtex; uniform vec3 center; uniform vec3 col; @@ -8,13 +7,9 @@ uniform float spec; uniform vec2 screen; uniform mat4 invproj; -float decdepth(vec4 rgba) { - return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); -} - void main() { vec2 texc = gl_FragCoord.xy / screen; - float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0)); + float z = texture2D(ntex, texc).a; vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; xpos = invproj * xpos; diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index 588199f1e..7ab7dcc89 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -1,7 +1,4 @@ #version 130 -uniform float far; -uniform float objectid; - uniform sampler2D tex_layout; uniform sampler2D tex_detail0; uniform sampler2D tex_detail1; @@ -11,22 +8,7 @@ uniform sampler2D tex_detail3; noperspective in vec3 nor; -const float near = 1.0; - -vec4 encdepth(float v) { - vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; - enc = fract(enc); - enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0); - return enc; -} - void main() { - - float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near)); - - // Tune for better inside range without losing outdoors - linear_z *= 2.0; - // Splatting part vec4 splatting = texture2D(tex_layout, gl_TexCoord[1].st); vec4 detail0 = texture2D(tex_detail0, gl_TexCoord[0].st); @@ -45,6 +27,5 @@ void main() { gl_FragData[0] = splatted; - gl_FragData[1] = vec4(normalize(nor) * 0.5 + 0.5, linear_z); - gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + gl_FragData[1] = vec4(normalize(nor) * 0.5 + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index e6c496027..27fb2b140 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,7 +1,5 @@ #version 120 - uniform sampler2D normals_and_depth; -uniform sampler2D depth; uniform mat4 invprojm; uniform mat4 projm; uniform vec4 samplePoints[16]; @@ -13,10 +11,6 @@ const float radius = .1f; const float invSamples = strengh / SAMPLES; -float decdepth(vec4 rgba) { - return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); -} - void main(void) { // A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4 @@ -26,7 +20,7 @@ void main(void) vec2 uv = gl_TexCoord[0].xy; vec4 cur = texture2D(normals_and_depth, uv); - float curdepth = decdepth(vec4(texture2D(depth, uv).xyz, 0.0)); + float curdepth = texture2D(normals_and_depth, uv).a; vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); FragPos /= FragPos.w; @@ -47,7 +41,7 @@ void main(void) sampleProj /= sampleProj.w; // get the depth of the occluder fragment - float occluderFragmentDepth = decdepth(vec4(texture2D(depth, (sampleProj.xy * 0.5) + 0.5).xyz, 0.0)); + float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; // Position of the occluder fragment in worldSpace vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); occluderPos /= occluderPos.w; diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index 9edee8d59..fb0009934 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -1,5 +1,4 @@ uniform sampler2D ntex; -uniform sampler2D dtex; uniform sampler2D cloudtex; uniform vec3 center; @@ -9,14 +8,10 @@ uniform mat4 invproj; uniform int hasclouds; uniform vec2 wind; -float decdepth(vec4 rgba) { - return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); -} - void main() { vec2 texc = gl_FragCoord.xy / screen; - float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0)); + float z = texture2D(ntex, texc).a; if (z < 0.03) { diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index dacf451f7..9df107192 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -109,16 +109,6 @@ void WaterShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int) void GrassShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int userData) { - - const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue(); - srv->setVertexShaderConstant("far", &camfar, 1); - - float objectid = 0; - const stringc name = mat.TextureLayer[0].Texture->getName().getPath(); - objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f; - srv->setVertexShaderConstant("objectid", &objectid, 1); - - IVideoDriver * const drv = srv->getVideoDriver(); const core::vector3df pos = drv->getTransform(ETS_WORLD).getTranslation(); const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; @@ -165,14 +155,6 @@ void ColorLevelsProvider::OnSetConstants(IMaterialRendererServices *srv, int use void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int) { - const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue(); - srv->setVertexShaderConstant("far", &camfar, 1); - - float objectid = 0; - const stringc name = mat.TextureLayer[0].Texture->getName().getPath(); - objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f; - srv->setVertexShaderConstant("objectid", &objectid, 1); - if (!firstdone) { s32 tex_layout = 1; @@ -324,23 +306,12 @@ void GlowProvider::OnSetConstants(IMaterialRendererServices *srv, int) void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int) { - const float camfar = irr_driver->getSceneManager()->getActiveCamera()->getFarValue(); - srv->setVertexShaderConstant("far", &camfar, 1); - const int hastex = mat.TextureLayer[0].Texture != NULL; srv->setVertexShaderConstant("hastex", &hastex, 1); const int haslightmap = mat.TextureLayer[1].Texture != NULL; srv->setVertexShaderConstant("haslightmap", &haslightmap, 1); - float objectid = 0; - if (hastex) - { - const stringc name = mat.TextureLayer[0].Texture->getName().getPath(); - objectid = shash8((const u8 *) name.c_str(), name.size()) / 255.0f; - } - srv->setVertexShaderConstant("objectid", &objectid, 1); - //if (!firstdone) // Can't use the firstdone optimization, as this callback is used for multiple shaders { diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index cc05f05fc..d56292c5d 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -424,8 +424,7 @@ void IrrDriver::initDevice() m_mrt.clear(); m_mrt.reallocate(3); m_mrt.push_back(m_rtts->getRTT(RTT_COLOR)); - m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL)); - m_mrt.push_back(m_rtts->getRTT(RTT_DEPTH)); + m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH)); irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); gl_driver->extGlGenQueries(1, &m_lensflare_query); diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index bbc0d0da6..09d9465d1 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -43,8 +43,7 @@ LightNode::LightNode(scene::ISceneManager* mgr, float radius, float r, float g, mat.Lighting = false; mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT); - mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); - mat.setTexture(1, irr_driver->getRTT(RTT_DEPTH)); + mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) { diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index e4340f7c5..362f1d64d 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -217,16 +217,13 @@ void PostProcessing::renderSolid(const u32 cam) GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> getCallback(ES_GAUSSIAN3H); - const TypeRTT curssao = tick ? RTT_SSAO2 : RTT_SSAO1; - if (UserConfigParams::m_ssao == 1) // SSAO low { m_material.MaterialType = irr_driver->getShader(ES_SSAO); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); - m_material.setTexture(1, irr_driver->getRTT(RTT_DEPTH)); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - drv->setRenderTarget(irr_driver->getRTT(curssao), true, false, + drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, SColor(255, 255, 255, 255)); drawQuad(cam, m_material); @@ -236,21 +233,21 @@ void PostProcessing::renderSolid(const u32 cam) gacb->setResolution(UserConfigParams::m_width / 4, UserConfigParams::m_height / 4); m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(curssao)); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); drawQuad(cam, m_material); m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(curssao), false, false); + drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); drawQuad(cam, m_material); } // Overlay m_material.MaterialType = EMT_ONETEXTURE_BLEND; - m_material.setTexture(0, irr_driver->getRTT(curssao)); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); m_material.setTexture(1, 0); m_material.BlendOperation = EBO_ADD; m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO); @@ -264,10 +261,9 @@ void PostProcessing::renderSolid(const u32 cam) } else if (UserConfigParams::m_ssao == 2) // SSAO high { m_material.MaterialType = irr_driver->getShader(ES_SSAO); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); - m_material.setTexture(1, irr_driver->getRTT(RTT_DEPTH)); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - drv->setRenderTarget(irr_driver->getRTT(curssao), true, false, + drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, SColor(255, 255, 255, 255)); drawQuad(cam, m_material); @@ -277,21 +273,21 @@ void PostProcessing::renderSolid(const u32 cam) gacb->setResolution(UserConfigParams::m_width, UserConfigParams::m_height); m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(curssao)); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); drawQuad(cam, m_material); m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - drv->setRenderTarget(irr_driver->getRTT(curssao), false, false); + drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); drawQuad(cam, m_material); } // Overlay m_material.MaterialType = EMT_ONETEXTURE_BLEND; - m_material.setTexture(0, irr_driver->getRTT(curssao)); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); m_material.setTexture(1, 0); m_material.BlendOperation = EBO_ADD; m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO); @@ -306,7 +302,7 @@ void PostProcessing::renderSolid(const u32 cam) if (World::getWorld()->getTrack()->isFogEnabled()) { m_material.MaterialType = irr_driver->getShader(ES_FOG); - m_material.setTexture(0, irr_driver->getRTT(RTT_DEPTH)); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); // Overlay m_material.BlendOperation = EBO_ADD; @@ -733,11 +729,11 @@ void PostProcessing::render() if (irr_driver->getNormals()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); } else if (irr_driver->getSSAOViz()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO1)); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); } else if (irr_driver->getShadowViz()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index d7c53fbdd..84b73f7f5 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -139,8 +139,7 @@ void IrrDriver::renderGLSL(float dt) world->getClearColor()); // Clear normal and depth to zero - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_NORMAL), true, false, video::SColor(0,0,0,0)); - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_DEPTH), true, false, video::SColor(0,0,0,0)); + m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH), true, false, video::SColor(0,0,0,0)); irr_driver->getVideoDriver()->enableMaterial2D(); RaceGUIBase *rg = world->getRaceGUI(); diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 33789aff2..45c0efee8 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -66,8 +66,7 @@ RTT::RTT() rtts[RTT_TMP2] = drv->addRenderTargetTexture(res, "rtt.tmp2", ECF_A8R8G8B8, stencil); rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A8R8G8B8, stencil); rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_A8R8G8B8, stencil); - rtts[RTT_DEPTH] = drv->addRenderTargetTexture(res, "rtt.depth", ECF_A8R8G8B8, stencil); - rtts[RTT_NORMAL] = drv->addRenderTargetTexture(res, "rtt.normal", ECF_A32B32G32R32F, stencil); + rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_A32B32G32R32F, stencil); rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A8R8G8B8, stencil); rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A8R8G8B8, stencil); @@ -83,8 +82,7 @@ RTT::RTT() rtts[RTT_SIXTEENTH1] = drv->addRenderTargetTexture(sixteenth, "rtt.s1", ECF_A8R8G8B8, stencil); rtts[RTT_SIXTEENTH2] = drv->addRenderTargetTexture(sixteenth, "rtt.s2", ECF_A8R8G8B8, stencil); - rtts[RTT_SSAO1] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao1", ECF_A8R8G8B8, stencil); - rtts[RTT_SSAO2] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao2", ECF_A8R8G8B8, stencil); + rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_A8R8G8B8, stencil); rtts[RTT_SHADOW] = drv->addRenderTargetTexture(shadowsize, "rtt.shadow", ECF_A8R8G8B8, stencil); rtts[RTT_WARPV] = drv->addRenderTargetTexture(warpvsize, "rtt.warpv", ECF_A8R8G8B8, stencil); @@ -125,8 +123,7 @@ RTT::RTT() // Clear those that should be cleared drv->beginScene(false, false); - drv->setRenderTarget(rtts[RTT_SSAO1], true, false, SColor(255, 255, 255, 255)); - drv->setRenderTarget(rtts[RTT_SSAO2], true, false, SColor(255, 255, 255, 255)); + drv->setRenderTarget(rtts[RTT_SSAO], true, false, SColor(255, 255, 255, 255)); drv->setRenderTarget(rtts[RTT_COLLAPSEV], true, false); drv->setRenderTarget(rtts[RTT_COLLAPSEH], true, false); diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 8000c02b9..0b91b9087 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -31,8 +31,7 @@ enum TypeRTT RTT_TMP2, RTT_TMP3, RTT_TMP4, - RTT_DEPTH, - RTT_NORMAL, + RTT_NORMAL_AND_DEPTH, RTT_COLOR, RTT_HALF1, @@ -48,8 +47,7 @@ enum TypeRTT RTT_SIXTEENTH1, RTT_SIXTEENTH2, - RTT_SSAO1, - RTT_SSAO2, + RTT_SSAO, RTT_SHADOW, RTT_COLLAPSE, diff --git a/src/graphics/shadow_importance.cpp b/src/graphics/shadow_importance.cpp index 9f89a8cac..5a25f1a01 100644 --- a/src/graphics/shadow_importance.cpp +++ b/src/graphics/shadow_importance.cpp @@ -45,8 +45,7 @@ public: mat.ZWriteEnable = false; mat.MaterialType = irr_driver->getShader(ES_SHADOW_IMPORTANCE); - mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); - mat.setTexture(1, irr_driver->getRTT(RTT_DEPTH)); + mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); mat.setTexture(2, irr_driver->getRTT(RTT_COLOR)); mat.setFlag(EMF_BILINEAR_FILTER, false); diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index 514aec28e..462e4a89f 100644 --- a/src/graphics/sun.cpp +++ b/src/graphics/sun.cpp @@ -43,8 +43,7 @@ SunNode::SunNode(scene::ISceneManager* mgr, float r, float g, float b): SMaterial &m = sq->getMaterial(); m.MaterialType = irr_driver->getShader(ES_SUNLIGHT); - m.setTexture(0, irr_driver->getRTT(RTT_NORMAL)); - m.setTexture(1, irr_driver->getRTT(RTT_DEPTH)); + m.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); m.setTexture(2, irr_driver->getTexture(file_manager->getAsset(FileManager::TEXTURE,"cloudshadow.png"))); m.setFlag(EMF_BILINEAR_FILTER, false); m.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE); From 5db670588913ca4e9fb76cdd0c115c3fe5275c63 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 17:00:27 +0000 Subject: [PATCH 012/412] Move SSAO code into renderLight in order to use a lighter rtt (8 bits instead of 32) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14755 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/lightblend.frag | 9 +-- src/graphics/callbacks.cpp | 6 +- src/graphics/post_processing.cpp | 100 ------------------------------- src/graphics/render.cpp | 45 +++++++++++++- src/graphics/rtts.cpp | 5 +- src/graphics/rtts.hpp | 1 + 6 files changed, 56 insertions(+), 110 deletions(-) diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index e181d4197..101f2e9e0 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -1,4 +1,5 @@ -uniform sampler2D tex; +uniform sampler2D diffuse_and_spec; +uniform sampler2D ambient_occlusion; uniform vec3 ambient; //uniform sampler2D spectex; @@ -6,10 +7,10 @@ void main() { vec2 texc = gl_TexCoord[0].xy; - vec4 col = texture2D(tex, texc); - //vec4 specular = texture2D(spectex, texc); + vec4 col = texture2D(diffuse_and_spec, texc); + float ao = texture2D(ambient_occlusion, texc).x; - col.xyz += ambient; + col.xyz += ao * ambient; float spec = col.a - 0.05; //spec *= specular.a; col.xyz += spec * col.xyz; diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 9df107192..9bc7991a3 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -332,8 +332,10 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) float ambient[3] = { s.r, s.g, s.b }; srv->setVertexShaderConstant("ambient", ambient, 3); - //int spectex = 1; - //srv->setVertexShaderConstant("spectex", &spectex, 1); + int tex = 0; + srv->setVertexShaderConstant("diffuse_and_spec", &tex, 1); + tex = 1; + srv->setVertexShaderConstant("ambient_occlusion", &tex, 1); } //------------------------------------- diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 362f1d64d..519c2cc5d 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -203,102 +203,7 @@ void PostProcessing::renderSolid(const u32 cam) { if (!irr_driver->isGLSL()) return; - // Early out: do nothing if at all possible - if (UserConfigParams::m_ssao < 1 && !World::getWorld()->getTrack()->isFogEnabled()) - return; - - static u8 tick = 0; - IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setTransform(ETS_WORLD, core::IdentityMatrix); - drv->setTransform(ETS_VIEW, core::IdentityMatrix); - drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); - - GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> - getCallback(ES_GAUSSIAN3H); - - - if (UserConfigParams::m_ssao == 1) // SSAO low - { - m_material.MaterialType = irr_driver->getShader(ES_SSAO); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, - SColor(255, 255, 255, 255)); - - drawQuad(cam, m_material); - - // Blur it to reduce noise. - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); - - drawQuad(cam, m_material); - } - - // Overlay - m_material.MaterialType = EMT_ONETEXTURE_BLEND; - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - m_material.setTexture(1, 0); - m_material.BlendOperation = EBO_ADD; - m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO); - - drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - m_material.MaterialTypeParam = 0; - - } else if (UserConfigParams::m_ssao == 2) // SSAO high - { - m_material.MaterialType = irr_driver->getShader(ES_SSAO); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, - SColor(255, 255, 255, 255)); - - drawQuad(cam, m_material); - - // Blur it to reduce noise. - { - gacb->setResolution(UserConfigParams::m_width, - UserConfigParams::m_height); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - drv->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); - - drawQuad(cam, m_material); - } - - // Overlay - m_material.MaterialType = EMT_ONETEXTURE_BLEND; - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - m_material.setTexture(1, 0); - m_material.BlendOperation = EBO_ADD; - m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_DST_COLOR, EBF_ZERO); - - drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - m_material.MaterialTypeParam = 0; - } - if (World::getWorld()->getTrack()->isFogEnabled()) { m_material.MaterialType = irr_driver->getShader(ES_FOG); @@ -314,11 +219,6 @@ void PostProcessing::renderSolid(const u32 cam) m_material.BlendOperation = EBO_NONE; m_material.MaterialTypeParam = 0; } - - - - tick++; - tick %= 2; } // ---------------------------------------------------------------------------- diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 84b73f7f5..8dedd1050 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -765,6 +765,47 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, } // for i in lights + // Handle SSAO + SMaterial m_material; + GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> + getCallback(ES_GAUSSIAN3H); + + m_material.ZWriteEnable = false; + m_material.MaterialType = irr_driver->getShader(ES_SSAO); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + + m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, + SColor(255, 255, 255, 255)); + + m_post_processing->drawQuad(cam, m_material); + + // Blur it to reduce noise. + if(UserConfigParams::m_ssao == 1) { + gacb->setResolution(UserConfigParams::m_width / 4, + UserConfigParams::m_height / 4); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); + m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_QUARTER4), true, false); + m_post_processing->drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER4)); + m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); + m_post_processing->drawQuad(cam, m_material); + } else if (UserConfigParams::m_ssao == 2) { + gacb->setResolution(UserConfigParams::m_width, + UserConfigParams::m_height); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); + m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_TMP4), true, false); + m_post_processing->drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); + m_material.setTexture(0, irr_driver->getRTT(RTT_TMP4)); + m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); + m_post_processing->drawQuad(cam, m_material); + } + // Blend lights to the image video::SMaterial lightmat; lightmat.Lighting = false; @@ -773,8 +814,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, lightmat.setFlag(video::EMF_BILINEAR_FILTER, false); lightmat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); - // Specular mapping - //lightmat.setTexture(1, m_rtts->getRTT(RTT_COLOR)); + // Apply ambient occlusion + lightmat.setTexture(1, m_rtts->getRTT(RTT_SSAO)); lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_DST_COLOR, video::EBF_ZERO); diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 45c0efee8..0a52c7431 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -65,7 +65,7 @@ RTT::RTT() } rtts[RTT_TMP2] = drv->addRenderTargetTexture(res, "rtt.tmp2", ECF_A8R8G8B8, stencil); rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A8R8G8B8, stencil); - rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_A8R8G8B8, stencil); + rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R8, stencil); rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_A32B32G32R32F, stencil); rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A8R8G8B8, stencil); @@ -75,6 +75,7 @@ RTT::RTT() rtts[RTT_QUARTER1] = drv->addRenderTargetTexture(quarter, "rtt.q1", ECF_A8R8G8B8, stencil); rtts[RTT_QUARTER2] = drv->addRenderTargetTexture(quarter, "rtt.q2", ECF_A8R8G8B8, stencil); rtts[RTT_QUARTER3] = drv->addRenderTargetTexture(quarter, "rtt.q3", ECF_A8R8G8B8, stencil); + rtts[RTT_QUARTER4] = drv->addRenderTargetTexture(quarter, "rtt.q4", ECF_R8, stencil); rtts[RTT_EIGHTH1] = drv->addRenderTargetTexture(eighth, "rtt.e1", ECF_A8R8G8B8, stencil); rtts[RTT_EIGHTH2] = drv->addRenderTargetTexture(eighth, "rtt.e2", ECF_A8R8G8B8, stencil); @@ -82,7 +83,7 @@ RTT::RTT() rtts[RTT_SIXTEENTH1] = drv->addRenderTargetTexture(sixteenth, "rtt.s1", ECF_A8R8G8B8, stencil); rtts[RTT_SIXTEENTH2] = drv->addRenderTargetTexture(sixteenth, "rtt.s2", ECF_A8R8G8B8, stencil); - rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_A8R8G8B8, stencil); + rtts[RTT_SSAO] = drv->addRenderTargetTexture(ssaosize, "rtt.ssao", ECF_R8, stencil); rtts[RTT_SHADOW] = drv->addRenderTargetTexture(shadowsize, "rtt.shadow", ECF_A8R8G8B8, stencil); rtts[RTT_WARPV] = drv->addRenderTargetTexture(warpvsize, "rtt.warpv", ECF_A8R8G8B8, stencil); diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 0b91b9087..29e7f5257 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -40,6 +40,7 @@ enum TypeRTT RTT_QUARTER1, RTT_QUARTER2, RTT_QUARTER3, + RTT_QUARTER4, RTT_EIGHTH1, RTT_EIGHTH2, From 34d83859cd9aff669da3d0d64b918e3ac4efe3ae Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 17:00:34 +0000 Subject: [PATCH 013/412] Add support for specular light Note that specular light is applied unconditionnaly, thus every object will shine. TODO : Specular map should be defined using texture or a material flag. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14756 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/lightblend.frag | 11 +++-------- data/shaders/pointlight.frag | 11 +++++------ data/shaders/sunlight.frag | 15 +++++++-------- src/graphics/render.cpp | 2 +- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index 101f2e9e0..f44c94098 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -7,14 +7,9 @@ void main() { vec2 texc = gl_TexCoord[0].xy; - vec4 col = texture2D(diffuse_and_spec, texc); + vec3 diffuse = texture2D(diffuse_and_spec, texc).xyz; + vec3 specular = texture2D(diffuse_and_spec, texc).www; float ao = texture2D(ambient_occlusion, texc).x; - col.xyz += ao * ambient; - float spec = col.a - 0.05; - //spec *= specular.a; - col.xyz += spec * col.xyz; - col.a = 1.0; - - gl_FragColor = col; + gl_FragColor = vec4(diffuse + specular + ao * ambient, 1.0); } diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 91ccf6b5e..e017fe03b 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -24,13 +24,12 @@ void main() { // Light Direction vec3 L = normalize(xpos.xyz - center); - vec3 eyedir = normalize(xpos.xyz); - vec3 H = normalize(-L + eyedir); float NdotL = max(0.0, dot(norm, -L)) * att; - float NdotH = max(0.0, dot(norm, H)); - NdotH = pow(NdotH, spec); - NdotH += 0.05; // offset so that the alpha test doesn't kill us + // Reflected light dir + vec3 R = reflect(-L, norm); + float RdotE = max(0.0, dot(R, normalize(xpos))); + float Specular = pow(RdotE, spec); - gl_FragColor = NdotL * vec4(NdotL * col, NdotH); + gl_FragColor = vec4(NdotL * col, Specular + 0.001); // Irrlicht force alpha test, can't be 0 } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index fb0009934..0691a5194 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -12,6 +12,9 @@ void main() { vec2 texc = gl_FragCoord.xy / screen; float z = texture2D(ntex, texc).a; + vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0; + xpos = invproj * xpos; + xpos.xyz /= xpos.w; if (z < 0.03) { @@ -28,18 +31,14 @@ void main() { vec3 L = center; float NdotL = max(0.0, dot(norm, L)); + vec3 R = reflect(L, norm); + float RdotE = max(0.0, dot(R, normalize(xpos))); + float Specular = pow(RdotE, 200); vec3 outcol = NdotL * col; if (hasclouds == 1) { - vec3 tmp = vec3(texc, z); - tmp = tmp * 2.0 - 1.0; - - vec4 xpos = vec4(tmp, 1.0); - xpos = invproj * xpos; - xpos.xyz /= xpos.w; - vec2 cloudcoord = (xpos.xz * 0.00833333) + wind; float cloud = texture2D(cloudtex, cloudcoord).x; //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y); @@ -47,6 +46,6 @@ void main() { outcol *= cloud; } - gl_FragData[0] = vec4(outcol, 0.05); + gl_FragData[0] = vec4(NdotL * col, Specular+ 0.001); // Irrlicht force alpha test, can't be 0 gl_FragData[1] = vec4(1.0); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8dedd1050..613b61fe2 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -673,7 +673,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, if (!m_lightviz) { m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP1), true, false, - video::SColor(1, 0, 0, 0)); + video::SColor(0, 0, 0, 0)); } else { m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); From 352009b2ce4518af619f02a99995b58d22eb2a11 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 17:00:42 +0000 Subject: [PATCH 014/412] RTT_COLOR uses float format. This allows for hdr, however there is no tone mapping at the moment. color_level.frag can be currently used for such purpose, it gives a nice look in harvest, although it is way too bright. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14757 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/rtts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 0a52c7431..e1a80393c 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -67,7 +67,7 @@ RTT::RTT() rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A8R8G8B8, stencil); rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R8, stencil); rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_A32B32G32R32F, stencil); - rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A8R8G8B8, stencil); + rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A16B16G16R16F, stencil); rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A8R8G8B8, stencil); rtts[RTT_HALF2] = drv->addRenderTargetTexture(half, "rtt.half2", ECF_A8R8G8B8, stencil); From a9db4c7c3fa511ea172c3b9c4270b889d9ab0663 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 18:14:02 +0000 Subject: [PATCH 015/412] Generate random value for SSAO sampling It should improve SSAO at least with grass. However this make the algorithm even more sensitive to bad normals. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14758 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 6 ++++-- src/graphics/callbacks.cpp | 19 ------------------- src/graphics/callbacks.hpp | 12 ++++++++++++ 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 27fb2b140..b9ea427ca 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -4,7 +4,7 @@ uniform mat4 invprojm; uniform mat4 projm; uniform vec4 samplePoints[16]; -const float strengh = 4.; +const float strengh = 20.; const float radius = .1f; #define SAMPLES 16 @@ -47,7 +47,9 @@ void main(void) occluderPos /= occluderPos.w; float depthDifference = sampleProj.z - (2. * occluderFragmentDepth - 1.0); - bl += (distance(occluderPos, FragPos) < radius) ? step(0., depthDifference) : 0.0; + // depthDifference between 0 and radius + float increment = step(0., depthDifference) * step(-radius, -depthDifference); + bl += increment * smoothstep(radius, 0, distance(samplePos, FragPos)); } // output the result diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 9bc7991a3..b3eaa9196 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -494,25 +494,6 @@ void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int) void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int) { - static const float array[64] = { - 0.43589, -0.9, 0.667945, 0., - -0.9, 0.43589, 0.667945, 0., - -0.8, -0.6, 0.7, 0., - 0.6, 0.8, 0.7, 0., - 0.866025, -0.5, 0.6830125, 0., - -0.5, 0.866025, 0.6830125, 0., - -0.3, -0.953939, 0.6269695, 0., - 0.953939, 0.3, 0.6269695, 0., - 0.3, -0.781025, 0.5405125, 0., - -0.781025, 0.3, 0.5405125, 0., - -0.56, -0.621611, 0.5908055, 0., - 0.621611, 0.56, 0.5908055, 0., - 0.734847, -0.4, 0.5674235, 0., - -0.4, 0.734847, 0.5674235, 0., - -0.2, -0.6, 0.4, 0., - 0.6, 0.2, 0.4, 0., - }; - srv->setPixelShaderConstant("invprojm", invprojm.pointer(), 16); srv->setPixelShaderConstant("projm", projm.pointer(), 16); srv->setPixelShaderConstant("samplePoints[0]", array, 64); diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 0614688d8..53037e4dc 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -541,7 +541,19 @@ class SSAOProvider: public CallBase { private: core::matrix4 projm, invprojm; + float array[64]; public: + SSAOProvider() : CallBase() { + for (unsigned i = 0; i < 64; i++) { + array[i] = rand(); + array[i] /= RAND_MAX; + if (i % 4 != 2) + array[i] = 2 * array[i] - 1; + if (i % 4 == 3) + continue; + } + } + virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); void updateIPVMatrix() { From a3cc62a9853d046fbf5c1884cb79f35f0e1fcf48 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 20:02:11 +0000 Subject: [PATCH 016/412] SSAO: Use a costheta factor to ease transition git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14759 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index b9ea427ca..0e2acadd3 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -39,6 +39,8 @@ void main(void) vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0); vec4 sampleProj = projm * samplePos; sampleProj /= sampleProj.w; + // Projection of sampleDir over nom + float cosTheta = samplePoints[i].z; // get the depth of the occluder fragment float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; @@ -49,7 +51,7 @@ void main(void) float depthDifference = sampleProj.z - (2. * occluderFragmentDepth - 1.0); // depthDifference between 0 and radius float increment = step(0., depthDifference) * step(-radius, -depthDifference); - bl += increment * smoothstep(radius, 0, distance(samplePos, FragPos)); + bl += increment * smoothstep(radius, 0, distance(samplePos, FragPos)) * cosTheta; } // output the result From 3fc63a9f27ae597a3a55dfca67504e1636e110c4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 20:25:58 +0000 Subject: [PATCH 017/412] SSAO:Ensure sampled point are inside the unit sphere. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14760 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 3 ++- src/graphics/callbacks.hpp | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 0e2acadd3..d5c8aefab 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -4,7 +4,7 @@ uniform mat4 invprojm; uniform mat4 projm; uniform vec4 samplePoints[16]; -const float strengh = 20.; +const float strengh = 4.; const float radius = .1f; #define SAMPLES 16 @@ -36,6 +36,7 @@ void main(void) 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 = projm * samplePos; sampleProj /= sampleProj.w; diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 53037e4dc..df1239cb3 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -544,13 +544,25 @@ private: float array[64]; public: SSAOProvider() : CallBase() { - for (unsigned i = 0; i < 64; i++) { - array[i] = rand(); - array[i] /= RAND_MAX; - if (i % 4 != 2) - array[i] = 2 * array[i] - 1; - if (i % 4 == 3) - continue; + for (unsigned i = 0; i < 16; i++) { + // Generate x/y component between -1 and 1 + // Use double to avoid denorm and get a true uniform distribution + double x = rand(); + x /= RAND_MAX; + x = 2 * x - 1; + double y = rand(); + y /= RAND_MAX; + y = 2 * y - 1; + + // compute z so that norm (x,y,z) is one + double z = sqrt(x * x + y * y); + // Norm factor + double w = rand(); + w /= RAND_MAX; + array[4 * i] = x; + array[4 * i + 1] = y; + array[4 * i + 2] = z; + array[4 * i + 3] = w; } } From f17f8b62cb2a36d68c163bce1d1c3c5234dcc63c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 23 Dec 2013 23:25:14 +0000 Subject: [PATCH 019/412] SSAO: Use the correct distance for range checking It should remove halo around kart heads. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14763 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index d5c8aefab..e3ff614f4 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -49,10 +49,8 @@ void main(void) vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); occluderPos /= occluderPos.w; - float depthDifference = sampleProj.z - (2. * occluderFragmentDepth - 1.0); - // depthDifference between 0 and radius - float increment = step(0., depthDifference) * step(-radius, -depthDifference); - bl += increment * smoothstep(radius, 0, distance(samplePos, FragPos)) * cosTheta; + bool isOccluded = (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); + bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) * cosTheta : 0.; } // output the result From 49131c68af33719fb427c5530792b4a164021af1 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 00:33:57 +0000 Subject: [PATCH 021/412] Rain: Fade instead of intersecting geometry git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14765 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/rain.frag | 13 +++++++++++++ src/graphics/callbacks.cpp | 10 ++++++++++ src/graphics/rain.cpp | 1 + 3 files changed, 24 insertions(+) diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index 10f94ce0d..65db9ef68 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -1,6 +1,19 @@ uniform sampler2D tex; +uniform sampler2D normals_and_depth; +uniform mat4 invproj; +uniform vec2 screen; void main() { + vec2 xy = gl_FragCoord / screen; + float FragZ = gl_FragCoord.z; + float EnvZ = texture2D(normals_and_depth, xy).a; + vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); + FragmentPos /= FragmentPos.w; + vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); + EnvPos /= EnvPos.w; + float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); + float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); + gl_FragColor.a *= alpha; } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index b3eaa9196..453e4ac6e 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -209,12 +209,22 @@ void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) const float screenw = (float)UserConfigParams::m_width; const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; const matrix4 viewm = srv->getVideoDriver()->getTransform(ETS_VIEW); + matrix4 invproj = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + invproj.makeInverse(); const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); + float screen[2] = { (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height }; srv->setVertexShaderConstant("screenw", &screenw, 1); srv->setVertexShaderConstant("time", &time, 1); srv->setVertexShaderConstant("viewm", viewm.pointer(), 16); srv->setVertexShaderConstant("campos", &campos.X, 3); + srv->setPixelShaderConstant("invproj", invproj.pointer(), 16); + srv->setPixelShaderConstant("screen", screen, 2); + s32 tex = 0; + srv->setPixelShaderConstant("tex", &tex, 1); + tex = 1; + srv->setPixelShaderConstant("normals_and_depth", &tex, 1); } //------------------------------------- diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index adfe7c0cd..ca8c64a48 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -92,6 +92,7 @@ public: glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); IVideoDriver * const drv = irr_driver->getVideoDriver(); + mat.setTexture(1, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); drv->setTransform(ETS_WORLD, AbsoluteTransformation); drv->setMaterial(mat); From bd52770ceb03bbd59fbae077a964dcbfccac30e9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 00:37:58 +0000 Subject: [PATCH 023/412] SSAO: Avoid sampling outside of RTT_NORMAL_AND_DEPTH textures. It should remove artifact at the edge of the screen. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14767 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index e3ff614f4..dc516803b 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -43,13 +43,14 @@ void main(void) // Projection of sampleDir over nom float cosTheta = samplePoints[i].z; + bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); // get the depth of the occluder fragment float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; // Position of the occluder fragment in worldSpace vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); occluderPos /= occluderPos.w; - bool isOccluded = (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); + bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) * cosTheta : 0.; } From dec4cd1453ff461ebea116a9a439e63188644c39 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 01:33:42 +0000 Subject: [PATCH 024/412] Change light visualization. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14768 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/render.cpp | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 613b61fe2..2f2f8a47b 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -670,14 +670,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, video::SOverrideMaterial &overridemat, int cam) { - if (!m_lightviz) - { - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP1), true, false, + m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP1), true, false, video::SColor(0, 0, 0, 0)); - } else - { - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); - } const vector3df camcenter = cambox.getCenter(); const float camradius = cambox.getExtent().getLength() / 2; @@ -726,26 +720,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m.ZBuffer = video::ECFN_GREATER; } - if (m_lightviz) - { - overridemat.Enabled = true; - overridemat.EnableFlags = video::EMF_MATERIAL_TYPE | video::EMF_WIREFRAME | - video::EMF_FRONT_FACE_CULLING | - video::EMF_BACK_FACE_CULLING | - video::EMF_ZBUFFER; - overridemat.Material.MaterialType = m_shaders->getShader(ES_COLORIZE); - overridemat.Material.Wireframe = true; - overridemat.Material.BackfaceCulling = false; - overridemat.Material.FrontfaceCulling = false; - overridemat.Material.ZBuffer = video::ECFN_LESSEQUAL; - - - ColorizeProvider * const cb = (ColorizeProvider *) m_shaders->m_callbacks[ES_COLORIZE]; - float col[3]; - m_lights[i]->getColor(col); - cb->setColor(col[0], col[1], col[2]); - } - // Action m_lights[i]->render(); @@ -757,12 +731,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m.BackfaceCulling = true; m.ZBuffer = video::ECFN_LESSEQUAL; } - - if (m_lightviz) - { - overridemat.Enabled = false; - } - } // for i in lights // Handle SSAO @@ -818,7 +786,10 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, lightmat.setTexture(1, m_rtts->getRTT(RTT_SSAO)); lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); - lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_DST_COLOR, video::EBF_ZERO); + if (!m_lightviz) + lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_DST_COLOR, video::EBF_ZERO); + else + lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_ONE, video::EBF_ZERO); lightmat.BlendOperation = video::EBO_ADD; lightmat.TextureLayer[0].TextureWrapU = From 88ac0ba6cffe1bcda832098051f1ba199427442f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 01:44:40 +0000 Subject: [PATCH 025/412] Attempt to mimic blender light behavior. The attenuation assumes a power distributed on the whole sphere surface. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14769 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index e017fe03b..885826671 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -17,7 +17,7 @@ void main() { float d = distance(center, xpos.xyz); if (d > r) discard; - float att = 1.0 - smoothstep(0.0, r, d); + float att = 200.0 / (4 * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; From 7f51c9737b3382e8b2ff15ce8a2eb00bd101e8b5 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 01:59:35 +0000 Subject: [PATCH 026/412] Test commit, to be reverted git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14770 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/lightblend.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index f44c94098..4e72ef987 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -11,5 +11,5 @@ void main() vec3 specular = texture2D(diffuse_and_spec, texc).www; float ao = texture2D(ambient_occlusion, texc).x; - gl_FragColor = vec4(diffuse + specular + ao * ambient, 1.0); + gl_FragColor = vec4(diffuse + ao * ambient, 1.0); } From 5f23483bd90ae8c6385c0f642b5856c61c30a785 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 02:47:33 +0000 Subject: [PATCH 027/412] Fix some shaders not building with mesa git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14775 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 4 ++-- data/shaders/rain.frag | 2 +- data/shaders/sunlight.frag | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 885826671..c1e860014 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -17,7 +17,7 @@ void main() { float d = distance(center, xpos.xyz); if (d > r) discard; - float att = 200.0 / (4 * 3.14 * d * d); + float att = 200.0 / (4. * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; @@ -28,7 +28,7 @@ void main() { float NdotL = max(0.0, dot(norm, -L)) * att; // Reflected light dir vec3 R = reflect(-L, norm); - float RdotE = max(0.0, dot(R, normalize(xpos))); + float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); float Specular = pow(RdotE, spec); gl_FragColor = vec4(NdotL * col, Specular + 0.001); // Irrlicht force alpha test, can't be 0 diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index 65db9ef68..fd02f9cae 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -5,7 +5,7 @@ uniform vec2 screen; void main() { - vec2 xy = gl_FragCoord / screen; + vec2 xy = gl_FragCoord.xy / screen; float FragZ = gl_FragCoord.z; float EnvZ = texture2D(normals_and_depth, xy).a; vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index 0691a5194..333897c1a 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -32,7 +32,7 @@ void main() { float NdotL = max(0.0, dot(norm, L)); vec3 R = reflect(L, norm); - float RdotE = max(0.0, dot(R, normalize(xpos))); + float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); float Specular = pow(RdotE, 200); vec3 outcol = NdotL * col; From 65b32757f3b900da240f5f9bd4468dcd89293755 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 20:51:53 +0000 Subject: [PATCH 028/412] Separate Diffuse and Specular components This allows to bypass alpha test, and have colored specular lights. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14777 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/lightblend.frag | 10 +++++----- data/shaders/pointlight.frag | 5 +++-- data/shaders/sunlight.frag | 5 +++-- src/graphics/callbacks.cpp | 4 +++- src/graphics/render.cpp | 13 +++++++++---- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index 4e72ef987..be44256b2 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -1,15 +1,15 @@ -uniform sampler2D diffuse_and_spec; +uniform sampler2D diffuse; +uniform sampler2D specular; uniform sampler2D ambient_occlusion; uniform vec3 ambient; -//uniform sampler2D spectex; void main() { vec2 texc = gl_TexCoord[0].xy; - vec3 diffuse = texture2D(diffuse_and_spec, texc).xyz; - vec3 specular = texture2D(diffuse_and_spec, texc).www; + vec3 diffuse = texture2D(diffuse, texc).xyz; + vec3 spec = texture2D(specular, texc).xyz; float ao = texture2D(ambient_occlusion, texc).x; - gl_FragColor = vec4(diffuse + ao * ambient, 1.0); + gl_FragColor = vec4(diffuse + spec + ao * ambient, 1.0); } diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index c1e860014..30a933b8f 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -25,11 +25,12 @@ void main() { // Light Direction vec3 L = normalize(xpos.xyz - center); - float NdotL = max(0.0, dot(norm, -L)) * att; + float NdotL = max(0.0, dot(norm, -L)); // Reflected light dir vec3 R = reflect(-L, norm); float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); float Specular = pow(RdotE, spec); - gl_FragColor = vec4(NdotL * col, Specular + 0.001); // Irrlicht force alpha test, can't be 0 + gl_FragData[0] = vec4(NdotL * col * att, 1.); + gl_FragData[1] = vec4(Specular * col, 1.); } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index 333897c1a..a96812ce6 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -46,6 +46,7 @@ void main() { outcol *= cloud; } - gl_FragData[0] = vec4(NdotL * col, Specular+ 0.001); // Irrlicht force alpha test, can't be 0 - gl_FragData[1] = vec4(1.0); + gl_FragData[0] = vec4(NdotL * col, 1.); + gl_FragData[1] = vec4(Specular * col, 1.); + gl_FragData[2] = vec4(1.0); } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 453e4ac6e..283dddaa7 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -343,8 +343,10 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("ambient", ambient, 3); int tex = 0; - srv->setVertexShaderConstant("diffuse_and_spec", &tex, 1); + srv->setVertexShaderConstant("diffuse", &tex, 1); tex = 1; + srv->setVertexShaderConstant("specular", &tex, 1); + tex = 2; srv->setVertexShaderConstant("ambient_occlusion", &tex, 1); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 2f2f8a47b..f6962a206 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -670,7 +670,13 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, video::SOverrideMaterial &overridemat, int cam) { - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP1), true, false, + core::array rtts; + // Diffuse + rtts.push_back(m_rtts->getRTT(RTT_TMP1)); + // Specular + rtts.push_back(m_rtts->getRTT(RTT_TMP2)); + + m_video_driver->setRenderTarget(rtts, true, false, video::SColor(0, 0, 0, 0)); const vector3df camcenter = cambox.getCenter(); @@ -781,9 +787,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, lightmat.ZBuffer = video::ECFN_ALWAYS; lightmat.setFlag(video::EMF_BILINEAR_FILTER, false); lightmat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); - - // Apply ambient occlusion - lightmat.setTexture(1, m_rtts->getRTT(RTT_SSAO)); + lightmat.setTexture(1, m_rtts->getRTT(RTT_TMP2)); + lightmat.setTexture(2, m_rtts->getRTT(RTT_SSAO)); lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); if (!m_lightviz) From c9b87347175b51b2a33ba36735effe191d95b399 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 24 Dec 2013 23:07:42 +0000 Subject: [PATCH 030/412] Plug-in energy parameter into pointlight shader git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14779 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 3 ++- src/graphics/callbacks.cpp | 1 + src/graphics/callbacks.hpp | 5 +++++ src/graphics/irr_driver.cpp | 4 ++-- src/graphics/irr_driver.hpp | 2 +- src/graphics/light.cpp | 4 +++- src/graphics/light.hpp | 3 ++- src/graphics/sun.cpp | 2 +- src/tracks/track.cpp | 6 ++++-- 9 files changed, 21 insertions(+), 9 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 30a933b8f..bd900c24d 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -6,6 +6,7 @@ uniform float r; uniform float spec; uniform vec2 screen; uniform mat4 invproj; +uniform float energy; void main() { vec2 texc = gl_FragCoord.xy / screen; @@ -17,7 +18,7 @@ void main() { float d = distance(center, xpos.xyz); if (d > r) discard; - float att = 200.0 / (4. * 3.14 * d * d); + float att = energy * 200.0 / (4. * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 283dddaa7..96c5a2eac 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -360,6 +360,7 @@ void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("center", m_pos, 3); srv->setVertexShaderConstant("r", &m_radius, 1); srv->setVertexShaderConstant("invproj", m_invproj.pointer(), 16); + srv->setVertexShaderConstant("energy", &m_energy, 1); if (!firstdone) { diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index df1239cb3..a1953d217 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -419,6 +419,10 @@ public: m_specular = s; } + void setEnergy(float e) { + m_energy = e; + } + void updateIPVMatrix() { const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); @@ -435,6 +439,7 @@ private: float m_screen[2]; float m_radius; float m_specular; + float m_energy; }; // diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index d56292c5d..c72e4cade 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2110,14 +2110,14 @@ void IrrDriver::applyObjectPassShader() } scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, - float r, float g, float b, bool sun) + float energy, float r, float g, float b, bool sun) { if (m_glsl) { LightNode *light = NULL; if (!sun) - light = new LightNode(m_scene_manager, radius, r, g, b); + light = new LightNode(m_scene_manager, radius, energy, r, g, b); else light = new SunNode(m_scene_manager, r, g, b); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index acf6f1843..1bc552c4f 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -454,7 +454,7 @@ public: void applyObjectPassShader(); void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false); // ------------------------------------------------------------------------ - scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float r = 1.0f, + scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float energy = 1., float r = 1.0f, float g = 1.0f, float b = 1.0f, bool sun = false); // ------------------------------------------------------------------------ void clearLights(); diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 09d9465d1..4c2fb6e0f 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -35,7 +35,7 @@ SMaterial LightNode::mat; aabbox3df LightNode::box; -LightNode::LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b): +LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): ISceneNode(mgr->getRootSceneNode(), mgr, -1) { if (!sphere) @@ -63,6 +63,7 @@ LightNode::LightNode(scene::ISceneManager* mgr, float radius, float r, float g, setScale(vector3df(radius)); m_radius = radius; + energy = e; m_color[0] = r; m_color[1] = g; @@ -79,6 +80,7 @@ void LightNode::render() cb->setColor(m_color[0], m_color[1], m_color[2]); cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z); cb->setRadius(m_radius); + cb->setEnergy(energy); IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setTransform(ETS_WORLD, AbsoluteTransformation); diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 245a3250e..d48ea7708 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -33,7 +33,7 @@ namespace irr class LightNode: public scene::ISceneNode { public: - LightNode(scene::ISceneManager* mgr, float radius, float r, float g, float b); + LightNode(scene::ISceneManager* mgr, float radius, float energy, float r, float g, float b); virtual ~LightNode(); virtual void render() OVERRIDE; @@ -59,6 +59,7 @@ protected: float m_radius; float m_color[3]; + float energy; }; #endif diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index 462e4a89f..cd3dc3cf7 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, float r, float g, float b): - LightNode(mgr, 10000, r, g, b) + LightNode(mgr, 10000, 0., r, g, b) { sq = new ScreenQuad(irr_driver->getVideoDriver()); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 507b863a8..ca1cae2da 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1590,10 +1590,12 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) float distance = 25.0f; node->get("distance", &distance); + float energy = 1.; + node->get("energy", &energy); if (irr_driver->isGLSL()) { - irr_driver->addLight(pos, distance, colorf.r, colorf.g, colorf.b); + irr_driver->addLight(pos, distance, energy, colorf.r, colorf.g, colorf.b); } else { scene::ILightSceneNode* node = irr_driver->getSceneManager()->addLightSceneNode(NULL, pos, color, distance); @@ -1756,7 +1758,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, 10000.0f, tmpf.r, tmpf.g, tmpf.b, true); + m_sun = irr_driver->addLight(m_sun_position, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true); if (!irr_driver->isGLSL()) { From ec3fd4fa135e91bf65e6345f03860e1c637d0d16 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 25 Dec 2013 20:19:18 +0000 Subject: [PATCH 035/412] Light: Support for specularmap The specular map is embedded in the alpha component of texture. Alpha value of 1. means no specular, alpha of 0. means 100% specular. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14786 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/lightblend.frag | 4 +++- data/shaders/objectpass.frag | 7 +++++-- data/shaders/objectpass_ref.frag | 3 ++- data/shaders/objectpass_rimlit.frag | 7 +++++-- src/graphics/callbacks.cpp | 2 ++ src/graphics/irr_driver.cpp | 1 + src/graphics/render.cpp | 1 + src/graphics/rtts.cpp | 1 + src/graphics/rtts.hpp | 1 + 9 files changed, 21 insertions(+), 6 deletions(-) diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index be44256b2..a9100da0e 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -1,6 +1,7 @@ uniform sampler2D diffuse; uniform sampler2D specular; uniform sampler2D ambient_occlusion; +uniform sampler2D specular_map; uniform vec3 ambient; void main() @@ -9,7 +10,8 @@ void main() vec3 diffuse = texture2D(diffuse, texc).xyz; vec3 spec = texture2D(specular, texc).xyz; + float specmap = texture2D(specular_map, texc).x; float ao = texture2D(ambient_occlusion, texc).x; - gl_FragColor = vec4(diffuse + spec + ao * ambient, 1.0); + gl_FragColor = vec4(diffuse + spec * specmap + ao * ambient, 1.0); } diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag index 9ae602623..d90250cc2 100644 --- a/data/shaders/objectpass.frag +++ b/data/shaders/objectpass.frag @@ -8,16 +8,19 @@ noperspective in vec3 nor; void main() { vec4 light = vec4(1.0); + vec4 color; if (haslightmap != 0) { light = texture2D(lighttex, gl_TexCoord[1].xy); } if (hastex != 0) - gl_FragData[0] = texture2D(tex, gl_TexCoord[0].xy) * light; + color = texture2D(tex, gl_TexCoord[0].xy) * light; else - gl_FragData[0] = gl_Color; + color = gl_Color; + gl_FragData[0] = vec4(color.xyz, 1.); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1. - color.a); } diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag index 6c9bc83dc..67071d4e0 100644 --- a/data/shaders/objectpass_ref.frag +++ b/data/shaders/objectpass_ref.frag @@ -13,11 +13,12 @@ void main() { if (col.a < 0.5) discard; - gl_FragData[0] = col; + gl_FragData[0] = vec4(col.xyz, 1.); //} else { // gl_FragData[0] = gl_Color; //} gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1. - col.a); } diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag index 6bdb15754..8c29f33dc 100644 --- a/data/shaders/objectpass_rimlit.frag +++ b/data/shaders/objectpass_rimlit.frag @@ -10,6 +10,7 @@ noperspective in vec3 viewpos; void main() { float rim = 1.0 - dot(eyenor, viewpos); rim = smoothstep(0.5, 1.5, rim) * 0.35; + vec4 color; if (hastex != 0) { vec4 col = texture2D(tex, gl_TexCoord[0].xy); @@ -19,11 +20,13 @@ void main() { col.xyz += rim; - gl_FragData[0] = col; + color = col; } else { - gl_FragData[0] = gl_Color + vec4(vec3(rim), 0.0); + color = gl_Color + vec4(vec3(rim), 0.0); } + gl_FragData[0] = vec4(color.xyz, 1.); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1. - color.a); } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 96c5a2eac..b8465204f 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -348,6 +348,8 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("specular", &tex, 1); tex = 2; srv->setVertexShaderConstant("ambient_occlusion", &tex, 1); + tex = 3; + srv->setVertexShaderConstant("specular_map", &tex, 1); } //------------------------------------- diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index c72e4cade..3788599b8 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -425,6 +425,7 @@ void IrrDriver::initDevice() m_mrt.reallocate(3); m_mrt.push_back(m_rtts->getRTT(RTT_COLOR)); m_mrt.push_back(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH)); + m_mrt.push_back(m_rtts->getRTT(RTT_SPECULARMAP)); irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver(); gl_driver->extGlGenQueries(1, &m_lensflare_query); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index f6962a206..7ba3013d3 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -789,6 +789,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, lightmat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); lightmat.setTexture(1, m_rtts->getRTT(RTT_TMP2)); lightmat.setTexture(2, m_rtts->getRTT(RTT_SSAO)); + lightmat.setTexture(3, m_rtts->getRTT(RTT_SPECULARMAP)); lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); if (!m_lightviz) diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index e1a80393c..e7509bb8c 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -68,6 +68,7 @@ RTT::RTT() rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_R8, stencil); rtts[RTT_NORMAL_AND_DEPTH] = drv->addRenderTargetTexture(res, "rtt.normal_and_depth", ECF_A32B32G32R32F, stencil); rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A16B16G16R16F, stencil); + rtts[RTT_SPECULARMAP] = drv->addRenderTargetTexture(res, "rtt.specularmap", ECF_R8, stencil); rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A8R8G8B8, stencil); rtts[RTT_HALF2] = drv->addRenderTargetTexture(half, "rtt.half2", ECF_A8R8G8B8, stencil); diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp index 29e7f5257..7ad8c3d7e 100644 --- a/src/graphics/rtts.hpp +++ b/src/graphics/rtts.hpp @@ -33,6 +33,7 @@ enum TypeRTT RTT_TMP4, RTT_NORMAL_AND_DEPTH, RTT_COLOR, + RTT_SPECULARMAP, RTT_HALF1, RTT_HALF2, From 3a6e75b656a106c48252740605ba18ae4750c990 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 25 Dec 2013 20:40:14 +0000 Subject: [PATCH 037/412] Light: Fix skybox bug with specmap and update grass/splatting shader git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14788 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/grass.frag | 4 ++-- data/shaders/splatting.frag | 3 ++- src/graphics/render.cpp | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index 109a87a01..5885d76ae 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -7,7 +7,7 @@ noperspective in vec3 nor; void main() { - vec4 color = texture2D(tex, gl_TexCoord[0].st); - gl_FragData[0] = color; + gl_FragData[0] = texture2D(tex, gl_TexCoord[0].st); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1.); } diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index 7ab7dcc89..d6b2291a2 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -25,7 +25,8 @@ void main() { (1.0 - splatting.a) * detail4) * gl_Color; - gl_FragData[0] = splatted; + gl_FragData[0] = vec4(splatted.xyz, 1.); gl_FragData[1] = vec4(normalize(nor) * 0.5 + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(splatted.a); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 7ba3013d3..e4a1c963b 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -140,6 +140,8 @@ void IrrDriver::renderGLSL(float dt) // Clear normal and depth to zero m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_NORMAL_AND_DEPTH), true, false, video::SColor(0,0,0,0)); + // Clear specular map to zero + m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_SPECULARMAP), true, false, video::SColor(0,0,0,0)); irr_driver->getVideoDriver()->enableMaterial2D(); RaceGUIBase *rg = world->getRaceGUI(); From c2b18a0a1ccd7fe0c0bac56cf0d6581108d2a27f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 25 Dec 2013 20:48:27 +0000 Subject: [PATCH 038/412] Light: Export the correct value for specmap in grass/splatting shaders git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14789 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/grass.frag | 2 +- data/shaders/splatting.frag | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index 5885d76ae..a42f2544f 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -9,5 +9,5 @@ void main() { gl_FragData[0] = texture2D(tex, gl_TexCoord[0].st); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1.); + gl_FragData[2] = vec4(0.); } diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index d6b2291a2..d5c7ce1f5 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -28,5 +28,5 @@ void main() { gl_FragData[0] = vec4(splatted.xyz, 1.); gl_FragData[1] = vec4(normalize(nor) * 0.5 + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(splatted.a); + gl_FragData[2] = vec4(1. - splatted.a); } From 122567f0d36e58487b06baa19314ca7fba1807a8 Mon Sep 17 00:00:00 2001 From: samuncle Date: Thu, 26 Dec 2013 01:01:12 +0000 Subject: [PATCH 042/412] Increase the max distance of the displacement effect git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14793 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/displace.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/displace.frag b/data/shaders/displace.frag index 4ab1a4feb..a54dea589 100644 --- a/data/shaders/displace.frag +++ b/data/shaders/displace.frag @@ -20,7 +20,7 @@ void main() offset -= 1.0; // Fade according to distance to cam - float fade = 1.0 - smoothstep(1.0, 40.0, camdist); + float fade = 1.0 - smoothstep(1.0, 100.0, camdist); // Fade according to distance from the edges vec2 edger = gl_TexCoord[1].xy; From 067564c7cf12e6f28065af7461a5a18e7defbf66 Mon Sep 17 00:00:00 2001 From: samuncle Date: Thu, 26 Dec 2013 02:55:10 +0000 Subject: [PATCH 044/412] A little change to make the SSAO better (IMHO) other opinions are welcome) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14795 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- 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 dc516803b..3edfad13d 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -5,7 +5,7 @@ uniform mat4 projm; uniform vec4 samplePoints[16]; const float strengh = 4.; -const float radius = .1f; +const float radius = .4f; #define SAMPLES 16 From 5512a72d62aa19a1b4fdf5fe99dab450eaac190e Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 26 Dec 2013 18:00:54 +0000 Subject: [PATCH 045/412] Lights: Remove hard edge and attenuate specular git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14796 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 3 +- src/graphics/callbacks.hpp | 4 --- src/graphics/light.cpp | 55 ++++++++++++++++++++---------------- src/graphics/light.hpp | 1 + src/graphics/render.cpp | 28 ------------------ 5 files changed, 32 insertions(+), 59 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index bd900c24d..f19e4f8a9 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -17,7 +17,6 @@ void main() { xpos /= xpos.w; float d = distance(center, xpos.xyz); - if (d > r) discard; float att = energy * 200.0 / (4. * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; @@ -33,5 +32,5 @@ void main() { float Specular = pow(RdotE, spec); gl_FragData[0] = vec4(NdotL * col * att, 1.); - gl_FragData[1] = vec4(Specular * col, 1.); + gl_FragData[1] = vec4(Specular * col * att, 1.); } diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index a1953d217..4f3cbecd0 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -393,11 +393,7 @@ public: void setPosition(float x, float y, float z) { - const core::vector3df &campos = - irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - core::vector3df pos(x,y,z); - pos -= campos; // get position in eye space coordinates core::matrix4 m_view = drv->getTransform(video::ETS_VIEW); diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 4c2fb6e0f..dd096f131 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -25,6 +25,7 @@ #include "graphics/material.hpp" #include "graphics/rtts.hpp" #include "graphics/shaders.hpp" +#include "graphics/screenquad.hpp" using namespace video; using namespace scene; @@ -38,29 +39,29 @@ aabbox3df LightNode::box; LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): ISceneNode(mgr->getRootSceneNode(), mgr, -1) { - if (!sphere) + sq = new ScreenQuad(irr_driver->getVideoDriver()); + SMaterial &mat = sq->getMaterial(); + + mat.Lighting = false; + mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT); + + mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + + for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) { - mat.Lighting = false; - mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT); - - mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) - { - mat.TextureLayer[i].TextureWrapU = - mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; - } - - mat.setFlag(EMF_BILINEAR_FILTER, false); - mat.setFlag(EMF_ZWRITE_ENABLE, false); - - mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE); - mat.BlendOperation = EBO_ADD; - - sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16); - box = sphere->getBoundingBox(); + mat.TextureLayer[i].TextureWrapU = + mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; } + mat.setFlag(EMF_BILINEAR_FILTER, false); + mat.setFlag(EMF_ZWRITE_ENABLE, false); + + mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE); + mat.BlendOperation = EBO_ADD; + + sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16); + box = sphere->getBoundingBox(); + setScale(vector3df(radius)); m_radius = radius; energy = e; @@ -81,12 +82,16 @@ void LightNode::render() cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z); cb->setRadius(m_radius); cb->setEnergy(energy); - + // Irrlicht's ScreenQuad reset the matrixes, we need to keep them IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setTransform(ETS_WORLD, AbsoluteTransformation); - drv->setMaterial(mat); - - drv->drawMeshBuffer(sphere->getMeshBuffer(0)); + matrix4 tmpworld = drv->getTransform(ETS_WORLD); + matrix4 tmpview = drv->getTransform(ETS_VIEW); + matrix4 tmpproj = drv->getTransform(ETS_PROJECTION); + sq->render(false); + drv->setTransform(ETS_WORLD, tmpworld); + drv->setTransform(ETS_VIEW, tmpview); + drv->setTransform(ETS_PROJECTION, tmpproj); + return; } void LightNode::OnRegisterSceneNode() diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index d48ea7708..645d7b686 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -56,6 +56,7 @@ protected: static core::aabbox3df box; static scene::IMesh *sphere; + class ScreenQuad *sq; float m_radius; float m_color[3]; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index e4a1c963b..cf05c9e02 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -710,35 +710,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, radius_sum *= radius_sum; if (radius_sum < distance_sq) continue; - - bool inside = false; - - const float camdistance_sq = (m_lights[i]->getPosition() - campos).getLengthSQ(); - float adjusted_radius = m_lights[i]->getRadius() + camnear; - adjusted_radius *= adjusted_radius; - - // Camera inside the light's radius? Needs adjustment for the near plane. - if (camdistance_sq < adjusted_radius) - { - inside = true; - - video::SMaterial &m = m_lights[i]->getMaterial(0); - m.FrontfaceCulling = true; - m.BackfaceCulling = false; - m.ZBuffer = video::ECFN_GREATER; - } - - // Action m_lights[i]->render(); - - // Reset the inside change - if (inside) - { - video::SMaterial &m = m_lights[i]->getMaterial(0); - m.FrontfaceCulling = false; - m.BackfaceCulling = true; - m.ZBuffer = video::ECFN_LESSEQUAL; - } } // for i in lights // Handle SSAO From 4f36e43b1451a15b61933ca8a066c3465d5588b7 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 26 Dec 2013 18:28:35 +0000 Subject: [PATCH 046/412] Fix unexported FragData git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14797 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/normalmap.frag | 1 + data/shaders/objectpass_spheremap.frag | 1 + 2 files changed, 2 insertions(+) diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 5d1f61b76..55b66e563 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -22,4 +22,5 @@ void main() gl_FragData[0] = texture2D (texture, gl_TexCoord[0].st); gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(0.); } diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index c2a07952b..7db065066 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -22,4 +22,5 @@ void main() { gl_FragData[0] = detail0 * gl_Color; gl_FragData[1] = vec4(nor, gl_FragCoord.z); + gl_FragData[2] = vec4(0.); } From 46cce1e34786b9dc4100469f82451be6c926b886 Mon Sep 17 00:00:00 2001 From: samuncle Date: Thu, 26 Dec 2013 19:42:11 +0000 Subject: [PATCH 047/412] I updated the requirements to something a but more realistic git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14798 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- README | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README b/README index 108cf1387..c3a69fb1c 100644 --- a/README +++ b/README @@ -19,9 +19,13 @@ Hope you enjoy the game. HARDWARE REQUIREMENTS ===================== -* You need a 3D graphics card that supports OpenGL or Mesa. -* You should have a CPU that's running at 450MHz or better. -* You'll need at least 600 MB of free RAM. +* You need a 3D graphics card. + NVIDIA GeForce 8xxx and higher + ATI Radeon HD 4xxx and higher + Intel HD 3000 and higher +* You should have a CPU that's running at 1GHz or better. +* You'll need at least 512 MB of free VRAM (video memory). +* Disk space: 400MB * Ideally, you want a joystick with at least 6 buttons. From 508d866a2bca8c44adc6243f0fb8d5762384c317 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 26 Dec 2013 20:14:49 +0000 Subject: [PATCH 048/412] Lights: Improve culling system git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14799 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/light.hpp | 1 + src/graphics/render.cpp | 31 +++++++++++++++++++++---------- src/graphics/sun.hpp | 1 + 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 645d7b686..27dd68076 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -47,6 +47,7 @@ public: virtual u32 getMaterialCount() const OVERRIDE { return 1; } virtual video::SMaterial& getMaterial(u32 i) OVERRIDE { return mat; } + virtual bool isCullable() { return true; } float getRadius() const { return m_radius; } void getColor(float out[3]) const { memcpy(out, m_color, 3 * sizeof(float)); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index cf05c9e02..a10594418 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -683,8 +683,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, const vector3df camcenter = cambox.getCenter(); const float camradius = cambox.getExtent().getLength() / 2; - const vector3df campos = camnode->getPosition(); - const float camnear = camnode->getNearValue(); m_scene_manager->drawAll(scene::ESNRP_CAMERA); PointLightProvider * const pcb = (PointLightProvider *) irr_driver-> @@ -702,17 +700,30 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, const u32 lightcount = m_lights.size(); + const core::vector3df &camdir = (camnode->getTarget() - camcenter).normalize(); + + float fov = camnode->getFOV() / 2.; for (unsigned int i = 0; i < lightcount; i++) { - // Sphere culling - const float distance_sq = (m_lights[i]->getPosition() - camcenter).getLengthSQ(); - float radius_sum = camradius + m_lights[i]->getRadius(); - radius_sum *= radius_sum; - if (radius_sum < distance_sq) - continue; + // Light culling + const core::vector3df &lightpos = (m_lights[i]->getPosition() - camcenter); + float light_radius = m_lights[i]->getRadius(); + float dotprod = camdir.dotProduct(lightpos); + if (m_lights[i]->isCullable()) { + if (dotprod > 0.) { + // Pixels in front of camera + // Are they too far ? + if (lightpos.getLength() > camradius) + continue; + // Is it too divergent from camera normal ? + float othogonal_max_dst = light_radius + dotprod * tan(fov); + if (lightpos.getLengthSQ() - dotprod * dotprod > othogonal_max_dst * othogonal_max_dst) + continue; + } else if (lightpos.getLength() > light_radius) + continue; + } m_lights[i]->render(); } // for i in lights - // Handle SSAO SMaterial m_material; GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> @@ -845,4 +856,4 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat, glDisable(GL_STENCIL_TEST); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); -} \ No newline at end of file +} diff --git a/src/graphics/sun.hpp b/src/graphics/sun.hpp index 387444c30..beacb8c32 100644 --- a/src/graphics/sun.hpp +++ b/src/graphics/sun.hpp @@ -32,6 +32,7 @@ public: virtual ~SunNode(); virtual void render() OVERRIDE; + virtual bool isCullable() { return false; } private: ScreenQuad *sq; From 4d0b9236b2ecfde1e4377d98b34cf668c9782e35 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 26 Dec 2013 22:55:15 +0000 Subject: [PATCH 049/412] Lights: improve bandwidth usage It should improve performance a lot, but it handles at most 32 simultaneous lights on screen. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14800 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 45 ++++++++++++++++++++++------------- src/graphics/callbacks.cpp | 10 ++++---- src/graphics/callbacks.hpp | 38 +++++++++-------------------- src/graphics/light.cpp | 45 ++++++++++++++++------------------- src/graphics/light.hpp | 10 ++++---- src/graphics/render.cpp | 46 ++++++++++++++++++++++++++---------- src/graphics/sun.hpp | 2 +- 7 files changed, 105 insertions(+), 91 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index f19e4f8a9..336839c6e 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -1,12 +1,13 @@ uniform sampler2D ntex; -uniform vec3 center; -uniform vec3 col; -uniform float r; +uniform vec4 center[32]; +uniform vec4 col[32]; +uniform float energy[32]; +uniform int lightcount; uniform float spec; uniform vec2 screen; uniform mat4 invproj; -uniform float energy; +uniform mat4 viewm; void main() { vec2 texc = gl_FragCoord.xy / screen; @@ -16,21 +17,31 @@ void main() { xpos = invproj * xpos; xpos /= xpos.w; - float d = distance(center, xpos.xyz); - float att = energy * 200.0 / (4. * 3.14 * d * d); + vec3 diffuse = vec3(0.), specular = vec3(0.); - vec3 norm = texture2D(ntex, texc).xyz; - norm = (norm - 0.5) * 2.0; + for (int i = 0; i < lightcount; ++i) { + vec4 pseudocenter = viewm * vec4(center[i].xyz, 1.0); + pseudocenter /= pseudocenter.w; + vec3 light_pos = pseudocenter.xyz; + vec3 light_col = col[i].xyz; + float d = distance(light_pos, xpos.xyz); + float att = energy[i] * 200. / (4. * 3.14 * d * d); - // Light Direction - vec3 L = normalize(xpos.xyz - center); + vec3 norm = texture2D(ntex, texc).xyz; + norm = (norm - 0.5) * 2.0; - float NdotL = max(0.0, dot(norm, -L)); - // Reflected light dir - vec3 R = reflect(-L, norm); - float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); - float Specular = pow(RdotE, spec); + // Light Direction + vec3 L = normalize(xpos.xyz - light_pos); - gl_FragData[0] = vec4(NdotL * col * att, 1.); - gl_FragData[1] = vec4(Specular * col * att, 1.); + float NdotL = max(0.0, dot(norm, -L)); + diffuse += NdotL * light_col * att; + // Reflected light dir + vec3 R = reflect(-L, norm); + float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); + float Specular = pow(RdotE, spec); + specular += Specular * light_col * att; + } + + gl_FragData[0] = vec4(diffuse, 1.); + gl_FragData[1] = vec4(specular , 1.); } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index b8465204f..5587e968f 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -356,13 +356,15 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + int lightcount = m_color.size() / 4; srv->setVertexShaderConstant("screen", m_screen, 2); srv->setVertexShaderConstant("spec", &m_specular, 1); - srv->setVertexShaderConstant("col", m_color, 3); - srv->setVertexShaderConstant("center", m_pos, 3); - srv->setVertexShaderConstant("r", &m_radius, 1); srv->setVertexShaderConstant("invproj", m_invproj.pointer(), 16); - srv->setVertexShaderConstant("energy", &m_energy, 1); + srv->setVertexShaderConstant("energy[0]", m_energy.data(), m_energy.size()); + srv->setVertexShaderConstant("col[0]", m_color.data(), m_color.size()); + srv->setVertexShaderConstant("center[0]", m_pos.data(), m_pos.size()); + srv->setVertexShaderConstant("viewm", m_view.pointer(), 16); + srv->setVertexShaderConstant("lightcount", &lightcount, 1); if (!firstdone) { diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 4f3cbecd0..d8a4461eb 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -384,30 +384,15 @@ public: virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - void setColor(float r, float g, float b) + void setColor(const std::vector &col) { - m_color[0] = r; - m_color[1] = g; - m_color[2] = b; + m_color = col; } - void setPosition(float x, float y, float z) + void setPosition(const std::vector &pos) { - const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - - // get position in eye space coordinates - core::matrix4 m_view = drv->getTransform(video::ETS_VIEW); - float *mat = m_view.pointer(); - - float scale = mat[3] * x + mat[7] * y + mat[11] * z + mat[15]; - m_pos[0] = (mat[0] * x + mat[4] * y + mat[8] * z + mat[12]) / scale; - m_pos[1] = (mat[1] * x + mat[5] * y + mat[9] * z + mat[13]) / scale; - m_pos[2] = (mat[2] * x + mat[6] * y + mat[10] * z + mat[14]) / scale; - } - - void setRadius(float r) - { - m_radius = r; + m_pos = pos; + return; } void setSpecular(float s) @@ -415,27 +400,26 @@ public: m_specular = s; } - void setEnergy(float e) { + void setEnergy(const std::vector &e) { m_energy = e; } void updateIPVMatrix() { const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - + m_view = drv->getTransform(video::ETS_VIEW); m_invproj = drv->getTransform(video::ETS_PROJECTION); m_invproj.makeInverse(); } private: - core::matrix4 m_invproj; + core::matrix4 m_invproj, m_view; - float m_color[3]; - float m_pos[3]; + std::vector m_color; + std::vector m_pos; + std::vector m_energy; float m_screen[2]; - float m_radius; float m_specular; - float m_energy; }; // diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index dd096f131..77ef04e49 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -31,15 +31,31 @@ using namespace video; using namespace scene; using namespace core; -IMesh * LightNode::sphere = NULL; -SMaterial LightNode::mat; aabbox3df LightNode::box; LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): ISceneNode(mgr->getRootSceneNode(), mgr, -1) { - sq = new ScreenQuad(irr_driver->getVideoDriver()); + energy = e; + m_color[0] = r; + m_color[1] = g; + m_color[2] = b; +} + +LightNode::~LightNode() +{ +} + +void LightNode::render() +{ + return; +} + +void LightNode::renderLightSet(const std::vector &positions, const std::vector &colors, const std::vector &energy) +{ + assert (colors.size() == positions.size() && positions.size() == (energy.size() * 4)); + ScreenQuad *sq = new ScreenQuad(irr_driver->getVideoDriver()); SMaterial &mat = sq->getMaterial(); mat.Lighting = false; @@ -59,28 +75,9 @@ LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE); mat.BlendOperation = EBO_ADD; - sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16); - box = sphere->getBoundingBox(); - - setScale(vector3df(radius)); - m_radius = radius; - energy = e; - - m_color[0] = r; - m_color[1] = g; - m_color[2] = b; -} - -LightNode::~LightNode() -{ -} - -void LightNode::render() -{ PointLightProvider * const cb = (PointLightProvider *) irr_driver->getCallback(ES_POINTLIGHT); - cb->setColor(m_color[0], m_color[1], m_color[2]); - cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z); - cb->setRadius(m_radius); + cb->setColor(colors); + cb->setPosition(positions); cb->setEnergy(energy); // Irrlicht's ScreenQuad reset the matrixes, we need to keep them IVideoDriver * const drv = irr_driver->getVideoDriver(); diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 27dd68076..f0a37e7fb 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -21,6 +21,7 @@ #include #include +#include using namespace irr; @@ -37,6 +38,7 @@ public: virtual ~LightNode(); virtual void render() OVERRIDE; + static void renderLightSet(const std::vector &positions, const std::vector &colors, const std::vector &energy); virtual const core::aabbox3d& getBoundingBox() const OVERRIDE { @@ -46,17 +48,15 @@ public: virtual void OnRegisterSceneNode() OVERRIDE; virtual u32 getMaterialCount() const OVERRIDE { return 1; } - virtual video::SMaterial& getMaterial(u32 i) OVERRIDE { return mat; } - virtual bool isCullable() { return true; } + virtual bool isPointLight() { return true; } float getRadius() const { return m_radius; } - void getColor(float out[3]) const { memcpy(out, m_color, 3 * sizeof(float)); } + float getEnergy() const { return energy; } + core::vector3df getColor() const { return core::vector3df(m_color[0], m_color[1], m_color[2]); } protected: - static video::SMaterial mat; static core::aabbox3df box; - static scene::IMesh *sphere; class ScreenQuad *sq; float m_radius; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index a10594418..12d468dfa 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -703,27 +703,47 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, const core::vector3df &camdir = (camnode->getTarget() - camcenter).normalize(); float fov = camnode->getFOV() / 2.; + std::vector accumulatedLightPos; + std::vector accumulatedLightColor; + std::vector accumulatedLightEnergy; + unsigned lightnum = 0; for (unsigned int i = 0; i < lightcount; i++) { + if (!m_lights[i]->isPointLight()) { + m_lights[i]->render(); + continue; + } + if (lightnum >= 32) + continue; // Light culling const core::vector3df &lightpos = (m_lights[i]->getPosition() - camcenter); float light_radius = m_lights[i]->getRadius(); float dotprod = camdir.dotProduct(lightpos); - if (m_lights[i]->isCullable()) { - if (dotprod > 0.) { - // Pixels in front of camera - // Are they too far ? - if (lightpos.getLength() > camradius) - continue; - // Is it too divergent from camera normal ? - float othogonal_max_dst = light_radius + dotprod * tan(fov); - if (lightpos.getLengthSQ() - dotprod * dotprod > othogonal_max_dst * othogonal_max_dst) - continue; - } else if (lightpos.getLength() > light_radius) + if (dotprod > 0.) { + // Pixels in front of camera + // Are they too far ? + if (lightpos.getLength() > camradius) continue; - } - m_lights[i]->render(); + // Is it too divergent from camera normal ? + float othogonal_max_dst = light_radius + dotprod * tan(fov); + if (lightpos.getLengthSQ() - dotprod * dotprod > othogonal_max_dst * othogonal_max_dst) + continue; + } else if (lightpos.getLength() > light_radius) + continue; + const core::vector3df &pos = m_lights[i]->getPosition(); + accumulatedLightPos.push_back(pos.X); + accumulatedLightPos.push_back(pos.Y); + accumulatedLightPos.push_back(pos.Z); + accumulatedLightPos.push_back(0.); + const core::vector3df &col = m_lights[i]->getColor(); + accumulatedLightColor.push_back(col.X); + accumulatedLightColor.push_back(col.Y); + accumulatedLightColor.push_back(col.Z); + accumulatedLightColor.push_back(0.); + accumulatedLightEnergy.push_back(m_lights[i]->getEnergy()); + lightnum++; } // for i in lights + LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO SMaterial m_material; GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> diff --git a/src/graphics/sun.hpp b/src/graphics/sun.hpp index beacb8c32..62052ca14 100644 --- a/src/graphics/sun.hpp +++ b/src/graphics/sun.hpp @@ -32,7 +32,7 @@ public: virtual ~SunNode(); virtual void render() OVERRIDE; - virtual bool isCullable() { return false; } + virtual bool isPointLight() OVERRIDE { return false; } private: ScreenQuad *sq; From 30a030bd4cd3fe8a7e95f1515dcdee9123ec40a9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 00:34:41 +0000 Subject: [PATCH 050/412] Light: Pseudo sort lights distance using bucket to evict them fast. Lower max light level to 16 as it proves sufficient. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14801 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 6 ++--- src/graphics/render.cpp | 52 ++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 336839c6e..8ed992a35 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -1,8 +1,8 @@ uniform sampler2D ntex; -uniform vec4 center[32]; -uniform vec4 col[32]; -uniform float energy[32]; +uniform vec4 center[16]; +uniform vec4 col[16]; +uniform float energy[16]; uniform int lightcount; uniform float spec; uniform vec2 screen; diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 12d468dfa..e3f0e767f 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -666,7 +666,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, } // ---------------------------------------------------------------------------- - +#define MAXLIGHT 16 // to be adjusted in pointlight.frag too void IrrDriver::renderLights(const core::aabbox3df& cambox, scene::ICameraSceneNode * const camnode, video::SOverrideMaterial &overridemat, @@ -681,9 +681,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_video_driver->setRenderTarget(rtts, true, false, video::SColor(0, 0, 0, 0)); - const vector3df camcenter = cambox.getCenter(); - const float camradius = cambox.getExtent().getLength() / 2; - m_scene_manager->drawAll(scene::ESNRP_CAMERA); PointLightProvider * const pcb = (PointLightProvider *) irr_driver-> getCallback(ES_POINTLIGHT); @@ -700,49 +697,46 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, const u32 lightcount = m_lights.size(); - const core::vector3df &camdir = (camnode->getTarget() - camcenter).normalize(); - - float fov = camnode->getFOV() / 2.; + const core::vector3df &campos = + irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); std::vector accumulatedLightPos; std::vector accumulatedLightColor; std::vector accumulatedLightEnergy; - unsigned lightnum = 0; + std::vector BucketedLN[15]; for (unsigned int i = 0; i < lightcount; i++) { if (!m_lights[i]->isPointLight()) { m_lights[i]->render(); continue; } - if (lightnum >= 32) + const core::vector3df &lightpos = (m_lights[i]->getPosition() - campos); + unsigned idx = lightpos.getLength() / 10; + if(idx > 14) continue; - // Light culling - const core::vector3df &lightpos = (m_lights[i]->getPosition() - camcenter); - float light_radius = m_lights[i]->getRadius(); - float dotprod = camdir.dotProduct(lightpos); - if (dotprod > 0.) { - // Pixels in front of camera - // Are they too far ? - if (lightpos.getLength() > camradius) - continue; - // Is it too divergent from camera normal ? - float othogonal_max_dst = light_radius + dotprod * tan(fov); - if (lightpos.getLengthSQ() - dotprod * dotprod > othogonal_max_dst * othogonal_max_dst) - continue; - } else if (lightpos.getLength() > light_radius) - continue; - const core::vector3df &pos = m_lights[i]->getPosition(); + 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) + break; + LightNode *LN = BucketedLN[i].at(j); + const core::vector3df &pos = LN->getPosition(); accumulatedLightPos.push_back(pos.X); accumulatedLightPos.push_back(pos.Y); accumulatedLightPos.push_back(pos.Z); accumulatedLightPos.push_back(0.); - const core::vector3df &col = m_lights[i]->getColor(); + const core::vector3df &col = LN->getColor(); + accumulatedLightColor.push_back(col.X); accumulatedLightColor.push_back(col.Y); accumulatedLightColor.push_back(col.Z); accumulatedLightColor.push_back(0.); - accumulatedLightEnergy.push_back(m_lights[i]->getEnergy()); - lightnum++; - } // for i in lights + accumulatedLightEnergy.push_back(LN->getEnergy()); + } + if (lightnum > MAXLIGHT) + break; + } LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO SMaterial m_material; From 0506b9854003104e941aa8fc3bfa545786669f06 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 01:00:20 +0000 Subject: [PATCH 051/412] Lights: Add a metric to measure light count pressure in a scene. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14802 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/irr_driver.cpp | 6 +++--- src/graphics/irr_driver.hpp | 2 ++ src/graphics/render.cpp | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 3788599b8..db07c5c27 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1397,7 +1397,7 @@ void IrrDriver::displayFPS() { gui::IGUIFont* font = GUIEngine::getFont(); - irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,800,50),NULL); + irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,50),NULL); // We will let pass some time to let things settle before trusting FPS counter // even if we also ignore fps = 1, which tends to happen in first checks @@ -1450,8 +1450,8 @@ void IrrDriver::displayFPS() if (UserConfigParams::m_artist_debug_mode) { - sprintf(buffer, "FPS: %i/%i/%i - %.2f/%.2f/%.2f KTris", - min, fps, max, low, kilotris, high); + sprintf(buffer, "FPS: %i/%i/%i - %.2f/%.2f/%.2f KTris - LightDst : ~%d", + min, fps, max, low, kilotris, high, m_last_light_bucket_distance); } else { diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 1bc552c4f..f8e512bfb 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -149,6 +149,7 @@ private: bool m_shadowviz; bool m_lightviz; bool m_distortviz; + unsigned m_last_light_bucket_distance; u32 m_renderpass; u32 m_lensflare_query; scene::IMeshSceneNode *m_sun_interposer; @@ -270,6 +271,7 @@ public: void showPointer(); void hidePointer(); + void setLastLightBucketDistance(unsigned d) { m_last_light_bucket_distance = d; } bool isPointerShown() const { return m_pointer_shown; } core::position2di getMouseLocation(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index e3f0e767f..60af9c4d7 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -734,8 +734,10 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, accumulatedLightColor.push_back(0.); accumulatedLightEnergy.push_back(LN->getEnergy()); } - if (lightnum > MAXLIGHT) + if (lightnum > MAXLIGHT) { + irr_driver->setLastLightBucketDistance(i * 10); break; + } } LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO From 32a61d770e4e033a04737f580484e5152bd7b09f Mon Sep 17 00:00:00 2001 From: samuncle Date: Fri, 27 Dec 2013 02:06:08 +0000 Subject: [PATCH 052/412] Allow kart to use specular map git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14803 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/objectpass_rimlit.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag index 8c29f33dc..af5a46030 100644 --- a/data/shaders/objectpass_rimlit.frag +++ b/data/shaders/objectpass_rimlit.frag @@ -15,7 +15,7 @@ void main() { if (hastex != 0) { vec4 col = texture2D(tex, gl_TexCoord[0].xy); - if (col.a < 0.5) + if (col.a < 0.1) discard; col.xyz += rim; From 27e397d2c79f2d86b72532200d3e3b727f5d98b6 Mon Sep 17 00:00:00 2001 From: deveee Date: Fri, 27 Dec 2013 02:12:16 +0000 Subject: [PATCH 053/412] Fixed #1086 - Popup message was displayed constantly when you were in garage in overworld. TODO: Compare distance between garage and kart with for example length of the kart or distance of object defined in scene.xml. Currently (m_garage_pos-m_kart_pos).length2_2d() gives much higher values than getKart(0)->getKartModel()->getLength() and I must look at this closer. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14804 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/modes/overworld.cpp | 28 +++++++++++++++++++++++- src/tracks/track_object.cpp | 9 ++++++++ src/tracks/track_object.hpp | 7 ++++-- src/tracks/track_object_presentation.cpp | 2 ++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 00344b3c2..b7709d097 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -31,6 +31,7 @@ #include "states_screens/offline_kart_selection.hpp" #include "states_screens/race_gui_overworld.hpp" #include "tracks/track.hpp" +#include "tracks/track_object_manager.hpp" //----------------------------------------------------------------------------- OverWorld::OverWorld() : WorldWithRank() @@ -124,6 +125,31 @@ void OverWorld::update(float dt) m_karts[n]->setEnergy(100.0f); } + TrackObjectManager* tom = getTrack()->getTrackObjectManager(); + PtrVector& objects = tom->getObjects(); + for(int i=0; iisGarage()) + continue; + + Vec3 m_garage_pos = obj->getPosition(); + + AbstractKart* m_kart = getKart(0); + Vec3 m_kart_pos = m_kart->getXYZ(); + //~ float kart_len = m_kart->getKartModel()->getLength(); + + //~ printf("%f\n", (m_garage_pos-m_kart_pos).length2_2d()); + //~ printf("%f\n", kart_len); + + //TODO: Compare distance between garage and kart with for example length + // of the kart or distance of object defined in scene.xml + if ((m_garage_pos-m_kart_pos).length2_2d() > CHALLENGE_DISTANCE_SQUARED*3) + { + obj->reset(); + } + } + if (m_return_to_garage) { m_return_to_garage = false; @@ -133,7 +159,7 @@ void OverWorld::update(float dt) s->setMultiplayer(false); s->setFromOverworld(true); StateManager::get()->resetAndGoToScreen(s); - } + } } // update //----------------------------------------------------------------------------- diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 9d21e413f..56f1be769 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -101,6 +101,8 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) m_soccer_ball = false; xml_node.get("soccer_ball", &m_soccer_ball); + + m_garage = false; std::string type; xml_node.get("type", &type ); @@ -122,6 +124,13 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) } else if (type == "action-trigger") { + std::string m_action; + xml_node.get("action", &m_action); + if (m_action == "garage") + { + m_garage = true; + } + m_presentation = new TrackObjectPresentationActionTrigger(xml_node); } else if (type == "billboard") diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index fceba17bf..c807534b7 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -73,11 +73,13 @@ protected: std::string m_type; bool m_soccer_ball; + + bool m_garage; PhysicalObject* m_rigid_body; ThreeDAnimation* m_animator; - + void init(const XMLNode &xml_node, LODNode* lodNode); public: @@ -106,7 +108,8 @@ public: const std::string& getType() const { return m_type; } bool isSoccerBall() const { return m_soccer_ball; } - + bool isGarage() const { return m_garage; } + const PhysicalObject* getPhysics() const { return m_rigid_body; } PhysicalObject* getPhysics() { return m_rigid_body; } diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 828c4ee13..497d3c904 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -612,6 +612,8 @@ void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) if (m_action == "garage") { + m_action_active = false; + new RacePausedDialog(0.8f, 0.6f); //dynamic_cast(World::getWorld())->scheduleSelectKart(); } From cb21815054e86ec27cd62e21e878b5989bc7e016 Mon Sep 17 00:00:00 2001 From: samuncle Date: Fri, 27 Dec 2013 02:41:58 +0000 Subject: [PATCH 054/412] Improved the specularity by adding a little offset to the energy git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14805 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 8ed992a35..b7e55ffa2 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -26,6 +26,7 @@ void main() { vec3 light_col = col[i].xyz; float d = distance(light_pos, xpos.xyz); float att = energy[i] * 200. / (4. * 3.14 * d * d); + float spec_att = (energy[i] + 10) * 200. / (4. * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; @@ -39,7 +40,7 @@ void main() { vec3 R = reflect(-L, norm); float RdotE = max(0.0, dot(R, normalize(xpos.xyz))); float Specular = pow(RdotE, spec); - specular += Specular * light_col * att; + specular += Specular * light_col * spec_att; } gl_FragData[0] = vec4(diffuse, 1.); From 053170fc2749cc0a3e7ea86d93238b3e4c2bc99a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 02:50:25 +0000 Subject: [PATCH 055/412] Rain: Use transform feedback to decouple simulation from rendering It's the base for a future gpu based particle system git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14806 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/rain.frag | 6 +- data/shaders/rain.vert | 23 +--- data/shaders/rainsim.vert | 27 ++++ src/graphics/rain.cpp | 261 +++++++++++++++++++++++++++++++++++++- 4 files changed, 293 insertions(+), 24 deletions(-) create mode 100644 data/shaders/rainsim.vert diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index fd02f9cae..9b4508f50 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -1,4 +1,6 @@ +#version 130 uniform sampler2D tex; +uniform float bdiscard = 0.0; uniform sampler2D normals_and_depth; uniform mat4 invproj; uniform vec2 screen; @@ -14,6 +16,8 @@ void main() EnvPos /= EnvPos.w; float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); + if (bdiscard < 0.5) + discard; + gl_FragColor = texture2D(tex, gl_PointCoord.xy); gl_FragColor.a *= alpha; } diff --git a/data/shaders/rain.vert b/data/shaders/rain.vert index 5fc5473c5..6c999eb32 100644 --- a/data/shaders/rain.vert +++ b/data/shaders/rain.vert @@ -1,33 +1,12 @@ uniform float screenw; -uniform float time; -uniform mat4 viewm; -uniform vec3 campos; void main() { const float size = 0.5; - // This simulation will run accurately for a bit under five days. - vec4 start = gl_Vertex; - start.y -= time; - - // How many times has it fell? - float count = floor(start.y / 24.0); - start.x += sin(count); - start.z += cos(count); - - vec2 signs = sign(start.xz); - start.xz = mod(start.xz, 17.5) * signs; - - start.y = mod(start.y, 24.0) - 3.0; - - start.xyz += campos; - - vec4 eyepos = viewm * start; + vec4 eyepos = gl_Vertex; vec4 projCorner = gl_ProjectionMatrix * vec4(vec2(size), eyepos.z, eyepos.w); gl_PointSize = screenw * projCorner.x / projCorner.w; gl_Position = gl_ProjectionMatrix * eyepos; - - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; } diff --git a/data/shaders/rainsim.vert b/data/shaders/rainsim.vert new file mode 100644 index 000000000..184b049b6 --- /dev/null +++ b/data/shaders/rainsim.vert @@ -0,0 +1,27 @@ +uniform float time; +uniform vec3 campos; +uniform mat4 viewm; + +in vec3 initialPosition; +out vec3 currentPosition; + +void main() +{ + // This simulation will run accurately for a bit under five days. + vec4 start = vec4(initialPosition, 1.0); + start.y -= time; + + // How many times has it fell? + float count = floor(start.y / 24.0); + start.x += sin(count); + start.z += cos(count); + + vec2 signs = sign(start.xz); + start.xz = mod(start.xz, 17.5) * signs; + + start.y = mod(start.y, 24.0) - 3.0; + + start.xyz += campos; + + currentPosition = (viewm * start).xyz; +} diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index ca8c64a48..5b86adaef 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -37,9 +37,260 @@ using namespace video; using namespace scene; using namespace core; +// OPENGL PARTICLE SYSTEM +#include +#include "../source/Irrlicht/COpenGLExtensionHandler.h" +#include "io/file_manager.hpp" + +#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) +#else +#include +#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) +#endif + + +PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLUNIFORM1FPROC glUniform1f; +PFNGLUNIFORM3FPROC glUniform3f; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +#ifdef _IRR_WINDOWS_API_ +PFNGLACTIVETEXTUREPROC glActiveTexture; +#endif +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; + +void initGL() +{ + glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); + glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); + glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); + glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); + glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); + glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); + glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); + glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); + glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); + glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); + glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); +#ifdef _IRR_WINDOWS_API_ + glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); +#endif + glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); + glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); +} + +// Mostly from shader tutorial +GLuint LoadShader(const char * file, unsigned type) { + GLuint Id = glCreateShader(type); + std::string Code; + std::ifstream Stream(file, std::ios::in); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + printf("Compiling shader : %s\n", file); + char const * SourcePointer = Code.c_str(); + int length = strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) { + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + return Id; +} + +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path){ + GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); + + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +GLuint getTextureGLuint(ITexture *tex) { return static_cast(tex)->getOpenGLTextureName(); } + +void bindUniformToTextureUnit(GLuint program, const char * name, GLuint texid, unsigned textureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, texid); + GLuint location = glGetUniformLocation(program, name); + glUniform1i(location, textureUnit); +} + +class GPUParticle { +private: + GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; + GLuint texture; + GLuint normal_and_depth; + unsigned count; +public: + GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : + count(c), texture(tex), normal_and_depth(rtt) { + initGL(); + glGenBuffers(2, tfb_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); + + RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); + GLuint SimShader = LoadShader(file_manager->getAsset("shaders/rainsim.vert").c_str(), GL_VERTEX_SHADER); + SimulationProgram = glCreateProgram(); + glAttachShader(SimulationProgram, SimShader); + const char *varying[] = { "currentPosition" }; + glTransformFeedbackVaryings(SimulationProgram, 1, varying, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(SimulationProgram); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(SimulationProgram, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(SimulationProgram, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(SimulationProgram, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + glDeleteShader(SimShader); + } + + void simulate() { + glUseProgram(SimulationProgram); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; + const matrix4 viewm = irr_driver->getVideoDriver()->getTransform(ETS_VIEW); + const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); + + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); + GLuint lcampos = glGetUniformLocation(SimulationProgram, "campos"); + GLuint lviewm = glGetUniformLocation(SimulationProgram, "viewm"); + GLuint ltime = glGetUniformLocation(SimulationProgram, "time"); + glUniformMatrix4fv(lviewm, 1, GL_FALSE, viewm.pointer()); + glUniform1f(ltime, time); + glUniform3f(lcampos, campos.X, campos.Y, campos.Z); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisable(GL_RASTERIZER_DISCARD); + } + + void render() { + const float screenw = (float)UserConfigParams::m_width; + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + float screen[2] = { (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height }; + matrix4 invproj = irr_driver->getVideoDriver()->getTransform(ETS_PROJECTION); + invproj.makeInverse(); + + GLuint lscreenw = glGetUniformLocation(RenderProgram, "screenw"); + GLuint bdiscard = glGetUniformLocation(RenderProgram, "bdiscard"); + GLuint lscreen = glGetUniformLocation(RenderProgram, "screen"); + GLuint linvproj = glGetUniformLocation(RenderProgram, "invproj"); + + bindUniformToTextureUnit(RenderProgram, "tex", texture, 0); + bindUniformToTextureUnit(RenderProgram, "normals_and_depth", normal_and_depth, 1); + + + glUniformMatrix4fv(linvproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(lscreen, screen[0], screen[1]); + glUniform1f(bdiscard, 1.0); + glUniform1f(lscreenw, screenw); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + } +}; +// END OPENGL PARTICLE SYSTEM + // The actual rain node class RainNode: public scene::ISceneNode { +private: + GPUParticle *gpupart; public: RainNode(scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(0, mgr, -1) @@ -68,7 +319,7 @@ public: buf.setHardwareMappingHint(EHM_STATIC); u32 i; - float x, y, z; + float x, y, z, vertices[7500]; for (i = 0; i < count; i++) { x = ((rand() % area) - area/2) / 100.0f; @@ -77,7 +328,11 @@ public: buf.Indices[i] = i; buf.Vertices[i] = S3DVertex(x, y, z, 0, 0, 0, SColor(255, 255, 0, 0), 0, 0); + vertices[3 * i] = x; + vertices[3 * i + 1] = y; + vertices[3 * i + 2] = z; } + gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); box.addInternalPoint(vector3df((float)(-area/2))); box.addInternalPoint(vector3df((float)( area/2))); @@ -85,10 +340,14 @@ public: ~RainNode() { + delete gpupart; } virtual void render() { + gpupart->simulate(); + gpupart->render(); + // We need to let irrlicht render something so it updates its internal states glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); IVideoDriver * const drv = irr_driver->getVideoDriver(); From f1aac9e31727fc1a5a5bd23af026073905fda1e8 Mon Sep 17 00:00:00 2001 From: auria Date: Fri, 27 Dec 2013 03:02:33 +0000 Subject: [PATCH 056/412] Adjust logging to make STK less annoying to debug under visual studio : output the logging directly to VS's output pane, instead of having to reply on the small cmd.exe popup that closes as soon as the application exits git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14807 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/utils/log.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/utils/log.cpp b/src/utils/log.cpp index 98e58a8e3..61017d284 100644 --- a/src/utils/log.cpp +++ b/src/utils/log.cpp @@ -163,6 +163,10 @@ void Log::printMessage(int level, const char *component, const char *format, { va_copy(copy, args); } +#if defined(_MSC_FULL_VER) && defined(_DEBUG) + VALIST copy2; + va_copy(copy2, args); +#endif // If we don't have a console file, write to stdout and hope for the best if(!m_file_stdout || level >= LL_WARN || @@ -178,6 +182,21 @@ void Log::printMessage(int level, const char *component, const char *format, va_end(out); } + +#if defined(_MSC_FULL_VER) && defined(_DEBUG) + static char szBuff[2048]; + vsnprintf(szBuff, sizeof(szBuff), format, copy2); + + OutputDebugString("["); + OutputDebugString(names[level]); + OutputDebugString("] "); + OutputDebugString(component); + OutputDebugString(": "); + OutputDebugString(szBuff); + OutputDebugString("\r\n"); +#endif + + if(m_file_stdout) { fprintf (m_file_stdout, "[%s] %s: ", names[level], component); From 224b246f173806e8f251bc69c18f3655118cb82d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 16:37:15 +0000 Subject: [PATCH 059/412] Irrlicht: make setRenderStates3DMode public git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14810 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- lib/irrlicht/source/Irrlicht/COpenGLDriver.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/COpenGLDriver.h b/lib/irrlicht/source/Irrlicht/COpenGLDriver.h index bc722cb9c..c556bd913 100644 --- a/lib/irrlicht/source/Irrlicht/COpenGLDriver.h +++ b/lib/irrlicht/source/Irrlicht/COpenGLDriver.h @@ -408,6 +408,9 @@ namespace video //! Get ZBuffer bits. GLenum getZBufferBits() const; + //! sets the needed renderstates + void setRenderStates3DMode(); + //! Get Cg context #ifdef _IRR_COMPILE_WITH_CG_ const CGcontext& getCgContext(); @@ -438,9 +441,6 @@ namespace video //! get native wrap mode value GLint getTextureWrapMode(const u8 clamp); - //! sets the needed renderstates - void setRenderStates3DMode(); - //! sets the needed renderstates void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); From 9826af0747479eb8ba2ef6f4dd4c00862da77fad Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 16:37:24 +0000 Subject: [PATCH 060/412] Rain: Avoid making a draw call that won't be used and make some cleanup git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14811 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/rain.frag | 3 --- data/shaders/rain.vert | 1 + data/shaders/rainsim.vert | 2 ++ src/graphics/rain.cpp | 36 ++++++++---------------------------- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index 9b4508f50..5b8e28e8a 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -1,6 +1,5 @@ #version 130 uniform sampler2D tex; -uniform float bdiscard = 0.0; uniform sampler2D normals_and_depth; uniform mat4 invproj; uniform vec2 screen; @@ -16,8 +15,6 @@ void main() EnvPos /= EnvPos.w; float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - if (bdiscard < 0.5) - discard; gl_FragColor = texture2D(tex, gl_PointCoord.xy); gl_FragColor.a *= alpha; } diff --git a/data/shaders/rain.vert b/data/shaders/rain.vert index 6c999eb32..77832bfd5 100644 --- a/data/shaders/rain.vert +++ b/data/shaders/rain.vert @@ -1,3 +1,4 @@ +#version 130 uniform float screenw; void main() diff --git a/data/shaders/rainsim.vert b/data/shaders/rainsim.vert index 184b049b6..4c7a29d98 100644 --- a/data/shaders/rainsim.vert +++ b/data/shaders/rainsim.vert @@ -1,3 +1,4 @@ +#version 130 uniform float time; uniform vec3 campos; uniform mat4 viewm; @@ -24,4 +25,5 @@ void main() start.xyz += campos; currentPosition = (viewm * start).xyz; + gl_Position = vec4(0.); } diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index 5b86adaef..ed5c8d7bc 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -280,7 +280,8 @@ public: glUniform1f(lscreenw, screenw); glDrawArrays(GL_POINTS, 0, count); glDisableVertexAttribArray(0); - + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); } }; @@ -308,16 +309,6 @@ public: count = 2500; area = 3500; - // Fill in the mesh buffer - buf.Vertices.clear(); - buf.Indices.clear(); - - buf.Vertices.set_used(count); - buf.Indices.set_used(count); - - buf.Primitive = EPT_POINT_SPRITES; - buf.setHardwareMappingHint(EHM_STATIC); - u32 i; float x, y, z, vertices[7500]; for (i = 0; i < count; i++) @@ -326,8 +317,6 @@ public: y = ((rand() % 2400)) / 100.0f; z = ((rand() % area) - area/2) / 100.0f; - buf.Indices[i] = i; - buf.Vertices[i] = S3DVertex(x, y, z, 0, 0, 0, SColor(255, 255, 0, 0), 0, 0); vertices[3 * i] = x; vertices[3 * i + 1] = y; vertices[3 * i + 2] = z; @@ -340,24 +329,17 @@ public: ~RainNode() { - delete gpupart; + delete gpupart; } virtual void render() - { - gpupart->simulate(); - gpupart->render(); - // We need to let irrlicht render something so it updates its internal states - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - + { + gpupart->simulate(); + gpupart->render(); + // We need to force irrlicht to update its internal states IVideoDriver * const drv = irr_driver->getVideoDriver(); - mat.setTexture(1, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - drv->setTransform(ETS_WORLD, AbsoluteTransformation); drv->setMaterial(mat); - - drv->drawMeshBuffer(&buf); - - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + static_cast(drv)->setRenderStates3DMode(); } virtual const core::aabbox3d& getBoundingBox() const @@ -384,8 +366,6 @@ private: core::aabbox3d box; u32 count; s32 area; - - scene::SMeshBuffer buf; }; // The rain manager From 616a2e7a75d4f95a2bf60b99a7adefb83f01fed2 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 17:01:45 +0000 Subject: [PATCH 061/412] Rain: Precompute as many shader data as possible git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14812 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/rain.cpp | 83 +++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index ed5c8d7bc..0d794067a 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -181,20 +181,41 @@ GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_pat return ProgramID; } +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount){ + GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint Program = glCreateProgram(); + glAttachShader(Program, Shader); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + glDeleteShader(Shader); + return Program; +} + GLuint getTextureGLuint(ITexture *tex) { return static_cast(tex)->getOpenGLTextureName(); } -void bindUniformToTextureUnit(GLuint program, const char * name, GLuint texid, unsigned textureUnit) { +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(GL_TEXTURE_2D, texid); - GLuint location = glGetUniformLocation(program, name); glUniform1i(location, textureUnit); } class GPUParticle { private: GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; - GLuint texture; - GLuint normal_and_depth; + GLuint texture, normal_and_depth; + GLuint loc_campos, loc_viewm, loc_time; + GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; unsigned count; public: GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : @@ -207,24 +228,17 @@ public: glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); - GLuint SimShader = LoadShader(file_manager->getAsset("shaders/rainsim.vert").c_str(), GL_VERTEX_SHADER); - SimulationProgram = glCreateProgram(); - glAttachShader(SimulationProgram, SimShader); - const char *varying[] = { "currentPosition" }; - glTransformFeedbackVaryings(SimulationProgram, 1, varying, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(SimulationProgram); + loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + texloc_tex = glGetUniformLocation(RenderProgram, "tex"); + texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(SimulationProgram, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(SimulationProgram, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(SimulationProgram, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - glDeleteShader(SimShader); + const char *varyings[] = {"currentPosition"}; + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); + loc_campos = glGetUniformLocation(SimulationProgram, "campos"); + loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); + loc_time = glGetUniformLocation(SimulationProgram, "time"); } void simulate() { @@ -238,12 +252,10 @@ public: glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); - GLuint lcampos = glGetUniformLocation(SimulationProgram, "campos"); - GLuint lviewm = glGetUniformLocation(SimulationProgram, "viewm"); - GLuint ltime = glGetUniformLocation(SimulationProgram, "time"); - glUniformMatrix4fv(lviewm, 1, GL_FALSE, viewm.pointer()); - glUniform1f(ltime, time); - glUniform3f(lcampos, campos.X, campos.Y, campos.Z); + + glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); + glUniform1f(loc_time, time); + glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); @@ -265,19 +277,12 @@ public: matrix4 invproj = irr_driver->getVideoDriver()->getTransform(ETS_PROJECTION); invproj.makeInverse(); - GLuint lscreenw = glGetUniformLocation(RenderProgram, "screenw"); - GLuint bdiscard = glGetUniformLocation(RenderProgram, "bdiscard"); - GLuint lscreen = glGetUniformLocation(RenderProgram, "screen"); - GLuint linvproj = glGetUniformLocation(RenderProgram, "invproj"); + bindUniformToTextureUnit(texloc_tex, texture, 0); + bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); - bindUniformToTextureUnit(RenderProgram, "tex", texture, 0); - bindUniformToTextureUnit(RenderProgram, "normals_and_depth", normal_and_depth, 1); - - - glUniformMatrix4fv(linvproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(lscreen, screen[0], screen[1]); - glUniform1f(bdiscard, 1.0); - glUniform1f(lscreenw, screenw); + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniform1f(loc_screenw, screenw); glDrawArrays(GL_POINTS, 0, count); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); From 6d0e6a67b2beaa89629affbabc7bc6171b861356 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 17:03:02 +0000 Subject: [PATCH 062/412] PointLight:Fix shader arithmetic type mismatch reported by mesa git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14813 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index b7e55ffa2..cb535e70d 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -26,7 +26,7 @@ void main() { vec3 light_col = col[i].xyz; float d = distance(light_pos, xpos.xyz); float att = energy[i] * 200. / (4. * 3.14 * d * d); - float spec_att = (energy[i] + 10) * 200. / (4. * 3.14 * d * d); + float spec_att = (energy[i] + 10.) * 200. / (4. * 3.14 * d * d); vec3 norm = texture2D(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; From df2bd304ab752c1d680fead775967c963eaebda4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 20:56:29 +0000 Subject: [PATCH 063/412] GPUParticles: Put it in its own file Disable rain while doing ping-pong between os to get windows opengl callback git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14814 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 5 +- src/graphics/gpuparticles.cpp | 210 +++++++++++++++++++++++++++ src/graphics/gpuparticles.h | 73 ++++++++++ src/graphics/rain.cpp | 266 +--------------------------------- 4 files changed, 292 insertions(+), 262 deletions(-) create mode 100644 src/graphics/gpuparticles.cpp create mode 100644 src/graphics/gpuparticles.h diff --git a/sources.cmake b/sources.cmake index 6ed2afbdd..7ee80c697 100644 --- a/sources.cmake +++ b/sources.cmake @@ -34,6 +34,7 @@ src/graphics/camera.cpp src/graphics/CBatchingMesh.cpp src/graphics/explosion.cpp src/graphics/glow.cpp +src/graphics/gpuparticles.cpp src/graphics/hardware_skinning.cpp src/graphics/hit_sfx.cpp src/graphics/irr_driver.cpp @@ -478,8 +479,8 @@ src/modes/tutorial_world.hpp src/modes/world.hpp src/modes/world_status.hpp src/modes/world_with_rank.hpp -src/network/event.hpp src/network/client_network_manager.hpp +src/network/event.hpp src/network/game_setup.hpp src/network/network_interface.hpp src/network/network_manager.hpp @@ -636,10 +637,10 @@ src/tracks/track_object_presentation.hpp src/tracks/track_sector.hpp src/utils/aligned_array.hpp src/utils/constants.hpp +src/utils/crash_reporting.hpp src/utils/debug.hpp src/utils/helpers.hpp src/utils/interpolation_array.hpp -src/utils/crash_reporting.hpp src/utils/leak_check.hpp src/utils/log.hpp src/utils/no_copy.hpp diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp new file mode 100644 index 000000000..33260b0c3 --- /dev/null +++ b/src/graphics/gpuparticles.cpp @@ -0,0 +1,210 @@ +#if 0 +#include "graphics/irr_driver.hpp" +#include "gpuparticles.h" +#include +#include "io/file_manager.hpp" +#include "config/user_config.hpp" +#include + +void initGL() +{ +/* glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); + glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); + glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); + glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); + glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); + glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); + glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); + glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); + glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); + glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); + glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); +#ifdef _IRR_WINDOWS_API_ + glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); +#endif + glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); + glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");*/ +} + +// Mostly from shader tutorial +static +GLuint LoadShader(const char * file, unsigned type) { + GLuint Id = glCreateShader(type); + std::string Code; + std::ifstream Stream(file, std::ios::in); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + printf("Compiling shader : %s\n", file); + char const * SourcePointer = Code.c_str(); + int length = strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) { + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + return Id; +} + +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) { + GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); + + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { + GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint Program = glCreateProgram(); + glAttachShader(Program, Shader); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + glDeleteShader(Shader); + return Program; +} + +GLuint getTextureGLuint(irr::video::ITexture *tex) { + return static_cast(tex)->getOpenGLTextureName(); +} + +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, texid); + glUniform1i(location, textureUnit); +} + +GPUParticle::GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : + count(c), texture(tex), normal_and_depth(rtt) { + initGL(); + glGenBuffers(2, tfb_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); + + RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); + loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + texloc_tex = glGetUniformLocation(RenderProgram, "tex"); + texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); + + const char *varyings[] = {"currentPosition"}; + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); + loc_campos = glGetUniformLocation(SimulationProgram, "campos"); + loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); + loc_time = glGetUniformLocation(SimulationProgram, "time"); + } + +void GPUParticle::simulate() { + glUseProgram(SimulationProgram); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; + const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW); + const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); + + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); + + glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); + glUniform1f(loc_time, time); + glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisable(GL_RASTERIZER_DISCARD); +} + +void GPUParticle::render() { + const float screenw = (float)UserConfigParams::m_width; + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); + invproj.makeInverse(); + + bindUniformToTextureUnit(texloc_tex, texture, 0); + bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); + + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniform1f(loc_screenw, screenw); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); +} +#endif diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h new file mode 100644 index 000000000..85cb446fe --- /dev/null +++ b/src/graphics/gpuparticles.h @@ -0,0 +1,73 @@ +#if 0 +#ifndef GPUPARTICLES_H +#define GPUPARTICLES_H + +#define GL_GLEXT_PROTOTYPES 1 +#include "graphics/glwrap.hpp" +#include + +/*#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) +#else +#include +#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) +#endif + + +PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLUNIFORM1FPROC glUniform1f; +PFNGLUNIFORM3FPROC glUniform3f; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +#ifdef _IRR_WINDOWS_API_ +PFNGLACTIVETEXTUREPROC glActiveTexture; +#endif +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;*/ + +void initGL(); +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); +GLuint getTextureGLuint(irr::video::ITexture *tex); +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); + + +class GPUParticle { +private: + unsigned count; + GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; + GLuint texture, normal_and_depth; + GLuint loc_campos, loc_viewm, loc_time; + GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; +public: + GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt); + void simulate(); + void render(); +}; + +#endif // GPUPARTICLES_H +#endif diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index 0d794067a..07d5a4119 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -32,271 +32,17 @@ #include #include +#include "graphics/gpuparticles.h" using namespace video; using namespace scene; using namespace core; -// OPENGL PARTICLE SYSTEM -#include -#include "../source/Irrlicht/COpenGLExtensionHandler.h" -#include "io/file_manager.hpp" - -#ifdef _IRR_WINDOWS_API_ -#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) -#else -#include -#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) -#endif - - -PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; -PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; -PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -PFNGLBINDBUFFERBASEPROC glBindBufferBase; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLUNIFORM1FPROC glUniform1f; -PFNGLUNIFORM3FPROC glUniform3f; -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -#ifdef _IRR_WINDOWS_API_ -PFNGLACTIVETEXTUREPROC glActiveTexture; -#endif -PFNGLUNIFORM2FPROC glUniform2f; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; - -void initGL() -{ - glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); - glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); - glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); - glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); - glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); - glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); - glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); - glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); - glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); - glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); - glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); - glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); -#ifdef _IRR_WINDOWS_API_ - glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); -#endif - glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); - glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); - glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); -} - -// Mostly from shader tutorial -GLuint LoadShader(const char * file, unsigned type) { - GLuint Id = glCreateShader(type); - std::string Code; - std::ifstream Stream(file, std::ios::in); - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - Code += "\n" + Line; - Stream.close(); - } - GLint Result = GL_FALSE; - int InfoLogLength; - printf("Compiling shader : %s\n", file); - char const * SourcePointer = Code.c_str(); - int length = strlen(SourcePointer); - glShaderSource(Id, 1, &SourcePointer, &length); - glCompileShader(Id); - - glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); - if (Result == GL_FALSE) { - glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - return Id; -} - -GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path){ - GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); - - GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, FragmentShaderID); - glLinkProgram(ProgramID); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return ProgramID; -} - -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount){ - GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint Program = glCreateProgram(); - glAttachShader(Program, Shader); - glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(Program); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(Program, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - glDeleteShader(Shader); - return Program; -} - -GLuint getTextureGLuint(ITexture *tex) { return static_cast(tex)->getOpenGLTextureName(); } - -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, texid); - glUniform1i(location, textureUnit); -} - -class GPUParticle { -private: - GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; - GLuint texture, normal_and_depth; - GLuint loc_campos, loc_viewm, loc_time; - GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; - unsigned count; -public: - GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : - count(c), texture(tex), normal_and_depth(rtt) { - initGL(); - glGenBuffers(2, tfb_vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); - - RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); - loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); - loc_screen = glGetUniformLocation(RenderProgram, "screen"); - loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); - texloc_tex = glGetUniformLocation(RenderProgram, "tex"); - texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - - const char *varyings[] = {"currentPosition"}; - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); - loc_campos = glGetUniformLocation(SimulationProgram, "campos"); - loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); - loc_time = glGetUniformLocation(SimulationProgram, "time"); - } - - void simulate() { - glUseProgram(SimulationProgram); - const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const matrix4 viewm = irr_driver->getVideoDriver()->getTransform(ETS_VIEW); - const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); - - glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); - - glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); - glUniform1f(loc_time, time); - glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); - glBeginTransformFeedback(GL_POINTS); - glDrawArrays(GL_POINTS, 0, count); - glEndTransformFeedback(); - glDisable(GL_RASTERIZER_DISCARD); - } - - void render() { - const float screenw = (float)UserConfigParams::m_width; - - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); - glUseProgram(RenderProgram); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - - float screen[2] = { (float)UserConfigParams::m_width, - (float)UserConfigParams::m_height }; - matrix4 invproj = irr_driver->getVideoDriver()->getTransform(ETS_PROJECTION); - invproj.makeInverse(); - - bindUniformToTextureUnit(texloc_tex, texture, 0); - bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); - - glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(loc_screen, screen[0], screen[1]); - glUniform1f(loc_screenw, screenw); - glDrawArrays(GL_POINTS, 0, count); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - } -}; -// END OPENGL PARTICLE SYSTEM - // The actual rain node class RainNode: public scene::ISceneNode { private: - GPUParticle *gpupart; +// GPUParticle *gpupart; public: RainNode(scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(0, mgr, -1) @@ -326,7 +72,7 @@ public: vertices[3 * i + 1] = y; vertices[3 * i + 2] = z; } - gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); + //gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); box.addInternalPoint(vector3df((float)(-area/2))); box.addInternalPoint(vector3df((float)( area/2))); @@ -334,13 +80,13 @@ public: ~RainNode() { - delete gpupart; +// delete gpupart; } virtual void render() { - gpupart->simulate(); - gpupart->render(); +// gpupart->simulate(); +// gpupart->render(); // We need to force irrlicht to update its internal states IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setMaterial(mat); From 187abe584bdcec553f5997294a5f93b4a4684920 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 22:02:12 +0000 Subject: [PATCH 064/412] GPUParticles: Reenable rain, windows build is fixed git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14815 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 1315 +++++++++++++++++---------------- src/graphics/gpuparticles.cpp | 48 +- src/graphics/gpuparticles.h | 49 +- src/graphics/rain.cpp | 10 +- 4 files changed, 708 insertions(+), 714 deletions(-) diff --git a/sources.cmake b/sources.cmake index 7ee80c697..ecc5e0cc4 100644 --- a/sources.cmake +++ b/sources.cmake @@ -1,657 +1,658 @@ -# Generated by ./update_file_list.sh. Do not edit this file manually. -set(STK_SOURCES -src/achievements/achievement.cpp -src/achievements/achievement_info.cpp -src/achievements/achievements_manager.cpp -src/achievements/achievements_slot.cpp -src/addons/addon.cpp -src/addons/addons_manager.cpp -src/addons/inetwork_http.cpp -src/addons/network_http.cpp -src/addons/news_manager.cpp -src/addons/request.cpp -src/addons/zip.cpp -src/animations/animation_base.cpp -src/animations/ipo.cpp -src/animations/three_d_animation.cpp -src/audio/music_information.cpp -src/audio/music_manager.cpp -src/audio/music_ogg.cpp -src/audio/sfx_buffer.cpp -src/audio/sfx_manager.cpp -src/audio/sfx_openal.cpp -src/challenges/challenge.cpp -src/challenges/challenge_data.cpp -src/challenges/game_slot.cpp -src/challenges/unlock_manager.cpp -src/config/device_config.cpp -src/config/player.cpp -src/config/saved_grand_prix.cpp -src/config/stk_config.cpp -src/config/user_config.cpp -src/graphics/callbacks.cpp -src/graphics/camera.cpp -src/graphics/CBatchingMesh.cpp -src/graphics/explosion.cpp -src/graphics/glow.cpp -src/graphics/gpuparticles.cpp -src/graphics/hardware_skinning.cpp -src/graphics/hit_sfx.cpp -src/graphics/irr_driver.cpp -src/graphics/lens_flare.cpp -src/graphics/light.cpp -src/graphics/lod_node.cpp -src/graphics/material.cpp -src/graphics/material_manager.cpp -src/graphics/mesh_tools.cpp -src/graphics/moving_texture.cpp -src/graphics/particle_emitter.cpp -src/graphics/particle_kind.cpp -src/graphics/particle_kind_manager.cpp -src/graphics/per_camera_node.cpp -src/graphics/post_processing.cpp -src/graphics/rain.cpp -src/graphics/referee.cpp -src/graphics/render.cpp -src/graphics/rtts.cpp -src/graphics/screenquad.cpp -src/graphics/shaders.cpp -src/graphics/shadow.cpp -src/graphics/shadow_importance.cpp -src/graphics/show_curve.cpp -src/graphics/skid_marks.cpp -src/graphics/slip_stream.cpp -src/graphics/stars.cpp -src/graphics/sun.cpp -src/graphics/water.cpp -src/graphics/wind.cpp -src/guiengine/abstract_state_manager.cpp -src/guiengine/abstract_top_level_container.cpp -src/guiengine/CGUISpriteBank.cpp -src/guiengine/dialog_queue.cpp -src/guiengine/engine.cpp -src/guiengine/event_handler.cpp -src/guiengine/layout_manager.cpp -src/guiengine/modaldialog.cpp -src/guiengine/scalable_font.cpp -src/guiengine/screen.cpp -src/guiengine/screen_loader.cpp -src/guiengine/skin.cpp -src/guiengine/widget.cpp -src/guiengine/widgets/bubble_widget.cpp -src/guiengine/widgets/button_widget.cpp -src/guiengine/widgets/CGUIEditBox.cpp -src/guiengine/widgets/CGUISTKListBox.cpp -src/guiengine/widgets/check_box_widget.cpp -src/guiengine/widgets/dynamic_ribbon_widget.cpp -src/guiengine/widgets/icon_button_widget.cpp -src/guiengine/widgets/label_widget.cpp -src/guiengine/widgets/list_widget.cpp -src/guiengine/widgets/model_view_widget.cpp -src/guiengine/widgets/progress_bar_widget.cpp -src/guiengine/widgets/rating_bar_widget.cpp -src/guiengine/widgets/ribbon_widget.cpp -src/guiengine/widgets/spinner_widget.cpp -src/guiengine/widgets/text_box_widget.cpp -src/input/binding.cpp -src/input/device_manager.cpp -src/input/input_device.cpp -src/input/input_manager.cpp -src/input/wiimote.cpp -src/input/wiimote_manager.cpp -src/io/file_manager.cpp -src/io/xml_node.cpp -src/io/xml_writer.cpp -src/items/attachment.cpp -src/items/attachment_manager.cpp -src/items/bowling.cpp -src/items/cake.cpp -src/items/flyable.cpp -src/items/item.cpp -src/items/item_manager.cpp -src/items/plunger.cpp -src/items/powerup.cpp -src/items/powerup_manager.cpp -src/items/projectile_manager.cpp -src/items/rubber_ball.cpp -src/items/rubber_band.cpp -src/items/swatter.cpp -src/karts/abstract_kart_animation.cpp -src/karts/abstract_kart.cpp -src/karts/cannon_animation.cpp -src/karts/controller/ai_base_controller.cpp -src/karts/controller/ai_properties.cpp -src/karts/controller/controller.cpp -src/karts/controller/end_controller.cpp -src/karts/controller/network_player_controller.cpp -src/karts/controller/player_controller.cpp -src/karts/controller/skidding_ai.cpp -src/karts/explosion_animation.cpp -src/karts/ghost_kart.cpp -src/karts/kart.cpp -src/karts/kart_gfx.cpp -src/karts/kart_model.cpp -src/karts/kart_properties.cpp -src/karts/kart_properties_manager.cpp -src/karts/kart_with_stats.cpp -src/karts/max_speed.cpp -src/karts/moveable.cpp -src/karts/rescue_animation.cpp -src/karts/skidding.cpp -src/karts/skidding_properties.cpp -src/main.cpp -src/main_loop.cpp -src/modes/cutscene_world.cpp -src/modes/demo_world.cpp -src/modes/easter_egg_hunt.cpp -src/modes/follow_the_leader.cpp -src/modes/linear_world.cpp -src/modes/overworld.cpp -src/modes/profile_world.cpp -src/modes/soccer_world.cpp -src/modes/standard_race.cpp -src/modes/three_strikes_battle.cpp -src/modes/tutorial_world.cpp -src/modes/world.cpp -src/modes/world_status.cpp -src/modes/world_with_rank.cpp -src/network/client_network_manager.cpp -src/network/event.cpp -src/network/game_setup.cpp -src/network/network_interface.cpp -src/network/network_manager.cpp -src/network/network_string.cpp -src/network/network_world.cpp -src/network/protocol.cpp -src/network/protocol_manager.cpp -src/network/protocols/client_lobby_room_protocol.cpp -src/network/protocols/connect_to_peer.cpp -src/network/protocols/connect_to_server.cpp -src/network/protocols/controller_events_protocol.cpp -src/network/protocols/game_events_protocol.cpp -src/network/protocols/get_peer_address.cpp -src/network/protocols/get_public_address.cpp -src/network/protocols/hide_public_address.cpp -src/network/protocols/kart_update_protocol.cpp -src/network/protocols/lobby_room_protocol.cpp -src/network/protocols/ping_protocol.cpp -src/network/protocols/quick_join_protocol.cpp -src/network/protocols/request_connection.cpp -src/network/protocols/server_lobby_room_protocol.cpp -src/network/protocols/show_public_address.cpp -src/network/protocols/start_game_protocol.cpp -src/network/protocols/start_server.cpp -src/network/protocols/stop_server.cpp -src/network/protocols/synchronization_protocol.cpp -src/network/race_config.cpp -src/network/server_network_manager.cpp -src/network/stk_host.cpp -src/network/stk_peer.cpp -src/network/types.cpp -src/online/current_user.cpp -src/online/http_manager.cpp -src/online/messages.cpp -src/online/profile.cpp -src/online/profile_manager.cpp -src/online/request.cpp -src/online/server.cpp -src/online/servers_manager.cpp -src/physics/btKart.cpp -src/physics/btKartRaycast.cpp -src/physics/btUprightConstraint.cpp -src/physics/irr_debug_drawer.cpp -src/physics/physical_object.cpp -src/physics/physics.cpp -src/physics/triangle_mesh.cpp -src/race/grand_prix_data.cpp -src/race/grand_prix_manager.cpp -src/race/highscore_manager.cpp -src/race/highscores.cpp -src/race/history.cpp -src/race/race_manager.cpp -src/replay/replay_base.cpp -src/replay/replay_play.cpp -src/replay/replay_recorder.cpp -src/states_screens/addons_screen.cpp -src/states_screens/arenas_screen.cpp -src/states_screens/create_server_screen.cpp -src/states_screens/credits.cpp -src/states_screens/cutscene_gui.cpp -src/states_screens/dialogs/add_device_dialog.cpp -src/states_screens/dialogs/addons_loading.cpp -src/states_screens/dialogs/change_password_dialog.cpp -src/states_screens/dialogs/confirm_resolution_dialog.cpp -src/states_screens/dialogs/custom_video_settings.cpp -src/states_screens/dialogs/enter_player_name_dialog.cpp -src/states_screens/dialogs/gp_info_dialog.cpp -src/states_screens/dialogs/login_dialog.cpp -src/states_screens/dialogs/message_dialog.cpp -src/states_screens/dialogs/notification_dialog.cpp -src/states_screens/dialogs/player_info_dialog.cpp -src/states_screens/dialogs/press_a_key_dialog.cpp -src/states_screens/dialogs/race_paused_dialog.cpp -src/states_screens/dialogs/recovery_dialog.cpp -src/states_screens/dialogs/registration_dialog.cpp -src/states_screens/dialogs/select_challenge.cpp -src/states_screens/dialogs/server_info_dialog.cpp -src/states_screens/dialogs/track_info_dialog.cpp -src/states_screens/dialogs/tutorial_message_dialog.cpp -src/states_screens/dialogs/user_info_dialog.cpp -src/states_screens/dialogs/vote_dialog.cpp -src/states_screens/easter_egg_screen.cpp -src/states_screens/feature_unlocked.cpp -src/states_screens/grand_prix_lose.cpp -src/states_screens/grand_prix_win.cpp -src/states_screens/help_screen_1.cpp -src/states_screens/help_screen_2.cpp -src/states_screens/help_screen_3.cpp -src/states_screens/help_screen_4.cpp -src/states_screens/kart_selection.cpp -src/states_screens/main_menu_screen.cpp -src/states_screens/networking_lobby.cpp -src/states_screens/network_kart_selection.cpp -src/states_screens/offline_kart_selection.cpp -src/states_screens/online_profile_achievements.cpp -src/states_screens/online_profile_base.cpp -src/states_screens/online_profile_friends.cpp -src/states_screens/online_profile_overview.cpp -src/states_screens/online_profile_settings.cpp -src/states_screens/online_screen.cpp -src/states_screens/online_user_search.cpp -src/states_screens/options_screen_audio.cpp -src/states_screens/options_screen_input2.cpp -src/states_screens/options_screen_input.cpp -src/states_screens/options_screen_players.cpp -src/states_screens/options_screen_ui.cpp -src/states_screens/options_screen_video.cpp -src/states_screens/race_gui_base.cpp -src/states_screens/race_gui.cpp -src/states_screens/race_gui_overworld.cpp -src/states_screens/race_result_gui.cpp -src/states_screens/race_setup_screen.cpp -src/states_screens/server_selection.cpp -src/states_screens/soccer_setup_screen.cpp -src/states_screens/state_manager.cpp -src/states_screens/story_mode_lobby.cpp -src/states_screens/tracks_screen.cpp -src/tinygettext/dictionary.cpp -src/tinygettext/dictionary_manager.cpp -src/tinygettext/iconv.cpp -src/tinygettext/language.cpp -src/tinygettext/plural_forms.cpp -src/tinygettext/po_parser.cpp -src/tinygettext/stk_file_system.cpp -src/tinygettext/tgt_log.cpp -src/tinygettext/tinygettext.cpp -src/tracks/ambient_light_sphere.cpp -src/tracks/bezier_curve.cpp -src/tracks/check_cannon.cpp -src/tracks/check_goal.cpp -src/tracks/check_lap.cpp -src/tracks/check_line.cpp -src/tracks/check_manager.cpp -src/tracks/check_sphere.cpp -src/tracks/check_structure.cpp -src/tracks/graph_node.cpp -src/tracks/lod_node_loader.cpp -src/tracks/quad.cpp -src/tracks/quad_graph.cpp -src/tracks/quad_set.cpp -src/tracks/terrain_info.cpp -src/tracks/track.cpp -src/tracks/track_manager.cpp -src/tracks/track_object.cpp -src/tracks/track_object_manager.cpp -src/tracks/track_object_presentation.cpp -src/tracks/track_sector.cpp -src/utils/constants.cpp -src/utils/crash_reporting.cpp -src/utils/debug.cpp -src/utils/helpers.cpp -src/utils/leak_check.cpp -src/utils/log.cpp -src/utils/profiler.cpp -src/utils/random_generator.cpp -src/utils/string_utils.cpp -src/utils/time.cpp -src/utils/translation.cpp -src/utils/vec3.cpp -) -set(STK_HEADERS -src/achievements/achievement.hpp -src/achievements/achievement_info.hpp -src/achievements/achievements_manager.hpp -src/achievements/achievements_slot.hpp -src/addons/addon.hpp -src/addons/addons_manager.hpp -src/addons/dummy_network_http.hpp -src/addons/inetwork_http.hpp -src/addons/network_http.hpp -src/addons/news_manager.hpp -src/addons/request.hpp -src/addons/zip.hpp -src/animations/animation_base.hpp -src/animations/ipo.hpp -src/animations/three_d_animation.hpp -src/audio/dummy_sfx.hpp -src/audio/music_dummy.hpp -src/audio/music.hpp -src/audio/music_information.hpp -src/audio/music_manager.hpp -src/audio/music_ogg.hpp -src/audio/sfx_base.hpp -src/audio/sfx_buffer.hpp -src/audio/sfx_manager.hpp -src/audio/sfx_openal.hpp -src/challenges/challenge_data.hpp -src/challenges/challenge.hpp -src/challenges/game_slot.hpp -src/challenges/unlock_manager.hpp -src/config/device_config.hpp -src/config/player.hpp -src/config/saved_grand_prix.hpp -src/config/stk_config.hpp -src/config/user_config.hpp -src/graphics/callbacks.hpp -src/graphics/camera.hpp -src/graphics/CBatchingMesh.hpp -src/graphics/explosion.hpp -src/graphics/glow.hpp -src/graphics/glwrap.hpp -src/graphics/hardware_skinning.hpp -src/graphics/hit_effect.hpp -src/graphics/hit_sfx.hpp -src/graphics/irr_driver.hpp -src/graphics/large_mesh_buffer.hpp -src/graphics/lens_flare.hpp -src/graphics/light.hpp -src/graphics/lod_node.hpp -src/graphics/material.hpp -src/graphics/material_manager.hpp -src/graphics/mesh_tools.hpp -src/graphics/mlaa_areamap.hpp -src/graphics/moving_texture.hpp -src/graphics/particle_emitter.hpp -src/graphics/particle_kind.hpp -src/graphics/particle_kind_manager.hpp -src/graphics/per_camera_node.hpp -src/graphics/post_processing.hpp -src/graphics/rain.hpp -src/graphics/referee.hpp -src/graphics/rtts.hpp -src/graphics/screenquad.hpp -src/graphics/shaders.hpp -src/graphics/shadow.hpp -src/graphics/shadow_importance.hpp -src/graphics/show_curve.hpp -src/graphics/skid_marks.hpp -src/graphics/slip_stream.hpp -src/graphics/stars.hpp -src/graphics/sun.hpp -src/graphics/water.hpp -src/graphics/wind.hpp -src/guiengine/abstract_state_manager.hpp -src/guiengine/abstract_top_level_container.hpp -src/guiengine/dialog_queue.hpp -src/guiengine/engine.hpp -src/guiengine/event_handler.hpp -src/guiengine/layout_manager.hpp -src/guiengine/modaldialog.hpp -src/guiengine/scalable_font.hpp -src/guiengine/screen.hpp -src/guiengine/skin.hpp -src/guiengine/widget.hpp -src/guiengine/widgets/bubble_widget.hpp -src/guiengine/widgets/button_widget.hpp -src/guiengine/widgets/check_box_widget.hpp -src/guiengine/widgets/dynamic_ribbon_widget.hpp -src/guiengine/widgets.hpp -src/guiengine/widgets/icon_button_widget.hpp -src/guiengine/widgets/label_widget.hpp -src/guiengine/widgets/list_widget.hpp -src/guiengine/widgets/model_view_widget.hpp -src/guiengine/widgets/progress_bar_widget.hpp -src/guiengine/widgets/rating_bar_widget.hpp -src/guiengine/widgets/ribbon_widget.hpp -src/guiengine/widgets/spinner_widget.hpp -src/guiengine/widgets/text_box_widget.hpp -src/input/binding.hpp -src/input/device_manager.hpp -src/input/input_device.hpp -src/input/input.hpp -src/input/input_manager.hpp -src/input/wiimote.hpp -src/input/wiimote_manager.hpp -src/io/file_manager.hpp -src/io/xml_node.hpp -src/io/xml_writer.hpp -src/items/attachment.hpp -src/items/attachment_manager.hpp -src/items/attachment_plugin.hpp -src/items/bowling.hpp -src/items/cake.hpp -src/items/flyable.hpp -src/items/item.hpp -src/items/item_manager.hpp -src/items/plunger.hpp -src/items/powerup.hpp -src/items/powerup_manager.hpp -src/items/projectile_manager.hpp -src/items/rubber_ball.hpp -src/items/rubber_band.hpp -src/items/swatter.hpp -src/karts/abstract_kart_animation.hpp -src/karts/abstract_kart.hpp -src/karts/cannon_animation.hpp -src/karts/controller/ai_base_controller.hpp -src/karts/controller/ai_properties.hpp -src/karts/controller/controller.hpp -src/karts/controller/end_controller.hpp -src/karts/controller/kart_control.hpp -src/karts/controller/network_player_controller.hpp -src/karts/controller/player_controller.hpp -src/karts/controller/skidding_ai.hpp -src/karts/explosion_animation.hpp -src/karts/ghost_kart.hpp -src/karts/kart_gfx.hpp -src/karts/kart.hpp -src/karts/kart_model.hpp -src/karts/kart_properties.hpp -src/karts/kart_properties_manager.hpp -src/karts/kart_with_stats.hpp -src/karts/max_speed.hpp -src/karts/moveable.hpp -src/karts/rescue_animation.hpp -src/karts/skidding.hpp -src/karts/skidding_properties.hpp -src/main_loop.hpp -src/modes/cutscene_world.hpp -src/modes/demo_world.hpp -src/modes/easter_egg_hunt.hpp -src/modes/follow_the_leader.hpp -src/modes/linear_world.hpp -src/modes/overworld.hpp -src/modes/profile_world.hpp -src/modes/soccer_world.hpp -src/modes/standard_race.hpp -src/modes/three_strikes_battle.hpp -src/modes/tutorial_world.hpp -src/modes/world.hpp -src/modes/world_status.hpp -src/modes/world_with_rank.hpp -src/network/client_network_manager.hpp -src/network/event.hpp -src/network/game_setup.hpp -src/network/network_interface.hpp -src/network/network_manager.hpp -src/network/network_string.hpp -src/network/network_world.hpp -src/network/protocol.hpp -src/network/protocol_manager.hpp -src/network/protocols/client_lobby_room_protocol.hpp -src/network/protocols/connect_to_peer.hpp -src/network/protocols/connect_to_server.hpp -src/network/protocols/controller_events_protocol.hpp -src/network/protocols/game_events_protocol.hpp -src/network/protocols/get_peer_address.hpp -src/network/protocols/get_public_address.hpp -src/network/protocols/hide_public_address.hpp -src/network/protocols/kart_update_protocol.hpp -src/network/protocols/lobby_room_protocol.hpp -src/network/protocols/ping_protocol.hpp -src/network/protocols/quick_join_protocol.hpp -src/network/protocols/request_connection.hpp -src/network/protocols/server_lobby_room_protocol.hpp -src/network/protocols/show_public_address.hpp -src/network/protocols/start_game_protocol.hpp -src/network/protocols/start_server.hpp -src/network/protocols/stop_server.hpp -src/network/protocols/synchronization_protocol.hpp -src/network/race_config.hpp -src/network/remote_kart_info.hpp -src/network/server_network_manager.hpp -src/network/singleton.hpp -src/network/stk_host.hpp -src/network/stk_peer.hpp -src/network/types.hpp -src/online/current_user.hpp -src/online/http_manager.hpp -src/online/messages.hpp -src/online/profile.hpp -src/online/profile_manager.hpp -src/online/request.hpp -src/online/server.hpp -src/online/servers_manager.hpp -src/physics/btKart.hpp -src/physics/btKartRaycast.hpp -src/physics/btUprightConstraint.hpp -src/physics/irr_debug_drawer.hpp -src/physics/kart_motion_state.hpp -src/physics/physical_object.hpp -src/physics/physics.hpp -src/physics/stk_dynamics_world.hpp -src/physics/triangle_mesh.hpp -src/physics/user_pointer.hpp -src/race/grand_prix_data.hpp -src/race/grand_prix_manager.hpp -src/race/highscore_manager.hpp -src/race/highscores.hpp -src/race/history.hpp -src/race/race_manager.hpp -src/replay/replay_base.hpp -src/replay/replay_play.hpp -src/replay/replay_recorder.hpp -src/states_screens/addons_screen.hpp -src/states_screens/arenas_screen.hpp -src/states_screens/create_server_screen.hpp -src/states_screens/credits.hpp -src/states_screens/cutscene_gui.hpp -src/states_screens/dialogs/add_device_dialog.hpp -src/states_screens/dialogs/addons_loading.hpp -src/states_screens/dialogs/change_password_dialog.hpp -src/states_screens/dialogs/confirm_resolution_dialog.hpp -src/states_screens/dialogs/custom_video_settings.hpp -src/states_screens/dialogs/enter_player_name_dialog.hpp -src/states_screens/dialogs/gp_info_dialog.hpp -src/states_screens/dialogs/login_dialog.hpp -src/states_screens/dialogs/message_dialog.hpp -src/states_screens/dialogs/notification_dialog.hpp -src/states_screens/dialogs/player_info_dialog.hpp -src/states_screens/dialogs/press_a_key_dialog.hpp -src/states_screens/dialogs/race_paused_dialog.hpp -src/states_screens/dialogs/recovery_dialog.hpp -src/states_screens/dialogs/registration_dialog.hpp -src/states_screens/dialogs/select_challenge.hpp -src/states_screens/dialogs/server_info_dialog.hpp -src/states_screens/dialogs/track_info_dialog.hpp -src/states_screens/dialogs/tutorial_message_dialog.hpp -src/states_screens/dialogs/user_info_dialog.hpp -src/states_screens/dialogs/vote_dialog.hpp -src/states_screens/easter_egg_screen.hpp -src/states_screens/feature_unlocked.hpp -src/states_screens/grand_prix_lose.hpp -src/states_screens/grand_prix_win.hpp -src/states_screens/help_screen_1.hpp -src/states_screens/help_screen_2.hpp -src/states_screens/help_screen_3.hpp -src/states_screens/help_screen_4.hpp -src/states_screens/kart_selection.hpp -src/states_screens/main_menu_screen.hpp -src/states_screens/networking_lobby.hpp -src/states_screens/network_kart_selection.hpp -src/states_screens/offline_kart_selection.hpp -src/states_screens/online_profile_achievements.hpp -src/states_screens/online_profile_base.hpp -src/states_screens/online_profile_friends.hpp -src/states_screens/online_profile_overview.hpp -src/states_screens/online_profile_settings.hpp -src/states_screens/online_screen.hpp -src/states_screens/online_user_search.hpp -src/states_screens/options_screen_audio.hpp -src/states_screens/options_screen_input2.hpp -src/states_screens/options_screen_input.hpp -src/states_screens/options_screen_players.hpp -src/states_screens/options_screen_ui.hpp -src/states_screens/options_screen_video.hpp -src/states_screens/race_gui_base.hpp -src/states_screens/race_gui.hpp -src/states_screens/race_gui_overworld.hpp -src/states_screens/race_result_gui.hpp -src/states_screens/race_setup_screen.hpp -src/states_screens/server_selection.hpp -src/states_screens/soccer_setup_screen.hpp -src/states_screens/state_manager.hpp -src/states_screens/story_mode_lobby.hpp -src/states_screens/tracks_screen.hpp -src/tinygettext/dictionary.hpp -src/tinygettext/dictionary_manager.hpp -src/tinygettext/file_system.hpp -src/tinygettext/iconv.hpp -src/tinygettext/language.hpp -src/tinygettext/log_stream.hpp -src/tinygettext/plural_forms.hpp -src/tinygettext/po_parser.hpp -src/tinygettext/stk_file_system.hpp -src/tinygettext/tgt_log.hpp -src/tinygettext/tinygettext.hpp -src/tracks/ambient_light_sphere.hpp -src/tracks/bezier_curve.hpp -src/tracks/check_cannon.hpp -src/tracks/check_goal.hpp -src/tracks/check_lap.hpp -src/tracks/check_line.hpp -src/tracks/check_manager.hpp -src/tracks/check_sphere.hpp -src/tracks/check_structure.hpp -src/tracks/graph_node.hpp -src/tracks/lod_node_loader.hpp -src/tracks/quad_graph.hpp -src/tracks/quad.hpp -src/tracks/quad_set.hpp -src/tracks/terrain_info.hpp -src/tracks/track.hpp -src/tracks/track_manager.hpp -src/tracks/track_object.hpp -src/tracks/track_object_manager.hpp -src/tracks/track_object_presentation.hpp -src/tracks/track_sector.hpp -src/utils/aligned_array.hpp -src/utils/constants.hpp -src/utils/crash_reporting.hpp -src/utils/debug.hpp -src/utils/helpers.hpp -src/utils/interpolation_array.hpp -src/utils/leak_check.hpp -src/utils/log.hpp -src/utils/no_copy.hpp -src/utils/profiler.hpp -src/utils/ptr_vector.hpp -src/utils/random_generator.hpp -src/utils/string_utils.hpp -src/utils/synchronised.hpp -src/utils/time.hpp -src/utils/translation.hpp -src/utils/types.hpp -src/utils/vec3.hpp -src/utils/vs.hpp -) +# Generated by ./update_file_list.sh. Do not edit this file manually. +set(STK_SOURCES +src/achievements/achievement.cpp +src/achievements/achievement_info.cpp +src/achievements/achievements_manager.cpp +src/achievements/achievements_slot.cpp +src/addons/addon.cpp +src/addons/addons_manager.cpp +src/addons/inetwork_http.cpp +src/addons/network_http.cpp +src/addons/news_manager.cpp +src/addons/request.cpp +src/addons/zip.cpp +src/animations/animation_base.cpp +src/animations/ipo.cpp +src/animations/three_d_animation.cpp +src/audio/music_information.cpp +src/audio/music_manager.cpp +src/audio/music_ogg.cpp +src/audio/sfx_buffer.cpp +src/audio/sfx_manager.cpp +src/audio/sfx_openal.cpp +src/challenges/challenge.cpp +src/challenges/challenge_data.cpp +src/challenges/game_slot.cpp +src/challenges/unlock_manager.cpp +src/config/device_config.cpp +src/config/player.cpp +src/config/saved_grand_prix.cpp +src/config/stk_config.cpp +src/config/user_config.cpp +src/graphics/callbacks.cpp +src/graphics/camera.cpp +src/graphics/CBatchingMesh.cpp +src/graphics/explosion.cpp +src/graphics/glow.cpp +src/graphics/gpuparticles.cpp +src/graphics/hardware_skinning.cpp +src/graphics/hit_sfx.cpp +src/graphics/irr_driver.cpp +src/graphics/lens_flare.cpp +src/graphics/light.cpp +src/graphics/lod_node.cpp +src/graphics/material.cpp +src/graphics/material_manager.cpp +src/graphics/mesh_tools.cpp +src/graphics/moving_texture.cpp +src/graphics/particle_emitter.cpp +src/graphics/particle_kind.cpp +src/graphics/particle_kind_manager.cpp +src/graphics/per_camera_node.cpp +src/graphics/post_processing.cpp +src/graphics/rain.cpp +src/graphics/referee.cpp +src/graphics/render.cpp +src/graphics/rtts.cpp +src/graphics/screenquad.cpp +src/graphics/shaders.cpp +src/graphics/shadow.cpp +src/graphics/shadow_importance.cpp +src/graphics/show_curve.cpp +src/graphics/skid_marks.cpp +src/graphics/slip_stream.cpp +src/graphics/stars.cpp +src/graphics/sun.cpp +src/graphics/water.cpp +src/graphics/wind.cpp +src/guiengine/abstract_state_manager.cpp +src/guiengine/abstract_top_level_container.cpp +src/guiengine/CGUISpriteBank.cpp +src/guiengine/dialog_queue.cpp +src/guiengine/engine.cpp +src/guiengine/event_handler.cpp +src/guiengine/layout_manager.cpp +src/guiengine/modaldialog.cpp +src/guiengine/scalable_font.cpp +src/guiengine/screen.cpp +src/guiengine/screen_loader.cpp +src/guiengine/skin.cpp +src/guiengine/widget.cpp +src/guiengine/widgets/bubble_widget.cpp +src/guiengine/widgets/button_widget.cpp +src/guiengine/widgets/CGUIEditBox.cpp +src/guiengine/widgets/CGUISTKListBox.cpp +src/guiengine/widgets/check_box_widget.cpp +src/guiengine/widgets/dynamic_ribbon_widget.cpp +src/guiengine/widgets/icon_button_widget.cpp +src/guiengine/widgets/label_widget.cpp +src/guiengine/widgets/list_widget.cpp +src/guiengine/widgets/model_view_widget.cpp +src/guiengine/widgets/progress_bar_widget.cpp +src/guiengine/widgets/rating_bar_widget.cpp +src/guiengine/widgets/ribbon_widget.cpp +src/guiengine/widgets/spinner_widget.cpp +src/guiengine/widgets/text_box_widget.cpp +src/input/binding.cpp +src/input/device_manager.cpp +src/input/input_device.cpp +src/input/input_manager.cpp +src/input/wiimote.cpp +src/input/wiimote_manager.cpp +src/io/file_manager.cpp +src/io/xml_node.cpp +src/io/xml_writer.cpp +src/items/attachment.cpp +src/items/attachment_manager.cpp +src/items/bowling.cpp +src/items/cake.cpp +src/items/flyable.cpp +src/items/item.cpp +src/items/item_manager.cpp +src/items/plunger.cpp +src/items/powerup.cpp +src/items/powerup_manager.cpp +src/items/projectile_manager.cpp +src/items/rubber_ball.cpp +src/items/rubber_band.cpp +src/items/swatter.cpp +src/karts/abstract_kart_animation.cpp +src/karts/abstract_kart.cpp +src/karts/cannon_animation.cpp +src/karts/controller/ai_base_controller.cpp +src/karts/controller/ai_properties.cpp +src/karts/controller/controller.cpp +src/karts/controller/end_controller.cpp +src/karts/controller/network_player_controller.cpp +src/karts/controller/player_controller.cpp +src/karts/controller/skidding_ai.cpp +src/karts/explosion_animation.cpp +src/karts/ghost_kart.cpp +src/karts/kart.cpp +src/karts/kart_gfx.cpp +src/karts/kart_model.cpp +src/karts/kart_properties.cpp +src/karts/kart_properties_manager.cpp +src/karts/kart_with_stats.cpp +src/karts/max_speed.cpp +src/karts/moveable.cpp +src/karts/rescue_animation.cpp +src/karts/skidding.cpp +src/karts/skidding_properties.cpp +src/main.cpp +src/main_loop.cpp +src/modes/cutscene_world.cpp +src/modes/demo_world.cpp +src/modes/easter_egg_hunt.cpp +src/modes/follow_the_leader.cpp +src/modes/linear_world.cpp +src/modes/overworld.cpp +src/modes/profile_world.cpp +src/modes/soccer_world.cpp +src/modes/standard_race.cpp +src/modes/three_strikes_battle.cpp +src/modes/tutorial_world.cpp +src/modes/world.cpp +src/modes/world_status.cpp +src/modes/world_with_rank.cpp +src/network/client_network_manager.cpp +src/network/event.cpp +src/network/game_setup.cpp +src/network/network_interface.cpp +src/network/network_manager.cpp +src/network/network_string.cpp +src/network/network_world.cpp +src/network/protocol.cpp +src/network/protocol_manager.cpp +src/network/protocols/client_lobby_room_protocol.cpp +src/network/protocols/connect_to_peer.cpp +src/network/protocols/connect_to_server.cpp +src/network/protocols/controller_events_protocol.cpp +src/network/protocols/game_events_protocol.cpp +src/network/protocols/get_peer_address.cpp +src/network/protocols/get_public_address.cpp +src/network/protocols/hide_public_address.cpp +src/network/protocols/kart_update_protocol.cpp +src/network/protocols/lobby_room_protocol.cpp +src/network/protocols/ping_protocol.cpp +src/network/protocols/quick_join_protocol.cpp +src/network/protocols/request_connection.cpp +src/network/protocols/server_lobby_room_protocol.cpp +src/network/protocols/show_public_address.cpp +src/network/protocols/start_game_protocol.cpp +src/network/protocols/start_server.cpp +src/network/protocols/stop_server.cpp +src/network/protocols/synchronization_protocol.cpp +src/network/race_config.cpp +src/network/server_network_manager.cpp +src/network/stk_host.cpp +src/network/stk_peer.cpp +src/network/types.cpp +src/online/current_user.cpp +src/online/http_manager.cpp +src/online/messages.cpp +src/online/profile.cpp +src/online/profile_manager.cpp +src/online/request.cpp +src/online/server.cpp +src/online/servers_manager.cpp +src/physics/btKart.cpp +src/physics/btKartRaycast.cpp +src/physics/btUprightConstraint.cpp +src/physics/irr_debug_drawer.cpp +src/physics/physical_object.cpp +src/physics/physics.cpp +src/physics/triangle_mesh.cpp +src/race/grand_prix_data.cpp +src/race/grand_prix_manager.cpp +src/race/highscore_manager.cpp +src/race/highscores.cpp +src/race/history.cpp +src/race/race_manager.cpp +src/replay/replay_base.cpp +src/replay/replay_play.cpp +src/replay/replay_recorder.cpp +src/states_screens/addons_screen.cpp +src/states_screens/arenas_screen.cpp +src/states_screens/create_server_screen.cpp +src/states_screens/credits.cpp +src/states_screens/cutscene_gui.cpp +src/states_screens/dialogs/add_device_dialog.cpp +src/states_screens/dialogs/addons_loading.cpp +src/states_screens/dialogs/change_password_dialog.cpp +src/states_screens/dialogs/confirm_resolution_dialog.cpp +src/states_screens/dialogs/custom_video_settings.cpp +src/states_screens/dialogs/enter_player_name_dialog.cpp +src/states_screens/dialogs/gp_info_dialog.cpp +src/states_screens/dialogs/login_dialog.cpp +src/states_screens/dialogs/message_dialog.cpp +src/states_screens/dialogs/notification_dialog.cpp +src/states_screens/dialogs/player_info_dialog.cpp +src/states_screens/dialogs/press_a_key_dialog.cpp +src/states_screens/dialogs/race_paused_dialog.cpp +src/states_screens/dialogs/recovery_dialog.cpp +src/states_screens/dialogs/registration_dialog.cpp +src/states_screens/dialogs/select_challenge.cpp +src/states_screens/dialogs/server_info_dialog.cpp +src/states_screens/dialogs/track_info_dialog.cpp +src/states_screens/dialogs/tutorial_message_dialog.cpp +src/states_screens/dialogs/user_info_dialog.cpp +src/states_screens/dialogs/vote_dialog.cpp +src/states_screens/easter_egg_screen.cpp +src/states_screens/feature_unlocked.cpp +src/states_screens/grand_prix_lose.cpp +src/states_screens/grand_prix_win.cpp +src/states_screens/help_screen_1.cpp +src/states_screens/help_screen_2.cpp +src/states_screens/help_screen_3.cpp +src/states_screens/help_screen_4.cpp +src/states_screens/kart_selection.cpp +src/states_screens/main_menu_screen.cpp +src/states_screens/networking_lobby.cpp +src/states_screens/network_kart_selection.cpp +src/states_screens/offline_kart_selection.cpp +src/states_screens/online_profile_achievements.cpp +src/states_screens/online_profile_base.cpp +src/states_screens/online_profile_friends.cpp +src/states_screens/online_profile_overview.cpp +src/states_screens/online_profile_settings.cpp +src/states_screens/online_screen.cpp +src/states_screens/online_user_search.cpp +src/states_screens/options_screen_audio.cpp +src/states_screens/options_screen_input2.cpp +src/states_screens/options_screen_input.cpp +src/states_screens/options_screen_players.cpp +src/states_screens/options_screen_ui.cpp +src/states_screens/options_screen_video.cpp +src/states_screens/race_gui_base.cpp +src/states_screens/race_gui.cpp +src/states_screens/race_gui_overworld.cpp +src/states_screens/race_result_gui.cpp +src/states_screens/race_setup_screen.cpp +src/states_screens/server_selection.cpp +src/states_screens/soccer_setup_screen.cpp +src/states_screens/state_manager.cpp +src/states_screens/story_mode_lobby.cpp +src/states_screens/tracks_screen.cpp +src/tinygettext/dictionary.cpp +src/tinygettext/dictionary_manager.cpp +src/tinygettext/iconv.cpp +src/tinygettext/language.cpp +src/tinygettext/plural_forms.cpp +src/tinygettext/po_parser.cpp +src/tinygettext/stk_file_system.cpp +src/tinygettext/tgt_log.cpp +src/tinygettext/tinygettext.cpp +src/tracks/ambient_light_sphere.cpp +src/tracks/bezier_curve.cpp +src/tracks/check_cannon.cpp +src/tracks/check_goal.cpp +src/tracks/check_lap.cpp +src/tracks/check_line.cpp +src/tracks/check_manager.cpp +src/tracks/check_sphere.cpp +src/tracks/check_structure.cpp +src/tracks/graph_node.cpp +src/tracks/lod_node_loader.cpp +src/tracks/quad.cpp +src/tracks/quad_graph.cpp +src/tracks/quad_set.cpp +src/tracks/terrain_info.cpp +src/tracks/track.cpp +src/tracks/track_manager.cpp +src/tracks/track_object.cpp +src/tracks/track_object_manager.cpp +src/tracks/track_object_presentation.cpp +src/tracks/track_sector.cpp +src/utils/constants.cpp +src/utils/crash_reporting.cpp +src/utils/debug.cpp +src/utils/helpers.cpp +src/utils/leak_check.cpp +src/utils/log.cpp +src/utils/profiler.cpp +src/utils/random_generator.cpp +src/utils/string_utils.cpp +src/utils/time.cpp +src/utils/translation.cpp +src/utils/vec3.cpp +) +set(STK_HEADERS +src/achievements/achievement.hpp +src/achievements/achievement_info.hpp +src/achievements/achievements_manager.hpp +src/achievements/achievements_slot.hpp +src/addons/addon.hpp +src/addons/addons_manager.hpp +src/addons/dummy_network_http.hpp +src/addons/inetwork_http.hpp +src/addons/network_http.hpp +src/addons/news_manager.hpp +src/addons/request.hpp +src/addons/zip.hpp +src/animations/animation_base.hpp +src/animations/ipo.hpp +src/animations/three_d_animation.hpp +src/audio/dummy_sfx.hpp +src/audio/music_dummy.hpp +src/audio/music.hpp +src/audio/music_information.hpp +src/audio/music_manager.hpp +src/audio/music_ogg.hpp +src/audio/sfx_base.hpp +src/audio/sfx_buffer.hpp +src/audio/sfx_manager.hpp +src/audio/sfx_openal.hpp +src/challenges/challenge_data.hpp +src/challenges/challenge.hpp +src/challenges/game_slot.hpp +src/challenges/unlock_manager.hpp +src/config/device_config.hpp +src/config/player.hpp +src/config/saved_grand_prix.hpp +src/config/stk_config.hpp +src/config/user_config.hpp +src/graphics/callbacks.hpp +src/graphics/camera.hpp +src/graphics/CBatchingMesh.hpp +src/graphics/explosion.hpp +src/graphics/glow.hpp +src/graphics/glwrap.hpp +src/graphics/gpuparticles.h +src/graphics/hardware_skinning.hpp +src/graphics/hit_effect.hpp +src/graphics/hit_sfx.hpp +src/graphics/irr_driver.hpp +src/graphics/large_mesh_buffer.hpp +src/graphics/lens_flare.hpp +src/graphics/light.hpp +src/graphics/lod_node.hpp +src/graphics/material.hpp +src/graphics/material_manager.hpp +src/graphics/mesh_tools.hpp +src/graphics/mlaa_areamap.hpp +src/graphics/moving_texture.hpp +src/graphics/particle_emitter.hpp +src/graphics/particle_kind.hpp +src/graphics/particle_kind_manager.hpp +src/graphics/per_camera_node.hpp +src/graphics/post_processing.hpp +src/graphics/rain.hpp +src/graphics/referee.hpp +src/graphics/rtts.hpp +src/graphics/screenquad.hpp +src/graphics/shaders.hpp +src/graphics/shadow.hpp +src/graphics/shadow_importance.hpp +src/graphics/show_curve.hpp +src/graphics/skid_marks.hpp +src/graphics/slip_stream.hpp +src/graphics/stars.hpp +src/graphics/sun.hpp +src/graphics/water.hpp +src/graphics/wind.hpp +src/guiengine/abstract_state_manager.hpp +src/guiengine/abstract_top_level_container.hpp +src/guiengine/dialog_queue.hpp +src/guiengine/engine.hpp +src/guiengine/event_handler.hpp +src/guiengine/layout_manager.hpp +src/guiengine/modaldialog.hpp +src/guiengine/scalable_font.hpp +src/guiengine/screen.hpp +src/guiengine/skin.hpp +src/guiengine/widget.hpp +src/guiengine/widgets/bubble_widget.hpp +src/guiengine/widgets/button_widget.hpp +src/guiengine/widgets/check_box_widget.hpp +src/guiengine/widgets/dynamic_ribbon_widget.hpp +src/guiengine/widgets.hpp +src/guiengine/widgets/icon_button_widget.hpp +src/guiengine/widgets/label_widget.hpp +src/guiengine/widgets/list_widget.hpp +src/guiengine/widgets/model_view_widget.hpp +src/guiengine/widgets/progress_bar_widget.hpp +src/guiengine/widgets/rating_bar_widget.hpp +src/guiengine/widgets/ribbon_widget.hpp +src/guiengine/widgets/spinner_widget.hpp +src/guiengine/widgets/text_box_widget.hpp +src/input/binding.hpp +src/input/device_manager.hpp +src/input/input_device.hpp +src/input/input.hpp +src/input/input_manager.hpp +src/input/wiimote.hpp +src/input/wiimote_manager.hpp +src/io/file_manager.hpp +src/io/xml_node.hpp +src/io/xml_writer.hpp +src/items/attachment.hpp +src/items/attachment_manager.hpp +src/items/attachment_plugin.hpp +src/items/bowling.hpp +src/items/cake.hpp +src/items/flyable.hpp +src/items/item.hpp +src/items/item_manager.hpp +src/items/plunger.hpp +src/items/powerup.hpp +src/items/powerup_manager.hpp +src/items/projectile_manager.hpp +src/items/rubber_ball.hpp +src/items/rubber_band.hpp +src/items/swatter.hpp +src/karts/abstract_kart_animation.hpp +src/karts/abstract_kart.hpp +src/karts/cannon_animation.hpp +src/karts/controller/ai_base_controller.hpp +src/karts/controller/ai_properties.hpp +src/karts/controller/controller.hpp +src/karts/controller/end_controller.hpp +src/karts/controller/kart_control.hpp +src/karts/controller/network_player_controller.hpp +src/karts/controller/player_controller.hpp +src/karts/controller/skidding_ai.hpp +src/karts/explosion_animation.hpp +src/karts/ghost_kart.hpp +src/karts/kart_gfx.hpp +src/karts/kart.hpp +src/karts/kart_model.hpp +src/karts/kart_properties.hpp +src/karts/kart_properties_manager.hpp +src/karts/kart_with_stats.hpp +src/karts/max_speed.hpp +src/karts/moveable.hpp +src/karts/rescue_animation.hpp +src/karts/skidding.hpp +src/karts/skidding_properties.hpp +src/main_loop.hpp +src/modes/cutscene_world.hpp +src/modes/demo_world.hpp +src/modes/easter_egg_hunt.hpp +src/modes/follow_the_leader.hpp +src/modes/linear_world.hpp +src/modes/overworld.hpp +src/modes/profile_world.hpp +src/modes/soccer_world.hpp +src/modes/standard_race.hpp +src/modes/three_strikes_battle.hpp +src/modes/tutorial_world.hpp +src/modes/world.hpp +src/modes/world_status.hpp +src/modes/world_with_rank.hpp +src/network/client_network_manager.hpp +src/network/event.hpp +src/network/game_setup.hpp +src/network/network_interface.hpp +src/network/network_manager.hpp +src/network/network_string.hpp +src/network/network_world.hpp +src/network/protocol.hpp +src/network/protocol_manager.hpp +src/network/protocols/client_lobby_room_protocol.hpp +src/network/protocols/connect_to_peer.hpp +src/network/protocols/connect_to_server.hpp +src/network/protocols/controller_events_protocol.hpp +src/network/protocols/game_events_protocol.hpp +src/network/protocols/get_peer_address.hpp +src/network/protocols/get_public_address.hpp +src/network/protocols/hide_public_address.hpp +src/network/protocols/kart_update_protocol.hpp +src/network/protocols/lobby_room_protocol.hpp +src/network/protocols/ping_protocol.hpp +src/network/protocols/quick_join_protocol.hpp +src/network/protocols/request_connection.hpp +src/network/protocols/server_lobby_room_protocol.hpp +src/network/protocols/show_public_address.hpp +src/network/protocols/start_game_protocol.hpp +src/network/protocols/start_server.hpp +src/network/protocols/stop_server.hpp +src/network/protocols/synchronization_protocol.hpp +src/network/race_config.hpp +src/network/remote_kart_info.hpp +src/network/server_network_manager.hpp +src/network/singleton.hpp +src/network/stk_host.hpp +src/network/stk_peer.hpp +src/network/types.hpp +src/online/current_user.hpp +src/online/http_manager.hpp +src/online/messages.hpp +src/online/profile.hpp +src/online/profile_manager.hpp +src/online/request.hpp +src/online/server.hpp +src/online/servers_manager.hpp +src/physics/btKart.hpp +src/physics/btKartRaycast.hpp +src/physics/btUprightConstraint.hpp +src/physics/irr_debug_drawer.hpp +src/physics/kart_motion_state.hpp +src/physics/physical_object.hpp +src/physics/physics.hpp +src/physics/stk_dynamics_world.hpp +src/physics/triangle_mesh.hpp +src/physics/user_pointer.hpp +src/race/grand_prix_data.hpp +src/race/grand_prix_manager.hpp +src/race/highscore_manager.hpp +src/race/highscores.hpp +src/race/history.hpp +src/race/race_manager.hpp +src/replay/replay_base.hpp +src/replay/replay_play.hpp +src/replay/replay_recorder.hpp +src/states_screens/addons_screen.hpp +src/states_screens/arenas_screen.hpp +src/states_screens/create_server_screen.hpp +src/states_screens/credits.hpp +src/states_screens/cutscene_gui.hpp +src/states_screens/dialogs/add_device_dialog.hpp +src/states_screens/dialogs/addons_loading.hpp +src/states_screens/dialogs/change_password_dialog.hpp +src/states_screens/dialogs/confirm_resolution_dialog.hpp +src/states_screens/dialogs/custom_video_settings.hpp +src/states_screens/dialogs/enter_player_name_dialog.hpp +src/states_screens/dialogs/gp_info_dialog.hpp +src/states_screens/dialogs/login_dialog.hpp +src/states_screens/dialogs/message_dialog.hpp +src/states_screens/dialogs/notification_dialog.hpp +src/states_screens/dialogs/player_info_dialog.hpp +src/states_screens/dialogs/press_a_key_dialog.hpp +src/states_screens/dialogs/race_paused_dialog.hpp +src/states_screens/dialogs/recovery_dialog.hpp +src/states_screens/dialogs/registration_dialog.hpp +src/states_screens/dialogs/select_challenge.hpp +src/states_screens/dialogs/server_info_dialog.hpp +src/states_screens/dialogs/track_info_dialog.hpp +src/states_screens/dialogs/tutorial_message_dialog.hpp +src/states_screens/dialogs/user_info_dialog.hpp +src/states_screens/dialogs/vote_dialog.hpp +src/states_screens/easter_egg_screen.hpp +src/states_screens/feature_unlocked.hpp +src/states_screens/grand_prix_lose.hpp +src/states_screens/grand_prix_win.hpp +src/states_screens/help_screen_1.hpp +src/states_screens/help_screen_2.hpp +src/states_screens/help_screen_3.hpp +src/states_screens/help_screen_4.hpp +src/states_screens/kart_selection.hpp +src/states_screens/main_menu_screen.hpp +src/states_screens/networking_lobby.hpp +src/states_screens/network_kart_selection.hpp +src/states_screens/offline_kart_selection.hpp +src/states_screens/online_profile_achievements.hpp +src/states_screens/online_profile_base.hpp +src/states_screens/online_profile_friends.hpp +src/states_screens/online_profile_overview.hpp +src/states_screens/online_profile_settings.hpp +src/states_screens/online_screen.hpp +src/states_screens/online_user_search.hpp +src/states_screens/options_screen_audio.hpp +src/states_screens/options_screen_input2.hpp +src/states_screens/options_screen_input.hpp +src/states_screens/options_screen_players.hpp +src/states_screens/options_screen_ui.hpp +src/states_screens/options_screen_video.hpp +src/states_screens/race_gui_base.hpp +src/states_screens/race_gui.hpp +src/states_screens/race_gui_overworld.hpp +src/states_screens/race_result_gui.hpp +src/states_screens/race_setup_screen.hpp +src/states_screens/server_selection.hpp +src/states_screens/soccer_setup_screen.hpp +src/states_screens/state_manager.hpp +src/states_screens/story_mode_lobby.hpp +src/states_screens/tracks_screen.hpp +src/tinygettext/dictionary.hpp +src/tinygettext/dictionary_manager.hpp +src/tinygettext/file_system.hpp +src/tinygettext/iconv.hpp +src/tinygettext/language.hpp +src/tinygettext/log_stream.hpp +src/tinygettext/plural_forms.hpp +src/tinygettext/po_parser.hpp +src/tinygettext/stk_file_system.hpp +src/tinygettext/tgt_log.hpp +src/tinygettext/tinygettext.hpp +src/tracks/ambient_light_sphere.hpp +src/tracks/bezier_curve.hpp +src/tracks/check_cannon.hpp +src/tracks/check_goal.hpp +src/tracks/check_lap.hpp +src/tracks/check_line.hpp +src/tracks/check_manager.hpp +src/tracks/check_sphere.hpp +src/tracks/check_structure.hpp +src/tracks/graph_node.hpp +src/tracks/lod_node_loader.hpp +src/tracks/quad_graph.hpp +src/tracks/quad.hpp +src/tracks/quad_set.hpp +src/tracks/terrain_info.hpp +src/tracks/track.hpp +src/tracks/track_manager.hpp +src/tracks/track_object.hpp +src/tracks/track_object_manager.hpp +src/tracks/track_object_presentation.hpp +src/tracks/track_sector.hpp +src/utils/aligned_array.hpp +src/utils/constants.hpp +src/utils/crash_reporting.hpp +src/utils/debug.hpp +src/utils/helpers.hpp +src/utils/interpolation_array.hpp +src/utils/leak_check.hpp +src/utils/log.hpp +src/utils/no_copy.hpp +src/utils/profiler.hpp +src/utils/ptr_vector.hpp +src/utils/random_generator.hpp +src/utils/string_utils.hpp +src/utils/synchronised.hpp +src/utils/time.hpp +src/utils/translation.hpp +src/utils/types.hpp +src/utils/vec3.hpp +src/utils/vs.hpp +) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 33260b0c3..fa65fda77 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -1,4 +1,3 @@ -#if 0 #include "graphics/irr_driver.hpp" #include "gpuparticles.h" #include @@ -6,9 +5,48 @@ #include "config/user_config.hpp" #include +#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) + + +PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLUNIFORM1FPROC glUniform1f; +PFNGLUNIFORM3FPROC glUniform3f; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +PFNGLACTIVETEXTUREPROC glActiveTexture; +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +#endif + void initGL() { -/* glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); +#ifdef _IRR_WINDOWS_API_ + glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); @@ -34,14 +72,13 @@ void initGL() glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); -#ifdef _IRR_WINDOWS_API_ glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); -#endif glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); - glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings");*/ + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); +#endif } // Mostly from shader tutorial @@ -207,4 +244,3 @@ void GPUParticle::render() { glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); } -#endif diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 85cb446fe..ba3892823 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -1,54 +1,12 @@ -#if 0 #ifndef GPUPARTICLES_H #define GPUPARTICLES_H +#ifndef _IRR_WINDOWS_API_ #define GL_GLEXT_PROTOTYPES 1 +#endif #include "graphics/glwrap.hpp" #include -/*#ifdef _IRR_WINDOWS_API_ -#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) -#else -#include -#define IRR_OGL_LOAD_EXTENSION(X) glXGetProcAddress(reinterpret_cast(X)) -#endif - - -PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; -PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; -PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -PFNGLBINDBUFFERBASEPROC glBindBufferBase; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLUNIFORM1FPROC glUniform1f; -PFNGLUNIFORM3FPROC glUniform3f; -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -#ifdef _IRR_WINDOWS_API_ -PFNGLACTIVETEXTUREPROC glActiveTexture; -#endif -PFNGLUNIFORM2FPROC glUniform2f; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;*/ - void initGL(); GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); @@ -69,5 +27,4 @@ public: void render(); }; -#endif // GPUPARTICLES_H -#endif +#endif // GPUPARTICLES_H \ No newline at end of file diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index 07d5a4119..9e8c668f2 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -42,7 +42,7 @@ using namespace core; class RainNode: public scene::ISceneNode { private: -// GPUParticle *gpupart; + GPUParticle *gpupart; public: RainNode(scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(0, mgr, -1) @@ -72,7 +72,7 @@ public: vertices[3 * i + 1] = y; vertices[3 * i + 2] = z; } - //gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); + gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); box.addInternalPoint(vector3df((float)(-area/2))); box.addInternalPoint(vector3df((float)( area/2))); @@ -80,13 +80,13 @@ public: ~RainNode() { -// delete gpupart; + delete gpupart; } virtual void render() { -// gpupart->simulate(); -// gpupart->render(); + gpupart->simulate(); + gpupart->render(); // We need to force irrlicht to update its internal states IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setMaterial(mat); From 4dd0c066df15ca0d70f8ddd4cdcc2804de77f940 Mon Sep 17 00:00:00 2001 From: deveee Date: Fri, 27 Dec 2013 22:02:52 +0000 Subject: [PATCH 065/412] Fixed problem with distance in my previous commit git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14816 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/modes/overworld.cpp | 14 +++++--------- src/tracks/track_object.cpp | 2 ++ src/tracks/track_object.hpp | 3 +++ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index b7709d097..c200eba1b 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -134,17 +134,13 @@ void OverWorld::update(float dt) continue; Vec3 m_garage_pos = obj->getPosition(); + float m_distance = obj->getDistance(); - AbstractKart* m_kart = getKart(0); - Vec3 m_kart_pos = m_kart->getXYZ(); - //~ float kart_len = m_kart->getKartModel()->getLength(); + Vec3 m_kart_pos = getKart(0)->getXYZ(); - //~ printf("%f\n", (m_garage_pos-m_kart_pos).length2_2d()); - //~ printf("%f\n", kart_len); - - //TODO: Compare distance between garage and kart with for example length - // of the kart or distance of object defined in scene.xml - if ((m_garage_pos-m_kart_pos).length2_2d() > CHALLENGE_DISTANCE_SQUARED*3) + // Distance should be written as m_distance*m_distance. Look at + // m_distance_2 variable in item.cpp file. + if ((m_garage_pos-m_kart_pos).length2_2d() > m_distance*m_distance) { obj->reset(); } diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 56f1be769..4169079a7 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -103,6 +103,7 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) xml_node.get("soccer_ball", &m_soccer_ball); m_garage = false; + m_distance = 0; std::string type; xml_node.get("type", &type ); @@ -126,6 +127,7 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) { std::string m_action; xml_node.get("action", &m_action); + xml_node.get("distance", &m_distance); if (m_action == "garage") { m_garage = true; diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index c807534b7..3d8bd52d2 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -75,6 +75,8 @@ protected: bool m_soccer_ball; bool m_garage; + + float m_distance; PhysicalObject* m_rigid_body; @@ -109,6 +111,7 @@ public: bool isSoccerBall() const { return m_soccer_ball; } bool isGarage() const { return m_garage; } + float getDistance() const { return m_distance; } const PhysicalObject* getPhysics() const { return m_rigid_body; } PhysicalObject* getPhysics() { return m_rigid_body; } From e72e2de8caacaf07f230f7b2f3cbca1e5f990a02 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 27 Dec 2013 22:52:44 +0000 Subject: [PATCH 066/412] GPUParticle: Make RainNode a child of GPUParticle git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14817 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 189 ++++++++++++++++++++++------------ src/graphics/gpuparticles.h | 38 +++++-- src/graphics/rain.cpp | 81 --------------- 3 files changed, 149 insertions(+), 159 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index fa65fda77..70ffe833a 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -171,76 +171,129 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glUniform1i(location, textureUnit); } -GPUParticle::GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt) : - count(c), texture(tex), normal_and_depth(rtt) { +GPUParticle::GPUParticle(scene::ISceneManager* mgr, ITexture *tex) + : scene::ISceneNode(0, mgr, -1) { initGL(); - glGenBuffers(2, tfb_vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), initialSamples, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); - - RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); - loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); - loc_screen = glGetUniformLocation(RenderProgram, "screen"); - loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); - texloc_tex = glGetUniformLocation(RenderProgram, "tex"); - texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - - const char *varyings[] = {"currentPosition"}; - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); - loc_campos = glGetUniformLocation(SimulationProgram, "campos"); - loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); - loc_time = glGetUniformLocation(SimulationProgram, "time"); + fakemat.Lighting = false; + fakemat.ZWriteEnable = false; + fakemat.MaterialType = irr_driver->getShader(ES_RAIN); + fakemat.Thickness = 200; + fakemat.setTexture(0, tex); } -void GPUParticle::simulate() { - glUseProgram(SimulationProgram); - const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW); - const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); - - glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); - - glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); - glUniform1f(loc_time, time); - glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); - glBeginTransformFeedback(GL_POINTS); - glDrawArrays(GL_POINTS, 0, count); - glEndTransformFeedback(); - glDisable(GL_RASTERIZER_DISCARD); -} - void GPUParticle::render() { - const float screenw = (float)UserConfigParams::m_width; - - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); - glUseProgram(RenderProgram); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - - float screen[2] = { - (float)UserConfigParams::m_width, - (float)UserConfigParams::m_height - }; - irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); - invproj.makeInverse(); - - bindUniformToTextureUnit(texloc_tex, texture, 0); - bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); - - glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(loc_screen, screen[0], screen[1]); - glUniform1f(loc_screenw, screenw); - glDrawArrays(GL_POINTS, 0, count); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + simulate(); + draw(); + // We need to force irrlicht to update its internal states + irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); + drv->setMaterial(fakemat); + static_cast(drv)->setRenderStates3DMode(); } + +void GPUParticle::OnRegisterSceneNode() { + if (IsVisible && + (irr_driver->getRenderPass() & irr::scene::ESNRP_TRANSPARENT) == irr::scene::ESNRP_TRANSPARENT) + { + SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT); + } + ISceneNode::OnRegisterSceneNode(); +} + +RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) + : GPUParticle(mgr, tex) +{ + RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); + loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + texloc_tex = glGetUniformLocation(RenderProgram, "tex"); + texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); + + const char *varyings[] = { "currentPosition" }; + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); + loc_campos = glGetUniformLocation(SimulationProgram, "campos"); + loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); + loc_time = glGetUniformLocation(SimulationProgram, "time"); + count = 2500; + area = 3500; + + u32 i; + float x, y, z, vertices[7500]; + for (i = 0; i < count; i++) + { + x = ((rand() % area) - area / 2) / 100.0f; + y = ((rand() % 2400)) / 100.0f; + z = ((rand() % area) - area / 2) / 100.0f; + + vertices[3 * i] = x; + vertices[3 * i + 1] = y; + vertices[3 * i + 2] = z; + } + + texture = getTextureGLuint(tex); + normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + glGenBuffers(2, tfb_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), vertices, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); + + box.addInternalPoint(vector3df((float)(-area / 2))); + box.addInternalPoint(vector3df((float)(area / 2))); +} + +void RainNode::simulate() { + glUseProgram(SimulationProgram); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; + const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW); + const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); + + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); + + glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); + glUniform1f(loc_time, time); + glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisable(GL_RASTERIZER_DISCARD); +} + +void RainNode::draw() { + const float screenw = (float)UserConfigParams::m_width; + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); + invproj.makeInverse(); + + bindUniformToTextureUnit(texloc_tex, texture, 0); + bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); + + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniform1f(loc_screenw, screenw); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); +} + +const core::aabbox3d& RainNode::getBoundingBox() const +{ + return box; +} \ No newline at end of file diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index ba3892823..e0bf03ddc 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -14,17 +14,35 @@ GLuint getTextureGLuint(irr::video::ITexture *tex); void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); -class GPUParticle { -private: - unsigned count; - GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; - GLuint texture, normal_and_depth; - GLuint loc_campos, loc_viewm, loc_time; - GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; +class GPUParticle : public scene::ISceneNode { +protected: + video::SMaterial fakemat; + virtual void simulate() = 0; + virtual void draw() = 0; public: - GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt); - void simulate(); - void render(); + //GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt); + GPUParticle(scene::ISceneManager* mgr, ITexture *tex); + virtual void render(); + virtual void OnRegisterSceneNode(); +}; + +class RainNode : public GPUParticle +{ +protected: + GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; + unsigned count; + GLuint texture, normal_and_depth; + GLuint loc_campos, loc_viewm, loc_time; + GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; + s32 area; + core::aabbox3d box; + + virtual void simulate(); + virtual void draw(); +public: + RainNode(scene::ISceneManager* mgr, ITexture *tex); + virtual const core::aabbox3d& getBoundingBox() const; + virtual u32 getMaterialCount() const { return 1; } }; #endif // GPUPARTICLES_H \ No newline at end of file diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index 9e8c668f2..b2adc28c9 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -38,87 +38,6 @@ using namespace video; using namespace scene; using namespace core; -// The actual rain node -class RainNode: public scene::ISceneNode -{ -private: - GPUParticle *gpupart; -public: - RainNode(scene::ISceneManager* mgr, ITexture *tex) - : scene::ISceneNode(0, mgr, -1) - { - mat.Lighting = false; - mat.ZWriteEnable = false; - mat.MaterialType = irr_driver->getShader(ES_RAIN); - mat.Thickness = 200; - mat.BlendOperation = EBO_ADD; - - mat.setTexture(0, tex); - mat.TextureLayer[0].TextureWrapU = - mat.TextureLayer[0].TextureWrapV = ETC_CLAMP_TO_EDGE; - - count = 2500; - area = 3500; - - u32 i; - float x, y, z, vertices[7500]; - for (i = 0; i < count; i++) - { - x = ((rand() % area) - area/2) / 100.0f; - y = ((rand() % 2400)) / 100.0f; - z = ((rand() % area) - area/2) / 100.0f; - - vertices[3 * i] = x; - vertices[3 * i + 1] = y; - vertices[3 * i + 2] = z; - } - gpupart = new GPUParticle(count, vertices, getTextureGLuint(mat.getTexture(0)), getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))); - - box.addInternalPoint(vector3df((float)(-area/2))); - box.addInternalPoint(vector3df((float)( area/2))); - } - - ~RainNode() - { - delete gpupart; - } - - virtual void render() - { - gpupart->simulate(); - gpupart->render(); - // We need to force irrlicht to update its internal states - IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setMaterial(mat); - static_cast(drv)->setRenderStates3DMode(); - } - - virtual const core::aabbox3d& getBoundingBox() const - { - return box; - } - - virtual void OnRegisterSceneNode() - { - if (IsVisible && - (irr_driver->getRenderPass() & ESNRP_TRANSPARENT) == ESNRP_TRANSPARENT) - { - SceneManager->registerNodeForRendering(this, ESNRP_TRANSPARENT); - } - - ISceneNode::OnRegisterSceneNode(); - } - - virtual u32 getMaterialCount() const { return 1; } - virtual video::SMaterial& getMaterial(u32 i) { return mat; } - -private: - video::SMaterial mat; - core::aabbox3d box; - u32 count; - s32 area; -}; - // The rain manager Rain::Rain(Camera *camera, irr::scene::ISceneNode* parent) From 14655bcdb91ab231cb9c1ab345db5554289da328 Mon Sep 17 00:00:00 2001 From: auria Date: Fri, 27 Dec 2013 23:55:57 +0000 Subject: [PATCH 067/412] Change lights to be TrackObjects, so that they can be animated. Exporter part not yet committed git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14818 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 22 +------------ src/tracks/track_object.cpp | 7 ++++- src/tracks/track_object_presentation.cpp | 39 +++++++++++++++++++++++- src/tracks/track_object_presentation.hpp | 19 ++++++++++++ 4 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index ca1cae2da..6351314d9 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1581,27 +1581,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } else if(name=="light") { - core::vector3df pos; - node->get("xyz", &pos); - - video::SColor color; - node->get("color", &color); - const video::SColorf colorf(color); - - float distance = 25.0f; - node->get("distance", &distance); - float energy = 1.; - node->get("energy", &energy); - - if (irr_driver->isGLSL()) - { - irr_driver->addLight(pos, distance, energy, colorf.r, colorf.g, colorf.b); - } else - { - scene::ILightSceneNode* node = irr_driver->getSceneManager()->addLightSceneNode(NULL, pos, color, distance); - node->setLightType(video::ELT_POINT); - node->enableCastShadow(true); - } + m_track_object_manager->add(*node); } else if(name=="weather") { diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 4169079a7..0bf6e79cf 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -116,6 +116,11 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) m_type = "particle-emitter"; m_presentation = new TrackObjectPresentationParticles(xml_node); } + else if (xml_node.getName() == "light") + { + m_type = "light"; + m_presentation = new TrackObjectPresentationLight(xml_node); + } else if (type == "sfx-emitter") { // FIXME: at this time sound emitters are just disabled in multiplayer @@ -181,7 +186,7 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) b = glow.getBlue() / 255.0f; irr_driver->addGlowingNode(glownode, r, g, b); - } + } bool forcedbloom = false; if (xml_node.get("forcedbloom", &forcedbloom) && forcedbloom && glownode) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 497d3c904..23eff7860 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -39,6 +39,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- @@ -499,7 +500,6 @@ TrackObjectPresentationBillboard::~TrackObjectPresentationBillboard() // ---------------------------------------------------------------------------- - TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode& xml_node) : TrackObjectPresentationSceneNode(xml_node) { @@ -587,6 +587,43 @@ void TrackObjectPresentationParticles::triggerParticles() // ---------------------------------------------------------------------------- +TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_node) : + TrackObjectPresentationSceneNode(xml_node) +{ + 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); + + if (irr_driver->isGLSL()) + { + m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, colorf.r, colorf.g, colorf.b); + } + else + { + m_node = NULL; // lights require shaders to work + //scene::ILightSceneNode* node = irr_driver->getSceneManager()->addLightSceneNode(NULL, m_init_xyz, m_color, m_distance); + //node->setLightType(video::ELT_POINT); + //node->enableCastShadow(true); + //m_node = node; + } +} + +TrackObjectPresentationLight::~TrackObjectPresentationLight() +{ + // TODO +} + +void TrackObjectPresentationLight::update(float dt) +{ + // TODO +} + +// ---------------------------------------------------------------------------- TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(const XMLNode& xml_node) : TrackObjectPresentation(xml_node) diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 7894748cc..58c5f38fd 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -263,6 +263,25 @@ public: void triggerParticles(); }; +/** +* \ingroup tracks +* A track object representation that consists of a light emitter +*/ +class TrackObjectPresentationLight : public TrackObjectPresentationSceneNode +{ +private: + video::SColor m_color; + float m_distance; + float m_energy; + +public: + TrackObjectPresentationLight(const XMLNode& xml_node); + virtual ~TrackObjectPresentationLight(); + + virtual void update(float dt) OVERRIDE; +}; + + /** * \ingroup tracks * A track object representation that consists of an action trigger From 6b4d91effa73b69c7a4eba37d182ac8c64ef79e8 Mon Sep 17 00:00:00 2001 From: auria Date: Fri, 27 Dec 2013 23:56:42 +0000 Subject: [PATCH 068/412] Misc code style improvements and warning fixes git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14819 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.hpp | 8 ++-- src/graphics/irr_driver.cpp | 6 ++- src/graphics/render.cpp | 2 +- src/tracks/track_object_manager.cpp | 59 ----------------------------- 4 files changed, 9 insertions(+), 66 deletions(-) diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index d8a4461eb..1a058492b 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -544,10 +544,10 @@ public: // Norm factor double w = rand(); w /= RAND_MAX; - array[4 * i] = x; - array[4 * i + 1] = y; - array[4 * i + 2] = z; - array[4 * i + 3] = w; + array[4 * i] = (float)x; + array[4 * i + 1] = (float)y; + array[4 * i + 2] = (float)z; + array[4 * i + 3] = (float)w; } } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index db07c5c27..f67b5fea0 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2130,7 +2130,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, m_lights.push_back(light); - if (sun) { + if (sun) + { m_sun_interposer->setPosition(pos); m_sun_interposer->updateAbsolutePosition(); @@ -2144,7 +2145,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, } return light; - } else + } + else { return m_scene_manager->addLightSceneNode(NULL, pos, video::SColorf(r, g, b), radius); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 60af9c4d7..a7c88ae90 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -710,7 +710,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, continue; } const core::vector3df &lightpos = (m_lights[i]->getPosition() - campos); - unsigned idx = lightpos.getLength() / 10; + unsigned idx = (unsigned)(lightpos.getLength() / 10); if(idx > 14) continue; BucketedLN[idx].push_back(m_lights[i]); diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index fa8ccf3e3..6ff5c5e5f 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -55,71 +55,12 @@ void TrackObjectManager::add(const XMLNode &xml_node) if (is_lod) { - //printf("Adding lod obj to group <%s>\n", groupname.c_str()); m_lod_objects[groupname].push_back(&xml_node); } else { m_all_objects.push_back(new TrackObject(xml_node)); } - - /* - std::string groupname; - xml_node.get("lod_group", &groupname); - bool is_lod = !groupname.empty(); - - std::string type; - xml_node.get("type", &type); - - if (xml_node.getName() == "particle-emitter") - { - m_all_objects.push_back(new ThreeDAnimation(xml_node)); - } - else if (type=="movable") - { - if (is_lod) - { - assert(false); // TODO - //_lod_objects[groupname].push_back(new TrackObject(xml_node)); - } - else - { - m_all_objects.push_back(new TrackObject(xml_node)); - } - } - else if(type=="animation") - { - if (is_lod) - { - m_lod_objects[groupname].push_back(new ThreeDAnimation(xml_node)); - } - else - { - m_all_objects.push_back(new ThreeDAnimation(xml_node)); - } - } - else if(type=="billboard") - { - m_all_objects.push_back(new BillboardAnimation(xml_node)); - } - else if(type=="sfx-emitter") - { - m_all_objects.push_back(new ThreeDAnimation(xml_node)); - } - else if(type=="cutscene_camera") - { - m_all_objects.push_back(new ThreeDAnimation(xml_node)); - } - else if(type=="action-trigger") - { - m_all_objects.push_back(new TrackObject(xml_node)); - } - else - { - fprintf(stderr, "Unknown track object: '%s' - ignored.\n", - type.c_str()); - } - */ } catch (std::exception& e) { From 4c2c76088a48f5901eabd00a6d45c64d48a4a265 Mon Sep 17 00:00:00 2001 From: auria Date: Sat, 28 Dec 2013 02:09:08 +0000 Subject: [PATCH 070/412] Change pt-BR name to be more accurate git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14822 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tinygettext/language.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tinygettext/language.cpp b/src/tinygettext/language.cpp index daca81f31..5a470bbe9 100644 --- a/src/tinygettext/language.cpp +++ b/src/tinygettext/language.cpp @@ -213,7 +213,7 @@ static const LanguageSpec languages[] = { { "pl", "PL", 0, "Polish (Poland)" }, { "ps", 0, 0, "Pashto" }, { "pt", 0, 0, "Portuguese" }, - { "pt", "BR", 0, "Brazilian" }, + { "pt", "BR", 0, "Portuguese (Brazil)" }, { "pt", "PT", 0, "Portuguese (Portugal)" }, { "qu", 0, 0, "Quechua" }, { "rm", 0, 0, "Rhaeto-Romance" }, From ad3ea6c5e0d8281fdfbb4586c6a89620a5639b5d Mon Sep 17 00:00:00 2001 From: auria Date: Sat, 28 Dec 2013 02:10:12 +0000 Subject: [PATCH 071/412] Remove uneeded code git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14823 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track_object_presentation.cpp | 6 ------ src/tracks/track_object_presentation.hpp | 2 -- 2 files changed, 8 deletions(-) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 23eff7860..1bb577818 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -615,12 +615,6 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no TrackObjectPresentationLight::~TrackObjectPresentationLight() { - // TODO -} - -void TrackObjectPresentationLight::update(float dt) -{ - // TODO } // ---------------------------------------------------------------------------- diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 58c5f38fd..eb077ecac 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -277,8 +277,6 @@ private: public: TrackObjectPresentationLight(const XMLNode& xml_node); virtual ~TrackObjectPresentationLight(); - - virtual void update(float dt) OVERRIDE; }; From db44852d8b9f42d23f99984a0b41b3bdf3234ade Mon Sep 17 00:00:00 2001 From: auria Date: Sat, 28 Dec 2013 22:02:29 +0000 Subject: [PATCH 072/412] Make lights fade in when they appear git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14824 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/irr_driver.hpp | 2 +- src/graphics/light.cpp | 3 +- src/graphics/light.hpp | 11 ++++-- src/graphics/render.cpp | 71 ++++++++++++++++++++++++------------- 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index f8e512bfb..953c18100 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -194,7 +194,7 @@ private: void renderLights(const core::aabbox3df& cambox, scene::ICameraSceneNode * const camnode, video::SOverrideMaterial &overridemat, - int cam); + int cam, float dt); void renderDisplacement(video::SOverrideMaterial &overridemat, int cam); void doScreenShot(); diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 77ef04e49..105c760e5 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -37,7 +37,8 @@ aabbox3df LightNode::box; LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): ISceneNode(mgr->getRootSceneNode(), mgr, -1) { - energy = e; + m_energy = e; + m_energy_multiplier = 1.0f; m_color[0] = r; m_color[1] = g; m_color[2] = b; diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index f0a37e7fb..542aa23f5 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -51,9 +51,13 @@ public: virtual bool isPointLight() { return true; } float getRadius() const { return m_radius; } - float getEnergy() const { return energy; } + 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]); } + float getEnergyMultiplier() const { return m_energy_multiplier; } + void setEnergyMultiplier(float newval) { m_energy_multiplier = newval; } + protected: static core::aabbox3df box; @@ -61,7 +65,10 @@ protected: float m_radius; float m_color[3]; - float energy; + float m_energy; + + /// The energy multiplier is in range [0, 1] and is used to fade in lights when they come in range + float m_energy_multiplier; }; #endif diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index a7c88ae90..f9b87bf2e 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -47,6 +47,8 @@ #include "utils/log.hpp" #include "utils/profiler.hpp" +#include + void IrrDriver::renderGLSL(float dt) { World *world = World::getWorld(); // Never NULL. @@ -214,7 +216,7 @@ void IrrDriver::renderGLSL(float dt) } // Lights - renderLights(cambox, camnode, overridemat, cam); + renderLights(cambox, camnode, overridemat, cam, dt); if (!bgnodes) { @@ -670,7 +672,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, void IrrDriver::renderLights(const core::aabbox3df& cambox, scene::ICameraSceneNode * const camnode, video::SOverrideMaterial &overridemat, - int cam) + int cam, float dt) { core::array rtts; // Diffuse @@ -705,39 +707,58 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, 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(); continue; } const core::vector3df &lightpos = (m_lights[i]->getPosition() - campos); unsigned idx = (unsigned)(lightpos.getLength() / 10); - if(idx > 14) + if (idx > 14) continue; 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) + + 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->getPosition(); + accumulatedLightPos.push_back(pos.X); + accumulatedLightPos.push_back(pos.Y); + accumulatedLightPos.push_back(pos.Z); + accumulatedLightPos.push_back(0.); + const core::vector3df &col = light_node->getColor(); + + accumulatedLightColor.push_back(col.X); + accumulatedLightColor.push_back(col.Y); + accumulatedLightColor.push_back(col.Z); + accumulatedLightColor.push_back(0.); + accumulatedLightEnergy.push_back(light_node->getEffectiveEnergy()); + } + } + if (lightnum > MAXLIGHT) + { + irr_driver->setLastLightBucketDistance(i * 10); break; - LightNode *LN = BucketedLN[i].at(j); - const core::vector3df &pos = LN->getPosition(); - accumulatedLightPos.push_back(pos.X); - accumulatedLightPos.push_back(pos.Y); - accumulatedLightPos.push_back(pos.Z); - accumulatedLightPos.push_back(0.); - const core::vector3df &col = LN->getColor(); - - accumulatedLightColor.push_back(col.X); - accumulatedLightColor.push_back(col.Y); - accumulatedLightColor.push_back(col.Z); - accumulatedLightColor.push_back(0.); - accumulatedLightEnergy.push_back(LN->getEnergy()); - } - if (lightnum > MAXLIGHT) { - irr_driver->setLastLightBucketDistance(i * 10); - break; - } + } } LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO From 4c725ac8f4f46fab821739ebc3daefe219275acf Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 18:23:36 +0000 Subject: [PATCH 074/412] GPUParticles: Got PointEmitter to draw something at last. Still WIP, uses a #ifdef to disable it but I wanted to keep a working commit somewhere in case I mess up somewhere. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14829 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 12 + data/shaders/particle.vert | 13 + data/shaders/pointemitter.vert | 20 + src/graphics/gpuparticles.cpp | 616 ++++++++++++++++++------------ src/graphics/gpuparticles.h | 93 +++-- src/graphics/particle_emitter.cpp | 17 +- 6 files changed, 484 insertions(+), 287 deletions(-) create mode 100644 data/shaders/particle.frag create mode 100644 data/shaders/particle.vert create mode 100644 data/shaders/pointemitter.vert diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag new file mode 100644 index 000000000..f7edc445f --- /dev/null +++ b/data/shaders/particle.frag @@ -0,0 +1,12 @@ +#version 130 +in float lifetime; + +out vec3 color; + +void main(void) +{ + color = vec3( + (lifetime < 33.) ? 1. : 0., + (lifetime < 67. && lifetime >= 34.) ? 1. : 0., + (lifetime > 68.) ? 1. : 0.); +} diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert new file mode 100644 index 000000000..fcc348b41 --- /dev/null +++ b/data/shaders/particle.vert @@ -0,0 +1,13 @@ +#version 130 +in vec3 position; +in float lf; +uniform mat4 matrix; + +out float lifetime; + +void main(void) +{ + gl_PointSize = 10.; + gl_Position = matrix * vec4(position, 1.0); + lifetime = lf; +} diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert new file mode 100644 index 000000000..b3a236c26 --- /dev/null +++ b/data/shaders/pointemitter.vert @@ -0,0 +1,20 @@ +#version 130 +uniform int dt; +uniform vec3 source; +uniform int duration; + +in vec3 particle_position; +in float lifetime; +in vec4 particle_velocity; + +out vec3 new_particle_position; +out float new_lifetime; +out vec4 new_particle_velocity; + +void main(void) +{ + new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : vec3(0., 0., 0.); + new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration); + new_particle_velocity = particle_velocity; + gl_Position = vec4(0.); +} diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 70ffe833a..f73cbcadc 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -1,218 +1,326 @@ -#include "graphics/irr_driver.hpp" -#include "gpuparticles.h" -#include -#include "io/file_manager.hpp" -#include "config/user_config.hpp" -#include - -#ifdef _IRR_WINDOWS_API_ -#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) - - -PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; -PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; -PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -PFNGLBINDBUFFERBASEPROC glBindBufferBase; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLUNIFORM1FPROC glUniform1f; -PFNGLUNIFORM3FPROC glUniform3f; -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -PFNGLACTIVETEXTUREPROC glActiveTexture; -PFNGLUNIFORM2FPROC glUniform2f; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -#endif - -void initGL() -{ -#ifdef _IRR_WINDOWS_API_ - glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); - glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); - glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); - glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); - glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); - glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); - glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); - glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); - glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); - glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); - glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); - glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); - glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); - glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); - glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); - glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); -#endif -} - -// Mostly from shader tutorial -static -GLuint LoadShader(const char * file, unsigned type) { - GLuint Id = glCreateShader(type); - std::string Code; - std::ifstream Stream(file, std::ios::in); - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - Code += "\n" + Line; - Stream.close(); - } - GLint Result = GL_FALSE; - int InfoLogLength; - printf("Compiling shader : %s\n", file); - char const * SourcePointer = Code.c_str(); - int length = strlen(SourcePointer); - glShaderSource(Id, 1, &SourcePointer, &length); - glCompileShader(Id); - - glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); - if (Result == GL_FALSE) { - glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - return Id; -} - -GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) { - GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); - - GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, FragmentShaderID); - glLinkProgram(ProgramID); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return ProgramID; -} - -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { - GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint Program = glCreateProgram(); - glAttachShader(Program, Shader); - glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(Program); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(Program, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - glDeleteShader(Shader); - return Program; -} - -GLuint getTextureGLuint(irr::video::ITexture *tex) { - return static_cast(tex)->getOpenGLTextureName(); -} - -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, texid); - glUniform1i(location, textureUnit); -} - +#include "graphics/irr_driver.hpp" +#include "gpuparticles.h" +#include +#include "io/file_manager.hpp" +#include "config/user_config.hpp" +#include + +#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) + + +PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLUNIFORM1FPROC glUniform1f; +PFNGLUNIFORM3FPROC glUniform3f; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +PFNGLACTIVETEXTUREPROC glActiveTexture; +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +#endif + +void initGL() +{ +#ifdef _IRR_WINDOWS_API_ + glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); + glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); + glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); + glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); + glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); + glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); + glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); + glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); + glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); + glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); + glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); + glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); + glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); + glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation"); +#endif +} + +// Mostly from shader tutorial +static +GLuint LoadShader(const char * file, unsigned type) { + GLuint Id = glCreateShader(type); + std::string Code; + std::ifstream Stream(file, std::ios::in); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + printf("Compiling shader : %s\n", file); + char const * SourcePointer = Code.c_str(); + int length = strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) { + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + return Id; +} + +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) { + GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); + + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { + GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint Program = glCreateProgram(); + glAttachShader(Program, Shader); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + glDeleteShader(Shader); + return Program; +} + +GLuint getTextureGLuint(irr::video::ITexture *tex) { + return static_cast(tex)->getOpenGLTextureName(); +} + +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, texid); + glUniform1i(location, textureUnit); +} + GPUParticle::GPUParticle(scene::ISceneManager* mgr, ITexture *tex) - : scene::ISceneNode(0, mgr, -1) { - initGL(); + : scene::ISceneNode(0, mgr, -1) { + initGL(); fakemat.Lighting = false; fakemat.ZWriteEnable = false; fakemat.MaterialType = irr_driver->getShader(ES_RAIN); fakemat.Thickness = 200; - fakemat.setTexture(0, tex); - } - -void GPUParticle::render() { - simulate(); - draw(); + fakemat.setTexture(0, tex); + } + +void GPUParticle::render() { + simulate(); + draw(); // We need to force irrlicht to update its internal states irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setMaterial(fakemat); - static_cast(drv)->setRenderStates3DMode(); -} - -void GPUParticle::OnRegisterSceneNode() { - if (IsVisible && + static_cast(drv)->setRenderStates3DMode(); +} + +void GPUParticle::OnRegisterSceneNode() { + if ( (irr_driver->getRenderPass() & irr::scene::ESNRP_TRANSPARENT) == irr::scene::ESNRP_TRANSPARENT) { SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_TRANSPARENT); } - ISceneNode::OnRegisterSceneNode(); + ISceneNode::OnRegisterSceneNode(); +} + +#define COMPONENTCOUNT 8 + +PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, + const core::vector3df& direction, + u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, + const video::SColor& minStartColor, + const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees +// const core::dimension2df& minStartSize, +// const core::dimension2df& maxStartSize +) : GPUParticle(mgr, tex) { + const char *varyings[] = { + "new_particle_position", + "new_lifetime", + "new_particle_velocity", + //"gl_SkipComponents3" + }; + + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); + loc_duration = glGetUniformLocation(SimulationProgram, "duration"); + loc_dt = glGetUniformLocation(SimulationProgram, "dt"); + loc_source = glGetUniformLocation(SimulationProgram, "source"); + loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); + loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); + loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); + printf("locs are %d, %d, %d\n", loc_position, loc_lifetime, loc_velocity); + + RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); + loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); + count = 25; + + float *particles = new float[COMPONENTCOUNT * count]; + for (unsigned i = 0; i < count; i++) { + particles[COMPONENTCOUNT * i] = 0.;// getPosition().X; + particles[COMPONENTCOUNT * i + 1] = 0.;// getPosition().Y; + particles[COMPONENTCOUNT * i + 2] = 0.;//getPosition().Z; + particles[COMPONENTCOUNT * i + 3] = i * 10; + + particles[COMPONENTCOUNT * i + 4] = direction.X; + particles[COMPONENTCOUNT * i + 5] = direction.Y; + particles[COMPONENTCOUNT * i + 6] = direction.Z; + +// particles[COMPONENTCOUNT * i + 8] = 100.; + //memcpy(&particles[COMPONENTCOUNT * i + 3], &i, sizeof(float)); + } + printf("dir is %f, %f, %f\n", direction.X, direction.Y, direction.Z); + glGenBuffers(2, tfb_buffers); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + delete [] particles; +} + +void PointEmitter::simulate() +{ + glUseProgram(SimulationProgram); + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glVertexAttribPointer(loc_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); + glVertexAttribPointer(loc_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); + + glUniform1i(loc_dt, 1); + glUniform1i(loc_duration, 100); + glUniform3f(loc_source, getPosition().X, getPosition().Y, getPosition().Z); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisable(GL_RASTERIZER_DISCARD); + std::swap(tfb_buffers[0], tfb_buffers[1]); +} + +void PointEmitter::draw() +{ + glDisable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + matrix *= getAbsoluteTransformation();; + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); + glVertexAttribPointer(glGetAttribLocation(RenderProgram, "position"), 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); + glVertexAttribPointer(glGetAttribLocation(RenderProgram, "lf"), 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *)(3 * sizeof(float))); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) : GPUParticle(mgr, tex) { - RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); - loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); - loc_screen = glGetUniformLocation(RenderProgram, "screen"); - loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); - texloc_tex = glGetUniformLocation(RenderProgram, "tex"); - texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - - const char *varyings[] = { "currentPosition" }; - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); - loc_campos = glGetUniformLocation(SimulationProgram, "campos"); - loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); + RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); + loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + texloc_tex = glGetUniformLocation(RenderProgram, "tex"); + texloc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); + + const char *varyings[] = { "currentPosition" }; + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/rainsim.vert").c_str(), varyings, 1); + loc_campos = glGetUniformLocation(SimulationProgram, "campos"); + loc_viewm = glGetUniformLocation(SimulationProgram, "viewm"); loc_time = glGetUniformLocation(SimulationProgram, "time"); count = 2500; area = 3500; @@ -232,68 +340,68 @@ RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) texture = getTextureGLuint(tex); normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - glGenBuffers(2, tfb_vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), vertices, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glGenBuffers(2, tfb_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), vertices, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); glBufferData(GL_ARRAY_BUFFER, 3 * count * sizeof(float), 0, GL_STREAM_DRAW); box.addInternalPoint(vector3df((float)(-area / 2))); box.addInternalPoint(vector3df((float)(area / 2))); } -void RainNode::simulate() { - glUseProgram(SimulationProgram); - const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW); - const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); - - glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); - - glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); - glUniform1f(loc_time, time); - glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); - glBeginTransformFeedback(GL_POINTS); - glDrawArrays(GL_POINTS, 0, count); - glEndTransformFeedback(); - glDisable(GL_RASTERIZER_DISCARD); -} - -void RainNode::draw() { - const float screenw = (float)UserConfigParams::m_width; - - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); - glUseProgram(RenderProgram); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - - float screen[2] = { - (float)UserConfigParams::m_width, - (float)UserConfigParams::m_height - }; - irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); - invproj.makeInverse(); - - bindUniformToTextureUnit(texloc_tex, texture, 0); - bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); - - glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(loc_screen, screen[0], screen[1]); - glUniform1f(loc_screenw, screenw); - glDrawArrays(GL_POINTS, 0, count); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); -} - +void RainNode::simulate() { + glUseProgram(SimulationProgram); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; + const irr::core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_VIEW); + const irr::core::vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); + + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[0]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_vertex_buffer[1]); + + glUniformMatrix4fv(loc_viewm, 1, GL_FALSE, viewm.pointer()); + glUniform1f(loc_time, time); + glUniform3f(loc_campos, campos.X, campos.Y, campos.Z); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisable(GL_RASTERIZER_DISCARD); +} + +void RainNode::draw() { + const float screenw = (float)UserConfigParams::m_width; + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_vertex_buffer[1]); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); + invproj.makeInverse(); + + bindUniformToTextureUnit(texloc_tex, texture, 0); + bindUniformToTextureUnit(texloc_normal_and_depths, normal_and_depth, 1); + + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniform1f(loc_screenw, screenw); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); +} + const core::aabbox3d& RainNode::getBoundingBox() const { return box; -} \ No newline at end of file +} diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index e0bf03ddc..2be2dc771 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -1,48 +1,77 @@ -#ifndef GPUPARTICLES_H -#define GPUPARTICLES_H - -#ifndef _IRR_WINDOWS_API_ -#define GL_GLEXT_PROTOTYPES 1 -#endif -#include "graphics/glwrap.hpp" -#include - -void initGL(); -GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); -GLuint getTextureGLuint(irr::video::ITexture *tex); -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); - - -class GPUParticle : public scene::ISceneNode { -protected: - video::SMaterial fakemat; - virtual void simulate() = 0; - virtual void draw() = 0; -public: - //GPUParticle(unsigned c, float *initialSamples, GLuint tex, GLuint rtt); +#ifndef GPUPARTICLES_H +#define GPUPARTICLES_H + +#ifndef _IRR_WINDOWS_API_ +#define GL_GLEXT_PROTOTYPES 1 +#endif +#include "graphics/glwrap.hpp" +#include + +void initGL(); +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); +GLuint getTextureGLuint(irr::video::ITexture *tex); +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); + + +class GPUParticle : public scene::ISceneNode { +protected: + video::SMaterial fakemat; + virtual void simulate() = 0; + virtual void draw() = 0; +public: GPUParticle(scene::ISceneManager* mgr, ITexture *tex); - virtual void render(); - virtual void OnRegisterSceneNode(); -}; + virtual void render(); + virtual void OnRegisterSceneNode(); +}; + +class PointEmitter : public GPUParticle +{ +protected: + GLuint SimulationProgram, RenderProgram; + GLuint loc_duration, loc_source, loc_dt, loc_matrix; + GLuint loc_position, loc_velocity, loc_lifetime; + GLuint tfb_buffers[2]; + unsigned duration, count; + core::vector3df direction; + core::aabbox3d box; + + virtual void simulate(); + virtual void draw(); +public: + PointEmitter( + scene::ISceneManager* mgr, ITexture *tex, + const core::vector3df& dir, + u32 minParticlesPerSecond, + u32 maxParticlesPerSecond, + const video::SColor& minStartColor, + const video::SColor& maxStartColor, + u32 lifeTimeMin, u32 lifeTimeMax, + s32 maxAngleDegrees +// const core::dimension2df& minStartSize, +// const core::dimension2df& maxStartSize + ); + virtual const core::aabbox3d& getBoundingBox() const { return box; } + virtual u32 getMaterialCount() const { return 1; } +}; class RainNode : public GPUParticle { protected: GLuint SimulationProgram, RenderProgram, tfb_vertex_buffer[2]; unsigned count; - GLuint texture, normal_and_depth; - GLuint loc_campos, loc_viewm, loc_time; + GLuint texture, normal_and_depth; + GLuint loc_campos, loc_viewm, loc_time; GLuint loc_screenw, loc_screen, loc_invproj, texloc_tex, texloc_normal_and_depths; s32 area; core::aabbox3d box; - virtual void simulate(); + virtual void simulate(); virtual void draw(); public: RainNode(scene::ISceneManager* mgr, ITexture *tex); virtual const core::aabbox3d& getBoundingBox() const; virtual u32 getMaterialCount() const { return 1; } -}; - -#endif // GPUPARTICLES_H \ No newline at end of file +}; + +#endif // GPUPARTICLES_H diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index f08080a92..28c72fc42 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -28,6 +28,7 @@ #include "tracks/track.hpp" #include "utils/constants.hpp" #include "utils/helpers.hpp" +#include "graphics/gpuparticles.h" #include #include @@ -436,11 +437,25 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) case EMITTER_POINT: { m_emitter = m_node->createPointEmitter(velocity, - type->getMinRate(), type->getMaxRate(), +#ifdef GPUPARTICLE + 0., 0., +#else + type->getMinRate(), type->getMaxRate(), +#endif type->getMinColor(), type->getMaxColor(), lifeTimeMin, lifeTimeMax, m_particle_type->getAngleSpread() /* angle */ ); +#ifdef GPUPARTICLE + PointEmitter *PE = new PointEmitter(irr_driver->getSceneManager(), m_node->getMaterial(0).getTexture(0), + velocity, + type->getMinRate(), type->getMaxRate(), + type->getMinColor(), type->getMaxColor(), + lifeTimeMin, lifeTimeMax, + m_particle_type->getAngleSpread()); + PE->setPosition(m_node->getPosition()); + irr_driver->addPerCameraNode(PE, irr_driver->getSceneManager()->getActiveCamera(), NULL); +#endif break; } From a2d1a86bac59bd0b0d130d69c01c56e8a4ed5838 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 18:37:45 +0000 Subject: [PATCH 075/412] Lights: Make possible for gpu drivers to unroll loop. GPU doesn't like indirect addressing and thus it's better to have unrolled loop. This is only possible for loop with a static iteration count. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14830 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 3 +-- src/graphics/callbacks.cpp | 1 - src/graphics/render.cpp | 12 ++++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index cb535e70d..bcdb5f0d7 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -3,7 +3,6 @@ uniform sampler2D ntex; uniform vec4 center[16]; uniform vec4 col[16]; uniform float energy[16]; -uniform int lightcount; uniform float spec; uniform vec2 screen; uniform mat4 invproj; @@ -19,7 +18,7 @@ void main() { vec3 diffuse = vec3(0.), specular = vec3(0.); - for (int i = 0; i < lightcount; ++i) { + for (int i = 0; i < 16; ++i) { vec4 pseudocenter = viewm * vec4(center[i].xyz, 1.0); pseudocenter /= pseudocenter.w; vec3 light_pos = pseudocenter.xyz; diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 5587e968f..07fc92297 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -364,7 +364,6 @@ void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("col[0]", m_color.data(), m_color.size()); srv->setVertexShaderConstant("center[0]", m_pos.data(), m_pos.size()); srv->setVertexShaderConstant("viewm", m_view.pointer(), 16); - srv->setVertexShaderConstant("lightcount", &lightcount, 1); if (!firstdone) { diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index f9b87bf2e..e1c74bdb8 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -760,6 +760,18 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, break; } } + // Fill lights + for (; lightnum < MAXLIGHT; lightnum++) { + accumulatedLightPos.push_back(0.); + accumulatedLightPos.push_back(0.); + accumulatedLightPos.push_back(0.); + accumulatedLightPos.push_back(0.); + accumulatedLightColor.push_back(0.); + accumulatedLightColor.push_back(0.); + accumulatedLightColor.push_back(0.); + accumulatedLightColor.push_back(0.); + accumulatedLightEnergy.push_back(0.); + } LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO SMaterial m_material; From 636f6412ab26f99f170e57d5a3b686986b3ba7fd Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 19:24:19 +0000 Subject: [PATCH 076/412] GPUParticles: Use some parameters, and texture, to display particles. Still not enabled. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14831 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 10 +++------- data/shaders/particle.vert | 8 ++------ src/graphics/gpuparticles.cpp | 34 +++++++++++++++------------------- src/graphics/gpuparticles.h | 3 ++- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index f7edc445f..f45f30911 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -1,12 +1,8 @@ #version 130 -in float lifetime; - -out vec3 color; +uniform sampler2D texture; +out vec4 color; void main(void) { - color = vec3( - (lifetime < 33.) ? 1. : 0., - (lifetime < 67. && lifetime >= 34.) ? 1. : 0., - (lifetime > 68.) ? 1. : 0.); + color = texture2D(texture, gl_PointCoord.xy); } diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index fcc348b41..753a93c7f 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,13 +1,9 @@ #version 130 -in vec3 position; -in float lf; uniform mat4 matrix; - -out float lifetime; +in vec3 position; void main(void) { - gl_PointSize = 10.; + gl_PointSize = 50.; gl_Position = matrix * vec4(position, 1.0); - lifetime = lf; } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index f73cbcadc..53efe3c99 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -214,12 +214,16 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, // const core::dimension2df& minStartSize, // const core::dimension2df& maxStartSize ) : GPUParticle(mgr, tex) { + count = lifeTimeMax * maxParticlesPerSecond / 1000; + duration = lifeTimeMax; + float initial_lifetime_incr = 1000.; + initial_lifetime_incr /= maxParticlesPerSecond; const char *varyings[] = { "new_particle_position", "new_lifetime", "new_particle_velocity", - //"gl_SkipComponents3" }; + texture = getTextureGLuint(tex); SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); loc_duration = glGetUniformLocation(SimulationProgram, "duration"); @@ -228,27 +232,23 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); - printf("locs are %d, %d, %d\n", loc_position, loc_lifetime, loc_velocity); + printf("count:%d\nduration:%d\ninitial_lifetine:%f\n", count, duration, initial_lifetime_incr); RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); - count = 25; + loc_texture = glGetUniformLocation(RenderProgram, "texture"); float *particles = new float[COMPONENTCOUNT * count]; for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = 0.;// getPosition().X; - particles[COMPONENTCOUNT * i + 1] = 0.;// getPosition().Y; - particles[COMPONENTCOUNT * i + 2] = 0.;//getPosition().Z; - particles[COMPONENTCOUNT * i + 3] = i * 10; + particles[COMPONENTCOUNT * i] = 0.; + particles[COMPONENTCOUNT * i + 1] = 0.; + particles[COMPONENTCOUNT * i + 2] = 0.; + particles[COMPONENTCOUNT * i + 3] = rand() % duration; particles[COMPONENTCOUNT * i + 4] = direction.X; particles[COMPONENTCOUNT * i + 5] = direction.Y; particles[COMPONENTCOUNT * i + 6] = direction.Z; - -// particles[COMPONENTCOUNT * i + 8] = 100.; - //memcpy(&particles[COMPONENTCOUNT * i + 3], &i, sizeof(float)); } - printf("dir is %f, %f, %f\n", direction.X, direction.Y, direction.Z); glGenBuffers(2, tfb_buffers); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); @@ -271,7 +271,7 @@ void PointEmitter::simulate() glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); glUniform1i(loc_dt, 1); - glUniform1i(loc_duration, 100); + glUniform1i(loc_duration, duration); glUniform3f(loc_source, getPosition().X, getPosition().Y, getPosition().Z); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); @@ -285,23 +285,19 @@ void PointEmitter::simulate() void PointEmitter::draw() { - glDisable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - matrix *= getAbsoluteTransformation();; + matrix *= getAbsoluteTransformation(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); glUseProgram(RenderProgram); glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); - glVertexAttribPointer(glGetAttribLocation(RenderProgram, "position"), 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); - glVertexAttribPointer(glGetAttribLocation(RenderProgram, "lf"), 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *)(3 * sizeof(float))); + bindUniformToTextureUnit(loc_texture, texture, 0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); glDrawArrays(GL_POINTS, 0, count); glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 2be2dc771..25c745cd5 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,9 +29,10 @@ class PointEmitter : public GPUParticle { protected: GLuint SimulationProgram, RenderProgram; - GLuint loc_duration, loc_source, loc_dt, loc_matrix; + GLuint loc_duration, loc_source, loc_dt, loc_matrix, loc_texture; GLuint loc_position, loc_velocity, loc_lifetime; GLuint tfb_buffers[2]; + GLuint texture; unsigned duration, count; core::vector3df direction; core::aabbox3d box; From 871e2b998b92f0a8bb7d55f48c574ceed4ce668b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 20:36:21 +0000 Subject: [PATCH 077/412] GPUParticles: Implement softness and use maxangle spread git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14832 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 15 ++++++++++++++- data/shaders/particle.vert | 2 +- src/graphics/gpuparticles.cpp | 35 ++++++++++++++++++++++++++++++----- src/graphics/gpuparticles.h | 4 ++-- 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index f45f30911..6b14ed7b1 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -1,8 +1,21 @@ #version 130 uniform sampler2D texture; +uniform sampler2D normals_and_depth; +uniform mat4 invproj; +uniform vec2 screen; out vec4 color; void main(void) { - color = texture2D(texture, gl_PointCoord.xy); + vec2 xy = gl_FragCoord.xy / screen; + float FragZ = gl_FragCoord.z; + float EnvZ = texture2D(normals_and_depth, xy).a; + vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); + FragmentPos /= FragmentPos.w; + vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); + EnvPos /= EnvPos.w; + float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); + float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); + color = texture2D(texture, gl_PointCoord.xy); + color.a *= alpha; } diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index 753a93c7f..e3cdb088f 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -4,6 +4,6 @@ in vec3 position; void main(void) { - gl_PointSize = 50.; gl_Position = matrix * vec4(position, 1.0); + gl_PointSize = 300. / gl_Position.w; } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 53efe3c99..7074c34ab 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -42,6 +42,7 @@ PFNGLUNIFORM1IPROC glUniform1i; PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +PFNGLBLENDEQUATIONPROC glBlendEquation; #endif void initGL() @@ -80,6 +81,7 @@ void initGL() glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation"); + glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation"); #endif } @@ -214,7 +216,7 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, // const core::dimension2df& minStartSize, // const core::dimension2df& maxStartSize ) : GPUParticle(mgr, tex) { - count = lifeTimeMax * maxParticlesPerSecond / 1000; + count = maxParticlesPerSecond; duration = lifeTimeMax; float initial_lifetime_incr = 1000.; initial_lifetime_incr /= maxParticlesPerSecond; @@ -224,6 +226,7 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, "new_particle_velocity", }; texture = getTextureGLuint(tex); + normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); loc_duration = glGetUniformLocation(SimulationProgram, "duration"); @@ -237,6 +240,9 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); loc_texture = glGetUniformLocation(RenderProgram, "texture"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); float *particles = new float[COMPONENTCOUNT * count]; for (unsigned i = 0; i < count; i++) { @@ -244,10 +250,14 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, particles[COMPONENTCOUNT * i + 1] = 0.; particles[COMPONENTCOUNT * i + 2] = 0.; particles[COMPONENTCOUNT * i + 3] = rand() % duration; + core::vector3df particledir = direction; + particledir.rotateXYBy(os::Randomizer::frand() * maxAngleDegrees); + particledir.rotateYZBy(os::Randomizer::frand() * maxAngleDegrees); + particledir.rotateXZBy(os::Randomizer::frand() * maxAngleDegrees); - particles[COMPONENTCOUNT * i + 4] = direction.X; - particles[COMPONENTCOUNT * i + 5] = direction.Y; - particles[COMPONENTCOUNT * i + 6] = direction.Z; + particles[COMPONENTCOUNT * i + 4] = particledir.X; + particles[COMPONENTCOUNT * i + 5] = particledir.Y; + particles[COMPONENTCOUNT * i + 6] = particledir.Z; } glGenBuffers(2, tfb_buffers); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); @@ -285,16 +295,31 @@ void PointEmitter::simulate() void PointEmitter::draw() { + glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); matrix *= getAbsoluteTransformation(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); glUseProgram(RenderProgram); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); + invproj.makeInverse(); + bindUniformToTextureUnit(loc_texture, texture, 0); + bindUniformToTextureUnit(loc_normal_and_depths, normal_and_depth, 1); + + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); glDrawArrays(GL_POINTS, 0, count); glDisableVertexAttribArray(0); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 25c745cd5..2742b979a 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,10 +29,10 @@ class PointEmitter : public GPUParticle { protected: GLuint SimulationProgram, RenderProgram; - GLuint loc_duration, loc_source, loc_dt, loc_matrix, loc_texture; + GLuint loc_duration, loc_source, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; GLuint loc_position, loc_velocity, loc_lifetime; GLuint tfb_buffers[2]; - GLuint texture; + GLuint texture, normal_and_depth; unsigned duration, count; core::vector3df direction; core::aabbox3d box; From 64fa58d1988c798eea9715aaab2ab443baf8a7ab Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 22:26:50 +0000 Subject: [PATCH 078/412] GPUParticles: Add them to scenemanager root instead of a percamera node git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14833 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 5 +++-- src/graphics/particle_emitter.cpp | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 7074c34ab..617041711 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -176,13 +176,14 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni } GPUParticle::GPUParticle(scene::ISceneManager* mgr, ITexture *tex) - : scene::ISceneNode(0, mgr, -1) { + : scene::ISceneNode(mgr->getRootSceneNode(), mgr, -1) { initGL(); fakemat.Lighting = false; fakemat.ZWriteEnable = false; fakemat.MaterialType = irr_driver->getShader(ES_RAIN); fakemat.Thickness = 200; - fakemat.setTexture(0, tex); + fakemat.setTexture(0, tex); + setAutomaticCulling(0); } void GPUParticle::render() { diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 28c72fc42..3cc1392ba 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -454,7 +454,6 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) lifeTimeMin, lifeTimeMax, m_particle_type->getAngleSpread()); PE->setPosition(m_node->getPosition()); - irr_driver->addPerCameraNode(PE, irr_driver->getSceneManager()->getActiveCamera(), NULL); #endif break; } From ea1e5077a21575f8f8a81017976639183a1c6b51 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 22:26:59 +0000 Subject: [PATCH 079/412] GPUParticles: Disable depth test to avoid rendering artifacts git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14834 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 617041711..3f536da75 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -296,6 +296,8 @@ void PointEmitter::simulate() void PointEmitter::draw() { + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); @@ -327,6 +329,8 @@ void PointEmitter::draw() glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) From ab447c1bed61d4f4035ded12c05c88e228bdfade Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 22:53:17 +0000 Subject: [PATCH 080/412] GPUParticle: Disable depth write instead of disabling depth test. It's probably faster. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14835 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 3f536da75..fee1840af 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -297,7 +297,7 @@ void PointEmitter::simulate() void PointEmitter::draw() { glDisable(GL_ALPHA_TEST); - glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); @@ -330,7 +330,7 @@ void PointEmitter::draw() glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_ALPHA_TEST); - glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) From 88f39e41862ec9301078bb540f64cc8330458223 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 22:53:28 +0000 Subject: [PATCH 081/412] GPUParticles: Properly handle parent for gpuparticles git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14836 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 12 +++++++----- src/graphics/gpuparticles.h | 4 ++-- src/graphics/particle_emitter.cpp | 7 +++++-- src/graphics/particle_emitter.hpp | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index fee1840af..67507426f 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -175,8 +175,8 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glUniform1i(location, textureUnit); } -GPUParticle::GPUParticle(scene::ISceneManager* mgr, ITexture *tex) - : scene::ISceneNode(mgr->getRootSceneNode(), mgr, -1) { +GPUParticle::GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex) + : scene::ISceneNode(parent, mgr, -1) { initGL(); fakemat.Lighting = false; fakemat.ZWriteEnable = false; @@ -206,7 +206,8 @@ void GPUParticle::OnRegisterSceneNode() { #define COMPONENTCOUNT 8 -PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, +PointEmitter::PointEmitter(scene::ISceneNode *parent, + scene::ISceneManager* mgr, ITexture *tex, const core::vector3df& direction, u32 minParticlesPerSecond, u32 maxParticlesPerSecond, @@ -216,7 +217,7 @@ PointEmitter::PointEmitter(scene::ISceneManager* mgr, ITexture *tex, s32 maxAngleDegrees // const core::dimension2df& minStartSize, // const core::dimension2df& maxStartSize -) : GPUParticle(mgr, tex) { +) : GPUParticle(parent, mgr, tex) { count = maxParticlesPerSecond; duration = lifeTimeMax; float initial_lifetime_incr = 1000.; @@ -296,6 +297,7 @@ void PointEmitter::simulate() void PointEmitter::draw() { + updateAbsolutePosition(); glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); @@ -334,7 +336,7 @@ void PointEmitter::draw() } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) - : GPUParticle(mgr, tex) + : GPUParticle(0, mgr, tex) { RenderProgram = LoadProgram(file_manager->getAsset("shaders/rain.vert").c_str(), file_manager->getAsset("shaders/rain.frag").c_str()); loc_screenw = glGetUniformLocation(RenderProgram, "screenw"); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 2742b979a..d5a1b9350 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -20,7 +20,7 @@ protected: virtual void simulate() = 0; virtual void draw() = 0; public: - GPUParticle(scene::ISceneManager* mgr, ITexture *tex); + GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex); virtual void render(); virtual void OnRegisterSceneNode(); }; @@ -40,7 +40,7 @@ protected: virtual void simulate(); virtual void draw(); public: - PointEmitter( + PointEmitter(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex, const core::vector3df& dir, u32 minParticlesPerSecond, diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 3cc1392ba..ede0f198c 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -233,6 +233,7 @@ ParticleEmitter::ParticleEmitter(const ParticleKind* type, m_particle_type = NULL; m_parent = parent; m_emission_decay_rate = 0; + PE = 0; setParticleType(type); assert(m_node != NULL); @@ -344,7 +345,9 @@ int ParticleEmitter::getCreationRate() */ void ParticleEmitter::setPosition(const Vec3 &pos) { - m_node->setPosition(pos.toIrrVector()); + if (PE) + PE->setPosition(pos.toIrrVector()); + m_node->setPosition(pos.toIrrVector()); } // setPosition //----------------------------------------------------------------------------- @@ -447,7 +450,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) m_particle_type->getAngleSpread() /* angle */ ); #ifdef GPUPARTICLE - PointEmitter *PE = new PointEmitter(irr_driver->getSceneManager(), m_node->getMaterial(0).getTexture(0), + PE = new PointEmitter(m_node->getParent(), irr_driver->getSceneManager(), m_node->getMaterial(0).getTexture(0), velocity, type->getMinRate(), type->getMaxRate(), type->getMinColor(), type->getMaxColor(), diff --git a/src/graphics/particle_emitter.hpp b/src/graphics/particle_emitter.hpp index 8c3dd941a..55e43dc76 100644 --- a/src/graphics/particle_emitter.hpp +++ b/src/graphics/particle_emitter.hpp @@ -49,6 +49,7 @@ private: /** Irrlicht's particle systems. */ scene::IParticleSystemSceneNode *m_node; + class PointEmitter *PE; Vec3 m_position; From ebb45f8de601a064ec15c4fd235ab424a8c76c2f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 29 Dec 2013 23:55:55 +0000 Subject: [PATCH 082/412] GPUParticles: Use an ugly hack to get correct position git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14837 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 3 ++- src/graphics/gpuparticles.h | 2 ++ src/graphics/particle_emitter.cpp | 3 +-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 67507426f..b698ee884 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -4,6 +4,7 @@ #include "io/file_manager.hpp" #include "config/user_config.hpp" #include +#include #ifdef _IRR_WINDOWS_API_ #define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) @@ -303,7 +304,7 @@ void PointEmitter::draw() glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - matrix *= getAbsoluteTransformation(); + matrix *= m_node->getAbsoluteTransformation(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); glBlendEquation(GL_FUNC_ADD); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index d5a1b9350..1b3bfa958 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -36,6 +36,7 @@ protected: unsigned duration, count; core::vector3df direction; core::aabbox3d box; + scene::IParticleSystemSceneNode *m_node; virtual void simulate(); virtual void draw(); @@ -52,6 +53,7 @@ public: // const core::dimension2df& minStartSize, // const core::dimension2df& maxStartSize ); + void set_m_node(scene::IParticleSystemSceneNode *nd) { m_node = nd; } virtual const core::aabbox3d& getBoundingBox() const { return box; } virtual u32 getMaterialCount() const { return 1; } }; diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index ede0f198c..2519aa6c3 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -345,8 +345,6 @@ int ParticleEmitter::getCreationRate() */ void ParticleEmitter::setPosition(const Vec3 &pos) { - if (PE) - PE->setPosition(pos.toIrrVector()); m_node->setPosition(pos.toIrrVector()); } // setPosition @@ -457,6 +455,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) lifeTimeMin, lifeTimeMax, m_particle_type->getAngleSpread()); PE->setPosition(m_node->getPosition()); + PE->set_m_node(m_node); #endif break; } From d4b9ccf499fb8ce8b5098a465a90eb1ad2c64f45 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 30 Dec 2013 13:57:55 +0000 Subject: [PATCH 083/412] GPUParticles: Particles don't follow their source. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14838 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 5 +++-- src/graphics/gpuparticles.cpp | 7 +++---- src/graphics/gpuparticles.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index b3a236c26..ef3581224 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -1,6 +1,6 @@ #version 130 uniform int dt; -uniform vec3 source; +uniform mat4 sourcematrix; uniform int duration; in vec3 particle_position; @@ -13,7 +13,8 @@ out vec4 new_particle_velocity; void main(void) { - new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : vec3(0., 0., 0.); + vec4 initialposition = sourcematrix * vec4(0., 0., 0., 1.0); + new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration); new_particle_velocity = particle_velocity; gl_Position = vec4(0.); diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index b698ee884..3eb540b26 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -234,7 +234,7 @@ PointEmitter::PointEmitter(scene::ISceneNode *parent, SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); loc_duration = glGetUniformLocation(SimulationProgram, "duration"); loc_dt = glGetUniformLocation(SimulationProgram, "dt"); - loc_source = glGetUniformLocation(SimulationProgram, "source"); + loc_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); @@ -272,6 +272,7 @@ PointEmitter::PointEmitter(scene::ISceneNode *parent, void PointEmitter::simulate() { + core::matrix4 matrix = m_node->getAbsoluteTransformation(); glUseProgram(SimulationProgram); glEnable(GL_RASTERIZER_DISCARD); glEnableVertexAttribArray(0); @@ -285,7 +286,7 @@ void PointEmitter::simulate() glUniform1i(loc_dt, 1); glUniform1i(loc_duration, duration); - glUniform3f(loc_source, getPosition().X, getPosition().Y, getPosition().Z); + glUniformMatrix4fv(loc_sourcematrix, 1, GL_FALSE, matrix.pointer()); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); @@ -298,13 +299,11 @@ void PointEmitter::simulate() void PointEmitter::draw() { - updateAbsolutePosition(); glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - matrix *= m_node->getAbsoluteTransformation(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_POINT_SPRITE); glBlendEquation(GL_FUNC_ADD); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 1b3bfa958..379745752 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,7 +29,7 @@ class PointEmitter : public GPUParticle { protected: GLuint SimulationProgram, RenderProgram; - GLuint loc_duration, loc_source, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; + GLuint loc_duration, loc_sourcematrix, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; GLuint loc_position, loc_velocity, loc_lifetime; GLuint tfb_buffers[2]; GLuint texture, normal_and_depth; From 7645883508cb1d98dc910c857c653993bfc44fdc Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 30 Dec 2013 14:10:32 +0000 Subject: [PATCH 084/412] GPUParticles: Remove PE when the particle emitter is removed. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14839 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/particle_emitter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 2519aa6c3..f54e361c8 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -248,6 +248,8 @@ ParticleEmitter::~ParticleEmitter() assert(m_magic_number == 0x58781325); if (m_node != NULL) irr_driver->removeNode(m_node); + if (PE) + irr_driver->removeNode(PE); m_emitter->drop(); m_magic_number = 0xDEADBEEF; @@ -454,7 +456,6 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) type->getMinColor(), type->getMaxColor(), lifeTimeMin, lifeTimeMax, m_particle_type->getAngleSpread()); - PE->setPosition(m_node->getPosition()); PE->set_m_node(m_node); #endif break; From 36fc36c7fb9f5eecb89de70bdb11a820eb9a8b6d Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 30 Dec 2013 22:32:30 +0000 Subject: [PATCH 085/412] Add initial library object loading code. Not complete yet. Samuncle, this is for you ;) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14840 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/lod_node_loader.cpp | 15 +- src/tracks/track.cpp | 412 ++++++++++++----------- src/tracks/track.hpp | 1 + src/tracks/track_object_presentation.cpp | 18 +- 4 files changed, 245 insertions(+), 201 deletions(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index 57f690150..0de17f1fb 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -154,12 +154,17 @@ void LodNodeLoader::done(Track* track, full_path = directory + "/" + group[m].second.m_model_file; // TODO: check whether the mesh contains animations or not? - scene::IMesh *a_mesh = irr_driver->getMesh(full_path); - if(!a_mesh) + scene::IMesh* a_mesh = irr_driver->getMesh(full_path); + if (!a_mesh) { - fprintf(stderr, "Warning: object model '%s' not found, ignored.\n", - full_path.c_str()); - continue; + a_mesh = irr_driver->getMesh(group[m].second.m_model_file); + + if (!a_mesh) + { + Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", + full_path.c_str()); + continue; + } } if (group[m].second.m_tangent) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 6351314d9..6bbc34fff 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1425,7 +1425,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) // Add the track directory to the texture search path file_manager->pushTextureSearchPath(m_root); file_manager->pushModelSearchPath (m_root); - // First read the temporary materials.dat file if it exists + + // First read the temporary materials.xml file if it exists try { std::string materials_file = m_root+"materials.xml"; @@ -1440,24 +1441,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } catch (std::exception& e) { - // no temporary materials.dat file, ignore + // no temporary materials.xml file, ignore (void)e; } - // Start building the scene graph - std::string path = m_root+m_all_modes[mode_id].m_scene; - XMLNode *root = file_manager->createXMLTree(path); - - // Make sure that we have a track (which is used for raycasts to - // place other objects). - if(!root || root->getName()!="scene") - { - std::ostringstream msg; - msg<< "No track model defined in '"<getNode("default-start"); - if(default_start) + + // Start building the scene graph + std::string path = m_root + m_all_modes[mode_id].m_scene; + XMLNode *root = file_manager->createXMLTree(path); + + // Make sure that we have a track (which is used for raycasts to + // place other objects). + if (!root || root->getName()!="scene") + { + std::ostringstream msg; + msg<< "No track model defined in '"<getNode("default-start"); + if (default_start) { default_start->get("forwards-distance", &forwards_distance ); default_start->get("sidewards-distance", &sidewards_distance); default_start->get("upwards-distance", &upwards_distance ); default_start->get("karts-per-row", &karts_per_row ); } - if(!m_is_arena && !m_is_soccer && !m_is_cutscene) + + if (!m_is_arena && !m_is_soccer && !m_is_cutscene) { m_start_transforms.resize(race_manager->getNumberOfKarts()); QuadGraph::get()->setDefaultStartPositions(&m_start_transforms, @@ -1491,10 +1494,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) upwards_distance); } - unsigned int start_position_counter = 0; - // we need to check for fog before loading the main track model - if(const XMLNode *node = root->getNode("sun")) + if (const XMLNode *node = root->getNode("sun")) { node->get("xyz", &m_sun_position ); node->get("ambient", &m_default_ambient_color); @@ -1512,31 +1513,204 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) loadMainTrack(*root); unsigned int main_track_count = m_all_nodes.size(); - LodNodeLoader lod_loader; + loadObjects(root, path); - for(unsigned int i=0; igetNumNodes(); i++) + // ---- Fog + // It's important to execute this BEFORE the code that creates the skycube, + // otherwise the skycube node could be modified to have fog enabled, which + // we don't want + if (m_use_fog && !UserConfigParams::m_camera_debug && !irr_driver->isGLSL()) + { + /* NOTE: if LINEAR type, density does not matter, if EXP or EXP2, start + and end do not matter */ + irr_driver->getVideoDriver()->setFog(m_fog_color, + video::EFT_FOG_LINEAR, + m_fog_start, m_fog_end, + 1.0f); + } + + // Enable for for all track nodes if fog is used + const unsigned int count = m_all_nodes.size(); + for(unsigned int i=0; ienableFog(m_use_fog); + + // Sky dome and boxes support + // -------------------------- + if(m_sky_type==SKY_DOME && m_sky_textures.size() > 0) + { + scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0], + m_sky_hori_segments, + m_sky_vert_segments, + m_sky_texture_percent, + m_sky_sphere_percent); + for(unsigned int i=0; igetMaterialCount(); i++) + { + video::SMaterial &irrMaterial=node->getMaterial(i); + for(unsigned int j=0; jaddSkyBox(m_sky_textures)); + } + else if(m_sky_type==SKY_COLOR) + { + World::getWorld()->setClearbackBufferColor(m_sky_color); + } + + + file_manager->popTextureSearchPath(); + file_manager->popModelSearchPath (); + + // ---- Set ambient color + m_ambient_color = m_default_ambient_color; + irr_driver->getSceneManager()->setAmbientLight(m_ambient_color); + + // ---- Create sun (non-ambient directional light) + if (m_sun_position.getLengthSQ() < 0.03f) + { + m_sun_position = core::vector3df(500, 250, 250); + } + + const video::SColorf tmpf(m_sun_diffuse_color); + m_sun = irr_driver->addLight(m_sun_position, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true); + + if (!irr_driver->isGLSL()) + { + scene::ILightSceneNode *sun = (scene::ILightSceneNode *) m_sun; + sun->setLightType(video::ELT_DIRECTIONAL); + + // The angle of the light is rather important - let the sun + // point towards (0,0,0). + if (m_sun_position.getLengthSQ() < 0.03f) + // Backward compatibility: if no sun is specified, use the + // old hardcoded default angle + m_sun->setRotation( core::vector3df(180, 45, 45) ); + else + m_sun->setRotation((-m_sun_position).getHorizontalAngle()); + + sun->getLightData().SpecularColor = m_sun_specular_color; + } + + + createPhysicsModel(main_track_count); + + + for (unsigned int i=0; igetNumNodes(); i++) + { + const XMLNode *node = root->getNode(i); + const std::string &name = node->getName(); + if (name=="banana" || name=="item" || + name=="small-nitro" || name=="big-nitro" || + name=="easter-egg" ) + { + itemCommand(node); + } + } // for igetNumNodes() + + delete root; + + if (UserConfigParams::m_track_debug && + race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && + !m_is_cutscene) + { + QuadGraph::get()->createDebugMesh(); + } + + // Only print warning if not in battle mode, since battle tracks don't have + // any quads or check lines. + if (CheckManager::get()->getCheckStructureCount()==0 && + race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && !m_is_cutscene) + { + Log::warn("track", "No check lines found in track '%s'.", + m_ident.c_str()); + Log::warn("track", "Lap counting will not work, and start " + "positions might be incorrect."); + } + + if (UserConfigParams::logMemory()) + { + Log::debug("track", "[memory] After loading '%s': mesh cache %d " + "texture cache %d\n", getIdent().c_str(), + irr_driver->getSceneManager()->getMeshCache()->getMeshCount(), + irr_driver->getVideoDriver()->getTextureCount()); + } + + World *world = World::getWorld(); + if (world->useChecklineRequirements()) + { + QuadGraph::get()->computeChecklineRequirements(); + } + + EasterEggHunt *easter_world = dynamic_cast(world); + if(easter_world) + { + std::string dir = StringUtils::getPath(m_filename); + easter_world->readData(dir+"/easter_eggs.xml"); + } + + irr_driver->unsetTextureErrorMessage(); +} // loadTrackModel + +//----------------------------------------------------------------------------- + +void Track::loadObjects(const XMLNode* root, const std::string& path) +{ + LodNodeLoader lod_loader; + unsigned int start_position_counter = 0; + + unsigned int node_count = root->getNumNodes(); + for (unsigned int i = 0; i < node_count; i++) { const XMLNode *node = root->getNode(i); const std::string name = node->getName(); // The track object was already converted before the loop, and the // default start was already used, too - so ignore those. - if(name=="track" || name=="default-start") continue; - if(name=="object") + if (name == "track" || name == "default-start") continue; + if (name == "object") { lod_loader.check(node); m_track_object_manager->add(*node); } - else if(name=="water") + else if (name == "library") + { + std::string name; + node->get("name", &name); + std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml"); + std::string lib_path = file_manager->getAsset("library/" + name); + XMLNode *libroot = file_manager->createXMLTree(lib_node_path); + if (libroot == NULL) continue; + + file_manager->pushTextureSearchPath(lib_path + "/"); + file_manager->pushModelSearchPath (lib_path); + + loadObjects(libroot, lib_path); + + file_manager->popTextureSearchPath(); + file_manager->popModelSearchPath(); + } + else if (name == "water") { createWater(*node); } - else if(name=="banana" || name=="item" || - name=="small-nitro" || name=="big-nitro" || - name=="easter-egg" ) + else if (name == "banana" || name == "item" || + name == "small-nitro" || name == "big-nitro" || + name == "easter-egg" ) { // will be handled later } - else if (name=="start") + else if (name == "start") { unsigned int position = start_position_counter; start_position_counter++; @@ -1556,34 +1730,34 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) btQuaternion(btVector3(0,1,0), h*DEGREE_TO_RAD ) ); } - else if(name=="camera") + else if (name == "camera") { node->get("far", &m_camera_far); } - else if(name=="checks") + else if (name == "checks") { CheckManager::get()->load(*node); } - else if (name=="particle-emitter") + else if (name == "particle-emitter") { if (UserConfigParams::m_graphical_effects) { m_track_object_manager->add(*node); } } - else if(name=="sky-dome" || name=="sky-box" || name=="sky-color") + else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") { handleSky(*node, path); } - else if(name=="end-cameras") + else if (name == "end-cameras") { Camera::readEndCamera(*node); } - else if(name=="light") + else if (name == "light") { m_track_object_manager->add(*node); } - else if(name=="weather") + else if (name == "weather") { std::string weather_particles; std::string weather_type; @@ -1646,13 +1820,16 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) // -------- Create and assign LOD nodes -------- // recheck the static area, we will need LOD info const XMLNode* track_node = root->getNode("track"); - for(unsigned int i=0; igetNumNodes(); i++) + if (track_node != NULL) { - const XMLNode* n = track_node->getNode(i); - bool is_instance = false; - n->get("lod_instance", &is_instance); + for(unsigned int i=0; igetNumNodes(); i++) + { + const XMLNode* n = track_node->getNode(i); + bool is_instance = false; + n->get("lod_instance", &is_instance); - if (!is_instance) lod_loader.check(n); + if (!is_instance) lod_loader.check(n); + } } std::vector lod_nodes; @@ -1664,154 +1841,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) // Init all track objects m_track_object_manager->init(); - - - // ---- Fog - // It's important to execute this BEFORE the code that creates the skycube, - // otherwise the skycube node could be modified to have fog enabled, which - // we don't want - if (m_use_fog && !UserConfigParams::m_camera_debug && !irr_driver->isGLSL()) - { - /* NOTE: if LINEAR type, density does not matter, if EXP or EXP2, start - and end do not matter */ - irr_driver->getVideoDriver()->setFog(m_fog_color, - video::EFT_FOG_LINEAR, - m_fog_start, m_fog_end, - 1.0f); - } - - // Enable for for all track nodes if fog is used - //if(m_use_fog) - //{ - const unsigned int count = m_all_nodes.size(); - for(unsigned int i=0; ienableFog(m_use_fog); - - // Sky dome and boxes support - // -------------------------- - if(m_sky_type==SKY_DOME && m_sky_textures.size() > 0) - { - scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0], - m_sky_hori_segments, - m_sky_vert_segments, - m_sky_texture_percent, - m_sky_sphere_percent); - for(unsigned int i=0; igetMaterialCount(); i++) - { - video::SMaterial &irrMaterial=node->getMaterial(i); - for(unsigned int j=0; jaddSkyBox(m_sky_textures)); - } - else if(m_sky_type==SKY_COLOR) - { - World::getWorld()->setClearbackBufferColor(m_sky_color); - } - - - file_manager->popTextureSearchPath(); - file_manager->popModelSearchPath (); - - // ---- Set ambient color - m_ambient_color = m_default_ambient_color; - irr_driver->getSceneManager()->setAmbientLight(m_ambient_color); - - // ---- Create sun (non-ambient directional light) - if (m_sun_position.getLengthSQ() < 0.03f) - { - m_sun_position = core::vector3df(500, 250, 250); - } - - const video::SColorf tmpf(m_sun_diffuse_color); - m_sun = irr_driver->addLight(m_sun_position, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true); - - if (!irr_driver->isGLSL()) - { - scene::ILightSceneNode *sun = (scene::ILightSceneNode *) m_sun; - sun->setLightType(video::ELT_DIRECTIONAL); - - // The angle of the light is rather important - let the sun - // point towards (0,0,0). - if(m_sun_position.getLengthSQ() < 0.03f) - // Backward compatibility: if no sun is specified, use the - // old hardcoded default angle - m_sun->setRotation( core::vector3df(180, 45, 45) ); - else - m_sun->setRotation((-m_sun_position).getHorizontalAngle()); - - sun->getLightData().SpecularColor = m_sun_specular_color; - } - - - createPhysicsModel(main_track_count); - - - for(unsigned int i=0; igetNumNodes(); i++) - { - const XMLNode *node = root->getNode(i); - const std::string &name = node->getName(); - if (name=="banana" || name=="item" || - name=="small-nitro" || name=="big-nitro" || - name=="easter-egg" ) - { - itemCommand(node); - } - } // for igetNumNodes() - - delete root; - - if (UserConfigParams::m_track_debug && - race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && - !m_is_cutscene) - QuadGraph::get()->createDebugMesh(); - - // Only print warning if not in battle mode, since battle tracks don't have - // any quads or check lines. - if(CheckManager::get()->getCheckStructureCount()==0 && - race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && !m_is_cutscene) - { - Log::warn("track", "No check lines found in track '%s'.", - m_ident.c_str()); - Log::warn("track", "Lap counting will not work, and start " - "positions might be incorrect."); - } - - if(UserConfigParams::logMemory()) - Log::debug("track", "[memory] After loading '%s': mesh cache %d " - "texture cache %d\n", getIdent().c_str(), - irr_driver->getSceneManager()->getMeshCache()->getMeshCount(), - irr_driver->getVideoDriver()->getTextureCount()); - - World *world = World::getWorld(); - if (world->useChecklineRequirements()) - { - QuadGraph::get()->computeChecklineRequirements(); - } - - EasterEggHunt *easter_world = dynamic_cast(world); - if(easter_world) - { - std::string dir = StringUtils::getPath(m_filename); - easter_world->readData(dir+"/easter_eggs.xml"); - } - - irr_driver->unsetTextureErrorMessage(); -} // loadTrackModel +} //----------------------------------------------------------------------------- /** Changes all materials of the given mesh to use the current fog diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 862ac050f..d6c1558ed 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -399,6 +399,7 @@ private: std::vector& m_music ); void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); + void loadObjects(const XMLNode* root, const std::string& path); public: diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 1bb577818..1fbaf0343 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -186,9 +186,14 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node full_path = file_manager->getAsset(FileManager::MODEL,model_name); m_mesh = irr_driver->getAnimatedMesh(full_path); - if(!m_mesh) + if (!m_mesh) { - throw std::runtime_error("Model '" + model_name + "' cannot be found"); + m_mesh = irr_driver->getAnimatedMesh(model_name); + + if (!m_mesh) + { + throw std::runtime_error("Model '" + model_name + "' cannot be found"); + } } } @@ -457,10 +462,13 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode xml_node.get("end", &m_fade_out_end ); } - video::ITexture *texture = + video::ITexture* texture = irr_driver->getTexture(file_manager->searchTexture(texture_name)); - m_node = irr_driver->addBillboard(core::dimension2df(width, height), - texture); + if (texture == NULL) + { + Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found", texture_name.c_str()); + } + m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture); Material *stk_material = material_manager->getMaterial(texture_name); stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL); From fc5a8021358725fd160cb1672013877ea9ce1933 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 30 Dec 2013 22:52:32 +0000 Subject: [PATCH 086/412] GPUParticles: Subclass CParticleSystemSceneNode to make implementation cleaner git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14842 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 253 +++++++++++++++++------------- src/graphics/gpuparticles.h | 32 +++- src/graphics/particle_emitter.cpp | 18 +-- src/graphics/particle_emitter.hpp | 1 - 4 files changed, 175 insertions(+), 129 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 3eb540b26..42b64da53 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -176,6 +176,8 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glUniform1i(location, textureUnit); } +#define COMPONENTCOUNT 8 + GPUParticle::GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(parent, mgr, -1) { initGL(); @@ -205,134 +207,165 @@ void GPUParticle::OnRegisterSceneNode() { ISceneNode::OnRegisterSceneNode(); } -#define COMPONENTCOUNT 8 +scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode( + bool withDefaultEmitter, ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) { + if (!parent) + parent = irr_driver->getSceneManager()->getRootSceneNode(); -PointEmitter::PointEmitter(scene::ISceneNode *parent, - scene::ISceneManager* mgr, ITexture *tex, - const core::vector3df& direction, - u32 minParticlesPerSecond, - u32 maxParticlesPerSecond, - const video::SColor& minStartColor, - const video::SColor& maxStartColor, - u32 lifeTimeMin, u32 lifeTimeMax, - s32 maxAngleDegrees -// const core::dimension2df& minStartSize, -// const core::dimension2df& maxStartSize -) : GPUParticle(parent, mgr, tex) { - count = maxParticlesPerSecond; - duration = lifeTimeMax; + IParticleSystemSceneNode* node = new ParticleSystemProxy(withDefaultEmitter, + parent, irr_driver->getSceneManager(), id, position, rotation, scale); + node->drop(); + + return node; +} + +ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, + ISceneNode* parent, scene::ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale) { +} + +void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) +{ + if (!emitter) + return; + CParticleSystemSceneNode::setEmitter(emitter); + if (emitter->getType() != scene::EPET_POINT) + return; + setAutomaticCulling(0); + initGL(); + count = emitter->getMaxParticlesPerSecond(); + duration = emitter->getMaxLifeTime(); float initial_lifetime_incr = 1000.; - initial_lifetime_incr /= maxParticlesPerSecond; - const char *varyings[] = { - "new_particle_position", - "new_lifetime", - "new_particle_velocity", - }; - texture = getTextureGLuint(tex); - normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + const char *varyings[] = { + "new_particle_position", + "new_lifetime", + "new_particle_velocity", + }; + texture = getTextureGLuint(getMaterial(0).getTexture(0)); + normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); - loc_duration = glGetUniformLocation(SimulationProgram, "duration"); - loc_dt = glGetUniformLocation(SimulationProgram, "dt"); - loc_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); - loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); - loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); - loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); - printf("count:%d\nduration:%d\ninitial_lifetine:%f\n", count, duration, initial_lifetime_incr); + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); + loc_duration = glGetUniformLocation(SimulationProgram, "duration"); + loc_dt = glGetUniformLocation(SimulationProgram, "dt"); + loc_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); + loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); + loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); + loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); + printf("count:%d\nduration:%d\ninitial_lifetine:%f\n", count, duration, initial_lifetime_incr); - RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); - loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); - loc_texture = glGetUniformLocation(RenderProgram, "texture"); - loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); - loc_screen = glGetUniformLocation(RenderProgram, "screen"); - loc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); + RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); + loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); + loc_texture = glGetUniformLocation(RenderProgram, "texture"); + loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); + loc_screen = glGetUniformLocation(RenderProgram, "screen"); + loc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - float *particles = new float[COMPONENTCOUNT * count]; - for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = 0.; - particles[COMPONENTCOUNT * i + 1] = 0.; - particles[COMPONENTCOUNT * i + 2] = 0.; - particles[COMPONENTCOUNT * i + 3] = rand() % duration; - core::vector3df particledir = direction; - particledir.rotateXYBy(os::Randomizer::frand() * maxAngleDegrees); - particledir.rotateYZBy(os::Randomizer::frand() * maxAngleDegrees); - particledir.rotateXZBy(os::Randomizer::frand() * maxAngleDegrees); + float *particles = new float[COMPONENTCOUNT * count]; + for (unsigned i = 0; i < count; i++) { + particles[COMPONENTCOUNT * i] = 0.; + particles[COMPONENTCOUNT * i + 1] = 0.; + particles[COMPONENTCOUNT * i + 2] = 0.; + particles[COMPONENTCOUNT * i + 3] = rand() % duration; + core::vector3df particledir = emitter->getDirection(); + particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particles[COMPONENTCOUNT * i + 4] = particledir.X; - particles[COMPONENTCOUNT * i + 5] = particledir.Y; - particles[COMPONENTCOUNT * i + 6] = particledir.Z; - } - glGenBuffers(2, tfb_buffers); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); - delete [] particles; + particles[COMPONENTCOUNT * i + 4] = particledir.X; + particles[COMPONENTCOUNT * i + 5] = particledir.Y; + particles[COMPONENTCOUNT * i + 6] = particledir.Z; + } + glGenBuffers(2, tfb_buffers); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + delete [] particles; } -void PointEmitter::simulate() -{ - core::matrix4 matrix = m_node->getAbsoluteTransformation(); - glUseProgram(SimulationProgram); - glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(loc_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); - glVertexAttribPointer(loc_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); - glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); - glUniform1i(loc_dt, 1); - glUniform1i(loc_duration, duration); - glUniformMatrix4fv(loc_sourcematrix, 1, GL_FALSE, matrix.pointer()); - glBeginTransformFeedback(GL_POINTS); - glDrawArrays(GL_POINTS, 0, count); - glEndTransformFeedback(); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - glDisable(GL_RASTERIZER_DISCARD); - std::swap(tfb_buffers[0], tfb_buffers[1]); +void ParticleSystemProxy::simulate() +{ + core::matrix4 matrix = getAbsoluteTransformation(); + glUseProgram(SimulationProgram); + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glVertexAttribPointer(loc_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); + glVertexAttribPointer(loc_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); + + glUniform1i(loc_dt, 1); + glUniform1i(loc_duration, duration); + glUniformMatrix4fv(loc_sourcematrix, 1, GL_FALSE, matrix.pointer()); + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisable(GL_RASTERIZER_DISCARD); + std::swap(tfb_buffers[0], tfb_buffers[1]); } -void PointEmitter::draw() +void ParticleSystemProxy::draw() { - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glUseProgram(RenderProgram); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - float screen[2] = { - (float)UserConfigParams::m_width, - (float)UserConfigParams::m_height - }; - irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); - invproj.makeInverse(); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glUseProgram(RenderProgram); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); + invproj.makeInverse(); - bindUniformToTextureUnit(loc_texture, texture, 0); - bindUniformToTextureUnit(loc_normal_and_depths, normal_and_depth, 1); + bindUniformToTextureUnit(loc_texture, texture, 0); + bindUniformToTextureUnit(loc_normal_and_depths, normal_and_depth, 1); - glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(loc_screen, screen[0], screen[1]); - glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); + glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(loc_screen, screen[0], screen[1]); + glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); - glDrawArrays(GL_POINTS, 0, count); - glDisableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); + glEnable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); +} + +void ParticleSystemProxy::render() { + if (getEmitter()->getType() != scene::EPET_POINT) + { + CParticleSystemSceneNode::render(); + return; + } + simulate(); + draw(); + // We need to force irrlicht to update its internal states + irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); + drv->setMaterial(getMaterial(0)); + static_cast(drv)->setRenderStates3DMode(); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 379745752..470289028 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -5,7 +5,9 @@ #define GL_GLEXT_PROTOTYPES 1 #endif #include "graphics/glwrap.hpp" +#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h" #include +#include void initGL(); GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); @@ -21,8 +23,36 @@ protected: virtual void draw() = 0; public: GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex); + virtual void GPUParticle::render(); + virtual void GPUParticle::OnRegisterSceneNode(); +}; + +class ParticleSystemProxy : public scene::CParticleSystemSceneNode { +protected: + GLuint SimulationProgram, RenderProgram; + GLuint loc_duration, loc_sourcematrix, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; + GLuint loc_position, loc_velocity, loc_lifetime; + GLuint tfb_buffers[2]; + GLuint texture, normal_and_depth; + unsigned duration, count; + + virtual void simulate(); + virtual void draw(); +public: + static IParticleSystemSceneNode *addParticleNode( + bool withDefaultEmitter = true, ISceneNode* parent = 0, s32 id = -1, + const core::vector3df& position = core::vector3df(0, 0, 0), + const core::vector3df& rotation = core::vector3df(0, 0, 0), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); + + ParticleSystemProxy(bool createDefaultEmitter, + ISceneNode* parent, scene::ISceneManager* mgr, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale); + + virtual void setEmitter(scene::IParticleEmitter* emitter); virtual void render(); - virtual void OnRegisterSceneNode(); }; class PointEmitter : public GPUParticle diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index f54e361c8..b2937676d 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -233,7 +233,6 @@ ParticleEmitter::ParticleEmitter(const ParticleKind* type, m_particle_type = NULL; m_parent = parent; m_emission_decay_rate = 0; - PE = 0; setParticleType(type); assert(m_node != NULL); @@ -248,8 +247,6 @@ ParticleEmitter::~ParticleEmitter() assert(m_magic_number == 0x58781325); if (m_node != NULL) irr_driver->removeNode(m_node); - if (PE) - irr_driver->removeNode(PE); m_emitter->drop(); m_magic_number = 0xDEADBEEF; @@ -373,7 +370,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) } else { - m_node = irr_driver->addParticleNode(); + m_node = ParticleSystemProxy::addParticleNode(); } if (m_parent != NULL) @@ -440,24 +437,11 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) case EMITTER_POINT: { m_emitter = m_node->createPointEmitter(velocity, -#ifdef GPUPARTICLE - 0., 0., -#else type->getMinRate(), type->getMaxRate(), -#endif type->getMinColor(), type->getMaxColor(), lifeTimeMin, lifeTimeMax, m_particle_type->getAngleSpread() /* angle */ ); -#ifdef GPUPARTICLE - PE = new PointEmitter(m_node->getParent(), irr_driver->getSceneManager(), m_node->getMaterial(0).getTexture(0), - velocity, - type->getMinRate(), type->getMaxRate(), - type->getMinColor(), type->getMaxColor(), - lifeTimeMin, lifeTimeMax, - m_particle_type->getAngleSpread()); - PE->set_m_node(m_node); -#endif break; } diff --git a/src/graphics/particle_emitter.hpp b/src/graphics/particle_emitter.hpp index 55e43dc76..8c3dd941a 100644 --- a/src/graphics/particle_emitter.hpp +++ b/src/graphics/particle_emitter.hpp @@ -49,7 +49,6 @@ private: /** Irrlicht's particle systems. */ scene::IParticleSystemSceneNode *m_node; - class PointEmitter *PE; Vec3 m_position; From 392f63d1a18ffcfd7877e7d445af39071267e1cd Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 30 Dec 2013 23:00:59 +0000 Subject: [PATCH 087/412] More work for library nodes. Remove some code that hardcoded search paths, let's just use our file manager for that, it does it right and easier git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14843 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 50 +++++++++++++++++++----- src/tracks/track.hpp | 3 +- src/tracks/track_object_presentation.cpp | 34 +++++----------- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 6bbc34fff..893828c87 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1513,7 +1513,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) loadMainTrack(*root); unsigned int main_track_count = m_all_nodes.size(); - loadObjects(root, path); + loadObjects(root, path, true); // ---- Fog // It's important to execute this BEFORE the code that creates the skycube, @@ -1665,11 +1665,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) //----------------------------------------------------------------------------- -void Track::loadObjects(const XMLNode* root, const std::string& path) +void Track::loadObjects(const XMLNode* root, const std::string& path, + bool create_lod_definitions) { LodNodeLoader lod_loader; unsigned int start_position_counter = 0; + std::map library_nodes; + unsigned int node_count = root->getNumNodes(); for (unsigned int i = 0; i < node_count; i++) { @@ -1680,22 +1683,51 @@ void Track::loadObjects(const XMLNode* root, const std::string& path) if (name == "track" || name == "default-start") continue; if (name == "object") { - lod_loader.check(node); + bool is_instance = false; + node->get("lod_instance", &is_instance); + + float lod_distance = -1; + node->get("lod_distance", &lod_distance); + + if (lod_distance > 0.0f && !is_instance) + { + // lod definition + if (create_lod_definitions) + lod_loader.check(node); + } + else + { + lod_loader.check(node); + } m_track_object_manager->add(*node); } else if (name == "library") { std::string name; node->get("name", &name); - std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml"); + + XMLNode* libroot; std::string lib_path = file_manager->getAsset("library/" + name); - XMLNode *libroot = file_manager->createXMLTree(lib_node_path); - if (libroot == NULL) continue; + bool create_lod_definitions = true; + + if (library_nodes.find(name) == library_nodes.end()) + { + std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml"); + libroot = file_manager->createXMLTree(lib_node_path); + if (libroot == NULL) continue; + } + else + { + libroot = library_nodes[name]; + create_lod_definitions = false; // LOD definitions are already created, don't create them again + } + + library_nodes[name] = libroot; file_manager->pushTextureSearchPath(lib_path + "/"); file_manager->pushModelSearchPath (lib_path); - loadObjects(libroot, lib_path); + loadObjects(libroot, lib_path, create_lod_definitions); file_manager->popTextureSearchPath(); file_manager->popModelSearchPath(); @@ -1822,13 +1854,13 @@ void Track::loadObjects(const XMLNode* root, const std::string& path) const XMLNode* track_node = root->getNode("track"); if (track_node != NULL) { - for(unsigned int i=0; igetNumNodes(); i++) + for (unsigned int i=0; igetNumNodes(); i++) { const XMLNode* n = track_node->getNode(i); bool is_instance = false; n->get("lod_instance", &is_instance); - if (!is_instance) lod_loader.check(n); + if (!is_instance && create_lod_definitions) lod_loader.check(n); } } diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index d6c1558ed..1e2a7d6b3 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -399,7 +399,8 @@ private: std::vector& m_music ); void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); - void loadObjects(const XMLNode* root, const std::string& path); + void loadObjects(const XMLNode* root, const std::string& path, + bool create_lod_definitions); public: diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 1fbaf0343..8b1eb2534 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -160,41 +160,25 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node m_is_in_skybox = true; } - std::string full_path = - World::getWorld()->getTrack()->getTrackFile(model_name); + //std::string full_path = + // World::getWorld()->getTrack()->getTrackFile(model_name); bool animated = (UserConfigParams::m_graphical_effects || World::getWorld()->getIdent() == IDENT_CUSTSCENE); - if (file_manager->fileExists(full_path)) + if (animated) { - if (animated) - { - m_mesh = irr_driver->getAnimatedMesh(full_path); - } - else - { - m_mesh = irr_driver->getMesh(full_path); - } + m_mesh = irr_driver->getAnimatedMesh(model_name); + } + else + { + m_mesh = irr_driver->getMesh(model_name); } if (!m_mesh) { - // If the model isn't found in the track directory, look - // in STK's model directory. - full_path = file_manager->getAsset(FileManager::MODEL,model_name); - m_mesh = irr_driver->getAnimatedMesh(full_path); - - if (!m_mesh) - { - m_mesh = irr_driver->getAnimatedMesh(model_name); - - if (!m_mesh) - { - throw std::runtime_error("Model '" + model_name + "' cannot be found"); - } - } + throw std::runtime_error("Model '" + model_name + "' cannot be found"); } init(&xml_node, enabled); From 0829c150ca0001883bdb82d22c9c44326588192e Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 30 Dec 2013 23:10:43 +0000 Subject: [PATCH 088/412] Simplify code to use the file manager instead of hardcoding paths git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14844 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/lod_node_loader.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index 0de17f1fb..10abbca2d 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -151,20 +151,14 @@ void LodNodeLoader::done(Track* track, lod_node->updateAbsolutePosition(); for (unsigned int m=0; mgetMesh(full_path); - if (!a_mesh) - { - a_mesh = irr_driver->getMesh(group[m].second.m_model_file); + scene::IMesh* a_mesh = irr_driver->getMesh(group[m].second.m_model_file); - if (!a_mesh) - { - Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", - full_path.c_str()); - continue; - } + if (!a_mesh) + { + Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", + full_path.c_str()); + continue; } if (group[m].second.m_tangent) @@ -181,9 +175,6 @@ void LodNodeLoader::done(Track* track, cache.push_back(a_mesh); irr_driver->grabAllTextures(a_mesh); scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh); - //scene_node->setPosition(xyz); - //scene_node->setRotation(hpr); - //scene_node->setScale(scale); track->handleAnimatedTextures( scene_node, *group[m].second.m_xml ); From e7a355c38effe590abf6ada062e412971c26bc7a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 31 Dec 2013 00:06:08 +0000 Subject: [PATCH 089/412] GPUParticle: Use a fake material to avoid Irrlicht to bypass material update. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14845 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 42b64da53..632515e28 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -236,6 +236,8 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) CParticleSystemSceneNode::setEmitter(emitter); if (emitter->getType() != scene::EPET_POINT) return; + // Pass a fake material type to force irrlicht to update its internal states on rendering + setMaterialType(irr_driver->getShader(ES_RAIN)); setAutomaticCulling(0); initGL(); count = emitter->getMaxParticlesPerSecond(); From e2dc4d98df164a1f88a45b361ac9dafcbfec755f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 31 Dec 2013 00:18:31 +0000 Subject: [PATCH 090/412] GPUParticle: Fix typo in header file. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14846 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 470289028..cf4ab3e74 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -23,8 +23,8 @@ protected: virtual void draw() = 0; public: GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex); - virtual void GPUParticle::render(); - virtual void GPUParticle::OnRegisterSceneNode(); + virtual void render(); + virtual void OnRegisterSceneNode(); }; class ParticleSystemProxy : public scene::CParticleSystemSceneNode { From 43f4d1cdfbe19a0a44b0ba12b36cc43b88b12999 Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 00:24:07 +0000 Subject: [PATCH 091/412] Update track objects with the ability to have a parent, getting us one step closer to the library git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14847 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/irr_driver.cpp | 6 ++-- src/graphics/irr_driver.hpp | 2 +- src/graphics/light.cpp | 4 +-- src/graphics/light.hpp | 2 +- src/graphics/sun.cpp | 5 ++-- src/graphics/sun.hpp | 2 +- src/tracks/lod_node_loader.cpp | 5 ++-- src/tracks/lod_node_loader.hpp | 2 ++ src/tracks/track.cpp | 30 +++++++++++++------ src/tracks/track.hpp | 2 +- src/tracks/track_object.cpp | 17 ++++++----- src/tracks/track_object.hpp | 4 +-- src/tracks/track_object_manager.cpp | 8 ++--- src/tracks/track_object_manager.hpp | 4 +-- src/tracks/track_object_presentation.cpp | 37 ++++++++++++------------ src/tracks/track_object_presentation.hpp | 12 ++++---- 16 files changed, 78 insertions(+), 64 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index f67b5fea0..b9b0a43d5 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2111,16 +2111,16 @@ void IrrDriver::applyObjectPassShader() } scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, - float energy, float r, float g, float b, bool sun) + float energy, float r, float g, float b, bool sun, scene::ISceneNode* parent) { if (m_glsl) { LightNode *light = NULL; if (!sun) - light = new LightNode(m_scene_manager, radius, energy, r, g, b); + light = new LightNode(m_scene_manager, parent, radius, energy, r, g, b); else - light = new SunNode(m_scene_manager, r, g, b); + light = new SunNode(m_scene_manager, parent, r, g, b); light->grab(); light->setParent(NULL); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 953c18100..88b7c4dc4 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -457,7 +457,7 @@ public: void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false); // ------------------------------------------------------------------------ scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float energy = 1., float r = 1.0f, - float g = 1.0f, float b = 1.0f, bool sun = false); + float g = 1.0f, float b = 1.0f, bool sun = false, scene::ISceneNode* parent = NULL); // ------------------------------------------------------------------------ void clearLights(); // ------------------------------------------------------------------------ diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 105c760e5..46f8de22e 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -34,8 +34,8 @@ using namespace core; aabbox3df LightNode::box; -LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b): - ISceneNode(mgr->getRootSceneNode(), mgr, -1) +LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float e, float r, float g, float b): + ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1) { m_energy = e; m_energy_multiplier = 1.0f; diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 542aa23f5..29de481da 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -34,7 +34,7 @@ namespace irr class LightNode: public scene::ISceneNode { public: - LightNode(scene::ISceneManager* mgr, float radius, float energy, float r, float g, float b); + LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float energy, float r, float g, float b); virtual ~LightNode(); virtual void render() OVERRIDE; diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index cd3dc3cf7..91ebb5ad4 100644 --- a/src/graphics/sun.cpp +++ b/src/graphics/sun.cpp @@ -34,10 +34,9 @@ using namespace video; using namespace scene; using namespace core; -SunNode::SunNode(scene::ISceneManager* mgr, float r, float g, float b): - LightNode(mgr, 10000, 0., r, g, b) +SunNode::SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b): + LightNode(mgr, parent, 10000, 0., r, g, b) { - sq = new ScreenQuad(irr_driver->getVideoDriver()); SMaterial &m = sq->getMaterial(); diff --git a/src/graphics/sun.hpp b/src/graphics/sun.hpp index 62052ca14..ff719084c 100644 --- a/src/graphics/sun.hpp +++ b/src/graphics/sun.hpp @@ -28,7 +28,7 @@ class ScreenQuad; class SunNode: public LightNode { public: - SunNode(scene::ISceneManager* mgr, float r, float g, float b); + SunNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float r, float g, float b); virtual ~SunNode(); virtual void render() OVERRIDE; diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index 10abbca2d..f64a49866 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -88,10 +88,11 @@ bool LodNodeLoader::check(const XMLNode* xml) void LodNodeLoader::done(Track* track, std::string directory, std::vector& cache, + scene::ISceneNode* parent, std::vector& out) { scene::ISceneManager* sm = irr_driver->getSceneManager(); - scene::ISceneNode* sroot = sm->getRootSceneNode(); + if (parent == NULL) parent = sm->getRootSceneNode(); // Creating LOD nodes is more complicated than one might have hoped, on the C++ side; // but it was done this way to minimize the work needed on the side of the artists @@ -144,7 +145,7 @@ void LodNodeLoader::done(Track* track, if (group.size() > 0) { - LODNode* lod_node = new LODNode(groupname, sroot, sm); + LODNode* lod_node = new LODNode(groupname, parent, sm); lod_node->setPosition(xyz); lod_node->setRotation(hpr); lod_node->setScale(scale); diff --git a/src/tracks/lod_node_loader.hpp b/src/tracks/lod_node_loader.hpp index 3da7b9eca..293dc1669 100644 --- a/src/tracks/lod_node_loader.hpp +++ b/src/tracks/lod_node_loader.hpp @@ -32,6 +32,7 @@ namespace irr namespace scene { class IMesh; + class ISceneNode; } } @@ -76,6 +77,7 @@ public: void done(Track* track, std::string directory, std::vector& cache, + scene::ISceneNode* parent, std::vector& out); void clear(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 893828c87..0699e9a92 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1183,7 +1183,7 @@ bool Track::loadMainTrack(const XMLNode &root) // Create LOD nodes std::vector lod_nodes; - lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes); + lodLoader.done(this, m_root, m_all_cached_meshes, NULL, lod_nodes); for (unsigned int n=0; nadd(*node); + m_track_object_manager->add(*node, parent); } else if (name == "library") { std::string name; node->get("name", &name); + core::vector3df xyz; + node->get("xyz", &xyz); + XMLNode* libroot; std::string lib_path = file_manager->getAsset("library/" + name); bool create_lod_definitions = true; @@ -1727,7 +1730,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, file_manager->pushTextureSearchPath(lib_path + "/"); file_manager->pushModelSearchPath (lib_path); - loadObjects(libroot, lib_path, create_lod_definitions); + scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode(); + parent->setPosition(xyz); + parent->updateAbsolutePosition(); + loadObjects(libroot, lib_path, create_lod_definitions, parent); file_manager->popTextureSearchPath(); file_manager->popModelSearchPath(); @@ -1774,7 +1780,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, { if (UserConfigParams::m_graphical_effects) { - m_track_object_manager->add(*node); + m_track_object_manager->add(*node, parent); } } else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") @@ -1787,7 +1793,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, } else if (name == "light") { - m_track_object_manager->add(*node); + m_track_object_manager->add(*node, parent); } else if (name == "weather") { @@ -1866,13 +1872,19 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, std::vector lod_nodes; std::vector devnull; - lod_loader.done(this, m_root, devnull, lod_nodes); + lod_loader.done(this, m_root, devnull, parent, lod_nodes); - m_track_object_manager->assingLodNodes(lod_nodes); + m_track_object_manager->assingLodNodes(lod_nodes, parent); // --------------------------------------------- // Init all track objects m_track_object_manager->init(); + + for (std::map::iterator it = library_nodes.begin(); + it != library_nodes.end(); it++) + { + delete it->second; + } } //----------------------------------------------------------------------------- diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 1e2a7d6b3..e1591b8f1 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -400,7 +400,7 @@ private: void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); void loadObjects(const XMLNode* root, const std::string& path, - bool create_lod_definitions); + bool create_lod_definitions, scene::ISceneNode* parent); public: diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 0bf6e79cf..f10c47366 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -38,9 +38,9 @@ * model, enable/disable status, timer information. * \param lod_node Lod node (defaults to NULL). */ -TrackObject::TrackObject(const XMLNode &xml_node, LODNode* lod_node) +TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) { - init(xml_node, lod_node); + init(xml_node, parent, lod_node); } // ---------------------------------------------------------------------------- @@ -79,7 +79,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, // ---------------------------------------------------------------------------- -void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) +void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) { m_init_xyz = core::vector3df(0,0,0); m_init_hpr = core::vector3df(0,0,0); @@ -114,19 +114,19 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) if (xml_node.getName() == "particle-emitter") { m_type = "particle-emitter"; - m_presentation = new TrackObjectPresentationParticles(xml_node); + m_presentation = new TrackObjectPresentationParticles(xml_node, parent); } else if (xml_node.getName() == "light") { m_type = "light"; - m_presentation = new TrackObjectPresentationLight(xml_node); + m_presentation = new TrackObjectPresentationLight(xml_node, parent); } else if (type == "sfx-emitter") { // FIXME: at this time sound emitters are just disabled in multiplayer // otherwise the sounds would be constantly heard if (race_manager->getNumLocalPlayers() < 2) - m_presentation = new TrackObjectPresentationSound(xml_node); + m_presentation = new TrackObjectPresentationSound(xml_node, parent); } else if (type == "action-trigger") { @@ -142,7 +142,7 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) } else if (type == "billboard") { - m_presentation = new TrackObjectPresentationBillboard(xml_node); + m_presentation = new TrackObjectPresentationBillboard(xml_node, parent); } else if (type=="cutscene_camera") { @@ -163,7 +163,8 @@ void TrackObject::init(const XMLNode &xml_node, LODNode* lod_node) { m_type = "mesh"; m_presentation = new TrackObjectPresentationMesh(xml_node, - m_enabled); + m_enabled, + parent); glownode = ((TrackObjectPresentationMesh *) m_presentation)->getNode(); } diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 3d8bd52d2..8c41bbd73 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -82,10 +82,10 @@ protected: ThreeDAnimation* m_animator; - void init(const XMLNode &xml_node, LODNode* lodNode); + void init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode); public: - TrackObject(const XMLNode &xml_node, LODNode* lodNode=NULL); + TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode=NULL); TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index 6ff5c5e5f..ffb876b13 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -45,7 +45,7 @@ TrackObjectManager::~TrackObjectManager() * TrackObjectManager::assingLodNodes after everything is loaded * to finalize their creation. */ -void TrackObjectManager::add(const XMLNode &xml_node) +void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) { try { @@ -59,7 +59,7 @@ void TrackObjectManager::add(const XMLNode &xml_node) } else { - m_all_objects.push_back(new TrackObject(xml_node)); + m_all_objects.push_back(new TrackObject(xml_node, parent)); } } catch (std::exception& e) @@ -218,7 +218,7 @@ void TrackObjectManager::removeObject(TrackObject* obj) * * \param lod_nodes the LOD nodes created by the LodNodeLoader. */ -void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes) +void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes, scene::ISceneNode* parent) { for (unsigned int n=0; n& lod_nodes) assert( queue.size() > 0 ); const XMLNode* xml = queue[ queue.size() - 1 ]; - TrackObject* obj = new TrackObject(*xml, lod_nodes[n]); + TrackObject* obj = new TrackObject(*xml, parent, lod_nodes[n]); queue.erase( queue.end() - 1 ); m_all_objects.push_back(obj); diff --git a/src/tracks/track_object_manager.hpp b/src/tracks/track_object_manager.hpp index eba7b9300..99a2ae289 100644 --- a/src/tracks/track_object_manager.hpp +++ b/src/tracks/track_object_manager.hpp @@ -54,7 +54,7 @@ protected: public: TrackObjectManager(); ~TrackObjectManager(); - void add(const XMLNode &xml_node); + void add(const XMLNode &xml_node, scene::ISceneNode* parent); void update(float dt); void handleExplosion(const Vec3 &pos, const PhysicalObject *mp, bool secondary_hits=true); @@ -68,7 +68,7 @@ public: void removeObject(TrackObject* who); - void assingLodNodes(const std::vector& lod); + void assingLodNodes(const std::vector& lod, scene::ISceneNode* parent); PtrVector& getObjects() { return m_all_objects; } const PtrVector& getObjects() const { return m_all_objects; } diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 8b1eb2534..3e23509b2 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -140,7 +140,8 @@ TrackObjectPresentationLOD::~TrackObjectPresentationLOD() } // ---------------------------------------------------------------------------- -TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled) : +TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, + bool enabled, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { m_is_looped = false; @@ -181,7 +182,7 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node throw std::runtime_error("Model '" + model_name + "' cannot be found"); } - init(&xml_node, enabled); + init(&xml_node, parent, enabled); } TrackObjectPresentationMesh::TrackObjectPresentationMesh( @@ -213,10 +214,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh( throw std::runtime_error("Model '" + model_file + "' cannot be found"); } - init(NULL, true); + init(NULL, NULL, true); } -void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) +void TrackObjectPresentationMesh::init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled) { bool animated = (UserConfigParams::m_graphical_effects || World::getWorld()->getIdent() == IDENT_CUSTSCENE); @@ -239,7 +240,7 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) else if (animated) { scene::IAnimatedMeshSceneNode *node = - irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_mesh); + irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_mesh, parent); m_node = node; m_frame_start = node->getStartFrame(); @@ -252,7 +253,7 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, bool enabled) } else { - m_node = irr_driver->addMesh(m_mesh); + m_node = irr_driver->addMesh(m_mesh, parent); m_frame_start = 0; m_frame_end = 0; } @@ -311,9 +312,11 @@ void TrackObjectPresentationMesh::reset() // ---------------------------------------------------------------------------- -TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node) : +TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentation(xml_node) { + // TODO: respect 'parent' if any + m_sound = NULL; m_xyz = m_init_xyz; @@ -424,7 +427,7 @@ void TrackObjectPresentationSound::move(const core::vector3df& xyz, const core:: // ---------------------------------------------------------------------------- -TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node) : +TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { std::string texture_name; @@ -452,7 +455,7 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode { Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found", texture_name.c_str()); } - m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture); + m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture, parent); Material *stk_material = material_manager->getMaterial(texture_name); stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL); @@ -492,7 +495,7 @@ TrackObjectPresentationBillboard::~TrackObjectPresentationBillboard() // ---------------------------------------------------------------------------- -TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode& xml_node) : +TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { m_emitter = NULL; @@ -500,10 +503,7 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode std::string path; xml_node.get("kind", &path); - - //irr::core::vector3df emitter_origin; - //xml_node.getXYZ(&emitter_origin); - + int clip_distance = -1; xml_node.get("clip_distance", &clip_distance); @@ -516,16 +516,15 @@ TrackObjectPresentationParticles::TrackObjectPresentationParticles(const XMLNode { throw std::runtime_error(path + " could not be loaded"); } - ParticleEmitter* emitter = new ParticleEmitter( kind, m_init_xyz ); + ParticleEmitter* emitter = new ParticleEmitter(kind, m_init_xyz, parent); if (clip_distance > 0) { scene::ISceneManager* sm = irr_driver->getSceneManager(); scene::ISceneNode* sroot = sm->getRootSceneNode(); - LODNode* lod = new LODNode("particles", sroot, sm); + LODNode* lod = new LODNode("particles", parent == NULL ? sroot : parent, sm); lod->add(clip_distance, (scene::ISceneNode*)emitter->getNode(), true); - //m_all_emitters.push_back(emitter); m_node = lod; m_lod_emitter_node = lod; m_emitter = emitter; @@ -579,7 +578,7 @@ void TrackObjectPresentationParticles::triggerParticles() // ---------------------------------------------------------------------------- -TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_node) : +TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_node, scene::ISceneNode* parent) : TrackObjectPresentationSceneNode(xml_node) { xml_node.get("color", &m_color); @@ -593,7 +592,7 @@ TrackObjectPresentationLight::TrackObjectPresentationLight(const XMLNode& xml_no if (irr_driver->isGLSL()) { - m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, colorf.r, colorf.g, colorf.b); + m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, 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 eb077ecac..a4d64c457 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -174,10 +174,10 @@ private: /** End frame of the animation to be played. */ unsigned int m_frame_end; - void init(const XMLNode* xml_node, bool enabled); + void init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled); public: - TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled); + TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled, scene::ISceneNode* parent); TrackObjectPresentationMesh( const std::string& model_file, const core::vector3df& xyz, @@ -207,7 +207,7 @@ private: public: - TrackObjectPresentationSound(const XMLNode& xml_node); + TrackObjectPresentationSound(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationSound(); virtual void onTriggerItemApproached(Item* who) OVERRIDE; virtual void update(float dt) OVERRIDE; @@ -235,7 +235,7 @@ class TrackObjectPresentationBillboard : public TrackObjectPresentationSceneNode float m_fade_out_start; float m_fade_out_end; public: - TrackObjectPresentationBillboard(const XMLNode& xml_node); + TrackObjectPresentationBillboard(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationBillboard(); virtual void update(float dt) OVERRIDE; }; @@ -253,7 +253,7 @@ private: std::string m_trigger_condition; public: - TrackObjectPresentationParticles(const XMLNode& xml_node); + TrackObjectPresentationParticles(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationParticles(); virtual void update(float dt) OVERRIDE; @@ -275,7 +275,7 @@ private: float m_energy; public: - TrackObjectPresentationLight(const XMLNode& xml_node); + TrackObjectPresentationLight(const XMLNode& xml_node, scene::ISceneNode* parent); virtual ~TrackObjectPresentationLight(); }; From 8670aa86dc4c765175f7f9182f2feac1fdd28d60 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 31 Dec 2013 00:58:42 +0000 Subject: [PATCH 092/412] GPUParticle: Fix some parameters not used correctly. Some previous value (like dt) came from debug attempt. This fixes the particles behind the wheels of the wagon in minel. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14848 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 4 ++-- src/graphics/gpuparticles.cpp | 19 +++++++++++++++---- src/graphics/gpuparticles.h | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index ef3581224..d1d6353d8 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -14,8 +14,8 @@ out vec4 new_particle_velocity; void main(void) { vec4 initialposition = sourcematrix * vec4(0., 0., 0., 1.0); - new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; - new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration); + new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz - particle_velocity.xyz * lifetime; + new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration) - lifetime; new_particle_velocity = particle_velocity; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 632515e28..90ce099ff 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -239,10 +239,10 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) // Pass a fake material type to force irrlicht to update its internal states on rendering setMaterialType(irr_driver->getShader(ES_RAIN)); setAutomaticCulling(0); + LastEmitTime = 0; initGL(); - count = emitter->getMaxParticlesPerSecond(); duration = emitter->getMaxLifeTime(); - float initial_lifetime_incr = 1000.; + count = emitter->getMaxParticlesPerSecond() * duration / 1000; const char *varyings[] = { "new_particle_position", "new_lifetime", @@ -258,7 +258,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); - printf("count:%d\nduration:%d\ninitial_lifetine:%f\n", count, duration, initial_lifetime_incr); + printf("count:%d\nduration:%d\n", count, duration); RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); @@ -293,6 +293,17 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) void ParticleSystemProxy::simulate() { + unsigned time = os::Timer::getTime(); + if (LastEmitTime == 0) + { + LastEmitTime = time; + return; + } + + u32 now = time; + u32 timediff = time - LastEmitTime; + LastEmitTime = time; + core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(SimulationProgram); glEnable(GL_RASTERIZER_DISCARD); @@ -305,7 +316,7 @@ void ParticleSystemProxy::simulate() glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); - glUniform1i(loc_dt, 1); + glUniform1i(loc_dt, timediff); glUniform1i(loc_duration, duration); glUniformMatrix4fv(loc_sourcematrix, 1, GL_FALSE, matrix.pointer()); glBeginTransformFeedback(GL_POINTS); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index cf4ab3e74..9adb8762b 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -34,7 +34,7 @@ protected: GLuint loc_position, loc_velocity, loc_lifetime; GLuint tfb_buffers[2]; GLuint texture, normal_and_depth; - unsigned duration, count; + unsigned duration, count, LastEmitTime; virtual void simulate(); virtual void draw(); From d5e598f7f63cd3b7aed263c51cbd3ab9ef41aa52 Mon Sep 17 00:00:00 2001 From: samuncle Date: Tue, 31 Dec 2013 01:03:46 +0000 Subject: [PATCH 093/412] I had some problem with -fno-rtti when I tried to build then trunk git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14849 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- lib/irrlicht/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/irrlicht/CMakeLists.txt b/lib/irrlicht/CMakeLists.txt index 0172ccb73..1fed7ea4b 100644 --- a/lib/irrlicht/CMakeLists.txt +++ b/lib/irrlicht/CMakeLists.txt @@ -17,8 +17,8 @@ if(MSVC) add_definitions(/D_IRR_STATIC_LIB_) add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff else() - set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fno-rtti -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fno-rtti -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include") + set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pipe -O3 -fno-exceptions -fstrict-aliasing -fexpensive-optimizations -I/usr/X11R6/include") endif() set(IRRLICHT_SOURCES From 9417541adf006a99a72bdebf22f40f3cd969312a Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 31 Dec 2013 09:30:41 +0000 Subject: [PATCH 095/412] Uodated list of dependencies. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14851 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- INSTALL | 2 ++ 1 file changed, 2 insertions(+) diff --git a/INSTALL b/INSTALL index 3c7f3df31..b6a196efb 100644 --- a/INSTALL +++ b/INSTALL @@ -10,6 +10,8 @@ First, make sure that you have the following packages installed: * OpenAL (recommended: openal-soft-devel) * Ogg (libogg-dev) * Vorbis (libvorbis-dev) + * libcurl (libcurl-devel) + * libbluetooth (bluez-devel) * fribidi (fribidi-devel) - optional for right-to-left text Unpack the files from the tarball like this: From 9fbd2b19b156350ee8f91906dc66b4d439d0474b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 31 Dec 2013 17:25:10 +0000 Subject: [PATCH 096/412] GPUParticle: Implements generic fade out and rework particles lifetime. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14852 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 26 ++++---- data/shaders/particle.vert | 5 ++ data/shaders/pointemitter.vert | 12 ++-- src/graphics/gpuparticles.cpp | 110 +++++++++++++++++++++------------ src/graphics/gpuparticles.h | 14 +++-- 5 files changed, 109 insertions(+), 58 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index 6b14ed7b1..cb5febfad 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -1,21 +1,23 @@ #version 130 uniform sampler2D texture; -uniform sampler2D normals_and_depth; -uniform mat4 invproj; +uniform sampler2D normals_and_depth; +uniform mat4 invproj; uniform vec2 screen; + +in float lf; out vec4 color; void main(void) { - vec2 xy = gl_FragCoord.xy / screen; - float FragZ = gl_FragCoord.z; - float EnvZ = texture2D(normals_and_depth, xy).a; - vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); - FragmentPos /= FragmentPos.w; - vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); - EnvPos /= EnvPos.w; - float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); - float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); + vec2 xy = gl_FragCoord.xy / screen; + float FragZ = gl_FragCoord.z; + float EnvZ = texture2D(normals_and_depth, xy).a; + vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); + FragmentPos /= FragmentPos.w; + vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); + EnvPos /= EnvPos.w; + float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); + float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); color = texture2D(texture, gl_PointCoord.xy); - color.a *= alpha; + color.a *= alpha * (1. - lf); } diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index e3cdb088f..9e5ca50b7 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,9 +1,14 @@ #version 130 uniform mat4 matrix; + in vec3 position; +in float lifetime; + +out float lf; void main(void) { + lf = lifetime; gl_Position = matrix * vec4(position, 1.0); gl_PointSize = 300. / gl_Position.w; } diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index d1d6353d8..fc95a7cb8 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -3,6 +3,10 @@ uniform int dt; uniform mat4 sourcematrix; uniform int duration; +in vec3 particle_position_initial; +in float lifetime_initial; +in vec4 particle_velocity_initial; + in vec3 particle_position; in float lifetime; in vec4 particle_velocity; @@ -13,9 +17,9 @@ out vec4 new_particle_velocity; void main(void) { - vec4 initialposition = sourcematrix * vec4(0., 0., 0., 1.0); - new_particle_position = (lifetime > 0.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz - particle_velocity.xyz * lifetime; - new_lifetime = (lifetime > 0.) ? lifetime - float(dt) : float(duration) - lifetime; - new_particle_velocity = particle_velocity; + vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); + new_particle_position = (lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; + new_lifetime = (lifetime < 1.) ? lifetime + (float(dt)/lifetime_initial) : 0.; + new_particle_velocity = (lifetime < 1.) ? particle_velocity : particle_velocity_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 90ce099ff..a7a1ae0e5 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -252,27 +252,44 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); - loc_duration = glGetUniformLocation(SimulationProgram, "duration"); - loc_dt = glGetUniformLocation(SimulationProgram, "dt"); - loc_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); - loc_position = glGetAttribLocation(SimulationProgram, "particle_position"); - loc_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); - loc_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); - printf("count:%d\nduration:%d\n", count, duration); + + uniform_duration = glGetUniformLocation(SimulationProgram, "duration"); + uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); + uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); + + attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); + attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); + attrib_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); + attrib_initial_position = glGetAttribLocation(SimulationProgram, "particle_position_initial"); + attrib_initial_lifetime = glGetAttribLocation(SimulationProgram, "lifetime_initial"); + attrib_initial_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity_initial"); RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); - loc_matrix = glGetUniformLocation(RenderProgram, "matrix"); - loc_texture = glGetUniformLocation(RenderProgram, "texture"); - loc_invproj = glGetUniformLocation(RenderProgram, "invproj"); - loc_screen = glGetUniformLocation(RenderProgram, "screen"); - loc_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); + attrib_pos = glGetAttribLocation(RenderProgram, "position"); + attrib_lf = glGetAttribLocation(RenderProgram, "lifetime"); + uniform_matrix = glGetUniformLocation(RenderProgram, "matrix"); + uniform_texture = glGetUniformLocation(RenderProgram, "texture"); + uniform_invproj = glGetUniformLocation(RenderProgram, "invproj"); + uniform_screen = glGetUniformLocation(RenderProgram, "screen"); + uniform_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - float *particles = new float[COMPONENTCOUNT * count]; + float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; + unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + + printf("count:%d\nduration_min:%d\nduration_max:%d\n", count, emitter->getMinLifeTime(), emitter->getMaxLifeTime()); for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = 0.; - particles[COMPONENTCOUNT * i + 1] = 0.; - particles[COMPONENTCOUNT * i + 2] = 0.; - particles[COMPONENTCOUNT * i + 3] = rand() % duration; + particles[COMPONENTCOUNT * i] = getAbsolutePosition().X; + particles[COMPONENTCOUNT * i + 1] = getAbsolutePosition().Y; + particles[COMPONENTCOUNT * i + 2] = getAbsolutePosition().Z; + // Initial lifetime is 0 percent + particles[COMPONENTCOUNT * i + 3] = 0.; + + initialvalue[COMPONENTCOUNT * i] = 0.; + initialvalue[COMPONENTCOUNT * i + 1] = 0.; + initialvalue[COMPONENTCOUNT * i + 2] = 0.; + initialvalue[COMPONENTCOUNT * i + 3] = rand() % lifetime_range; + initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); + core::vector3df particledir = emitter->getDirection(); particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); @@ -281,8 +298,13 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) particles[COMPONENTCOUNT * i + 4] = particledir.X; particles[COMPONENTCOUNT * i + 5] = particledir.Y; particles[COMPONENTCOUNT * i + 6] = particledir.Z; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; } glGenBuffers(2, tfb_buffers); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); @@ -307,31 +329,40 @@ void ParticleSystemProxy::simulate() core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(SimulationProgram); glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_lifetime); + glEnableVertexAttribArray(attrib_velocity); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(loc_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); - glVertexAttribPointer(loc_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(loc_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); + glVertexAttribPointer(attrib_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(attrib_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glEnableVertexAttribArray(attrib_initial_position); + glEnableVertexAttribArray(attrib_initial_lifetime); + glEnableVertexAttribArray(attrib_initial_velocity); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glVertexAttribPointer(attrib_initial_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); + glVertexAttribPointer(attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); - glUniform1i(loc_dt, timediff); - glUniform1i(loc_duration, duration); - glUniformMatrix4fv(loc_sourcematrix, 1, GL_FALSE, matrix.pointer()); + glUniform1i(uniform_dt, 16); + glUniform1i(uniform_duration, duration); + glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); + glDisableVertexAttribArray(attrib_position); + glDisableVertexAttribArray(attrib_lifetime); + glDisableVertexAttribArray(attrib_velocity); + glDisableVertexAttribArray(attrib_initial_position); + glDisableVertexAttribArray(attrib_initial_lifetime); + glDisableVertexAttribArray(attrib_initial_velocity); glDisable(GL_RASTERIZER_DISCARD); std::swap(tfb_buffers[0], tfb_buffers[1]); } void ParticleSystemProxy::draw() { - glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); @@ -341,6 +372,8 @@ void ParticleSystemProxy::draw() glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glUseProgram(RenderProgram); + glEnableVertexAttribArray(attrib_pos); + glEnableVertexAttribArray(attrib_lf); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); float screen[2] = { @@ -350,20 +383,21 @@ void ParticleSystemProxy::draw() irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); invproj.makeInverse(); - bindUniformToTextureUnit(loc_texture, texture, 0); - bindUniformToTextureUnit(loc_normal_and_depths, normal_and_depth, 1); + bindUniformToTextureUnit(uniform_texture, texture, 0); + bindUniformToTextureUnit(uniform_normal_and_depths, normal_and_depth, 1); - glUniformMatrix4fv(loc_invproj, 1, GL_FALSE, invproj.pointer()); - glUniform2f(loc_screen, screen[0], screen[1]); - glUniformMatrix4fv(loc_matrix, 1, GL_FALSE, matrix.pointer()); + glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, invproj.pointer()); + glUniform2f(uniform_screen, screen[0], screen[1]); + glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, matrix.pointer()); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); + glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); + glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *) (3 * sizeof(float))); glDrawArrays(GL_POINTS, 0, count); - glDisableVertexAttribArray(0); + glDisableVertexAttribArray(attrib_pos); + glDisableVertexAttribArray(attrib_lf); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); } diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 9adb8762b..22528f2c6 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,10 +29,16 @@ public: class ParticleSystemProxy : public scene::CParticleSystemSceneNode { protected: - GLuint SimulationProgram, RenderProgram; - GLuint loc_duration, loc_sourcematrix, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; - GLuint loc_position, loc_velocity, loc_lifetime; - GLuint tfb_buffers[2]; + GLuint tfb_buffers[2], initial_values_buffer; + + GLuint SimulationProgram; + GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime; + GLuint uniform_duration, uniform_sourcematrix, uniform_dt; + + GLuint RenderProgram; + GLuint attrib_pos, attrib_lf; + GLuint uniform_matrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + GLuint texture, normal_and_depth; unsigned duration, count, LastEmitTime; From 3cdf3409bf688948ed2315db900e2195b3849d3b Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 18:09:13 +0000 Subject: [PATCH 097/412] Refactor LOD to allow parenting git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14853 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/lod_node_loader.cpp | 17 ++--- src/tracks/lod_node_loader.hpp | 24 +++++- src/tracks/track.cpp | 110 +++++++++++++++------------- src/tracks/track.hpp | 6 +- src/tracks/track_object_manager.cpp | 4 +- src/tracks/track_object_manager.hpp | 2 +- 6 files changed, 93 insertions(+), 70 deletions(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index f64a49866..abdcca639 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -43,7 +43,7 @@ bool PairCompare(const std::pair& i, const std::pairget("lod_distance", &lod_distance); @@ -61,7 +61,7 @@ bool LodNodeLoader::check(const XMLNode* xml) { if (lod_instance) { - lod_instances[lodgroup].push_back(xml); + lod_instances[lodgroup].push_back(LodInstance(xml, parent)); } else { @@ -88,11 +88,9 @@ bool LodNodeLoader::check(const XMLNode* xml) void LodNodeLoader::done(Track* track, std::string directory, std::vector& cache, - scene::ISceneNode* parent, std::vector& out) { scene::ISceneManager* sm = irr_driver->getSceneManager(); - if (parent == NULL) parent = sm->getRootSceneNode(); // Creating LOD nodes is more complicated than one might have hoped, on the C++ side; // but it was done this way to minimize the work needed on the side of the artists @@ -120,15 +118,15 @@ void LodNodeLoader::done(Track* track, // 2. Read the XML nodes and instanciate LOD scene nodes where relevant std::string groupname; - std::map< std::string, std::vector< const XMLNode* > >::iterator it3; + std::map< std::string, std::vector< LodInstance > >::iterator it3; for (it3 = lod_instances.begin(); it3 != lod_instances.end(); it3++) { std::vector< std::pair >& group = sorted_lod_groups[it3->first]; - std::vector< const XMLNode* >& v = it3->second; + std::vector< LodInstance >& v = it3->second; for (unsigned int n=0; nget("lod_group", &groupname); @@ -141,10 +139,9 @@ void LodNodeLoader::done(Track* track, core::vector3df scale(1.0f, 1.0f, 1.0f); node->get("scale", &scale); - std::string full_path; - if (group.size() > 0) { + scene::ISceneNode* parent = (v[n].m_parent == NULL ? sm->getRootSceneNode() : v[n].m_parent); LODNode* lod_node = new LODNode(groupname, parent, sm); lod_node->setPosition(xyz); lod_node->setRotation(hpr); @@ -158,7 +155,7 @@ void LodNodeLoader::done(Track* track, if (!a_mesh) { Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", - full_path.c_str()); + group[m].second.m_model_file.c_str()); continue; } diff --git a/src/tracks/lod_node_loader.hpp b/src/tracks/lod_node_loader.hpp index 293dc1669..d3c551b15 100644 --- a/src/tracks/lod_node_loader.hpp +++ b/src/tracks/lod_node_loader.hpp @@ -36,6 +36,25 @@ namespace irr } } +struct LodInstance +{ + const XMLNode* m_xml_node; + scene::ISceneNode* m_parent; + + /** Constructor to allow storing this in STL containers */ + LodInstance() + { + m_parent = NULL; + m_xml_node = NULL; + } + + LodInstance(const XMLNode* xml_node, scene::ISceneNode* parent) + { + m_xml_node = xml_node; + m_parent = parent; + } +}; + struct LodModel { std::string m_model_file; @@ -68,16 +87,15 @@ class LodNodeLoader { private: std::map< std::string, std::map< int, LodModel > > lod_groups; - std::map< std::string, std::vector< const XMLNode* > > lod_instances; + std::map< std::string, std::vector< LodInstance > > lod_instances; public: LodNodeLoader(); - bool check(const XMLNode* xml); + bool check(const XMLNode* xml, scene::ISceneNode* parent); void done(Track* track, std::string directory, std::vector& cache, - scene::ISceneNode* parent, std::vector& out); void clear(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 0699e9a92..0d105b3eb 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1016,7 +1016,7 @@ bool Track::loadMainTrack(const XMLNode &root) std::string challenge; n->get("challenge", &challenge); - bool is_lod = lodLoader.check(n); + bool is_lod = lodLoader.check(n, NULL); if (tangent) { @@ -1183,7 +1183,7 @@ bool Track::loadMainTrack(const XMLNode &root) // Create LOD nodes std::vector lod_nodes; - lodLoader.done(this, m_root, m_all_cached_meshes, NULL, lod_nodes); + lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes); for (unsigned int n=0; n library_nodes; + loadObjects(root, path, lod_loader, true, NULL, library_nodes); + + // -------- Create and assign LOD nodes -------- + // recheck the static area, we will need LOD info + const XMLNode* track_node = root->getNode("track"); + if (track_node != NULL) + { + for (unsigned int i=0; igetNumNodes(); i++) + { + const XMLNode* n = track_node->getNode(i); + bool is_instance = false; + n->get("lod_instance", &is_instance); + + if (!is_instance) lod_loader.check(n, NULL); + } + } + + std::vector lod_nodes; + std::vector devnull; + lod_loader.done(this, m_root, devnull, lod_nodes); + + m_track_object_manager->assingLodNodes(lod_nodes); + // --------------------------------------------- + + // Cleanup library nodes + for (std::map::iterator it = library_nodes.begin(); + it != library_nodes.end(); it++) + { + delete it->second; + + file_manager->popTextureSearchPath(); + file_manager->popModelSearchPath(); + } + + // Init all track objects + m_track_object_manager->init(); + // ---- Fog // It's important to execute this BEFORE the code that creates the skycube, @@ -1665,14 +1703,12 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) //----------------------------------------------------------------------------- -void Track::loadObjects(const XMLNode* root, const std::string& path, - bool create_lod_definitions, scene::ISceneNode* parent) +void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader, + bool create_lod_definitions, scene::ISceneNode* parent, + std::map& library_nodes) { - LodNodeLoader lod_loader; unsigned int start_position_counter = 0; - std::map library_nodes; - unsigned int node_count = root->getNumNodes(); for (unsigned int i = 0; i < node_count; i++) { @@ -1693,11 +1729,11 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, { // lod definition if (create_lod_definitions) - lod_loader.check(node); + lod_loader.check(node, parent); } else { - lod_loader.check(node); + lod_loader.check(node, parent); } m_track_object_manager->add(*node, parent); } @@ -1715,28 +1751,29 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, if (library_nodes.find(name) == library_nodes.end()) { - std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml"); + std::string node_path = "library/" + name + "/node.xml"; + std::string lib_node_path = file_manager->getAsset(node_path); libroot = file_manager->createXMLTree(lib_node_path); - if (libroot == NULL) continue; + if (libroot == NULL) + { + Log::error("Track", "Cannot find library '%s'", node_path.c_str()); + continue; + } + + file_manager->pushTextureSearchPath(lib_path + "/"); + file_manager->pushModelSearchPath (lib_path); + library_nodes[name] = libroot; } else { libroot = library_nodes[name]; create_lod_definitions = false; // LOD definitions are already created, don't create them again } - - library_nodes[name] = libroot; - - file_manager->pushTextureSearchPath(lib_path + "/"); - file_manager->pushModelSearchPath (lib_path); scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode(); parent->setPosition(xyz); parent->updateAbsolutePosition(); - loadObjects(libroot, lib_path, create_lod_definitions, parent); - - file_manager->popTextureSearchPath(); - file_manager->popModelSearchPath(); + loadObjects(libroot, lib_path, lod_loader, create_lod_definitions, parent, library_nodes); } else if (name == "water") { @@ -1854,37 +1891,6 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, } } // for igetNumNodes() - - // -------- Create and assign LOD nodes -------- - // recheck the static area, we will need LOD info - const XMLNode* track_node = root->getNode("track"); - if (track_node != NULL) - { - for (unsigned int i=0; igetNumNodes(); i++) - { - const XMLNode* n = track_node->getNode(i); - bool is_instance = false; - n->get("lod_instance", &is_instance); - - if (!is_instance && create_lod_definitions) lod_loader.check(n); - } - } - - std::vector lod_nodes; - std::vector devnull; - lod_loader.done(this, m_root, devnull, parent, lod_nodes); - - m_track_object_manager->assingLodNodes(lod_nodes, parent); - // --------------------------------------------- - - // Init all track objects - m_track_object_manager->init(); - - for (std::map::iterator it = library_nodes.begin(); - it != library_nodes.end(); it++) - { - delete it->second; - } } //----------------------------------------------------------------------------- diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index e1591b8f1..6c6c0e91f 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -35,6 +35,7 @@ namespace irr namespace scene { class IMesh; class ILightSceneNode; } } using namespace irr; +class LodNodeLoader; #include "LinearMath/btTransform.h" @@ -399,8 +400,9 @@ private: std::vector& m_music ); void loadCurves(const XMLNode &node); void handleSky(const XMLNode &root, const std::string &filename); - void loadObjects(const XMLNode* root, const std::string& path, - bool create_lod_definitions, scene::ISceneNode* parent); + void loadObjects(const XMLNode* root, const std::string& path, LodNodeLoader& lod_loader, + bool create_lod_definitions, scene::ISceneNode* parent, + std::map& library_nodes); public: diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index ffb876b13..26138ba33 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -218,7 +218,7 @@ void TrackObjectManager::removeObject(TrackObject* obj) * * \param lod_nodes the LOD nodes created by the LodNodeLoader. */ -void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes, scene::ISceneNode* parent) +void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes) { for (unsigned int n=0; n& lod_nodes, assert( queue.size() > 0 ); const XMLNode* xml = queue[ queue.size() - 1 ]; - TrackObject* obj = new TrackObject(*xml, parent, lod_nodes[n]); + TrackObject* obj = new TrackObject(*xml, lod_nodes[n]->getParent(), lod_nodes[n]); queue.erase( queue.end() - 1 ); m_all_objects.push_back(obj); diff --git a/src/tracks/track_object_manager.hpp b/src/tracks/track_object_manager.hpp index 99a2ae289..5539f08cd 100644 --- a/src/tracks/track_object_manager.hpp +++ b/src/tracks/track_object_manager.hpp @@ -68,7 +68,7 @@ public: void removeObject(TrackObject* who); - void assingLodNodes(const std::vector& lod, scene::ISceneNode* parent); + void assingLodNodes(const std::vector& lod); PtrVector& getObjects() { return m_all_objects; } const PtrVector& getObjects() const { return m_all_objects; } From 5cd71bdc9679c1c5f5367fb49d24d886be7841e7 Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 18:45:18 +0000 Subject: [PATCH 098/412] Fix LOD objects in a library git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14854 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track_object_manager.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index 26138ba33..60ffe4c66 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -44,6 +44,10 @@ TrackObjectManager::~TrackObjectManager() * \note If you add add any objects with LOD, don't forget to call * TrackObjectManager::assingLodNodes after everything is loaded * to finalize their creation. + * + * FIXME: all of this is horrible, just make the exporter write LOD definitions + * in a separate section that's read before everything and remove all this + * crap */ void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) { @@ -55,7 +59,11 @@ void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) if (is_lod) { - m_lod_objects[groupname].push_back(&xml_node); + bool lod_instance = false; + xml_node.get("lod_instance", &lod_instance); + + if (lod_instance) + m_lod_objects[groupname].push_back(&xml_node); } else { From 692d5a582da43c1d8c5ece795db20beedc4eab2b Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 19:11:23 +0000 Subject: [PATCH 099/412] Fix OSX compilation git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14855 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index fcac96621..699bc7820 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -3,6 +3,7 @@ #if defined(__APPLE__) # include +# include #elif defined(ANDROID) # include #elif defined(WIN32) From 6fb8188e070ab098c7abe882f61b5e83cf0222d4 Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 19:22:05 +0000 Subject: [PATCH 100/412] Fix finding data files on OSX git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14856 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/io/file_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 42491e754..89067e8dc 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -151,7 +151,7 @@ FileManager::FileManager(char *argv[]) if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL ) root_dir = std::string(getenv("SUPERTUXKART_DATADIR"))+"/" ; #ifdef __APPLE__ - else if( macSetBundlePathIfRelevant( root_dir ) ) { /* nothing to do */ } + else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "/data/"; } #endif else if(m_file_system->existFile("data")) root_dir = "data/" ; From 56dcb9b3a2f8f1fabe34f9d13d147f816c2d4d89 Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 19:49:53 +0000 Subject: [PATCH 101/412] Add support for a new way of loading LOD definitions, that should eventually fully replace the previous method (instead of exporting LOD definitions as standard objects that can appear anywhere in the XML file, group them in a section, this way we can load all LOD definitions right at the start of the load sequence, instead of the delayed creation hacks we do atm). Old code still in place for now, since we have a lot of tracks using the old way git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14857 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 0d105b3eb..6e1c3ba6e 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -789,7 +789,7 @@ bool Track::loadMainTrack(const XMLNode &root) m_track_mesh = new TriangleMesh(); m_gfx_effect_mesh = new TriangleMesh(); - const XMLNode *track_node= root.getNode("track"); + const XMLNode *track_node = root.getNode("track"); std::string model_name; track_node->get("model", &model_name); std::string full_path = m_root+model_name; @@ -856,7 +856,24 @@ bool Track::loadMainTrack(const XMLNode &root) LodNodeLoader lodLoader; - for(unsigned int i=0; igetNumNodes(); i++) + // Load LOD groups + const XMLNode *lod_xml_node = root.getNode("lod"); + if (lod_xml_node != NULL) + { + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) + { + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + // TODO: eventually, remove support for the old way of specifying LOD + // definitions among node, and support only the new way of using + // a section. Then, the LOD loading sequence can be simplified a lot + lodLoader.check(lod_group_xml->getNode(j), NULL); + } + } + } + + for (unsigned int i=0; igetNumNodes(); i++) { const XMLNode *n=track_node->getNode(i); // Animated textures have already been handled @@ -1763,6 +1780,23 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa file_manager->pushTextureSearchPath(lib_path + "/"); file_manager->pushModelSearchPath (lib_path); library_nodes[name] = libroot; + + // Load LOD groups + const XMLNode *lod_xml_node = libroot->getNode("lod"); + if (lod_xml_node != NULL) + { + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) + { + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + // TODO: eventually, remove support for the old way of specifying LOD + // definitions among node, and support only the new way of using + // a section. Then, the LOD loading sequence can be simplified a lot + lod_loader.check(lod_group_xml->getNode(j), NULL); + } + } + } } else { From be691c9afc84e3a8ce1ad2242ec2f7b02ff1982d Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 31 Dec 2013 20:27:13 +0000 Subject: [PATCH 102/412] Do not report the new XML node as an unknown node type git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14860 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 6e1c3ba6e..34e19affc 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1900,6 +1900,10 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa { // handled above } + else if (name == "lod") + { + // handled above + } else if (name == "subtitles") { std::vector subtitles; From 1d3a33bf8e47d186245dbe8d2a097641f60823b9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 31 Dec 2013 20:39:00 +0000 Subject: [PATCH 103/412] GPUParticles: Use quad instead of POINT_SPRITE git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14861 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 4 ++- data/shaders/particle.vert | 7 ++-- data/shaders/pointemitter.vert | 1 - src/graphics/gpuparticles.cpp | 63 ++++++++++++++++++++++++++-------- src/graphics/gpuparticles.h | 3 +- 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index cb5febfad..3587367b0 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -5,8 +5,10 @@ uniform mat4 invproj; uniform vec2 screen; in float lf; +in vec2 tc; out vec4 color; + void main(void) { vec2 xy = gl_FragCoord.xy / screen; @@ -18,6 +20,6 @@ void main(void) EnvPos /= EnvPos.w; float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - color = texture2D(texture, gl_PointCoord.xy); + color = texture2D(texture, tc); color.a *= alpha * (1. - lf); } diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index 9e5ca50b7..75b228ab5 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,14 +1,17 @@ #version 130 uniform mat4 matrix; +in vec2 quadcorner; +in vec2 texcoord; in vec3 position; in float lifetime; out float lf; +out vec2 tc; void main(void) { + tc = texcoord; lf = lifetime; - gl_Position = matrix * vec4(position, 1.0); - gl_PointSize = 300. / gl_Position.w; + gl_Position = matrix * vec4(vec3(quadcorner, 0.) + position, 1.0); } diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index fc95a7cb8..af648a8ab 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -1,7 +1,6 @@ #version 130 uniform int dt; uniform mat4 sourcematrix; -uniform int duration; in vec3 particle_position_initial; in float lifetime_initial; diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index a7a1ae0e5..183a49353 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -44,6 +44,8 @@ PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; PFNGLBLENDEQUATIONPROC glBlendEquation; +PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; +PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; #endif void initGL() @@ -83,6 +85,8 @@ void initGL() glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation"); glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation"); + glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor"); + glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); #endif } @@ -227,6 +231,17 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale) { + static const GLfloat quad_vertex[] = { + -.5, -.5, 0., 0., + .5, -.5, 1., 0., + -.5, .5, 0., 1., + .5, .5, 1., 1., + }; + initGL(); + glGenBuffers(1, &quad_vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex), quad_vertex, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); } void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) @@ -240,7 +255,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) setMaterialType(irr_driver->getShader(ES_RAIN)); setAutomaticCulling(0); LastEmitTime = 0; - initGL(); + duration = emitter->getMaxLifeTime(); count = emitter->getMaxParticlesPerSecond() * duration / 1000; const char *varyings[] = { @@ -253,7 +268,6 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); - uniform_duration = glGetUniformLocation(SimulationProgram, "duration"); uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); @@ -267,6 +281,9 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); attrib_pos = glGetAttribLocation(RenderProgram, "position"); attrib_lf = glGetAttribLocation(RenderProgram, "lifetime"); + attrib_quadcorner = glGetAttribLocation(RenderProgram, "quadcorner"); + attrib_texcoord = glGetAttribLocation(RenderProgram, "texcoord"); + uniform_matrix = glGetUniformLocation(RenderProgram, "matrix"); uniform_texture = glGetUniformLocation(RenderProgram, "texture"); uniform_invproj = glGetUniformLocation(RenderProgram, "invproj"); @@ -276,13 +293,15 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + printf("count:%d\nduration_min:%d\nduration_max:%d\n", count, emitter->getMinLifeTime(), emitter->getMaxLifeTime()); for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = getAbsolutePosition().X; - particles[COMPONENTCOUNT * i + 1] = getAbsolutePosition().Y; - particles[COMPONENTCOUNT * i + 2] = getAbsolutePosition().Z; + particles[COMPONENTCOUNT * i] = 0; + particles[COMPONENTCOUNT * i + 1] = 0; + particles[COMPONENTCOUNT * i + 2] = 0; // Initial lifetime is 0 percent - particles[COMPONENTCOUNT * i + 3] = 0.; + particles[COMPONENTCOUNT * i + 3] = rand(); + particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; initialvalue[COMPONENTCOUNT * i] = 0.; initialvalue[COMPONENTCOUNT * i + 1] = 0.; @@ -302,14 +321,16 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; } - glGenBuffers(2, tfb_buffers); + glGenBuffers(1, &initial_values_buffer); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glGenBuffers(2, tfb_buffers); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); delete [] particles; + delete [] initialvalue; } @@ -346,7 +367,6 @@ void ParticleSystemProxy::simulate() glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); glUniform1i(uniform_dt, 16); - glUniform1i(uniform_duration, duration); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); @@ -365,17 +385,17 @@ void ParticleSystemProxy::draw() { glDepthMask(GL_FALSE); glEnable(GL_BLEND); + glDisable(GL_CULL_FACE); core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - glEnable(GL_POINT_SPRITE); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glUseProgram(RenderProgram); glEnableVertexAttribArray(attrib_pos); glEnableVertexAttribArray(attrib_lf); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glEnableVertexAttribArray(attrib_quadcorner); + glEnableVertexAttribArray(attrib_texcoord); + float screen[2] = { (float)UserConfigParams::m_width, (float)UserConfigParams::m_height @@ -390,15 +410,30 @@ void ParticleSystemProxy::draw() glUniform2f(uniform_screen, screen[0], screen[1]); glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, matrix.pointer()); + glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); + glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *) (3 * sizeof(float))); - glDrawArrays(GL_POINTS, 0, count); + + +// glVertexAttribDivisor(attrib_quadcorner, 0); +// glVertexAttribDivisor(attrib_texcoord, 0); + glVertexAttribDivisor(attrib_lf, 1); + glVertexAttribDivisor(attrib_pos, 1); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); + glVertexAttribDivisor(attrib_lf, 0); + glVertexAttribDivisor(attrib_pos, 0); glDisableVertexAttribArray(attrib_pos); glDisableVertexAttribArray(attrib_lf); + glDisableVertexAttribArray(attrib_quadcorner); + glDisableVertexAttribArray(attrib_texcoord); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDepthMask(GL_TRUE); + glEnable(GL_CULL_FACE); } void ParticleSystemProxy::render() { diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 22528f2c6..dc6f78bb0 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,6 +29,7 @@ public: class ParticleSystemProxy : public scene::CParticleSystemSceneNode { protected: + GLuint quad_vertex_buffer; GLuint tfb_buffers[2], initial_values_buffer; GLuint SimulationProgram; @@ -36,7 +37,7 @@ protected: GLuint uniform_duration, uniform_sourcematrix, uniform_dt; GLuint RenderProgram; - GLuint attrib_pos, attrib_lf; + GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord; GLuint uniform_matrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; GLuint texture, normal_and_depth; From a38522da7006f47a7bacd32d780e2ccf064c9411 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 01:11:44 +0000 Subject: [PATCH 104/412] GPUParticle: Implement size parameter. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14862 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.vert | 8 +++++-- data/shaders/pointemitter.vert | 10 ++++++--- src/graphics/gpuparticles.cpp | 40 ++++++++++++++++++++++++++-------- src/graphics/gpuparticles.h | 6 ++--- 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index 75b228ab5..82d0f2e76 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,10 +1,12 @@ #version 130 -uniform mat4 matrix; +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; in vec2 quadcorner; in vec2 texcoord; in vec3 position; in float lifetime; +in float size; out float lf; out vec2 tc; @@ -13,5 +15,7 @@ void main(void) { tc = texcoord; lf = lifetime; - gl_Position = matrix * vec4(vec3(quadcorner, 0.) + position, 1.0); + vec4 viewpos = ViewMatrix * vec4(position, 1.0); + viewpos += size * vec4(quadcorner, 0., 0.); + gl_Position = ProjectionMatrix * viewpos; } diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index af648a8ab..be30c647c 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -4,15 +4,18 @@ uniform mat4 sourcematrix; in vec3 particle_position_initial; in float lifetime_initial; -in vec4 particle_velocity_initial; +in vec3 particle_velocity_initial; +in float size_initial; in vec3 particle_position; in float lifetime; -in vec4 particle_velocity; +in vec3 particle_velocity; +in float size; out vec3 new_particle_position; out float new_lifetime; -out vec4 new_particle_velocity; +out vec3 new_particle_velocity; +out float new_size; void main(void) { @@ -20,5 +23,6 @@ void main(void) new_particle_position = (lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; new_lifetime = (lifetime < 1.) ? lifetime + (float(dt)/lifetime_initial) : 0.; new_particle_velocity = (lifetime < 1.) ? particle_velocity : particle_velocity_initial; + new_size = size_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 183a49353..245553aaa 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -262,11 +262,12 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) "new_particle_position", "new_lifetime", "new_particle_velocity", + "new_size", }; texture = getTextureGLuint(getMaterial(0).getTexture(0)); normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 3); + SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 4); uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); @@ -274,17 +275,21 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); attrib_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); + attrib_size = glGetAttribLocation(SimulationProgram, "size"); attrib_initial_position = glGetAttribLocation(SimulationProgram, "particle_position_initial"); attrib_initial_lifetime = glGetAttribLocation(SimulationProgram, "lifetime_initial"); attrib_initial_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity_initial"); + attrib_initial_size = glGetAttribLocation(SimulationProgram, "size_initial"); RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); attrib_pos = glGetAttribLocation(RenderProgram, "position"); + attrib_sz = glGetAttribLocation(RenderProgram, "size"); attrib_lf = glGetAttribLocation(RenderProgram, "lifetime"); attrib_quadcorner = glGetAttribLocation(RenderProgram, "quadcorner"); attrib_texcoord = glGetAttribLocation(RenderProgram, "texcoord"); - uniform_matrix = glGetUniformLocation(RenderProgram, "matrix"); + uniform_matrix = glGetUniformLocation(RenderProgram, "ProjectionMatrix"); + uniform_viewmatrix = glGetUniformLocation(RenderProgram, "ViewMatrix"); uniform_texture = glGetUniformLocation(RenderProgram, "texture"); uniform_invproj = glGetUniformLocation(RenderProgram, "invproj"); uniform_screen = glGetUniformLocation(RenderProgram, "screen"); @@ -293,8 +298,12 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + float sizeMin = emitter->getMinStartSize().Height; + float sizeMax = emitter->getMaxStartSize().Height; - printf("count:%d\nduration_min:%d\nduration_max:%d\n", count, emitter->getMinLifeTime(), emitter->getMaxLifeTime()); + printf("count:%d\nduration_min:%d\nduration_max:%d\nsize_min:%f\nsize_max:%f\n", count, + emitter->getMinLifeTime(), emitter->getMaxLifeTime(), + sizeMin, sizeMax); for (unsigned i = 0; i < count; i++) { particles[COMPONENTCOUNT * i] = 0; particles[COMPONENTCOUNT * i + 1] = 0; @@ -320,6 +329,11 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; + + initialvalue[COMPONENTCOUNT * i + 7] = rand(); + initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; + initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); + initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; } glGenBuffers(1, &initial_values_buffer); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); @@ -353,17 +367,21 @@ void ParticleSystemProxy::simulate() glEnableVertexAttribArray(attrib_position); glEnableVertexAttribArray(attrib_lifetime); glEnableVertexAttribArray(attrib_velocity); + glEnableVertexAttribArray(attrib_size); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); glVertexAttribPointer(attrib_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(attrib_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(attrib_size, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(7 * sizeof(float))); glEnableVertexAttribArray(attrib_initial_position); glEnableVertexAttribArray(attrib_initial_lifetime); glEnableVertexAttribArray(attrib_initial_velocity); + glEnableVertexAttribArray(attrib_initial_size); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glVertexAttribPointer(attrib_initial_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); glVertexAttribPointer(attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(attrib_initial_size, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(7 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); glUniform1i(uniform_dt, 16); @@ -374,9 +392,11 @@ void ParticleSystemProxy::simulate() glDisableVertexAttribArray(attrib_position); glDisableVertexAttribArray(attrib_lifetime); glDisableVertexAttribArray(attrib_velocity); + glDisableVertexAttribArray(attrib_size); glDisableVertexAttribArray(attrib_initial_position); glDisableVertexAttribArray(attrib_initial_lifetime); glDisableVertexAttribArray(attrib_initial_velocity); + glDisableVertexAttribArray(attrib_initial_size); glDisable(GL_RASTERIZER_DISCARD); std::swap(tfb_buffers[0], tfb_buffers[1]); } @@ -386,8 +406,8 @@ void ParticleSystemProxy::draw() glDepthMask(GL_FALSE); glEnable(GL_BLEND); glDisable(GL_CULL_FACE); - core::matrix4 matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - matrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glUseProgram(RenderProgram); @@ -395,6 +415,7 @@ void ParticleSystemProxy::draw() glEnableVertexAttribArray(attrib_lf); glEnableVertexAttribArray(attrib_quadcorner); glEnableVertexAttribArray(attrib_texcoord); + glEnableVertexAttribArray(attrib_sz); float screen[2] = { (float)UserConfigParams::m_width, @@ -408,7 +429,8 @@ void ParticleSystemProxy::draw() glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, invproj.pointer()); glUniform2f(uniform_screen, screen[0], screen[1]); - glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, matrix.pointer()); + glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, projm.pointer()); + glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, viewm.pointer()); glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); @@ -416,12 +438,11 @@ void ParticleSystemProxy::draw() glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *) (3 * sizeof(float))); + glVertexAttribPointer(attrib_sz, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *)(7 * sizeof(float))); - -// glVertexAttribDivisor(attrib_quadcorner, 0); -// glVertexAttribDivisor(attrib_texcoord, 0); glVertexAttribDivisor(attrib_lf, 1); glVertexAttribDivisor(attrib_pos, 1); + glVertexAttribDivisor(attrib_sz, 1); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); glVertexAttribDivisor(attrib_lf, 0); @@ -430,6 +451,7 @@ void ParticleSystemProxy::draw() glDisableVertexAttribArray(attrib_lf); glDisableVertexAttribArray(attrib_quadcorner); glDisableVertexAttribArray(attrib_texcoord); + glDisableVertexAttribArray(attrib_sz); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glDepthMask(GL_TRUE); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index dc6f78bb0..68fb97242 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -33,12 +33,12 @@ protected: GLuint tfb_buffers[2], initial_values_buffer; GLuint SimulationProgram; - GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime; + GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; GLuint uniform_duration, uniform_sourcematrix, uniform_dt; GLuint RenderProgram; - GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord; - GLuint uniform_matrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; + GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; GLuint texture, normal_and_depth; unsigned duration, count, LastEmitTime; From 0fc2f664b696f987ac5fd00ae816f8a50dadbd6d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 01:51:52 +0000 Subject: [PATCH 105/412] GPUParticles: Forgot to reset vertexattrib divisor git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14863 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 245553aaa..c3a19c977 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -447,6 +447,7 @@ void ParticleSystemProxy::draw() glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); glVertexAttribDivisor(attrib_lf, 0); glVertexAttribDivisor(attrib_pos, 0); + glVertexAttribDivisor(attrib_sz, 0); glDisableVertexAttribArray(attrib_pos); glDisableVertexAttribArray(attrib_lf); glDisableVertexAttribArray(attrib_quadcorner); From 94d9eb056ab885391c4041e4290b3792b7f068a8 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 01:59:02 +0000 Subject: [PATCH 106/412] GPUParticle: Use Irrlicht blending state git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14864 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index c3a19c977..b4aaa0b63 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -404,12 +404,9 @@ void ParticleSystemProxy::simulate() void ParticleSystemProxy::draw() { glDepthMask(GL_FALSE); - glEnable(GL_BLEND); glDisable(GL_CULL_FACE); core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); glUseProgram(RenderProgram); glEnableVertexAttribArray(attrib_pos); glEnableVertexAttribArray(attrib_lf); @@ -469,8 +466,8 @@ void ParticleSystemProxy::render() { draw(); // We need to force irrlicht to update its internal states irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setMaterial(getMaterial(0)); - static_cast(drv)->setRenderStates3DMode(); + //drv->setMaterial(getMaterial(0)); + //static_cast(drv)->setRenderStates3DMode(); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) From 217d512d5fceab95fe671638388784034905f9b9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 02:17:58 +0000 Subject: [PATCH 107/412] This shouldn't have been added to previous commit, sorry. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14865 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index b4aaa0b63..1a9f5986f 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -466,8 +466,8 @@ void ParticleSystemProxy::render() { draw(); // We need to force irrlicht to update its internal states irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - //drv->setMaterial(getMaterial(0)); - //static_cast(drv)->setRenderStates3DMode(); + drv->setMaterial(getMaterial(0)); + static_cast(drv)->setRenderStates3DMode(); } RainNode::RainNode(scene::ISceneManager* mgr, ITexture *tex) From 7f45adeeb0bed6d03b9baa0c92a8215b95beb327 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 02:45:47 +0000 Subject: [PATCH 109/412] GPUParticles: Enforce GL_BLEND This fixes some issue with Harvest experienced by samuncle git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14867 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 1a9f5986f..2e9bddc89 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -405,6 +405,7 @@ void ParticleSystemProxy::draw() { glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); glUseProgram(RenderProgram); From 823a40e45e09435143de40e3de653c4742ecf97c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 03:06:23 +0000 Subject: [PATCH 110/412] GPUParticles: Fix particles randomly becoming blocky in some track. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14868 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2e9bddc89..719eccfbd 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -408,6 +408,7 @@ void ParticleSystemProxy::draw() glEnable(GL_BLEND); core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(RenderProgram); glEnableVertexAttribArray(attrib_pos); glEnableVertexAttribArray(attrib_lf); From 245910d3a7938dcc97f66fb8841f2c0dd3fc9b19 Mon Sep 17 00:00:00 2001 From: auria Date: Wed, 1 Jan 2014 16:43:03 +0000 Subject: [PATCH 111/412] Apply patch to improve paths on osx git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14869 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/io/file_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 89067e8dc..096ea1672 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -151,7 +151,7 @@ FileManager::FileManager(char *argv[]) if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL ) root_dir = std::string(getenv("SUPERTUXKART_DATADIR"))+"/" ; #ifdef __APPLE__ - else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "/data/"; } + else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; } #endif else if(m_file_system->existFile("data")) root_dir = "data/" ; From 28ebf0c08c1bc71fe07ce57d30f2e3f40dddfc46 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 18:11:28 +0000 Subject: [PATCH 112/412] GPUParticles: Implement box emitter git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14870 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 171 +++++++++++++++++++++++----------- src/graphics/gpuparticles.h | 2 + 2 files changed, 121 insertions(+), 52 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 719eccfbd..4fd1b9c0f 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -244,12 +244,117 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, glBindBuffer(GL_ARRAY_BUFFER, 0); } +void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePointEmitter *emitter) +{ + float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; + unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + + float sizeMin = emitter->getMinStartSize().Height; + float sizeMax = emitter->getMaxStartSize().Height; + + for (unsigned i = 0; i < count; i++) { + particles[COMPONENTCOUNT * i] = 0; + particles[COMPONENTCOUNT * i + 1] = 0; + particles[COMPONENTCOUNT * i + 2] = 0; + // Initial lifetime is 0 percent + particles[COMPONENTCOUNT * i + 3] = rand(); + particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + + initialvalue[COMPONENTCOUNT * i] = 0.; + initialvalue[COMPONENTCOUNT * i + 1] = 0.; + initialvalue[COMPONENTCOUNT * i + 2] = 0.; + initialvalue[COMPONENTCOUNT * i + 3] = rand() % lifetime_range; + initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); + + core::vector3df particledir = emitter->getDirection(); + particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + + particles[COMPONENTCOUNT * i + 4] = particledir.X; + particles[COMPONENTCOUNT * i + 5] = particledir.Y; + particles[COMPONENTCOUNT * i + 6] = particledir.Z; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; + + initialvalue[COMPONENTCOUNT * i + 7] = rand(); + initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; + initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); + initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; + } + glGenBuffers(1, &initial_values_buffer); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glGenBuffers(2, tfb_buffers); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + delete[] particles; + delete[] initialvalue; +} + +void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter *emitter) +{ + float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; + unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + + float sizeMin = emitter->getMinStartSize().Height; + float sizeMax = emitter->getMaxStartSize().Height; + + const core::vector3df& extent = emitter->getBox().getExtent(); + printf("particle lifetime [%d-%d]\n", emitter->getMinLifeTime(), emitter->getMaxLifeTime()); + + for (unsigned i = 0; i < count; i++) { + particles[COMPONENTCOUNT * i] = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; + particles[COMPONENTCOUNT * i + 1] = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; + particles[COMPONENTCOUNT * i + 2] = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; + // Initial lifetime is 0 percent + particles[COMPONENTCOUNT * i + 3] = rand(); + particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + + initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; + initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; + initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; + initialvalue[COMPONENTCOUNT * i + 3] = (lifetime_range > 0) ? rand() % lifetime_range : 0; + initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); + + core::vector3df particledir = emitter->getDirection(); + particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + + particles[COMPONENTCOUNT * i + 4] = particledir.X; + particles[COMPONENTCOUNT * i + 5] = particledir.Y; + particles[COMPONENTCOUNT * i + 6] = particledir.Z; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; + + initialvalue[COMPONENTCOUNT * i + 7] = rand(); + initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; + initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); + initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; + } + glGenBuffers(1, &initial_values_buffer); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glGenBuffers(2, tfb_buffers); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + delete[] particles; + delete[] initialvalue; +} + void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) { if (!emitter) return; CParticleSystemSceneNode::setEmitter(emitter); - if (emitter->getType() != scene::EPET_POINT) + if (emitter->getType() != scene::EPET_POINT && emitter->getType() != scene::EPET_BOX) return; // Pass a fake material type to force irrlicht to update its internal states on rendering setMaterialType(irr_driver->getShader(ES_RAIN)); @@ -295,57 +400,19 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_screen = glGetUniformLocation(RenderProgram, "screen"); uniform_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; - unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); - - float sizeMin = emitter->getMinStartSize().Height; - float sizeMax = emitter->getMaxStartSize().Height; - - printf("count:%d\nduration_min:%d\nduration_max:%d\nsize_min:%f\nsize_max:%f\n", count, - emitter->getMinLifeTime(), emitter->getMaxLifeTime(), - sizeMin, sizeMax); - for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = 0; - particles[COMPONENTCOUNT * i + 1] = 0; - particles[COMPONENTCOUNT * i + 2] = 0; - // Initial lifetime is 0 percent - particles[COMPONENTCOUNT * i + 3] = rand(); - particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; - - initialvalue[COMPONENTCOUNT * i] = 0.; - initialvalue[COMPONENTCOUNT * i + 1] = 0.; - initialvalue[COMPONENTCOUNT * i + 2] = 0.; - initialvalue[COMPONENTCOUNT * i + 3] = rand() % lifetime_range; - initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); - - core::vector3df particledir = emitter->getDirection(); - particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - - particles[COMPONENTCOUNT * i + 4] = particledir.X; - particles[COMPONENTCOUNT * i + 5] = particledir.Y; - particles[COMPONENTCOUNT * i + 6] = particledir.Z; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; - - initialvalue[COMPONENTCOUNT * i + 7] = rand(); - initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; - initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); - initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; + switch (emitter->getType()) + { + case scene::EPET_POINT: + generateParticlesFromPointEmitter(emitter); + break; + case scene::EPET_BOX: + generateParticlesFromBoxEmitter(static_cast(emitter)); + break; + default: + assert(0 && "Wrong particle type"); } - glGenBuffers(1, &initial_values_buffer); - glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); - glGenBuffers(2, tfb_buffers); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); - delete [] particles; - delete [] initialvalue; -} + } + void ParticleSystemProxy::simulate() @@ -459,7 +526,7 @@ void ParticleSystemProxy::draw() } void ParticleSystemProxy::render() { - if (getEmitter()->getType() != scene::EPET_POINT) + if (getEmitter()->getType() != scene::EPET_POINT && getEmitter()->getType() != scene::EPET_BOX) { CParticleSystemSceneNode::render(); return; diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 68fb97242..2824ffeb3 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -45,6 +45,8 @@ protected: virtual void simulate(); virtual void draw(); + void generateParticlesFromPointEmitter(scene::IParticlePointEmitter *); + void generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter *); public: static IParticleSystemSceneNode *addParticleNode( bool withDefaultEmitter = true, ISceneNode* parent = 0, s32 id = -1, From 09926f6f4e885399d5f1d7d2c541403bed33c2f6 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 18:59:15 +0000 Subject: [PATCH 114/412] GPUParticles: Modulate direction length to avoid banding with lot of particles. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14873 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 45 +++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 4fd1b9c0f..25f29c347 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -271,17 +271,20 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particles[COMPONENTCOUNT * i + 4] = particledir.X; - particles[COMPONENTCOUNT * i + 5] = particledir.Y; - particles[COMPONENTCOUNT * i + 6] = particledir.Z; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; + float size = rand(); + size /= RAND_MAX; + size *= (sizeMax - sizeMin); + size += sizeMin; + + initialvalue[COMPONENTCOUNT * i + 7] = size; + + particles[COMPONENTCOUNT * i + 4] = particledir.X / size; + particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; + particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; - initialvalue[COMPONENTCOUNT * i + 7] = rand(); - initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; - initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); - initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; } glGenBuffers(1, &initial_values_buffer); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); @@ -325,17 +328,19 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particles[COMPONENTCOUNT * i + 4] = particledir.X; - particles[COMPONENTCOUNT * i + 5] = particledir.Y; - particles[COMPONENTCOUNT * i + 6] = particledir.Z; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z; + float size = rand(); + size /= RAND_MAX; + size *= (sizeMax - sizeMin); + size += sizeMin; - initialvalue[COMPONENTCOUNT * i + 7] = rand(); - initialvalue[COMPONENTCOUNT * i + 7] /= RAND_MAX; - initialvalue[COMPONENTCOUNT * i + 7] *= (sizeMax - sizeMin); - initialvalue[COMPONENTCOUNT * i + 7] += sizeMin; + initialvalue[COMPONENTCOUNT * i + 7] = size; + + particles[COMPONENTCOUNT * i + 4] = particledir.X / size; + particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; + particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; } glGenBuffers(1, &initial_values_buffer); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); From 6b7e33a2670399cbe97ac3165263bd6d378a54d6 Mon Sep 17 00:00:00 2001 From: auria Date: Wed, 1 Jan 2014 19:11:01 +0000 Subject: [PATCH 115/412] Convert a bunch of prints to our logging system, it's long overdue we fix that git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14874 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/addons/network_http.cpp | 46 +++++++++++++++---------------- src/addons/zip.cpp | 16 ++++------- src/animations/ipo.cpp | 13 ++++----- src/audio/music_manager.cpp | 8 +++--- src/audio/music_ogg.cpp | 1 - src/audio/sfx_manager.cpp | 9 +----- src/audio/sfx_openal.cpp | 4 +-- src/challenges/challenge_data.cpp | 25 ++++++++--------- src/challenges/unlock_manager.cpp | 4 +-- 9 files changed, 55 insertions(+), 71 deletions(-) diff --git a/src/addons/network_http.cpp b/src/addons/network_http.cpp index 977197d21..33b240bab 100644 --- a/src/addons/network_http.cpp +++ b/src/addons/network_http.cpp @@ -99,7 +99,7 @@ void NetworkHttp::startNetworkThread() delete m_thread_id.getData(); m_thread_id.unlock(); m_thread_id.setAtomic(0); - printf("[addons] Warning: could not create thread, error=%d.\n", errno); + Log::warn("addons", "Could not create thread, error=%d", errno); } pthread_attr_destroy(&attr); } // startNetworkThread @@ -129,7 +129,7 @@ void *NetworkHttp::mainLoop(void *obj) while(empty) { if(UserConfigParams::logAddons()) - printf("[addons] No request, sleeping.\n"); + Log::debug("addons", "No request, sleeping."); pthread_cond_wait(&me->m_cond_request, me->m_all_requests.getMutex()); @@ -143,12 +143,12 @@ void *NetworkHttp::mainLoop(void *obj) if(UserConfigParams::logAddons()) { if(me->m_current_request->getCommand()==Request::HC_DOWNLOAD_FILE) - printf("[addons] Executing download '%s' to '%s' priority %d.\n", + Log::info("addons", "Executing download '%s' to '%s' priority %d", me->m_current_request->getURL().c_str(), me->m_current_request->getSavePath().c_str(), me->m_current_request->getPriority()); else - printf("[addons] Executing command '%d' priority %d.\n", + Log::info("addons", "Executing command '%d' priority %d.", me->m_current_request->getCommand(), me->m_current_request->getPriority()); } @@ -189,7 +189,7 @@ void *NetworkHttp::mainLoop(void *obj) me->m_all_requests.lock(); } // while !quit if(UserConfigParams::logAddons()) - printf("[addons] Network exiting.\n"); + Log::info("addons", "Network exiting."); // At this stage we have the lock for m_all_requests while(!me->m_all_requests.getData().empty()) @@ -227,7 +227,7 @@ void NetworkHttp::stopNetworkThread() Request *r = new Request(Request::HC_QUIT, 9999); if(UserConfigParams::logAddons()) - printf("[addons] Inserting QUIT request.\n"); + Log::info("addons", "Inserting QUIT request."); insertRequest(r); } // stopNetworkThread @@ -275,7 +275,7 @@ CURLcode NetworkHttp::init(bool forceRefresh) // Initialise the online portion of the addons manager. if(download && UserConfigParams::logAddons()) - printf("[addons] Downloading list.\n"); + Log::info("addons", "Downloading list."); Request r(Request::HC_DOWNLOAD_FILE, 9999, false, "news.xml", "news.xml"); @@ -350,7 +350,7 @@ CURLcode NetworkHttp::init(bool forceRefresh) news_manager->setErrorMessage(error_message); if(UserConfigParams::logAddons()) - printf("[addons] %s\n", core::stringc(error_message).c_str()); + Log::error("addons", "Error raised in NetworkHttp::init : %s", core::stringc(error_message).c_str()); return status; } // init @@ -365,7 +365,7 @@ void NetworkHttp::insertReInit() /*manage_memory*/true); if(UserConfigParams::logAddons()) - printf("[addons] Inserting reInit request.\n"); + Log::info("addons", "Inserting reInit request."); insertRequest(request); } // insertReInit @@ -387,7 +387,7 @@ CURLcode NetworkHttp::reInit() m_all_requests.unlock(); if(UserConfigParams::logAddons()) - printf("[addons] Xml files deleted, re-initialising addon manager.\n"); + Log::info("addons", "Xml files deleted, re-initialising addon manager."); return init(true /* force refresh */); @@ -453,14 +453,14 @@ CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml, const XMLNode *xml = new XMLNode(xml_file); addons_manager->initOnline(xml); if(UserConfigParams::logAddons()) - printf("[addons] Addons manager list downloaded\n"); + Log::info("addons", "Addons manager list downloaded"); return status; } // Aborted by STK in progress callback, don't display error message if(status==CURLE_ABORTED_BY_CALLBACK) return status; - printf("[addons] Error on download addons.xml: %d\n", + Log::error("addons", "Error on download addons.xml: %d\n", status); return status; } // loadAddonsList @@ -482,7 +482,7 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) full_url = (std::string)UserConfigParams::m_server_addons + "/" + full_url; if(UserConfigParams::logAddons()) - printf("[addons] Downloading '%s' as '%s'.\n", + Log::info("addons", "Downloading '%s' as '%s'.", full_url.c_str(), request->getSavePath().c_str()); curl_easy_setopt(m_curl_session, CURLOPT_URL, full_url.c_str()); @@ -507,7 +507,7 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) if(!fout) { - printf("[addons] Can't open '%s' for writing, ignored.\n", + Log::error("addons", "Can't open '%s' for writing, ignored.", (full_save+".part").c_str()); return CURLE_WRITE_ERROR; } @@ -535,7 +535,7 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) if(status==CURLE_OK) { if(UserConfigParams::logAddons()) - printf("[addons] Download successful.\n"); + Log::info("addons", "Download successful."); // The behaviour of rename is unspecified if the target // file should already exist - so remove it. file_manager->removeFile(full_save); @@ -544,7 +544,7 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) if(ret!=0) { if(UserConfigParams::logAddons()) - printf("[addons] Could not rename downloaded file!\n"); + Log::error("addons", "Could not rename downloaded file!"); status=CURLE_WRITE_ERROR; } else @@ -552,8 +552,8 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) } else { - printf("[addons] Problems downloading file - return code %d.\n", - status); + Log::error("addons", "Problems downloading file - return code %d.", + status); } request->setProgress( (status==CURLE_OK) ? 1.0f : -1.0f ); @@ -568,7 +568,7 @@ CURLcode NetworkHttp::downloadFileInternal(Request *request) void NetworkHttp::cancelAllDownloads() { if(UserConfigParams::logAddons()) - printf("[addons] Requesting cancellation of download.\n"); + Log::info("addons", "Requesting cancellation of download."); m_abort.setAtomic(true); } // cancelAllDownload @@ -594,8 +594,8 @@ Request *NetworkHttp::downloadFileAsynchron(const std::string &url, url, (save!="") ? save : url ); if(UserConfigParams::logAddons()) - printf("[addons] Download asynchron '%s' as '%s'.\n", - request->getURL().c_str(), request->getSavePath().c_str()); + Log::info("addons", "Download asynchron '%s' as '%s'.", + request->getURL().c_str(), request->getSavePath().c_str()); insertRequest(request); return request; } // downloadFileAsynchron @@ -643,10 +643,10 @@ int NetworkHttp::progressDownload(void *clientp, // Reset abort flag so that the next download will work // as expected. self->m_abort.setAtomic(false); - printf("[addons] Global abort of downloads.\n"); + Log::info("addons", "Global abort of downloads."); } else - printf("[addons] Cancel this download.\n"); + Log::info("addons", "Cancel this download."); } // Indicates to abort the current download, which means that this // thread will go back to the mainloop and handle the next request. diff --git a/src/addons/zip.cpp b/src/addons/zip.cpp index 6cadcb7f9..9b4fd5ff8 100644 --- a/src/addons/zip.cpp +++ b/src/addons/zip.cpp @@ -75,7 +75,7 @@ bool extract_zip(const std::string &from, const std::string &to) for(unsigned int i=0; igetFileCount(); i++) { const std::string current_file=zip_file_list->getFileName(i).c_str(); - printf("[addons] Unzipping file '%s'.\n", current_file.c_str()); + Log::info("addons", "Unzipping file '%s'.", current_file.c_str()); if(zip_file_list->isDirectory(i)) continue; if(current_file[0]=='.') continue; const std::string base = StringUtils::getBasename(current_file); @@ -84,8 +84,7 @@ bool extract_zip(const std::string &from, const std::string &to) zip_archive->createAndOpenFile(current_file.c_str()); if(!src_file) { - printf("[addons] Can't read file '%s'.\n", current_file.c_str()); - printf("[addons] This is ignored, but the addon might not work.\n"); + Log::warn("addons", "Can't read file '%s'. This is ignored, but the addon might not work", current_file.c_str()); error = true; continue; } @@ -94,19 +93,16 @@ bool extract_zip(const std::string &from, const std::string &to) file_system->createAndWriteFile((to+"/"+base).c_str()); if(dst_file == NULL) { - printf("[addons] Couldn't create the file '%s'.\n", - (to+"/"+current_file).c_str()); - printf("[addons] The directory might not exist.\n"); - printf("[addons] This is ignored, but the addon might not work.\n"); + Log::warn("addons", "Couldn't create the file '%s'. The directory might not exist. This is ignored, but the addon might not work.", + (to+"/"+current_file).c_str()); error = true; continue; } if (IFileSystem_copyFileToFile(dst_file, src_file) < 0) { - printf("[addons] Could not copy '%s' from archive '%s'.\n", - current_file.c_str(), from.c_str()); - printf("[addons] This is ignored, but the addon might not work.\n"); + Log::warn("addons", "Could not copy '%s' from archive '%s'. This is ignored, but the addon might not work.", + current_file.c_str(), from.c_str()); error = true; } dst_file->drop(); diff --git a/src/animations/ipo.cpp b/src/animations/ipo.cpp index d5c4db071..dfa241ee6 100644 --- a/src/animations/ipo.cpp +++ b/src/animations/ipo.cpp @@ -42,8 +42,8 @@ Ipo::IpoData::IpoData(const XMLNode &curve, float fps, bool reverse) { if(curve.getName()!="curve") { - fprintf(stderr, "Expected 'curve' for animation, got '%s' --> Ignored.\n", - curve.getName().c_str()); + Log::warn("Animations", "Expected 'curve' for animation, got '%s' --> Ignored.", + curve.getName().c_str()); return; } std::string channel; @@ -59,9 +59,9 @@ Ipo::IpoData::IpoData(const XMLNode &curve, float fps, bool reverse) } if(m_channel==IPO_MAX) { - fprintf(stderr, "Unknown animation channel: '%s' - aborting.\n", + Log::error("Animation", "Unknown animation channel: '%s' --> Ignored", channel.c_str()); - exit(-1); + return; } std::string interp; @@ -76,10 +76,9 @@ Ipo::IpoData::IpoData(const XMLNode &curve, float fps, bool reverse) else if (extend=="const" ) m_extend = ET_CONST; else { - // FIXME: do we want an error message here? // For now extrap and cyclic_extrap do not work - fprintf(stderr, "Unsupported extend '%s' - defaulting to CONST.\n", - extend.c_str()); + Log::warn("Animation", "Unsupported extend '%s' - defaulting to CONST.", + extend.c_str()); m_extend = ET_CONST; } diff --git a/src/audio/music_manager.cpp b/src/audio/music_manager.cpp index 65ba81ff8..99c156c77 100644 --- a/src/audio/music_manager.cpp +++ b/src/audio/music_manager.cpp @@ -60,7 +60,7 @@ MusicManager::MusicManager() ALCdevice* device = alcOpenDevice ( NULL ); //The default sound device if( device == NULL ) { - fprintf(stderr, "WARNING: Could not open the default sound device.\n"); + Log::warn("MusicManager", "Could not open the default sound device."); m_initialized = false; } else @@ -70,7 +70,7 @@ MusicManager::MusicManager() if( context == NULL ) { - fprintf(stderr, "WARNING: Could not create a sound context.\n"); + Log::warn("MusicManager", "Could not create a sound context."); m_initialized = false; } else @@ -153,8 +153,8 @@ void MusicManager::addMusicToTracks() { if(!i->second) { - fprintf(stderr, "Can't find music file '%s' - ignored.\n", - i->first.c_str()); + Log::warn("MusicManager", "Can't find music file '%s' - ignored.", + i->first.c_str()); continue; } i->second->addMusicToTracks(); diff --git a/src/audio/music_ogg.cpp b/src/audio/music_ogg.cpp index 711769df9..4306d9056 100644 --- a/src/audio/music_ogg.cpp +++ b/src/audio/music_ogg.cpp @@ -293,7 +293,6 @@ void MusicOggStream::update() // no more data. Seek to beginning (causes the sound to loop) ov_time_seek(&m_oggStream, 0); active = streamIntoBuffer(buffer);//now there really should be data - //fprintf(stdout,"Music buffer under-run.\n"); } alSourceQueueBuffers(m_soundSource, 1, &buffer); diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 497031969..30eb98d5b 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -251,14 +251,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node, } std::string sfx_name = StringUtils::removeExtension(filename); - /* - if (node->get("name", &sfx_name) == 0) - { - fprintf(stderr, - "/!\\ The 'name' attribute is mandatory in the SFX XML file!\n"); - return; - } - */ + if(m_all_sfx_types.find(sfx_name)!=m_all_sfx_types.end()) { Log::error("SFXManager", diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index a08d9b63b..778f29032 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -250,7 +250,7 @@ void SFXOpenAL::position(const Vec3 &position) return; if (!m_ok) { - fprintf(stderr, "WARNING, position called on non-ok SFX <%s>\n", m_soundBuffer->getFileName().c_str()); + Log::warn("SFX", "Position called on non-ok SFX <%s>", m_soundBuffer->getFileName().c_str()); return; } if (!m_positional) @@ -260,7 +260,7 @@ void SFXOpenAL::position(const Vec3 &position) // (note that 0 players is also possible, in cutscenes) if (race_manager->getNumLocalPlayers() < 2) { - fprintf(stderr, "WARNING, position called on non-positional SFX\n"); + Log::warn("SFX", "Position called on non-positional SFX"); } return; } diff --git a/src/challenges/challenge_data.cpp b/src/challenges/challenge_data.cpp index b0fe57a68..ae0c6ab9d 100644 --- a/src/challenges/challenge_data.cpp +++ b/src/challenges/challenge_data.cpp @@ -73,9 +73,9 @@ ChallengeData::ChallengeData(const std::string& filename) // is not supported anyway (id is needed for warning message) if(!unlock_manager->isSupportedVersion(*this)) { - fprintf(stderr, "[ChallengeData] WARNING: challenge <%s> is older " - "or newer than this version of STK, will be ignored.\n", - filename.c_str()); + Log::warn("ChallengeData", "Challenge <%s> is older " + "or newer than this version of STK, will be ignored.\n", + filename.c_str()); return; } @@ -191,9 +191,8 @@ ChallengeData::ChallengeData(const std::string& filename) } else { - fprintf(stderr, - "[ChallengeData] WARNING: Unknown A superpower '%s'\n", - superPower.c_str()); + Log::warn("ChallengeData", "Unknown superpower '%s'", + superPower.c_str()); } } @@ -241,10 +240,8 @@ ChallengeData::ChallengeData(const std::string& filename) setUnlocks(s, ChallengeData::UNLOCK_DIFFICULTY); else { - fprintf(stderr, "[ChallengeData] unknown unlock entry.\n"); - fprintf(stderr, - "Must be one of kart, track, gp, mode, difficulty.\n"); - exit(-1); + Log::warn("ChallengeData", "Unknown unlock entry. Must be one of kart, track, gp, mode, difficulty."); + throw std::runtime_error("Unknown unlock entry"); } } @@ -266,7 +263,7 @@ void ChallengeData::error(const char *id) const msg << "Undefined or incorrect value for '" << id << "' in challenge file '" << m_filename << "'."; - printf("ChallengeData : %s\n", msg.str().c_str()); + Log::error("ChallengeData", "%s", msg.str().c_str()); throw std::runtime_error(msg.str()); } // error @@ -339,9 +336,9 @@ void ChallengeData::setUnlocks(const std::string &id, RewardType reward) kart_properties_manager->getKart(id); if (prop == NULL) { - fprintf(stderr, "Challenge refers to kart %s, " - "which is unknown. Ignoring reward.\n", - id.c_str()); + Log::warn("ChallengeData", "Challenge refers to kart %s, " + "which is unknown. Ignoring reward.", + id.c_str()); break; } irr::core::stringw user_name = prop->getName(); diff --git a/src/challenges/unlock_manager.cpp b/src/challenges/unlock_manager.cpp index 6b766c06c..119a4c0a2 100644 --- a/src/challenges/unlock_manager.cpp +++ b/src/challenges/unlock_manager.cpp @@ -158,8 +158,8 @@ void UnlockManager::addOrFreeChallenge(ChallengeData *c) m_all_challenges[c->getId()]=c; else { - printf("[challenge] Challenge '%s' is not supported - ignored.\n", - c->getId().c_str()); + Log::warn("Challenge", "Challenge '%s' is not supported - ignored.", + c->getId().c_str()); delete c; } } // addOrFreeChallenge From be934786875d382ca436a7a34faa21a027ddd806 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 19:13:57 +0000 Subject: [PATCH 116/412] GPUParticles: Fix orientation of reemitted particles. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14875 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 5 ++++- src/graphics/gpuparticles.cpp | 5 +++++ src/graphics/gpuparticles.h | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index be30c647c..42eda521f 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -1,6 +1,7 @@ #version 130 uniform int dt; uniform mat4 sourcematrix; +uniform mat4 tinvsourcematrix; in vec3 particle_position_initial; in float lifetime_initial; @@ -20,9 +21,11 @@ out float new_size; void main(void) { vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); + vec4 adjusted_initial_velocity = tinvsourcematrix * vec4(particle_velocity_initial, 1.0); + adjusted_initial_velocity /= adjusted_initial_velocity.w; new_particle_position = (lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; new_lifetime = (lifetime < 1.) ? lifetime + (float(dt)/lifetime_initial) : 0.; - new_particle_velocity = (lifetime < 1.) ? particle_velocity : particle_velocity_initial; + new_particle_velocity = (lifetime < 1.) ? particle_velocity : adjusted_initial_velocity.xyz; new_size = size_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 25f29c347..eeb814744 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -381,6 +381,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); + uniform_tinvsourcematrix = glGetUniformLocation(SimulationProgram, "tinvsourcematrix"); attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); @@ -434,6 +435,9 @@ void ParticleSystemProxy::simulate() LastEmitTime = time; core::matrix4 matrix = getAbsoluteTransformation(); + core::matrix4 tinvmatrix; + matrix.getInverse(tinvmatrix); + tinvmatrix = tinvmatrix.getTransposed(); glUseProgram(SimulationProgram); glEnable(GL_RASTERIZER_DISCARD); glEnableVertexAttribArray(attrib_position); @@ -458,6 +462,7 @@ void ParticleSystemProxy::simulate() glUniform1i(uniform_dt, 16); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); + glUniformMatrix4fv(uniform_tinvsourcematrix, 1, GL_FALSE, tinvmatrix.pointer()); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 2824ffeb3..3e6766c1e 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -34,7 +34,7 @@ protected: GLuint SimulationProgram; GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - GLuint uniform_duration, uniform_sourcematrix, uniform_dt; + GLuint uniform_duration, uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt; GLuint RenderProgram; GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; From 9c163db7c78eade40e7fea0d82be8b9895849f78 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 19:52:32 +0000 Subject: [PATCH 117/412] GPUParticles: Add an parameter to turn alpha additive particle on/off. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14876 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 9 +++++++-- src/graphics/gpuparticles.h | 2 ++ src/graphics/material.hpp | 3 +++ src/graphics/particle_emitter.cpp | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index eeb814744..3180c4a8a 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -230,7 +230,7 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, ISceneNode* parent, scene::ISceneManager* mgr, s32 id, const core::vector3df& position, const core::vector3df& rotation, - const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale) { + const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale), m_alpha_additive(false) { static const GLfloat quad_vertex[] = { -.5, -.5, 0., 0., .5, -.5, 1., 0., @@ -244,6 +244,8 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, glBindBuffer(GL_ARRAY_BUFFER, 0); } +void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } + void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePointEmitter *emitter) { float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; @@ -485,7 +487,10 @@ void ParticleSystemProxy::draw() glEnable(GL_BLEND); core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (m_alpha_additive) + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(RenderProgram); glEnableVertexAttribArray(attrib_pos); glEnableVertexAttribArray(attrib_lf); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 3e6766c1e..514489c28 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -31,6 +31,7 @@ class ParticleSystemProxy : public scene::CParticleSystemSceneNode { protected: GLuint quad_vertex_buffer; GLuint tfb_buffers[2], initial_values_buffer; + bool m_alpha_additive; GLuint SimulationProgram; GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; @@ -62,6 +63,7 @@ public: virtual void setEmitter(scene::IParticleEmitter* emitter); virtual void render(); + void setAlphaAdditive(bool); }; class PointEmitter : public GPUParticle diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index f63e470bb..e14f20de4 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -335,6 +335,9 @@ public: void onMadeVisible(scene::IMeshBuffer* who); void onHidden(scene::IMeshBuffer* who); void isInitiallyHidden(scene::IMeshBuffer* who); + /** For particle system : specify if the particle should be additively blended + */ + bool isAlphaAdditive() const { return !m_alpha_blending; } } ; diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index b2937676d..85f1e8454 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -371,6 +371,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) else { m_node = ParticleSystemProxy::addParticleNode(); + static_cast(m_node)->setAlphaAdditive(type->getMaterial()->isAlphaAdditive()); } if (m_parent != NULL) From 419bea3bfd90a582fcd3faf2114b647ade5f89ba Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 20:20:21 +0000 Subject: [PATCH 118/412] GPUParticles: Avoid recompiling the same shaders over and over, and use a global vbo for quads. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14877 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 74 +++++++++++++++++++++++++---------- src/graphics/gpuparticles.h | 15 +++---- 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 3180c4a8a..78415e76f 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -226,18 +226,22 @@ scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode( return node; } +GLuint ParticleSystemProxy::quad_vertex_buffer = 0; + ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, ISceneNode* parent, scene::ISceneManager* mgr, s32 id, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale), m_alpha_additive(false) { + if (quad_vertex_buffer) + return; + initGL(); static const GLfloat quad_vertex[] = { -.5, -.5, 0., 0., .5, -.5, 1., 0., -.5, .5, 0., 1., .5, .5, 1., 1., }; - initGL(); glGenBuffers(1, &quad_vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertex), quad_vertex, GL_STATIC_DRAW); @@ -309,7 +313,6 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi float sizeMax = emitter->getMaxStartSize().Height; const core::vector3df& extent = emitter->getBox().getExtent(); - printf("particle lifetime [%d-%d]\n", emitter->getMinLifeTime(), emitter->getMaxLifeTime()); for (unsigned i = 0; i < count; i++) { particles[COMPONENTCOUNT * i] = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; @@ -356,6 +359,34 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi delete[] initialvalue; } +GLuint ParticleSystemProxy::SimulationProgram = 0; +GLuint ParticleSystemProxy::RenderProgram = 0; + +GLuint ParticleSystemProxy::attrib_position; +GLuint ParticleSystemProxy::attrib_velocity; +GLuint ParticleSystemProxy::attrib_lifetime; +GLuint ParticleSystemProxy::attrib_initial_position; +GLuint ParticleSystemProxy::attrib_initial_velocity; +GLuint ParticleSystemProxy::attrib_initial_lifetime; +GLuint ParticleSystemProxy::attrib_size; +GLuint ParticleSystemProxy::attrib_initial_size; +GLuint ParticleSystemProxy::uniform_sourcematrix; +GLuint ParticleSystemProxy::uniform_tinvsourcematrix; +GLuint ParticleSystemProxy::uniform_dt; + + +GLuint ParticleSystemProxy::attrib_pos; +GLuint ParticleSystemProxy::attrib_lf; +GLuint ParticleSystemProxy::attrib_quadcorner; +GLuint ParticleSystemProxy::attrib_texcoord; +GLuint ParticleSystemProxy::attrib_sz; +GLuint ParticleSystemProxy::uniform_matrix; +GLuint ParticleSystemProxy::uniform_viewmatrix; +GLuint ParticleSystemProxy::uniform_texture; +GLuint ParticleSystemProxy::uniform_normal_and_depths; +GLuint ParticleSystemProxy::uniform_screen; +GLuint ParticleSystemProxy::uniform_invproj; + void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) { if (!emitter) @@ -368,16 +399,31 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) setAutomaticCulling(0); LastEmitTime = 0; - duration = emitter->getMaxLifeTime(); - count = emitter->getMaxParticlesPerSecond() * duration / 1000; + count = emitter->getMaxParticlesPerSecond() * emitter->getMaxParticlesPerSecond() / 1000; + switch (emitter->getType()) + { + case scene::EPET_POINT: + generateParticlesFromPointEmitter(emitter); + break; + case scene::EPET_BOX: + generateParticlesFromBoxEmitter(static_cast(emitter)); + break; + default: + assert(0 && "Wrong particle type"); + } + + texture = getTextureGLuint(getMaterial(0).getTexture(0)); + normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + + if (SimulationProgram && RenderProgram) + return; + const char *varyings[] = { "new_particle_position", "new_lifetime", "new_particle_velocity", "new_size", }; - texture = getTextureGLuint(getMaterial(0).getTexture(0)); - normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 4); @@ -407,21 +453,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_invproj = glGetUniformLocation(RenderProgram, "invproj"); uniform_screen = glGetUniformLocation(RenderProgram, "screen"); uniform_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - - switch (emitter->getType()) - { - case scene::EPET_POINT: - generateParticlesFromPointEmitter(emitter); - break; - case scene::EPET_BOX: - generateParticlesFromBoxEmitter(static_cast(emitter)); - break; - default: - assert(0 && "Wrong particle type"); - } - } - - +} void ParticleSystemProxy::simulate() { diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 514489c28..1217d69b2 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,17 +29,18 @@ public: class ParticleSystemProxy : public scene::CParticleSystemSceneNode { protected: - GLuint quad_vertex_buffer; GLuint tfb_buffers[2], initial_values_buffer; bool m_alpha_additive; - GLuint SimulationProgram; - GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - GLuint uniform_duration, uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt; + static GLuint SimulationProgram; + static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; + static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt; - GLuint RenderProgram; - GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; - GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + static GLuint RenderProgram; + static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; + static GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + + static GLuint quad_vertex_buffer; GLuint texture, normal_and_depth; unsigned duration, count, LastEmitTime; From 9fe6b6a6e9daf5b2fd96ccd534021d810661d806 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 20:32:18 +0000 Subject: [PATCH 119/412] GPUParticles: Clean vbo memory when ParticleSystemProxy is deleted git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14878 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 22 +++++++++++++++++----- src/graphics/gpuparticles.h | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 78415e76f..b70237f31 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -46,10 +46,15 @@ PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; PFNGLBLENDEQUATIONPROC glBlendEquation; PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; +PFNGLDELETEBUFFERSPROC glDeleteBuffers; #endif +static bool is_gl_init = false; void initGL() { + if (is_gl_init) + return; + is_gl_init = true; #ifdef _IRR_WINDOWS_API_ glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); @@ -87,6 +92,7 @@ void initGL() glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation"); glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor"); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); #endif } @@ -233,9 +239,11 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale), m_alpha_additive(false) { + initGL(); + glGenBuffers(1, &initial_values_buffer); + glGenBuffers(2, tfb_buffers); if (quad_vertex_buffer) return; - initGL(); static const GLfloat quad_vertex[] = { -.5, -.5, 0., 0., .5, -.5, 1., 0., @@ -248,6 +256,12 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, glBindBuffer(GL_ARRAY_BUFFER, 0); } +ParticleSystemProxy::~ParticleSystemProxy() +{ + glDeleteBuffers(2, tfb_buffers); + glDeleteBuffers(1, &initial_values_buffer); +} + void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePointEmitter *emitter) @@ -292,7 +306,7 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; } - glGenBuffers(1, &initial_values_buffer); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); glGenBuffers(2, tfb_buffers); @@ -347,10 +361,8 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; } - glGenBuffers(1, &initial_values_buffer); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); - glGenBuffers(2, tfb_buffers); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); @@ -399,7 +411,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) setAutomaticCulling(0); LastEmitTime = 0; - count = emitter->getMaxParticlesPerSecond() * emitter->getMaxParticlesPerSecond() / 1000; + count = emitter->getMaxParticlesPerSecond() * emitter->getMaxLifeTime() / 1000; switch (emitter->getType()) { case scene::EPET_POINT: diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 1217d69b2..ba70a9fa7 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -61,6 +61,7 @@ public: const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale); + ~ParticleSystemProxy(); virtual void setEmitter(scene::IParticleEmitter* emitter); virtual void render(); From 0f97aee66a1be35a51a885c3b72b9c38b11c9cee Mon Sep 17 00:00:00 2001 From: auria Date: Wed, 1 Jan 2014 21:18:06 +0000 Subject: [PATCH 120/412] Remove the old LOD loading code, we now support only the new much cleaner way. Will need to re-export all tracks that use LOD, meanwhile LOD objects will be missing from tracks git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14879 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/lod_node_loader.cpp | 186 +++++++---------------- src/tracks/lod_node_loader.hpp | 37 ++--- src/tracks/track.cpp | 90 ++++------- src/tracks/track_object.cpp | 16 +- src/tracks/track_object.hpp | 6 +- src/tracks/track_object_manager.cpp | 33 +--- src/tracks/track_object_manager.hpp | 9 +- src/tracks/track_object_presentation.cpp | 9 +- src/tracks/track_object_presentation.hpp | 5 +- 9 files changed, 129 insertions(+), 262 deletions(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index abdcca639..d9add8869 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -29,174 +29,104 @@ using namespace irr; #include #include -LodNodeLoader::LodNodeLoader() +LodNodeLoader::LodNodeLoader(Track* track) { + m_track = track; } // ---------------------------------------------------------------------------- -bool PairCompare(const std::pair& i, const std::pair& j) -{ - return (i.first < j.first); -} - -// ---------------------------------------------------------------------------- - -/** Check a XML node in case it contains a LOD object and if so remember it */ -bool LodNodeLoader::check(const XMLNode* xml, scene::ISceneNode* parent) +void LodNodeLoader::addLODModelDefinition(const XMLNode* xml) { float lod_distance = -1.0f; xml->get("lod_distance", &lod_distance); - bool lod_instance = false; - xml->get("lod_instance", &lod_instance); - std::string lodgroup; xml->get("lod_group", &lodgroup); bool tangent = false; xml->get("tangents", &tangent); - if (!lodgroup.empty()) - { - if (lod_instance) - { - lod_instances[lodgroup].push_back(LodInstance(xml, parent)); - } - else - { - std::string model_name; - xml->get("model", &model_name); + std::string model_name; + xml->get("model", &model_name); - lod_groups[lodgroup][(int)lod_distance] = LodModel(xml, model_name, tangent); - } - return true; - } - else - { - return false; - } + m_lod_groups[lodgroup].push_back(LodModel(xml, (int)lod_distance, model_name, tangent)); } // ---------------------------------------------------------------------------- -/** - * Call when the XML file is fully parsed and we're ready to create the node - * @param cache the individual meshes will be added there - * @param[out] out the nodes are added here - */ -void LodNodeLoader::done(Track* track, - std::string directory, - std::vector& cache, - std::vector& out) +LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* parent) + //Track* track, std::vector& cache) { scene::ISceneManager* sm = irr_driver->getSceneManager(); - // Creating LOD nodes is more complicated than one might have hoped, on the C++ side; - // but it was done this way to minimize the work needed on the side of the artists + std::string groupname = ""; + node->get("lod_group", &groupname); - // 1. Sort LOD groups (highest detail first, lowest detail last) - std::map > > sorted_lod_groups; + std::vector< LodModel >& group = m_lod_groups[groupname]; - std::map >::iterator it; - for (it = lod_groups.begin(); it != lod_groups.end(); it++) + //core::vector3df xyz(0,0,0); + //node->get("xyz", &xyz); + //core::vector3df hpr(0,0,0); + //node->get("hpr", &hpr); + //core::vector3df scale(1.0f, 1.0f, 1.0f); + //node->get("scale", &scale); + + if (group.size() > 0) { - std::map::iterator it2; - for (it2 = it->second.begin(); it2 != it->second.end(); it2++) + scene::ISceneNode* actual_parent = (parent == NULL ? sm->getRootSceneNode() : parent); + LODNode* lod_node = new LODNode(groupname, actual_parent, sm); + //lod_node->setPosition(xyz); + //lod_node->setRotation(hpr); + //lod_node->setScale(scale); + lod_node->updateAbsolutePosition(); + for (unsigned int m=0; mfirst, it2->second.c_str(), it->first.c_str()); - sorted_lod_groups[it->first].push_back( std::pair(it2->first, it2->second) ); - } - std::sort( sorted_lod_groups[it->first].begin(), sorted_lod_groups[it->first].end(), PairCompare ); + // TODO: check whether the mesh contains animations or not? + scene::IMesh* a_mesh = irr_driver->getMesh(group[m].m_model_file); - //printf("Group '%s' :\n", it->first.c_str()); - //for (unsigned int x=0; xfirst].size(); x++) - //{ - // printf(" - (%i) %s\n", sorted_lod_groups[it->first][x].first, sorted_lod_groups[it->first][x].second.c_str()); - //} - } - - // 2. Read the XML nodes and instanciate LOD scene nodes where relevant - std::string groupname; - std::map< std::string, std::vector< LodInstance > >::iterator it3; - for (it3 = lod_instances.begin(); it3 != lod_instances.end(); it3++) - { - std::vector< std::pair >& group = sorted_lod_groups[it3->first]; - - std::vector< LodInstance >& v = it3->second; - for (unsigned int n=0; nget("lod_group", &groupname); - //if (model_name != sorted_lod_groups[it3->first][0].second) continue; - - core::vector3df xyz(0,0,0); - node->get("xyz", &xyz); - core::vector3df hpr(0,0,0); - node->get("hpr", &hpr); - core::vector3df scale(1.0f, 1.0f, 1.0f); - node->get("scale", &scale); - - if (group.size() > 0) + if (!a_mesh) { - scene::ISceneNode* parent = (v[n].m_parent == NULL ? sm->getRootSceneNode() : v[n].m_parent); - LODNode* lod_node = new LODNode(groupname, parent, sm); - lod_node->setPosition(xyz); - lod_node->setRotation(hpr); - lod_node->setScale(scale); - lod_node->updateAbsolutePosition(); - for (unsigned int m=0; mgetMesh(group[m].second.m_model_file); + Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", + group[m].m_model_file.c_str()); + continue; + } - if (!a_mesh) - { - Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n", - group[m].second.m_model_file.c_str()); - continue; - } + if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) + { + scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); + scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); + // FIXME: do we need to clean up 'a_mesh' ? + a_mesh = m2; + irr_driver->setAllMaterialFlags(a_mesh); + } - if (group[m].second.m_tangent) - { - scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); - scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); - // FIXME: do we need to clean up 'a_mesh' ? - a_mesh = m2; - irr_driver->setAllMaterialFlags(a_mesh); + a_mesh->grab(); + //cache.push_back(a_mesh); + irr_driver->grabAllTextures(a_mesh); + scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh); - } + m_track->handleAnimatedTextures( scene_node, *group[m].m_xml ); - a_mesh->grab(); - cache.push_back(a_mesh); - irr_driver->grabAllTextures(a_mesh); - scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh); - - track->handleAnimatedTextures( scene_node, *group[m].second.m_xml ); - - lod_node->add( group[m].first, scene_node, true ); - } + lod_node->add( group[m].m_distance, scene_node, true ); + } #ifdef DEBUG - std::string debug_name = groupname+" (LOD track-object)"; - lod_node->setName(debug_name.c_str()); + std::string debug_name = groupname+" (LOD track-object)"; + lod_node->setName(debug_name.c_str()); #endif - out.push_back(lod_node); - } - else - { - fprintf(stderr, "[LodNodeLoader] WARNING, LOD group '%s' is empty\n", groupname.c_str()); - } - } - } // end for + return lod_node; + } + else + { + Log::warn("LodNodeLoader", "LOD group '%s' is empty", groupname.c_str()); + return NULL; + } } // ---------------------------------------------------------------------------- void LodNodeLoader::clear() { - lod_groups.clear(); - lod_instances.clear(); + m_lod_groups.clear(); } diff --git a/src/tracks/lod_node_loader.hpp b/src/tracks/lod_node_loader.hpp index d3c551b15..29e97b747 100644 --- a/src/tracks/lod_node_loader.hpp +++ b/src/tracks/lod_node_loader.hpp @@ -36,43 +36,28 @@ namespace irr } } -struct LodInstance -{ - const XMLNode* m_xml_node; - scene::ISceneNode* m_parent; - - /** Constructor to allow storing this in STL containers */ - LodInstance() - { - m_parent = NULL; - m_xml_node = NULL; - } - - LodInstance(const XMLNode* xml_node, scene::ISceneNode* parent) - { - m_xml_node = xml_node; - m_parent = parent; - } -}; struct LodModel { std::string m_model_file; bool m_tangent; const XMLNode* m_xml; + int m_distance; /** Constructor to allow storing this in STL containers */ LodModel() { m_tangent = false; + m_distance = 0; m_xml = NULL; } - LodModel(const XMLNode* xml, std::string& model, bool tangent) + LodModel(const XMLNode* xml, int distance, std::string& model, bool tangent) { m_model_file = model; m_tangent = tangent; m_xml = xml; + m_distance = distance; } ~LodModel() @@ -86,17 +71,15 @@ struct LodModel class LodNodeLoader { private: - std::map< std::string, std::map< int, LodModel > > lod_groups; - std::map< std::string, std::vector< LodInstance > > lod_instances; + std::map< std::string, std::vector< LodModel > > m_lod_groups; + Track* m_track; public: - LodNodeLoader(); + LodNodeLoader(Track* track); - bool check(const XMLNode* xml, scene::ISceneNode* parent); - void done(Track* track, - std::string directory, - std::vector& cache, - std::vector& out); + void addLODModelDefinition(const XMLNode* xml); + LODNode* instanciate(const XMLNode* xml_node, scene::ISceneNode* parent); + //Track* track, std::vector& cache); void clear(); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 34e19affc..895f9f7cd 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -854,7 +854,7 @@ bool Track::loadMainTrack(const XMLNode &root) m_aabb_max.setY(m_aabb_max.getY()+30.0f); World::getWorld()->getPhysics()->init(m_aabb_min, m_aabb_max); - LodNodeLoader lodLoader; + LodNodeLoader lodLoader(this); // Load LOD groups const XMLNode *lod_xml_node = root.getNode("lod"); @@ -865,10 +865,7 @@ bool Track::loadMainTrack(const XMLNode &root) const XMLNode* lod_group_xml = lod_xml_node->getNode(i); for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) { - // TODO: eventually, remove support for the old way of specifying LOD - // definitions among node, and support only the new way of using - // a section. Then, the LOD loading sequence can be simplified a lot - lodLoader.check(lod_group_xml->getNode(j), NULL); + lodLoader.addLODModelDefinition(lod_group_xml->getNode(j)); } } } @@ -1033,7 +1030,8 @@ bool Track::loadMainTrack(const XMLNode &root) std::string challenge; n->get("challenge", &challenge); - bool is_lod = lodLoader.check(n, NULL); + bool lod_instance = false; + n->get("lod_instance", &lod_instance); if (tangent) { @@ -1078,9 +1076,17 @@ bool Track::loadMainTrack(const XMLNode &root) handleAnimatedTextures(scene_node, *n); m_all_nodes.push_back( scene_node ); } - else if (is_lod) + else if (lod_instance) { - // nothing to do + LODNode* node = lodLoader.instanciate(n, NULL); + if (node != NULL) + { + node->setPosition(xyz); + node->setRotation(hpr); + node->setScale(scale); + + m_all_nodes.push_back( node ); + } } else { @@ -1198,16 +1204,6 @@ bool Track::loadMainTrack(const XMLNode &root) } // for i - // Create LOD nodes - std::vector lod_nodes; - lodLoader.done(this, m_root, m_all_cached_meshes, lod_nodes); - for (unsigned int n=0; n library_nodes; - loadObjects(root, path, lod_loader, true, NULL, library_nodes); + LodNodeLoader lod_loader(this); - // -------- Create and assign LOD nodes -------- - // recheck the static area, we will need LOD info - const XMLNode* track_node = root->getNode("track"); - if (track_node != NULL) + // Load LOD groups + const XMLNode *lod_xml_node = root->getNode("lod"); + if (lod_xml_node != NULL) { - for (unsigned int i=0; igetNumNodes(); i++) + for (unsigned int i = 0; i < lod_xml_node->getNumNodes(); i++) { - const XMLNode* n = track_node->getNode(i); - bool is_instance = false; - n->get("lod_instance", &is_instance); - - if (!is_instance) lod_loader.check(n, NULL); + const XMLNode* lod_group_xml = lod_xml_node->getNode(i); + for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) + { + lod_loader.addLODModelDefinition(lod_group_xml->getNode(j)); + } } } - std::vector lod_nodes; - std::vector devnull; - lod_loader.done(this, m_root, devnull, lod_nodes); - - m_track_object_manager->assingLodNodes(lod_nodes); - // --------------------------------------------- + std::map library_nodes; + loadObjects(root, path, lod_loader, true, NULL, library_nodes); // Cleanup library nodes for (std::map::iterator it = library_nodes.begin(); @@ -1736,23 +1725,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa if (name == "track" || name == "default-start") continue; if (name == "object") { - bool is_instance = false; - node->get("lod_instance", &is_instance); - - float lod_distance = -1; - node->get("lod_distance", &lod_distance); - - if (lod_distance > 0.0f && !is_instance) - { - // lod definition - if (create_lod_definitions) - lod_loader.check(node, parent); - } - else - { - lod_loader.check(node, parent); - } - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } else if (name == "library") { @@ -1790,10 +1763,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa const XMLNode* lod_group_xml = lod_xml_node->getNode(i); for (unsigned int j = 0; j < lod_group_xml->getNumNodes(); j++) { - // TODO: eventually, remove support for the old way of specifying LOD - // definitions among node, and support only the new way of using - // a section. Then, the LOD loading sequence can be simplified a lot - lod_loader.check(lod_group_xml->getNode(j), NULL); + lod_loader.addLODModelDefinition(lod_group_xml->getNode(j)); } } } @@ -1851,7 +1821,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa { if (UserConfigParams::m_graphical_effects) { - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } } else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") @@ -1864,7 +1834,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa } else if (name == "light") { - m_track_object_manager->add(*node, parent); + m_track_object_manager->add(*node, parent, lod_loader); } else if (name == "weather") { diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index f10c47366..42f9f30a0 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -38,9 +38,9 @@ * model, enable/disable status, timer information. * \param lod_node Lod node (defaults to NULL). */ -TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) +TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { - init(xml_node, parent, lod_node); + init(xml_node, parent, lod_loader); } // ---------------------------------------------------------------------------- @@ -79,7 +79,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, // ---------------------------------------------------------------------------- -void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lod_node) +void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { m_init_xyz = core::vector3df(0,0,0); m_init_hpr = core::vector3df(0,0,0); @@ -99,6 +99,9 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNo xml_node.get("interaction", &m_interaction); xml_node.get("lod_group", &m_lod_group); + bool lod_instance = false; + xml_node.get("lod_instance", &lod_instance); + m_soccer_ball = false; xml_node.get("soccer_ball", &m_soccer_ball); @@ -152,12 +155,13 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNo { scene::ISceneNode *glownode = NULL; - if (lod_node != NULL) + if (lod_instance) { m_type = "lod"; - m_presentation = new TrackObjectPresentationLOD(xml_node, lod_node); + TrackObjectPresentationLOD* lod_node = new TrackObjectPresentationLOD(xml_node, parent, lod_loader); + m_presentation = lod_node; - glownode = lod_node->getAllNodes()[0]; + glownode = ((LODNode*)lod_node->getNode())->getAllNodes()[0]; } else { diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 8c41bbd73..4fca007e6 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -31,7 +31,7 @@ class XMLNode; class ThreeDAnimation; - +class LodNodeLoader; /** * \ingroup tracks @@ -82,10 +82,10 @@ protected: ThreeDAnimation* m_animator; - void init(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode); + void init(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); public: - TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LODNode* lodNode=NULL); + TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); TrackObject(const core::vector3df& xyz, const core::vector3df& hpr, diff --git a/src/tracks/track_object_manager.cpp b/src/tracks/track_object_manager.cpp index 60ffe4c66..6e20f4208 100644 --- a/src/tracks/track_object_manager.cpp +++ b/src/tracks/track_object_manager.cpp @@ -49,31 +49,16 @@ TrackObjectManager::~TrackObjectManager() * in a separate section that's read before everything and remove all this * crap */ -void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent) +void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader) { try { - std::string groupname; - xml_node.get("lod_group", &groupname); - bool is_lod = !groupname.empty(); - - if (is_lod) - { - bool lod_instance = false; - xml_node.get("lod_instance", &lod_instance); - - if (lod_instance) - m_lod_objects[groupname].push_back(&xml_node); - } - else - { - m_all_objects.push_back(new TrackObject(xml_node, parent)); - } + m_all_objects.push_back(new TrackObject(xml_node, parent, lod_loader)); } catch (std::exception& e) { - fprintf(stderr, "[TrackObjectManager] WARNING: Could not load track object. Reason : %s\n", - e.what()); + Log::warn("TrackObjectManager", "Could not load track object. Reason : %s", + e.what()); } } // add @@ -219,13 +204,8 @@ void TrackObjectManager::removeObject(TrackObject* obj) } // removeObject // ---------------------------------------------------------------------------- -/** - * \brief To be called after all objects are loaded and the LodNodeLoader is done - * parsing everything. - * This method exists because LOD objects need to be created after others. - * - * \param lod_nodes the LOD nodes created by the LodNodeLoader. - */ + +/* void TrackObjectManager::assingLodNodes(const std::vector& lod_nodes) { for (unsigned int n=0; n& lod_nodes) m_lod_objects.clear(); } +*/ \ No newline at end of file diff --git a/src/tracks/track_object_manager.hpp b/src/tracks/track_object_manager.hpp index 5539f08cd..f45bd390d 100644 --- a/src/tracks/track_object_manager.hpp +++ b/src/tracks/track_object_manager.hpp @@ -46,15 +46,10 @@ protected: enum TrackObjectType {TO_PHYSICAL, TO_GRAPHICAL}; PtrVector m_all_objects; - /** Temporary storage for LOD objects whose XML node was read but whose - * scene node is not yet ready - */ - std::map > m_lod_objects; - public: TrackObjectManager(); ~TrackObjectManager(); - void add(const XMLNode &xml_node, scene::ISceneNode* parent); + void add(const XMLNode &xml_node, scene::ISceneNode* parent, LodNodeLoader& lod_loader); void update(float dt); void handleExplosion(const Vec3 &pos, const PhysicalObject *mp, bool secondary_hits=true); @@ -68,8 +63,6 @@ public: void removeObject(TrackObject* who); - void assingLodNodes(const std::vector& lod); - PtrVector& getObjects() { return m_all_objects; } const PtrVector& getObjects() const { return m_all_objects; } diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 3e23509b2..21975a93a 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -32,6 +32,7 @@ #include "modes/world.hpp" #include "states_screens/dialogs/race_paused_dialog.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp" +#include "tracks/lod_node_loader.hpp" #include "tracks/track.hpp" #include @@ -125,10 +126,12 @@ TrackObjectPresentationEmpty::~TrackObjectPresentationEmpty() // ---------------------------------------------------------------------------- -TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node) : +TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, + scene::ISceneNode* parent, LodNodeLoader& lod_loader) : TrackObjectPresentationSceneNode(xml_node) { - m_node = lod_node; + m_node = lod_loader.instanciate(&xml_node, parent); + if (m_node == NULL) throw std::exception("Cannot load LOD node"); m_node->setPosition(m_init_xyz); m_node->setRotation(m_init_hpr); m_node->setScale(m_init_scale); @@ -136,8 +139,8 @@ TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, TrackObjectPresentationLOD::~TrackObjectPresentationLOD() { - irr_driver->removeNode(m_node); } + // ---------------------------------------------------------------------------- TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node, diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index a4d64c457..e12c3fdd5 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -40,6 +40,7 @@ class SFXBase; class ParticleEmitter; class PhysicalObject; class ThreeDAnimation; +class LodNodeLoader; /** * \ingroup tracks @@ -147,7 +148,9 @@ class TrackObjectPresentationLOD : public TrackObjectPresentationSceneNode { public: - TrackObjectPresentationLOD(const XMLNode& xml_node, LODNode* lod_node); + TrackObjectPresentationLOD(const XMLNode& xml_node, + scene::ISceneNode* parent, + LodNodeLoader& lod_loader); virtual ~TrackObjectPresentationLOD(); }; From 93643d660f7103061e942a402cb41c210cc3e1f8 Mon Sep 17 00:00:00 2001 From: auria Date: Wed, 1 Jan 2014 21:21:48 +0000 Subject: [PATCH 121/412] misc minor stuff git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14880 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/material.cpp | 2 +- src/states_screens/dialogs/addons_loading.cpp | 9 +++++---- src/tracks/track_object_presentation.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index dc0b64cd9..b34d36376 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -644,7 +644,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m (m->getTexture(0) != NULL && ((core::stringc)m->getTexture(0)->getName()).find("deprecated") != -1)) { - Log::warn("material", "Track uses deprecated texture '%s'\n", + Log::warn("material", "Track uses deprecated texture '%s'", m_texname.c_str()); } diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index e1cefaf61..41fbb1b87 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -132,10 +132,11 @@ void AddonsLoading::beforeAddingWidgets() else if(m_addon.testStatus(Addon::AS_RC)) l.push_back("RC"); - if(m_addon.testStatus(Addon::AS_BAD_DIM)) - l.push_back("bad-texture"); - if(!m_addon.testStatus(Addon::AS_DFSG)) - l.push_back("non-DFSG"); + // Don't displat those for now, they're more confusing than helpful for the average player + //if(m_addon.testStatus(Addon::AS_BAD_DIM)) + // l.push_back("bad-texture"); + //if(!m_addon.testStatus(Addon::AS_DFSG)) + // l.push_back("non-DFSG"); } if(m_addon.testStatus(Addon::AS_FEATURED)) l.push_back(_("featured")); diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 21975a93a..fc30f85ce 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -131,7 +131,7 @@ TrackObjectPresentationLOD::TrackObjectPresentationLOD(const XMLNode& xml_node, TrackObjectPresentationSceneNode(xml_node) { m_node = lod_loader.instanciate(&xml_node, parent); - if (m_node == NULL) throw std::exception("Cannot load LOD node"); + if (m_node == NULL) throw std::runtime_error("Cannot load LOD node"); m_node->setPosition(m_init_xyz); m_node->setRotation(m_init_hpr); m_node->setScale(m_init_scale); From 66ab51789f9d042db5f111bfdf6012c29eaf25ac Mon Sep 17 00:00:00 2001 From: vincentlj Date: Wed, 1 Jan 2014 21:36:13 +0000 Subject: [PATCH 122/412] GPUParticles: Implements SphereEmitter. Explosion looks a bit like a geyser of flame, needs tweaking. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14881 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 67 +++++++++++++++++++++++++++++++++-- src/graphics/gpuparticles.h | 1 + 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index b70237f31..2709eda82 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -371,6 +371,66 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi delete[] initialvalue; } +void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSphereEmitter *emitter) +{ + float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; + unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + + float sizeMin = emitter->getMinStartSize().Height; + float sizeMax = emitter->getMaxStartSize().Height; + + for (unsigned i = 0; i < count; i++) { + // Random distance from center + const f32 distance = os::Randomizer::frand() * emitter->getRadius(); + + // Random direction from center + vector3df pos = emitter->getCenter() + distance; + pos.rotateXYBy(os::Randomizer::frand() * 360.f, emitter->getCenter()); + pos.rotateYZBy(os::Randomizer::frand() * 360.f, emitter->getCenter()); + pos.rotateXZBy(os::Randomizer::frand() * 360.f, emitter->getCenter()); + + particles[COMPONENTCOUNT * i] = pos.X; + particles[COMPONENTCOUNT * i + 1] = pos.Y; + particles[COMPONENTCOUNT * i + 2] = pos.Z; + // Initial lifetime is 0 percent + particles[COMPONENTCOUNT * i + 3] = rand(); + particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + + initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; + initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; + initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; + initialvalue[COMPONENTCOUNT * i + 3] = (lifetime_range > 0) ? rand() % lifetime_range : 0; + initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); + + core::vector3df particledir = emitter->getDirection(); + particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + + float size = rand(); + size /= RAND_MAX; + size *= (sizeMax - sizeMin); + size += sizeMin; + + initialvalue[COMPONENTCOUNT * i + 7] = size; + + particles[COMPONENTCOUNT * i + 4] = particledir.X / size; + particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; + particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; + initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; + initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; + initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; + } + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); + glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + delete[] particles; + delete[] initialvalue; +} + GLuint ParticleSystemProxy::SimulationProgram = 0; GLuint ParticleSystemProxy::RenderProgram = 0; @@ -404,7 +464,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) if (!emitter) return; CParticleSystemSceneNode::setEmitter(emitter); - if (emitter->getType() != scene::EPET_POINT && emitter->getType() != scene::EPET_BOX) + if (emitter->getType() != scene::EPET_POINT && emitter->getType() != scene::EPET_BOX && emitter->getType() != scene::EPET_SPHERE) return; // Pass a fake material type to force irrlicht to update its internal states on rendering setMaterialType(irr_driver->getShader(ES_RAIN)); @@ -420,6 +480,9 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) case scene::EPET_BOX: generateParticlesFromBoxEmitter(static_cast(emitter)); break; + case scene::EPET_SPHERE: + generateParticlesFromSphereEmitter(static_cast(emitter)); + break; default: assert(0 && "Wrong particle type"); } @@ -585,7 +648,7 @@ void ParticleSystemProxy::draw() } void ParticleSystemProxy::render() { - if (getEmitter()->getType() != scene::EPET_POINT && getEmitter()->getType() != scene::EPET_BOX) + if (getEmitter()->getType() != scene::EPET_POINT && getEmitter()->getType() != scene::EPET_BOX && getEmitter()->getType() != scene::EPET_SPHERE) { CParticleSystemSceneNode::render(); return; diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index ba70a9fa7..27b83f8d0 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -49,6 +49,7 @@ protected: virtual void draw(); void generateParticlesFromPointEmitter(scene::IParticlePointEmitter *); void generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter *); + void generateParticlesFromSphereEmitter(scene::IParticleSphereEmitter *); public: static IParticleSystemSceneNode *addParticleNode( bool withDefaultEmitter = true, ISceneNode* parent = 0, s32 id = -1, From 2a1a28c459f4aa177901e220ef6465cd52ecb57e Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 00:53:41 +0000 Subject: [PATCH 123/412] GPUParticles: Avoid emitting particle at (0,0,0) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14882 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 35 ++++++++++++++++++------------- src/graphics/particle_emitter.cpp | 13 +++++++++++- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2709eda82..f54fdae09 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -276,9 +276,8 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin particles[COMPONENTCOUNT * i] = 0; particles[COMPONENTCOUNT * i + 1] = 0; particles[COMPONENTCOUNT * i + 2] = 0; - // Initial lifetime is 0 percent - particles[COMPONENTCOUNT * i + 3] = rand(); - particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + // Initial lifetime is >1 + particles[COMPONENTCOUNT * i + 3] = 2.; initialvalue[COMPONENTCOUNT * i] = 0.; initialvalue[COMPONENTCOUNT * i + 1] = 0.; @@ -309,7 +308,6 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); - glGenBuffers(2, tfb_buffers); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); @@ -332,9 +330,8 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi particles[COMPONENTCOUNT * i] = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; particles[COMPONENTCOUNT * i + 1] = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; particles[COMPONENTCOUNT * i + 2] = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; - // Initial lifetime is 0 percent - particles[COMPONENTCOUNT * i + 3] = rand(); - particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + // Initial lifetime is > 1 + particles[COMPONENTCOUNT * i + 3] = 2.; initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; @@ -392,9 +389,8 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph particles[COMPONENTCOUNT * i] = pos.X; particles[COMPONENTCOUNT * i + 1] = pos.Y; particles[COMPONENTCOUNT * i + 2] = pos.Z; - // Initial lifetime is 0 percent - particles[COMPONENTCOUNT * i + 3] = rand(); - particles[COMPONENTCOUNT * i + 3] /= RAND_MAX; + // Initial lifetime is > 1 + particles[COMPONENTCOUNT * i + 3] = 2.; initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; @@ -459,12 +455,23 @@ GLuint ParticleSystemProxy::uniform_normal_and_depths; GLuint ParticleSystemProxy::uniform_screen; GLuint ParticleSystemProxy::uniform_invproj; +static bool isGPUParticleType(scene::E_PARTICLE_EMITTER_TYPE type) +{ + switch (type) + { + case scene::EPET_POINT: + case scene::EPET_BOX: + case scene::EPET_SPHERE: + return true; + default: + return false; + } +} + void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) { - if (!emitter) - return; CParticleSystemSceneNode::setEmitter(emitter); - if (emitter->getType() != scene::EPET_POINT && emitter->getType() != scene::EPET_BOX && emitter->getType() != scene::EPET_SPHERE) + if (!emitter || !isGPUParticleType(emitter->getType())) return; // Pass a fake material type to force irrlicht to update its internal states on rendering setMaterialType(irr_driver->getShader(ES_RAIN)); @@ -648,7 +655,7 @@ void ParticleSystemProxy::draw() } void ParticleSystemProxy::render() { - if (getEmitter()->getType() != scene::EPET_POINT && getEmitter()->getType() != scene::EPET_BOX && getEmitter()->getType() != scene::EPET_SPHERE) + if (!getEmitter() || !isGPUParticleType(getEmitter()->getType())) { CParticleSystemSceneNode::render(); return; diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 85f1e8454..df818cd51 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -317,17 +317,28 @@ void ParticleEmitter::setCreationRateAbsolute(float f) m_min_rate = f; m_max_rate = f; +#if 0 // FIXME: to work around irrlicht bug, when an emitter is paused by setting the rate // to 0 results in a massive emission when enabling it back. In irrlicht 1.8 // the node has a method called "clearParticles" that should be cleaner than this + if (f <= 0.0f && m_node->getEmitter()) { - m_node->setEmitter(NULL); + m_node->clearParticles(); } else if (m_node->getEmitter() == NULL) { m_node->setEmitter(m_emitter); } +#endif + if (f <= 0.0f) + { + m_node->setVisible(false); + } + else + { + m_node->setVisible(true); + } } // setCreationRateAbsolute //----------------------------------------------------------------------------- From c25e1c2472bdc1ebd2030f53ec32cacb1c8d4a8c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 01:06:21 +0000 Subject: [PATCH 124/412] GPUParticles: Use a better fake material that modelize well which states we touch. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14883 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 8 ++++++-- src/graphics/gpuparticles.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index f54fdae09..19ffca029 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -240,6 +240,11 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, const core::vector3df& rotation, const core::vector3df& scale) : CParticleSystemSceneNode(createDefaultEmitter, parent, mgr, id, position, rotation, scale), m_alpha_additive(false) { initGL(); + fakemat.Lighting = false; + fakemat.ZWriteEnable = false; + fakemat.MaterialType = irr_driver->getShader(ES_RAIN); + fakemat.Thickness = 200; + fakemat.setTexture(0, getMaterial(0).getTexture(0)); glGenBuffers(1, &initial_values_buffer); glGenBuffers(2, tfb_buffers); if (quad_vertex_buffer) @@ -650,7 +655,6 @@ void ParticleSystemProxy::draw() glDisableVertexAttribArray(attrib_sz); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); - glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE); } @@ -664,7 +668,7 @@ void ParticleSystemProxy::render() { draw(); // We need to force irrlicht to update its internal states irr::video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setMaterial(getMaterial(0)); + drv->setMaterial(fakemat); static_cast(drv)->setRenderStates3DMode(); } diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 27b83f8d0..2806f6f30 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,6 +29,7 @@ public: class ParticleSystemProxy : public scene::CParticleSystemSceneNode { protected: + video::SMaterial fakemat; GLuint tfb_buffers[2], initial_values_buffer; bool m_alpha_additive; From ea7231170ab5d00e3ea5f8688a5bbae1fc797aca Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 2 Jan 2014 01:27:15 +0000 Subject: [PATCH 125/412] Remove unused light distance property git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14884 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/irr_driver.cpp | 16 ++++++++++++---- src/graphics/irr_driver.hpp | 2 +- src/graphics/light.cpp | 2 +- src/graphics/light.hpp | 6 +++--- src/graphics/sun.cpp | 2 +- src/tracks/track.cpp | 2 +- src/tracks/track_object_presentation.cpp | 6 +++--- src/tracks/track_object_presentation.hpp | 2 +- 8 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index b9b0a43d5..0a621677e 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2036,6 +2036,8 @@ video::ITexture* IrrDriver::RTTProvider::renderToTexture(float angle, return m_render_target_texture; } +// ---------------------------------------------------------------------------- + void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimlit) { if (!m_glsl) @@ -2102,6 +2104,8 @@ void IrrDriver::applyObjectPassShader(scene::ISceneNode * const node, bool rimli } } +// ---------------------------------------------------------------------------- + void IrrDriver::applyObjectPassShader() { if (!m_glsl) @@ -2110,15 +2114,17 @@ void IrrDriver::applyObjectPassShader() applyObjectPassShader(m_scene_manager->getRootSceneNode()); } -scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, - float energy, float r, float g, float b, bool sun, scene::ISceneNode* parent) +// ---------------------------------------------------------------------------- + +scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, + float r, float g, float b, bool sun, scene::ISceneNode* parent) { if (m_glsl) { LightNode *light = NULL; if (!sun) - light = new LightNode(m_scene_manager, parent, radius, energy, r, g, b); + light = new LightNode(m_scene_manager, parent, energy, r, g, b); else light = new SunNode(m_scene_manager, parent, r, g, b); @@ -2148,10 +2154,12 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float radius, } else { - return m_scene_manager->addLightSceneNode(NULL, pos, video::SColorf(r, g, b), radius); + return NULL; } } +// ---------------------------------------------------------------------------- + void IrrDriver::clearLights() { u32 i; diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 88b7c4dc4..68fcfcfe9 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -456,7 +456,7 @@ public: void applyObjectPassShader(); void applyObjectPassShader(scene::ISceneNode * const node, bool rimlit = false); // ------------------------------------------------------------------------ - scene::ISceneNode *addLight(const core::vector3df &pos, float radius = 1.0f, float energy = 1., float r = 1.0f, + 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); // ------------------------------------------------------------------------ void clearLights(); diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 46f8de22e..671fb0d99 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -34,7 +34,7 @@ using namespace core; aabbox3df LightNode::box; -LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float e, float r, float g, float b): +LightNode::LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float e, float r, float g, float b): ISceneNode(parent == NULL ? mgr->getRootSceneNode() : parent, mgr, -1) { m_energy = e; diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index 29de481da..05e6ee210 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -34,7 +34,7 @@ namespace irr class LightNode: public scene::ISceneNode { public: - LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float radius, float energy, float r, float g, float b); + LightNode(scene::ISceneManager* mgr, scene::ISceneNode* parent, float energy, float r, float g, float b); virtual ~LightNode(); virtual void render() OVERRIDE; @@ -50,7 +50,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]); } @@ -63,7 +63,7 @@ protected: class ScreenQuad *sq; - float m_radius; + //float m_radius; float m_color[3]; float m_energy; diff --git a/src/graphics/sun.cpp b/src/graphics/sun.cpp index 91ebb5ad4..399896f3d 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, 10000, 0., r, g, b) + LightNode(mgr, parent, 0., r, g, b) { sq = new ScreenQuad(irr_driver->getVideoDriver()); diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 895f9f7cd..a2ce45536 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1628,7 +1628,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, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true); + m_sun = irr_driver->addLight(m_sun_position, 0., tmpf.r, tmpf.g, tmpf.b, true); if (!irr_driver->isGLSL()) { diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index fc30f85ce..94c19b41e 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -587,15 +587,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_distance = 25.0f; + //xml_node.get("distance", &m_distance); m_energy = 1.0f; xml_node.get("energy", &m_energy); if (irr_driver->isGLSL()) { - m_node = irr_driver->addLight(m_init_xyz, m_distance, m_energy, colorf.r, colorf.g, colorf.b, false, parent); + m_node = irr_driver->addLight(m_init_xyz, m_energy, 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 e12c3fdd5..708880c64 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -274,7 +274,7 @@ class TrackObjectPresentationLight : public TrackObjectPresentationSceneNode { private: video::SColor m_color; - float m_distance; + //float m_distance; float m_energy; public: From 4c11ca65f0f7809f02cbc16b82712ceb0c5a1581 Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 2 Jan 2014 01:35:42 +0000 Subject: [PATCH 126/412] Properly parent light nodes and add them to the scene manager git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14885 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/irr_driver.cpp | 2 +- src/graphics/render.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 0a621677e..50a55b908 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2121,6 +2121,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, { if (m_glsl) { + if (parent == NULL) parent = m_scene_manager->getRootSceneNode(); LightNode *light = NULL; if (!sun) @@ -2129,7 +2130,6 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, light = new SunNode(m_scene_manager, parent, r, g, b); light->grab(); - light->setParent(NULL); light->setPosition(pos); light->updateAbsolutePosition(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index e1c74bdb8..8b5cc5e13 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -740,7 +740,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, light_node->setEnergyMultiplier(std::min(1.0f, em + dt)); } - const core::vector3df &pos = light_node->getPosition(); + const core::vector3df &pos = light_node->getAbsolutePosition(); accumulatedLightPos.push_back(pos.X); accumulatedLightPos.push_back(pos.Y); accumulatedLightPos.push_back(pos.Z); From 5da3b32be967efe04528e65063d3bf2517c5e085 Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 2 Jan 2014 01:42:45 +0000 Subject: [PATCH 127/412] support rotation and scale on library objects git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14886 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index a2ce45536..5ad1ea2e4 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1735,6 +1735,12 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa core::vector3df xyz; node->get("xyz", &xyz); + core::vector3df hpr; + node->get("hpr", &hpr); + + core::vector3df scale; + node->get("scale", &scale); + XMLNode* libroot; std::string lib_path = file_manager->getAsset("library/" + name); bool create_lod_definitions = true; @@ -1776,6 +1782,8 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode(); parent->setPosition(xyz); + parent->setRotation(hpr); + parent->setScale(scale); parent->updateAbsolutePosition(); loadObjects(libroot, lib_path, lod_loader, create_lod_definitions, parent, library_nodes); } From 1b564a81a7b050491a6ce6422e2792303e9f206d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 15:59:39 +0000 Subject: [PATCH 128/412] GPUParticles: Attribute initial lifetime to box emitter. This is needed so that effect looks stationnary. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14887 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 19ffca029..a262bb010 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -336,7 +336,7 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi particles[COMPONENTCOUNT * i + 1] = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; particles[COMPONENTCOUNT * i + 2] = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; // Initial lifetime is > 1 - particles[COMPONENTCOUNT * i + 3] = 2.; + particles[COMPONENTCOUNT * i + 3] = os::Randomizer::frand(); initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; From 39d79c555aeffb608330197f484be6152b769a5a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 16:53:55 +0000 Subject: [PATCH 129/412] GPUParticles: Reset irrlicht blending state. It fixes some flickering artifact. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14888 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index a262bb010..70be4953d 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -196,6 +196,7 @@ GPUParticle::GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, I fakemat.MaterialType = irr_driver->getShader(ES_RAIN); fakemat.Thickness = 200; fakemat.setTexture(0, tex); + fakemat.BlendOperation = video::EBO_NONE; setAutomaticCulling(0); } @@ -656,6 +657,7 @@ void ParticleSystemProxy::draw() glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); } void ParticleSystemProxy::render() { From 96841f5731b547a8b250ef8f42225f8087886cc4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 17:20:26 +0000 Subject: [PATCH 130/412] GPUParticles: Avoid particle respawning at too old location. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14889 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 7 ++++--- src/graphics/gpuparticles.cpp | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 42eda521f..f73371d53 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -23,9 +23,10 @@ void main(void) vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); vec4 adjusted_initial_velocity = tinvsourcematrix * vec4(particle_velocity_initial, 1.0); adjusted_initial_velocity /= adjusted_initial_velocity.w; - new_particle_position = (lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; - new_lifetime = (lifetime < 1.) ? lifetime + (float(dt)/lifetime_initial) : 0.; - new_particle_velocity = (lifetime < 1.) ? particle_velocity : adjusted_initial_velocity.xyz; + float adjusted_lifetime = lifetime + (float(dt)/lifetime_initial); + new_particle_position = (adjusted_lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; + new_lifetime = (adjusted_lifetime < 1.) ? adjusted_lifetime : 0.; + new_particle_velocity = (adjusted_lifetime < 1.) ? particle_velocity : adjusted_initial_velocity.xyz; new_size = size_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 70be4953d..508477636 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -246,6 +246,7 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, fakemat.MaterialType = irr_driver->getShader(ES_RAIN); fakemat.Thickness = 200; fakemat.setTexture(0, getMaterial(0).getTexture(0)); + fakemat.BlendOperation = video::EBO_NONE; glGenBuffers(1, &initial_values_buffer); glGenBuffers(2, tfb_buffers); if (quad_vertex_buffer) @@ -582,7 +583,7 @@ void ParticleSystemProxy::simulate() glVertexAttribPointer(attrib_initial_size, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(7 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); - glUniform1i(uniform_dt, 16); + glUniform1i(uniform_dt, timediff); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); glUniformMatrix4fv(uniform_tinvsourcematrix, 1, GL_FALSE, tinvmatrix.pointer()); glBeginTransformFeedback(GL_POINTS); From d63b5af530459d425d88fd3d7da504643ff42762 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 17:40:14 +0000 Subject: [PATCH 131/412] GPUParticles: Tell irrlicht that we disable cullface test. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14890 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 508477636..85b70c1f3 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -244,9 +244,10 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, fakemat.Lighting = false; fakemat.ZWriteEnable = false; fakemat.MaterialType = irr_driver->getShader(ES_RAIN); - fakemat.Thickness = 200; fakemat.setTexture(0, getMaterial(0).getTexture(0)); fakemat.BlendOperation = video::EBO_NONE; + fakemat.FrontfaceCulling = false; + fakemat.BackfaceCulling = false; glGenBuffers(1, &initial_values_buffer); glGenBuffers(2, tfb_buffers); if (quad_vertex_buffer) @@ -657,7 +658,6 @@ void ParticleSystemProxy::draw() glDisableVertexAttribArray(attrib_sz); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); - glEnable(GL_CULL_FACE); glDisable(GL_BLEND); } From d8302dcaeedb306cdfd78f49498485762ed42ff7 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 18:07:11 +0000 Subject: [PATCH 132/412] GPUParticles: Refactoring git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14891 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 97 ++++++++++++----------------------- 1 file changed, 33 insertions(+), 64 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 85b70c1f3..d2f3b3e06 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -272,13 +272,34 @@ ParticleSystemProxy::~ParticleSystemProxy() void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } +static +void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &lifetime, float &size, float &dirX, float &dirY, float &dirZ) +{ + float sizeMin = emitter->getMinStartSize().Height; + float sizeMax = emitter->getMaxStartSize().Height; + float lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + + lifetime = os::Randomizer::frand() * lifetime_range; + lifetime += emitter->getMinLifeTime(); + + size = os::Randomizer::frand(); + size *= (sizeMax - sizeMin); + size += sizeMin; + + core::vector3df particledir = emitter->getDirection(); + particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); + + dirX = particledir.X / size; + dirY = particledir.Y / size; + dirZ = particledir.Z / size; +} + void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePointEmitter *emitter) { float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; - unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); - float sizeMin = emitter->getMinStartSize().Height; - float sizeMax = emitter->getMaxStartSize().Height; for (unsigned i = 0; i < count; i++) { particles[COMPONENTCOUNT * i] = 0; @@ -290,28 +311,10 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin initialvalue[COMPONENTCOUNT * i] = 0.; initialvalue[COMPONENTCOUNT * i + 1] = 0.; initialvalue[COMPONENTCOUNT * i + 2] = 0.; - initialvalue[COMPONENTCOUNT * i + 3] = rand() % lifetime_range; - initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); - - core::vector3df particledir = emitter->getDirection(); - particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - - float size = rand(); - size /= RAND_MAX; - size *= (sizeMax - sizeMin); - size += sizeMin; - - initialvalue[COMPONENTCOUNT * i + 7] = size; - - particles[COMPONENTCOUNT * i + 4] = particledir.X / size; - particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; - particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; + generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], + initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); + memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); @@ -344,27 +347,10 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; - initialvalue[COMPONENTCOUNT * i + 3] = (lifetime_range > 0) ? rand() % lifetime_range : 0; - initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); - core::vector3df particledir = emitter->getDirection(); - particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - - float size = rand(); - size /= RAND_MAX; - size *= (sizeMax - sizeMin); - size += sizeMin; - - initialvalue[COMPONENTCOUNT * i + 7] = size; - - particles[COMPONENTCOUNT * i + 4] = particledir.X / size; - particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; - particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; + generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], + initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); + memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); @@ -403,27 +389,10 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; - initialvalue[COMPONENTCOUNT * i + 3] = (lifetime_range > 0) ? rand() % lifetime_range : 0; - initialvalue[COMPONENTCOUNT * i + 3] += emitter->getMinLifeTime(); - core::vector3df particledir = emitter->getDirection(); - particledir.rotateXYBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - - float size = rand(); - size /= RAND_MAX; - size *= (sizeMax - sizeMin); - size += sizeMin; - - initialvalue[COMPONENTCOUNT * i + 7] = size; - - particles[COMPONENTCOUNT * i + 4] = particledir.X / size; - particles[COMPONENTCOUNT * i + 5] = particledir.Y / size; - particles[COMPONENTCOUNT * i + 6] = particledir.Z / size; - initialvalue[COMPONENTCOUNT * i + 4] = particledir.X / size; - initialvalue[COMPONENTCOUNT * i + 5] = particledir.Y / size; - initialvalue[COMPONENTCOUNT * i + 6] = particledir.Z / size; + generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], + initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); + memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); From 977494c88f3b645110473dfc89975f667b269458 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 18:21:13 +0000 Subject: [PATCH 133/412] GPUParticles: More refactoring git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14892 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d2f3b3e06..feadaf5ae 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -308,10 +308,7 @@ void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePoin // Initial lifetime is >1 particles[COMPONENTCOUNT * i + 3] = 2.; - initialvalue[COMPONENTCOUNT * i] = 0.; - initialvalue[COMPONENTCOUNT * i + 1] = 0.; - initialvalue[COMPONENTCOUNT * i + 2] = 0.; - + memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); @@ -344,10 +341,7 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi // Initial lifetime is > 1 particles[COMPONENTCOUNT * i + 3] = os::Randomizer::frand(); - initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; - initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; - initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; - + memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); @@ -386,10 +380,7 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph // Initial lifetime is > 1 particles[COMPONENTCOUNT * i + 3] = 2.; - initialvalue[COMPONENTCOUNT * i] = particles[COMPONENTCOUNT * i]; - initialvalue[COMPONENTCOUNT * i + 1] = particles[COMPONENTCOUNT * i + 1]; - initialvalue[COMPONENTCOUNT * i + 2] = particles[COMPONENTCOUNT * i + 2]; - + memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); From ccf226d8e85f90b0b172c4ade392ba0a31f7d691 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 18:52:48 +0000 Subject: [PATCH 134/412] GPUParticles: Use a struct instead of hardcoded stride/offset values git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14893 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 117 ++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index feadaf5ae..9643261ff 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -296,73 +296,78 @@ void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &life dirZ = particledir.Z / size; } +struct ParticleData +{ + float PositionX; + float PositionY; + float PositionZ; + float Lifetime; + float DirectionX; + float DirectionY; + float DirectionZ; + float Size; +}; + void ParticleSystemProxy::generateParticlesFromPointEmitter(scene::IParticlePointEmitter *emitter) { - float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; - + ParticleData *particles = new ParticleData[count], *initialvalue = new ParticleData[count]; for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = 0; - particles[COMPONENTCOUNT * i + 1] = 0; - particles[COMPONENTCOUNT * i + 2] = 0; + particles[i].PositionX = 0; + particles[i].PositionY = 0; + particles[i].PositionZ = 0; // Initial lifetime is >1 - particles[COMPONENTCOUNT * i + 3] = 2.; + particles[i].Lifetime = 2.; - memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); - generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], - initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); - memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); + memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); + + generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size, + initialvalue[i].DirectionX, initialvalue[i].DirectionY, initialvalue[i].DirectionZ); + + memcpy(&(particles[i].DirectionX), &(initialvalue[i].DirectionX), 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), initialvalue, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STREAM_DRAW); delete[] particles; delete[] initialvalue; } void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter *emitter) { - float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; - unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); - - float sizeMin = emitter->getMinStartSize().Height; - float sizeMax = emitter->getMaxStartSize().Height; + ParticleData *particles = new ParticleData[count], *initialvalue = new ParticleData[count]; const core::vector3df& extent = emitter->getBox().getExtent(); for (unsigned i = 0; i < count; i++) { - particles[COMPONENTCOUNT * i] = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; - particles[COMPONENTCOUNT * i + 1] = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; - particles[COMPONENTCOUNT * i + 2] = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; + particles[i].PositionX = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; + particles[i].PositionY = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; + particles[i].PositionZ = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; // Initial lifetime is > 1 - particles[COMPONENTCOUNT * i + 3] = os::Randomizer::frand(); + particles[i].Lifetime = os::Randomizer::frand(); - memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); - generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], - initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); - memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); + memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); + generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size, + initialvalue[i].DirectionX, initialvalue[i].DirectionY, initialvalue[i].DirectionZ); + memcpy(&(particles[i].DirectionX), &(initialvalue[i].DirectionZ), 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), initialvalue, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STREAM_DRAW); delete[] particles; delete[] initialvalue; } void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSphereEmitter *emitter) { - float *particles = new float[COMPONENTCOUNT * count], *initialvalue = new float[COMPONENTCOUNT * count]; - unsigned lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); - - float sizeMin = emitter->getMinStartSize().Height; - float sizeMax = emitter->getMaxStartSize().Height; + ParticleData *particles = new ParticleData[count], *initialvalue = new ParticleData[count]; for (unsigned i = 0; i < count; i++) { // Random distance from center @@ -374,23 +379,23 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph pos.rotateYZBy(os::Randomizer::frand() * 360.f, emitter->getCenter()); pos.rotateXZBy(os::Randomizer::frand() * 360.f, emitter->getCenter()); - particles[COMPONENTCOUNT * i] = pos.X; - particles[COMPONENTCOUNT * i + 1] = pos.Y; - particles[COMPONENTCOUNT * i + 2] = pos.Z; + particles[i].PositionX = pos.X; + particles[i].PositionY = pos.Y; + particles[i].PositionZ = pos.Z; // Initial lifetime is > 1 - particles[COMPONENTCOUNT * i + 3] = 2.; + particles[i].Lifetime = 2.; - memcpy(&initialvalue[COMPONENTCOUNT * i], &particles[COMPONENTCOUNT * i], 3 * sizeof(float)); - generateLifetimeSizeDirection(emitter, initialvalue[COMPONENTCOUNT * i + 3], initialvalue[COMPONENTCOUNT * i + 7], - initialvalue[COMPONENTCOUNT * i + 4], initialvalue[COMPONENTCOUNT * i + 5], initialvalue[COMPONENTCOUNT * i + 6]); - memcpy(&particles[COMPONENTCOUNT * i + 4], &initialvalue[COMPONENTCOUNT * i + 4], 4 * sizeof(float)); + memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); + generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size, + initialvalue[i].DirectionX, initialvalue[i].DirectionY, initialvalue[i].DirectionZ); + memcpy(&(particles[i].DirectionX), &(initialvalue[i].DirectionX), 4 * sizeof(float)); } glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), initialvalue, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), initialvalue, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), particles, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), particles, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[1]); - glBufferData(GL_ARRAY_BUFFER, COMPONENTCOUNT * count * sizeof(float), 0, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, count * sizeof(ParticleData), 0, GL_STREAM_DRAW); delete[] particles; delete[] initialvalue; } @@ -529,19 +534,19 @@ void ParticleSystemProxy::simulate() glEnableVertexAttribArray(attrib_velocity); glEnableVertexAttribArray(attrib_size); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); - glVertexAttribPointer(attrib_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(attrib_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); - glVertexAttribPointer(attrib_size, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(7 * sizeof(float))); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); glEnableVertexAttribArray(attrib_initial_position); glEnableVertexAttribArray(attrib_initial_lifetime); glEnableVertexAttribArray(attrib_initial_velocity); glEnableVertexAttribArray(attrib_initial_size); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glVertexAttribPointer(attrib_initial_position, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)0); - glVertexAttribPointer(attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(4 * sizeof(float))); - glVertexAttribPointer(attrib_initial_size, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid*)(7 * sizeof(float))); + glVertexAttribPointer(attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(attrib_initial_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); glUniform1i(uniform_dt, timediff); @@ -599,9 +604,9 @@ void ParticleSystemProxy::draw() glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), 0); - glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *) (3 * sizeof(float))); - glVertexAttribPointer(attrib_sz, 1, GL_FLOAT, GL_FALSE, COMPONENTCOUNT * sizeof(float), (GLvoid *)(7 * sizeof(float))); + glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0); + glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float))); + glVertexAttribPointer(attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float))); glVertexAttribDivisor(attrib_lf, 1); glVertexAttribDivisor(attrib_pos, 1); From 10947608d899a2efd0183b49e9f921ef2d812368 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 2 Jan 2014 20:01:09 +0000 Subject: [PATCH 135/412] GPUParticles: Honor decrease in emission rate. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14894 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 9643261ff..c2f96d244 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -569,6 +569,9 @@ void ParticleSystemProxy::simulate() void ParticleSystemProxy::draw() { + unsigned active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; + // No max in windows ?? + active_count = (active_count > count) ? count : active_count; glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); @@ -612,7 +615,8 @@ void ParticleSystemProxy::draw() glVertexAttribDivisor(attrib_pos, 1); glVertexAttribDivisor(attrib_sz, 1); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); + if (active_count) + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, active_count); glVertexAttribDivisor(attrib_lf, 0); glVertexAttribDivisor(attrib_pos, 0); glVertexAttribDivisor(attrib_sz, 0); From d095e140393077255c1f7d46880c9323b3c1a89f Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 2 Jan 2014 23:44:13 +0000 Subject: [PATCH 136/412] Bugfix with new lod git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14895 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 5ad1ea2e4..ba886c53f 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -609,6 +609,7 @@ void Track::convertTrackToBullet(scene::ISceneNode *node) "This track contains an empty LOD group."); return; } + node->updateAbsolutePosition(); } node->updateAbsolutePosition(); @@ -1084,6 +1085,7 @@ bool Track::loadMainTrack(const XMLNode &root) node->setPosition(xyz); node->setRotation(hpr); node->setScale(scale); + node->updateAbsolutePosition(); m_all_nodes.push_back( node ); } From aa1bdcf10fe185f3256195db98659215782dee09 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 16:09:33 +0000 Subject: [PATCH 138/412] GPUParticles: Move opengl function to newly created glwrap.cpp git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14902 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 179 ++++++++++++++++++++++++++++++++++ src/graphics/glwrap.hpp | 48 +++++++++ src/graphics/gpuparticles.cpp | 179 +--------------------------------- src/graphics/gpuparticles.h | 8 -- 4 files changed, 228 insertions(+), 186 deletions(-) create mode 100644 src/graphics/glwrap.cpp diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp new file mode 100644 index 000000000..457c7c5f3 --- /dev/null +++ b/src/graphics/glwrap.cpp @@ -0,0 +1,179 @@ +#include "graphics\glwrap.hpp" +#include +#include + +#ifdef _IRR_WINDOWS_API_ +#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) +PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +PFNGLBINDBUFFERBASEPROC glBindBufferBase; +PFNGLGENBUFFERSPROC glGenBuffers; +PFNGLBINDBUFFERPROC glBindBuffer; +PFNGLBUFFERDATAPROC glBufferData; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +PFNGLCREATESHADERPROC glCreateShader; +PFNGLCOMPILESHADERPROC glCompileShader; +PFNGLSHADERSOURCEPROC glShaderSource; +PFNGLCREATEPROGRAMPROC glCreateProgram; +PFNGLATTACHSHADERPROC glAttachShader; +PFNGLLINKPROGRAMPROC glLinkProgram; +PFNGLUSEPROGRAMPROC glUseProgram; +PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +PFNGLUNIFORM1FPROC glUniform1f; +PFNGLUNIFORM3FPROC glUniform3f; +PFNGLDELETESHADERPROC glDeleteShader; +PFNGLGETSHADERIVPROC glGetShaderiv; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +PFNGLACTIVETEXTUREPROC glActiveTexture; +PFNGLUNIFORM2FPROC glUniform2f; +PFNGLUNIFORM1IPROC glUniform1i; +PFNGLGETPROGRAMIVPROC glGetProgramiv; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +PFNGLBLENDEQUATIONPROC glBlendEquation; +PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; +PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; +PFNGLDELETEBUFFERSPROC glDeleteBuffers; +#endif + +static bool is_gl_init = false; +void initGL() +{ + if (is_gl_init) + return; + is_gl_init = true; +#ifdef _IRR_WINDOWS_API_ + glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); + glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); + glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); + glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); + glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); + glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); + glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); + glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); + glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); + glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); + glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); + glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); + glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); + glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); + glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); + glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation"); + glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation"); + glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor"); + glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); +#endif +} + +// Mostly from shader tutorial +static +GLuint LoadShader(const char * file, unsigned type) { + GLuint Id = glCreateShader(type); + std::string Code; + std::ifstream Stream(file, std::ios::in); + if (Stream.is_open()) + { + std::string Line = ""; + while (getline(Stream, Line)) + Code += "\n" + Line; + Stream.close(); + } + GLint Result = GL_FALSE; + int InfoLogLength; + printf("Compiling shader : %s\n", file); + char const * SourcePointer = Code.c_str(); + int length = strlen(SourcePointer); + glShaderSource(Id, 1, &SourcePointer, &length); + glCompileShader(Id); + + glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); + if (Result == GL_FALSE) { + glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + return Id; +} + +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) { + GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); + + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} + +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { + GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); + GLuint Program = glCreateProgram(); + glAttachShader(Program, Shader); + glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); + glLinkProgram(Program); + + GLint Result = GL_FALSE; + int InfoLogLength; + glGetProgramiv(Program, GL_LINK_STATUS, &Result); + if (Result == GL_FALSE) { + glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); + char *ErrorMessage = new char[InfoLogLength]; + glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); + printf(ErrorMessage); + delete[] ErrorMessage; + } + glDeleteShader(Shader); + return Program; +} + + + +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, texid); + glUniform1i(location, textureUnit); +} \ No newline at end of file diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 699bc7820..7bf54b788 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -12,11 +12,59 @@ # include # include #else +#define GL_GLEXT_PROTOTYPES # include +# include #endif +void initGL(); +GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); +GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); +void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); + + // already includes glext.h, which defines useful GL constants. // COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery) +#ifdef WIN32 #include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h" +extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; +extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; +extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; +extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; +extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; +extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; +extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; +extern PFNGLGENBUFFERSPROC glGenBuffers; +extern PFNGLBINDBUFFERPROC glBindBuffer; +extern PFNGLBUFFERDATAPROC glBufferData; +extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; +extern PFNGLCREATESHADERPROC glCreateShader; +extern PFNGLCOMPILESHADERPROC glCompileShader; +extern PFNGLSHADERSOURCEPROC glShaderSource; +extern PFNGLCREATEPROGRAMPROC glCreateProgram; +extern PFNGLATTACHSHADERPROC glAttachShader; +extern PFNGLLINKPROGRAMPROC glLinkProgram; +extern PFNGLUSEPROGRAMPROC glUseProgram; +extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; +extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; +extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; +extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; +extern PFNGLUNIFORM1FPROC glUniform1f; +extern PFNGLUNIFORM3FPROC glUniform3f; +extern PFNGLDELETESHADERPROC glDeleteShader; +extern PFNGLGETSHADERIVPROC glGetShaderiv; +extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; +extern PFNGLACTIVETEXTUREPROC glActiveTexture; +extern PFNGLUNIFORM2FPROC glUniform2f; +extern PFNGLUNIFORM1IPROC glUniform1i; +extern PFNGLGETPROGRAMIVPROC glGetProgramiv; +extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; +extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; +extern PFNGLBLENDEQUATIONPROC glBlendEquation; +extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; +extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; +extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; +#endif + #endif diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index c2f96d244..0163b0de3 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -1,189 +1,12 @@ #include "graphics/irr_driver.hpp" #include "gpuparticles.h" -#include #include "io/file_manager.hpp" #include "config/user_config.hpp" #include #include -#ifdef _IRR_WINDOWS_API_ -#define IRR_OGL_LOAD_EXTENSION(X) wglGetProcAddress(reinterpret_cast(X)) - - -PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; -PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; -PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; -PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -PFNGLBINDBUFFERBASEPROC glBindBufferBase; -PFNGLGENBUFFERSPROC glGenBuffers; -PFNGLBINDBUFFERPROC glBindBuffer; -PFNGLBUFFERDATAPROC glBufferData; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -PFNGLCREATESHADERPROC glCreateShader; -PFNGLCOMPILESHADERPROC glCompileShader; -PFNGLSHADERSOURCEPROC glShaderSource; -PFNGLCREATEPROGRAMPROC glCreateProgram; -PFNGLATTACHSHADERPROC glAttachShader; -PFNGLLINKPROGRAMPROC glLinkProgram; -PFNGLUSEPROGRAMPROC glUseProgram; -PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -PFNGLUNIFORM1FPROC glUniform1f; -PFNGLUNIFORM3FPROC glUniform3f; -PFNGLDELETESHADERPROC glDeleteShader; -PFNGLGETSHADERIVPROC glGetShaderiv; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; -PFNGLACTIVETEXTUREPROC glActiveTexture; -PFNGLUNIFORM2FPROC glUniform2f; -PFNGLUNIFORM1IPROC glUniform1i; -PFNGLGETPROGRAMIVPROC glGetProgramiv; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; -PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; -PFNGLBLENDEQUATIONPROC glBlendEquation; -PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; -PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; -PFNGLDELETEBUFFERSPROC glDeleteBuffers; -#endif - -static bool is_gl_init = false; -void initGL() -{ - if (is_gl_init) - return; - is_gl_init = true; -#ifdef _IRR_WINDOWS_API_ - glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)IRR_OGL_LOAD_EXTENSION("glGenTransformFeedbacks"); - glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBindTransformFeedback"); - glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glDrawTransformFeedback"); - glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glBeginTransformFeedback"); - glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)IRR_OGL_LOAD_EXTENSION("glEndTransformFeedback"); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)IRR_OGL_LOAD_EXTENSION("glBindBufferBase"); - glGenBuffers = (PFNGLGENBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glGenBuffers"); - glBindBuffer = (PFNGLBINDBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindBuffer"); - glBufferData = (PFNGLBUFFERDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferData"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribPointer"); - glCreateShader = (PFNGLCREATESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCreateShader"); - glCompileShader = (PFNGLCOMPILESHADERPROC)IRR_OGL_LOAD_EXTENSION("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC)IRR_OGL_LOAD_EXTENSION("glShaderSource"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC)IRR_OGL_LOAD_EXTENSION("glAttachShader"); - glLinkProgram = (PFNGLLINKPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glLinkProgram"); - glUseProgram = (PFNGLUSEPROGRAMPROC)IRR_OGL_LOAD_EXTENSION("glUseProgram"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glEnableVertexAttribArray"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformLocation"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniformMatrix4fv"); - glUniform1f = (PFNGLUNIFORM1FPROC)IRR_OGL_LOAD_EXTENSION("glUniform1f"); - glUniform3f = (PFNGLUNIFORM3FPROC)IRR_OGL_LOAD_EXTENSION("glUniform3f"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)IRR_OGL_LOAD_EXTENSION("glDisableVertexAttribArray"); - glDeleteShader = (PFNGLDELETESHADERPROC)IRR_OGL_LOAD_EXTENSION("glDeleteShader"); - glGetShaderiv = (PFNGLGETSHADERIVPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderiv"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); - glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); - glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); - glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); - glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)IRR_OGL_LOAD_EXTENSION("glTransformFeedbackVaryings"); - glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)IRR_OGL_LOAD_EXTENSION("glGetAttribLocation"); - glBlendEquation = (PFNGLBLENDEQUATIONPROC)IRR_OGL_LOAD_EXTENSION("glBlendEquation"); - glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor"); - glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); -#endif -} - -// Mostly from shader tutorial -static -GLuint LoadShader(const char * file, unsigned type) { - GLuint Id = glCreateShader(type); - std::string Code; - std::ifstream Stream(file, std::ios::in); - if (Stream.is_open()) - { - std::string Line = ""; - while (getline(Stream, Line)) - Code += "\n" + Line; - Stream.close(); - } - GLint Result = GL_FALSE; - int InfoLogLength; - printf("Compiling shader : %s\n", file); - char const * SourcePointer = Code.c_str(); - int length = strlen(SourcePointer); - glShaderSource(Id, 1, &SourcePointer, &length); - glCompileShader(Id); - - glGetShaderiv(Id, GL_COMPILE_STATUS, &Result); - if (Result == GL_FALSE) { - glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - return Id; -} - -GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path) { - GLuint VertexShaderID = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint FragmentShaderID = LoadShader(fragment_file_path, GL_FRAGMENT_SHADER); - - GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, FragmentShaderID); - glLinkProgram(ProgramID); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - - return ProgramID; -} - -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { - GLuint Shader = LoadShader(vertex_file_path, GL_VERTEX_SHADER); - GLuint Program = glCreateProgram(); - glAttachShader(Program, Shader); - glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); - glLinkProgram(Program); - - GLint Result = GL_FALSE; - int InfoLogLength; - glGetProgramiv(Program, GL_LINK_STATUS, &Result); - if (Result == GL_FALSE) { - glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &InfoLogLength); - char *ErrorMessage = new char[InfoLogLength]; - glGetProgramInfoLog(Program, InfoLogLength, NULL, ErrorMessage); - printf(ErrorMessage); - delete[] ErrorMessage; - } - glDeleteShader(Shader); - return Program; -} - GLuint getTextureGLuint(irr::video::ITexture *tex) { - return static_cast(tex)->getOpenGLTextureName(); -} - -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit) { - glActiveTexture(GL_TEXTURE0 + textureUnit); - glBindTexture(GL_TEXTURE_2D, texid); - glUniform1i(location, textureUnit); + return static_cast(tex)->getOpenGLTextureName(); } #define COMPONENTCOUNT 8 diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 2806f6f30..cca0be2d4 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -1,20 +1,12 @@ #ifndef GPUPARTICLES_H #define GPUPARTICLES_H -#ifndef _IRR_WINDOWS_API_ -#define GL_GLEXT_PROTOTYPES 1 -#endif #include "graphics/glwrap.hpp" #include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h" #include #include -void initGL(); -GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); -GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); GLuint getTextureGLuint(irr::video::ITexture *tex); -void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); - class GPUParticle : public scene::ISceneNode { protected: From b28044e603a69cf3493bd3f96af5ca20d13078e9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 17:12:30 +0000 Subject: [PATCH 139/412] OGL32CTX: Implement a draw2DImage function using shaders. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14903 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/texturedquad.frag | 9 +++++ data/shaders/texturedquad.vert | 13 +++++++ src/guiengine/engine.cpp | 71 +++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 data/shaders/texturedquad.frag create mode 100644 data/shaders/texturedquad.vert diff --git a/data/shaders/texturedquad.frag b/data/shaders/texturedquad.frag new file mode 100644 index 000000000..b2c3f9612 --- /dev/null +++ b/data/shaders/texturedquad.frag @@ -0,0 +1,9 @@ +#version 130 +uniform sampler2D texture; + +in vec2 tc; + +void main() +{ + gl_FragColor = texture2D(texture, tc); +} \ No newline at end of file diff --git a/data/shaders/texturedquad.vert b/data/shaders/texturedquad.vert new file mode 100644 index 000000000..aebd1222c --- /dev/null +++ b/data/shaders/texturedquad.vert @@ -0,0 +1,13 @@ +#version 130 +uniform vec2 center; +uniform vec2 size; + +in vec2 position; +in vec2 texcoord; +out vec2 tc; + +void main() +{ + tc = texcoord; + gl_Position = vec4(position * size + center, 0., 1.); +} \ No newline at end of file diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index e06c2ca5f..07371f7e3 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -665,6 +665,7 @@ namespace GUIEngine #include #include #include +#include "graphics/glwrap.hpp" using namespace irr::gui; using namespace irr::video; @@ -1275,6 +1276,72 @@ namespace GUIEngine } // render // ----------------------------------------------------------------------- + static GLuint quad_buffer; + static GLuint TexturedQuadShader; + static GLuint TexturedQuadAttribPosition; + static GLuint TexturedQuadAttribTexCoord; + static GLuint TexturedQuadUniformTexture; + static GLuint TexturedQuadUniformCenter; + static GLuint TexturedQuadUniformSize; + + 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) + { +#ifndef OGL32CTX + GUIEngine::getDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); +#else + core::dimension2d frame_size = + GUIEngine::getDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + float center_pos_x = destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X; + center_pos_x /= screen_w; + center_pos_x -= 1; + float center_pos_y = destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y; + center_pos_y /= screen_h; + center_pos_y = 1 - center_pos_y; + float width = destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X; + width /= screen_w; + float height = destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y; + height /= screen_h; + + initGL(); + const float quad_vertex[] = { + -1., -1., 0., 1., + -1., 1., 0., 0., + 1., -1., 1., 1., + 1., 1., 1., 0. + }; + if (!TexturedQuadShader) { + TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); + glGenBuffers(1, &quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); + TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); + TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); + TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); + TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); + } + glUseProgram(TexturedQuadShader); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); + glUniform1i(TexturedQuadUniformTexture, 0); + glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); + glUniform2f(TexturedQuadUniformSize, width, height); + glEnableVertexAttribArray(TexturedQuadAttribPosition); + glEnableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *) (2 * sizeof(float))); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(TexturedQuadAttribPosition); + glDisableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, 0); +#endif + } + std::vector g_loading_icons; @@ -1309,7 +1376,7 @@ namespace GUIEngine const core::rect< s32 > source_area = core::rect< s32 >(0, 0, texture_w, texture_h); - GUIEngine::getDriver()->draw2DImage( loading, dest_area, source_area, + draw2DImage( loading, dest_area, source_area, 0 /* no clipping */, 0, true /* alpha */); @@ -1329,7 +1396,7 @@ namespace GUIEngine int y = screen_h - icon_size - ICON_MARGIN; for (int n=0; ndraw2DImage(g_loading_icons[n], + draw2DImage(g_loading_icons[n], core::rect(x, y, x+icon_size, y+icon_size), core::rect(core::position2d(0, 0), g_loading_icons[n]->getSize()), From 9555bf8c7f731399892ab41e88ebf08dd70ce2df Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 17:15:29 +0000 Subject: [PATCH 140/412] OGL32CTX: Use alpha when required git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14904 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/engine.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index 07371f7e3..a5e3667d0 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1313,6 +1313,17 @@ namespace GUIEngine 1., -1., 1., 1., 1., 1., 1., 0. }; + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } if (!TexturedQuadShader) { TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); glGenBuffers(1, &quad_buffer); From c18248220a274f695d2c89754455344d1ea97559 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 17:32:42 +0000 Subject: [PATCH 141/412] OGL32CTX: Move an include outside of win32 #ifdef, and always define OGL32CTX for apple git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14905 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 1 + src/graphics/glwrap.hpp | 59 ++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/sources.cmake b/sources.cmake index ecc5e0cc4..d021cb042 100644 --- a/sources.cmake +++ b/sources.cmake @@ -34,6 +34,7 @@ src/graphics/camera.cpp src/graphics/CBatchingMesh.cpp src/graphics/explosion.cpp src/graphics/glow.cpp +src/graphics/glwrap.cpp src/graphics/gpuparticles.cpp src/graphics/hardware_skinning.cpp src/graphics/hit_sfx.cpp diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 7bf54b788..a57ac5838 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -1,33 +1,32 @@ -#ifndef GLWRAP_HEADER_H -#define GLWRAP_HEADER_H - -#if defined(__APPLE__) -# include -# include -#elif defined(ANDROID) -# include -#elif defined(WIN32) -# define _WINSOCKAPI_ -// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions -# include -# include -#else -#define GL_GLEXT_PROTOTYPES -# include -# include -#endif - +#ifndef GLWRAP_HEADER_H +#define GLWRAP_HEADER_H + +#if defined(__APPLE__) +# include +# include +# define OGL32CTX +#elif defined(ANDROID) +# include +#elif defined(WIN32) +# define _WINSOCKAPI_ +// has to be included before gl.h because of WINGDIAPI and APIENTRY definitions +# include +# include +#else +#define GL_GLEXT_PROTOTYPES +# include +#endif + void initGL(); GLuint LoadProgram(const char * vertex_file_path, const char * fragment_file_path); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUnit); - - -// already includes glext.h, which defines useful GL constants. -// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery) -#ifdef WIN32 -#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h" - + + +// already includes glext.h, which defines useful GL constants. +// COpenGLDriver has already loaded the extension GL functions we use (e.g glBeginQuery) +#include "../../lib/irrlicht/source/Irrlicht/COpenGLDriver.h" +#ifdef WIN32 extern PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; extern PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; extern PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; @@ -64,7 +63,7 @@ extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; extern PFNGLBLENDEQUATIONPROC glBlendEquation; extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -#endif - -#endif +extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; +#endif + +#endif From aedb68a88ae2538ee6d60dfca70886f54bb6bc18 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sat, 4 Jan 2014 20:29:02 +0000 Subject: [PATCH 142/412] Minor correction for a window path git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14906 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 19 +++++++++++++++++++ src/graphics/callbacks.hpp | 17 +++++++++++++++++ src/graphics/glwrap.cpp | 4 ++-- src/graphics/irr_driver.cpp | 11 +++++++++-- src/graphics/material.cpp | 18 ++++++++++++++++++ src/graphics/material.hpp | 1 + src/graphics/shaders.cpp | 8 ++++++-- src/graphics/shaders.hpp | 1 + 8 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 07fc92297..fbde078ed 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -151,6 +151,25 @@ void ColorLevelsProvider::OnSetConstants(IMaterialRendererServices *srv, int use } } +//------------------------------------- +void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int) +{ + const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; + srv->setVertexShaderConstant("time", &time, 1); + + vector3df sun_pos = m_sunpos; + srv->setVertexShaderConstant("sun_pos", &sun_pos.X, 3); + + if (!firstdone) + { + s32 tex = 0; + srv->setPixelShaderConstant("tex", &tex, 1); + s32 glow_tex = 1; + srv->setPixelShaderConstant("glow_tex", &glow_tex, 1); + firstdone = true; + } +} + //------------------------------------- void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int) diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 1a058492b..95bc47021 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -156,6 +156,23 @@ private: // +class SkyboxProvider: public CallBase +{ +public: + virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); + + void setSunPosition(const core::vector3df &in) + { + m_sunpos = in; + //m_sunpos.normalize(); + } + +private: + core::vector3df m_sunpos; +}; + +// + class SplattingProvider: public CallBase { public: diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 457c7c5f3..954a2af06 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -1,4 +1,4 @@ -#include "graphics\glwrap.hpp" +#include "graphics/glwrap.hpp" #include #include @@ -176,4 +176,4 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(GL_TEXTURE_2D, texid); glUniform1i(location, textureUnit); -} \ No newline at end of file +} diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 50a55b908..a8f3fc190 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1397,8 +1397,14 @@ void IrrDriver::displayFPS() { gui::IGUIFont* font = GUIEngine::getFont(); - irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,50),NULL); - + if(UserConfigParams::m_artist_debug_mode) + { + irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,1100,50),NULL); + } + else + { + irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,50),NULL); + } // We will let pass some time to let things settle before trusting FPS counter // even if we also ignore fps = 1, which tends to happen in first checks const int NO_TRUST_COUNT = 200; @@ -2148,6 +2154,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, m_suncam->updateAbsolutePosition(); ((WaterShaderProvider *) m_shaders->m_callbacks[ES_WATER])->setSunPosition(pos); + ((SkyboxProvider *) m_shaders->m_callbacks[ES_SKYBOX])->setSunPosition(pos); } return light; diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index b34d36376..206b97d8a 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -217,6 +217,11 @@ Material::Material(const XMLNode *node, int index, bool deprecated) { m_graphical_effect = GE_SPHERE_MAP; } + else if (s == "skybox") + { + printf("[sam] Coucou\n"); + m_graphical_effect = GE_SKYBOX; + } else if (s == "splatting") { m_graphical_effect = GE_SPLATTING; @@ -801,6 +806,19 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m m->SpecularColor.set(0,0,0,0); modes++; } + + if(m_graphical_effect == GE_SKYBOX && irr_driver->isGLSL()) + { + printf("[sam] Hello world :)\n"); + ITexture* tex = irr_driver->getTexture("cloud_mask.png"); + m->setTexture(1, tex); + if(m->getTexture(1) == NULL) + { + printf("[sam] Error :( \n"); + } + + m->MaterialType = irr_driver->getShader(ES_SKYBOX); + } if (m_graphical_effect == GE_SPLATTING) { if (irr_driver->supportsSplatting()) diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index e14f20de4..be0bf2c57 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -54,6 +54,7 @@ public: GE_WATER_SHADER, GE_SPHERE_MAP, GE_SPLATTING, + GE_SKYBOX, GE_NORMAL_MAP, GE_CAUSTICS}; diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 51023dd32..ccc74a297 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -34,6 +34,7 @@ Shaders::Shaders() m_callbacks[ES_NORMAL_MAP_LIGHTMAP] = new NormalMapProvider(true); m_callbacks[ES_NORMAL_MAP] = new NormalMapProvider(false); + m_callbacks[ES_SKYBOX] = new SkyboxProvider(); m_callbacks[ES_SPLATTING] = new SplattingProvider(); m_callbacks[ES_WATER] = new WaterShaderProvider(); m_callbacks[ES_GRASS] = new GrassShaderProvider(); @@ -94,8 +95,11 @@ void Shaders::loadShaders() m_shaders[ES_NORMAL_MAP_LIGHTMAP] = glslmat(dir + "normalmap.vert", dir + "normalmap.frag", m_callbacks[ES_NORMAL_MAP_LIGHTMAP], EMT_SOLID_2_LAYER); - m_shaders[ES_SPLATTING] = glsl(dir + "objectpass.vert", dir + "splatting.frag", - m_callbacks[ES_SPLATTING]); + m_shaders[ES_SKYBOX] = glslmat(dir + "skybox.vert", dir + "skybox.frag", + m_callbacks[ES_SKYBOX], EMT_TRANSPARENT_ALPHA_CHANNEL); + + m_shaders[ES_SPLATTING] = glslmat(dir + "objectpass.vert", dir + "splatting.frag", + m_callbacks[ES_SPLATTING], EMT_SOLID); m_shaders[ES_WATER] = glslmat(dir + "water.vert", dir + "water.frag", m_callbacks[ES_WATER], EMT_TRANSPARENT_ALPHA_CHANNEL); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 3a713d0c4..a3fdd5439 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -25,6 +25,7 @@ using namespace irr; #define FOREACH_SHADER(ACT) \ ACT(ES_NORMAL_MAP) \ ACT(ES_NORMAL_MAP_LIGHTMAP) \ + ACT(ES_SKYBOX) \ ACT(ES_SPLATTING) \ ACT(ES_WATER) \ ACT(ES_WATER_SURFACE) \ From 54a9a94ed2a9f74c9c6be267ea358e3422630e39 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sat, 4 Jan 2014 20:34:38 +0000 Subject: [PATCH 143/412] Oups I forget to remove some debug printf :3 git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14907 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/material.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 206b97d8a..43fc695b8 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -219,7 +219,6 @@ Material::Material(const XMLNode *node, int index, bool deprecated) } else if (s == "skybox") { - printf("[sam] Coucou\n"); m_graphical_effect = GE_SKYBOX; } else if (s == "splatting") @@ -809,13 +808,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m if(m_graphical_effect == GE_SKYBOX && irr_driver->isGLSL()) { - printf("[sam] Hello world :)\n"); ITexture* tex = irr_driver->getTexture("cloud_mask.png"); m->setTexture(1, tex); - if(m->getTexture(1) == NULL) - { - printf("[sam] Error :( \n"); - } + m->MaterialType = irr_driver->getShader(ES_SKYBOX); } From bd69c8c0d7ae2b73492076861387dba84c111686 Mon Sep 17 00:00:00 2001 From: samuncle Date: Sat, 4 Jan 2014 20:43:18 +0000 Subject: [PATCH 145/412] Add the skybox shader for harvest. For the moment it's still an object in the transparent pass. The object should be in the skybox pass git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14909 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/skybox.frag | 67 ++++++++++++++++++++++++++++++++++++++++ data/shaders/skybox.vert | 49 +++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 data/shaders/skybox.frag create mode 100644 data/shaders/skybox.vert diff --git a/data/shaders/skybox.frag b/data/shaders/skybox.frag new file mode 100644 index 000000000..6c2dcb5a6 --- /dev/null +++ b/data/shaders/skybox.frag @@ -0,0 +1,67 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 the SuperTuxKart team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +uniform sampler2D tex; +uniform sampler2D glow_tex; +uniform float transparency; +uniform vec3 sun_pos; + +varying vec2 uv_anim; +varying vec2 uv; +varying vec2 uv_cl; +varying vec3 vertex; +varying vec2 uv_fast; + +void main() +{ + + vec3 V = normalize(vertex); + vec3 L = normalize(vec3(sun_pos)); + + vec3 col = texture2D(tex, vec2((L.y + 1.0) / 2.0, V.y)); + + float vl = clamp(dot(V, L), 0, 1); + + vec3 paint = texture2D(tex, uv * 3).a; + + uv += 20; + vec3 paint2 = texture2D(tex, uv * 5).a; + + // Get the general cloud mask + + + float hello = texture2D(glow_tex, (uv_cl + paint2 * 0.07) *2).g; + + float cld_mask = texture2D(glow_tex, (uv_anim + hello * 0.007 )).r; + + vec2 fast = vec2(-uv_fast.x, uv_fast.y);// + (hello * 0.007); + float cld_fast = texture2D(glow_tex, fast ).r; + + + + + cld_mask = (cld_mask * hello * 0.5); + cld_fast = (cld_fast + hello ); + + col = cld_mask + col*(1 - cld_mask); + col = cld_fast + col*(1 - cld_fast); + + gl_FragColor = vec4( (col * paint2 * paint), 1.0); + + + //gl_FragColor = vec4(vec3(ou), 1.0); +} diff --git a/data/shaders/skybox.vert b/data/shaders/skybox.vert new file mode 100644 index 000000000..dae614974 --- /dev/null +++ b/data/shaders/skybox.vert @@ -0,0 +1,49 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 the SuperTuxKart team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +// Creates a bubble (wave) effect by distorting the texture depending on time + +uniform float time; + +varying vec2 uv; +varying vec2 uv_anim; +varying vec2 uv_cl; +varying vec2 uv_fast; + +varying vec3 vertex; + + +void main() +{ + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_Position = ftransform(); + + + float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 ); + float delta_y = cos(time*2.0) * sin( 3.0 * gl_TexCoord[0].st.t * 6.28318531 ); + + vertex = gl_Vertex.xyz; + + uv = gl_TexCoord[0].st; + + + uv_anim = gl_TexCoord[0].st + vec2(0.002*time, 0); + uv_cl = gl_TexCoord[0].st + vec2(-0.001*time, 0); + + uv_fast = gl_TexCoord[0].st + vec2(0.005*time, 0); +} From 169f29f7b280bca447612bfcb399b25be54be163 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 21:31:57 +0000 Subject: [PATCH 147/412] OGL32CTX: Spread use of Draw2DImage custom function. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14913 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 80 ++++++++++++++++++++++++++++++++++++++++ src/graphics/glwrap.hpp | 8 ++++ src/guiengine/engine.cpp | 78 --------------------------------------- src/guiengine/skin.cpp | 3 +- 4 files changed, 90 insertions(+), 79 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 954a2af06..f8fa62795 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -1,4 +1,5 @@ #include "graphics/glwrap.hpp" +#include "irr_driver.hpp" #include #include @@ -177,3 +178,82 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glBindTexture(GL_TEXTURE_2D, texid); glUniform1i(location, textureUnit); } + +#define OGL32CTX + +static GLuint quad_buffer; +static GLuint TexturedQuadShader; +static GLuint TexturedQuadAttribPosition; +static GLuint TexturedQuadAttribTexCoord; +static GLuint TexturedQuadUniformTexture; +static GLuint TexturedQuadUniformCenter; +static GLuint TexturedQuadUniformSize; + +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) +{ +#ifndef OGL32CTX + irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); +#else + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + float center_pos_x = destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X; + center_pos_x /= screen_w; + center_pos_x -= 1; + float center_pos_y = destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y; + center_pos_y /= screen_h; + center_pos_y = 1 - center_pos_y; + float width = destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X; + width /= screen_w; + float height = destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y; + height /= screen_h; + + initGL(); + const float quad_vertex[] = { + -1., -1., 0., 1., + -1., 1., 0., 0., + 1., -1., 1., 1., + 1., 1., 1., 0. + }; + if (useAlphaChannelOfTexture) + { + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + if (!TexturedQuadShader) { + TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); + glGenBuffers(1, &quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); + TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); + TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); + TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); + TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); + } + glUseProgram(TexturedQuadShader); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); + glUniform1i(TexturedQuadUniformTexture, 0); + glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); + glUniform2f(TexturedQuadUniformSize, width, height); + glEnableVertexAttribArray(TexturedQuadAttribPosition); + glEnableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(TexturedQuadAttribPosition); + glDisableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, 0); +#endif +} diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index a57ac5838..b961654b8 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -66,4 +66,12 @@ extern PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; #endif +// core::rect needs these includes +#include +#include "utils/vec3.hpp" + +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* const colors, bool useAlphaChannelOfTexture); + #endif diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index a5e3667d0..fd1a79b37 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1276,84 +1276,6 @@ namespace GUIEngine } // render // ----------------------------------------------------------------------- - static GLuint quad_buffer; - static GLuint TexturedQuadShader; - static GLuint TexturedQuadAttribPosition; - static GLuint TexturedQuadAttribTexCoord; - static GLuint TexturedQuadUniformTexture; - static GLuint TexturedQuadUniformCenter; - static GLuint TexturedQuadUniformSize; - - 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) - { -#ifndef OGL32CTX - GUIEngine::getDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); -#else - core::dimension2d frame_size = - GUIEngine::getDriver()->getCurrentRenderTargetSize(); - const int screen_w = frame_size.Width; - const int screen_h = frame_size.Height; - float center_pos_x = destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X; - center_pos_x /= screen_w; - center_pos_x -= 1; - float center_pos_y = destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y; - center_pos_y /= screen_h; - center_pos_y = 1 - center_pos_y; - float width = destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X; - width /= screen_w; - float height = destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y; - height /= screen_h; - - initGL(); - const float quad_vertex[] = { - -1., -1., 0., 1., - -1., 1., 0., 0., - 1., -1., 1., 1., - 1., 1., 1., 0. - }; - if (useAlphaChannelOfTexture) - { - glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.f); - } - else - { - glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - } - if (!TexturedQuadShader) { - TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); - glGenBuffers(1, &quad_buffer); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); - TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); - TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); - TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); - TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); - TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); - } - glUseProgram(TexturedQuadShader); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); - glUniform1i(TexturedQuadUniformTexture, 0); - glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); - glUniform2f(TexturedQuadUniformSize, width, height); - glEnableVertexAttribArray(TexturedQuadAttribPosition); - glEnableVertexAttribArray(TexturedQuadAttribTexCoord); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *) (2 * sizeof(float))); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(TexturedQuadAttribPosition); - glDisableVertexAttribArray(TexturedQuadAttribTexCoord); - glBindBuffer(GL_ARRAY_BUFFER, 0); -#endif - } - - std::vector g_loading_icons; void renderLoading(bool clearIcons) diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index 9e62ddb77..a6caddf99 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -32,6 +32,7 @@ #include "io/file_manager.hpp" #include "states_screens/state_manager.hpp" #include "utils/log.hpp" +#include "graphics/glwrap.hpp" using namespace GUIEngine; using namespace irr; @@ -366,7 +367,7 @@ void Skin::drawBgImage() } irr_driver->getVideoDriver()->enableMaterial2D(); - GUIEngine::getDriver()->draw2DImage(bg_image, dest, source_area, + draw2DImage(bg_image, dest, source_area, /* no clipping */0, /*color*/ 0, /*alpha*/false); irr_driver->getVideoDriver()->enableMaterial2D(false); From bfc7efa5cc17ce0800b8ed18a20a388a0caba609 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 21:34:06 +0000 Subject: [PATCH 148/412] OGL32CTX: Remove it in default build. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14914 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index f8fa62795..02d96f3fd 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -179,8 +179,6 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glUniform1i(location, textureUnit); } -#define OGL32CTX - static GLuint quad_buffer; static GLuint TexturedQuadShader; static GLuint TexturedQuadAttribPosition; From 35986433322189381ab3af294977306170ac994c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 21:43:49 +0000 Subject: [PATCH 149/412] OGL32CTX: Uses draw2DImage in skin.cpp git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14915 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/skin.cpp | 54 +++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index a6caddf99..aacaaae29 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -613,34 +613,34 @@ X##_yflip.LowerRightCorner.Y = w->m_skin_dest_y + \ if ((areas & BoxRenderParams::LEFT) != 0) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_left, + draw2DImage(source, dest_area_left, m_source_area_left, clipRect, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::BODY) != 0) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_center, + draw2DImage(source, dest_area_center, m_source_area_center, clipRect, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::RIGHT) != 0) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_right, + draw2DImage(source, dest_area_right, m_source_area_right, clipRect, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::TOP) != 0) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_top, + draw2DImage(source, dest_area_top, m_source_area_top, clipRect, colorptr, true /* alpha */); } if ((areas & BoxRenderParams::BOTTOM) != 0) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom, + draw2DImage(source, dest_area_bottom, m_source_area_bottom, clipRect, colorptr, true /* alpha */); } @@ -648,21 +648,21 @@ X##_yflip.LowerRightCorner.Y = w->m_skin_dest_y + \ if ( ((areas & BoxRenderParams::LEFT) != 0) && ((areas & BoxRenderParams::TOP ) != 0) ) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_top_left, + draw2DImage(source, dest_area_top_left, m_source_area_top_left, clipRect, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::RIGHT) != 0) && ((areas & BoxRenderParams::TOP ) != 0) ) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_top_right, + draw2DImage(source, dest_area_top_right, m_source_area_top_right, clipRect, colorptr, true /* alpha */); } if ( ((areas & BoxRenderParams::LEFT ) != 0) && ((areas & BoxRenderParams::BOTTOM) != 0) ) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom_left, + draw2DImage(source, dest_area_bottom_left, m_source_area_bottom_left, clipRect, colorptr, /*alpha*/true ); @@ -670,7 +670,7 @@ X##_yflip.LowerRightCorner.Y = w->m_skin_dest_y + \ if ( ((areas & BoxRenderParams::RIGHT ) != 0) && ((areas & BoxRenderParams::BOTTOM) != 0) ) { - GUIEngine::getDriver()->draw2DImage(source, dest_area_bottom_right, + draw2DImage(source, dest_area_bottom_right, m_source_area_bottom_right, clipRect, colorptr, /*alpha*/true ); @@ -859,7 +859,7 @@ void Skin::drawRatingBar(Widget *w, const core::recti &rect, const core::recti source_area(texture_w * step, 0, texture_w * (step + 1), texture_h); - GUIEngine::getDriver()->draw2DImage(texture, + draw2DImage(texture, star_rect, source_area, 0 /* no clipping */, (w->m_deactivated || ID_DEBUG) ? colors : 0, @@ -1022,14 +1022,14 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget, SColor(100,255,255,255), SColor(100,255,255,255), SColor(100,255,255,255) }; - GUIEngine::getDriver()->draw2DImage(tex_bubble, rect2, + draw2DImage(tex_bubble, rect2, source_area, 0 /* no clipping */, colors, true /* alpha */); } else { - GUIEngine::getDriver()->draw2DImage(tex_bubble, rect2, + draw2DImage(tex_bubble, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); @@ -1078,7 +1078,7 @@ void Skin::drawRibbonChild(const core::recti &rect, Widget* widget, glow_center_x + 45 + grow, glow_center_y + 25 + grow/2); - GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, + draw2DImage(tex_ficonhighlight, rect2, source_area, /*clipping*/ 0, /*color*/ 0, @@ -1306,7 +1306,7 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget, const core::recti source_area(0, 0, texture_w, texture_h); - GUIEngine::getDriver()->draw2DImage(texture, + draw2DImage(texture, dest_area, source_area, 0 /* no clipping */, 0, true /* alpha */); @@ -1401,7 +1401,7 @@ void Skin::drawIconButton(const core::recti &rect, Widget* widget, glow_center_x + 45 + grow, glow_center_y + 25 + grow/2); - GUIEngine::getDriver()->draw2DImage(tex_ficonhighlight, rect2, + draw2DImage(tex_ficonhighlight, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); @@ -1444,7 +1444,7 @@ void Skin::drawIconButton(const core::recti &rect, Widget* widget, SColor(100,255,255,255), SColor(100,255,255,255) }; core::recti r(0,0,icon_widget->m_texture_w, icon_widget->m_texture_h); - GUIEngine::getDriver()->draw2DImage(icon_widget->m_texture, sized_rect, + draw2DImage(icon_widget->m_texture, sized_rect, r, 0 /* no clipping */, colors, true /* alpha */); } @@ -1461,7 +1461,7 @@ void Skin::drawIconButton(const core::recti &rect, Widget* widget, t = icon_widget->m_highlight_texture; } core::recti r(0,0,icon_widget->m_texture_w, icon_widget->m_texture_h); - GUIEngine::getDriver()->draw2DImage(t, sized_rect, r,0 + draw2DImage(t, sized_rect, r,0 /* no clipping */, 0, true /* alpha */); } @@ -1511,13 +1511,13 @@ void Skin::drawCheckBox(const core::recti &rect, Widget* widget, bool focused) SColor(100,255,255,255), SColor(100,255,255,255), SColor(100,255,255,255) }; - GUIEngine::getDriver()->draw2DImage( texture, rect, source_area, + draw2DImage( texture, rect, source_area, 0 /* no clipping */, colors, true /* alpha */); } else { - GUIEngine::getDriver()->draw2DImage( texture, rect, source_area, + draw2DImage( texture, rect, source_area, 0 /* no clipping */, 0, true /* alpha */); } @@ -1580,7 +1580,7 @@ void Skin::drawListHeader(const irr::core::rect< irr::s32 > &rect, core::dimension2di(rect.getHeight(), rect.getHeight())); core::recti srcRect(core::position2d(0,0), img->getSize()); - irr_driver->getVideoDriver()->draw2DImage(img, destRect, srcRect, + draw2DImage(img, destRect, srcRect, NULL, NULL, /* alpha */true); } @@ -1644,7 +1644,7 @@ void Skin::renderSections(PtrVector* within_vector) core::recti r1(0, (int)(widget.m_y - 40*y_size), framesize.Width, framesize.Height); core::recti r2(core::dimension2di(0,0), tex->getSize()); - irr_driver->getVideoDriver()->draw2DImage(tex, r1, r2, + draw2DImage(tex, r1, r2, 0, 0, /*alpha*/true); } else if (widget.isTopBar()) @@ -1655,7 +1655,7 @@ void Skin::renderSections(PtrVector* within_vector) core::recti r1(0, 0, (int)widget.m_w, (int)widget.m_h); core::recti r2(core::dimension2di(0,0), tex->getSize()); - irr_driver->getVideoDriver()->draw2DImage(tex, r1, r2, + draw2DImage(tex, r1, r2, 0, 0, /*alpha*/false); } else @@ -1679,7 +1679,7 @@ void Skin::drawScrollbarBackground(const irr::core::rect< irr::s32 > &rect) BoxRenderParams& p = SkinConfig::m_render_params["scrollbar_background::neutral"]; - GUIEngine::getDriver()->draw2DImage(p.getImage(), rect2, + draw2DImage(p.getImage(), rect2, p.m_source_area_center, 0 /* no clipping */, 0, true /* alpha */); @@ -1692,7 +1692,7 @@ void Skin::drawScrollbarThumb(const irr::core::rect< irr::s32 > &rect) BoxRenderParams& p = SkinConfig::m_render_params["scrollbar_thumb::neutral"]; - GUIEngine::getDriver()->draw2DImage(p.getImage(), rect, + draw2DImage(p.getImage(), rect, p.m_source_area_center, 0 /* no clipping */, 0, true /* alpha */); @@ -1709,7 +1709,7 @@ void Skin::drawScrollbarButton(const irr::core::rect< irr::s32 > &rect, if (!bottomArrow) { - GUIEngine::getDriver()->draw2DImage(p.getImage(), rect, + draw2DImage(p.getImage(), rect, p.m_source_area_center, 0 /* no clipping */, 0, true /* alpha */); @@ -1723,7 +1723,7 @@ void Skin::drawScrollbarButton(const irr::core::rect< irr::s32 > &rect, const int y0 = source_area.UpperLeftCorner.Y; const int y1 = source_area.LowerRightCorner.Y; - GUIEngine::getDriver()->draw2DImage(p.getImage(), rect, + draw2DImage(p.getImage(), rect, core::recti(x0, y1, x1, y0), 0 /* no clipping */, 0, true /* alpha */); @@ -1927,7 +1927,7 @@ void doDrawBadge(ITexture* texture, const core::recti& rect, : rect.LowerRightCorner.X, rect.LowerRightCorner.Y ); - GUIEngine::getDriver()->draw2DImage(texture, rect2, source_area, + draw2DImage(texture, rect2, source_area, 0 /* no clipping */, 0, true /* alpha */); } // doDrawBadge From 7bb1e671b200cc05b20518c511e283556244f175 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 22:10:56 +0000 Subject: [PATCH 150/412] OGL32CTX: Port draw2DRectangle too git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14916 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/coloredquad.frag | 7 ++++ data/shaders/coloredquad.vert | 11 ++++++ src/graphics/glwrap.cpp | 73 +++++++++++++++++++++++++++++++++++ src/graphics/glwrap.hpp | 4 ++ src/guiengine/skin.cpp | 8 ++-- 5 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 data/shaders/coloredquad.frag create mode 100644 data/shaders/coloredquad.vert diff --git a/data/shaders/coloredquad.frag b/data/shaders/coloredquad.frag new file mode 100644 index 000000000..da7911156 --- /dev/null +++ b/data/shaders/coloredquad.frag @@ -0,0 +1,7 @@ +#version 130 +uniform vec4 color; + +void main() +{ + gl_FragColor = color; +} \ No newline at end of file diff --git a/data/shaders/coloredquad.vert b/data/shaders/coloredquad.vert new file mode 100644 index 000000000..53c486ce3 --- /dev/null +++ b/data/shaders/coloredquad.vert @@ -0,0 +1,11 @@ +#version 130 +uniform vec2 center; +uniform vec2 size; + +in vec2 position; + + +void main() +{ + gl_Position = vec4(position * size + center, 0., 1.); +} \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 02d96f3fd..dfdff2d79 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -35,6 +35,8 @@ PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLUNIFORM2FPROC glUniform2f; PFNGLUNIFORM1IPROC glUniform1i; +PFNGLUNIFORM3IPROC glUniform3i; +PFNGLUNIFORM4IPROC glUniform4i; PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; @@ -79,6 +81,8 @@ void initGL() glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetShaderInfoLog"); glActiveTexture = (PFNGLACTIVETEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glActiveTexture"); glUniform2f = (PFNGLUNIFORM2FPROC)IRR_OGL_LOAD_EXTENSION("glUniform2f"); + glUniform4i = (PFNGLUNIFORM4IPROC)IRR_OGL_LOAD_EXTENSION("glUniform4i"); + glUniform3i = (PFNGLUNIFORM3IPROC)IRR_OGL_LOAD_EXTENSION("glUniform3i"); glUniform1i = (PFNGLUNIFORM1IPROC)IRR_OGL_LOAD_EXTENSION("glUniform1i"); glGetProgramiv = (PFNGLGETPROGRAMIVPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramiv"); glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)IRR_OGL_LOAD_EXTENSION("glGetProgramInfoLog"); @@ -255,3 +259,72 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glBindBuffer(GL_ARRAY_BUFFER, 0); #endif } + +static GLuint ColoredQuadShader; +static GLuint ColoredQuadUniformCenter; +static GLuint ColoredQuadUniformSize; +static GLuint ColoredQuadUniformColor; + +void GL32_draw2DRectangle(video::SColor color, const core::rect& position, + const core::rect* clip) +{ + +#ifndef OGL32CTX + irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); +#else + core::dimension2d frame_size = + irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); + const int screen_w = frame_size.Width; + const int screen_h = frame_size.Height; + float center_pos_x = position.UpperLeftCorner.X + position.LowerRightCorner.X; + center_pos_x /= screen_w; + center_pos_x -= 1; + float center_pos_y = position.UpperLeftCorner.Y + position.LowerRightCorner.Y; + center_pos_y /= screen_h; + center_pos_y = 1 - center_pos_y; + float width = position.LowerRightCorner.X - position.UpperLeftCorner.X; + width /= screen_w; + float height = position.LowerRightCorner.Y - position.UpperLeftCorner.Y; + height /= screen_h; + + initGL(); + const float quad_vertex[] = + { + -1., -1., 0., 1., + -1., 1., 0., 0., + 1., -1., 1., 1., + 1., 1., 1., 0. + }; + + if (color.getAlpha() < 255) + { + glEnable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + } + else + { + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + } + + if (!ColoredQuadShader) + { + ColoredQuadShader = LoadProgram(file_manager->getAsset("shaders/coloredquad.vert").c_str(), file_manager->getAsset("shaders/coloredquad.frag").c_str()); + glGenBuffers(1, &quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + ColoredQuadUniformColor = glGetUniformLocation(ColoredQuadShader, "color"); + } + glUseProgram(ColoredQuadShader); + glUniform2f(ColoredQuadUniformCenter, center_pos_x, center_pos_y); + glUniform2f(ColoredQuadUniformSize, width, height); + glUniform4i(ColoredQuadUniformColor, color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +#endif +} diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index b961654b8..beda6dd2c 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -57,6 +57,8 @@ extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLUNIFORM2FPROC glUniform2f; extern PFNGLUNIFORM1IPROC glUniform1i; +extern PFNGLUNIFORM3IPROC glUniform3i; +extern PFNGLUNIFORM4IPROC glUniform4i; extern PFNGLGETPROGRAMIVPROC glGetProgramiv; extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; @@ -74,4 +76,6 @@ void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect const irr::core::rect& sourceRect, const irr::core::rect* clipRect, const irr::video::SColor* const colors, bool useAlphaChannelOfTexture); +void GL32_draw2DRectangle(irr::video::SColor color, const irr::core::rect& position, + const irr::core::rect* clip = 0); #endif diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index aacaaae29..d17128d39 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -2061,12 +2061,12 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, center.Y + (int)(((int)rect.LowerRightCorner.Y - (int)center.Y)*texture_size); } - GUIEngine::getDriver()->draw2DRectangle(focused ? border_color_focus : border_color, borderArea); + GL32_draw2DRectangle(focused ? border_color_focus : border_color, borderArea); core::recti innerArea = borderArea; innerArea.UpperLeftCorner += position2d< s32 >( 3, 3 ); innerArea.LowerRightCorner -= position2d< s32 >( 3, 3 ); - GUIEngine::getDriver()->draw2DRectangle(focused ? bg_color_focused : bg_color, innerArea); + GL32_draw2DRectangle(focused ? bg_color_focused : bg_color, innerArea); return; } else if (type == WTYPE_LIST) @@ -2130,7 +2130,7 @@ void Skin::drawBGFadeColor() SColor color = SkinConfig::m_colors["dialog_background::neutral"]; if (m_dialog_size < 1.0f) color.setAlpha( (unsigned int)(color.getAlpha()*m_dialog_size )); - GUIEngine::getDriver()->draw2DRectangle( color, + GL32_draw2DRectangle(color, core::recti(position2d< s32 >(0,0), GUIEngine::getDriver()->getCurrentRenderTargetSize()) ); } // drawBGFadeColor @@ -2178,7 +2178,7 @@ void Skin::draw3DMenuPane (IGUIElement *element, const core::recti &rect, const core::recti *clip) { SColor color = SColor(150, 96, 74, 196); - GUIEngine::getDriver()->draw2DRectangle(color, rect); + GL32_draw2DRectangle(color, rect); } // draw3DMenuPane // ----------------------------------------------------------------------------- From 1a883f740f1259e51bf066407ef83b2cb8b218fe Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 22:15:28 +0000 Subject: [PATCH 151/412] OGL32CTX: Fix build issue git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14917 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index dfdff2d79..2e86d3dc2 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -270,7 +270,7 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, { #ifndef OGL32CTX - irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); + irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); #else core::dimension2d frame_size = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); From 57d5d658a0620763dd694c049b6c25244663aa41 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 4 Jan 2014 23:28:59 +0000 Subject: [PATCH 152/412] OGL32CTX: Fixes sourcerect in draw2DImage replacement git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14918 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/texturedquad.vert | 4 +- src/graphics/glwrap.cpp | 68 ++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/data/shaders/texturedquad.vert b/data/shaders/texturedquad.vert index aebd1222c..6e14ea24e 100644 --- a/data/shaders/texturedquad.vert +++ b/data/shaders/texturedquad.vert @@ -1,6 +1,8 @@ #version 130 uniform vec2 center; uniform vec2 size; +uniform vec2 texcenter; +uniform vec2 texsize; in vec2 position; in vec2 texcoord; @@ -8,6 +10,6 @@ out vec2 tc; void main() { - tc = texcoord; + tc = texcoord * texsize + texcenter; gl_Position = vec4(position * size + center, 0., 1.); } \ No newline at end of file diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 2e86d3dc2..8d702b763 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -46,7 +46,9 @@ PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; PFNGLDELETEBUFFERSPROC glDeleteBuffers; #endif +static GLuint quad_buffer; static bool is_gl_init = false; + void initGL() { if (is_gl_init) @@ -93,6 +95,16 @@ void initGL() glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); #endif + const float quad_vertex[] = { + -1., -1., -1., 1., // UpperLeft + -1., 1., -1., -1., // LowerLeft + 1., 1., 1., -1., // LowerRight + 1., -1., 1., 1. // UpperRight + }; + glGenBuffers(1, &quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); } // Mostly from shader tutorial @@ -183,13 +195,14 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni glUniform1i(location, textureUnit); } -static GLuint quad_buffer; static GLuint TexturedQuadShader; static GLuint TexturedQuadAttribPosition; static GLuint TexturedQuadAttribTexCoord; static GLuint TexturedQuadUniformTexture; static GLuint TexturedQuadUniformCenter; static GLuint TexturedQuadUniformSize; +static GLuint TexturedQuadUniformTexcenter; +static GLuint TexturedQuadUniformTexsize; void draw2DImage(const video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect, @@ -198,28 +211,45 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect #ifndef OGL32CTX irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); #else + core::dimension2d frame_size = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); const int screen_w = frame_size.Width; const int screen_h = frame_size.Height; float center_pos_x = destRect.UpperLeftCorner.X + destRect.LowerRightCorner.X; center_pos_x /= screen_w; - center_pos_x -= 1; + center_pos_x -= 1.; float center_pos_y = destRect.UpperLeftCorner.Y + destRect.LowerRightCorner.Y; center_pos_y /= screen_h; - center_pos_y = 1 - center_pos_y; + center_pos_y = 1. - center_pos_y; float width = destRect.LowerRightCorner.X - destRect.UpperLeftCorner.X; width /= screen_w; float height = destRect.LowerRightCorner.Y - destRect.UpperLeftCorner.Y; height /= screen_h; + const core::dimension2d& ss = texture->getOriginalSize(); + + float tex_center_pos_x = sourceRect.UpperLeftCorner.X + sourceRect.LowerRightCorner.X; + tex_center_pos_x /= ss.Width * 2.; + //tex_center_pos_x -= 1.; + float tex_center_pos_y = sourceRect.UpperLeftCorner.Y + sourceRect.LowerRightCorner.Y; + tex_center_pos_y /= ss.Height * 2.; + //tex_center_pos_y -= 1.; + float tex_width = sourceRect.LowerRightCorner.X - sourceRect.UpperLeftCorner.X; + tex_width /= ss.Width * 2.; + float tex_height = sourceRect.LowerRightCorner.Y - sourceRect.UpperLeftCorner.Y; + tex_height /= ss.Height * 2.; + + const f32 invW = 1.f / static_cast(ss.Width); + const f32 invH = 1.f / static_cast(ss.Height); + const core::rect tcoords( + sourceRect.UpperLeftCorner.X * invW, + sourceRect.UpperLeftCorner.Y * invH, + sourceRect.LowerRightCorner.X * invW, + sourceRect.LowerRightCorner.Y *invH); + initGL(); - const float quad_vertex[] = { - -1., -1., 0., 1., - -1., 1., 0., 0., - 1., -1., 1., 1., - 1., 1., 1., 0. - }; + if (useAlphaChannelOfTexture) { glEnable(GL_BLEND); @@ -233,14 +263,14 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect } if (!TexturedQuadShader) { TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); - glGenBuffers(1, &quad_buffer); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); + TexturedQuadUniformTexcenter = glGetUniformLocation(TexturedQuadShader, "texcenter"); + TexturedQuadUniformTexsize = glGetUniformLocation(TexturedQuadShader, "texsize"); } glUseProgram(TexturedQuadShader); glActiveTexture(GL_TEXTURE0); @@ -248,12 +278,14 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glUniform1i(TexturedQuadUniformTexture, 0); glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); glUniform2f(TexturedQuadUniformSize, width, height); + glUniform2f(TexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); + glUniform2f(TexturedQuadUniformTexsize, tex_width, tex_height); glEnableVertexAttribArray(TexturedQuadAttribPosition); glEnableVertexAttribArray(TexturedQuadAttribTexCoord); glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_QUADS, 0, 4); glDisableVertexAttribArray(TexturedQuadAttribPosition); glDisableVertexAttribArray(TexturedQuadAttribTexCoord); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -288,13 +320,6 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, height /= screen_h; initGL(); - const float quad_vertex[] = - { - -1., -1., 0., 1., - -1., 1., 0., 0., - 1., -1., 1., 1., - 1., 1., 1., 0. - }; if (color.getAlpha() < 255) { @@ -311,9 +336,6 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, if (!ColoredQuadShader) { ColoredQuadShader = LoadProgram(file_manager->getAsset("shaders/coloredquad.vert").c_str(), file_manager->getAsset("shaders/coloredquad.frag").c_str()); - glGenBuffers(1, &quad_buffer); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); ColoredQuadUniformColor = glGetUniformLocation(ColoredQuadShader, "color"); } glUseProgram(ColoredQuadShader); From fa068d7810163ceaddcf986b47d5956d0ccf25a1 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 00:08:00 +0000 Subject: [PATCH 153/412] OGL32CTX: Ask #version 130 for all our shaders git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14919 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/bloom.frag | 1 + data/shaders/bloomblend.frag | 1 + data/shaders/bloompower.frag | 1 + data/shaders/bubble.frag | 2 +- data/shaders/bubble.vert | 2 +- data/shaders/caustics.frag | 1 + data/shaders/collapse.frag | 1 + data/shaders/color_levels.frag | 1 + data/shaders/colorize.frag | 1 + data/shaders/colorize_ref.frag | 1 + data/shaders/displace.frag | 1 + data/shaders/displace.vert | 1 + data/shaders/farplane.vert | 1 + data/shaders/flip.frag | 1 + data/shaders/fog.frag | 1 + data/shaders/gaussian3h.frag | 1 + data/shaders/gaussian3v.frag | 1 + data/shaders/gaussian6h.frag | 1 + data/shaders/gaussian6v.frag | 1 + data/shaders/glow.frag | 1 + data/shaders/godfade.frag | 1 + data/shaders/godray.frag | 1 + data/shaders/gum_shield.frag | 2 +- data/shaders/gum_shield.vert | 2 +- data/shaders/lightbeam.frag | 2 +- data/shaders/lightbeam.vert | 2 +- data/shaders/lightblend.frag | 1 + data/shaders/mipviz.frag | 2 +- data/shaders/mlaa_blend2.frag | 1 + data/shaders/mlaa_color1.frag | 1 + data/shaders/mlaa_neigh3.frag | 1 + data/shaders/mlaa_offset.vert | 1 + data/shaders/motion_blur.frag | 1 + data/shaders/motion_blur.vert | 1 + data/shaders/multiply.frag | 1 + data/shaders/pass.frag | 1 + data/shaders/pass.vert | 2 ++ data/shaders/penumbrah.frag | 1 + data/shaders/penumbrav.frag | 1 + data/shaders/pointlight.frag | 1 + data/shaders/ppdisplace.frag | 1 + data/shaders/shadowgen.frag | 1 + data/shaders/shadowimportance.frag | 1 + data/shaders/shadowimportance.vert | 1 + data/shaders/shadowpass.frag | 1 + data/shaders/shadowpass.vert | 1 + data/shaders/shadowwarph.frag | 1 + data/shaders/shadowwarpv.frag | 1 + data/shaders/skinning.vert | 2 +- data/shaders/skybox.frag | 2 +- data/shaders/skybox.vert | 2 +- data/shaders/snow.frag | 1 + data/shaders/snow.vert | 1 + data/shaders/spheremap.frag | 2 +- data/shaders/spheremap.vert | 2 +- data/shaders/ssao.frag | 2 +- data/shaders/sunlight.frag | 1 + data/shaders/sunlightshadow.frag | 1 + data/shaders/water.frag | 2 +- data/shaders/water.vert | 2 +- data/shaders/white.frag | 1 + 61 files changed, 62 insertions(+), 15 deletions(-) diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index f00f76c1e..cdd30a12b 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform float low; diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag index 6cb0ec93d..c01aaa9b9 100644 --- a/data/shaders/bloomblend.frag +++ b/data/shaders/bloomblend.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; void main() diff --git a/data/shaders/bloompower.frag b/data/shaders/bloompower.frag index 441090cb6..227e0523d 100644 --- a/data/shaders/bloompower.frag +++ b/data/shaders/bloompower.frag @@ -1,3 +1,4 @@ +#version 130 uniform float power; uniform sampler2D tex; diff --git a/data/shaders/bubble.frag b/data/shaders/bubble.frag index 6e900c98e..aceba169f 100644 --- a/data/shaders/bubble.frag +++ b/data/shaders/bubble.frag @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +#version 130 uniform sampler2D tex; uniform float transparency; varying vec2 uv; diff --git a/data/shaders/bubble.vert b/data/shaders/bubble.vert index eb332ea1c..07cd1b31f 100644 --- a/data/shaders/bubble.vert +++ b/data/shaders/bubble.vert @@ -17,7 +17,7 @@ // Creates a bubble (wave) effect by distorting the texture depending on time - +#version 130 uniform float time; varying vec2 uv; diff --git a/data/shaders/caustics.frag b/data/shaders/caustics.frag index 8ce7a6303..eefba44b6 100644 --- a/data/shaders/caustics.frag +++ b/data/shaders/caustics.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform sampler2D caustictex; uniform vec2 dir; diff --git a/data/shaders/collapse.frag b/data/shaders/collapse.frag index 7e2e8b64c..8586f7aca 100644 --- a/data/shaders/collapse.frag +++ b/data/shaders/collapse.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform sampler2D oldtex; uniform vec2 pixel; diff --git a/data/shaders/color_levels.frag b/data/shaders/color_levels.frag index 6de49ca71..2aed42742 100644 --- a/data/shaders/color_levels.frag +++ b/data/shaders/color_levels.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec3 inlevel; uniform vec2 outlevel; diff --git a/data/shaders/colorize.frag b/data/shaders/colorize.frag index 2e44f6a07..d1a10a4c5 100644 --- a/data/shaders/colorize.frag +++ b/data/shaders/colorize.frag @@ -1,3 +1,4 @@ +#version 130 uniform vec3 col; void main() diff --git a/data/shaders/colorize_ref.frag b/data/shaders/colorize_ref.frag index c7dac6c99..d3944c0c7 100644 --- a/data/shaders/colorize_ref.frag +++ b/data/shaders/colorize_ref.frag @@ -1,3 +1,4 @@ +#version 130 uniform vec3 col; uniform sampler2D tex; diff --git a/data/shaders/displace.frag b/data/shaders/displace.frag index a54dea589..9dee23292 100644 --- a/data/shaders/displace.frag +++ b/data/shaders/displace.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 screen; uniform vec2 dir; diff --git a/data/shaders/displace.vert b/data/shaders/displace.vert index f2fe1c59f..8cb364888 100644 --- a/data/shaders/displace.vert +++ b/data/shaders/displace.vert @@ -1,3 +1,4 @@ +#version 130 varying float camdist; void main() { diff --git a/data/shaders/farplane.vert b/data/shaders/farplane.vert index cec567fb2..d6a859a07 100644 --- a/data/shaders/farplane.vert +++ b/data/shaders/farplane.vert @@ -1,3 +1,4 @@ +#version 130 void main() { gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; diff --git a/data/shaders/flip.frag b/data/shaders/flip.frag index 7ed45f0a2..f108cb0b3 100644 --- a/data/shaders/flip.frag +++ b/data/shaders/flip.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; void main() diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag index 6ac828d43..6c74800f8 100644 --- a/data/shaders/fog.frag +++ b/data/shaders/fog.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform float fogmax; diff --git a/data/shaders/gaussian3h.frag b/data/shaders/gaussian3h.frag index f1ec80b89..66d56f5f4 100644 --- a/data/shaders/gaussian3h.frag +++ b/data/shaders/gaussian3h.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/gaussian3v.frag b/data/shaders/gaussian3v.frag index fec9ce8b1..fe9897949 100644 --- a/data/shaders/gaussian3v.frag +++ b/data/shaders/gaussian3v.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/gaussian6h.frag b/data/shaders/gaussian6h.frag index 3aad9b7c0..69c1197e6 100644 --- a/data/shaders/gaussian6h.frag +++ b/data/shaders/gaussian6h.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/gaussian6v.frag b/data/shaders/gaussian6v.frag index 5b3e70ee2..2b520ca04 100644 --- a/data/shaders/gaussian6v.frag +++ b/data/shaders/gaussian6v.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag index c3c9acbc7..75940a806 100644 --- a/data/shaders/glow.frag +++ b/data/shaders/glow.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 res; diff --git a/data/shaders/godfade.frag b/data/shaders/godfade.frag index 659742738..59e7aa4d3 100644 --- a/data/shaders/godfade.frag +++ b/data/shaders/godfade.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec3 col; diff --git a/data/shaders/godray.frag b/data/shaders/godray.frag index 0e06dfb03..8f360e650 100644 --- a/data/shaders/godray.frag +++ b/data/shaders/godray.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 sunpos; diff --git a/data/shaders/gum_shield.frag b/data/shaders/gum_shield.frag index e2d4b6e44..f7ff37f37 100644 --- a/data/shaders/gum_shield.frag +++ b/data/shaders/gum_shield.frag @@ -19,7 +19,7 @@ // Jean-manuel clemencon (c) supertuxkart 2013 // bubble gum shield // TODO: Add a nice texture and soft edges when intersect with geometry - +#version 130 uniform sampler2D tex; uniform float transparency; diff --git a/data/shaders/gum_shield.vert b/data/shaders/gum_shield.vert index 60f72a853..1a60f1f8e 100644 --- a/data/shaders/gum_shield.vert +++ b/data/shaders/gum_shield.vert @@ -22,7 +22,7 @@ // TODO: The texture should reflect the strength of the shield, // such that the user gets to know whether the shield has several // "layers" or whether the shield is about to break. - +#version 130 varying vec2 uv; varying vec3 eyeVec; varying vec3 normal; diff --git a/data/shaders/lightbeam.frag b/data/shaders/lightbeam.frag index 1b5817c1c..3c98fc665 100644 --- a/data/shaders/lightbeam.frag +++ b/data/shaders/lightbeam.frag @@ -21,7 +21,7 @@ // Original idea: http://udn.epicgames.com/Three/VolumetricLightbeamTutorial.html // TODO: Soft edges when it intesects geometry // Some artefacts are still visible - +#version 130 uniform sampler2D tex; uniform float transparency; diff --git a/data/shaders/lightbeam.vert b/data/shaders/lightbeam.vert index b584b9ba5..b81d8dda7 100644 --- a/data/shaders/lightbeam.vert +++ b/data/shaders/lightbeam.vert @@ -18,7 +18,7 @@ // Jean-manuel clemencon (C) Copyright supertuxkart // Creates a cone lightbeam effect by smoothing edges - +#version 130 varying vec2 uv; varying vec3 eyeVec; varying vec3 normal; diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index a9100da0e..7391105eb 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D diffuse; uniform sampler2D specular; uniform sampler2D ambient_occlusion; diff --git a/data/shaders/mipviz.frag b/data/shaders/mipviz.frag index e6bd31741..b73a7d14c 100644 --- a/data/shaders/mipviz.frag +++ b/data/shaders/mipviz.frag @@ -1,4 +1,4 @@ -#version 120 +#version 130 uniform sampler2D tex; uniform vec2 texsize; diff --git a/data/shaders/mlaa_blend2.frag b/data/shaders/mlaa_blend2.frag index 0be80576b..5116c9099 100644 --- a/data/shaders/mlaa_blend2.frag +++ b/data/shaders/mlaa_blend2.frag @@ -1,3 +1,4 @@ +#version 130 #define MAX_SEARCH_STEPS 8.0 #define MAX_DISTANCE 33.0 diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag index 390c3f72c..068e13985 100644 --- a/data/shaders/mlaa_color1.frag +++ b/data/shaders/mlaa_color1.frag @@ -1,3 +1,4 @@ +#version 130 varying vec4 offset[2]; uniform sampler2D colorMapG; diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag index 6f9bfabb0..28f189015 100644 --- a/data/shaders/mlaa_neigh3.frag +++ b/data/shaders/mlaa_neigh3.frag @@ -1,3 +1,4 @@ +#version 130 varying vec4 offset[2]; uniform sampler2D blendMap; diff --git a/data/shaders/mlaa_offset.vert b/data/shaders/mlaa_offset.vert index a0b03702e..e457a0f1b 100644 --- a/data/shaders/mlaa_offset.vert +++ b/data/shaders/mlaa_offset.vert @@ -1,3 +1,4 @@ +#version 130 varying vec4 offset[2]; uniform vec2 PIXEL_SIZE; diff --git a/data/shaders/motion_blur.frag b/data/shaders/motion_blur.frag index aef0843fb..f558a5677 100644 --- a/data/shaders/motion_blur.frag +++ b/data/shaders/motion_blur.frag @@ -21,6 +21,7 @@ // The actual boost amount (which linearly scales the blur to be shown). // should be in the range [0.0, 1.0], though a larger value might make // the blurring too string. Atm we are using [0, 0.5]. +#version 130 uniform float boost_amount; // The color buffer to use. diff --git a/data/shaders/motion_blur.vert b/data/shaders/motion_blur.vert index 50c721f79..608115086 100644 --- a/data/shaders/motion_blur.vert +++ b/data/shaders/motion_blur.vert @@ -17,6 +17,7 @@ // motion_blur.vert +#version 130 void main() { diff --git a/data/shaders/multiply.frag b/data/shaders/multiply.frag index 9394e9595..2e8f3eb5a 100644 --- a/data/shaders/multiply.frag +++ b/data/shaders/multiply.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex1; uniform sampler2D tex2; diff --git a/data/shaders/pass.frag b/data/shaders/pass.frag index 10f94ce0d..da55410ec 100644 --- a/data/shaders/pass.frag +++ b/data/shaders/pass.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; void main() diff --git a/data/shaders/pass.vert b/data/shaders/pass.vert index 5b5aa7261..30ea1f514 100644 --- a/data/shaders/pass.vert +++ b/data/shaders/pass.vert @@ -1,3 +1,5 @@ +#version 130 + void main() { gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; diff --git a/data/shaders/penumbrah.frag b/data/shaders/penumbrah.frag index 822c73e56..e4598d354 100644 --- a/data/shaders/penumbrah.frag +++ b/data/shaders/penumbrah.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/penumbrav.frag b/data/shaders/penumbrav.frag index 6a6ef2ca0..e8e6bbefd 100644 --- a/data/shaders/penumbrav.frag +++ b/data/shaders/penumbrav.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform vec2 pixel; diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index bcdb5f0d7..b60cb1005 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D ntex; uniform vec4 center[16]; diff --git a/data/shaders/ppdisplace.frag b/data/shaders/ppdisplace.frag index a06293649..5e4cf1606 100644 --- a/data/shaders/ppdisplace.frag +++ b/data/shaders/ppdisplace.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform sampler2D dtex; diff --git a/data/shaders/shadowgen.frag b/data/shaders/shadowgen.frag index 6c2d8501a..55ed4e86d 100644 --- a/data/shaders/shadowgen.frag +++ b/data/shaders/shadowgen.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D halft; // half is a reserved word uniform sampler2D quarter; uniform sampler2D eighth; diff --git a/data/shaders/shadowimportance.frag b/data/shaders/shadowimportance.frag index 190d40418..6751b41bf 100644 --- a/data/shaders/shadowimportance.frag +++ b/data/shaders/shadowimportance.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D ntex; uniform sampler2D ctex; uniform vec3 campos; diff --git a/data/shaders/shadowimportance.vert b/data/shaders/shadowimportance.vert index 87ab5c783..4f47d2a4a 100644 --- a/data/shaders/shadowimportance.vert +++ b/data/shaders/shadowimportance.vert @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D dtex; uniform mat4 ipvmat; uniform mat4 shadowmat; diff --git a/data/shaders/shadowpass.frag b/data/shaders/shadowpass.frag index 974cce97f..bdbfde05c 100644 --- a/data/shaders/shadowpass.frag +++ b/data/shaders/shadowpass.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform int hastex; uniform int viz; diff --git a/data/shaders/shadowpass.vert b/data/shaders/shadowpass.vert index 631dbb5a6..35a104882 100644 --- a/data/shaders/shadowpass.vert +++ b/data/shaders/shadowpass.vert @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D warpx; uniform sampler2D warpy; diff --git a/data/shaders/shadowwarph.frag b/data/shaders/shadowwarph.frag index e7e9d5632..a7e09b740 100644 --- a/data/shaders/shadowwarph.frag +++ b/data/shaders/shadowwarph.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform int size; uniform vec2 pixel; diff --git a/data/shaders/shadowwarpv.frag b/data/shaders/shadowwarpv.frag index 6998c61e7..89fd11bc8 100644 --- a/data/shaders/shadowwarpv.frag +++ b/data/shaders/shadowwarpv.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform int size; uniform vec2 pixel; diff --git a/data/shaders/skinning.vert b/data/shaders/skinning.vert index 5de0a2631..2f2e0d083 100644 --- a/data/shaders/skinning.vert +++ b/data/shaders/skinning.vert @@ -16,7 +16,7 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // skinning.vert - +#version 130 #define MAX_JOINT_NUM 36 #define MAX_LIGHT_NUM 8 diff --git a/data/shaders/skybox.frag b/data/shaders/skybox.frag index 6c2dcb5a6..61aacff4b 100644 --- a/data/shaders/skybox.frag +++ b/data/shaders/skybox.frag @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +#version 130 uniform sampler2D tex; uniform sampler2D glow_tex; uniform float transparency; diff --git a/data/shaders/skybox.vert b/data/shaders/skybox.vert index dae614974..e3ed7f3ea 100644 --- a/data/shaders/skybox.vert +++ b/data/shaders/skybox.vert @@ -17,7 +17,7 @@ // Creates a bubble (wave) effect by distorting the texture depending on time - +#version 130 uniform float time; varying vec2 uv; diff --git a/data/shaders/snow.frag b/data/shaders/snow.frag index 3fddd77ec..62abb54d1 100644 --- a/data/shaders/snow.frag +++ b/data/shaders/snow.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D tex; uniform float time; diff --git a/data/shaders/snow.vert b/data/shaders/snow.vert index 232f74268..120b6b650 100644 --- a/data/shaders/snow.vert +++ b/data/shaders/snow.vert @@ -1,3 +1,4 @@ +#version 130 void main() { gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; diff --git a/data/shaders/spheremap.frag b/data/shaders/spheremap.frag index 80c03f71b..960dfd228 100644 --- a/data/shaders/spheremap.frag +++ b/data/shaders/spheremap.frag @@ -15,7 +15,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +#version 130 uniform sampler2D texture; varying vec3 normal; uniform vec3 lightdir; diff --git a/data/shaders/spheremap.vert b/data/shaders/spheremap.vert index 8e899a862..407016756 100644 --- a/data/shaders/spheremap.vert +++ b/data/shaders/spheremap.vert @@ -15,7 +15,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - +#version 130 varying vec3 normal; varying vec4 vertex_color; varying vec3 eyeVec; diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 3edfad13d..cbcd8ceb3 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,4 +1,4 @@ -#version 120 +#version 130 uniform sampler2D normals_and_depth; uniform mat4 invprojm; uniform mat4 projm; diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index a96812ce6..c202b38d1 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D ntex; uniform sampler2D cloudtex; diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index af2d8428d..b3f95c0c4 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -1,3 +1,4 @@ +#version 130 uniform sampler2D ntex; uniform sampler2D dtex; uniform sampler2D cloudtex; diff --git a/data/shaders/water.frag b/data/shaders/water.frag index 3f36b8b72..c882f9970 100644 --- a/data/shaders/water.frag +++ b/data/shaders/water.frag @@ -1,6 +1,6 @@ // Shader based on work by Fabien Sanglard // Released under the terms of CC-BY 3.0 - +#version 130 uniform sampler2D BumpTex1; // Normal map 1 uniform sampler2D BumpTex2; // Normal map 2 uniform sampler2D DecalTex; //The texture diff --git a/data/shaders/water.vert b/data/shaders/water.vert index 95d59fe76..b3bae373f 100644 --- a/data/shaders/water.vert +++ b/data/shaders/water.vert @@ -1,6 +1,6 @@ // Shader based on work by Fabien Sanglard // Released under the terms of CC-BY 3.0 - +#version 130 uniform float speed; uniform float height; uniform float waveLength; diff --git a/data/shaders/white.frag b/data/shaders/white.frag index 1cc07d303..e396c44e2 100644 --- a/data/shaders/white.frag +++ b/data/shaders/white.frag @@ -1,3 +1,4 @@ +#version 130 void main() { gl_FragColor = vec4(1.0); From d28a869444d618716387cbb4861289e981bb25f5 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 00:08:11 +0000 Subject: [PATCH 154/412] Fix skybox frag shader git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14920 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/skybox.frag | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/data/shaders/skybox.frag b/data/shaders/skybox.frag index 61aacff4b..d46c3f5ce 100644 --- a/data/shaders/skybox.frag +++ b/data/shaders/skybox.frag @@ -28,18 +28,18 @@ varying vec2 uv_fast; void main() { - + vec2 uv_temp = uv; vec3 V = normalize(vertex); vec3 L = normalize(vec3(sun_pos)); - vec3 col = texture2D(tex, vec2((L.y + 1.0) / 2.0, V.y)); + vec3 col = texture2D(tex, vec2((L.y + 1.0) / 2.0, V.y)).xyz; float vl = clamp(dot(V, L), 0, 1); - vec3 paint = texture2D(tex, uv * 3).a; + float paint = texture2D(tex, uv_temp * 3).a; - uv += 20; - vec3 paint2 = texture2D(tex, uv * 5).a; + uv_temp += 20; + float paint2 = texture2D(tex, uv_temp * 5).a; // Get the general cloud mask From d44c28ca9ea1d86b38180bfcffd6ffa909d4e322 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 17:34:01 +0000 Subject: [PATCH 157/412] OGL32CTX: GL_QUADS was deprecated, use TRIANGLE_STRIP git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14923 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- 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 8d702b763..74c2fd67a 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -98,8 +98,8 @@ void initGL() const float quad_vertex[] = { -1., -1., -1., 1., // UpperLeft -1., 1., -1., -1., // LowerLeft + 1., -1., 1., 1., // UpperRight 1., 1., 1., -1., // LowerRight - 1., -1., 1., 1. // UpperRight }; glGenBuffers(1, &quad_buffer); glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); @@ -285,7 +285,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(TexturedQuadAttribPosition); glDisableVertexAttribArray(TexturedQuadAttribTexCoord); glBindBuffer(GL_ARRAY_BUFFER, 0); From 8a33f14da5a5ba1e557eb75fa7418ac2744f4e8a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 17:48:36 +0000 Subject: [PATCH 158/412] OGL32CTX: Request a 3.0 backward compatible context in linux. This allows to enable ARB_DEBUG_OUTPUT extension. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14924 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 17 ++++- .../source/Irrlicht/CIrrDeviceLinux.h | 1 + src/graphics/glwrap.cpp | 66 +++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index f9d2d0052..5f6536196 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -724,8 +724,23 @@ bool CIrrDeviceLinux::createWindow() glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); if (glxWin) { + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + // Uncomment to discard deprecated features + //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, +#if DEBUG + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, +#endif + None + }; + + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) + glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); // create glx context - Context = glXCreateNewContext(display, glxFBConfig, GLX_RGBA_TYPE, NULL, True); + Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, context_attribs); if (Context) { if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h index 4d2a2c650..bc4a99a6d 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h @@ -22,6 +22,7 @@ #define GLX_GLXEXT_LEGACY 1 #include #ifdef _IRR_OPENGL_USE_EXTPOINTER_ +#define GLX_GLXEXT_PROTOTYPES #include "glxext.h" #endif #endif diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 74c2fd67a..3a5405a07 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -49,6 +49,69 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers; static GLuint quad_buffer; static bool is_gl_init = false; +static +void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar* msg, const void *userparam) +{ + switch(source) + { + case GL_DEBUG_SOURCE_API_ARB: + printf("[API]"); + break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: + printf("[WINDOW_SYSTEM]"); + break; + case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: + printf("[SHADER_COMPILER]"); + break; + case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: + printf("[THIRD_PARTY]"); + break; + case GL_DEBUG_SOURCE_APPLICATION_ARB: + printf("[APPLICATION]"); + break; + case GL_DEBUG_SOURCE_OTHER_ARB: + printf("[OTHER]"); + break; + } + + switch(type) + { + case GL_DEBUG_TYPE_ERROR_ARB: + printf("[ERROR]"); + break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: + printf("[DEPRECATED_BEHAVIOR]"); + break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: + printf("[UNDEFINED_BEHAVIOR]"); + break; + case GL_DEBUG_TYPE_PORTABILITY_ARB: + printf("[PORTABILITY]"); + break; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: + printf("[PERFORMANCE]"); + break; + case GL_DEBUG_TYPE_OTHER_ARB: + printf("[OTHER]"); + break; + } + + switch(severity) + { + case GL_DEBUG_SEVERITY_HIGH_ARB: + printf("[HIGH]"); + break; + case GL_DEBUG_SEVERITY_MEDIUM_ARB: + printf("[MEDIUM]"); + break; + case GL_DEBUG_SEVERITY_LOW_ARB: + printf("[LOW]"); + break; + } + printf("%s\n", msg); +} + void initGL() { if (is_gl_init) @@ -94,6 +157,9 @@ void initGL() glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribDivisor"); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); +#endif +#if DEBUG + glDebugMessageCallbackARB(debugCallback, NULL); #endif const float quad_vertex[] = { -1., -1., -1., 1., // UpperLeft From ce62c0b3b742784d40c254bb9bb8317aab9d8727 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 17:57:22 +0000 Subject: [PATCH 159/412] OGL32CTX: Fix osx build git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14925 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 4 +++- src/graphics/glwrap.hpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 3a5405a07..f60e9bf66 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -49,6 +49,7 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers; static GLuint quad_buffer; static bool is_gl_init = false; +#ifdef DEBUG_OUTPUT_DECLARED static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *userparam) @@ -111,6 +112,7 @@ void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsiz } printf("%s\n", msg); } +#endif void initGL() { @@ -158,7 +160,7 @@ void initGL() glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); #endif -#if DEBUG +#ifdef DEBUG_OUTPUT_DECLARED glDebugMessageCallbackARB(debugCallback, NULL); #endif const float quad_vertex[] = { diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index beda6dd2c..4a5f4755b 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -14,6 +14,7 @@ # include #else #define GL_GLEXT_PROTOTYPES +#define DEBUG_OUTPUT_DECLARED # include #endif From aad565a9bfc5340fe29d78e900af57a399f72b27 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 18:44:52 +0000 Subject: [PATCH 160/412] GPUParticles: Use size value so that it doesn't get optimized away Spotted by arb debug output. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14926 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index f73371d53..a304914f7 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -27,6 +27,6 @@ void main(void) new_particle_position = (adjusted_lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; new_lifetime = (adjusted_lifetime < 1.) ? adjusted_lifetime : 0.; new_particle_velocity = (adjusted_lifetime < 1.) ? particle_velocity : adjusted_initial_velocity.xyz; - new_size = size_initial; + new_size = (adjusted_lifetime < 1.) ? size : size_initial; gl_Position = vec4(0.); } From 7778a71c0a46e93abab97d5c75e7132a9f967838 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 18:54:40 +0000 Subject: [PATCH 161/412] OGL32CTX: Use correct type in coloredquad.frag Spotted by arb debug output too. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14927 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/coloredquad.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/coloredquad.frag b/data/shaders/coloredquad.frag index da7911156..3a794e33c 100644 --- a/data/shaders/coloredquad.frag +++ b/data/shaders/coloredquad.frag @@ -1,5 +1,5 @@ #version 130 -uniform vec4 color; +uniform ivec4 color; void main() { From 869386c3384d07a7422ef8dd4c2bb00d27c60591 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 21:12:19 +0000 Subject: [PATCH 162/412] Centralize view and proj matrix to avoid recomputation. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14928 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 18 +++++++----------- src/graphics/callbacks.hpp | 30 +----------------------------- src/graphics/gpuparticles.cpp | 12 ++++-------- src/graphics/irr_driver.hpp | 13 ++++++++++++- src/graphics/render.cpp | 12 +++--------- 5 files changed, 27 insertions(+), 58 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index fbde078ed..77e7ac32c 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -227,18 +227,15 @@ void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const float screenw = (float)UserConfigParams::m_width; const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const matrix4 viewm = srv->getVideoDriver()->getTransform(ETS_VIEW); - matrix4 invproj = srv->getVideoDriver()->getTransform(ETS_PROJECTION); - invproj.makeInverse(); const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); float screen[2] = { (float)UserConfigParams::m_width, (float)UserConfigParams::m_height }; srv->setVertexShaderConstant("screenw", &screenw, 1); srv->setVertexShaderConstant("time", &time, 1); - srv->setVertexShaderConstant("viewm", viewm.pointer(), 16); + srv->setVertexShaderConstant("viewm", irr_driver->getViewMatrix().pointer(), 16); srv->setVertexShaderConstant("campos", &campos.X, 3); - srv->setPixelShaderConstant("invproj", invproj.pointer(), 16); + srv->setPixelShaderConstant("invproj", irr_driver->getInvProjMatrix().pointer(), 16); srv->setPixelShaderConstant("screen", screen, 2); s32 tex = 0; srv->setPixelShaderConstant("tex", &tex, 1); @@ -375,14 +372,13 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) { - int lightcount = m_color.size() / 4; srv->setVertexShaderConstant("screen", m_screen, 2); srv->setVertexShaderConstant("spec", &m_specular, 1); - srv->setVertexShaderConstant("invproj", m_invproj.pointer(), 16); + srv->setVertexShaderConstant("invproj", irr_driver->getInvProjMatrix().pointer(), 16); srv->setVertexShaderConstant("energy[0]", m_energy.data(), m_energy.size()); srv->setVertexShaderConstant("col[0]", m_color.data(), m_color.size()); srv->setVertexShaderConstant("center[0]", m_pos.data(), m_pos.size()); - srv->setVertexShaderConstant("viewm", m_view.pointer(), 16); + srv->setVertexShaderConstant("viewm", irr_driver->getViewMatrix().pointer(), 16); if (!firstdone) { @@ -406,7 +402,7 @@ void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("screen", m_screen, 2); srv->setVertexShaderConstant("col", m_color, 3); srv->setVertexShaderConstant("center", m_pos, 3); - srv->setVertexShaderConstant("invproj", m_invproj.pointer(), 16); + srv->setVertexShaderConstant("invproj", irr_driver->getInvProjMatrix().pointer(), 16); srv->setVertexShaderConstant("hasclouds", &hasclouds, 1); const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; @@ -529,8 +525,8 @@ void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int) void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int) { - srv->setPixelShaderConstant("invprojm", invprojm.pointer(), 16); - srv->setPixelShaderConstant("projm", projm.pointer(), 16); + srv->setPixelShaderConstant("invprojm", irr_driver->getInvProjMatrix().pointer(), 16); + srv->setPixelShaderConstant("projm", irr_driver->getProjMatrix().pointer(), 16); srv->setPixelShaderConstant("samplePoints[0]", array, 64); if (!firstdone) diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 95bc47021..99ef8c1cf 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -421,17 +421,7 @@ public: m_energy = e; } - void updateIPVMatrix() - { - const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - m_view = drv->getTransform(video::ETS_VIEW); - m_invproj = drv->getTransform(video::ETS_PROJECTION); - m_invproj.makeInverse(); - } - private: - core::matrix4 m_invproj, m_view; - std::vector m_color; std::vector m_pos; std::vector m_energy; @@ -476,22 +466,13 @@ public: m_pos[2] = pos.Z; } - void updateIPVMatrix() - { - // Update the IPV matrix, only once per frame since it's costly - const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - - m_invproj = drv->getTransform(video::ETS_PROJECTION); - m_invproj.makeInverse(); - } - void setShadowMatrix(const core::matrix4 &mat) { m_shadowmat = mat; } private: - core::matrix4 m_invproj, m_shadowmat; + core::matrix4 m_shadowmat; float m_color[3]; float m_pos[3]; float m_screen[2]; @@ -542,7 +523,6 @@ public: class SSAOProvider: public CallBase { private: - core::matrix4 projm, invprojm; float array[64]; public: SSAOProvider() : CallBase() { @@ -569,14 +549,6 @@ public: } virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - void updateIPVMatrix() - { - // Update the IPV matrix, only once per frame since it's costly - const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - - projm = drv->getTransform(video::ETS_PROJECTION); - projm.getInverse(invprojm); - } }; // diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 0163b0de3..a12b87a39 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -342,7 +342,6 @@ void ParticleSystemProxy::simulate() return; } - u32 now = time; u32 timediff = time - LastEmitTime; LastEmitTime = time; @@ -398,8 +397,7 @@ void ParticleSystemProxy::draw() glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); - core::matrix4 projm = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - core::matrix4 viewm = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + if (m_alpha_additive) glBlendFunc(GL_SRC_ALPHA, GL_ONE); else @@ -415,16 +413,14 @@ void ParticleSystemProxy::draw() (float)UserConfigParams::m_width, (float)UserConfigParams::m_height }; - irr::core::matrix4 invproj = irr_driver->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION); - invproj.makeInverse(); bindUniformToTextureUnit(uniform_texture, texture, 0); bindUniformToTextureUnit(uniform_normal_and_depths, normal_and_depth, 1); - glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, invproj.pointer()); + glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); glUniform2f(uniform_screen, screen[0], screen[1]); - glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, projm.pointer()); - glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, viewm.pointer()); + glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); + glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 68fcfcfe9..8f95f4653 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -99,6 +99,9 @@ private: /** The main MRT setup. */ core::array m_mrt; + /** Matrixes used in several places stored here to avoid recomputation. */ + core::matrix4 m_ViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix; + /** Flag to indicate if a resolution change is pending (which will be * acted upon in the next update). None means no change, yes means * change to new resolution and trigger confirmation dialog. @@ -462,7 +465,15 @@ public: void clearLights(); // ------------------------------------------------------------------------ scene::IMeshSceneNode *getSunInterposer() { return m_sun_interposer; } - + // ------------------------------------------------------------------------ + void setViewMatrix(core::matrix4 matrix) { m_ViewMatrix = matrix; } + const core::matrix4 &getViewMatrix() const { return m_ViewMatrix; } + void setProjMatrix(core::matrix4 matrix) { m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix); } + const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; } + const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; } + void genProjViewMatrix() { m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix; m_InvProjViewMatrix = m_ProjViewMatrix; m_InvProjViewMatrix.makeInverse(); } + const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; } + const core::matrix4 &getInvProjViewMatrix() const { return m_InvProjViewMatrix; } #ifdef DEBUG /** Removes debug meshes. */ void clearDebugMesh() { m_debug_meshes.clear(); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8b5cc5e13..276a5e046 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -194,6 +194,9 @@ void IrrDriver::renderGLSL(float dt) m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID; m_scene_manager->drawAll(m_renderpass); + irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)); + irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); + irr_driver->genProjViewMatrix(); ShadowImportanceProvider * const sicb = (ShadowImportanceProvider *) irr_driver->getCallback(ES_SHADOW_IMPORTANCE); @@ -684,18 +687,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, video::SColor(0, 0, 0, 0)); m_scene_manager->drawAll(scene::ESNRP_CAMERA); - PointLightProvider * const pcb = (PointLightProvider *) irr_driver-> - getCallback(ES_POINTLIGHT); - pcb->updateIPVMatrix(); - SunLightProvider * const scb = (SunLightProvider *) irr_driver-> - getCallback(ES_SUNLIGHT); - scb->updateIPVMatrix(); FogProvider * const fogcb = (FogProvider *) irr_driver-> getCallback(ES_FOG); fogcb->updateIPVMatrix(); - SSAOProvider * const ssaocb = (SSAOProvider *) irr_driver-> - getCallback(ES_SSAO); - ssaocb->updateIPVMatrix(); const u32 lightcount = m_lights.size(); From 2fe8eafbe12dba8aa7fe82bdeda48b1d17c766fc Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 21:14:10 +0000 Subject: [PATCH 163/412] OGL Debug : looks like not all driver on linux support arb debug output :( git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14929 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- 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 f60e9bf66..09caf8876 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -49,7 +49,7 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers; static GLuint quad_buffer; static bool is_gl_init = false; -#ifdef DEBUG_OUTPUT_DECLARED +#if 0 static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *userparam) @@ -160,7 +160,7 @@ void initGL() glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); #endif -#ifdef DEBUG_OUTPUT_DECLARED +#if 0 glDebugMessageCallbackARB(debugCallback, NULL); #endif const float quad_vertex[] = { From 9bf632fb4b31a9e40687ba8b3fa7997e2a0fda3b Mon Sep 17 00:00:00 2001 From: stephenjust Date: Sun, 5 Jan 2014 21:14:28 +0000 Subject: [PATCH 164/412] Fix crash loading tracks when shaders are disabled git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14930 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- 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 a8f3fc190..eae9566d8 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2161,7 +2161,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, } else { - return NULL; + return m_scene_manager->addLightSceneNode(m_scene_manager->getRootSceneNode(), pos, video::SColor(1., r, g, b)); } } From ffc1524bf775641d15c251b1a6f92a82f3ea49bb Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 21:39:42 +0000 Subject: [PATCH 166/412] GPUParticles: Use fallback if glsl is disabled. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14932 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 2 ++ src/graphics/particle_emitter.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index a12b87a39..2d702986f 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -46,6 +46,8 @@ scene::IParticleSystemSceneNode *ParticleSystemProxy::addParticleNode( const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) { + if (!irr_driver->isGLSL()) + return irr_driver->addParticleNode(); if (!parent) parent = irr_driver->getSceneManager()->getRootSceneNode(); diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index df818cd51..15b302d8b 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -382,7 +382,8 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) else { m_node = ParticleSystemProxy::addParticleNode(); - static_cast(m_node)->setAlphaAdditive(type->getMaterial()->isAlphaAdditive()); + if (irr_driver->isGLSL()) + static_cast(m_node)->setAlphaAdditive(type->getMaterial()->isAlphaAdditive()); } if (m_parent != NULL) From 62f815ff68b6abef1733821b3cfc9d4d82c195eb Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 21:39:54 +0000 Subject: [PATCH 167/412] Debug output: Use a comment to tell not to remove that code git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14933 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 09caf8876..219401175 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -49,7 +49,9 @@ PFNGLDELETEBUFFERSPROC glDeleteBuffers; static GLuint quad_buffer; static bool is_gl_init = false; -#if 0 +// Please leave this code, it's for debugging purpose +//#define ENABLE_ARB_DEBUG_OUTPUT +#ifdef ENABLE_ARB_DEBUG_OUTPUT static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *userparam) @@ -160,7 +162,7 @@ void initGL() glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)IRR_OGL_LOAD_EXTENSION("glDrawArraysInstanced"); glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteBuffers"); #endif -#if 0 +#if ENABLE_ARB_DEBUG_OUTPUT glDebugMessageCallbackARB(debugCallback, NULL); #endif const float quad_vertex[] = { From 78ca6f2b9c7bac38cde71cd18aa5a54dafd3af61 Mon Sep 17 00:00:00 2001 From: stephenjust Date: Sun, 5 Jan 2014 22:56:27 +0000 Subject: [PATCH 168/412] Don't crash when shaders are disabled when drawing snow git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14934 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/particle_emitter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 15b302d8b..c9912a635 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -569,7 +569,8 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) const bool flips = type->getFlips(); if (flips) { - m_node->getMaterial(0).MaterialType = irr_driver->getShader(ES_SNOW); + if (irr_driver->isGLSL()) + m_node->getMaterial(0).MaterialType = irr_driver->getShader(ES_SNOW); m_node->getMaterial(0).BlendOperation = video::EBO_ADD; } } From fb57b75cc02b95b568fe99cc43347670721f211d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 5 Jan 2014 23:32:24 +0000 Subject: [PATCH 169/412] GPUParticles: Attempt at fixing the green flash bug in minel git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14935 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2d702986f..0bbfd040a 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -291,6 +291,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) default: assert(0 && "Wrong particle type"); } + glBindBuffer(GL_ARRAY_BUFFER, 0); texture = getTextureGLuint(getMaterial(0).getTexture(0)); normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); From 068eb8ece213f11e93a66c75d26a7c4d3c6396f6 Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 6 Jan 2014 02:55:37 +0000 Subject: [PATCH 172/412] Add ozoneone's new snow song git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14938 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/CREDITS | Bin 12854 -> 12896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/CREDITS b/data/CREDITS index 92fc11536754fb925aede34a4975915c5216eb2d..b358814c2b3e38b26c38b64200b32e33ba814731 100644 GIT binary patch delta 90 zcmdm%@*riy4jEG&1_cInhG2#~hJ1!{hDsnCBI3=E!;r|31jMBbB@C$yML=~aKwch0 aGDGU*vofZPI+HnNrFl{GZ&s8Q6$JpJh7#`p delta 70 zcmaEmvMpu94jEAehD3%uh7<+`26cvDAS<7toS|~^TNzV%WEmHRREAujTpmze216!8 M4nxjnZ&^`M0E7$>Jpcdz From 6ee751e3c375af4cf7c7b25b9d0aba191718b55c Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 6 Jan 2014 12:23:16 +0000 Subject: [PATCH 173/412] Added new class to handle command line parameters, which simplifies parameter handling in main (e.g. it's not necessary to list and ignore parameters in the 2nd pass, when they were handled in the first pass). Removed some command line options for which there is a guy (e.g. --weather), or which are not really useful (--list-karts). All parameters to options must now consistently be specified using '=', e.g.: --log=1 and --kart=tux. Also removed support for 'classic' camera (which was not used anymore). Removed now unneccessary #include in user_config.hpp, which made some #include changes in other files necessary. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14939 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 31 +- src/config/player.hpp | 1 + src/config/saved_grand_prix.cpp | 1 + src/config/user_config.hpp | 8 - src/graphics/callbacks.cpp | 2 + src/graphics/camera.cpp | 17 - src/graphics/camera.hpp | 9 - src/graphics/gpuparticles.cpp | 2 +- src/graphics/gpuparticles.h | 13 +- src/graphics/irr_driver.cpp | 3 +- src/graphics/post_processing.cpp | 3 +- src/graphics/rain.cpp | 4 +- src/io/file_manager.cpp | 7 +- src/io/file_manager.hpp | 2 +- src/items/rubber_ball.cpp | 1 + src/karts/controller/player_controller.hpp | 1 + src/karts/explosion_animation.cpp | 2 + src/karts/rescue_animation.cpp | 2 + src/main.cpp | 1145 ++++++++------------ src/modes/follow_the_leader.cpp | 1 + src/modes/three_strikes_battle.cpp | 1 + src/states_screens/race_gui_base.cpp | 1 + src/tracks/check_structure.cpp | 1 + src/tracks/track.cpp | 1 + src/utils/command_line.cpp | 67 ++ src/utils/command_line.hpp | 121 +++ src/utils/log.cpp | 18 +- 27 files changed, 722 insertions(+), 743 deletions(-) create mode 100644 src/utils/command_line.cpp create mode 100644 src/utils/command_line.hpp diff --git a/sources.cmake b/sources.cmake index d021cb042..ec7051ef2 100644 --- a/sources.cmake +++ b/sources.cmake @@ -117,8 +117,8 @@ src/items/projectile_manager.cpp src/items/rubber_ball.cpp src/items/rubber_band.cpp src/items/swatter.cpp -src/karts/abstract_kart_animation.cpp src/karts/abstract_kart.cpp +src/karts/abstract_kart_animation.cpp src/karts/cannon_animation.cpp src/karts/controller/ai_base_controller.cpp src/karts/controller/ai_properties.cpp @@ -249,8 +249,8 @@ src/states_screens/help_screen_3.cpp src/states_screens/help_screen_4.cpp src/states_screens/kart_selection.cpp src/states_screens/main_menu_screen.cpp -src/states_screens/networking_lobby.cpp src/states_screens/network_kart_selection.cpp +src/states_screens/networking_lobby.cpp src/states_screens/offline_kart_selection.cpp src/states_screens/online_profile_achievements.cpp src/states_screens/online_profile_base.cpp @@ -260,13 +260,13 @@ src/states_screens/online_profile_settings.cpp src/states_screens/online_screen.cpp src/states_screens/online_user_search.cpp src/states_screens/options_screen_audio.cpp -src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_input.cpp +src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_players.cpp src/states_screens/options_screen_ui.cpp src/states_screens/options_screen_video.cpp -src/states_screens/race_gui_base.cpp src/states_screens/race_gui.cpp +src/states_screens/race_gui_base.cpp src/states_screens/race_gui_overworld.cpp src/states_screens/race_result_gui.cpp src/states_screens/race_setup_screen.cpp @@ -305,6 +305,7 @@ src/tracks/track_object.cpp src/tracks/track_object_manager.cpp src/tracks/track_object_presentation.cpp src/tracks/track_sector.cpp +src/utils/command_line.cpp src/utils/constants.cpp src/utils/crash_reporting.cpp src/utils/debug.cpp @@ -335,8 +336,8 @@ src/animations/animation_base.hpp src/animations/ipo.hpp src/animations/three_d_animation.hpp src/audio/dummy_sfx.hpp -src/audio/music_dummy.hpp src/audio/music.hpp +src/audio/music_dummy.hpp src/audio/music_information.hpp src/audio/music_manager.hpp src/audio/music_ogg.hpp @@ -344,8 +345,8 @@ src/audio/sfx_base.hpp src/audio/sfx_buffer.hpp src/audio/sfx_manager.hpp src/audio/sfx_openal.hpp -src/challenges/challenge_data.hpp src/challenges/challenge.hpp +src/challenges/challenge_data.hpp src/challenges/game_slot.hpp src/challenges/unlock_manager.hpp src/config/device_config.hpp @@ -359,7 +360,6 @@ src/graphics/CBatchingMesh.hpp src/graphics/explosion.hpp src/graphics/glow.hpp src/graphics/glwrap.hpp -src/graphics/gpuparticles.h src/graphics/hardware_skinning.hpp src/graphics/hit_effect.hpp src/graphics/hit_sfx.hpp @@ -403,11 +403,11 @@ src/guiengine/scalable_font.hpp src/guiengine/screen.hpp src/guiengine/skin.hpp src/guiengine/widget.hpp +src/guiengine/widgets.hpp src/guiengine/widgets/bubble_widget.hpp src/guiengine/widgets/button_widget.hpp src/guiengine/widgets/check_box_widget.hpp src/guiengine/widgets/dynamic_ribbon_widget.hpp -src/guiengine/widgets.hpp src/guiengine/widgets/icon_button_widget.hpp src/guiengine/widgets/label_widget.hpp src/guiengine/widgets/list_widget.hpp @@ -419,8 +419,8 @@ src/guiengine/widgets/spinner_widget.hpp src/guiengine/widgets/text_box_widget.hpp src/input/binding.hpp src/input/device_manager.hpp -src/input/input_device.hpp src/input/input.hpp +src/input/input_device.hpp src/input/input_manager.hpp src/input/wiimote.hpp src/input/wiimote_manager.hpp @@ -442,8 +442,8 @@ src/items/projectile_manager.hpp src/items/rubber_ball.hpp src/items/rubber_band.hpp src/items/swatter.hpp -src/karts/abstract_kart_animation.hpp src/karts/abstract_kart.hpp +src/karts/abstract_kart_animation.hpp src/karts/cannon_animation.hpp src/karts/controller/ai_base_controller.hpp src/karts/controller/ai_properties.hpp @@ -455,8 +455,8 @@ src/karts/controller/player_controller.hpp src/karts/controller/skidding_ai.hpp src/karts/explosion_animation.hpp src/karts/ghost_kart.hpp -src/karts/kart_gfx.hpp src/karts/kart.hpp +src/karts/kart_gfx.hpp src/karts/kart_model.hpp src/karts/kart_properties.hpp src/karts/kart_properties_manager.hpp @@ -579,8 +579,8 @@ src/states_screens/help_screen_3.hpp src/states_screens/help_screen_4.hpp src/states_screens/kart_selection.hpp src/states_screens/main_menu_screen.hpp -src/states_screens/networking_lobby.hpp src/states_screens/network_kart_selection.hpp +src/states_screens/networking_lobby.hpp src/states_screens/offline_kart_selection.hpp src/states_screens/online_profile_achievements.hpp src/states_screens/online_profile_base.hpp @@ -590,13 +590,13 @@ src/states_screens/online_profile_settings.hpp src/states_screens/online_screen.hpp src/states_screens/online_user_search.hpp src/states_screens/options_screen_audio.hpp -src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_input.hpp +src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_players.hpp src/states_screens/options_screen_ui.hpp src/states_screens/options_screen_video.hpp -src/states_screens/race_gui_base.hpp src/states_screens/race_gui.hpp +src/states_screens/race_gui_base.hpp src/states_screens/race_gui_overworld.hpp src/states_screens/race_result_gui.hpp src/states_screens/race_setup_screen.hpp @@ -627,8 +627,8 @@ src/tracks/check_sphere.hpp src/tracks/check_structure.hpp src/tracks/graph_node.hpp src/tracks/lod_node_loader.hpp -src/tracks/quad_graph.hpp src/tracks/quad.hpp +src/tracks/quad_graph.hpp src/tracks/quad_set.hpp src/tracks/terrain_info.hpp src/tracks/track.hpp @@ -638,6 +638,7 @@ src/tracks/track_object_manager.hpp src/tracks/track_object_presentation.hpp src/tracks/track_sector.hpp src/utils/aligned_array.hpp +src/utils/command_line.hpp src/utils/constants.hpp src/utils/crash_reporting.hpp src/utils/debug.hpp diff --git a/src/config/player.hpp b/src/config/player.hpp index 809d5416e..b94d8136e 100644 --- a/src/config/player.hpp +++ b/src/config/player.hpp @@ -22,6 +22,7 @@ #include #include "config/user_config.hpp" #include "utils/no_copy.hpp" +#include "utils/types.hpp" #include using namespace irr; diff --git a/src/config/saved_grand_prix.cpp b/src/config/saved_grand_prix.cpp index bf8f2b01d..7bb889192 100644 --- a/src/config/saved_grand_prix.cpp +++ b/src/config/saved_grand_prix.cpp @@ -19,6 +19,7 @@ #include "config/saved_grand_prix.hpp" +#include "io/xml_node.hpp" #include "karts/kart_properties_manager.hpp" #include "utils/ptr_vector.hpp" #include "utils/string_utils.hpp" diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index 81d59034f..77fb4ebfb 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -46,7 +46,6 @@ using irr::core::stringc; using irr::core::stringw; -#include "graphics/camera.hpp" #include "io/xml_writer.hpp" #include "utils/constants.hpp" #include "utils/no_copy.hpp" @@ -528,9 +527,6 @@ namespace UserConfigParams // not saved to file // ---- Networking - PARAM_PREFIX IntUserConfigParam m_server_port - PARAM_DEFAULT( IntUserConfigParam(7321, "server_port", - "Information about the port to listen on.") ); PARAM_PREFIX IntUserConfigParam m_server_max_players PARAM_DEFAULT( IntUserConfigParam(16, "server_max_players", @@ -666,10 +662,6 @@ namespace UserConfigParams PARAM_DEFAULT( IntUserConfigParam(0, "reverse_look_threshold", "If the kart is driving backwards faster than this value,\n" "switch automatically to reverse camera (set to 0 to disable).") ); - PARAM_PREFIX IntUserConfigParam m_camera_style - PARAM_DEFAULT( IntUserConfigParam(Camera::CS_MODERN, - "camera_style", "Camera Style") ); - PARAM_PREFIX StringUserConfigParam m_item_style PARAM_DEFAULT( StringUserConfigParam("items", "item_style", diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 77e7ac32c..057f00b11 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -15,6 +15,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "graphics/callbacks.hpp" + +#include "graphics/camera.hpp" #include "graphics/irr_driver.hpp" #include "graphics/wind.hpp" #include "guiengine/engine.hpp" diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 0e9026e85..f58b43941 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -71,13 +71,6 @@ Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL) m_target_speed = 10.0f; m_rotation_range = 0.4f; m_rotation_range = 0.0f; - // TODO: Make this per user too if the one above goes that way. - switch(UserConfigParams::m_camera_style) - { - case 1: m_camera_style = CS_CLASSIC; break; - case 0: - default: m_camera_style = CS_MODERN; break; - } reset(); } // Camera @@ -373,16 +366,6 @@ void Camera::getCameraSettings(float *above_kart, float *cam_angle, switch(m_mode) { case CM_NORMAL: - if(m_camera_style==CS_CLASSIC) - { - *above_kart = 0.3f; - *cam_angle = kp->getCameraBackwardUpAngle(); - *sideway = 0.0f; - *distance = -1.5f*m_distance; - *smoothing = true; - break; - } - // Fall through to falling mode. case CM_FALLING: { if(UserConfigParams::m_camera_debug==2) diff --git a/src/graphics/camera.hpp b/src/graphics/camera.hpp index 01426c802..07ac34865 100644 --- a/src/graphics/camera.hpp +++ b/src/graphics/camera.hpp @@ -59,11 +59,6 @@ public: CM_FALLING }; - enum Style { - CS_MODERN, //!< Flexible link between kart and camera - CS_CLASSIC, //!< Fixed position style, like STK v0.6 - }; - private: /** The camera scene node. */ scene::ICameraSceneNode *m_camera; @@ -117,10 +112,6 @@ private: /** Velocity of the target of the camera, only used for end camera. */ core::vector3df m_target_velocity; - /* Whether we should use the pre-0.7 camera style or the - * modern style. Should default to modern. */ - Style m_camera_style; - /** List of all cameras. */ static std::vector m_all_cameras; diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 0bbfd040a..9f9519e39 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -102,7 +102,7 @@ void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &life { float sizeMin = emitter->getMinStartSize().Height; float sizeMax = emitter->getMaxStartSize().Height; - float lifetime_range = emitter->getMaxLifeTime() - emitter->getMinLifeTime(); + float lifetime_range = float(emitter->getMaxLifeTime() - emitter->getMinLifeTime()); lifetime = os::Randomizer::frand() * lifetime_range; lifetime += emitter->getMinLifeTime(); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index cca0be2d4..5cd8fdd3d 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -2,19 +2,24 @@ #define GPUPARTICLES_H #include "graphics/glwrap.hpp" + #include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h" #include #include +namespace irr { namespace video{ class ITexture; } } + GLuint getTextureGLuint(irr::video::ITexture *tex); -class GPUParticle : public scene::ISceneNode { +class GPUParticle : public scene::ISceneNode +{ protected: video::SMaterial fakemat; virtual void simulate() = 0; virtual void draw() = 0; public: - GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex); + GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, + video::ITexture *tex); virtual void render(); virtual void OnRegisterSceneNode(); }; @@ -79,7 +84,7 @@ protected: virtual void draw(); public: PointEmitter(scene::ISceneNode *parent, - scene::ISceneManager* mgr, ITexture *tex, + scene::ISceneManager* mgr, video::ITexture *tex, const core::vector3df& dir, u32 minParticlesPerSecond, u32 maxParticlesPerSecond, @@ -109,7 +114,7 @@ protected: virtual void simulate(); virtual void draw(); public: - RainNode(scene::ISceneManager* mgr, ITexture *tex); + RainNode(scene::ISceneManager* mgr, video::ITexture *tex); virtual const core::aabbox3d& getBoundingBox() const; virtual u32 getMaterialCount() const { return 1; } }; diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index eae9566d8..af09d8e6b 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2161,7 +2161,8 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, } else { - return m_scene_manager->addLightSceneNode(m_scene_manager->getRootSceneNode(), pos, video::SColor(1., r, g, b)); + return m_scene_manager->addLightSceneNode(m_scene_manager->getRootSceneNode(), + pos, video::SColor(1.0f, r, g, b)); } } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 519c2cc5d..f4a4b8b22 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -18,12 +18,13 @@ #include "post_processing.hpp" #include "config/user_config.hpp" -#include "io/file_manager.hpp" #include "graphics/callbacks.hpp" +#include "graphics/camera.hpp" #include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" #include "graphics/mlaa_areamap.hpp" #include "graphics/shaders.hpp" +#include "io/file_manager.hpp" #include "karts/abstract_kart.hpp" #include "karts/kart_model.hpp" #include "modes/world.hpp" diff --git a/src/graphics/rain.cpp b/src/graphics/rain.cpp index b2adc28c9..091025f72 100644 --- a/src/graphics/rain.cpp +++ b/src/graphics/rain.cpp @@ -18,7 +18,9 @@ #include "audio/sfx_base.hpp" #include "audio/sfx_manager.hpp" +#include "graphics/camera.hpp" #include "graphics/glwrap.hpp" +#include "graphics/gpuparticles.h" #include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "graphics/material.hpp" @@ -30,9 +32,9 @@ #include "utils/constants.hpp" #include "utils/random_generator.hpp" + #include #include -#include "graphics/gpuparticles.h" using namespace video; using namespace scene; diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 096ea1672..765dff7df 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -25,6 +25,7 @@ #include "graphics/material_manager.hpp" #include "karts/kart_properties_manager.hpp" #include "tracks/track_manager.hpp" +#include "utils/command_line.hpp" #include "utils/log.hpp" #include "utils/string_utils.hpp" @@ -105,7 +106,7 @@ FileManager* file_manager = 0; * exists) changed in reInit(). * */ -FileManager::FileManager(char *argv[]) +FileManager::FileManager() { m_subdir_name.resize(ASSET_COUNT); m_subdir_name[CHALLENGE ] = "challenges"; @@ -144,8 +145,8 @@ FileManager::FileManager(char *argv[]) // This is esp. useful for Visual Studio, since it's not necessary // to define the working directory when debugging, it works automatically. std::string root_dir; - if(m_file_system->existFile(argv[0])) - exe_path = m_file_system->getFileDir(argv[0]); + if(m_file_system->existFile(CommandLine::getExecName().c_str())) + exe_path = m_file_system->getFileDir(CommandLine::getExecName().c_str()); if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/') exe_path += "/"; if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL ) diff --git a/src/io/file_manager.hpp b/src/io/file_manager.hpp index 55e11385d..4037cb464 100644 --- a/src/io/file_manager.hpp +++ b/src/io/file_manager.hpp @@ -96,7 +96,7 @@ private: #endif public: - FileManager(char *argv[]); + FileManager(); ~FileManager(); void reInit(); void dropFileSystem(); diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 3d14a3086..b8086a759 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -21,6 +21,7 @@ #include "audio/sfx_base.hpp" #include "audio/sfx_manager.hpp" #include "config/stk_config.hpp" +#include "io/xml_node.hpp" #include "items/attachment.hpp" #include "items/projectile_manager.hpp" #include "karts/abstract_kart.hpp" diff --git a/src/karts/controller/player_controller.hpp b/src/karts/controller/player_controller.hpp index 7bb7c0a13..5839c5992 100644 --- a/src/karts/controller/player_controller.hpp +++ b/src/karts/controller/player_controller.hpp @@ -25,6 +25,7 @@ #include "karts/controller/controller.hpp" class AbstractKart; +class Camera; class Player; class SFXBase; diff --git a/src/karts/explosion_animation.cpp b/src/karts/explosion_animation.cpp index 08ac464ce..37656b295 100644 --- a/src/karts/explosion_animation.cpp +++ b/src/karts/explosion_animation.cpp @@ -19,6 +19,8 @@ #include "karts/explosion_animation.hpp" #include "audio/sfx_manager.hpp" +#include "graphics/callbacks.hpp" +#include "graphics/camera.hpp" #include "items/attachment.hpp" #include "karts/abstract_kart.hpp" #include "karts/kart_properties.hpp" diff --git a/src/karts/rescue_animation.cpp b/src/karts/rescue_animation.cpp index 4c77b9813..62330f421 100644 --- a/src/karts/rescue_animation.cpp +++ b/src/karts/rescue_animation.cpp @@ -18,6 +18,8 @@ #include "karts/rescue_animation.hpp" +#include "graphics/callbacks.hpp" +#include "graphics/camera.hpp" #include "graphics/referee.hpp" #include "items/attachment.hpp" #include "karts/abstract_kart.hpp" diff --git a/src/main.cpp b/src/main.cpp index 84b27c91f..686b6f127 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -196,6 +196,7 @@ #include "states_screens/dialogs/message_dialog.hpp" #include "tracks/track.hpp" #include "tracks/track_manager.hpp" +#include "utils/command_line.hpp" #include "utils/constants.hpp" #include "utils/crash_reporting.hpp" #include "utils/leak_check.hpp" @@ -388,7 +389,7 @@ void handleXmasMode() // ---------------------------------------------------------------------------- /** Prints help for command line options to stdout. */ -void cmdLineHelp(char* invocation) +void cmdLineHelp() { Log::info("main", "Usage: %s [OPTIONS]\n\n" @@ -399,49 +400,37 @@ void cmdLineHelp(char* invocation) "menu.\n" " -R, --race-now Same as -N but also skip the ready-set-go phase" " and the music.\n" - " -t, --track NAME Start at track NAME (see --list-tracks).\n" - " --gp NAME Start the specified Grand Prix.\n" - " --stk-config FILE use ./data/FILE instead of " + " -t, --track=NAME Start at track NAME.\n" + " --gp=NAME Start the specified Grand Prix.\n" + " --stk-config=FILE use ./data/FILE instead of " "./data/stk_config.xml\n" - " -l, --list-tracks Show available tracks.\n" - " -k, --numkarts NUM Number of karts on the racetrack.\n" - " --kart NAME Use kart number NAME (see --list-karts).\n" + " -k, --numkarts=NUM Number of karts on the racetrack.\n" + " --kart=NAME Use kart number NAME.\n" " --ai=a,b,... Use the karts a, b, ... for the AI.\n" - " --list-karts Show available karts.\n" - " --laps N Define number of laps to N.\n" - " --mode N N=1 novice, N=2 driver, N=3 racer.\n" - " --type N N=0 Normal, N=1 Time trial, N=2 FTL\n" + " --laps=N Define number of laps to N.\n" + " --mode=N N=1 novice, N=2 driver, N=3 racer.\n" + " --type=N N=0 Normal, N=1 Time trial, N=2 FTL\n" " --reverse Play track in reverse (if allowed)\n" // TODO: add back "--players" switch // " --players n Define number of players to between 1 and 4.\n" " -f, --fullscreen Select fullscreen display.\n" " -w, --windowed Windowed display (default).\n" - " -s, --screensize WxH Set the screen size (e.g. 320x200).\n" + " -s, --screensize=WxH Set the screen size (e.g. 320x200).\n" " -v, --version Show version of SuperTuxKart.\n" - " --trackdir DIR A directory from which additional tracks are " + " --trackdir=DIR A directory from which additional tracks are " "loaded.\n" - " --animations=n Play karts' animations (All: 2, Humans only: 1," - " Nobody: 0).\n" - " --gfx=n Play other graphical effects like impact stars " - "dance,\n" - " water animations or explosions (Enable: 1, " - "Disable: 0).\n" - " --weather=n Show weather effects like rain or snow (0 or 1 " - "as --gfx).\n" - " --camera-style=n Flexible (0) or hard like v0.6 (1) kart-camera " - "link.\n" " --profile-laps=n Enable automatic driven profile mode for n " "laps.\n" " --profile-time=n Enable automatic driven profile mode for n " "seconds.\n" " --no-graphics Do not display the actual race.\n" " --with-profile Enables the profile mode.\n" - " --demo-mode t Enables demo mode after t seconds idle time in " + " --demo-mode=t Enables demo mode after t seconds idle time in " "main menu.\n" - " --demo-tracks t1,t2 List of tracks to be used in demo mode. No\n" + " --demo-tracks=t1,t2 List of tracks to be used in demo mode. No\n" " spaces are allowed in the track names.\n" - " --demo-laps n Number of laps in a demo.\n" - " --demo-karts n Number of karts to use in a demo.\n" + " --demo-laps=n Number of laps in a demo.\n" + " --demo-karts=n Number of karts to use in a demo.\n" " --ghost Replay ghost data together with one player kart.\n" // " --history Replay history file 'history.dat'.\n" // " --history=n Replay history file 'history.dat' using:\n" @@ -458,7 +447,8 @@ void cmdLineHelp(char* invocation) " -h, --help Show this help.\n" "\n" "You can visit SuperTuxKart's homepage at " - "http://supertuxkart.sourceforge.net\n\n", invocation + "http://supertuxkart.sourceforge.net\n\n", + CommandLine::getExecName().c_str() ); } // cmdLineHelp @@ -470,676 +460,484 @@ void cmdLineHelp(char* invocation) * track_manager, since their search path might be extended by command * line options). */ -int handleCmdLinePreliminary(int argc, char **argv) +int handleCmdLinePreliminary() { - int n; - for(int i=1; iload(file_manager->getAsset(argv[i+1])); - Log::info("main", "STK config will be read from %s.\n",argv[i+1] ); - i++; - } - else if( !strcmp(argv[i], "--trackdir") && i+1load(file_manager->getAsset(s)); + Log::info("main", "STK config will be read from %s.",s); + } + if( CommandLine::has( "--trackdir", &s)) + TrackManager::addTrackSearchDir(s); + if( CommandLine::has( "--kartdir", &s)) + KartPropertiesManager::addKartSearchDir(s); + + if( CommandLine::has( "--no-graphics") || + CommandLine::has("-l" ) ) + { + ProfileWorld::disableGraphics(); + UserConfigParams::m_log_errors_to_console=true; + } + + if(CommandLine::has("--screensize", &s) || + CommandLine::has("-s", &s) ) + { + //Check if fullscreen and new res is blacklisted + int width, height; + if (sscanf(s.c_str(), "%dx%d", &width, &height) == 2) + { + // Reassemble the string in case that the original width or + // height contained a leading 0 + std::ostringstream o; + o << width << "x" << height; + std::string res = o.str(); + if (!UserConfigParams::m_fullscreen || + std::find(UserConfigParams::m_blacklist_res.begin(), + UserConfigParams::m_blacklist_res.end(),res) == + UserConfigParams::m_blacklist_res.end()) + { + UserConfigParams::m_prev_width = + UserConfigParams::m_width = width; + UserConfigParams::m_prev_height = + UserConfigParams::m_height = height; + Log::verbose("main", "You choose to use %dx%d.", + (int)UserConfigParams::m_width, + (int)UserConfigParams::m_height ); + } + else + Log::warn("main", "Resolution %s has been blacklisted, so " + "it is not available!", res.c_str()); + } + else + { + Log::fatal("main", "Error: --screensize argument must be " + "given as WIDTHxHEIGHT"); + } + } + + +//#if !defined(WIN32) && !defined(__CYGWIN) + if(CommandLine::has("--fullscreen") || CommandLine::has("-f")) + { + // Check that current res is not blacklisted + std::ostringstream o; + o << UserConfigParams::m_width << "x" << UserConfigParams::m_height; + std::string res = o.str(); + if (std::find(UserConfigParams::m_blacklist_res.begin(), + UserConfigParams::m_blacklist_res.end(),res) + == UserConfigParams::m_blacklist_res.end()) + UserConfigParams::m_fullscreen = true; + else + Log::warn("main", "Resolution %s has been blacklisted, so it " + "is not available!", res.c_str()); + } + if(CommandLine::has("--windowed") || CommandLine::has("-w")) + UserConfigParams::m_fullscreen = false; +//#endif + + if(CommandLine::has("--version") || CommandLine::has("-v")) + { + Log::info("main", "=============================="); + Log::info("main", "SuperTuxKart, %s.", STK_VERSION ) ; +#ifdef SVNVERSION + Log::info("main", "SuperTuxKart, SVN revision number '%s'.", + SVNVERSION ) ; +#endif + // IRRLICHT_VERSION_SVN + Log::info("main", "Irrlicht version %i.%i.%i (%s)", + IRRLICHT_VERSION_MAJOR , IRRLICHT_VERSION_MINOR, + IRRLICHT_VERSION_REVISION, IRRLICHT_SDK_VERSION ); + Log::info("main", "=============================="); + } // --verbose or -v + + int n; + if(CommandLine::has("--xmas", &n)) + UserConfigParams::m_xmas_mode = n; + if(CommandLine::has("--log", &n)) + Log::setLogLevel(n); + return 0; } // handleCmdLinePreliminary // ============================================================================ /** Handles command line options. * \param argc Number of command line options - * \param argv Command line options. */ -int handleCmdLine(int argc, char **argv) +int handleCmdLine() { + // Some generic variables used in scanning: int n; - char s[1024]; + std::string s; bool try_login = false; irr::core::stringw login, password; - for(int i=1; igetNumberOfKarts(); i++) - { - const KartProperties *km = - kart_properties_manager->getKartById(i); - Log::info("main", "%s:\t%swidth: %f length: %f height: %f " - "mesh-buffer count %d", - km->getIdent().c_str(), - (km->getIdent().size()<7) ? "\t" : "", - km->getMasterKartModel().getWidth(), - km->getMasterKartModel().getLength(), - km->getMasterKartModel().getHeight(), - km->getMasterKartModel().getModel() - ->getMeshBufferCount()); - } - } - else if(UserConfigParams::m_artist_debug_mode && - !strcmp(argv[i], "--check-debug")) - { - UserConfigParams::m_check_debug=true; - } - else if(!strcmp(argv[i], "--slipstream-debug")) - { + if(CommandLine::has( "--track-debug",&n)) + UserConfigParams::m_track_debug=n; + if(CommandLine::has( "--track-debug")) + UserConfigParams::m_track_debug=1; + if(CommandLine::has("--material-debug")) + UserConfigParams::m_material_debug = true; + if(CommandLine::has("--ftl-debug")) + UserConfigParams::m_ftl_debug = true; + if(CommandLine::has("--slipstream-debug")) UserConfigParams::m_slipstream_debug=true; - } - else if(!strcmp(argv[i], "--rendering-debug")) - { - UserConfigParams::m_rendering_debug=true; - } - else if(!strcmp(argv[i], "--ai-debug")) - { - AIBaseController::enableDebug(); - } - else if(sscanf(argv[i], "--port=%d",&n)) - { - UserConfigParams::m_server_port = n; - } - else if( !strcmp(argv[i], "--server") ) - { - NetworkManager::getInstance(); - Log::info("main", "Creating a server network manager."); - } - else if( sscanf(argv[i], "--max-players=%d", &n) ) - { - UserConfigParams::m_server_max_players=n; - } - else if( sscanf(argv[i], "--login=%1023s", s) ) - { - login = s; - try_login = true; - } - else if( sscanf(argv[i], "--password=%1023s", s) ) - { - password = s; - } - else if ( sscanf(argv[i], "--gfx=%d", &n) ) - { - if (n) - { - UserConfigParams::m_graphical_effects = true; - } - else - { - UserConfigParams::m_graphical_effects = false; - } - } - else if ( sscanf(argv[i], "--weather=%d", &n) ) - { - if (n) - { - UserConfigParams::m_weather_effects = true; - } - else - { - UserConfigParams::m_weather_effects = false; - } - } - else if ( sscanf(argv[i], "--animations=%d", &n) ) - { - UserConfigParams::m_show_steering_animations = n; - } + if(CommandLine::has("--rendering-debug")) + UserConfigParams::m_rendering_debug=true; + if(CommandLine::has("--ai-debug")) + AIBaseController::enableDebug(); - else if ( sscanf(argv[i], "--camera-style=%d", &n) ) - { - UserConfigParams::m_camera_style = n; - } - else if( (!strcmp(argv[i], "--kart") && i+1setCurrentSlot(UserConfigParams::m_all_players[0] - .getUniqueID() ); + if(UserConfigParams::m_artist_debug_mode) + { + if(CommandLine::has("--camera-wheel-debug")) + UserConfigParams::m_camera_debug=2; + if(CommandLine::has("--camera-debug")) + UserConfigParams::m_camera_debug=1; + if(CommandLine::has("--physics-debug")) + UserConfigParams::m_physics_debug=1; + if(CommandLine::has("--check-debug")) + UserConfigParams::m_check_debug=true; + } - if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1])) - { - const KartProperties *prop = - kart_properties_manager->getKart(argv[i+1]); - if(prop) - { - UserConfigParams::m_default_kart = argv[i+1]; + // Networking command lines + if(CommandLine::has("--server") ) + { + NetworkManager::getInstance(); + Log::info("main", "Creating a server network manager."); + } // -server - // if a player was added with -N, change its kart. - // Otherwise, nothing to do, kart choice will be picked - // up upon player creation. - if (StateManager::get()->activePlayerCount() > 0) - { - race_manager->setLocalKartInfo(0, argv[i+1]); - } - Log::verbose("main", "You chose to use kart '%s'.", - argv[i+1] ) ; - i++; - } - else - { - Log::warn("main", "Kart '%s' not found, ignored.", - argv[i+1]); - i++; // ignore the next parameter, otherwise STK will abort - } - } - else // kart locked - { - Log::warn("main", "Kart '%s' has not been unlocked yet.", - argv[i+1]); - Log::warn("main", - "Use --list-karts to list available karts."); - return 0; - } // if kart locked - } - else if( sscanf(argv[i], "--ai=%1023s", s)==1) - { - const std::vector l= - StringUtils::split(std::string(s),','); - race_manager->setDefaultAIKartList(l); - // Add 1 for the player kart - race_manager->setNumKarts(l.size()+1); - } - else if( (!strcmp(argv[i], "--mode") && i+1RaceManager::DIFFICULTY_LAST) - Log::warn("main", "Invalid difficulty '%s' - ignored.\n", - argv[i+1]); - else - race_manager->setDifficulty(RaceManager::Difficulty(n)); - i++; - } - else if( (!strcmp(argv[i], "--type") && i+1setMinorMode(RaceManager::MINOR_MODE_NORMAL_RACE); - break; - case 1: race_manager - ->setMinorMode(RaceManager::MINOR_MODE_TIME_TRIAL); - break; - case 2: race_manager - ->setMinorMode(RaceManager::MINOR_MODE_FOLLOW_LEADER); - break; - default: - Log::warn("main", "Invalid race type '%d' - ignored.", - atoi(argv[i+1])); - } - i++; - } - else if( !strcmp(argv[i], "--reverse")) - { - race_manager->setReverseTrack(true); - } - else if( (!strcmp(argv[i], "--track") || !strcmp(argv[i], "-t")) - && i+1setCurrentSlot(UserConfigParams::m_all_players[0] - .getUniqueID() ); - if (!unlock_manager->getCurrentSlot()->isLocked(argv[i+1])) - { - race_manager->setTrack(argv[i+1]); - Log::verbose("main", "You choose to start in track '%s'.", - argv[i+1] ); + if(CommandLine::has("--max-players", &n)) + UserConfigParams::m_server_max_players=n; - Track* t = track_manager->getTrack(argv[i+1]); - if (t == NULL) - { - Log::warn("main", "Can't find track named '%s'.", - argv[i+1]); - } - else if (t->isArena()) - { - //if it's arena, don't create ai karts - const std::vector l; - race_manager->setDefaultAIKartList(l); - // Add 1 for the player kart - race_manager->setNumKarts(1); - race_manager->setMinorMode(RaceManager::MINOR_MODE_3_STRIKES); - } - else if(t->isSoccer()) - { - //if it's soccer, don't create ai karts - const std::vector l; - race_manager->setDefaultAIKartList(l); - // Add 1 for the player kart - race_manager->setNumKarts(1); - race_manager->setMinorMode(RaceManager::MINOR_MODE_SOCCER); - } - } - else - { - Log::warn("main", "Track '%s' has not been unlocked yet.", - argv[i+1]); - Log::warn("main", "Use --list-tracks to list available " - "tracks."); - return 0; - } - i++; - } - else if( (!strcmp(argv[i], "--gp")) && i+1setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX); - const GrandPrixData *gp = - grand_prix_manager->getGrandPrix(argv[i+1]); + if(CommandLine::has("--login", &s) ) + { + login = s.c_str(); + try_login = true; + } // --login - if (gp == NULL) - { - Log::warn("main", "There is no GP named '%s'.", argv[i+1]); - return 0; - } + if(CommandLine::has("--password", &s)) + password = s.c_str(); - race_manager->setGrandPrix(*gp); - i++; - } - else if( (!strcmp(argv[i], "--numkarts") || !strcmp(argv[i], "-k")) && - i+1 stk_config->m_max_karts) - { - Log::warn("main", - "Number of karts reset to maximum number %d.", - stk_config->m_max_karts); - UserConfigParams::m_num_karts = stk_config->m_max_karts; - } - race_manager->setNumKarts( UserConfigParams::m_num_karts ); - Log::verbose("main", "%d karts will be used.", - (int)UserConfigParams::m_num_karts); - i++; - } - else if( !strcmp(argv[i], "--list-tracks") || !strcmp(argv[i], "-l") ) + // Race parameters + if(CommandLine::has("--kartsize-debug")) + { + for(unsigned int i=0; + igetNumberOfKarts(); i++) { + const KartProperties *km = + kart_properties_manager->getKartById(i); + Log::info("main", "%s:\t%swidth: %f length: %f height: %f " + "mesh-buffer count %d", + km->getIdent().c_str(), + (km->getIdent().size()<7) ? "\t" : "", + km->getMasterKartModel().getWidth(), + km->getMasterKartModel().getLength(), + km->getMasterKartModel().getHeight(), + km->getMasterKartModel().getModel() + ->getMeshBufferCount()); + } // for i + } // --kartsize-debug - Log::info("main", " Available tracks:" ); - unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] - .getUniqueID() ); - - for (size_t i = 0; i != track_manager->getNumberOfTracks(); i++) - { - const Track *track = track_manager->getTrack(i); - const char * locked = ""; - if ( unlock_manager->getCurrentSlot() - ->isLocked(track->getIdent()) ) - { - locked = " (locked)"; - } - Log::info("main", "%-18s: %ls %s", - track->getIdent().c_str(), - track->getName(), locked); - //} - } - - Log::info("main", "Use --track N to choose track."); - - exit(0); - } - else if( !strcmp(argv[i], "--list-karts") ) - { - Log::info("main", " Available karts:"); - for (unsigned int i = 0; - i < kart_properties_manager->getNumberOfKarts(); i++) - { - const KartProperties* KP = - kart_properties_manager->getKartById(i); - unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] - .getUniqueID() ); - const char * locked = ""; - if (unlock_manager->getCurrentSlot()->isLocked(KP->getIdent())) - locked = "(locked)"; - - Log::info("main", " %-10s: %ls %s", KP->getIdent().c_str(), - KP->getName(), locked); - } - - exit(0); - } - else if ( !strcmp(argv[i], "--no-start-screen") - || !strcmp(argv[i], "-N") ) - { - UserConfigParams::m_no_start_screen = true; - } - else if ( !strcmp(argv[i], "--race-now") - || !strcmp(argv[i], "-R") ) - { - UserConfigParams::m_no_start_screen = true; - UserConfigParams::m_race_now = true; - } - else if ( !strcmp(argv[i], "--laps") && i+1setNumLaps(laps); - i++; - } - } - else if( sscanf(argv[i], "--profile-laps=%d", &n)==1) - { - if (n < 0) - { - Log::error("main", "Invalid number of profile-laps: %i.\n", n ); - return 0; - } - else - { - Log::verbose("main", "Profiling %d laps.",n); - UserConfigParams::m_no_start_screen = true; - ProfileWorld::setProfileModeLaps(n); - race_manager->setNumLaps(n); - } - } - else if( sscanf(argv[i], "--profile-time=%d", &n)==1) - { - Log::verbose("main", "Profiling: %d seconds.", n); - UserConfigParams::m_no_start_screen = true; - ProfileWorld::setProfileModeTime((float)n); - race_manager->setNumLaps(999999); // profile end depends on time - } - else if( !strcmp(argv[i], "--no-graphics") ) - { - } - else if( !strcmp(argv[i], "--with-profile") ) - { - // Set default profile mode of 1 lap if we haven't already set one - if (!ProfileWorld::isProfileMode()) { - UserConfigParams::m_no_start_screen = true; - ProfileWorld::setProfileModeLaps(1); - race_manager->setNumLaps(1); - } - } - else if( !strcmp(argv[i], "--ghost")) - { - ReplayPlay::create(); - } - else if( sscanf(argv[i], "--history=%d", &n)==1) - { - history->doReplayHistory( (History::HistoryReplayMode)n); - // Force the no-start screen flag, since this initialises - // the player structures correctly. - UserConfigParams::m_no_start_screen = true; - - } - else if( !strcmp(argv[i], "--history") ) - { - history->doReplayHistory(History::HISTORY_POSITION); - // Force the no-start screen flag, since this initialises - // the player structures correctly. - UserConfigParams::m_no_start_screen = true; - - } - else if( !strcmp(argv[i], "--demo-mode") && i+1setCurrentSlot(UserConfigParams::m_all_players[0] + if(CommandLine::has("--kart", &s)) + { + unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] .getUniqueID() ); - float t; - StringUtils::fromString(argv[i+1], t); - DemoWorld::enableDemoMode(t); - // The default number of laps is taken from ProfileWorld and - // is 0. So set a more useful default for demo mode. - DemoWorld::setNumLaps(2); - i++; - } - else if( !strcmp(argv[i], "--demo-laps") && i+1getCurrentSlot()->isLocked(s)) { - // Note that we use a separate setting for demo mode to avoid the - // problem that someone plays a game, and in further demos then - // the wrong (i.e. last selected) number of laps would be used - DemoWorld::setNumLaps(atoi(argv[i+1])); - i++; + const KartProperties *prop = + kart_properties_manager->getKart(s); + if(prop) + { + UserConfigParams::m_default_kart = s; + + // if a player was added with -N, change its kart. + // Otherwise, nothing to do, kart choice will be picked + // up upon player creation. + if (StateManager::get()->activePlayerCount() > 0) + { + race_manager->setLocalKartInfo(0, s); + } + Log::verbose("main", "You chose to use kart '%s'.", + s.c_str() ) ; + } + else + { + Log::warn("main", "Kart '%s' not found, ignored.", + s.c_str()); + } } - else if( !strcmp(argv[i], "--demo-karts") && i+1 l=StringUtils::split(std::string(s),','); + race_manager->setDefaultAIKartList(l); + // Add 1 for the player kart + race_manager->setNumKarts(l.size()+1); + } // --ai + + if(CommandLine::has( "--mode", &s)) + { + int n = atoi(s.c_str()); + if(n<0 || n>RaceManager::DIFFICULTY_LAST) + Log::warn("main", "Invalid difficulty '%s' - ignored.\n", + s.c_str()); + else + race_manager->setDifficulty(RaceManager::Difficulty(n)); + } // --mode + + if(CommandLine::has("--type", &n)) + { + switch (n) { - DemoWorld::setTracks(StringUtils::split(std::string(argv[i+1]), - ',')); - i++; + case 0: race_manager->setMinorMode(RaceManager::MINOR_MODE_NORMAL_RACE); + break; + case 1: race_manager->setMinorMode(RaceManager::MINOR_MODE_TIME_TRIAL); + break; + case 2: race_manager->setMinorMode(RaceManager::MINOR_MODE_FOLLOW_LEADER); + break; + default: + Log::warn("main", "Invalid race type '%d' - ignored.", n); } -#ifdef ENABLE_WIIUSE - else if( !strcmp(argv[i], "--wii")) + } // --type + + if(CommandLine::has("--track", &s) || CommandLine::has("-t", &s)) + { + unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] + .getUniqueID() ); + if (!unlock_manager->getCurrentSlot()->isLocked(s)) { - WiimoteManager::enable(); + race_manager->setTrack(s); + Log::verbose("main", "You choose to start in track '%s'.", + s.c_str()); + + Track* t = track_manager->getTrack(s); + if (!t) + { + Log::warn("main", "Can't find track named '%s'.", s.c_str()); + } + else if (t->isArena()) + { + //if it's arena, don't create ai karts + const std::vector l; + race_manager->setDefaultAIKartList(l); + // Add 1 for the player kart + race_manager->setNumKarts(1); + race_manager->setMinorMode(RaceManager::MINOR_MODE_3_STRIKES); + } + else if(t->isSoccer()) + { + //if it's soccer, don't create ai karts + const std::vector l; + race_manager->setDefaultAIKartList(l); + // Add 1 for the player kart + race_manager->setNumKarts(1); + race_manager->setMinorMode(RaceManager::MINOR_MODE_SOCCER); + } } -#endif - // these commands are already processed in handleCmdLinePreliminary, - // but repeat this just so that we don't get error messages about - // unknown commands - else if( !strcmp(argv[i], "--stk-config")&& i+1setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX); + const GrandPrixData *gp = grand_prix_manager->getGrandPrix(s); + + if (!gp) + { + Log::warn("main", "There is no GP named '%s'.", s.c_str()); + return 0; + } + race_manager->setGrandPrix(*gp); + } // --gp + + if(CommandLine::has("--numkarts", &n) ||CommandLine::has("-k", &n)) + { + UserConfigParams::m_num_karts = n; + if(UserConfigParams::m_num_karts > stk_config->m_max_karts) + { + Log::warn("main", "Number of karts reset to maximum number %d.", + stk_config->m_max_karts); + UserConfigParams::m_num_karts = stk_config->m_max_karts; + } + race_manager->setNumKarts( UserConfigParams::m_num_karts ); + Log::verbose("main", "%d karts will be used.", + (int)UserConfigParams::m_num_karts); + } // --numkarts + + if(CommandLine::has( "--no-start-screen") || + CommandLine::has("-N") ) + UserConfigParams::m_no_start_screen = true; + if(CommandLine::has("--race-now") || CommandLine::has("-R")) + { + UserConfigParams::m_no_start_screen = true; + UserConfigParams::m_race_now = true; + } // --race-now + + if(CommandLine::has("--laps", &s)) + { + int laps = atoi(s.c_str()); + if (laps < 0) + { + Log::error("main", "Invalid number of laps: %s.\n", s.c_str()); + return 0; + } + else + { + Log::verbose("main", "You choose to have %d laps.", laps); + race_manager->setNumLaps(laps); + } + } // --laps + + if(CommandLine::has("--profile-laps=", &n)) + { + if (n < 0) + { + Log::error("main", "Invalid number of profile-laps: %i.", n ); + return 0; + } + else + { + Log::verbose("main", "Profiling %d laps.",n); + UserConfigParams::m_no_start_screen = true; + ProfileWorld::setProfileModeLaps(n); + race_manager->setNumLaps(n); + } + } // --profile-laps + + if(CommandLine::has("--profile-time", &n)) + { + Log::verbose("main", "Profiling: %d seconds.", n); + UserConfigParams::m_no_start_screen = true; + ProfileWorld::setProfileModeTime((float)n); + race_manager->setNumLaps(999999); // profile end depends on time + } // --profile-time + + if(CommandLine::has("--with-profile") ) + { + // Set default profile mode of 1 lap if we haven't already set one + if (!ProfileWorld::isProfileMode()) { + UserConfigParams::m_no_start_screen = true; + ProfileWorld::setProfileModeLaps(1); + race_manager->setNumLaps(1); + } + } // --with-profile + + if(CommandLine::has("--ghost")) + ReplayPlay::create(); + + if(CommandLine::has("--history", &n)) + { + history->doReplayHistory( (History::HistoryReplayMode)n); + // Force the no-start screen flag, since this initialises + // the player structures correctly. + UserConfigParams::m_no_start_screen = true; + } // --history=%d + + if(CommandLine::has("--history")) // handy default for --history=1 + { + history->doReplayHistory(History::HISTORY_POSITION); + // Force the no-start screen flag, since this initialises + // the player structures correctly. + UserConfigParams::m_no_start_screen = true; + } // --history + + // Demo mode + if(CommandLine::has("--demo-mode", &s)) + { + unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] + .getUniqueID() ); + float t; + StringUtils::fromString(s, t); + DemoWorld::enableDemoMode(t); + // The default number of laps is taken from ProfileWorld and + // is 0. So set a more useful default for demo mode. + DemoWorld::setNumLaps(2); + } // --demo-mode + + if(CommandLine::has("--demo-laps", &n)) + { + // Note that we use a separate setting for demo mode to avoid the + // problem that someone plays a game, and in further demos then + // the wrong (i.e. last selected) number of laps would be used + DemoWorld::setNumLaps(n); + } // --demo-laps + + if(CommandLine::has("--demo-karts", &n)) + { + // Note that we use a separate setting for demo mode to avoid the + // problem that someone plays a game, and in further demos then + // the wrong (i.e. last selected) number of karts would be used + DemoWorld::setNumKarts(n); + } // --demo-karts + + if(CommandLine::has("--demo-tracks", &s)) + DemoWorld::setTracks(StringUtils::split(s,',')); + +#ifdef ENABLE_WIIUSE + if(CommandLine::has("--wii")) + WiimoteManager::enable(); +#endif + +#ifdef __APPLE__ + // on OS X, sometimes the Finder will pass a -psn* something parameter + // to the application --> ignore it + CommandLine::has("-psn"); +#endif + + CommandLine::reportInvalidParameters(); + if(UserConfigParams::m_no_start_screen) unlock_manager->setCurrentSlot(UserConfigParams::m_all_players[0] .getUniqueID() ); @@ -1169,10 +967,10 @@ int handleCmdLine(int argc, char **argv) //============================================================================= /** Initialises the minimum number of managers to get access to user_config. */ -void initUserConfig(char *argv[]) +void initUserConfig() { irr_driver = new IrrDriver(); - file_manager = new FileManager(argv); + file_manager = new FileManager(); user_config = new UserConfig(); // needs file_manager const bool config_ok = user_config->loadConfig(); if (UserConfigParams::m_language.toString() != "system") @@ -1349,32 +1147,33 @@ bool ShowDumpResults(const wchar_t* dump_path, #pragma comment(linker, "/SUBSYSTEM:console") #endif +// ---------------------------------------------------------------------------- int main(int argc, char *argv[] ) { #ifdef BREAKPAD google_breakpad::ExceptionHandler eh(L"C:\\Temp", NULL, ShowDumpResults, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL); #endif + CommandLine::init(argc, argv); + CrashReporting::installHandlers(); srand(( unsigned ) time( 0 )); - try { - // Check for "--root COLON:SEPARATED:LIST" parameter - for(int i=0; i #include "audio/music_manager.hpp" +#include "graphics/camera.hpp" #include "graphics/irr_driver.hpp" #include "io/file_manager.hpp" #include "karts/abstract_kart.hpp" diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index cb1b96cbb..7a085f2f9 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -21,6 +21,7 @@ #include "states_screens/race_gui_base.hpp" #include "audio/music_manager.hpp" +#include "graphics/camera.hpp" #include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material.hpp" diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index be36cc64a..5f2bf1e75 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -20,6 +20,7 @@ #include +#include "io/xml_node.hpp" #include "karts/abstract_kart.hpp" #include "modes/linear_world.hpp" #include "modes/world.hpp" diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index ba886c53f..8b32bff50 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1635,6 +1635,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) if (!irr_driver->isGLSL()) { scene::ILightSceneNode *sun = (scene::ILightSceneNode *) m_sun; + sun->setLightType(video::ELT_DIRECTIONAL); // The angle of the light is rather important - let the sun diff --git a/src/utils/command_line.cpp b/src/utils/command_line.cpp new file mode 100644 index 000000000..f4dee8dfc --- /dev/null +++ b/src/utils/command_line.cpp @@ -0,0 +1,67 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2008-2013 Joerg Henrichs +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "utils/command_line.hpp" + +#include "config/user_config.hpp" +#include "utils/log.hpp" + +std::vector CommandLine::m_argv; +std::string CommandLine::m_exec_name=""; + +/** The constructor takes the standard C arguments argc and argv and + * stores the information internally. + * \param argc Number of arguments (in argv). + * \param argv Array of char* with all command line arguments. + */ +void CommandLine::init(unsigned int argc, char *argv[]) +{ + m_exec_name = argv[0]; + for(unsigned int i=1; i::iterator i; + for(i=m_argv.begin(); i!=m_argv.end(); i++) + { + if(*i==option) + { + m_argv.erase(i); + return true; + } + } // for i in m_argv + + return false; +} // has + +// ---------------------------------------------------------------------------- +/** Reports any parameters that have not been handled yet to be an error. + */ +void CommandLine::reportInvalidParameters() +{ + for(unsigned int i=0; i +#include + +/** A small class to manage the 'argv' parameters of a program. That includes + * the name of the executable (argv[0]) and all command line parameters. + * Example usage + * \code + * CommandLine::init(argc, argv); + * if( CommandLine::has("--help") || + * CommandLine::has("-h") ) ... + * int n; + * if(CommandLine::has("--log", &n)) + * Log::setLogLevel(n); + * ... + * CommandLine::reportInvalidParameters(); + * \endcode + * The two 'has' functions will remove a parameter from the list of all + * parameters, so any parameters remaining at the end are invalid + * parameters, which will be listed by reportInvalidParameters. + */ +class CommandLine +{ +private: + /** The array with all command line options. */ + static std::vector m_argv; + + /** Name of the executable. */ + static std::string m_exec_name; + + // ------------------------------------------------------------------------ + /** Searches for an option 'option=XX'. If found, *t will contain 'XX'. + * If the value was found, the entry is removed from the list of all + * command line arguments. + * \param option The option (must include '-' or '--' as required). + * \param t Address of a variable to store the value. + * \param format The '%' format to sscanf the value in t with. + * \return true if the value was found, false otherwise. + */ + static bool has(const std::string &option, void *t, const char* const format) + { + if(m_argv.size()==0) return false; + + std::string equal=option+"="+format; + std::vector::iterator i; + for(i=m_argv.begin(); ic_str(), equal.c_str(), t)==1) + { + m_argv.erase(i); + return true; + } + } + return false; + } // has + +public: + static void init(unsigned int argc, char *argv[]); + static void reportInvalidParameters(); + static bool has(const std::string &option); + // ------------------------------------------------------------------------ + /** Searches for an option 'option=XX'. If found, *t will contain 'XX'. + * If the value was found, the entry is removed from the list of all + * command line arguments. This is the interface for any integer + * values (i.e. using %d as format while scanning). + * \param option The option (must include '-' or '--' as required). + * \param t Address of a variable to store the value. + * \param format The '%' format to sscanf the value in t with. + * \return true if the value was found, false otherwise. + */ + static bool has(const std::string &option, int *t) + { + return has(option, t, "%d"); + } + // ------------------------------------------------------------------------ + /** Searches for an option 'option=XX'. If found, *t will contain 'XX'. + * If the value was found, the entry is removed from the list of all + * command line arguments. This is the interface for a std::string + * \param option The option (must include '-' or '--' as required). + * \param t Address of a variable to store the value. + * \param format The '%' format to sscanf the value in t with. + * \return true if the value was found, false otherwise. + */ + static bool has(const std::string &option, std::string *t) + { + char s[1024]; + if(has(option, s, "%1023s")) + { + *t = s; + return true; + } + return false; + } // has + // ------------------------------------------------------------------------ + /** Returns the name of the executable. */ + static const std::string& getExecName() { return m_exec_name; } +}; // CommandLine +#endif diff --git a/src/utils/log.cpp b/src/utils/log.cpp index 61017d284..59d9d8ad4 100644 --- a/src/utils/log.cpp +++ b/src/utils/log.cpp @@ -183,15 +183,15 @@ void Log::printMessage(int level, const char *component, const char *format, va_end(out); } -#if defined(_MSC_FULL_VER) && defined(_DEBUG) - static char szBuff[2048]; - vsnprintf(szBuff, sizeof(szBuff), format, copy2); - - OutputDebugString("["); - OutputDebugString(names[level]); - OutputDebugString("] "); - OutputDebugString(component); - OutputDebugString(": "); +#if defined(_MSC_FULL_VER) && defined(_DEBUG) + static char szBuff[2048]; + vsnprintf(szBuff, sizeof(szBuff), format, copy2); + + OutputDebugString("["); + OutputDebugString(names[level]); + OutputDebugString("] "); + OutputDebugString(component); + OutputDebugString(": "); OutputDebugString(szBuff); OutputDebugString("\r\n"); #endif From 3e8741c442e8a5fc0a09ef0f2cf897eab993bcaa Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 6 Jan 2014 12:28:24 +0000 Subject: [PATCH 174/412] Fixed typo. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14940 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 686b6f127..0925a7bf6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -497,7 +497,7 @@ int handleCmdLinePreliminary() if( CommandLine::has( "--stk-config", &s)) { stk_config->load(file_manager->getAsset(s)); - Log::info("main", "STK config will be read from %s.",s); + Log::info("main", "STK config will be read from %s.",s.c_str()); } if( CommandLine::has( "--trackdir", &s)) TrackManager::addTrackSearchDir(s); From 841aa05cc043d738a19bd93d3b4f2eed36364800 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 6 Jan 2014 18:05:21 +0000 Subject: [PATCH 175/412] GPUParticles: Use gl_vertexID to improve particle emission rate handling. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14941 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 11 +++++++---- src/graphics/gpuparticles.cpp | 18 +++++++++--------- src/graphics/gpuparticles.h | 2 +- src/graphics/particle_emitter.cpp | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index a304914f7..b5bea966c 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -2,6 +2,7 @@ uniform int dt; uniform mat4 sourcematrix; uniform mat4 tinvsourcematrix; +uniform int level; in vec3 particle_position_initial; in float lifetime_initial; @@ -24,9 +25,11 @@ void main(void) vec4 adjusted_initial_velocity = tinvsourcematrix * vec4(particle_velocity_initial, 1.0); adjusted_initial_velocity /= adjusted_initial_velocity.w; float adjusted_lifetime = lifetime + (float(dt)/lifetime_initial); - new_particle_position = (adjusted_lifetime < 1.) ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; - new_lifetime = (adjusted_lifetime < 1.) ? adjusted_lifetime : 0.; - new_particle_velocity = (adjusted_lifetime < 1.) ? particle_velocity : adjusted_initial_velocity.xyz; - new_size = (adjusted_lifetime < 1.) ? size : size_initial; + bool reset = (adjusted_lifetime > 1.) && (gl_VertexID <= level); + reset = reset || (lifetime < 0.); + new_particle_position = !reset ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; + new_lifetime = !reset ? adjusted_lifetime : 0.; + new_particle_velocity = !reset ? particle_velocity : adjusted_initial_velocity.xyz; + new_size = !reset ? size : size_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 9f9519e39..34285e935 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -172,7 +172,7 @@ void ParticleSystemProxy::generateParticlesFromBoxEmitter(scene::IParticleBoxEmi particles[i].PositionX = emitter->getBox().MinEdge.X + os::Randomizer::frand() * extent.X; particles[i].PositionY = emitter->getBox().MinEdge.Y + os::Randomizer::frand() * extent.Y; particles[i].PositionZ = emitter->getBox().MinEdge.Z + os::Randomizer::frand() * extent.Z; - // Initial lifetime is > 1 + // Initial lifetime is random particles[i].Lifetime = os::Randomizer::frand(); memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); @@ -207,8 +207,8 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph particles[i].PositionX = pos.X; particles[i].PositionY = pos.Y; particles[i].PositionZ = pos.Z; - // Initial lifetime is > 1 - particles[i].Lifetime = 2.; + // Initial lifetime is < 0 + particles[i].Lifetime = -1.; memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size, @@ -239,6 +239,7 @@ GLuint ParticleSystemProxy::attrib_initial_size; GLuint ParticleSystemProxy::uniform_sourcematrix; GLuint ParticleSystemProxy::uniform_tinvsourcematrix; GLuint ParticleSystemProxy::uniform_dt; +GLuint ParticleSystemProxy::uniform_level; GLuint ParticleSystemProxy::attrib_pos; @@ -311,6 +312,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); uniform_tinvsourcematrix = glGetUniformLocation(SimulationProgram, "tinvsourcematrix"); + uniform_level = glGetUniformLocation(SimulationProgram, "level"); attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); @@ -347,7 +349,7 @@ void ParticleSystemProxy::simulate() u32 timediff = time - LastEmitTime; LastEmitTime = time; - + int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); core::matrix4 tinvmatrix; matrix.getInverse(tinvmatrix); @@ -375,6 +377,7 @@ void ParticleSystemProxy::simulate() glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); glUniform1i(uniform_dt, timediff); + glUniform1i(uniform_level, active_count); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); glUniformMatrix4fv(uniform_tinvsourcematrix, 1, GL_FALSE, tinvmatrix.pointer()); glBeginTransformFeedback(GL_POINTS); @@ -390,13 +393,11 @@ void ParticleSystemProxy::simulate() glDisableVertexAttribArray(attrib_initial_size); glDisable(GL_RASTERIZER_DISCARD); std::swap(tfb_buffers[0], tfb_buffers[1]); + } void ParticleSystemProxy::draw() { - unsigned active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; - // No max in windows ?? - active_count = (active_count > count) ? count : active_count; glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); @@ -437,8 +438,7 @@ void ParticleSystemProxy::draw() glVertexAttribDivisor(attrib_pos, 1); glVertexAttribDivisor(attrib_sz, 1); - if (active_count) - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, active_count); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); glVertexAttribDivisor(attrib_lf, 0); glVertexAttribDivisor(attrib_pos, 0); glVertexAttribDivisor(attrib_sz, 0); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 5cd8fdd3d..9d68944a4 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -32,7 +32,7 @@ protected: static GLuint SimulationProgram; static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt; + static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt, uniform_level; static GLuint RenderProgram; static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index c9912a635..f59e9c585 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -331,14 +331,14 @@ void ParticleEmitter::setCreationRateAbsolute(float f) m_node->setEmitter(m_emitter); } #endif - if (f <= 0.0f) +/* if (f <= 0.0f) { m_node->setVisible(false); } else { m_node->setVisible(true); - } + }*/ } // setCreationRateAbsolute //----------------------------------------------------------------------------- From 75cfde3d69913da6c3c3380842e3e3712bea2d41 Mon Sep 17 00:00:00 2001 From: deveee Date: Mon, 6 Jan 2014 20:05:23 +0000 Subject: [PATCH 176/412] Fixed compilation in debug mode. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14942 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/input/input_manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index 87692b266..ba5c6062f 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -18,6 +18,7 @@ #include "input/input_manager.hpp" #include "main_loop.hpp" +#include "graphics/camera.hpp" #include "guiengine/engine.hpp" #include "guiengine/event_handler.hpp" #include "guiengine/modaldialog.hpp" From 6808a9df1adb4c3545d1d8e2e40a4fd9146a170d Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 6 Jan 2014 21:10:50 +0000 Subject: [PATCH 177/412] Fixed warning and incorrect color values (for non-shader). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14943 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- 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 af09d8e6b..25aa6c85d 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -2162,7 +2162,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy, else { return m_scene_manager->addLightSceneNode(m_scene_manager->getRootSceneNode(), - pos, video::SColor(1.0f, r, g, b)); + pos, video::SColorf(1.0f, r, g, b)); } } From 7a95d46448c2619bb0a8f20edefd5227d7209e4f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 6 Jan 2014 22:35:54 +0000 Subject: [PATCH 178/412] GPUParticles: Use smoothstep for fade out and remove direction modulation by size. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14944 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.frag | 2 +- src/graphics/gpuparticles.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index 3587367b0..08157c24e 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -21,5 +21,5 @@ void main(void) float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); color = texture2D(texture, tc); - color.a *= alpha * (1. - lf); + color.a *= alpha * smoothstep(1., 0.8, lf); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 34285e935..1de3853ec 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -116,9 +116,9 @@ void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &life particledir.rotateYZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); particledir.rotateXZBy(os::Randomizer::frand() * emitter->getMaxAngleDegrees()); - dirX = particledir.X / size; - dirY = particledir.Y / size; - dirZ = particledir.Z / size; + dirX = particledir.X; + dirY = particledir.Y; + dirZ = particledir.Z; } struct ParticleData From 88bb3a8da8237767205250af84bec7b7be54fbf9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 6 Jan 2014 22:58:04 +0000 Subject: [PATCH 179/412] GPUParticles: Add support for increase factor git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14945 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 3 ++- src/graphics/gpuparticles.cpp | 8 +++++++- src/graphics/gpuparticles.h | 4 +++- src/graphics/particle_emitter.cpp | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index b5bea966c..48a192906 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -3,6 +3,7 @@ uniform int dt; uniform mat4 sourcematrix; uniform mat4 tinvsourcematrix; uniform int level; +uniform float size_increase_factor; in vec3 particle_position_initial; in float lifetime_initial; @@ -30,6 +31,6 @@ void main(void) new_particle_position = !reset ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; new_lifetime = !reset ? adjusted_lifetime : 0.; new_particle_velocity = !reset ? particle_velocity : adjusted_initial_velocity.xyz; - new_size = !reset ? size : size_initial; + new_size = !reset ? mix(size_initial, size_initial * size_increase_factor, adjusted_lifetime) : size_initial; gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 1de3853ec..2cbafa660 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -75,6 +75,7 @@ ParticleSystemProxy::ParticleSystemProxy(bool createDefaultEmitter, fakemat.BackfaceCulling = false; glGenBuffers(1, &initial_values_buffer); glGenBuffers(2, tfb_buffers); + size_increase_factor = 0.; if (quad_vertex_buffer) return; static const GLfloat quad_vertex[] = { @@ -95,7 +96,9 @@ ParticleSystemProxy::~ParticleSystemProxy() glDeleteBuffers(1, &initial_values_buffer); } -void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } +void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } + +void ParticleSystemProxy::setIncreaseFactor(float val) { size_increase_factor = val; } static void generateLifetimeSizeDirection(scene::IParticleEmitter *emitter, float &lifetime, float &size, float &dirX, float &dirY, float &dirZ) @@ -240,6 +243,7 @@ GLuint ParticleSystemProxy::uniform_sourcematrix; GLuint ParticleSystemProxy::uniform_tinvsourcematrix; GLuint ParticleSystemProxy::uniform_dt; GLuint ParticleSystemProxy::uniform_level; +GLuint ParticleSystemProxy::uniform_size_increase_factor; GLuint ParticleSystemProxy::attrib_pos; @@ -313,6 +317,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); uniform_tinvsourcematrix = glGetUniformLocation(SimulationProgram, "tinvsourcematrix"); uniform_level = glGetUniformLocation(SimulationProgram, "level"); + uniform_size_increase_factor = glGetUniformLocation(SimulationProgram, "size_increase_factor"); attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); @@ -380,6 +385,7 @@ void ParticleSystemProxy::simulate() glUniform1i(uniform_level, active_count); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); glUniformMatrix4fv(uniform_tinvsourcematrix, 1, GL_FALSE, tinvmatrix.pointer()); + glUniform1f(uniform_size_increase_factor, size_increase_factor); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 9d68944a4..a6579919f 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -29,10 +29,11 @@ protected: video::SMaterial fakemat; GLuint tfb_buffers[2], initial_values_buffer; bool m_alpha_additive; + float size_increase_factor; static GLuint SimulationProgram; static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt, uniform_level; + static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; static GLuint RenderProgram; static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; @@ -65,6 +66,7 @@ public: virtual void setEmitter(scene::IParticleEmitter* emitter); virtual void render(); void setAlphaAdditive(bool); + void setIncreaseFactor(float); }; class PointEmitter : public GPUParticle diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index f59e9c585..bd9a009ab 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -556,6 +556,8 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) m_node->createScaleParticleAffector(factor); m_node->addAffector(scale_affector); scale_affector->drop(); + if (irr_driver->isGLSL()) + static_cast(m_node)->setIncreaseFactor(type->getScaleAffectorFactorX()); } const float windspeed = type->getWindSpeed(); From 6e3466c838b7ba0490419721e94301ca122a57fb Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 6 Jan 2014 23:29:12 +0000 Subject: [PATCH 180/412] load material.xml from libraries git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14946 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/tracks/track.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 8b32bff50..cfe1a212a 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1761,6 +1761,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, LodNodeLoa file_manager->pushTextureSearchPath(lib_path + "/"); file_manager->pushModelSearchPath (lib_path); + material_manager->pushTempMaterial(lib_path + "/materials.xml"); library_nodes[name] = libroot; // Load LOD groups From 51023ceb81b78ab7f2bd396742a287556589f6bb Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 7 Jan 2014 00:04:43 +0000 Subject: [PATCH 181/412] GPUParticles: Fix adjusted_initial_velocity computation. Thank to Auria and hiker for their help. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14947 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 4 +--- src/graphics/gpuparticles.cpp | 6 ------ src/graphics/gpuparticles.h | 2 +- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 48a192906..9a448228e 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -1,7 +1,6 @@ #version 130 uniform int dt; uniform mat4 sourcematrix; -uniform mat4 tinvsourcematrix; uniform int level; uniform float size_increase_factor; @@ -23,8 +22,7 @@ out float new_size; void main(void) { vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); - vec4 adjusted_initial_velocity = tinvsourcematrix * vec4(particle_velocity_initial, 1.0); - adjusted_initial_velocity /= adjusted_initial_velocity.w; + vec4 adjusted_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - initialposition; float adjusted_lifetime = lifetime + (float(dt)/lifetime_initial); bool reset = (adjusted_lifetime > 1.) && (gl_VertexID <= level); reset = reset || (lifetime < 0.); diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2cbafa660..1625d7cbb 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -240,7 +240,6 @@ GLuint ParticleSystemProxy::attrib_initial_lifetime; GLuint ParticleSystemProxy::attrib_size; GLuint ParticleSystemProxy::attrib_initial_size; GLuint ParticleSystemProxy::uniform_sourcematrix; -GLuint ParticleSystemProxy::uniform_tinvsourcematrix; GLuint ParticleSystemProxy::uniform_dt; GLuint ParticleSystemProxy::uniform_level; GLuint ParticleSystemProxy::uniform_size_increase_factor; @@ -315,7 +314,6 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); - uniform_tinvsourcematrix = glGetUniformLocation(SimulationProgram, "tinvsourcematrix"); uniform_level = glGetUniformLocation(SimulationProgram, "level"); uniform_size_increase_factor = glGetUniformLocation(SimulationProgram, "size_increase_factor"); @@ -356,9 +354,6 @@ void ParticleSystemProxy::simulate() LastEmitTime = time; int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); - core::matrix4 tinvmatrix; - matrix.getInverse(tinvmatrix); - tinvmatrix = tinvmatrix.getTransposed(); glUseProgram(SimulationProgram); glEnable(GL_RASTERIZER_DISCARD); glEnableVertexAttribArray(attrib_position); @@ -384,7 +379,6 @@ void ParticleSystemProxy::simulate() glUniform1i(uniform_dt, timediff); glUniform1i(uniform_level, active_count); glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); - glUniformMatrix4fv(uniform_tinvsourcematrix, 1, GL_FALSE, tinvmatrix.pointer()); glUniform1f(uniform_size_increase_factor, size_increase_factor); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index a6579919f..4f0dac86d 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -33,7 +33,7 @@ protected: static GLuint SimulationProgram; static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - static GLuint uniform_sourcematrix, uniform_tinvsourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; + static GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; static GLuint RenderProgram; static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; From b1c8898b54985b868ef4aa928c3a5ca8e20c8345 Mon Sep 17 00:00:00 2001 From: auria Date: Tue, 7 Jan 2014 00:05:40 +0000 Subject: [PATCH 182/412] Bump track XML version number to 6 git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14948 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/stk_config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/stk_config.xml b/data/stk_config.xml index 18d1cb51c..1208fbe0c 100644 --- a/data/stk_config.xml +++ b/data/stk_config.xml @@ -7,7 +7,7 @@ - + - + - + getSkyParticles(), - core::vector3df(0.0f, 20.0f, 100.0f), + core::vector3df(0.0f, 30.0f, 100.0f), getNode()); // FIXME: in multiplayer mode, this will result in several instances From 99fde5faa4c8161acf6dfb96077c34706a2f1962 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 01:49:06 +0000 Subject: [PATCH 207/412] GPUParticles: Kill snow flake when it hit the ground according to the heightmap. (Actually we move it outside of the player view) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14977 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particle.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index 29f2d5545..b7c7a366d 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -34,7 +34,7 @@ void main(void) if (hasHeightMap) { float h = position.y - texelFetch(heightmap, i * 256 + j).r; - newposition.y = (h > 0.)? position.y : position.y - h; + newposition.y = (h > 0.)? position.y : 1000.; } if (flips) From 54e6396df6654651d8411598ab958f66315f66b5 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 9 Jan 2014 04:57:58 +0000 Subject: [PATCH 208/412] Renamed HTTPManager to RequestManager, and split request into three files request, http_request and xml_request. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14978 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 8 +- src/achievements/achievements_slot.hpp | 3 +- src/main.cpp | 12 +- src/main_loop.cpp | 6 +- src/network/protocols/get_peer_address.cpp | 4 +- src/network/protocols/hide_public_address.cpp | 4 +- src/network/protocols/quick_join_protocol.cpp | 4 +- src/network/protocols/request_connection.cpp | 4 +- .../protocols/server_lobby_room_protocol.cpp | 2 +- src/network/protocols/show_public_address.cpp | 4 +- src/network/protocols/start_server.cpp | 4 +- src/network/protocols/stop_server.cpp | 4 +- src/network/stk_host.hpp | 2 +- src/online/current_user.cpp | 40 +-- src/online/current_user.hpp | 3 +- src/online/http_request.cpp | 232 ++++++++++++++++ src/online/http_request.hpp | 145 ++++++++++ src/online/profile.cpp | 6 +- src/online/profile.hpp | 4 +- src/online/request.cpp | 262 +----------------- src/online/request.hpp | 181 +----------- .../{http_manager.cpp => request_manager.cpp} | 40 +-- .../{http_manager.hpp => request_manager.hpp} | 19 +- src/online/servers_manager.cpp | 2 +- src/online/servers_manager.hpp | 3 +- src/online/xml_request.cpp | 82 ++++++ src/online/xml_request.hpp | 97 +++++++ 27 files changed, 666 insertions(+), 511 deletions(-) create mode 100644 src/online/http_request.cpp create mode 100644 src/online/http_request.hpp rename src/online/{http_manager.cpp => request_manager.cpp} (92%) rename src/online/{http_manager.hpp => request_manager.hpp} (91%) create mode 100644 src/online/xml_request.cpp create mode 100644 src/online/xml_request.hpp diff --git a/sources.cmake b/sources.cmake index ec7051ef2..2e9db0485 100644 --- a/sources.cmake +++ b/sources.cmake @@ -190,13 +190,15 @@ src/network/stk_host.cpp src/network/stk_peer.cpp src/network/types.cpp src/online/current_user.cpp -src/online/http_manager.cpp +src/online/http_request.cpp src/online/messages.cpp src/online/profile.cpp src/online/profile_manager.cpp src/online/request.cpp +src/online/request_manager.cpp src/online/server.cpp src/online/servers_manager.cpp +src/online/xml_request.cpp src/physics/btKart.cpp src/physics/btKartRaycast.cpp src/physics/btUprightConstraint.cpp @@ -517,13 +519,15 @@ src/network/stk_host.hpp src/network/stk_peer.hpp src/network/types.hpp src/online/current_user.hpp -src/online/http_manager.hpp +src/online/http_request.hpp src/online/messages.hpp src/online/profile.hpp src/online/profile_manager.hpp src/online/request.hpp +src/online/request_manager.hpp src/online/server.hpp src/online/servers_manager.hpp +src/online/xml_request.hpp src/physics/btKart.hpp src/physics/btKartRaycast.hpp src/physics/btUprightConstraint.hpp diff --git a/src/achievements/achievements_slot.hpp b/src/achievements/achievements_slot.hpp index 97ed65d72..cfb73ab07 100644 --- a/src/achievements/achievements_slot.hpp +++ b/src/achievements/achievements_slot.hpp @@ -21,7 +21,8 @@ #include "utils/types.hpp" #include "achievements/achievement.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" +#include "online/xml_request.hpp" #include #include diff --git a/src/main.cpp b/src/main.cpp index e67c6cfe8..e98dc57b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -176,13 +176,13 @@ #include "network/protocol_manager.hpp" #include "network/protocols/server_lobby_room_protocol.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "network/client_network_manager.hpp" #include "network/server_network_manager.hpp" #include "network/protocol_manager.hpp" #include "network/protocols/server_lobby_room_protocol.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/profile_manager.hpp" #include "online/servers_manager.hpp" #include "race/grand_prix_manager.hpp" @@ -1027,7 +1027,7 @@ void initRest() // to network_http (since the thread might use network_http, otherwise // a race condition can be introduced resulting in a crash). INetworkHttp::get()->startNetworkThread(); - Online::HTTPManager::get()->startNetworkThread(); + Online::RequestManager::get()->startNetworkThread(); AchievementsManager::get()->init(); music_manager = new MusicManager(); sfx_manager = new SFXManager(); @@ -1083,12 +1083,12 @@ static void cleanSuperTuxKart() if(INetworkHttp::get()) INetworkHttp::get()->stopNetworkThread(); - if(Online::HTTPManager::isRunning()) - Online::HTTPManager::get()->stopNetworkThread(); + if(Online::RequestManager::isRunning()) + Online::RequestManager::get()->stopNetworkThread(); //delete in reverse order of what they were created in. //see InitTuxkart() - Online::HTTPManager::deallocate(); + Online::RequestManager::deallocate(); Online::ServersManager::deallocate(); Online::ProfileManager::deallocate(); AchievementsManager::deallocate(); diff --git a/src/main_loop.cpp b/src/main_loop.cpp index e7299a915..cdb571b65 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -32,7 +32,7 @@ #include "modes/world.hpp" #include "network/protocol_manager.hpp" #include "network/network_world.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "race/race_manager.hpp" #include "states_screens/state_manager.hpp" #include "utils/profiler.hpp" @@ -156,7 +156,7 @@ void MainLoop::run() PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); - Online::HTTPManager::get()->update(dt); + Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_SYNC_FRAME(); @@ -168,7 +168,7 @@ void MainLoop::run() PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); - Online::HTTPManager::get()->update(dt); + Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); } diff --git a/src/network/protocols/get_peer_address.cpp b/src/network/protocols/get_peer_address.cpp index 7585898a6..1cf772dcb 100644 --- a/src/network/protocols/get_peer_address.cpp +++ b/src/network/protocols/get_peer_address.cpp @@ -20,7 +20,7 @@ #include "network/protocol_manager.hpp" #include "network/network_manager.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/current_user.hpp" #include "config/user_config.hpp" #include "utils/log.hpp" @@ -51,7 +51,7 @@ void GetPeerAddress::asynchronousUpdate() m_request->addParameter("peer_id",m_peer_id); m_request->addParameter("action","get"); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/protocols/hide_public_address.cpp b/src/network/protocols/hide_public_address.cpp index 6c3758957..1d1578712 100644 --- a/src/network/protocols/hide_public_address.cpp +++ b/src/network/protocols/hide_public_address.cpp @@ -19,7 +19,7 @@ #include "network/protocols/hide_public_address.hpp" #include "network/protocol_manager.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/current_user.hpp" #include "config/user_config.hpp" #include "utils/log.hpp" @@ -47,7 +47,7 @@ void HidePublicAddress::asynchronousUpdate() m_request->addParameter("token",Online::CurrentUser::get()->getToken()); m_request->addParameter("action","unset"); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/protocols/quick_join_protocol.cpp b/src/network/protocols/quick_join_protocol.cpp index 57843e430..6ef50d0f7 100644 --- a/src/network/protocols/quick_join_protocol.cpp +++ b/src/network/protocols/quick_join_protocol.cpp @@ -20,7 +20,7 @@ #include "network/network_manager.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "config/user_config.hpp" #include "utils/log.hpp" @@ -49,7 +49,7 @@ void QuickJoinProtocol::asynchronousUpdate() m_request->addParameter("token",Online::CurrentUser::get()->getToken()); m_request->addParameter("action","quick-join"); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/protocols/request_connection.cpp b/src/network/protocols/request_connection.cpp index cd8824e3d..e412f711a 100644 --- a/src/network/protocols/request_connection.cpp +++ b/src/network/protocols/request_connection.cpp @@ -19,7 +19,7 @@ #include "network/protocols/request_connection.hpp" #include "network/protocol_manager.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/current_user.hpp" #include "config/user_config.hpp" @@ -50,7 +50,7 @@ void RequestConnection::asynchronousUpdate() m_request->addParameter("server_id",m_server_id); m_request->addParameter("action","request-connection"); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; break; } diff --git a/src/network/protocols/server_lobby_room_protocol.cpp b/src/network/protocols/server_lobby_room_protocol.cpp index 676c42aa8..0c5d28088 100644 --- a/src/network/protocols/server_lobby_room_protocol.cpp +++ b/src/network/protocols/server_lobby_room_protocol.cpp @@ -27,7 +27,7 @@ #include "network/protocols/start_game_protocol.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "config/user_config.hpp" #include "modes/world.hpp" #include "utils/log.hpp" diff --git a/src/network/protocols/show_public_address.cpp b/src/network/protocols/show_public_address.cpp index 0e0e2e604..a22b8fff9 100644 --- a/src/network/protocols/show_public_address.cpp +++ b/src/network/protocols/show_public_address.cpp @@ -19,7 +19,7 @@ #include "network/protocols/show_public_address.hpp" #include "network/network_manager.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/current_user.hpp" #include "config/user_config.hpp" #include "utils/log.hpp" @@ -52,7 +52,7 @@ void ShowPublicAddress::asynchronousUpdate() m_request->addParameter("action","set"); Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/protocols/start_server.cpp b/src/network/protocols/start_server.cpp index 978a3b794..bc689ea6c 100644 --- a/src/network/protocols/start_server.cpp +++ b/src/network/protocols/start_server.cpp @@ -20,7 +20,7 @@ #include "network/network_manager.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "config/user_config.hpp" StartServer::StartServer() : Protocol(NULL, PROTOCOL_SILENT) @@ -52,7 +52,7 @@ void StartServer::asynchronousUpdate() m_request->addParameter("action","start-server"); Log::info("ShowPublicAddress", "Showing addr %u and port %d", addr.ip, addr.port); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/protocols/stop_server.cpp b/src/network/protocols/stop_server.cpp index c0d7ded4a..0dc5dbe0b 100644 --- a/src/network/protocols/stop_server.cpp +++ b/src/network/protocols/stop_server.cpp @@ -20,7 +20,7 @@ #include "network/network_manager.hpp" #include "online/current_user.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "config/user_config.hpp" StopServer::StopServer() : Protocol(NULL, PROTOCOL_SILENT) @@ -55,7 +55,7 @@ void StopServer::asynchronousUpdate() m_request->addParameter("action","stop-server"); Log::info("StopServer", "address %u, port %d", addr.ip, addr.port); - Online::HTTPManager::get()->addRequest(m_request); + Online::RequestManager::get()->addRequest(m_request); m_state = REQUEST_PENDING; } else if (m_state == REQUEST_PENDING && m_request->isDone()) diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp index a9951000c..97cc96dad 100644 --- a/src/network/stk_host.hpp +++ b/src/network/stk_host.hpp @@ -28,7 +28,7 @@ // enet.h includes win32.h, which without lean_and_mean includes // winspool.h, which defines MAX_PRIORITY as a macro, which then -// results in http_manager.hpp not being compilable. +// results in request_manager.hpp not being compilable. #define WIN32_LEAN_AND_MEAN #include diff --git a/src/online/current_user.cpp b/src/online/current_user.cpp index c86c79190..dede03afc 100644 --- a/src/online/current_user.cpp +++ b/src/online/current_user.cpp @@ -77,7 +77,7 @@ namespace Online request->addParameter("action", std::string("recovery")); request->addParameter("username", username); request->addParameter("email", email); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -97,7 +97,7 @@ namespace Online request->addParameter("password_confirm", password_confirm); request->addParameter("email", email); request->addParameter("terms", std::string("on")); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -112,7 +112,7 @@ namespace Online request->addParameter("action",std::string("saved-session")); request->addParameter("userid", UserConfigParams::m_saved_user); request->addParameter("token", UserConfigParams::m_saved_token.c_str()); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); m_state = US_SIGNING_IN; } } @@ -131,7 +131,7 @@ namespace Online request->addParameter("save-session", StringUtils::boolstr(save_session)); if (request_now) { - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); m_state = US_SIGNING_IN; } return request; @@ -200,7 +200,7 @@ namespace Online request->addParameter("userid", getID()); request->addParameter("name", name); request->addParameter("max_players", max_players); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -222,7 +222,7 @@ namespace Online request->addParameter("action",std::string("disconnect")); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); m_state = US_SIGNING_OUT; } @@ -260,7 +260,7 @@ namespace Online request->addParameter("id", getID()); request->addParameter("server_id", server_id); if (request_now) - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -286,7 +286,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("addonid", addon_id.substr(6)); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -304,7 +304,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("search-string", search_string); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -324,7 +324,7 @@ namespace Online request->addParameter("userid", getID()); request->addParameter("addonid", addon_id.substr(6)); request->addParameter("rating", rating); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); return request; } @@ -357,7 +357,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -394,7 +394,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -432,7 +432,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -471,7 +471,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -510,7 +510,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -554,7 +554,7 @@ namespace Online request->addParameter("current", current_password); request->addParameter("new1", new_password); request->addParameter("new2", new_password_ver); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -586,7 +586,7 @@ namespace Online request->addParameter("action", std::string("poll")); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } /** @@ -713,12 +713,12 @@ namespace Online { if(isRegisteredUser()) { - HTTPRequest * request = new HTTPRequest(true, HTTPManager::HTTP_MAX_PRIORITY); + HTTPRequest * request = new HTTPRequest(true, RequestManager::HTTP_MAX_PRIORITY); request->setServerURL("client-user.php"); request->addParameter("action", std::string("client-quit")); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } } @@ -737,7 +737,7 @@ namespace Online request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("achievementid", achievement_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } } diff --git a/src/online/current_user.hpp b/src/online/current_user.hpp index 7eb6f4857..c75e62604 100644 --- a/src/online/current_user.hpp +++ b/src/online/current_user.hpp @@ -19,9 +19,10 @@ #ifndef HEADER_CURRENT_ONLINE_USER_HPP #define HEADER_CURRENT_ONLINE_USER_HPP -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/server.hpp" #include "online/profile.hpp" +#include "online/xml_request.hpp" #include "utils/types.hpp" #include "utils/synchronised.hpp" diff --git a/src/online/http_request.cpp b/src/online/http_request.cpp new file mode 100644 index 000000000..a303da6f3 --- /dev/null +++ b/src/online/http_request.cpp @@ -0,0 +1,232 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 Glenn De Jonghe +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "online/http_request.hpp" + +#include "config/user_config.hpp" +#include "online/request_manager.hpp" +#include "utils/constants.hpp" +#include "utils/translation.hpp" + +#ifdef WIN32 +# include +#endif + +#include + +#include + + +namespace Online{ + + /** Creates a HTTP(S) request that will have a raw string as result. (Can + * of course be used if the result doesn't matter.) + * \param manage_memory whether or not the HTTPManager should take care of + * deleting the object after all callbacks have been done. + * \param priority by what priority should the HTTPManager take care of + * this request. + */ + HTTPRequest::HTTPRequest(bool manage_memory, int priority) + : Request(manage_memory, priority, 0) + { + m_url = ""; + m_string_buffer = ""; + m_parameters = new Parameters(); + m_progress.setAtomic(0); + } // HTTPRequest + + // ------------------------------------------------------------------------ + HTTPRequest::~HTTPRequest() + { + delete m_parameters; + } // ~HTTPRequest + + // ------------------------------------------------------------------------ + /** A handy shortcut that appends the given path to the URL of the server. + * \param path The path to add to the server. + */ + void HTTPRequest::setServerURL(const std::string& path) + { + setURL((std::string)UserConfigParams::m_server_multiplayer+path); + } // setServerURL + + // ------------------------------------------------------------------------ + /** Checks the request if it has enough (correct) information to be + * executed (and thus allowed to add to the queue). + */ + bool HTTPRequest::isAllowedToAdd() + { + return Request::isAllowedToAdd() && m_url.substr(0, 5) == "http:"; + } // isAllowedToAdd + + // ------------------------------------------------------------------------ + /** Sets up the curl data structures. + */ + void HTTPRequest::prepareOperation() + { + m_curl_session = curl_easy_init(); + if(!m_curl_session) + { + Log::error("HTTPRequest::prepareOperation", + "LibCurl session not initialized."); + return; + } + curl_easy_setopt(m_curl_session, CURLOPT_URL, m_url.c_str()); + curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, + &HTTPRequest::writeCallback); + curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION, + &HTTPRequest::progressDownload); + curl_easy_setopt(m_curl_session, CURLOPT_CONNECTTIMEOUT, 20); + curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10); + curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20); + //https + struct curl_slist *chunk = NULL; + chunk = curl_slist_append(chunk, "Host: api.stkaddons.net"); + curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk); + curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, + (file_manager->getAsset("web.tuxfamily.org.pem")).c_str()); + curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L); + //curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, &m_string_buffer); + } // prepareOperation + + // ------------------------------------------------------------------------ + /** The actual curl download happens here. + */ + void HTTPRequest::operation() + { + if(!m_curl_session) + return; + Parameters::iterator iter; + std::string postString(""); + for (iter = m_parameters->begin(); iter != m_parameters->end(); ++iter) + { + if(iter != m_parameters->begin()) + postString.append("&"); + char* escaped = curl_easy_escape(m_curl_session , + iter->first.c_str(), + iter->first.size()); + postString.append(escaped); + curl_free(escaped); + postString.append("="); + escaped = curl_easy_escape(m_curl_session, + iter->second.c_str(), + iter->second.size()); + postString.append(escaped); + curl_free(escaped); + } + Log::info("HTTPRequest::operation", "Sending : %s", + postString.c_str()); + curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, + postString.c_str()); + std::string uagent( std::string("SuperTuxKart/") + STK_VERSION ); + #ifdef WIN32 + uagent += (std::string)" (Windows)"; + #elif defined(__APPLE__) + uagent += (std::string)" (Macintosh)"; + #elif defined(__FreeBSD__) + uagent += (std::string)" (FreeBSD)"; + #elif defined(linux) + uagent += (std::string)" (Linux)"; + #else + // Unknown system type + #endif + curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str()); + + m_curl_code = curl_easy_perform(m_curl_session); + Request::operation(); + } // operation + + // ------------------------------------------------------------------------ + /** Cleanup once the download is finished. The value of progress is + * guaranteed to be >=0 and <1 while the download is in progress, and + * will only be set to 1 on a successfull finish here. + */ + void HTTPRequest::afterOperation() + { + if(m_curl_code == CURLE_OK) + setProgress(1.0f); + else + setProgress(-1.0f); + Request::afterOperation(); + curl_easy_cleanup(m_curl_session); + } // afterOperation + + // ------------------------------------------------------------------------ + /** Callback from curl. This stores the data received by curl in the + * buffer of this request. + * \param content Pointer to the data received by curl. + * \param size Size of one block. + * \param nmemb Number of blocks received. + * \param userp Pointer to the user buffer. + */ + size_t HTTPRequest::writeCallback(void *contents, size_t size, + size_t nmemb, void *userp) + { + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; + } // writeCallback + + // ---------------------------------------------------------------------------- + /** Callback function from curl: inform about progress. It makes sure that + * the value reported by getProgress () is <1 while the download is still + * in progress. + * \param clientp + * \param download_total Total size of data to download. + * \param download_now How much has been downloaded so far. + * \param upload_total Total amount of upload. + * \param upload_now How muc has been uploaded so far. + */ + int HTTPRequest::progressDownload(void *clientp, + double download_total, double download_now, + double upload_total, double upload_now) + { + HTTPRequest *request = (HTTPRequest *)clientp; + + RequestManager* request_manager = RequestManager::get(); + + // Check if we are asked to abort the download. If so, signal this + // back to libcurl by returning a non-zero status. + if(request_manager->getAbort() || request->isCancelled() ) + { + // Indicates to abort the current download, which means that this + // thread will go back to the mainloop and handle the next request. + return 1; + } + + float f; + if(download_now < download_total) + { + f = (float)download_now / (float)download_total; + // In case of floating point rouding errors make sure that + // 1.0 is only reached when downloadFileInternal is finished + if (f>=1.0f) f=0.99f; + } + else + { + // Don't set progress to 1.0f; this is done in afterOperation() + // after checking curls return code! + f= download_total==0 ? 0 : 0.99f; + } + request->setProgress(f); + return 0; + } // progressDownload + + +} // namespace Online diff --git a/src/online/http_request.hpp b/src/online/http_request.hpp new file mode 100644 index 000000000..91ea86f95 --- /dev/null +++ b/src/online/http_request.hpp @@ -0,0 +1,145 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2011-2013 Joerg Henrichs +// 2013 Glenn De Jonghe +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_HTTP_REQUEST_HPP +#define HEADER_HTTP_REQUEST_HPP + +#include "io/file_manager.hpp" +#include "online/request.hpp" +#include "utils/cpp2011.h" +#include "utils/string_utils.hpp" +#include "utils/synchronised.hpp" + +#ifdef WIN32 +# include +#endif +#include +#include +#include + +namespace Online +{ + /** A http request. + */ + class HTTPRequest : public Request + { + private: + typedef std::map Parameters; + + /** The progress indicator. 0 untill it is started and the first + * packet is downloaded. Guaranteed to be <1 while the download + * is in progress, it will be set to either -1 (error) or 1 + * (everything ok) at the end. */ + Synchronised m_progress; + + /** The url to download. */ + std::string m_url; + + /** The POST parameters that will be send with the request. */ + Parameters *m_parameters; + + /** Pointer to the curl data structure for this request. */ + CURL *m_curl_session; + + /** curl return code. */ + CURLcode m_curl_code; + + /** String to store the received data in. */ + std::string m_string_buffer; + + protected: + virtual void prepareOperation() OVERRIDE; + virtual void operation() OVERRIDE; + virtual void afterOperation() OVERRIDE; + + static int progressDownload(void *clientp, double dltotal, + double dlnow, double ultotal, + double ulnow); + + static size_t writeCallback(void *contents, size_t size, + size_t nmemb, void *userp); + + + public : + HTTPRequest(bool manage_memory = false, + int priority = 1); + virtual ~HTTPRequest(); + virtual bool isAllowedToAdd() OVERRIDE; + void setServerURL(const std::string& url); + // ------------------------------------------------------------------------ + /** Returns the curl error status of the request. + */ + CURLcode getResult() const { return m_curl_code; } + // ------------------------------------------------------------------------ + /** Returns the downloaded string. + * \pre request has to be done + * \return get the result string from the request reply + */ + const std::string & getData() const + { + assert(hasBeenExecuted()); + return m_string_buffer; + } // getData + + // -------------------------------------------------------------------- + /** Sets a parameter to 'value' (std::string). + */ + void addParameter(const std::string & name, const std::string &value) + { + assert(isPreparing()); + (*m_parameters)[name] = value; + }; // addParameter + // -------------------------------------------------------------------- + /** Sets a parameter to 'value' (stringw). + */ + void addParameter(const std::string & name, + const irr::core::stringw &value) + { + assert(isPreparing()); + (*m_parameters)[name] = irr::core::stringc(value.c_str()).c_str(); + } // addParameter + // -------------------------------------------------------------------- + /** Sets a parameter to 'value' (arbitrary types). + */ + template + void addParameter(const std::string & name, const T& value){ + assert(isPreparing()); + (*m_parameters)[name] = StringUtils::toString(value); + } // addParameter + // -------------------------------------------------------------------- + /** Returns the current progress. */ + float getProgress() const { return m_progress.getAtomic(); } + // -------------------------------------------------------------------- + /** Sets the current progress. */ + void setProgress(float f) { m_progress.setAtomic(f); } + // -------------------------------------------------------------------- + const std::string & getURL() const { assert(isBusy()); return m_url;} + // -------------------------------------------------------------------- + /** Sets the URL for this request. */ + void setURL(const std::string & url) + { + assert(isPreparing()); + m_url = url; + } // setURL + + }; // class HTTPRequest + +} //namespace Online + +#endif + diff --git a/src/online/profile.cpp b/src/online/profile.cpp index 2a65c6633..fbddd2f05 100644 --- a/src/online/profile.cpp +++ b/src/online/profile.cpp @@ -20,7 +20,7 @@ #include "online/profile.hpp" #include "online/profile_manager.hpp" -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "config/user_config.hpp" #include "online/current_user.hpp" #include "utils/log.hpp" @@ -146,7 +146,7 @@ namespace Online{ request->addParameter("token", CurrentUser::get()->getToken()); request->addParameter("userid", CurrentUser::get()->getID()); request->addParameter("visitingid", m_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } void Profile::AchievementsRequest::callback() @@ -202,7 +202,7 @@ namespace Online{ request->addParameter("token", CurrentUser::get()->getToken()); request->addParameter("userid", CurrentUser::get()->getID()); request->addParameter("visitingid", m_id); - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } void Profile::FriendsListRequest::callback() diff --git a/src/online/profile.hpp b/src/online/profile.hpp index 60f5b39b6..1095d474d 100644 --- a/src/online/profile.hpp +++ b/src/online/profile.hpp @@ -19,8 +19,8 @@ #ifndef HEADER_ONLINE_PROFILE_HPP #define HEADER_ONLINE_PROFILE_HPP -#include "http_manager.hpp" -#include "online/request.hpp" +#include "online/request_manager.hpp" +#include "online/xml_request.hpp" #include "utils/types.hpp" #include "utils/ptr_vector.hpp" diff --git a/src/online/request.cpp b/src/online/request.cpp index a33c7f666..7c6eb9fc0 100644 --- a/src/online/request.cpp +++ b/src/online/request.cpp @@ -17,32 +17,27 @@ #include "online/request.hpp" #include "config/user_config.hpp" -#include "online/http_manager.hpp" -#include "utils/constants.hpp" -#include "utils/translation.hpp" +#include "online/request_manager.hpp" #ifdef WIN32 # include #endif -#include - #include -namespace Online{ - - class HTTPManager; +namespace Online +{ // ======================================================================== /** - * Creates a request that can be handled by the HTTPManager - * \param manage_memory whether or not the HTTPManager should take care of + * Creates a request that can be handled by the RequestManager + * \param manage_memory whether or not the RequestManager should take care of * deleting the object after all callbacks have been done - * \param priority by what priority should the HTTPManager take care of + * \param priority by what priority should the RequestManager take care of * this request * \param type indicates whether the request has a special task for the - * HTTPManager + * RequestManager */ Request::Request(bool manage_memory, int priority, int type) : m_type(type), m_manage_memory(manage_memory), m_priority(priority) @@ -77,248 +72,5 @@ namespace Online{ setDone(); } // executeNow - // ======================================================================== - /** Creates a HTTP(S) request that will have a raw string as result. (Can - * of course be used if the result doesn't matter.) - * \param manage_memory whether or not the HTTPManager should take care of - * deleting the object after all callbacks have been done. - * \param priority by what priority should the HTTPManager take care of - * this request. - */ - HTTPRequest::HTTPRequest(bool manage_memory, int priority) - : Request(manage_memory, priority, 0) - { - m_url = ""; - m_string_buffer = ""; - m_parameters = new Parameters(); - m_progress.setAtomic(0); - } // HTTPRequest - - // ------------------------------------------------------------------------ - HTTPRequest::~HTTPRequest() - { - delete m_parameters; - } // ~HTTPRequest - - // ------------------------------------------------------------------------ - /** A handy shortcut that appends the given path to the URL of the server. - * \param path The path to add to the server. - */ - void HTTPRequest::setServerURL(const std::string& path) - { - setURL((std::string)UserConfigParams::m_server_multiplayer+path); - } // setServerURL - - // ------------------------------------------------------------------------ - /** Checks the request if it has enough (correct) information to be - * executed (and thus allowed to add to the queue). - */ - bool HTTPRequest::isAllowedToAdd() - { - return Request::isAllowedToAdd() && m_url.substr(0, 5) == "http:"; - } // isAllowedToAdd - - // ------------------------------------------------------------------------ - /** Sets up the curl data structures. - */ - void HTTPRequest::prepareOperation() - { - m_curl_session = curl_easy_init(); - if(!m_curl_session) - { - Log::error("HTTPRequest::prepareOperation", - "LibCurl session not initialized."); - return; - } - curl_easy_setopt(m_curl_session, CURLOPT_URL, m_url.c_str()); - curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, - &HTTPRequest::writeCallback); - curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION, - &HTTPRequest::progressDownload); - curl_easy_setopt(m_curl_session, CURLOPT_CONNECTTIMEOUT, 20); - curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10); - curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20); - //https - struct curl_slist *chunk = NULL; - chunk = curl_slist_append(chunk, "Host: api.stkaddons.net"); - curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk); - curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, - (file_manager->getAsset("web.tuxfamily.org.pem")).c_str()); - curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L); - //curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, &m_string_buffer); - } // prepareOperation - - // ------------------------------------------------------------------------ - /** The actual curl download happens here. - */ - void HTTPRequest::operation() - { - if(!m_curl_session) - return; - Parameters::iterator iter; - std::string postString(""); - for (iter = m_parameters->begin(); iter != m_parameters->end(); ++iter) - { - if(iter != m_parameters->begin()) - postString.append("&"); - char* escaped = curl_easy_escape(m_curl_session , - iter->first.c_str(), - iter->first.size()); - postString.append(escaped); - curl_free(escaped); - postString.append("="); - escaped = curl_easy_escape(m_curl_session, - iter->second.c_str(), - iter->second.size()); - postString.append(escaped); - curl_free(escaped); - } - Log::info("HTTPRequest::operation", "Sending : %s", - postString.c_str()); - curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, - postString.c_str()); - std::string uagent( std::string("SuperTuxKart/") + STK_VERSION ); - #ifdef WIN32 - uagent += (std::string)" (Windows)"; - #elif defined(__APPLE__) - uagent += (std::string)" (Macintosh)"; - #elif defined(__FreeBSD__) - uagent += (std::string)" (FreeBSD)"; - #elif defined(linux) - uagent += (std::string)" (Linux)"; - #else - // Unknown system type - #endif - curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str()); - - m_curl_code = curl_easy_perform(m_curl_session); - Request::operation(); - } // operation - - // ------------------------------------------------------------------------ - /** Cleanup once the download is finished. The value of progress is - * guaranteed to be >=0 and <1 while the download is in progress, and - * will only be set to 1 on a successfull finish here. - */ - void HTTPRequest::afterOperation() - { - if(m_curl_code == CURLE_OK) - setProgress(1.0f); - else - setProgress(-1.0f); - Request::afterOperation(); - curl_easy_cleanup(m_curl_session); - } // afterOperation - - // ------------------------------------------------------------------------ - /** Callback from curl. This stores the data received by curl in the - * buffer of this request. - * \param content Pointer to the data received by curl. - * \param size Size of one block. - * \param nmemb Number of blocks received. - * \param userp Pointer to the user buffer. - */ - size_t HTTPRequest::writeCallback(void *contents, size_t size, - size_t nmemb, void *userp) - { - ((std::string*)userp)->append((char*)contents, size * nmemb); - return size * nmemb; - } // writeCallback - - // ---------------------------------------------------------------------------- - /** Callback function from curl: inform about progress. It makes sure that - * the value reported by getProgress () is <1 while the download is still - * in progress. - * \param clientp - * \param download_total Total size of data to download. - * \param download_now How much has been downloaded so far. - * \param upload_total Total amount of upload. - * \param upload_now How muc has been uploaded so far. - */ - int HTTPRequest::progressDownload(void *clientp, - double download_total, double download_now, - double upload_total, double upload_now) - { - HTTPRequest *request = (HTTPRequest *)clientp; - - HTTPManager* http_manager = HTTPManager::get(); - - // Check if we are asked to abort the download. If so, signal this - // back to libcurl by returning a non-zero status. - if(http_manager->getAbort() || request->isCancelled() ) - { - // Indicates to abort the current download, which means that this - // thread will go back to the mainloop and handle the next request. - return 1; - } - - float f; - if(download_now < download_total) - { - f = (float)download_now / (float)download_total; - // In case of floating point rouding errors make sure that - // 1.0 is only reached when downloadFileInternal is finished - if (f>=1.0f) f=0.99f; - } - else - { - // Don't set progress to 1.0f; this is done in afterOperation() - // after checking curls return code! - f= download_total==0 ? 0 : 0.99f; - } - request->setProgress(f); - return 0; - } // progressDownload - - // ======================================================================== - /** Creates a HTTP(S) request that will automatically parse the answer into - * a XML structure. - * \param manage_memory whether or not the HTTPManager should take care of - * deleting the object after all callbacks have been done. - * \param priority by what priority should the HTTPManager take care of - * this request. - */ - XMLRequest::XMLRequest(bool manage_memory, int priority) - : HTTPRequest(manage_memory, priority) - { - m_info = ""; - m_success = false; - m_xml_data = NULL; - } // XMLRequest - - // ------------------------------------------------------------------------ - /** Cleans up the XML tree. */ - XMLRequest::~XMLRequest() - { - delete m_xml_data; - } // ~XMLRequest - - // ------------------------------------------------------------------------ - /** On a successful download converts the string into an XML tree. - */ - void XMLRequest::afterOperation() - { - m_xml_data = file_manager->createXMLTreeFromString(getData()); - if(getResult() != CURLE_OK) - Log::error("XMLRequest::afterOperation", - "curl_easy_perform() failed: %s", - curl_easy_strerror(getResult())); - m_success = false; - std::string rec_success; - if(m_xml_data->get("success", &rec_success)) - { - m_success = rec_success =="yes"; - m_xml_data->get("info", &m_info); - } - else - m_info = _("Unable to connect to the server. Check your internet " - "connection or try again later."); - HTTPRequest::afterOperation(); - } // afterOperation - } // namespace Online diff --git a/src/online/request.hpp b/src/online/request.hpp index 8e0423cc5..66ece63ac 100644 --- a/src/online/request.hpp +++ b/src/online/request.hpp @@ -31,7 +31,8 @@ #include #include -namespace Online{ +namespace Online +{ /** Stores a request for the HTTP Manager. They will be sorted by * prioritiy. Requests have four different states they can be in, and @@ -40,7 +41,7 @@ namespace Online{ * and code to the main thread. The states are: * - Preparing\n The request is created, and parameter are set. * Only the main thread can access this object. - * - Busy\n The request is put into the http_manager queue. It remains + * - Busy\n The request is put into the request_manager queue. It remains * in this states till its operation is finished. No more changes * to this object by the main thread are allowed, only the manager * thread can change it now. @@ -75,15 +76,15 @@ namespace Online{ * - S_PREPARING:\n The request is created and can be configured, it * is not yet started. * - S_BUSY:\n The request is added to the execution queue of the - * http_manager (and potentially executing). This implies that - * now only the http_manager thread should access the requests's + * request_manager (and potentially executing). This implies that + * now only the request_manager thread should access the requests's * data structures. * - S_EXECUTED:\n The request was executed, but was not yet marked - * as finished in the http_manager. This importantly indicates + * as finished in the request_manager. This importantly indicates * that the main thread should not yet access this request, * since the http thread is still executing it. * - S_DONE:\n The request is finished, and it is marked as - * finished in the http_manager. This implies that the main + * finished in the request_manager. This implies that the main * stk thread can access its data safely now. */ enum State @@ -199,174 +200,10 @@ namespace Online{ { return a->getPriority() < b->getPriority(); } - }; // Compare - }; // Request + }; // class Compare + }; // class Request - // ======================================================================== - /** A http request. - */ - class HTTPRequest : public Request - { - private: - typedef std::map Parameters; - - /** The progress indicator. 0 untill it is started and the first - * packet is downloaded. Guaranteed to be <1 while the download - * is in progress, it will be set to either -1 (error) or 1 - * (everything ok) at the end. */ - Synchronised m_progress; - - /** The url to download. */ - std::string m_url; - - /** The POST parameters that will be send with the request. */ - Parameters *m_parameters; - - /** Pointer to the curl data structure for this request. */ - CURL *m_curl_session; - - /** curl return code. */ - CURLcode m_curl_code; - - /** String to store the received data in. */ - std::string m_string_buffer; - - protected: - virtual void prepareOperation() OVERRIDE; - virtual void operation() OVERRIDE; - virtual void afterOperation() OVERRIDE; - - static int progressDownload(void *clientp, double dltotal, - double dlnow, double ultotal, - double ulnow); - - static size_t writeCallback(void *contents, size_t size, - size_t nmemb, void *userp); - - - public : - HTTPRequest(bool manage_memory = false, - int priority = 1); - virtual ~HTTPRequest(); - virtual bool isAllowedToAdd() OVERRIDE; - void setServerURL(const std::string& url); - // ------------------------------------------------------------------------ - /** Returns the curl error status of the request. - */ - CURLcode getResult() const { return m_curl_code; } - // ------------------------------------------------------------------------ - /** Returns the downloaded string. - * \pre request has to be done - * \return get the result string from the request reply - */ - const std::string & getData() const - { - assert(hasBeenExecuted()); - return m_string_buffer; - } // getData - - // -------------------------------------------------------------------- - /** Sets a parameter to 'value' (std::string). - */ - void addParameter(const std::string & name, const std::string &value) - { - assert(isPreparing()); - (*m_parameters)[name] = value; - }; // addParameter - // -------------------------------------------------------------------- - /** Sets a parameter to 'value' (stringw). - */ - void addParameter(const std::string & name, - const irr::core::stringw &value) - { - assert(isPreparing()); - (*m_parameters)[name] = irr::core::stringc(value.c_str()).c_str(); - } // addParameter - // -------------------------------------------------------------------- - /** Sets a parameter to 'value' (arbitrary types). - */ - template - void addParameter(const std::string & name, const T& value){ - assert(isPreparing()); - (*m_parameters)[name] = StringUtils::toString(value); - } // addParameter - // -------------------------------------------------------------------- - /** Returns the current progress. */ - float getProgress() const { return m_progress.getAtomic(); } - // -------------------------------------------------------------------- - /** Sets the current progress. */ - void setProgress(float f) { m_progress.setAtomic(f); } - // -------------------------------------------------------------------- - const std::string & getURL() const { assert(isBusy()); return m_url;} - // -------------------------------------------------------------------- - /** Sets the URL for this request. */ - void setURL(const std::string & url) - { - assert(isPreparing()); - m_url = url; - } // setURL - - }; // class HTTPRequest - - // ======================================================================== - /** A http request expecting a xml return value. - */ - class XMLRequest : public HTTPRequest - { - private: - /** On a successful download contains the converted XML tree. */ - XMLNode *m_xml_data; - - /** Additional info contained the downloaded data (or an error - * message if a problem occurred). */ - irr::core::stringw m_info; - - /** True if the request was successful executed on the server. */ - bool m_success; - - protected: - virtual void afterOperation() OVERRIDE; - - public : - XMLRequest(bool manage_memory = false, int priority = 1); - virtual ~XMLRequest(); - - // ------------------------------------------------------------------------ - /** Get the downloaded XML tree. - * \pre request has to be executed. - * \return get the complete result from the request reply. - */ - const XMLNode * getXMLData() const - { - assert(hasBeenExecuted()); - return m_xml_data; - } // getXMLData - - // ------------------------------------------------------------------------ - /** Returns the additional information (or error message) contained in - * a finished request. - * \pre request had to be executed. - * \return get the info from the request reply - */ - const irr::core::stringw & getInfo() const - { - assert(hasBeenExecuted()); - return m_info; - } // getInfo - - // -------------------------------------------------------------------- - /** Returns whether the request was successfully executed on the server. - * \pre request had to be executed. - * \return whether or not the request was a success. */ - bool isSuccess() const - { - assert(hasBeenExecuted()); - return m_success; - } // isSuccess - - }; // class XMLRequest - } //namespace Online #endif diff --git a/src/online/http_manager.cpp b/src/online/request_manager.cpp similarity index 92% rename from src/online/http_manager.cpp rename to src/online/request_manager.cpp index 6400f2d07..065fd38b9 100644 --- a/src/online/http_manager.cpp +++ b/src/online/request_manager.cpp @@ -18,7 +18,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include "online/http_manager.hpp" +#include "online/request_manager.hpp" #include "online/current_user.hpp" #include "states_screens/state_manager.hpp" @@ -37,18 +37,19 @@ using namespace Online; -namespace Online{ +namespace Online +{ #define MENU_POLLING_INTERVAL 10.0f #define GAME_POLLING_INTERVAL 15.0f - static HTTPManager * http_singleton = NULL; + static RequestManager * http_singleton = NULL; // ------------------------------------------------------------------------ - HTTPManager* HTTPManager::get() + RequestManager* RequestManager::get() { if (http_singleton == NULL) { - http_singleton = new HTTPManager(); + http_singleton = new RequestManager(); } return http_singleton; } // get @@ -56,7 +57,7 @@ namespace Online{ // ------------------------------------------------------------------------ /** Deletes the http manager. */ - void HTTPManager::deallocate() + void RequestManager::deallocate() { if (http_singleton != NULL) { @@ -68,14 +69,14 @@ namespace Online{ // ------------------------------------------------------------------------ /** Checks if the http manager is running. */ - bool HTTPManager::isRunning() + bool RequestManager::isRunning() { return http_singleton != NULL; } // isRunning // ------------------------------------------------------------------------ - HTTPManager::HTTPManager() + RequestManager::RequestManager() { curl_global_init(CURL_GLOBAL_DEFAULT); pthread_cond_init(&m_cond_request, NULL); @@ -84,7 +85,8 @@ namespace Online{ } // ------------------------------------------------------------------------ - HTTPManager::~HTTPManager(){ + RequestManager::~RequestManager() + { m_thread_id.lock(); pthread_join(*m_thread_id.getData(), NULL); delete m_thread_id.getData(); @@ -101,7 +103,7 @@ namespace Online{ * use network_http - a very subtle race condition. So the thread can * only be started after the assignment (in main) has been done. */ - void HTTPManager::startNetworkThread() + void RequestManager::startNetworkThread() { pthread_attr_t attr; pthread_attr_init(&attr); @@ -112,7 +114,7 @@ namespace Online{ m_thread_id.setAtomic(new pthread_t()); int error = pthread_create(m_thread_id.getData(), &attr, - &HTTPManager::mainLoop, this); + &RequestManager::mainLoop, this); if(error) { m_thread_id.lock(); @@ -132,7 +134,7 @@ namespace Online{ * Separating this allows more time for the thread to finish cleanly, * before it gets cancelled in the destructor. */ - void HTTPManager::stopNetworkThread() + void RequestManager::stopNetworkThread() { // If a download should be active (which means it was cancelled by the // user, in which case it will still be ongoing in the background) @@ -150,7 +152,7 @@ namespace Online{ * cancelled. This function can also be called if there is actually no * download atm. The function progressDownload checks m_abort and will * return a non-zero value which causes libcurl to abort. */ - void HTTPManager::cancelAllDownloads() + void RequestManager::cancelAllDownloads() { m_abort.setAtomic(true); // FIXME doesn't get called at the moment. When using this again, @@ -162,7 +164,7 @@ namespace Online{ * sorted by priority. * \param request The pointer to the new request to insert. */ - void HTTPManager::addRequest(Request *request) + void RequestManager::addRequest(Request *request) { assert(request->isPreparing()); request->setBusy(); @@ -179,9 +181,9 @@ namespace Online{ * of packages to download, it will wait for commands to be issued. * \param obj: A pointer to this object, passed on by pthread_create */ - void *HTTPManager::mainLoop(void *obj) + void *RequestManager::mainLoop(void *obj) { - HTTPManager *me = (HTTPManager*) obj; + RequestManager *me = (RequestManager*) obj; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); @@ -227,7 +229,7 @@ namespace Online{ /** Inserts a request into the queue of results. * \param request The pointer to the request to insert. */ - void HTTPManager::addResult(Online::Request *request) + void RequestManager::addResult(Online::Request *request) { assert(request->hasBeenExecuted()); m_result_queue.lock(); @@ -240,7 +242,7 @@ namespace Online{ * Calls the callback method of the request and takes care of memory * management if necessary. */ - void HTTPManager::handleResultQueue() + void RequestManager::handleResultQueue() { Request * request = NULL; m_result_queue.lock(); @@ -267,7 +269,7 @@ namespace Online{ /** Should be called every frame and takes care of processing the result * queue and polling the database server if a user is signed in. */ - void HTTPManager::update(float dt) + void RequestManager::update(float dt) { handleResultQueue(); diff --git a/src/online/http_manager.hpp b/src/online/request_manager.hpp similarity index 91% rename from src/online/http_manager.hpp rename to src/online/request_manager.hpp index d9e95f47d..a8b57e8e3 100644 --- a/src/online/http_manager.hpp +++ b/src/online/request_manager.hpp @@ -18,8 +18,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HTTP_MANAGER_HPP -#define HTTP_MANAGER_HPP +#ifndef HEADER_REQUEST_MANAGER_HPP +#define HEADER_REQUEST_MANAGER_HPP #include "io/xml_node.hpp" #include "online/request.hpp" @@ -39,13 +39,14 @@ #include -namespace Online{ +namespace Online +{ /** * \brief Class to connect with a server over HTTP(S) * \ingroup online */ - class HTTPManager + class RequestManager { protected: @@ -79,14 +80,14 @@ namespace Online{ static void *mainLoop(void *obj); - HTTPManager(); //const std::string &url - ~HTTPManager(); + RequestManager(); //const std::string &url + ~RequestManager(); public: static const int HTTP_MAX_PRIORITY = 9999; // singleton - static HTTPManager* get(); + static RequestManager* get(); static void deallocate(); static bool isRunning(); @@ -98,9 +99,9 @@ namespace Online{ bool getAbort(){ return m_abort.getAtomic(); }; void update(float dt); - }; //class HTTPManager + }; //class RequestManager } // namespace Online -#endif // HTTP_MANAGER_HPP +#endif // request_manager_HPP /*EOF*/ diff --git a/src/online/servers_manager.cpp b/src/online/servers_manager.cpp index c810e01b3..248441c4c 100644 --- a/src/online/servers_manager.cpp +++ b/src/online/servers_manager.cpp @@ -78,7 +78,7 @@ namespace Online{ request->setServerURL("client-user.php"); request->addParameter("action",std::string("get_server_list")); if (request_now) - HTTPManager::get()->addRequest(request); + RequestManager::get()->addRequest(request); } return request; } diff --git a/src/online/servers_manager.hpp b/src/online/servers_manager.hpp index 808ae6b1b..3c0d26a40 100644 --- a/src/online/servers_manager.hpp +++ b/src/online/servers_manager.hpp @@ -22,7 +22,8 @@ #include "utils/ptr_vector.hpp" #include "utils/types.hpp" #include "online/server.hpp" -#include "http_manager.hpp" +#include "online/request_manager.hpp" +#include "online/xml_request.hpp" #include "utils/synchronised.hpp" diff --git a/src/online/xml_request.cpp b/src/online/xml_request.cpp new file mode 100644 index 000000000..d1a663886 --- /dev/null +++ b/src/online/xml_request.cpp @@ -0,0 +1,82 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 Glenn De Jonghe +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "online/xml_request.hpp" + +#include "config/user_config.hpp" +#include "online/request_manager.hpp" +#include "utils/constants.hpp" +#include "utils/translation.hpp" + +#ifdef WIN32 +# include +#endif + +#include + +#include + + +namespace Online +{ + + /** Creates a HTTP(S) request that will automatically parse the answer into + * a XML structure. + * \param manage_memory whether or not the RequestManager should take care of + * deleting the object after all callbacks have been done. + * \param priority by what priority should the RequestManager take care of + * this request. + */ + XMLRequest::XMLRequest(bool manage_memory, int priority) + : HTTPRequest(manage_memory, priority) + { + m_info = ""; + m_success = false; + m_xml_data = NULL; + } // XMLRequest + + // ------------------------------------------------------------------------ + /** Cleans up the XML tree. */ + XMLRequest::~XMLRequest() + { + delete m_xml_data; + } // ~XMLRequest + + // ------------------------------------------------------------------------ + /** On a successful download converts the string into an XML tree. + */ + void XMLRequest::afterOperation() + { + m_xml_data = file_manager->createXMLTreeFromString(getData()); + if(getResult() != CURLE_OK) + Log::error("XMLRequest::afterOperation", + "curl_easy_perform() failed: %s", + curl_easy_strerror(getResult())); + m_success = false; + std::string rec_success; + if(m_xml_data->get("success", &rec_success)) + { + m_success = rec_success =="yes"; + m_xml_data->get("info", &m_info); + } + else + m_info = _("Unable to connect to the server. Check your internet " + "connection or try again later."); + HTTPRequest::afterOperation(); + } // afterOperation + + +} // namespace Online diff --git a/src/online/xml_request.hpp b/src/online/xml_request.hpp new file mode 100644 index 000000000..120bb1691 --- /dev/null +++ b/src/online/xml_request.hpp @@ -0,0 +1,97 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2011-2013 Joerg Henrichs +// 2013 Glenn De Jonghe +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_XML_REQUEST_HPP +#define HEADER_XML_REQUEST_HPP + +#include "io/file_manager.hpp" +#include "online/http_request.hpp" +#include "utils/cpp2011.h" +#include "utils/string_utils.hpp" +#include "utils/synchronised.hpp" + +#ifdef WIN32 +# include +#endif +#include +#include +#include + +namespace Online +{ + /** A http request expecting a xml return value. + */ + class XMLRequest : public HTTPRequest + { + private: + /** On a successful download contains the converted XML tree. */ + XMLNode *m_xml_data; + + /** Additional info contained the downloaded data (or an error + * message if a problem occurred). */ + irr::core::stringw m_info; + + /** True if the request was successful executed on the server. */ + bool m_success; + + protected: + virtual void afterOperation() OVERRIDE; + + public : + XMLRequest(bool manage_memory = false, int priority = 1); + virtual ~XMLRequest(); + + // ------------------------------------------------------------------------ + /** Get the downloaded XML tree. + * \pre request has to be executed. + * \return get the complete result from the request reply. + */ + const XMLNode * getXMLData() const + { + assert(hasBeenExecuted()); + return m_xml_data; + } // getXMLData + + // ------------------------------------------------------------------------ + /** Returns the additional information (or error message) contained in + * a finished request. + * \pre request had to be executed. + * \return get the info from the request reply + */ + const irr::core::stringw & getInfo() const + { + assert(hasBeenExecuted()); + return m_info; + } // getInfo + + // -------------------------------------------------------------------- + /** Returns whether the request was successfully executed on the server. + * \pre request had to be executed. + * \return whether or not the request was a success. */ + bool isSuccess() const + { + assert(hasBeenExecuted()); + return m_success; + } // isSuccess + + }; // class XMLRequest + +} //namespace Online + +#endif + From 9d7ab41c11481cbb9aeb4a17388cafb339f972d8 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 16:09:27 +0000 Subject: [PATCH 209/412] OGL32CTX: Replace ftransform by gl_ModelViewProjectionMatrix * gl_Vertex. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14979 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/bubble.vert | 2 +- data/shaders/displace.vert | 2 +- data/shaders/gum_shield.vert | 2 +- data/shaders/lightbeam.vert | 2 +- data/shaders/mlaa_offset.vert | 2 +- data/shaders/normalmap.vert | 2 +- data/shaders/objectpass.vert | 2 +- data/shaders/objectpass_rimlit.vert | 2 +- data/shaders/shadowpass.vert | 2 +- data/shaders/skybox.vert | 2 +- data/shaders/snow.vert | 2 +- data/shaders/spheremap.vert | 2 +- data/shaders/splatting.vert | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/shaders/bubble.vert b/data/shaders/bubble.vert index 96e3a8fc1..4b7efd9a2 100644 --- a/data/shaders/bubble.vert +++ b/data/shaders/bubble.vert @@ -23,7 +23,7 @@ out vec2 uv; void main() { - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 ); float delta_y = cos(time*2.0) * sin( 3.0 * gl_TexCoord[0].st.t * 6.28318531 ); diff --git a/data/shaders/displace.vert b/data/shaders/displace.vert index 327f28522..55455cb4f 100644 --- a/data/shaders/displace.vert +++ b/data/shaders/displace.vert @@ -5,7 +5,7 @@ out vec2 edger_uv; out float camdist; void main() { - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; uv = gl_MultiTexCoord0.xy; edger_uv = gl_MultiTexCoord1.xy; diff --git a/data/shaders/gum_shield.vert b/data/shaders/gum_shield.vert index fc6cab9ad..220988a0d 100644 --- a/data/shaders/gum_shield.vert +++ b/data/shaders/gum_shield.vert @@ -34,7 +34,7 @@ void main() eyeVec = normalize(-viewp).xyz; normal = gl_NormalMatrix * gl_Normal; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; } diff --git a/data/shaders/lightbeam.vert b/data/shaders/lightbeam.vert index 49a58a837..61d6b99ed 100644 --- a/data/shaders/lightbeam.vert +++ b/data/shaders/lightbeam.vert @@ -30,7 +30,7 @@ void main() eyeVec = normalize(-viewp).xyz; normal = gl_NormalMatrix * gl_Normal; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; uv = gl_MultiTexCoord0.st; } diff --git a/data/shaders/mlaa_offset.vert b/data/shaders/mlaa_offset.vert index e457a0f1b..ecf0c3649 100644 --- a/data/shaders/mlaa_offset.vert +++ b/data/shaders/mlaa_offset.vert @@ -3,7 +3,7 @@ varying vec4 offset[2]; uniform vec2 PIXEL_SIZE; void main() { - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec4 invy = gl_MultiTexCoord0; // invy.y = 1.0 - invy.y; gl_TexCoord[0] = invy; diff --git a/data/shaders/normalmap.vert b/data/shaders/normalmap.vert index b9ab89268..7e2a40cb8 100644 --- a/data/shaders/normalmap.vert +++ b/data/shaders/normalmap.vert @@ -9,6 +9,6 @@ void main() normal = gl_NormalMatrix * gl_Normal; tangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; bitangent = gl_NormalMatrix * gl_MultiTexCoord2.xyz; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; } diff --git a/data/shaders/objectpass.vert b/data/shaders/objectpass.vert index 578e91cc3..a070c3ee3 100644 --- a/data/shaders/objectpass.vert +++ b/data/shaders/objectpass.vert @@ -7,6 +7,6 @@ void main() { nor = gl_NormalMatrix * gl_Normal; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_FrontColor = gl_Color; } diff --git a/data/shaders/objectpass_rimlit.vert b/data/shaders/objectpass_rimlit.vert index ceca62539..deabe12cc 100644 --- a/data/shaders/objectpass_rimlit.vert +++ b/data/shaders/objectpass_rimlit.vert @@ -10,6 +10,6 @@ void main() { viewpos = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_FrontColor = gl_Color; } diff --git a/data/shaders/shadowpass.vert b/data/shaders/shadowpass.vert index aa2101b51..90ef95474 100644 --- a/data/shaders/shadowpass.vert +++ b/data/shaders/shadowpass.vert @@ -10,7 +10,7 @@ float decdepth(vec4 rgba) { void main() { - vec4 pos = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; uv = gl_MultiTexCoord0.xy; vec2 tc = pos.xy * vec2(0.5) + vec2(0.5); diff --git a/data/shaders/skybox.vert b/data/shaders/skybox.vert index a0dc66a9e..6bc0ea519 100644 --- a/data/shaders/skybox.vert +++ b/data/shaders/skybox.vert @@ -31,7 +31,7 @@ out vec3 vertex; void main() { uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 ); diff --git a/data/shaders/snow.vert b/data/shaders/snow.vert index 120b6b650..d1a121596 100644 --- a/data/shaders/snow.vert +++ b/data/shaders/snow.vert @@ -2,7 +2,7 @@ void main() { gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_FrontColor = gl_Color; } diff --git a/data/shaders/spheremap.vert b/data/shaders/spheremap.vert index b0534aa93..a0b829c8b 100644 --- a/data/shaders/spheremap.vert +++ b/data/shaders/spheremap.vert @@ -25,7 +25,7 @@ noperspective out vec3 lightVec; void main() { - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vertex_color = gl_Color; //vec3 normal3 = normalize(gl_Normal); diff --git a/data/shaders/splatting.vert b/data/shaders/splatting.vert index 73ddce486..0ee6f9e11 100644 --- a/data/shaders/splatting.vert +++ b/data/shaders/splatting.vert @@ -27,7 +27,7 @@ void main() { uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; uv_bis = (gl_TextureMatrix[1] * gl_MultiTexCoord1).st; - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; color = gl_Color; nor = gl_NormalMatrix * gl_Normal; } From 9ba803140a3c98da7426a26331a720bbf289ae90 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:08:03 +0000 Subject: [PATCH 210/412] OGL32CTX: Remove implicitly defined uniforms in grass git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14980 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/grass.frag | 3 ++- data/shaders/grass.vert | 9 ++++++--- src/graphics/callbacks.cpp | 9 +++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index a42f2544f..1ac631895 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -4,10 +4,11 @@ uniform float objectid; uniform sampler2D tex; noperspective in vec3 nor; +in vec2 uv; void main() { - gl_FragData[0] = texture2D(tex, gl_TexCoord[0].st); + gl_FragData[0] = texture2D(tex, uv); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); gl_FragData[2] = vec4(0.); } diff --git a/data/shaders/grass.vert b/data/shaders/grass.vert index 776a059d2..cf22df960 100644 --- a/data/shaders/grass.vert +++ b/data/shaders/grass.vert @@ -1,15 +1,18 @@ #version 130 uniform vec3 windDir; +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; noperspective out vec3 nor; +out vec2 uv; void main() { - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + uv = gl_MultiTexCoord0.st; vec4 vertexPosition = gl_Vertex; vertexPosition.xyz += windDir * gl_Color.r; - nor = gl_NormalMatrix * gl_Normal; - gl_Position = gl_ModelViewProjectionMatrix * vertexPosition; + nor = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; + gl_Position = ModelViewProjectionMatrix * vertexPosition; } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 057f00b11..7cc6476d5 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -121,8 +121,17 @@ void GrassShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int use // Pre-multiply on the cpu vector3df wind = irr_driver->getWind() * strength; + core::matrix4 ModelViewProjectionMatrix = drv->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= drv->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= drv->getTransform(ETS_WORLD); + core::matrix4 TransposeInverseModelView = drv->getTransform(ETS_VIEW); + TransposeInverseModelView *= drv->getTransform(ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); srv->setVertexShaderConstant("windDir", &wind.X, 3); + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); if (!firstdone) { From e6d774a3acd5d5e6103ad858175b2209997da459 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:08:15 +0000 Subject: [PATCH 211/412] OGL32CTX: Remove implicitly defined uniforms in splatting git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14981 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/splatting.frag | 4 +--- data/shaders/splatting.vert | 12 ++++++------ src/graphics/callbacks.cpp | 11 +++++++++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index ea07e0dea..ea1e398f0 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -9,7 +9,6 @@ uniform sampler2D tex_detail3; noperspective in vec3 nor; in vec2 uv; in vec2 uv_bis; -in vec4 color; void main() { // Splatting part @@ -25,8 +24,7 @@ void main() { splatting.g * detail1 + splatting.b * detail2 + (1.0 - splatting.r - splatting.g - splatting.b) * detail3 + - (1.0 - splatting.a) * detail4) - * color; + (1.0 - splatting.a) * detail4); gl_FragData[0] = vec4(splatted.xyz, 1.); diff --git a/data/shaders/splatting.vert b/data/shaders/splatting.vert index 0ee6f9e11..871a062ed 100644 --- a/data/shaders/splatting.vert +++ b/data/shaders/splatting.vert @@ -17,17 +17,17 @@ #version 130 uniform vec3 lightdir; +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; noperspective out vec3 nor; out vec2 uv; out vec2 uv_bis; -out vec4 color; void main() { - uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; - uv_bis = (gl_TextureMatrix[1] * gl_MultiTexCoord1).st; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - color = gl_Color; - nor = gl_NormalMatrix * gl_Normal; + uv = gl_MultiTexCoord0.st; + uv_bis = gl_MultiTexCoord1.st; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; + nor = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 7cc6476d5..9b6533438 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -185,6 +185,17 @@ void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int) void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW); + TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); + if (!firstdone) { s32 tex_layout = 1; From 986f3a60980949f2ec394ed170d9f95d74d5cc4f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:08:23 +0000 Subject: [PATCH 212/412] OGL32CTX: Remove implicitly defined uniforms in normalmap git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14982 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/normalmap.frag | 5 +++-- data/shaders/normalmap.vert | 14 +++++++++----- src/graphics/callbacks.cpp | 11 +++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 55b66e563..4b56d5d00 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -5,11 +5,12 @@ uniform sampler2D normalMap; //The bump-map noperspective in vec3 tangent; noperspective in vec3 bitangent; noperspective in vec3 normal; +in vec2 uv; void main() { // normal in Tangent Space - vec3 TS_normal = 2.0 * texture2D (normalMap, gl_TexCoord[0].st).rgb - 1.0; + vec3 TS_normal = 2.0 * texture2D (normalMap, uv).rgb - 1.0; // Because of interpolation, we need to renormalize vec3 Frag_tangent = normalize(tangent); vec3 Frag_bitangent = normalize(cross(normal, tangent)); @@ -20,7 +21,7 @@ void main() FragmentNormal = normalize(FragmentNormal); - gl_FragData[0] = texture2D (texture, gl_TexCoord[0].st); + gl_FragData[0] = texture2D (texture, uv); gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); gl_FragData[2] = vec4(0.); } diff --git a/data/shaders/normalmap.vert b/data/shaders/normalmap.vert index 7e2a40cb8..32b14aaa1 100644 --- a/data/shaders/normalmap.vert +++ b/data/shaders/normalmap.vert @@ -1,14 +1,18 @@ #version 130 +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; + noperspective out vec3 tangent; noperspective out vec3 bitangent; noperspective out vec3 normal; +out vec2 uv; void main() { - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - normal = gl_NormalMatrix * gl_Normal; - tangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; - bitangent = gl_NormalMatrix * gl_MultiTexCoord2.xyz; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + uv = gl_MultiTexCoord0.st; + normal = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; + tangent = (TransposeInverseModelView * gl_MultiTexCoord1).xyz; + bitangent = (TransposeInverseModelView * gl_MultiTexCoord2).xyz; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 9b6533438..ecf1f01cf 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -31,6 +31,17 @@ using namespace core; void NormalMapProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW); + TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); + if (!firstdone) { s32 texture = 0; From 751d09d35f92a83d98a1225092978468262aa2b9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:09:50 +0000 Subject: [PATCH 213/412] GPUParticles: Remove snow shader as we use another now. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14983 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/snow.frag | 19 ------------------- data/shaders/snow.vert | 8 -------- 2 files changed, 27 deletions(-) delete mode 100644 data/shaders/snow.frag delete mode 100644 data/shaders/snow.vert diff --git a/data/shaders/snow.frag b/data/shaders/snow.frag deleted file mode 100644 index 62abb54d1..000000000 --- a/data/shaders/snow.frag +++ /dev/null @@ -1,19 +0,0 @@ -#version 130 -uniform sampler2D tex; -uniform float time; - -void main() -{ - vec2 change; - change.x = abs(sin(time * gl_Color.r)); - change.y = abs(cos(time * gl_Color.g)); - - change = smoothstep(0.0, 1.0, change) * 0.5; - - vec2 tc = gl_TexCoord[0].xy; - tc = smoothstep(0.5 - change, 0.5 + change, tc); - - vec4 tcol = texture2D(tex, tc); - - gl_FragColor = tcol; -} diff --git a/data/shaders/snow.vert b/data/shaders/snow.vert deleted file mode 100644 index d1a121596..000000000 --- a/data/shaders/snow.vert +++ /dev/null @@ -1,8 +0,0 @@ -#version 130 -void main() -{ - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - - gl_FrontColor = gl_Color; -} From 75b492b8718fa7756f0ac781e94c1262b3cfeb09 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:32:38 +0000 Subject: [PATCH 214/412] OGL32CTX: Replace implicitly declared uniforms in bubble git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14984 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/bubble.vert | 5 +++-- src/graphics/callbacks.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/data/shaders/bubble.vert b/data/shaders/bubble.vert index 4b7efd9a2..f216f4f4e 100644 --- a/data/shaders/bubble.vert +++ b/data/shaders/bubble.vert @@ -18,15 +18,16 @@ // Creates a bubble (wave) effect by distorting the texture depending on time #version 130 +uniform mat4 ModelViewProjectionMatrix; uniform float time; out vec2 uv; void main() { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 ); float delta_y = cos(time*2.0) * sin( 3.0 * gl_TexCoord[0].st.t * 6.28318531 ); - uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st + vec2(0.02*delta_x, 0.02*delta_y); + uv = gl_MultiTexCoord0.st + vec2(0.02*delta_x, 0.02*delta_y); } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index ecf1f01cf..176cb7d3a 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -239,6 +239,12 @@ void BubbleEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) const float diff = (time - start) / 3.0f; + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + if (visible) { transparency = diff; From 9a99c3dae67955a4ce2c769fdd4c2005557b63c3 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Thu, 9 Jan 2014 17:32:51 +0000 Subject: [PATCH 215/412] OGL32CTX: Replace implicitly defined uniforms in displace git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14985 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/displace.vert | 7 +++++-- src/graphics/callbacks.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/data/shaders/displace.vert b/data/shaders/displace.vert index 55455cb4f..3e2587249 100644 --- a/data/shaders/displace.vert +++ b/data/shaders/displace.vert @@ -1,13 +1,16 @@ #version 130 +uniform mat4 ModelViewMatrix; +uniform mat4 ProjectionMatrix; out vec2 uv; out vec2 edger_uv; out float camdist; void main() { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + vec4 position = ModelViewMatrix * gl_Vertex; + gl_Position = ProjectionMatrix * position; uv = gl_MultiTexCoord0.xy; edger_uv = gl_MultiTexCoord1.xy; - camdist = length((gl_ModelViewMatrix * gl_Vertex).xyz); + camdist = length(position.xyz); } diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 176cb7d3a..cebfe354d 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -754,6 +754,13 @@ void CausticsProvider::OnSetConstants(IMaterialRendererServices *srv, int) void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + core::matrix4 ModelViewMatrix = srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + + srv->setVertexShaderConstant("ProjectionMatrix", ProjectionMatrix.pointer(), 16); + srv->setVertexShaderConstant("ModelViewMatrix", ModelViewMatrix.pointer(), 16); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; const float speed = World::getWorld()->getTrack()->getDisplacementSpeed(); From e2f636153bc5088583ef5e1ae2de82547a22a9e7 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 9 Jan 2014 22:52:18 +0000 Subject: [PATCH 216/412] Fixed crash #1146 ('install' widgets is removed in case of an installed icon, so m_install was NULL). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14986 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/states_screens/dialogs/addons_loading.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index 41fbb1b87..3b113efa7 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -398,8 +398,8 @@ void AddonsLoading::doUninstall() RibbonWidget* r = getWidget("actions"); r->setVisible(true); - - m_install_button->setLabel(_("Try again")); + IconButtonWidget *u = getWidget ("uninstall" ); + u->setLabel(_("Try again")); } else { From 0566d785b15ec7c9328528c1a2f1353612c44d5f Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 9 Jan 2014 23:03:00 +0000 Subject: [PATCH 217/412] Fix crash when re-trying to delete an addon (that was deleted previously, but had an error). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14987 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/addons/addons_manager.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index 4d50a63c4..d44deafb9 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -463,13 +463,24 @@ bool AddonsManager::uninstall(const Addon &addon) if (file_manager->fileExists(addon.getDataDir())) { error = !file_manager->removeDirectory(addon.getDataDir()); + + // Even if an error happened when removing the data files + // still remove the addon, since it is unknown if e.g. only + // some files were successfully removed. Since we can not + // know if the addon is still functional, better remove it. + // On the other hand, in case of a problem the user will have + // the option in the GUI to try again. In this case + // removeTrack/Kart would not find the addon and assert. So + // check first if the track is still known. if(addon.getType()=="kart") { - kart_properties_manager->removeKart(addon.getId()); + if(kart_properties_manager->getKart(addon.getId())) + kart_properties_manager->removeKart(addon.getId()); } else if(addon.getType()=="track" || addon.getType()=="arena") { - track_manager->removeTrack(addon.getId()); + if(track_manager->getTrack(addon.getId())) + track_manager->removeTrack(addon.getId()); } } saveInstalled(); From ba1e6465ef72fc6932ae644fafde52c4dc6aebb1 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 9 Jan 2014 23:07:01 +0000 Subject: [PATCH 218/412] Fixed #1146 - removing directories didn't work (listFiles() returns absolute paths (now??)). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14988 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/io/file_manager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 765dff7df..11797d6ce 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -1066,8 +1066,7 @@ bool FileManager::removeDirectory(const std::string &name) const if(UserConfigParams::logMisc()) Log::verbose("FileManager", "Deleting directory '%s'.", (*i).c_str()); - std::string full_path=name+"/"+*i; - if(isDirectory(full_path)) + if(isDirectory(*i)) { // This should not be necessary (since this function is only // used to remove addons), and it limits the damage in case @@ -1076,7 +1075,7 @@ bool FileManager::removeDirectory(const std::string &name) const } else { - removeFile(full_path); + removeFile(*i); } } #if defined(WIN32) From 857f675f35a16a983dd2766354afa0ec07702302 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 00:30:56 +0000 Subject: [PATCH 219/412] OGL32CTX: Replace another series of implicit declared uniforms git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14989 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/farplane.vert | 7 +++---- data/shaders/gum_shield.vert | 9 ++++++--- data/shaders/lightbeam.vert | 9 ++++++--- data/shaders/mlaa_color1.frag | 5 +++-- data/shaders/mlaa_neigh3.frag | 7 ++++--- data/shaders/mlaa_offset.vert | 9 ++++++--- data/shaders/skybox.vert | 5 +++-- data/shaders/spheremap.vert | 8 +++++--- src/graphics/callbacks.cpp | 22 ++++++++++++++++++++++ 9 files changed, 58 insertions(+), 23 deletions(-) diff --git a/data/shaders/farplane.vert b/data/shaders/farplane.vert index d6a859a07..1f7bc1fb9 100644 --- a/data/shaders/farplane.vert +++ b/data/shaders/farplane.vert @@ -1,7 +1,6 @@ #version 130 +uniform mat4 ModelViewProjectionMatrix; + void main() { - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; - gl_Position = (gl_ModelViewProjectionMatrix * gl_Vertex).xyww; - gl_FrontColor = gl_Color; + gl_Position = (ModelViewProjectionMatrix * gl_Vertex).xyww; } diff --git a/data/shaders/gum_shield.vert b/data/shaders/gum_shield.vert index 220988a0d..919e01cc7 100644 --- a/data/shaders/gum_shield.vert +++ b/data/shaders/gum_shield.vert @@ -23,18 +23,21 @@ // such that the user gets to know whether the shield has several // "layers" or whether the shield is about to break. #version 130 +uniform mat4 ModelViewMatrix; +uniform mat4 ProjectionMatrix; +uniform mat4 TransposeInverseModelView; out vec2 uv; noperspective out vec3 eyeVec; noperspective out vec3 normal; void main() { - vec4 viewp = gl_ModelViewMatrix * gl_Vertex; + vec4 viewp = ModelViewMatrix * gl_Vertex; eyeVec = normalize(-viewp).xyz; - normal = gl_NormalMatrix * gl_Normal; + normal = (TransposeInverseModelView * vec4(gl_Normal, 1.).xyz; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ProjectionMatrix * viewp; uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; } diff --git a/data/shaders/lightbeam.vert b/data/shaders/lightbeam.vert index 61d6b99ed..3f8837991 100644 --- a/data/shaders/lightbeam.vert +++ b/data/shaders/lightbeam.vert @@ -19,18 +19,21 @@ // Jean-manuel clemencon (C) Copyright supertuxkart // Creates a cone lightbeam effect by smoothing edges #version 130 +uniform mat4 ModelViewMatrix; +uniform mat4 ProjectionMatrix; +uniform mat4 TransposeInverseModelView; out vec2 uv; noperspective out vec3 eyeVec; noperspective out vec3 normal; void main() { - vec4 viewp = gl_ModelViewMatrix * gl_Vertex; + vec4 viewp = ModelViewMatrix * gl_Vertex; eyeVec = normalize(-viewp).xyz; - normal = gl_NormalMatrix * gl_Normal; + normal = (TransposeInverseModelView * vec4(gl_Normal, 1.).xyz; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ProjectionMatrix * viewp; uv = gl_MultiTexCoord0.st; } diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag index 068e13985..52c846425 100644 --- a/data/shaders/mlaa_color1.frag +++ b/data/shaders/mlaa_color1.frag @@ -1,5 +1,6 @@ #version 130 -varying vec4 offset[2]; +in vec4 offset[2]; +in vec2 uv; uniform sampler2D colorMapG; const float threshold = 0.1; @@ -10,7 +11,7 @@ void main() { /** * Luma calculation requires gamma-corrected colors: */ - float L = dot(texture2D(colorMapG, gl_TexCoord[0].xy).rgb, weights); + float L = dot(texture2D(colorMapG, uv).rgb, weights); float Lleft = dot(texture2D(colorMapG, offset[0].xy).rgb, weights); float Ltop = dot(texture2D(colorMapG, offset[0].zw).rgb, weights); float Lright = dot(texture2D(colorMapG, offset[1].xy).rgb, weights); diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag index 28f189015..65984a1c2 100644 --- a/data/shaders/mlaa_neigh3.frag +++ b/data/shaders/mlaa_neigh3.frag @@ -1,12 +1,13 @@ #version 130 -varying vec4 offset[2]; +in vec4 offset[2]; +in vec2 uv; uniform sampler2D blendMap; uniform sampler2D colorMap; void main() { // Fetch the blending weights for current pixel: - vec4 topLeft = texture2D(blendMap, gl_TexCoord[0].xy); + vec4 topLeft = texture2D(blendMap, uv); float bottom = texture2D(blendMap, offset[1].zw).g; float right = texture2D(blendMap, offset[1].xy).a; vec4 a = vec4(topLeft.r, bottom, topLeft.b, right); @@ -24,7 +25,7 @@ void main() { vec4 color = vec4(0.0); // Add the contributions of the possible 4 lines that can cross this pixel: - vec4 C = texture2D(colorMap, gl_TexCoord[0].xy); + vec4 C = texture2D(colorMap, uv); vec4 Cleft = texture2D(colorMap, offset[0].xy); vec4 Ctop = texture2D(colorMap, offset[0].zw); vec4 Cright = texture2D(colorMap, offset[1].xy); diff --git a/data/shaders/mlaa_offset.vert b/data/shaders/mlaa_offset.vert index ecf0c3649..6725e19e6 100644 --- a/data/shaders/mlaa_offset.vert +++ b/data/shaders/mlaa_offset.vert @@ -1,12 +1,15 @@ #version 130 -varying vec4 offset[2]; uniform vec2 PIXEL_SIZE; +uniform mat4 ModelViewProjectionMatrix; + +out vec4 offset[2]; +out vec2 uv; void main() { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; vec4 invy = gl_MultiTexCoord0; // invy.y = 1.0 - invy.y; - gl_TexCoord[0] = invy; + uv = invy.st; offset[0] = invy.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, 1.0); offset[1] = invy.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, -1.0); diff --git a/data/shaders/skybox.vert b/data/shaders/skybox.vert index 6bc0ea519..1db3a3480 100644 --- a/data/shaders/skybox.vert +++ b/data/shaders/skybox.vert @@ -18,6 +18,7 @@ // Creates a bubble (wave) effect by distorting the texture depending on time #version 130 +uniform mat4 ModelViewProjectionMatrix; uniform float time; out vec2 uv; @@ -30,8 +31,8 @@ out vec3 vertex; void main() { - uv = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + uv = gl_MultiTexCoord0.st; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; float delta_x = cos(time*3.0) * sin( 4.0 * gl_TexCoord[0].st.s * 6.28318531 ); diff --git a/data/shaders/spheremap.vert b/data/shaders/spheremap.vert index a0b829c8b..175568130 100644 --- a/data/shaders/spheremap.vert +++ b/data/shaders/spheremap.vert @@ -16,6 +16,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #version 130 +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; uniform vec3 lightdir; noperspective out vec3 normal; @@ -25,7 +27,7 @@ noperspective out vec3 lightVec; void main() { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; vertex_color = gl_Color; //vec3 normal3 = normalize(gl_Normal); @@ -33,11 +35,11 @@ void main() //normal = normal4.xyz; eyeVec = normalize(-gl_Position).xyz; // we are in Eye Coordinates, so EyePos is (0,0,0) - normal = normalize(gl_NormalMatrix*gl_Normal); + normal = normalize((TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz); // Building the matrix Eye Space -> Tangent Space // gl_MultiTexCoord1.xyz - vec3 t = normalize (gl_NormalMatrix * vec3(0.0, 0.0, 1.0)); // tangent + vec3 t = normalize ((TransposeInverseModelView * vec4(0.0, 0.0, 1.0, 1.)).xyz); // tangent vec3 b = cross (normal, t); // transform light and half angle vectors by tangent basis diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index cebfe354d..68b2510ca 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -182,6 +182,11 @@ void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int) vector3df sun_pos = m_sunpos; srv->setVertexShaderConstant("sun_pos", &sun_pos.X, 3); + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + if (!firstdone) { s32 tex = 0; @@ -357,6 +362,11 @@ void MipVizProvider::OnSetConstants(IMaterialRendererServices *srv, int) void ColorizeProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); srv->setVertexShaderConstant("col", m_color, 3); } @@ -498,6 +508,12 @@ void BloomProvider::OnSetConstants(IMaterialRendererServices *srv, int) void MLAAColor1Provider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + if (!firstdone) { const float pixels[2] = { @@ -540,6 +556,12 @@ void MLAABlend2Provider::OnSetConstants(IMaterialRendererServices *srv, int) void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + if (!firstdone) { const float pixels[2] = { From 90f701c42dbf263086ca494d2d3ee15f174a2041 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 00:31:22 +0000 Subject: [PATCH 220/412] OGL32CTX: Attempt to replace implicitly defined uniforms for objectpass This breaks animated textures in xr591... git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14990 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/objectpass.frag | 15 +++++++++------ data/shaders/objectpass.vert | 17 ++++++++++++----- data/shaders/objectpass_ref.frag | 4 +++- src/graphics/callbacks.cpp | 13 +++++++++++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag index d90250cc2..81d5d9962 100644 --- a/data/shaders/objectpass.frag +++ b/data/shaders/objectpass.frag @@ -5,22 +5,25 @@ uniform int hastex; uniform int haslightmap; noperspective in vec3 nor; +in vec4 color; +in vec2 uv0; +in vec2 uv1; void main() { vec4 light = vec4(1.0); - vec4 color; + vec4 col; if (haslightmap != 0) { - light = texture2D(lighttex, gl_TexCoord[1].xy); + light = texture2D(lighttex, uv1); } if (hastex != 0) - color = texture2D(tex, gl_TexCoord[0].xy) * light; + col = texture2D(tex, uv0) * light; else - color = gl_Color; + col = color; - gl_FragData[0] = vec4(color.xyz, 1.); + gl_FragData[0] = vec4(col.xyz, 1.); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - color.a); + gl_FragData[2] = vec4(1. - col.a); } diff --git a/data/shaders/objectpass.vert b/data/shaders/objectpass.vert index a070c3ee3..ced95ae19 100644 --- a/data/shaders/objectpass.vert +++ b/data/shaders/objectpass.vert @@ -1,12 +1,19 @@ #version 130 +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; +uniform mat4 TextureMatrix0; +uniform mat4 TextureMatrix1; noperspective out vec3 nor; +out vec4 color; +out vec2 uv0; +out vec2 uv1; void main() { - nor = gl_NormalMatrix * gl_Normal; - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - gl_FrontColor = gl_Color; + nor = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; + uv0 = (TextureMatrix0 * gl_MultiTexCoord0).st; + uv1 = (TextureMatrix1 * gl_MultiTexCoord1).st; + gl_Position = ModelViewProjectionMatrix * gl_Vertex; + color = gl_Color; } diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag index 67071d4e0..62f9f57bc 100644 --- a/data/shaders/objectpass_ref.frag +++ b/data/shaders/objectpass_ref.frag @@ -4,11 +4,13 @@ uniform int hastex; uniform float objectid; noperspective in vec3 nor; +in vec2 uv0; +in vec2 uv1; void main() { //if (hastex != 0) { - vec4 col = texture2D(tex, gl_TexCoord[0].xy); + vec4 col = texture2D(tex, uv0); if (col.a < 0.5) discard; diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 68b2510ca..5cdb2188d 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -381,6 +381,19 @@ void GlowProvider::OnSetConstants(IMaterialRendererServices *srv, int) void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int) { + core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); + ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); + core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW); + TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); + srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); + srv->setVertexShaderConstant("TextureMatrix0", mat.getTextureMatrix(0).pointer(), 16); + srv->setVertexShaderConstant("TextureMatrix1", mat.getTextureMatrix(1).pointer(), 16); + const int hastex = mat.TextureLayer[0].Texture != NULL; srv->setVertexShaderConstant("hastex", &hastex, 1); From 0a50518fb9c3b9b77160bd616456221ab39b7096 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 00:59:15 +0000 Subject: [PATCH 221/412] Remove code loading snow shaders. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14991 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/shaders.cpp | 4 ---- src/graphics/shaders.hpp | 1 - 2 files changed, 5 deletions(-) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 41b03f049..5656ca5b4 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -41,7 +41,6 @@ Shaders::Shaders() m_callbacks[ES_COLOR_LEVELS] = new ColorLevelsProvider(); m_callbacks[ES_BUBBLES] = new BubbleEffectProvider(); m_callbacks[ES_RAIN] = new RainEffectProvider(); - m_callbacks[ES_SNOW] = new SnowEffectProvider(); m_callbacks[ES_MOTIONBLUR] = new MotionBlurProvider(); m_callbacks[ES_GAUSSIAN3V] = m_callbacks[ES_GAUSSIAN3H] = new GaussianBlurProvider(); m_callbacks[ES_MIPVIZ] = new MipVizProvider(); @@ -120,9 +119,6 @@ void Shaders::loadShaders() m_shaders[ES_RAIN] = glslmat(dir + "rain.vert", dir + "rain.frag", m_callbacks[ES_RAIN], EMT_TRANSPARENT_ALPHA_CHANNEL); - m_shaders[ES_SNOW] = glslmat(dir + "snow.vert", dir + "snow.frag", - m_callbacks[ES_SNOW], EMT_TRANSPARENT_ALPHA_CHANNEL); - m_shaders[ES_MOTIONBLUR] = glsl(std::string(""), dir + "motion_blur.frag", m_callbacks[ES_MOTIONBLUR]); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index a3fdd5439..285363cf6 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -34,7 +34,6 @@ using namespace irr; ACT(ES_GRASS_REF) \ ACT(ES_BUBBLES) \ ACT(ES_RAIN) \ - ACT(ES_SNOW) \ ACT(ES_MOTIONBLUR) \ ACT(ES_GAUSSIAN3H) \ ACT(ES_GAUSSIAN3V) \ From 45067e59cfc0ebc6fe0850dc9d88e25ad710f083 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 01:29:32 +0000 Subject: [PATCH 222/412] OGL32CTX: Revert to use gl_TextureMatrix[] git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14992 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/objectpass.vert | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shaders/objectpass.vert b/data/shaders/objectpass.vert index ced95ae19..f40e32215 100644 --- a/data/shaders/objectpass.vert +++ b/data/shaders/objectpass.vert @@ -12,8 +12,8 @@ out vec2 uv1; void main() { nor = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; - uv0 = (TextureMatrix0 * gl_MultiTexCoord0).st; - uv1 = (TextureMatrix1 * gl_MultiTexCoord1).st; + uv0 = (gl_TextureMatrix[0] * gl_MultiTexCoord0).st; + uv1 = (gl_TextureMatrix[1] * gl_MultiTexCoord1).st; gl_Position = ModelViewProjectionMatrix * gl_Vertex; color = gl_Color; } From af81015fcd7cbddc6d44a688937660d7efa1f1a6 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 17:26:57 +0000 Subject: [PATCH 223/412] GPUParticles: Use different shaders to avoid unneeded uniforms. Heightmap affector is temporarly disabled. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14993 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/flipparticle.vert | 61 ++++++++++++++++++++++++++++ data/shaders/particle.vert | 73 ++-------------------------------- 2 files changed, 64 insertions(+), 70 deletions(-) create mode 100644 data/shaders/flipparticle.vert diff --git a/data/shaders/flipparticle.vert b/data/shaders/flipparticle.vert new file mode 100644 index 000000000..150f52b3c --- /dev/null +++ b/data/shaders/flipparticle.vert @@ -0,0 +1,61 @@ +#version 140 +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrix; + +in vec2 quadcorner; +in vec2 texcoord; +in vec3 position; +in float lifetime; +in float size; + +in vec3 rotationvec; +in float anglespeed; + +out float lf; +out vec2 tc; + +void main(void) +{ + tc = texcoord; + lf = lifetime; + vec3 newposition = position; + + // from http://jeux.developpez.com/faq/math + float angle = lf * anglespeed; + float sin_a = sin(angle / 2.); + float cos_a = cos(angle / 2.); + + vec4 quaternion = normalize(vec4(rotationvec * sin_a, cos_a)); + float xx = quaternion.x * quaternion.x; + float xy = quaternion.x * quaternion.y; + float xz = quaternion.x * quaternion.z; + float xw = quaternion.x * quaternion.w; + float yy = quaternion.y * quaternion.y; + float yz = quaternion.y * quaternion.z; + float yw = quaternion.y * quaternion.w; + float zz = quaternion.z * quaternion.z; + float zw = quaternion.z * quaternion.w; + + vec4 col1 = vec4( + 1. - 2. * ( yy + zz ), + 2. * ( xy + zw ), + 2. * ( xz - yw ), + 0.); + vec4 col2 = vec4( + 2. * ( xy - zw ), + 1. - 2. * ( xx + zz ), + 2. * ( yz + xw ), + 0.); + vec4 col3 = vec4( + 2. * ( xz + yw ), + 2. * ( yz - xw ), + 1. - 2. * ( xx + yy ), + 0.); + vec4 col4 = vec4(0., 0., 0., 1.); + mat4 rotationMatrix = mat4(col1, col2, col3, col4); + vec3 newquadcorner = size * vec3(quadcorner, 0.); + newquadcorner = (rotationMatrix * vec4(newquadcorner, 0.)).xyz; + + vec4 viewpos = ViewMatrix * vec4(newposition + newquadcorner, 1.0); + gl_Position = ProjectionMatrix * viewpos; +} diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index b7c7a366d..d2d6ee63b 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,13 +1,6 @@ #version 140 uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; -uniform float track_x; -uniform float track_z; -uniform float track_x_len; -uniform float track_z_len; -uniform samplerBuffer heightmap; -uniform bool hasHeightMap; -uniform bool flips; in vec2 quadcorner; in vec2 texcoord; @@ -15,9 +8,6 @@ in vec3 position; in float lifetime; in float size; -in vec3 rotationvec; -in float anglespeed; - out float lf; out vec2 tc; @@ -26,65 +16,8 @@ void main(void) tc = texcoord; lf = lifetime; vec3 newposition = position; - - float i_as_float = clamp(256. * (position.x - track_x) / track_x_len, 0., 255.); - float j_as_float = clamp(256. * (position.z - track_z) / track_z_len, 0., 255.); - int i = int(i_as_float); - int j = int(j_as_float); - - if (hasHeightMap) { - float h = position.y - texelFetch(heightmap, i * 256 + j).r; - newposition.y = (h > 0.)? position.y : 1000.; - } - - if (flips) - { - // from http://jeux.developpez.com/faq/math - float angle = lf * anglespeed; - float sin_a = sin(angle / 2.); - float cos_a = cos(angle / 2.); - - vec4 quaternion = normalize(vec4(rotationvec * sin_a, cos_a)); - - float xx = quaternion.x * quaternion.x; - float xy = quaternion.x * quaternion.y; - float xz = quaternion.x * quaternion.z; - float xw = quaternion.x * quaternion.w; - - float yy = quaternion.y * quaternion.y; - float yz = quaternion.y * quaternion.z; - float yw = quaternion.y * quaternion.w; - - float zz = quaternion.z * quaternion.z; - float zw = quaternion.z * quaternion.w; - - vec4 col1 = vec4( - 1. - 2. * ( yy + zz ), - 2. * ( xy + zw ), - 2. * ( xz - yw ), - 0.); - vec4 col2 = vec4( - 2. * ( xy - zw ), - 1. - 2. * ( xx + zz ), - 2. * ( yz + xw ), - 0.); - vec4 col3 = vec4( - 2. * ( xz + yw ), - 2. * ( yz - xw ), - 1. - 2. * ( xx + yy ), - 0.); - vec4 col4 = vec4(0., 0., 0., 1.); - mat4 rotationMatrix = mat4(col1, col2, col3, col4); - vec3 newquadcorner = size * vec3(quadcorner, 0.); - newquadcorner = (rotationMatrix * vec4(newquadcorner, 0.)).xyz; - - vec4 viewpos = ViewMatrix * vec4(newposition + newquadcorner, 1.0); - gl_Position = ProjectionMatrix * viewpos; - } else { - vec4 viewpos = ViewMatrix * vec4(newposition, 1.0); - viewpos += size * vec4(quadcorner, 0., 0.); - gl_Position = ProjectionMatrix * viewpos; - } - + vec4 viewpos = ViewMatrix * vec4(newposition, 1.0); + viewpos += size * vec4(quadcorner, 0., 0.); + gl_Position = ProjectionMatrix * viewpos; } From ba61e2cbe4fcdddeee3350c00ecae69c2ebafbaa Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 17:40:25 +0000 Subject: [PATCH 224/412] GPUParticles: Finish refactorisation. Heightmap are enabled again for snow. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14994 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/particlesimheightmap.vert | 50 +++ src/graphics/gpuparticles.cpp | 558 +++++++++++++++++-------- src/graphics/gpuparticles.h | 14 +- 3 files changed, 429 insertions(+), 193 deletions(-) create mode 100644 data/shaders/particlesimheightmap.vert diff --git a/data/shaders/particlesimheightmap.vert b/data/shaders/particlesimheightmap.vert new file mode 100644 index 000000000..e74663c8f --- /dev/null +++ b/data/shaders/particlesimheightmap.vert @@ -0,0 +1,50 @@ +#version 130 +uniform int dt; +uniform mat4 sourcematrix; +uniform int level; +uniform float size_increase_factor; + +uniform float track_x; +uniform float track_z; +uniform float track_x_len; +uniform float track_z_len; +uniform samplerBuffer heightmap; + +in vec3 particle_position_initial; +in float lifetime_initial; +in vec3 particle_velocity_initial; +in float size_initial; + +in vec3 particle_position; +in float lifetime; +in vec3 particle_velocity; +in float size; + +out vec3 new_particle_position; +out float new_lifetime; +out vec3 new_particle_velocity; +out float new_size; + +void main(void) +{ + bool reset = false; + + float i_as_float = clamp(256. * (particle_position.x - track_x) / track_x_len, 0., 255.); + float j_as_float = clamp(256. * (particle_position.z - track_z) / track_z_len, 0., 255.); + int i = int(i_as_float); + int j = int(j_as_float); + + float h = particle_position.y - texelFetch(heightmap, i * 256 + j).r; + reset = h < 0.; + + vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); + vec4 adjusted_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - initialposition; + float adjusted_lifetime = lifetime + (float(dt)/lifetime_initial); + reset = reset || (adjusted_lifetime > 1.) && (gl_VertexID <= level); + reset = reset || (lifetime < 0.); + new_particle_position = !reset ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; + new_lifetime = !reset ? adjusted_lifetime : 0.; + new_particle_velocity = !reset ? particle_velocity : adjusted_initial_velocity.xyz; + new_size = !reset ? mix(size_initial, size_initial * size_increase_factor, adjusted_lifetime) : size_initial; + gl_Position = vec4(0.); +} diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 9a119cd6e..3c3a7fc61 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -11,6 +11,133 @@ GLuint getTextureGLuint(irr::video::ITexture *tex) { #define COMPONENTCOUNT 8 + +namespace SimpleSimulationShader +{ + GLuint Program; + GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; + GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; + + void init() + { + initGL(); + const char *varyings[] = { + "new_particle_position", + "new_lifetime", + "new_particle_velocity", + "new_size", + }; + Program = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 4); + + uniform_dt = glGetUniformLocation(Program, "dt"); + uniform_sourcematrix = glGetUniformLocation(Program, "sourcematrix"); + uniform_level = glGetUniformLocation(Program, "level"); + uniform_size_increase_factor = glGetUniformLocation(Program, "size_increase_factor"); + + attrib_position = glGetAttribLocation(Program, "particle_position"); + attrib_lifetime = glGetAttribLocation(Program, "lifetime"); + attrib_velocity = glGetAttribLocation(Program, "particle_velocity"); + attrib_size = glGetAttribLocation(Program, "size"); + attrib_initial_position = glGetAttribLocation(Program, "particle_position_initial"); + attrib_initial_lifetime = glGetAttribLocation(Program, "lifetime_initial"); + attrib_initial_velocity = glGetAttribLocation(Program, "particle_velocity_initial"); + attrib_initial_size = glGetAttribLocation(Program, "size_initial"); + } +} + +namespace HeightmapSimulationShader +{ + GLuint Program; + GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; + GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; + GLuint uniform_track_x, uniform_track_z, uniform_track_x_len, uniform_track_z_len, uniform_heightmap; + + void init() + { + initGL(); + const char *varyings[] = { + "new_particle_position", + "new_lifetime", + "new_particle_velocity", + "new_size", + }; + Program = LoadTFBProgram(file_manager->getAsset("shaders/particlesimheightmap.vert").c_str(), varyings, 4); + + uniform_dt = glGetUniformLocation(Program, "dt"); + uniform_sourcematrix = glGetUniformLocation(Program, "sourcematrix"); + uniform_level = glGetUniformLocation(Program, "level"); + uniform_size_increase_factor = glGetUniformLocation(Program, "size_increase_factor"); + + attrib_position = glGetAttribLocation(Program, "particle_position"); + attrib_lifetime = glGetAttribLocation(Program, "lifetime"); + attrib_velocity = glGetAttribLocation(Program, "particle_velocity"); + attrib_size = glGetAttribLocation(Program, "size"); + attrib_initial_position = glGetAttribLocation(Program, "particle_position_initial"); + attrib_initial_lifetime = glGetAttribLocation(Program, "lifetime_initial"); + attrib_initial_velocity = glGetAttribLocation(Program, "particle_velocity_initial"); + attrib_initial_size = glGetAttribLocation(Program, "size_initial"); + + uniform_heightmap = glGetUniformLocation(Program, "heightmap"); + uniform_track_x = glGetUniformLocation(Program, "track_x"); + uniform_track_x_len = glGetUniformLocation(Program, "track_x_len"); + uniform_track_z = glGetUniformLocation(Program, "track_z"); + uniform_track_z_len = glGetUniformLocation(Program, "track_z_len"); + } +} + +namespace SimpleParticleRender +{ + GLuint Program; + GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; + GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); + attrib_pos = glGetAttribLocation(Program, "position"); + attrib_sz = glGetAttribLocation(Program, "size"); + attrib_lf = glGetAttribLocation(Program, "lifetime"); + attrib_quadcorner = glGetAttribLocation(Program, "quadcorner"); + attrib_texcoord = glGetAttribLocation(Program, "texcoord"); + + + uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix"); + uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix"); + uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_invproj = glGetUniformLocation(Program, "invproj"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_normal_and_depths = glGetUniformLocation(Program, "normals_and_depth"); + } +} + +namespace FlipParticleRender +{ + GLuint Program; + GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz, attrib_rotationvec, attrib_anglespeed; + GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/flipparticle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); + attrib_pos = glGetAttribLocation(Program, "position"); + attrib_sz = glGetAttribLocation(Program, "size"); + attrib_lf = glGetAttribLocation(Program, "lifetime"); + attrib_quadcorner = glGetAttribLocation(Program, "quadcorner"); + attrib_texcoord = glGetAttribLocation(Program, "texcoord"); + attrib_anglespeed = glGetAttribLocation(Program, "anglespeed"); + attrib_rotationvec = glGetAttribLocation(Program, "rotationvec"); + + uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix"); + uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix"); + uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_invproj = glGetUniformLocation(Program, "invproj"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_normal_and_depths = glGetUniformLocation(Program, "normals_and_depth"); + } +} + GPUParticle::GPUParticle(scene::ISceneNode *parent, scene::ISceneManager* mgr, ITexture *tex) : scene::ISceneNode(parent, mgr, -1) { initGL(); @@ -109,7 +236,23 @@ void ParticleSystemProxy::setAlphaAdditive(bool val) { m_alpha_additive = val; } void ParticleSystemProxy::setIncreaseFactor(float val) { size_increase_factor = val; } void ParticleSystemProxy::setFlip() { - flip = true; + flip = true; + float *quaternions = new float[4 * count]; + for (unsigned i = 0; i < count; i++) + { + core::vector3df rotationdir(0., 1., 0.); + /*rotationdir.rotateXYBy(os::Randomizer::frand() * 180.); + rotationdir.rotateYZBy(os::Randomizer::frand() * 180.); + rotationdir.rotateXZBy(os::Randomizer::frand() * 180.);*/ + quaternions[4 * i] = rotationdir.X; + quaternions[4 * i + 1] = rotationdir.Y; + quaternions[4 * i + 2] = rotationdir.Z; + quaternions[4 * i + 3] = 3.14 * 3. * (2. * os::Randomizer::frand() - 1.); // 3 half rotation during lifetime at max + } + glGenBuffers(1, &quaternionsbuffer); + glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer); + glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STATIC_DRAW); + delete[] quaternions; } void ParticleSystemProxy::setHeightmap(const std::vector > &hm, @@ -266,44 +409,6 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph delete[] initialvalue; } -GLuint ParticleSystemProxy::SimulationProgram = 0; -GLuint ParticleSystemProxy::RenderProgram = 0; - -GLuint ParticleSystemProxy::attrib_position; -GLuint ParticleSystemProxy::attrib_velocity; -GLuint ParticleSystemProxy::attrib_lifetime; -GLuint ParticleSystemProxy::attrib_initial_position; -GLuint ParticleSystemProxy::attrib_initial_velocity; -GLuint ParticleSystemProxy::attrib_initial_lifetime; -GLuint ParticleSystemProxy::attrib_size; -GLuint ParticleSystemProxy::attrib_initial_size; -GLuint ParticleSystemProxy::uniform_sourcematrix; -GLuint ParticleSystemProxy::uniform_dt; -GLuint ParticleSystemProxy::uniform_level; -GLuint ParticleSystemProxy::uniform_size_increase_factor; -GLuint ParticleSystemProxy::uniform_has_heightmap; -GLuint ParticleSystemProxy::uniform_heightmap; -GLuint ParticleSystemProxy::uniform_track_x; -GLuint ParticleSystemProxy::uniform_track_x_len; -GLuint ParticleSystemProxy::uniform_track_z; -GLuint ParticleSystemProxy::uniform_track_z_len; -GLuint ParticleSystemProxy::uniform_flips; - - -GLuint ParticleSystemProxy::attrib_pos; -GLuint ParticleSystemProxy::attrib_lf; -GLuint ParticleSystemProxy::attrib_quadcorner; -GLuint ParticleSystemProxy::attrib_texcoord; -GLuint ParticleSystemProxy::attrib_sz; -GLuint ParticleSystemProxy::attrib_rotationvec; -GLuint ParticleSystemProxy::attrib_anglespeed; -GLuint ParticleSystemProxy::uniform_matrix; -GLuint ParticleSystemProxy::uniform_viewmatrix; -GLuint ParticleSystemProxy::uniform_texture; -GLuint ParticleSystemProxy::uniform_normal_and_depths; -GLuint ParticleSystemProxy::uniform_screen; -GLuint ParticleSystemProxy::uniform_invproj; - static bool isGPUParticleType(scene::E_PARTICLE_EMITTER_TYPE type) { switch (type) @@ -345,80 +450,20 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) assert(0 && "Wrong particle type"); } - float *quaternions = new float[4 * count]; - for (unsigned i = 0; i < count; i++) - { - core::vector3df rotationdir(0., 1., 0.); - /*rotationdir.rotateXYBy(os::Randomizer::frand() * 180.); - rotationdir.rotateYZBy(os::Randomizer::frand() * 180.); - rotationdir.rotateXZBy(os::Randomizer::frand() * 180.);*/ - quaternions[4 * i] = rotationdir.X; - quaternions[4 * i + 1] = rotationdir.Y; - quaternions[4 * i + 2] = rotationdir.Z; - quaternions[4 * i + 3] = 3.14 * 3. * ( 2. * os::Randomizer::frand() - 1.); // 3 half rotation during lifetime at max - } - glGenBuffers(1, &quaternionsbuffer); - glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer); - glBufferData(GL_ARRAY_BUFFER, 4 * count * sizeof(float), quaternions, GL_STATIC_DRAW); - delete[] quaternions; - glBindBuffer(GL_ARRAY_BUFFER, 0); texture = getTextureGLuint(getMaterial(0).getTexture(0)); normal_and_depth = getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - if (SimulationProgram && RenderProgram) + if (SimpleSimulationShader::Program && SimpleParticleRender::Program && FlipParticleRender::Program && HeightmapSimulationShader::Program) return; - - const char *varyings[] = { - "new_particle_position", - "new_lifetime", - "new_particle_velocity", - "new_size", - }; - - SimulationProgram = LoadTFBProgram(file_manager->getAsset("shaders/pointemitter.vert").c_str(), varyings, 4); - - uniform_dt = glGetUniformLocation(SimulationProgram, "dt"); - uniform_sourcematrix = glGetUniformLocation(SimulationProgram, "sourcematrix"); - uniform_level = glGetUniformLocation(SimulationProgram, "level"); - uniform_size_increase_factor = glGetUniformLocation(SimulationProgram, "size_increase_factor"); - - attrib_position = glGetAttribLocation(SimulationProgram, "particle_position"); - attrib_lifetime = glGetAttribLocation(SimulationProgram, "lifetime"); - attrib_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity"); - attrib_size = glGetAttribLocation(SimulationProgram, "size"); - attrib_initial_position = glGetAttribLocation(SimulationProgram, "particle_position_initial"); - attrib_initial_lifetime = glGetAttribLocation(SimulationProgram, "lifetime_initial"); - attrib_initial_velocity = glGetAttribLocation(SimulationProgram, "particle_velocity_initial"); - attrib_initial_size = glGetAttribLocation(SimulationProgram, "size_initial"); - - RenderProgram = LoadProgram(file_manager->getAsset("shaders/particle.vert").c_str(), file_manager->getAsset("shaders/particle.frag").c_str()); - attrib_pos = glGetAttribLocation(RenderProgram, "position"); - attrib_sz = glGetAttribLocation(RenderProgram, "size"); - attrib_lf = glGetAttribLocation(RenderProgram, "lifetime"); - attrib_quadcorner = glGetAttribLocation(RenderProgram, "quadcorner"); - attrib_texcoord = glGetAttribLocation(RenderProgram, "texcoord"); - attrib_rotationvec = glGetAttribLocation(RenderProgram, "rotationvec"); - attrib_anglespeed = glGetAttribLocation(RenderProgram, "anglespeed"); - - - uniform_matrix = glGetUniformLocation(RenderProgram, "ProjectionMatrix"); - uniform_viewmatrix = glGetUniformLocation(RenderProgram, "ViewMatrix"); - uniform_texture = glGetUniformLocation(RenderProgram, "texture"); - uniform_invproj = glGetUniformLocation(RenderProgram, "invproj"); - uniform_screen = glGetUniformLocation(RenderProgram, "screen"); - uniform_normal_and_depths = glGetUniformLocation(RenderProgram, "normals_and_depth"); - uniform_has_heightmap = glGetUniformLocation(RenderProgram, "hasHeightMap"); - uniform_heightmap = glGetUniformLocation(RenderProgram, "heightmap"); - uniform_track_x = glGetUniformLocation(RenderProgram, "track_x"); - uniform_track_x_len = glGetUniformLocation(RenderProgram, "track_x_len"); - uniform_track_z = glGetUniformLocation(RenderProgram, "track_z"); - uniform_track_z_len = glGetUniformLocation(RenderProgram, "track_z_len"); - uniform_flips = glGetUniformLocation(RenderProgram, "flips"); + SimpleSimulationShader::init(); + HeightmapSimulationShader::init(); + SimpleParticleRender::init(); + FlipParticleRender::init(); } -void ParticleSystemProxy::simulate() +void ParticleSystemProxy::simulateHeightmap() { unsigned time = os::Timer::getTime(); if (LastEmitTime == 0) @@ -431,50 +476,120 @@ void ParticleSystemProxy::simulate() LastEmitTime = time; int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); - glUseProgram(SimulationProgram); + glUseProgram(HeightmapSimulationShader::Program); glEnable(GL_RASTERIZER_DISCARD); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_lifetime); - glEnableVertexAttribArray(attrib_velocity); - glEnableVertexAttribArray(attrib_size); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_position); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_lifetime); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_velocity); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_size); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); - glVertexAttribPointer(attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); - glVertexAttribPointer(attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); - glEnableVertexAttribArray(attrib_initial_position); - glEnableVertexAttribArray(attrib_initial_lifetime); - glEnableVertexAttribArray(attrib_initial_velocity); - glEnableVertexAttribArray(attrib_initial_size); + glVertexAttribPointer(HeightmapSimulationShader::attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(HeightmapSimulationShader::attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(HeightmapSimulationShader::attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(HeightmapSimulationShader::attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_position); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_lifetime); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_velocity); + glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_size); glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); - glVertexAttribPointer(attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); - glVertexAttribPointer(attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribPointer(attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); - glVertexAttribPointer(attrib_initial_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); + glVertexAttribPointer(HeightmapSimulationShader::attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(HeightmapSimulationShader::attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(HeightmapSimulationShader::attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(HeightmapSimulationShader::attrib_initial_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); - glUniform1i(uniform_dt, timediff); - glUniform1i(uniform_level, active_count); - glUniformMatrix4fv(uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); - glUniform1f(uniform_size_increase_factor, size_increase_factor); + glUniform1i(HeightmapSimulationShader::uniform_dt, timediff); + glUniform1i(HeightmapSimulationShader::uniform_level, active_count); + glUniformMatrix4fv(HeightmapSimulationShader::uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); + glUniform1f(HeightmapSimulationShader::uniform_size_increase_factor, size_increase_factor); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture); + glUniform1i(HeightmapSimulationShader::uniform_heightmap, 2); + glUniform1f(HeightmapSimulationShader::uniform_track_x, track_x); + glUniform1f(HeightmapSimulationShader::uniform_track_z, track_z); + glUniform1f(HeightmapSimulationShader::uniform_track_x_len, track_x_len); + glUniform1f(HeightmapSimulationShader::uniform_track_z_len, track_z_len); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, count); glEndTransformFeedback(); - glDisableVertexAttribArray(attrib_position); - glDisableVertexAttribArray(attrib_lifetime); - glDisableVertexAttribArray(attrib_velocity); - glDisableVertexAttribArray(attrib_size); - glDisableVertexAttribArray(attrib_initial_position); - glDisableVertexAttribArray(attrib_initial_lifetime); - glDisableVertexAttribArray(attrib_initial_velocity); - glDisableVertexAttribArray(attrib_initial_size); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_position); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_lifetime); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_velocity); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_size); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_position); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_lifetime); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_velocity); + glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_size); glDisable(GL_RASTERIZER_DISCARD); std::swap(tfb_buffers[0], tfb_buffers[1]); - } -void ParticleSystemProxy::draw() +void ParticleSystemProxy::simulateNoHeightmap() +{ + + unsigned time = os::Timer::getTime(); + if (LastEmitTime == 0) + { + LastEmitTime = time; + return; + } + + u32 timediff = time - LastEmitTime; + LastEmitTime = time; + int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; + core::matrix4 matrix = getAbsoluteTransformation(); + glUseProgram(SimpleSimulationShader::Program); + glEnable(GL_RASTERIZER_DISCARD); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_position); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_lifetime); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_velocity); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_size); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glVertexAttribPointer(SimpleSimulationShader::attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(SimpleSimulationShader::attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(SimpleSimulationShader::attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(SimpleSimulationShader::attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_initial_position); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_initial_lifetime); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_initial_velocity); + glEnableVertexAttribArray(SimpleSimulationShader::attrib_initial_size); + glBindBuffer(GL_ARRAY_BUFFER, initial_values_buffer); + glVertexAttribPointer(SimpleSimulationShader::attrib_initial_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); + glVertexAttribPointer(SimpleSimulationShader::attrib_initial_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); + glVertexAttribPointer(SimpleSimulationShader::attrib_initial_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); + glVertexAttribPointer(SimpleSimulationShader::attrib_initial_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfb_buffers[1]); + + glUniform1i(SimpleSimulationShader::uniform_dt, timediff); + glUniform1i(SimpleSimulationShader::uniform_level, active_count); + glUniformMatrix4fv(SimpleSimulationShader::uniform_sourcematrix, 1, GL_FALSE, matrix.pointer()); + glUniform1f(SimpleSimulationShader::uniform_size_increase_factor, size_increase_factor); + + glBeginTransformFeedback(GL_POINTS); + glDrawArrays(GL_POINTS, 0, count); + glEndTransformFeedback(); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_position); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_lifetime); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_velocity); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_size); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_initial_position); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_initial_lifetime); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_initial_velocity); + glDisableVertexAttribArray(SimpleSimulationShader::attrib_initial_size); + glDisable(GL_RASTERIZER_DISCARD); + std::swap(tfb_buffers[0], tfb_buffers[1]); +} + +void ParticleSystemProxy::simulate() +{ + if (has_height_map) + simulateHeightmap(); + else + simulateNoHeightmap(); +} + +void ParticleSystemProxy::drawFlip() { glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); @@ -484,74 +599,151 @@ void ParticleSystemProxy::draw() glBlendFunc(GL_SRC_ALPHA, GL_ONE); else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(RenderProgram); - glEnableVertexAttribArray(attrib_pos); - glEnableVertexAttribArray(attrib_lf); - glEnableVertexAttribArray(attrib_quadcorner); - glEnableVertexAttribArray(attrib_texcoord); - glEnableVertexAttribArray(attrib_sz); - + glUseProgram(FlipParticleRender::Program); + glEnableVertexAttribArray(FlipParticleRender::attrib_pos); + glEnableVertexAttribArray(FlipParticleRender::attrib_lf); + glEnableVertexAttribArray(FlipParticleRender::attrib_quadcorner); + glEnableVertexAttribArray(FlipParticleRender::attrib_texcoord); + glEnableVertexAttribArray(FlipParticleRender::attrib_sz); + float screen[2] = { (float)UserConfigParams::m_width, (float)UserConfigParams::m_height }; - bindUniformToTextureUnit(uniform_texture, texture, 0); - bindUniformToTextureUnit(uniform_normal_and_depths, normal_and_depth, 1); + bindUniformToTextureUnit(FlipParticleRender::uniform_texture, texture, 0); + bindUniformToTextureUnit(FlipParticleRender::uniform_normal_and_depths, normal_and_depth, 1); - glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); - glUniform2f(uniform_screen, screen[0], screen[1]); - glUniformMatrix4fv(uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); - glUniformMatrix4fv(uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); + glUniformMatrix4fv(FlipParticleRender::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); + glUniform2f(FlipParticleRender::uniform_screen, screen[0], screen[1]); + glUniformMatrix4fv(FlipParticleRender::uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); + glUniformMatrix4fv(FlipParticleRender::uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); - glUniform1i(uniform_has_heightmap, has_height_map); +/* glUniform1i(FlipParticleRender::uniform_has_heightmap, has_height_map); if (has_height_map) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture); - glUniform1i(uniform_heightmap, 2); - glUniform1f(uniform_track_x, track_x); - glUniform1f(uniform_track_z, track_z); - glUniform1f(uniform_track_x_len, track_x_len); - glUniform1f(uniform_track_z_len, track_z_len); - } - glEnableVertexAttribArray(attrib_rotationvec); - glEnableVertexAttribArray(attrib_anglespeed); - glUniform1i(uniform_flips, flip); + glUniform1i(FlipParticleRender::uniform_heightmap, 2); + glUniform1f(FlipParticleRender::uniform_track_x, track_x); + glUniform1f(FlipParticleRender::uniform_track_z, track_z); + glUniform1f(FlipParticleRender::uniform_track_x_len, track_x_len); + glUniform1f(FlipParticleRender::uniform_track_z_len, track_z_len); + }*/ + glEnableVertexAttribArray(FlipParticleRender::attrib_rotationvec); + glEnableVertexAttribArray(FlipParticleRender::attrib_anglespeed); glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer); - glVertexAttribPointer(attrib_rotationvec, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_anglespeed, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float))); + glVertexAttribPointer(FlipParticleRender::attrib_rotationvec, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(FlipParticleRender::attrib_anglespeed, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(3 * sizeof(float))); glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); - glVertexAttribPointer(attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glVertexAttribPointer(FlipParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(FlipParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); - glVertexAttribPointer(attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0); - glVertexAttribPointer(attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float))); - glVertexAttribPointer(attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float))); + glVertexAttribPointer(FlipParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0); + glVertexAttribPointer(FlipParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float))); + glVertexAttribPointer(FlipParticleRender::attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float))); - glVertexAttribDivisor(attrib_lf, 1); - glVertexAttribDivisor(attrib_pos, 1); - glVertexAttribDivisor(attrib_sz, 1); - glVertexAttribDivisor(attrib_rotationvec, 1); - glVertexAttribDivisor(attrib_anglespeed, 1); + glVertexAttribDivisor(FlipParticleRender::attrib_lf, 1); + glVertexAttribDivisor(FlipParticleRender::attrib_pos, 1); + glVertexAttribDivisor(FlipParticleRender::attrib_sz, 1); + glVertexAttribDivisor(FlipParticleRender::attrib_rotationvec, 1); + glVertexAttribDivisor(FlipParticleRender::attrib_anglespeed, 1); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); - glVertexAttribDivisor(attrib_lf, 0); - glVertexAttribDivisor(attrib_pos, 0); - glVertexAttribDivisor(attrib_sz, 0); - glVertexAttribDivisor(attrib_rotationvec, 0); - glVertexAttribDivisor(attrib_anglespeed, 0); - glDisableVertexAttribArray(attrib_pos); - glDisableVertexAttribArray(attrib_lf); - glDisableVertexAttribArray(attrib_quadcorner); - glDisableVertexAttribArray(attrib_texcoord); - glDisableVertexAttribArray(attrib_sz); - glDisableVertexAttribArray(attrib_rotationvec); - glDisableVertexAttribArray(attrib_anglespeed); + glVertexAttribDivisor(FlipParticleRender::attrib_lf, 0); + glVertexAttribDivisor(FlipParticleRender::attrib_pos, 0); + glVertexAttribDivisor(FlipParticleRender::attrib_sz, 0); + glVertexAttribDivisor(FlipParticleRender::attrib_rotationvec, 0); + glVertexAttribDivisor(FlipParticleRender::attrib_anglespeed, 0); + glDisableVertexAttribArray(FlipParticleRender::attrib_pos); + glDisableVertexAttribArray(FlipParticleRender::attrib_lf); + glDisableVertexAttribArray(FlipParticleRender::attrib_quadcorner); + glDisableVertexAttribArray(FlipParticleRender::attrib_texcoord); + glDisableVertexAttribArray(FlipParticleRender::attrib_sz); + glDisableVertexAttribArray(FlipParticleRender::attrib_rotationvec); + glDisableVertexAttribArray(FlipParticleRender::attrib_anglespeed); glBindBuffer(GL_ARRAY_BUFFER, 0); glActiveTexture(GL_TEXTURE0); glDisable(GL_BLEND); + +} + +void ParticleSystemProxy::drawNotFlip() +{ + glDepthMask(GL_FALSE); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + + if (m_alpha_additive) + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + else + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(SimpleParticleRender::Program); + glEnableVertexAttribArray(SimpleParticleRender::attrib_pos); + glEnableVertexAttribArray(SimpleParticleRender::attrib_lf); + glEnableVertexAttribArray(SimpleParticleRender::attrib_quadcorner); + glEnableVertexAttribArray(SimpleParticleRender::attrib_texcoord); + glEnableVertexAttribArray(SimpleParticleRender::attrib_sz); + + float screen[2] = { + (float)UserConfigParams::m_width, + (float)UserConfigParams::m_height + }; + + bindUniformToTextureUnit(SimpleParticleRender::uniform_texture, texture, 0); + bindUniformToTextureUnit(SimpleParticleRender::uniform_normal_and_depths, normal_and_depth, 1); + + glUniformMatrix4fv(SimpleParticleRender::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); + glUniform2f(SimpleParticleRender::uniform_screen, screen[0], screen[1]); + glUniformMatrix4fv(SimpleParticleRender::uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); + glUniformMatrix4fv(SimpleParticleRender::uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); + +/* glUniform1i(SimpleParticleRender::uniform_has_heightmap, has_height_map); + if (has_height_map) + { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture); + glUniform1i(SimpleParticleRender::uniform_heightmap, 2); + glUniform1f(SimpleParticleRender::uniform_track_x, track_x); + glUniform1f(SimpleParticleRender::uniform_track_z, track_z); + glUniform1f(SimpleParticleRender::uniform_track_x_len, track_x_len); + glUniform1f(SimpleParticleRender::uniform_track_z_len, track_z_len); + }*/ + + glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); + glVertexAttribPointer(SimpleParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(SimpleParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); + glVertexAttribPointer(SimpleParticleRender::attrib_pos, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), 0); + glVertexAttribPointer(SimpleParticleRender::attrib_lf, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(3 * sizeof(float))); + glVertexAttribPointer(SimpleParticleRender::attrib_sz, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid *)(7 * sizeof(float))); + + glVertexAttribDivisor(SimpleParticleRender::attrib_lf, 1); + glVertexAttribDivisor(SimpleParticleRender::attrib_pos, 1); + glVertexAttribDivisor(SimpleParticleRender::attrib_sz, 1); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count); + glVertexAttribDivisor(SimpleParticleRender::attrib_lf, 0); + glVertexAttribDivisor(SimpleParticleRender::attrib_pos, 0); + glVertexAttribDivisor(SimpleParticleRender::attrib_sz, 0); + glDisableVertexAttribArray(SimpleParticleRender::attrib_pos); + glDisableVertexAttribArray(SimpleParticleRender::attrib_lf); + glDisableVertexAttribArray(SimpleParticleRender::attrib_quadcorner); + glDisableVertexAttribArray(SimpleParticleRender::attrib_texcoord); + glDisableVertexAttribArray(SimpleParticleRender::attrib_sz); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glActiveTexture(GL_TEXTURE0); + glDisable(GL_BLEND); + +} + +void ParticleSystemProxy::draw() +{ + if (flip) + drawFlip(); + else + drawNotFlip(); } void ParticleSystemProxy::render() { diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 993802494..843c80af1 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -31,21 +31,15 @@ protected: bool m_alpha_additive, has_height_map, flip; float size_increase_factor, track_x, track_z, track_x_len, track_z_len; - static GLuint SimulationProgram; - static GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - static GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor, uniform_has_heightmap, uniform_heightmap; - - static GLuint RenderProgram; - static GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz, attrib_rotationvec, attrib_anglespeed; - static GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj, uniform_flips; - - static GLuint uniform_track_x, uniform_track_z, uniform_track_x_len, uniform_track_z_len; - static GLuint quad_vertex_buffer; GLuint texture, normal_and_depth; unsigned duration, count, LastEmitTime; + void simulateHeightmap(); + void simulateNoHeightmap(); + void drawFlip(); + void drawNotFlip(); virtual void simulate(); virtual void draw(); void generateParticlesFromPointEmitter(scene::IParticlePointEmitter *); From 80faf282dc0ba88a853c4a2dbed50a82cd38c8de Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 17:42:43 +0000 Subject: [PATCH 225/412] GPUParticles: Fix glsl versions. Only heightmap sim require version 140. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14995 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/flipparticle.vert | 2 +- data/shaders/particle.frag | 2 +- data/shaders/particle.vert | 2 +- data/shaders/particlesimheightmap.vert | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/flipparticle.vert b/data/shaders/flipparticle.vert index 150f52b3c..d834b7ee9 100644 --- a/data/shaders/flipparticle.vert +++ b/data/shaders/flipparticle.vert @@ -1,4 +1,4 @@ -#version 140 +#version 130 uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index d65d3395c..08157c24e 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -1,4 +1,4 @@ -#version 140 +#version 130 uniform sampler2D texture; uniform sampler2D normals_and_depth; uniform mat4 invproj; diff --git a/data/shaders/particle.vert b/data/shaders/particle.vert index d2d6ee63b..fcfc3af0d 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,4 +1,4 @@ -#version 140 +#version 130 uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; diff --git a/data/shaders/particlesimheightmap.vert b/data/shaders/particlesimheightmap.vert index e74663c8f..c731612db 100644 --- a/data/shaders/particlesimheightmap.vert +++ b/data/shaders/particlesimheightmap.vert @@ -1,4 +1,4 @@ -#version 130 +#version 140 uniform int dt; uniform mat4 sourcematrix; uniform int level; From 9b1853ef211661d5c518802061efcd028fc78d50 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 21:12:38 +0000 Subject: [PATCH 226/412] GPUParticles: Remove the unused PointEmitter class. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14996 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.h | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 843c80af1..5a5cdfee6 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -67,39 +67,6 @@ public: void setFlip(); }; -class PointEmitter : public GPUParticle -{ -protected: - GLuint SimulationProgram, RenderProgram; - GLuint loc_duration, loc_sourcematrix, loc_dt, loc_matrix, loc_texture, loc_normal_and_depths, loc_screen, loc_invproj; - GLuint loc_position, loc_velocity, loc_lifetime; - GLuint tfb_buffers[2]; - GLuint texture, normal_and_depth; - unsigned duration, count; - core::vector3df direction; - core::aabbox3d box; - scene::IParticleSystemSceneNode *m_node; - - virtual void simulate(); - virtual void draw(); -public: - PointEmitter(scene::ISceneNode *parent, - scene::ISceneManager* mgr, video::ITexture *tex, - const core::vector3df& dir, - u32 minParticlesPerSecond, - u32 maxParticlesPerSecond, - const video::SColor& minStartColor, - const video::SColor& maxStartColor, - u32 lifeTimeMin, u32 lifeTimeMax, - s32 maxAngleDegrees -// const core::dimension2df& minStartSize, -// const core::dimension2df& maxStartSize - ); - void set_m_node(scene::IParticleSystemSceneNode *nd) { m_node = nd; } - virtual const core::aabbox3d& getBoundingBox() const { return box; } - virtual u32 getMaterialCount() const { return 1; } -}; - class RainNode : public GPUParticle { protected: From c3a4f7d8ce76ad30a68fc3a3fae5443c283ba7a9 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 21:30:17 +0000 Subject: [PATCH 227/412] Use a custom stk mesh git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14997 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 1330 ++++++++++++++++++----------------- src/graphics/irr_driver.cpp | 12 +- src/graphics/stkmesh.cpp | 15 + src/graphics/stkmesh.hpp | 19 + src/tracks/track.cpp | 4 +- 5 files changed, 713 insertions(+), 667 deletions(-) create mode 100644 src/graphics/stkmesh.cpp create mode 100644 src/graphics/stkmesh.hpp diff --git a/sources.cmake b/sources.cmake index 2e9db0485..b59bf4fb9 100644 --- a/sources.cmake +++ b/sources.cmake @@ -1,664 +1,666 @@ -# Generated by ./update_file_list.sh. Do not edit this file manually. -set(STK_SOURCES -src/achievements/achievement.cpp -src/achievements/achievement_info.cpp -src/achievements/achievements_manager.cpp -src/achievements/achievements_slot.cpp -src/addons/addon.cpp -src/addons/addons_manager.cpp -src/addons/inetwork_http.cpp -src/addons/network_http.cpp -src/addons/news_manager.cpp -src/addons/request.cpp -src/addons/zip.cpp -src/animations/animation_base.cpp -src/animations/ipo.cpp -src/animations/three_d_animation.cpp -src/audio/music_information.cpp -src/audio/music_manager.cpp -src/audio/music_ogg.cpp -src/audio/sfx_buffer.cpp -src/audio/sfx_manager.cpp -src/audio/sfx_openal.cpp -src/challenges/challenge.cpp -src/challenges/challenge_data.cpp -src/challenges/game_slot.cpp -src/challenges/unlock_manager.cpp -src/config/device_config.cpp -src/config/player.cpp -src/config/saved_grand_prix.cpp -src/config/stk_config.cpp -src/config/user_config.cpp -src/graphics/callbacks.cpp -src/graphics/camera.cpp -src/graphics/CBatchingMesh.cpp -src/graphics/explosion.cpp -src/graphics/glow.cpp -src/graphics/glwrap.cpp -src/graphics/gpuparticles.cpp -src/graphics/hardware_skinning.cpp -src/graphics/hit_sfx.cpp -src/graphics/irr_driver.cpp -src/graphics/lens_flare.cpp -src/graphics/light.cpp -src/graphics/lod_node.cpp -src/graphics/material.cpp -src/graphics/material_manager.cpp -src/graphics/mesh_tools.cpp -src/graphics/moving_texture.cpp -src/graphics/particle_emitter.cpp -src/graphics/particle_kind.cpp -src/graphics/particle_kind_manager.cpp -src/graphics/per_camera_node.cpp -src/graphics/post_processing.cpp -src/graphics/rain.cpp -src/graphics/referee.cpp -src/graphics/render.cpp -src/graphics/rtts.cpp -src/graphics/screenquad.cpp -src/graphics/shaders.cpp -src/graphics/shadow.cpp -src/graphics/shadow_importance.cpp -src/graphics/show_curve.cpp -src/graphics/skid_marks.cpp -src/graphics/slip_stream.cpp -src/graphics/stars.cpp -src/graphics/sun.cpp -src/graphics/water.cpp -src/graphics/wind.cpp -src/guiengine/abstract_state_manager.cpp -src/guiengine/abstract_top_level_container.cpp -src/guiengine/CGUISpriteBank.cpp -src/guiengine/dialog_queue.cpp -src/guiengine/engine.cpp -src/guiengine/event_handler.cpp -src/guiengine/layout_manager.cpp -src/guiengine/modaldialog.cpp -src/guiengine/scalable_font.cpp -src/guiengine/screen.cpp -src/guiengine/screen_loader.cpp -src/guiengine/skin.cpp -src/guiengine/widget.cpp -src/guiengine/widgets/bubble_widget.cpp -src/guiengine/widgets/button_widget.cpp -src/guiengine/widgets/CGUIEditBox.cpp -src/guiengine/widgets/CGUISTKListBox.cpp -src/guiengine/widgets/check_box_widget.cpp -src/guiengine/widgets/dynamic_ribbon_widget.cpp -src/guiengine/widgets/icon_button_widget.cpp -src/guiengine/widgets/label_widget.cpp -src/guiengine/widgets/list_widget.cpp -src/guiengine/widgets/model_view_widget.cpp -src/guiengine/widgets/progress_bar_widget.cpp -src/guiengine/widgets/rating_bar_widget.cpp -src/guiengine/widgets/ribbon_widget.cpp -src/guiengine/widgets/spinner_widget.cpp -src/guiengine/widgets/text_box_widget.cpp -src/input/binding.cpp -src/input/device_manager.cpp -src/input/input_device.cpp -src/input/input_manager.cpp -src/input/wiimote.cpp -src/input/wiimote_manager.cpp -src/io/file_manager.cpp -src/io/xml_node.cpp -src/io/xml_writer.cpp -src/items/attachment.cpp -src/items/attachment_manager.cpp -src/items/bowling.cpp -src/items/cake.cpp -src/items/flyable.cpp -src/items/item.cpp -src/items/item_manager.cpp -src/items/plunger.cpp -src/items/powerup.cpp -src/items/powerup_manager.cpp -src/items/projectile_manager.cpp -src/items/rubber_ball.cpp -src/items/rubber_band.cpp -src/items/swatter.cpp -src/karts/abstract_kart.cpp -src/karts/abstract_kart_animation.cpp -src/karts/cannon_animation.cpp -src/karts/controller/ai_base_controller.cpp -src/karts/controller/ai_properties.cpp -src/karts/controller/controller.cpp -src/karts/controller/end_controller.cpp -src/karts/controller/network_player_controller.cpp -src/karts/controller/player_controller.cpp -src/karts/controller/skidding_ai.cpp -src/karts/explosion_animation.cpp -src/karts/ghost_kart.cpp -src/karts/kart.cpp -src/karts/kart_gfx.cpp -src/karts/kart_model.cpp -src/karts/kart_properties.cpp -src/karts/kart_properties_manager.cpp -src/karts/kart_with_stats.cpp -src/karts/max_speed.cpp -src/karts/moveable.cpp -src/karts/rescue_animation.cpp -src/karts/skidding.cpp -src/karts/skidding_properties.cpp -src/main.cpp -src/main_loop.cpp -src/modes/cutscene_world.cpp -src/modes/demo_world.cpp -src/modes/easter_egg_hunt.cpp -src/modes/follow_the_leader.cpp -src/modes/linear_world.cpp -src/modes/overworld.cpp -src/modes/profile_world.cpp -src/modes/soccer_world.cpp -src/modes/standard_race.cpp -src/modes/three_strikes_battle.cpp -src/modes/tutorial_world.cpp -src/modes/world.cpp -src/modes/world_status.cpp -src/modes/world_with_rank.cpp -src/network/client_network_manager.cpp -src/network/event.cpp -src/network/game_setup.cpp -src/network/network_interface.cpp -src/network/network_manager.cpp -src/network/network_string.cpp -src/network/network_world.cpp -src/network/protocol.cpp -src/network/protocol_manager.cpp -src/network/protocols/client_lobby_room_protocol.cpp -src/network/protocols/connect_to_peer.cpp -src/network/protocols/connect_to_server.cpp -src/network/protocols/controller_events_protocol.cpp -src/network/protocols/game_events_protocol.cpp -src/network/protocols/get_peer_address.cpp -src/network/protocols/get_public_address.cpp -src/network/protocols/hide_public_address.cpp -src/network/protocols/kart_update_protocol.cpp -src/network/protocols/lobby_room_protocol.cpp -src/network/protocols/ping_protocol.cpp -src/network/protocols/quick_join_protocol.cpp -src/network/protocols/request_connection.cpp -src/network/protocols/server_lobby_room_protocol.cpp -src/network/protocols/show_public_address.cpp -src/network/protocols/start_game_protocol.cpp -src/network/protocols/start_server.cpp -src/network/protocols/stop_server.cpp -src/network/protocols/synchronization_protocol.cpp -src/network/race_config.cpp -src/network/server_network_manager.cpp -src/network/stk_host.cpp -src/network/stk_peer.cpp -src/network/types.cpp -src/online/current_user.cpp -src/online/http_request.cpp -src/online/messages.cpp -src/online/profile.cpp -src/online/profile_manager.cpp -src/online/request.cpp -src/online/request_manager.cpp -src/online/server.cpp -src/online/servers_manager.cpp -src/online/xml_request.cpp -src/physics/btKart.cpp -src/physics/btKartRaycast.cpp -src/physics/btUprightConstraint.cpp -src/physics/irr_debug_drawer.cpp -src/physics/physical_object.cpp -src/physics/physics.cpp -src/physics/triangle_mesh.cpp -src/race/grand_prix_data.cpp -src/race/grand_prix_manager.cpp -src/race/highscore_manager.cpp -src/race/highscores.cpp -src/race/history.cpp -src/race/race_manager.cpp -src/replay/replay_base.cpp -src/replay/replay_play.cpp -src/replay/replay_recorder.cpp -src/states_screens/addons_screen.cpp -src/states_screens/arenas_screen.cpp -src/states_screens/create_server_screen.cpp -src/states_screens/credits.cpp -src/states_screens/cutscene_gui.cpp -src/states_screens/dialogs/add_device_dialog.cpp -src/states_screens/dialogs/addons_loading.cpp -src/states_screens/dialogs/change_password_dialog.cpp -src/states_screens/dialogs/confirm_resolution_dialog.cpp -src/states_screens/dialogs/custom_video_settings.cpp -src/states_screens/dialogs/enter_player_name_dialog.cpp -src/states_screens/dialogs/gp_info_dialog.cpp -src/states_screens/dialogs/login_dialog.cpp -src/states_screens/dialogs/message_dialog.cpp -src/states_screens/dialogs/notification_dialog.cpp -src/states_screens/dialogs/player_info_dialog.cpp -src/states_screens/dialogs/press_a_key_dialog.cpp -src/states_screens/dialogs/race_paused_dialog.cpp -src/states_screens/dialogs/recovery_dialog.cpp -src/states_screens/dialogs/registration_dialog.cpp -src/states_screens/dialogs/select_challenge.cpp -src/states_screens/dialogs/server_info_dialog.cpp -src/states_screens/dialogs/track_info_dialog.cpp -src/states_screens/dialogs/tutorial_message_dialog.cpp -src/states_screens/dialogs/user_info_dialog.cpp -src/states_screens/dialogs/vote_dialog.cpp -src/states_screens/easter_egg_screen.cpp -src/states_screens/feature_unlocked.cpp -src/states_screens/grand_prix_lose.cpp -src/states_screens/grand_prix_win.cpp -src/states_screens/help_screen_1.cpp -src/states_screens/help_screen_2.cpp -src/states_screens/help_screen_3.cpp -src/states_screens/help_screen_4.cpp -src/states_screens/kart_selection.cpp -src/states_screens/main_menu_screen.cpp -src/states_screens/network_kart_selection.cpp -src/states_screens/networking_lobby.cpp -src/states_screens/offline_kart_selection.cpp -src/states_screens/online_profile_achievements.cpp -src/states_screens/online_profile_base.cpp -src/states_screens/online_profile_friends.cpp -src/states_screens/online_profile_overview.cpp -src/states_screens/online_profile_settings.cpp -src/states_screens/online_screen.cpp -src/states_screens/online_user_search.cpp -src/states_screens/options_screen_audio.cpp -src/states_screens/options_screen_input.cpp -src/states_screens/options_screen_input2.cpp -src/states_screens/options_screen_players.cpp -src/states_screens/options_screen_ui.cpp -src/states_screens/options_screen_video.cpp -src/states_screens/race_gui.cpp -src/states_screens/race_gui_base.cpp -src/states_screens/race_gui_overworld.cpp -src/states_screens/race_result_gui.cpp -src/states_screens/race_setup_screen.cpp -src/states_screens/server_selection.cpp -src/states_screens/soccer_setup_screen.cpp -src/states_screens/state_manager.cpp -src/states_screens/story_mode_lobby.cpp -src/states_screens/tracks_screen.cpp -src/tinygettext/dictionary.cpp -src/tinygettext/dictionary_manager.cpp -src/tinygettext/iconv.cpp -src/tinygettext/language.cpp -src/tinygettext/plural_forms.cpp -src/tinygettext/po_parser.cpp -src/tinygettext/stk_file_system.cpp -src/tinygettext/tgt_log.cpp -src/tinygettext/tinygettext.cpp -src/tracks/ambient_light_sphere.cpp -src/tracks/bezier_curve.cpp -src/tracks/check_cannon.cpp -src/tracks/check_goal.cpp -src/tracks/check_lap.cpp -src/tracks/check_line.cpp -src/tracks/check_manager.cpp -src/tracks/check_sphere.cpp -src/tracks/check_structure.cpp -src/tracks/graph_node.cpp -src/tracks/lod_node_loader.cpp -src/tracks/quad.cpp -src/tracks/quad_graph.cpp -src/tracks/quad_set.cpp -src/tracks/terrain_info.cpp -src/tracks/track.cpp -src/tracks/track_manager.cpp -src/tracks/track_object.cpp -src/tracks/track_object_manager.cpp -src/tracks/track_object_presentation.cpp -src/tracks/track_sector.cpp -src/utils/command_line.cpp -src/utils/constants.cpp -src/utils/crash_reporting.cpp -src/utils/debug.cpp -src/utils/helpers.cpp -src/utils/leak_check.cpp -src/utils/log.cpp -src/utils/profiler.cpp -src/utils/random_generator.cpp -src/utils/string_utils.cpp -src/utils/time.cpp -src/utils/translation.cpp -src/utils/vec3.cpp -) -set(STK_HEADERS -src/achievements/achievement.hpp -src/achievements/achievement_info.hpp -src/achievements/achievements_manager.hpp -src/achievements/achievements_slot.hpp -src/addons/addon.hpp -src/addons/addons_manager.hpp -src/addons/dummy_network_http.hpp -src/addons/inetwork_http.hpp -src/addons/network_http.hpp -src/addons/news_manager.hpp -src/addons/request.hpp -src/addons/zip.hpp -src/animations/animation_base.hpp -src/animations/ipo.hpp -src/animations/three_d_animation.hpp -src/audio/dummy_sfx.hpp -src/audio/music.hpp -src/audio/music_dummy.hpp -src/audio/music_information.hpp -src/audio/music_manager.hpp -src/audio/music_ogg.hpp -src/audio/sfx_base.hpp -src/audio/sfx_buffer.hpp -src/audio/sfx_manager.hpp -src/audio/sfx_openal.hpp -src/challenges/challenge.hpp -src/challenges/challenge_data.hpp -src/challenges/game_slot.hpp -src/challenges/unlock_manager.hpp -src/config/device_config.hpp -src/config/player.hpp -src/config/saved_grand_prix.hpp -src/config/stk_config.hpp -src/config/user_config.hpp -src/graphics/callbacks.hpp -src/graphics/camera.hpp -src/graphics/CBatchingMesh.hpp -src/graphics/explosion.hpp -src/graphics/glow.hpp -src/graphics/glwrap.hpp -src/graphics/hardware_skinning.hpp -src/graphics/hit_effect.hpp -src/graphics/hit_sfx.hpp -src/graphics/irr_driver.hpp -src/graphics/large_mesh_buffer.hpp -src/graphics/lens_flare.hpp -src/graphics/light.hpp -src/graphics/lod_node.hpp -src/graphics/material.hpp -src/graphics/material_manager.hpp -src/graphics/mesh_tools.hpp -src/graphics/mlaa_areamap.hpp -src/graphics/moving_texture.hpp -src/graphics/particle_emitter.hpp -src/graphics/particle_kind.hpp -src/graphics/particle_kind_manager.hpp -src/graphics/per_camera_node.hpp -src/graphics/post_processing.hpp -src/graphics/rain.hpp -src/graphics/referee.hpp -src/graphics/rtts.hpp -src/graphics/screenquad.hpp -src/graphics/shaders.hpp -src/graphics/shadow.hpp -src/graphics/shadow_importance.hpp -src/graphics/show_curve.hpp -src/graphics/skid_marks.hpp -src/graphics/slip_stream.hpp -src/graphics/stars.hpp -src/graphics/sun.hpp -src/graphics/water.hpp -src/graphics/wind.hpp -src/guiengine/abstract_state_manager.hpp -src/guiengine/abstract_top_level_container.hpp -src/guiengine/dialog_queue.hpp -src/guiengine/engine.hpp -src/guiengine/event_handler.hpp -src/guiengine/layout_manager.hpp -src/guiengine/modaldialog.hpp -src/guiengine/scalable_font.hpp -src/guiengine/screen.hpp -src/guiengine/skin.hpp -src/guiengine/widget.hpp -src/guiengine/widgets.hpp -src/guiengine/widgets/bubble_widget.hpp -src/guiengine/widgets/button_widget.hpp -src/guiengine/widgets/check_box_widget.hpp -src/guiengine/widgets/dynamic_ribbon_widget.hpp -src/guiengine/widgets/icon_button_widget.hpp -src/guiengine/widgets/label_widget.hpp -src/guiengine/widgets/list_widget.hpp -src/guiengine/widgets/model_view_widget.hpp -src/guiengine/widgets/progress_bar_widget.hpp -src/guiengine/widgets/rating_bar_widget.hpp -src/guiengine/widgets/ribbon_widget.hpp -src/guiengine/widgets/spinner_widget.hpp -src/guiengine/widgets/text_box_widget.hpp -src/input/binding.hpp -src/input/device_manager.hpp -src/input/input.hpp -src/input/input_device.hpp -src/input/input_manager.hpp -src/input/wiimote.hpp -src/input/wiimote_manager.hpp -src/io/file_manager.hpp -src/io/xml_node.hpp -src/io/xml_writer.hpp -src/items/attachment.hpp -src/items/attachment_manager.hpp -src/items/attachment_plugin.hpp -src/items/bowling.hpp -src/items/cake.hpp -src/items/flyable.hpp -src/items/item.hpp -src/items/item_manager.hpp -src/items/plunger.hpp -src/items/powerup.hpp -src/items/powerup_manager.hpp -src/items/projectile_manager.hpp -src/items/rubber_ball.hpp -src/items/rubber_band.hpp -src/items/swatter.hpp -src/karts/abstract_kart.hpp -src/karts/abstract_kart_animation.hpp -src/karts/cannon_animation.hpp -src/karts/controller/ai_base_controller.hpp -src/karts/controller/ai_properties.hpp -src/karts/controller/controller.hpp -src/karts/controller/end_controller.hpp -src/karts/controller/kart_control.hpp -src/karts/controller/network_player_controller.hpp -src/karts/controller/player_controller.hpp -src/karts/controller/skidding_ai.hpp -src/karts/explosion_animation.hpp -src/karts/ghost_kart.hpp -src/karts/kart.hpp -src/karts/kart_gfx.hpp -src/karts/kart_model.hpp -src/karts/kart_properties.hpp -src/karts/kart_properties_manager.hpp -src/karts/kart_with_stats.hpp -src/karts/max_speed.hpp -src/karts/moveable.hpp -src/karts/rescue_animation.hpp -src/karts/skidding.hpp -src/karts/skidding_properties.hpp -src/main_loop.hpp -src/modes/cutscene_world.hpp -src/modes/demo_world.hpp -src/modes/easter_egg_hunt.hpp -src/modes/follow_the_leader.hpp -src/modes/linear_world.hpp -src/modes/overworld.hpp -src/modes/profile_world.hpp -src/modes/soccer_world.hpp -src/modes/standard_race.hpp -src/modes/three_strikes_battle.hpp -src/modes/tutorial_world.hpp -src/modes/world.hpp -src/modes/world_status.hpp -src/modes/world_with_rank.hpp -src/network/client_network_manager.hpp -src/network/event.hpp -src/network/game_setup.hpp -src/network/network_interface.hpp -src/network/network_manager.hpp -src/network/network_string.hpp -src/network/network_world.hpp -src/network/protocol.hpp -src/network/protocol_manager.hpp -src/network/protocols/client_lobby_room_protocol.hpp -src/network/protocols/connect_to_peer.hpp -src/network/protocols/connect_to_server.hpp -src/network/protocols/controller_events_protocol.hpp -src/network/protocols/game_events_protocol.hpp -src/network/protocols/get_peer_address.hpp -src/network/protocols/get_public_address.hpp -src/network/protocols/hide_public_address.hpp -src/network/protocols/kart_update_protocol.hpp -src/network/protocols/lobby_room_protocol.hpp -src/network/protocols/ping_protocol.hpp -src/network/protocols/quick_join_protocol.hpp -src/network/protocols/request_connection.hpp -src/network/protocols/server_lobby_room_protocol.hpp -src/network/protocols/show_public_address.hpp -src/network/protocols/start_game_protocol.hpp -src/network/protocols/start_server.hpp -src/network/protocols/stop_server.hpp -src/network/protocols/synchronization_protocol.hpp -src/network/race_config.hpp -src/network/remote_kart_info.hpp -src/network/server_network_manager.hpp -src/network/singleton.hpp -src/network/stk_host.hpp -src/network/stk_peer.hpp -src/network/types.hpp -src/online/current_user.hpp -src/online/http_request.hpp -src/online/messages.hpp -src/online/profile.hpp -src/online/profile_manager.hpp -src/online/request.hpp -src/online/request_manager.hpp -src/online/server.hpp -src/online/servers_manager.hpp -src/online/xml_request.hpp -src/physics/btKart.hpp -src/physics/btKartRaycast.hpp -src/physics/btUprightConstraint.hpp -src/physics/irr_debug_drawer.hpp -src/physics/kart_motion_state.hpp -src/physics/physical_object.hpp -src/physics/physics.hpp -src/physics/stk_dynamics_world.hpp -src/physics/triangle_mesh.hpp -src/physics/user_pointer.hpp -src/race/grand_prix_data.hpp -src/race/grand_prix_manager.hpp -src/race/highscore_manager.hpp -src/race/highscores.hpp -src/race/history.hpp -src/race/race_manager.hpp -src/replay/replay_base.hpp -src/replay/replay_play.hpp -src/replay/replay_recorder.hpp -src/states_screens/addons_screen.hpp -src/states_screens/arenas_screen.hpp -src/states_screens/create_server_screen.hpp -src/states_screens/credits.hpp -src/states_screens/cutscene_gui.hpp -src/states_screens/dialogs/add_device_dialog.hpp -src/states_screens/dialogs/addons_loading.hpp -src/states_screens/dialogs/change_password_dialog.hpp -src/states_screens/dialogs/confirm_resolution_dialog.hpp -src/states_screens/dialogs/custom_video_settings.hpp -src/states_screens/dialogs/enter_player_name_dialog.hpp -src/states_screens/dialogs/gp_info_dialog.hpp -src/states_screens/dialogs/login_dialog.hpp -src/states_screens/dialogs/message_dialog.hpp -src/states_screens/dialogs/notification_dialog.hpp -src/states_screens/dialogs/player_info_dialog.hpp -src/states_screens/dialogs/press_a_key_dialog.hpp -src/states_screens/dialogs/race_paused_dialog.hpp -src/states_screens/dialogs/recovery_dialog.hpp -src/states_screens/dialogs/registration_dialog.hpp -src/states_screens/dialogs/select_challenge.hpp -src/states_screens/dialogs/server_info_dialog.hpp -src/states_screens/dialogs/track_info_dialog.hpp -src/states_screens/dialogs/tutorial_message_dialog.hpp -src/states_screens/dialogs/user_info_dialog.hpp -src/states_screens/dialogs/vote_dialog.hpp -src/states_screens/easter_egg_screen.hpp -src/states_screens/feature_unlocked.hpp -src/states_screens/grand_prix_lose.hpp -src/states_screens/grand_prix_win.hpp -src/states_screens/help_screen_1.hpp -src/states_screens/help_screen_2.hpp -src/states_screens/help_screen_3.hpp -src/states_screens/help_screen_4.hpp -src/states_screens/kart_selection.hpp -src/states_screens/main_menu_screen.hpp -src/states_screens/network_kart_selection.hpp -src/states_screens/networking_lobby.hpp -src/states_screens/offline_kart_selection.hpp -src/states_screens/online_profile_achievements.hpp -src/states_screens/online_profile_base.hpp -src/states_screens/online_profile_friends.hpp -src/states_screens/online_profile_overview.hpp -src/states_screens/online_profile_settings.hpp -src/states_screens/online_screen.hpp -src/states_screens/online_user_search.hpp -src/states_screens/options_screen_audio.hpp -src/states_screens/options_screen_input.hpp -src/states_screens/options_screen_input2.hpp -src/states_screens/options_screen_players.hpp -src/states_screens/options_screen_ui.hpp -src/states_screens/options_screen_video.hpp -src/states_screens/race_gui.hpp -src/states_screens/race_gui_base.hpp -src/states_screens/race_gui_overworld.hpp -src/states_screens/race_result_gui.hpp -src/states_screens/race_setup_screen.hpp -src/states_screens/server_selection.hpp -src/states_screens/soccer_setup_screen.hpp -src/states_screens/state_manager.hpp -src/states_screens/story_mode_lobby.hpp -src/states_screens/tracks_screen.hpp -src/tinygettext/dictionary.hpp -src/tinygettext/dictionary_manager.hpp -src/tinygettext/file_system.hpp -src/tinygettext/iconv.hpp -src/tinygettext/language.hpp -src/tinygettext/log_stream.hpp -src/tinygettext/plural_forms.hpp -src/tinygettext/po_parser.hpp -src/tinygettext/stk_file_system.hpp -src/tinygettext/tgt_log.hpp -src/tinygettext/tinygettext.hpp -src/tracks/ambient_light_sphere.hpp -src/tracks/bezier_curve.hpp -src/tracks/check_cannon.hpp -src/tracks/check_goal.hpp -src/tracks/check_lap.hpp -src/tracks/check_line.hpp -src/tracks/check_manager.hpp -src/tracks/check_sphere.hpp -src/tracks/check_structure.hpp -src/tracks/graph_node.hpp -src/tracks/lod_node_loader.hpp -src/tracks/quad.hpp -src/tracks/quad_graph.hpp -src/tracks/quad_set.hpp -src/tracks/terrain_info.hpp -src/tracks/track.hpp -src/tracks/track_manager.hpp -src/tracks/track_object.hpp -src/tracks/track_object_manager.hpp -src/tracks/track_object_presentation.hpp -src/tracks/track_sector.hpp -src/utils/aligned_array.hpp -src/utils/command_line.hpp -src/utils/constants.hpp -src/utils/crash_reporting.hpp -src/utils/debug.hpp -src/utils/helpers.hpp -src/utils/interpolation_array.hpp -src/utils/leak_check.hpp -src/utils/log.hpp -src/utils/no_copy.hpp -src/utils/profiler.hpp -src/utils/ptr_vector.hpp -src/utils/random_generator.hpp -src/utils/string_utils.hpp -src/utils/synchronised.hpp -src/utils/time.hpp -src/utils/translation.hpp -src/utils/types.hpp -src/utils/vec3.hpp -src/utils/vs.hpp -) +# Generated by ./update_file_list.sh. Do not edit this file manually. +set(STK_SOURCES +src/achievements/achievement.cpp +src/achievements/achievement_info.cpp +src/achievements/achievements_manager.cpp +src/achievements/achievements_slot.cpp +src/addons/addon.cpp +src/addons/addons_manager.cpp +src/addons/inetwork_http.cpp +src/addons/network_http.cpp +src/addons/news_manager.cpp +src/addons/request.cpp +src/addons/zip.cpp +src/animations/animation_base.cpp +src/animations/ipo.cpp +src/animations/three_d_animation.cpp +src/audio/music_information.cpp +src/audio/music_manager.cpp +src/audio/music_ogg.cpp +src/audio/sfx_buffer.cpp +src/audio/sfx_manager.cpp +src/audio/sfx_openal.cpp +src/challenges/challenge.cpp +src/challenges/challenge_data.cpp +src/challenges/game_slot.cpp +src/challenges/unlock_manager.cpp +src/config/device_config.cpp +src/config/player.cpp +src/config/saved_grand_prix.cpp +src/config/stk_config.cpp +src/config/user_config.cpp +src/graphics/callbacks.cpp +src/graphics/camera.cpp +src/graphics/CBatchingMesh.cpp +src/graphics/explosion.cpp +src/graphics/glow.cpp +src/graphics/glwrap.cpp +src/graphics/gpuparticles.cpp +src/graphics/hardware_skinning.cpp +src/graphics/hit_sfx.cpp +src/graphics/irr_driver.cpp +src/graphics/lens_flare.cpp +src/graphics/light.cpp +src/graphics/lod_node.cpp +src/graphics/material.cpp +src/graphics/material_manager.cpp +src/graphics/mesh_tools.cpp +src/graphics/moving_texture.cpp +src/graphics/particle_emitter.cpp +src/graphics/particle_kind.cpp +src/graphics/particle_kind_manager.cpp +src/graphics/per_camera_node.cpp +src/graphics/post_processing.cpp +src/graphics/rain.cpp +src/graphics/referee.cpp +src/graphics/render.cpp +src/graphics/rtts.cpp +src/graphics/screenquad.cpp +src/graphics/shaders.cpp +src/graphics/shadow.cpp +src/graphics/shadow_importance.cpp +src/graphics/show_curve.cpp +src/graphics/skid_marks.cpp +src/graphics/slip_stream.cpp +src/graphics/stars.cpp +src/graphics/stkmesh.cpp +src/graphics/sun.cpp +src/graphics/water.cpp +src/graphics/wind.cpp +src/guiengine/abstract_state_manager.cpp +src/guiengine/abstract_top_level_container.cpp +src/guiengine/CGUISpriteBank.cpp +src/guiengine/dialog_queue.cpp +src/guiengine/engine.cpp +src/guiengine/event_handler.cpp +src/guiengine/layout_manager.cpp +src/guiengine/modaldialog.cpp +src/guiengine/scalable_font.cpp +src/guiengine/screen.cpp +src/guiengine/screen_loader.cpp +src/guiengine/skin.cpp +src/guiengine/widget.cpp +src/guiengine/widgets/bubble_widget.cpp +src/guiengine/widgets/button_widget.cpp +src/guiengine/widgets/CGUIEditBox.cpp +src/guiengine/widgets/CGUISTKListBox.cpp +src/guiengine/widgets/check_box_widget.cpp +src/guiengine/widgets/dynamic_ribbon_widget.cpp +src/guiengine/widgets/icon_button_widget.cpp +src/guiengine/widgets/label_widget.cpp +src/guiengine/widgets/list_widget.cpp +src/guiengine/widgets/model_view_widget.cpp +src/guiengine/widgets/progress_bar_widget.cpp +src/guiengine/widgets/rating_bar_widget.cpp +src/guiengine/widgets/ribbon_widget.cpp +src/guiengine/widgets/spinner_widget.cpp +src/guiengine/widgets/text_box_widget.cpp +src/input/binding.cpp +src/input/device_manager.cpp +src/input/input_device.cpp +src/input/input_manager.cpp +src/input/wiimote.cpp +src/input/wiimote_manager.cpp +src/io/file_manager.cpp +src/io/xml_node.cpp +src/io/xml_writer.cpp +src/items/attachment.cpp +src/items/attachment_manager.cpp +src/items/bowling.cpp +src/items/cake.cpp +src/items/flyable.cpp +src/items/item.cpp +src/items/item_manager.cpp +src/items/plunger.cpp +src/items/powerup.cpp +src/items/powerup_manager.cpp +src/items/projectile_manager.cpp +src/items/rubber_ball.cpp +src/items/rubber_band.cpp +src/items/swatter.cpp +src/karts/abstract_kart_animation.cpp +src/karts/abstract_kart.cpp +src/karts/cannon_animation.cpp +src/karts/controller/ai_base_controller.cpp +src/karts/controller/ai_properties.cpp +src/karts/controller/controller.cpp +src/karts/controller/end_controller.cpp +src/karts/controller/network_player_controller.cpp +src/karts/controller/player_controller.cpp +src/karts/controller/skidding_ai.cpp +src/karts/explosion_animation.cpp +src/karts/ghost_kart.cpp +src/karts/kart.cpp +src/karts/kart_gfx.cpp +src/karts/kart_model.cpp +src/karts/kart_properties.cpp +src/karts/kart_properties_manager.cpp +src/karts/kart_with_stats.cpp +src/karts/max_speed.cpp +src/karts/moveable.cpp +src/karts/rescue_animation.cpp +src/karts/skidding.cpp +src/karts/skidding_properties.cpp +src/main.cpp +src/main_loop.cpp +src/modes/cutscene_world.cpp +src/modes/demo_world.cpp +src/modes/easter_egg_hunt.cpp +src/modes/follow_the_leader.cpp +src/modes/linear_world.cpp +src/modes/overworld.cpp +src/modes/profile_world.cpp +src/modes/soccer_world.cpp +src/modes/standard_race.cpp +src/modes/three_strikes_battle.cpp +src/modes/tutorial_world.cpp +src/modes/world.cpp +src/modes/world_status.cpp +src/modes/world_with_rank.cpp +src/network/client_network_manager.cpp +src/network/event.cpp +src/network/game_setup.cpp +src/network/network_interface.cpp +src/network/network_manager.cpp +src/network/network_string.cpp +src/network/network_world.cpp +src/network/protocol.cpp +src/network/protocol_manager.cpp +src/network/protocols/client_lobby_room_protocol.cpp +src/network/protocols/connect_to_peer.cpp +src/network/protocols/connect_to_server.cpp +src/network/protocols/controller_events_protocol.cpp +src/network/protocols/game_events_protocol.cpp +src/network/protocols/get_peer_address.cpp +src/network/protocols/get_public_address.cpp +src/network/protocols/hide_public_address.cpp +src/network/protocols/kart_update_protocol.cpp +src/network/protocols/lobby_room_protocol.cpp +src/network/protocols/ping_protocol.cpp +src/network/protocols/quick_join_protocol.cpp +src/network/protocols/request_connection.cpp +src/network/protocols/server_lobby_room_protocol.cpp +src/network/protocols/show_public_address.cpp +src/network/protocols/start_game_protocol.cpp +src/network/protocols/start_server.cpp +src/network/protocols/stop_server.cpp +src/network/protocols/synchronization_protocol.cpp +src/network/race_config.cpp +src/network/server_network_manager.cpp +src/network/stk_host.cpp +src/network/stk_peer.cpp +src/network/types.cpp +src/online/current_user.cpp +src/online/http_request.cpp +src/online/messages.cpp +src/online/profile.cpp +src/online/profile_manager.cpp +src/online/request.cpp +src/online/request_manager.cpp +src/online/server.cpp +src/online/servers_manager.cpp +src/online/xml_request.cpp +src/physics/btKart.cpp +src/physics/btKartRaycast.cpp +src/physics/btUprightConstraint.cpp +src/physics/irr_debug_drawer.cpp +src/physics/physical_object.cpp +src/physics/physics.cpp +src/physics/triangle_mesh.cpp +src/race/grand_prix_data.cpp +src/race/grand_prix_manager.cpp +src/race/highscore_manager.cpp +src/race/highscores.cpp +src/race/history.cpp +src/race/race_manager.cpp +src/replay/replay_base.cpp +src/replay/replay_play.cpp +src/replay/replay_recorder.cpp +src/states_screens/addons_screen.cpp +src/states_screens/arenas_screen.cpp +src/states_screens/create_server_screen.cpp +src/states_screens/credits.cpp +src/states_screens/cutscene_gui.cpp +src/states_screens/dialogs/add_device_dialog.cpp +src/states_screens/dialogs/addons_loading.cpp +src/states_screens/dialogs/change_password_dialog.cpp +src/states_screens/dialogs/confirm_resolution_dialog.cpp +src/states_screens/dialogs/custom_video_settings.cpp +src/states_screens/dialogs/enter_player_name_dialog.cpp +src/states_screens/dialogs/gp_info_dialog.cpp +src/states_screens/dialogs/login_dialog.cpp +src/states_screens/dialogs/message_dialog.cpp +src/states_screens/dialogs/notification_dialog.cpp +src/states_screens/dialogs/player_info_dialog.cpp +src/states_screens/dialogs/press_a_key_dialog.cpp +src/states_screens/dialogs/race_paused_dialog.cpp +src/states_screens/dialogs/recovery_dialog.cpp +src/states_screens/dialogs/registration_dialog.cpp +src/states_screens/dialogs/select_challenge.cpp +src/states_screens/dialogs/server_info_dialog.cpp +src/states_screens/dialogs/track_info_dialog.cpp +src/states_screens/dialogs/tutorial_message_dialog.cpp +src/states_screens/dialogs/user_info_dialog.cpp +src/states_screens/dialogs/vote_dialog.cpp +src/states_screens/easter_egg_screen.cpp +src/states_screens/feature_unlocked.cpp +src/states_screens/grand_prix_lose.cpp +src/states_screens/grand_prix_win.cpp +src/states_screens/help_screen_1.cpp +src/states_screens/help_screen_2.cpp +src/states_screens/help_screen_3.cpp +src/states_screens/help_screen_4.cpp +src/states_screens/kart_selection.cpp +src/states_screens/main_menu_screen.cpp +src/states_screens/networking_lobby.cpp +src/states_screens/network_kart_selection.cpp +src/states_screens/offline_kart_selection.cpp +src/states_screens/online_profile_achievements.cpp +src/states_screens/online_profile_base.cpp +src/states_screens/online_profile_friends.cpp +src/states_screens/online_profile_overview.cpp +src/states_screens/online_profile_settings.cpp +src/states_screens/online_screen.cpp +src/states_screens/online_user_search.cpp +src/states_screens/options_screen_audio.cpp +src/states_screens/options_screen_input2.cpp +src/states_screens/options_screen_input.cpp +src/states_screens/options_screen_players.cpp +src/states_screens/options_screen_ui.cpp +src/states_screens/options_screen_video.cpp +src/states_screens/race_gui_base.cpp +src/states_screens/race_gui.cpp +src/states_screens/race_gui_overworld.cpp +src/states_screens/race_result_gui.cpp +src/states_screens/race_setup_screen.cpp +src/states_screens/server_selection.cpp +src/states_screens/soccer_setup_screen.cpp +src/states_screens/state_manager.cpp +src/states_screens/story_mode_lobby.cpp +src/states_screens/tracks_screen.cpp +src/tinygettext/dictionary.cpp +src/tinygettext/dictionary_manager.cpp +src/tinygettext/iconv.cpp +src/tinygettext/language.cpp +src/tinygettext/plural_forms.cpp +src/tinygettext/po_parser.cpp +src/tinygettext/stk_file_system.cpp +src/tinygettext/tgt_log.cpp +src/tinygettext/tinygettext.cpp +src/tracks/ambient_light_sphere.cpp +src/tracks/bezier_curve.cpp +src/tracks/check_cannon.cpp +src/tracks/check_goal.cpp +src/tracks/check_lap.cpp +src/tracks/check_line.cpp +src/tracks/check_manager.cpp +src/tracks/check_sphere.cpp +src/tracks/check_structure.cpp +src/tracks/graph_node.cpp +src/tracks/lod_node_loader.cpp +src/tracks/quad.cpp +src/tracks/quad_graph.cpp +src/tracks/quad_set.cpp +src/tracks/terrain_info.cpp +src/tracks/track.cpp +src/tracks/track_manager.cpp +src/tracks/track_object.cpp +src/tracks/track_object_manager.cpp +src/tracks/track_object_presentation.cpp +src/tracks/track_sector.cpp +src/utils/command_line.cpp +src/utils/constants.cpp +src/utils/crash_reporting.cpp +src/utils/debug.cpp +src/utils/helpers.cpp +src/utils/leak_check.cpp +src/utils/log.cpp +src/utils/profiler.cpp +src/utils/random_generator.cpp +src/utils/string_utils.cpp +src/utils/time.cpp +src/utils/translation.cpp +src/utils/vec3.cpp +) +set(STK_HEADERS +src/achievements/achievement.hpp +src/achievements/achievement_info.hpp +src/achievements/achievements_manager.hpp +src/achievements/achievements_slot.hpp +src/addons/addon.hpp +src/addons/addons_manager.hpp +src/addons/dummy_network_http.hpp +src/addons/inetwork_http.hpp +src/addons/network_http.hpp +src/addons/news_manager.hpp +src/addons/request.hpp +src/addons/zip.hpp +src/animations/animation_base.hpp +src/animations/ipo.hpp +src/animations/three_d_animation.hpp +src/audio/dummy_sfx.hpp +src/audio/music_dummy.hpp +src/audio/music.hpp +src/audio/music_information.hpp +src/audio/music_manager.hpp +src/audio/music_ogg.hpp +src/audio/sfx_base.hpp +src/audio/sfx_buffer.hpp +src/audio/sfx_manager.hpp +src/audio/sfx_openal.hpp +src/challenges/challenge_data.hpp +src/challenges/challenge.hpp +src/challenges/game_slot.hpp +src/challenges/unlock_manager.hpp +src/config/device_config.hpp +src/config/player.hpp +src/config/saved_grand_prix.hpp +src/config/stk_config.hpp +src/config/user_config.hpp +src/graphics/callbacks.hpp +src/graphics/camera.hpp +src/graphics/CBatchingMesh.hpp +src/graphics/explosion.hpp +src/graphics/glow.hpp +src/graphics/glwrap.hpp +src/graphics/hardware_skinning.hpp +src/graphics/hit_effect.hpp +src/graphics/hit_sfx.hpp +src/graphics/irr_driver.hpp +src/graphics/large_mesh_buffer.hpp +src/graphics/lens_flare.hpp +src/graphics/light.hpp +src/graphics/lod_node.hpp +src/graphics/material.hpp +src/graphics/material_manager.hpp +src/graphics/mesh_tools.hpp +src/graphics/mlaa_areamap.hpp +src/graphics/moving_texture.hpp +src/graphics/particle_emitter.hpp +src/graphics/particle_kind.hpp +src/graphics/particle_kind_manager.hpp +src/graphics/per_camera_node.hpp +src/graphics/post_processing.hpp +src/graphics/rain.hpp +src/graphics/referee.hpp +src/graphics/rtts.hpp +src/graphics/screenquad.hpp +src/graphics/shaders.hpp +src/graphics/shadow.hpp +src/graphics/shadow_importance.hpp +src/graphics/show_curve.hpp +src/graphics/skid_marks.hpp +src/graphics/slip_stream.hpp +src/graphics/stars.hpp +src/graphics/stkmesh.hpp +src/graphics/sun.hpp +src/graphics/water.hpp +src/graphics/wind.hpp +src/guiengine/abstract_state_manager.hpp +src/guiengine/abstract_top_level_container.hpp +src/guiengine/dialog_queue.hpp +src/guiengine/engine.hpp +src/guiengine/event_handler.hpp +src/guiengine/layout_manager.hpp +src/guiengine/modaldialog.hpp +src/guiengine/scalable_font.hpp +src/guiengine/screen.hpp +src/guiengine/skin.hpp +src/guiengine/widget.hpp +src/guiengine/widgets/bubble_widget.hpp +src/guiengine/widgets/button_widget.hpp +src/guiengine/widgets/check_box_widget.hpp +src/guiengine/widgets/dynamic_ribbon_widget.hpp +src/guiengine/widgets.hpp +src/guiengine/widgets/icon_button_widget.hpp +src/guiengine/widgets/label_widget.hpp +src/guiengine/widgets/list_widget.hpp +src/guiengine/widgets/model_view_widget.hpp +src/guiengine/widgets/progress_bar_widget.hpp +src/guiengine/widgets/rating_bar_widget.hpp +src/guiengine/widgets/ribbon_widget.hpp +src/guiengine/widgets/spinner_widget.hpp +src/guiengine/widgets/text_box_widget.hpp +src/input/binding.hpp +src/input/device_manager.hpp +src/input/input_device.hpp +src/input/input.hpp +src/input/input_manager.hpp +src/input/wiimote.hpp +src/input/wiimote_manager.hpp +src/io/file_manager.hpp +src/io/xml_node.hpp +src/io/xml_writer.hpp +src/items/attachment.hpp +src/items/attachment_manager.hpp +src/items/attachment_plugin.hpp +src/items/bowling.hpp +src/items/cake.hpp +src/items/flyable.hpp +src/items/item.hpp +src/items/item_manager.hpp +src/items/plunger.hpp +src/items/powerup.hpp +src/items/powerup_manager.hpp +src/items/projectile_manager.hpp +src/items/rubber_ball.hpp +src/items/rubber_band.hpp +src/items/swatter.hpp +src/karts/abstract_kart_animation.hpp +src/karts/abstract_kart.hpp +src/karts/cannon_animation.hpp +src/karts/controller/ai_base_controller.hpp +src/karts/controller/ai_properties.hpp +src/karts/controller/controller.hpp +src/karts/controller/end_controller.hpp +src/karts/controller/kart_control.hpp +src/karts/controller/network_player_controller.hpp +src/karts/controller/player_controller.hpp +src/karts/controller/skidding_ai.hpp +src/karts/explosion_animation.hpp +src/karts/ghost_kart.hpp +src/karts/kart_gfx.hpp +src/karts/kart.hpp +src/karts/kart_model.hpp +src/karts/kart_properties.hpp +src/karts/kart_properties_manager.hpp +src/karts/kart_with_stats.hpp +src/karts/max_speed.hpp +src/karts/moveable.hpp +src/karts/rescue_animation.hpp +src/karts/skidding.hpp +src/karts/skidding_properties.hpp +src/main_loop.hpp +src/modes/cutscene_world.hpp +src/modes/demo_world.hpp +src/modes/easter_egg_hunt.hpp +src/modes/follow_the_leader.hpp +src/modes/linear_world.hpp +src/modes/overworld.hpp +src/modes/profile_world.hpp +src/modes/soccer_world.hpp +src/modes/standard_race.hpp +src/modes/three_strikes_battle.hpp +src/modes/tutorial_world.hpp +src/modes/world.hpp +src/modes/world_status.hpp +src/modes/world_with_rank.hpp +src/network/client_network_manager.hpp +src/network/event.hpp +src/network/game_setup.hpp +src/network/network_interface.hpp +src/network/network_manager.hpp +src/network/network_string.hpp +src/network/network_world.hpp +src/network/protocol.hpp +src/network/protocol_manager.hpp +src/network/protocols/client_lobby_room_protocol.hpp +src/network/protocols/connect_to_peer.hpp +src/network/protocols/connect_to_server.hpp +src/network/protocols/controller_events_protocol.hpp +src/network/protocols/game_events_protocol.hpp +src/network/protocols/get_peer_address.hpp +src/network/protocols/get_public_address.hpp +src/network/protocols/hide_public_address.hpp +src/network/protocols/kart_update_protocol.hpp +src/network/protocols/lobby_room_protocol.hpp +src/network/protocols/ping_protocol.hpp +src/network/protocols/quick_join_protocol.hpp +src/network/protocols/request_connection.hpp +src/network/protocols/server_lobby_room_protocol.hpp +src/network/protocols/show_public_address.hpp +src/network/protocols/start_game_protocol.hpp +src/network/protocols/start_server.hpp +src/network/protocols/stop_server.hpp +src/network/protocols/synchronization_protocol.hpp +src/network/race_config.hpp +src/network/remote_kart_info.hpp +src/network/server_network_manager.hpp +src/network/singleton.hpp +src/network/stk_host.hpp +src/network/stk_peer.hpp +src/network/types.hpp +src/online/current_user.hpp +src/online/http_request.hpp +src/online/messages.hpp +src/online/profile.hpp +src/online/profile_manager.hpp +src/online/request.hpp +src/online/request_manager.hpp +src/online/server.hpp +src/online/servers_manager.hpp +src/online/xml_request.hpp +src/physics/btKart.hpp +src/physics/btKartRaycast.hpp +src/physics/btUprightConstraint.hpp +src/physics/irr_debug_drawer.hpp +src/physics/kart_motion_state.hpp +src/physics/physical_object.hpp +src/physics/physics.hpp +src/physics/stk_dynamics_world.hpp +src/physics/triangle_mesh.hpp +src/physics/user_pointer.hpp +src/race/grand_prix_data.hpp +src/race/grand_prix_manager.hpp +src/race/highscore_manager.hpp +src/race/highscores.hpp +src/race/history.hpp +src/race/race_manager.hpp +src/replay/replay_base.hpp +src/replay/replay_play.hpp +src/replay/replay_recorder.hpp +src/states_screens/addons_screen.hpp +src/states_screens/arenas_screen.hpp +src/states_screens/create_server_screen.hpp +src/states_screens/credits.hpp +src/states_screens/cutscene_gui.hpp +src/states_screens/dialogs/add_device_dialog.hpp +src/states_screens/dialogs/addons_loading.hpp +src/states_screens/dialogs/change_password_dialog.hpp +src/states_screens/dialogs/confirm_resolution_dialog.hpp +src/states_screens/dialogs/custom_video_settings.hpp +src/states_screens/dialogs/enter_player_name_dialog.hpp +src/states_screens/dialogs/gp_info_dialog.hpp +src/states_screens/dialogs/login_dialog.hpp +src/states_screens/dialogs/message_dialog.hpp +src/states_screens/dialogs/notification_dialog.hpp +src/states_screens/dialogs/player_info_dialog.hpp +src/states_screens/dialogs/press_a_key_dialog.hpp +src/states_screens/dialogs/race_paused_dialog.hpp +src/states_screens/dialogs/recovery_dialog.hpp +src/states_screens/dialogs/registration_dialog.hpp +src/states_screens/dialogs/select_challenge.hpp +src/states_screens/dialogs/server_info_dialog.hpp +src/states_screens/dialogs/track_info_dialog.hpp +src/states_screens/dialogs/tutorial_message_dialog.hpp +src/states_screens/dialogs/user_info_dialog.hpp +src/states_screens/dialogs/vote_dialog.hpp +src/states_screens/easter_egg_screen.hpp +src/states_screens/feature_unlocked.hpp +src/states_screens/grand_prix_lose.hpp +src/states_screens/grand_prix_win.hpp +src/states_screens/help_screen_1.hpp +src/states_screens/help_screen_2.hpp +src/states_screens/help_screen_3.hpp +src/states_screens/help_screen_4.hpp +src/states_screens/kart_selection.hpp +src/states_screens/main_menu_screen.hpp +src/states_screens/networking_lobby.hpp +src/states_screens/network_kart_selection.hpp +src/states_screens/offline_kart_selection.hpp +src/states_screens/online_profile_achievements.hpp +src/states_screens/online_profile_base.hpp +src/states_screens/online_profile_friends.hpp +src/states_screens/online_profile_overview.hpp +src/states_screens/online_profile_settings.hpp +src/states_screens/online_screen.hpp +src/states_screens/online_user_search.hpp +src/states_screens/options_screen_audio.hpp +src/states_screens/options_screen_input2.hpp +src/states_screens/options_screen_input.hpp +src/states_screens/options_screen_players.hpp +src/states_screens/options_screen_ui.hpp +src/states_screens/options_screen_video.hpp +src/states_screens/race_gui_base.hpp +src/states_screens/race_gui.hpp +src/states_screens/race_gui_overworld.hpp +src/states_screens/race_result_gui.hpp +src/states_screens/race_setup_screen.hpp +src/states_screens/server_selection.hpp +src/states_screens/soccer_setup_screen.hpp +src/states_screens/state_manager.hpp +src/states_screens/story_mode_lobby.hpp +src/states_screens/tracks_screen.hpp +src/tinygettext/dictionary.hpp +src/tinygettext/dictionary_manager.hpp +src/tinygettext/file_system.hpp +src/tinygettext/iconv.hpp +src/tinygettext/language.hpp +src/tinygettext/log_stream.hpp +src/tinygettext/plural_forms.hpp +src/tinygettext/po_parser.hpp +src/tinygettext/stk_file_system.hpp +src/tinygettext/tgt_log.hpp +src/tinygettext/tinygettext.hpp +src/tracks/ambient_light_sphere.hpp +src/tracks/bezier_curve.hpp +src/tracks/check_cannon.hpp +src/tracks/check_goal.hpp +src/tracks/check_lap.hpp +src/tracks/check_line.hpp +src/tracks/check_manager.hpp +src/tracks/check_sphere.hpp +src/tracks/check_structure.hpp +src/tracks/graph_node.hpp +src/tracks/lod_node_loader.hpp +src/tracks/quad_graph.hpp +src/tracks/quad.hpp +src/tracks/quad_set.hpp +src/tracks/terrain_info.hpp +src/tracks/track.hpp +src/tracks/track_manager.hpp +src/tracks/track_object.hpp +src/tracks/track_object_manager.hpp +src/tracks/track_object_presentation.hpp +src/tracks/track_sector.hpp +src/utils/aligned_array.hpp +src/utils/command_line.hpp +src/utils/constants.hpp +src/utils/crash_reporting.hpp +src/utils/debug.hpp +src/utils/helpers.hpp +src/utils/interpolation_array.hpp +src/utils/leak_check.hpp +src/utils/log.hpp +src/utils/no_copy.hpp +src/utils/profiler.hpp +src/utils/ptr_vector.hpp +src/utils/random_generator.hpp +src/utils/string_utils.hpp +src/utils/synchronised.hpp +src/utils/time.hpp +src/utils/translation.hpp +src/utils/types.hpp +src/utils/vec3.hpp +src/utils/vs.hpp +) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 133e88b62..de3600af1 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -32,6 +32,7 @@ #include "graphics/referee.hpp" #include "graphics/shaders.hpp" #include "graphics/shadow_importance.hpp" +#include "graphics/stkmesh.hpp" #include "graphics/sun.hpp" #include "graphics/rtts.hpp" #include "graphics/water.hpp" @@ -902,7 +903,16 @@ scene::IParticleSystemSceneNode *IrrDriver::addParticleNode(bool default_emitter scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh, scene::ISceneNode *parent) { - return m_scene_manager->addMeshSceneNode(mesh, parent); + if (!isGLSL()) + return m_scene_manager->addMeshSceneNode(mesh, parent); + + if (!parent) + parent = m_scene_manager->getRootSceneNode(); + + scene::IMeshSceneNode* node = new STKMesh(mesh, parent, m_scene_manager, -1); + node->drop(); + + return node; } // addMesh // ---------------------------------------------------------------------------- diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp new file mode 100644 index 000000000..8841d150a --- /dev/null +++ b/src/graphics/stkmesh.cpp @@ -0,0 +1,15 @@ +#include "stkmesh.hpp" + +STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, + const irr::core::vector3df& position, + const irr::core::vector3df& rotation, + const irr::core::vector3df& scale) : + CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale) +{ + +} + +void STKMesh::render() +{ + CMeshSceneNode::render(); +} diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp new file mode 100644 index 000000000..ae2e6999d --- /dev/null +++ b/src/graphics/stkmesh.hpp @@ -0,0 +1,19 @@ +#ifndef STKMESH_H +#define STKMESH_H + + +#include +#include +#include "../lib/irrlicht/source/Irrlicht/CMeshSceneNode.h" + +class STKMesh : public irr::scene::CMeshSceneNode +{ +public: + STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, + const irr::core::vector3df& position = irr::core::vector3df(0,0,0), + const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0), + const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f)); + virtual void render(); +}; + +#endif // STKMESH_H diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index e1f805678..597492e98 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -818,8 +818,8 @@ bool Track::loadMainTrack(const XMLNode &root) // The merged mesh is grabbed by the octtree, so we don't need // to keep a reference to it. - //scene::ISceneNode *scene_node = irr_driver->addMesh(merged_mesh); - scene::IMeshSceneNode *scene_node = irr_driver->addOctTree(merged_mesh); + scene::ISceneNode *scene_node = irr_driver->addMesh(merged_mesh); + //scene::IMeshSceneNode *scene_node = irr_driver->addOctTree(merged_mesh); // We should drop the merged mesh (since it's now referred to in the // scene node), but then we need to grab it since it's in the // m_all_cached_meshes. From 2aea7a26240ed193a983b17ce16afa426fb8caf5 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Fri, 10 Jan 2014 22:10:21 +0000 Subject: [PATCH 228/412] STKMesh: Add some code that just mimic CMeshNode behavior git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14998 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/stkmesh.cpp | 44 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 8841d150a..901e1923d 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -1,4 +1,8 @@ #include "stkmesh.hpp" +#include "graphics/irr_driver.hpp" +#include +#include +#include "glwrap.hpp" STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position, @@ -6,10 +10,46 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene const irr::core::vector3df& scale) : CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale) { - + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) + continue; + } } void STKMesh::render() { - CMeshSceneNode::render(); + irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); + + if (!Mesh || !driver) + return; + + bool isTransparentPass = + SceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT; + + ++PassCount; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + Box = Mesh->getBoundingBox(); + + for (u32 i=0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (mb) + { + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent == isTransparentPass) + { + driver->setMaterial(material); + driver->drawMeshBuffer(mb); + } + } + } } From d255f4f049ad61b2cba452dc99a6e29d63b3c487 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 11 Jan 2014 18:12:04 +0000 Subject: [PATCH 229/412] STKMesh: Some more code to load vertex data, but rendering is still using old path git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14999 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/stkmesh.cpp | 99 +++++++++++++++++++++++++++++++++++++++- src/graphics/stkmesh.hpp | 9 ++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 901e1923d..0596a64ae 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -2,7 +2,54 @@ #include "graphics/irr_driver.hpp" #include #include -#include "glwrap.hpp" + +static +void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint idx) +{ + GLuint bufferid, indexbufferid; + glGenBuffers(1, &bufferid); + glGenBuffers(1, &indexbufferid); + + glBindBuffer(GL_ARRAY_BUFFER, bufferid); + const void* vertices=mb->getVertices(); + const u32 vertexCount=mb->getVertexCount(); + const irr::video::E_VERTEX_TYPE vType=mb->getVertexType(); + const u32 vertexSize = getVertexPitchFromType(vType); + const c8* vbuf = static_cast(vertices); + core::array buffer; + buffer.set_used(vertexSize * vertexCount); + memcpy(buffer.pointer(), vertices, vertexSize * vertexCount); + vbuf = buffer.const_pointer(); + glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbufferid); + const void* indices=mb->getIndices(); + u32 indexCount= mb->getIndexCount(); + GLenum indexSize; + switch (mb->getIndexType()) + { + case irr::video::EIT_16BIT: + { + indexSize=sizeof(u16); + break; + } + case irr::video::EIT_32BIT: + { + indexSize=sizeof(u32); + break; + } + default: + { + assert(0 && "Wrong index size"); + } + } + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + vbo = bufferid; + idx = indexbufferid; +} STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position, @@ -15,9 +62,59 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; + GLuint vbo, idx; + allocateMeshBuffer(mb, vbo, idx); + vertex_buffer.push_back(vbo); + index_buffer.push_back(idx); + Indexcount.push_back(mb->getIndexCount()); + switch (mb->getPrimitiveType()) + { + case scene::EPT_POINTS: + Primitivetype.push_back(GL_POINTS); + break; + case scene::EPT_TRIANGLE_STRIP: + Primitivetype.push_back(GL_TRIANGLE_STRIP); + break; + case scene::EPT_TRIANGLE_FAN: + Primitivetype.push_back(GL_TRIANGLE_FAN); + break; + case scene::EPT_LINES: + Primitivetype.push_back(GL_LINES); + case scene::EPT_TRIANGLES: + Primitivetype.push_back(GL_TRIANGLES); + break; + case scene::EPT_POINT_SPRITES: + case scene::EPT_LINE_LOOP: + case scene::EPT_POLYGON: + case scene::EPT_LINE_STRIP: + case scene::EPT_QUAD_STRIP: + case scene::EPT_QUADS: + assert(0 && "Unsupported primitive type"); + } } } +STKMesh::~STKMesh() +{ + glDeleteBuffers(vertex_buffer.size(), vertex_buffer.data()); + glDeleteBuffers(index_buffer.size(), index_buffer.data()); +} + +void STKMesh::draw(unsigned i) +{ + GLuint vbo = vertex_buffer[i], idx = index_buffer[i]; + GLenum ptype = Primitivetype[i]; + size_t count = Indexcount[i]; + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); + +/* glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12)); + glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0));*/ + glDrawElements(ptype, count, GL_UNSIGNED_BYTE, 0); +} + void STKMesh::render() { irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index ae2e6999d..06dccd28f 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -5,15 +5,24 @@ #include #include #include "../lib/irrlicht/source/Irrlicht/CMeshSceneNode.h" +#include "glwrap.hpp" +#include class STKMesh : public irr::scene::CMeshSceneNode { +protected: + std::vector vertex_buffer, index_buffer; + std::vector Primitivetype; + std::vector Indexcount; + + void draw(unsigned i); public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), const irr::core::vector3df& rotation = irr::core::vector3df(0,0,0), const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f)); virtual void render(); + ~STKMesh(); }; #endif // STKMESH_H From 15dc149799d39b966a9ea474bc4bc83070af4561 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 11 Jan 2014 22:57:48 +0000 Subject: [PATCH 230/412] STKMesh: Rendering implemented although it's a big red shader git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15000 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/object.frag | 8 +++++++ data/shaders/object.vert | 9 ++++++++ src/graphics/stkmesh.cpp | 49 ++++++++++++++++++++++++++++++++++++---- src/graphics/stkmesh.hpp | 1 + 4 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 data/shaders/object.frag create mode 100644 data/shaders/object.vert diff --git a/data/shaders/object.frag b/data/shaders/object.frag new file mode 100644 index 000000000..9508ea42d --- /dev/null +++ b/data/shaders/object.frag @@ -0,0 +1,8 @@ +#version 130 + +void main(void) +{ + gl_FragData[0] = vec4(1., 0., 0., 1.); + gl_FragData[1] = vec4(0., 0., 0., 1.); + gl_FragData[2] = vec4(0., 0., 0., 1.); +} diff --git a/data/shaders/object.vert b/data/shaders/object.vert new file mode 100644 index 000000000..c44aa7192 --- /dev/null +++ b/data/shaders/object.vert @@ -0,0 +1,9 @@ +#version 130 +uniform mat4 ModelViewProjectionMatrix; + +in vec3 Position; + +void main(void) +{ + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); +} diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 0596a64ae..059d3826c 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -3,9 +3,23 @@ #include #include +namespace ObjectShader +{ + GLuint Program; + GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; + GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/object.frag").c_str()); + } +} + static void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint idx) { + initGL(); GLuint bufferid, indexbufferid; glGenBuffers(1, &bufferid); glGenBuffers(1, &indexbufferid); @@ -91,7 +105,21 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene case scene::EPT_QUADS: assert(0 && "Unsupported primitive type"); } + switch (mb->getVertexType()) + { + case video::EVT_STANDARD: + Stride.push_back(sizeof(video::S3DVertex)); + break; + case video::EVT_2TCOORDS: + Stride.push_back(sizeof(video::S3DVertex2TCoords)); + break; + case video::EVT_TANGENTS: + Stride.push_back(sizeof(video::S3DVertexTangents)); + break; + } } + if (!ObjectShader::Program) + ObjectShader::init(); } STKMesh::~STKMesh() @@ -108,11 +136,18 @@ void STKMesh::draw(unsigned i) glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); -/* glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12)); - glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); - glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); - glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0));*/ + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + GLuint attrib_pos = glGetUniformLocation(ObjectShader::Program, "ModelViewProjectionMatrix"); + glUniformMatrix4fv(attrib_pos, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUseProgram(ObjectShader::Program); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); + glDisableVertexAttribArray(0); glDrawElements(ptype, count, GL_UNSIGNED_BYTE, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void STKMesh::render() @@ -130,6 +165,11 @@ void STKMesh::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); Box = Mesh->getBoundingBox(); + for (unsigned i = 0; i < index_buffer.size(); i++) + { +// draw(i); + } + for (u32 i=0; igetMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); @@ -145,6 +185,7 @@ void STKMesh::render() if (transparent == isTransparentPass) { driver->setMaterial(material); +// static_cast(driver)->setRenderStates3DMode(); driver->drawMeshBuffer(mb); } } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 06dccd28f..5d8666e9b 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -14,6 +14,7 @@ protected: std::vector vertex_buffer, index_buffer; std::vector Primitivetype; std::vector Indexcount; + std::vector Stride; void draw(unsigned i); public: From b5a99321692269e08ab3eb77e480c051cc00ef97 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sat, 11 Jan 2014 23:26:58 +0000 Subject: [PATCH 231/412] STKMesh: Forget to add byref modifier git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15001 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/stkmesh.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 059d3826c..5cde0bba5 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -17,7 +17,7 @@ namespace ObjectShader } static -void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint idx) +void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint &idx) { initGL(); GLuint bufferid, indexbufferid; @@ -130,24 +130,33 @@ STKMesh::~STKMesh() void STKMesh::draw(unsigned i) { + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_CULL_FACE); GLuint vbo = vertex_buffer[i], idx = index_buffer[i]; GLenum ptype = Primitivetype[i]; size_t count = Indexcount[i]; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + glUseProgram(ObjectShader::Program); + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); GLuint attrib_pos = glGetUniformLocation(ObjectShader::Program, "ModelViewProjectionMatrix"); glUniformMatrix4fv(attrib_pos, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUseProgram(ObjectShader::Program); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); - glDisableVertexAttribArray(0); glDrawElements(ptype, count, GL_UNSIGNED_BYTE, 0); + glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + video::SMaterial material; + material.MaterialType = irr_driver->getShader(ES_RAIN); +// fakemat.setTexture(0, tex); +// fakemat.BlendOperation = video::EBO_NONE; + irr_driver->getVideoDriver()->setMaterial(material); + static_cast(irr_driver->getVideoDriver())->setRenderStates3DMode(); } void STKMesh::render() @@ -185,7 +194,6 @@ void STKMesh::render() if (transparent == isTransparentPass) { driver->setMaterial(material); -// static_cast(driver)->setRenderStates3DMode(); driver->drawMeshBuffer(mb); } } From ebaec55f4d11a50bbf5df49be8238316ce76db05 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 00:26:18 +0000 Subject: [PATCH 232/412] STKMesh: Rendering works...sortof git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15002 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/object.frag | 4 +++- data/shaders/object.vert | 3 +++ src/graphics/stkmesh.cpp | 43 ++++++++++++++++++++++++++++++++-------- src/graphics/stkmesh.hpp | 4 ++-- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/data/shaders/object.frag b/data/shaders/object.frag index 9508ea42d..fc6c21b8d 100644 --- a/data/shaders/object.frag +++ b/data/shaders/object.frag @@ -1,8 +1,10 @@ #version 130 +uniform sampler2D texture; +in vec2 uv; void main(void) { - gl_FragData[0] = vec4(1., 0., 0., 1.); + gl_FragData[0] = texture2D(texture, uv); gl_FragData[1] = vec4(0., 0., 0., 1.); gl_FragData[2] = vec4(0., 0., 0., 1.); } diff --git a/data/shaders/object.vert b/data/shaders/object.vert index c44aa7192..7ba1d77d0 100644 --- a/data/shaders/object.vert +++ b/data/shaders/object.vert @@ -2,8 +2,11 @@ uniform mat4 ModelViewProjectionMatrix; in vec3 Position; +in vec2 Texcoord; +out vec2 uv; void main(void) { + uv = Texcoord; gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 5cde0bba5..5f815353a 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -6,13 +6,17 @@ namespace ObjectShader { GLuint Program; - GLuint attrib_position, attrib_velocity, attrib_lifetime, attrib_initial_position, attrib_initial_velocity, attrib_initial_lifetime, attrib_size, attrib_initial_size; - GLuint uniform_sourcematrix, uniform_dt, uniform_level, uniform_size_increase_factor; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_MVP, uniform_texture; void init() { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/object.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_texture = glGetUniformLocation(Program, "texture"); } } @@ -117,6 +121,20 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene Stride.push_back(sizeof(video::S3DVertexTangents)); break; } + switch (mb->getIndexType()) + { + case video::EIT_16BIT: + Indextype.push_back(GL_UNSIGNED_SHORT); + break; + case video::EIT_32BIT: + Indextype.push_back(GL_UNSIGNED_INT); + break; + } + ITexture *tex = mb->getMaterial().getTexture(0); + if (tex) + textures.push_back(static_cast(tex)->getOpenGLTextureName()); + else + textures.push_back(0); } if (!ObjectShader::Program) ObjectShader::init(); @@ -130,6 +148,8 @@ STKMesh::~STKMesh() void STKMesh::draw(unsigned i) { + if (!textures[i]) + return; glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDisable(GL_CULL_FACE); @@ -143,12 +163,19 @@ void STKMesh::draw(unsigned i) core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - GLuint attrib_pos = glGetUniformLocation(ObjectShader::Program, "ModelViewProjectionMatrix"); - glUniformMatrix4fv(attrib_pos, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); - glDrawElements(ptype, count, GL_UNSIGNED_BYTE, 0); - glDisableVertexAttribArray(0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textures[i]); + glUniform1f(ObjectShader::uniform_texture, 0); + glUniformMatrix4fv(ObjectShader::uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glEnableVertexAttribArray(ObjectShader::attrib_position); + glEnableVertexAttribArray(ObjectShader::attrib_texcoord); + glVertexAttribPointer(ObjectShader::attrib_position, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); + glVertexAttribPointer(ObjectShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, Stride[i], (GLvoid*) 28); + glDrawElements(ptype, count, Indextype[i], 0); + glDisableVertexAttribArray(ObjectShader::attrib_position); + glDisableVertexAttribArray(ObjectShader::attrib_texcoord); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); video::SMaterial material; diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 5d8666e9b..f406a4b9c 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -11,8 +11,8 @@ class STKMesh : public irr::scene::CMeshSceneNode { protected: - std::vector vertex_buffer, index_buffer; - std::vector Primitivetype; + std::vector vertex_buffer, index_buffer, textures; + std::vector Primitivetype, Indextype; std::vector Indexcount; std::vector Stride; From b136e16f7a59d4b1e52b54a0104606b0dd486e4a Mon Sep 17 00:00:00 2001 From: hikerstk Date: Sun, 12 Jan 2014 11:20:32 +0000 Subject: [PATCH 235/412] Preparation to remove network_http (its work will be taken over by the reqeust manager). Initialise news and addons manager in a separate thread and not from the network_http thread anymore. Icons are also downloaded now from the request manager instead of the network_http. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15006 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/addons/addons_manager.cpp | 109 +++++++++++++--- src/addons/addons_manager.hpp | 5 +- src/addons/network_http.cpp | 95 +------------- src/addons/network_http.hpp | 6 +- src/addons/news_manager.cpp | 163 ++++++++++++++++++++++-- src/addons/news_manager.hpp | 36 +++++- src/main.cpp | 8 +- src/online/http_request.cpp | 162 +++++++++++++++++------ src/online/http_request.hpp | 54 ++++++-- src/online/request.cpp | 8 ++ src/online/request.hpp | 1 + src/online/request_manager.cpp | 6 +- src/online/xml_request.cpp | 4 +- src/states_screens/main_menu_screen.cpp | 4 +- 14 files changed, 460 insertions(+), 201 deletions(-) diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index d44deafb9..265f919db 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -20,6 +20,21 @@ #include "addons/addons_manager.hpp" +#include "addons/inetwork_http.hpp" +#include "addons./news_manager.hpp" +#include "addons/zip.hpp" +#include "io/file_manager.hpp" +#include "io/xml_node.hpp" +#include "karts/kart_properties.hpp" +#include "karts/kart_properties_manager.hpp" +#include "online/http_request.hpp" +#include "online/request_manager.hpp" +#include "states_screens/kart_selection.hpp" +#include "tracks/track.hpp" +#include "tracks/track_manager.hpp" +#include "utils/string_utils.hpp" + + #include #include #include @@ -27,18 +42,6 @@ #include #include -#include "addons/inetwork_http.hpp" -#include "addons/request.hpp" -#include "addons/zip.hpp" -#include "io/file_manager.hpp" -#include "io/xml_node.hpp" -#include "karts/kart_properties.hpp" -#include "karts/kart_properties_manager.hpp" -#include "states_screens/kart_selection.hpp" -#include "tracks/track.hpp" -#include "tracks/track_manager.hpp" -#include "utils/string_utils.hpp" - AddonsManager* addons_manager = 0; // ---------------------------------------------------------------------------- @@ -68,6 +71,59 @@ AddonsManager::~AddonsManager() saveInstalled(); } // ~AddonsManager +// ---------------------------------------------------------------------------- +void AddonsManager::init(const XMLNode *xml, + bool force_refresh) +{ + std::string addon_list_url(""); + StkTime::TimeType mtime(0); + const XMLNode *include = xml->getNode("include"); + std::string filename=file_manager->getAddonsFile("addons.xml"); + if(!include) + { + file_manager->removeFile(filename); + NewsManager::get()->addNewsMessage(_("Can't access stkaddons server...")); + // Use a curl error code here: + //return CURLE_COULDNT_CONNECT; + return; + } + + include->get("file", &addon_list_url); + + int64_t tmp; + include->get("mtime", &tmp); + mtime = tmp; + + bool download = mtime > UserConfigParams::m_addons_last_updated || + force_refresh || + !file_manager->fileExists(filename); + + if (download) + { + Log::info("NetworkHttp", "Downloading updated addons.xml"); + Online::HTTPRequest *download_request = new Online::HTTPRequest("addons.xml"); + download_request->setURL(addon_list_url); + download_request->executeNow(); + if(download_request->hadDownloadError()) + { + Log::error("addons", "Error on download addons.xml: %s\n", + download_request->getDownloadErrorMessage()); + delete download_request; + return; + } + delete download_request; + UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch(); + } + else + Log::info("NetworkHttp", "Using cached addons.xml"); + + const XMLNode *xml_addons = new XMLNode(filename); + addons_manager->initAddons(xml_addons); // will free xml_addons + if(UserConfigParams::logAddons()) + Log::info("addons", "Addons manager list downloaded"); + + +} // ---------------------------------------------------------------------------- /** This initialises the online portion of the addons manager. It uses the * downloaded list of available addons. This is called by network_http before @@ -76,7 +132,7 @@ AddonsManager::~AddonsManager() * main GUI is not blocked anyway). This function will update the state * variable */ -void AddonsManager::initOnline(const XMLNode *xml) +void AddonsManager::initAddons(const XMLNode *xml) { m_addons_list.lock(); // Clear the list in case that a reinit is being done. @@ -204,7 +260,7 @@ void AddonsManager::initOnline(const XMLNode *xml) if (UserConfigParams::m_internet_status == INetworkHttp::IPERM_ALLOWED) downloadIcons(); -} // initOnline +} // initAddons // ---------------------------------------------------------------------------- /** Reinitialises the addon manager, which happens when the user selects @@ -297,12 +353,25 @@ void AddonsManager::downloadIcons() addon.getId().c_str()); continue; } - std::string save = "icons/"+icon; - Request *r = INetworkHttp::get()->downloadFileAsynchron(url, save, - /*priority*/1, - /*manage_mem*/true); - if (r != NULL) - r->setAddonIconNotification(&addon); + + // A simple class that will notify the addon via a callback + class IconRequest : public Online::HTTPRequest + { + Addon *m_addon; // stores this addon object + void afterOperation() + { + m_addon->setIconReady(); + } // callback + public: + IconRequest(const std::string &filename, + const std::string &url, + Addon *addon ) : HTTPRequest(filename, true, 1) + { + m_addon = addon; setURL(url); + } // IconRequest + }; + IconRequest *r = new IconRequest("icons/"+icon, url, &addon); + r->queue(); } else m_addons_list.getData()[i].setIconReady(); diff --git a/src/addons/addons_manager.hpp b/src/addons/addons_manager.hpp index e5d90bdf8..075a4a07f 100644 --- a/src/addons/addons_manager.hpp +++ b/src/addons/addons_manager.hpp @@ -39,8 +39,6 @@ private: Synchronised > m_addons_list; /** Full filename of the addons_installed.xml file. */ std::string m_file_installed; - std::string m_type; - int m_download_state; /** List of loaded icons. */ std::vector m_icon_list; @@ -60,7 +58,8 @@ private: public: AddonsManager(); ~AddonsManager(); - void initOnline(const XMLNode *xml); + void init(const XMLNode *xml, bool force_refresh); + void initAddons(const XMLNode *xml); void checkInstalledAddons(); const Addon* getAddon(const std::string &id) const; int getAddonIndex(const std::string &id) const; diff --git a/src/addons/network_http.cpp b/src/addons/network_http.cpp index 33b240bab..b0fec6e73 100644 --- a/src/addons/network_http.cpp +++ b/src/addons/network_http.cpp @@ -256,102 +256,19 @@ NetworkHttp::~NetworkHttp() */ CURLcode NetworkHttp::init(bool forceRefresh) { - news_manager->clearErrorMessage(); - core::stringw error_message(""); - // The news message must be updated if either it has never been updated, - // or if the time of the last update was more than news_frequency ago. - bool download = UserConfigParams::m_news_last_updated==0 || - UserConfigParams::m_news_last_updated - +UserConfigParams::m_news_frequency - < StkTime::getTimeSinceEpoch() || forceRefresh; - - if(!download) - { - // If there is no old news message file, force a new download - std::string xml_file = file_manager->getAddonsFile("news.xml"); - if(!file_manager->fileExists(xml_file)) - download=true; - } - - // Initialise the online portion of the addons manager. - if(download && UserConfigParams::logAddons()) - Log::info("addons", "Downloading list."); - - Request r(Request::HC_DOWNLOAD_FILE, 9999, false, - "news.xml", "news.xml"); - CURLcode status = download ? downloadFileInternal(&r) - : CURLE_OK; - if(download && - status==CURLE_COULDNT_RESOLVE_HOST) - { - // Assume that the server address is wrong. And retry - // with the default server address again (just in case - // that a redirect went wrong, or a wrong/incorrect - // address somehow made its way into the config file. - UserConfigParams::m_server_addons.revertToDefaults(); - status = downloadFileInternal(&r); - } - - if(status==CURLE_OK) - { - std::string xml_file = file_manager->getAddonsFile("news.xml"); - if(download) - UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch(); - const XMLNode *xml = new XMLNode(xml_file); - - // A proper news file has at least a version number, mtime, and - // frequency defined. If this is not the case, assume that - // it's an invalid download. Try downloading again after - // resetting the news server back to the default. - int version=-1; - if( !xml->get("version", &version) || version!=1 || - !xml->get("mtime", &version) || - !xml->get("frequency", &version) ) - { - UserConfigParams::m_server_addons.revertToDefaults(); - status = downloadFileInternal(&r); - if(status==CURLE_OK) - UserConfigParams::m_news_last_updated = - StkTime::getTimeSinceEpoch(); - delete xml; - xml = new XMLNode(xml_file); - } - news_manager->init(); +#ifdef xx status = loadAddonsList(xml, xml_file, forceRefresh); - delete xml; - if(status==CURLE_OK) - { - return status; - } - else - { - // This message must be translated dynamically in the main menu. - // If it would be translated here, it wouldn't be translated - // if the language is changed in the menu! - error_message= - N_("Can't download addons list, check terminal for details."); - } - // Now fall through to error handling. - } - else - { - // This message must be translated dynamically in the main menu. - // If it would be translated here, it wouldn't be translated - // if the language is changed in the menu! - error_message= - N_("Can't download news file, check terminal for details."); - } - // Abort requested by stk -> display no error message and return + // Abort requested by stk -> display no error message and return if(status==CURLE_ABORTED_BY_CALLBACK) return status; - addons_manager->setErrorState(); - news_manager->setErrorMessage(error_message); if(UserConfigParams::logAddons()) Log::error("addons", "Error raised in NetworkHttp::init : %s", core::stringc(error_message).c_str()); return status; +#endif + return CURLE_OK; } // init // --------------------------------------------------------------------------- @@ -422,7 +339,7 @@ CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml, if(addon_list_url.size()==0) { file_manager->removeFile(filename); - news_manager->addNewsMessage(_("Can't access stkaddons server...")); + NewsManager::get()->addNewsMessage(_("Can't access stkaddons server...")); // Use a curl error code here: return CURLE_COULDNT_CONNECT; } @@ -451,7 +368,7 @@ CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml, if(download) UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch(); const XMLNode *xml = new XMLNode(xml_file); - addons_manager->initOnline(xml); +// addons_manager->initOnline(xml); if(UserConfigParams::logAddons()) Log::info("addons", "Addons manager list downloaded"); return status; diff --git a/src/addons/network_http.hpp b/src/addons/network_http.hpp index 5ea3d0f0d..d551acbb1 100644 --- a/src/addons/network_http.hpp +++ b/src/addons/network_http.hpp @@ -66,9 +66,6 @@ private: static void *mainLoop(void *obj); CURLcode init(bool forceRefresh); - CURLcode loadAddonsList(const XMLNode *xml, - const std::string &filename, - bool forceRefresh); CURLcode downloadFileInternal(Request *request); static int progressDownload(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); @@ -85,6 +82,9 @@ public: int priority = 1, bool manage_memory=true); void cancelAllDownloads(); + CURLcode loadAddonsList(const XMLNode *xml, + const std::string &filename, + bool forceRefresh); }; // NetworkHttp #endif diff --git a/src/addons/news_manager.cpp b/src/addons/news_manager.cpp index eadf6d7b1..0dec8bd0a 100644 --- a/src/addons/news_manager.cpp +++ b/src/addons/news_manager.cpp @@ -19,6 +19,7 @@ #include "config/user_config.hpp" #include "io/file_manager.hpp" +#include "online/http_request.hpp" #include "states_screens/addons_screen.hpp" #include "states_screens/main_menu_screen.hpp" #include "utils/string_utils.hpp" @@ -27,13 +28,14 @@ #include -NewsManager *news_manager=NULL; +NewsManager *NewsManager::m_news_manager=NULL; // ---------------------------------------------------------------------------- NewsManager::NewsManager() : m_news(std::vector()) { m_current_news_message = -1; - m_error_message = ""; + m_error_message.setAtomic(""); + init(false); } // NewsManage // --------------------------------------------------------------------------- @@ -41,6 +43,149 @@ NewsManager::~NewsManager() { } // ~NewsManager +// --------------------------------------------------------------------------- +/** This function initialises the data for the news manager. If necessary, + * it will use a separate thread to download the news.xml file. + */ +void NewsManager::init(bool force_refresh) +{ + // The rest (which potentially involves downloading news.xml) is handled + // in a separate thread, so that the GUI remains responsive. + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + // Should be the default, but just in case: + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + pthread_t thread_id; + int error = pthread_create(&thread_id, &attr, + &NewsManager::downloadNews, this); + if(error) + { + Log::warn("news", "Could not create thread, error=%d", errno); + // In this case just execute the downloading code with this thread + downloadNews(this); + } + pthread_attr_destroy(&attr); + +} //init + +// --------------------------------------------------------------------------- +/** This function submits request which will download the news.xml file + * if necessary. It is running in its own thread, so we can use blocking + * download calls without blocking the GUI. + * \param obj This is 'this' object, passed on during pthread creation. + */ +void* NewsManager::downloadNews(void *obj) +{ + bool force_refresh = false; + NewsManager *me = (NewsManager*)obj; + me->clearErrorMessage(); + + std::string xml_file = file_manager->getAddonsFile("news.xml"); + bool news_exists = file_manager->fileExists(xml_file); + + // The news message must be updated if either it has never been updated, + // or if the time of the last update was more than news_frequency ago, + // or because a 'refresh' was explicitly requested by the user, or no + // news.xml file exists. + bool download = UserConfigParams::m_news_last_updated==0 || + UserConfigParams::m_news_last_updated + +UserConfigParams::m_news_frequency + < StkTime::getTimeSinceEpoch() || + force_refresh || + !news_exists; + + const XMLNode *xml = NULL; + + if(!download) + { + // If (so far) we don't need to download, there should be an existing + // file. Try to read this, and do some basic checks + xml = new XMLNode(xml_file); + // A proper news file has at least a version number, mtime, frequency + // and an include node (which contains addon data) defined. If this is + // not the case, assume that it is an invalid download, or a corrupt + // local file. Try downloading again after resetting the news server + // back to the default. + int version=-1; + if( !xml->get("version", &version) || version!=1 || + !xml->get("mtime", &version) || + !xml->getNode("include") || + !xml->get("frequency", &version) ) + { + delete xml; + xml = NULL; + download = true; + } // if xml not consistemt + } // if !download + + if(download) + { + core::stringw error_message(""); + + Online::HTTPRequest *download_req = new Online::HTTPRequest("news.xml"); + download_req->setAddonsURL("news.xml"); + // Initialise the online portion of the addons manager. + if(UserConfigParams::logAddons()) + Log::info("addons", "Downloading news."); + download_req->executeNow(); + + if(download_req->hadDownloadError()) + { + // Assume that the server address is wrong. And retry + // with the default server address again (just in case + // that a redirect went wrong, or a wrong/incorrect + // address somehow made its way into the config file. + delete download_req; + // We need a new object, since the state of the old + // download request is now done. + download_req = new Online::HTTPRequest("news.xml"); + UserConfigParams::m_server_addons.revertToDefaults(); + // make sure the new server address is actually used + download_req->setAddonsURL("news.xml"); + download_req->executeNow(); + + if(download_req->hadDownloadError()) + { + // This message must be translated dynamically in the main menu. + // If it would be translated here, it wouldn't be translated + // if the language is changed in the menu! + error_message = N_("Error downloading news: '%s'."); + const char *const curl_error = download_req->getDownloadErrorMessage(); + error_message = StringUtils::insertValues(error_message, curl_error); + addons_manager->setErrorState(); + me->setErrorMessage(error_message); + Log::error("news", core::stringc(error_message).c_str()); + } // hadDownloadError + } // hadDownloadError + + if(!download_req->hadDownloadError()) + UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch(); + delete download_req; + + // No download error, update the last_updated time value, and delete + // the potentially loaded xml file + delete xml; + xml = NULL; + } // hadDownloadError + + // Process new.xml now. + if(file_manager->fileExists(xml_file)) + { + xml = new XMLNode(xml_file); + me->checkRedirect(xml); + me->updateNews(xml, xml_file); + addons_manager->init(xml, force_refresh); + delete xml; + } + + pthread_exit(NULL); + return 0; // prevent warning +} // downloadNews + // --------------------------------------------------------------------------- /** Initialises the online part of the network manager. It downloads the * news.xml file from the server (if the frequency of downloads makes this @@ -48,16 +193,6 @@ NewsManager::~NewsManager() * \return 0 if an error happened and no online connection will be available, * 1 otherwise. */ -void NewsManager::init() -{ - UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch(); - - std::string xml_file = file_manager->getAddonsFile("news.xml"); - const XMLNode *xml = new XMLNode(xml_file); - checkRedirect(xml); - updateNews(xml, xml_file); - delete xml; -} // init // --------------------------------------------------------------------------- /** Checks if a redirect is received, causing a new server to be used for @@ -210,8 +345,8 @@ const core::stringw NewsManager::getImportantMessage() const core::stringw NewsManager::getNextNewsMessage() { // Only display error message in case of a problem. - if(m_error_message.size()>0) - return _(m_error_message.c_str()); + if(m_error_message.getAtomic().size()>0) + return _(m_error_message.getAtomic().c_str()); m_news.lock(); if(m_all_news_messages.size()>0) diff --git a/src/addons/news_manager.hpp b/src/addons/news_manager.hpp index f55baa138..4fb50349e 100644 --- a/src/addons/news_manager.hpp +++ b/src/addons/news_manager.hpp @@ -35,6 +35,8 @@ class XMLNode; class NewsManager { private: + static NewsManager *m_news_manager; + // A wrapper class to store news message together with // a message id and a display count. class NewsMessage @@ -87,28 +89,50 @@ private: /** A high priority error message that is shown instead of * any news message (usually indicating connection problems). */ - core::stringw m_error_message; + Synchronised m_error_message; void checkRedirect(const XMLNode *xml); void updateNews(const XMLNode *xml, const std::string &filename); bool conditionFulfilled(const std::string &cond); + static void* downloadNews(void *obj); + NewsManager(); + ~NewsManager(); public: - NewsManager(); - ~NewsManager(); + /** Singleton: if necessary create and get the news managers */ + static NewsManager* get() + { + if(!m_news_manager) + m_news_manager = new NewsManager(); + return m_news_manager; + } // + // ------------------------------------------------------------------------ + static void deallocate() + { + if(m_news_manager) + { + delete m_news_manager; + m_news_manager = NULL; + } + } // deallocate + // ------------------------------------------------------------------------ const core::stringw getNextNewsMessage(); const core::stringw getImportantMessage(); - void init(); + void init(bool force_refresh); void addNewsMessage(const core::stringw &s); + // ------------------------------------------------------------------------ /** Sets an error message that is displayed instead of any news message. */ - void setErrorMessage(const core::stringw &s) { m_error_message=s;} + void setErrorMessage(const core::stringw &s) + { + m_error_message.setAtomic(s); + } // setErrorMessage // ------------------------------------------------------------------------ /** Clears the error message. */ - void clearErrorMessage() {m_error_message=""; } + void clearErrorMessage() {m_error_message.setAtomic(""); } // ------------------------------------------------------------------------ }; // NewsManager diff --git a/src/main.cpp b/src/main.cpp index e98dc57b4..736183d9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1018,10 +1018,10 @@ void initRest() // This only initialises the non-network part of the addons manager. The // online section of the addons manager will be initialised from a // separate thread running in network http. - news_manager = new NewsManager(); addons_manager = new AddonsManager(); INetworkHttp::create(); + NewsManager::get(); // this will create the news manager // Note that the network thread must be started after the assignment // to network_http (since the thread might use network_http, otherwise @@ -1099,7 +1099,7 @@ static void cleanSuperTuxKart() if(ReplayPlay::get()) ReplayPlay::destroy(); if(race_manager) delete race_manager; INetworkHttp::destroy(); - if(news_manager) delete news_manager; + NewsManager::deallocate(); if(addons_manager) delete addons_manager; NetworkManager::kill(); @@ -1252,7 +1252,7 @@ int main(int argc, char *argv[] ) std::string xml_file = file_manager->getAddonsFile("addons.xml"); if (file_manager->fileExists(xml_file)) { const XMLNode *xml = new XMLNode (xml_file); - addons_manager->initOnline(xml); + addons_manager->initAddons(xml); } } @@ -1354,7 +1354,7 @@ int main(int argc, char *argv[] ) // If an important news message exists it is shown in a popup dialog. const core::stringw important_message = - news_manager->getImportantMessage(); + NewsManager::get()->getImportantMessage(); if(important_message!="") { new MessageDialog(important_message, diff --git a/src/online/http_request.cpp b/src/online/http_request.cpp index a303da6f3..54630c841 100644 --- a/src/online/http_request.cpp +++ b/src/online/http_request.cpp @@ -30,32 +30,66 @@ #include -namespace Online{ - +namespace Online +{ /** Creates a HTTP(S) request that will have a raw string as result. (Can * of course be used if the result doesn't matter.) - * \param manage_memory whether or not the HTTPManager should take care of + * \param manage_memory whether or not the RequestManager should take care of * deleting the object after all callbacks have been done. - * \param priority by what priority should the HTTPManager take care of + * \param priority by what priority should the RequestManager take care of * this request. */ HTTPRequest::HTTPRequest(bool manage_memory, int priority) : Request(manage_memory, priority, 0) { - m_url = ""; - m_string_buffer = ""; - m_parameters = new Parameters(); - m_progress.setAtomic(0); + init(); } // HTTPRequest // ------------------------------------------------------------------------ - HTTPRequest::~HTTPRequest() + /** This constructor configures this request to save the data in a flie. + * \param filename Name of the file to save the data to. + * \param manage_memory whether or not the RequestManager should take care of + * deleting the object after all callbacks have been done. + * \param priority by what priority should the RequestManager take care of + * this request. + */ + HTTPRequest::HTTPRequest(const std::string &filename, bool manage_memory, + int priority) + : Request(manage_memory, priority, 0) { - delete m_parameters; - } // ~HTTPRequest + assert(filename.size()>0); + init(); + m_filename = file_manager->getAddonsFile(filename); + } // HTTPRequest(filename ...) // ------------------------------------------------------------------------ - /** A handy shortcut that appends the given path to the URL of the server. + /** Char * needs a separate constructor, otherwise it will be considered + * to be the no-filename constructor (char* -> bool). + */ + HTTPRequest::HTTPRequest(const char* const filename, bool manage_memory, + int priority) + : Request(manage_memory, priority, 0) + { + init(); + m_filename = file_manager->getAddonsFile(filename); + } // HTTPRequest(filename ...) + + // ------------------------------------------------------------------------ + /** Initialises all member variables. + */ + void HTTPRequest::init() + { + m_url = ""; + m_string_buffer = ""; + m_filename = ""; + m_parameters = ""; + m_curl_code = CURLE_OK; + m_progress.setAtomic(0); + } // init + + // ------------------------------------------------------------------------ + /** A handy shortcut that appends the given path to the URL of the + * mutiplayer server. * \param path The path to add to the server. */ void HTTPRequest::setServerURL(const std::string& path) @@ -63,6 +97,16 @@ namespace Online{ setURL((std::string)UserConfigParams::m_server_multiplayer+path); } // setServerURL + // ------------------------------------------------------------------------ + /** A handy shortcut that appends the given path to the URL of the addons + * server. + * \param path The path to add to the server. + */ + void HTTPRequest::setAddonsURL(const std::string& path) + { + setURL((std::string)UserConfigParams::m_server_addons + + "/" + path); + } // set AddonsURL // ------------------------------------------------------------------------ /** Checks the request if it has enough (correct) information to be * executed (and thus allowed to add to the queue). @@ -84,10 +128,9 @@ namespace Online{ "LibCurl session not initialized."); return; } + curl_easy_setopt(m_curl_session, CURLOPT_URL, m_url.c_str()); curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, - &HTTPRequest::writeCallback); curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, this); curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION, @@ -95,15 +138,17 @@ namespace Online{ curl_easy_setopt(m_curl_session, CURLOPT_CONNECTTIMEOUT, 20); curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10); curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20); - //https - struct curl_slist *chunk = NULL; - chunk = curl_slist_append(chunk, "Host: api.stkaddons.net"); - curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk); - curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, - (file_manager->getAsset("web.tuxfamily.org.pem")).c_str()); - curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L); - //curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); - curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, &m_string_buffer); + if(m_filename.size()==0) + { + //https + struct curl_slist *chunk = NULL; + chunk = curl_slist_append(chunk, "Host: api.stkaddons.net"); + curl_easy_setopt(m_curl_session, CURLOPT_HTTPHEADER, chunk); + curl_easy_setopt(m_curl_session, CURLOPT_CAINFO, + file_manager->getAsset("web.tuxfamily.org.pem").c_str()); + curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L); + //curl_easy_setopt(m_curl_session, CURLOPT_VERBOSE, 1L); + } } // prepareOperation // ------------------------------------------------------------------------ @@ -113,28 +158,38 @@ namespace Online{ { if(!m_curl_session) return; - Parameters::iterator iter; - std::string postString(""); - for (iter = m_parameters->begin(); iter != m_parameters->end(); ++iter) + + FILE *fout = NULL; + if(m_filename.size()>0) { - if(iter != m_parameters->begin()) - postString.append("&"); - char* escaped = curl_easy_escape(m_curl_session , - iter->first.c_str(), - iter->first.size()); - postString.append(escaped); - curl_free(escaped); - postString.append("="); - escaped = curl_easy_escape(m_curl_session, - iter->second.c_str(), - iter->second.size()); - postString.append(escaped); - curl_free(escaped); + fout = fopen((m_filename+".part").c_str(), "wb"); + + if(!fout) + { + Log::error("HTTPRequest", + "Can't open '%s' for writing, ignored.", + (m_filename+".part").c_str()); + return; + } + curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, fout ); + curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, fwrite); } - Log::info("HTTPRequest::operation", "Sending : %s", - postString.c_str()); + else + { + curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, + &m_string_buffer); + curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, + &HTTPRequest::writeCallback); + } + + // All parameters added have a '&' added + if(m_parameters.size()>0) + m_parameters.pop_back(); + + Log::info("HTTPRequest", "Sending %s to %s", + m_parameters.c_str(), m_url.c_str()); curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, - postString.c_str()); + m_parameters.c_str()); std::string uagent( std::string("SuperTuxKart/") + STK_VERSION ); #ifdef WIN32 uagent += (std::string)" (Windows)"; @@ -151,6 +206,28 @@ namespace Online{ m_curl_code = curl_easy_perform(m_curl_session); Request::operation(); + + if(fout) + { + fclose(fout); + if(m_curl_code==CURLE_OK) + { + if(UserConfigParams::logAddons()) + Log::info("HTTPRequest", "Download successful."); + // The behaviour of rename is unspecified if the target + // file should already exist - so remove it. + file_manager->removeFile(m_filename); + int ret = rename((m_filename+".part").c_str(), + m_filename.c_str() ); + // In case of an error, set the status to indicate this + if(ret!=0) + { + if(UserConfigParams::logAddons()) + Log::error("addons", "Could not rename downloaded file!"); + m_curl_code = CURLE_WRITE_ERROR; + } + } // m_curl_code ==CURLE_OK + } // if fout } // operation // ------------------------------------------------------------------------ @@ -229,4 +306,5 @@ namespace Online{ } // progressDownload + } // namespace Online diff --git a/src/online/http_request.hpp b/src/online/http_request.hpp index 91ea86f95..c92d08df1 100644 --- a/src/online/http_request.hpp +++ b/src/online/http_request.hpp @@ -39,8 +39,6 @@ namespace Online class HTTPRequest : public Request { private: - typedef std::map Parameters; - /** The progress indicator. 0 untill it is started and the first * packet is downloaded. Guaranteed to be <1 while the download * is in progress, it will be set to either -1 (error) or 1 @@ -51,7 +49,11 @@ namespace Online std::string m_url; /** The POST parameters that will be send with the request. */ - Parameters *m_parameters; + std::string m_parameters; + + /** Contains a filename if the data should be saved into a file + * instead of being kept in in memory. Otherwise this is "". */ + std::string m_filename; /** Pointer to the curl data structure for this request. */ CURL *m_curl_session; @@ -73,18 +75,35 @@ namespace Online static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp); - + void init(); public : HTTPRequest(bool manage_memory = false, int priority = 1); - virtual ~HTTPRequest(); + HTTPRequest(const std::string &filename, + bool manage_memory = false, + int priority = 1); + HTTPRequest(const char * const filename, + bool manage_memory = false, + int priority = 1); + virtual ~HTTPRequest() {}; virtual bool isAllowedToAdd() OVERRIDE; void setServerURL(const std::string& url); + void setAddonsURL(const std::string& path); // ------------------------------------------------------------------------ - /** Returns the curl error status of the request. + /** Returns true if there was an error downloading the file. */ - CURLcode getResult() const { return m_curl_code; } + bool hadDownloadError() const { return m_curl_code!=CURLE_OK; } + // ------------------------------------------------------------------------ + /** Returns the curl error message if an error has occurred. + * \pre m_curl_code!=CURLE_OK + */ + const char* getDownloadErrorMessage() const + { + assert(hadDownloadError()); + return curl_easy_strerror(m_curl_code); + } // getDownloadErrorMessage + // ------------------------------------------------------------------------ /** Returns the downloaded string. * \pre request has to be done @@ -101,8 +120,8 @@ namespace Online */ void addParameter(const std::string & name, const std::string &value) { - assert(isPreparing()); - (*m_parameters)[name] = value; + // Call the template, so that the strings are escaped properly + addParameter(name, value.c_str()); }; // addParameter // -------------------------------------------------------------------- /** Sets a parameter to 'value' (stringw). @@ -110,16 +129,25 @@ namespace Online void addParameter(const std::string & name, const irr::core::stringw &value) { - assert(isPreparing()); - (*m_parameters)[name] = irr::core::stringc(value.c_str()).c_str(); + core::stringc s = core::stringc(value.c_str()); + // Call the template to escape strings properly + addParameter(name, s.c_str()); } // addParameter + // -------------------------------------------------------------------- /** Sets a parameter to 'value' (arbitrary types). */ template - void addParameter(const std::string & name, const T& value){ + void addParameter(const std::string & name, const T& value) + { assert(isPreparing()); - (*m_parameters)[name] = StringUtils::toString(value); + std::string s = StringUtils::toString(value); + char *s1 = curl_easy_escape(m_curl_session, name.c_str(), + name.size() ); + char *s2 = curl_easy_escape(m_curl_session, s.c_str(), s.size()); + m_parameters.append(std::string(s1)+"="+s2+"&"); + curl_free(s1); + curl_free(s2); } // addParameter // -------------------------------------------------------------------- /** Returns the current progress. */ diff --git a/src/online/request.cpp b/src/online/request.cpp index 7c6eb9fc0..85c1bd798 100644 --- a/src/online/request.cpp +++ b/src/online/request.cpp @@ -46,6 +46,14 @@ namespace Online m_state.setAtomic(S_PREPARING); } // Request + // ------------------------------------------------------------------------ + /** Inserts this request into the RequestManager's queue for executing. + */ + void Request::queue() + { + RequestManager::get()->addRequest(this); + } // queue + // ------------------------------------------------------------------------ /** Executes the request. This calles prepareOperation, operation, and * afterOperation. diff --git a/src/online/request.hpp b/src/online/request.hpp index 66ece63ac..a326fb823 100644 --- a/src/online/request.hpp +++ b/src/online/request.hpp @@ -124,6 +124,7 @@ namespace Online virtual ~Request() {} void execute(); void executeNow(); + void queue(); // -------------------------------------------------------------------- /** Executed when a request has finished. */ virtual void callback() {} diff --git a/src/online/request_manager.cpp b/src/online/request_manager.cpp index 065fd38b9..b717c4d46 100644 --- a/src/online/request_manager.cpp +++ b/src/online/request_manager.cpp @@ -1,8 +1,8 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010 Lucas Baudin -// 2011 Joerg Henrichs -// 2013 Glenn De Jonghe +// Copyright (C) 2010-2014 Lucas Baudin +// 2011-201 Joerg Henrichs +// 2013-2014 Glenn De Jonghe // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/online/xml_request.cpp b/src/online/xml_request.cpp index d1a663886..ffa145b06 100644 --- a/src/online/xml_request.cpp +++ b/src/online/xml_request.cpp @@ -61,10 +61,10 @@ namespace Online void XMLRequest::afterOperation() { m_xml_data = file_manager->createXMLTreeFromString(getData()); - if(getResult() != CURLE_OK) + if(hadDownloadError()) Log::error("XMLRequest::afterOperation", "curl_easy_perform() failed: %s", - curl_easy_strerror(getResult())); + getDownloadErrorMessage()); m_success = false; std::string rec_success; if(m_xml_data->get("success", &rec_success)) diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 33151a2a6..3ff0f444f 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -112,7 +112,7 @@ void MainMenuScreen::init() LabelWidget* w = getWidget("info_addons"); - const core::stringw &news_text = news_manager->getNextNewsMessage(); + const core::stringw &news_text = NewsManager::get()->getNextNewsMessage(); w->setText(news_text, true); w->update(0.01f); @@ -165,7 +165,7 @@ void MainMenuScreen::onUpdate(float delta, irr::video::IVideoDriver* driver) w->update(delta); if(w->scrolledOff()) { - const core::stringw &news_text = news_manager->getNextNewsMessage(); + const core::stringw &news_text = NewsManager::get()->getNextNewsMessage(); w->setText(news_text, true); } } // onUpdate From f6b7fb385353d4aad3f1eaca75be26ff1ed1f6c7 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 14:34:34 +0000 Subject: [PATCH 236/412] Fix what looks like type git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15007 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/addons/addons_manager.cpp | 2 +- src/addons/news_manager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index 265f919db..49c53b61b 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -21,7 +21,7 @@ #include "addons/addons_manager.hpp" #include "addons/inetwork_http.hpp" -#include "addons./news_manager.hpp" +#include "addons/news_manager.hpp" #include "addons/zip.hpp" #include "io/file_manager.hpp" #include "io/xml_node.hpp" diff --git a/src/addons/news_manager.cpp b/src/addons/news_manager.cpp index 0dec8bd0a..28c833146 100644 --- a/src/addons/news_manager.cpp +++ b/src/addons/news_manager.cpp @@ -64,7 +64,7 @@ void NewsManager::init(bool force_refresh) &NewsManager::downloadNews, this); if(error) { - Log::warn("news", "Could not create thread, error=%d", errno); + Log::warn("news", "Could not create thread, error=%d", error); // In this case just execute the downloading code with this thread downloadNews(this); } From fda86ed45c75d9514a890c3986e8ae2f075a503a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 15:27:24 +0000 Subject: [PATCH 237/412] STKMesh: Rendering in minel is working (except transparent part) git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15008 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/object.frag | 8 +++++--- data/shaders/object.vert | 4 ++++ src/graphics/stkmesh.cpp | 27 ++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/data/shaders/object.frag b/data/shaders/object.frag index fc6c21b8d..06f06b711 100644 --- a/data/shaders/object.frag +++ b/data/shaders/object.frag @@ -1,10 +1,12 @@ #version 130 uniform sampler2D texture; in vec2 uv; +noperspective in vec3 nor; void main(void) { - gl_FragData[0] = texture2D(texture, uv); - gl_FragData[1] = vec4(0., 0., 0., 1.); - gl_FragData[2] = vec4(0., 0., 0., 1.); + vec4 tex = texture2D(texture, uv); + gl_FragData[0] = vec4(tex.xyz, 1.); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1. - tex.a); } diff --git a/data/shaders/object.vert b/data/shaders/object.vert index 7ba1d77d0..d34409e5b 100644 --- a/data/shaders/object.vert +++ b/data/shaders/object.vert @@ -1,12 +1,16 @@ #version 130 uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; in vec3 Position; in vec2 Texcoord; +in vec3 Normal; out vec2 uv; +noperspective out vec3 nor; void main(void) { uv = Texcoord; gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); + nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 5f815353a..844c1e58b 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -6,8 +6,8 @@ namespace ObjectShader { GLuint Program; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_MVP, uniform_texture; + GLuint attrib_position, attrib_texcoord, attrib_normal; + GLuint uniform_MVP, uniform_TIMV, uniform_texture; void init() { @@ -15,7 +15,9 @@ namespace ObjectShader Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/object.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_normal = glGetAttribLocation(Program, "Normal"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); uniform_texture = glGetUniformLocation(Program, "texture"); } } @@ -152,7 +154,7 @@ void STKMesh::draw(unsigned i) return; glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); - glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); GLuint vbo = vertex_buffer[i], idx = index_buffer[i]; GLenum ptype = Primitivetype[i]; size_t count = Indexcount[i]; @@ -163,18 +165,29 @@ void STKMesh::draw(unsigned i) core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glUniform1f(ObjectShader::uniform_texture, 0); + glUniformMatrix4fv(ObjectShader::uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(ObjectShader::uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); glEnableVertexAttribArray(ObjectShader::attrib_position); glEnableVertexAttribArray(ObjectShader::attrib_texcoord); + glEnableVertexAttribArray(ObjectShader::attrib_normal); glVertexAttribPointer(ObjectShader::attrib_position, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); glVertexAttribPointer(ObjectShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, Stride[i], (GLvoid*) 28); + glVertexAttribPointer(ObjectShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, Stride[i], (GLvoid*) 12); glDrawElements(ptype, count, Indextype[i], 0); glDisableVertexAttribArray(ObjectShader::attrib_position); glDisableVertexAttribArray(ObjectShader::attrib_texcoord); + glDisableVertexAttribArray(ObjectShader::attrib_normal); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -201,9 +214,13 @@ void STKMesh::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); Box = Mesh->getBoundingBox(); - for (unsigned i = 0; i < index_buffer.size(); i++) + if (!isTransparentPass) { -// draw(i); + for (unsigned i = 0; i < index_buffer.size(); i++) + { + //draw(i); + } + //return; } for (u32 i=0; igetMeshBufferCount(); ++i) From 61003eda910b311fd51f576523de9a28efb6847c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 15:53:41 +0000 Subject: [PATCH 238/412] STKMesh: Some refactorisation work git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15009 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/stkmesh.cpp | 171 +++++++++++++++++++-------------------- src/graphics/stkmesh.hpp | 17 ++-- 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 844c1e58b..1690b23e9 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -23,14 +23,16 @@ namespace ObjectShader } static -void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint &idx) +GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { initGL(); - GLuint bufferid, indexbufferid; - glGenBuffers(1, &bufferid); - glGenBuffers(1, &indexbufferid); + GLMesh result; + if (!mb) + return result; + glGenBuffers(1, &(result.vertex_buffer)); + glGenBuffers(1, &(result.index_buffer)); - glBindBuffer(GL_ARRAY_BUFFER, bufferid); + glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer); const void* vertices=mb->getVertices(); const u32 vertexCount=mb->getVertexCount(); const irr::video::E_VERTEX_TYPE vType=mb->getVertexType(); @@ -42,7 +44,7 @@ void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint &idx) vbuf = buffer.const_pointer(); glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbufferid); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer); const void* indices=mb->getIndices(); u32 indexCount= mb->getIndexCount(); GLenum indexSize; @@ -67,8 +69,59 @@ void allocateMeshBuffer(scene::IMeshBuffer* mb, GLuint &vbo, GLuint &idx) glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - vbo = bufferid; - idx = indexbufferid; + + result.IndexCount = mb->getIndexCount(); + switch (mb->getPrimitiveType()) + { + case scene::EPT_POINTS: + result.PrimitiveType = GL_POINTS; + break; + case scene::EPT_TRIANGLE_STRIP: + result.PrimitiveType = GL_TRIANGLE_STRIP; + break; + case scene::EPT_TRIANGLE_FAN: + result.PrimitiveType = GL_TRIANGLE_FAN; + break; + case scene::EPT_LINES: + result.PrimitiveType = GL_LINES; + case scene::EPT_TRIANGLES: + result.PrimitiveType = GL_TRIANGLES; + break; + case scene::EPT_POINT_SPRITES: + case scene::EPT_LINE_LOOP: + case scene::EPT_POLYGON: + case scene::EPT_LINE_STRIP: + case scene::EPT_QUAD_STRIP: + case scene::EPT_QUADS: + assert(0 && "Unsupported primitive type"); + } + switch (mb->getVertexType()) + { + case video::EVT_STANDARD: + result.Stride = sizeof(video::S3DVertex); + break; + case video::EVT_2TCOORDS: + result.Stride = sizeof(video::S3DVertex2TCoords); + break; + case video::EVT_TANGENTS: + result.Stride = sizeof(video::S3DVertexTangents); + break; + } + switch (mb->getIndexType()) + { + case video::EIT_16BIT: + result.IndexType = GL_UNSIGNED_SHORT; + break; + case video::EIT_32BIT: + result.IndexType = GL_UNSIGNED_INT; + break; + } + ITexture *tex = mb->getMaterial().getTexture(0); + if (tex) + result.textures = static_cast(tex)->getOpenGLTextureName(); + else + result.textures = 0; + return result; } STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, @@ -80,63 +133,8 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene for (u32 i=0; igetMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); - if (!mb) - continue; - GLuint vbo, idx; - allocateMeshBuffer(mb, vbo, idx); - vertex_buffer.push_back(vbo); - index_buffer.push_back(idx); - Indexcount.push_back(mb->getIndexCount()); - switch (mb->getPrimitiveType()) - { - case scene::EPT_POINTS: - Primitivetype.push_back(GL_POINTS); - break; - case scene::EPT_TRIANGLE_STRIP: - Primitivetype.push_back(GL_TRIANGLE_STRIP); - break; - case scene::EPT_TRIANGLE_FAN: - Primitivetype.push_back(GL_TRIANGLE_FAN); - break; - case scene::EPT_LINES: - Primitivetype.push_back(GL_LINES); - case scene::EPT_TRIANGLES: - Primitivetype.push_back(GL_TRIANGLES); - break; - case scene::EPT_POINT_SPRITES: - case scene::EPT_LINE_LOOP: - case scene::EPT_POLYGON: - case scene::EPT_LINE_STRIP: - case scene::EPT_QUAD_STRIP: - case scene::EPT_QUADS: - assert(0 && "Unsupported primitive type"); - } - switch (mb->getVertexType()) - { - case video::EVT_STANDARD: - Stride.push_back(sizeof(video::S3DVertex)); - break; - case video::EVT_2TCOORDS: - Stride.push_back(sizeof(video::S3DVertex2TCoords)); - break; - case video::EVT_TANGENTS: - Stride.push_back(sizeof(video::S3DVertexTangents)); - break; - } - switch (mb->getIndexType()) - { - case video::EIT_16BIT: - Indextype.push_back(GL_UNSIGNED_SHORT); - break; - case video::EIT_32BIT: - Indextype.push_back(GL_UNSIGNED_INT); - break; - } - ITexture *tex = mb->getMaterial().getTexture(0); - if (tex) - textures.push_back(static_cast(tex)->getOpenGLTextureName()); - else - textures.push_back(0); + GLmeshes.push_back(allocateMeshBuffer(mb)); + } if (!ObjectShader::Program) ObjectShader::init(); @@ -144,20 +142,24 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene STKMesh::~STKMesh() { - glDeleteBuffers(vertex_buffer.size(), vertex_buffer.data()); - glDeleteBuffers(index_buffer.size(), index_buffer.data()); +// glDeleteBuffers(vertex_buffer.size(), vertex_buffer.data()); +// glDeleteBuffers(index_buffer.size(), index_buffer.data()); } -void STKMesh::draw(unsigned i) +static +void draw(const GLMesh &mesh) { - if (!textures[i]) - return; + if (!mesh.textures) + return; glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); glDisable(GL_BLEND); - GLuint vbo = vertex_buffer[i], idx = index_buffer[i]; - GLenum ptype = Primitivetype[i]; - size_t count = Indexcount[i]; + GLuint vbo = mesh.vertex_buffer, idx = mesh.index_buffer; + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + size_t stride = mesh.Stride; glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); @@ -171,7 +173,7 @@ void STKMesh::draw(unsigned i) TransposeInverseModelView = TransposeInverseModelView.getTransposed(); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textures[i]); + glBindTexture(GL_TEXTURE_2D, mesh.textures); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glUniform1f(ObjectShader::uniform_texture, 0); @@ -181,10 +183,10 @@ void STKMesh::draw(unsigned i) glEnableVertexAttribArray(ObjectShader::attrib_position); glEnableVertexAttribArray(ObjectShader::attrib_texcoord); glEnableVertexAttribArray(ObjectShader::attrib_normal); - glVertexAttribPointer(ObjectShader::attrib_position, 3, GL_FLOAT, GL_FALSE, Stride[i], 0); - glVertexAttribPointer(ObjectShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, Stride[i], (GLvoid*) 28); - glVertexAttribPointer(ObjectShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, Stride[i], (GLvoid*) 12); - glDrawElements(ptype, count, Indextype[i], 0); + glVertexAttribPointer(ObjectShader::attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); + glVertexAttribPointer(ObjectShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + glVertexAttribPointer(ObjectShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + glDrawElements(ptype, count, itype, 0); glDisableVertexAttribArray(ObjectShader::attrib_position); glDisableVertexAttribArray(ObjectShader::attrib_texcoord); glDisableVertexAttribArray(ObjectShader::attrib_normal); @@ -214,15 +216,6 @@ void STKMesh::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); Box = Mesh->getBoundingBox(); - if (!isTransparentPass) - { - for (unsigned i = 0; i < index_buffer.size(); i++) - { - //draw(i); - } - //return; - } - for (u32 i=0; igetMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); @@ -235,7 +228,9 @@ void STKMesh::render() // only render transparent buffer if this is the transparent render pass // and solid only in solid pass - if (transparent == isTransparentPass) + /*if (isTransparentPass && transparent) + draw(GLmeshes[i]); + else*/ if (transparent == isTransparentPass) { driver->setMaterial(material); driver->drawMeshBuffer(mb); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index f406a4b9c..b4917d7a6 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -8,15 +8,20 @@ #include "glwrap.hpp" #include +struct GLMesh { + GLuint vertex_buffer; + GLuint index_buffer; + GLuint textures; + GLenum PrimitiveType; + GLenum IndexType; + size_t IndexCount; + size_t Stride; +}; + class STKMesh : public irr::scene::CMeshSceneNode { protected: - std::vector vertex_buffer, index_buffer, textures; - std::vector Primitivetype, Indextype; - std::vector Indexcount; - std::vector Stride; - - void draw(unsigned i); + std::vector GLmeshes; public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), From 1e84b57269a48afdd363bb675d88f7725155cb13 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 16:25:47 +0000 Subject: [PATCH 239/412] STKMesh: Some improvements git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15010 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/stkmesh.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 1690b23e9..a51014d65 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -201,6 +201,13 @@ void draw(const GLMesh &mesh) static_cast(irr_driver->getVideoDriver())->setRenderStates3DMode(); } +static bool isObject(video::E_MATERIAL_TYPE type) +{ + if (type == irr_driver->getShader(ES_OBJECTPASS_REF) || type == irr_driver->getShader(ES_OBJECTPASS)) + return true; + return false; +} + void STKMesh::render() { irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); @@ -228,7 +235,7 @@ void STKMesh::render() // only render transparent buffer if this is the transparent render pass // and solid only in solid pass - /*if (isTransparentPass && transparent) +/* if (isObject(material.MaterialType) && !isTransparentPass && !transparent) draw(GLmeshes[i]); else*/ if (transparent == isTransparentPass) { From 8e7e84c984580260abdc74238898e80b38b3663b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 17:03:02 +0000 Subject: [PATCH 240/412] STKMesh: Use VAO for faster rendering git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15011 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/object.frag | 2 ++ src/graphics/stkmesh.cpp | 47 ++++++++++++++++++++-------------------- src/graphics/stkmesh.hpp | 1 + 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/data/shaders/object.frag b/data/shaders/object.frag index 06f06b711..8bac092c2 100644 --- a/data/shaders/object.frag +++ b/data/shaders/object.frag @@ -6,6 +6,8 @@ noperspective in vec3 nor; void main(void) { vec4 tex = texture2D(texture, uv); + if (tex.a < 0.5) + discard; gl_FragData[0] = vec4(tex.xyz, 1.); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); gl_FragData[2] = vec4(1. - tex.a); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index a51014d65..6cddbdb68 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -3,7 +3,7 @@ #include #include -namespace ObjectShader +namespace ObjectRefShader { GLuint Program; GLuint attrib_position, attrib_texcoord, attrib_normal; @@ -121,6 +121,17 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) result.textures = static_cast(tex)->getOpenGLTextureName(); else result.textures = 0; + glGenVertexArrays(1, &(result.vao)); + glBindVertexArray(result.vao); + glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer); + glEnableVertexAttribArray(ObjectRefShader::attrib_position); + glEnableVertexAttribArray(ObjectRefShader::attrib_texcoord); + glEnableVertexAttribArray(ObjectRefShader::attrib_normal); + glVertexAttribPointer(ObjectRefShader::attrib_position, 3, GL_FLOAT, GL_FALSE, result.Stride, 0); + glVertexAttribPointer(ObjectRefShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, result.Stride, (GLvoid*) 28); + glVertexAttribPointer(ObjectRefShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, result.Stride, (GLvoid*) 12); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer); + glBindVertexArray(0); return result; } @@ -136,8 +147,8 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene GLmeshes.push_back(allocateMeshBuffer(mb)); } - if (!ObjectShader::Program) - ObjectShader::init(); + if (!ObjectRefShader::Program) + ObjectRefShader::init(); } STKMesh::~STKMesh() @@ -155,15 +166,11 @@ void draw(const GLMesh &mesh) glEnable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); glDisable(GL_BLEND); - GLuint vbo = mesh.vertex_buffer, idx = mesh.index_buffer; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - size_t stride = mesh.Stride; - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); - glUseProgram(ObjectShader::Program); + glUseProgram(ObjectRefShader::Program); core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); @@ -176,27 +183,19 @@ void draw(const GLMesh &mesh) glBindTexture(GL_TEXTURE_2D, mesh.textures); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glUniform1f(ObjectShader::uniform_texture, 0); + glUniform1f(ObjectRefShader::uniform_texture, 0); - glUniformMatrix4fv(ObjectShader::uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(ObjectShader::uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glEnableVertexAttribArray(ObjectShader::attrib_position); - glEnableVertexAttribArray(ObjectShader::attrib_texcoord); - glEnableVertexAttribArray(ObjectShader::attrib_normal); - glVertexAttribPointer(ObjectShader::attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); - glVertexAttribPointer(ObjectShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); - glVertexAttribPointer(ObjectShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + glUniformMatrix4fv(ObjectRefShader::uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(ObjectRefShader::uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); - glDisableVertexAttribArray(ObjectShader::attrib_position); - glDisableVertexAttribArray(ObjectShader::attrib_texcoord); - glDisableVertexAttribArray(ObjectShader::attrib_normal); + glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); video::SMaterial material; material.MaterialType = irr_driver->getShader(ES_RAIN); -// fakemat.setTexture(0, tex); -// fakemat.BlendOperation = video::EBO_NONE; + material.BlendOperation = video::EBO_NONE; + material.ZWriteEnable = true; + material.Lighting = false; irr_driver->getVideoDriver()->setMaterial(material); static_cast(irr_driver->getVideoDriver())->setRenderStates3DMode(); } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index b4917d7a6..051b4f6b3 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -9,6 +9,7 @@ #include struct GLMesh { + GLuint vao; GLuint vertex_buffer; GLuint index_buffer; GLuint textures; From 55d085bf6d1858fd61d37c13e8b0ce430dca0775 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 17:40:39 +0000 Subject: [PATCH 241/412] STKMesh: Now use separate shader for ref/noref object git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15012 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/object.frag | 2 - data/shaders/objectref.frag | 14 ++++ src/graphics/stkmesh.cpp | 152 +++++++++++++++++++++++++++++------- 3 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 data/shaders/objectref.frag diff --git a/data/shaders/object.frag b/data/shaders/object.frag index 8bac092c2..06f06b711 100644 --- a/data/shaders/object.frag +++ b/data/shaders/object.frag @@ -6,8 +6,6 @@ noperspective in vec3 nor; void main(void) { vec4 tex = texture2D(texture, uv); - if (tex.a < 0.5) - discard; gl_FragData[0] = vec4(tex.xyz, 1.); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); gl_FragData[2] = vec4(1. - tex.a); diff --git a/data/shaders/objectref.frag b/data/shaders/objectref.frag new file mode 100644 index 000000000..8bac092c2 --- /dev/null +++ b/data/shaders/objectref.frag @@ -0,0 +1,14 @@ +#version 130 +uniform sampler2D texture; +in vec2 uv; +noperspective in vec3 nor; + +void main(void) +{ + vec4 tex = texture2D(texture, uv); + if (tex.a < 0.5) + discard; + gl_FragData[0] = vec4(tex.xyz, 1.); + gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + gl_FragData[2] = vec4(1. - tex.a); +} diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 6cddbdb68..29cd7ce4b 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -9,6 +9,57 @@ namespace ObjectRefShader GLuint attrib_position, attrib_texcoord, attrib_normal; GLuint uniform_MVP, uniform_TIMV, uniform_texture; + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/objectref.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_texture = glGetUniformLocation(Program, "texture"); + } + + GLuint createVAO(GLuint vbo, GLuint idx, size_t stride) + { + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glEnableVertexAttribArray(attrib_normal); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); + glBindVertexArray(0); + return vao; + } + + void setProgramAndUniforms() + { + glUseProgram(Program); + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + } +} + +namespace ObjectShader +{ + GLuint Program; + GLuint attrib_position, attrib_texcoord, attrib_normal; + GLuint uniform_MVP, uniform_TIMV, uniform_texture; + void init() { initGL(); @@ -20,6 +71,38 @@ namespace ObjectRefShader uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); uniform_texture = glGetUniformLocation(Program, "texture"); } + + GLuint createVAO(GLuint vbo, GLuint idx, size_t stride) + { + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glEnableVertexAttribArray(attrib_normal); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); + glBindVertexArray(0); + return vao; + } + + void setProgramAndUniforms() + { + glUseProgram(Program); + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + } } static @@ -121,17 +204,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) result.textures = static_cast(tex)->getOpenGLTextureName(); else result.textures = 0; - glGenVertexArrays(1, &(result.vao)); - glBindVertexArray(result.vao); - glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer); - glEnableVertexAttribArray(ObjectRefShader::attrib_position); - glEnableVertexAttribArray(ObjectRefShader::attrib_texcoord); - glEnableVertexAttribArray(ObjectRefShader::attrib_normal); - glVertexAttribPointer(ObjectRefShader::attrib_position, 3, GL_FLOAT, GL_FALSE, result.Stride, 0); - glVertexAttribPointer(ObjectRefShader::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, result.Stride, (GLvoid*) 28); - glVertexAttribPointer(ObjectRefShader::attrib_normal, 3, GL_FLOAT, GL_FALSE, result.Stride, (GLvoid*) 12); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer); - glBindVertexArray(0); + result.vao = 0; return result; } @@ -147,8 +220,10 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene GLmeshes.push_back(allocateMeshBuffer(mb)); } - if (!ObjectRefShader::Program) - ObjectRefShader::init(); + if (ObjectRefShader::Program) + return; + ObjectRefShader::init(); + ObjectShader::init(); } STKMesh::~STKMesh() @@ -158,7 +233,7 @@ STKMesh::~STKMesh() } static -void draw(const GLMesh &mesh) +void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (!mesh.textures) return; @@ -170,23 +245,27 @@ void draw(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glUseProgram(ObjectRefShader::Program); - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + { + ObjectRefShader::setProgramAndUniforms(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glUniform1f(ObjectRefShader::uniform_texture, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glUniform1f(ObjectRefShader::uniform_texture, 0); + } + if (type == irr_driver->getShader(ES_OBJECTPASS)) + { + ObjectShader::setProgramAndUniforms(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glUniform1f(ObjectShader::uniform_texture, 0); + } - glUniformMatrix4fv(ObjectRefShader::uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(ObjectRefShader::uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); @@ -207,6 +286,16 @@ static bool isObject(video::E_MATERIAL_TYPE type) return false; } +static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) +{ + if (mesh.vao) + return; + if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + mesh.vao = ObjectRefShader::createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.Stride); + if (type == irr_driver->getShader(ES_OBJECTPASS)) + mesh.vao = ObjectShader::createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.Stride); +} + void STKMesh::render() { irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); @@ -235,7 +324,10 @@ void STKMesh::render() // only render transparent buffer if this is the transparent render pass // and solid only in solid pass /* if (isObject(material.MaterialType) && !isTransparentPass && !transparent) - draw(GLmeshes[i]); + { + initvaostate(GLmeshes[i], material.MaterialType); + draw(GLmeshes[i], material.MaterialType); + } else*/ if (transparent == isTransparentPass) { driver->setMaterial(material); From 03618a5bc5403ba4536e56093059027b989c2b72 Mon Sep 17 00:00:00 2001 From: auria Date: Sun, 12 Jan 2014 18:04:00 +0000 Subject: [PATCH 242/412] Apply slighly modified version of patch from ticket #1121 git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15013 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/input/input_manager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/input/input_manager.cpp b/src/input/input_manager.cpp index ba5c6062f..a068bfe44 100644 --- a/src/input/input_manager.cpp +++ b/src/input/input_manager.cpp @@ -479,6 +479,15 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID, if (m_mode == INPUT_SENSE_KEYBOARD || m_mode == INPUT_SENSE_GAMEPAD) { + // Do not pick disabled gamepads for input sensing + if (type == Input::IT_STICKBUTTON || type == Input::IT_STICKMOTION) + { + GamePadDevice *gPad = m_device_manager->getGamePadFromIrrID(deviceID); + DeviceConfig *conf = gPad->getConfiguration(); + if (!conf->isEnabled()) + return; + } + inputSensing(type, deviceID, button, axisDirection, value); return; } From e4dd3c9ed6f2d45466d8d153d428acaf03d1a5a1 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 18:40:04 +0000 Subject: [PATCH 244/412] GPUParticle: Fix sudden amount of particle for boxemitter git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15015 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 27 ++++++++++++++++++--------- src/graphics/gpuparticles.cpp | 4 ++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 9a448228e..843692257 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -21,14 +21,23 @@ out float new_size; void main(void) { - vec4 initialposition = sourcematrix * vec4(particle_position_initial, 1.0); - vec4 adjusted_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - initialposition; - float adjusted_lifetime = lifetime + (float(dt)/lifetime_initial); - bool reset = (adjusted_lifetime > 1.) && (gl_VertexID <= level); - reset = reset || (lifetime < 0.); - new_particle_position = !reset ? particle_position + particle_velocity.xyz * float(dt) : initialposition.xyz; - new_lifetime = !reset ? adjusted_lifetime : 0.; - new_particle_velocity = !reset ? particle_velocity : adjusted_initial_velocity.xyz; - new_size = !reset ? mix(size_initial, size_initial * size_increase_factor, adjusted_lifetime) : size_initial; + float updated_lifetime = lifetime + (float(dt)/lifetime_initial); + if ((updated_lifetime > 1.) && (gl_VertexID <= level)) + { + float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial; + vec4 updated_initialposition = sourcematrix * vec4(particle_position_initial, 1.0); + vec4 updated_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - updated_initialposition; + new_particle_position = updated_initialposition.xyz + updated_initial_velocity.xyz * float(dt_from_last_frame); + new_particle_velocity = updated_initial_velocity.xyz; + new_lifetime = fract(updated_lifetime); + new_size = mix(size_initial, size_initial * size_increase_factor, fract(updated_lifetime)); + } + else + { + new_particle_position = particle_position + particle_velocity.xyz * float(dt); + new_particle_velocity = particle_velocity; + new_lifetime = updated_lifetime; + new_size = mix(size_initial, size_initial * size_increase_factor, updated_lifetime); + } gl_Position = vec4(0.); } diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 3c3a7fc61..d5169400c 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -391,8 +391,8 @@ void ParticleSystemProxy::generateParticlesFromSphereEmitter(scene::IParticleSph particles[i].PositionX = pos.X; particles[i].PositionY = pos.Y; particles[i].PositionZ = pos.Z; - // Initial lifetime is < 0 - particles[i].Lifetime = -1.; + // Initial lifetime is > 1 + particles[i].Lifetime = 2.; memcpy(&(initialvalue[i].PositionX), &(particles[i].PositionX), 3 * sizeof(float)); generateLifetimeSizeDirection(emitter, initialvalue[i].Lifetime, initialvalue[i].Size, From c5edf82a6c94ff3f52cdd0067b91e20f52759c63 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 19:49:23 +0000 Subject: [PATCH 246/412] GPUParticles: This should fix boxemitters. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15017 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 24 ++++++++++++++++-------- src/graphics/gpuparticles.cpp | 23 +++-------------------- src/graphics/gpuparticles.h | 2 +- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 843692257..155d32b6b 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -22,15 +22,23 @@ out float new_size; void main(void) { float updated_lifetime = lifetime + (float(dt)/lifetime_initial); - if ((updated_lifetime > 1.) && (gl_VertexID <= level)) + if (updated_lifetime > 1.) { - float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial; - vec4 updated_initialposition = sourcematrix * vec4(particle_position_initial, 1.0); - vec4 updated_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - updated_initialposition; - new_particle_position = updated_initialposition.xyz + updated_initial_velocity.xyz * float(dt_from_last_frame); - new_particle_velocity = updated_initial_velocity.xyz; - new_lifetime = fract(updated_lifetime); - new_size = mix(size_initial, size_initial * size_increase_factor, fract(updated_lifetime)); + if (gl_VertexID <= level) + { + float dt_from_last_frame = fract(updated_lifetime) * lifetime_initial; + vec4 updated_initialposition = sourcematrix * vec4(particle_position_initial, 1.0); + vec4 updated_initial_velocity = sourcematrix * vec4(particle_position_initial + particle_velocity_initial, 1.0) - updated_initialposition; + new_particle_position = updated_initialposition.xyz + updated_initial_velocity.xyz * float(dt_from_last_frame); + new_particle_velocity = updated_initial_velocity.xyz; + new_lifetime = fract(updated_lifetime); + new_size = mix(size_initial, size_initial * size_increase_factor, fract(updated_lifetime)); + } + else + { + new_lifetime = fract(updated_lifetime); + new_size = 0; + } } else { diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d5169400c..d854756b7 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -4,6 +4,7 @@ #include "config/user_config.hpp" #include #include +#include "guiengine/engine.hpp" GLuint getTextureGLuint(irr::video::ITexture *tex) { return static_cast(tex)->getOpenGLTextureName(); @@ -432,7 +433,6 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) // Pass a fake material type to force irrlicht to update its internal states on rendering setMaterialType(irr_driver->getShader(ES_RAIN)); setAutomaticCulling(0); - LastEmitTime = 0; count = emitter->getMaxParticlesPerSecond() * emitter->getMaxLifeTime() / 1000; switch (emitter->getType()) @@ -465,15 +465,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) void ParticleSystemProxy::simulateHeightmap() { - unsigned time = os::Timer::getTime(); - if (LastEmitTime == 0) - { - LastEmitTime = time; - return; - } - - u32 timediff = time - LastEmitTime; - LastEmitTime = time; + int timediff = GUIEngine::getLatestDt() * 1000.; int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(HeightmapSimulationShader::Program); @@ -527,16 +519,7 @@ void ParticleSystemProxy::simulateHeightmap() void ParticleSystemProxy::simulateNoHeightmap() { - - unsigned time = os::Timer::getTime(); - if (LastEmitTime == 0) - { - LastEmitTime = time; - return; - } - - u32 timediff = time - LastEmitTime; - LastEmitTime = time; + int timediff = GUIEngine::getLatestDt() * 1000.; int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(SimpleSimulationShader::Program); diff --git a/src/graphics/gpuparticles.h b/src/graphics/gpuparticles.h index 5a5cdfee6..70e8a7aac 100644 --- a/src/graphics/gpuparticles.h +++ b/src/graphics/gpuparticles.h @@ -34,7 +34,7 @@ protected: static GLuint quad_vertex_buffer; GLuint texture, normal_and_depth; - unsigned duration, count, LastEmitTime; + unsigned count; void simulateHeightmap(); void simulateNoHeightmap(); From 37851c75083c6082bd953682292f09459805a5d8 Mon Sep 17 00:00:00 2001 From: auria Date: Sun, 12 Jan 2014 20:19:58 +0000 Subject: [PATCH 247/412] Add absolute position getter to trackobject git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15018 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/physics/physical_object.cpp | 2 +- src/tracks/track_object.cpp | 10 ++++++++++ src/tracks/track_object.hpp | 1 + src/tracks/track_object_presentation.cpp | 8 ++++++++ src/tracks/track_object_presentation.hpp | 2 ++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/physics/physical_object.cpp b/src/physics/physical_object.cpp index dee4f40bb..761282ab9 100644 --- a/src/physics/physical_object.cpp +++ b/src/physics/physical_object.cpp @@ -126,7 +126,7 @@ PhysicalObject::PhysicalObject(bool is_dynamic, m_object = object; - m_init_xyz = object->getPosition(); + m_init_xyz = object->getAbsolutePosition(); m_init_hpr = object->getRotation(); m_init_scale = object->getScale(); diff --git a/src/tracks/track_object.cpp b/src/tracks/track_object.cpp index 42f9f30a0..8796e767f 100644 --- a/src/tracks/track_object.cpp +++ b/src/tracks/track_object.cpp @@ -282,6 +282,16 @@ const core::vector3df& TrackObject::getPosition() const // ---------------------------------------------------------------------------- +const core::vector3df& TrackObject::getAbsolutePosition() const +{ + if (m_presentation != NULL) + return m_presentation->getAbsolutePosition(); + else + return m_init_xyz; +} + +// ---------------------------------------------------------------------------- + const core::vector3df& TrackObject::getRotation() const { if (m_presentation != NULL) diff --git a/src/tracks/track_object.hpp b/src/tracks/track_object.hpp index 4fca007e6..10ec656aa 100644 --- a/src/tracks/track_object.hpp +++ b/src/tracks/track_object.hpp @@ -133,6 +133,7 @@ public: const ThreeDAnimation* getAnimator() const { return m_animator; } const core::vector3df& getPosition() const; + const core::vector3df& getAbsolutePosition() const; const core::vector3df& getRotation() const; const core::vector3df& getScale() const; diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 92caa4741..52fec7861 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -70,6 +70,14 @@ const core::vector3df& TrackObjectPresentationSceneNode::getPosition() const return m_node->getPosition(); } +const core::vector3df& TrackObjectPresentationSceneNode::getAbsolutePosition() const +{ + if (m_node == NULL) return m_init_xyz; + m_node->updateAbsolutePosition(); + return m_node->getAbsolutePosition(); +} + + const core::vector3df& TrackObjectPresentationSceneNode::getRotation() const { if (m_node == NULL) return m_init_hpr; diff --git a/src/tracks/track_object_presentation.hpp b/src/tracks/track_object_presentation.hpp index 708880c64..1267025ac 100644 --- a/src/tracks/track_object_presentation.hpp +++ b/src/tracks/track_object_presentation.hpp @@ -82,6 +82,7 @@ public: const core::vector3df& scale) {} virtual const core::vector3df& getPosition() const { return m_init_xyz; } + virtual const core::vector3df& getAbsolutePosition() const { return m_init_xyz; } virtual const core::vector3df& getRotation() const { return m_init_hpr; } virtual const core::vector3df& getScale() const { return m_init_scale; } @@ -115,6 +116,7 @@ public: } virtual const core::vector3df& getPosition() const OVERRIDE; + virtual const core::vector3df& getAbsolutePosition() const OVERRIDE; virtual const core::vector3df& getRotation() const OVERRIDE; virtual const core::vector3df& getScale() const OVERRIDE; virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, From 9968ff1ccfcf7336684d89baf246226e2e4aae11 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 21:07:14 +0000 Subject: [PATCH 251/412] Use custom opengl call for bloom fullscreen shader. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15022 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/bloom.frag | 4 +- data/shaders/screenquad.vert | 10 + src/graphics/post_processing.cpp | 1384 ++++++++++++++++-------------- 3 files changed, 735 insertions(+), 663 deletions(-) create mode 100644 data/shaders/screenquad.vert diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index cdd30a12b..c33e06905 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -2,10 +2,12 @@ uniform sampler2D tex; uniform float low; +in vec2 uv; + void main() { vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709 - vec3 col = texture2D(tex, gl_TexCoord[0].xy).xyz; + vec3 col = texture2D(tex, uv).xyz; float luma = dot(weights, col); col *= smoothstep(low, 0.9, luma); diff --git a/data/shaders/screenquad.vert b/data/shaders/screenquad.vert new file mode 100644 index 000000000..ac88dba7a --- /dev/null +++ b/data/shaders/screenquad.vert @@ -0,0 +1,10 @@ +#version 130 + +in vec2 Position; +in vec2 Texcoord; +out vec2 uv; + +void main() { + uv = Texcoord; + gl_Position = vec4(Position, 0., 1.); +} diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f4a4b8b22..9085d5dc1 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -1,666 +1,726 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2011-2013 the SuperTuxKart-Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -#include "post_processing.hpp" - -#include "config/user_config.hpp" -#include "graphics/callbacks.hpp" -#include "graphics/camera.hpp" -#include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" -#include "graphics/mlaa_areamap.hpp" -#include "graphics/shaders.hpp" -#include "io/file_manager.hpp" -#include "karts/abstract_kart.hpp" -#include "karts/kart_model.hpp" -#include "modes/world.hpp" -#include "race/race_manager.hpp" -#include "tracks/track.hpp" -#include "utils/log.hpp" - -#include - -using namespace video; -using namespace scene; - -PostProcessing::PostProcessing(IVideoDriver* video_driver) +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2011-2013 the SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +#include "post_processing.hpp" + +#include "config/user_config.hpp" +#include "graphics/callbacks.hpp" +#include "graphics/camera.hpp" +#include "graphics/glwrap.hpp" +#include "graphics/irr_driver.hpp" +#include "graphics/mlaa_areamap.hpp" +#include "graphics/shaders.hpp" +#include "io/file_manager.hpp" +#include "karts/abstract_kart.hpp" +#include "karts/kart_model.hpp" +#include "modes/world.hpp" +#include "race/race_manager.hpp" +#include "tracks/track.hpp" +#include "utils/log.hpp" +#include "graphics/glwrap.hpp" + +#include + +using namespace video; +using namespace scene; + +PostProcessing::PostProcessing(IVideoDriver* video_driver) +{ + // Initialization + m_material.Wireframe = false; + m_material.Lighting = false; + m_material.ZWriteEnable = false; + m_material.ZBuffer = ECFN_ALWAYS; + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + + for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) + { + m_material.TextureLayer[i].TextureWrapU = + m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; + } + + // Load the MLAA area map + io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()-> + createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33), + "AreaMap33", false); + if (!areamap) Log::fatal("postprocessing", "Failed to load the areamap"); + m_areamap = irr_driver->getVideoDriver()->getTexture(areamap); + areamap->drop(); + +} // PostProcessing + +// ---------------------------------------------------------------------------- +PostProcessing::~PostProcessing() +{ + // TODO: do we have to delete/drop anything? +} // ~PostProcessing + +// ---------------------------------------------------------------------------- +/** Initialises post processing at the (re-)start of a race. This sets up + * the vertices, normals and texture coordinates for each + */ +void PostProcessing::reset() +{ + const u32 n = Camera::getNumCameras(); + m_boost_time.resize(n); + m_vertices.resize(n); + m_center.resize(n); + m_direction.resize(n); + + MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver-> + getCallback(ES_MOTIONBLUR); + + for(unsigned int i=0; igetViewport(); + // Map viewport to [-1,1] x [-1,1]. First define the coordinates + // left, right, top, bottom: + float right = vp.LowerRightCorner.X < UserConfigParams::m_width + ? 0.0f : 1.0f; + float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f; + float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f; + float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height + ? 0.0f : -1.0f; + + // Use left etc to define 4 vertices on which the rendered screen + // will be displayed: + m_vertices[i].v0.Pos = core::vector3df(left, bottom, 0); + m_vertices[i].v1.Pos = core::vector3df(left, top, 0); + m_vertices[i].v2.Pos = core::vector3df(right, top, 0); + m_vertices[i].v3.Pos = core::vector3df(right, bottom, 0); + // Define the texture coordinates of each vertex, which must + // be in [0,1]x[0,1] + m_vertices[i].v0.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, + bottom==-1.0f ? 0.0f : 0.5f); + m_vertices[i].v1.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, + top == 1.0f ? 1.0f : 0.5f); + m_vertices[i].v2.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, + top == 1.0f ? 1.0f : 0.5f); + m_vertices[i].v3.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, + bottom==-1.0f ? 0.0f : 0.5f); + // Set normal and color: + core::vector3df normal(0,0,1); + m_vertices[i].v0.Normal = m_vertices[i].v1.Normal = + m_vertices[i].v2.Normal = m_vertices[i].v3.Normal = normal; + SColor white(0xFF, 0xFF, 0xFF, 0xFF); + m_vertices[i].v0.Color = m_vertices[i].v1.Color = + m_vertices[i].v2.Color = m_vertices[i].v3.Color = white; + + m_center[i].X=(m_vertices[i].v0.TCoords.X + +m_vertices[i].v2.TCoords.X) * 0.5f; + + // Center is around 20 percent from bottom of screen: + const float tex_height = m_vertices[i].v1.TCoords.Y + - m_vertices[i].v0.TCoords.Y; + m_direction[i].X = m_center[i].X; + m_direction[i].Y = m_vertices[i].v0.TCoords.Y + 0.7f*tex_height; + + setMotionBlurCenterY(i, 0.2f); + + cb->setDirection(i, m_direction[i].X, m_direction[i].Y); + cb->setMaxHeight(i, m_vertices[i].v1.TCoords.Y); + } // for i + getCallback(ES_MOTIONBLUR); + + const float tex_height = m_vertices[num].v1.TCoords.Y - m_vertices[num].v0.TCoords.Y; + m_center[num].Y = m_vertices[num].v0.TCoords.Y + y * tex_height; + + cb->setCenter(num, m_center[num].X, m_center[num].Y); +} + +// ---------------------------------------------------------------------------- +/** Setup some PP data. + */ +void PostProcessing::begin() +{ + m_any_boost = false; + for (u32 i = 0; i < m_boost_time.size(); i++) + m_any_boost |= m_boost_time[i] > 0.01f; +} // beginCapture + +// ---------------------------------------------------------------------------- +/** Set the boost amount according to the speed of the camera */ +void PostProcessing::giveBoost(unsigned int camera_index) +{ + if (irr_driver->isGLSL()) + { + m_boost_time[camera_index] = 0.75f; + + MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver-> + getCallback(ES_MOTIONBLUR); + cb->setBoostTime(camera_index, m_boost_time[camera_index]); + } +} // giveBoost + +// ---------------------------------------------------------------------------- +/** Updates the boost times for all cameras, called once per frame. + * \param dt Time step size. + */ +void PostProcessing::update(float dt) +{ + if (!irr_driver->isGLSL()) + return; + + MotionBlurProvider* const cb = + (MotionBlurProvider*) irr_driver->getCallback(ES_MOTIONBLUR); + + if (cb == NULL) return; + + for (unsigned int i=0; i 0.0f) + { + m_boost_time[i] -= dt; + if (m_boost_time[i] < 0.0f) m_boost_time[i] = 0.0f; + } + + cb->setBoostTime(i, m_boost_time[i]); + } +} // update + +// ---------------------------------------------------------------------------- +/** Render the post-processed scene, solids only, color to color, no stencil */ +void PostProcessing::renderSolid(const u32 cam) +{ + if (!irr_driver->isGLSL()) return; + + IVideoDriver * const drv = irr_driver->getVideoDriver(); + if (World::getWorld()->getTrack()->isFogEnabled()) + { + m_material.MaterialType = irr_driver->getShader(ES_FOG); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + + // Overlay + m_material.BlendOperation = EBO_ADD; + m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); + + drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + drawQuad(cam, m_material); + + m_material.BlendOperation = EBO_NONE; + m_material.MaterialTypeParam = 0; + } +} + +GLuint quad_vbo = 0; + +static void initQuadVBO() +{ + initGL(); + const float quad_vertex[] = { + -1., -1., 0., 0., // UpperLeft + -1., 1., 0., 1., // LowerLeft + 1., -1., 1., 0., // UpperRight + 1., 1., 1., 1., // LowerRight + }; + glGenBuffers(1, &quad_vbo); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +namespace BloomShader { - // Initialization - m_material.Wireframe = false; - m_material.Lighting = false; - m_material.ZWriteEnable = false; - m_material.ZBuffer = ECFN_ALWAYS; - m_material.setFlag(EMF_TRILINEAR_FILTER, true); + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture, uniform_low; + GLuint vao = 0; - for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) - { - m_material.TextureLayer[i].TextureWrapU = - m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; - } + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "tex"); + uniform_low = glGetUniformLocation(Program, "low"); - // Load the MLAA area map - io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()-> - createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33), - "AreaMap33", false); - if (!areamap) Log::fatal("postprocessing", "Failed to load the areamap"); - m_areamap = irr_driver->getVideoDriver()->getTexture(areamap); - areamap->drop(); - -} // PostProcessing - -// ---------------------------------------------------------------------------- -PostProcessing::~PostProcessing() -{ - // TODO: do we have to delete/drop anything? -} // ~PostProcessing - -// ---------------------------------------------------------------------------- -/** Initialises post processing at the (re-)start of a race. This sets up - * the vertices, normals and texture coordinates for each - */ -void PostProcessing::reset() -{ - const u32 n = Camera::getNumCameras(); - m_boost_time.resize(n); - m_vertices.resize(n); - m_center.resize(n); - m_direction.resize(n); - - MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver-> - getCallback(ES_MOTIONBLUR); - - for(unsigned int i=0; igetViewport(); - // Map viewport to [-1,1] x [-1,1]. First define the coordinates - // left, right, top, bottom: - float right = vp.LowerRightCorner.X < UserConfigParams::m_width - ? 0.0f : 1.0f; - float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f; - float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f; - float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height - ? 0.0f : -1.0f; - - // Use left etc to define 4 vertices on which the rendered screen - // will be displayed: - m_vertices[i].v0.Pos = core::vector3df(left, bottom, 0); - m_vertices[i].v1.Pos = core::vector3df(left, top, 0); - m_vertices[i].v2.Pos = core::vector3df(right, top, 0); - m_vertices[i].v3.Pos = core::vector3df(right, bottom, 0); - // Define the texture coordinates of each vertex, which must - // be in [0,1]x[0,1] - m_vertices[i].v0.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, - bottom==-1.0f ? 0.0f : 0.5f); - m_vertices[i].v1.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, - top == 1.0f ? 1.0f : 0.5f); - m_vertices[i].v2.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, - top == 1.0f ? 1.0f : 0.5f); - m_vertices[i].v3.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, - bottom==-1.0f ? 0.0f : 0.5f); - // Set normal and color: - core::vector3df normal(0,0,1); - m_vertices[i].v0.Normal = m_vertices[i].v1.Normal = - m_vertices[i].v2.Normal = m_vertices[i].v3.Normal = normal; - SColor white(0xFF, 0xFF, 0xFF, 0xFF); - m_vertices[i].v0.Color = m_vertices[i].v1.Color = - m_vertices[i].v2.Color = m_vertices[i].v3.Color = white; - - m_center[i].X=(m_vertices[i].v0.TCoords.X - +m_vertices[i].v2.TCoords.X) * 0.5f; - - // Center is around 20 percent from bottom of screen: - const float tex_height = m_vertices[i].v1.TCoords.Y - - m_vertices[i].v0.TCoords.Y; - m_direction[i].X = m_center[i].X; - m_direction[i].Y = m_vertices[i].v0.TCoords.Y + 0.7f*tex_height; - - setMotionBlurCenterY(i, 0.2f); - - cb->setDirection(i, m_direction[i].X, m_direction[i].Y); - cb->setMaxHeight(i, m_vertices[i].v1.TCoords.Y); - } // for i - getCallback(ES_MOTIONBLUR); - - const float tex_height = m_vertices[num].v1.TCoords.Y - m_vertices[num].v0.TCoords.Y; - m_center[num].Y = m_vertices[num].v0.TCoords.Y + y * tex_height; - - cb->setCenter(num, m_center[num].X, m_center[num].Y); -} - -// ---------------------------------------------------------------------------- -/** Setup some PP data. - */ -void PostProcessing::begin() -{ - m_any_boost = false; - for (u32 i = 0; i < m_boost_time.size(); i++) - m_any_boost |= m_boost_time[i] > 0.01f; -} // beginCapture - -// ---------------------------------------------------------------------------- -/** Set the boost amount according to the speed of the camera */ -void PostProcessing::giveBoost(unsigned int camera_index) -{ - if (irr_driver->isGLSL()) - { - m_boost_time[camera_index] = 0.75f; - - MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver-> - getCallback(ES_MOTIONBLUR); - cb->setBoostTime(camera_index, m_boost_time[camera_index]); - } -} // giveBoost - -// ---------------------------------------------------------------------------- -/** Updates the boost times for all cameras, called once per frame. - * \param dt Time step size. - */ -void PostProcessing::update(float dt) -{ - if (!irr_driver->isGLSL()) - return; - - MotionBlurProvider* const cb = - (MotionBlurProvider*) irr_driver->getCallback(ES_MOTIONBLUR); - - if (cb == NULL) return; - - for (unsigned int i=0; i 0.0f) - { - m_boost_time[i] -= dt; - if (m_boost_time[i] < 0.0f) m_boost_time[i] = 0.0f; - } - - cb->setBoostTime(i, m_boost_time[i]); - } -} // update - -// ---------------------------------------------------------------------------- -/** Render the post-processed scene, solids only, color to color, no stencil */ -void PostProcessing::renderSolid(const u32 cam) -{ - if (!irr_driver->isGLSL()) return; - - IVideoDriver * const drv = irr_driver->getVideoDriver(); - if (World::getWorld()->getTrack()->isFogEnabled()) - { - m_material.MaterialType = irr_driver->getShader(ES_FOG); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - // Overlay - m_material.BlendOperation = EBO_ADD; - m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); - - drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - m_material.MaterialTypeParam = 0; - } -} - -// ---------------------------------------------------------------------------- -/** Render the post-processed scene */ -void PostProcessing::render() -{ - if (!irr_driver->isGLSL()) return; - - IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setTransform(ETS_WORLD, core::IdentityMatrix); - drv->setTransform(ETS_VIEW, core::IdentityMatrix); - drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); - - MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver-> - getCallback(ES_MOTIONBLUR); - GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> - getCallback(ES_GAUSSIAN3H); - - const u32 cams = Camera::getNumCameras(); - for(u32 cam = 0; cam < cams; cam++) - { - scene::ICameraSceneNode * const camnode = - Camera::getCamera(cam)->getCameraSceneNode(); - mocb->setCurrentCamera(cam); - ITexture *in = irr_driver->getRTT(RTT_COLOR); - ITexture *out = irr_driver->getRTT(RTT_TMP1); - // 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. - - if (1) // bloom - { - // Blit the base to tmp1 - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, in); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - const bool globalbloom = World::getWorld()->getTrack()->getBloom(); - - BloomPowerProvider * const bloomcb = (BloomPowerProvider *) - irr_driver-> - getCallback(ES_BLOOM_POWER); - - if (globalbloom) - { - const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); - ((BloomProvider *) irr_driver->getCallback(ES_BLOOM))->setThreshold(threshold); - - // Catch bright areas, and progressively minify - m_material.MaterialType = irr_driver->getShader(ES_BLOOM); - m_material.setTexture(0, in); - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - drawQuad(cam, m_material); - } - - // Do we have any forced bloom nodes? If so, draw them now - const std::vector &blooms = irr_driver->getForcedBloom(); - const u32 bloomsize = blooms.size(); - - if (!globalbloom && bloomsize) - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - - if (globalbloom || bloomsize) - { - // Clear the alpha to a suitable value, stencil - glClearColor(0, 0, 0, 0.1f); - glColorMask(0, 0, 0, 1); - - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glClearColor(0, 0, 0, 0); - glColorMask(1, 1, 1, 1); - - // The forced-bloom objects are drawn again, to know which pixels to pick. - // While it's more drawcalls, there's a cost to using four MRTs over three, - // and there shouldn't be many such objects in a track. - // The stencil is already in use for the glow. The alpha channel is best - // reserved for other use (specular, etc). - // - // They are drawn with depth and color writes off, giving 4x-8x drawing speed. - if (bloomsize) - { - const core::aabbox3df &cambox = camnode-> - getViewFrustum()-> - getBoundingBox(); - - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); - SOverrideMaterial &overridemat = drv->getOverrideMaterial(); - overridemat.EnablePasses = ESNRP_SOLID; - overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK; - overridemat.Enabled = true; - - overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER); - overridemat.Material.ZWriteEnable = false; - overridemat.Material.ColorMask = ECP_ALPHA; - - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, ~0); - glEnable(GL_STENCIL_TEST); - - camnode->render(); - - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - // Second pass for transparents. No-op for solids. - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT); - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - overridemat.Enabled = 0; - overridemat.EnablePasses = 0; - - // Ok, we have the stencil; now use it to blit from color to bloom tex - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, ~0); - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR)); - - // Just in case. - glColorMask(1, 1, 1, 0); - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false); - - m_material.ColorMask = ECP_RGB; - drawQuad(cam, m_material); - m_material.ColorMask = ECP_ALL; - - glColorMask(1, 1, 1, 1); - glDisable(GL_STENCIL_TEST); - } // end forced bloom - - // To half - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); - - drawQuad(cam, m_material); - - // To quarter - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); - - drawQuad(cam, m_material); - - // To eighth - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); - - drawQuad(cam, m_material); - - // Blur it for distribution. - { - gacb->setResolution(UserConfigParams::m_width / 8, - UserConfigParams::m_height / 8); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false); - - drawQuad(cam, m_material); - } - - // Additively blend on top of tmp1 - m_material.BlendOperation = EBO_ADD; - m_material.MaterialType = irr_driver->getShader(ES_BLOOM_BLEND); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); - drv->setRenderTarget(out, false, false); - - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - } // end if bloom - - in = irr_driver->getRTT(RTT_TMP1); - out = irr_driver->getRTT(RTT_TMP2); - } - - if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays - { - // Grab the sky - drv->setRenderTarget(out, true, false); - irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX); - - // Set the sun's color - ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE); - const SColor col = World::getWorld()->getTrack()->getSunColor(); - colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f); - - // The sun interposer - IMeshSceneNode * const sun = irr_driver->getSunInterposer(); - sun->getMaterial(0).ColorMask = ECP_ALL; - irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA); - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); - - sun->render(); - - sun->getMaterial(0).ColorMask = ECP_NONE; - - // Fade to quarter - m_material.MaterialType = irr_driver->getShader(ES_GODFADE); - m_material.setTexture(0, out); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); - - drawQuad(cam, m_material); - - // Blur - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); - - drawQuad(cam, m_material); - } - - // Calculate the sun's position in texcoords - const core::vector3df pos = sun->getPosition(); - float ndc[4]; - core::matrix4 trans = camnode->getProjectionMatrix(); - trans *= camnode->getViewMatrix(); - - 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 sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw; - const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh; - - ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))-> - setSunPosition(sunx, suny); - - // Rays please - m_material.MaterialType = irr_driver->getShader(ES_GODRAY); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - // Blur - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false); - - drawQuad(cam, m_material); - } - - // Overlay - m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR; - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(in, false, false); - - drawQuad(cam, m_material); - } - - if (UserConfigParams::m_motionblur && m_any_boost) // motion blur - { - // Calculate the kart's Y position on screen - const core::vector3df pos = - Camera::getCamera(cam)->getKart()->getNode()->getPosition(); - float ndc[4]; - core::matrix4 trans = camnode->getProjectionMatrix(); - trans *= camnode->getViewMatrix(); - - trans.transformVect(ndc, pos); - const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f; - setMotionBlurCenterY(cam, karty); - - - m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR); - m_material.setTexture(0, in); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - ITexture *tmp = in; - in = out; - out = tmp; - } - - if (irr_driver->getDisplacingNodes().size()) // Displacement - { - m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE); - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setTexture(0, in); - m_material.setTexture(1, irr_driver->getRTT(RTT_DISPLACE)); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - m_material.setTexture(1, 0); - m_material.setFlag(EMF_BILINEAR_FILTER, true); - - ITexture *tmp = in; - in = out; - out = tmp; - } - - if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. - { - drv->setRenderTarget(out, false, false); - - glEnable(GL_STENCIL_TEST); - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glStencilFunc(GL_ALWAYS, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - // Pass 1: color edge detection - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1); - m_material.setTexture(0, in); - - drawQuad(cam, m_material); - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - - glStencilFunc(GL_EQUAL, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - // Pass 2: blend weights - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2); - m_material.setTexture(0, out); - m_material.setTexture(1, m_areamap); - m_material.TextureLayer[1].BilinearFilter = false; - m_material.TextureLayer[1].TrilinearFilter = false; - - drawQuad(cam, m_material); - - m_material.TextureLayer[1].BilinearFilter = true; - m_material.TextureLayer[1].TrilinearFilter = true; - m_material.setTexture(1, 0); - - // Pass 3: gather - drv->setRenderTarget(in, false, false); - - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3); - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR)); - - drawQuad(cam, m_material); - - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - m_material.setTexture(1, 0); - - // Done. - glDisable(GL_STENCIL_TEST); - } - - // Final blit - - if (irr_driver->getNormals()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - } else if (irr_driver->getSSAOViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - } else if (irr_driver->getShadowViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SHADOW)); - } else - { - m_material.MaterialType = irr_driver->getShader(ES_COLOR_LEVELS); - m_material.setTexture(0, in); - } - - drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); - - drawQuad(cam, m_material); - } -} // render - -void PostProcessing::drawQuad(u32 cam, const SMaterial &mat) -{ - const u16 indices[6] = {0, 1, 2, 3, 0, 2}; - IVideoDriver * const drv = irr_driver->getVideoDriver(); - - drv->setTransform(ETS_WORLD, core::IdentityMatrix); - drv->setTransform(ETS_VIEW, core::IdentityMatrix); - drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); - - drv->setMaterial(mat); - drv->drawIndexedTriangleList(&(m_vertices[cam].v0), - 4, indices, 2); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } } + + +static +void renderBloom(ITexture *in) +{ + if (!BloomShader::Program) + BloomShader::init(); + + const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); + glUseProgram(BloomShader::Program); + glBindVertexArray(BloomShader::vao); + glUniform1f(BloomShader::uniform_low, threshold); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(BloomShader::uniform_texture, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); +} + +// ---------------------------------------------------------------------------- +/** Render the post-processed scene */ +void PostProcessing::render() +{ + if (!irr_driver->isGLSL()) return; + + IVideoDriver * const drv = irr_driver->getVideoDriver(); + drv->setTransform(ETS_WORLD, core::IdentityMatrix); + drv->setTransform(ETS_VIEW, core::IdentityMatrix); + drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); + + MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver-> + getCallback(ES_MOTIONBLUR); + GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> + getCallback(ES_GAUSSIAN3H); + + const u32 cams = Camera::getNumCameras(); + for(u32 cam = 0; cam < cams; cam++) + { + scene::ICameraSceneNode * const camnode = + Camera::getCamera(cam)->getCameraSceneNode(); + mocb->setCurrentCamera(cam); + ITexture *in = irr_driver->getRTT(RTT_COLOR); + ITexture *out = irr_driver->getRTT(RTT_TMP1); + // 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. + + if (1) // bloom + { + // Blit the base to tmp1 + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, in); + drv->setRenderTarget(out, true, false); + + drawQuad(cam, m_material); + + const bool globalbloom = World::getWorld()->getTrack()->getBloom(); + + BloomPowerProvider * const bloomcb = (BloomPowerProvider *) + irr_driver-> + getCallback(ES_BLOOM_POWER); + + if (globalbloom) + { + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + renderBloom(in); + } + + // Do we have any forced bloom nodes? If so, draw them now + const std::vector &blooms = irr_driver->getForcedBloom(); + const u32 bloomsize = blooms.size(); + + if (!globalbloom && bloomsize) + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + + + if (globalbloom || bloomsize) + { + // Clear the alpha to a suitable value, stencil + glClearColor(0, 0, 0, 0.1f); + glColorMask(0, 0, 0, 1); + + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + glClearColor(0, 0, 0, 0); + glColorMask(1, 1, 1, 1); + + // The forced-bloom objects are drawn again, to know which pixels to pick. + // While it's more drawcalls, there's a cost to using four MRTs over three, + // and there shouldn't be many such objects in a track. + // The stencil is already in use for the glow. The alpha channel is best + // reserved for other use (specular, etc). + // + // They are drawn with depth and color writes off, giving 4x-8x drawing speed. + if (bloomsize) + { + const core::aabbox3df &cambox = camnode-> + getViewFrustum()-> + getBoundingBox(); + + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); + SOverrideMaterial &overridemat = drv->getOverrideMaterial(); + overridemat.EnablePasses = ESNRP_SOLID; + overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK; + overridemat.Enabled = true; + + overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER); + overridemat.Material.ZWriteEnable = false; + overridemat.Material.ColorMask = ECP_ALPHA; + + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 1, ~0); + glEnable(GL_STENCIL_TEST); + + camnode->render(); + + for (u32 i = 0; i < bloomsize; i++) + { + scene::ISceneNode * const cur = blooms[i].node; + + // Quick box-based culling + const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); + if (!nodebox.intersectsWithBox(cambox)) + continue; + + bloomcb->setPower(blooms[i].power); + + cur->render(); + } + + // Second pass for transparents. No-op for solids. + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT); + for (u32 i = 0; i < bloomsize; i++) + { + scene::ISceneNode * const cur = blooms[i].node; + + // Quick box-based culling + const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); + if (!nodebox.intersectsWithBox(cambox)) + continue; + + bloomcb->setPower(blooms[i].power); + + cur->render(); + } + + overridemat.Enabled = 0; + overridemat.EnablePasses = 0; + + // Ok, we have the stencil; now use it to blit from color to bloom tex + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 1, ~0); + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR)); + + // Just in case. + glColorMask(1, 1, 1, 0); + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false); + + m_material.ColorMask = ECP_RGB; + drawQuad(cam, m_material); + m_material.ColorMask = ECP_ALL; + + glColorMask(1, 1, 1, 1); + glDisable(GL_STENCIL_TEST); + } // end forced bloom + + // To half + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); + drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); + + drawQuad(cam, m_material); + + // To quarter + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); + + drawQuad(cam, m_material); + + // To eighth + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); + + drawQuad(cam, m_material); + + // Blur it for distribution. + { + gacb->setResolution(UserConfigParams::m_width / 8, + UserConfigParams::m_height / 8); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); + m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); + m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false); + + drawQuad(cam, m_material); + } + + // Additively blend on top of tmp1 + m_material.BlendOperation = EBO_ADD; + m_material.MaterialType = irr_driver->getShader(ES_BLOOM_BLEND); + m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); + drv->setRenderTarget(out, false, false); + + drawQuad(cam, m_material); + + m_material.BlendOperation = EBO_NONE; + } // end if bloom + + in = irr_driver->getRTT(RTT_TMP1); + out = irr_driver->getRTT(RTT_TMP2); + } + + if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays + { + // Grab the sky + drv->setRenderTarget(out, true, false); + irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX); + + // Set the sun's color + ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE); + const SColor col = World::getWorld()->getTrack()->getSunColor(); + colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f); + + // The sun interposer + IMeshSceneNode * const sun = irr_driver->getSunInterposer(); + sun->getMaterial(0).ColorMask = ECP_ALL; + irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA); + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); + + sun->render(); + + sun->getMaterial(0).ColorMask = ECP_NONE; + + // Fade to quarter + m_material.MaterialType = irr_driver->getShader(ES_GODFADE); + m_material.setTexture(0, out); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); + + drawQuad(cam, m_material); + + // Blur + { + gacb->setResolution(UserConfigParams::m_width / 4, + UserConfigParams::m_height / 4); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); + + drawQuad(cam, m_material); + } + + // Calculate the sun's position in texcoords + const core::vector3df pos = sun->getPosition(); + float ndc[4]; + core::matrix4 trans = camnode->getProjectionMatrix(); + trans *= camnode->getViewMatrix(); + + 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 sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw; + const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh; + + ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))-> + setSunPosition(sunx, suny); + + // Rays please + m_material.MaterialType = irr_driver->getShader(ES_GODRAY); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); + + drawQuad(cam, m_material); + + // Blur + { + gacb->setResolution(UserConfigParams::m_width / 4, + UserConfigParams::m_height / 4); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false); + + drawQuad(cam, m_material); + } + + // Overlay + m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR; + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(in, false, false); + + drawQuad(cam, m_material); + } + + if (UserConfigParams::m_motionblur && m_any_boost) // motion blur + { + // Calculate the kart's Y position on screen + const core::vector3df pos = + Camera::getCamera(cam)->getKart()->getNode()->getPosition(); + float ndc[4]; + core::matrix4 trans = camnode->getProjectionMatrix(); + trans *= camnode->getViewMatrix(); + + trans.transformVect(ndc, pos); + const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f; + setMotionBlurCenterY(cam, karty); + + + m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR); + m_material.setTexture(0, in); + drv->setRenderTarget(out, true, false); + + drawQuad(cam, m_material); + + ITexture *tmp = in; + in = out; + out = tmp; + } + + if (irr_driver->getDisplacingNodes().size()) // Displacement + { + m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE); + m_material.setFlag(EMF_BILINEAR_FILTER, false); + m_material.setTexture(0, in); + m_material.setTexture(1, irr_driver->getRTT(RTT_DISPLACE)); + drv->setRenderTarget(out, true, false); + + drawQuad(cam, m_material); + + m_material.setTexture(1, 0); + m_material.setFlag(EMF_BILINEAR_FILTER, true); + + ITexture *tmp = in; + in = out; + out = tmp; + } + + if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. + { + drv->setRenderTarget(out, false, false); + + glEnable(GL_STENCIL_TEST); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glStencilFunc(GL_ALWAYS, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + // Pass 1: color edge detection + m_material.setFlag(EMF_BILINEAR_FILTER, false); + m_material.setFlag(EMF_TRILINEAR_FILTER, false); + m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1); + m_material.setTexture(0, in); + + drawQuad(cam, m_material); + m_material.setFlag(EMF_BILINEAR_FILTER, true); + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + + glStencilFunc(GL_EQUAL, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // Pass 2: blend weights + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + + m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2); + m_material.setTexture(0, out); + m_material.setTexture(1, m_areamap); + m_material.TextureLayer[1].BilinearFilter = false; + m_material.TextureLayer[1].TrilinearFilter = false; + + drawQuad(cam, m_material); + + m_material.TextureLayer[1].BilinearFilter = true; + m_material.TextureLayer[1].TrilinearFilter = true; + m_material.setTexture(1, 0); + + // Pass 3: gather + drv->setRenderTarget(in, false, false); + + m_material.setFlag(EMF_BILINEAR_FILTER, false); + m_material.setFlag(EMF_TRILINEAR_FILTER, false); + m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3); + m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); + m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR)); + + drawQuad(cam, m_material); + + m_material.setFlag(EMF_BILINEAR_FILTER, true); + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + m_material.setTexture(1, 0); + + // Done. + glDisable(GL_STENCIL_TEST); + } + + // Final blit + + if (irr_driver->getNormals()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + } else if (irr_driver->getSSAOViz()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); + } else if (irr_driver->getShadowViz()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_SHADOW)); + } else + { + m_material.MaterialType = irr_driver->getShader(ES_COLOR_LEVELS); + m_material.setTexture(0, in); + } + + drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); + + drawQuad(cam, m_material); + } +} // render + +void PostProcessing::drawQuad(u32 cam, const SMaterial &mat) +{ + const u16 indices[6] = {0, 1, 2, 3, 0, 2}; + IVideoDriver * const drv = irr_driver->getVideoDriver(); + + drv->setTransform(ETS_WORLD, core::IdentityMatrix); + drv->setTransform(ETS_VIEW, core::IdentityMatrix); + drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); + + drv->setMaterial(mat); + drv->drawIndexedTriangleList(&(m_vertices[cam].v0), + 4, indices, 2); +} From a49d85fa3eaab34d553b400ca7e38feddd4832cf Mon Sep 17 00:00:00 2001 From: hikerstk Date: Sun, 12 Jan 2014 22:43:45 +0000 Subject: [PATCH 253/412] Replaced pop_back, which is not available on all compilers (for std::string). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15025 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/online/http_request.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/online/http_request.cpp b/src/online/http_request.cpp index 54630c841..81593b038 100644 --- a/src/online/http_request.cpp +++ b/src/online/http_request.cpp @@ -184,7 +184,9 @@ namespace Online // All parameters added have a '&' added if(m_parameters.size()>0) - m_parameters.pop_back(); + { + m_parameters.erase(m_parameters.size()-1); + } Log::info("HTTPRequest", "Sending %s to %s", m_parameters.c_str(), m_url.c_str()); From f8e17ecffa82a7c7eca1b876ade9c785869d328d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 23:19:28 +0000 Subject: [PATCH 254/412] Use direct gl calls for BloomBlend too. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15026 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/bloomblend.frag | 6 +- src/graphics/post_processing.cpp | 121 ++++++++++++++++++++++--------- 2 files changed, 89 insertions(+), 38 deletions(-) diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag index c01aaa9b9..94c952d6f 100644 --- a/data/shaders/bloomblend.frag +++ b/data/shaders/bloomblend.frag @@ -1,11 +1,13 @@ #version 130 uniform sampler2D tex; +in vec2 uv; + void main() { - vec4 col = texture2D(tex, gl_TexCoord[0].xy); + vec4 col = texture2D(tex, uv); col.xyz *= 10.0 * col.a; - gl_FragColor = vec4(col.xyz, 1.0); + gl_FragColor = vec4(col.xyz, 1.); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 9085d5dc1..2ab7dc57c 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -240,34 +240,62 @@ static void initQuadVBO() glBindBuffer(GL_ARRAY_BUFFER, 0); } -namespace BloomShader -{ - GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_texture, uniform_low; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_texture = glGetUniformLocation(Program, "tex"); - uniform_low = glGetUniformLocation(Program, "low"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - } -} +namespace BloomShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture, uniform_low; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "tex"); + uniform_low = glGetUniformLocation(Program, "low"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace BloomBlendShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture, uniform_low; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "tex"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} static @@ -287,6 +315,33 @@ void renderBloom(ITexture *in) glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +static +void renderBloomBlend(ITexture *in) +{ + if (!BloomBlendShader::Program) + BloomBlendShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_DEPTH_TEST); + + glUseProgram(BloomBlendShader::Program); + glBindVertexArray(BloomBlendShader::vao); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(BloomBlendShader::uniform_texture, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); } // ---------------------------------------------------------------------------- @@ -477,14 +532,8 @@ void PostProcessing::render() } // Additively blend on top of tmp1 - m_material.BlendOperation = EBO_ADD; - m_material.MaterialType = irr_driver->getShader(ES_BLOOM_BLEND); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); - drv->setRenderTarget(out, false, false); - - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; + drv->setRenderTarget(out, false, false); + renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1)); } // end if bloom in = irr_driver->getRTT(RTT_TMP1); From 98f58d257cc06ca783616fa7b41817fbe9e9f38e Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 23:27:31 +0000 Subject: [PATCH 255/412] Clean bloom shader provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15027 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 7 ------- src/graphics/callbacks.hpp | 15 --------------- src/graphics/shaders.cpp | 6 ------ src/graphics/shaders.hpp | 2 -- 4 files changed, 30 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 5cdb2188d..5d1fb6f51 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -512,13 +512,6 @@ void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void BloomProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - srv->setVertexShaderConstant("low", &m_threshold, 1); -} - -//------------------------------------- - void MLAAColor1Provider::OnSetConstants(IMaterialRendererServices *srv, int) { core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 99ef8c1cf..f54b1d18c 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -481,21 +481,6 @@ private: // -class BloomProvider: public CallBase -{ -public: - BloomProvider() { m_threshold = 0.75f; } - - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - void setThreshold(const float f) { m_threshold = f; } - -private: - float m_threshold; -}; - -// - class MLAAColor1Provider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 5656ca5b4..4b26973db 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -50,7 +50,6 @@ Shaders::Shaders() m_callbacks[ES_LIGHTBLEND] = new LightBlendProvider(); m_callbacks[ES_POINTLIGHT] = new PointLightProvider(); m_callbacks[ES_SUNLIGHT] = new SunLightProvider(); - m_callbacks[ES_BLOOM] = new BloomProvider(); m_callbacks[ES_MLAA_COLOR1] = new MLAAColor1Provider(); m_callbacks[ES_MLAA_BLEND2] = new MLAABlend2Provider(); m_callbacks[ES_MLAA_NEIGH3] = new MLAANeigh3Provider(); @@ -143,9 +142,6 @@ void Shaders::loadShaders() m_shaders[ES_COLOR_LEVELS] = glslmat(std::string(""), dir + "color_levels.frag", m_callbacks[ES_COLOR_LEVELS], EMT_SOLID); - m_shaders[ES_BLOOM] = glslmat(std::string(""), dir + "bloom.frag", - m_callbacks[ES_BLOOM], EMT_SOLID); - m_shaders[ES_COLORIZE] = glslmat(std::string(""), dir + "colorize.frag", m_callbacks[ES_COLORIZE], EMT_SOLID); m_shaders[ES_COLORIZE_REF] = glslmat(std::string(""), dir + "colorize_ref.frag", @@ -205,8 +201,6 @@ void Shaders::loadShaders() m_shaders[ES_BLOOM_POWER] = glsl(std::string(""), dir + "bloompower.frag", m_callbacks[ES_BLOOM_POWER]); - m_shaders[ES_BLOOM_BLEND] = glslmat(std::string(""), dir + "bloomblend.frag", - 0, EMT_TRANSPARENT_ADD_COLOR); m_shaders[ES_MULTIPLY_ADD] = glslmat(std::string(""), dir + "multiply.frag", m_callbacks[ES_MULTIPLY_ADD], EMT_ONETEXTURE_BLEND); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 285363cf6..ecafde294 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -41,7 +41,6 @@ using namespace irr; ACT(ES_FLIP) \ ACT(ES_FLIP_ADDITIVE) \ ACT(ES_COLOR_LEVELS) \ - ACT(ES_BLOOM) \ ACT(ES_GAUSSIAN6H) \ ACT(ES_GAUSSIAN6V) \ ACT(ES_COLORIZE) \ @@ -68,7 +67,6 @@ using namespace irr; ACT(ES_SHADOW_WARPH) \ ACT(ES_SHADOW_WARPV) \ ACT(ES_BLOOM_POWER) \ - ACT(ES_BLOOM_BLEND) \ ACT(ES_MULTIPLY_ADD) \ ACT(ES_PENUMBRAH) \ ACT(ES_PENUMBRAV) \ From 47d7f4fdd4ec922005977fe55435567328f9161d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 23:43:00 +0000 Subject: [PATCH 256/412] Use direct gl calls for ppdisplace. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15028 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ppdisplace.frag | 4 +- src/graphics/post_processing.cpp | 69 ++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/data/shaders/ppdisplace.frag b/data/shaders/ppdisplace.frag index 5e4cf1606..fa4269f5e 100644 --- a/data/shaders/ppdisplace.frag +++ b/data/shaders/ppdisplace.frag @@ -4,9 +4,11 @@ uniform sampler2D dtex; uniform int viz; +in vec2 uv; + void main() { - vec2 tc = gl_TexCoord[0].xy; + vec2 tc = uv; vec4 shiftval = texture2D(dtex, tc) / vec4(50.0); vec2 shift; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 2ab7dc57c..af553ba4a 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -297,6 +297,36 @@ namespace BloomBlendShader } } +namespace PPDisplaceShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_dtex, uniform_viz; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_dtex = glGetUniformLocation(Program, "dtex"); + uniform_viz = glGetUniformLocation(Program, "viz"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -344,6 +374,37 @@ void renderBloomBlend(ITexture *in) glDisable(GL_BLEND); } +static +void renderPPDisplace(ITexture *in) +{ + if (!PPDisplaceShader::Program) + PPDisplaceShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_DEPTH_TEST); + + glUseProgram(PPDisplaceShader::Program); + glBindVertexArray(PPDisplaceShader::vao); + glUniform1i(PPDisplaceShader::uniform_viz, irr_driver->getDistortViz()); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(PPDisplaceShader::uniform_tex, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_DISPLACE))->getOpenGLTextureName()); + glUniform1i(PPDisplaceShader::uniform_dtex, 1); + + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -661,7 +722,9 @@ void PostProcessing::render() if (irr_driver->getDisplacingNodes().size()) // Displacement { - m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE); + drv->setRenderTarget(out, true, false); + renderPPDisplace(in); +/* m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE); m_material.setFlag(EMF_BILINEAR_FILTER, false); m_material.setTexture(0, in); m_material.setTexture(1, irr_driver->getRTT(RTT_DISPLACE)); @@ -670,7 +733,7 @@ void PostProcessing::render() drawQuad(cam, m_material); m_material.setTexture(1, 0); - m_material.setFlag(EMF_BILINEAR_FILTER, true); + m_material.setFlag(EMF_BILINEAR_FILTER, true);*/ ITexture *tmp = in; in = out; @@ -747,7 +810,7 @@ void PostProcessing::render() } else if (irr_driver->getShadowViz()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SHADOW)); + m_material.setTexture(0, irr_driver->getRTT(RTT_DISPLACE)); } else { m_material.MaterialType = irr_driver->getShader(ES_COLOR_LEVELS); From 1da42b81a667a8ff8d093d480021a085c76884e4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 23:47:34 +0000 Subject: [PATCH 257/412] Remove PPDisplace provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15029 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 19 ------------------- src/graphics/callbacks.hpp | 8 -------- src/graphics/shaders.cpp | 3 --- src/graphics/shaders.hpp | 1 - 4 files changed, 31 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 5d1fb6f51..c079f3a96 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -815,25 +815,6 @@ void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void PPDisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - int viz = irr_driver->getDistortViz(); - srv->setPixelShaderConstant("viz", &viz, 1); - - if (!firstdone) - { - int tex = 0; - srv->setPixelShaderConstant("tex", &tex, 1); - - tex = 1; - srv->setPixelShaderConstant("dtex", &tex, 1); - - firstdone = true; - } -} - -//------------------------------------- - void FogProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const Track * const track = World::getWorld()->getTrack(); diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index f54b1d18c..1099e23cb 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -693,14 +693,6 @@ private: // -class PPDisplaceProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class FogProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 4b26973db..ed7da6b42 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -63,7 +63,6 @@ Shaders::Shaders() m_callbacks[ES_SHADOWGEN] = new ShadowGenProvider(); m_callbacks[ES_CAUSTICS] = new CausticsProvider(); m_callbacks[ES_DISPLACE] = new DisplaceProvider(); - m_callbacks[ES_PPDISPLACE] = new PPDisplaceProvider(); m_callbacks[ES_FOG] = new FogProvider(); for(s32 i=0 ; i < ES_COUNT ; i++) @@ -217,8 +216,6 @@ void Shaders::loadShaders() m_shaders[ES_DISPLACE] = glsl(dir + "displace.vert", dir + "displace.frag", m_callbacks[ES_DISPLACE]); - m_shaders[ES_PPDISPLACE] = glsl(std::string(""), dir + "ppdisplace.frag", - m_callbacks[ES_PPDISPLACE]); m_shaders[ES_PASSFAR] = glsl(dir + "farplane.vert", dir + "colorize.frag", m_callbacks[ES_COLORIZE]); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index ecafde294..f6bf569d2 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -73,7 +73,6 @@ using namespace irr; ACT(ES_SHADOWGEN) \ ACT(ES_CAUSTICS) \ ACT(ES_DISPLACE) \ - ACT(ES_PPDISPLACE) \ ACT(ES_PASSFAR) \ ACT(ES_FOG) From 6d57947c739c4d461e884bf56b7b30e3d97ba4f6 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Sun, 12 Jan 2014 23:52:13 +0000 Subject: [PATCH 258/412] Remove some leftover comments. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15030 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 27 +-------------------------- src/graphics/post_processing.cpp | 10 ---------- 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d854756b7..2a3686fac 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -242,9 +242,7 @@ void ParticleSystemProxy::setFlip() { for (unsigned i = 0; i < count; i++) { core::vector3df rotationdir(0., 1., 0.); - /*rotationdir.rotateXYBy(os::Randomizer::frand() * 180.); - rotationdir.rotateYZBy(os::Randomizer::frand() * 180.); - rotationdir.rotateXZBy(os::Randomizer::frand() * 180.);*/ + quaternions[4 * i] = rotationdir.X; quaternions[4 * i + 1] = rotationdir.Y; quaternions[4 * i + 2] = rotationdir.Z; @@ -602,17 +600,6 @@ void ParticleSystemProxy::drawFlip() glUniformMatrix4fv(FlipParticleRender::uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); glUniformMatrix4fv(FlipParticleRender::uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); -/* glUniform1i(FlipParticleRender::uniform_has_heightmap, has_height_map); - if (has_height_map) - { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture); - glUniform1i(FlipParticleRender::uniform_heightmap, 2); - glUniform1f(FlipParticleRender::uniform_track_x, track_x); - glUniform1f(FlipParticleRender::uniform_track_z, track_z); - glUniform1f(FlipParticleRender::uniform_track_x_len, track_x_len); - glUniform1f(FlipParticleRender::uniform_track_z_len, track_z_len); - }*/ glEnableVertexAttribArray(FlipParticleRender::attrib_rotationvec); glEnableVertexAttribArray(FlipParticleRender::attrib_anglespeed); glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer); @@ -682,18 +669,6 @@ void ParticleSystemProxy::drawNotFlip() glUniformMatrix4fv(SimpleParticleRender::uniform_matrix, 1, GL_FALSE, irr_driver->getProjMatrix().pointer()); glUniformMatrix4fv(SimpleParticleRender::uniform_viewmatrix, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); -/* glUniform1i(SimpleParticleRender::uniform_has_heightmap, has_height_map); - if (has_height_map) - { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_BUFFER, heightmaptexture); - glUniform1i(SimpleParticleRender::uniform_heightmap, 2); - glUniform1f(SimpleParticleRender::uniform_track_x, track_x); - glUniform1f(SimpleParticleRender::uniform_track_z, track_z); - glUniform1f(SimpleParticleRender::uniform_track_x_len, track_x_len); - glUniform1f(SimpleParticleRender::uniform_track_z_len, track_z_len); - }*/ - glBindBuffer(GL_ARRAY_BUFFER, quad_vertex_buffer); glVertexAttribPointer(SimpleParticleRender::attrib_quadcorner, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(SimpleParticleRender::attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index af553ba4a..f627cfe57 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -724,16 +724,6 @@ void PostProcessing::render() { drv->setRenderTarget(out, true, false); renderPPDisplace(in); -/* m_material.MaterialType = irr_driver->getShader(ES_PPDISPLACE); - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setTexture(0, in); - m_material.setTexture(1, irr_driver->getRTT(RTT_DISPLACE)); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - m_material.setTexture(1, 0); - m_material.setFlag(EMF_BILINEAR_FILTER, true);*/ ITexture *tmp = in; in = out; From 164f1dda11ff620fe0334dbbb2f030098e426b15 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 00:04:53 +0000 Subject: [PATCH 259/412] Use direct gl calls for color_levels. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15031 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/color_levels.frag | 6 ++- src/graphics/post_processing.cpp | 70 ++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/data/shaders/color_levels.frag b/data/shaders/color_levels.frag index 2aed42742..af12b739c 100644 --- a/data/shaders/color_levels.frag +++ b/data/shaders/color_levels.frag @@ -3,10 +3,12 @@ uniform sampler2D tex; uniform vec3 inlevel; uniform vec2 outlevel; +in vec2 uv; + void main() { - vec2 texc = gl_TexCoord[0].xy; - texc.y = 1.0 - texc.y; + vec2 texc = uv; + //texc.y = 1.0 - texc.y; vec4 col = texture2D(tex, texc); diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f627cfe57..266eefc72 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -327,6 +327,36 @@ namespace PPDisplaceShader } } +namespace ColorLevelShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_inlevel, uniform_outlevel; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_inlevel = glGetUniformLocation(Program, "inlevel"); + uniform_outlevel = glGetUniformLocation(Program, "outlevel"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -405,6 +435,34 @@ void renderPPDisplace(ITexture *in) glDisable(GL_BLEND); } +static +void renderColorLevel(ITexture *in) +{ + core::vector3df m_inlevel = World::getWorld()->getTrack()->getColorLevelIn(); + core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut(); + + + if (!ColorLevelShader::Program) + ColorLevelShader::init(); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + glUseProgram(ColorLevelShader::Program); + glBindVertexArray(ColorLevelShader::vao); + glUniform3f(ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z); + glUniform2f(ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(ColorLevelShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -788,28 +846,26 @@ void PostProcessing::render() } // Final blit - + drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); if (irr_driver->getNormals()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + drawQuad(cam, m_material); } else if (irr_driver->getSSAOViz()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); + drawQuad(cam, m_material); } else if (irr_driver->getShadowViz()) { m_material.MaterialType = irr_driver->getShader(ES_FLIP); m_material.setTexture(0, irr_driver->getRTT(RTT_DISPLACE)); + drawQuad(cam, m_material); } else { - m_material.MaterialType = irr_driver->getShader(ES_COLOR_LEVELS); - m_material.setTexture(0, in); + renderColorLevel(in); } - - drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); - - drawQuad(cam, m_material); } } // render From 468d5458bccc4b7d6cb093ed404af9811bbd58df Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 00:11:31 +0000 Subject: [PATCH 260/412] Clean color_level shader providers. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15032 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 20 -------------------- src/graphics/callbacks.hpp | 17 ----------------- src/graphics/shaders.cpp | 4 ---- src/graphics/shaders.hpp | 1 - 4 files changed, 42 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index c079f3a96..6970ddf26 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -153,26 +153,6 @@ void GrassShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int use } } -//------------------------------------- - -void ColorLevelsProvider::OnSetConstants(IMaterialRendererServices *srv, int userData) -{ - - m_inlevel = World::getWorld()->getTrack()->getColorLevelIn(); - m_outlevel = World::getWorld()->getTrack()->getColorLevelOut(); - - srv->setVertexShaderConstant("inlevel", &m_inlevel.X, 3); - srv->setVertexShaderConstant("outlevel", &m_outlevel.X, 2); - - if (!firstdone) - { - s32 tex = 0; - srv->setVertexShaderConstant("tex", &tex, 1); - - firstdone = true; - } -} - //------------------------------------- void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int) { diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 1099e23cb..d7f946d52 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -139,23 +139,6 @@ private: // -class ColorLevelsProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - - ColorLevelsProvider() - { - } - -private: - core::vector3df m_inlevel; - core::vector2df m_outlevel; -}; - -// - class SkyboxProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index ed7da6b42..1e4f790ad 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -38,7 +38,6 @@ Shaders::Shaders() m_callbacks[ES_SPLATTING] = new SplattingProvider(); m_callbacks[ES_WATER] = new WaterShaderProvider(); m_callbacks[ES_GRASS] = new GrassShaderProvider(); - m_callbacks[ES_COLOR_LEVELS] = new ColorLevelsProvider(); m_callbacks[ES_BUBBLES] = new BubbleEffectProvider(); m_callbacks[ES_RAIN] = new RainEffectProvider(); m_callbacks[ES_MOTIONBLUR] = new MotionBlurProvider(); @@ -137,9 +136,6 @@ void Shaders::loadShaders() 0, EMT_SOLID); m_shaders[ES_FLIP_ADDITIVE] = glslmat(std::string(""), dir + "flip.frag", 0, EMT_TRANSPARENT_ADD_COLOR); - - m_shaders[ES_COLOR_LEVELS] = glslmat(std::string(""), dir + "color_levels.frag", - m_callbacks[ES_COLOR_LEVELS], EMT_SOLID); m_shaders[ES_COLORIZE] = glslmat(std::string(""), dir + "colorize.frag", m_callbacks[ES_COLORIZE], EMT_SOLID); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index f6bf569d2..a6968259f 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -40,7 +40,6 @@ using namespace irr; ACT(ES_MIPVIZ) \ ACT(ES_FLIP) \ ACT(ES_FLIP_ADDITIVE) \ - ACT(ES_COLOR_LEVELS) \ ACT(ES_GAUSSIAN6H) \ ACT(ES_GAUSSIAN6V) \ ACT(ES_COLORIZE) \ From c8d066ce370677e6dfac415c4c7e0f84f52a2dee Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 13 Jan 2014 03:02:08 +0000 Subject: [PATCH 261/412] Fixed compiler warnings. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15033 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/gpuparticles.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2a3686fac..2b33230d4 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -246,7 +246,7 @@ void ParticleSystemProxy::setFlip() { quaternions[4 * i] = rotationdir.X; quaternions[4 * i + 1] = rotationdir.Y; quaternions[4 * i + 2] = rotationdir.Z; - quaternions[4 * i + 3] = 3.14 * 3. * (2. * os::Randomizer::frand() - 1.); // 3 half rotation during lifetime at max + quaternions[4 * i + 3] = 3.14f * 3.f * (2.f * os::Randomizer::frand() - 1.f); // 3 half rotation during lifetime at max } glGenBuffers(1, &quaternionsbuffer); glBindBuffer(GL_ARRAY_BUFFER, quaternionsbuffer); @@ -463,7 +463,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) void ParticleSystemProxy::simulateHeightmap() { - int timediff = GUIEngine::getLatestDt() * 1000.; + int timediff = int(GUIEngine::getLatestDt() * 1000.f); int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(HeightmapSimulationShader::Program); From 428f74d859c4d316d0b46ff6cc887694d05d8782 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 13 Jan 2014 05:21:48 +0000 Subject: [PATCH 262/412] Removed old network_http and related data structure. Its function is now either in the addons/news_manager, or in Online::RequestManager. Also added leack check and copy-preventing to online/Request. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15034 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- sources.cmake | 35 +- src/addons/addons_manager.cpp | 37 +- src/addons/dummy_network_http.hpp | 49 -- src/addons/inetwork_http.cpp | 48 -- src/addons/inetwork_http.hpp | 67 -- src/addons/network_http.cpp | 592 ------------------ src/addons/network_http.hpp | 92 --- src/addons/news_manager.cpp | 15 +- src/addons/news_manager.hpp | 5 +- src/addons/request.cpp | 63 -- src/addons/request.hpp | 127 ---- src/graphics/gpuparticles.cpp | 2 +- src/main.cpp | 32 +- src/online/request.hpp | 6 +- src/online/request_manager.hpp | 12 +- src/states_screens/addons_screen.cpp | 17 +- src/states_screens/dialogs/addons_loading.cpp | 18 +- src/states_screens/dialogs/addons_loading.hpp | 4 +- src/states_screens/main_menu_screen.cpp | 7 +- src/states_screens/options_screen_ui.cpp | 19 +- 20 files changed, 106 insertions(+), 1141 deletions(-) delete mode 100644 src/addons/dummy_network_http.hpp delete mode 100644 src/addons/inetwork_http.cpp delete mode 100644 src/addons/inetwork_http.hpp delete mode 100644 src/addons/network_http.cpp delete mode 100644 src/addons/network_http.hpp delete mode 100644 src/addons/request.cpp delete mode 100644 src/addons/request.hpp diff --git a/sources.cmake b/sources.cmake index b59bf4fb9..d32269956 100644 --- a/sources.cmake +++ b/sources.cmake @@ -6,10 +6,7 @@ src/achievements/achievements_manager.cpp src/achievements/achievements_slot.cpp src/addons/addon.cpp src/addons/addons_manager.cpp -src/addons/inetwork_http.cpp -src/addons/network_http.cpp src/addons/news_manager.cpp -src/addons/request.cpp src/addons/zip.cpp src/animations/animation_base.cpp src/animations/ipo.cpp @@ -118,8 +115,8 @@ src/items/projectile_manager.cpp src/items/rubber_ball.cpp src/items/rubber_band.cpp src/items/swatter.cpp -src/karts/abstract_kart_animation.cpp src/karts/abstract_kart.cpp +src/karts/abstract_kart_animation.cpp src/karts/cannon_animation.cpp src/karts/controller/ai_base_controller.cpp src/karts/controller/ai_properties.cpp @@ -252,8 +249,8 @@ src/states_screens/help_screen_3.cpp src/states_screens/help_screen_4.cpp src/states_screens/kart_selection.cpp src/states_screens/main_menu_screen.cpp -src/states_screens/networking_lobby.cpp src/states_screens/network_kart_selection.cpp +src/states_screens/networking_lobby.cpp src/states_screens/offline_kart_selection.cpp src/states_screens/online_profile_achievements.cpp src/states_screens/online_profile_base.cpp @@ -263,13 +260,13 @@ src/states_screens/online_profile_settings.cpp src/states_screens/online_screen.cpp src/states_screens/online_user_search.cpp src/states_screens/options_screen_audio.cpp -src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_input.cpp +src/states_screens/options_screen_input2.cpp src/states_screens/options_screen_players.cpp src/states_screens/options_screen_ui.cpp src/states_screens/options_screen_video.cpp -src/states_screens/race_gui_base.cpp src/states_screens/race_gui.cpp +src/states_screens/race_gui_base.cpp src/states_screens/race_gui_overworld.cpp src/states_screens/race_result_gui.cpp src/states_screens/race_setup_screen.cpp @@ -329,18 +326,14 @@ src/achievements/achievements_manager.hpp src/achievements/achievements_slot.hpp src/addons/addon.hpp src/addons/addons_manager.hpp -src/addons/dummy_network_http.hpp -src/addons/inetwork_http.hpp -src/addons/network_http.hpp src/addons/news_manager.hpp -src/addons/request.hpp src/addons/zip.hpp src/animations/animation_base.hpp src/animations/ipo.hpp src/animations/three_d_animation.hpp src/audio/dummy_sfx.hpp -src/audio/music_dummy.hpp src/audio/music.hpp +src/audio/music_dummy.hpp src/audio/music_information.hpp src/audio/music_manager.hpp src/audio/music_ogg.hpp @@ -348,8 +341,8 @@ src/audio/sfx_base.hpp src/audio/sfx_buffer.hpp src/audio/sfx_manager.hpp src/audio/sfx_openal.hpp -src/challenges/challenge_data.hpp src/challenges/challenge.hpp +src/challenges/challenge_data.hpp src/challenges/game_slot.hpp src/challenges/unlock_manager.hpp src/config/device_config.hpp @@ -407,11 +400,11 @@ src/guiengine/scalable_font.hpp src/guiengine/screen.hpp src/guiengine/skin.hpp src/guiengine/widget.hpp +src/guiengine/widgets.hpp src/guiengine/widgets/bubble_widget.hpp src/guiengine/widgets/button_widget.hpp src/guiengine/widgets/check_box_widget.hpp src/guiengine/widgets/dynamic_ribbon_widget.hpp -src/guiengine/widgets.hpp src/guiengine/widgets/icon_button_widget.hpp src/guiengine/widgets/label_widget.hpp src/guiengine/widgets/list_widget.hpp @@ -423,8 +416,8 @@ src/guiengine/widgets/spinner_widget.hpp src/guiengine/widgets/text_box_widget.hpp src/input/binding.hpp src/input/device_manager.hpp -src/input/input_device.hpp src/input/input.hpp +src/input/input_device.hpp src/input/input_manager.hpp src/input/wiimote.hpp src/input/wiimote_manager.hpp @@ -446,8 +439,8 @@ src/items/projectile_manager.hpp src/items/rubber_ball.hpp src/items/rubber_band.hpp src/items/swatter.hpp -src/karts/abstract_kart_animation.hpp src/karts/abstract_kart.hpp +src/karts/abstract_kart_animation.hpp src/karts/cannon_animation.hpp src/karts/controller/ai_base_controller.hpp src/karts/controller/ai_properties.hpp @@ -459,8 +452,8 @@ src/karts/controller/player_controller.hpp src/karts/controller/skidding_ai.hpp src/karts/explosion_animation.hpp src/karts/ghost_kart.hpp -src/karts/kart_gfx.hpp src/karts/kart.hpp +src/karts/kart_gfx.hpp src/karts/kart_model.hpp src/karts/kart_properties.hpp src/karts/kart_properties_manager.hpp @@ -585,8 +578,8 @@ src/states_screens/help_screen_3.hpp src/states_screens/help_screen_4.hpp src/states_screens/kart_selection.hpp src/states_screens/main_menu_screen.hpp -src/states_screens/networking_lobby.hpp src/states_screens/network_kart_selection.hpp +src/states_screens/networking_lobby.hpp src/states_screens/offline_kart_selection.hpp src/states_screens/online_profile_achievements.hpp src/states_screens/online_profile_base.hpp @@ -596,13 +589,13 @@ src/states_screens/online_profile_settings.hpp src/states_screens/online_screen.hpp src/states_screens/online_user_search.hpp src/states_screens/options_screen_audio.hpp -src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_input.hpp +src/states_screens/options_screen_input2.hpp src/states_screens/options_screen_players.hpp src/states_screens/options_screen_ui.hpp src/states_screens/options_screen_video.hpp -src/states_screens/race_gui_base.hpp src/states_screens/race_gui.hpp +src/states_screens/race_gui_base.hpp src/states_screens/race_gui_overworld.hpp src/states_screens/race_result_gui.hpp src/states_screens/race_setup_screen.hpp @@ -633,8 +626,8 @@ src/tracks/check_sphere.hpp src/tracks/check_structure.hpp src/tracks/graph_node.hpp src/tracks/lod_node_loader.hpp -src/tracks/quad_graph.hpp src/tracks/quad.hpp +src/tracks/quad_graph.hpp src/tracks/quad_set.hpp src/tracks/terrain_info.hpp src/tracks/track.hpp diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index 49c53b61b..c54bbd9e0 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -20,7 +20,6 @@ #include "addons/addons_manager.hpp" -#include "addons/inetwork_http.hpp" #include "addons/news_manager.hpp" #include "addons/zip.hpp" #include "io/file_manager.hpp" @@ -42,12 +41,15 @@ #include #include +using namespace Online; + AddonsManager* addons_manager = 0; // ---------------------------------------------------------------------------- /** Initialises the non-online component of the addons manager (i.e. handling * the list of already installed addons). The online component is initialised - * later from a separate thread in network_http (once network_http is setup). + * later from a separate thread started from the news manager (see + * NewsManager::init() ). */ AddonsManager::AddonsManager() : m_addons_list(std::vector() ), m_state(STATE_INIT) @@ -72,6 +74,14 @@ AddonsManager::~AddonsManager() } // ~AddonsManager // ---------------------------------------------------------------------------- +/** This init function is called from a separate thread (started in + * news_manager, since the news.xml file contains the address of the + * addons.xml URL). + * \param xml The news.xml file, which inclues the data about the addons.xml + * file (in the 'include' node). + * \param force_refresh Download addons.xml, even if the usual waiting period + * between downloads hasn't passed yet. + */ void AddonsManager::init(const XMLNode *xml, bool force_refresh) { @@ -82,9 +92,8 @@ void AddonsManager::init(const XMLNode *xml, if(!include) { file_manager->removeFile(filename); + setErrorState(); NewsManager::get()->addNewsMessage(_("Can't access stkaddons server...")); - // Use a curl error code here: - //return CURLE_COULDNT_CONNECT; return; } @@ -121,16 +130,15 @@ void AddonsManager::init(const XMLNode *xml, addons_manager->initAddons(xml_addons); // will free xml_addons if(UserConfigParams::logAddons()) Log::info("addons", "Addons manager list downloaded"); - +} // init -} // ---------------------------------------------------------------------------- /** This initialises the online portion of the addons manager. It uses the - * downloaded list of available addons. This is called by network_http before - * it goes into command-receiving mode, so we can't use any asynchronous calls - * here (though this is being called from a separate thread , so the - * main GUI is not blocked anyway). This function will update the state - * variable + * downloaded list of available addons. It is called from init(), which is + * called from a separate thread, so blocking download requests can be used + * without blocking the GUI. This function will update the state variable. + * \param xml The xml tree of addons.xml with information about all available + * addons. */ void AddonsManager::initAddons(const XMLNode *xml) { @@ -144,8 +152,9 @@ void AddonsManager::initAddons(const XMLNode *xml) { const XMLNode *node = xml->getNode(i); const std::string &name = node->getName(); - // Ignore news/redirect, which is handled by network_http - if(name=="include" || name=="message") continue; + // Ignore news/redirect, which is handled by the NewsManager + if(name=="include" || name=="message") + continue; if(node->getName()=="track" || node->getName()=="kart" || node->getName()=="arena" ) { @@ -258,7 +267,7 @@ void AddonsManager::initAddons(const XMLNode *xml) m_state.setAtomic(STATE_READY); - if (UserConfigParams::m_internet_status == INetworkHttp::IPERM_ALLOWED) + if (UserConfigParams::m_internet_status == RequestManager::IPERM_ALLOWED) downloadIcons(); } // initAddons diff --git a/src/addons/dummy_network_http.hpp b/src/addons/dummy_network_http.hpp deleted file mode 100644 index 7b00fe586..000000000 --- a/src/addons/dummy_network_http.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010-2013 Lucas Baudin -// 2011 Lucas Baudin, Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_DUMMY_NETWORK_HTTP_HPP -#define HEADER_DUMMY_NETWORK_HTTP_HPP - - -#include "addons/request.hpp" -#include "addons/inetwork_http.hpp" - -class XMLNode; - -/** - * \ingroup addonsgroup - * Dummy implementation used when curl is not available - */ -class DummyNetworkHttp : public INetworkHttp -{ - -public: - virtual ~DummyNetworkHttp() {} - virtual void startNetworkThread() {} - virtual void stopNetworkThread() {} - virtual void insertReInit() {} - virtual Request *downloadFileAsynchron(const std::string &url, - const std::string &save = "", - int priority = 1, - bool manage_memory=true) { return NULL; } - virtual void cancelAllDownloads() {} -}; // NetworkHttp - - -#endif - diff --git a/src/addons/inetwork_http.cpp b/src/addons/inetwork_http.cpp deleted file mode 100644 index d1a8b9e96..000000000 --- a/src/addons/inetwork_http.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2012-2013 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "addons/dummy_network_http.hpp" -#include "addons/inetwork_http.hpp" -#include "addons/network_http.hpp" - -#include - -INetworkHttp *INetworkHttp::m_network_http = NULL; - -/** Creates the network_http instance (depending on compile time options). - */ -void INetworkHttp::create() -{ - assert(m_network_http == NULL); -#ifdef NO_CURL - m_network_http = new DummyNetworkHttp(); -#else - m_network_http = new NetworkHttp(); -#endif -} // create - -// ---------------------------------------------------------------------------- -/** Destroys the network_http instance. - */ -void INetworkHttp::destroy() -{ - if(m_network_http) - { - delete m_network_http; - m_network_http = NULL; - } -} // destroy diff --git a/src/addons/inetwork_http.hpp b/src/addons/inetwork_http.hpp deleted file mode 100644 index 7a49bf723..000000000 --- a/src/addons/inetwork_http.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010-2013 Lucas Baudin -// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_INETWORK_HTTP_HPP -#define HEADER_INETWORK_HTTP_HPP - - -#include "addons/request.hpp" - -class XMLNode; - -/** - * \ingroup addonsgroup - * Abstract base interface for the network manager - */ -class INetworkHttp -{ - -private: - /** The one instance of this object. */ - static INetworkHttp *m_network_http; - -public: - /** If stk has permission to access the internet (for news - * server etc). - * IPERM_NOT_ASKED: The user needs to be asked if he wants to - * grant permission - * IPERM_ALLOWED: STK is allowed to access server. - * IPERM_NOT_ALLOWED: STK must not access external servers. */ - enum InternetPermission {IPERM_NOT_ASKED =0, - IPERM_ALLOWED =1, - IPERM_NOT_ALLOWED=2 }; - -public: - virtual ~INetworkHttp() {} - virtual void startNetworkThread() = 0; - virtual void stopNetworkThread() = 0; - virtual void insertReInit() = 0; - virtual Request *downloadFileAsynchron(const std::string &url, - const std::string &save = "", - int priority = 1, - bool manage_memory=true) = 0; - virtual void cancelAllDownloads() = 0; - static void create(); - static INetworkHttp *get() { return m_network_http; } - static void destroy(); - -}; // NetworkHttp - - -#endif - diff --git a/src/addons/network_http.cpp b/src/addons/network_http.cpp deleted file mode 100644 index b0fec6e73..000000000 --- a/src/addons/network_http.cpp +++ /dev/null @@ -1,592 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010-2013 Lucas Baudin -// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef NO_CURL - -#include "addons/network_http.hpp" - -#include -#include -#include -#include -#include - -#include "addons/news_manager.hpp" -#include "addons/request.hpp" -#include "config/user_config.hpp" -#include "io/file_manager.hpp" -#include "states_screens/addons_screen.hpp" -#include "states_screens/main_menu_screen.hpp" -#include "utils/string_utils.hpp" -#include "utils/time.hpp" -#include "utils/translation.hpp" - -// ---------------------------------------------------------------------------- -/** Create a thread that handles all network functions independent of the - * main program. NetworkHttp supports only a single thread (i.e. it's not - * possible to download two addons at the same time), which makes handling - * and synchronisation a lot easier (otherwise all objects using this object - * would need an additional handle to get the right data back). - * This separate thread is running in NetworkHttp::mainLoop, and is being - * waken up if a command is issued (e.g. using downloadFileAsynchronous). - * While UserConfigParams are modified, they can't (easily) be saved here, - * since the user might trigger another save in the menu (potentially - * ending up with an corrupted file). - */ -NetworkHttp::NetworkHttp() : - m_current_request(NULL), - m_abort(false), - m_thread_id(NULL) -{ - // Don't even start the network threads if networking is disabled. - if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED ) - return; - - curl_global_init(CURL_GLOBAL_ALL); - m_curl_session = curl_easy_init(); - // Abort if curl error occurred. - if(!m_curl_session) - return; - - pthread_cond_init(&m_cond_request, NULL); - - Request *request = new Request(Request::HC_INIT, 9999); - m_all_requests.lock(); - m_all_requests.getData().push(request); - m_all_requests.unlock(); -} // NetworkHttp - -// --------------------------------------------------------------------------- -/** Start the actual network thread. This can not be done as part of - * the constructor, since the assignment to the global network_http - * variable has not been assigned at that stage, and the thread might - * use network_http - a very subtle race condition. So the thread can - * only be started after the assignment (in main) has been done. - */ -void NetworkHttp::startNetworkThread() -{ - if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED ) - return; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - // Should be the default, but just in case: - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - - m_thread_id.setAtomic(new pthread_t()); - int error = pthread_create(m_thread_id.getData(), &attr, - &NetworkHttp::mainLoop, this); - if(error) - { - m_thread_id.lock(); - delete m_thread_id.getData(); - m_thread_id.unlock(); - m_thread_id.setAtomic(0); - Log::warn("addons", "Could not create thread, error=%d", errno); - } - pthread_attr_destroy(&attr); -} // startNetworkThread - -// --------------------------------------------------------------------------- -/** The actual main loop, which is started as a separate thread from the - * constructor. After testing for a new server, fetching news, the list - * of packages to download, it will wait for commands to be issued. - * \param obj: A pointer to this object, passed on by pthread_create - */ -void *NetworkHttp::mainLoop(void *obj) -{ - NetworkHttp *me=(NetworkHttp*)obj; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - - me->m_current_request = NULL; - me->m_all_requests.lock(); - while(me->m_all_requests.getData().empty() || - me->m_all_requests.getData().top()->getCommand() != Request::HC_QUIT) - { - bool empty = me->m_all_requests.getData().empty(); - // Wait in cond_wait for a request to arrive. The 'while' is necessary - // since "spurious wakeups from the pthread_cond_wait ... may occur" - // (pthread_cond_wait man page)! - while(empty) - { - if(UserConfigParams::logAddons()) - Log::debug("addons", "No request, sleeping."); - - pthread_cond_wait(&me->m_cond_request, - me->m_all_requests.getMutex()); - empty = me->m_all_requests.getData().empty(); - } - // Get the first (=highest priority) request and remove it from the - // queue. Only this code actually removes requests from the queue, - // so it is certain that even - me->m_current_request = me->m_all_requests.getData().top(); - me->m_all_requests.getData().pop(); - if(UserConfigParams::logAddons()) - { - if(me->m_current_request->getCommand()==Request::HC_DOWNLOAD_FILE) - Log::info("addons", "Executing download '%s' to '%s' priority %d", - me->m_current_request->getURL().c_str(), - me->m_current_request->getSavePath().c_str(), - me->m_current_request->getPriority()); - else - Log::info("addons", "Executing command '%d' priority %d.", - me->m_current_request->getCommand(), - me->m_current_request->getPriority()); - } - if(me->m_current_request->getCommand()==Request::HC_QUIT) - { - delete me->m_current_request; - me->m_current_request = NULL; - break; - } - - me->m_all_requests.unlock(); - CURLcode status=CURLE_OK; - switch(me->m_current_request->getCommand()) - { - case Request::HC_INIT: - status = me->init(false); - break; - case Request::HC_REINIT: - status = me->reInit(); - break; - case Request::HC_DOWNLOAD_FILE: - status = me->downloadFileInternal(me->m_current_request); - break; - case Request::HC_QUIT: - assert(false); // quit is checked already - break; - default: - assert(false); // All commands should have been handled. - } // switch(request->getCommand()) - - if(me->m_current_request->manageMemory()) - { - delete me->m_current_request; - me->m_current_request = NULL; - } - // We have to lock here so that we can access m_all_requests - // in the while condition at the top of the loop - me->m_all_requests.lock(); - } // while !quit - if(UserConfigParams::logAddons()) - Log::info("addons", "Network exiting."); - - // At this stage we have the lock for m_all_requests - while(!me->m_all_requests.getData().empty()) - { - Request *r = me->m_all_requests.getData().top(); - me->m_all_requests.getData().pop(); - // Manage memory can be ignored here, all requests - // need to be freed. - delete r; - } - me->m_all_requests.unlock(); - - pthread_exit(NULL); - return 0; -} // mainLoop - -// --------------------------------------------------------------------------- -/** This function inserts a high priority request to quit into the request - * queue of the network thead, and also aborts any ongoing download. - * Separating this allows more time for the thread to finish cleanly, - * before it gets cancelled in the destructor. - */ -void NetworkHttp::stopNetworkThread() -{ - if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED) - return; - - // If a download should be active (which means it was cancelled by the - // user, in which case it will still be ongoing in the background) - // we can't get the mutex, and would have to wait for a timeout, - // and we couldn't finish STK. This way we request an abort of - // a download, which mean we can get the mutex and ask the service - // thread here to cancel properly. - cancelAllDownloads(); - - Request *r = new Request(Request::HC_QUIT, 9999); - if(UserConfigParams::logAddons()) - Log::info("addons", "Inserting QUIT request."); - insertRequest(r); -} // stopNetworkThread - -// --------------------------------------------------------------------------- -/** Aborts the thread running here, and returns then. - */ -NetworkHttp::~NetworkHttp() -{ - if(UserConfigParams::m_internet_status!=NetworkHttp::IPERM_ALLOWED) - return; - pthread_join(*m_thread_id.getData(), NULL); - delete m_thread_id.getAtomic(); - pthread_cond_destroy(&m_cond_request); - - curl_easy_cleanup(m_curl_session); - m_curl_session = NULL; - curl_global_cleanup(); -} // ~NetworkHttp - -// --------------------------------------------------------------------------- -/** Initialises the online part of the network manager. It downloads the - * news.xml file from the server (if the frequency of downloads makes this - * necessary), and (again if necessary) the addons.xml file. - * \return 0 if an error happened and no online connection will be available, - * 1 otherwise. - */ -CURLcode NetworkHttp::init(bool forceRefresh) -{ -#ifdef xx - status = loadAddonsList(xml, xml_file, forceRefresh); - - // Abort requested by stk -> display no error message and return - if(status==CURLE_ABORTED_BY_CALLBACK) - return status; - - - if(UserConfigParams::logAddons()) - Log::error("addons", "Error raised in NetworkHttp::init : %s", core::stringc(error_message).c_str()); - return status; -#endif - return CURLE_OK; -} // init - -// --------------------------------------------------------------------------- -/** Reinitialises the network manager. This is triggered when the users - * selects 'reload' in the addon manager screen. This function inserts - * a high priority reinit request into the request queue. - */ -void NetworkHttp::insertReInit() -{ - Request *request = new Request(Request::HC_REINIT, 9999, - /*manage_memory*/true); - - if(UserConfigParams::logAddons()) - Log::info("addons", "Inserting reInit request."); - insertRequest(request); -} // insertReInit - -// ---------------------------------------------------------------------------- -/** Reinitialises the addons manager. This function is triggered when a - * reInit request is handled. It removes all queued requests, deletes - * the news.xml and addons.xml files, and trigges a reload of those files. - */ -CURLcode NetworkHttp::reInit() -{ - // This also switches the addons_manager to be not ready anymore, - // so the main menu will grey out the addon manager icon. - addons_manager->reInit(); - - m_all_requests.lock(); - // There is no clear for a priority queue - while(!m_all_requests.getData().empty()) - m_all_requests.getData().pop(); - m_all_requests.unlock(); - - if(UserConfigParams::logAddons()) - Log::info("addons", "Xml files deleted, re-initialising addon manager."); - - return init(true /* force refresh */); - -} // reInit - -// ---------------------------------------------------------------------------- -/** Checks the last modified date and if necessary updates the - * list of addons. - * \param xml The news xml file which contains the data about - * the addon list. - * \param filename The filename of the news xml file. Only needed - * in case of an error (e.g. it might contain a corrupted - * url) - the file will be deleted so that on next start - * of stk it will be updated again. - * \return curl error code (esp. CURLE_OK if no error occurred) - */ -CURLcode NetworkHttp::loadAddonsList(const XMLNode *xml, - const std::string &filename, - bool forceRefresh) -{ - std::string addon_list_url(""); - StkTime::TimeType mtime(0); - const XMLNode *include = xml->getNode("include"); - if(include) - { - include->get("file", &addon_list_url); - - int64_t tmp; - include->get("mtime", &tmp); - mtime = tmp; - } - if(addon_list_url.size()==0) - { - file_manager->removeFile(filename); - NewsManager::get()->addNewsMessage(_("Can't access stkaddons server...")); - // Use a curl error code here: - return CURLE_COULDNT_CONNECT; - } - - bool download = (mtime > UserConfigParams::m_addons_last_updated) || forceRefresh; - - if(!download) - { - std::string filename=file_manager->getAddonsFile("addons.xml"); - if(!file_manager->fileExists(filename)) - download = true; - } - - if (download) - Log::info("NetworkHttp", "Downloading updated addons.xml"); - else - Log::info("NetworkHttp", "Using cached addons.xml"); - - Request r(Request::HC_DOWNLOAD_FILE, 9999, false, - addon_list_url, "addons.xml"); - CURLcode status = download ? downloadFileInternal(&r) - : CURLE_OK; - if(status==CURLE_OK) - { - std::string xml_file = file_manager->getAddonsFile("addons.xml"); - if(download) - UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch(); - const XMLNode *xml = new XMLNode(xml_file); -// addons_manager->initOnline(xml); - if(UserConfigParams::logAddons()) - Log::info("addons", "Addons manager list downloaded"); - return status; - } - - // Aborted by STK in progress callback, don't display error message - if(status==CURLE_ABORTED_BY_CALLBACK) - return status; - Log::error("addons", "Error on download addons.xml: %d\n", - status); - return status; -} // loadAddonsList - -// ---------------------------------------------------------------------------- -/** Download a file. The file name isn't absolute, the server in the config - * will be added to file. The file is downloaded with a ".part" extention, - * and the file is renamed after it was downloaded successfully. - * \param request The request object containing the url and the path where - * the file is saved to. - */ -CURLcode NetworkHttp::downloadFileInternal(Request *request) -{ - std::string full_save = - file_manager->getAddonsFile(request->getSavePath()); - - std::string full_url = request->getURL(); - if(full_url.substr(0, 5)!="http:" && full_url.substr(0, 4)!="ftp:") - full_url = (std::string)UserConfigParams::m_server_addons - + "/" + full_url; - if(UserConfigParams::logAddons()) - Log::info("addons", "Downloading '%s' as '%s'.", - full_url.c_str(), request->getSavePath().c_str()); - - curl_easy_setopt(m_curl_session, CURLOPT_URL, full_url.c_str()); - std::string uagent = (std::string)"SuperTuxKart/" + STK_VERSION; - // Add platform to user-agent string for informational purposes. - // Add more cases as necessary. - #ifdef WIN32 - uagent += (std::string)" (Windows)"; - #elif defined(__APPLE__) - uagent += (std::string)" (Macintosh)"; - #elif defined(__FreeBSD__) - uagent += (std::string)" (FreeBSD)"; - #elif defined(linux) - uagent += (std::string)" (Linux)"; - #else - // Unknown system type - #endif - curl_easy_setopt(m_curl_session, CURLOPT_USERAGENT, uagent.c_str()); - curl_easy_setopt(m_curl_session, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSDATA, request); - FILE * fout = fopen((full_save+".part").c_str(), "wb"); - - if(!fout) - { - Log::error("addons", "Can't open '%s' for writing, ignored.", - (full_save+".part").c_str()); - return CURLE_WRITE_ERROR; - } - //from and out - curl_easy_setopt(m_curl_session, CURLOPT_WRITEDATA, fout ); - curl_easy_setopt(m_curl_session, CURLOPT_WRITEFUNCTION, fwrite); - - curl_easy_setopt(m_curl_session, CURLOPT_PROGRESSFUNCTION, - &NetworkHttp::progressDownload); - curl_easy_setopt(m_curl_session, CURLOPT_NOPROGRESS, 0); - - // Timeout - // Reduce the connection phase timeout (it's 300 by default). - // Add a low speed limit to have a sort of timeout in the - // download phase. Being under 10 B/s during a certain time will - // probably only happen when no access to the net is available. - // The timeout is set to 20s, it should be enough to not produce - // false positive error. - curl_easy_setopt(m_curl_session, CURLOPT_CONNECTTIMEOUT, 20); - curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_LIMIT, 10); - curl_easy_setopt(m_curl_session, CURLOPT_LOW_SPEED_TIME, 20); - - CURLcode status = curl_easy_perform(m_curl_session); - fclose(fout); - if(status==CURLE_OK) - { - if(UserConfigParams::logAddons()) - Log::info("addons", "Download successful."); - // The behaviour of rename is unspecified if the target - // file should already exist - so remove it. - file_manager->removeFile(full_save); - int ret = rename((full_save+".part").c_str(), full_save.c_str()); - // In case of an error, set the status to indicate this - if(ret!=0) - { - if(UserConfigParams::logAddons()) - Log::error("addons", "Could not rename downloaded file!"); - status=CURLE_WRITE_ERROR; - } - else - request->notifyAddon(); - } - else - { - Log::error("addons", "Problems downloading file - return code %d.", - status); - } - - request->setProgress( (status==CURLE_OK) ? 1.0f : -1.0f ); - return status; -} // downloadFileInternal - -// ---------------------------------------------------------------------------- -/** Signals to the progress function to request any ongoing download to be - * cancelled. This function can also be called if there is actually no - * download atm. The function progressDownload checks m_abort and will - * return a non-zero value which causes libcurl to abort. */ -void NetworkHttp::cancelAllDownloads() -{ - if(UserConfigParams::logAddons()) - Log::info("addons", "Requesting cancellation of download."); - m_abort.setAtomic(true); -} // cancelAllDownload - -// ---------------------------------------------------------------------------- -/** External interface to download a file asynchronously. This will wake up - * the thread and schedule it to download the file. The calling program has - * to poll using getProgress() to find out if the download has finished. - * \param url The file from the server to download. - * \param save The name to save the downloaded file under. Defaults to - * the name given in file. - * \param priority Priority of the request (must be <=99) - */ -Request *NetworkHttp::downloadFileAsynchron(const std::string &url, - const std::string &save, - int priority, - bool manage_memory) -{ - // Limit priorities to 99 so that important system requests - // (init and quit) will have highest priority. - assert(priority<=99); - Request *request = new Request(Request::HC_DOWNLOAD_FILE, priority, - manage_memory, - url, (save!="") ? save : url ); - - if(UserConfigParams::logAddons()) - Log::info("addons", "Download asynchron '%s' as '%s'.", - request->getURL().c_str(), request->getSavePath().c_str()); - insertRequest(request); - return request; -} // downloadFileAsynchron - -// ---------------------------------------------------------------------------- -/** Inserts a request into the queue of all requests. The request will be - * sorted by priority. - * \param request The pointer to the new request to insert. - */ -void NetworkHttp::insertRequest(Request *request) -{ - m_all_requests.lock(); - - m_all_requests.getData().push(request); - // Wake up the network http thread - pthread_cond_signal(&m_cond_request); - - m_all_requests.unlock(); -} // insertRequest - -// ---------------------------------------------------------------------------- -/** Callback function from curl: inform about progress. - * \param clientp - * \param download_total Total size of data to download. - * \param download_now How much has been downloaded so far. - * \param upload_total Total amount of upload. - * \param upload_now How muc has been uploaded so far. - */ -int NetworkHttp::progressDownload(void *clientp, - double download_total, double download_now, - double upload_total, double upload_now) -{ - Request *request = (Request *)clientp; - - NetworkHttp* self = (NetworkHttp*)INetworkHttp::get(); - - // Check if we are asked to abort the download. If so, signal this - // back to libcurl by returning a non-zero status. - if(self->m_abort.getAtomic() || request->isCancelled() ) - { - if(UserConfigParams::logAddons()) - { - if(self->m_abort.getAtomic()) - { - // Reset abort flag so that the next download will work - // as expected. - self->m_abort.setAtomic(false); - Log::info("addons", "Global abort of downloads."); - } - else - Log::info("addons", "Cancel this download."); - } - // Indicates to abort the current download, which means that this - // thread will go back to the mainloop and handle the next request. - return 1; - } - - float f; - if(download_now < download_total) - { - f = (float)download_now / (float)download_total; - // In case of floating point rouding errors make sure that - // 1.0 is only reached when downloadFileInternal is finished - if (f>=1.0f) f=0.99f; - } - else - { - // Don't set progress to 1.0f; this is done in loadFileInternal - // after checking curls return code! - f= download_total==0 ? 0 : 0.99f; - } - request->setProgress(f); - return 0; -} // progressDownload - -#endif - diff --git a/src/addons/network_http.hpp b/src/addons/network_http.hpp deleted file mode 100644 index d551acbb1..000000000 --- a/src/addons/network_http.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2010-2013 Lucas Baudin -// Copyright (C) 2011-2013 Lucas Baudin, Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_NETWORK_HTTP_HPP -#define HEADER_NETWORK_HTTP_HPP - -#ifndef NO_CURL - -#include -#include -#include -#include - -#ifdef WIN32 -# include -#endif -#include - -#include "addons/inetwork_http.hpp" -#include "addons/request.hpp" -#include "utils/synchronised.hpp" - -class XMLNode; - -/** - * \ingroup addonsgroup - */ -class NetworkHttp : public INetworkHttp -{ -private: - - /** The list of pointes to all requests. */ - Synchronised< std::priority_queue, - Request::Compare > > m_all_requests; - - /** The current requested being worked on. */ - Request *m_current_request; - - /** A conditional variable to wake up the main loop. */ - pthread_cond_t m_cond_request; - - /** Signal an abort in case that a download is still happening. */ - Synchronised m_abort; - - /** Thread id of the thread running in this object. */ - Synchronised m_thread_id; - - /** The curl session. */ - CURL *m_curl_session; - - static void *mainLoop(void *obj); - CURLcode init(bool forceRefresh); - CURLcode downloadFileInternal(Request *request); - static int progressDownload(void *clientp, double dltotal, double dlnow, - double ultotal, double ulnow); - void insertRequest(Request *request); - CURLcode reInit(); -public: - NetworkHttp(); - virtual ~NetworkHttp(); - void startNetworkThread(); - void stopNetworkThread(); - void insertReInit(); - Request *downloadFileAsynchron(const std::string &url, - const std::string &save = "", - int priority = 1, - bool manage_memory=true); - void cancelAllDownloads(); - CURLcode loadAddonsList(const XMLNode *xml, - const std::string &filename, - bool forceRefresh); -}; // NetworkHttp - -#endif -#endif - diff --git a/src/addons/news_manager.cpp b/src/addons/news_manager.cpp index 28c833146..78e7c8e07 100644 --- a/src/addons/news_manager.cpp +++ b/src/addons/news_manager.cpp @@ -35,6 +35,7 @@ NewsManager::NewsManager() : m_news(std::vector()) { m_current_news_message = -1; m_error_message.setAtomic(""); + m_force_refresh = false; init(false); } // NewsManage @@ -44,8 +45,11 @@ NewsManager::~NewsManager() } // ~NewsManager // --------------------------------------------------------------------------- -/** This function initialises the data for the news manager. If necessary, - * it will use a separate thread to download the news.xml file. +/** This function initialises the data for the news manager. It starts a + * separate thread to execute downloadNews() - which (if necessary) the + * news.xml file and updating the list of news messages. It also initialises + * the addons manager (which can trigger another download of news.xml). + * \param force_refresh Re-download news.xml, even if */ void NewsManager::init(bool force_refresh) { @@ -59,6 +63,8 @@ void NewsManager::init(bool force_refresh) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + m_force_refresh = force_refresh; + pthread_t thread_id; int error = pthread_create(&thread_id, &attr, &NewsManager::downloadNews, this); @@ -80,7 +86,6 @@ void NewsManager::init(bool force_refresh) */ void* NewsManager::downloadNews(void *obj) { - bool force_refresh = false; NewsManager *me = (NewsManager*)obj; me->clearErrorMessage(); @@ -95,7 +100,7 @@ void* NewsManager::downloadNews(void *obj) UserConfigParams::m_news_last_updated +UserConfigParams::m_news_frequency < StkTime::getTimeSinceEpoch() || - force_refresh || + me->m_force_refresh || !news_exists; const XMLNode *xml = NULL; @@ -178,7 +183,7 @@ void* NewsManager::downloadNews(void *obj) xml = new XMLNode(xml_file); me->checkRedirect(xml); me->updateNews(xml, xml_file); - addons_manager->init(xml, force_refresh); + addons_manager->init(xml, me->m_force_refresh); delete xml; } diff --git a/src/addons/news_manager.hpp b/src/addons/news_manager.hpp index 4fb50349e..9e76f80fd 100644 --- a/src/addons/news_manager.hpp +++ b/src/addons/news_manager.hpp @@ -91,6 +91,9 @@ private: * any news message (usually indicating connection problems). */ Synchronised m_error_message; + /** True when all .xml files should be re-downloaded. */ + bool m_force_refresh; + void checkRedirect(const XMLNode *xml); void updateNews(const XMLNode *xml, const std::string &filename); @@ -106,7 +109,7 @@ public: if(!m_news_manager) m_news_manager = new NewsManager(); return m_news_manager; - } // + } // get // ------------------------------------------------------------------------ static void deallocate() { diff --git a/src/addons/request.cpp b/src/addons/request.cpp deleted file mode 100644 index 645d44e14..000000000 --- a/src/addons/request.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2011-2013 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "addons/request.hpp" - -#include - -#include "addons/addon.hpp" - -Request::Request(HttpCommands command, int priority, bool manage_memory) - : m_progress(0) -{ - m_command = command; - m_priority = priority; - m_url = ""; - m_full_path = ""; - m_manage_memory = manage_memory; - m_icon_addon = NULL; - m_cancel = false; - m_progress.setAtomic(0); -} // Request - -// ---------------------------------------------------------------------------- -Request::Request(HttpCommands command, int priority, bool manage_memory, - const std::string &url, const std::string &save) - : m_progress(0) -{ - m_command = command; - m_priority = priority; - m_url = url; - m_full_path = save; - m_icon_addon = NULL; - m_manage_memory = manage_memory; - m_cancel = false; - m_progress.setAtomic(0); -} // Request - -// ---------------------------------------------------------------------------- -void Request::setAddonIconNotification(Addon *a) -{ - m_icon_addon = a; -} // setADdonIconNotification - -// ---------------------------------------------------------------------------- -void Request::notifyAddon() -{ - if(m_icon_addon) - m_icon_addon->setIconReady(); -} // notifyAddon diff --git a/src/addons/request.hpp b/src/addons/request.hpp deleted file mode 100644 index 9090d84ee..000000000 --- a/src/addons/request.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2011-2013 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_REQUEST_HPP -#define HEADER_REQUEST_HPP - -#include - -#include "utils/leak_check.hpp" -#include "utils/synchronised.hpp" - -class Addon; - -/** - * Stores a download request. They will be sorted by priorities. - * \ingroup addonsgroup - */ -class Request -{ -public: - /** List of 'http commands' for this object: - * HC_INIT: Object is being initialised - * HC_DOWNLOAD_FILE : download a file - * HC_QUIT: Stop loop and terminate thread. - * HC_NEWS: Update the news - */ - enum HttpCommands {HC_QUIT, - HC_INIT, - HC_REINIT, - HC_DOWNLOAD_FILE }; - -private: - /** The progress indicator. 0 till it is started and the first - * packet is downloaded. At the end eithe -1 (error) or 1 - * (everything ok) at the end. */ - Synchronised m_progress; - /** The URL to download. */ - std::string m_url; - /** Where to store the file (including file name). */ - std::string m_full_path; - /** The priority of this request. The higher the value the more - important this request is. */ - int m_priority; - /** Cancel this request if it is active. */ - bool m_cancel; - /** The actual command to use. */ - HttpCommands m_command; - - /** True if the memory for this Request should be managed by - * network_http (i.e. this object is freed once the request - * is handled). Otherwise the memory is not freed, so it must - * be freed by the calling function. */ - bool m_manage_memory; - - /** If this is a download for an icon addon, this contains a pointer - * to the addon so that we can notify the addon that the icon is - * ready. */ - Addon *m_icon_addon; -public: - LEAK_CHECK() - - Request(HttpCommands command, int priority, - bool manage_memory=true); - Request(HttpCommands command, int priority, bool manage_memory, - const std::string &url, const std::string &save); - void setAddonIconNotification(Addon *a); - void notifyAddon(); - // ------------------------------------------------------------------------ - /** Returns the URL to download from. */ - const std::string &getURL() const {return m_url;} - // ------------------------------------------------------------------------ - /** Returns the full save file name. */ - const std::string &getSavePath() const {return m_full_path;} - // ------------------------------------------------------------------------ - /** Returns the command to do for this request. */ - HttpCommands getCommand() const { return m_command; } - // ------------------------------------------------------------------------ - /** Returns the priority of this request. */ - int getPriority() const { return m_priority; } - // ------------------------------------------------------------------------ - /** Returns the current progress. */ - float getProgress() const { return m_progress.getAtomic(); } - // ------------------------------------------------------------------------ - /** Sets the current progress. */ - void setProgress(float f) { m_progress.setAtomic(f); } - // ------------------------------------------------------------------------ - /** Signals that this request should be cancelled. */ - void cancel() { m_cancel = true; } - // ------------------------------------------------------------------------ - /** Returns if this request is to be cancelled. */ - bool isCancelled() const { return m_cancel; } - // ------------------------------------------------------------------------ - /** Specifies if the memory should be managed by network_http. */ - void setManageMemory(bool m) { m_manage_memory = m; } - // ------------------------------------------------------------------------ - /** Returns if the memory for this object should be managed by - * by network_http (i.e. freed once the request is handled). */ - bool manageMemory() const { return m_manage_memory; } - // ======================================================================== - /** This class is used by the priority queue to sort requests by priority. - */ - class Compare - { - public: - /** Compares two requests, returns if the first request has a lower - * priority than the second one. */ - bool operator() (const Request *a, const Request *b) const - { return a->getPriority() < b->getPriority(); } - }; // Compare -}; // Request - -#endif - diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 2b33230d4..d06de7e79 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -517,7 +517,7 @@ void ParticleSystemProxy::simulateHeightmap() void ParticleSystemProxy::simulateNoHeightmap() { - int timediff = GUIEngine::getLatestDt() * 1000.; + int timediff = int(GUIEngine::getLatestDt() * 1000.f); int active_count = getEmitter()->getMaxLifeTime() * getEmitter()->getMaxParticlesPerSecond() / 1000; core::matrix4 matrix = getAbsoluteTransformation(); glUseProgram(SimpleSimulationShader::Program); diff --git a/src/main.cpp b/src/main.cpp index 736183d9b..35ffe6429 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -142,7 +142,6 @@ #include "main_loop.hpp" #include "achievements/achievements_manager.hpp" #include "addons/addons_manager.hpp" -#include "addons/inetwork_http.hpp" #include "addons/news_manager.hpp" #include "audio/music_manager.hpp" #include "audio/sfx_manager.hpp" @@ -1020,14 +1019,9 @@ void initRest() // separate thread running in network http. addons_manager = new AddonsManager(); - INetworkHttp::create(); + Online::RequestManager::get()->startNetworkThread(); NewsManager::get(); // this will create the news manager - // Note that the network thread must be started after the assignment - // to network_http (since the thread might use network_http, otherwise - // a race condition can be introduced resulting in a crash). - INetworkHttp::get()->startNetworkThread(); - Online::RequestManager::get()->startNetworkThread(); AchievementsManager::get()->init(); music_manager = new MusicManager(); sfx_manager = new SFXManager(); @@ -1081,8 +1075,6 @@ static void cleanSuperTuxKart() irr_driver->updateConfigIfRelevant(); - if(INetworkHttp::get()) - INetworkHttp::get()->stopNetworkThread(); if(Online::RequestManager::isRunning()) Online::RequestManager::get()->stopNetworkThread(); @@ -1098,7 +1090,6 @@ static void cleanSuperTuxKart() Referee::cleanup(); if(ReplayPlay::get()) ReplayPlay::destroy(); if(race_manager) delete race_manager; - INetworkHttp::destroy(); NewsManager::deallocate(); if(addons_manager) delete addons_manager; NetworkManager::kill(); @@ -1248,7 +1239,9 @@ int main(int argc, char *argv[] ) // Load addons.xml to get info about addons even when not // allowed to access the internet - if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED) { + if (UserConfigParams::m_internet_status != + Online::RequestManager::IPERM_ALLOWED) + { std::string xml_file = file_manager->getAddonsFile("addons.xml"); if (file_manager->fileExists(xml_file)) { const XMLNode *xml = new XMLNode (xml_file); @@ -1278,7 +1271,7 @@ int main(int argc, char *argv[] ) } #endif if(UserConfigParams::m_internet_status == - INetworkHttp::IPERM_NOT_ASKED) + Online::RequestManager::IPERM_NOT_ASKED) { class ConfirmServer : public MessageDialog::IConfirmDialogListener @@ -1286,27 +1279,16 @@ int main(int argc, char *argv[] ) public: virtual void onConfirm() { - INetworkHttp::destroy(); UserConfigParams::m_internet_status = - INetworkHttp::IPERM_ALLOWED; + Online::RequestManager::IPERM_ALLOWED; GUIEngine::ModalDialog::dismiss(); - INetworkHttp::create(); - // Note that the network thread must be started after - // the assignment to network_http (since the thread - // might use network_http, otherwise a race condition - // can be introduced resulting in a crash). - INetworkHttp::get()->startNetworkThread(); - } // onConfirm // -------------------------------------------------------- virtual void onCancel() { - INetworkHttp::destroy(); UserConfigParams::m_internet_status = - INetworkHttp::IPERM_NOT_ALLOWED; + Online::RequestManager::IPERM_NOT_ALLOWED; GUIEngine::ModalDialog::dismiss(); - INetworkHttp::create(); - INetworkHttp::get()->startNetworkThread(); } // onCancel }; // ConfirmServer diff --git a/src/online/request.hpp b/src/online/request.hpp index a326fb823..a3572e644 100644 --- a/src/online/request.hpp +++ b/src/online/request.hpp @@ -21,6 +21,8 @@ #include "io/file_manager.hpp" #include "utils/cpp2011.h" +#include "utils/leak_check.hpp" +#include "utils/no_copy.hpp" #include "utils/string_utils.hpp" #include "utils/synchronised.hpp" @@ -58,9 +60,11 @@ namespace Online * * \ingroup online */ - class Request + class Request : public NoCopy { private: + LEAK_CHECK() + /** Type of the request. Has 0 as default value. */ const int m_type; /** True if the memory for this Request should be managed by diff --git a/src/online/request_manager.hpp b/src/online/request_manager.hpp index a8b57e8e3..682f1a10f 100644 --- a/src/online/request_manager.hpp +++ b/src/online/request_manager.hpp @@ -48,7 +48,17 @@ namespace Online */ class RequestManager { - protected: + public: + /** If stk has permission to access the internet (for news + * server etc). + * IPERM_NOT_ASKED: The user needs to be asked if he wants to + * grant permission + * IPERM_ALLOWED: STK is allowed to access server. + * IPERM_NOT_ALLOWED: STK must not access external servers. */ + enum InternetPermission {IPERM_NOT_ASKED =0, + IPERM_ALLOWED =1, + IPERM_NOT_ALLOWED=2 }; + protected: float m_time_since_poll; diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index 916f0a88c..298bcde72 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -20,13 +20,14 @@ #include #include "addons/addons_manager.hpp" -#include "addons/inetwork_http.hpp" +#include "addons/news_manager.hpp" #include "guiengine/CGUISpriteBank.h" #include "guiengine/modaldialog.hpp" #include "guiengine/scalable_font.hpp" #include "guiengine/widget.hpp" #include "guiengine/widgets/ribbon_widget.hpp" #include "io/file_manager.hpp" +#include "online/request_manager.hpp" #include "states_screens/dialogs/addons_loading.hpp" #include "states_screens/dialogs/message_dialog.hpp" #include "states_screens/state_manager.hpp" @@ -35,6 +36,7 @@ DEFINE_SCREEN_SINGLETON( AddonsScreen ); +using namespace Online; // ---------------------------------------------------------------------------- AddonsScreen::AddonsScreen() : Screen("addons_screen.stkgui") @@ -155,7 +157,7 @@ void AddonsScreen::init() w_list->setIcons(m_icon_bank, (int)(m_icon_height)); m_type = "kart"; - if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED) + if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED) getWidget("reload")->setDeactivated(); else getWidget("reload")->setActivated(); @@ -231,8 +233,9 @@ void AddonsScreen::loadList() if(!UserConfigParams::m_artist_debug_mode && !addon.testStatus(Addon::AS_APPROVED) ) continue; - if (!addon.isInstalled() && (addons_manager->wasError() - || UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED )) + if (!addon.isInstalled() && (addons_manager->wasError() || + UserConfigParams::m_internet_status != + RequestManager::IPERM_ALLOWED )) continue; // Filter by rating. @@ -424,10 +427,10 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget, if (!m_reloading) { m_reloading = true; - INetworkHttp::get()->insertReInit(); + NewsManager::get()->init(true); GUIEngine::ListWidget* w_list = - getWidget("list_addons"); + getWidget("list_addons"); w_list->clear(); w_list->addItem("spacer", L""); @@ -498,7 +501,7 @@ void AddonsScreen::onUpdate(float dt, irr::video::IVideoDriver*) { if (m_reloading) { - if(UserConfigParams::m_internet_status!=INetworkHttp::IPERM_ALLOWED) + if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED) { // not allowed to access the net. how did you get to this menu in // the first place?? diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index 3b113efa7..4521ec5ad 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -21,8 +21,6 @@ #include #include "addons/addons_manager.hpp" -#include "addons/inetwork_http.hpp" -#include "addons/request.hpp" #include "config/user_config.hpp" #include "guiengine/engine.hpp" #include "guiengine/scalable_font.hpp" @@ -39,6 +37,7 @@ #include "utils/translation.hpp" using namespace GUIEngine; +using namespace Online; using namespace irr::gui; // ---------------------------------------------------------------------------- @@ -95,7 +94,7 @@ void AddonsLoading::beforeAddingWidgets() * and not in error state */ if (m_addon.needsUpdate() && !addons_manager->wasError() - && UserConfigParams::m_internet_status==INetworkHttp::IPERM_ALLOWED) + && UserConfigParams::m_internet_status==RequestManager::IPERM_ALLOWED) getWidget ("install")->setLabel( _("Update") ); else r->removeChildNamed("install"); @@ -279,7 +278,7 @@ void AddonsLoading::onUpdate(float delta) new MessageDialog( _("Sorry, downloading the add-on failed")); return; } - else if(progress>=1.0f) + else if(m_download_request->isDone()) { m_back_button->setLabel(_("Back")); // No sense to update state text, since it all @@ -308,9 +307,11 @@ void AddonsLoading::startDownload() std::string file = m_addon.getZipFileName(); std::string save = "tmp/" + StringUtils::getBasename(m_addon.getZipFileName()); - m_download_request = INetworkHttp::get()->downloadFileAsynchron(file, save, - /*priority*/5, - /*manage memory*/false); + m_download_request = new Online::HTTPRequest(save, /*manage mem*/false, + /*priority*/5); + m_download_request->setURL(m_addon.getZipFileName()); + m_download_request->queue(); + } // startDownload // ---------------------------------------------------------------------------- @@ -327,7 +328,8 @@ void AddonsLoading::stopDownload() // network_http will potentially update the request. So in // order to avoid a memory leak, we let network_http free // the request. - m_download_request->setManageMemory(true); + //m_download_request->setManageMemory(true); + assert(false); m_download_request->cancel(); }; } // startDownload diff --git a/src/states_screens/dialogs/addons_loading.hpp b/src/states_screens/dialogs/addons_loading.hpp index 93d03ba10..76e05cfa4 100644 --- a/src/states_screens/dialogs/addons_loading.hpp +++ b/src/states_screens/dialogs/addons_loading.hpp @@ -25,7 +25,7 @@ #include "guiengine/modaldialog.hpp" #include "utils/synchronised.hpp" -class Request; +namespace Online { class HTTPRequest; } /** * \ingroup states_screens @@ -53,7 +53,7 @@ private: /** A pointer to the download request, which gives access * to the progress of a download. */ - Request *m_download_request; + Online::HTTPRequest *m_download_request; bool m_vote_clicked; diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 3ff0f444f..16436ee7d 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -21,7 +21,6 @@ #include -#include "addons/inetwork_http.hpp" #include "challenges/game_slot.hpp" #include "challenges/unlock_manager.hpp" #include "graphics/irr_driver.hpp" @@ -37,6 +36,7 @@ #include "modes/cutscene_world.hpp" #include "modes/overworld.hpp" #include "modes/demo_world.hpp" +#include "online/request_manager.hpp" #include "states_screens/online_screen.hpp" #include "states_screens/addons_screen.hpp" #include "states_screens/credits.hpp" @@ -60,6 +60,7 @@ #include "utils/string_utils.hpp" using namespace GUIEngine; +using namespace Online; DEFINE_SCREEN_SINGLETON( MainMenuScreen ); @@ -146,7 +147,7 @@ void MainMenuScreen::onUpdate(float delta, irr::video::IVideoDriver* driver) addons_icon->setBadge(BAD_BADGE); } else if (addons_manager->isLoading() && UserConfigParams::m_internet_status - == INetworkHttp::IPERM_ALLOWED) + == Online::RequestManager::IPERM_ALLOWED) { // Addons manager is still initialising/downloading. addons_icon->setDeactivated(); @@ -391,7 +392,7 @@ void MainMenuScreen::onDisabledItemClicked(const std::string& item) { if (item == "addons") { - if (UserConfigParams::m_internet_status != INetworkHttp::IPERM_ALLOWED) + if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED) { new MessageDialog( _("The add-ons module is currently disabled in " "the Options screen") ); diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index 80082d1de..ded5aba45 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -17,7 +17,6 @@ #include "states_screens/options_screen_ui.hpp" -#include "addons/inetwork_http.hpp" #include "audio/music_manager.hpp" #include "audio/sfx_manager.hpp" #include "audio/sfx_base.hpp" @@ -30,6 +29,7 @@ #include "guiengine/widgets/spinner_widget.hpp" #include "guiengine/widget.hpp" #include "io/file_manager.hpp" +#include "online/request_manager.hpp" #include "states_screens/main_menu_screen.hpp" #include "states_screens/options_screen_audio.hpp" #include "states_screens/options_screen_input.hpp" @@ -45,6 +45,7 @@ #include using namespace GUIEngine; +using namespace Online; DEFINE_SCREEN_SINGLETON( OptionsScreenUI ); @@ -126,7 +127,7 @@ void OptionsScreenUI::init() CheckBoxWidget* news = getWidget("enable-internet"); assert( news != NULL ); news->setState( UserConfigParams::m_internet_status - ==INetworkHttp::IPERM_ALLOWED ); + ==RequestManager::IPERM_ALLOWED ); // --- select the right skin in the spinner bool currSkinFound = false; @@ -229,19 +230,9 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con { CheckBoxWidget* news = getWidget("enable-internet"); assert( news != NULL ); - if(INetworkHttp::get()) - { - INetworkHttp::get()->stopNetworkThread(); - INetworkHttp::destroy(); - } UserConfigParams::m_internet_status = - news->getState() ? INetworkHttp::IPERM_ALLOWED - : INetworkHttp::IPERM_NOT_ALLOWED; - INetworkHttp::create(); - // Note that the network thread must be started after the assignment - // to network_http (since the thread might use network_http, otherwise - // a race condition can be introduced resulting in a crash). - INetworkHttp::get()->startNetworkThread(); + news->getState() ? RequestManager::IPERM_ALLOWED + : RequestManager::IPERM_NOT_ALLOWED; } else if (name == "language") { From d53e3180ac81ad186f650b06844e6b129227f7e9 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Mon, 13 Jan 2014 11:35:12 +0000 Subject: [PATCH 263/412] Fixed enabling internet in the GUI (i.e. re-init of news manager and addons manager will happen now). For online menu a dialog is now presented to explain why it can't be selected if internet is disabled. Addons can be selected with internet is disabled if there are existing addons (so that it's possible to remove addons without internet access). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15035 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/addons/addons_manager.cpp | 18 +++++++++++--- src/addons/addons_manager.hpp | 1 + src/addons/news_manager.cpp | 30 ++++++++++-------------- src/online/http_request.cpp | 13 ++++++++-- src/online/request_manager.hpp | 20 ++++++++-------- src/states_screens/main_menu_screen.cpp | 19 +++++++++++++++ src/states_screens/options_screen_ui.cpp | 14 +++++++---- 7 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index c54bbd9e0..42974a75f 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -98,14 +98,18 @@ void AddonsManager::init(const XMLNode *xml, } include->get("file", &addon_list_url); + int frequency = 0; + include->get("frequency", &frequency); int64_t tmp; include->get("mtime", &tmp); mtime = tmp; - bool download = mtime > UserConfigParams::m_addons_last_updated || - force_refresh || - !file_manager->fileExists(filename); + bool download = + ( mtime > UserConfigParams::m_addons_last_updated +frequency || + force_refresh || + !file_manager->fileExists(filename) ) + && UserConfigParams::m_internet_status == RequestManager::IPERM_ALLOWED; if (download) { @@ -445,6 +449,14 @@ int AddonsManager::getAddonIndex(const std::string &id) const } return -1; } // getAddonIndex +// ---------------------------------------------------------------------------- +bool AddonsManager::anyAddonsInstalled() const +{ + for(unsigned int i=0; i +using namespace Online; + NewsManager *NewsManager::m_news_manager=NULL; // ---------------------------------------------------------------------------- @@ -96,16 +99,17 @@ void* NewsManager::downloadNews(void *obj) // or if the time of the last update was more than news_frequency ago, // or because a 'refresh' was explicitly requested by the user, or no // news.xml file exists. - bool download = UserConfigParams::m_news_last_updated==0 || - UserConfigParams::m_news_last_updated - +UserConfigParams::m_news_frequency - < StkTime::getTimeSinceEpoch() || - me->m_force_refresh || - !news_exists; + bool download = ( UserConfigParams::m_news_last_updated==0 || + UserConfigParams::m_news_last_updated + +UserConfigParams::m_news_frequency + < StkTime::getTimeSinceEpoch() || + me->m_force_refresh || + !news_exists ) + && UserConfigParams::m_internet_status==RequestManager::IPERM_ALLOWED; const XMLNode *xml = NULL; - if(!download) + if(!download && news_exists) { // If (so far) we don't need to download, there should be an existing // file. Try to read this, and do some basic checks @@ -131,7 +135,7 @@ void* NewsManager::downloadNews(void *obj) { core::stringw error_message(""); - Online::HTTPRequest *download_req = new Online::HTTPRequest("news.xml"); + HTTPRequest *download_req = new HTTPRequest("news.xml"); download_req->setAddonsURL("news.xml"); // Initialise the online portion of the addons manager. if(UserConfigParams::logAddons()) @@ -147,7 +151,7 @@ void* NewsManager::downloadNews(void *obj) delete download_req; // We need a new object, since the state of the old // download request is now done. - download_req = new Online::HTTPRequest("news.xml"); + download_req = new HTTPRequest("news.xml"); UserConfigParams::m_server_addons.revertToDefaults(); // make sure the new server address is actually used download_req->setAddonsURL("news.xml"); @@ -191,14 +195,6 @@ void* NewsManager::downloadNews(void *obj) return 0; // prevent warning } // downloadNews -// --------------------------------------------------------------------------- -/** Initialises the online part of the network manager. It downloads the - * news.xml file from the server (if the frequency of downloads makes this - * necessary), and (again if necessary) the addons.xml file. - * \return 0 if an error happened and no online connection will be available, - * 1 otherwise. - */ - // --------------------------------------------------------------------------- /** Checks if a redirect is received, causing a new server to be used for * downloading addons. diff --git a/src/online/http_request.cpp b/src/online/http_request.cpp index 81593b038..5e5cab606 100644 --- a/src/online/http_request.cpp +++ b/src/online/http_request.cpp @@ -57,6 +57,9 @@ namespace Online int priority) : Request(manage_memory, priority, 0) { + // A http request should not even be created when internet is disabled + assert(UserConfigParams::m_internet_status == + RequestManager::IPERM_ALLOWED); assert(filename.size()>0); init(); m_filename = file_manager->getAddonsFile(filename); @@ -70,6 +73,9 @@ namespace Online int priority) : Request(manage_memory, priority, 0) { + // A http request should not even be created when internet is disabled + assert(UserConfigParams::m_internet_status == + RequestManager::IPERM_ALLOWED); init(); m_filename = file_manager->getAddonsFile(filename); } // HTTPRequest(filename ...) @@ -188,8 +194,11 @@ namespace Online m_parameters.erase(m_parameters.size()-1); } - Log::info("HTTPRequest", "Sending %s to %s", - m_parameters.c_str(), m_url.c_str()); + if(m_parameters.size()==0) + Log::info("HTTPRequest", "Downloading %s", m_url.c_str()); + else + Log::info("HTTPRequest", "Sending %s to %s", + m_parameters.c_str(), m_url.c_str()); curl_easy_setopt(m_curl_session, CURLOPT_POSTFIELDS, m_parameters.c_str()); std::string uagent( std::string("SuperTuxKart/") + STK_VERSION ); diff --git a/src/online/request_manager.hpp b/src/online/request_manager.hpp index 682f1a10f..6f060442a 100644 --- a/src/online/request_manager.hpp +++ b/src/online/request_manager.hpp @@ -48,16 +48,16 @@ namespace Online */ class RequestManager { - public: - /** If stk has permission to access the internet (for news - * server etc). - * IPERM_NOT_ASKED: The user needs to be asked if he wants to - * grant permission - * IPERM_ALLOWED: STK is allowed to access server. - * IPERM_NOT_ALLOWED: STK must not access external servers. */ - enum InternetPermission {IPERM_NOT_ASKED =0, - IPERM_ALLOWED =1, - IPERM_NOT_ALLOWED=2 }; + public: + /** If stk has permission to access the internet (for news + * server etc). + * IPERM_NOT_ASKED: The user needs to be asked if he wants to + * grant permission + * IPERM_ALLOWED: STK is allowed to access server. + * IPERM_NOT_ALLOWED: STK must not access external servers. */ + enum InternetPermission {IPERM_NOT_ASKED =0, + IPERM_ALLOWED =1, + IPERM_NOT_ALLOWED=2 }; protected: float m_time_since_poll; diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 16436ee7d..4c56e1624 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -372,10 +372,29 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, } else if (selection == "online") { + if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED) + { + new MessageDialog(_("You can not play online without internet access. " + "If you want to play online, go to options, select " + " tab 'User Interface', and edit " + "\"Allow STK to connect to the Internet\".")); + return; + } StateManager::get()->pushScreen(OnlineScreen::getInstance()); } else if (selection == "addons") { + // Don't go to addons if there is no internet, unless some addons are + // already installed (so that you can delete addons without being online). + if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED && + !addons_manager->anyAddonsInstalled()) + { + new MessageDialog(_("You can not download addons without internet access. " + "If you want to download addons, go to options, select " + " tab 'User Interface', and edit " + "\"Allow STK to connect to the Internet\".")); + return; + } StateManager::get()->pushScreen(AddonsScreen::getInstance()); } } // eventCallback diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index ded5aba45..927355c8e 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -17,6 +17,7 @@ #include "states_screens/options_screen_ui.hpp" +#include "addons/news_manager.hpp" #include "audio/music_manager.hpp" #include "audio/sfx_manager.hpp" #include "audio/sfx_base.hpp" @@ -228,11 +229,16 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con } else if (name=="enable-internet") { - CheckBoxWidget* news = getWidget("enable-internet"); - assert( news != NULL ); + CheckBoxWidget* internet = getWidget("enable-internet"); + assert( internet != NULL ); UserConfigParams::m_internet_status = - news->getState() ? RequestManager::IPERM_ALLOWED - : RequestManager::IPERM_NOT_ALLOWED; + internet->getState() ? RequestManager::IPERM_ALLOWED + : RequestManager::IPERM_NOT_ALLOWED; + // If internet gets enabled, re-initialise the addon manager (which + // happens in a separate thread) so that news.xml etc can be + // downloaded if necessary. + if(internet->getState()) + NewsManager::get()->init(false); } else if (name == "language") { From f654967b073761b96763d29600203886a31c7a6c Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 12:56:27 +0000 Subject: [PATCH 264/412] Lights: Use custom gl calls. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15036 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 4 + src/graphics/glwrap.hpp | 2 + src/graphics/post_processing.cpp | 1831 ++++++++++++++++-------------- src/graphics/post_processing.hpp | 3 + src/graphics/render.cpp | 2 +- 5 files changed, 959 insertions(+), 883 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7f04e293a..63d541d05 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -37,6 +37,8 @@ PFNGLUNIFORM2FPROC glUniform2f; PFNGLUNIFORM1IPROC glUniform1i; PFNGLUNIFORM3IPROC glUniform3i; PFNGLUNIFORM4IPROC glUniform4i; +PFNGLUNIFORM1FVPROC glUniform1fv; +PFNGLUNIFORM4FVPROC glUniform4fv; PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; @@ -169,6 +171,8 @@ void initGL() glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)IRR_OGL_LOAD_EXTENSION("glBindVertexArray"); glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)IRR_OGL_LOAD_EXTENSION("glDeleteVertexArrays"); glTexBuffer = (PFNGLTEXBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glTexBuffer"); + glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv"); + glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv"); #endif #if ENABLE_ARB_DEBUG_OUTPUT glDebugMessageCallbackARB(debugCallback, NULL); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 10c65a3e3..126e482d0 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -52,6 +52,8 @@ extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; extern PFNGLUNIFORM1FPROC glUniform1f; extern PFNGLUNIFORM3FPROC glUniform3f; +extern PFNGLUNIFORM1FVPROC glUniform1fv; +extern PFNGLUNIFORM4FVPROC glUniform4fv; extern PFNGLDELETESHADERPROC glDeleteShader; extern PFNGLGETSHADERIVPROC glGetShaderiv; extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 266eefc72..ce112bc03 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -1,884 +1,951 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2011-2013 the SuperTuxKart-Team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -#include "post_processing.hpp" - -#include "config/user_config.hpp" -#include "graphics/callbacks.hpp" -#include "graphics/camera.hpp" -#include "graphics/glwrap.hpp" -#include "graphics/irr_driver.hpp" -#include "graphics/mlaa_areamap.hpp" -#include "graphics/shaders.hpp" -#include "io/file_manager.hpp" -#include "karts/abstract_kart.hpp" -#include "karts/kart_model.hpp" -#include "modes/world.hpp" -#include "race/race_manager.hpp" -#include "tracks/track.hpp" -#include "utils/log.hpp" -#include "graphics/glwrap.hpp" - -#include - -using namespace video; -using namespace scene; - -PostProcessing::PostProcessing(IVideoDriver* video_driver) -{ - // Initialization - m_material.Wireframe = false; - m_material.Lighting = false; - m_material.ZWriteEnable = false; - m_material.ZBuffer = ECFN_ALWAYS; - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - - for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) - { - m_material.TextureLayer[i].TextureWrapU = - m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; - } - - // Load the MLAA area map - io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()-> - createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33), - "AreaMap33", false); - if (!areamap) Log::fatal("postprocessing", "Failed to load the areamap"); - m_areamap = irr_driver->getVideoDriver()->getTexture(areamap); - areamap->drop(); - -} // PostProcessing - -// ---------------------------------------------------------------------------- -PostProcessing::~PostProcessing() -{ - // TODO: do we have to delete/drop anything? -} // ~PostProcessing - -// ---------------------------------------------------------------------------- -/** Initialises post processing at the (re-)start of a race. This sets up - * the vertices, normals and texture coordinates for each - */ -void PostProcessing::reset() -{ - const u32 n = Camera::getNumCameras(); - m_boost_time.resize(n); - m_vertices.resize(n); - m_center.resize(n); - m_direction.resize(n); - - MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver-> - getCallback(ES_MOTIONBLUR); - - for(unsigned int i=0; igetViewport(); - // Map viewport to [-1,1] x [-1,1]. First define the coordinates - // left, right, top, bottom: - float right = vp.LowerRightCorner.X < UserConfigParams::m_width - ? 0.0f : 1.0f; - float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f; - float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f; - float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height - ? 0.0f : -1.0f; - - // Use left etc to define 4 vertices on which the rendered screen - // will be displayed: - m_vertices[i].v0.Pos = core::vector3df(left, bottom, 0); - m_vertices[i].v1.Pos = core::vector3df(left, top, 0); - m_vertices[i].v2.Pos = core::vector3df(right, top, 0); - m_vertices[i].v3.Pos = core::vector3df(right, bottom, 0); - // Define the texture coordinates of each vertex, which must - // be in [0,1]x[0,1] - m_vertices[i].v0.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, - bottom==-1.0f ? 0.0f : 0.5f); - m_vertices[i].v1.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, - top == 1.0f ? 1.0f : 0.5f); - m_vertices[i].v2.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, - top == 1.0f ? 1.0f : 0.5f); - m_vertices[i].v3.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, - bottom==-1.0f ? 0.0f : 0.5f); - // Set normal and color: - core::vector3df normal(0,0,1); - m_vertices[i].v0.Normal = m_vertices[i].v1.Normal = - m_vertices[i].v2.Normal = m_vertices[i].v3.Normal = normal; - SColor white(0xFF, 0xFF, 0xFF, 0xFF); - m_vertices[i].v0.Color = m_vertices[i].v1.Color = - m_vertices[i].v2.Color = m_vertices[i].v3.Color = white; - - m_center[i].X=(m_vertices[i].v0.TCoords.X - +m_vertices[i].v2.TCoords.X) * 0.5f; - - // Center is around 20 percent from bottom of screen: - const float tex_height = m_vertices[i].v1.TCoords.Y - - m_vertices[i].v0.TCoords.Y; - m_direction[i].X = m_center[i].X; - m_direction[i].Y = m_vertices[i].v0.TCoords.Y + 0.7f*tex_height; - - setMotionBlurCenterY(i, 0.2f); - - cb->setDirection(i, m_direction[i].X, m_direction[i].Y); - cb->setMaxHeight(i, m_vertices[i].v1.TCoords.Y); - } // for i - getCallback(ES_MOTIONBLUR); - - const float tex_height = m_vertices[num].v1.TCoords.Y - m_vertices[num].v0.TCoords.Y; - m_center[num].Y = m_vertices[num].v0.TCoords.Y + y * tex_height; - - cb->setCenter(num, m_center[num].X, m_center[num].Y); -} - -// ---------------------------------------------------------------------------- -/** Setup some PP data. - */ -void PostProcessing::begin() -{ - m_any_boost = false; - for (u32 i = 0; i < m_boost_time.size(); i++) - m_any_boost |= m_boost_time[i] > 0.01f; -} // beginCapture - -// ---------------------------------------------------------------------------- -/** Set the boost amount according to the speed of the camera */ -void PostProcessing::giveBoost(unsigned int camera_index) -{ - if (irr_driver->isGLSL()) - { - m_boost_time[camera_index] = 0.75f; - - MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver-> - getCallback(ES_MOTIONBLUR); - cb->setBoostTime(camera_index, m_boost_time[camera_index]); - } -} // giveBoost - -// ---------------------------------------------------------------------------- -/** Updates the boost times for all cameras, called once per frame. - * \param dt Time step size. - */ -void PostProcessing::update(float dt) -{ - if (!irr_driver->isGLSL()) - return; - - MotionBlurProvider* const cb = - (MotionBlurProvider*) irr_driver->getCallback(ES_MOTIONBLUR); - - if (cb == NULL) return; - - for (unsigned int i=0; i 0.0f) - { - m_boost_time[i] -= dt; - if (m_boost_time[i] < 0.0f) m_boost_time[i] = 0.0f; - } - - cb->setBoostTime(i, m_boost_time[i]); - } -} // update - -// ---------------------------------------------------------------------------- -/** Render the post-processed scene, solids only, color to color, no stencil */ -void PostProcessing::renderSolid(const u32 cam) -{ - if (!irr_driver->isGLSL()) return; - - IVideoDriver * const drv = irr_driver->getVideoDriver(); - if (World::getWorld()->getTrack()->isFogEnabled()) - { - m_material.MaterialType = irr_driver->getShader(ES_FOG); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - // Overlay - m_material.BlendOperation = EBO_ADD; - m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); - - drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - m_material.MaterialTypeParam = 0; - } -} - -GLuint quad_vbo = 0; - -static void initQuadVBO() -{ - initGL(); - const float quad_vertex[] = { - -1., -1., 0., 0., // UpperLeft - -1., 1., 0., 1., // LowerLeft - 1., -1., 1., 0., // UpperRight - 1., 1., 1., 1., // LowerRight - }; - glGenBuffers(1, &quad_vbo); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -namespace BloomShader -{ - GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_texture, uniform_low; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_texture = glGetUniformLocation(Program, "tex"); - uniform_low = glGetUniformLocation(Program, "low"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - } -} - -namespace BloomBlendShader -{ - GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_texture, uniform_low; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_texture = glGetUniformLocation(Program, "tex"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - } -} - -namespace PPDisplaceShader -{ - GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_tex, uniform_dtex, uniform_viz; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_dtex = glGetUniformLocation(Program, "dtex"); - uniform_viz = glGetUniformLocation(Program, "viz"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - } -} - -namespace ColorLevelShader -{ - GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_tex, uniform_inlevel, uniform_outlevel; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_inlevel = glGetUniformLocation(Program, "inlevel"); - uniform_outlevel = glGetUniformLocation(Program, "outlevel"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - } -} - - -static -void renderBloom(ITexture *in) -{ - if (!BloomShader::Program) - BloomShader::init(); - - const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); - glUseProgram(BloomShader::Program); - glBindVertexArray(BloomShader::vao); - glUniform1f(BloomShader::uniform_low, threshold); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(BloomShader::uniform_texture, 0); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -static -void renderBloomBlend(ITexture *in) -{ - if (!BloomBlendShader::Program) - BloomBlendShader::init(); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_ONE, GL_ONE); - glDisable(GL_DEPTH_TEST); - - glUseProgram(BloomBlendShader::Program); - glBindVertexArray(BloomBlendShader::vao); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(BloomBlendShader::uniform_texture, 0); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); -} - -static -void renderPPDisplace(ITexture *in) -{ - if (!PPDisplaceShader::Program) - PPDisplaceShader::init(); - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_ONE, GL_ONE); - glDisable(GL_DEPTH_TEST); - - glUseProgram(PPDisplaceShader::Program); - glBindVertexArray(PPDisplaceShader::vao); - glUniform1i(PPDisplaceShader::uniform_viz, irr_driver->getDistortViz()); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(PPDisplaceShader::uniform_tex, 0); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_DISPLACE))->getOpenGLTextureName()); - glUniform1i(PPDisplaceShader::uniform_dtex, 1); - - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); -} - -static -void renderColorLevel(ITexture *in) +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2011-2013 the SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +#include "post_processing.hpp" + +#include "config/user_config.hpp" +#include "graphics/callbacks.hpp" +#include "graphics/camera.hpp" +#include "graphics/glwrap.hpp" +#include "graphics/irr_driver.hpp" +#include "graphics/mlaa_areamap.hpp" +#include "graphics/shaders.hpp" +#include "io/file_manager.hpp" +#include "karts/abstract_kart.hpp" +#include "karts/kart_model.hpp" +#include "modes/world.hpp" +#include "race/race_manager.hpp" +#include "tracks/track.hpp" +#include "utils/log.hpp" +#include "graphics/glwrap.hpp" + +#include + +using namespace video; +using namespace scene; + +PostProcessing::PostProcessing(IVideoDriver* video_driver) +{ + // Initialization + m_material.Wireframe = false; + m_material.Lighting = false; + m_material.ZWriteEnable = false; + m_material.ZBuffer = ECFN_ALWAYS; + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + + for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) + { + m_material.TextureLayer[i].TextureWrapU = + m_material.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; + } + + // Load the MLAA area map + io::IReadFile *areamap = irr_driver->getDevice()->getFileSystem()-> + createMemoryReadFile((void *) AreaMap33, sizeof(AreaMap33), + "AreaMap33", false); + if (!areamap) Log::fatal("postprocessing", "Failed to load the areamap"); + m_areamap = irr_driver->getVideoDriver()->getTexture(areamap); + areamap->drop(); + +} // PostProcessing + +// ---------------------------------------------------------------------------- +PostProcessing::~PostProcessing() +{ + // TODO: do we have to delete/drop anything? +} // ~PostProcessing + +// ---------------------------------------------------------------------------- +/** Initialises post processing at the (re-)start of a race. This sets up + * the vertices, normals and texture coordinates for each + */ +void PostProcessing::reset() +{ + const u32 n = Camera::getNumCameras(); + m_boost_time.resize(n); + m_vertices.resize(n); + m_center.resize(n); + m_direction.resize(n); + + MotionBlurProvider * const cb = (MotionBlurProvider *) irr_driver-> + getCallback(ES_MOTIONBLUR); + + for(unsigned int i=0; igetViewport(); + // Map viewport to [-1,1] x [-1,1]. First define the coordinates + // left, right, top, bottom: + float right = vp.LowerRightCorner.X < UserConfigParams::m_width + ? 0.0f : 1.0f; + float left = vp.UpperLeftCorner.X > 0.0f ? 0.0f : -1.0f; + float top = vp.UpperLeftCorner.Y > 0.0f ? 0.0f : 1.0f; + float bottom = vp.LowerRightCorner.Y < UserConfigParams::m_height + ? 0.0f : -1.0f; + + // Use left etc to define 4 vertices on which the rendered screen + // will be displayed: + m_vertices[i].v0.Pos = core::vector3df(left, bottom, 0); + m_vertices[i].v1.Pos = core::vector3df(left, top, 0); + m_vertices[i].v2.Pos = core::vector3df(right, top, 0); + m_vertices[i].v3.Pos = core::vector3df(right, bottom, 0); + // Define the texture coordinates of each vertex, which must + // be in [0,1]x[0,1] + m_vertices[i].v0.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, + bottom==-1.0f ? 0.0f : 0.5f); + m_vertices[i].v1.TCoords = core::vector2df(left ==-1.0f ? 0.0f : 0.5f, + top == 1.0f ? 1.0f : 0.5f); + m_vertices[i].v2.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, + top == 1.0f ? 1.0f : 0.5f); + m_vertices[i].v3.TCoords = core::vector2df(right == 0.0f ? 0.5f : 1.0f, + bottom==-1.0f ? 0.0f : 0.5f); + // Set normal and color: + core::vector3df normal(0,0,1); + m_vertices[i].v0.Normal = m_vertices[i].v1.Normal = + m_vertices[i].v2.Normal = m_vertices[i].v3.Normal = normal; + SColor white(0xFF, 0xFF, 0xFF, 0xFF); + m_vertices[i].v0.Color = m_vertices[i].v1.Color = + m_vertices[i].v2.Color = m_vertices[i].v3.Color = white; + + m_center[i].X=(m_vertices[i].v0.TCoords.X + +m_vertices[i].v2.TCoords.X) * 0.5f; + + // Center is around 20 percent from bottom of screen: + const float tex_height = m_vertices[i].v1.TCoords.Y + - m_vertices[i].v0.TCoords.Y; + m_direction[i].X = m_center[i].X; + m_direction[i].Y = m_vertices[i].v0.TCoords.Y + 0.7f*tex_height; + + setMotionBlurCenterY(i, 0.2f); + + cb->setDirection(i, m_direction[i].X, m_direction[i].Y); + cb->setMaxHeight(i, m_vertices[i].v1.TCoords.Y); + } // for i + getCallback(ES_MOTIONBLUR); + + const float tex_height = m_vertices[num].v1.TCoords.Y - m_vertices[num].v0.TCoords.Y; + m_center[num].Y = m_vertices[num].v0.TCoords.Y + y * tex_height; + + cb->setCenter(num, m_center[num].X, m_center[num].Y); +} + +// ---------------------------------------------------------------------------- +/** Setup some PP data. + */ +void PostProcessing::begin() +{ + m_any_boost = false; + for (u32 i = 0; i < m_boost_time.size(); i++) + m_any_boost |= m_boost_time[i] > 0.01f; +} // beginCapture + +// ---------------------------------------------------------------------------- +/** Set the boost amount according to the speed of the camera */ +void PostProcessing::giveBoost(unsigned int camera_index) +{ + if (irr_driver->isGLSL()) + { + m_boost_time[camera_index] = 0.75f; + + MotionBlurProvider * const cb = (MotionBlurProvider *)irr_driver-> + getCallback(ES_MOTIONBLUR); + cb->setBoostTime(camera_index, m_boost_time[camera_index]); + } +} // giveBoost + +// ---------------------------------------------------------------------------- +/** Updates the boost times for all cameras, called once per frame. + * \param dt Time step size. + */ +void PostProcessing::update(float dt) +{ + if (!irr_driver->isGLSL()) + return; + + MotionBlurProvider* const cb = + (MotionBlurProvider*) irr_driver->getCallback(ES_MOTIONBLUR); + + if (cb == NULL) return; + + for (unsigned int i=0; i 0.0f) + { + m_boost_time[i] -= dt; + if (m_boost_time[i] < 0.0f) m_boost_time[i] = 0.0f; + } + + cb->setBoostTime(i, m_boost_time[i]); + } +} // update + +// ---------------------------------------------------------------------------- +/** Render the post-processed scene, solids only, color to color, no stencil */ +void PostProcessing::renderSolid(const u32 cam) +{ + if (!irr_driver->isGLSL()) return; + + IVideoDriver * const drv = irr_driver->getVideoDriver(); + if (World::getWorld()->getTrack()->isFogEnabled()) + { + m_material.MaterialType = irr_driver->getShader(ES_FOG); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + + // Overlay + m_material.BlendOperation = EBO_ADD; + m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); + + drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + drawQuad(cam, m_material); + + m_material.BlendOperation = EBO_NONE; + m_material.MaterialTypeParam = 0; + } +} + +GLuint quad_vbo = 0; + +static void initQuadVBO() +{ + initGL(); + const float quad_vertex[] = { + -1., -1., 0., 0., // UpperLeft + -1., 1., 0., 1., // LowerLeft + 1., -1., 1., 0., // UpperRight + 1., 1., 1., 1., // LowerRight + }; + glGenBuffers(1, &quad_vbo); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +namespace BloomShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture, uniform_low; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "tex"); + uniform_low = glGetUniformLocation(Program, "low"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace BloomBlendShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture, uniform_low; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "tex"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace PPDisplaceShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_dtex, uniform_viz; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_dtex = glGetUniformLocation(Program, "dtex"); + uniform_viz = glGetUniformLocation(Program, "viz"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace ColorLevelShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_inlevel, uniform_outlevel; + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_inlevel = glGetUniformLocation(Program, "inlevel"); + uniform_outlevel = glGetUniformLocation(Program, "outlevel"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace PointLightShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_screen, uniform_invproj, uniform_viewm; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_ntex = glGetUniformLocation(Program, "ntex"); + uniform_center = glGetUniformLocation(Program, "center[0]"); + uniform_col = glGetUniformLocation(Program, "col[0]"); + uniform_energy = glGetUniformLocation(Program, "energy[0]"); + uniform_spec = glGetUniformLocation(Program, "spec"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_invproj = glGetUniformLocation(Program, "invproj"); + uniform_viewm = glGetUniformLocation(Program, "viewm"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + + +static +void renderBloom(ITexture *in) +{ + if (!BloomShader::Program) + BloomShader::init(); + + const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); + glUseProgram(BloomShader::Program); + glBindVertexArray(BloomShader::vao); + glUniform1f(BloomShader::uniform_low, threshold); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(BloomShader::uniform_texture, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +static +void renderBloomBlend(ITexture *in) +{ + if (!BloomBlendShader::Program) + BloomBlendShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_DEPTH_TEST); + + glUseProgram(BloomBlendShader::Program); + glBindVertexArray(BloomBlendShader::vao); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(BloomBlendShader::uniform_texture, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + +static +void renderPPDisplace(ITexture *in) +{ + if (!PPDisplaceShader::Program) + PPDisplaceShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_DEPTH_TEST); + + glUseProgram(PPDisplaceShader::Program); + glBindVertexArray(PPDisplaceShader::vao); + glUniform1i(PPDisplaceShader::uniform_viz, irr_driver->getDistortViz()); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(PPDisplaceShader::uniform_tex, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_DISPLACE))->getOpenGLTextureName()); + glUniform1i(PPDisplaceShader::uniform_dtex, 1); + + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + +static +void renderColorLevel(ITexture *in) { core::vector3df m_inlevel = World::getWorld()->getTrack()->getColorLevelIn(); - core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut(); - - - if (!ColorLevelShader::Program) - ColorLevelShader::init(); - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - - glUseProgram(ColorLevelShader::Program); - glBindVertexArray(ColorLevelShader::vao); - glUniform3f(ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z); - glUniform2f(ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(ColorLevelShader::uniform_tex, 0); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glEnable(GL_DEPTH_TEST); -} - -// ---------------------------------------------------------------------------- -/** Render the post-processed scene */ -void PostProcessing::render() -{ - if (!irr_driver->isGLSL()) return; - - IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setTransform(ETS_WORLD, core::IdentityMatrix); - drv->setTransform(ETS_VIEW, core::IdentityMatrix); - drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); - - MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver-> - getCallback(ES_MOTIONBLUR); - GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> - getCallback(ES_GAUSSIAN3H); - - const u32 cams = Camera::getNumCameras(); - for(u32 cam = 0; cam < cams; cam++) - { - scene::ICameraSceneNode * const camnode = - Camera::getCamera(cam)->getCameraSceneNode(); - mocb->setCurrentCamera(cam); - ITexture *in = irr_driver->getRTT(RTT_COLOR); - ITexture *out = irr_driver->getRTT(RTT_TMP1); - // 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. - - if (1) // bloom - { - // Blit the base to tmp1 - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, in); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - const bool globalbloom = World::getWorld()->getTrack()->getBloom(); - - BloomPowerProvider * const bloomcb = (BloomPowerProvider *) - irr_driver-> - getCallback(ES_BLOOM_POWER); - - if (globalbloom) - { - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - renderBloom(in); - } - - // Do we have any forced bloom nodes? If so, draw them now - const std::vector &blooms = irr_driver->getForcedBloom(); - const u32 bloomsize = blooms.size(); - - if (!globalbloom && bloomsize) - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - - if (globalbloom || bloomsize) - { - // Clear the alpha to a suitable value, stencil - glClearColor(0, 0, 0, 0.1f); - glColorMask(0, 0, 0, 1); - - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - - glClearColor(0, 0, 0, 0); - glColorMask(1, 1, 1, 1); - - // The forced-bloom objects are drawn again, to know which pixels to pick. - // While it's more drawcalls, there's a cost to using four MRTs over three, - // and there shouldn't be many such objects in a track. - // The stencil is already in use for the glow. The alpha channel is best - // reserved for other use (specular, etc). - // - // They are drawn with depth and color writes off, giving 4x-8x drawing speed. - if (bloomsize) - { - const core::aabbox3df &cambox = camnode-> - getViewFrustum()-> - getBoundingBox(); - - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); - SOverrideMaterial &overridemat = drv->getOverrideMaterial(); - overridemat.EnablePasses = ESNRP_SOLID; - overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK; - overridemat.Enabled = true; - - overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER); - overridemat.Material.ZWriteEnable = false; - overridemat.Material.ColorMask = ECP_ALPHA; - - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, ~0); - glEnable(GL_STENCIL_TEST); - - camnode->render(); - - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - // Second pass for transparents. No-op for solids. - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT); - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - overridemat.Enabled = 0; - overridemat.EnablePasses = 0; - - // Ok, we have the stencil; now use it to blit from color to bloom tex - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, ~0); - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR)); - - // Just in case. - glColorMask(1, 1, 1, 0); - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false); - - m_material.ColorMask = ECP_RGB; - drawQuad(cam, m_material); - m_material.ColorMask = ECP_ALL; - - glColorMask(1, 1, 1, 1); - glDisable(GL_STENCIL_TEST); - } // end forced bloom - - // To half - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); - - drawQuad(cam, m_material); - - // To quarter - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); - - drawQuad(cam, m_material); - - // To eighth - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); - - drawQuad(cam, m_material); - - // Blur it for distribution. - { - gacb->setResolution(UserConfigParams::m_width / 8, - UserConfigParams::m_height / 8); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false); - - drawQuad(cam, m_material); - } - - // Additively blend on top of tmp1 - drv->setRenderTarget(out, false, false); - renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1)); - } // end if bloom - - in = irr_driver->getRTT(RTT_TMP1); - out = irr_driver->getRTT(RTT_TMP2); - } - - if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays - { - // Grab the sky - drv->setRenderTarget(out, true, false); - irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX); - - // Set the sun's color - ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE); - const SColor col = World::getWorld()->getTrack()->getSunColor(); - colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f); - - // The sun interposer - IMeshSceneNode * const sun = irr_driver->getSunInterposer(); - sun->getMaterial(0).ColorMask = ECP_ALL; - irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA); - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); - - sun->render(); - - sun->getMaterial(0).ColorMask = ECP_NONE; - - // Fade to quarter - m_material.MaterialType = irr_driver->getShader(ES_GODFADE); - m_material.setTexture(0, out); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); - - drawQuad(cam, m_material); - - // Blur - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); - - drawQuad(cam, m_material); - } - - // Calculate the sun's position in texcoords - const core::vector3df pos = sun->getPosition(); - float ndc[4]; - core::matrix4 trans = camnode->getProjectionMatrix(); - trans *= camnode->getViewMatrix(); - - 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 sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw; - const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh; - - ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))-> - setSunPosition(sunx, suny); - - // Rays please - m_material.MaterialType = irr_driver->getShader(ES_GODRAY); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - // Blur - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false); - - drawQuad(cam, m_material); - } - - // Overlay - m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR; - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(in, false, false); - - drawQuad(cam, m_material); - } - - if (UserConfigParams::m_motionblur && m_any_boost) // motion blur - { - // Calculate the kart's Y position on screen - const core::vector3df pos = - Camera::getCamera(cam)->getKart()->getNode()->getPosition(); - float ndc[4]; - core::matrix4 trans = camnode->getProjectionMatrix(); - trans *= camnode->getViewMatrix(); - - trans.transformVect(ndc, pos); - const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f; - setMotionBlurCenterY(cam, karty); - - - m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR); - m_material.setTexture(0, in); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); - - ITexture *tmp = in; - in = out; - out = tmp; - } - - if (irr_driver->getDisplacingNodes().size()) // Displacement - { - drv->setRenderTarget(out, true, false); - renderPPDisplace(in); - - ITexture *tmp = in; - in = out; - out = tmp; - } - - if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. - { - drv->setRenderTarget(out, false, false); - - glEnable(GL_STENCIL_TEST); - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glStencilFunc(GL_ALWAYS, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - // Pass 1: color edge detection - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1); - m_material.setTexture(0, in); - - drawQuad(cam, m_material); - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - - glStencilFunc(GL_EQUAL, 1, ~0); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - // Pass 2: blend weights - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2); - m_material.setTexture(0, out); - m_material.setTexture(1, m_areamap); - m_material.TextureLayer[1].BilinearFilter = false; - m_material.TextureLayer[1].TrilinearFilter = false; - - drawQuad(cam, m_material); - - m_material.TextureLayer[1].BilinearFilter = true; - m_material.TextureLayer[1].TrilinearFilter = true; - m_material.setTexture(1, 0); - - // Pass 3: gather - drv->setRenderTarget(in, false, false); - - m_material.setFlag(EMF_BILINEAR_FILTER, false); - m_material.setFlag(EMF_TRILINEAR_FILTER, false); - m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3); - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); - m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR)); - - drawQuad(cam, m_material); - - m_material.setFlag(EMF_BILINEAR_FILTER, true); - m_material.setFlag(EMF_TRILINEAR_FILTER, true); - m_material.setTexture(1, 0); - - // Done. - glDisable(GL_STENCIL_TEST); - } - - // Final blit - drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); - if (irr_driver->getNormals()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - drawQuad(cam, m_material); - } else if (irr_driver->getSSAOViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - drawQuad(cam, m_material); - } else if (irr_driver->getShadowViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_DISPLACE)); - drawQuad(cam, m_material); - } else - { - renderColorLevel(in); - } - } -} // render - -void PostProcessing::drawQuad(u32 cam, const SMaterial &mat) -{ - const u16 indices[6] = {0, 1, 2, 3, 0, 2}; - IVideoDriver * const drv = irr_driver->getVideoDriver(); - - drv->setTransform(ETS_WORLD, core::IdentityMatrix); - drv->setTransform(ETS_VIEW, core::IdentityMatrix); - drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); - - drv->setMaterial(mat); - drv->drawIndexedTriangleList(&(m_vertices[cam].v0), - 4, indices, 2); -} + core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut(); + + + if (!ColorLevelShader::Program) + ColorLevelShader::init(); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + glUseProgram(ColorLevelShader::Program); + glBindVertexArray(ColorLevelShader::vao); + glUniform3f(ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z); + glUniform2f(ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(ColorLevelShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + +void PostProcessing::renderPointlight(ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy) +{ + float width = (float)UserConfigParams::m_width; + float height = (float)UserConfigParams::m_height; + if (!PointLightShader::Program) + PointLightShader::init(); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + glUseProgram(PointLightShader::Program); + glBindVertexArray(PointLightShader::vao); + + glUniform4fv(PointLightShader::uniform_center, 16, positions.data()); + glUniform4fv(PointLightShader::uniform_col, 16, colors.data()); + glUniform1fv(PointLightShader::uniform_energy, 16, energy.data()); + glUniform1f(PointLightShader::uniform_spec, 200); + glUniform2f(PointLightShader::uniform_screen, width, height); + glUniformMatrix4fv(PointLightShader::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); + glUniformMatrix4fv(PointLightShader::uniform_viewm, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(PointLightShader::uniform_ntex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + +// ---------------------------------------------------------------------------- +/** Render the post-processed scene */ +void PostProcessing::render() +{ + if (!irr_driver->isGLSL()) return; + + IVideoDriver * const drv = irr_driver->getVideoDriver(); + drv->setTransform(ETS_WORLD, core::IdentityMatrix); + drv->setTransform(ETS_VIEW, core::IdentityMatrix); + drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); + + MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver-> + getCallback(ES_MOTIONBLUR); + GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> + getCallback(ES_GAUSSIAN3H); + + const u32 cams = Camera::getNumCameras(); + for(u32 cam = 0; cam < cams; cam++) + { + scene::ICameraSceneNode * const camnode = + Camera::getCamera(cam)->getCameraSceneNode(); + mocb->setCurrentCamera(cam); + ITexture *in = irr_driver->getRTT(RTT_COLOR); + ITexture *out = irr_driver->getRTT(RTT_TMP1); + // 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. + + if (1) // bloom + { + // Blit the base to tmp1 + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, in); + drv->setRenderTarget(out, true, false); + + drawQuad(cam, m_material); + + const bool globalbloom = World::getWorld()->getTrack()->getBloom(); + + BloomPowerProvider * const bloomcb = (BloomPowerProvider *) + irr_driver-> + getCallback(ES_BLOOM_POWER); + + if (globalbloom) + { + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + renderBloom(in); + } + + // Do we have any forced bloom nodes? If so, draw them now + const std::vector &blooms = irr_driver->getForcedBloom(); + const u32 bloomsize = blooms.size(); + + if (!globalbloom && bloomsize) + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + + + if (globalbloom || bloomsize) + { + // Clear the alpha to a suitable value, stencil + glClearColor(0, 0, 0, 0.1f); + glColorMask(0, 0, 0, 1); + + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + + glClearColor(0, 0, 0, 0); + glColorMask(1, 1, 1, 1); + + // The forced-bloom objects are drawn again, to know which pixels to pick. + // While it's more drawcalls, there's a cost to using four MRTs over three, + // and there shouldn't be many such objects in a track. + // The stencil is already in use for the glow. The alpha channel is best + // reserved for other use (specular, etc). + // + // They are drawn with depth and color writes off, giving 4x-8x drawing speed. + if (bloomsize) + { + const core::aabbox3df &cambox = camnode-> + getViewFrustum()-> + getBoundingBox(); + + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); + SOverrideMaterial &overridemat = drv->getOverrideMaterial(); + overridemat.EnablePasses = ESNRP_SOLID; + overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK; + overridemat.Enabled = true; + + overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER); + overridemat.Material.ZWriteEnable = false; + overridemat.Material.ColorMask = ECP_ALPHA; + + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 1, ~0); + glEnable(GL_STENCIL_TEST); + + camnode->render(); + + for (u32 i = 0; i < bloomsize; i++) + { + scene::ISceneNode * const cur = blooms[i].node; + + // Quick box-based culling + const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); + if (!nodebox.intersectsWithBox(cambox)) + continue; + + bloomcb->setPower(blooms[i].power); + + cur->render(); + } + + // Second pass for transparents. No-op for solids. + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT); + for (u32 i = 0; i < bloomsize; i++) + { + scene::ISceneNode * const cur = blooms[i].node; + + // Quick box-based culling + const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); + if (!nodebox.intersectsWithBox(cambox)) + continue; + + bloomcb->setPower(blooms[i].power); + + cur->render(); + } + + overridemat.Enabled = 0; + overridemat.EnablePasses = 0; + + // Ok, we have the stencil; now use it to blit from color to bloom tex + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_EQUAL, 1, ~0); + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR)); + + // Just in case. + glColorMask(1, 1, 1, 0); + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false); + + m_material.ColorMask = ECP_RGB; + drawQuad(cam, m_material); + m_material.ColorMask = ECP_ALL; + + glColorMask(1, 1, 1, 1); + glDisable(GL_STENCIL_TEST); + } // end forced bloom + + // To half + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); + drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); + + drawQuad(cam, m_material); + + // To quarter + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); + + drawQuad(cam, m_material); + + // To eighth + m_material.MaterialType = EMT_SOLID; + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); + + drawQuad(cam, m_material); + + // Blur it for distribution. + { + gacb->setResolution(UserConfigParams::m_width / 8, + UserConfigParams::m_height / 8); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); + m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); + m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false); + + drawQuad(cam, m_material); + } + + // Additively blend on top of tmp1 + drv->setRenderTarget(out, false, false); + renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1)); + } // end if bloom + + in = irr_driver->getRTT(RTT_TMP1); + out = irr_driver->getRTT(RTT_TMP2); + } + + if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays + { + // Grab the sky + drv->setRenderTarget(out, true, false); + irr_driver->getSceneManager()->drawAll(ESNRP_SKY_BOX); + + // Set the sun's color + ColorizeProvider * const colcb = (ColorizeProvider *) irr_driver->getCallback(ES_COLORIZE); + const SColor col = World::getWorld()->getTrack()->getSunColor(); + colcb->setColor(col.getRed() / 255.0f, col.getGreen() / 255.0f, col.getBlue() / 255.0f); + + // The sun interposer + IMeshSceneNode * const sun = irr_driver->getSunInterposer(); + sun->getMaterial(0).ColorMask = ECP_ALL; + irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA); + irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); + + sun->render(); + + sun->getMaterial(0).ColorMask = ECP_NONE; + + // Fade to quarter + m_material.MaterialType = irr_driver->getShader(ES_GODFADE); + m_material.setTexture(0, out); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); + + drawQuad(cam, m_material); + + // Blur + { + gacb->setResolution(UserConfigParams::m_width / 4, + UserConfigParams::m_height / 4); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); + + drawQuad(cam, m_material); + } + + // Calculate the sun's position in texcoords + const core::vector3df pos = sun->getPosition(); + float ndc[4]; + core::matrix4 trans = camnode->getProjectionMatrix(); + trans *= camnode->getViewMatrix(); + + 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 sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw; + const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh; + + ((GodRayProvider *) irr_driver->getCallback(ES_GODRAY))-> + setSunPosition(sunx, suny); + + // Rays please + m_material.MaterialType = irr_driver->getShader(ES_GODRAY); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); + + drawQuad(cam, m_material); + + // Blur + { + gacb->setResolution(UserConfigParams::m_width / 4, + UserConfigParams::m_height / 4); + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); + + drawQuad(cam, m_material); + + m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), false, false); + + drawQuad(cam, m_material); + } + + // Overlay + m_material.MaterialType = EMT_TRANSPARENT_ADD_COLOR; + m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); + drv->setRenderTarget(in, false, false); + + drawQuad(cam, m_material); + } + + if (UserConfigParams::m_motionblur && m_any_boost) // motion blur + { + // Calculate the kart's Y position on screen + const core::vector3df pos = + Camera::getCamera(cam)->getKart()->getNode()->getPosition(); + float ndc[4]; + core::matrix4 trans = camnode->getProjectionMatrix(); + trans *= camnode->getViewMatrix(); + + trans.transformVect(ndc, pos); + const float karty = (ndc[1] / ndc[3]) * 0.5f + 0.5f; + setMotionBlurCenterY(cam, karty); + + + m_material.MaterialType = irr_driver->getShader(ES_MOTIONBLUR); + m_material.setTexture(0, in); + drv->setRenderTarget(out, true, false); + + drawQuad(cam, m_material); + + ITexture *tmp = in; + in = out; + out = tmp; + } + + if (irr_driver->getDisplacingNodes().size()) // Displacement + { + drv->setRenderTarget(out, true, false); + renderPPDisplace(in); + + ITexture *tmp = in; + in = out; + out = tmp; + } + + if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. + { + drv->setRenderTarget(out, false, false); + + glEnable(GL_STENCIL_TEST); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glStencilFunc(GL_ALWAYS, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + // Pass 1: color edge detection + m_material.setFlag(EMF_BILINEAR_FILTER, false); + m_material.setFlag(EMF_TRILINEAR_FILTER, false); + m_material.MaterialType = irr_driver->getShader(ES_MLAA_COLOR1); + m_material.setTexture(0, in); + + drawQuad(cam, m_material); + m_material.setFlag(EMF_BILINEAR_FILTER, true); + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + + glStencilFunc(GL_EQUAL, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + + // Pass 2: blend weights + drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); + + m_material.MaterialType = irr_driver->getShader(ES_MLAA_BLEND2); + m_material.setTexture(0, out); + m_material.setTexture(1, m_areamap); + m_material.TextureLayer[1].BilinearFilter = false; + m_material.TextureLayer[1].TrilinearFilter = false; + + drawQuad(cam, m_material); + + m_material.TextureLayer[1].BilinearFilter = true; + m_material.TextureLayer[1].TrilinearFilter = true; + m_material.setTexture(1, 0); + + // Pass 3: gather + drv->setRenderTarget(in, false, false); + + m_material.setFlag(EMF_BILINEAR_FILTER, false); + m_material.setFlag(EMF_TRILINEAR_FILTER, false); + m_material.MaterialType = irr_driver->getShader(ES_MLAA_NEIGH3); + m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); + m_material.setTexture(1, irr_driver->getRTT(RTT_COLOR)); + + drawQuad(cam, m_material); + + m_material.setFlag(EMF_BILINEAR_FILTER, true); + m_material.setFlag(EMF_TRILINEAR_FILTER, true); + m_material.setTexture(1, 0); + + // Done. + glDisable(GL_STENCIL_TEST); + } + + // Final blit + drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); + if (irr_driver->getNormals()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + drawQuad(cam, m_material); + } else if (irr_driver->getSSAOViz()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); + drawQuad(cam, m_material); + } else if (irr_driver->getShadowViz()) + { + m_material.MaterialType = irr_driver->getShader(ES_FLIP); + m_material.setTexture(0, irr_driver->getRTT(RTT_DISPLACE)); + drawQuad(cam, m_material); + } else + { + renderColorLevel(in); + } + } +} // render + +void PostProcessing::drawQuad(u32 cam, const SMaterial &mat) +{ + const u16 indices[6] = {0, 1, 2, 3, 0, 2}; + IVideoDriver * const drv = irr_driver->getVideoDriver(); + + drv->setTransform(ETS_WORLD, core::IdentityMatrix); + drv->setTransform(ETS_VIEW, core::IdentityMatrix); + drv->setTransform(ETS_PROJECTION, core::IdentityMatrix); + + drv->setMaterial(mat); + drv->drawIndexedTriangleList(&(m_vertices[cam].v0), + 4, indices, 2); +} diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 020cb3ffc..b1ab9a410 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -75,6 +75,9 @@ public: /** Render the post-processed scene, solids only, color to color, no stencil */ void renderSolid(const u32 cam); + /** Generate diffuse and specular map */ + void renderPointlight(video::ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index df00e8972..26dc99f97 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -766,7 +766,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, accumulatedLightColor.push_back(0.); accumulatedLightEnergy.push_back(0.); } - LightNode::renderLightSet(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); + m_post_processing->renderPointlight(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH) , accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO SMaterial m_material; GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> From 1edba6d39431732d49e46c7a25b42bf1f8d45d88 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 13:07:12 +0000 Subject: [PATCH 265/412] Clean PointLight Provider and snow provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15037 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 33 ------------------------- src/graphics/callbacks.hpp | 50 -------------------------------------- src/graphics/light.cpp | 39 ----------------------------- src/graphics/light.hpp | 1 - src/graphics/shaders.cpp | 4 --- src/graphics/shaders.hpp | 1 - 6 files changed, 128 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 6970ddf26..326941c32 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -269,15 +269,6 @@ void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void SnowEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; - - srv->setVertexShaderConstant("time", &time, 1); -} - -//------------------------------------- - void MotionBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int) { // We need the maximum texture coordinates: @@ -412,30 +403,6 @@ void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void PointLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - srv->setVertexShaderConstant("screen", m_screen, 2); - srv->setVertexShaderConstant("spec", &m_specular, 1); - srv->setVertexShaderConstant("invproj", irr_driver->getInvProjMatrix().pointer(), 16); - srv->setVertexShaderConstant("energy[0]", m_energy.data(), m_energy.size()); - srv->setVertexShaderConstant("col[0]", m_color.data(), m_color.size()); - srv->setVertexShaderConstant("center[0]", m_pos.data(), m_pos.size()); - srv->setVertexShaderConstant("viewm", irr_driver->getViewMatrix().pointer(), 16); - - if (!firstdone) - { - int tex = 0; - srv->setVertexShaderConstant("ntex", &tex, 1); - - tex = 1; - srv->setVertexShaderConstant("dtex", &tex, 1); - - firstdone = true; - } -} - -//------------------------------------- - void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const int hasclouds = World::getWorld()->getTrack()->hasClouds() && diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index d7f946d52..d5a39ac24 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -236,14 +236,6 @@ public: // -class SnowEffectProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class MotionBlurProvider: public CallBase { public: @@ -370,48 +362,6 @@ public: virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); }; -// -class PointLightProvider: public CallBase -{ -public: - PointLightProvider() - { - m_screen[0] = (float)UserConfigParams::m_width; - m_screen[1] = (float)UserConfigParams::m_height; - - m_specular = 200; - } - - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - void setColor(const std::vector &col) - { - m_color = col; - } - - void setPosition(const std::vector &pos) - { - m_pos = pos; - return; - } - - void setSpecular(float s) - { - m_specular = s; - } - - void setEnergy(const std::vector &e) { - m_energy = e; - } - -private: - std::vector m_color; - std::vector m_pos; - std::vector m_energy; - float m_screen[2]; - float m_specular; -}; - // class SunLightProvider: public CallBase diff --git a/src/graphics/light.cpp b/src/graphics/light.cpp index 196799f4d..d534ad4cb 100644 --- a/src/graphics/light.cpp +++ b/src/graphics/light.cpp @@ -57,45 +57,6 @@ void LightNode::render() return; } -void LightNode::renderLightSet(const std::vector &positions, const std::vector &colors, const std::vector &energy) -{ - assert (colors.size() == positions.size() && positions.size() == (energy.size() * 4)); - ScreenQuad *sq = new ScreenQuad(irr_driver->getVideoDriver()); - SMaterial &mat = sq->getMaterial(); - - mat.Lighting = false; - mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT); - - mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) - { - mat.TextureLayer[i].TextureWrapU = - mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE; - } - - mat.setFlag(EMF_BILINEAR_FILTER, false); - mat.setFlag(EMF_ZWRITE_ENABLE, false); - - mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE); - mat.BlendOperation = EBO_ADD; - - PointLightProvider * const cb = (PointLightProvider *) irr_driver->getCallback(ES_POINTLIGHT); - cb->setColor(colors); - cb->setPosition(positions); - cb->setEnergy(energy); - // Irrlicht's ScreenQuad reset the matrixes, we need to keep them - IVideoDriver * const drv = irr_driver->getVideoDriver(); - matrix4 tmpworld = drv->getTransform(ETS_WORLD); - matrix4 tmpview = drv->getTransform(ETS_VIEW); - matrix4 tmpproj = drv->getTransform(ETS_PROJECTION); - sq->render(false); - drv->setTransform(ETS_WORLD, tmpworld); - drv->setTransform(ETS_VIEW, tmpview); - drv->setTransform(ETS_PROJECTION, tmpproj); - return; -} - void LightNode::OnRegisterSceneNode() { // This node is only drawn manually. diff --git a/src/graphics/light.hpp b/src/graphics/light.hpp index b6309f56e..c649bc495 100644 --- a/src/graphics/light.hpp +++ b/src/graphics/light.hpp @@ -44,7 +44,6 @@ public: virtual ~LightNode(); virtual void render() OVERRIDE; - static void renderLightSet(const std::vector &positions, const std::vector &colors, const std::vector &energy); virtual const core::aabbox3d& getBoundingBox() const OVERRIDE { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1e4f790ad..d84d762fd 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -47,7 +47,6 @@ Shaders::Shaders() m_callbacks[ES_GLOW] = new GlowProvider(); m_callbacks[ES_OBJECTPASS] = new ObjectPassProvider(); m_callbacks[ES_LIGHTBLEND] = new LightBlendProvider(); - m_callbacks[ES_POINTLIGHT] = new PointLightProvider(); m_callbacks[ES_SUNLIGHT] = new SunLightProvider(); m_callbacks[ES_MLAA_COLOR1] = new MLAAColor1Provider(); m_callbacks[ES_MLAA_BLEND2] = new MLAABlend2Provider(); @@ -160,9 +159,6 @@ void Shaders::loadShaders() m_shaders[ES_LIGHTBLEND] = glslmat(dir + "pass.vert", dir + "lightblend.frag", m_callbacks[ES_LIGHTBLEND], EMT_ONETEXTURE_BLEND); - m_shaders[ES_POINTLIGHT] = glslmat(dir + "pass.vert", dir + "pointlight.frag", - m_callbacks[ES_POINTLIGHT], EMT_ONETEXTURE_BLEND); - m_shaders[ES_SUNLIGHT] = glslmat(std::string(""), dir + "sunlight.frag", m_callbacks[ES_SUNLIGHT], EMT_SOLID); m_shaders[ES_SUNLIGHT_SHADOW] = glslmat(dir + "pass.vert", dir + "sunlightshadow.frag", diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index a6968259f..0ece19b45 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -50,7 +50,6 @@ using namespace irr; ACT(ES_OBJECTPASS) \ ACT(ES_OBJECTPASS_REF) \ ACT(ES_LIGHTBLEND) \ - ACT(ES_POINTLIGHT) \ ACT(ES_SUNLIGHT) \ ACT(ES_SUNLIGHT_SHADOW) \ ACT(ES_OBJECTPASS_RIMLIT) \ From 4f209d38c6602a2a0ad0f00b582f8184fc454961 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 13:15:51 +0000 Subject: [PATCH 266/412] Light: Readd blending so that sunlight is not killed by pointlight. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15038 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index ce112bc03..6d9fab60c 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -505,7 +505,9 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po float height = (float)UserConfigParams::m_height; if (!PointLightShader::Program) PointLightShader::init(); - glDisable(GL_BLEND); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); glUseProgram(PointLightShader::Program); @@ -528,6 +530,7 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); } // ---------------------------------------------------------------------------- From a21f77706a7afda874f80d3ac319d29618a07a27 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 13:38:59 +0000 Subject: [PATCH 267/412] Lights: Also use direct calls for lightblend. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15039 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 72 ++++++++++++++++++++++++++++++++ src/graphics/post_processing.hpp | 3 ++ src/graphics/render.cpp | 23 +--------- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 6d9fab60c..0ac4396eb 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -393,6 +393,39 @@ namespace PointLightShader } } +namespace LightBlendShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_diffuse, uniform_specular, uniform_ambient_occlusion, uniform_specular_map, uniform_ambient; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/lightblend.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_diffuse = glGetUniformLocation(Program, "diffuse"); + uniform_specular = glGetUniformLocation(Program, "specular"); + uniform_ambient_occlusion = glGetUniformLocation(Program, "ambient_occlusion"); + uniform_specular_map = glGetUniformLocation(Program, "specular_map"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -533,6 +566,45 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po glDisable(GL_BLEND); } +void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, ITexture *ao, ITexture *specmap, bool debug) +{ + const SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + if (!LightBlendShader::Program) + LightBlendShader::init(); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + if (debug) + glBlendFunc(GL_ONE, GL_ZERO); + else + glBlendFunc(GL_DST_COLOR, GL_ZERO); + glDisable(GL_DEPTH_TEST); + + glUseProgram(LightBlendShader::Program); + glBindVertexArray(LightBlendShader::vao); + + glUniform3f(LightBlendShader::uniform_ambient, s.r, s.g, s.b); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(diffuse)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_diffuse, 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(specular)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_specular, 1); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(ao)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_ambient_occlusion, 2); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(specmap)->getOpenGLTextureName()); + glUniform1i(LightBlendShader::uniform_specular_map, 3); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index b1ab9a410..97434d02e 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -78,6 +78,9 @@ public: /** Generate diffuse and specular map */ void renderPointlight(video::ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy); + /** Blend all light related map */ + void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 26dc99f97..fea8f7265 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -808,30 +808,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_post_processing->drawQuad(cam, m_material); } - // Blend lights to the image - video::SMaterial lightmat; - lightmat.Lighting = false; - lightmat.ZWriteEnable = false; - lightmat.ZBuffer = video::ECFN_ALWAYS; - lightmat.setFlag(video::EMF_BILINEAR_FILTER, false); - lightmat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); - lightmat.setTexture(1, m_rtts->getRTT(RTT_TMP2)); - lightmat.setTexture(2, m_rtts->getRTT(RTT_SSAO)); - lightmat.setTexture(3, m_rtts->getRTT(RTT_SPECULARMAP)); - - lightmat.MaterialType = m_shaders->getShader(ES_LIGHTBLEND); - if (!m_lightviz) - lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_DST_COLOR, video::EBF_ZERO); - else - lightmat.MaterialTypeParam = video::pack_textureBlendFunc(video::EBF_ONE, video::EBF_ZERO); - lightmat.BlendOperation = video::EBO_ADD; - - lightmat.TextureLayer[0].TextureWrapU = - lightmat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); if (!m_mipviz) - m_post_processing->drawQuad(cam, lightmat); + m_post_processing->renderLightbBlend(m_rtts->getRTT(RTT_TMP1), m_rtts->getRTT(RTT_TMP2), m_rtts->getRTT(RTT_SSAO), m_rtts->getRTT(RTT_SPECULARMAP), m_lightviz); } // ---------------------------------------------------------------------------- From 9b4288b576f4f723fdb1d3e0cb5e8418a3af40c2 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 13:43:18 +0000 Subject: [PATCH 268/412] Lights: Clean lightblend provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15040 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 19 ------------------- src/graphics/callbacks.hpp | 8 -------- src/graphics/shaders.cpp | 4 ---- src/graphics/shaders.hpp | 1 - 4 files changed, 32 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 326941c32..eec14389f 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -384,25 +384,6 @@ void ObjectPassProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void LightBlendProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - const SColorf s = irr_driver->getSceneManager()->getAmbientLight(); - - float ambient[3] = { s.r, s.g, s.b }; - srv->setVertexShaderConstant("ambient", ambient, 3); - - int tex = 0; - srv->setVertexShaderConstant("diffuse", &tex, 1); - tex = 1; - srv->setVertexShaderConstant("specular", &tex, 1); - tex = 2; - srv->setVertexShaderConstant("ambient_occlusion", &tex, 1); - tex = 3; - srv->setVertexShaderConstant("specular_map", &tex, 1); -} - -//------------------------------------- - void SunLightProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const int hasclouds = World::getWorld()->getTrack()->hasClouds() && diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index d5a39ac24..24da48ed2 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -356,14 +356,6 @@ public: // -class LightBlendProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class SunLightProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d84d762fd..47d36def8 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -46,7 +46,6 @@ Shaders::Shaders() m_callbacks[ES_COLORIZE] = new ColorizeProvider(); m_callbacks[ES_GLOW] = new GlowProvider(); m_callbacks[ES_OBJECTPASS] = new ObjectPassProvider(); - m_callbacks[ES_LIGHTBLEND] = new LightBlendProvider(); m_callbacks[ES_SUNLIGHT] = new SunLightProvider(); m_callbacks[ES_MLAA_COLOR1] = new MLAAColor1Provider(); m_callbacks[ES_MLAA_BLEND2] = new MLAABlend2Provider(); @@ -156,9 +155,6 @@ void Shaders::loadShaders() m_shaders[ES_OBJECTPASS_RIMLIT] = glslmat(dir + "objectpass_rimlit.vert", dir + "objectpass_rimlit.frag", m_callbacks[ES_OBJECTPASS], EMT_SOLID); - m_shaders[ES_LIGHTBLEND] = glslmat(dir + "pass.vert", dir + "lightblend.frag", - m_callbacks[ES_LIGHTBLEND], EMT_ONETEXTURE_BLEND); - m_shaders[ES_SUNLIGHT] = glslmat(std::string(""), dir + "sunlight.frag", m_callbacks[ES_SUNLIGHT], EMT_SOLID); m_shaders[ES_SUNLIGHT_SHADOW] = glslmat(dir + "pass.vert", dir + "sunlightshadow.frag", diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 0ece19b45..758e39f44 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -49,7 +49,6 @@ using namespace irr; ACT(ES_GLOW) \ ACT(ES_OBJECTPASS) \ ACT(ES_OBJECTPASS_REF) \ - ACT(ES_LIGHTBLEND) \ ACT(ES_SUNLIGHT) \ ACT(ES_SUNLIGHT_SHADOW) \ ACT(ES_OBJECTPASS_RIMLIT) \ From 62e5fbf6ad7ac76337d27747a52f1ea81b7e4ef8 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 14:23:30 +0000 Subject: [PATCH 269/412] Use direct call for Gaussian 6 Blur. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15041 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 117 +++++++++++++++++++++++++++---- src/graphics/post_processing.hpp | 3 + src/graphics/render.cpp | 15 +--- 3 files changed, 107 insertions(+), 28 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 0ac4396eb..3632634b2 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -426,6 +426,64 @@ namespace LightBlendShader } } +namespace Gaussian6HBlurShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_pixel; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6h.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + +namespace Gaussian6VBlurShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_pixel; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6v.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -605,6 +663,46 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT glDisable(GL_BLEND); } +void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height) +{ + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + { + if (!Gaussian6VBlurShader::Program) + Gaussian6VBlurShader::init(); + irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false); + glUseProgram(Gaussian6VBlurShader::Program); + glBindVertexArray(Gaussian6VBlurShader::vao); + + glUniform2f(Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(Gaussian6VBlurShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + { + if (!Gaussian6HBlurShader::Program) + Gaussian6HBlurShader::init(); + irr_driver->getVideoDriver()->setRenderTarget(in, false, false); + glUseProgram(Gaussian6HBlurShader::Program); + glBindVertexArray(Gaussian6HBlurShader::vao); + + glUniform2f(Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); + glUniform1i(Gaussian6HBlurShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -776,25 +874,14 @@ void PostProcessing::render() drawQuad(cam, m_material); // Blur it for distribution. - { - gacb->setResolution(UserConfigParams::m_width / 8, - UserConfigParams::m_height / 8); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); - m_material.setTexture(0, irr_driver->getRTT(RTT_EIGHTH2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), false, false); - - drawQuad(cam, m_material); - } + renderGaussian6Blur(irr_driver->getRTT(RTT_EIGHTH1), irr_driver->getRTT(RTT_EIGHTH2), 8.f / UserConfigParams::m_width, 8.f / UserConfigParams::m_height); // Additively blend on top of tmp1 drv->setRenderTarget(out, false, false); renderBloomBlend(irr_driver->getRTT(RTT_EIGHTH1)); + m_material.MaterialType = irr_driver->getShader(ES_RAIN); + drv->setMaterial(m_material); + static_cast(drv)->setRenderStates3DMode(); } // end if bloom in = irr_driver->getRTT(RTT_TMP1); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 97434d02e..b9a41fac4 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -81,6 +81,9 @@ public: /** Blend all light related map */ void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); + /** Blur the in texture */ + void renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index fea8f7265..a30108751 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -794,19 +794,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER4)); m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); m_post_processing->drawQuad(cam, m_material); - } else if (UserConfigParams::m_ssao == 2) { - gacb->setResolution(UserConfigParams::m_width, - UserConfigParams::m_height); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6V); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_TMP4), true, false); - m_post_processing->drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN6H); - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP4)); - m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); - m_post_processing->drawQuad(cam, m_material); - } + } else if (UserConfigParams::m_ssao == 2) + m_post_processing->renderGaussian6Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_TMP4), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); if (!m_mipviz) From 645d4504ab7b2192469b145cd6bb5c593e19d34f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 14:31:31 +0000 Subject: [PATCH 270/412] Clean GaussianBlur6 shaders. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15042 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/render.cpp | 18 +++--------------- src/graphics/shaders.cpp | 5 ----- src/graphics/shaders.hpp | 2 -- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index a30108751..8b4ee3453 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -502,13 +502,13 @@ void IrrDriver::renderShadows(ShadowImportanceProvider * const sicb, m_rtts->getRTT(RTT_WARPV)->getSize().Height, m_rtts->getRTT(RTT_WARPV)->getSize().Height); - sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H)); +/* sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6H)); sq.setTexture(m_rtts->getRTT(RTT_WARPH)); sq.render(m_rtts->getRTT(curh)); sq.setMaterialType(m_shaders->getShader(ES_GAUSSIAN6V)); sq.setTexture(m_rtts->getRTT(RTT_WARPV)); - sq.render(m_rtts->getRTT(curv)); + sq.render(m_rtts->getRTT(curv));*/ // Convert importance maps to warp maps // @@ -649,19 +649,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, m_post_processing->drawQuad(cam, minimat); // Blur it - ((GaussianBlurProvider *) m_shaders->m_callbacks[ES_GAUSSIAN3H])->setResolution( - UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - - minimat.MaterialType = m_shaders->getShader(ES_GAUSSIAN6H); - minimat.setTexture(0, m_rtts->getRTT(RTT_QUARTER1)); - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_QUARTER2), false, false); - m_post_processing->drawQuad(cam, minimat); - - minimat.MaterialType = m_shaders->getShader(ES_GAUSSIAN6V); - minimat.setTexture(0, m_rtts->getRTT(RTT_QUARTER2)); - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_QUARTER1), false, false); - m_post_processing->drawQuad(cam, minimat); + m_post_processing->renderGaussian6Blur(m_rtts->getRTT(RTT_QUARTER1), m_rtts->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); // The glows will be rendered in the transparent phase m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 47d36def8..013c7ab96 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -122,11 +122,6 @@ void Shaders::loadShaders() m_shaders[ES_GAUSSIAN3V] = glslmat(dir + "pass.vert", dir + "gaussian3v.frag", m_callbacks[ES_GAUSSIAN3V], EMT_SOLID); - m_shaders[ES_GAUSSIAN6H] = glslmat(dir + "pass.vert", dir + "gaussian6h.frag", - m_callbacks[ES_GAUSSIAN3H], EMT_SOLID); - m_shaders[ES_GAUSSIAN6V] = glslmat(dir + "pass.vert", dir + "gaussian6v.frag", - m_callbacks[ES_GAUSSIAN3V], EMT_SOLID); - m_shaders[ES_MIPVIZ] = glslmat(std::string(""), dir + "mipviz.frag", m_callbacks[ES_MIPVIZ], EMT_SOLID); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 758e39f44..6f71fe00c 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -40,8 +40,6 @@ using namespace irr; ACT(ES_MIPVIZ) \ ACT(ES_FLIP) \ ACT(ES_FLIP_ADDITIVE) \ - ACT(ES_GAUSSIAN6H) \ - ACT(ES_GAUSSIAN6V) \ ACT(ES_COLORIZE) \ ACT(ES_COLORIZE_REF) \ ACT(ES_PASS) \ From 7d1df1934208ca25593e3980fd9f61ff806f9fed Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 14:50:16 +0000 Subject: [PATCH 271/412] Use a passthrough shader for some fullscreen effect. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15043 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/texturedquad.frag | 4 +- data/shaders/texturedquad.vert | 2 +- src/graphics/post_processing.cpp | 94 +++++++++++++++++++++----------- 3 files changed, 66 insertions(+), 34 deletions(-) diff --git a/data/shaders/texturedquad.frag b/data/shaders/texturedquad.frag index b2c3f9612..cf1aade40 100644 --- a/data/shaders/texturedquad.frag +++ b/data/shaders/texturedquad.frag @@ -1,9 +1,9 @@ #version 130 uniform sampler2D texture; -in vec2 tc; +in vec2 uv; void main() { - gl_FragColor = texture2D(texture, tc); + gl_FragColor = texture2D(texture, uv); } \ No newline at end of file diff --git a/data/shaders/texturedquad.vert b/data/shaders/texturedquad.vert index 6e14ea24e..5364b2209 100644 --- a/data/shaders/texturedquad.vert +++ b/data/shaders/texturedquad.vert @@ -6,7 +6,7 @@ uniform vec2 texsize; in vec2 position; in vec2 texcoord; -out vec2 tc; +out vec2 uv; void main() { diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 3632634b2..00071e558 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -484,6 +484,34 @@ namespace Gaussian6VBlurShader } } +namespace PassThroughShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_texture; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_texture = glGetUniformLocation(Program, "texture"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -703,6 +731,28 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t glEnable(GL_DEPTH_TEST); } +static +void renderPassThrough(ITexture *tex) +{ + if (!PassThroughShader::Program) + PassThroughShader::init(); + glDisable(GL_DEPTH_TEST); + + glUseProgram(PassThroughShader::Program); + glBindVertexArray(PassThroughShader::vao); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); + glUniform1i(PassThroughShader::uniform_texture, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() @@ -853,25 +903,17 @@ void PostProcessing::render() } // end forced bloom // To half - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_TMP3)); drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); + renderPassThrough(irr_driver->getRTT(RTT_TMP3)); - drawQuad(cam, m_material); // To quarter - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_HALF1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); - - drawQuad(cam, m_material); - + drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), true, false); + renderPassThrough(irr_driver->getRTT(RTT_HALF1)); + // To eighth - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); - - drawQuad(cam, m_material); + drv->setRenderTarget(irr_driver->getRTT(RTT_EIGHTH1), true, false); + renderPassThrough(irr_driver->getRTT(RTT_QUARTER1)); // Blur it for distribution. renderGaussian6Blur(irr_driver->getRTT(RTT_EIGHTH1), irr_driver->getRTT(RTT_EIGHTH2), 8.f / UserConfigParams::m_width, 8.f / UserConfigParams::m_height); @@ -1075,26 +1117,16 @@ void PostProcessing::render() } // Final blit + // TODO : Use glBlitFramebuffer drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); if (irr_driver->getNormals()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - drawQuad(cam, m_material); - } else if (irr_driver->getSSAOViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - drawQuad(cam, m_material); - } else if (irr_driver->getShadowViz()) - { - m_material.MaterialType = irr_driver->getShader(ES_FLIP); - m_material.setTexture(0, irr_driver->getRTT(RTT_DISPLACE)); - drawQuad(cam, m_material); - } else - { + renderPassThrough(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); + else if (irr_driver->getSSAOViz()) + renderPassThrough(irr_driver->getRTT(RTT_SSAO)); + else if (irr_driver->getShadowViz()) + renderPassThrough(irr_driver->getRTT(RTT_SHADOW)); + else renderColorLevel(in); - } } } // render From 3504f04a4e49febc8be67bf92c04699bb07cedb0 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 14:54:07 +0000 Subject: [PATCH 272/412] Remove unneeded flip shader. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15044 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/flip.frag | 11 ----------- src/graphics/shaders.cpp | 5 ----- src/graphics/shaders.hpp | 2 -- 3 files changed, 18 deletions(-) delete mode 100644 data/shaders/flip.frag diff --git a/data/shaders/flip.frag b/data/shaders/flip.frag deleted file mode 100644 index f108cb0b3..000000000 --- a/data/shaders/flip.frag +++ /dev/null @@ -1,11 +0,0 @@ -#version 130 -uniform sampler2D tex; - -void main() -{ - vec2 texc = gl_TexCoord[0].xy; - texc.y = 1.0 - texc.y; - - - gl_FragColor = vec4(texture2D(tex, texc).rgb, 1.0); -} diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 013c7ab96..ff272a8ac 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -125,11 +125,6 @@ void Shaders::loadShaders() m_shaders[ES_MIPVIZ] = glslmat(std::string(""), dir + "mipviz.frag", m_callbacks[ES_MIPVIZ], EMT_SOLID); - m_shaders[ES_FLIP] = glslmat(std::string(""), dir + "flip.frag", - 0, EMT_SOLID); - m_shaders[ES_FLIP_ADDITIVE] = glslmat(std::string(""), dir + "flip.frag", - 0, EMT_TRANSPARENT_ADD_COLOR); - m_shaders[ES_COLORIZE] = glslmat(std::string(""), dir + "colorize.frag", m_callbacks[ES_COLORIZE], EMT_SOLID); m_shaders[ES_COLORIZE_REF] = glslmat(std::string(""), dir + "colorize_ref.frag", diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 6f71fe00c..03a5500b4 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -38,8 +38,6 @@ using namespace irr; ACT(ES_GAUSSIAN3H) \ ACT(ES_GAUSSIAN3V) \ ACT(ES_MIPVIZ) \ - ACT(ES_FLIP) \ - ACT(ES_FLIP_ADDITIVE) \ ACT(ES_COLORIZE) \ ACT(ES_COLORIZE_REF) \ ACT(ES_PASS) \ From 6a8396ea331aedc93e3a204fc70d0a705a6c52e8 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 15:22:58 +0000 Subject: [PATCH 273/412] Forget a passthrough call and fix texturedquad shader. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15045 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/texturedquad.vert | 2 +- src/graphics/post_processing.cpp | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/data/shaders/texturedquad.vert b/data/shaders/texturedquad.vert index 5364b2209..668c52eb5 100644 --- a/data/shaders/texturedquad.vert +++ b/data/shaders/texturedquad.vert @@ -10,6 +10,6 @@ out vec2 uv; void main() { - tc = texcoord * texsize + texcenter; + uv = texcoord * texsize + texcenter; gl_Position = vec4(position * size + center, 0., 1.); } \ No newline at end of file diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 00071e558..5ab2c84b1 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -784,12 +784,9 @@ void PostProcessing::render() if (1) // bloom { - // Blit the base to tmp1 - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, in); - drv->setRenderTarget(out, true, false); - - drawQuad(cam, m_material); + // Blit the base to tmp1 + drv->setRenderTarget(out, true, false); + renderPassThrough(in); const bool globalbloom = World::getWorld()->getTrack()->getBloom(); From c520db663fc16d05ba162754858d06920c94561a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 15:28:37 +0000 Subject: [PATCH 274/412] OGL32CTX: Some fixes. The track is now displayed (even with light) but not the karts, animations... git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15046 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 +- src/graphics/stkmesh.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 63d541d05..b7999f8ff 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -174,7 +174,7 @@ void initGL() glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv"); glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv"); #endif -#if ENABLE_ARB_DEBUG_OUTPUT +#ifdef ENABLE_ARB_DEBUG_OUTPUT glDebugMessageCallbackARB(debugCallback, NULL); #endif const float quad_vertex[] = { diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 29cd7ce4b..57cdcec0f 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -321,14 +321,18 @@ void STKMesh::render() video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); bool transparent = (rnd && rnd->isTransparent()); +#ifdef OGL32CTX // only render transparent buffer if this is the transparent render pass // and solid only in solid pass -/* if (isObject(material.MaterialType) && !isTransparentPass && !transparent) + if (isObject(material.MaterialType) && !isTransparentPass && !transparent) { initvaostate(GLmeshes[i], material.MaterialType); draw(GLmeshes[i], material.MaterialType); } - else*/ if (transparent == isTransparentPass) + else if (transparent == isTransparentPass) +#else + if (transparent == isTransparentPass) +#endif { driver->setMaterial(material); driver->drawMeshBuffer(mb); From c02d99ed9f192a94d402acfad13f2cab5569b58e Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 16:05:26 +0000 Subject: [PATCH 275/412] GPUParticles: Do not grow when size is 0 git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15047 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointemitter.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 155d32b6b..ea29258b7 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -45,7 +45,7 @@ void main(void) new_particle_position = particle_position + particle_velocity.xyz * float(dt); new_particle_velocity = particle_velocity; new_lifetime = updated_lifetime; - new_size = mix(size_initial, size_initial * size_increase_factor, updated_lifetime); + new_size = (size == 0) ? 0. : mix(size_initial, size_initial * size_increase_factor, updated_lifetime); } gl_Position = vec4(0.); } From 4063fe83a9bda800d3d98cd1b8418456dd873762 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 16:05:46 +0000 Subject: [PATCH 276/412] Remove rain effect provider it's not used anymore. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15048 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 22 ---------------------- src/graphics/callbacks.hpp | 8 -------- src/graphics/shaders.cpp | 1 - 3 files changed, 31 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index eec14389f..756325efa 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -247,28 +247,6 @@ void BubbleEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void RainEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - const float screenw = (float)UserConfigParams::m_width; - const float time = irr_driver->getDevice()->getTimer()->getTime() / 90.0f; - const vector3df campos = irr_driver->getSceneManager()->getActiveCamera()->getPosition(); - float screen[2] = { (float)UserConfigParams::m_width, - (float)UserConfigParams::m_height }; - - srv->setVertexShaderConstant("screenw", &screenw, 1); - srv->setVertexShaderConstant("time", &time, 1); - srv->setVertexShaderConstant("viewm", irr_driver->getViewMatrix().pointer(), 16); - srv->setVertexShaderConstant("campos", &campos.X, 3); - srv->setPixelShaderConstant("invproj", irr_driver->getInvProjMatrix().pointer(), 16); - srv->setPixelShaderConstant("screen", screen, 2); - s32 tex = 0; - srv->setPixelShaderConstant("tex", &tex, 1); - tex = 1; - srv->setPixelShaderConstant("normals_and_depth", &tex, 1); -} - -//------------------------------------- - void MotionBlurProvider::OnSetConstants(IMaterialRendererServices *srv, int) { // We need the maximum texture coordinates: diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 24da48ed2..7a6441b96 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -228,14 +228,6 @@ private: // -class RainEffectProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class MotionBlurProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index ff272a8ac..121d163f4 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -39,7 +39,6 @@ Shaders::Shaders() m_callbacks[ES_WATER] = new WaterShaderProvider(); m_callbacks[ES_GRASS] = new GrassShaderProvider(); m_callbacks[ES_BUBBLES] = new BubbleEffectProvider(); - m_callbacks[ES_RAIN] = new RainEffectProvider(); m_callbacks[ES_MOTIONBLUR] = new MotionBlurProvider(); m_callbacks[ES_GAUSSIAN3V] = m_callbacks[ES_GAUSSIAN3H] = new GaussianBlurProvider(); m_callbacks[ES_MIPVIZ] = new MipVizProvider(); From f2ef95a7b53bd81ee446d97d56b01b3df6353890 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 16:40:31 +0000 Subject: [PATCH 277/412] Found another instance of PassThrough Shader usage. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15049 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 3 +-- src/graphics/post_processing.hpp | 3 +++ src/graphics/render.cpp | 6 ++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 5ab2c84b1..2b062f19d 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -731,8 +731,7 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t glEnable(GL_DEPTH_TEST); } -static -void renderPassThrough(ITexture *tex) +void PostProcessing::renderPassThrough(ITexture *tex) { if (!PassThroughShader::Program) PassThroughShader::init(); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index b9a41fac4..fd90f25d6 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -84,6 +84,9 @@ public: /** Blur the in texture */ void renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); + /** Render tex. Used for blit/texture resize */ + void renderPassThrough(video::ITexture *tex); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8b4ee3453..4cfe4cab8 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -639,14 +639,12 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, minimat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; // To half - minimat.setTexture(0, m_rtts->getRTT(RTT_TMP1)); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_HALF1), false, false); - m_post_processing->drawQuad(cam, minimat); + m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_TMP1)); // To quarter - minimat.setTexture(0, m_rtts->getRTT(RTT_HALF1)); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_QUARTER1), false, false); - m_post_processing->drawQuad(cam, minimat); + m_post_processing->renderPassThrough(m_rtts->getRTT(RTT_HALF1)); // Blur it m_post_processing->renderGaussian6Blur(m_rtts->getRTT(RTT_QUARTER1), m_rtts->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); From 6f2f7c480aa73c5829a14b0483a4cd14ea6d9e0a Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 16:54:48 +0000 Subject: [PATCH 278/412] Use direct call for some gaussian3blur invokation. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15050 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 115 +++++++++++++++++++++++++++---- src/graphics/post_processing.hpp | 1 + src/graphics/render.cpp | 32 ++------- 3 files changed, 105 insertions(+), 43 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 2b062f19d..588bbe3cf 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -455,6 +455,35 @@ namespace Gaussian6HBlurShader } } +namespace Gaussian3HBlurShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_pixel; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3h.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + namespace Gaussian6VBlurShader { GLuint Program = 0; @@ -484,6 +513,35 @@ namespace Gaussian6VBlurShader } } +namespace Gaussian3VBlurShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_pixel; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3v.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + namespace PassThroughShader { GLuint Program = 0; @@ -691,6 +749,47 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT glDisable(GL_BLEND); } + +void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height) +{ + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + { + if (!Gaussian3VBlurShader::Program) + Gaussian3VBlurShader::init(); + irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false); + glUseProgram(Gaussian3VBlurShader::Program); + glBindVertexArray(Gaussian3VBlurShader::vao); + + glUniform2f(Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glUniform1i(Gaussian3VBlurShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + { + if (!Gaussian3HBlurShader::Program) + Gaussian3HBlurShader::init(); + irr_driver->getVideoDriver()->setRenderTarget(in, false, false); + glUseProgram(Gaussian3HBlurShader::Program); + glBindVertexArray(Gaussian3HBlurShader::vao); + + glUniform2f(Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); + glUniform1i(Gaussian3HBlurShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height) { glDisable(GL_BLEND); @@ -955,21 +1054,7 @@ void PostProcessing::render() drawQuad(cam, m_material); // Blur - { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER1)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER2), true, false); - - drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER2)); - drv->setRenderTarget(irr_driver->getRTT(RTT_QUARTER1), false, false); - - drawQuad(cam, m_material); - } + renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER1), irr_driver->getRTT(RTT_QUARTER2), 4. / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); // Calculate the sun's position in texcoords const core::vector3df pos = sun->getPosition(); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index fd90f25d6..4de8c2e9f 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -82,6 +82,7 @@ public: void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); /** Blur the in texture */ + void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); void renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); /** Render tex. Used for blit/texture resize */ diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 4cfe4cab8..154e7c342 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -755,8 +755,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_post_processing->renderPointlight(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH) , accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO SMaterial m_material; - GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver-> - getCallback(ES_GAUSSIAN3H); m_material.ZWriteEnable = false; m_material.MaterialType = irr_driver->getShader(ES_SSAO); @@ -768,19 +766,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_post_processing->drawQuad(cam, m_material); // Blur it to reduce noise. - if(UserConfigParams::m_ssao == 1) { - gacb->setResolution(UserConfigParams::m_width / 4, - UserConfigParams::m_height / 4); - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3V); - m_material.setTexture(0, irr_driver->getRTT(RTT_SSAO)); - m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_QUARTER4), true, false); - m_post_processing->drawQuad(cam, m_material); - - m_material.MaterialType = irr_driver->getShader(ES_GAUSSIAN3H); - m_material.setTexture(0, irr_driver->getRTT(RTT_QUARTER4)); - m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), false, false); - m_post_processing->drawQuad(cam, m_material); - } else if (UserConfigParams::m_ssao == 2) + if(UserConfigParams::m_ssao == 1) + m_post_processing->renderGaussian3Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_QUARTER4), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); + else if (UserConfigParams::m_ssao == 2) m_post_processing->renderGaussian6Blur(irr_driver->getRTT(RTT_SSAO), irr_driver->getRTT(RTT_TMP4), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); @@ -837,19 +825,7 @@ void IrrDriver::renderDisplacement(video::SOverrideMaterial &overridemat, minimat.TextureLayer[0].TextureWrapU = minimat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; - ((GaussianBlurProvider *) m_shaders->m_callbacks[ES_GAUSSIAN3H])->setResolution( - UserConfigParams::m_width, - UserConfigParams::m_height); - - minimat.MaterialType = m_shaders->getShader(ES_GAUSSIAN3H); - minimat.setTexture(0, m_rtts->getRTT(RTT_DISPLACE)); - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_TMP2), true, false); - m_post_processing->drawQuad(cam, minimat); - - minimat.MaterialType = m_shaders->getShader(ES_GAUSSIAN3V); - minimat.setTexture(0, m_rtts->getRTT(RTT_TMP2)); - m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_DISPLACE), true, false); - m_post_processing->drawQuad(cam, minimat); + m_post_processing->renderGaussian3Blur(m_rtts->getRTT(RTT_DISPLACE), m_rtts->getRTT(RTT_TMP2), 1.f / UserConfigParams::m_width, 1.f / UserConfigParams::m_height); glDisable(GL_STENCIL_TEST); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); From badb01c68bb412db77399dbe6b1cf4d29efd1326 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 17:30:25 +0000 Subject: [PATCH 279/412] Use custom gl calls for fog. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15051 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 109 ++++++++++++++++++++++++------- src/graphics/post_processing.hpp | 5 +- src/graphics/render.cpp | 5 +- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 588bbe3cf..d3cac48cd 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -199,30 +199,6 @@ void PostProcessing::update(float dt) } } // update -// ---------------------------------------------------------------------------- -/** Render the post-processed scene, solids only, color to color, no stencil */ -void PostProcessing::renderSolid(const u32 cam) -{ - if (!irr_driver->isGLSL()) return; - - IVideoDriver * const drv = irr_driver->getVideoDriver(); - if (World::getWorld()->getTrack()->isFogEnabled()) - { - m_material.MaterialType = irr_driver->getShader(ES_FOG); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - - // Overlay - m_material.BlendOperation = EBO_ADD; - m_material.MaterialTypeParam = pack_textureBlendFunc(EBF_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); - - drv->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - drawQuad(cam, m_material); - - m_material.BlendOperation = EBO_NONE; - m_material.MaterialTypeParam = 0; - } -} - GLuint quad_vbo = 0; static void initQuadVBO() @@ -570,6 +546,42 @@ namespace PassThroughShader } } +namespace FogShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_campos, uniform_ipvmat; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/fog.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_fogmax = glGetUniformLocation(Program, "fogmax"); + uniform_startH = glGetUniformLocation(Program, "startH"); + uniform_endH = glGetUniformLocation(Program, "endH"); + uniform_start = glGetUniformLocation(Program, "start"); + uniform_end = glGetUniformLocation(Program, "end"); + uniform_col = glGetUniformLocation(Program, "col"); + uniform_campos = glGetUniformLocation(Program, "campos"); + uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + } +} + static void renderBloom(ITexture *in) @@ -851,6 +863,55 @@ void PostProcessing::renderPassThrough(ITexture *tex) glDisable(GL_BLEND); } +// ---------------------------------------------------------------------------- +/** Render the post-processed scene, solids only, color to color, no stencil */ +void PostProcessing::renderFog(const core::vector3df &campos, const core::matrix4 &ipvmat) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + const Track * const track = World::getWorld()->getTrack(); + + // This function is only called once per frame - thus no need for setters. + const float fogmax = track->getFogMax(); + const float startH = track->getFogStartHeight(); + const float endH = track->getFogEndHeight(); + const float start = track->getFogStart(); + const float end = track->getFogEnd(); + const SColor tmpcol = track->getFogColor(); + + const float col[3] = { tmpcol.getRed() / 255.0f, + tmpcol.getGreen() / 255.0f, + tmpcol.getBlue() / 255.0f }; + + if (!FogShader::Program) + FogShader::init(); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glUseProgram(FogShader::Program); + glBindVertexArray(FogShader::vao); + + glUniform1f(FogShader::uniform_fogmax, fogmax); + glUniform1f(FogShader::uniform_startH, startH); + glUniform1f(FogShader::uniform_endH, endH); + glUniform1f(FogShader::uniform_start, start); + glUniform1f(FogShader::uniform_end, end); + glUniform3f(FogShader::uniform_col, col[0], col[1], col[2]); + glUniform3f(FogShader::uniform_campos, campos.X, campos.Y, campos.Z); + glUniformMatrix4fv(FogShader::uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer()); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName()); + glUniform1i(FogShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + // ---------------------------------------------------------------------------- /** Render the post-processed scene */ void PostProcessing::render() diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 4de8c2e9f..c64d2ef2f 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -72,15 +72,14 @@ public: void begin(); void update(float dt); - /** Render the post-processed scene, solids only, color to color, no stencil */ - void renderSolid(const u32 cam); - /** Generate diffuse and specular map */ void renderPointlight(video::ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy); /** Blend all light related map */ void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); + void renderFog(const core::vector3df &campos, const core::matrix4 &ipvmat); + /** Blur the in texture */ void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); void renderGaussian6Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 154e7c342..805911c69 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -255,8 +255,9 @@ void IrrDriver::renderGLSL(float dt) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } - // Render the post-processed scene for solids - m_post_processing->renderSolid(cam); + // Render fog on top of solid + if (World::getWorld()->getTrack()->isFogEnabled()) + m_post_processing->renderFog(camnode->getAbsolutePosition(), irr_driver->getInvProjViewMatrix()); // We need to re-render camera due to the per-cam-node hack. m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT | From 959ad054dec437ae7d545d645504d4ec9e0dae6b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 17:37:33 +0000 Subject: [PATCH 280/412] Clean Fog provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15052 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 30 +----------------------------- src/graphics/callbacks.hpp | 28 ---------------------------- src/graphics/render.cpp | 4 ---- src/graphics/shaders.cpp | 4 ---- src/graphics/shaders.hpp | 1 - 5 files changed, 1 insertion(+), 66 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 756325efa..16166193c 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -717,32 +717,4 @@ void DisplaceProvider::OnSetConstants(IMaterialRendererServices *srv, int) srv->setVertexShaderConstant("dir2", m_dir2, 2); srv->setVertexShaderConstant("screen", m_screen, 2); -} - -//------------------------------------- - -void FogProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - const Track * const track = World::getWorld()->getTrack(); - - // This function is only called once per frame - thus no need for setters. - const float fogmax = track->getFogMax(); - const float startH = track->getFogStartHeight(); - const float endH = track->getFogEndHeight(); - const float start = track->getFogStart(); - const float end = track->getFogEnd(); - const SColor tmpcol = track->getFogColor(); - - const float col[3] = { tmpcol.getRed() / 255.0f, - tmpcol.getGreen() / 255.0f, - tmpcol.getBlue() / 255.0f }; - - srv->setPixelShaderConstant("fogmax", &fogmax, 1); - srv->setPixelShaderConstant("startH", &startH, 1); - srv->setPixelShaderConstant("endH", &endH, 1); - srv->setPixelShaderConstant("start", &start, 1); - srv->setPixelShaderConstant("end", &end, 1); - srv->setPixelShaderConstant("col", col, 3); - srv->setVertexShaderConstant("ipvmat", m_invprojview.pointer(), 16); - srv->setVertexShaderConstant("campos", m_campos, 3); -} +} \ No newline at end of file diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 7a6441b96..e0369e823 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -608,32 +608,4 @@ private: float m_dir[2], m_dir2[2]; }; -// - -class FogProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - void updateIPVMatrix() - { - // Update the campos and IPV matrix, only once per frame since it's costly - const core::vector3df &campos = - irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); - m_campos[0] = campos.X; - m_campos[1] = campos.Y; - m_campos[2] = campos.Z; - - const video::IVideoDriver * const drv = irr_driver->getVideoDriver(); - - m_invprojview = drv->getTransform(video::ETS_PROJECTION); - m_invprojview *= drv->getTransform(video::ETS_VIEW); - m_invprojview.makeInverse(); - } - -private: - core::matrix4 m_invprojview; - float m_campos[3]; -}; - #endif diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 805911c69..f38317344 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -674,10 +674,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, video::SColor(0, 0, 0, 0)); m_scene_manager->drawAll(scene::ESNRP_CAMERA); - FogProvider * const fogcb = (FogProvider *) irr_driver-> - getCallback(ES_FOG); - fogcb->updateIPVMatrix(); - const u32 lightcount = m_lights.size(); const core::vector3df &campos = diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 121d163f4..075faf758 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -59,7 +59,6 @@ Shaders::Shaders() m_callbacks[ES_SHADOWGEN] = new ShadowGenProvider(); m_callbacks[ES_CAUSTICS] = new CausticsProvider(); m_callbacks[ES_DISPLACE] = new DisplaceProvider(); - m_callbacks[ES_FOG] = new FogProvider(); for(s32 i=0 ; i < ES_COUNT ; i++) m_shaders[i] = -1; @@ -197,9 +196,6 @@ void Shaders::loadShaders() m_shaders[ES_PASSFAR] = glsl(dir + "farplane.vert", dir + "colorize.frag", m_callbacks[ES_COLORIZE]); - m_shaders[ES_FOG] = glslmat(dir + "pass.vert", dir + "fog.frag", - m_callbacks[ES_FOG], EMT_ONETEXTURE_BLEND); - // Check that all successfully loaded for (s32 i = 0; i < ES_COUNT; i++) { diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 03a5500b4..8d68bfbf2 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -67,7 +67,6 @@ using namespace irr; ACT(ES_CAUSTICS) \ ACT(ES_DISPLACE) \ ACT(ES_PASSFAR) \ - ACT(ES_FOG) #define ENUM(a) a, #define STR(a) #a, From e2a6ce78893cf564e18c77eb3c56f4d2849a9a2b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 17:41:19 +0000 Subject: [PATCH 281/412] Remove an unneeded drawAll. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15053 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/render.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index f38317344..0e3eb9354 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -673,8 +673,6 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_video_driver->setRenderTarget(rtts, true, false, video::SColor(0, 0, 0, 0)); - m_scene_manager->drawAll(scene::ESNRP_CAMERA); - const u32 lightcount = m_lights.size(); const core::vector3df &campos = irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); From d84bc88d4743eecb308ed9ba7a3397593238eddb Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 17:56:05 +0000 Subject: [PATCH 282/412] SSAO: Use direct gl calls. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15054 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/post_processing.cpp | 80 +++++++++++++++++++++++++++++++- src/graphics/post_processing.hpp | 1 + src/graphics/render.cpp | 8 +--- 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index d3cac48cd..72f3c88ad 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -546,6 +546,59 @@ namespace PassThroughShader } } +namespace SSAOShader +{ + GLuint Program = 0; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_normals_and_depth, uniform_invprojm, uniform_projm, uniform_samplePoints; + float SSAOSamples[64]; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ssao.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_normals_and_depth = glGetUniformLocation(Program, "normals_and_depth"); + uniform_invprojm = glGetUniformLocation(Program, "invprojm"); + uniform_projm = glGetUniformLocation(Program, "projm"); + uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); + if (!quad_vbo) + initQuadVBO(); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + + for (unsigned i = 0; i < 16; i++) { + // Generate x/y component between -1 and 1 + // Use double to avoid denorm and get a true uniform distribution + double x = rand(); + x /= RAND_MAX; + x = 2 * x - 1; + double y = rand(); + y /= RAND_MAX; + y = 2 * y - 1; + + // compute z so that norm (x,y,z) is one + double z = sqrt(x * x + y * y); + // Norm factor + double w = rand(); + w /= RAND_MAX; + SSAOSamples[4 * i] = (float)x; + SSAOSamples[4 * i + 1] = (float)y; + SSAOSamples[4 * i + 2] = (float)z; + SSAOSamples[4 * i + 3] = (float)w; + } + } +} + namespace FogShader { GLuint Program = 0; @@ -863,8 +916,31 @@ void PostProcessing::renderPassThrough(ITexture *tex) glDisable(GL_BLEND); } -// ---------------------------------------------------------------------------- -/** Render the post-processed scene, solids only, color to color, no stencil */ + +void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm) +{ + if (!SSAOShader::Program) + SSAOShader::init(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + glUseProgram(SSAOShader::Program); + glBindVertexArray(SSAOShader::vao); + glUniformMatrix4fv(SSAOShader::uniform_invprojm, 1, GL_FALSE, invprojm.pointer()); + glUniformMatrix4fv(SSAOShader::uniform_projm, 1, GL_FALSE, projm.pointer()); + glUniform4fv(SSAOShader::uniform_samplePoints, 16, SSAOShader::SSAOSamples); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName()); + glUniform1i(SSAOShader::uniform_normals_and_depth, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); +} + void PostProcessing::renderFog(const core::vector3df &campos, const core::matrix4 &ipvmat) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index c64d2ef2f..7bcc8cb6d 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -79,6 +79,7 @@ public: void renderLightbBlend(video::ITexture *diffuse, video::ITexture *specular, video::ITexture *ao, video::ITexture *specmap, bool debug); void renderFog(const core::vector3df &campos, const core::matrix4 &ipvmat); + void renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm); /** Blur the in texture */ void renderGaussian3Blur(video::ITexture *in, video::ITexture *temprtt, float inv_width, float inv_height); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 0e3eb9354..8793085f5 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -749,16 +749,10 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, } m_post_processing->renderPointlight(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH) , accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); // Handle SSAO - SMaterial m_material; - - m_material.ZWriteEnable = false; - m_material.MaterialType = irr_driver->getShader(ES_SSAO); - m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); - m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, SColor(255, 255, 255, 255)); - m_post_processing->drawQuad(cam, m_material); + m_post_processing->renderSSAO(irr_driver->getInvProjMatrix(), irr_driver->getProjMatrix()); // Blur it to reduce noise. if(UserConfigParams::m_ssao == 1) From e23d9c23e93dea19f13cc00d7ca9aba137815093 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 18:02:39 +0000 Subject: [PATCH 283/412] Clean SSAO Provider. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15055 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/callbacks.cpp | 20 -------------------- src/graphics/callbacks.hpp | 33 --------------------------------- src/graphics/shaders.cpp | 3 --- src/graphics/shaders.hpp | 1 - 4 files changed, 57 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 16166193c..0943cbfb9 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -496,26 +496,6 @@ void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - srv->setPixelShaderConstant("invprojm", irr_driver->getInvProjMatrix().pointer(), 16); - srv->setPixelShaderConstant("projm", irr_driver->getProjMatrix().pointer(), 16); - srv->setPixelShaderConstant("samplePoints[0]", array, 64); - - if (!firstdone) - { - int tex = 0; - srv->setPixelShaderConstant("normals_and_depth", &tex, 1); - - tex = 1; - srv->setPixelShaderConstant("depth", &tex, 1); - - firstdone = true; - } -} - -//------------------------------------- - void GodRayProvider::OnSetConstants(IMaterialRendererServices *srv, int) { srv->setPixelShaderConstant("sunpos", m_sunpos, 2); diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index e0369e823..38412930a 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -422,39 +422,6 @@ public: // -class SSAOProvider: public CallBase -{ -private: - float array[64]; -public: - SSAOProvider() : CallBase() { - for (unsigned i = 0; i < 16; i++) { - // Generate x/y component between -1 and 1 - // Use double to avoid denorm and get a true uniform distribution - double x = rand(); - x /= RAND_MAX; - x = 2 * x - 1; - double y = rand(); - y /= RAND_MAX; - y = 2 * y - 1; - - // compute z so that norm (x,y,z) is one - double z = sqrt(x * x + y * y); - // Norm factor - double w = rand(); - w /= RAND_MAX; - array[4 * i] = (float)x; - array[4 * i + 1] = (float)y; - array[4 * i + 2] = (float)z; - array[4 * i + 3] = (float)w; - } - } - - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class GodRayProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 075faf758..46935d8e1 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -49,7 +49,6 @@ Shaders::Shaders() m_callbacks[ES_MLAA_COLOR1] = new MLAAColor1Provider(); m_callbacks[ES_MLAA_BLEND2] = new MLAABlend2Provider(); m_callbacks[ES_MLAA_NEIGH3] = new MLAANeigh3Provider(); - m_callbacks[ES_SSAO] = new SSAOProvider(); m_callbacks[ES_GODRAY] = new GodRayProvider(); m_callbacks[ES_SHADOWPASS] = new ShadowPassProvider(); m_callbacks[ES_SHADOW_IMPORTANCE] = new ShadowImportanceProvider(); @@ -155,8 +154,6 @@ void Shaders::loadShaders() m_shaders[ES_MLAA_NEIGH3] = glsl(dir + "mlaa_offset.vert", dir + "mlaa_neigh3.frag", m_callbacks[ES_MLAA_NEIGH3]); - m_shaders[ES_SSAO] = glsl(dir + "pass.vert", dir + "ssao.frag", m_callbacks[ES_SSAO]); - m_shaders[ES_GODFADE] = glsl(std::string(""), dir + "godfade.frag", m_callbacks[ES_COLORIZE]); m_shaders[ES_GODRAY] = glsl(std::string(""), dir + "godray.frag", m_callbacks[ES_GODRAY]); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 8d68bfbf2..82dbffb8e 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -51,7 +51,6 @@ using namespace irr; ACT(ES_MLAA_COLOR1) \ ACT(ES_MLAA_BLEND2) \ ACT(ES_MLAA_NEIGH3) \ - ACT(ES_SSAO) \ ACT(ES_GODFADE) \ ACT(ES_GODRAY) \ ACT(ES_SHADOWPASS) \ From 6f680c1a8e2b550defd3cf5cf33269c91821083f Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 18:18:40 +0000 Subject: [PATCH 284/412] OGL32CTX: Use our draw2DImage for scalable_font. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15056 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/scalable_font.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index 0af6645a2..37a5db03f 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -13,6 +13,7 @@ #include "guiengine/engine.hpp" #include "io/file_manager.hpp" #include "utils/translation.hpp" +#include "graphics/glwrap.hpp" namespace irr { @@ -650,7 +651,7 @@ void ScalableFont::draw(const core::stringw& text, for (int y_delta=-2; y_delta<=2; y_delta++) { if (x_delta == 0 || y_delta == 0) continue; - driver->draw2DImage(texture, + draw2DImage(texture, dest + core::position2d(x_delta, y_delta), source, clip, @@ -665,7 +666,7 @@ void ScalableFont::draw(const core::stringw& text, static video::SColor orange(color.getAlpha(), 255, 100, 0); static video::SColor yellow(color.getAlpha(), 255, 220, 15); video::SColor title_colors[] = {yellow, orange, orange, yellow}; - driver->draw2DImage(texture, + draw2DImage(texture, dest, source, clip, From a16402e67610f71bb53b1d2dfd7d4d1dbcbe7b55 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 18:22:47 +0000 Subject: [PATCH 285/412] OGL32CTX: Missed a draw2DImage call git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15057 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/scalable_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index 37a5db03f..24aa6a635 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -674,7 +674,7 @@ void ScalableFont::draw(const core::stringw& text, } else { - driver->draw2DImage(texture, + draw2DImage(texture, dest, source, clip, From df62ac5949f56ba2f66a3e470feea97dcd3b1cb7 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 18:31:47 +0000 Subject: [PATCH 286/412] OGL32CTX: Render gui using shaders. Font is temporarily white. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15058 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index b7999f8ff..5a5f487ad 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -290,9 +290,11 @@ 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) { -#ifndef OGL32CTX - irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); -#else + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DImage(texture, destRect, sourceRect, clipRect, colors, useAlphaChannelOfTexture); + return; + } core::dimension2d frame_size = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); @@ -371,7 +373,6 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glDisableVertexAttribArray(TexturedQuadAttribPosition); glDisableVertexAttribArray(TexturedQuadAttribTexCoord); glBindBuffer(GL_ARRAY_BUFFER, 0); -#endif } static GLuint ColoredQuadShader; @@ -383,9 +384,12 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, const core::rect* clip) { -#ifndef OGL32CTX - irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); -#else + if (!irr_driver->isGLSL()) + { + irr_driver->getVideoDriver()->draw2DRectangle(color, position, clip); + return; + } + core::dimension2d frame_size = irr_driver->getVideoDriver()->getCurrentRenderTargetSize(); const int screen_w = frame_size.Width; @@ -430,5 +434,4 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); -#endif } From c88d89a4f051aef463b768907ca8782e0bacec3d Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 18:59:59 +0000 Subject: [PATCH 287/412] SSAO: Some tweaks. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15059 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 36365d1ac..ee3ed0551 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -15,10 +15,6 @@ const float invSamples = strengh / SAMPLES; void main(void) { - // A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4 - // Again not using const because of broken Intel Windows drivers - - vec4 cur = texture2D(normals_and_depth, uv); float curdepth = texture2D(normals_and_depth, uv).a; vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); @@ -40,8 +36,6 @@ void main(void) vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0); vec4 sampleProj = projm * samplePos; sampleProj /= sampleProj.w; - // Projection of sampleDir over nom - float cosTheta = samplePoints[i].z; bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); // get the depth of the occluder fragment @@ -51,11 +45,11 @@ void main(void) occluderPos /= occluderPos.w; bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); - bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) * cosTheta : 0.; + bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) / smoothstep(0., 1., curdepth) : 0.; } // output the result float ao = 1.0 - bl * invSamples; - gl_FragColor = vec4(vec3(ao), curdepth + 0.05); // offset so that the alpha test doesn't kill us + gl_FragColor = vec4(ao); } From 43a206ff2c1466c4f5c6177d7df48322f1ca2dc4 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 22:16:04 +0000 Subject: [PATCH 288/412] Characters are now black again. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15060 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/colortexturedquad.frag | 10 ++ data/shaders/colortexturedquad.vert | 18 ++++ src/graphics/glwrap.cpp | 137 ++++++++++++++++++++++------ 3 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 data/shaders/colortexturedquad.frag create mode 100644 data/shaders/colortexturedquad.vert diff --git a/data/shaders/colortexturedquad.frag b/data/shaders/colortexturedquad.frag new file mode 100644 index 000000000..811ab9d3c --- /dev/null +++ b/data/shaders/colortexturedquad.frag @@ -0,0 +1,10 @@ +#version 130 +uniform sampler2D texture; + +in vec2 uv; +in vec4 col; + +void main() +{ + gl_FragColor = texture2D(texture, uv) * col; +} diff --git a/data/shaders/colortexturedquad.vert b/data/shaders/colortexturedquad.vert new file mode 100644 index 000000000..9b567da79 --- /dev/null +++ b/data/shaders/colortexturedquad.vert @@ -0,0 +1,18 @@ +#version 130 +uniform vec2 center; +uniform vec2 size; +uniform vec2 texcenter; +uniform vec2 texsize; + +in vec2 position; +in vec2 texcoord; +in ivec4 color; +out vec2 uv; +out vec4 col; + +void main() +{ + col = vec4(color) / 255.; + uv = texcoord * texsize + texcenter; + gl_Position = vec4(position * size + center, 0., 1.); +} diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 5a5f487ad..0368dcf15 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -53,6 +53,7 @@ PFNGLTEXBUFFERPROC glTexBuffer; #endif static GLuint quad_buffer; +static GLuint ColoredVertex; static bool is_gl_init = false; // Please leave this code, it's for debugging purpose @@ -186,6 +187,17 @@ void initGL() glGenBuffers(1, &quad_buffer); glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + + const int quad_color[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }; + glGenBuffers(1, &ColoredVertex); + glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(int), quad_color, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -286,6 +298,97 @@ static GLuint TexturedQuadUniformSize; static GLuint TexturedQuadUniformTexcenter; static GLuint TexturedQuadUniformTexsize; +static GLuint ColorTexturedQuadShader; +static GLuint ColorTexturedQuadAttribPosition; +static GLuint ColorTexturedQuadAttribTexCoord; +static GLuint ColorTexturedQuadAttribColor; +static GLuint ColorTexturedQuadUniformTexture; +static GLuint ColorTexturedQuadUniformCenter; +static GLuint ColorTexturedQuadUniformSize; +static GLuint ColorTexturedQuadUniformTexcenter; +static GLuint ColorTexturedQuadUniformTexsize; + +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) +{ + int colors[] = { + col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), + col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), + col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), + col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), + }; + if (!ColorTexturedQuadShader) { + ColorTexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/colortexturedquad.vert").c_str(), file_manager->getAsset("shaders/colortexturedquad.frag").c_str()); + + ColorTexturedQuadAttribPosition = glGetAttribLocation(ColorTexturedQuadShader, "position"); + ColorTexturedQuadAttribTexCoord = glGetAttribLocation(ColorTexturedQuadShader, "texcoord"); + ColorTexturedQuadAttribColor = glGetAttribLocation(ColorTexturedQuadShader, "color"); + ColorTexturedQuadUniformTexture = glGetUniformLocation(ColorTexturedQuadShader, "texture"); + ColorTexturedQuadUniformCenter = glGetUniformLocation(ColorTexturedQuadShader, "center"); + ColorTexturedQuadUniformSize = glGetUniformLocation(ColorTexturedQuadShader, "size"); + ColorTexturedQuadUniformTexcenter = glGetUniformLocation(ColorTexturedQuadShader, "texcenter"); + ColorTexturedQuadUniformTexsize = glGetUniformLocation(ColorTexturedQuadShader, "texsize"); + } + glUseProgram(ColorTexturedQuadShader); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); + glUniform1i(ColorTexturedQuadUniformTexture, 0); + glUniform2f(ColorTexturedQuadUniformCenter, center_pos_x, center_pos_y); + glUniform2f(ColorTexturedQuadUniformSize, width, height); + glUniform2f(ColorTexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); + glUniform2f(ColorTexturedQuadUniformTexsize, tex_width, tex_height); + glEnableVertexAttribArray(ColorTexturedQuadAttribPosition); + glEnableVertexAttribArray(ColorTexturedQuadAttribTexCoord); + glEnableVertexAttribArray(ColorTexturedQuadAttribColor); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(ColorTexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(ColorTexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); + glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(int), colors); + glVertexAttribPointer(ColorTexturedQuadAttribColor, 4, GL_UNSIGNED_INT, GL_FALSE, 4 * sizeof(float), 0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(ColorTexturedQuadAttribPosition); + glDisableVertexAttribArray(ColorTexturedQuadAttribTexCoord); + glDisableVertexAttribArray(ColorTexturedQuadAttribColor); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void drawTexQuad(const video::ITexture *texture, 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) +{ + if (!TexturedQuadShader) { + TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); + + TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); + TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); + TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); + TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); + TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); + TexturedQuadUniformTexcenter = glGetUniformLocation(TexturedQuadShader, "texcenter"); + TexturedQuadUniformTexsize = glGetUniformLocation(TexturedQuadShader, "texsize"); + } + glUseProgram(TexturedQuadShader); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); + glUniform1i(TexturedQuadUniformTexture, 0); + glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); + glUniform2f(TexturedQuadUniformSize, width, height); + glUniform2f(TexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); + glUniform2f(TexturedQuadUniformTexsize, tex_width, tex_height); + glEnableVertexAttribArray(TexturedQuadAttribPosition); + glEnableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(TexturedQuadAttribPosition); + glDisableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, 0); + +} + 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) @@ -345,34 +448,12 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); } - if (!TexturedQuadShader) { - TexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/texturedquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); - - TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); - TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); - TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); - TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); - TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); - TexturedQuadUniformTexcenter = glGetUniformLocation(TexturedQuadShader, "texcenter"); - TexturedQuadUniformTexsize = glGetUniformLocation(TexturedQuadShader, "texsize"); - } - glUseProgram(TexturedQuadShader); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); - glUniform1i(TexturedQuadUniformTexture, 0); - glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); - glUniform2f(TexturedQuadUniformSize, width, height); - glUniform2f(TexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); - glUniform2f(TexturedQuadUniformTexsize, tex_width, tex_height); - glEnableVertexAttribArray(TexturedQuadAttribPosition); - glEnableVertexAttribArray(TexturedQuadAttribTexCoord); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(TexturedQuadAttribPosition); - glDisableVertexAttribArray(TexturedQuadAttribTexCoord); - glBindBuffer(GL_ARRAY_BUFFER, 0); + if (colors) + drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); + else + drawTexQuad(texture, width, height, center_pos_x, center_pos_y, + tex_center_pos_x, tex_center_pos_y, tex_width, tex_height); } static GLuint ColoredQuadShader; From 35f37a62c295b1eacff7b77f4dcab110b56c9e2e Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 22:28:10 +0000 Subject: [PATCH 289/412] Font looks better now. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15061 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/colortexturedquad.frag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/shaders/colortexturedquad.frag b/data/shaders/colortexturedquad.frag index 811ab9d3c..19f1559c3 100644 --- a/data/shaders/colortexturedquad.frag +++ b/data/shaders/colortexturedquad.frag @@ -6,5 +6,6 @@ in vec4 col; void main() { - gl_FragColor = texture2D(texture, uv) * col; + vec4 res = texture2D(texture, uv); + gl_FragColor = vec4(res.xyz * col.xyz, res.a); } From a60f54976070c6f80e2f0918379da5fee8f378ce Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 22:59:45 +0000 Subject: [PATCH 290/412] Fix draw2drectangle and spread use of draw2Dimage git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15062 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 ++ src/graphics/irr_driver.cpp | 6 +++--- src/states_screens/race_gui.cpp | 16 ++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 0368dcf15..59f3edc8a 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -504,6 +504,8 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, { ColoredQuadShader = LoadProgram(file_manager->getAsset("shaders/coloredquad.vert").c_str(), file_manager->getAsset("shaders/coloredquad.frag").c_str()); ColoredQuadUniformColor = glGetUniformLocation(ColoredQuadShader, "color"); + ColoredQuadUniformCenter = glGetUniformLocation(ColoredQuadShader, "center"); + ColoredQuadUniformSize = glGetUniformLocation(ColoredQuadShader, "size"); } glUseProgram(ColoredQuadShader); glUniform2f(ColoredQuadUniformCenter, center_pos_x, center_pos_y); diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index de3600af1..9b997c9ab 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -619,7 +619,7 @@ void IrrDriver::applyResolutionSettings() // show black before resolution switch so we don't see OpenGL's buffer // garbage during switch m_video_driver->beginScene(true, true, video::SColor(255,100,101,140)); - m_video_driver->draw2DRectangle( video::SColor(255, 0, 0, 0), + GL32_draw2DRectangle( video::SColor(255, 0, 0, 0), core::rect(0, 0, UserConfigParams::m_prev_width, UserConfigParams::m_prev_height) ); @@ -1409,11 +1409,11 @@ void IrrDriver::displayFPS() if(UserConfigParams::m_artist_debug_mode) { - irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,1100,50),NULL); + GL32_draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,1100,50),NULL); } else { - irr_driver->getVideoDriver()->draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,50),NULL); + GL32_draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,50),NULL); } // We will let pass some time to let things settle before trusting FPS counter // even if we also ignore fps = 1, which tends to happen in first checks diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 2dc632b45..34f2cd3ae 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -26,6 +26,7 @@ using namespace irr; #include "challenges/unlock_manager.hpp" #include "config/user_config.hpp" #include "graphics/camera.hpp" +#include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" @@ -145,8 +146,7 @@ void RaceGUI::renderGlobal(float dt) !GUIEngine::ModalDialog::isADialogActive()) { static video::SColor black = video::SColor(255,0,0,0); - irr_driver->getVideoDriver() - ->draw2DRectangle(black, + GL32_draw2DRectangle(black, core::rect(UserConfigParams::m_width/2, UserConfigParams::m_height/2, UserConfigParams::m_width, @@ -240,7 +240,7 @@ void RaceGUI::drawScores() (j+1)*m_marker_rendered_size,m_marker_rendered_size); core::recti position(offsetX, offsetY, offsetX + 2*m_marker_player_size, offsetY + 2*m_marker_player_size); - irr_driver->getVideoDriver()->draw2DImage(m_marker, position, source, + draw2DImage(m_marker, position, source, NULL, NULL, true); core::stringw score = StringUtils::toWString(soccerWorld->getScore(i)); int string_height = @@ -263,7 +263,7 @@ void RaceGUI::drawScores() offsetY + (int)(m_marker_player_size/1.25f)); core::rect sourceRect(core::position2d(0,0), team_icon->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(team_icon,indicatorPos,sourceRect, + draw2DImage(team_icon,indicatorPos,sourceRect, NULL,NULL,true); numLeader++; offsetX += position.LowerRightCorner.X; @@ -344,7 +344,7 @@ void RaceGUI::drawGlobalMiniMap() m_map_left + m_map_width, lower_y); core::rect source(core::position2di(0, 0), mini_map->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(mini_map, dest, source, + draw2DImage(mini_map, dest, source, NULL, NULL, true); } @@ -367,7 +367,7 @@ void RaceGUI::drawGlobalMiniMap() lower_y -(int)(draw_at.getY()+marker_half_size), m_map_left+(int)(draw_at.getX()+marker_half_size), lower_y -(int)(draw_at.getY()-marker_half_size)); - irr_driver->getVideoDriver()->draw2DImage(m_marker, position, source, + draw2DImage(m_marker, position, source, NULL, NULL, true); } // for igetVideoDriver()->draw2DImage(m_gauge_empty, + draw2DImage(m_gauge_empty, core::rect((int)offset.X, (int) offset.Y-gauge_height, (int) offset.X + gauge_width, @@ -615,7 +615,7 @@ void RaceGUI::drawSpeedAndEnergy(const AbstractKart* kart, video::ITexture *meter_texture = m_speed_meter_icon->getTexture(); const core::rect meter_texture_coords(core::position2d(0,0), meter_texture->getOriginalSize()); - video->draw2DImage(meter_texture, meter_pos, meter_texture_coords, NULL, + draw2DImage(meter_texture, meter_pos, meter_texture_coords, NULL, NULL, true); const float speed = kart->getSpeed(); From c283f82729fb9cdb0578d533d544796bdca8ef47 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 23:07:29 +0000 Subject: [PATCH 291/412] Use draw2DImage for other components in race gui git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15063 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/states_screens/race_gui_base.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/states_screens/race_gui_base.cpp b/src/states_screens/race_gui_base.cpp index 7a085f2f9..04a7d9702 100644 --- a/src/states_screens/race_gui_base.cpp +++ b/src/states_screens/race_gui_base.cpp @@ -219,7 +219,7 @@ void RaceGUIBase::createMarkerTexture() (i+1)*m_marker_rendered_size, m_marker_rendered_size); core::recti source_rect(core::vector2di(0,0), t->getSize()); - irr_driver->getVideoDriver()->draw2DImage(t, dest_rect, + draw2DImage(t, dest_rect, source_rect, /*clipRect*/0, /*color*/ 0, @@ -412,7 +412,7 @@ void RaceGUIBase::drawPowerupIcons(const AbstractKart* kart, { int x2 = (int)(x1+i*itemSpacing); core::rect pos(x2, y1, x2+nSize, y1+nSize); - irr_driver->getVideoDriver()->draw2DImage(t, pos, rect, NULL, + draw2DImage(t, pos, rect, NULL, NULL, true); } // for i } // drawPowerupIcons @@ -669,7 +669,7 @@ void RaceGUIBase::drawGlobalMusicDescription() const core::rect source(core::position2d(0,0), t->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(t, dest, source, + draw2DImage(t, dest, source, NULL, NULL, true); } // drawGlobalMusicDescription @@ -936,7 +936,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) } const core::rect rect(core::position2d(0,0), m_icons_frame->getTexture()->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage( + draw2DImage( m_icons_frame->getTexture(), pos, rect,NULL, colors, true); } @@ -945,7 +945,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) { const core::rect rect(core::position2d(0,0), icon->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(icon, pos, rect, + draw2DImage(icon, pos, rect, NULL, NULL, true); } @@ -960,7 +960,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) icon->getOriginalSize()); const core::rect pos1((int)(x-t_anim), y, (int)(x+w-t_anim), y+w); - irr_driver->getVideoDriver()->draw2DImage(icon, pos1, rect1, + draw2DImage(icon, pos1, rect1, NULL, NULL, true); } @@ -971,7 +971,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) core::position2d(x+w,y+w*3/4)); const core::rect sourceRect(core::position2d(0,0), icon->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(icon, destRect, + draw2DImage(icon, destRect, sourceRect, NULL, NULL, true); } @@ -989,7 +989,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) const core::rect pos1((int)(x-t_anim), (int)(y-t_anim), (int)(x+w/2-t_anim), (int)(y+w/2-t_anim)); - irr_driver->getVideoDriver()->draw2DImage(icon, pos1, rect1, + draw2DImage(icon, pos1, rect1, NULL, NULL, true); const core::rect rect2(icon_size_x/2,0, @@ -998,18 +998,18 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) (int)(y-t_anim), (int)(x+w+t_anim), (int)(y+w/2-t_anim)); - irr_driver->getVideoDriver()->draw2DImage(icon, pos2, rect2, + draw2DImage(icon, pos2, rect2, NULL, NULL, true); const core::rect rect3(0, icon_size_y/2, icon_size_x/2,icon_size_y); const core::rect pos3((int)(x-t_anim), (int)(y+w/2+t_anim), (int)(x+w/2-t_anim), (int)(y+w+t_anim)); - irr_driver->getVideoDriver()->draw2DImage(icon, pos3, rect3, NULL, NULL, true); + draw2DImage(icon, pos3, rect3, NULL, NULL, true); const core::rect rect4(icon_size_x/2,icon_size_y/2,icon_size_x,icon_size_y); const core::rect pos4((int)(x+w/2+t_anim), (int)(y+w/2+t_anim), (int)(x+w+t_anim), (int)(y+w+t_anim)); - irr_driver->getVideoDriver()->draw2DImage(icon, pos4, rect4, NULL, NULL, true); + draw2DImage(icon, pos4, rect4, NULL, NULL, true); } //Plunger @@ -1022,7 +1022,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) const core::rect rect(core::position2d(0,0), icon_plunger->getOriginalSize()); const core::rect pos1(x+10, y-10, x+w+10, y+w-10); - irr_driver->getVideoDriver()->draw2DImage(icon_plunger, pos1, + draw2DImage(icon_plunger, pos1, rect, NULL, NULL, true); } @@ -1038,7 +1038,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin) const core::rect rect(core::position2d(0,0), icon_attachment->getOriginalSize()); const core::rect pos1(x-20, y-10, x+w-20, y+w-10); - irr_driver->getVideoDriver()->draw2DImage(icon_attachment, + draw2DImage(icon_attachment, pos1, rect, NULL, NULL, true); } @@ -1136,7 +1136,7 @@ void RaceGUIBase::drawPlungerInFace(const Camera *camera, float dt) const core::rect source(core::position2d(0,0), t->getOriginalSize()); - irr_driver->getVideoDriver()->draw2DImage(t, dest, source, + draw2DImage(t, dest, source, &viewport /* clip */, NULL /* color */, true /* alpha */ ); From 6697a2d7afd6abb8b42b57f039745e1fd7bcf7d3 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 23:19:47 +0000 Subject: [PATCH 292/412] Another batch of conversion to draw2DImage git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15064 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/CGUISpriteBank.cpp | 3 ++- src/guiengine/engine.cpp | 2 +- src/guiengine/skin.cpp | 2 +- src/guiengine/widgets/CGUIEditBox.cpp | 3 ++- src/states_screens/race_result_gui.cpp | 13 +++++++------ 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/guiengine/CGUISpriteBank.cpp b/src/guiengine/CGUISpriteBank.cpp index 8c756453a..a80ca4409 100644 --- a/src/guiengine/CGUISpriteBank.cpp +++ b/src/guiengine/CGUISpriteBank.cpp @@ -9,6 +9,7 @@ #include "IVideoDriver.h" #include "ITexture.h" #include +#include "graphics/glwrap.hpp" namespace irr { @@ -217,7 +218,7 @@ void STKModifiedSpriteBank::draw2DSprite(u32 index, const video::SColor *const colors=0, bool useAlphaChannelOfTexture=false)=0 */ - Driver->draw2DImage(tex, dest, r /* source rect */, clip, + draw2DImage(tex, dest, r /* source rect */, clip, NULL /* colors */, true); } // draw2DSprite diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index 7c925bb32..e6b69ca59 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -1237,7 +1237,7 @@ namespace GUIEngine core::dimension2d(screen_size.Width, text_height) ); - Private::g_driver->draw2DRectangle(SColor(255,252,248,230), + GL32_draw2DRectangle(SColor(255,252,248,230), msgRect); Private::g_font->draw((*it).m_message.c_str(), msgRect, diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index d17128d39..4b80ce9f1 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -795,7 +795,7 @@ void Skin::drawProgress(Widget* w, const core::recti &rect, SkinConfig::m_render_params["progress::fill"], w->m_deactivated); #if 0 - GUIEngine::getDriver()->draw2DImage( + draw2DImage( SkinConfig::m_render_params["progress::fill"].getImage(), sized_rect, core::recti(0,0,progress->m_w, progress->m_h), 0 /* no clipping */, colors, true); diff --git a/src/guiengine/widgets/CGUIEditBox.cpp b/src/guiengine/widgets/CGUIEditBox.cpp index 5f852c194..f2688b3c2 100644 --- a/src/guiengine/widgets/CGUIEditBox.cpp +++ b/src/guiengine/widgets/CGUIEditBox.cpp @@ -12,6 +12,7 @@ //#include "os.h" #include "Keycodes.h" +#include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" #include "utils/translation.hpp" #include "utils/time.hpp" @@ -937,7 +938,7 @@ void CGUIEditBox::draw() core::rect< s32 > caret_rect = CurrentTextRect; caret_rect.UpperLeftCorner.X += charcursorpos - 1; caret_rect.LowerRightCorner.X = caret_rect.UpperLeftCorner.X + 2; - irr_driver->getVideoDriver()->draw2DRectangle( video::SColor(255,0,0,0), caret_rect ); + GL32_draw2DRectangle( video::SColor(255,0,0,0), caret_rect ); /* font->draw(L"_", CurrentTextRect, diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index a20d5444e..0a51182c8 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -21,6 +21,7 @@ #include "audio/music_manager.hpp" #include "audio/sfx_base.hpp" #include "challenges/unlock_manager.hpp" +#include "graphics/glwrap.hpp" #include "graphics/material.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" @@ -813,7 +814,7 @@ void RaceResultGUI::displayOneEntry(unsigned int x, unsigned int y, ri->m_kart_icon->getSize()); core::recti dest_rect(current_x, y, current_x+m_width_icon, y+m_width_icon); - irr_driver->getVideoDriver()->draw2DImage(ri->m_kart_icon, dest_rect, + draw2DImage(ri->m_kart_icon, dest_rect, source_rect, NULL, NULL, true); } @@ -921,12 +922,12 @@ void RaceResultGUI::displaySoccerResults() core::recti sourceRect(core::vector2di(0,0), redTeamIcon->getSize()); core::recti destRect(currX, currY, currX+redTeamIcon->getSize().Width/2, currY+redTeamIcon->getSize().Height/2); - irr_driver->getVideoDriver()->draw2DImage(redTeamIcon, destRect,sourceRect, + draw2DImage(redTeamIcon, destRect,sourceRect, NULL,NULL, true); currX += UserConfigParams::m_width/2 - redTeamIcon->getSize().Width/2; destRect = core::recti(currX, currY, currX+redTeamIcon->getSize().Width/2, currY+redTeamIcon->getSize().Height/2); - irr_driver->getVideoDriver()->draw2DImage(blueTeamIcon,destRect,sourceRect, + draw2DImage(blueTeamIcon,destRect,sourceRect, NULL, NULL, true); resultText = StringUtils::toWString(teamScore[1]); @@ -977,7 +978,7 @@ void RaceResultGUI::displaySoccerResults() sourceRect = core::recti(core::vector2di(0,0), scorerIcon->getSize()); irr::u32 offsetX = GUIEngine::getFont()->getDimension(resultText.c_str()).Width/2; destRect = core::recti(currX-offsetX-30, currY, currX-offsetX, currY+ 30); - irr_driver->getVideoDriver()->draw2DImage(scorerIcon, destRect, sourceRect, + draw2DImage(scorerIcon, destRect, sourceRect, NULL, NULL, true); } @@ -1009,7 +1010,7 @@ void RaceResultGUI::displaySoccerResults() irr::u32 offsetX = GUIEngine::getFont()->getDimension(resultText.c_str()).Width/2; destRect = core::recti(currX-offsetX-30, currY, currX-offsetX, currY+ 30); - irr_driver->getVideoDriver()->draw2DImage(scorerIcon, destRect, sourceRect, + draw2DImage(scorerIcon, destRect, sourceRect, NULL, NULL, true); } } @@ -1180,7 +1181,7 @@ void RaceResultGUI::displayHighScores() core::recti dest_rect(current_x, current_y, current_x+m_width_icon, current_y+m_width_icon); - irr_driver->getVideoDriver()->draw2DImage( + draw2DImage( kart_icon_texture, dest_rect, source_rect, NULL, NULL, true); From 492dae53585226232e4065e5eec650e624c505b1 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Mon, 13 Jan 2014 23:56:59 +0000 Subject: [PATCH 293/412] Fix windows build git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15065 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 ++ src/graphics/glwrap.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 59f3edc8a..9bdd7b7eb 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -50,6 +50,7 @@ PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; PFNGLBINDVERTEXARRAYPROC glBindVertexArray; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLTEXBUFFERPROC glTexBuffer; +PFNGLBUFFERSUBDATAPROC glBufferSubData; #endif static GLuint quad_buffer; @@ -174,6 +175,7 @@ void initGL() glTexBuffer = (PFNGLTEXBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glTexBuffer"); glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv"); glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv"); + glBufferSubData = (PFNGLBUFFERSUBDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferSubData"); #endif #ifdef ENABLE_ARB_DEBUG_OUTPUT glDebugMessageCallbackARB(debugCallback, NULL); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 126e482d0..fc208c61c 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -73,8 +73,10 @@ extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; extern PFNGLTEXBUFFERPROC glTexBuffer; +extern PFNGLBUFFERSUBDATAPROC glBufferSubData; #endif + // core::rect needs these includes #include #include "utils/vec3.hpp" From 1cdb8ec8f377563a7cf097a17f62361b57abdb35 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 00:00:21 +0000 Subject: [PATCH 294/412] OGL32CTX: Use VAO for draw2DImage, remove ALPHA_TEST as it is deprecated git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15066 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 68 +++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 9bdd7b7eb..da4374b51 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -300,6 +300,8 @@ static GLuint TexturedQuadUniformSize; static GLuint TexturedQuadUniformTexcenter; static GLuint TexturedQuadUniformTexsize; +static GLuint TQvao; + static GLuint ColorTexturedQuadShader; static GLuint ColorTexturedQuadAttribPosition; static GLuint ColorTexturedQuadAttribTexCoord; @@ -310,6 +312,8 @@ static GLuint ColorTexturedQuadUniformSize; static GLuint ColorTexturedQuadUniformTexcenter; static GLuint ColorTexturedQuadUniformTexsize; +static GLuint CTQvao; + 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) @@ -331,8 +335,22 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol ColorTexturedQuadUniformSize = glGetUniformLocation(ColorTexturedQuadShader, "size"); ColorTexturedQuadUniformTexcenter = glGetUniformLocation(ColorTexturedQuadShader, "texcenter"); ColorTexturedQuadUniformTexsize = glGetUniformLocation(ColorTexturedQuadShader, "texsize"); + glGenVertexArrays(1, &CTQvao); + glBindVertexArray(CTQvao); + glEnableVertexAttribArray(ColorTexturedQuadAttribPosition); + glEnableVertexAttribArray(ColorTexturedQuadAttribTexCoord); + glEnableVertexAttribArray(ColorTexturedQuadAttribColor); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(ColorTexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(ColorTexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); + glVertexAttribPointer(ColorTexturedQuadAttribColor, 4, GL_UNSIGNED_INT, GL_FALSE, 4 * sizeof(float), 0); + glBindVertexArray(0); } + glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); + glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(int), colors); glUseProgram(ColorTexturedQuadShader); + glBindVertexArray(CTQvao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); glUniform1i(ColorTexturedQuadUniformTexture, 0); @@ -340,19 +358,8 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol glUniform2f(ColorTexturedQuadUniformSize, width, height); glUniform2f(ColorTexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); glUniform2f(ColorTexturedQuadUniformTexsize, tex_width, tex_height); - glEnableVertexAttribArray(ColorTexturedQuadAttribPosition); - glEnableVertexAttribArray(ColorTexturedQuadAttribTexCoord); - glEnableVertexAttribArray(ColorTexturedQuadAttribColor); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glVertexAttribPointer(ColorTexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(ColorTexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); - glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); - glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(int), colors); - glVertexAttribPointer(ColorTexturedQuadAttribColor, 4, GL_UNSIGNED_INT, GL_FALSE, 4 * sizeof(float), 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(ColorTexturedQuadAttribPosition); - glDisableVertexAttribArray(ColorTexturedQuadAttribTexCoord); - glDisableVertexAttribArray(ColorTexturedQuadAttribColor); + glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -370,8 +377,17 @@ void drawTexQuad(const video::ITexture *texture, float width, float height, TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); TexturedQuadUniformTexcenter = glGetUniformLocation(TexturedQuadShader, "texcenter"); TexturedQuadUniformTexsize = glGetUniformLocation(TexturedQuadShader, "texsize"); + glGenVertexArrays(1, &TQvao); + glBindVertexArray(TQvao); + glEnableVertexAttribArray(TexturedQuadAttribPosition); + glEnableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); + glBindVertexArray(0); } glUseProgram(TexturedQuadShader); + glBindVertexArray(TQvao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); glUniform1i(TexturedQuadUniformTexture, 0); @@ -379,16 +395,9 @@ void drawTexQuad(const video::ITexture *texture, float width, float height, glUniform2f(TexturedQuadUniformSize, width, height); glUniform2f(TexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); glUniform2f(TexturedQuadUniformTexsize, tex_width, tex_height); - glEnableVertexAttribArray(TexturedQuadAttribPosition); - glEnableVertexAttribArray(TexturedQuadAttribTexCoord); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glVertexAttribPointer(TexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(TexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(TexturedQuadAttribPosition); - glDisableVertexAttribArray(TexturedQuadAttribTexCoord); + glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); - } void draw2DImage(const video::ITexture* texture, const core::rect& destRect, @@ -442,13 +451,10 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect if (useAlphaChannelOfTexture) { glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.f); } else { glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); } if (colors) drawTexColoredQuad(texture, colors, width, height, center_pos_x, center_pos_y, @@ -462,6 +468,7 @@ static GLuint ColoredQuadShader; static GLuint ColoredQuadUniformCenter; static GLuint ColoredQuadUniformSize; static GLuint ColoredQuadUniformColor; +static GLuint CQvao; void GL32_draw2DRectangle(video::SColor color, const core::rect& position, const core::rect* clip) @@ -493,13 +500,10 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, if (color.getAlpha() < 255) { glEnable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.f); } else { glDisable(GL_BLEND); - glDisable(GL_ALPHA_TEST); } if (!ColoredQuadShader) @@ -508,15 +512,19 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, ColoredQuadUniformColor = glGetUniformLocation(ColoredQuadShader, "color"); ColoredQuadUniformCenter = glGetUniformLocation(ColoredQuadShader, "center"); ColoredQuadUniformSize = glGetUniformLocation(ColoredQuadShader, "size"); + glGenVertexArrays(1, &CQvao); + glBindVertexArray(CQvao); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glBindVertexArray(0); } glUseProgram(ColoredQuadShader); + glBindVertexArray(CQvao); glUniform2f(ColoredQuadUniformCenter, center_pos_x, center_pos_y); glUniform2f(ColoredQuadUniformSize, width, height); glUniform4i(ColoredQuadUniformColor, color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } From d5c06c8583afcc43e780ea2b2f25e3206a10b4e0 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 00:11:59 +0000 Subject: [PATCH 295/412] Fix colored rectangle color. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15067 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/coloredquad.frag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shaders/coloredquad.frag b/data/shaders/coloredquad.frag index 3a794e33c..4d2c007c1 100644 --- a/data/shaders/coloredquad.frag +++ b/data/shaders/coloredquad.frag @@ -3,5 +3,5 @@ uniform ivec4 color; void main() { - gl_FragColor = color; -} \ No newline at end of file + gl_FragColor = vec4(color) / 255.; +} From a5c84822cc57aae7e8fcf6afb36ced6cd24c1d59 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 01:05:03 +0000 Subject: [PATCH 296/412] Fix colortexturedquad shader/vertexpointer. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15068 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/colortexturedquad.vert | 2 +- src/graphics/glwrap.cpp | 21 ++++++++++++--------- src/graphics/glwrap.hpp | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/data/shaders/colortexturedquad.vert b/data/shaders/colortexturedquad.vert index 9b567da79..b5827a64a 100644 --- a/data/shaders/colortexturedquad.vert +++ b/data/shaders/colortexturedquad.vert @@ -6,7 +6,7 @@ uniform vec2 texsize; in vec2 position; in vec2 texcoord; -in ivec4 color; +in uvec4 color; out vec2 uv; out vec4 col; diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index da4374b51..a01d93da4 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -51,6 +51,7 @@ PFNGLBINDVERTEXARRAYPROC glBindVertexArray; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLTEXBUFFERPROC glTexBuffer; PFNGLBUFFERSUBDATAPROC glBufferSubData; +PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; #endif static GLuint quad_buffer; @@ -176,6 +177,7 @@ void initGL() glUniform1fv = (PFNGLUNIFORM1FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform1fv"); glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv"); glBufferSubData = (PFNGLBUFFERSUBDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferSubData"); + glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribIPointer"); #endif #ifdef ENABLE_ARB_DEBUG_OUTPUT glDebugMessageCallbackARB(debugCallback, NULL); @@ -190,15 +192,15 @@ void initGL() glBindBuffer(GL_ARRAY_BUFFER, quad_buffer); glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); - const int quad_color[] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, + const unsigned quad_color[] = { + 0, 0, 0, 255, + 255, 0, 0, 255, + 0, 255, 0, 255, + 0, 0, 255, 255, }; glGenBuffers(1, &ColoredVertex); glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(int), quad_color, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(unsigned), quad_color, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -318,12 +320,13 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y, float tex_width, float tex_height) { - int colors[] = { + unsigned colors[] = { col[0].getRed(), col[0].getGreen(), col[0].getBlue(), col[0].getAlpha(), col[1].getRed(), col[1].getGreen(), col[1].getBlue(), col[1].getAlpha(), col[2].getRed(), col[2].getGreen(), col[2].getBlue(), col[2].getAlpha(), col[3].getRed(), col[3].getGreen(), col[3].getBlue(), col[3].getAlpha(), }; + if (!ColorTexturedQuadShader) { ColorTexturedQuadShader = LoadProgram(file_manager->getAsset("shaders/colortexturedquad.vert").c_str(), file_manager->getAsset("shaders/colortexturedquad.frag").c_str()); @@ -344,11 +347,11 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol glVertexAttribPointer(ColorTexturedQuadAttribPosition, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); glVertexAttribPointer(ColorTexturedQuadAttribTexCoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid *)(2 * sizeof(float))); glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); - glVertexAttribPointer(ColorTexturedQuadAttribColor, 4, GL_UNSIGNED_INT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribIPointer(ColorTexturedQuadAttribColor, 4, GL_UNSIGNED_INT, 4 * sizeof(unsigned), 0); glBindVertexArray(0); } glBindBuffer(GL_ARRAY_BUFFER, ColoredVertex); - glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(int), colors); + glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(unsigned), colors); glUseProgram(ColorTexturedQuadShader); glBindVertexArray(CTQvao); glActiveTexture(GL_TEXTURE0); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index fc208c61c..1773a34ea 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -74,6 +74,7 @@ extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; extern PFNGLTEXBUFFERPROC glTexBuffer; extern PFNGLBUFFERSUBDATAPROC glBufferSubData; +extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; #endif From 23d0b42b5f055a4777c758b12dc9b774a2126543 Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 01:24:28 +0000 Subject: [PATCH 297/412] Light: Simplify slightly shader git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15069 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/pointlight.frag | 5 +++-- src/graphics/post_processing.cpp | 6 +----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index b60cb1005..929b2323d 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -5,12 +5,13 @@ uniform vec4 center[16]; uniform vec4 col[16]; uniform float energy[16]; uniform float spec; -uniform vec2 screen; uniform mat4 invproj; uniform mat4 viewm; +in vec2 uv; + void main() { - vec2 texc = gl_FragCoord.xy / screen; + vec2 texc = uv; float z = texture2D(ntex, texc).a; vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 72f3c88ad..b82356bcb 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -337,7 +337,7 @@ namespace PointLightShader { GLuint Program = 0; GLuint attrib_position, attrib_texcoord; - GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_screen, uniform_invproj, uniform_viewm; + GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_invproj, uniform_viewm; GLuint vao = 0; @@ -352,7 +352,6 @@ namespace PointLightShader uniform_col = glGetUniformLocation(Program, "col[0]"); uniform_energy = glGetUniformLocation(Program, "energy[0]"); uniform_spec = glGetUniformLocation(Program, "spec"); - uniform_screen = glGetUniformLocation(Program, "screen"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_viewm = glGetUniformLocation(Program, "viewm"); @@ -743,8 +742,6 @@ void renderColorLevel(ITexture *in) void PostProcessing::renderPointlight(ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy) { - float width = (float)UserConfigParams::m_width; - float height = (float)UserConfigParams::m_height; if (!PointLightShader::Program) PointLightShader::init(); glEnable(GL_BLEND); @@ -759,7 +756,6 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po glUniform4fv(PointLightShader::uniform_col, 16, colors.data()); glUniform1fv(PointLightShader::uniform_energy, 16, energy.data()); glUniform1f(PointLightShader::uniform_spec, 200); - glUniform2f(PointLightShader::uniform_screen, width, height); glUniformMatrix4fv(PointLightShader::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); glUniformMatrix4fv(PointLightShader::uniform_viewm, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); From dafc30b2d0a2a2e43a2e056b5aa051de6c56f08b Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 01:31:26 +0000 Subject: [PATCH 298/412] Force blending mode for draw2d. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15070 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/glwrap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index a01d93da4..69030a9e0 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -454,6 +454,7 @@ void draw2DImage(const video::ITexture* texture, const core::rect& destRect if (useAlphaChannelOfTexture) { glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { @@ -503,6 +504,7 @@ void GL32_draw2DRectangle(video::SColor color, const core::rect& position, if (color.getAlpha() < 255) { glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { From 9ee06a5fe0f7d93fc911d7ddcfd9fdaf6134d258 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Tue, 14 Jan 2014 11:47:25 +0000 Subject: [PATCH 299/412] Replaced boolstr with toString specialisation for bool; fixed translations in current user. Otherwise many many cosmetic only changes. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15071 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/achievements/achievement.cpp | 17 +- src/achievements/achievements_slot.cpp | 2 +- src/challenges/challenge.cpp | 12 +- src/graphics/post_processing.cpp | 5 +- src/main.cpp | 2 +- src/online/current_user.cpp | 622 ++++++++++++++----------- src/online/current_user.hpp | 50 +- src/online/profile.cpp | 4 +- src/online/servers_manager.cpp | 2 +- src/utils/string_utils.cpp | 15 +- src/utils/string_utils.hpp | 132 +++--- 11 files changed, 496 insertions(+), 367 deletions(-) diff --git a/src/achievements/achievement.cpp b/src/achievements/achievement.cpp index 0c16eafdf..be439a8ed 100644 --- a/src/achievements/achievement.cpp +++ b/src/achievements/achievement.cpp @@ -95,7 +95,7 @@ void SingleAchievement::load(XMLNode * input) void SingleAchievement::save(std::ofstream & out) { out << " \n"; + out << " \n"; if(!m_achieved) { - std::map::iterator iter; - for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) { - out << " first.c_str() << "\" value=\"" << StringUtils::toString(iter->second) << "\"/>\n"; + std::map::iterator i; + for ( i = m_progress_map.begin(); i != m_progress_map.end(); ++i ) + { + out << " first.c_str() + << "\" value=\"" << StringUtils::toString(i->second) + << "\"/>\n"; } } out << " \n"; @@ -178,7 +182,8 @@ int MapAchievement::getValue(const std::string & key) void MapAchievement::reset() { std::map::iterator iter; - for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) { + for ( iter = m_progress_map.begin(); iter != m_progress_map.end(); ++iter ) + { iter->second = 0; } } // reset diff --git a/src/achievements/achievements_slot.cpp b/src/achievements/achievements_slot.cpp index 9acbe78c5..931c4164c 100644 --- a/src/achievements/achievements_slot.cpp +++ b/src/achievements/achievements_slot.cpp @@ -112,7 +112,7 @@ void AchievementsSlot::createFreshSlot() void AchievementsSlot::save(std::ofstream & out) { out << " \n"; std::map::const_iterator i; for(i = m_achievements.begin(); i != m_achievements.end(); i++) diff --git a/src/challenges/challenge.cpp b/src/challenges/challenge.cpp index 29d9e2af8..ea2badca6 100644 --- a/src/challenges/challenge.cpp +++ b/src/challenges/challenge.cpp @@ -93,8 +93,14 @@ void Challenge::setSolved(RaceManager::Difficulty d) void Challenge::save(std::ofstream& writer) { writer << " <" << m_data->getId().c_str() << ">\n" - << " \n" - << " \n" - << " \n" + << " \n" + << " \n" + << " \n" << " getId().c_str() << ">\n"; } // save diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index b82356bcb..26495f655 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -1187,7 +1187,10 @@ void PostProcessing::render() drawQuad(cam, m_material); // Blur - renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER1), irr_driver->getRTT(RTT_QUARTER2), 4. / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); + renderGaussian3Blur(irr_driver->getRTT(RTT_QUARTER1), + irr_driver->getRTT(RTT_QUARTER2), + 4.f / UserConfigParams::m_width, + 4.f / UserConfigParams::m_height); // Calculate the sun's position in texcoords const core::vector3df pos = sun->getPosition(); diff --git a/src/main.cpp b/src/main.cpp index 35ffe6429..bd48a167c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -949,7 +949,7 @@ int handleCmdLine() if (try_login) { irr::core::stringw s; - Online::CurrentUser::SignInRequest* request = + Online::XMLRequest* request = Online::CurrentUser::get()->requestSignIn(login, password, false, false); request->executeNow(); diff --git a/src/online/current_user.cpp b/src/online/current_user.cpp index dede03afc..bc0ef7b08 100644 --- a/src/online/current_user.cpp +++ b/src/online/current_user.cpp @@ -39,69 +39,74 @@ #include #include +using namespace irr; using namespace Online; namespace Online { static CurrentUser* current_user_singleton(NULL); + /** Singleton create function. */ CurrentUser* CurrentUser::get() { if (current_user_singleton == NULL) current_user_singleton = new CurrentUser(); return current_user_singleton; - } + } // get + // ------------------------------------------------------------------------ void CurrentUser::deallocate() { delete current_user_singleton; current_user_singleton = NULL; } // deallocate - // ============================================================================ + // ======================================================================== CurrentUser::CurrentUser() { - m_state = US_SIGNED_OUT; - m_token = ""; + m_state = US_SIGNED_OUT; + m_token = ""; m_save_session = false; - m_profile = NULL; - } + m_profile = NULL; + } // CurrentUser - // ============================================================================ - const XMLRequest * CurrentUser::requestRecovery( const irr::core::stringw &username, - const irr::core::stringw &email) + // ------------------------------------------------------------------------ + const XMLRequest * CurrentUser::requestRecovery(const core::stringw &username, + const core::stringw &email) { assert(m_state == US_SIGNED_OUT || m_state == US_GUEST); XMLRequest * request = new XMLRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("recovery")); + request->addParameter("action", "recovery"); request->addParameter("username", username); request->addParameter("email", email); - RequestManager::get()->addRequest(request); + request->queue(); return request; - } + } // requestRecovery - // ============================================================================ - const XMLRequest * CurrentUser::requestSignUp( const irr::core::stringw &username, - const irr::core::stringw &password, - const irr::core::stringw &password_confirm, - const irr::core::stringw &email, - bool terms) + // ------------------------------------------------------------------------ + const XMLRequest * CurrentUser::requestSignUp(const core::stringw &username, + const core::stringw &password, + const core::stringw &password_confirm, + const core::stringw &email, + bool terms) { assert(m_state == US_SIGNED_OUT || m_state == US_GUEST); XMLRequest * request = new XMLRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("register")); + request->addParameter("action", "register"); request->addParameter("username", username); request->addParameter("password", password); request->addParameter("password_confirm", password_confirm); request->addParameter("email", email); - request->addParameter("terms", std::string("on")); - RequestManager::get()->addRequest(request); + request->addParameter("terms", "on"); + request->queue(); return request; - } + } // requestSignUp - // ============================================================================ + // ------------------------------------------------------------------------ + /** Request a login using the saved credentials of the user. + */ void CurrentUser::requestSavedSession() { SignInRequest * request = NULL; @@ -109,50 +114,89 @@ namespace Online { request = new SignInRequest(true); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("saved-session")); + request->addParameter("action","saved-session"); request->addParameter("userid", UserConfigParams::m_saved_user); - request->addParameter("token", UserConfigParams::m_saved_token.c_str()); - RequestManager::get()->addRequest(request); + request->addParameter("token", + UserConfigParams::m_saved_token.c_str()); + request->queue(); m_state = US_SIGNING_IN; } - } + } // requestSavedSession - CurrentUser::SignInRequest * CurrentUser::requestSignIn( const irr::core::stringw &username, - const irr::core::stringw &password, - bool save_session, bool request_now) + // ------------------------------------------------------------------------ + /** Create a signin request. + * \param username Name of user. + * \param password Password. + * \param save_session If true, the login credential will be saved to + * allow a password-less login. + * \param request_now Immediately submit this request to the + * RequestManager. + */ + CurrentUser::SignInRequest* + CurrentUser::requestSignIn(const core::stringw &username, + const core::stringw &password, + bool save_session, bool request_now) { assert(m_state == US_SIGNED_OUT); m_save_session = save_session; SignInRequest * request = new SignInRequest(request_now); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("connect")); + request->addParameter("action","connect"); request->addParameter("username",username); request->addParameter("password",password); - request->addParameter("save-session", StringUtils::boolstr(save_session)); + request->addParameter("save-session", save_session); if (request_now) { - RequestManager::get()->addRequest(request); + request->queue(); m_state = US_SIGNING_IN; } return request; - } + } // requestSignIn + // ------------------------------------------------------------------------ + /** Called when the signin request is finished. + */ + void CurrentUser::SignInRequest::callback() + { + CurrentUser::get()->signIn(isSuccess(), getXMLData()); + if(GUIEngine::ModalDialog::isADialogActive()) + { + LoginDialog * dialog = + dynamic_cast(GUIEngine::ModalDialog::getCurrent()); + if(dialog) + { + if(isSuccess()) + dialog->success(); + else + dialog->error(getInfo()); + } // if dialog + } // isDialogActive + } // SignInRequest::callback + + // ------------------------------------------------------------------------ + /** Checks the server respond after a login attempt. If the login + * was successful, it marks the user as logged in, and (if requested) + * saves data to be able to login next time. + * \param success If the answer from the server indicated a + * successful login attemp. + * \param input Xml tree with the complete server response. + */ void CurrentUser::signIn(bool success, const XMLNode * input) { if (success) { int token_fetched = input->get("token", &m_token); - irr::core::stringw username(""); + core::stringw username(""); int username_fetched = input->get("username", &username); uint32_t userid(0); int userid_fetched = input->get("userid", &userid); m_profile = new Profile(userid, username, true); assert(token_fetched && username_fetched && userid_fetched); m_state = US_SIGNED_IN; - if(getSaveSession()) + if(saveSession()) { - UserConfigParams::m_saved_user = getID(); - UserConfigParams::m_saved_token = getToken(); + UserConfigParams::m_saved_user = getID(); + UserConfigParams::m_saved_token = getToken(); UserConfigParams::m_saved_session = true; } ProfileManager::get()->addPersistent(m_profile); @@ -160,77 +204,45 @@ namespace Online std::string achieved_string(""); if(input->get("achieved", &achieved_string) == 1) { - std::vector achieved_ids = StringUtils::splitToUInt(achieved_string, ' '); + std::vector achieved_ids = + StringUtils::splitToUInt(achieved_string, ' '); AchievementsManager::get()->getActive()->sync(achieved_ids); } m_profile->fetchFriends(); - } + } // if success else { m_state = US_SIGNED_OUT; } - } + } // signIn - void CurrentUser::SignInRequest::callback() + // ------------------------------------------------------------------------ + void CurrentUser::requestSignOut() { - CurrentUser::get()->signIn(isSuccess(), getXMLData()); - if(GUIEngine::ModalDialog::isADialogActive()) - { - LoginDialog * dialog = dynamic_cast(GUIEngine::ModalDialog::getCurrent()); - if(dialog != NULL) - { - if(isSuccess()) - dialog->success(); - else - dialog->error(getInfo()); - } - } - } - - // ============================================================================ - - const CurrentUser::ServerCreationRequest * CurrentUser::requestServerCreation( const irr::core::stringw &name, - int max_players) - { - assert(m_state == US_SIGNED_IN); - ServerCreationRequest * request = new ServerCreationRequest(); - request->setServerURL("client-user.php"); - request->addParameter("action", std::string("create_server")); - request->addParameter("token", getToken()); - request->addParameter("userid", getID()); - request->addParameter("name", name); - request->addParameter("max_players", max_players); - RequestManager::get()->addRequest(request); - return request; - } - - void CurrentUser::ServerCreationRequest::callback() - { - if(isSuccess()) - { - Server * server = new Server(*getXMLData()->getNode("server")); - ServersManager::get()->addServer(server); - m_created_server_id = server->getServerId(); - } - } - - // ============================================================================ - void CurrentUser::requestSignOut(){ assert(m_state == US_SIGNED_IN || m_state == US_GUEST); SignOutRequest * request = new SignOutRequest(); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("disconnect")); + request->addParameter("action","disconnect"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - RequestManager::get()->addRequest(request); + request->queue(); m_state = US_SIGNING_OUT; - } + } // requestSignOut + // -------------------------------------------------------------------- + void CurrentUser::SignOutRequest::callback() + { + CurrentUser::get()->signOut(isSuccess(), getXMLData()); + } // SignOutRequest::callback + + // ------------------------------------------------------------------------ void CurrentUser::signOut(bool success, const XMLNode * input) { if(!success) { - Log::warn("CurrentUser::signOut", "%s", "There were some connection issues while signing out. Report a bug if this caused issues."); + Log::warn("CurrentUser::signOut", "%s", + "There were some connection issues while signing out. " + "Report a bug if this caused issues."); } m_token = ""; ProfileManager::get()->clearPersistent(); @@ -240,30 +252,54 @@ namespace Online UserConfigParams::m_saved_token = ""; UserConfigParams::m_saved_session = false; AchievementsManager::get()->updateCurrentPlayer(); - } + } // signOut - void CurrentUser::SignOutRequest::callback() + // ------------------------------------------------------------------------ + const CurrentUser::ServerCreationRequest* + CurrentUser::requestServerCreation(const core::stringw &name, + int max_players) { - CurrentUser::get()->signOut(isSuccess(), getXMLData()); - } + assert(m_state == US_SIGNED_IN); + ServerCreationRequest * request = new ServerCreationRequest(); + request->setServerURL("client-user.php"); + request->addParameter("action", "create_server"); + request->addParameter("token", getToken()); + request->addParameter("userid", getID()); + request->addParameter("name", name); + request->addParameter("max_players", max_players); + request->queue(); + return request; + } // requestServerCreation - // ============================================================================ + // ------------------------------------------------------------------------ + void CurrentUser::ServerCreationRequest::callback() + { + if(isSuccess()) + { + Server * server = new Server(*getXMLData()->getNode("server")); + ServersManager::get()->addServer(server); + m_created_server_id = server->getServerId(); + } + } // ServerCreationRequest::callback - CurrentUser::ServerJoinRequest * CurrentUser::requestServerJoin(uint32_t server_id, - bool request_now) + // ------------------------------------------------------------------------ + CurrentUser::ServerJoinRequest* + CurrentUser::requestServerJoin(uint32_t server_id, + bool request_now) { assert(m_state == US_SIGNED_IN || m_state == US_GUEST); ServerJoinRequest * request = new ServerJoinRequest(); request->setServerURL("address-management.php"); - request->addParameter("action",std::string("request-connection")); + request->addParameter("action","request-connection"); request->addParameter("token", getToken()); request->addParameter("id", getID()); request->addParameter("server_id", server_id); if (request_now) - RequestManager::get()->addRequest(request); + request->queue(); return request; - } + } // requestServerJoin + // ------------------------------------------------------------------------ void CurrentUser::ServerJoinRequest::callback() { if(isSuccess()) @@ -273,63 +309,48 @@ namespace Online ServersManager::get()->setJoinedServer(server_id); } //FIXME needs changes for actual valid joining - } + } // ServerJoinRequest::callback - // ============================================================================ - - const XMLRequest * CurrentUser::requestGetAddonVote( const std::string & addon_id) const + // ------------------------------------------------------------------------ + const XMLRequest* + CurrentUser::requestGetAddonVote(const std::string & addon_id) const { assert(m_state == US_SIGNED_IN); XMLRequest * request = new XMLRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("get-addon-vote")); + request->addParameter("action", "get-addon-vote"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("addonid", addon_id.substr(6)); - RequestManager::get()->addRequest(request); + request->queue(); return request; - } + } // requestGetAddonVote - // ============================================================================ - /** - * A request to the server, to fetch matching results for the supplied search term. - * \param search_string the string to search for. + // ------------------------------------------------------------------------ + /** A request to the server, to perform a vote on an addon. + * \param addon_id the id of the addon to vote for. + * \param rating the voted rating. */ - const XMLRequest * CurrentUser::requestUserSearch( const irr::core::stringw & search_string) const + const CurrentUser::SetAddonVoteRequest* + CurrentUser::requestSetAddonVote(const std::string & addon_id, + float rating) const { assert(m_state == US_SIGNED_IN); - XMLRequest * request = new XMLRequest(); + CurrentUser::SetAddonVoteRequest * request = + new CurrentUser::SetAddonVoteRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("user-search")); - request->addParameter("token", getToken()); - request->addParameter("userid", getID()); - request->addParameter("search-string", search_string); - RequestManager::get()->addRequest(request); - return request; - } - - // ============================================================================ - /** - * A request to the server, to perform a vote on an addon. - * \param addon_id the id of the addon to vote for. - * \param rating the voted rating. - */ - const CurrentUser::SetAddonVoteRequest * CurrentUser::requestSetAddonVote( const std::string & addon_id, float rating) const - { - assert(m_state == US_SIGNED_IN); - CurrentUser::SetAddonVoteRequest * request = new CurrentUser::SetAddonVoteRequest(); - request->setServerURL("client-user.php"); - request->addParameter("action", std::string("set-addon-vote")); + request->addParameter("action", "set-addon-vote"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("addonid", addon_id.substr(6)); request->addParameter("rating", rating); - RequestManager::get()->addRequest(request); + request->queue(); return request; - } + } // requestSetAddonVote - /** - * Callback for the request to vote for an addon. Updates the local average rating. + // ------------------------------------------------------------------------ + /** Callback for the request to vote for an addon. Updates the local + * average rating. */ void CurrentUser::SetAddonVoteRequest::callback() { @@ -339,110 +360,144 @@ namespace Online getXMLData()->get("addon-id", &addon_id); float average; getXMLData()->get("new-average", &average); - addons_manager->getAddon(Addon::createAddonId(addon_id))->setRating(average); + addons_manager->getAddon(Addon::createAddonId(addon_id)) + ->setRating(average); } - } + } // SetAddonVoteRequest::callback - // ============================================================================ - /** - * A request to the server, to invite a user to be friends. - * \param friend_id The id of the user which has to be friended. + // ------------------------------------------------------------------------ + /** A request to the server, to fetch matching results for the supplied + * search term. + * \param search_string the string to search for. + */ + const XMLRequest* + CurrentUser::requestUserSearch(const core::stringw &search_string) const + { + assert(m_state == US_SIGNED_IN); + XMLRequest * request = new XMLRequest(); + request->setServerURL("client-user.php"); + request->addParameter("action", "user-search"); + request->addParameter("token", getToken()); + request->addParameter("userid", getID()); + request->addParameter("search-string", search_string); + request->queue(); + return request; + } // requestUserSearch + + // ------------------------------------------------------------------------ + /** A request to the server, to invite a user to be friends. + * \param friend_id The id of the user which has to be friended. */ void CurrentUser::requestFriendRequest(const uint32_t friend_id) const { assert(m_state == US_SIGNED_IN); CurrentUser::FriendRequest * request = new CurrentUser::FriendRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("friend-request")); + request->addParameter("action", "friend-request"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestFriendRequest - /** - * Callback for the request to send a friend invitation. Shows a confirmation message and takes care of updating all the cached information. + // ------------------------------------------------------------------------ + /** Callback for the request to send a friend invitation. Shows a + * confirmation message and takes care of updating all the cached + * information. */ void CurrentUser::FriendRequest::callback() { uint32_t id(0); getXMLData()->get("friendid", &id); - irr::core::stringw info_text(""); + core::stringw info_text(""); if(isSuccess()) { CurrentUser::get()->getProfile()->addFriend(id); - ProfileManager::get()->getProfileByID(id)->setRelationInfo(new Profile::RelationInfo(_("Today"), false, true, false)); + Profile::RelationInfo *info = + new Profile::RelationInfo(_("Today"), false, true, false); + ProfileManager::get()->getProfileByID(id)->setRelationInfo(info); OnlineProfileFriends::getInstance()->refreshFriendsList(); info_text = _("Friend request send!"); } else info_text = getInfo(); - GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!isSuccess(), true), true); - } + UserInfoDialog *dialog = new UserInfoDialog(id, info_text, + !isSuccess(), true); + GUIEngine::DialogQueue::get()->pushDialog(dialog, true); + } // FriendRequest::callback - // ============================================================================ - /** - * A request to the server, to accept a friend request. - * \param friend_id The id of the user of which the request has to be accepted. + // ------------------------------------------------------------------------ + /** A request to the server, to accept a friend request. + * \param friend_id The id of the user of which the request has to be + * accepted. */ void CurrentUser::requestAcceptFriend(const uint32_t friend_id) const { assert(m_state == US_SIGNED_IN); - CurrentUser::AcceptFriendRequest * request = new CurrentUser::AcceptFriendRequest(); + CurrentUser::AcceptFriendRequest * request = + new CurrentUser::AcceptFriendRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("accept-friend-request")); + request->addParameter("action", "accept-friend-request"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestAcceptFriend - /** - * Callback for the request to accept a friend invitation. Shows a confirmation message and takes care of updating all the cached information. + // ------------------------------------------------------------------------ + /** Callback for the request to accept a friend invitation. Shows a + * confirmation message and takes care of updating all the cached + * information. */ void CurrentUser::AcceptFriendRequest::callback() { uint32_t id(0); getXMLData()->get("friendid", &id); - irr::core::stringw info_text(""); + core::stringw info_text(""); if(isSuccess()) { Profile * profile = ProfileManager::get()->getProfileByID(id); profile->setFriend(); - profile->setRelationInfo(new Profile::RelationInfo(_("Today"), false, false, true)); + Profile::RelationInfo *info = + new Profile::RelationInfo(_("Today"), false, false, true); + profile->setRelationInfo(info); OnlineProfileFriends::getInstance()->refreshFriendsList(); info_text = _("Friend request accepted!"); } else info_text = getInfo(); - GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!isSuccess(), true), true); - } + GUIEngine::DialogQueue::get()->pushDialog( + new UserInfoDialog(id, info_text,!isSuccess(), true), true); + } // AcceptFriendRequest::callback - // ============================================================================ - /** - * A request to the server, to decline a friend request. - * \param friend_id The id of the user of which the request has to be declined. + // ------------------------------------------------------------------------ + /** A request to the server, to decline a friend request. + * \param friend_id The id of the user of which the request has to be + * declined. */ void CurrentUser::requestDeclineFriend(const uint32_t friend_id) const { assert(m_state == US_SIGNED_IN); - CurrentUser::DeclineFriendRequest * request = new CurrentUser::DeclineFriendRequest(); + CurrentUser::DeclineFriendRequest * request = + new CurrentUser::DeclineFriendRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("decline-friend-request")); + request->addParameter("action", "decline-friend-request"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestDeclineFriend - /** - * Callback for the request to decline a friend invitation. Shows a confirmation message and takes care of updating all the cached information. + // ------------------------------------------------------------------------ + /** Callback for the request to decline a friend invitation. Shows a + * confirmation message and takes care of updating all the cached + * information. */ void CurrentUser::DeclineFriendRequest::callback() { uint32_t id(0); getXMLData()->get("friendid", &id); - irr::core::stringw info_text(""); + core::stringw info_text(""); if(isSuccess()) { CurrentUser::get()->getProfile()->removeFriend(id); @@ -453,35 +508,38 @@ namespace Online } else info_text = getInfo(); - GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!isSuccess(), true), true); + GUIEngine::DialogQueue::get()->pushDialog( + new UserInfoDialog(id, info_text,!isSuccess(), true), true); + } // DeclineFriendRequest::callback - } - - // ============================================================================ - /** - * A request to the server, to cancel a pending friend request. - * \param friend_id The id of the user of which the request has to be canceled. + // ------------------------------------------------------------------------ + /** A request to the server, to cancel a pending friend request. + * \param friend_id The id of the user of which the request has to be + * canceled. */ void CurrentUser::requestCancelFriend(const uint32_t friend_id) const { assert(m_state == US_SIGNED_IN); - CurrentUser::CancelFriendRequest * request = new CurrentUser::CancelFriendRequest(); + CurrentUser::CancelFriendRequest * request = + new CurrentUser::CancelFriendRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("cancel-friend-request")); + request->addParameter("action", "cancel-friend-request"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestCancelFriend - /** - * Callback for the request to cancel a friend invitation. Shows a confirmation message and takes care of updating all the cached information. + // ------------------------------------------------------------------------ + /** Callback for the request to cancel a friend invitation. Shows a + * confirmation message and takes care of updating all the cached + * information. */ void CurrentUser::CancelFriendRequest::callback() { uint32_t id(0); getXMLData()->get("friendid", &id); - irr::core::stringw info_text(""); + core::stringw info_text(""); if(isSuccess()) { CurrentUser::get()->getProfile()->removeFriend(id); @@ -492,35 +550,37 @@ namespace Online } else info_text = getInfo(); - GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!isSuccess(), true), true); + UserInfoDialog *dia = new UserInfoDialog(id, info_text,!isSuccess(), + true); + GUIEngine::DialogQueue::get()->pushDialog(dia, true); + } // CancelFriendRequest::callback - } - - // ============================================================================ - /** - * A request to the server, to remove a friend relation. - * \param friend_id The id of the friend to be removed. + // ------------------------------------------------------------------------ + /** A request to the server, to remove a friend relation. + * \param friend_id The id of the friend to be removed. */ void CurrentUser::requestRemoveFriend(const uint32_t friend_id) const { assert(m_state == US_SIGNED_IN); - CurrentUser::RemoveFriendRequest * request = new CurrentUser::RemoveFriendRequest(); + CurrentUser::RemoveFriendRequest * request = + new CurrentUser::RemoveFriendRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("remove-friend")); + request->addParameter("action", "remove-friend"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("friendid", friend_id); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestRemoveFriend - /** - * Callback for the request to remove a friend. Shows a confirmation message and takes care of updating all the cached information. + // ------------------------------------------------------------------------ + /** Callback for the request to remove a friend. Shows a confirmation + * message and takes care of updating all the cached information. */ void CurrentUser::RemoveFriendRequest::callback() { uint32_t id(0); getXMLData()->get("friendid", &id); - irr::core::stringw info_text(""); + core::stringw info_text(""); if(isSuccess()) { CurrentUser::get()->getProfile()->removeFriend(id); @@ -531,40 +591,45 @@ namespace Online } else info_text = getInfo(); - GUIEngine::DialogQueue::get()->pushDialog( new UserInfoDialog(id, info_text,!isSuccess(), true), true); + UserInfoDialog *info = new UserInfoDialog(id, info_text,!isSuccess(), + true); + GUIEngine::DialogQueue::get()->pushDialog(info, true); - } + } // RemoveFriendRequest::callback - // ============================================================================ - /** - * A request to the server, to change the password of the signed in user. - * \param current_password The active password of the currently signed in user. - * \param new_password The password the user wants to change to. - * \param new_password_ver Confirmation of that password. Has to be the exact same. + // ------------------------------------------------------------------------ + /** A request to the server, to change the password of the signed in user. + * \param current_password The active password of the currently signed in + * user. + * \param new_password The password the user wants to change to. + * \param new_password_ver Confirmation of that password. Has to be the + * exact same. */ - void CurrentUser::requestPasswordChange(const irr::core::stringw ¤t_password, - const irr::core::stringw &new_password, - const irr::core::stringw &new_password_ver) const + void CurrentUser::requestPasswordChange(const core::stringw ¤t_password, + const core::stringw &new_password, + const core::stringw &new_password_ver) const { assert(m_state == US_SIGNED_IN); ChangePasswordRequest * request = new ChangePasswordRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("change_password")); + request->addParameter("action", "change_password"); request->addParameter("userid", getID()); request->addParameter("current", current_password); request->addParameter("new1", new_password); request->addParameter("new2", new_password_ver); - RequestManager::get()->addRequest(request); - } - - /** - * Callback for the change password request. If the matching dialog is still open, show a confirmation message. + request->queue(); + } // requestPasswordChange + // ------------------------------------------------------------------------ + /** Callback for the change password request. If the matching dialog is + * still open, show a confirmation message. */ void CurrentUser::ChangePasswordRequest::callback() { if(GUIEngine::ModalDialog::isADialogActive()) { - ChangePasswordDialog * dialog = dynamic_cast(GUIEngine::ModalDialog::getCurrent()); + ChangePasswordDialog * dialog = + dynamic_cast(GUIEngine::ModalDialog + ::getCurrent()); if(dialog != NULL) { if(isSuccess()) @@ -573,24 +638,26 @@ namespace Online dialog->error(getInfo()); } } - } - // ============================================================================ - /** - * Sends a request to the server to see if any new information is available. (online friends, notifications, etc.). + } // ChangePasswordRequest::callback + + // ------------------------------------------------------------------------ + /** Sends a request to the server to see if any new information is + * available. (online friends, notifications, etc.). */ void CurrentUser::requestPoll() const { assert(m_state == US_SIGNED_IN); CurrentUser::PollRequest * request = new CurrentUser::PollRequest(); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("poll")); + request->addParameter("action", "poll"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - RequestManager::get()->addRequest(request); - } + request->queue(); + } // requestPoll() - /** - * Callback for the poll request. Parses the information and spawns notifications accordingly. + // ------------------------------------------------------------------------ + /** Callback for the poll request. Parses the information and spawns + * notifications accordingly. */ void CurrentUser::PollRequest::callback() { @@ -603,22 +670,27 @@ namespace Online std::string online_friends_string(""); if(getXMLData()->get("online", &online_friends_string) == 1) { - std::vector online_friends = StringUtils::splitToUInt(online_friends_string, ' '); + std::vector online_friends = + StringUtils::splitToUInt(online_friends_string, ' '); bool went_offline = false; - std::vector friends = CurrentUser::get()->getProfile()->getFriends(); - std::vector to_notify; + std::vector friends = + CurrentUser::get()->getProfile()->getFriends(); + std::vector to_notify; for(unsigned int i = 0; i < friends.size(); ++i) { bool now_online = false; std::vector::iterator iter = - std::find(online_friends.begin(),online_friends.end(), friends[i]); + std::find(online_friends.begin(), + online_friends.end(), friends[i]); if (iter != online_friends.end()) { now_online = true; online_friends.erase(iter); } - Profile * profile = ProfileManager::get()->getProfileByID(friends[i]); - Profile::RelationInfo * relation_info = profile->getRelationInfo(); + Profile * profile = + ProfileManager::get()->getProfileByID(friends[i]); + Profile::RelationInfo * relation_info = + profile->getRelationInfo(); if( relation_info->isOnline() ) { if (!now_online) @@ -633,7 +705,9 @@ namespace Online { //User came online relation_info->setOnline(true); - profile->setFriend(); //Do this because a user might have accepted a pending friend request. + // Do this because a user might have accepted + // a pending friend request. + profile->setFriend(); to_notify.push_back(profile->getUserName()); } } @@ -642,24 +716,30 @@ namespace Online if(to_notify.size() > 0) { - irr::core::stringw message(""); + core::stringw message(""); if(to_notify.size() == 1) { - message = to_notify[0] + irr::core::stringw(_(" is now online.")); + message = _("%s is now online.", to_notify[0]); } else if(to_notify.size() == 2) { - message = to_notify[0] + irr::core::stringw(_(" and ")) + to_notify[1] + irr::core::stringw(_(" are now online.")); + message = _("%s and %s are now online.", + to_notify[0], to_notify[1] ); } else if(to_notify.size() == 3) { - message = to_notify[0] + irr::core::stringw(_(", ")) + to_notify[1] + irr::core::stringw(_(" and ")) + to_notify[2] + irr::core::stringw(_(" are now online.")); + message = _("%s, %s and %s are now online.", + to_notify[0], to_notify[1], to_notify[2]); } else if(to_notify.size() > 3) { - message = StringUtils::toWString(to_notify.size()) + irr::core::stringw(_(" friends are now online.")); + message = _("%d friends are now online.", + to_notify.size()); } - GUIEngine::DialogQueue::get()->pushDialog( new NotificationDialog(NotificationDialog::T_Friends, message), false); + NotificationDialog *dia = + new NotificationDialog(NotificationDialog::T_Friends, + message); + GUIEngine::DialogQueue::get()->pushDialog(dia, false); OnlineProfileFriends::getInstance()->refreshFriendsList(); } else if(went_offline) @@ -679,7 +759,8 @@ namespace Online const XMLNode * node = getXMLData()->getNode(i); if(node->getName() == "new_friend_request") { - Profile::RelationInfo * ri = new Profile::RelationInfo("New", false, true, true); + Profile::RelationInfo * ri = + new Profile::RelationInfo("New", false, true, true); Profile * p = new Profile(node); p->setRelationInfo(ri); ProfileManager::get()->addPersistent(p); @@ -688,44 +769,50 @@ namespace Online } if(friend_request_count > 0) { - irr::core::stringw message(""); + core::stringw message(""); if(friend_request_count > 1) { - message = irr::core::stringw(_("You have ")) + StringUtils::toWString(friend_request_count) + irr::core::stringw(_(" new friend requests!.")); + message = _("You have %d new friend requests!", + friend_request_count); } else { message = _("You have a new friend request!"); } - GUIEngine::DialogQueue::get()->pushDialog( new NotificationDialog(NotificationDialog::T_Friends, message), false); + NotificationDialog *dia = + new NotificationDialog(NotificationDialog::T_Friends, + message); + GUIEngine::DialogQueue::get()->pushDialog(dia, false); OnlineProfileFriends::getInstance()->refreshFriendsList(); } } // FIXME show connection error?? // Perhaps show something after 2 misses. - } - // ============================================================================ - /** - * Sends a message to the server that the client has been closed, if a user is signed in. + } // PollRequest::callback + + // ------------------------------------------------------------------------ + /** Sends a message to the server that the client has been closed, if a + * user is signed in. */ void CurrentUser::onSTKQuit() const { if(isRegisteredUser()) { - HTTPRequest * request = new HTTPRequest(true, RequestManager::HTTP_MAX_PRIORITY); + HTTPRequest * request = + new HTTPRequest(true, RequestManager::HTTP_MAX_PRIORITY); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("client-quit")); + request->addParameter("action", "client-quit"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); - RequestManager::get()->addRequest(request); + request->queue(); } } - // ============================================================================ - /** - * Sends a confirmation to the server that an achievement has been completed, if a user is signed in. - * \param achievement_id the id of the achievement that got completed + // ------------------------------------------------------------------------ + /** Sends a confirmation to the server that an achievement has been + * completed, if a user is signed in. + * \param achievement_id the id of the achievement that got completed. */ void CurrentUser::onAchieving(uint32_t achievement_id) const { @@ -733,17 +820,17 @@ namespace Online { HTTPRequest * request = new HTTPRequest(true); request->setServerURL("client-user.php"); - request->addParameter("action", std::string("achieving")); + request->addParameter("action", "achieving"); request->addParameter("token", getToken()); request->addParameter("userid", getID()); request->addParameter("achievementid", achievement_id); - RequestManager::get()->addRequest(request); + request->queue(); } - } + } // onAchieving - // ============================================================================ + // ------------------------------------------------------------------------ /** \return the username if signed in. */ - irr::core::stringw CurrentUser::getUserName() const + core::stringw CurrentUser::getUserName() const { if((m_state == US_SIGNED_IN ) || (m_state == US_GUEST)) { @@ -751,9 +838,9 @@ namespace Online return m_profile->getUserName(); } return _("Currently not signed in"); - } + } // getUserName - // ============================================================================ + // ------------------------------------------------------------------------ /** \return the online id. */ uint32_t CurrentUser::getID() const { @@ -763,5 +850,6 @@ namespace Online return m_profile->getID(); } return 0; - } + } // getID + } // namespace Online diff --git a/src/online/current_user.hpp b/src/online/current_user.hpp index c75e62604..d7d4b106a 100644 --- a/src/online/current_user.hpp +++ b/src/online/current_user.hpp @@ -52,82 +52,100 @@ namespace Online US_SIGNING_OUT }; + // ---------------------------------------------------------------- class SignInRequest : public XMLRequest { virtual void callback (); public: - SignInRequest(bool manage_memory = false) : XMLRequest(manage_memory) {} - }; + SignInRequest(bool manage_memory = false) + : XMLRequest(manage_memory, /*priority*/10) {} + }; // SignInRequest + // ---------------------------------------------------------------- class SignOutRequest : public XMLRequest { virtual void callback (); public: - SignOutRequest() : XMLRequest(true) {} - }; + SignOutRequest() : XMLRequest(true,/*priority*/10) {} + }; // SignOutRequest + // ---------------------------------------------------------------- class ServerCreationRequest : public XMLRequest { virtual void callback (); uint32_t m_created_server_id; public: ServerCreationRequest() : XMLRequest() {} - const uint32_t getCreatedServerID() const { assert(isDone()); return m_created_server_id;} - }; + const uint32_t getCreatedServerID() const + { + assert(isDone()); + return m_created_server_id; + } // getCreatedServerID + }; // ServerCreationRequest + + // ---------------------------------------------------------------- class ServerJoinRequest : public XMLRequest { virtual void callback (); public: ServerJoinRequest() : XMLRequest() {} - }; + }; // ServerJoinRequest + // ---------------------------------------------------------------- class SetAddonVoteRequest : public XMLRequest { virtual void callback (); public: SetAddonVoteRequest() : XMLRequest() {} - }; + }; // SetAddonVoteRequest + // ---------------------------------------------------------------- class FriendRequest : public XMLRequest { virtual void callback (); public: FriendRequest() : XMLRequest(true) {} - }; + }; // FriendRequest + // ---------------------------------------------------------------- class AcceptFriendRequest : public XMLRequest { virtual void callback (); public: AcceptFriendRequest() : XMLRequest(true) {} - }; + }; // AcceptFriendRequest + // ---------------------------------------------------------------- class DeclineFriendRequest : public XMLRequest { virtual void callback (); public: DeclineFriendRequest() : XMLRequest(true) {} - }; + }; // DeclineFriendRequest + // ---------------------------------------------------------------- class RemoveFriendRequest : public XMLRequest { virtual void callback (); public: RemoveFriendRequest() : XMLRequest(true) {} - }; + }; // RemoveFriendRequest + // ---------------------------------------------------------------- class CancelFriendRequest : public XMLRequest { virtual void callback (); public: CancelFriendRequest() : XMLRequest(true) {} - }; + }; // CancelFriendRequest + // ---------------------------------------------------------------- class PollRequest : public XMLRequest { virtual void callback (); public: PollRequest() : XMLRequest(true) {} - }; + }; // PollRequest + // ---------------------------------------------------------------- class ChangePasswordRequest : public XMLRequest { virtual void callback (); public: ChangePasswordRequest() : XMLRequest(true) {} - }; + }; // ChangePasswordRequest private: @@ -136,7 +154,7 @@ namespace Online UserState m_state; Profile * m_profile; - bool getSaveSession() const { return m_save_session; } + bool saveSession() const { return m_save_session; } CurrentUser(); diff --git a/src/online/profile.cpp b/src/online/profile.cpp index fbddd2f05..e84afe1cd 100644 --- a/src/online/profile.cpp +++ b/src/online/profile.cpp @@ -142,7 +142,7 @@ namespace Online{ assert(CurrentUser::get()->isRegisteredUser() && !m_is_current_user); AchievementsRequest * request = new AchievementsRequest(); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("get-achievements")); + request->addParameter("action","get-achievements"); request->addParameter("token", CurrentUser::get()->getToken()); request->addParameter("userid", CurrentUser::get()->getID()); request->addParameter("visitingid", m_id); @@ -198,7 +198,7 @@ namespace Online{ assert(CurrentUser::get()->isRegisteredUser()); FriendsListRequest * request = new FriendsListRequest(); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("get-friends-list")); + request->addParameter("action","get-friends-list"); request->addParameter("token", CurrentUser::get()->getToken()); request->addParameter("userid", CurrentUser::get()->getID()); request->addParameter("visitingid", m_id); diff --git a/src/online/servers_manager.cpp b/src/online/servers_manager.cpp index 248441c4c..9f47739f4 100644 --- a/src/online/servers_manager.cpp +++ b/src/online/servers_manager.cpp @@ -76,7 +76,7 @@ namespace Online{ { request = new RefreshRequest(); request->setServerURL("client-user.php"); - request->addParameter("action",std::string("get_server_list")); + request->addParameter("action","get_server_list"); if (request_now) RequestManager::get()->addRequest(request); } diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index f1bc44cc6..cc73bfad8 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -114,7 +114,8 @@ namespace StringUtils } // getExtension //------------------------------------------------------------------------- - /** Checks if the input string is not empty. ( = has characters different from a space) + /** Checks if the input string is not empty. ( = has characters different + * from a space). */ bool notEmpty(const irr::core::stringw& input) { @@ -523,7 +524,13 @@ namespace StringUtils } // timeToString // ------------------------------------------------------------------------ - + /** Replaces values in a string. + * \param other string in which to replace stuff + * \param from pattern to remove from the string + * \param to pattern to insert instead + * \return a string with all occurrences of \c from replaced by + * occurrences of \c to + */ std::string replace(const std::string& other, const std::string& from, const std::string& to) { @@ -725,10 +732,6 @@ namespace StringUtils return version; } // versionToInt - const char* boolstr(bool b) - { - return (b ? "true" : "false"); - } } // namespace StringUtils diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index 7b3063663..71649b561 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -44,35 +44,59 @@ namespace StringUtils std::string getExtension(const std::string& filename); bool notEmpty(const irr::core::stringw& input); + std::string timeToString(float time); + std::string toUpperCase(const std::string&); + std::string toLowerCase(const std::string&); + std::vector split(const std::string& s, char c, + bool keepSplitChar=false); + std::vector split(const irr::core::stringw& s, + char c, bool keepSplitChar=false); + std::vector splitToUInt(const std::string& s, char c, + bool keepSplitChar=false); + std::vector splitPath(const std::string& path); + std::string replace(const std::string& other, const std::string& from, const std::string& to); + irr::core::stringw decodeFromHtmlEntities(const std::string& input); + + std::string encodeToHtmlEntities(const irr::core::stringw &output); + + /** Compute a simple hash of a string */ + unsigned int simpleHash(const char* input); + + // ------------------------------------------------------------------------ template std::string toString (const T& any) { std::ostringstream oss; oss << any ; return oss.str(); - } + } // toString template + // ------------------------------------------------------------------------ + /** Specialisiation for bools to return 'true' or 'false'/ + */ + static std::string toString(bool b) + { + return (b ? "true" : "false"); + } // toString(bool) + + // ------------------------------------------------------------------------ template irr::core::stringw toWString (const T& any) { std::ostringstream oss; oss << any ; return oss.str().c_str(); - } + } // toWString - /** Converts a time in seconds into a string of the form mm:ss:hh (minutes, - * seconds, 1/100 seconds. - * \param time Time in seconds. - */ - std::string timeToString(float time); + // ------------------------------------------------------------------------ /** Convert the contents in string \a rep to type \a T, if conversion fails false is returned and the value of \a x is unchanged, if true is returned the conversation was successfull. */ template bool fromString(const std::string& rep, T& x) { - // this is necessary so that if "x" is not modified if the conversion fails + // Don't modify x" if the conversion fails by using a temp T temp; std::istringstream iss(rep); iss >> temp; @@ -86,17 +110,7 @@ namespace StringUtils x = temp; return true; } - } - - std::string toUpperCase(const std::string&); - std::string toLowerCase(const std::string&); - std::vector split(const std::string& s, char c, - bool keepSplitChar=false); - std::vector split(const irr::core::stringw& s, - char c, bool keepSplitChar=false); - std::vector splitToUInt(const std::string& s, char c, - bool keepSplitChar=false); - std::vector splitPath(const std::string& path); + } // fromString // ------------------------------------------------------------------------ /** @@ -113,22 +127,25 @@ namespace StringUtils * and this is in the best case very confusing for translators (which get * to see two strings instead of one sentence, see xgettext manual * for why this is a bad idea) - * In order to accomodate translations even more, you can use formats %0, %1, %2, etc... - * where %0 is replaced by the first argument, %1 by the second argument, etc... - * This allows translated strings to not necessarily insert the words in the same order as - * in english. + * In order to accomodate translations even more, you can use formats + * %0, %1, %2, etc..., where %0 is replaced by the first argument, %1 by + * the second argument, etc... This allows translated strings to not + * necessarily insert the words in the same order as in English. * \param s String in which all %s or %d are replaced. * \param all_vals Value(s) to replace all %s or %d with. */ - std::string insertValues(const std::string &s, std::vector& all_vals); + std::string insertValues(const std::string &s, + std::vector& all_vals); - /** This no-op is useful when using variadic arguments, so that we may support the case with 0 variadic arguments */ + /** This no-op is useful when using variadic arguments, so that we may + * support the case with 0 variadic arguments */ template T1 insertValues(const T1& s) { return s; } // ------------------------------------------------------------------------ /** Same as above but for wide-strings */ - irr::core::stringw insertValues(const irr::core::stringw &s, std::vector& all_vals); + irr::core::stringw insertValues(const irr::core::stringw &s, + std::vector& all_vals); // ------------------------------------------------------------------------ // Note: the order in which the templates are specified is important, since @@ -148,8 +165,9 @@ namespace StringUtils dummy << v5; all_vals.push_back(dummy.str()); dummy.str(""); dummy << v6; all_vals.push_back(dummy.str()); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v6) + // ------------------------------------------------------------------------ template std::string insertValues(const std::string &s, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, @@ -163,8 +181,9 @@ namespace StringUtils dummy << v4; all_vals.push_back(dummy.str()); dummy.str(""); dummy << v5; all_vals.push_back(dummy.str()); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v5) + // ------------------------------------------------------------------------ template std::string insertValues(const std::string &s, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) @@ -176,8 +195,9 @@ namespace StringUtils dummy << v3; all_vals.push_back(dummy.str()); dummy.str(""); dummy << v4; all_vals.push_back(dummy.str()); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v4) + // ------------------------------------------------------------------------ /** Shortcut insert_values taking three values, see above for * full docs. * \param s String in which all %s or %d are replaced. @@ -193,7 +213,7 @@ namespace StringUtils dummy << v2; all_vals.push_back(dummy.str()); dummy.str(""); dummy << v3; all_vals.push_back(dummy.str()); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v3) // ------------------------------------------------------------------------ // Note: the order in which the templates are specified is important, since @@ -213,7 +233,7 @@ namespace StringUtils dummy << v2; all_vals.push_back(dummy.str()); dummy.str(""); return insertValues(s, all_vals); - } + } // insertValues(s, v1, v2) // ------------------------------------------------------------------------ /** Shortcut insert_values taking three values, see above for * full docs. @@ -228,7 +248,7 @@ namespace StringUtils dummy << v1; all_vals.push_back(dummy.str()); dummy.str(""); return insertValues(s, all_vals); - } + } // insertValues(s, v1) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -245,7 +265,7 @@ namespace StringUtils all_vals.push_back( irr::core::stringw(v5) ); all_vals.push_back( irr::core::stringw(v6) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v6) // ------------------------------------------------------------------------ @@ -262,7 +282,7 @@ namespace StringUtils all_vals.push_back( irr::core::stringw(v4) ); all_vals.push_back( irr::core::stringw(v5) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v5) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -276,7 +296,7 @@ namespace StringUtils all_vals.push_back( irr::core::stringw(v3) ); all_vals.push_back( irr::core::stringw(v4) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v4) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -290,7 +310,7 @@ namespace StringUtils all_vals.push_back( irr::core::stringw(v2) ); all_vals.push_back( irr::core::stringw(v3) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1, ..., v3) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -302,7 +322,7 @@ namespace StringUtils all_vals.push_back( irr::core::stringw(v1) ); all_vals.push_back( irr::core::stringw(v2) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1, v2) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -312,7 +332,7 @@ namespace StringUtils std::vector all_vals; all_vals.push_back( irr::core::stringw(v1) ); return insertValues(s, all_vals); - } + } // insertValues(s, v1) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -323,7 +343,7 @@ namespace StringUtils { irr::core::stringw s(chars); return insertValues(s, v1, v2, v3, v4, v5); - } + } // insertValues(s, v1, ..., v5) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -333,7 +353,7 @@ namespace StringUtils { irr::core::stringw s(chars); return insertValues(s, v1, v2, v3); - } + } // insertValues(s, v1, ..., v3) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -343,7 +363,7 @@ namespace StringUtils { irr::core::stringw s(chars); return insertValues(s, v1, v2); - } + } // insertValues(s, v1, v2) // ------------------------------------------------------------------------ /** Like the other ones above but for wide strings */ @@ -352,7 +372,7 @@ namespace StringUtils { irr::core::stringw s(chars); return insertValues(s, v1); - } + } // insertValues(s, v1) // ------------------------------------------------------------------------ /** Like the other ones above but for C strings */ @@ -362,7 +382,7 @@ namespace StringUtils { std::string s(chars); return insertValues(s, v1, v2, v3); - } + } // insertValues(s, v1, ..., v3) // ------------------------------------------------------------------------ /** Like the other ones above but for C strings */ @@ -372,7 +392,7 @@ namespace StringUtils { std::string s(chars); return insertValues(s, v1, v2); - } + } // insertValues(s, v1, v2) // ------------------------------------------------------------------------ /** Like the other ones above but for C strings */ @@ -381,8 +401,9 @@ namespace StringUtils { std::string s(chars); return insertValues(s, v1); - } + } // insertValues(s, v1) + // ------------------------------------------------------------------------ template bool parseString(const char* input, T* output) { @@ -395,30 +416,15 @@ namespace StringUtils return false; } return true; - } + } // parseString + // ------------------------------------------------------------------------ template bool parseString(const std::string& input, T* output) { return parseString(input.c_str(), output); - } + } // parseString - /** - * \param other string in which to replace stuff - * \param from pattern to remove from the string - * \param to pattern to insert instead - * \return a string with all occurrences of \c from replaced by occurrences of \c to - */ - std::string replace(const std::string& other, const std::string& from, const std::string& to); - - irr::core::stringw decodeFromHtmlEntities(const std::string& input); - - std::string encodeToHtmlEntities(const irr::core::stringw &output); - - /** Compute a simple hash of a string */ - unsigned int simpleHash(const char* input); - - const char* boolstr(bool b); } // namespace StringUtils #endif From f338fbacb1eaacb02255507c05f92eb705a3c0bb Mon Sep 17 00:00:00 2001 From: vincentlj Date: Tue, 14 Jan 2014 14:22:01 +0000 Subject: [PATCH 300/412] SSAO: Use a proper rand() function to generate fragment local coordinate system. This new level of randomness get rid of most banding effect, SSAO now looks quite good. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@15072 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/shaders/ssao.frag | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index ee3ed0551..39636e05d 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -13,6 +13,12 @@ const float radius = .4f; const float invSamples = strengh / SAMPLES; +// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float rand(vec2 co) +{ + return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453); +} + void main(void) { vec4 cur = texture2D(normals_and_depth, uv); @@ -24,8 +30,13 @@ void main(void) vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0)); // Workaround for nvidia and skyboxes float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2 || curdepth > 0.999) discard; - vec3 tangent = normalize(cross(norm, norm.yzx)); + if (len < 0.2 || curdepth > 0.99) discard; + // Make a tangent as random as possible + vec3 randvect; + randvect.x = rand(uv); + randvect.y = rand(vec2(randvect.x, FragPos.z)); + randvect.z = rand(randvect.xy); + vec3 tangent = normalize(cross(norm, randvect)); vec3 bitangent = cross(norm, tangent); float bl = 0.0; @@ -45,7 +56,7 @@ void main(void) occluderPos /= occluderPos.w; bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); - bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) / smoothstep(0., 1., curdepth) : 0.; + bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) : 0.; } // output the result From e6bfc695cbdd02fd319840b05f2ad7877eaabd96 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:47:24 +1100 Subject: [PATCH 301/412] SSAO: Honor the user parameter. --- src/graphics/render.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 8793085f5..d9fe82358 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -752,7 +752,8 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, m_video_driver->setRenderTarget(irr_driver->getRTT(RTT_SSAO), true, false, SColor(255, 255, 255, 255)); - m_post_processing->renderSSAO(irr_driver->getInvProjMatrix(), irr_driver->getProjMatrix()); + if(UserConfigParams::m_ssao) + m_post_processing->renderSSAO(irr_driver->getInvProjMatrix(), irr_driver->getProjMatrix()); // Blur it to reduce noise. if(UserConfigParams::m_ssao == 1) From 0adddd44012114abb422daaca2217c455aee47f8 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:48:40 +1100 Subject: [PATCH 302/412] STKMesh: Force GL_REPEAT to wrapped texture component. It fixes bad uv in valley. --- src/graphics/stkmesh.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 57cdcec0f..c8bc91b7b 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -253,6 +253,8 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glBindTexture(GL_TEXTURE_2D, mesh.textures); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glUniform1f(ObjectRefShader::uniform_texture, 0); } if (type == irr_driver->getShader(ES_OBJECTPASS)) @@ -263,12 +265,15 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glBindTexture(GL_TEXTURE_2D, mesh.textures); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glUniform1f(ObjectShader::uniform_texture, 0); } glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); video::SMaterial material; material.MaterialType = irr_driver->getShader(ES_RAIN); From 949877b8268e01f4525793df3201ae18d07928f5 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:49:37 +1100 Subject: [PATCH 303/412] Fixed compiler warning. --- src/utils/string_utils.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index 71649b561..f1674c404 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -75,7 +75,8 @@ namespace StringUtils // ------------------------------------------------------------------------ /** Specialisiation for bools to return 'true' or 'false'/ */ - static std::string toString(bool b) + template + std::string toString(bool &b) { return (b ? "true" : "false"); } // toString(bool) From bc6be28f7d061bdb9ac70c485075d45cc22da39e Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Tue, 14 Jan 2014 19:50:51 -0500 Subject: [PATCH 304/412] Add ignore file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..7a2735b63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +cmake_build/ +dependencies/ From 0464274b84df9001cf2341473c48cad605695103 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:51:01 +1100 Subject: [PATCH 305/412] STKMesh: Fix glUniform wrong call --- src/graphics/stkmesh.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index c8bc91b7b..c01ec6951 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -255,7 +255,7 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUniform1f(ObjectRefShader::uniform_texture, 0); + glUniform1i(ObjectRefShader::uniform_texture, 0); } if (type == irr_driver->getShader(ES_OBJECTPASS)) { @@ -267,7 +267,7 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUniform1f(ObjectShader::uniform_texture, 0); + glUniform1i(ObjectShader::uniform_texture, 0); } glBindVertexArray(mesh.vao); From 4f740fd6a57afb0d5352eed6b7ee3c85d4dc2e6d Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:51:48 +1100 Subject: [PATCH 306/412] Some refactoring --- src/graphics/post_processing.cpp | 206 +++++-------------------------- 1 file changed, 31 insertions(+), 175 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 26495f655..2edc855bf 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -216,10 +216,27 @@ static void initQuadVBO() glBindBuffer(GL_ARRAY_BUFFER, 0); } +static GLuint createVAO(GLuint Program) +{ + if (!quad_vbo) + initQuadVBO(); + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + GLuint attrib_position = glGetAttribLocation(Program, "Position"); + GLuint attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + return vao; +} + namespace BloomShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_texture, uniform_low; GLuint vao = 0; @@ -227,28 +244,15 @@ namespace BloomShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_texture = glGetUniformLocation(Program, "tex"); uniform_low = glGetUniformLocation(Program, "low"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace BloomBlendShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_texture, uniform_low; GLuint vao = 0; @@ -256,27 +260,14 @@ namespace BloomBlendShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_texture = glGetUniformLocation(Program, "tex"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace PPDisplaceShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_dtex, uniform_viz; GLuint vao = 0; @@ -284,29 +275,16 @@ namespace PPDisplaceShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_dtex = glGetUniformLocation(Program, "dtex"); uniform_viz = glGetUniformLocation(Program, "viz"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace ColorLevelShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_inlevel, uniform_outlevel; GLuint vao = 0; @@ -314,29 +292,16 @@ namespace ColorLevelShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_inlevel = glGetUniformLocation(Program, "inlevel"); uniform_outlevel = glGetUniformLocation(Program, "outlevel"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace PointLightShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_invproj, uniform_viewm; GLuint vao = 0; @@ -345,8 +310,6 @@ namespace PointLightShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_ntex = glGetUniformLocation(Program, "ntex"); uniform_center = glGetUniformLocation(Program, "center[0]"); uniform_col = glGetUniformLocation(Program, "col[0]"); @@ -354,24 +317,13 @@ namespace PointLightShader uniform_spec = glGetUniformLocation(Program, "spec"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_viewm = glGetUniformLocation(Program, "viewm"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace LightBlendShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_diffuse, uniform_specular, uniform_ambient_occlusion, uniform_specular_map, uniform_ambient; GLuint vao = 0; @@ -380,31 +332,18 @@ namespace LightBlendShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/lightblend.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_diffuse = glGetUniformLocation(Program, "diffuse"); uniform_specular = glGetUniformLocation(Program, "specular"); uniform_ambient_occlusion = glGetUniformLocation(Program, "ambient_occlusion"); uniform_specular_map = glGetUniformLocation(Program, "specular_map"); uniform_ambient = glGetUniformLocation(Program, "ambient"); - - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace Gaussian6HBlurShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_pixel; GLuint vao = 0; @@ -413,27 +352,15 @@ namespace Gaussian6HBlurShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6h.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_pixel = glGetUniformLocation(Program, "pixel"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace Gaussian3HBlurShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_pixel; GLuint vao = 0; @@ -442,27 +369,15 @@ namespace Gaussian3HBlurShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3h.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_pixel = glGetUniformLocation(Program, "pixel"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace Gaussian6VBlurShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_pixel; GLuint vao = 0; @@ -471,27 +386,15 @@ namespace Gaussian6VBlurShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6v.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_pixel = glGetUniformLocation(Program, "pixel"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace Gaussian3VBlurShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_pixel; GLuint vao = 0; @@ -500,27 +403,15 @@ namespace Gaussian3VBlurShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3v.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_pixel = glGetUniformLocation(Program, "pixel"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace PassThroughShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_texture; GLuint vao = 0; @@ -529,26 +420,14 @@ namespace PassThroughShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_texture = glGetUniformLocation(Program, "texture"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } namespace SSAOShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_normals_and_depth, uniform_invprojm, uniform_projm, uniform_samplePoints; float SSAOSamples[64]; @@ -558,22 +437,11 @@ namespace SSAOShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ssao.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_normals_and_depth = glGetUniformLocation(Program, "normals_and_depth"); uniform_invprojm = glGetUniformLocation(Program, "invprojm"); uniform_projm = glGetUniformLocation(Program, "projm"); uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); for (unsigned i = 0; i < 16; i++) { // Generate x/y component between -1 and 1 @@ -601,7 +469,6 @@ namespace SSAOShader namespace FogShader { GLuint Program = 0; - GLuint attrib_position, attrib_texcoord; GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_campos, uniform_ipvmat; GLuint vao = 0; @@ -610,8 +477,6 @@ namespace FogShader { initGL(); Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/fog.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_fogmax = glGetUniformLocation(Program, "fogmax"); uniform_startH = glGetUniformLocation(Program, "startH"); @@ -621,16 +486,7 @@ namespace FogShader uniform_col = glGetUniformLocation(Program, "col"); uniform_campos = glGetUniformLocation(Program, "campos"); uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); - if (!quad_vbo) - initQuadVBO(); - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); + vao = createVAO(Program); } } From c622ba258c6f5dbd5a73a9d056f002323ff04f22 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 11:56:34 +1100 Subject: [PATCH 307/412] Made stk-assets the default name of the assets data directory. --- src/io/file_manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 11797d6ce..43696b298 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -178,8 +178,8 @@ FileManager::FileManager() } addRootDirs(root_dir); - if( fileExists(root_dir+"../../data_supertuxkart")) - addRootDirs(root_dir+"../../data_supertuxkart"); + if( fileExists(root_dir+"../../stk-assets")) + addRootDirs(root_dir+"../../stk-assets"); if ( getenv ( "SUPERTUXKART_ROOT_PATH" ) != NULL ) addRootDirs(getenv("SUPERTUXKART_ROOT_PATH")); From 0a1016db71aa0cb239b7c18e5c9a489bcfde40e3 Mon Sep 17 00:00:00 2001 From: Joerg Henrichs Date: Wed, 15 Jan 2014 13:19:55 +1100 Subject: [PATCH 308/412] STKMesh: Some factorisation --- src/graphics/stkmesh.cpp | 107 +++++++++++++-------------------------- 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index c01ec6951..c9f5a985a 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -3,6 +3,24 @@ #include #include +static +GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride) +{ + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glEnableVertexAttribArray(attrib_normal); + glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); + glBindVertexArray(0); + return vao; +} + namespace ObjectRefShader { GLuint Program; @@ -21,23 +39,6 @@ namespace ObjectRefShader uniform_texture = glGetUniformLocation(Program, "texture"); } - GLuint createVAO(GLuint vbo, GLuint idx, size_t stride) - { - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glEnableVertexAttribArray(attrib_normal); - glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); - glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); - glBindVertexArray(0); - return vao; - } - void setProgramAndUniforms() { glUseProgram(Program); @@ -72,23 +73,6 @@ namespace ObjectShader uniform_texture = glGetUniformLocation(Program, "texture"); } - GLuint createVAO(GLuint vbo, GLuint idx, size_t stride) - { - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glEnableVertexAttribArray(attrib_normal); - glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); - glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); - glBindVertexArray(0); - return vao; - } - void setProgramAndUniforms() { glUseProgram(Program); @@ -109,38 +93,36 @@ static GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { initGL(); - GLMesh result; + GLMesh result = {}; if (!mb) return result; glGenBuffers(1, &(result.vertex_buffer)); glGenBuffers(1, &(result.index_buffer)); glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer); - const void* vertices=mb->getVertices(); - const u32 vertexCount=mb->getVertexCount(); - const irr::video::E_VERTEX_TYPE vType=mb->getVertexType(); - const u32 vertexSize = getVertexPitchFromType(vType); + const void* vertices = mb->getVertices(); + const u32 vertexCount = mb->getVertexCount(); + const irr::video::E_VERTEX_TYPE vType = mb->getVertexType(); + result.Stride = getVertexPitchFromType(vType); const c8* vbuf = static_cast(vertices); - core::array buffer; - buffer.set_used(vertexSize * vertexCount); - memcpy(buffer.pointer(), vertices, vertexSize * vertexCount); - vbuf = buffer.const_pointer(); - glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, vbuf, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertexCount * result.Stride, vbuf, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer); - const void* indices=mb->getIndices(); - u32 indexCount= mb->getIndexCount(); + const void* indices = mb->getIndices(); + u32 indexCount = mb->getIndexCount(); GLenum indexSize; switch (mb->getIndexType()) { case irr::video::EIT_16BIT: { - indexSize=sizeof(u16); + indexSize = sizeof(u16); + result.IndexType = GL_UNSIGNED_SHORT; break; } case irr::video::EIT_32BIT: { - indexSize=sizeof(u32); + indexSize = sizeof(u32); + result.IndexType = GL_UNSIGNED_INT; break; } default: @@ -178,27 +160,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) case scene::EPT_QUADS: assert(0 && "Unsupported primitive type"); } - switch (mb->getVertexType()) - { - case video::EVT_STANDARD: - result.Stride = sizeof(video::S3DVertex); - break; - case video::EVT_2TCOORDS: - result.Stride = sizeof(video::S3DVertex2TCoords); - break; - case video::EVT_TANGENTS: - result.Stride = sizeof(video::S3DVertexTangents); - break; - } - switch (mb->getIndexType()) - { - case video::EIT_16BIT: - result.IndexType = GL_UNSIGNED_SHORT; - break; - case video::EIT_32BIT: - result.IndexType = GL_UNSIGNED_INT; - break; - } ITexture *tex = mb->getMaterial().getTexture(0); if (tex) result.textures = static_cast(tex)->getOpenGLTextureName(); @@ -296,9 +257,13 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) if (mesh.vao) return; if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - mesh.vao = ObjectRefShader::createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.Stride); + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectRefShader::attrib_position, ObjectRefShader::attrib_texcoord, ObjectRefShader::attrib_normal, + mesh.Stride); if (type == irr_driver->getShader(ES_OBJECTPASS)) - mesh.vao = ObjectShader::createVAO(mesh.vertex_buffer, mesh.index_buffer, mesh.Stride); + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectShader::attrib_position, ObjectShader::attrib_texcoord, ObjectShader::attrib_normal, + mesh.Stride); } void STKMesh::render() From 4dd5ab3b65c47bf9fc9079b65b55b5282c1a4f79 Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Wed, 15 Jan 2014 18:20:53 +0100 Subject: [PATCH 309/412] README rewritten in Markdown. Fixed some minor mistakes too. --- README => README.md | 56 ++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) rename README => README.md (61%) diff --git a/README b/README.md similarity index 61% rename from README rename to README.md index c3a69fb1c..03267e3ee 100644 --- a/README +++ b/README.md @@ -1,41 +1,31 @@ -SuperTuxKart -============ +#SuperTuxKart SuperTuxKart is a free kart racing game. It is focusing on fun and not on realistic kart physics. Instruction can be found on the in-game help page. -The SuperTuxKart homepage can be found at: +The SuperTuxKart homepage can be found at: - http://supertuxkart.sourceforge.net - -The official SuperTuxKart forum is at. If you need support, +The official SuperTuxKart forum is at . If you need support, this would be the best place to start. - http://supertuxkart.sourceforge.net/forum - Hope you enjoy the game. - - The SuperTuxKart development team. + +-- The SuperTuxKart development team. -HARDWARE REQUIREMENTS -===================== -* You need a 3D graphics card. - NVIDIA GeForce 8xxx and higher - ATI Radeon HD 4xxx and higher - Intel HD 3000 and higher +##Hardware Requirements +* You need a 3D graphics card. (NVIDIA GeForce 8xxx and higher, ATI Radeon HD 4xxx and higher or Intel HD 3000 and higher) * You should have a CPU that's running at 1GHz or better. * You'll need at least 512 MB of free VRAM (video memory). * Disk space: 400MB * Ideally, you want a joystick with at least 6 buttons. -COMPILING SuperTuxkart -====================== +##Compiling SuperTuxKart -WINDOWS -------- +###Windows A project file for Visual Studio 9 (e.g. the free 2008 express -edition) is included in the sources in src/ide/vc9. A separate +edition) is included in the sources in `src/ide/vc9`. A separate dependency package is available on SuperTuxKart's sourceforge page, which includes all necessary libraries, header files, and dlls to compile and run the source code. @@ -43,36 +33,30 @@ and dlls to compile and run the source code. While compilation with cygwin is not officially supported, this has been done (check with the forum for details). -MAC OSX -------- +###Mac OS X The latest information about compilation on Mac are on our wiki: -http://supertuxkart.sourceforge.net/Building_and_packaging_on_OSX -The Xcode project file is in /src/ide/Xcode/, but it still + +The Xcode project file is in `/src/ide/Xcode/`, but it still requires that all dependencies are installed as explained on the wiki. -UNIX ----- -See INSTALL for details. +###UNIX +See `INSTALL` for details. -LICENSE -======= +##License This software is released under the GNU General Public License (GPL) which -can be found in the file 'LICENSE' in the same directory as this file. +can be found in the file `LICENSE` in the same directory as this file. Information about the licenses for artwork are contained in -data/licenses. +`data/licenses`. -3D COORDINATES -============== +##3D coordinates A reminder for those looking at the code and 3d models: STK : X right, Y up, Z forwards + Blender: X right, Y forwards, Z up The exporters perform the needed transform, so in Blender you just work with XY plane as ground, and things will appear fine in STK (using XZ as ground in the code, obviously). - - - From 2bb859dcd7a860450a10626c4f3a3ffb3d56a51f Mon Sep 17 00:00:00 2001 From: Deve Date: Wed, 15 Jan 2014 19:56:06 +0100 Subject: [PATCH 310/412] Actually testing commit. Update .gitignore file. --- .gitignore | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.gitignore b/.gitignore index 7a2735b63..16d0c2e7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,25 @@ +build/ +build-32/ +build-64/ +build-win/ cmake_build/ dependencies/ + +.config/ + +*.o +*.d +*.a +*.patch +*.diff +*.orig +*.rej +*.log +*.lib +*.dll +*.exe +*.vcxproj +*.vcxproj.filters + +packets_log.txt +history.dat From 57ea6ae0d06b4b1dc5734f64f679466ea0eae141 Mon Sep 17 00:00:00 2001 From: Deve Date: Wed, 15 Jan 2014 20:31:15 +0100 Subject: [PATCH 311/412] Update .gitignore file --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 16d0c2e7b..046449887 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,14 @@ cmake_build/ dependencies/ .config/ +supertuxkart-64 + +data/karts +data/library +data/music +data/sfx +data/textures +data/tracks *.o *.d From 472274561d61e5bdfc46699e6f7830a61baa6479 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Wed, 15 Jan 2014 18:41:17 -0500 Subject: [PATCH 312/412] Update INSTALL file --- INSTALL | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/INSTALL b/INSTALL index b6a196efb..b329fd6b5 100644 --- a/INSTALL +++ b/INSTALL @@ -1,19 +1,27 @@ SUPERTUXKART INSTALLATION INSTRUCTIONS ====================================== -General -------- +Note : If you obtained this source code from github, you also need to download the game assets from sourceforge using SVN. + svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets +Place the stk-assets folder next to the source root stk-code folder. +See http://supertuxkart.sourceforge.net/Source_control for more information + + +Building STK on Linux +-------------------- First, make sure that you have the following packages installed: - * OpenGL (or Mesa 3.0 or later) + * OpenGL (mesa) * OpenAL (recommended: openal-soft-devel) * Ogg (libogg-dev) * Vorbis (libvorbis-dev) * libcurl (libcurl-devel) * libbluetooth (bluez-devel) - * fribidi (fribidi-devel) - optional for right-to-left text +Ubuntu command : + sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev + Unpack the files from the tarball like this: tar xzf supertuxkart-*.tar.gz @@ -21,9 +29,6 @@ Unpack the files from the tarball like this: where '*' is the version of SuperTuxkart you downloaded - eg 0.8.0. Then: -* Build irrlicht (atm, this will be included in cmake soonish) - cd lib/irrlicht/source/Irrlicht - NDEBUG=1 make * Compile SuperTuxKart: mkdir cmake_build @@ -46,6 +51,7 @@ will be copied to /usr/local/bin. To change the default installation location, specify CMAKE_INSTALL_PREFIX when running cmake, e.g.: cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk + Building STK on OS X -------------------- See http://supertuxkart.sourceforge.net/Building_and_packaging_on_OSX From da7bad92e63351ed23a1cb88123224eaf1f4b69c Mon Sep 17 00:00:00 2001 From: hiker Date: Thu, 16 Jan 2014 15:29:47 +1100 Subject: [PATCH 313/412] Don't return error code if a file to be removed does not exist. Improved error handling in addons.xml download. --- src/io/file_manager.cpp | 9 +- src/io/file_manager.cpp~ | 1087 +++++++++++++++++++++++++++++++++++ src/online/http_request.cpp | 12 +- 3 files changed, 1103 insertions(+), 5 deletions(-) create mode 100644 src/io/file_manager.cpp~ diff --git a/src/io/file_manager.cpp b/src/io/file_manager.cpp index 43696b298..601071f6c 100644 --- a/src/io/file_manager.cpp +++ b/src/io/file_manager.cpp @@ -1037,11 +1037,16 @@ void FileManager::checkAndCreateDirForAddons(const std::string &dir) } // checkAndCreateDirForAddons // ---------------------------------------------------------------------------- -/** Removes the specified file, returns true if successful, or false - * if the file is not a regular file or can not be removed. +/** Removes the specified file. + * \return True if successful, or false if the file is not a regular file or + * can not be removed. */ bool FileManager::removeFile(const std::string &name) const { + // If the file does not exists, everything is fine + if(!fileExists(name)) + return true; + struct stat mystat; if(stat(name.c_str(), &mystat) < 0) return false; if( S_ISREG(mystat.st_mode)) diff --git a/src/io/file_manager.cpp~ b/src/io/file_manager.cpp~ new file mode 100644 index 000000000..43696b298 --- /dev/null +++ b/src/io/file_manager.cpp~ @@ -0,0 +1,1087 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2004 Steve Baker +// Copyright (C) 2008-2013 Steve Baker, Joerg Henrichs +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#include "io/file_manager.hpp" + +#include "config/user_config.hpp" +#include "graphics/irr_driver.hpp" +#include "graphics/material_manager.hpp" +#include "karts/kart_properties_manager.hpp" +#include "tracks/track_manager.hpp" +#include "utils/command_line.hpp" +#include "utils/log.hpp" +#include "utils/string_utils.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +// For mkdir +#if !defined(WIN32) +# include +# include +# include +# include +#else +# include +# include +# include +# ifndef __CYGWIN__ + /*Needed by the remove directory function */ +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +# endif +#endif + + +std::vector FileManager::m_root_dirs; + +#ifdef __APPLE__ +// dynamic data path detection onmac +# include + +bool macSetBundlePathIfRelevant(std::string& data_dir) +{ + Log::debug("FileManager", "Checking whether we are using an app bundle... "); + // the following code will enable STK to find its data when placed in an + // app bundle on mac OS X. + // returns true if path is set, returns false if path was not set + char path[1024]; + CFBundleRef main_bundle = CFBundleGetMainBundle(); assert(main_bundle); + CFURLRef main_bundle_URL = CFBundleCopyBundleURL(main_bundle); + assert(main_bundle_URL); + CFStringRef cf_string_ref = CFURLCopyFileSystemPath(main_bundle_URL, + kCFURLPOSIXPathStyle); + assert(cf_string_ref); + CFStringGetCString(cf_string_ref, path, 1024, kCFStringEncodingASCII); + CFRelease(main_bundle_URL); + CFRelease(cf_string_ref); + + std::string contents = std::string(path) + std::string("/Contents"); + if(contents.find(".app") != std::string::npos) + { + Log::debug("FileManager", "yes\n"); + // executable is inside an app bundle, use app bundle-relative paths + data_dir = contents + std::string("/Resources/"); + return true; + } + else + { + Log::debug("FileManager", "no\n"); + return false; + } +} +#endif + +// ============================================================================ +FileManager* file_manager = 0; + +/** With irrlicht the constructor creates a NULL device. This is necessary to + * handle the Chicken/egg problem with irrlicht: access to the file system + * is given from the device, but we can't create the device before reading + * the user_config file (for resolution, fullscreen). So we create a dummy + * device here to begin with, which is then later (once the real device + * exists) changed in reInit(). + * + */ +FileManager::FileManager() +{ + m_subdir_name.resize(ASSET_COUNT); + m_subdir_name[CHALLENGE ] = "challenges"; + m_subdir_name[FONT ] = "fonts"; + m_subdir_name[GFX ] = "gfx"; + m_subdir_name[GRANDPRIX ] = "grandprix"; + m_subdir_name[GUI ] = "gui"; + m_subdir_name[MODEL ] = "models"; + m_subdir_name[MUSIC ] = "music"; + m_subdir_name[TRANSLATION] = "po"; + m_subdir_name[TEXTURE ] = "textures"; + m_subdir_name[SFX ] = "sfx"; + m_subdir_name[SKIN ] = "skins"; + m_subdir_name[SHADER ] = "shaders"; +#ifdef __APPLE__ + // irrLicht's createDevice method has a nasty habit of messing the CWD. + // since the code above may rely on it, save it to be able to restore + // it after. + char buffer[256]; + getcwd(buffer, 256); +#endif + +#ifdef __APPLE__ + chdir( buffer ); +#endif + + m_file_system = irr_driver->getDevice()->getFileSystem(); + m_file_system->grab(); + + irr::io::path exe_path; + + // Search for the root directory + // ============================= + + // Also check for data dirs relative to the path of the executable. + // This is esp. useful for Visual Studio, since it's not necessary + // to define the working directory when debugging, it works automatically. + std::string root_dir; + if(m_file_system->existFile(CommandLine::getExecName().c_str())) + exe_path = m_file_system->getFileDir(CommandLine::getExecName().c_str()); + if(exe_path.size()==0 || exe_path[exe_path.size()-1]!='/') + exe_path += "/"; + if ( getenv ( "SUPERTUXKART_DATADIR" ) != NULL ) + root_dir = std::string(getenv("SUPERTUXKART_DATADIR"))+"/" ; +#ifdef __APPLE__ + else if( macSetBundlePathIfRelevant( root_dir ) ) { root_dir = root_dir + "data/"; } +#endif + else if(m_file_system->existFile("data")) + root_dir = "data/" ; + else if(m_file_system->existFile("../data")) + root_dir = "../data/" ; + else if(m_file_system->existFile(exe_path+"data")) + root_dir = (exe_path+"data/").c_str(); + else if(m_file_system->existFile(exe_path+"/../data")) + { + root_dir = exe_path.c_str(); + root_dir += "/../data/"; + } + else + { +#ifdef SUPERTUXKART_DATADIR + root_dir = SUPERTUXKART_DATADIR; + if(root_dir.size()==0 || root_dir[root_dir.size()-1]!='/') + root_dir+='/'; + +#else + root_dir = "/usr/local/share/games/supertuxkart/"; +#endif + } + + addRootDirs(root_dir); + if( fileExists(root_dir+"../../stk-assets")) + addRootDirs(root_dir+"../../stk-assets"); + if ( getenv ( "SUPERTUXKART_ROOT_PATH" ) != NULL ) + addRootDirs(getenv("SUPERTUXKART_ROOT_PATH")); + + checkAndCreateConfigDir(); + checkAndCreateAddonsDir(); + checkAndCreateScreenshotDir(); + +#ifdef WIN32 + redirectOutput(); + +#endif + + // We can't use _() here, since translations will only be initalised + // after the filemanager (to get the path to the tranlsations from it) + for(unsigned int i=0; i dir_found; + dir_found.resize(ASSET_COUNT, false); + for(unsigned int i=0; idrop(); +} // dropFileSystem + +//----------------------------------------------------------------------------- +/** This function is used to re-initialise the file-manager after reading in + * the user configuration data. +*/ +void FileManager::reInit() +{ + m_file_system = irr_driver->getDevice()->getFileSystem(); + m_file_system->grab(); + + // Note that we can't push the texture search path in the constructor + // since this also adds a file archive to te file system - and + // m_file_system is deleted (in irr_driver) after + pushTextureSearchPath(m_subdir_name[TEXTURE]); + if(fileExists(m_subdir_name[TEXTURE]+"deprecated/")) + pushTextureSearchPath(m_subdir_name[TEXTURE]+"deprecated/"); + + pushTextureSearchPath(m_subdir_name[GUI]); + + + pushModelSearchPath (m_subdir_name[MODEL]); + pushMusicSearchPath (m_subdir_name[MUSIC]); + + // Add more paths from the STK_MUSIC_PATH environment variable + if(getenv("SUPERTUXKART_MUSIC_PATH")!=NULL) + { + std::string path=getenv("SUPERTUXKART_MUSIC_PATH"); + std::vector dirs = StringUtils::splitPath(path); + for(int i=0;i<(int)dirs.size(); i++) + pushMusicSearchPath(dirs[i]); + } +} // reInit + +//----------------------------------------------------------------------------- +FileManager::~FileManager() +{ + // Clean up left-over files in addons/tmp that are older than 24h + // ============================================================== + // (The 24h delay is useful when debugging a problem with a zip file) + std::set allfiles; + std::string tmp=getAddonsFile("tmp"); + listFiles(allfiles, tmp); + for(std::set::iterator i=allfiles.begin(); + i!=allfiles.end(); i++) + { + if((*i)=="." || (*i)=="..") continue; + // For now there should be only zip files or .part files + // (not fully downloaded files) in tmp. Warn about any + // other files. + std::string full_path=tmp+"/"+*i; + if(StringUtils::getExtension(*i)!="zip" && + StringUtils::getExtension(*i)!="part" ) + { + Log::warn("FileManager", "Unexpected tmp file '%s' found.", + full_path.c_str()); + continue; + } + if(isDirectory(full_path)) + { + // Gee, a .zip file which is a directory - stay away from it + Log::warn("FileManager", "'%s' is a directory and will not be deleted.", + full_path.c_str()); + continue; + } + struct stat mystat; + stat(full_path.c_str(), &mystat); + StkTime::TimeType current = StkTime::getTimeSinceEpoch(); + if(current - mystat.st_ctime <24*3600) + { + if(UserConfigParams::logAddons()) + Log::verbose("FileManager", "'%s' is less than 24h old " + "and will not be deleted.", + full_path.c_str()); + continue; + } + if(UserConfigParams::logAddons()) + Log::verbose("FileManager", "Deleting tmp file'%s'.",full_path.c_str()); + removeFile(full_path); + + } // for i in all files in tmp + + // Clean up rest of file manager + // ============================= + popMusicSearchPath(); + popModelSearchPath(); + popTextureSearchPath(); + popTextureSearchPath(); + m_file_system->drop(); + m_file_system = NULL; +} // ~FileManager + +//----------------------------------------------------------------------------- +/** Adds paths to the list of stk root directories. + * \param roots A ":" separated string of directories to add. + */ +void FileManager::addRootDirs(const std::string &roots) +{ + std::vector all = StringUtils::split(roots, ':'); + for(unsigned int i=0; icreateXMLReader(filename.c_str()); +} // getXMLReader +//----------------------------------------------------------------------------- +/** Reads in a XML file and converts it into a XMLNode tree. + * \param filename Name of the XML file to read. + */ +XMLNode *FileManager::createXMLTree(const std::string &filename) +{ + try + { + XMLNode* node = new XMLNode(filename); + return node; + } + catch (std::runtime_error& e) + { + if (UserConfigParams::logMisc()) + { + Log::error("FileManager", "createXMLTree: %s\n", e.what()); + } + return NULL; + } +} // createXMLTree + +//----------------------------------------------------------------------------- +/** Reads in XML from a string and converts it into a XMLNode tree. + * \param content the string containing the XML content. + */ +XMLNode *FileManager::createXMLTreeFromString(const std::string & content) +{ + try + { + char *b = new char[content.size()]; + memcpy(b, content.c_str(), content.size()); + io::IReadFile * ireadfile = m_file_system->createMemoryReadFile(b, strlen(b), "tempfile", true); + io::IXMLReader * reader = m_file_system->createXMLReader(ireadfile); + XMLNode* node = new XMLNode(reader); + reader->drop(); + return node; + } + catch (std::runtime_error& e) + { + if (UserConfigParams::logMisc()) + { + Log::error("FileManager", "createXMLTreeFromString: %s\n", e.what()); + } + return NULL; + } +} // createXMLTreeFromString + +//----------------------------------------------------------------------------- +/** In order to add and later remove paths we have to specify the absolute + * filename (and replace '\' with '/' on windows). + */ +io::path FileManager::createAbsoluteFilename(const std::string &f) +{ + io::path abs_path=m_file_system->getAbsolutePath(f.c_str()); + abs_path=m_file_system->flattenFilename(abs_path); + return abs_path; +} // createAbsoluteFilename + +//----------------------------------------------------------------------------- +/** Adds a model search path to the list of model search paths. + * This path will be searched before any other existing paths. + */ +void FileManager::pushModelSearchPath(const std::string& path) +{ + m_model_search_path.push_back(path); + const int n=m_file_system->getFileArchiveCount(); + m_file_system->addFileArchive(createAbsoluteFilename(path), + /*ignoreCase*/false, + /*ignorePaths*/false, + io::EFAT_FOLDER); + // A later added file archive should be searched first (so that + // track specific models are found before models in data/models). + // This is not necessary if this is the first member, or if the + // addFileArchive call did not add this file systems (this can + // happen if the file archive has been added prevously, which + // commonly happens since each kart/track specific path is added + // twice: once for textures and once for models). + if(n>0 && (int)m_file_system->getFileArchiveCount()>n) + { + // In this case move the just added file archive + // (which has index n) to position 0 (by -n positions): + m_file_system->moveFileArchive(n, -n); + } +} // pushModelSearchPath + +//----------------------------------------------------------------------------- +/** Adds a texture search path to the list of texture search paths. + * This path will be searched before any other existing paths. + */ +void FileManager::pushTextureSearchPath(const std::string& path) +{ + m_texture_search_path.push_back(path); + const int n=m_file_system->getFileArchiveCount(); + m_file_system->addFileArchive(createAbsoluteFilename(path), + /*ignoreCase*/false, + /*ignorePaths*/false, + io::EFAT_FOLDER); + // A later added file archive should be searched first (so that + // e.g. track specific textures are found before textures in + // data/textures). + // This is not necessary if this is the first member, or if the + // addFileArchive call did not add this file systems (this can + // happen if the file archive has been added previously, which + // commonly happens since each kart/track specific path is added + // twice: once for textures and once for models). + if(n>0 && (int)m_file_system->getFileArchiveCount()>n) + { + // In this case move the just added file archive + // (which has index n) to position 0 (by -n positions): + m_file_system->moveFileArchive(n, -n); + } +} // pushTextureSearchPath + +//----------------------------------------------------------------------------- +/** Removes the last added texture search path from the list of paths. + */ +void FileManager::popTextureSearchPath() +{ + std::string dir = m_texture_search_path.back(); + m_texture_search_path.pop_back(); + m_file_system->removeFileArchive(createAbsoluteFilename(dir)); +} // popTextureSearchPath + +//----------------------------------------------------------------------------- +/** Removes the last added model search path from the list of paths. + */ +void FileManager::popModelSearchPath() +{ + std::string dir = m_model_search_path.back(); + m_model_search_path.pop_back(); + m_file_system->removeFileArchive(createAbsoluteFilename(dir)); +} // popModelSearchPath + +//----------------------------------------------------------------------------- +/** Tries to find the specified file in any of the given search paths. + * \param full_path On return contains the full path of the file, or + * "" if the file is not found. + * \param file_name The name of the file to look for. + * \param search_path The list of paths to search for the file. + * \return True if the file is found, false otherwise. + */ +bool FileManager::findFile(std::string& full_path, + const std::string& file_name, + const std::vector& search_path) const +{ + for(std::vector::const_reverse_iterator + i = search_path.rbegin(); + i != search_path.rend(); ++i) + { + full_path = *i + file_name; + if(m_file_system->existFile(full_path.c_str())) return true; + } + full_path=""; + return false; +} // findFile + +//----------------------------------------------------------------------------- +std::string FileManager::getAssetChecked(FileManager::AssetType type, + const std::string& name, + bool abort_on_error) const +{ + std::string path = m_subdir_name[type]+name; + if(fileExists(path)) + return path; + + if(abort_on_error) + { + Log::fatal("FileManager", "Can not find file '%s' in '%s'", + name.c_str(), m_subdir_name[type].c_str()); + } + return ""; +} // getAssetChecked + +//----------------------------------------------------------------------------- +/** Returns the full path of a file of the given asset class. It is not + * checked if the file actually exists (use getAssetChecked() instead if + * checking is needed). + * \param type Type of the asset class. + * \param name Name of the file to search. + * \return Full path to the file. + */ +std::string FileManager::getAsset(FileManager::AssetType type, + const std::string &name) const +{ + return m_subdir_name[type]+name; +} // getAsset + +//----------------------------------------------------------------------------- +/** Searches in all root directories for the specified file. + * \param name Name of the file to find. + * \return Full path of the file, or "" if not found. + */ +std::string FileManager::getAsset(const std::string &name) const +{ + std::string path; + findFile(path, name, m_root_dirs); + return path; +} // getAsset + +//----------------------------------------------------------------------------- +/** Returns the directory in which screenshots should be stored. + */ +std::string FileManager::getScreenshotDir() const +{ + return m_screenshot_dir; +} // getScreenshotDir + +//----------------------------------------------------------------------------- +/** Returns the full path of a texture file name by searching in all + * directories currently in the texture search path. The difference to + * a call getAsset(TEXTURE,...) is that the latter will only return + * textures from .../textures, while the searchTexture will also + * search e.g. in kart or track directories (depending on what is currently + * being loaded). + * \param file_name Name of the texture file to search. + * \return The full path for the texture, or "" if the texture was not found. + */ +std::string FileManager::searchTexture(const std::string& file_name) const +{ + std::string path; + findFile(path, file_name, m_texture_search_path); + return path; +} // searchTexture + +//----------------------------------------------------------------------------- +/** Returns the list of all directories in which music files are searched. + */ +std::vector FileManager::getMusicDirs() const +{ + return m_music_search_path; +} // getMusicDirs + +//----------------------------------------------------------------------------- +/** If the directory specified in path does not exist, it is created. This + * function does not support recursive operations, so if a directory "a/b" + * is tested, and "a" does not exist, this function will fail. + * \params path Directory to test. + * \return True if the directory exists or could be created, + * false otherwise. + */ +bool FileManager::checkAndCreateDirectory(const std::string &path) +{ + // irrlicht apparently returns true for files and directory + // (using access/_access internally): + if(m_file_system->existFile(io::path(path.c_str()))) + return true; + + Log::info("FileManager", "Creating directory '%s'.", path.c_str()); + + // Otherwise try to create the directory: +#if defined(WIN32) && !defined(__CYGWIN__) + bool error = _mkdir(path.c_str()) != 0; +#else + bool error = mkdir(path.c_str(), 0755) != 0; +#endif + return !error; +} // checkAndCreateDirectory + +//----------------------------------------------------------------------------- +/** If the directory specified in path does not exist, it is created + * recursively (mkdir -p style). + * \params path Directory to test. + * \return True if the directory exists or could be created, false otherwise. + */ +bool FileManager::checkAndCreateDirectoryP(const std::string &path) +{ + // irrlicht apparently returns true for files and directory + // (using access/_access internally): + if(m_file_system->existFile(io::path(path.c_str()))) + return true; + + std::cout << "[FileManager] Creating directory(ies) '" << path << "'.\n"; + + std::vector split = StringUtils::split(path,'/'); + std::string current_path = ""; + for (unsigned int i=0; iexistFile(io::path(current_path.c_str()))) + { + if (!checkAndCreateDirectory(current_path)) + { + Log::error("FileManager", "Can't create dir '%s'", + current_path.c_str()); + break; + } + } + } + bool error = checkAndCreateDirectory(path); + + return error; +} // checkAndCreateDirectory + +//----------------------------------------------------------------------------- +/** Checks if the config directory exists, and it not, tries to create it. + * It will set m_user_config_dir to the path to which user-specific config + * files are stored. + */ +void FileManager::checkAndCreateConfigDir() +{ + if(getenv("SUPERTUXKART_SAVEDIR") && + checkAndCreateDirectory(getenv("SUPERTUXKART_SAVEDIR")) ) + { + m_user_config_dir = getenv("SUPERTUXKART_SAVEDIR"); + } + else + { + +#if defined(WIN32) || defined(__CYGWIN__) + + // Try to use the APPDATA directory to store config files and highscore + // lists. If not defined, used the current directory. + if(getenv("APPDATA")!=NULL) + { + m_user_config_dir = getenv("APPDATA"); + if(!checkAndCreateDirectory(m_user_config_dir)) + { + std::cerr << "[FileManager] Can't create config dir '" + << m_user_config_dir << "', falling back to '.'.\n"; + m_user_config_dir = "."; + } + } + else + m_user_config_dir = "."; + + m_user_config_dir += "/supertuxkart"; + +#elif defined(__APPLE__) + + if (getenv("HOME")!=NULL) + { + m_user_config_dir = getenv("HOME"); + } + else + { + std::cerr << + "[FileManager] No home directory, this should NOT happen!\n"; + // Fall back to system-wide app data (rather than + // user-specific data), but should not happen anyway. + m_user_config_dir = ""; + } + m_user_config_dir += "/Library/Application Support/"; + const std::string CONFIGDIR("SuperTuxKart"); + m_user_config_dir += CONFIGDIR; + +#else + + // Remaining unix variants. Use the new standards for config directory + // i.e. either XDG_CONFIG_HOME or $HOME/.config + if (getenv("XDG_CONFIG_HOME")!=NULL){ + m_user_config_dir = getenv("XDG_CONFIG_HOME"); + } + else if (!getenv("HOME")) + { + std::cerr + << "[FileManager] No home directory, this should NOT happen " + << "- trying '.' for config files!\n"; + m_user_config_dir = "."; + } + else + { + m_user_config_dir = getenv("HOME"); + m_user_config_dir += "/.config"; + if(!checkAndCreateDirectory(m_user_config_dir)) + { + // If $HOME/.config can not be created: + std::cerr << "[FileManager] Cannot create directory '" + << m_user_config_dir <<"', falling back to use '" + << getenv("HOME")<< "'.\n"; + m_user_config_dir = getenv("HOME"); + } + } + m_user_config_dir += "/supertuxkart"; + +#endif + + } // if(getenv("SUPERTUXKART_SAVEDIR") && checkAndCreateDirectory(...)) + + if(m_user_config_dir.size()>0 && *m_user_config_dir.rbegin()!='/') + m_user_config_dir += "/"; + + if(!checkAndCreateDirectory(m_user_config_dir)) + { + Log::warn("FileManager", "Can not create config dir '%s', " + "falling back to '.'.", m_user_config_dir.c_str()); + m_user_config_dir = "./"; + } + return; +} // checkAndCreateConfigDir + +// ---------------------------------------------------------------------------- +/** Creates the directories for the addons data. This will set m_addons_dir + * with the appropriate path, and also create the subdirectories in this + * directory. + */ +void FileManager::checkAndCreateAddonsDir() +{ +#if defined(WIN32) || defined(__CYGWIN__) + m_addons_dir = m_user_config_dir+"addons/"; +#elif defined(__APPLE__) + m_addons_dir = getenv("HOME"); + m_addons_dir += "/Library/Application Support/SuperTuxKart/Addons/"; +#else + m_addons_dir = checkAndCreateLinuxDir("XDG_DATA_HOME", "supertuxkart", + ".local/share", ".stkaddons"); + m_addons_dir += "addons/"; +#endif + + if(!checkAndCreateDirectory(m_addons_dir)) + { + Log::error("FileManager", "Can not create add-ons dir '%s', " + "falling back to '.'.", m_addons_dir.c_str()); + m_addons_dir = "./"; + } + + if (!checkAndCreateDirectory(m_addons_dir + "icons/")) + { + Log::error("FileManager", "Failed to create add-ons icon dir at '%s'.", + (m_addons_dir + "icons/").c_str()); + } + if (!checkAndCreateDirectory(m_addons_dir + "tmp/")) + { + Log::error("FileManager", "Failed to create add-ons tmp dir at '%s'.", + (m_addons_dir + "tmp/").c_str()); + } + +} // checkAndCreateAddonsDir + +// ---------------------------------------------------------------------------- +/** Creates the directories for screenshots. This will set m_screenshot_dir + * with the appropriate path. + */ +void FileManager::checkAndCreateScreenshotDir() +{ +#if defined(WIN32) || defined(__CYGWIN__) + m_screenshot_dir = m_user_config_dir+"screenshots/"; +#elif defined(__APPLE__) + m_screenshot_dir = getenv("HOME"); + m_screenshot_dir += "/Library/Application Support/SuperTuxKart/Screenshots/"; +#else + m_screenshot_dir = checkAndCreateLinuxDir("XDG_CACHE_HOME", "supertuxkart", ".cache/", "."); + m_screenshot_dir += "screenshots/"; +#endif + + if(!checkAndCreateDirectory(m_screenshot_dir)) + { + Log::error("FileManager", "Can not create screenshot directory '%s', " + "falling back to '.'.", m_screenshot_dir.c_str()); + m_screenshot_dir = "."; + } + +} // checkAndCreateScreenshotDir + +// ---------------------------------------------------------------------------- +#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__) + +/** Find a directory to use for remaining unix variants. Use the new standards + * for config directory based on XDG_* environment variables, or a + * subdirectory under $HOME, trying two different fallbacks. It will also + * check if the directory 'dirname' can be created (to avoid problems that + * e.g. $env_name is '/', which exists, but can not be written to. + * \param env_name Name of the environment variable to test first. + * \param dir_name Name of the directory to create + * \param fallback1 Subdirectory under $HOME to use if the environment + * variable is not defined or can not be created. + * \param fallback2 Subdirectory under $HOME to use if the environment + * variable and fallback1 are not defined or can not be created. + */ +std::string FileManager::checkAndCreateLinuxDir(const char *env_name, + const char *dir_name, + const char *fallback1, + const char *fallback2) +{ + bool dir_ok = false; + std::string dir; + + if (getenv(env_name)!=NULL) + { + dir = getenv(env_name); + dir_ok = checkAndCreateDirectory(dir); + if(!dir_ok) + Log::warn("FileManager", "Cannot create $%s.", env_name); + + if(dir[dir.size()-1]!='/') dir += "/"; + // Do an additional test here, e.g. in case that XDG_DATA_HOME is '/' + // and since dir_ok is set, it would not test any of the other options + // like $HOME/.local/share + dir_ok = checkAndCreateDirectory(dir+dir_name); + if(!dir_ok) + Log::warn("FileManager", "Cannot create $%s/%s.", dir.c_str(), + dir_name); + } + + if(!dir_ok && getenv("HOME")) + { + // Use ~/.local/share : + dir = getenv("HOME"); + if(dir.size()>0 && dir[dir.size()-1]!='/') dir += "/"; + dir += fallback1; + // This will create each individual subdirectory if + // dir_name contains "/". + dir_ok = checkAndCreateDirectoryP(dir); + if(!dir_ok) + Log::warn("FileManager", "Cannot create $HOME/%s.", + fallback1); + } + if(!dir_ok && fallback2 && getenv("HOME")) + { + dir = getenv("HOME"); + if(dir.size()>0 && dir[dir.size()-1]!='/') dir += "/"; + dir += fallback2; + dir_ok = checkAndCreateDirectory(dir); + if(!dir_ok) + Log::warn("FileManager", "Cannot create $HOME/%s.", + fallback2); + } + + if(!dir_ok) + { + Log::warn("FileManager", "Falling back to use '.'."); + dir = "./"; + } + + if(dir.size()>0 && dir[dir.size()-1]!='/') dir += "/"; + dir += dir_name; + dir_ok = checkAndCreateDirectory(dir); + if(!dir_ok) + { + // If the directory can not be created + Log::error("FileManager", "Cannot create directory '%s', " + "falling back to use '.'.", dir.c_str()); + dir="./"; + } + if(dir.size()>0 && dir[dir.size()-1]!='/') dir += "/"; + return dir; +} // checkAndCreateLinuxDir +#endif + +//----------------------------------------------------------------------------- +/** Redirects output to go into files in the user's config directory + * instead of to the console. + */ +void FileManager::redirectOutput() +{ + //Enable logging of stdout and stderr to logfile + std::string logoutfile = getUserConfigFile("stdout.log"); + Log::verbose("main", "Error messages and other text output will " + "be logged to %s.", logoutfile.c_str()); + Log::openOutputFiles(logoutfile); +} // redirectOutput + +//----------------------------------------------------------------------------- +/** Returns the directory for addon files. */ +const std::string &FileManager::getAddonsDir() const +{ + return m_addons_dir; +} // getAddonsDir + +//----------------------------------------------------------------------------- +/** Returns the full path of a file in the addons directory. + * \param name Name of the file. + */ +std::string FileManager::getAddonsFile(const std::string &name) +{ + return getAddonsDir()+name; +} // getAddonsFile + +//----------------------------------------------------------------------------- +/** Returns the full path of the config directory. + */ +std::string FileManager::getUserConfigFile(const std::string &fname) const +{ + return m_user_config_dir+fname; +} // getUserConfigFile + +//----------------------------------------------------------------------------- +/** Returns the full path of a music file by searching all music search paths. + * It throws an exception if the file is not found. + * \param file_name File name to search for. + */ +std::string FileManager::searchMusic(const std::string& file_name) const +{ + std::string path; + bool success = findFile(path, file_name, m_music_search_path); + if(!success) + { + // If a music file is not found in any of the music search paths + // check all root dirs. This is used by stk_config to load the + // title music before any music search path is defined) + path = getAsset(MUSIC, file_name); + success = fileExists(path); + } + if (!success) + { + throw std::runtime_error( + "[FileManager::getMusicFile] Cannot find music file '" + +file_name+"'."); + } + return path; +} // searchMusic + +//----------------------------------------------------------------------------- +/** Returns true if the given name is a directory. + * \param path File name to test. + */ +bool FileManager::isDirectory(const std::string &path) const +{ + struct stat mystat; + std::string s(path); + // At least on windows stat returns an error if there is + // a '/' at the end of the path. + if(s[s.size()-1]=='/') + s.erase(s.end()-1, s.end()); + if(stat(s.c_str(), &mystat) < 0) return false; + return S_ISDIR(mystat.st_mode); +} // isDirectory + +//----------------------------------------------------------------------------- +/** Returns a list of files in a given directory. + * \param result A reference to a std::vector which will + * hold all files in a directory. The vector will be cleared. + * \param dir The director for which to get the directory listing. + * \param make_full_path If set to true, all listed files will be full paths. + */ +void FileManager::listFiles(std::set& result, + const std::string& dir, + bool make_full_path) const +{ + result.clear(); + +#ifndef ANDROID + if(!isDirectory(dir)) + return; +#endif + + io::path previous_cwd = m_file_system->getWorkingDirectory(); + + if(!m_file_system->changeWorkingDirectoryTo( dir.c_str() )) + { + Log::error("FileManager", "listFiles : Could not change CWD!\n"); + return; + } + irr::io::IFileList* files = m_file_system->createFileList(); + + for(int n=0; n<(int)files->getFileCount(); n++) + { + result.insert(make_full_path ? dir+"/"+ files->getFileName(n).c_str() + : files->getFileName(n).c_str() ); + } + + m_file_system->changeWorkingDirectoryTo( previous_cwd ); + files->drop(); +} // listFiles + +//----------------------------------------------------------------------------- +/** Creates a directory for an addon. + * \param addons_name Name of the directory to create. + * \param addons_type The type, which is used as a subdirectory. E.g.: + * 'karts' (m_addons_dir/karts/name will be created). + */ +void FileManager::checkAndCreateDirForAddons(const std::string &dir) +{ + // Tries to create directory recursively + bool success = checkAndCreateDirectoryP(dir); + if(!success) + { + Log::warn("FileManager", "There is a problem with the addons dir."); + return; + } +} // checkAndCreateDirForAddons + +// ---------------------------------------------------------------------------- +/** Removes the specified file, returns true if successful, or false + * if the file is not a regular file or can not be removed. + */ +bool FileManager::removeFile(const std::string &name) const +{ + struct stat mystat; + if(stat(name.c_str(), &mystat) < 0) return false; + if( S_ISREG(mystat.st_mode)) + return remove(name.c_str())==0; + return false; +} // removeFile + +// ---------------------------------------------------------------------------- +/** Removes a directory (including all files contained). The function could + * easily recursively delete further subdirectories, but this is commented + * out atm (to limit the amount of damage in case of a bug). + * \param name Directory name to remove. + * \param return True if removal was successful. + */ +bool FileManager::removeDirectory(const std::string &name) const +{ + std::set files; + listFiles(files, name, /*is full path*/ true); + for(std::set::iterator i=files.begin(); i!=files.end(); i++) + { + if((*i)=="." || (*i)=="..") continue; + if(UserConfigParams::logMisc()) + Log::verbose("FileManager", "Deleting directory '%s'.", + (*i).c_str()); + if(isDirectory(*i)) + { + // This should not be necessary (since this function is only + // used to remove addons), and it limits the damage in case + // of any bugs - i.e. if name should be "/" or so. + // removeDirectory(full_path); + } + else + { + removeFile(*i); + } + } +#if defined(WIN32) + return RemoveDirectory(name.c_str())==TRUE; +#else + return remove(name.c_str())==0; +#endif +} // remove directory + diff --git a/src/online/http_request.cpp b/src/online/http_request.cpp index 5e5cab606..99d6decc1 100644 --- a/src/online/http_request.cpp +++ b/src/online/http_request.cpp @@ -227,14 +227,20 @@ namespace Online Log::info("HTTPRequest", "Download successful."); // The behaviour of rename is unspecified if the target // file should already exist - so remove it. - file_manager->removeFile(m_filename); + bool ok = file_manager->removeFile(m_filename); + if(!ok) + { + Log::error("addons", + "Could not removed existing addons.xml file."); + m_curl_code = CURLE_WRITE_ERROR; + } int ret = rename((m_filename+".part").c_str(), m_filename.c_str() ); // In case of an error, set the status to indicate this if(ret!=0) { - if(UserConfigParams::logAddons()) - Log::error("addons", "Could not rename downloaded file!"); + Log::error("addons", + "Could not rename downloaded addons.xml file!"); m_curl_code = CURLE_WRITE_ERROR; } } // m_curl_code ==CURLE_OK From 62ece5cd59e9ce8ac0cc08d4fe7129948907f61a Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Thu, 16 Jan 2014 17:13:26 +0100 Subject: [PATCH 314/412] CHANGELOG rewritten in Markdown. --- ChangeLog => CHANGELOG.md | 127 ++++++++++++-------------------------- 1 file changed, 40 insertions(+), 87 deletions(-) rename ChangeLog => CHANGELOG.md (76%) diff --git a/ChangeLog b/CHANGELOG.md similarity index 76% rename from ChangeLog rename to CHANGELOG.md index d7730a8b3..85c5e0c76 100644 --- a/ChangeLog +++ b/CHANGELOG.md @@ -1,5 +1,4 @@ -SuperTuxkart 0.8.1 -~~~~~~~~~~~~~~~ +##SuperTuxKart 0.8.1 * New track STK Enterprise * Updated track The old mines * Updated Lighthouse track @@ -20,8 +19,7 @@ SuperTuxkart 0.8.1 -SuperTuxkart 0.8 -~~~~~~~~~~~~~~~ +##SuperTuxKart 0.8 * Story mode and new challenge set * Improved AI * Skidding and better collision physics @@ -36,8 +34,7 @@ SuperTuxkart 0.8 * New music -SuperTuxKart 0.7.3 -~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.7.3 * New Zen Garden and Subsea tracks * New Island battle arena * New Suzanne kart @@ -53,8 +50,7 @@ SuperTuxKart 0.7.3 * Better placement of rescued karts * Transition track-making to blender 2.5/2.6 -SuperTuxKart 0.7.2 -~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.7.2 * Added in-game addon manager * Fixed major memory leaks * New Snow Peak track by Samuncle @@ -64,13 +60,11 @@ SuperTuxKart 0.7.2 * Improve gamepad configuration under Windows (add ability to tell gamepads apart) * Various other tweaks done and glitches fixed -SuperTuxkart 0.7.1b -~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.7.1b * Fix circular dependency in challenges * Updated translations -SuperTuxKart 0.7.1 -~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.7.1 * Particle (smoke, splash, fire) and weather effects * New Fort Magma by Samuncle, new Shiny Suburbs track by Horace * New Beagle kart by wolterh @@ -89,9 +83,9 @@ SuperTuxKart 0.7.1 * Full RTL (right to left) support * Various other tweaks done and glitches fixed -SuperTuxKart 0.7 (December 2010) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.7 (December 2010) Too many to list them all. Main points: + * Irrlicht: - Ported from plib to irrlicht - Added animations to karts and some tracks @@ -103,48 +97,34 @@ Too many to list them all. Main points: * New art: - New tracks farm, hacienda, scotland, secret garden -SuperTuxKart 0.6.2a (October 2009) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.6.2a (October 2009) * Bugfix: STK would crash while trying to save the config file on Windows Vista. -SuperTuxKart 0.6.2 (July 2009) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.6.2 (July 2009) * Bugfix: Game could crash in rare circumstances. -* Bugfix: Restarting a GP (with the in-race menu ESC) would - not subtract already allocated points. +* Bugfix: Restarting a GP (with the in-race menu ESC) would not subtract already allocated points. * Bugfix: A race could be finished with an invalid shortcut. -* Bugfix: Playing a challenge after a splitscreen game would - play the challenge in split screen. +* Bugfix: Playing a challenge after a splitscreen game would play the challenge in split screen. * Bugfix: Items explode over void. * Bugfix: Grass in castle arena slowed down the kart. * Bugfix: GP result showed kart identifier instead of name. -* Improvement: there is now 1 1 sec. wait period for the race - result screen, avoiding the problem that someone - presses space/enter at the end of a race, immediately - quitting the menu before it can be read. +* Improvement: there is now 1 1 sec. wait period for the race result screen, avoiding the problem that someone presses space/enter at the end of a race, immediately quitting the menu before it can be read. -SuperTuxKart 0.6.1a (February 2009) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.6.1a (February 2009) * Bugfix: battle mode would not display track groups. -SuperTuxKart 0.6.1 (February 2009) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Added new kart ("Puffy"), new battle map ("Cave"), and new music - for Snow Mountain. -* Fixed bug in track selection screen that could cause a crash - when track groups were used. -* Fixed crash in character selection that could happen if an - old user config file existed. +##SuperTuxKart 0.6.1 (February 2009) +* Added new kart ("Puffy"), new battle map ("Cave"), and new music for Snow Mountain. +* Fixed bug in track selection screen that could cause a crash when track groups were used. +* Fixed crash in character selection that could happen if an old user config file existed. * Fixed incorrect rescues in Fort Magma. -* Improved track selection screen to not display empty track - groups. +* Improved track selection screen to not display empty track groups. * A plunger in the face is now removed when restarting. * Added slow-down for karts driving backwards. * Somewhat reduced 'shaking' of AI driven karts. -SuperTuxKart 0.6 (January 2009) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.6 (January 2009) * New improved physics and kart handling * Added sharp turns and nitro speed boost (replacing wheelies and jump) * Totally rewrote powerups (plunger, bowling ball, cake, bubblegum) and new look for bananas @@ -167,10 +147,8 @@ SuperTuxKart 0.6 (January 2009) - Fixed 'joystick locks' (kart would turn even if the joystick is in neutral), thanks to Samjam for the patch. -SuperTuxKart 0.5 (May 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Six new tracks and one improved track: Fort Magma, SnowTux Peak, Amazonian Journey, City, - Canyon, Crescent Crossing and StarTrack +##SuperTuxKart 0.5 (May 2008) +* Six new tracks and one improved track: Fort Magma, SnowTux Peak, Amazonian Journey, City, Canyon, Crescent Crossing and StarTrack * Complete Challenges to unlock game modes, new tracks and a skidding preview * New Follow the Leader game mode * New Grand Prix @@ -179,12 +157,11 @@ SuperTuxKart 0.5 (May 2008) * German, French, Dutch, Spanish, Italian and Swedish translations * Additional music * Many Bugfixes including: - a memory leak fix (Charlie Head) - an AI crash fix (Chris Morris) + - a memory leak fix (Charlie Head) + - an AI crash fix (Chris Morris) -SuperTuxKart 0.4 (February 2008) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.4 (February 2008) * New physics handling using the bullet physics engine * New kart: wilber * Improved 'Shifting Sands' and 'Lighthouse' tracks @@ -195,8 +172,7 @@ SuperTuxKart 0.4 (February 2008) * Additional music and main theme -SuperTuxKart 0.3 (May 2007) -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.3 (May 2007) * Highscore lists * Shortcut detection * Improved AI @@ -226,8 +202,7 @@ SuperTuxKart 0.3 (May 2007) - Fixed keyboard keys unable to work on the first key press bug - And others -SuperTuxKart 0.2 (22. Sep 2006) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.2 (22. Sep 2006) * Significant performance improvement by using display lists * Improved AI * Support for different grand prixs @@ -245,83 +220,61 @@ SuperTuxKart 0.2 (22. Sep 2006) * Added help and about screens, added credits to track designer * Items were added to all tracks -SuperTuxKart 0.1 (04. May 2006) (not officially released) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * Significant speedup by using a new HOT and collision algorithm - --> all tracks are now playable +##SuperTuxKart 0.1 (04. May 2006) (not officially released) + * Significant speedup by using a new HOT and collision algorithm --> all tracks are now playable * Removed all SDL dependencies, only plib is needed * Single and multi-window menu can be used * Code structure changes * Some bug fixes and small improvements * Added profile option to support automatic profiling -SuperTuxKart 0.0.0 (22. Dec 2004) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##SuperTuxKart 0.0.0 (22. Dec 2004) * new tracks * new characters and karts * new user-interface * some additional effects (skid-marks, smoke) -TuxKart v0.4.0 (March 19th 2004) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.4.0 (March 19th 2004) * Changes for compatibility with PLIB 1.8.0 and later. * Removed some features that were only there to support truly ancient graphics cards like 3Dfx Voodoo-1/2. -TuxKart v0.3.0 (??) -~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.3.0 (??) * Converted to use the new PLIB/PW library and thus avoid the need to link to GLUT. -TuxKart v0.2.0 (Sept 3rd 2002) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.2.0 (Sept 3rd 2002) * Changes for compatibility with PLIB 1.6.0 and later. -TuxKart v0.0.5 (??) -~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.5 (??) * Changes for compatibility with PLIB 1.4.0 and later. -TuxKart v0.0.4 (??) -~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.4 (??) * Changes to suit rassin-frassin-Windoze-junk. - * Steady-cam camera - courtesy of cowtan@ysbl.york.ac.uk - * Changes for compatibility with PLIB 1.3.1 and later. - * Added new music courtesy of Matt Thomas. -TuxKart v0.0.3 (July 4th 2000) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.3 (July 4th 2000) * Fixed bug in Keyboard driver when no joystick driver is installed. - * More CygWin fixes. - * Started new feature to allow you to be rescued from lava, etc. -TuxKart v0.0.2 (July 2nd 2000) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.2 (July 2nd 2000) * Added ability to add new tracks without recompiling. - * Can now drive using keyboard only - no joystick required. - * Should compile and run under Windoze using CygWin. -TuxKart v0.0.1 (July 1st 2000) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.1 (July 1st 2000) * Fixed a couple of files missing in initial Distro. -TuxKart v0.0.0 (June 29th 2000) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart v0.0.0 (June 29th 2000) * First CVS release. -TuxKart (unnumbered) (April 13th 2000) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +##TuxKart (unnumbered) (April 13th 2000) * First hack. - -# EOF # From 19b495d9a009fe3fc49f57b374392ba97cae1ac7 Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Thu, 16 Jan 2014 17:17:20 +0100 Subject: [PATCH 315/412] Remove unneeded CHANGES file. --- CHANGES | 1 - 1 file changed, 1 deletion(-) delete mode 100644 CHANGES diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 6a959142c..000000000 --- a/CHANGES +++ /dev/null @@ -1 +0,0 @@ -See the ChangeLog file. From 1b45204c0a75b432bbae547d53f29bacb13f57d1 Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Thu, 16 Jan 2014 17:22:59 +0100 Subject: [PATCH 316/412] TODO rewritten in Markdown. --- TODO => TODO.md | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) rename TODO => TODO.md (64%) diff --git a/TODO b/TODO.md similarity index 64% rename from TODO rename to TODO.md index d0e230b68..332f1386c 100644 --- a/TODO +++ b/TODO.md @@ -1,43 +1,37 @@ +##TODO + SuperTuxKart is looking for additional man power to make this one of the best free linux games out there :) We need (in no particular order): -1) Musicians/sound engineers +1. Musicians/sound engineers - Create additional background soundtrack - Create sound effects - -2) Artists and track designer +2. Artists and track designer - Create additional tracks - Create additional art work for tracks, background images - -3) Developers +3. Developers - See todo list below - it's rather long at the moment :) - -4) Web master +4. Web master - Extend the current web page, keep it up to date - -5) Tester +5. Tester - For just about everything - Esp. different platforms - -6) Package creators +6. Package creators - Create packages for - - most common linux Distributors + - most common Linux Distributors - Windows - -7) Writers +7. Writers - Write documentation, ranging from man page, to a description for the web, to a design document, ... If you want to help the SuperTuxKart - Project, please -contact us on the email list: - - supertuxkart-devel@lists.sourceforge.net +contact us on the email list: [supertuxkart-devel@lists.sourceforge.net](mailto:supertuxkart-devel@lists.sourceforge.net) Thanks in advance! - The SuperTuxKart-Team + +-- The SuperTuxKart-Team -For details, see - http://supertuxkart.sourceforge.net/Get_involved +For details, see From 7cda53445145f098617e99360a7219beb071a83d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 16 Jan 2014 00:26:51 +0100 Subject: [PATCH 317/412] STKMesh: Enable it unconditionnaly, but dont use it on shader_ref --- src/graphics/stkmesh.cpp | 104 +++++++++------------------------------ 1 file changed, 23 insertions(+), 81 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index c9f5a985a..9a66e0e1b 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -21,40 +21,6 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t return vao; } -namespace ObjectRefShader -{ - GLuint Program; - GLuint attrib_position, attrib_texcoord, attrib_normal; - GLuint uniform_MVP, uniform_TIMV, uniform_texture; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/objectref.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - attrib_normal = glGetAttribLocation(Program, "Normal"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_texture = glGetUniformLocation(Program, "texture"); - } - - void setProgramAndUniforms() - { - glUseProgram(Program); - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - } -} - namespace ObjectShader { GLuint Program; @@ -73,19 +39,11 @@ namespace ObjectShader uniform_texture = glGetUniformLocation(Program, "texture"); } - void setProgramAndUniforms() + void setProgramAndUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_texture) { - glUseProgram(Program); - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_texture, TU_texture); } } @@ -181,9 +139,8 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene GLmeshes.push_back(allocateMeshBuffer(mb)); } - if (ObjectRefShader::Program) + if (ObjectShader::Program) return; - ObjectRefShader::init(); ObjectShader::init(); } @@ -206,30 +163,23 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - { - ObjectRefShader::setProgramAndUniforms(); + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUniform1i(ObjectRefShader::uniform_texture, 0); - } - if (type == irr_driver->getShader(ES_OBJECTPASS)) - { - ObjectShader::setProgramAndUniforms(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUniform1i(ObjectShader::uniform_texture, 0); - } + glUseProgram(ObjectShader::Program); + ObjectShader::setProgramAndUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); @@ -247,7 +197,7 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) static bool isObject(video::E_MATERIAL_TYPE type) { - if (type == irr_driver->getShader(ES_OBJECTPASS_REF) || type == irr_driver->getShader(ES_OBJECTPASS)) + if (type == irr_driver->getShader(ES_OBJECTPASS)) return true; return false; } @@ -256,14 +206,10 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (mesh.vao) return; - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectRefShader::attrib_position, ObjectRefShader::attrib_texcoord, ObjectRefShader::attrib_normal, - mesh.Stride); - if (type == irr_driver->getShader(ES_OBJECTPASS)) - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectShader::attrib_position, ObjectShader::attrib_texcoord, ObjectShader::attrib_normal, - mesh.Stride); + + mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectShader::attrib_position, ObjectShader::attrib_texcoord, ObjectShader::attrib_normal, + mesh.Stride); } void STKMesh::render() @@ -291,7 +237,6 @@ void STKMesh::render() video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); bool transparent = (rnd && rnd->isTransparent()); -#ifdef OGL32CTX // only render transparent buffer if this is the transparent render pass // and solid only in solid pass if (isObject(material.MaterialType) && !isTransparentPass && !transparent) @@ -300,9 +245,6 @@ void STKMesh::render() draw(GLmeshes[i], material.MaterialType); } else if (transparent == isTransparentPass) -#else - if (transparent == isTransparentPass) -#endif { driver->setMaterial(material); driver->drawMeshBuffer(mb); From 734f320f75d99353d2c6f120375e3c315e2ae6cb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 16 Jan 2014 00:45:32 +0100 Subject: [PATCH 318/412] STKMesh: Filter stkmesh using stencil and disable lightblend on them. --- src/graphics/glow.cpp | 1 + src/graphics/post_processing.cpp | 3 +++ src/graphics/render.cpp | 17 ++++++++++++----- src/graphics/stkmesh.cpp | 2 ++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/graphics/glow.cpp b/src/graphics/glow.cpp index 780c506b0..897839065 100644 --- a/src/graphics/glow.cpp +++ b/src/graphics/glow.cpp @@ -61,6 +61,7 @@ GlowNode::~GlowNode() void GlowNode::render() { + return; IVideoDriver * const drv = irr_driver->getVideoDriver(); drv->setTransform(ETS_WORLD, AbsoluteTransformation); drv->setMaterial(mat); diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 2edc855bf..21abc0ab3 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -632,6 +632,8 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT const SColorf s = irr_driver->getSceneManager()->getAmbientLight(); if (!LightBlendShader::Program) LightBlendShader::init(); + glStencilFunc(GL_EQUAL, 1, ~0); + glEnable(GL_STENCIL_TEST); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); if (debug) @@ -664,6 +666,7 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); + glDisable(GL_STENCIL_TEST); } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index d9fe82358..a25af1342 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -193,14 +193,21 @@ void IrrDriver::renderGLSL(float dt) m_video_driver->setRenderTarget(m_mrt, false, false); m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID; + glClear(GL_STENCIL_BUFFER_BIT); + glStencilFunc(GL_ALWAYS, 1, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glEnable(GL_STENCIL_TEST); m_scene_manager->drawAll(m_renderpass); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDisable(GL_STENCIL_TEST); irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)); irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); irr_driver->genProjViewMatrix(); - ShadowImportanceProvider * const sicb = (ShadowImportanceProvider *) - irr_driver->getCallback(ES_SHADOW_IMPORTANCE); - sicb->updateIPVMatrix(); + // Todo : reenable glow and shadows + //ShadowImportanceProvider * const sicb = (ShadowImportanceProvider *) + // irr_driver->getCallback(ES_SHADOW_IMPORTANCE); + //sicb->updateIPVMatrix(); // Used to cull glowing items & lights const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox(); @@ -208,14 +215,14 @@ void IrrDriver::renderGLSL(float dt) // Render anything glowing. if (!m_mipviz && !m_wireframe) { - renderGlow(overridemat, glows, cambox, cam); + //renderGlow(overridemat, glows, cambox, cam); } // end glow // Shadows if (!m_mipviz && !m_wireframe && UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows()) { - renderShadows(sicb, camnode, overridemat, camera); + //renderShadows(sicb, camnode, overridemat, camera); } // Lights diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 9a66e0e1b..175083bf5 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -155,6 +155,7 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (!mesh.textures) return; + glStencilFunc(GL_ALWAYS, 0, ~0); glEnable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); @@ -185,6 +186,7 @@ void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); video::SMaterial material; material.MaterialType = irr_driver->getShader(ES_RAIN); From c7fe307a52ec89c9fd31bae15141d6c247578508 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Thu, 16 Jan 2014 01:08:37 +0100 Subject: [PATCH 319/412] LightPrepass: Split the rendering in 2 phases. --- data/shaders/object.frag | 12 -- data/shaders/object_pass1.frag | 7 + .../{object.vert => object_pass1.vert} | 3 - data/shaders/object_pass2.frag | 17 ++ data/shaders/object_pass2.vert | 12 ++ data/shaders/objectref.frag | 14 -- src/graphics/irr_driver.cpp | 15 ++ src/graphics/irr_driver.hpp | 5 + src/graphics/render.cpp | 8 + src/graphics/stkmesh.cpp | 183 +++++++++++++----- src/graphics/stkmesh.hpp | 3 +- 11 files changed, 198 insertions(+), 81 deletions(-) delete mode 100644 data/shaders/object.frag create mode 100644 data/shaders/object_pass1.frag rename data/shaders/{object.vert => object_pass1.vert} (85%) create mode 100644 data/shaders/object_pass2.frag create mode 100644 data/shaders/object_pass2.vert delete mode 100644 data/shaders/objectref.frag diff --git a/data/shaders/object.frag b/data/shaders/object.frag deleted file mode 100644 index 06f06b711..000000000 --- a/data/shaders/object.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 130 -uniform sampler2D texture; -in vec2 uv; -noperspective in vec3 nor; - -void main(void) -{ - vec4 tex = texture2D(texture, uv); - gl_FragData[0] = vec4(tex.xyz, 1.); - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - tex.a); -} diff --git a/data/shaders/object_pass1.frag b/data/shaders/object_pass1.frag new file mode 100644 index 000000000..46672cb9f --- /dev/null +++ b/data/shaders/object_pass1.frag @@ -0,0 +1,7 @@ +#version 130 +noperspective in vec3 nor; + +void main(void) +{ + gl_FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); +} diff --git a/data/shaders/object.vert b/data/shaders/object_pass1.vert similarity index 85% rename from data/shaders/object.vert rename to data/shaders/object_pass1.vert index d34409e5b..649dd13dc 100644 --- a/data/shaders/object.vert +++ b/data/shaders/object_pass1.vert @@ -3,14 +3,11 @@ uniform mat4 ModelViewProjectionMatrix; uniform mat4 TransposeInverseModelView; in vec3 Position; -in vec2 Texcoord; in vec3 Normal; -out vec2 uv; noperspective out vec3 nor; void main(void) { - uv = Texcoord; gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; } diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag new file mode 100644 index 000000000..f9024054f --- /dev/null +++ b/data/shaders/object_pass2.frag @@ -0,0 +1,17 @@ +#version 130 +uniform sampler2D Albedo; +uniform sampler2D DiffuseMap; +uniform sampler2D SpecularMap; +uniform vec2 screen; +uniform vec3 ambient; +in vec2 uv; + +void main(void) +{ + vec2 tc = gl_FragCoord.xy / screen; + vec4 color = texture2D(Albedo, uv); + vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; + vec3 LightFactor = ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + gl_FragColor = vec4(color.xyz * LightFactor, 1.); +} diff --git a/data/shaders/object_pass2.vert b/data/shaders/object_pass2.vert new file mode 100644 index 000000000..7ba1d77d0 --- /dev/null +++ b/data/shaders/object_pass2.vert @@ -0,0 +1,12 @@ +#version 130 +uniform mat4 ModelViewProjectionMatrix; + +in vec3 Position; +in vec2 Texcoord; +out vec2 uv; + +void main(void) +{ + uv = Texcoord; + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); +} diff --git a/data/shaders/objectref.frag b/data/shaders/objectref.frag deleted file mode 100644 index 8bac092c2..000000000 --- a/data/shaders/objectref.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 130 -uniform sampler2D texture; -in vec2 uv; -noperspective in vec3 nor; - -void main(void) -{ - vec4 tex = texture2D(texture, uv); - if (tex.a < 0.5) - discard; - gl_FragData[0] = vec4(tex.xyz, 1.); - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - tex.a); -} diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 9b997c9ab..2fec5b517 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -140,6 +140,21 @@ void IrrDriver::reset() if (m_glsl) m_post_processing->reset(); } // reset +void IrrDriver::setPhase(unsigned p) +{ + phase = p; +} + +unsigned IrrDriver::getPhase() const +{ + return phase; +} + +core::array &IrrDriver::getMainSetup() +{ + return m_mrt; +} + // ---------------------------------------------------------------------------- #if defined(__linux__) && !defined(ANDROID) diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 8f95f4653..fae6d05d3 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -174,6 +174,8 @@ private: std::vector m_background; + unsigned phase; + #ifdef DEBUG /** Used to visualise skeletons. */ std::vector m_debug_meshes; @@ -206,6 +208,9 @@ public: ~IrrDriver(); void initDevice(); void reset(); + void setPhase(unsigned); + unsigned getPhase() const; + core::array &getMainSetup(); void updateConfigIfRelevant(); void setAllMaterialFlags(scene::IMesh *mesh) const; scene::IAnimatedMesh *getAnimatedMesh(const std::string &name); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index a25af1342..3612121cf 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -193,6 +193,7 @@ void IrrDriver::renderGLSL(float dt) m_video_driver->setRenderTarget(m_mrt, false, false); m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID; + irr_driver->setPhase(0); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 1, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -227,6 +228,13 @@ void IrrDriver::renderGLSL(float dt) // Lights renderLights(cambox, camnode, overridemat, cam, dt); + irr_driver->setPhase(1); + m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID; + glStencilFunc(GL_EQUAL, 0, ~0); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glEnable(GL_STENCIL_TEST); + m_scene_manager->drawAll(m_renderpass); + glDisable(GL_STENCIL_TEST); if (!bgnodes) { diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 175083bf5..0d02d5104 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -2,6 +2,7 @@ #include "graphics/irr_driver.hpp" #include #include +#include "config/user_config.hpp" static GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride) @@ -11,39 +12,72 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glEnableVertexAttribArray(attrib_normal); + if ((GLint)attrib_texcoord != -1) + glEnableVertexAttribArray(attrib_texcoord); + if ((GLint)attrib_normal != -1) + glEnableVertexAttribArray(attrib_normal); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); - glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + if ((GLint)attrib_texcoord != -1) + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + if ((GLint)attrib_normal != -1) + glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); glBindVertexArray(0); return vao; } -namespace ObjectShader +namespace ObjectPass1Shader { GLuint Program; - GLuint attrib_position, attrib_texcoord, attrib_normal; - GLuint uniform_MVP, uniform_TIMV, uniform_texture; + GLuint attrib_position, attrib_normal; + GLuint uniform_MVP, uniform_TIMV; void init() { initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object.vert").c_str(), file_manager->getAsset("shaders/object.frag").c_str()); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_normal = glGetAttribLocation(Program, "Normal"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");; } - void setProgramAndUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_texture) + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glUniform1i(uniform_texture, TU_texture); + } +} + +namespace ObjectPass2Shader +{ + GLuint Program; + GLuint attrib_position, attrib_texcoord; + GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_screen, uniform_ambient; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); } } @@ -123,7 +157,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) result.textures = static_cast(tex)->getOpenGLTextureName(); else result.textures = 0; - result.vao = 0; return result; } @@ -139,9 +172,10 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene GLmeshes.push_back(allocateMeshBuffer(mb)); } - if (ObjectShader::Program) + if (ObjectPass1Shader::Program && ObjectPass2Shader::Program) return; - ObjectShader::init(); + ObjectPass1Shader::init(); + ObjectPass2Shader::init(); } STKMesh::~STKMesh() @@ -150,43 +184,87 @@ STKMesh::~STKMesh() // glDeleteBuffers(index_buffer.size(), index_buffer.data()); } +static +void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glUseProgram(ObjectPass1Shader::Program); + ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); + + glBindVertexArray(mesh.vao_first_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); +} + +static +void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + + glUseProgram(ObjectPass2Shader::Program); + ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} + static void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (!mesh.textures) return; - glStencilFunc(GL_ALWAYS, 0, ~0); - glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; - - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glUseProgram(ObjectShader::Program); - ObjectShader::setProgramAndUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); - - glBindVertexArray(mesh.vao); - glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 1, ~0); + if (irr_driver->getPhase() == 0) + drawFirstPass(mesh, type); + else + drawSecondPass(mesh, type); video::SMaterial material; material.MaterialType = irr_driver->getShader(ES_RAIN); @@ -206,11 +284,14 @@ static bool isObject(video::E_MATERIAL_TYPE type) static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) { - if (mesh.vao) + if (mesh.vao_first_pass) return; - mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectShader::attrib_position, ObjectShader::attrib_texcoord, ObjectShader::attrib_normal, + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, + mesh.Stride); + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, mesh.Stride); } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 051b4f6b3..90a41878f 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -9,7 +9,8 @@ #include struct GLMesh { - GLuint vao; + GLuint vao_first_pass; + GLuint vao_second_pass; GLuint vertex_buffer; GLuint index_buffer; GLuint textures; From 6ac970d9a34936af8ff98453da551c22765b5dfc Mon Sep 17 00:00:00 2001 From: vlj Date: Thu, 16 Jan 2014 23:04:12 +0100 Subject: [PATCH 320/412] STKMesh: Use SSAO --- data/shaders/object_pass2.frag | 4 +++- src/graphics/stkmesh.cpp | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index f9024054f..84724eb60 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -2,6 +2,7 @@ uniform sampler2D Albedo; uniform sampler2D DiffuseMap; uniform sampler2D SpecularMap; +uniform sampler2D SSAO; uniform vec2 screen; uniform vec3 ambient; in vec2 uv; @@ -12,6 +13,7 @@ void main(void) vec4 color = texture2D(Albedo, uv); vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - vec3 LightFactor = ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + float ao = texture2D(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); gl_FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 0d02d5104..9051ad254 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -53,7 +53,7 @@ namespace ObjectPass2Shader { GLuint Program; GLuint attrib_position, attrib_texcoord; - GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_screen, uniform_ambient; + GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; void init() { @@ -65,16 +65,18 @@ namespace ObjectPass2Shader uniform_Albedo = glGetUniformLocation(Program, "Albedo"); uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); } - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap) + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniform1i(uniform_Albedo, TU_Albedo); glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -245,9 +247,11 @@ void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); glUseProgram(ObjectPass2Shader::Program); - ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2); + ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); From 15401c0b022a2f3b092077031719c7240848d75d Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Thu, 16 Jan 2014 19:13:23 -0800 Subject: [PATCH 321/412] Fixed music starting in menu, also corrected using the startRightNow parameter in MusicManager::startMusic() --- src/audio/music_information.cpp | 8 ++++++++ src/audio/music_information.hpp | 5 +++++ src/audio/music_manager.cpp | 1 + src/states_screens/options_screen_audio.cpp | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/audio/music_information.cpp b/src/audio/music_information.cpp index 2d7cc8e86..1b545ceea 100644 --- a/src/audio/music_information.cpp +++ b/src/audio/music_information.cpp @@ -273,6 +273,8 @@ void MusicInformation::stopMusic() delete m_fast_music; m_fast_music=NULL; } + if(m_music_waiting) + m_music_waiting = false; } // stopMusic //----------------------------------------------------------------------------- @@ -284,6 +286,12 @@ void MusicInformation::pauseMusic() //----------------------------------------------------------------------------- void MusicInformation::resumeMusic() { + if(m_music_waiting) + { + startMusic(); + m_music_waiting = false; + return; + } if (m_normal_music != NULL) m_normal_music->resumeMusic(); if (m_fast_music != NULL) m_fast_music->resumeMusic(); } // resumeMusic diff --git a/src/audio/music_information.hpp b/src/audio/music_information.hpp index 07d1aebfa..296f039c1 100644 --- a/src/audio/music_information.hpp +++ b/src/audio/music_information.hpp @@ -48,6 +48,10 @@ private: std::vector m_all_tracks; //int m_numLoops; + /** If music is loaded but hasn't been started yet (MusicManager::startMusic() + * was told not to start right away). */ + bool m_music_waiting; + /** If faster music is enabled at all (either separate file or using * the pitch shift approach). */ bool m_enable_fast; @@ -87,6 +91,7 @@ public: //int getNumLoops () const {return m_numLoops; } float getFasterTime () const {return m_faster_time; } float getMaxPitch () const {return m_max_pitch; } + void setMusicWaiting () {m_music_waiting = true;} void addMusicToTracks (); void update (float dt); void startMusic (); diff --git a/src/audio/music_manager.cpp b/src/audio/music_manager.cpp index 99c156c77..3bb713804 100644 --- a/src/audio/music_manager.cpp +++ b/src/audio/music_manager.cpp @@ -182,6 +182,7 @@ void MusicManager::startMusic(MusicInformation* mi, bool startRightNow) mi->volumeMusic(m_masterGain); if (startRightNow) mi->startMusic(); + else mi->setMusicWaiting(); } // startMusic //----------------------------------------------------------------------------- diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index 5d6de54e0..3abd6a514 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -147,7 +147,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name, if(w->getState() == false) music_manager->stopMusic(); else - music_manager->startMusic(music_manager->getCurrentMusic()); + music_manager->startMusic(music_manager->getCurrentMusic(), 0); } else if(name == "sfx_enabled") { From 9730e05b1d4d6d1f17ef03d3989137f3fdde34b7 Mon Sep 17 00:00:00 2001 From: thelittlegumnut Date: Fri, 17 Jan 2014 19:34:22 +1100 Subject: [PATCH 322/412] Changed challenge completion strings. --- src/states_screens/feature_unlocked.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 602cdef76..b8568111e 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -171,16 +171,16 @@ void FeatureUnlockedCutScene::addTrophy(RaceManager::Difficulty difficulty) switch (difficulty) { case RaceManager::DIFFICULTY_EASY: - msg = _("You completed the easy challenge! This trophy is worth %i points", - CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY]); + msg = _("You completed the easy challenge! Points earned on this level: %i/%i", + CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]); break; case RaceManager::DIFFICULTY_MEDIUM: - msg = _("You completed the intermediate challenge! This trophy is worth %i points", - CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM]); + msg = _("You completed the intermediate challenge! Points earned on this level: %i/%i", + CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]); break; case RaceManager::DIFFICULTY_HARD: - msg = _("You completed the difficult challenge! This trophy is worth %i points", - CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]); + msg = _("You completed the difficult challenge! Points earned on this level: %i/%i", + CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]); break; default: assert(false); From b903f8788cd9084b3e7b89e8bd6c65d005ff55b3 Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Fri, 17 Jan 2014 17:02:53 +0100 Subject: [PATCH 323/412] INSTALL rewritten in Markdown. Note: This commit maybe needs a correction because the Ubuntu command is very long. --- INSTALL | 62 -------------------------------------------------- INSTALL.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 62 deletions(-) delete mode 100644 INSTALL create mode 100644 INSTALL.md diff --git a/INSTALL b/INSTALL deleted file mode 100644 index b329fd6b5..000000000 --- a/INSTALL +++ /dev/null @@ -1,62 +0,0 @@ -SUPERTUXKART INSTALLATION INSTRUCTIONS -====================================== - -Note : If you obtained this source code from github, you also need to download the game assets from sourceforge using SVN. - svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets -Place the stk-assets folder next to the source root stk-code folder. -See http://supertuxkart.sourceforge.net/Source_control for more information - - -Building STK on Linux --------------------- - -First, make sure that you have the following packages installed: - - * OpenGL (mesa) - * OpenAL (recommended: openal-soft-devel) - * Ogg (libogg-dev) - * Vorbis (libvorbis-dev) - * libcurl (libcurl-devel) - * libbluetooth (bluez-devel) - -Ubuntu command : - sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev - -Unpack the files from the tarball like this: - - tar xzf supertuxkart-*.tar.gz - cd supertuxkart-* - -where '*' is the version of SuperTuxkart you downloaded - eg 0.8.0. Then: - - -* Compile SuperTuxKart: - mkdir cmake_build - cd cmake_build - cmake .. - make VERBOSE=1 -j2 - To create a debug version of STK, use: - cmake .. -DCMAKE_BUILD_TYPE=Debug - -To test the compilation, supertuxkart can be run from the build -directory by ./bin/supertuxkart - -To install the file, as root execute: - - make install - -The default install location is /usr/local, i.e. the data files will -be written to /usr/local/share/games/supertuxkart, the executable -will be copied to /usr/local/bin. To change the default installation -location, specify CMAKE_INSTALL_PREFIX when running cmake, e.g.: - cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk - - -Building STK on OS X --------------------- -See http://supertuxkart.sourceforge.net/Building_and_packaging_on_OSX - - -Building STK on Windows ------------------------ -See http://supertuxkart.sourceforge.net/How_to_build_the_Windows_version diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..8279636ce --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,67 @@ +#SuperTuxKart Installation Instructions + +Note : If you obtained this source code from github, you also need to download the game assets from sourceforge using SVN. + +`svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets` + +Place the `stk-assets` folder next to the source root `stk-code` folder. +See for more information + + +##Building STK on Linux + +First, make sure that you have the following packages installed: + + * OpenGL (mesa) + * OpenAL (recommended: openal-soft-devel) + * Ogg (libogg-dev) + * Vorbis (libvorbis-dev) + * libcurl (libcurl-devel) + * libbluetooth (bluez-devel) + +Ubuntu command: + +`sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev` + +Unpack the files from the tarball like this: + +`tar xzf supertuxkart-*.tar.gz +cd supertuxkart-*` + +where `*` is the version of SuperTuxkart you downloaded - eg `0.8.0`. Then: + + +Compile SuperTuxKart: + +`mkdir cmake_build` + +`cd cmake_build` + +`cmake ..` + +`make VERBOSE=1 -j2` + +To create a debug version of STK, use: + +`cmake .. -DCMAKE_BUILD_TYPE=Debug` + +To test the compilation, supertuxkart can be run from the build +directory by ./bin/supertuxkart + +To install the file, as root execute: + +`make install` + +The default install location is `/usr/local`, i.e. the data files will +be written to `/usr/local/share/games/supertuxkart`, the executable +will be copied to `/usr/local/bin`. To change the default installation +location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.: +`cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk` + + +##Building STK on OS X +See + + +##Building STK on Windows +See From 77c92896451f34384053c9adf470b6d5925d06f9 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 18:13:57 +0100 Subject: [PATCH 324/412] LightPrepass: Reenable glow pass. --- data/shaders/glow.frag | 5 ++- src/graphics/callbacks.hpp | 15 +++++++ src/graphics/glow.cpp | 12 ----- src/graphics/post_processing.cpp | 37 +++++++++++++++ src/graphics/post_processing.hpp | 2 + src/graphics/render.cpp | 22 +++++---- src/graphics/stkmesh.cpp | 77 ++++++++++++++++++++++++++++---- src/graphics/stkmesh.hpp | 2 + 8 files changed, 141 insertions(+), 31 deletions(-) diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag index 75940a806..175d50822 100644 --- a/data/shaders/glow.frag +++ b/data/shaders/glow.frag @@ -1,10 +1,11 @@ #version 130 uniform sampler2D tex; -uniform vec2 res; + +in vec2 uv; void main() { - vec2 coords = gl_FragCoord.xy / res; + vec2 coords = uv; vec4 col = texture2D(tex, coords); float alpha = col.a; diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 38412930a..a08565739 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -317,6 +317,21 @@ public: m_color[2] = b; } + float getRed() const + { + return m_color[0]; + } + + float getGreen() const + { + return m_color[1]; + } + + float getBlue() const + { + return m_color[2]; + } + private: float m_color[3]; }; diff --git a/src/graphics/glow.cpp b/src/graphics/glow.cpp index 897839065..323bffc74 100644 --- a/src/graphics/glow.cpp +++ b/src/graphics/glow.cpp @@ -61,18 +61,6 @@ GlowNode::~GlowNode() void GlowNode::render() { - return; - IVideoDriver * const drv = irr_driver->getVideoDriver(); - drv->setTransform(ETS_WORLD, AbsoluteTransformation); - drv->setMaterial(mat); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 0, ~0); - glEnable(GL_STENCIL_TEST); - - drv->drawMeshBuffer(sphere->getMeshBuffer(0)); - - glDisable(GL_STENCIL_TEST); } void GlowNode::OnRegisterSceneNode() diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 21abc0ab3..eb981e109 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -425,6 +425,22 @@ namespace PassThroughShader } } +namespace GlowShader +{ + GLuint Program = 0; + GLuint uniform_tex; + + GLuint vao = 0; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/glow.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + vao = createVAO(Program); + } +} + namespace SSAOShader { GLuint Program = 0; @@ -771,6 +787,27 @@ void PostProcessing::renderPassThrough(ITexture *tex) glDisable(GL_BLEND); } +void PostProcessing::renderGlow(ITexture *tex) +{ + if (!GlowShader::Program) + GlowShader::init(); + glDisable(GL_DEPTH_TEST); + + glUseProgram(GlowShader::Program); + glBindVertexArray(GlowShader::vao); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); + glUniform1i(GlowShader::uniform_tex, 0); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm) { diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 7bcc8cb6d..3e807f95e 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -88,6 +88,8 @@ public: /** Render tex. Used for blit/texture resize */ void renderPassThrough(video::ITexture *tex); + void PostProcessing::renderGlow(video::ITexture *tex); + /** Render the post-processed scene */ void render(); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 3612121cf..5813db8c7 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -213,12 +213,6 @@ void IrrDriver::renderGLSL(float dt) // Used to cull glowing items & lights const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox(); - // Render anything glowing. - if (!m_mipviz && !m_wireframe) - { - //renderGlow(overridemat, glows, cambox, cam); - } // end glow - // Shadows if (!m_mipviz && !m_wireframe && UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows()) @@ -236,6 +230,13 @@ void IrrDriver::renderGLSL(float dt) m_scene_manager->drawAll(m_renderpass); glDisable(GL_STENCIL_TEST); + // Render anything glowing. + if (!m_mipviz && !m_wireframe) + { + irr_driver->setPhase(2); + renderGlow(overridemat, glows, cambox, cam); + } // end glow + if (!bgnodes) { // If there are no BG nodes, it's more efficient to do the skybox here. @@ -665,10 +666,13 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, // Blur it m_post_processing->renderGaussian6Blur(m_rtts->getRTT(RTT_QUARTER1), m_rtts->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height); - // The glows will be rendered in the transparent phase + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); + glStencilFunc(GL_EQUAL, 0, ~0); + glEnable(GL_STENCIL_TEST); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + m_post_processing->renderGlow(m_rtts->getRTT(RTT_QUARTER1)); glDisable(GL_STENCIL_TEST); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 9051ad254..e7e22d857 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -3,6 +3,7 @@ #include #include #include "config/user_config.hpp" +#include "graphics/callbacks.hpp" static GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride) @@ -83,6 +84,28 @@ namespace ObjectPass2Shader } } +namespace ColorizeShader +{ + GLuint Program; + GLuint attrib_position; + GLuint uniform_MVP, uniform_col; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/colorize.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_col = glGetUniformLocation(Program, "col"); + } + + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform3f(uniform_col, r, g, b); + } +} + static GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { @@ -178,6 +201,7 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene return; ObjectPass1Shader::init(); ObjectPass2Shader::init(); + ColorizeShader::init(); } STKMesh::~STKMesh() @@ -187,7 +211,7 @@ STKMesh::~STKMesh() } static -void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void drawFirstPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -220,7 +244,7 @@ void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) } static -void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void drawSecondPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); @@ -261,14 +285,49 @@ void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type) } static -void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void drawGlow(const GLMesh &mesh, float r, float g, float b) +{ + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + + glUseProgram(ColorizeShader::Program); + ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void STKMesh::draw(const GLMesh &mesh) { if (!mesh.textures) return; - if (irr_driver->getPhase() == 0) - drawFirstPass(mesh, type); - else - drawSecondPass(mesh, type); + switch (irr_driver->getPhase()) + { + case 0: + drawFirstPass(mesh); + break; + case 1: + drawSecondPass(mesh); + break; + case 2: + { + ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE); + drawGlow(mesh, cb->getRed(), cb->getGreen(), cb->getBlue()); + break; + } + } + video::SMaterial material; material.MaterialType = irr_driver->getShader(ES_RAIN); @@ -297,6 +356,8 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, mesh.Stride); + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ColorizeShader::attrib_position, -1, -1, mesh.Stride); } void STKMesh::render() @@ -329,7 +390,7 @@ void STKMesh::render() if (isObject(material.MaterialType) && !isTransparentPass && !transparent) { initvaostate(GLmeshes[i], material.MaterialType); - draw(GLmeshes[i], material.MaterialType); + draw(GLmeshes[i]); } else if (transparent == isTransparentPass) { diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 90a41878f..65dc513aa 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -11,6 +11,7 @@ struct GLMesh { GLuint vao_first_pass; GLuint vao_second_pass; + GLuint vao_glow_pass; GLuint vertex_buffer; GLuint index_buffer; GLuint textures; @@ -24,6 +25,7 @@ class STKMesh : public irr::scene::CMeshSceneNode { protected: std::vector GLmeshes; + void STKMesh::draw(const GLMesh &mesh); public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), From 2721e2d82a5c28f351050a62f2addda9a267df4d Mon Sep 17 00:00:00 2001 From: Max Teufel Date: Fri, 17 Jan 2014 18:31:15 +0100 Subject: [PATCH 325/412] Using GitHub Flavored Markdown in INSTALL.md to fix some mistakes from commit b903f8788c --- INSTALL.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 8279636ce..9e1a4f976 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -21,25 +21,29 @@ First, make sure that you have the following packages installed: Ubuntu command: -`sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev` +``` +sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \ +libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev +``` Unpack the files from the tarball like this: -`tar xzf supertuxkart-*.tar.gz -cd supertuxkart-*` +``` +tar xzf supertuxkart-*.tar.gz +cd supertuxkart-* +``` where `*` is the version of SuperTuxkart you downloaded - eg `0.8.0`. Then: Compile SuperTuxKart: -`mkdir cmake_build` - -`cd cmake_build` - -`cmake ..` - -`make VERBOSE=1 -j2` +``` +mkdir cmake_build +cd cmake_build +cmake .. +make VERBOSE=1 -j2 +``` To create a debug version of STK, use: From ef163b29dfcd26d79e85aeec9ab33266e2e3d017 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 19:21:19 +0100 Subject: [PATCH 326/412] LightPrepass: Remove Forced bloom. This will be implemented using emissive material but our material loaders doesn't support it. --- src/graphics/post_processing.cpp | 89 +------------------------------- 1 file changed, 1 insertion(+), 88 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index eb981e109..52a6d1640 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -927,15 +927,8 @@ void PostProcessing::render() renderBloom(in); } - // Do we have any forced bloom nodes? If so, draw them now - const std::vector &blooms = irr_driver->getForcedBloom(); - const u32 bloomsize = blooms.size(); - if (!globalbloom && bloomsize) - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); - - - if (globalbloom || bloomsize) + if (globalbloom) { // Clear the alpha to a suitable value, stencil glClearColor(0, 0, 0, 0.1f); @@ -946,86 +939,6 @@ void PostProcessing::render() glClearColor(0, 0, 0, 0); glColorMask(1, 1, 1, 1); - // The forced-bloom objects are drawn again, to know which pixels to pick. - // While it's more drawcalls, there's a cost to using four MRTs over three, - // and there shouldn't be many such objects in a track. - // The stencil is already in use for the glow. The alpha channel is best - // reserved for other use (specular, etc). - // - // They are drawn with depth and color writes off, giving 4x-8x drawing speed. - if (bloomsize) - { - const core::aabbox3df &cambox = camnode-> - getViewFrustum()-> - getBoundingBox(); - - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID); - SOverrideMaterial &overridemat = drv->getOverrideMaterial(); - overridemat.EnablePasses = ESNRP_SOLID; - overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK; - overridemat.Enabled = true; - - overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER); - overridemat.Material.ZWriteEnable = false; - overridemat.Material.ColorMask = ECP_ALPHA; - - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, ~0); - glEnable(GL_STENCIL_TEST); - - camnode->render(); - - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - // Second pass for transparents. No-op for solids. - irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT); - for (u32 i = 0; i < bloomsize; i++) - { - scene::ISceneNode * const cur = blooms[i].node; - - // Quick box-based culling - const core::aabbox3df nodebox = cur->getTransformedBoundingBox(); - if (!nodebox.intersectsWithBox(cambox)) - continue; - - bloomcb->setPower(blooms[i].power); - - cur->render(); - } - - overridemat.Enabled = 0; - overridemat.EnablePasses = 0; - - // Ok, we have the stencil; now use it to blit from color to bloom tex - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, ~0); - m_material.MaterialType = EMT_SOLID; - m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR)); - - // Just in case. - glColorMask(1, 1, 1, 0); - drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false); - - m_material.ColorMask = ECP_RGB; - drawQuad(cam, m_material); - m_material.ColorMask = ECP_ALL; - - glColorMask(1, 1, 1, 1); - glDisable(GL_STENCIL_TEST); - } // end forced bloom - // To half drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false); renderPassThrough(irr_driver->getRTT(RTT_TMP3)); From 2500c6cb4924a4252b88852868885dcddf931c22 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 19:22:00 +0100 Subject: [PATCH 327/412] Fix compilation on non VS build --- src/graphics/post_processing.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 3e807f95e..e622118de 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -88,7 +88,7 @@ public: /** Render tex. Used for blit/texture resize */ void renderPassThrough(video::ITexture *tex); - void PostProcessing::renderGlow(video::ITexture *tex); + void renderGlow(video::ITexture *tex); /** Render the post-processed scene */ void render(); From 5a5a39f586c7be0deb702597c95f927b005d732b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 19:28:26 +0100 Subject: [PATCH 328/412] OGL32CTX: Use the userconfig parameter to decide to use glsl. Queried extensions does seems to disable glsl when using a core context. --- src/graphics/irr_driver.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 2fec5b517..a59917cc4 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -413,8 +413,12 @@ void IrrDriver::initDevice() m_scene_manager = m_device->getSceneManager(); m_gui_env = m_device->getGUIEnvironment(); m_video_driver = m_device->getVideoDriver(); - m_glsl = m_video_driver->queryFeature(video::EVDF_ARB_GLSL) && - m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) && + m_glsl = +#if defined(__APPLE__) +#else + m_video_driver->queryFeature(video::EVDF_ARB_GLSL) && + m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) && +#endif UserConfigParams::m_pixel_shaders; // This remaps the window, so it has to be done before the clear to avoid flicker From 620be813ebed0cfd67adff830b1582de6b5a7d53 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 19:33:43 +0100 Subject: [PATCH 329/412] Forget an extra qualifier --- src/graphics/stkmesh.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 65dc513aa..8c4f89637 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -25,7 +25,7 @@ class STKMesh : public irr::scene::CMeshSceneNode { protected: std::vector GLmeshes; - void STKMesh::draw(const GLMesh &mesh); + void draw(const GLMesh &mesh); public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), From 8e1d76dd8fb507f635e711e3c1d3ad989e594ef8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 21:15:43 +0100 Subject: [PATCH 330/412] Throw a fatal error if we ask a normalmap effect and the underlying mesh doesnt have one. --- src/graphics/material.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 43fc695b8..b5c5c6ead 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -762,6 +762,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m IVideoDriver* video_driver = irr_driver->getVideoDriver(); if (irr_driver->isGLSL()) { + + if (mb->getVertexType() != video::EVT_TANGENTS) + Log::fatal("material", "Requiring normal map without tangent enabled mesh"); ITexture* tex = irr_driver->getTexture(m_normal_map_tex); if (m_is_heightmap) { From 7da65c15f0e1c51cc7660caa41b6da2c935bab3d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 21:29:39 +0100 Subject: [PATCH 331/412] Enable tangents on every lod instance and fix normalmap This will increase the memory footprint of lod object, however this is the only way I found to make meshbuffer using GE_NORMAL_MAP to provide the necessary info to this shader. Now the pedestal in overlord looks perfectly normal mapped. --- data/shaders/normalmap.frag | 8 +++----- data/shaders/normalmap.vert | 2 -- src/graphics/material.cpp | 2 +- src/tracks/lod_node_loader.cpp | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 4b56d5d00..fa98598f8 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -4,7 +4,6 @@ uniform sampler2D normalMap; //The bump-map noperspective in vec3 tangent; noperspective in vec3 bitangent; -noperspective in vec3 normal; in vec2 uv; void main() @@ -13,11 +12,10 @@ void main() vec3 TS_normal = 2.0 * texture2D (normalMap, uv).rgb - 1.0; // Because of interpolation, we need to renormalize vec3 Frag_tangent = normalize(tangent); - vec3 Frag_bitangent = normalize(cross(normal, tangent)); - vec3 Frag_normal = cross(Frag_tangent, Frag_bitangent); + vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent)); + vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent); - - vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent + TS_normal.z * Frag_normal; + vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal; FragmentNormal = normalize(FragmentNormal); diff --git a/data/shaders/normalmap.vert b/data/shaders/normalmap.vert index 32b14aaa1..8518a2399 100644 --- a/data/shaders/normalmap.vert +++ b/data/shaders/normalmap.vert @@ -4,13 +4,11 @@ uniform mat4 TransposeInverseModelView; noperspective out vec3 tangent; noperspective out vec3 bitangent; -noperspective out vec3 normal; out vec2 uv; void main() { uv = gl_MultiTexCoord0.st; - normal = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; tangent = (TransposeInverseModelView * gl_MultiTexCoord1).xyz; bitangent = (TransposeInverseModelView * gl_MultiTexCoord2).xyz; gl_Position = ModelViewProjectionMatrix * gl_Vertex; diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index b5c5c6ead..dedbae279 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -764,7 +764,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m { if (mb->getVertexType() != video::EVT_TANGENTS) - Log::fatal("material", "Requiring normal map without tangent enabled mesh"); + Log::error("material", "Requiring normal map without tangent enabled mesh"); ITexture* tex = irr_driver->getTexture(m_normal_map_tex); if (m_is_heightmap) { diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index d9add8869..e100e8634 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -92,7 +92,7 @@ LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* pare continue; } - if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) + //if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) { scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); From 693e2c7e33eb532bb165af80be3e9e7e7b507081 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 23:50:06 +0100 Subject: [PATCH 332/412] STKMesh: Support NormalMapped meshes. --- data/shaders/normalmap.frag | 8 +- data/shaders/normalmap.vert | 12 ++- src/graphics/stkmesh.cpp | 141 +++++++++++++++++++++++++++++++----- src/graphics/stkmesh.hpp | 4 +- 4 files changed, 133 insertions(+), 32 deletions(-) diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index fa98598f8..5a062849d 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -1,6 +1,5 @@ #version 130 -uniform sampler2D texture; //The texture -uniform sampler2D normalMap; //The bump-map +uniform sampler2D normalMap; noperspective in vec3 tangent; noperspective in vec3 bitangent; @@ -18,8 +17,5 @@ void main() vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal; FragmentNormal = normalize(FragmentNormal); - - gl_FragData[0] = texture2D (texture, uv); - gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(0.); + gl_FragColor = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/normalmap.vert b/data/shaders/normalmap.vert index 8518a2399..13b53645e 100644 --- a/data/shaders/normalmap.vert +++ b/data/shaders/normalmap.vert @@ -2,15 +2,19 @@ uniform mat4 ModelViewProjectionMatrix; uniform mat4 TransposeInverseModelView; +in vec3 Position; +in vec2 Texcoord; +in vec3 Tangent; +in vec3 Bitangent; noperspective out vec3 tangent; noperspective out vec3 bitangent; out vec2 uv; void main() { - uv = gl_MultiTexCoord0.st; - tangent = (TransposeInverseModelView * gl_MultiTexCoord1).xyz; - bitangent = (TransposeInverseModelView * gl_MultiTexCoord2).xyz; - gl_Position = ModelViewProjectionMatrix * gl_Vertex; + uv = Texcoord; + tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz; + bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz; + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index e7e22d857..0dfa60977 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -6,7 +6,7 @@ #include "graphics/callbacks.hpp" static -GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride) +GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, size_t stride) { GLuint vao; glGenVertexArrays(1, &vao); @@ -17,11 +17,28 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glEnableVertexAttribArray(attrib_texcoord); if ((GLint)attrib_normal != -1) glEnableVertexAttribArray(attrib_normal); + if ((GLint)attrib_tangent != -1) + glEnableVertexAttribArray(attrib_tangent); + if ((GLint)attrib_bitangent != -1) + glEnableVertexAttribArray(attrib_bitangent); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); if ((GLint)attrib_texcoord != -1) glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); if ((GLint)attrib_normal != -1) glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); + if ((GLint)attrib_tangent != -1) + { + assert(stride >= 48); + glVertexAttribPointer(attrib_tangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)36); + } + + if ((GLint)attrib_bitangent != -1) + { + printf("stride of is %d\n", stride); + assert(stride >= 60); + glVertexAttribPointer(attrib_bitangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)48); + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); glBindVertexArray(0); return vao; @@ -84,6 +101,33 @@ namespace ObjectPass2Shader } } +namespace NormalMapShader +{ + GLuint Program; + GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent; + GLuint uniform_MVP, uniform_TIMV, uniform_normalMap; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_tangent = glGetAttribLocation(Program, "Tangent"); + attrib_bitangent = glGetAttribLocation(Program, "Bitangent"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_normalMap = glGetUniformLocation(Program, "normalMap"); + } + + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_normalMap, TU_normalMap); + } +} + namespace ColorizeShader { GLuint Program; @@ -179,9 +223,14 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) } ITexture *tex = mb->getMaterial().getTexture(0); if (tex) - result.textures = static_cast(tex)->getOpenGLTextureName(); + result.textures[0] = static_cast(tex)->getOpenGLTextureName(); else - result.textures = 0; + result.textures[0] = 0; + tex = mb->getMaterial().getTexture(1); + if (tex) + result.textures[1] = static_cast(tex)->getOpenGLTextureName(); + else + result.textures[1] = 0; return result; } @@ -201,6 +250,7 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene return; ObjectPass1Shader::init(); ObjectPass2Shader::init(); + NormalMapShader::init(); ColorizeShader::init(); } @@ -243,6 +293,47 @@ void drawFirstPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } +static +void drawNormalPass(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + assert(mesh.textures[1]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glUseProgram(NormalMapShader::Program); + NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + + glBindVertexArray(mesh.vao_first_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); +} + static void drawSecondPass(const GLMesh &mesh) { @@ -261,7 +352,7 @@ void drawSecondPass(const GLMesh &mesh) ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -308,23 +399,26 @@ void drawGlow(const GLMesh &mesh, float r, float g, float b) glBindBuffer(GL_ARRAY_BUFFER, 0); } -void STKMesh::draw(const GLMesh &mesh) +void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { - if (!mesh.textures) + if (!mesh.textures[0]) return; switch (irr_driver->getPhase()) { case 0: - drawFirstPass(mesh); + if (type == irr_driver->getShader(ES_OBJECTPASS)) + drawFirstPass(mesh); + else if (type == irr_driver->getShader(ES_NORMAL_MAP)) + drawNormalPass(mesh); break; case 1: drawSecondPass(mesh); break; case 2: { - ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE); - drawGlow(mesh, cb->getRed(), cb->getGreen(), cb->getBlue()); - break; + ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE); + drawGlow(mesh, cb->getRed(), cb->getGreen(), cb->getBlue()); + break; } } @@ -342,6 +436,8 @@ static bool isObject(video::E_MATERIAL_TYPE type) { if (type == irr_driver->getShader(ES_OBJECTPASS)) return true; + if (type == irr_driver->getShader(ES_NORMAL_MAP)) + return true; return false; } @@ -349,15 +445,20 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (mesh.vao_first_pass) return; - - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, - mesh.Stride); + if (type == irr_driver->getShader(ES_OBJECTPASS)) + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + } + else if (type == irr_driver->getShader(ES_NORMAL_MAP)) + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride); + } mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, - mesh.Stride); - mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ColorizeShader::attrib_position, -1, -1, mesh.Stride); + ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, mesh.Stride); + + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, mesh.Stride); } void STKMesh::render() @@ -380,7 +481,7 @@ void STKMesh::render() scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (mb) { - const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); bool transparent = (rnd && rnd->isTransparent()); @@ -390,7 +491,7 @@ void STKMesh::render() if (isObject(material.MaterialType) && !isTransparentPass && !transparent) { initvaostate(GLmeshes[i], material.MaterialType); - draw(GLmeshes[i]); + draw(GLmeshes[i], material.MaterialType); } else if (transparent == isTransparentPass) { diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 8c4f89637..faf7144f3 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -14,7 +14,7 @@ struct GLMesh { GLuint vao_glow_pass; GLuint vertex_buffer; GLuint index_buffer; - GLuint textures; + GLuint textures[2]; GLenum PrimitiveType; GLenum IndexType; size_t IndexCount; @@ -25,7 +25,7 @@ class STKMesh : public irr::scene::CMeshSceneNode { protected: std::vector GLmeshes; - void draw(const GLMesh &mesh); + void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type); public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), From 787866909d701a3d65faa5b0cbf4452db50250ab Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 17 Jan 2014 23:59:08 +0100 Subject: [PATCH 333/412] SSAO: Do not use trilinear filtering Normals RTT is not mipmapped and thus bad things happened above a certain value in the depth buffer because of trilinear filtering. --- data/shaders/ssao.frag | 126 +++++++++++++++---------------- src/graphics/post_processing.cpp | 4 + 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 39636e05d..50a70921b 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,66 +1,66 @@ -#version 130 -uniform sampler2D normals_and_depth; -uniform mat4 invprojm; -uniform mat4 projm; -uniform vec4 samplePoints[16]; - -in vec2 uv; - -const float strengh = 4.; -const float radius = .4f; - -#define SAMPLES 16 - -const float invSamples = strengh / SAMPLES; - -// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +#version 130 +uniform sampler2D normals_and_depth; +uniform mat4 invprojm; +uniform mat4 projm; +uniform vec4 samplePoints[16]; + +in vec2 uv; + +const float strengh = 4.; +const float radius = .4f; + +#define SAMPLES 16 + +const float invSamples = strengh / SAMPLES; + +// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ float rand(vec2 co) { return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453); -} - -void main(void) -{ - vec4 cur = texture2D(normals_and_depth, uv); - float curdepth = texture2D(normals_and_depth, uv).a; - vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); - FragPos /= FragPos.w; - - // get the normal of current fragment - vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0)); - // Workaround for nvidia and skyboxes - float len = dot(vec3(1.0), abs(cur.xyz)); - if (len < 0.2 || curdepth > 0.99) discard; - // Make a tangent as random as possible - vec3 randvect; - randvect.x = rand(uv); - randvect.y = rand(vec2(randvect.x, FragPos.z)); - randvect.z = rand(randvect.xy); - vec3 tangent = normalize(cross(norm, randvect)); - vec3 bitangent = cross(norm, tangent); - - float bl = 0.0; - - 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 = projm * samplePos; - sampleProj /= sampleProj.w; - - bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); - // get the depth of the occluder fragment - float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; - // Position of the occluder fragment in worldSpace - vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); - occluderPos /= occluderPos.w; - - bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); - bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) : 0.; - } - - // output the result - float ao = 1.0 - bl * invSamples; - - gl_FragColor = vec4(ao); -} +} + +void main(void) +{ + vec4 cur = texture2D(normals_and_depth, uv); + float curdepth = texture2D(normals_and_depth, uv).a; + vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); + FragPos /= FragPos.w; + + // get the normal of current fragment + vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0)); + // Workaround for nvidia and skyboxes + float len = dot(vec3(1.0), abs(cur.xyz)); + if (len < 0.2 || curdepth > 0.999) discard; + // Make a tangent as random as possible + vec3 randvect; + randvect.x = rand(uv); + randvect.y = rand(vec2(randvect.x, FragPos.z)); + randvect.z = rand(randvect.xy); + vec3 tangent = normalize(cross(norm, randvect)); + vec3 bitangent = cross(norm, tangent); + + float bl = 0.0; + + 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 = projm * samplePos; + sampleProj /= sampleProj.w; + + bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); + // get the depth of the occluder fragment + float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; + // Position of the occluder fragment in worldSpace + vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); + occluderPos /= occluderPos.w; + + bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius); + bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) : 0.; + } + + // output the result + float ao = 1.0 - bl * invSamples; + + gl_FragColor = vec4(ao); +} diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 52a6d1640..f7c8988ea 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -824,6 +824,10 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glUniform1i(SSAOShader::uniform_normals_and_depth, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); From ec40e2f7fcc97fee01558d54fe84f8f34bee7c00 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Jan 2014 18:36:38 -0500 Subject: [PATCH 334/412] Undo the hack to always use tangents with LOD meshes, now that the exporter correctly exports the tangent flag --- src/tracks/lod_node_loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracks/lod_node_loader.cpp b/src/tracks/lod_node_loader.cpp index e100e8634..d9add8869 100644 --- a/src/tracks/lod_node_loader.cpp +++ b/src/tracks/lod_node_loader.cpp @@ -92,7 +92,7 @@ LODNode* LodNodeLoader::instanciate(const XMLNode* node, scene::ISceneNode* pare continue; } - //if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) + if (group[m].m_tangent && a_mesh->getMeshBuffer(0)->getVertexType() != video::EVT_TANGENTS) { scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); scene::IMesh* m2 = manip->createMeshWithTangents(a_mesh); From 605becfbdcd0dd26d7093af28d3aacc2f2b790b8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 00:47:31 +0100 Subject: [PATCH 335/412] OGL32CTX: Enable glsl based on GL major version. --- src/graphics/irr_driver.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index a59917cc4..05ec7b456 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -413,13 +413,12 @@ void IrrDriver::initDevice() m_scene_manager = m_device->getSceneManager(); m_gui_env = m_device->getGUIEnvironment(); m_video_driver = m_device->getVideoDriver(); - m_glsl = -#if defined(__APPLE__) -#else - m_video_driver->queryFeature(video::EVDF_ARB_GLSL) && - m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) && -#endif - UserConfigParams::m_pixel_shaders; + + int GLMajorVersion; + glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion); + printf("OPENGL VERSION IS %d\n", GLMajorVersion); + m_glsl = (GLMajorVersion >= 3) && UserConfigParams::m_pixel_shaders; + // This remaps the window, so it has to be done before the clear to avoid flicker m_device->setResizable(false); From 95103c988f30f178fba896546a5690687d895d49 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Jan 2014 18:55:47 -0500 Subject: [PATCH 336/412] respect the new flag and avoid creating animated meshes where unecessary --- src/tracks/track_object_presentation.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 52fec7861..35df504c9 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -169,7 +169,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node std::string render_pass; xml_node.get("renderpass", &render_pass); - if(render_pass == "skybox") + bool skeletal_animation = true; // for backwards compatibility, if unspecified assume there is + xml_node.get("skeletal-animation", &skeletal_animation); + + if (render_pass == "skybox") { m_is_in_skybox = true; } @@ -177,8 +180,8 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node //std::string full_path = // World::getWorld()->getTrack()->getTrackFile(model_name); - bool animated = (UserConfigParams::m_graphical_effects || - World::getWorld()->getIdent() == IDENT_CUSTSCENE); + bool animated = skeletal_animation && (UserConfigParams::m_graphical_effects || + World::getWorld()->getIdent() == IDENT_CUSTSCENE); if (animated) @@ -232,7 +235,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh( void TrackObjectPresentationMesh::init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled) { - bool animated = (UserConfigParams::m_graphical_effects || + bool skeletal_animation = true; // for backwards compatibility, if unspecified assume there is + xml_node->get("skeletal-animation", &skeletal_animation); + + bool animated = skeletal_animation && (UserConfigParams::m_graphical_effects || World::getWorld()->getIdent() == IDENT_CUSTSCENE); m_mesh->grab(); From 3941b782b8a9cd2a48eba93cc1f6a1aa5e0f0ec9 Mon Sep 17 00:00:00 2001 From: gl3nn Date: Sat, 18 Jan 2014 01:07:01 +0100 Subject: [PATCH 337/412] Fix for the overloaded toString() function that takes booleans as parameter. --- src/utils/string_utils.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index f1674c404..19c238368 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -26,6 +26,7 @@ #include #include #include "utils/types.hpp" +#include "utils/log.hpp" namespace StringUtils { @@ -75,12 +76,13 @@ namespace StringUtils // ------------------------------------------------------------------------ /** Specialisiation for bools to return 'true' or 'false'/ */ - template - std::string toString(bool &b) + inline std::string toString(bool &b) { + Log::info("string_utils","toString(bool) called"); return (b ? "true" : "false"); } // toString(bool) + // ------------------------------------------------------------------------ template irr::core::stringw toWString (const T& any) From 5a2ad7c8aafbc967907d138201b69f73cf0f86bb Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Jan 2014 19:16:01 -0500 Subject: [PATCH 338/412] Create mesh with tangents if needed in track objects too --- src/tracks/track_object_presentation.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 35df504c9..266e1ede8 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -41,6 +41,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- @@ -177,6 +178,9 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node m_is_in_skybox = true; } + bool tangent = false; + xml_node.get("tangents", &tangent); + //std::string full_path = // World::getWorld()->getTrack()->getTrackFile(model_name); @@ -191,6 +195,13 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node else { m_mesh = irr_driver->getMesh(model_name); + + if (tangent) + { + scene::IMeshManipulator* manip = irr_driver->getVideoDriver()->getMeshManipulator(); + // TODO: perhaps the original mesh leaks here? + m_mesh = manip->createMeshWithTangents(m_mesh); + } } if (!m_mesh) From 32ec3c0f0797d12a0da136a53d4493ba9196884e Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 01:18:06 +0100 Subject: [PATCH 339/412] STKMesh: Use a better error message instead of crashing --- src/graphics/stkmesh.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 0dfa60977..9a058ffef 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -28,14 +28,15 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); if ((GLint)attrib_tangent != -1) { - assert(stride >= 48); + if (stride < 48) + Log::error("material", "Tangents not present in VBO"); glVertexAttribPointer(attrib_tangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)36); } if ((GLint)attrib_bitangent != -1) { - printf("stride of is %d\n", stride); - assert(stride >= 60); + if (stride < 60) + Log::error("material", "Bitangents not present in VBO"); glVertexAttribPointer(attrib_bitangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)48); } From ca8d9560b70a250f18826998bcdb6db91b12dc9a Mon Sep 17 00:00:00 2001 From: gl3nn Date: Sat, 18 Jan 2014 01:23:48 +0100 Subject: [PATCH 340/412] Forgot to take out the log statement. --- src/utils/string_utils.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index 19c238368..355dfa841 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -74,15 +74,12 @@ namespace StringUtils } // toString template // ------------------------------------------------------------------------ - /** Specialisiation for bools to return 'true' or 'false'/ - */ + /** Specialisiation for bools to return 'true' or 'false'*/ inline std::string toString(bool &b) { - Log::info("string_utils","toString(bool) called"); return (b ? "true" : "false"); } // toString(bool) - // ------------------------------------------------------------------------ template irr::core::stringw toWString (const T& any) From 2e21d40ce4ef494e73da44a00aaa113a67708294 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Fri, 17 Jan 2014 19:33:54 -0500 Subject: [PATCH 341/412] Support tangent meshes in MeshTools --- src/graphics/mesh_tools.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/graphics/mesh_tools.cpp b/src/graphics/mesh_tools.cpp index ff44674e3..49c7814a0 100644 --- a/src/graphics/mesh_tools.cpp +++ b/src/graphics/mesh_tools.cpp @@ -19,20 +19,23 @@ #include "graphics/mesh_tools.hpp" #include #include +#include "utils/log.hpp" void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { Vec3 extend; *min = Vec3( 999999.9f); *max = Vec3(-999999.9f); - for(unsigned int i=0; igetMeshBufferCount(); i++) { + for(unsigned int i=0; igetMeshBufferCount(); i++) + { scene::IMeshBuffer *mb = mesh->getMeshBuffer(i); if (mb->getVertexType() == video::EVT_STANDARD) { u16 *mbIndices = mb->getIndices(); video::S3DVertex* mbVertices=(irr::video::S3DVertex*)mb->getVertices(); - for(unsigned int j=0; jgetIndexCount(); j+=1) { + for (unsigned int j=0; jgetIndexCount(); j+=1) + { int indx=mbIndices[j]; Vec3 c(mbVertices[indx].Pos.X, mbVertices[indx].Pos.Y, @@ -45,7 +48,22 @@ void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { { u16 *mbIndices = mb->getIndices(); video::S3DVertex2TCoords* mbVertices=(irr::video::S3DVertex2TCoords*)mb->getVertices(); - for(unsigned int j=0; jgetIndexCount(); j+=1) { + for (unsigned int j=0; jgetIndexCount(); j+=1) + { + int indx=mbIndices[j]; + Vec3 c(mbVertices[indx].Pos.X, + mbVertices[indx].Pos.Y, + mbVertices[indx].Pos.Z ); + min->min(c); + max->max(c); + } // for j + } + else if (mb->getVertexType() == video::EVT_TANGENTS) + { + u16 *mbIndices = mb->getIndices(); + video::S3DVertexTangents* mbVertices=(irr::video::S3DVertexTangents*)mb->getVertices(); + for (unsigned int j=0; jgetIndexCount(); j+=1) + { int indx=mbIndices[j]; Vec3 c(mbVertices[indx].Pos.X, mbVertices[indx].Pos.Y, @@ -56,8 +74,8 @@ void MeshTools::minMax3D(scene::IMesh* mesh, Vec3 *min, Vec3 *max) { } else { - fprintf(stderr, "Tools::minMax3D: Ignoring type '%d'!\n", - mb->getVertexType()); + Log::warn("Tools", "minMax3D: Ignoring type '%d'!\n", + mb->getVertexType()); } } // for i Date: Sat, 18 Jan 2014 02:28:22 +0100 Subject: [PATCH 342/412] Fix the game state of when dialogs should be popped up. --- src/guiengine/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guiengine/engine.cpp b/src/guiengine/engine.cpp index e6b69ca59..c3d28f6ed 100644 --- a/src/guiengine/engine.cpp +++ b/src/guiengine/engine.cpp @@ -837,7 +837,7 @@ namespace GUIEngine { widget->update(dt); } - DialogQueue::get()->update(); + if (state == GUIEngine::MENU) DialogQueue::get()->update(); } // Hack : on the first frame, irrlicht processes all events that have been queued From 42e6da443a0fc8132bdfae99aff25a5c344e7e4b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 03:24:55 +0100 Subject: [PATCH 343/412] Simplify Spheremap shader. --- data/shaders/objectpass_spheremap.frag | 15 +++++++-------- src/graphics/shaders.cpp | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 7db065066..7c907f629 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -1,8 +1,7 @@ #version 130 uniform sampler2D tex; -noperspective in vec3 eyenor; -noperspective in vec3 viewpos; +in vec4 color; noperspective in vec3 nor; void main() { @@ -10,16 +9,16 @@ void main() { const vec3 forward = vec3(0.0, 0.0, 1.0); // get the angle between the forward vector and the horizontal portion of the normal - vec3 normal_x = normalize(vec3(eyenor.x, 0.0, eyenor.z)); - float sin_theta_x = length(cross( forward, normal_x )) * eyenor.x/abs(eyenor.x); + vec3 normal_x = normalize(vec3(nor.x, 0.0, nor.z)); + float sin_theta_x = length(cross( forward, normal_x )) * nor.x/abs(nor.x); // get the angle between the forward vector and the vertical portion of the normal - vec3 normal_y = normalize(vec3(0.0, eyenor.y, eyenor.z)); - float sin_theta_y = length(cross( forward, normal_y )) * eyenor.y/abs(eyenor.y); + vec3 normal_y = normalize(vec3(0.0, nor.y, nor.z)); + float sin_theta_y = length(cross( forward, normal_y )) * nor.y/abs(nor.y); - vec4 detail0 = texture2D(tex, vec2(0.5 + sin_theta_x*0.5, 0.5 + sin_theta_y*0.5)); + vec4 detail0 = texture2D(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5); - gl_FragData[0] = detail0 * gl_Color; + gl_FragData[0] = detail0 * color; gl_FragData[1] = vec4(nor, gl_FragCoord.z); gl_FragData[2] = vec4(0.); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 46935d8e1..56354515e 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -97,7 +97,7 @@ void Shaders::loadShaders() m_shaders[ES_WATER_SURFACE] = glsl(dir + "water.vert", dir + "pass.frag", m_callbacks[ES_WATER]); - m_shaders[ES_SPHERE_MAP] = glslmat(dir + "objectpass_rimlit.vert", dir + "objectpass_spheremap.frag", + m_shaders[ES_SPHERE_MAP] = glslmat(dir + "objectpass.vert", dir + "objectpass_spheremap.frag", m_callbacks[ES_OBJECTPASS], EMT_SOLID); m_shaders[ES_GRASS] = glslmat(dir + "grass.vert", dir + "grass.frag", From 002bb9c2768771efb5caa61738c8f4a8e7298368 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 17:26:01 +0100 Subject: [PATCH 344/412] Remove unused spheremap.vert/frag --- data/shaders/spheremap.frag | 65 ------------------------------------- data/shaders/spheremap.vert | 51 ----------------------------- 2 files changed, 116 deletions(-) delete mode 100644 data/shaders/spheremap.frag delete mode 100644 data/shaders/spheremap.vert diff --git a/data/shaders/spheremap.frag b/data/shaders/spheremap.frag deleted file mode 100644 index 1223853e2..000000000 --- a/data/shaders/spheremap.frag +++ /dev/null @@ -1,65 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 the SuperTuxKart team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#version 130 -uniform sampler2D texture; -uniform vec3 lightdir; - -noperspective in vec3 normal; -in vec4 vertex_color; -noperspective in vec3 eyeVec; -noperspective in vec3 lightVec; - -void main() -{ - vec3 forward = vec3(0.0, 0.0, 1.0); - - // get the angle between the forward vector and the horizontal portion of the normal - vec3 normal_x = normalize(vec3(normal.x, 0.0, normal.z)); - float sin_theta_x = length(cross( forward, normal_x )) * normal.x/abs(normal.x); - - // get the angle between the forward vector and the vertical portion of the normal - vec3 normal_y = normalize(vec3(0.0, normal.y, normal.z)); - float sin_theta_y = length(cross( forward, normal_y ))* normal.y/abs(normal.y); - - vec4 detail0 = texture2D(texture, vec2(0.5 + sin_theta_x*0.5, 0.5 + sin_theta_y*0.5)); - - gl_FragColor = detail0 * (0.5 + dot(lightdir, normal)) * vertex_color; // 0.5 is the ambient light. - //gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - - // specular (phong) - vec3 R = normalize(reflect(lightVec, normal)); - float specular = max(dot(R,eyeVec),0.0); - - //gl_FragColor = vec4(specular, specular, specular, 1.0); - - if (specular > 0.0) - { - // weak specular - specular = specular*specular; - specular = specular*specular; - float specular_weak = specular*2.0; //max(specular*1.1, 1.0); - gl_FragColor += vec4(specular_weak, specular_weak, specular_weak, 0.0); - - /* - // strong specular - specular = specular*specular; - float specular_strong = specular; - gl_FragColor += vec4(specular_strong, specular_strong, specular_strong, 0.0); - */ - } -} diff --git a/data/shaders/spheremap.vert b/data/shaders/spheremap.vert deleted file mode 100644 index 175568130..000000000 --- a/data/shaders/spheremap.vert +++ /dev/null @@ -1,51 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 the SuperTuxKart team -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#version 130 -uniform mat4 ModelViewProjectionMatrix; -uniform mat4 TransposeInverseModelView; -uniform vec3 lightdir; - -noperspective out vec3 normal; -out vec4 vertex_color; -noperspective out vec3 eyeVec; -noperspective out vec3 lightVec; - -void main() -{ - gl_Position = ModelViewProjectionMatrix * gl_Vertex; - vertex_color = gl_Color; - - //vec3 normal3 = normalize(gl_Normal); - //vec4 normal4 = vec4(normal3.x, normal3.y, normal3.z, 0.0)*gl_ModelViewMatrix; - //normal = normal4.xyz; - - eyeVec = normalize(-gl_Position).xyz; // we are in Eye Coordinates, so EyePos is (0,0,0) - normal = normalize((TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz); - - // Building the matrix Eye Space -> Tangent Space - // gl_MultiTexCoord1.xyz - vec3 t = normalize ((TransposeInverseModelView * vec4(0.0, 0.0, 1.0, 1.)).xyz); // tangent - vec3 b = cross (normal, t); - - // transform light and half angle vectors by tangent basis - vec3 v; - v.x = dot(lightdir, t); - v.y = dot(lightdir, b); - v.z = dot(lightdir, normal); - lightVec = normalize (v); -} From fbe9b26127f14ceb0eec33b045bd9b214816590c Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 18:00:08 +0100 Subject: [PATCH 345/412] STKMesh: Support spheremap material --- data/shaders/objectpass_spheremap.frag | 10 +-- src/graphics/stkmesh.cpp | 107 +++++++++++++++++++++---- 2 files changed, 95 insertions(+), 22 deletions(-) diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 7c907f629..5d62c87c4 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -1,7 +1,6 @@ #version 130 uniform sampler2D tex; -in vec4 color; noperspective in vec3 nor; void main() { @@ -10,16 +9,13 @@ void main() { // get the angle between the forward vector and the horizontal portion of the normal vec3 normal_x = normalize(vec3(nor.x, 0.0, nor.z)); - float sin_theta_x = length(cross( forward, normal_x )) * nor.x/abs(nor.x); + float sin_theta_x = length(cross( forward, normal_x )) * nor.x / abs(nor.x); // get the angle between the forward vector and the vertical portion of the normal vec3 normal_y = normalize(vec3(0.0, nor.y, nor.z)); - float sin_theta_y = length(cross( forward, normal_y )) * nor.y/abs(nor.y); + float sin_theta_y = length(cross( forward, normal_y )) * nor.y / abs(nor.y); vec4 detail0 = texture2D(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5); - gl_FragData[0] = detail0 * color; - - gl_FragData[1] = vec4(nor, gl_FragCoord.z); - gl_FragData[2] = vec4(0.); + gl_FragColor = vec4(detail0.xyz, 1.); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 9a058ffef..b8fcf66a8 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -129,6 +129,31 @@ namespace NormalMapShader } } +namespace SphereMapShader +{ + GLuint Program; + GLuint attrib_position, attrib_normal; + GLuint uniform_MVP, uniform_TIMV, uniform_tex; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); + } + + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_tex, TU_tex); + } +} + namespace ColorizeShader { GLuint Program; @@ -253,6 +278,7 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene ObjectPass2Shader::init(); NormalMapShader::init(); ColorizeShader::init(); + SphereMapShader::init(); } STKMesh::~STKMesh() @@ -268,7 +294,7 @@ void drawFirstPass(const GLMesh &mesh) glStencilFunc(GL_ALWAYS, 0, ~0); glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); + glDisable(GL_ALPHA_TEST); glDepthMask(GL_TRUE); glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; @@ -335,13 +361,51 @@ void drawNormalPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } +static +void drawSphereMap(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glUseProgram(SphereMapShader::Program); + SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} + static void drawSecondPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); + glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; @@ -380,7 +444,7 @@ static void drawGlow(const GLMesh &mesh, float r, float g, float b) { glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); + glDisable(GL_ALPHA_TEST); glDepthMask(GL_FALSE); glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; @@ -407,13 +471,16 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) switch (irr_driver->getPhase()) { case 0: - if (type == irr_driver->getShader(ES_OBJECTPASS)) - drawFirstPass(mesh); - else if (type == irr_driver->getShader(ES_NORMAL_MAP)) + if (type == irr_driver->getShader(ES_NORMAL_MAP)) drawNormalPass(mesh); + else + drawFirstPass(mesh); break; case 1: - drawSecondPass(mesh); + if (type == irr_driver->getShader(ES_SPHERE_MAP)) + drawSphereMap(mesh); + else + drawSecondPass(mesh); break; case 2: { @@ -439,6 +506,8 @@ static bool isObject(video::E_MATERIAL_TYPE type) return true; if (type == irr_driver->getShader(ES_NORMAL_MAP)) return true; + if (type == irr_driver->getShader(ES_SPHERE_MAP)) + return true; return false; } @@ -446,19 +515,27 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) { if (mesh.vao_first_pass) return; - if (type == irr_driver->getShader(ES_OBJECTPASS)) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_NORMAL_MAP)) + if (type == irr_driver->getShader(ES_NORMAL_MAP)) { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride); } - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, mesh.Stride); + else + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + } + if (type == irr_driver->getShader(ES_SPHERE_MAP)) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + SphereMapShader::attrib_position, -1, SphereMapShader::attrib_normal, -1, -1, mesh.Stride); + } + else + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, mesh.Stride); + } mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, mesh.Stride); } From dec2cb29ec04f96ffafe6bca7c1a20457be68350 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 19:03:10 +0100 Subject: [PATCH 346/412] STKMesh: Support splatting --- data/shaders/splatting.frag | 24 +++-- data/shaders/splatting.vert | 12 +-- src/graphics/stkmesh.cpp | 170 ++++++++++++++++++++++++++++++++---- src/graphics/stkmesh.hpp | 2 +- 4 files changed, 176 insertions(+), 32 deletions(-) diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index ea1e398f0..5851248df 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -4,9 +4,12 @@ uniform sampler2D tex_detail0; uniform sampler2D tex_detail1; uniform sampler2D tex_detail2; uniform sampler2D tex_detail3; -//uniform sampler2D tex_detail4; +uniform sampler2D DiffuseMap; +uniform sampler2D SpecularMap; +uniform sampler2D SSAO; +uniform vec2 screen; +uniform vec3 ambient; -noperspective in vec3 nor; in vec2 uv; in vec2 uv_bis; @@ -17,17 +20,20 @@ void main() { vec4 detail1 = texture2D(tex_detail1, uv); vec4 detail2 = texture2D(tex_detail2, uv); vec4 detail3 = texture2D(tex_detail3, uv); -// vec4 detail4 = texture2D(tex_detail4, uv); vec4 detail4 = vec4(0.0); - vec4 splatted = (splatting.r * detail0 + + vec4 splatted = splatting.r * detail0 + splatting.g * detail1 + splatting.b * detail2 + - (1.0 - splatting.r - splatting.g - splatting.b) * detail3 + - (1.0 - splatting.a) * detail4); + (1.0 - splatting.r - splatting.g - splatting.b) * detail3; - gl_FragData[0] = vec4(splatted.xyz, 1.); + vec2 tc = gl_FragCoord.xy / screen; + vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; + float ao = texture2D(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; + + gl_FragColor = vec4(splatted.xyz * LightFactor, 1.); - gl_FragData[1] = vec4(normalize(nor) * 0.5 + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - splatted.a); +// gl_FragData[2] = vec4(1. - splatted.a); } diff --git a/data/shaders/splatting.vert b/data/shaders/splatting.vert index 871a062ed..772b957f3 100644 --- a/data/shaders/splatting.vert +++ b/data/shaders/splatting.vert @@ -16,18 +16,18 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #version 130 -uniform vec3 lightdir; uniform mat4 ModelViewProjectionMatrix; uniform mat4 TransposeInverseModelView; -noperspective out vec3 nor; +in vec3 Position; +in vec2 Texcoord; +in vec2 SecondTexcoord; out vec2 uv; out vec2 uv_bis; void main() { - uv = gl_MultiTexCoord0.st; - uv_bis = gl_MultiTexCoord1.st; - gl_Position = ModelViewProjectionMatrix * gl_Vertex; - nor = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz; + uv = Texcoord; + uv_bis = SecondTexcoord; + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index b8fcf66a8..b89342d01 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -6,7 +6,7 @@ #include "graphics/callbacks.hpp" static -GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, size_t stride) +GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, size_t stride) { GLuint vao; glGenVertexArrays(1, &vao); @@ -15,6 +15,8 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glEnableVertexAttribArray(attrib_position); if ((GLint)attrib_texcoord != -1) glEnableVertexAttribArray(attrib_texcoord); + if ((GLint)attrib_second_texcoord != -1) + glEnableVertexAttribArray(attrib_second_texcoord); if ((GLint)attrib_normal != -1) glEnableVertexAttribArray(attrib_normal); if ((GLint)attrib_tangent != -1) @@ -24,6 +26,12 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); if ((GLint)attrib_texcoord != -1) glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); + if ((GLint)attrib_second_texcoord != 1) + { + if (stride < 44) + Log::error("material", "Second texcoords not present in VBO"); + glVertexAttribPointer(attrib_second_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 36); + } if ((GLint)attrib_normal != -1) glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12); if ((GLint)attrib_tangent != -1) @@ -154,6 +162,49 @@ namespace SphereMapShader } } +namespace SplattingShader +{ + GLuint Program; + GLuint attrib_position, attrib_texcoord, attrib_second_texcoord; + GLuint uniform_MVP, uniform_tex_layout, uniform_tex_detail0, uniform_tex_detail1, uniform_tex_detail2, uniform_tex_detail3, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + + void init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/splatting.vert").c_str(), file_manager->getAsset("shaders/splatting.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_tex_layout = glGetUniformLocation(Program, "tex_layout"); + uniform_tex_detail0 = glGetUniformLocation(Program, "tex_detail0"); + uniform_tex_detail1 = glGetUniformLocation(Program, "tex_detail1"); + uniform_tex_detail2 = glGetUniformLocation(Program, "tex_detail2"); + uniform_tex_detail3 = glGetUniformLocation(Program, "tex_detail3"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_tex_layout, TU_tex_layout); + glUniform1i(uniform_tex_detail0, TU_tex_detail0); + glUniform1i(uniform_tex_detail1, TU_tex_detail1); + glUniform1i(uniform_tex_detail2, TU_tex_detail2); + glUniform1i(uniform_tex_detail3, TU_tex_detail3); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + } +} + namespace ColorizeShader { GLuint Program; @@ -247,16 +298,15 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) case scene::EPT_QUADS: assert(0 && "Unsupported primitive type"); } - ITexture *tex = mb->getMaterial().getTexture(0); - if (tex) - result.textures[0] = static_cast(tex)->getOpenGLTextureName(); - else - result.textures[0] = 0; - tex = mb->getMaterial().getTexture(1); - if (tex) - result.textures[1] = static_cast(tex)->getOpenGLTextureName(); - else - result.textures[1] = 0; + ITexture *tex; + for (unsigned i = 0; i < 6; i++) + { + tex = mb->getMaterial().getTexture(i); + if (tex) + result.textures[i] = static_cast(tex)->getOpenGLTextureName(); + else + result.textures[i] = 0; + } return result; } @@ -279,6 +329,7 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene NormalMapShader::init(); ColorizeShader::init(); SphereMapShader::init(); + SplattingShader::init(); } STKMesh::~STKMesh() @@ -399,6 +450,84 @@ void drawSphereMap(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } +static +void drawSplatting(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + + // Texlayout + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Tex detail0 + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mesh.textures[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Tex detail1 + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, mesh.textures[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Tex detail2 + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, mesh.textures[4]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + //Tex detail3 + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, mesh.textures[5]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + // Diffuse + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + // Specular + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + // SSAO + glActiveTexture(GL_TEXTURE7); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + + glUseProgram(SplattingShader::Program); + SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} + + static void drawSecondPass(const GLMesh &mesh) { @@ -479,6 +608,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) case 1: if (type == irr_driver->getShader(ES_SPHERE_MAP)) drawSphereMap(mesh); + else if (type == irr_driver->getShader(ES_SPLATTING)) + drawSplatting(mesh); else drawSecondPass(mesh); break; @@ -508,6 +639,8 @@ static bool isObject(video::E_MATERIAL_TYPE type) return true; if (type == irr_driver->getShader(ES_SPHERE_MAP)) return true; + if (type == irr_driver->getShader(ES_SPLATTING)) + return true; return false; } @@ -518,25 +651,30 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) if (type == irr_driver->getShader(ES_NORMAL_MAP)) { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride); + NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride); } else { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + ObjectPass1Shader::attrib_position, -1, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); } if (type == irr_driver->getShader(ES_SPHERE_MAP)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - SphereMapShader::attrib_position, -1, SphereMapShader::attrib_normal, -1, -1, mesh.Stride); + SphereMapShader::attrib_position, -1, -1, SphereMapShader::attrib_normal, -1, -1, mesh.Stride); + } + else if (type == irr_driver->getShader(ES_SPLATTING)) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + SplattingShader::attrib_position, SplattingShader::attrib_texcoord, SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, mesh.Stride); + ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); } - mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, mesh.Stride); + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, -1, mesh.Stride); } void STKMesh::render() diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index faf7144f3..84fa5f725 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -14,7 +14,7 @@ struct GLMesh { GLuint vao_glow_pass; GLuint vertex_buffer; GLuint index_buffer; - GLuint textures[2]; + GLuint textures[6]; GLenum PrimitiveType; GLenum IndexType; size_t IndexCount; From 5f7e6b28347e479edd686f60fa5fd72b7e195a66 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 19:47:18 +0100 Subject: [PATCH 347/412] Some fixes to the renderer. --- src/graphics/render.cpp | 10 +++++----- src/graphics/stkmesh.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 5813db8c7..61d3dc571 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -600,10 +600,10 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, glowcb->setResolution(UserConfigParams::m_width, UserConfigParams::m_height); - overridemat.Material.MaterialType = m_shaders->getShader(ES_COLORIZE); +/* overridemat.Material.MaterialType = m_shaders->getShader(ES_COLORIZE); overridemat.EnableFlags = video::EMF_MATERIAL_TYPE; overridemat.EnablePasses = scene::ESNRP_SOLID; - overridemat.Enabled = true; + overridemat.Enabled = true;*/ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glStencilFunc(GL_ALWAYS, 1, ~0); @@ -624,7 +624,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, } // Second round for transparents; it's a no-op for solids - m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT); +/* m_scene_manager->setCurrentRendertime(scene::ESNRP_TRANSPARENT); overridemat.Material.MaterialType = m_shaders->getShader(ES_COLORIZE_REF); for (u32 i = 0; i < glowcount; i++) { @@ -640,7 +640,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, cur->render(); } overridemat.Enabled = false; - overridemat.EnablePasses = 0; + overridemat.EnablePasses = 0;*/ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glDisable(GL_STENCIL_TEST); @@ -668,7 +668,7 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glStencilFunc(GL_EQUAL, 0, ~0); glEnable(GL_STENCIL_TEST); m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index b89342d01..e232fd05d 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -26,7 +26,7 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); if ((GLint)attrib_texcoord != -1) glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); - if ((GLint)attrib_second_texcoord != 1) + if ((GLint)attrib_second_texcoord != -1) { if (stride < 44) Log::error("material", "Second texcoords not present in VBO"); From 47099fb1a33b6bc2b66ef01b221a79cecb175c33 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 19:56:35 +0100 Subject: [PATCH 348/412] Use glow vao. --- src/graphics/stkmesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index e232fd05d..ca16e0ba1 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -587,7 +587,7 @@ void drawGlow(const GLMesh &mesh, float r, float g, float b) glUseProgram(ColorizeShader::Program); ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b); - glBindVertexArray(mesh.vao_second_pass); + glBindVertexArray(mesh.vao_glow_pass); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); From 00cf026051b392a8b327fad093923a7d9aab88af Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 20:11:18 +0100 Subject: [PATCH 349/412] Tweak glow so that black halo is less visible. --- data/shaders/glow.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag index 175d50822..9545f51b6 100644 --- a/data/shaders/glow.frag +++ b/data/shaders/glow.frag @@ -10,7 +10,7 @@ void main() vec4 col = texture2D(tex, coords); float alpha = col.a; - if (alpha < 0.04) discard; + if (alpha < 0.04 || length(col.xyz) < 0.2) discard; col *= vec4(vec3(4.0), 1.5); col.a *= 0.6; From a1f5e47cba7df174e50ca085925730db141b04b1 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 20:28:13 +0100 Subject: [PATCH 350/412] Use ARB_DEBUG_OUTPUT on windows in Debug mode. Hopefully the extension will work properly with every driver... --- lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp | 3 ++- src/graphics/glwrap.cpp | 12 +++++++----- src/graphics/glwrap.hpp | 3 +++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp index 3ab41c03e..d17e0532a 100644 --- a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp +++ b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp @@ -413,7 +413,8 @@ bool COpenGLDriver::initDriver(CIrrDeviceWin32* device) { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 1, -// WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + //WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, 0 }; hrc=wglCreateContextAttribs_ARB(HDc, 0, iAttribs); diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 69030a9e0..b3bc43dde 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -52,15 +52,14 @@ PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLTEXBUFFERPROC glTexBuffer; PFNGLBUFFERSUBDATAPROC glBufferSubData; PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; +PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; #endif static GLuint quad_buffer; static GLuint ColoredVertex; static bool is_gl_init = false; -// Please leave this code, it's for debugging purpose -//#define ENABLE_ARB_DEBUG_OUTPUT -#ifdef ENABLE_ARB_DEBUG_OUTPUT +#ifdef DEBUG static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *userparam) @@ -178,9 +177,12 @@ void initGL() glUniform4fv = (PFNGLUNIFORM4FVPROC)IRR_OGL_LOAD_EXTENSION("glUniform4fv"); glBufferSubData = (PFNGLBUFFERSUBDATAPROC)IRR_OGL_LOAD_EXTENSION("glBufferSubData"); glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)IRR_OGL_LOAD_EXTENSION("glVertexAttribIPointer"); +#ifdef DEBUG + glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); #endif -#ifdef ENABLE_ARB_DEBUG_OUTPUT - glDebugMessageCallbackARB(debugCallback, NULL); +#endif +#ifdef DEBUG + glDebugMessageCallbackARB((GLDEBUGPROCARB)debugCallback, NULL); #endif const float quad_vertex[] = { -1., -1., -1., 1., // UpperLeft diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index 1773a34ea..ee431953c 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -75,6 +75,9 @@ extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; extern PFNGLTEXBUFFERPROC glTexBuffer; extern PFNGLBUFFERSUBDATAPROC glBufferSubData; extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; +#ifdef DEBUG +extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; +#endif #endif From 6a995ab1782c70d2ab4c46f1d6f6dc6b7fd58142 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 20:47:53 +0100 Subject: [PATCH 351/412] STKMesh: Clean our buffers when deleted. --- src/graphics/stkmesh.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index ca16e0ba1..a35f7ce76 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -334,8 +334,18 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene STKMesh::~STKMesh() { -// glDeleteBuffers(vertex_buffer.size(), vertex_buffer.data()); -// glDeleteBuffers(index_buffer.size(), index_buffer.data()); + for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) + continue; + GLMesh mesh = GLmeshes[i]; + glDeleteVertexArrays(1, &(mesh.vao_first_pass)); + glDeleteVertexArrays(1, &(mesh.vao_second_pass)); + glDeleteVertexArrays(1, &(mesh.vao_glow_pass)); + glDeleteBuffers(1, &(mesh.vertex_buffer)); + glDeleteBuffers(1, &(mesh.index_buffer)); + } } static From 6df85e260c40f05f40f5a9de65acf5caaa3215ee Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 21:35:52 +0100 Subject: [PATCH 352/412] Shaders: FullScreenShader are not loaded at startup. Besides being cleaner it also help finding error in shaders. --- src/graphics/post_processing.cpp | 483 +++++-------------------------- src/graphics/shaders.cpp | 276 ++++++++++++++++++ src/graphics/shaders.hpp | 152 ++++++++++ 3 files changed, 500 insertions(+), 411 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f7c8988ea..f1773fe86 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -31,7 +31,6 @@ #include "race/race_manager.hpp" #include "tracks/track.hpp" #include "utils/log.hpp" -#include "graphics/glwrap.hpp" #include @@ -199,328 +198,17 @@ void PostProcessing::update(float dt) } } // update -GLuint quad_vbo = 0; - -static void initQuadVBO() -{ - initGL(); - const float quad_vertex[] = { - -1., -1., 0., 0., // UpperLeft - -1., 1., 0., 1., // LowerLeft - 1., -1., 1., 0., // UpperRight - 1., 1., 1., 1., // LowerRight - }; - glGenBuffers(1, &quad_vbo); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -static GLuint createVAO(GLuint Program) -{ - if (!quad_vbo) - initQuadVBO(); - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - GLuint attrib_position = glGetAttribLocation(Program, "Position"); - GLuint attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); - glEnableVertexAttribArray(attrib_position); - glEnableVertexAttribArray(attrib_texcoord); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); - glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); - glBindVertexArray(0); - return vao; -} - -namespace BloomShader -{ - GLuint Program = 0; - GLuint uniform_texture, uniform_low; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); - uniform_texture = glGetUniformLocation(Program, "tex"); - uniform_low = glGetUniformLocation(Program, "low"); - vao = createVAO(Program); - } -} - -namespace BloomBlendShader -{ - GLuint Program = 0; - GLuint uniform_texture, uniform_low; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); - uniform_texture = glGetUniformLocation(Program, "tex"); - vao = createVAO(Program); - } -} - -namespace PPDisplaceShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_dtex, uniform_viz; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_dtex = glGetUniformLocation(Program, "dtex"); - uniform_viz = glGetUniformLocation(Program, "viz"); - vao = createVAO(Program); - } -} - -namespace ColorLevelShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_inlevel, uniform_outlevel; - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_inlevel = glGetUniformLocation(Program, "inlevel"); - uniform_outlevel = glGetUniformLocation(Program, "outlevel"); - vao = createVAO(Program); - } -} - -namespace PointLightShader -{ - GLuint Program = 0; - GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_invproj, uniform_viewm; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); - uniform_ntex = glGetUniformLocation(Program, "ntex"); - uniform_center = glGetUniformLocation(Program, "center[0]"); - uniform_col = glGetUniformLocation(Program, "col[0]"); - uniform_energy = glGetUniformLocation(Program, "energy[0]"); - uniform_spec = glGetUniformLocation(Program, "spec"); - uniform_invproj = glGetUniformLocation(Program, "invproj"); - uniform_viewm = glGetUniformLocation(Program, "viewm"); - vao = createVAO(Program); - } -} - -namespace LightBlendShader -{ - GLuint Program = 0; - GLuint uniform_diffuse, uniform_specular, uniform_ambient_occlusion, uniform_specular_map, uniform_ambient; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/lightblend.frag").c_str()); - uniform_diffuse = glGetUniformLocation(Program, "diffuse"); - uniform_specular = glGetUniformLocation(Program, "specular"); - uniform_ambient_occlusion = glGetUniformLocation(Program, "ambient_occlusion"); - uniform_specular_map = glGetUniformLocation(Program, "specular_map"); - uniform_ambient = glGetUniformLocation(Program, "ambient"); - vao = createVAO(Program); - } -} - -namespace Gaussian6HBlurShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_pixel; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6h.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_pixel = glGetUniformLocation(Program, "pixel"); - vao = createVAO(Program); - } -} - -namespace Gaussian3HBlurShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_pixel; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3h.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_pixel = glGetUniformLocation(Program, "pixel"); - vao = createVAO(Program); - } -} - -namespace Gaussian6VBlurShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_pixel; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6v.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_pixel = glGetUniformLocation(Program, "pixel"); - vao = createVAO(Program); - } -} - -namespace Gaussian3VBlurShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_pixel; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3v.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_pixel = glGetUniformLocation(Program, "pixel"); - vao = createVAO(Program); - } -} - -namespace PassThroughShader -{ - GLuint Program = 0; - GLuint uniform_texture; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); - uniform_texture = glGetUniformLocation(Program, "texture"); - vao = createVAO(Program); - } -} - -namespace GlowShader -{ - GLuint Program = 0; - GLuint uniform_tex; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/glow.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - vao = createVAO(Program); - } -} - -namespace SSAOShader -{ - GLuint Program = 0; - GLuint uniform_normals_and_depth, uniform_invprojm, uniform_projm, uniform_samplePoints; - float SSAOSamples[64]; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ssao.frag").c_str()); - uniform_normals_and_depth = glGetUniformLocation(Program, "normals_and_depth"); - uniform_invprojm = glGetUniformLocation(Program, "invprojm"); - uniform_projm = glGetUniformLocation(Program, "projm"); - uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); - vao = createVAO(Program); - - for (unsigned i = 0; i < 16; i++) { - // Generate x/y component between -1 and 1 - // Use double to avoid denorm and get a true uniform distribution - double x = rand(); - x /= RAND_MAX; - x = 2 * x - 1; - double y = rand(); - y /= RAND_MAX; - y = 2 * y - 1; - - // compute z so that norm (x,y,z) is one - double z = sqrt(x * x + y * y); - // Norm factor - double w = rand(); - w /= RAND_MAX; - SSAOSamples[4 * i] = (float)x; - SSAOSamples[4 * i + 1] = (float)y; - SSAOSamples[4 * i + 2] = (float)z; - SSAOSamples[4 * i + 3] = (float)w; - } - } -} - -namespace FogShader -{ - GLuint Program = 0; - GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_campos, uniform_ipvmat; - - GLuint vao = 0; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/fog.frag").c_str()); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_fogmax = glGetUniformLocation(Program, "fogmax"); - uniform_startH = glGetUniformLocation(Program, "startH"); - uniform_endH = glGetUniformLocation(Program, "endH"); - uniform_start = glGetUniformLocation(Program, "start"); - uniform_end = glGetUniformLocation(Program, "end"); - uniform_col = glGetUniformLocation(Program, "col"); - uniform_campos = glGetUniformLocation(Program, "campos"); - uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); - vao = createVAO(Program); - } -} - - static void renderBloom(ITexture *in) { - if (!BloomShader::Program) - BloomShader::init(); - const float threshold = World::getWorld()->getTrack()->getBloomThreshold(); - glUseProgram(BloomShader::Program); - glBindVertexArray(BloomShader::vao); - glUniform1f(BloomShader::uniform_low, threshold); + glUseProgram(FullScreenShader::BloomShader::Program); + glBindVertexArray(FullScreenShader::BloomShader::vao); + glUniform1f(FullScreenShader::BloomShader::uniform_low, threshold); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(BloomShader::uniform_texture, 0); + glUniform1i(FullScreenShader::BloomShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -531,19 +219,17 @@ void renderBloom(ITexture *in) static void renderBloomBlend(ITexture *in) { - if (!BloomBlendShader::Program) - BloomBlendShader::init(); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); - glUseProgram(BloomBlendShader::Program); - glBindVertexArray(BloomBlendShader::vao); + glUseProgram(FullScreenShader::BloomBlendShader::Program); + glBindVertexArray(FullScreenShader::BloomBlendShader::vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(BloomBlendShader::uniform_texture, 0); + glUniform1i(FullScreenShader::BloomBlendShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -556,24 +242,22 @@ void renderBloomBlend(ITexture *in) static void renderPPDisplace(ITexture *in) { - if (!PPDisplaceShader::Program) - PPDisplaceShader::init(); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); - glUseProgram(PPDisplaceShader::Program); - glBindVertexArray(PPDisplaceShader::vao); - glUniform1i(PPDisplaceShader::uniform_viz, irr_driver->getDistortViz()); + glUseProgram(FullScreenShader::PPDisplaceShader::Program); + glBindVertexArray(FullScreenShader::PPDisplaceShader::vao); + glUniform1i(FullScreenShader::PPDisplaceShader::uniform_viz, irr_driver->getDistortViz()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(PPDisplaceShader::uniform_tex, 0); + glUniform1i(FullScreenShader::PPDisplaceShader::uniform_tex, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_DISPLACE))->getOpenGLTextureName()); - glUniform1i(PPDisplaceShader::uniform_dtex, 1); + glUniform1i(FullScreenShader::PPDisplaceShader::uniform_dtex, 1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -590,20 +274,17 @@ void renderColorLevel(ITexture *in) core::vector3df m_inlevel = World::getWorld()->getTrack()->getColorLevelIn(); core::vector2df m_outlevel = World::getWorld()->getTrack()->getColorLevelOut(); - - if (!ColorLevelShader::Program) - ColorLevelShader::init(); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); - glUseProgram(ColorLevelShader::Program); - glBindVertexArray(ColorLevelShader::vao); - glUniform3f(ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z); - glUniform2f(ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y); + glUseProgram(FullScreenShader::ColorLevelShader::Program); + glBindVertexArray(FullScreenShader::ColorLevelShader::vao); + glUniform3f(FullScreenShader::ColorLevelShader::uniform_inlevel, m_inlevel.X, m_inlevel.Y, m_inlevel.Z); + glUniform2f(FullScreenShader::ColorLevelShader::uniform_outlevel, m_outlevel.X, m_outlevel.Y); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(ColorLevelShader::uniform_tex, 0); + glUniform1i(FullScreenShader::ColorLevelShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -614,26 +295,24 @@ void renderColorLevel(ITexture *in) void PostProcessing::renderPointlight(ITexture *in, const std::vector &positions, const std::vector &colors, const std::vector &energy) { - if (!PointLightShader::Program) - PointLightShader::init(); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_DEPTH_TEST); - glUseProgram(PointLightShader::Program); - glBindVertexArray(PointLightShader::vao); + glUseProgram(FullScreenShader::PointLightShader::Program); + glBindVertexArray(FullScreenShader::PointLightShader::vao); - glUniform4fv(PointLightShader::uniform_center, 16, positions.data()); - glUniform4fv(PointLightShader::uniform_col, 16, colors.data()); - glUniform1fv(PointLightShader::uniform_energy, 16, energy.data()); - glUniform1f(PointLightShader::uniform_spec, 200); - glUniformMatrix4fv(PointLightShader::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); - glUniformMatrix4fv(PointLightShader::uniform_viewm, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); + glUniform4fv(FullScreenShader::PointLightShader::uniform_center, 16, positions.data()); + glUniform4fv(FullScreenShader::PointLightShader::uniform_col, 16, colors.data()); + glUniform1fv(FullScreenShader::PointLightShader::uniform_energy, 16, energy.data()); + glUniform1f(FullScreenShader::PointLightShader::uniform_spec, 200); + glUniformMatrix4fv(FullScreenShader::PointLightShader::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); + glUniformMatrix4fv(FullScreenShader::PointLightShader::uniform_viewm, 1, GL_FALSE, irr_driver->getViewMatrix().pointer()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(PointLightShader::uniform_ntex, 0); + glUniform1i(FullScreenShader::PointLightShader::uniform_ntex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -646,8 +325,6 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, ITexture *ao, ITexture *specmap, bool debug) { const SColorf s = irr_driver->getSceneManager()->getAmbientLight(); - if (!LightBlendShader::Program) - LightBlendShader::init(); glStencilFunc(GL_EQUAL, 1, ~0); glEnable(GL_STENCIL_TEST); glEnable(GL_BLEND); @@ -658,23 +335,23 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT glBlendFunc(GL_DST_COLOR, GL_ZERO); glDisable(GL_DEPTH_TEST); - glUseProgram(LightBlendShader::Program); - glBindVertexArray(LightBlendShader::vao); + glUseProgram(FullScreenShader::LightBlendShader::Program); + glBindVertexArray(FullScreenShader::LightBlendShader::vao); - glUniform3f(LightBlendShader::uniform_ambient, s.r, s.g, s.b); + glUniform3f(FullScreenShader::LightBlendShader::uniform_ambient, s.r, s.g, s.b); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(diffuse)->getOpenGLTextureName()); - glUniform1i(LightBlendShader::uniform_diffuse, 0); + glUniform1i(FullScreenShader::LightBlendShader::uniform_diffuse, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(specular)->getOpenGLTextureName()); - glUniform1i(LightBlendShader::uniform_specular, 1); + glUniform1i(FullScreenShader::LightBlendShader::uniform_specular, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, static_cast(ao)->getOpenGLTextureName()); - glUniform1i(LightBlendShader::uniform_ambient_occlusion, 2); + glUniform1i(FullScreenShader::LightBlendShader::uniform_ambient_occlusion, 2); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, static_cast(specmap)->getOpenGLTextureName()); - glUniform1i(LightBlendShader::uniform_specular_map, 3); + glUniform1i(FullScreenShader::LightBlendShader::uniform_specular_map, 3); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -691,32 +368,28 @@ void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *t glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); { - if (!Gaussian3VBlurShader::Program) - Gaussian3VBlurShader::init(); irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false); - glUseProgram(Gaussian3VBlurShader::Program); - glBindVertexArray(Gaussian3VBlurShader::vao); + glUseProgram(FullScreenShader::Gaussian3VBlurShader::Program); + glBindVertexArray(FullScreenShader::Gaussian3VBlurShader::vao); - glUniform2f(Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height); + glUniform2f(FullScreenShader::Gaussian3VBlurShader::uniform_pixel, inv_width, inv_height); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(Gaussian3VBlurShader::uniform_tex, 0); + glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } { - if (!Gaussian3HBlurShader::Program) - Gaussian3HBlurShader::init(); irr_driver->getVideoDriver()->setRenderTarget(in, false, false); - glUseProgram(Gaussian3HBlurShader::Program); - glBindVertexArray(Gaussian3HBlurShader::vao); + glUseProgram(FullScreenShader::Gaussian3HBlurShader::Program); + glBindVertexArray(FullScreenShader::Gaussian3HBlurShader::vao); - glUniform2f(Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height); + glUniform2f(FullScreenShader::Gaussian3HBlurShader::uniform_pixel, inv_width, inv_height); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); - glUniform1i(Gaussian3HBlurShader::uniform_tex, 0); + glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -731,32 +404,28 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); { - if (!Gaussian6VBlurShader::Program) - Gaussian6VBlurShader::init(); irr_driver->getVideoDriver()->setRenderTarget(temprtt, false, false); - glUseProgram(Gaussian6VBlurShader::Program); - glBindVertexArray(Gaussian6VBlurShader::vao); + glUseProgram(FullScreenShader::Gaussian6VBlurShader::Program); + glBindVertexArray(FullScreenShader::Gaussian6VBlurShader::vao); - glUniform2f(Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height); + glUniform2f(FullScreenShader::Gaussian6VBlurShader::uniform_pixel, inv_width, inv_height); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); - glUniform1i(Gaussian6VBlurShader::uniform_tex, 0); + glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } { - if (!Gaussian6HBlurShader::Program) - Gaussian6HBlurShader::init(); irr_driver->getVideoDriver()->setRenderTarget(in, false, false); - glUseProgram(Gaussian6HBlurShader::Program); - glBindVertexArray(Gaussian6HBlurShader::vao); + glUseProgram(FullScreenShader::Gaussian6HBlurShader::Program); + glBindVertexArray(FullScreenShader::Gaussian6HBlurShader::vao); - glUniform2f(Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height); + glUniform2f(FullScreenShader::Gaussian6HBlurShader::uniform_pixel, inv_width, inv_height); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); - glUniform1i(Gaussian6HBlurShader::uniform_tex, 0); + glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -768,16 +437,14 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t void PostProcessing::renderPassThrough(ITexture *tex) { - if (!PassThroughShader::Program) - PassThroughShader::init(); glDisable(GL_DEPTH_TEST); - glUseProgram(PassThroughShader::Program); - glBindVertexArray(PassThroughShader::vao); + glUseProgram(FullScreenShader::PassThroughShader::Program); + glBindVertexArray(FullScreenShader::PassThroughShader::vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); - glUniform1i(PassThroughShader::uniform_texture, 0); + glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -789,16 +456,14 @@ void PostProcessing::renderPassThrough(ITexture *tex) void PostProcessing::renderGlow(ITexture *tex) { - if (!GlowShader::Program) - GlowShader::init(); glDisable(GL_DEPTH_TEST); - glUseProgram(GlowShader::Program); - glBindVertexArray(GlowShader::vao); + glUseProgram(FullScreenShader::GlowShader::Program); + glBindVertexArray(FullScreenShader::GlowShader::vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); - glUniform1i(GlowShader::uniform_tex, 0); + glUniform1i(FullScreenShader::GlowShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -811,16 +476,14 @@ void PostProcessing::renderGlow(ITexture *tex) void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm) { - if (!SSAOShader::Program) - SSAOShader::init(); glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); - glUseProgram(SSAOShader::Program); - glBindVertexArray(SSAOShader::vao); - glUniformMatrix4fv(SSAOShader::uniform_invprojm, 1, GL_FALSE, invprojm.pointer()); - glUniformMatrix4fv(SSAOShader::uniform_projm, 1, GL_FALSE, projm.pointer()); - glUniform4fv(SSAOShader::uniform_samplePoints, 16, SSAOShader::SSAOSamples); + glUseProgram(FullScreenShader::SSAOShader::Program); + glBindVertexArray(FullScreenShader::SSAOShader::vao); + glUniformMatrix4fv(FullScreenShader::SSAOShader::uniform_invprojm, 1, GL_FALSE, invprojm.pointer()); + glUniformMatrix4fv(FullScreenShader::SSAOShader::uniform_projm, 1, GL_FALSE, projm.pointer()); + glUniform4fv(FullScreenShader::SSAOShader::uniform_samplePoints, 16, FullScreenShader::SSAOShader::SSAOSamples); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName()); @@ -828,7 +491,7 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUniform1i(SSAOShader::uniform_normals_and_depth, 0); + glUniform1i(FullScreenShader::SSAOShader::uniform_normals_and_depth, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); @@ -854,27 +517,25 @@ void PostProcessing::renderFog(const core::vector3df &campos, const core::matrix tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f }; - if (!FogShader::Program) - FogShader::init(); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(FogShader::Program); - glBindVertexArray(FogShader::vao); + glUseProgram(FullScreenShader::FogShader::Program); + glBindVertexArray(FullScreenShader::FogShader::vao); - glUniform1f(FogShader::uniform_fogmax, fogmax); - glUniform1f(FogShader::uniform_startH, startH); - glUniform1f(FogShader::uniform_endH, endH); - glUniform1f(FogShader::uniform_start, start); - glUniform1f(FogShader::uniform_end, end); - glUniform3f(FogShader::uniform_col, col[0], col[1], col[2]); - glUniform3f(FogShader::uniform_campos, campos.X, campos.Y, campos.Z); - glUniformMatrix4fv(FogShader::uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer()); + glUniform1f(FullScreenShader::FogShader::uniform_fogmax, fogmax); + glUniform1f(FullScreenShader::FogShader::uniform_startH, startH); + glUniform1f(FullScreenShader::FogShader::uniform_endH, endH); + glUniform1f(FullScreenShader::FogShader::uniform_start, start); + glUniform1f(FullScreenShader::FogShader::uniform_end, end); + glUniform3f(FullScreenShader::FogShader::uniform_col, col[0], col[1], col[2]); + glUniform3f(FullScreenShader::FogShader::uniform_campos, campos.X, campos.Y, campos.Z); + glUniformMatrix4fv(FullScreenShader::FogShader::uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName()); - glUniform1i(FogShader::uniform_tex, 0); + glUniform1i(FullScreenShader::FogShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 56354515e..28504282e 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -65,6 +65,23 @@ Shaders::Shaders() loadShaders(); } +GLuint quad_vbo = 0; + +static void initQuadVBO() +{ + initGL(); + const float quad_vertex[] = { + -1., -1., 0., 0., // UpperLeft + -1., 1., 0., 1., // LowerLeft + 1., -1., 1., 0., // UpperRight + 1., 1., 1., 1., // LowerRight + }; + glGenBuffers(1, &quad_vbo); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + void Shaders::loadShaders() { const std::string &dir = file_manager->getAsset(FileManager::SHADER, ""); @@ -214,6 +231,23 @@ void Shaders::loadShaders() if(m_shaders[i] == -1) m_shaders[i] = saved_shaders[i]; } + + initGL(); + initQuadVBO(); + FullScreenShader::BloomBlendShader::init(); + FullScreenShader::BloomShader::init(); + FullScreenShader::ColorLevelShader::init(); + FullScreenShader::FogShader::init(); + FullScreenShader::Gaussian3HBlurShader::init(); + FullScreenShader::Gaussian3VBlurShader::init(); + FullScreenShader::Gaussian6HBlurShader::init(); + FullScreenShader::Gaussian6VBlurShader::init(); + FullScreenShader::GlowShader::init(); + FullScreenShader::LightBlendShader::init(); + FullScreenShader::PassThroughShader::init(); + FullScreenShader::PointLightShader::init(); + FullScreenShader::PPDisplaceShader::init(); + FullScreenShader::SSAOShader::init(); } Shaders::~Shaders() @@ -241,3 +275,245 @@ void Shaders::check(const int num) const "persists, report a bug to us.", shader_names[num] + 3); } } + +static GLuint createVAO(GLuint Program) +{ + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + GLuint attrib_position = glGetAttribLocation(Program, "Position"); + GLuint attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glEnableVertexAttribArray(attrib_position); + glEnableVertexAttribArray(attrib_texcoord); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (GLvoid*)(2 * sizeof(float))); + glBindVertexArray(0); + return vao; +} + +namespace FullScreenShader +{ + GLuint BloomShader::Program; + GLuint BloomShader::uniform_texture; + GLuint BloomShader::uniform_low; + GLuint BloomShader::vao; + void BloomShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloom.frag").c_str()); + uniform_texture = glGetUniformLocation(Program, "tex"); + uniform_low = glGetUniformLocation(Program, "low"); + vao = createVAO(Program); + } + + GLuint BloomBlendShader::Program; + GLuint BloomBlendShader::uniform_texture; + GLuint BloomBlendShader::uniform_low; + GLuint BloomBlendShader::vao; + void BloomBlendShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/bloomblend.frag").c_str()); + uniform_texture = glGetUniformLocation(Program, "tex"); + vao = createVAO(Program); + } + + GLuint PPDisplaceShader::Program; + GLuint PPDisplaceShader::uniform_tex; + GLuint PPDisplaceShader::uniform_dtex; + GLuint PPDisplaceShader::uniform_viz; + GLuint PPDisplaceShader::vao; + void PPDisplaceShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ppdisplace.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_dtex = glGetUniformLocation(Program, "dtex"); + uniform_viz = glGetUniformLocation(Program, "viz"); + vao = createVAO(Program); + } + + GLuint ColorLevelShader::Program; + GLuint ColorLevelShader::uniform_tex; + GLuint ColorLevelShader::uniform_inlevel; + GLuint ColorLevelShader::uniform_outlevel; + GLuint ColorLevelShader::vao; + void ColorLevelShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/color_levels.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_inlevel = glGetUniformLocation(Program, "inlevel"); + uniform_outlevel = glGetUniformLocation(Program, "outlevel"); + vao = createVAO(Program); + } + + GLuint PointLightShader::Program; + GLuint PointLightShader::uniform_ntex; + GLuint PointLightShader::uniform_center; + GLuint PointLightShader::uniform_col; + GLuint PointLightShader::uniform_energy; + GLuint PointLightShader::uniform_spec; + GLuint PointLightShader::uniform_invproj; + GLuint PointLightShader::uniform_viewm; + GLuint PointLightShader::vao; + void PointLightShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); + uniform_ntex = glGetUniformLocation(Program, "ntex"); + uniform_center = glGetUniformLocation(Program, "center[0]"); + uniform_col = glGetUniformLocation(Program, "col[0]"); + uniform_energy = glGetUniformLocation(Program, "energy[0]"); + uniform_spec = glGetUniformLocation(Program, "spec"); + uniform_invproj = glGetUniformLocation(Program, "invproj"); + uniform_viewm = glGetUniformLocation(Program, "viewm"); + vao = createVAO(Program); + } + + GLuint LightBlendShader::Program; + GLuint LightBlendShader::uniform_diffuse; + GLuint LightBlendShader::uniform_specular; + GLuint LightBlendShader::uniform_ambient_occlusion; + GLuint LightBlendShader::uniform_specular_map; + GLuint LightBlendShader::uniform_ambient; + GLuint LightBlendShader::vao; + void LightBlendShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/lightblend.frag").c_str()); + uniform_diffuse = glGetUniformLocation(Program, "diffuse"); + uniform_specular = glGetUniformLocation(Program, "specular"); + uniform_ambient_occlusion = glGetUniformLocation(Program, "ambient_occlusion"); + uniform_specular_map = glGetUniformLocation(Program, "specular_map"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + vao = createVAO(Program); + } + + GLuint Gaussian6HBlurShader::Program; + GLuint Gaussian6HBlurShader::uniform_tex; + GLuint Gaussian6HBlurShader::uniform_pixel; + GLuint Gaussian6HBlurShader::vao; + void Gaussian6HBlurShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6h.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + vao = createVAO(Program); + } + + GLuint Gaussian3HBlurShader::Program; + GLuint Gaussian3HBlurShader::uniform_tex; + GLuint Gaussian3HBlurShader::uniform_pixel; + GLuint Gaussian3HBlurShader::vao; + void Gaussian3HBlurShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3h.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; + GLuint Gaussian6VBlurShader::vao; + void Gaussian6VBlurShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian6v.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + vao = createVAO(Program); + } + + GLuint Gaussian3VBlurShader::Program; + GLuint Gaussian3VBlurShader::uniform_tex; + GLuint Gaussian3VBlurShader::uniform_pixel; + GLuint Gaussian3VBlurShader::vao; + void Gaussian3VBlurShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/gaussian3v.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_pixel = glGetUniformLocation(Program, "pixel"); + vao = createVAO(Program); + } + + GLuint PassThroughShader::Program; + GLuint PassThroughShader::uniform_texture; + GLuint PassThroughShader::vao; + void PassThroughShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/texturedquad.frag").c_str()); + uniform_texture = glGetUniformLocation(Program, "texture"); + vao = createVAO(Program); + } + + GLuint GlowShader::Program; + GLuint GlowShader::uniform_tex; + GLuint GlowShader::vao; + void GlowShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/glow.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + vao = createVAO(Program); + } + + GLuint SSAOShader::Program; + GLuint SSAOShader::uniform_normals_and_depth; + GLuint SSAOShader::uniform_invprojm; + GLuint SSAOShader::uniform_projm; + GLuint SSAOShader::uniform_samplePoints; + GLuint SSAOShader::vao; + float SSAOShader::SSAOSamples[64]; + void SSAOShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ssao.frag").c_str()); + uniform_normals_and_depth = glGetUniformLocation(Program, "normals_and_depth"); + uniform_invprojm = glGetUniformLocation(Program, "invprojm"); + uniform_projm = glGetUniformLocation(Program, "projm"); + uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); + vao = createVAO(Program); + + for (unsigned i = 0; i < 16; i++) { + // Generate x/y component between -1 and 1 + // Use double to avoid denorm and get a true uniform distribution + double x = rand(); + x /= RAND_MAX; + x = 2 * x - 1; + double y = rand(); + y /= RAND_MAX; + y = 2 * y - 1; + + // compute z so that norm (x,y,z) is one + double z = sqrt(x * x + y * y); + // Norm factor + double w = rand(); + w /= RAND_MAX; + SSAOSamples[4 * i] = (float)x; + SSAOSamples[4 * i + 1] = (float)y; + SSAOSamples[4 * i + 2] = (float)z; + SSAOSamples[4 * i + 3] = (float)w; + } + } + + GLuint FogShader::Program; + GLuint FogShader::uniform_tex; + GLuint FogShader::uniform_fogmax; + GLuint FogShader::uniform_startH; + GLuint FogShader::uniform_endH; + GLuint FogShader::uniform_start; + GLuint FogShader::uniform_end; + GLuint FogShader::uniform_col; + GLuint FogShader::uniform_campos; + GLuint FogShader::uniform_ipvmat; + GLuint FogShader::vao; + void FogShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/fog.frag").c_str()); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_fogmax = glGetUniformLocation(Program, "fogmax"); + uniform_startH = glGetUniformLocation(Program, "startH"); + uniform_endH = glGetUniformLocation(Program, "endH"); + uniform_start = glGetUniformLocation(Program, "start"); + uniform_end = glGetUniformLocation(Program, "end"); + uniform_col = glGetUniformLocation(Program, "col"); + uniform_campos = glGetUniformLocation(Program, "campos"); + uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); + vao = createVAO(Program); + } +} \ No newline at end of file diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 82dbffb8e..a894d7cd9 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -20,8 +20,160 @@ #include #include #include +#include "graphics/glwrap.hpp" using namespace irr; +namespace MeshShader +{ + +} + +namespace FullScreenShader +{ + +class BloomShader +{ +public: + static GLuint Program; + static GLuint uniform_texture, uniform_low; + static GLuint vao; + + static void init(); +}; + +class BloomBlendShader +{ +public: + static GLuint Program; + static GLuint uniform_texture, uniform_low; + static GLuint vao; + + static void init(); +}; + +class PPDisplaceShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_dtex, uniform_viz; + static GLuint vao; + + static void init(); +}; + +class ColorLevelShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_inlevel, uniform_outlevel; + static GLuint vao; + + static void init(); +}; + +class PointLightShader +{ +public: + static GLuint Program; + static GLuint uniform_ntex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_invproj, uniform_viewm; + static GLuint vao; + + static void init(); +}; + +class LightBlendShader +{ +public: + static GLuint Program; + static GLuint uniform_diffuse, uniform_specular, uniform_ambient_occlusion, uniform_specular_map, uniform_ambient; + static GLuint vao; + + static void init(); +}; + +class Gaussian6HBlurShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + +class Gaussian3HBlurShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + +class Gaussian6VBlurShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + +class Gaussian3VBlurShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_pixel; + static GLuint vao; + + static void init(); +}; + +class PassThroughShader +{ +public: + static GLuint Program; + static GLuint uniform_texture; + static GLuint vao; + + static void init(); +}; + +class GlowShader +{ +public: + static GLuint Program; + static GLuint uniform_tex; + static GLuint vao; + + static void init(); +}; + +class SSAOShader +{ +public: + static GLuint Program; + static GLuint uniform_normals_and_depth, uniform_invprojm, uniform_projm, uniform_samplePoints; + static GLuint vao; + static float SSAOSamples[64]; + + static void init(); +}; + +class FogShader +{ +public: + static GLuint Program; + static GLuint uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col, uniform_campos, uniform_ipvmat; + static GLuint vao; + + static void init(); +}; + +} + #define FOREACH_SHADER(ACT) \ ACT(ES_NORMAL_MAP) \ ACT(ES_NORMAL_MAP_LIGHTMAP) \ From 603fdbb70acea6c48560984d528045eebf3105cd Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 21:59:48 +0100 Subject: [PATCH 353/412] Factorize mesh shader. --- src/graphics/shaders.cpp | 196 +++++++++++++++++++++++++++++++++++ src/graphics/shaders.hpp | 65 ++++++++++++ src/graphics/stkmesh.cpp | 218 ++++----------------------------------- 3 files changed, 279 insertions(+), 200 deletions(-) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 28504282e..d0e9359ae 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -248,6 +248,12 @@ void Shaders::loadShaders() FullScreenShader::PointLightShader::init(); FullScreenShader::PPDisplaceShader::init(); FullScreenShader::SSAOShader::init(); + MeshShader::ColorizeShader::init(); + MeshShader::NormalMapShader::init(); + MeshShader::ObjectPass1Shader::init(); + MeshShader::ObjectPass2Shader::init(); + MeshShader::SphereMapShader::init(); + MeshShader::SplattingShader::init(); } Shaders::~Shaders() @@ -276,6 +282,196 @@ void Shaders::check(const int num) const } } +namespace MeshShader +{ + GLuint ObjectPass1Shader::Program; + GLuint ObjectPass1Shader::attrib_position; + GLuint ObjectPass1Shader::attrib_normal; + GLuint ObjectPass1Shader::uniform_MVP; + GLuint ObjectPass1Shader::uniform_TIMV; + + void ObjectPass1Shader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + } + + void ObjectPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + } + + GLuint ObjectPass2Shader::Program; + GLuint ObjectPass2Shader::attrib_position; + GLuint ObjectPass2Shader::attrib_texcoord; + GLuint ObjectPass2Shader::uniform_MVP; + GLuint ObjectPass2Shader::uniform_TIMV; + GLuint ObjectPass2Shader::uniform_Albedo; + GLuint ObjectPass2Shader::uniform_DiffuseMap; + GLuint ObjectPass2Shader::uniform_SpecularMap; + GLuint ObjectPass2Shader::uniform_SSAO; + GLuint ObjectPass2Shader::uniform_screen; + GLuint ObjectPass2Shader::uniform_ambient; + + void ObjectPass2Shader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void ObjectPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + } + + GLuint NormalMapShader::Program; + GLuint NormalMapShader::attrib_position; + GLuint NormalMapShader::attrib_texcoord; + GLuint NormalMapShader::attrib_tangent; + GLuint NormalMapShader::attrib_bitangent; + GLuint NormalMapShader::uniform_MVP; + GLuint NormalMapShader::uniform_TIMV; + GLuint NormalMapShader::uniform_normalMap; + + void NormalMapShader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_tangent = glGetAttribLocation(Program, "Tangent"); + attrib_bitangent = glGetAttribLocation(Program, "Bitangent"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_normalMap = glGetUniformLocation(Program, "normalMap"); + } + + void NormalMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_normalMap, TU_normalMap); + } + + GLuint SphereMapShader::Program; + GLuint SphereMapShader::attrib_position; + GLuint SphereMapShader::attrib_normal; + GLuint SphereMapShader::uniform_MVP; + GLuint SphereMapShader::uniform_TIMV; + GLuint SphereMapShader::uniform_tex; + + void SphereMapShader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); + } + + void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_tex, TU_tex); + } + + GLuint SplattingShader::Program; + GLuint SplattingShader::attrib_position; + GLuint SplattingShader::attrib_texcoord; + GLuint SplattingShader::attrib_second_texcoord; + GLuint SplattingShader::uniform_MVP; + GLuint SplattingShader::uniform_tex_layout; + GLuint SplattingShader::uniform_tex_detail0; + GLuint SplattingShader::uniform_tex_detail1; + GLuint SplattingShader::uniform_tex_detail2; + GLuint SplattingShader::uniform_tex_detail3; + GLuint SplattingShader::uniform_DiffuseMap; + GLuint SplattingShader::uniform_SpecularMap; + GLuint SplattingShader::uniform_SSAO; + GLuint SplattingShader::uniform_screen; + GLuint SplattingShader::uniform_ambient; + + void SplattingShader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/splatting.vert").c_str(), file_manager->getAsset("shaders/splatting.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_tex_layout = glGetUniformLocation(Program, "tex_layout"); + uniform_tex_detail0 = glGetUniformLocation(Program, "tex_detail0"); + uniform_tex_detail1 = glGetUniformLocation(Program, "tex_detail1"); + uniform_tex_detail2 = glGetUniformLocation(Program, "tex_detail2"); + uniform_tex_detail3 = glGetUniformLocation(Program, "tex_detail3"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void SplattingShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_tex_layout, TU_tex_layout); + glUniform1i(uniform_tex_detail0, TU_tex_detail0); + glUniform1i(uniform_tex_detail1, TU_tex_detail1); + glUniform1i(uniform_tex_detail2, TU_tex_detail2); + glUniform1i(uniform_tex_detail3, TU_tex_detail3); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + } + + GLuint ColorizeShader::Program; + GLuint ColorizeShader::attrib_position; + GLuint ColorizeShader::uniform_MVP; + GLuint ColorizeShader::uniform_col; + + void ColorizeShader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/colorize.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_col = glGetUniformLocation(Program, "col"); + } + + void ColorizeShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform3f(uniform_col, r, g, b); + } +} + static GLuint createVAO(GLuint Program) { GLuint vao; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index a894d7cd9..98146b3ec 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -25,6 +25,71 @@ using namespace irr; namespace MeshShader { +class ObjectPass1Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_normal; + static GLuint uniform_MVP, uniform_TIMV; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView); +}; + +class ObjectPass2Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord; + static GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); +}; + +class NormalMapShader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent; + static GLuint uniform_MVP, uniform_TIMV, uniform_normalMap; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap); +}; + +class SphereMapShader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_normal; + static GLuint uniform_MVP, uniform_TIMV, uniform_tex; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex); +}; + +class SplattingShader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_second_texcoord; + static GLuint uniform_MVP, uniform_tex_layout, uniform_tex_detail0, uniform_tex_detail1, uniform_tex_detail2, uniform_tex_detail3, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); +}; + +class ColorizeShader +{ +public: + static GLuint Program; + static GLuint attrib_position; + static GLuint uniform_MVP, uniform_col; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b); +}; } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index a35f7ce76..9e68abc49 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -53,180 +53,6 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t return vao; } -namespace ObjectPass1Shader -{ - GLuint Program; - GLuint attrib_position, attrib_normal; - GLuint uniform_MVP, uniform_TIMV; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_normal = glGetAttribLocation(Program, "Normal"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");; - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - } -} - -namespace ObjectPass2Shader -{ - GLuint Program; - GLuint attrib_position, attrib_texcoord; - GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); - uniform_screen = glGetUniformLocation(Program, "screen"); - uniform_ambient = glGetUniformLocation(Program, "ambient"); - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); - glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); - const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); - glUniform3f(uniform_ambient, s.r, s.g, s.b); - } -} - -namespace NormalMapShader -{ - GLuint Program; - GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent; - GLuint uniform_MVP, uniform_TIMV, uniform_normalMap; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - attrib_tangent = glGetAttribLocation(Program, "Tangent"); - attrib_bitangent = glGetAttribLocation(Program, "Bitangent"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_normalMap = glGetUniformLocation(Program, "normalMap"); - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glUniform1i(uniform_normalMap, TU_normalMap); - } -} - -namespace SphereMapShader -{ - GLuint Program; - GLuint attrib_position, attrib_normal; - GLuint uniform_MVP, uniform_TIMV, uniform_tex; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_normal = glGetAttribLocation(Program, "Normal"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_tex = glGetUniformLocation(Program, "tex"); - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glUniform1i(uniform_tex, TU_tex); - } -} - -namespace SplattingShader -{ - GLuint Program; - GLuint attrib_position, attrib_texcoord, attrib_second_texcoord; - GLuint uniform_MVP, uniform_tex_layout, uniform_tex_detail0, uniform_tex_detail1, uniform_tex_detail2, uniform_tex_detail3, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/splatting.vert").c_str(), file_manager->getAsset("shaders/splatting.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_tex_layout = glGetUniformLocation(Program, "tex_layout"); - uniform_tex_detail0 = glGetUniformLocation(Program, "tex_detail0"); - uniform_tex_detail1 = glGetUniformLocation(Program, "tex_detail1"); - uniform_tex_detail2 = glGetUniformLocation(Program, "tex_detail2"); - uniform_tex_detail3 = glGetUniformLocation(Program, "tex_detail3"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); - uniform_screen = glGetUniformLocation(Program, "screen"); - uniform_ambient = glGetUniformLocation(Program, "ambient"); - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_tex_layout, TU_tex_layout); - glUniform1i(uniform_tex_detail0, TU_tex_detail0); - glUniform1i(uniform_tex_detail1, TU_tex_detail1); - glUniform1i(uniform_tex_detail2, TU_tex_detail2); - glUniform1i(uniform_tex_detail3, TU_tex_detail3); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); - glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); - const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); - glUniform3f(uniform_ambient, s.r, s.g, s.b); - } -} - -namespace ColorizeShader -{ - GLuint Program; - GLuint attrib_position; - GLuint uniform_MVP, uniform_col; - - void init() - { - initGL(); - Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/colorize.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_col = glGetUniformLocation(Program, "col"); - } - - void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform3f(uniform_col, r, g, b); - } -} - static GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { @@ -322,14 +148,6 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene GLmeshes.push_back(allocateMeshBuffer(mb)); } - if (ObjectPass1Shader::Program && ObjectPass2Shader::Program) - return; - ObjectPass1Shader::init(); - ObjectPass2Shader::init(); - NormalMapShader::init(); - ColorizeShader::init(); - SphereMapShader::init(); - SplattingShader::init(); } STKMesh::~STKMesh() @@ -370,8 +188,8 @@ void drawFirstPass(const GLMesh &mesh) TransposeInverseModelView.makeInverse(); TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - glUseProgram(ObjectPass1Shader::Program); - ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); + glUseProgram(MeshShader::ObjectPass1Shader::Program); + MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); @@ -411,8 +229,8 @@ void drawNormalPass(const GLMesh &mesh) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUseProgram(NormalMapShader::Program); - NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + glUseProgram(MeshShader::NormalMapShader::Program); + MeshShader::NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); @@ -450,8 +268,8 @@ void drawSphereMap(const GLMesh &mesh) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glUseProgram(SphereMapShader::Program); - SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + glUseProgram(MeshShader::SphereMapShader::Program); + MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -527,8 +345,8 @@ void drawSplatting(const GLMesh &mesh) glActiveTexture(GL_TEXTURE7); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glUseProgram(SplattingShader::Program); - SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); + glUseProgram(MeshShader::SplattingShader::Program); + MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -569,8 +387,8 @@ void drawSecondPass(const GLMesh &mesh) glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glUseProgram(ObjectPass2Shader::Program); - ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); + glUseProgram(MeshShader::ObjectPass2Shader::Program); + MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -594,8 +412,8 @@ void drawGlow(const GLMesh &mesh, float r, float g, float b) ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - glUseProgram(ColorizeShader::Program); - ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b); + glUseProgram(MeshShader::ColorizeShader::Program); + MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b); glBindVertexArray(mesh.vao_glow_pass); glDrawElements(ptype, count, itype, 0); @@ -661,30 +479,30 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) if (type == irr_driver->getShader(ES_NORMAL_MAP)) { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride); + MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, mesh.Stride); } else { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass1Shader::attrib_position, -1, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); } if (type == irr_driver->getShader(ES_SPHERE_MAP)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - SphereMapShader::attrib_position, -1, -1, SphereMapShader::attrib_normal, -1, -1, mesh.Stride); + MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, mesh.Stride); } else if (type == irr_driver->getShader(ES_SPLATTING)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - SplattingShader::attrib_position, SplattingShader::attrib_texcoord, SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); + MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); + MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); } - mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, -1, mesh.Stride); + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, mesh.Stride); } void STKMesh::render() From a33195bc1581a01f846f3ce472ee99f69fd7ad5c Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 18 Jan 2014 22:15:55 +0100 Subject: [PATCH 354/412] STKMesh: Avoid recomputing MVP several times --- src/graphics/stkmesh.cpp | 46 +++++++++------------------------------- src/graphics/stkmesh.hpp | 13 ++++++++++++ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 9e68abc49..c6160843e 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -166,8 +166,7 @@ STKMesh::~STKMesh() } } -static -void drawFirstPass(const GLMesh &mesh) +void STKMesh::drawFirstPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -180,10 +179,10 @@ void drawFirstPass(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); TransposeInverseModelView.makeInverse(); TransposeInverseModelView = TransposeInverseModelView.getTransposed(); @@ -199,8 +198,7 @@ void drawFirstPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } -static -void drawNormalPass(const GLMesh &mesh) +void STKMesh::drawNormalPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -213,10 +211,10 @@ void drawNormalPass(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); TransposeInverseModelView.makeInverse(); TransposeInverseModelView = TransposeInverseModelView.getTransposed(); @@ -240,8 +238,7 @@ void drawNormalPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } -static -void drawSphereMap(const GLMesh &mesh) +void STKMesh::drawSphereMap(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); @@ -253,14 +250,6 @@ void drawSphereMap(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -278,8 +267,7 @@ void drawSphereMap(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } -static -void drawSplatting(const GLMesh &mesh) +void STKMesh::drawSplatting(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); @@ -291,10 +279,6 @@ void drawSplatting(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - // Texlayout glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mesh.textures[1]); @@ -356,8 +340,7 @@ void drawSplatting(const GLMesh &mesh) } -static -void drawSecondPass(const GLMesh &mesh) +void STKMesh::drawSecondPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); @@ -369,10 +352,6 @@ void drawSecondPass(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -397,8 +376,7 @@ void drawSecondPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } -static -void drawGlow(const GLMesh &mesh, float r, float g, float b) +void STKMesh::drawGlow(const GLMesh &mesh, float r, float g, float b) { glEnable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); @@ -408,10 +386,6 @@ void drawGlow(const GLMesh &mesh, float r, float g, float b) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - glUseProgram(MeshShader::ColorizeShader::Program); MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 84fa5f725..bfdad00af 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -25,7 +25,20 @@ class STKMesh : public irr::scene::CMeshSceneNode { protected: std::vector GLmeshes; + core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type); + + // Pass 1 shader (ie shaders that outputs normals and depth) + void drawFirstPass(const GLMesh &mesh); + void drawNormalPass(const GLMesh &mesh); + + // Pass 2 shader (ie shaders that outputs final color) + void drawSphereMap(const GLMesh &mesh); + void drawSplatting(const GLMesh &mesh); + void drawSecondPass(const GLMesh &mesh); + + // Pass 3 shader (glow) + void drawGlow(const GLMesh &mesh, float r, float g, float b); public: STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0,0,0), From e8f8aae5f3c8e8ec34742b659ff5b8128e08e3e2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 00:02:30 +0100 Subject: [PATCH 355/412] Fix build on linux --- src/graphics/shaders.cpp | 2 +- src/graphics/shaders.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d0e9359ae..bc33312a7 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -21,7 +21,7 @@ #include "graphics/shaders.hpp" #include "io/file_manager.hpp" #include "utils/log.hpp" - +#include "graphics/glwrap.hpp" #include #include diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 98146b3ec..4dabe98b5 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -20,7 +20,8 @@ #include #include #include -#include "graphics/glwrap.hpp" + +typedef unsigned int GLuint; using namespace irr; namespace MeshShader From bd972be83a923c9964825afa60802167d5590399 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 00:26:54 +0100 Subject: [PATCH 356/412] Remove some unused shaders --- src/graphics/callbacks.cpp | 7 ------- src/graphics/callbacks.hpp | 16 ---------------- src/graphics/post_processing.cpp | 4 ---- src/graphics/shaders.cpp | 9 --------- src/graphics/shaders.hpp | 3 --- 5 files changed, 39 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 0943cbfb9..385219e48 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -587,13 +587,6 @@ void CollapseProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void BloomPowerProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - srv->setVertexShaderConstant("power", &m_power, 1); -} - -//------------------------------------- - void MultiplyProvider::OnSetConstants(IMaterialRendererServices *srv, int) { if (!firstdone) diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index a08565739..84cdc5156 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -527,22 +527,6 @@ private: // -class BloomPowerProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - void setPower(float power) - { - m_power = power / 10.0f; - } - -private: - float m_power; -}; - -// - class MultiplyProvider: public CallBase { public: diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f1773fe86..d7a99d775 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -582,10 +582,6 @@ void PostProcessing::render() const bool globalbloom = World::getWorld()->getTrack()->getBloom(); - BloomPowerProvider * const bloomcb = (BloomPowerProvider *) - irr_driver-> - getCallback(ES_BLOOM_POWER); - if (globalbloom) { drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index bc33312a7..6a3278b85 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -53,7 +53,6 @@ Shaders::Shaders() m_callbacks[ES_SHADOWPASS] = new ShadowPassProvider(); m_callbacks[ES_SHADOW_IMPORTANCE] = new ShadowImportanceProvider(); m_callbacks[ES_COLLAPSE] = new CollapseProvider(); - m_callbacks[ES_BLOOM_POWER] = new BloomPowerProvider(); m_callbacks[ES_MULTIPLY_ADD] = new MultiplyProvider(); m_callbacks[ES_SHADOWGEN] = new ShadowGenProvider(); m_callbacks[ES_CAUSTICS] = new CausticsProvider(); @@ -144,11 +143,6 @@ void Shaders::loadShaders() m_shaders[ES_COLORIZE_REF] = glslmat(std::string(""), dir + "colorize_ref.frag", m_callbacks[ES_COLORIZE], EMT_SOLID); - m_shaders[ES_PASS] = glslmat(std::string(""), dir + "pass.frag", - 0, EMT_SOLID); - m_shaders[ES_PASS_ADDITIVE] = glslmat(std::string(""), dir + "pass.frag", - 0, EMT_TRANSPARENT_ADD_COLOR); - m_shaders[ES_GLOW] = glslmat(std::string(""), dir + "glow.frag", m_callbacks[ES_GLOW], EMT_TRANSPARENT_ALPHA_CHANNEL); @@ -188,9 +182,6 @@ void Shaders::loadShaders() m_shaders[ES_SHADOW_WARPV] = glsl(std::string(""), dir + "shadowwarpv.frag", m_callbacks[ES_COLLAPSE]); - m_shaders[ES_BLOOM_POWER] = glsl(std::string(""), dir + "bloompower.frag", - m_callbacks[ES_BLOOM_POWER]); - m_shaders[ES_MULTIPLY_ADD] = glslmat(std::string(""), dir + "multiply.frag", m_callbacks[ES_MULTIPLY_ADD], EMT_ONETEXTURE_BLEND); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 4dabe98b5..9ae777e22 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -258,8 +258,6 @@ public: ACT(ES_MIPVIZ) \ ACT(ES_COLORIZE) \ ACT(ES_COLORIZE_REF) \ - ACT(ES_PASS) \ - ACT(ES_PASS_ADDITIVE) \ ACT(ES_GLOW) \ ACT(ES_OBJECTPASS) \ ACT(ES_OBJECTPASS_REF) \ @@ -276,7 +274,6 @@ public: ACT(ES_COLLAPSE) \ ACT(ES_SHADOW_WARPH) \ ACT(ES_SHADOW_WARPV) \ - ACT(ES_BLOOM_POWER) \ ACT(ES_MULTIPLY_ADD) \ ACT(ES_PENUMBRAH) \ ACT(ES_PENUMBRAV) \ From 9ddfa9261a6ce491babb0e862c531db14b6daff0 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 00:43:12 +0100 Subject: [PATCH 357/412] Revert to a specific define for ARB_DEBUG_OUTPUT It does not work well with nvidia driver. --- src/graphics/glwrap.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index b3bc43dde..042533b84 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -59,7 +59,8 @@ static GLuint quad_buffer; static GLuint ColoredVertex; static bool is_gl_init = false; -#ifdef DEBUG +//#define ARB_DEBUG_OUTPUT +#ifdef ARB_DEBUG_OUTPUT static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* msg, const void *userparam) @@ -181,7 +182,7 @@ void initGL() glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); #endif #endif -#ifdef DEBUG +#ifdef ARB_DEBUG_OUTPUT glDebugMessageCallbackARB((GLDEBUGPROCARB)debugCallback, NULL); #endif const float quad_vertex[] = { From 2609e5c70916612569fc988bb47a3e648cd77885 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 01:32:08 +0100 Subject: [PATCH 358/412] LightPrepass: start porting object_ref --- data/shaders/objectref_pass1.frag | 13 ++++++ data/shaders/objectref_pass1.vert | 16 ++++++++ data/shaders/objectref_pass2.frag | 20 ++++++++++ src/graphics/shaders.cpp | 66 +++++++++++++++++++++++++++++++ src/graphics/shaders.hpp | 22 +++++++++++ 5 files changed, 137 insertions(+) create mode 100644 data/shaders/objectref_pass1.frag create mode 100644 data/shaders/objectref_pass1.vert create mode 100644 data/shaders/objectref_pass2.frag diff --git a/data/shaders/objectref_pass1.frag b/data/shaders/objectref_pass1.frag new file mode 100644 index 000000000..6c98924bf --- /dev/null +++ b/data/shaders/objectref_pass1.frag @@ -0,0 +1,13 @@ +#version 130 +uniform sampler2D tex; + +noperspective in vec3 nor; +in vec2 uv; + +void main() { + vec4 col = texture2D(tex, uv); + if (col.a < 0.5) + discard; + gl_FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); +} + diff --git a/data/shaders/objectref_pass1.vert b/data/shaders/objectref_pass1.vert new file mode 100644 index 000000000..e75896eeb --- /dev/null +++ b/data/shaders/objectref_pass1.vert @@ -0,0 +1,16 @@ +#version 130 +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; + +in vec3 Position; +in vec3 Normal; +in vec2 Texcoord; +noperspective out vec3 nor; +out vec2 uv; + +void main(void) +{ + uv = Texcoord; + gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); + nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; +} diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag new file mode 100644 index 000000000..3fd35d295 --- /dev/null +++ b/data/shaders/objectref_pass2.frag @@ -0,0 +1,20 @@ +#version 130 +uniform sampler2D Albedo; +uniform sampler2D DiffuseMap; +uniform sampler2D SpecularMap; +uniform sampler2D SSAO; +uniform vec2 screen; +uniform vec3 ambient; +in vec2 uv; + +void main(void) +{ + vec4 color = texture2D(Albedo, uv); + if (color.a < 0.5) discard; + vec2 tc = gl_FragCoord.xy / screen; + vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; + float ao = texture2D(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + gl_FragColor = vec4(color.xyz * LightFactor, 1.); +} diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 6a3278b85..1530556fe 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -242,7 +242,9 @@ void Shaders::loadShaders() MeshShader::ColorizeShader::init(); MeshShader::NormalMapShader::init(); MeshShader::ObjectPass1Shader::init(); + MeshShader::ObjectRefPass1Shader::init(); MeshShader::ObjectPass2Shader::init(); + MeshShader::ObjectRefPass2Shader::init(); MeshShader::SphereMapShader::init(); MeshShader::SplattingShader::init(); } @@ -297,6 +299,31 @@ namespace MeshShader glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); } + GLuint ObjectRefPass1Shader::Program; + GLuint ObjectRefPass1Shader::attrib_position; + GLuint ObjectRefPass1Shader::attrib_normal; + GLuint ObjectRefPass1Shader::uniform_MVP; + GLuint ObjectRefPass1Shader::uniform_TIMV; + GLuint ObjectRefPass1Shader::uniform_tex; + + void ObjectRefPass1Shader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/objectref_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); + } + + void ObjectRefPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_tex) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_tex, TU_tex); + } + GLuint ObjectPass2Shader::Program; GLuint ObjectPass2Shader::attrib_position; GLuint ObjectPass2Shader::attrib_texcoord; @@ -336,6 +363,45 @@ namespace MeshShader glUniform3f(uniform_ambient, s.r, s.g, s.b); } + GLuint ObjectRefPass2Shader::Program; + GLuint ObjectRefPass2Shader::attrib_position; + GLuint ObjectRefPass2Shader::attrib_texcoord; + GLuint ObjectRefPass2Shader::uniform_MVP; + GLuint ObjectRefPass2Shader::uniform_TIMV; + GLuint ObjectRefPass2Shader::uniform_Albedo; + GLuint ObjectRefPass2Shader::uniform_DiffuseMap; + GLuint ObjectRefPass2Shader::uniform_SpecularMap; + GLuint ObjectRefPass2Shader::uniform_SSAO; + GLuint ObjectRefPass2Shader::uniform_screen; + GLuint ObjectRefPass2Shader::uniform_ambient; + + void ObjectRefPass2Shader::init() + { + initGL(); + Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + } + + void ObjectRefPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + } + GLuint NormalMapShader::Program; GLuint NormalMapShader::attrib_position; GLuint NormalMapShader::attrib_texcoord; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 9ae777e22..37b7e7952 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -37,6 +37,17 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView); }; +class ObjectRefPass1Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_normal; + static GLuint uniform_MVP, uniform_TIMV, uniform_tex; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_texture); +}; + class ObjectPass2Shader { public: @@ -48,6 +59,17 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); }; +class ObjectRefPass2Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord; + static GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); +}; + class NormalMapShader { public: From 5ce82f9f559e427d69e4a633effcd9e7cf4b58dd Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Sat, 18 Jan 2014 19:48:20 -0500 Subject: [PATCH 359/412] Add a bunch of profiling markers. Gives us some idea where time is spent. Not perfect but better than nothing --- src/graphics/post_processing.cpp | 11 +++++++++++ src/graphics/render.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index d7a99d775..d1dc1161f 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -31,6 +31,7 @@ #include "race/race_manager.hpp" #include "tracks/track.hpp" #include "utils/log.hpp" +#include "utils/profiler.hpp" #include @@ -574,6 +575,7 @@ void PostProcessing::render() // As the original color shouldn't be touched, the first effect can't be disabled. + PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00); if (1) // bloom { // Blit the base to tmp1 @@ -627,7 +629,9 @@ void PostProcessing::render() in = irr_driver->getRTT(RTT_TMP1); out = irr_driver->getRTT(RTT_TMP2); } + PROFILER_POP_CPU_MARKER(); + PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00); if (World::getWorld()->getTrack()->hasGodRays() && m_sunpixels > 30) // god rays { // Grab the sky @@ -710,9 +714,11 @@ void PostProcessing::render() drawQuad(cam, m_material); } + PROFILER_POP_CPU_MARKER(); if (UserConfigParams::m_motionblur && m_any_boost) // motion blur { + PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00); // Calculate the kart's Y position on screen const core::vector3df pos = Camera::getCamera(cam)->getKart()->getNode()->getPosition(); @@ -734,20 +740,24 @@ void PostProcessing::render() ITexture *tmp = in; in = out; out = tmp; + PROFILER_POP_CPU_MARKER(); } if (irr_driver->getDisplacingNodes().size()) // Displacement { + PROFILER_PUSH_CPU_MARKER("- Displacement", 0xFF, 0x00, 0x00); drv->setRenderTarget(out, true, false); renderPPDisplace(in); ITexture *tmp = in; in = out; out = tmp; + PROFILER_POP_CPU_MARKER(); } if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter. { + PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00); drv->setRenderTarget(out, false, false); glEnable(GL_STENCIL_TEST); @@ -801,6 +811,7 @@ void PostProcessing::render() // Done. glDisable(GL_STENCIL_TEST); + PROFILER_POP_CPU_MARKER(); } // Final blit diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 61d3dc571..f89991f0d 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -220,6 +220,9 @@ void IrrDriver::renderGLSL(float dt) //renderShadows(sicb, camnode, overridemat, camera); } + + PROFILER_PUSH_CPU_MARKER("- Light", 0xFF, 0x00, 0x00); + // Lights renderLights(cambox, camnode, overridemat, cam, dt); irr_driver->setPhase(1); @@ -230,6 +233,10 @@ void IrrDriver::renderGLSL(float dt) m_scene_manager->drawAll(m_renderpass); glDisable(GL_STENCIL_TEST); + PROFILER_POP_CPU_MARKER(); + + PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0x00, 0x00); + // Render anything glowing. if (!m_mipviz && !m_wireframe) { @@ -237,13 +244,20 @@ void IrrDriver::renderGLSL(float dt) renderGlow(overridemat, glows, cambox, cam); } // end glow + PROFILER_POP_CPU_MARKER(); + if (!bgnodes) { + PROFILER_PUSH_CPU_MARKER("- Skybox", 0xFF, 0x00, 0x00); + // If there are no BG nodes, it's more efficient to do the skybox here. m_renderpass = scene::ESNRP_SKY_BOX; m_scene_manager->drawAll(m_renderpass); + + PROFILER_POP_CPU_MARKER(); } + PROFILER_PUSH_CPU_MARKER("- Lensflare/godray", 0xFF, 0x00, 0x00); // Is the lens flare enabled & visible? Check last frame's query. const bool hasflare = World::getWorld()->getTrack()->hasLensFlare(); const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays(); @@ -270,22 +284,31 @@ void IrrDriver::renderGLSL(float dt) // Make sure the color mask is reset glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } + PROFILER_POP_CPU_MARKER(); // Render fog on top of solid if (World::getWorld()->getTrack()->isFogEnabled()) + { + PROFILER_PUSH_CPU_MARKER("- Fog", 0xFF, 0x00, 0x00); m_post_processing->renderFog(camnode->getAbsolutePosition(), irr_driver->getInvProjViewMatrix()); + PROFILER_POP_CPU_MARKER(); + } // We need to re-render camera due to the per-cam-node hack. + PROFILER_PUSH_CPU_MARKER("- SceneManager::drawAll", 0xFF, 0x00, 0x00); m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_TRANSPARENT | scene::ESNRP_TRANSPARENT_EFFECT; m_scene_manager->drawAll(m_renderpass); + PROFILER_POP_CPU_MARKER(); + PROFILER_PUSH_CPU_MARKER("- Displacement", 0xFF, 0x00, 0x00); // Handle displacing nodes, if any const u32 displacingcount = m_displacing.size(); if (displacingcount) { renderDisplacement(overridemat, cam); } + PROFILER_POP_CPU_MARKER(); // Drawing for this cam done, cleanup const u32 glowrepcount = transparent_glow_nodes.size(); @@ -305,8 +328,10 @@ void IrrDriver::renderGLSL(float dt) World::getWorld()->getPhysics()->draw(); } // for igetNumKarts() + PROFILER_PUSH_CPU_MARKER("Postprocessing", 0xFF, 0x00, 0x00); // Render the post-processed scene m_post_processing->render(); + PROFILER_POP_CPU_MARKER(); // Set the viewport back to the full screen for race gui m_video_driver->setViewPort(core::recti(0, 0, From 4d66503dae537c556fb7177c3365fcf4c1fe48f8 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 02:13:00 +0100 Subject: [PATCH 360/412] STKMesh: Use objectref now --- data/shaders/objectref_pass2.frag | 6 +- src/graphics/shaders.cpp | 4 +- src/graphics/shaders.hpp | 2 +- src/graphics/stkmesh.cpp | 91 +++++++++++++++++++++++++++++++ src/graphics/stkmesh.hpp | 2 + 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 3fd35d295..e2049a971 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -10,11 +10,11 @@ in vec2 uv; void main(void) { vec4 color = texture2D(Albedo, uv); - if (color.a < 0.5) discard; + if (color.a < 0.5) discard; vec2 tc = gl_FragCoord.xy / screen; vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - float ao = texture2D(SSAO, tc).x; - vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + float ao = texture2D(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; gl_FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1530556fe..c9a22ed15 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -302,6 +302,7 @@ namespace MeshShader GLuint ObjectRefPass1Shader::Program; GLuint ObjectRefPass1Shader::attrib_position; GLuint ObjectRefPass1Shader::attrib_normal; + GLuint ObjectRefPass1Shader::attrib_texcoord; GLuint ObjectRefPass1Shader::uniform_MVP; GLuint ObjectRefPass1Shader::uniform_TIMV; GLuint ObjectRefPass1Shader::uniform_tex; @@ -312,6 +313,7 @@ namespace MeshShader Program = LoadProgram(file_manager->getAsset("shaders/objectref_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); uniform_tex = glGetUniformLocation(Program, "tex"); @@ -769,4 +771,4 @@ namespace FullScreenShader uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); vao = createVAO(Program); } -} \ No newline at end of file +} diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 37b7e7952..4dfd6313d 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -41,7 +41,7 @@ class ObjectRefPass1Shader { public: static GLuint Program; - static GLuint attrib_position, attrib_normal; + static GLuint attrib_position, attrib_normal, attrib_texcoord; static GLuint uniform_MVP, uniform_TIMV, uniform_tex; static void init(); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index c6160843e..9ccf3f0ec 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -198,6 +198,45 @@ void STKMesh::drawFirstPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } +void STKMesh::drawObjectRefPass1(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glUseProgram(MeshShader::ObjectRefPass1Shader::Program); + MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + + glBindVertexArray(mesh.vao_first_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); +} + void STKMesh::drawNormalPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -339,6 +378,41 @@ void STKMesh::drawSplatting(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } +void STKMesh::drawObjectRefPass2(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + + glUseProgram(MeshShader::ObjectRefPass2Shader::Program); + MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} void STKMesh::drawSecondPass(const GLMesh &mesh) { @@ -404,6 +478,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) case 0: if (type == irr_driver->getShader(ES_NORMAL_MAP)) drawNormalPass(mesh); + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + drawObjectRefPass1(mesh); else drawFirstPass(mesh); break; @@ -412,6 +488,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) drawSphereMap(mesh); else if (type == irr_driver->getShader(ES_SPLATTING)) drawSplatting(mesh); + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + drawObjectRefPass2(mesh); else drawSecondPass(mesh); break; @@ -437,6 +515,8 @@ static bool isObject(video::E_MATERIAL_TYPE type) { if (type == irr_driver->getShader(ES_OBJECTPASS)) return true; + if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + return true; if (type == irr_driver->getShader(ES_NORMAL_MAP)) return true; if (type == irr_driver->getShader(ES_SPHERE_MAP)) @@ -455,6 +535,11 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, mesh.Stride); } + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + } else { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, @@ -471,6 +556,12 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); } + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); + + } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index bfdad00af..959fff563 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -31,11 +31,13 @@ protected: // Pass 1 shader (ie shaders that outputs normals and depth) void drawFirstPass(const GLMesh &mesh); void drawNormalPass(const GLMesh &mesh); + void drawObjectRefPass1(const GLMesh &mesh); // Pass 2 shader (ie shaders that outputs final color) void drawSphereMap(const GLMesh &mesh); void drawSplatting(const GLMesh &mesh); void drawSecondPass(const GLMesh &mesh); + void drawObjectRefPass2(const GLMesh &mesh); // Pass 3 shader (glow) void drawGlow(const GLMesh &mesh, float r, float g, float b); From f54b9efebd13e4f26322559d043295893c9d0dad Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 02:28:10 +0100 Subject: [PATCH 361/412] Use nearest filtering for some rtt --- src/graphics/post_processing.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index d1dc1161f..9202a8123 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -209,6 +209,8 @@ void renderBloom(ITexture *in) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::BloomShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -230,6 +232,8 @@ void renderBloomBlend(ITexture *in) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::BloomBlendShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -258,6 +262,8 @@ void renderPPDisplace(ITexture *in) glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_DISPLACE))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::PPDisplaceShader::uniform_dtex, 1); @@ -285,6 +291,8 @@ void renderColorLevel(ITexture *in) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::ColorLevelShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -313,6 +321,8 @@ void PostProcessing::renderPointlight(ITexture *in, const std::vector &po glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::PointLightShader::uniform_ntex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -343,15 +353,21 @@ void PostProcessing::renderLightbBlend(ITexture *diffuse, ITexture *specular, IT glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(diffuse)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::LightBlendShader::uniform_diffuse, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(specular)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::LightBlendShader::uniform_specular, 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, static_cast(ao)->getOpenGLTextureName()); glUniform1i(FullScreenShader::LightBlendShader::uniform_ambient_occlusion, 2); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, static_cast(specmap)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::LightBlendShader::uniform_specular_map, 3); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -377,6 +393,8 @@ void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *t glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::Gaussian3VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -390,6 +408,8 @@ void PostProcessing::renderGaussian3Blur(video::ITexture *in, video::ITexture *t glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::Gaussian3HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -413,6 +433,8 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(in)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::Gaussian6VBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -426,6 +448,8 @@ void PostProcessing::renderGaussian6Blur(video::ITexture *in, video::ITexture *t glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(temprtt)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::Gaussian6HBlurShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -445,6 +469,8 @@ void PostProcessing::renderPassThrough(ITexture *tex) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::PassThroughShader::uniform_texture, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -464,6 +490,8 @@ void PostProcessing::renderGlow(ITexture *tex) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUniform1i(FullScreenShader::GlowShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); From ab3cb863593ae71f83b633f4011792efb4d1159e Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 02:38:52 +0100 Subject: [PATCH 362/412] Use nearest sampling for some others rtts --- src/graphics/stkmesh.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 9ccf3f0ec..4afedb374 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -361,12 +361,18 @@ void STKMesh::drawSplatting(const GLMesh &mesh) // Diffuse glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Specular glActiveTexture(GL_TEXTURE6); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // SSAO glActiveTexture(GL_TEXTURE7); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUseProgram(MeshShader::SplattingShader::Program); MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); @@ -399,10 +405,16 @@ void STKMesh::drawObjectRefPass2(const GLMesh &mesh) glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUseProgram(MeshShader::ObjectRefPass2Shader::Program); MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); @@ -435,10 +447,16 @@ void STKMesh::drawSecondPass(const GLMesh &mesh) glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glUseProgram(MeshShader::ObjectPass2Shader::Program); MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); From d6d8301f17e5beae4da76d78fd9b5fb4d9252b96 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 18:20:57 +0100 Subject: [PATCH 363/412] SSAO: Use a noise texture rather than a function --- data/shaders/ssao.frag | 4 ++-- src/graphics/post_processing.cpp | 11 +++++++++++ src/graphics/shaders.cpp | 2 ++ src/graphics/shaders.hpp | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 50a70921b..87602ca3a 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,5 +1,6 @@ #version 130 uniform sampler2D normals_and_depth; +uniform sampler2D noise_texture; uniform mat4 invprojm; uniform mat4 projm; uniform vec4 samplePoints[16]; @@ -13,10 +14,9 @@ const float radius = .4f; const float invSamples = strengh / SAMPLES; -// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ float rand(vec2 co) { - return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453); + return texture(noise_texture, co).x; } void main(void) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 9202a8123..0a91f5760 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -502,6 +502,7 @@ void PostProcessing::renderGlow(ITexture *tex) glDisable(GL_BLEND); } +ITexture *noise_tex = 0; void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm) { @@ -522,6 +523,16 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glUniform1i(FullScreenShader::SSAOShader::uniform_normals_and_depth, 0); + if (!noise_tex) + noise_tex = irr_driver->getTexture(file_manager->getAsset("textures/tarmac.jpg").c_str()); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(noise_tex)->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glUniform1i(FullScreenShader::SSAOShader::uniform_noise_texture, 1); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index c9a22ed15..bc8566961 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -710,6 +710,7 @@ namespace FullScreenShader GLuint SSAOShader::Program; GLuint SSAOShader::uniform_normals_and_depth; + GLuint SSAOShader::uniform_noise_texture; GLuint SSAOShader::uniform_invprojm; GLuint SSAOShader::uniform_projm; GLuint SSAOShader::uniform_samplePoints; @@ -719,6 +720,7 @@ namespace FullScreenShader { Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/ssao.frag").c_str()); uniform_normals_and_depth = glGetUniformLocation(Program, "normals_and_depth"); + uniform_noise_texture = glGetUniformLocation(Program, "noise_texture"); uniform_invprojm = glGetUniformLocation(Program, "invprojm"); uniform_projm = glGetUniformLocation(Program, "projm"); uniform_samplePoints = glGetUniformLocation(Program, "samplePoints[0]"); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 4dfd6313d..f43b5272a 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -243,7 +243,7 @@ class SSAOShader { public: static GLuint Program; - static GLuint uniform_normals_and_depth, uniform_invprojm, uniform_projm, uniform_samplePoints; + static GLuint uniform_normals_and_depth, uniform_noise_texture, uniform_invprojm, uniform_projm, uniform_samplePoints; static GLuint vao; static float SSAOSamples[64]; From 496146b617304db57ec24a853836de53b34bf5b2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 18:21:19 +0100 Subject: [PATCH 364/412] Use linear filtering for glow effect --- src/graphics/post_processing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 0a91f5760..e8b4fea69 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -490,8 +490,8 @@ void PostProcessing::renderGlow(ITexture *tex) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(tex)->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glUniform1i(FullScreenShader::GlowShader::uniform_tex, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); From fb6649eaad2e3568758d85a10dbd7e78744fba9a Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 18:53:35 +0100 Subject: [PATCH 365/412] texture2D is deprecated, use texture instead --- data/shaders/bloom.frag | 2 +- data/shaders/bloomblend.frag | 2 +- data/shaders/bloompower.frag | 2 +- data/shaders/bubble.frag | 2 +- data/shaders/caustics.frag | 6 +++--- data/shaders/collapse.frag | 4 ++-- data/shaders/color_levels.frag | 2 +- data/shaders/colorize_ref.frag | 2 +- data/shaders/colortexturedquad.frag | 4 ++-- data/shaders/displace.frag | 4 ++-- data/shaders/fog.frag | 2 +- data/shaders/gaussian3h.frag | 10 +++++----- data/shaders/gaussian3v.frag | 10 +++++----- data/shaders/gaussian6h.frag | 14 +++++++------- data/shaders/gaussian6v.frag | 14 +++++++------- data/shaders/glow.frag | 2 +- data/shaders/godfade.frag | 2 +- data/shaders/godray.frag | 4 ++-- data/shaders/grass.frag | 2 +- data/shaders/gum_shield.frag | 2 +- data/shaders/lightbeam.frag | 2 +- data/shaders/lightblend.frag | 8 ++++---- data/shaders/mipviz.frag | 2 +- data/shaders/mlaa_blend2.frag | 2 +- data/shaders/mlaa_color1.frag | 10 +++++----- data/shaders/mlaa_neigh3.frag | 16 ++++++++-------- data/shaders/motion_blur.frag | 4 ++-- data/shaders/multiply.frag | 4 ++-- data/shaders/normalmap.frag | 2 +- data/shaders/object_pass2.frag | 8 ++++---- data/shaders/objectpass.frag | 4 ++-- data/shaders/objectpass_ref.frag | 2 +- data/shaders/objectpass_rimlit.frag | 2 +- data/shaders/objectpass_spheremap.frag | 2 +- data/shaders/objectref_pass1.frag | 2 +- data/shaders/objectref_pass2.frag | 8 ++++---- data/shaders/particle.frag | 8 ++++---- data/shaders/pass.frag | 2 +- data/shaders/penumbrah.frag | 14 +++++++------- data/shaders/penumbrav.frag | 14 +++++++------- data/shaders/pointlight.frag | 4 ++-- data/shaders/ppdisplace.frag | 4 ++-- data/shaders/rain.frag | 6 +++--- data/shaders/shadowgen.frag | 6 +++--- data/shaders/shadowimportance.frag | 4 ++-- data/shaders/shadowimportance.vert | 2 +- data/shaders/shadowpass.frag | 4 ++-- data/shaders/shadowpass.vert | 4 ++-- data/shaders/shadowwarph.frag | 2 +- data/shaders/shadowwarpv.frag | 2 +- data/shaders/skybox.frag | 14 +++++++------- data/shaders/splatting.frag | 16 ++++++++-------- data/shaders/ssao.frag | 6 +++--- data/shaders/sunlight.frag | 6 +++--- data/shaders/sunlightshadow.frag | 20 ++++++++++---------- data/shaders/texturedquad.frag | 4 ++-- data/shaders/water.frag | 6 +++--- src/graphics/glwrap.cpp | 12 ++++++------ src/graphics/gpuparticles.cpp | 12 ++++++------ 59 files changed, 171 insertions(+), 171 deletions(-) diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index c33e06905..43de30592 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -7,7 +7,7 @@ in vec2 uv; void main() { vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709 - vec3 col = texture2D(tex, uv).xyz; + vec3 col = texture(tex, uv).xyz; float luma = dot(weights, col); col *= smoothstep(low, 0.9, luma); diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag index 94c952d6f..fcd033b0a 100644 --- a/data/shaders/bloomblend.frag +++ b/data/shaders/bloomblend.frag @@ -5,7 +5,7 @@ in vec2 uv; void main() { - vec4 col = texture2D(tex, uv); + vec4 col = texture(tex, uv); col.xyz *= 10.0 * col.a; diff --git a/data/shaders/bloompower.frag b/data/shaders/bloompower.frag index 227e0523d..91dbf262c 100644 --- a/data/shaders/bloompower.frag +++ b/data/shaders/bloompower.frag @@ -4,7 +4,7 @@ uniform sampler2D tex; void main() { - vec4 col = texture2D(tex, gl_TexCoord[0].xy); + vec4 col = texture(tex, gl_TexCoord[0].xy); if (col.a < 0.5) discard; diff --git a/data/shaders/bubble.frag b/data/shaders/bubble.frag index 0c3c49e8d..d0e53a9a4 100644 --- a/data/shaders/bubble.frag +++ b/data/shaders/bubble.frag @@ -21,6 +21,6 @@ in vec2 uv; void main() { - gl_FragColor = texture2D(tex, uv); + gl_FragColor = texture(tex, uv); gl_FragColor.a *= transparency; } diff --git a/data/shaders/caustics.frag b/data/shaders/caustics.frag index eefba44b6..79478e0be 100644 --- a/data/shaders/caustics.frag +++ b/data/shaders/caustics.frag @@ -8,9 +8,9 @@ void main() { vec2 tc = gl_TexCoord[0].xy; - vec3 col = texture2D(tex, tc).xyz; - float caustic = texture2D(caustictex, tc + dir).x; - float caustic2 = texture2D(caustictex, (tc.yx + dir2 * vec2(-0.6, 0.3)) * vec2(0.6)).x; + vec3 col = texture(tex, tc).xyz; + float caustic = texture(caustictex, tc + dir).x; + float caustic2 = texture(caustictex, (tc.yx + dir2 * vec2(-0.6, 0.3)) * vec2(0.6)).x; col += caustic * caustic2 * 10.0; diff --git a/data/shaders/collapse.frag b/data/shaders/collapse.frag index 8586f7aca..9db482b33 100644 --- a/data/shaders/collapse.frag +++ b/data/shaders/collapse.frag @@ -14,13 +14,13 @@ void main() for (int i = 0; i < size; i++) { - float col = texture2D(tex, tc).x; + float col = texture(tex, tc).x; res = max(col, res); tc += pixel; } - float old = texture2D(oldtex, gl_TexCoord[0].xy).x; + float old = texture(oldtex, gl_TexCoord[0].xy).x; gl_FragColor = vec4(mix(old, res, 0.7)); } diff --git a/data/shaders/color_levels.frag b/data/shaders/color_levels.frag index af12b739c..90539fc2f 100644 --- a/data/shaders/color_levels.frag +++ b/data/shaders/color_levels.frag @@ -11,7 +11,7 @@ void main() //texc.y = 1.0 - texc.y; - vec4 col = texture2D(tex, texc); + vec4 col = texture(tex, texc); //col = col / (1 - col); diff --git a/data/shaders/colorize_ref.frag b/data/shaders/colorize_ref.frag index d3944c0c7..f8f51cd06 100644 --- a/data/shaders/colorize_ref.frag +++ b/data/shaders/colorize_ref.frag @@ -4,7 +4,7 @@ uniform sampler2D tex; void main() { - float alpha = texture2D(tex, gl_TexCoord[0].xy).a; + float alpha = texture(tex, gl_TexCoord[0].xy).a; if (alpha < 0.5) discard; diff --git a/data/shaders/colortexturedquad.frag b/data/shaders/colortexturedquad.frag index 19f1559c3..4d5a36671 100644 --- a/data/shaders/colortexturedquad.frag +++ b/data/shaders/colortexturedquad.frag @@ -1,11 +1,11 @@ #version 130 -uniform sampler2D texture; +uniform sampler2D tex; in vec2 uv; in vec4 col; void main() { - vec4 res = texture2D(texture, uv); + vec4 res = texture(tex, uv); gl_FragColor = vec4(res.xyz * col.xyz, res.a); } diff --git a/data/shaders/displace.frag b/data/shaders/displace.frag index 6ee1693c4..cbfe1a255 100644 --- a/data/shaders/displace.frag +++ b/data/shaders/displace.frag @@ -15,8 +15,8 @@ void main() vec4 col = vec4(0.0); const float maxlen = 0.02; - float horiz = texture2D(tex, tc + dir).x; - float vert = texture2D(tex, (tc.yx + dir2) * vec2(0.9)).x; + float horiz = texture(tex, tc + dir).x; + float vert = texture(tex, (tc.yx + dir2) * vec2(0.9)).x; vec2 offset = vec2(horiz, vert); offset *= 2.0; diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag index 10ab2b2a5..7d0bfb9c4 100644 --- a/data/shaders/fog.frag +++ b/data/shaders/fog.frag @@ -14,7 +14,7 @@ in vec2 uv; void main() { - float z = texture2D(tex, uv).a; + float z = texture(tex, uv).a; vec3 tmp = vec3(gl_TexCoord[0].xy, z); tmp = tmp * 2.0 - 1.0; diff --git a/data/shaders/gaussian3h.frag b/data/shaders/gaussian3h.frag index 46088136c..d044b214d 100644 --- a/data/shaders/gaussian3h.frag +++ b/data/shaders/gaussian3h.frag @@ -12,11 +12,11 @@ void main() float X = uv.x; float Y = uv.y; - sum += texture2D(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125; - sum += texture2D(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125; - sum += texture2D(tex, vec2(X, Y)) * 0.273438; - sum += texture2D(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125; - sum += texture2D(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125; + sum += texture(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125; + sum += texture(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125; + sum += texture(tex, vec2(X, Y)) * 0.273438; + sum += texture(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125; + sum += texture(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125; gl_FragColor = sum; } diff --git a/data/shaders/gaussian3v.frag b/data/shaders/gaussian3v.frag index 8d7d245a1..1eaafe1e9 100644 --- a/data/shaders/gaussian3v.frag +++ b/data/shaders/gaussian3v.frag @@ -12,11 +12,11 @@ void main() float X = uv.x; float Y = uv.y; - sum += texture2D(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125; - sum += texture2D(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125; - sum += texture2D(tex, vec2(X, Y)) * 0.273438; - sum += texture2D(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125; - sum += texture2D(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125; + sum += texture(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125; + sum += texture(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125; + sum += texture(tex, vec2(X, Y)) * 0.273438; + sum += texture(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125; + sum += texture(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125; gl_FragColor = sum; } diff --git a/data/shaders/gaussian6h.frag b/data/shaders/gaussian6h.frag index d21bee05a..91b37e0e2 100644 --- a/data/shaders/gaussian6h.frag +++ b/data/shaders/gaussian6h.frag @@ -12,13 +12,13 @@ void main() float X = uv.x; float Y = uv.y; - sum += texture2D(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869; - sum += texture2D(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313; - sum += texture2D(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481; - sum += texture2D(tex, vec2(X, Y)) * 0.209473; - sum += texture2D(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481; - sum += texture2D(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313; - sum += texture2D(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869; + sum += texture(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869; + sum += texture(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313; + sum += texture(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481; + sum += texture(tex, vec2(X, Y)) * 0.209473; + sum += texture(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481; + sum += texture(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313; + sum += texture(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869; gl_FragColor = sum; } diff --git a/data/shaders/gaussian6v.frag b/data/shaders/gaussian6v.frag index d4f0f6812..691309aea 100644 --- a/data/shaders/gaussian6v.frag +++ b/data/shaders/gaussian6v.frag @@ -12,13 +12,13 @@ void main() float X = uv.x; float Y = uv.y; - sum += texture2D(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869; - sum += texture2D(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313; - sum += texture2D(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481; - sum += texture2D(tex, vec2(X, Y)) * 0.209473; - sum += texture2D(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481; - sum += texture2D(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313; - sum += texture2D(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869; + sum += texture(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869; + sum += texture(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313; + sum += texture(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481; + sum += texture(tex, vec2(X, Y)) * 0.209473; + sum += texture(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481; + sum += texture(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313; + sum += texture(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869; gl_FragColor = sum; } diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag index 9545f51b6..dc62670d9 100644 --- a/data/shaders/glow.frag +++ b/data/shaders/glow.frag @@ -7,7 +7,7 @@ void main() { vec2 coords = uv; - vec4 col = texture2D(tex, coords); + vec4 col = texture(tex, coords); float alpha = col.a; if (alpha < 0.04 || length(col.xyz) < 0.2) discard; diff --git a/data/shaders/godfade.frag b/data/shaders/godfade.frag index 59e7aa4d3..0f297b333 100644 --- a/data/shaders/godfade.frag +++ b/data/shaders/godfade.frag @@ -4,7 +4,7 @@ uniform vec3 col; void main() { - vec4 res = texture2D(tex, gl_TexCoord[0].xy); + vec4 res = texture(tex, gl_TexCoord[0].xy); // Keep the sun fully bright, but fade the sky float mul = distance(res.xyz, col); diff --git a/data/shaders/godray.frag b/data/shaders/godray.frag index 8f360e650..812c1ce98 100644 --- a/data/shaders/godray.frag +++ b/data/shaders/godray.frag @@ -15,12 +15,12 @@ void main() vec2 dist = tosun * 1.0/(float(SAMPLES) * 1.12); - vec3 col = texture2D(tex, texc).xyz; + vec3 col = texture(tex, texc).xyz; float decay = 1.0; for (int i = 0; i < SAMPLES; i++) { texc += dist; - vec3 here = texture2D(tex, texc).xyz; + vec3 here = texture(tex, texc).xyz; here *= decay; col += here; decay *= decaystep; diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index 1ac631895..b34b94b63 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -8,7 +8,7 @@ in vec2 uv; void main() { - gl_FragData[0] = texture2D(tex, uv); + gl_FragData[0] = texture(tex, uv); gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); gl_FragData[2] = vec4(0.); } diff --git a/data/shaders/gum_shield.frag b/data/shaders/gum_shield.frag index 01d7dadb0..577c7d192 100644 --- a/data/shaders/gum_shield.frag +++ b/data/shaders/gum_shield.frag @@ -30,7 +30,7 @@ noperspective in vec3 normal; void main() { float inter = dot(normal, eyeVec); - float m = texture2D(tex, vec2(0.5, uv.y)).r; + float m = texture(tex, vec2(0.5, uv.y)).r; inter = 1.0 - inter; float alpha = inter + 1.0;// * m; diff --git a/data/shaders/lightbeam.frag b/data/shaders/lightbeam.frag index 93f622612..2004c62d2 100644 --- a/data/shaders/lightbeam.frag +++ b/data/shaders/lightbeam.frag @@ -32,7 +32,7 @@ noperspective in vec3 normal; void main() { float inter = dot(normal, eyeVec); - float m = texture2D(tex, vec2(0.5, uv.y)).r; + float m = texture(tex, vec2(0.5, uv.y)).r; float alpha = inter * inter * inter * inter * m; gl_FragColor = vec4(1.0, 1.0, 0.8, alpha); diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index e3d67b517..400c66fac 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -11,10 +11,10 @@ void main() { vec2 texc = uv; - vec3 diffuse = texture2D(diffuse, texc).xyz; - vec3 spec = texture2D(specular, texc).xyz; - float specmap = texture2D(specular_map, texc).x; - float ao = texture2D(ambient_occlusion, texc).x; + vec3 diffuse = texture(diffuse, texc).xyz; + vec3 spec = texture(specular, texc).xyz; + float specmap = texture(specular_map, texc).x; + float ao = texture(ambient_occlusion, texc).x; gl_FragColor = vec4(diffuse + spec * specmap + ao * ambient, 1.0); } diff --git a/data/shaders/mipviz.frag b/data/shaders/mipviz.frag index b73a7d14c..4e385ee1f 100644 --- a/data/shaders/mipviz.frag +++ b/data/shaders/mipviz.frag @@ -44,7 +44,7 @@ void main() { float mixer = fract(mip); vec4 mixcol = mix(levels[lowmip], levels[highmip], mixer); - vec4 tcol = texture2D(tex, gl_TexCoord[0].xy); + vec4 tcol = texture(tex, gl_TexCoord[0].xy); vec3 col = mix(tcol.xyz, mixcol.xyz, mixcol.a); diff --git a/data/shaders/mlaa_blend2.frag b/data/shaders/mlaa_blend2.frag index 5116c9099..9660b3e8d 100644 --- a/data/shaders/mlaa_blend2.frag +++ b/data/shaders/mlaa_blend2.frag @@ -77,7 +77,7 @@ vec2 Area(vec2 distance, float e1, float e2) { void main() { vec4 areas = vec4(0.0); - vec2 e = texture2D(edgesMap, gl_TexCoord[0].xy).rg; + vec2 e = texture(edgesMap, gl_TexCoord[0].xy).rg; if (e.g != 0.0) { // Edge at north diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag index 52c846425..b4724c1e5 100644 --- a/data/shaders/mlaa_color1.frag +++ b/data/shaders/mlaa_color1.frag @@ -11,11 +11,11 @@ void main() { /** * Luma calculation requires gamma-corrected colors: */ - float L = dot(texture2D(colorMapG, uv).rgb, weights); - float Lleft = dot(texture2D(colorMapG, offset[0].xy).rgb, weights); - float Ltop = dot(texture2D(colorMapG, offset[0].zw).rgb, weights); - float Lright = dot(texture2D(colorMapG, offset[1].xy).rgb, weights); - float Lbottom = dot(texture2D(colorMapG, offset[1].zw).rgb, weights); + float L = dot(texture(colorMapG, uv).rgb, weights); + float Lleft = dot(texture(colorMapG, offset[0].xy).rgb, weights); + float Ltop = dot(texture(colorMapG, offset[0].zw).rgb, weights); + float Lright = dot(texture(colorMapG, offset[1].xy).rgb, weights); + float Lbottom = dot(texture(colorMapG, offset[1].zw).rgb, weights); vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom)); vec4 edges = step(vec4(threshold), delta); diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag index 65984a1c2..eb136e405 100644 --- a/data/shaders/mlaa_neigh3.frag +++ b/data/shaders/mlaa_neigh3.frag @@ -7,9 +7,9 @@ uniform sampler2D colorMap; void main() { // Fetch the blending weights for current pixel: - vec4 topLeft = texture2D(blendMap, uv); - float bottom = texture2D(blendMap, offset[1].zw).g; - float right = texture2D(blendMap, offset[1].xy).a; + vec4 topLeft = texture(blendMap, uv); + float bottom = texture(blendMap, offset[1].zw).g; + float right = texture(blendMap, offset[1].xy).a; vec4 a = vec4(topLeft.r, bottom, topLeft.b, right); // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform @@ -25,11 +25,11 @@ void main() { vec4 color = vec4(0.0); // Add the contributions of the possible 4 lines that can cross this pixel: - vec4 C = texture2D(colorMap, uv); - vec4 Cleft = texture2D(colorMap, offset[0].xy); - vec4 Ctop = texture2D(colorMap, offset[0].zw); - vec4 Cright = texture2D(colorMap, offset[1].xy); - vec4 Cbottom = texture2D(colorMap, offset[1].zw); + vec4 C = texture(colorMap, uv); + vec4 Cleft = texture(colorMap, offset[0].xy); + vec4 Ctop = texture(colorMap, offset[0].zw); + vec4 Cright = texture(colorMap, offset[1].xy); + vec4 Cbottom = texture(colorMap, offset[1].zw); color = mix(C, Ctop, a.r) * w.r + color; color = mix(C, Cbottom, a.g) * w.g + color; color = mix(C, Cleft, a.b) * w.b + color; diff --git a/data/shaders/motion_blur.frag b/data/shaders/motion_blur.frag index f558a5677..6fb3ea4ef 100644 --- a/data/shaders/motion_blur.frag +++ b/data/shaders/motion_blur.frag @@ -49,7 +49,7 @@ void main() vec2 texcoords = gl_TexCoord[0].st; // Sample the color buffer - vec3 color = texture2D(color_buffer, texcoords).rgb; + vec3 color = texture(color_buffer, texcoords).rgb; // Compute the blur direction. // IMPORTANT: we don't normalize it so that it avoids a glitch around 'center', @@ -74,7 +74,7 @@ void main() vec2 blur_texcoords = texcoords + inc_vec; for(int i=1 ; i < NB_SAMPLES ; i++) { - color += texture2D(color_buffer, blur_texcoords).rgb; + color += texture(color_buffer, blur_texcoords).rgb; blur_texcoords += inc_vec; } color /= vec3(NB_SAMPLES); diff --git a/data/shaders/multiply.frag b/data/shaders/multiply.frag index 2e8f3eb5a..8e4e0065a 100644 --- a/data/shaders/multiply.frag +++ b/data/shaders/multiply.frag @@ -4,8 +4,8 @@ uniform sampler2D tex2; void main() { - vec4 col1 = texture2D(tex1, gl_TexCoord[0].xy); - vec4 col2 = vec4(vec3(texture2D(tex2, gl_TexCoord[0].xy).x), 1.0); + vec4 col1 = texture(tex1, gl_TexCoord[0].xy); + vec4 col2 = vec4(vec3(texture(tex2, gl_TexCoord[0].xy).x), 1.0); gl_FragColor = col1 * col2; } diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 5a062849d..2098c046d 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -8,7 +8,7 @@ in vec2 uv; void main() { // normal in Tangent Space - vec3 TS_normal = 2.0 * texture2D (normalMap, uv).rgb - 1.0; + vec3 TS_normal = 2.0 * texture (normalMap, uv).rgb - 1.0; // Because of interpolation, we need to renormalize vec3 Frag_tangent = normalize(tangent); vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent)); diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index 84724eb60..f72efc5e6 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -10,10 +10,10 @@ in vec2 uv; void main(void) { vec2 tc = gl_FragCoord.xy / screen; - vec4 color = texture2D(Albedo, uv); - vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; - vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - float ao = texture2D(SSAO, tc).x; + vec4 color = texture(Albedo, uv); + vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture(SpecularMap, tc).xyz; + float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); gl_FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag index 81d5d9962..683b0033d 100644 --- a/data/shaders/objectpass.frag +++ b/data/shaders/objectpass.frag @@ -14,11 +14,11 @@ void main() { vec4 col; if (haslightmap != 0) { - light = texture2D(lighttex, uv1); + light = texture(lighttex, uv1); } if (hastex != 0) - col = texture2D(tex, uv0) * light; + col = texture(tex, uv0) * light; else col = color; diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag index 62f9f57bc..5451d8584 100644 --- a/data/shaders/objectpass_ref.frag +++ b/data/shaders/objectpass_ref.frag @@ -10,7 +10,7 @@ in vec2 uv1; void main() { //if (hastex != 0) { - vec4 col = texture2D(tex, uv0); + vec4 col = texture(tex, uv0); if (col.a < 0.5) discard; diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag index af5a46030..e74a153cd 100644 --- a/data/shaders/objectpass_rimlit.frag +++ b/data/shaders/objectpass_rimlit.frag @@ -13,7 +13,7 @@ void main() { vec4 color; if (hastex != 0) { - vec4 col = texture2D(tex, gl_TexCoord[0].xy); + vec4 col = texture(tex, gl_TexCoord[0].xy); if (col.a < 0.1) discard; diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 5d62c87c4..bac98032c 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -15,7 +15,7 @@ void main() { vec3 normal_y = normalize(vec3(0.0, nor.y, nor.z)); float sin_theta_y = length(cross( forward, normal_y )) * nor.y / abs(nor.y); - vec4 detail0 = texture2D(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5); + vec4 detail0 = texture(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5); gl_FragColor = vec4(detail0.xyz, 1.); } diff --git a/data/shaders/objectref_pass1.frag b/data/shaders/objectref_pass1.frag index 6c98924bf..29464c27d 100644 --- a/data/shaders/objectref_pass1.frag +++ b/data/shaders/objectref_pass1.frag @@ -5,7 +5,7 @@ noperspective in vec3 nor; in vec2 uv; void main() { - vec4 col = texture2D(tex, uv); + vec4 col = texture(tex, uv); if (col.a < 0.5) discard; gl_FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index e2049a971..6580063af 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -9,12 +9,12 @@ in vec2 uv; void main(void) { - vec4 color = texture2D(Albedo, uv); + vec4 color = texture(Albedo, uv); if (color.a < 0.5) discard; vec2 tc = gl_FragCoord.xy / screen; - vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; - vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - float ao = texture2D(SSAO, tc).x; + vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture(SpecularMap, tc).xyz; + float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; gl_FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/particle.frag b/data/shaders/particle.frag index 08157c24e..f09df09de 100644 --- a/data/shaders/particle.frag +++ b/data/shaders/particle.frag @@ -1,5 +1,5 @@ #version 130 -uniform sampler2D texture; +uniform sampler2D tex; uniform sampler2D normals_and_depth; uniform mat4 invproj; uniform vec2 screen; @@ -13,13 +13,13 @@ void main(void) { vec2 xy = gl_FragCoord.xy / screen; float FragZ = gl_FragCoord.z; - float EnvZ = texture2D(normals_and_depth, xy).a; + float EnvZ = texture(normals_and_depth, xy).a; vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); FragmentPos /= FragmentPos.w; vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); EnvPos /= EnvPos.w; - float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); + float len = dot(vec3(1.0), abs(texture(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - color = texture2D(texture, tc); + color = texture(tex, tc); color.a *= alpha * smoothstep(1., 0.8, lf); } diff --git a/data/shaders/pass.frag b/data/shaders/pass.frag index da55410ec..63775f6af 100644 --- a/data/shaders/pass.frag +++ b/data/shaders/pass.frag @@ -3,5 +3,5 @@ uniform sampler2D tex; void main() { - gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); + gl_FragColor = texture(tex, gl_TexCoord[0].xy); } diff --git a/data/shaders/penumbrah.frag b/data/shaders/penumbrah.frag index e4598d354..28890d27f 100644 --- a/data/shaders/penumbrah.frag +++ b/data/shaders/penumbrah.frag @@ -13,37 +13,37 @@ void main() float width = 0.0; float zsum = 0.00001; - tmp = texture2D(tex, vec2(X - 5.13333 * pixel.x, Y)); + tmp = texture(tex, vec2(X - 5.13333 * pixel.x, Y)); sum += tmp.x * 0.00640869; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X - 3.26667 * pixel.x, Y)); + tmp = texture(tex, vec2(X - 3.26667 * pixel.x, Y)); sum += tmp.x * 0.083313; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X - 1.4 * pixel.x, Y)); + tmp = texture(tex, vec2(X - 1.4 * pixel.x, Y)); sum += tmp.x * 0.305481; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y)); + tmp = texture(tex, vec2(X, Y)); sum += tmp.x * 0.209473; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X + 1.4 * pixel.x, Y)); + tmp = texture(tex, vec2(X + 1.4 * pixel.x, Y)); sum += tmp.x * 0.305481; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X + 3.26667 * pixel.x, Y)); + tmp = texture(tex, vec2(X + 3.26667 * pixel.x, Y)); sum += tmp.x * 0.083313; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X + 5.13333 * pixel.x, Y)); + tmp = texture(tex, vec2(X + 5.13333 * pixel.x, Y)); sum += tmp.x * 0.00640869; zsum += tmp.z; width += tmp.y; diff --git a/data/shaders/penumbrav.frag b/data/shaders/penumbrav.frag index e8e6bbefd..ff25e8c6d 100644 --- a/data/shaders/penumbrav.frag +++ b/data/shaders/penumbrav.frag @@ -13,37 +13,37 @@ void main() float width = 0.0; float zsum = 0.00001; - tmp = texture2D(tex, vec2(X, Y - 5.13333 * pixel.y)); + tmp = texture(tex, vec2(X, Y - 5.13333 * pixel.y)); sum += tmp.x * 0.00640869; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y - 3.26667 * pixel.y)); + tmp = texture(tex, vec2(X, Y - 3.26667 * pixel.y)); sum += tmp.x * 0.083313; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y - 1.4 * pixel.y)); + tmp = texture(tex, vec2(X, Y - 1.4 * pixel.y)); sum += tmp.x * 0.305481; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y)); + tmp = texture(tex, vec2(X, Y)); sum += tmp.x * 0.209473; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y + 1.4 * pixel.y)); + tmp = texture(tex, vec2(X, Y + 1.4 * pixel.y)); sum += tmp.x * 0.305481; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y + 3.26667 * pixel.y)); + tmp = texture(tex, vec2(X, Y + 3.26667 * pixel.y)); sum += tmp.x * 0.083313; zsum += tmp.z; width += tmp.y; - tmp = texture2D(tex, vec2(X, Y + 5.13333 * pixel.y)); + tmp = texture(tex, vec2(X, Y + 5.13333 * pixel.y)); sum += tmp.x * 0.00640869; zsum += tmp.z; width += tmp.y; diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 929b2323d..642210108 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -12,7 +12,7 @@ in vec2 uv; void main() { vec2 texc = uv; - float z = texture2D(ntex, texc).a; + float z = texture(ntex, texc).a; vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0f; xpos = invproj * xpos; @@ -29,7 +29,7 @@ void main() { float att = energy[i] * 200. / (4. * 3.14 * d * d); float spec_att = (energy[i] + 10.) * 200. / (4. * 3.14 * d * d); - vec3 norm = texture2D(ntex, texc).xyz; + vec3 norm = texture(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; // Light Direction diff --git a/data/shaders/ppdisplace.frag b/data/shaders/ppdisplace.frag index fa4269f5e..8c3802b30 100644 --- a/data/shaders/ppdisplace.frag +++ b/data/shaders/ppdisplace.frag @@ -10,14 +10,14 @@ void main() { vec2 tc = uv; - vec4 shiftval = texture2D(dtex, tc) / vec4(50.0); + vec4 shiftval = texture(dtex, tc) / vec4(50.0); vec2 shift; shift.x = -shiftval.x + shiftval.y; shift.y = -shiftval.z + shiftval.w; tc += shift; - vec4 newcol = texture2D(tex, tc); + vec4 newcol = texture(tex, tc); if (viz < 1) { diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index 5b8e28e8a..4117c8ece 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -8,13 +8,13 @@ void main() { vec2 xy = gl_FragCoord.xy / screen; float FragZ = gl_FragCoord.z; - float EnvZ = texture2D(normals_and_depth, xy).a; + float EnvZ = texture(normals_and_depth, xy).a; vec4 FragmentPos = invproj * (2. * vec4(xy, FragZ, 1.0) - 1.); FragmentPos /= FragmentPos.w; vec4 EnvPos = invproj * (2. * vec4(xy, EnvZ, 1.0) - 1.); EnvPos /= EnvPos.w; - float len = dot(vec3(1.0), abs(texture2D(normals_and_depth, xy).xyz)); + float len = dot(vec3(1.0), abs(texture(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - gl_FragColor = texture2D(tex, gl_PointCoord.xy); + gl_FragColor = texture(tex, gl_PointCoord.xy); gl_FragColor.a *= alpha; } diff --git a/data/shaders/shadowgen.frag b/data/shaders/shadowgen.frag index 55ed4e86d..9a2da3d9e 100644 --- a/data/shaders/shadowgen.frag +++ b/data/shaders/shadowgen.frag @@ -6,9 +6,9 @@ uniform sampler2D eighth; void main() { vec3 val[3]; - val[0] = texture2D(halft, gl_TexCoord[0].xy).xyz; - val[1] = texture2D(quarter, gl_TexCoord[0].xy).xyz; - val[2] = texture2D(eighth, gl_TexCoord[0].xy).xyz; + val[0] = texture(halft, gl_TexCoord[0].xy).xyz; + val[1] = texture(quarter, gl_TexCoord[0].xy).xyz; + val[2] = texture(eighth, gl_TexCoord[0].xy).xyz; // Find the first level with a penumbra value int i; diff --git a/data/shaders/shadowimportance.frag b/data/shaders/shadowimportance.frag index 949ab493b..3d48a956f 100644 --- a/data/shaders/shadowimportance.frag +++ b/data/shaders/shadowimportance.frag @@ -13,7 +13,7 @@ float luminanceImp() if (low > 0) return 1.0; const vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709 - vec3 col = texture2D(ctex, texc).xyz; + vec3 col = texture(ctex, texc).xyz; float luma = dot(weights, col); @@ -51,7 +51,7 @@ float depthImp(float linearz) void main() { - vec4 ntmp = texture2D(ntex, texc); + vec4 ntmp = texture(ntex, texc); vec3 normal = ntmp.xyz * 2.0 - 1.0; float linearz = ntmp.a; diff --git a/data/shaders/shadowimportance.vert b/data/shaders/shadowimportance.vert index 044217826..938aeabe9 100644 --- a/data/shaders/shadowimportance.vert +++ b/data/shaders/shadowimportance.vert @@ -13,7 +13,7 @@ float decdepth(vec4 rgba) { void main() { texc = gl_Vertex.xy / vec2(32767.0); - float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0)); + float z = decdepth(vec4(texture(dtex, texc).xyz, 0.0)); vec3 tmp = vec3(texc, z); tmp = tmp * 2.0 - 1.0; diff --git a/data/shaders/shadowpass.frag b/data/shaders/shadowpass.frag index 6e2f5142e..7f59b6889 100644 --- a/data/shaders/shadowpass.frag +++ b/data/shaders/shadowpass.frag @@ -17,7 +17,7 @@ vec4 encdepth(float v) { void main() { if (hastex != 0) { - float alpha = texture2D(tex, uv).a; + float alpha = texture(tex, uv).a; if (alpha < 0.5) discard; @@ -31,7 +31,7 @@ void main() { if (wireframe > 0) gl_FragColor = vec4(1.0); else - gl_FragColor = texture2D(tex, uv); + gl_FragColor = texture(tex, uv); } } diff --git a/data/shaders/shadowpass.vert b/data/shaders/shadowpass.vert index 90ef95474..7233ab0d1 100644 --- a/data/shaders/shadowpass.vert +++ b/data/shaders/shadowpass.vert @@ -15,8 +15,8 @@ void main() vec2 tc = pos.xy * vec2(0.5) + vec2(0.5); - float movex = decdepth(texture2D(warpx, tc)); - float movey = decdepth(texture2D(warpy, tc)); + float movex = decdepth(texture(warpx, tc)); + float movey = decdepth(texture(warpy, tc)); float dx = movex * 2.0 - 1.0; float dy = movey * 2.0 - 1.0; diff --git a/data/shaders/shadowwarph.frag b/data/shaders/shadowwarph.frag index a7e09b740..5d110e575 100644 --- a/data/shaders/shadowwarph.frag +++ b/data/shaders/shadowwarph.frag @@ -22,7 +22,7 @@ void main() for (int i = 0; i < size; i++) { - float col = texture2D(tex, tc).x; + float col = texture(tex, tc).x; lower += col * step(tc.x, origtc.x); total += col; diff --git a/data/shaders/shadowwarpv.frag b/data/shaders/shadowwarpv.frag index 89fd11bc8..49980e940 100644 --- a/data/shaders/shadowwarpv.frag +++ b/data/shaders/shadowwarpv.frag @@ -22,7 +22,7 @@ void main() for (int i = 0; i < size; i++) { - float col = texture2D(tex, tc).x; + float col = texture(tex, tc).x; lower += col * step(tc.y, origtc.y); total += col; diff --git a/data/shaders/skybox.frag b/data/shaders/skybox.frag index 25f96662e..3c7e300be 100644 --- a/data/shaders/skybox.frag +++ b/data/shaders/skybox.frag @@ -32,26 +32,26 @@ void main() vec3 V = normalize(vertex); vec3 L = normalize(vec3(sun_pos)); - vec3 col = texture2D(tex, vec2((L.y + 1.0) / 2.0, V.y)).xyz; + vec3 col = texture(tex, vec2((L.y + 1.0) / 2.0, V.y)).xyz; float vl = clamp(dot(V, L), 0., 1.); - float paint = texture2D(tex, uv_temp * 3).a; + float paint = texture(tex, uv_temp * 3).a; uv_temp += 20; - //float paint2 = texture2D(tex, uv_temp * 5).a; + //float paint2 = texture(tex, uv_temp * 5).a; - float paint2 = texture2D(tex, uv * 5.).a; + float paint2 = texture(tex, uv * 5.).a; // Get the general cloud mask - float hello = texture2D(glow_tex, (uv_cl + paint2 * 0.07) *2.).g; + float hello = texture(glow_tex, (uv_cl + paint2 * 0.07) *2.).g; - float cld_mask = texture2D(glow_tex, (uv_anim + hello * 0.007 )).r; + float cld_mask = texture(glow_tex, (uv_anim + hello * 0.007 )).r; vec2 fast = vec2(-uv_fast.x, uv_fast.y);// + (hello * 0.007); - float cld_fast = texture2D(glow_tex, fast ).r; + float cld_fast = texture(glow_tex, fast ).r; diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index 5851248df..fd0f1cfbf 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -15,11 +15,11 @@ in vec2 uv_bis; void main() { // Splatting part - vec4 splatting = texture2D(tex_layout, uv_bis); - vec4 detail0 = texture2D(tex_detail0, uv); - vec4 detail1 = texture2D(tex_detail1, uv); - vec4 detail2 = texture2D(tex_detail2, uv); - vec4 detail3 = texture2D(tex_detail3, uv); + vec4 splatting = texture(tex_layout, uv_bis); + vec4 detail0 = texture(tex_detail0, uv); + vec4 detail1 = texture(tex_detail1, uv); + vec4 detail2 = texture(tex_detail2, uv); + vec4 detail3 = texture(tex_detail3, uv); vec4 detail4 = vec4(0.0); vec4 splatted = splatting.r * detail0 + @@ -28,9 +28,9 @@ void main() { (1.0 - splatting.r - splatting.g - splatting.b) * detail3; vec2 tc = gl_FragCoord.xy / screen; - vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; - vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - float ao = texture2D(SSAO, tc).x; + vec3 DiffuseComponent = texture(DiffuseMap, tc).xyz; + vec3 SpecularComponent = texture(SpecularMap, tc).xyz; + float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; gl_FragColor = vec4(splatted.xyz * LightFactor, 1.); diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 87602ca3a..e6d7a13bc 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -21,8 +21,8 @@ float rand(vec2 co) void main(void) { - vec4 cur = texture2D(normals_and_depth, uv); - float curdepth = texture2D(normals_and_depth, uv).a; + vec4 cur = texture(normals_and_depth, uv); + float curdepth = texture(normals_and_depth, uv).a; vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f); FragPos /= FragPos.w; @@ -50,7 +50,7 @@ void main(void) bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.); // get the depth of the occluder fragment - float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; + float occluderFragmentDepth = texture(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a; // Position of the occluder fragment in worldSpace vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f); occluderPos /= occluderPos.w; diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index c202b38d1..acabd1a6d 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -12,7 +12,7 @@ uniform vec2 wind; void main() { vec2 texc = gl_FragCoord.xy / screen; - float z = texture2D(ntex, texc).a; + float z = texture(ntex, texc).a; vec4 xpos = 2.0 * vec4(texc, z, 1.0) - 1.0; xpos = invproj * xpos; xpos.xyz /= xpos.w; @@ -25,7 +25,7 @@ void main() { return; } - vec3 norm = texture2D(ntex, texc).xyz; + vec3 norm = texture(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; // Normalized on the cpu @@ -41,7 +41,7 @@ void main() { if (hasclouds == 1) { vec2 cloudcoord = (xpos.xz * 0.00833333) + wind; - float cloud = texture2D(cloudtex, cloudcoord).x; + float cloud = texture(cloudtex, cloudcoord).x; //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y); outcol *= cloud; diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index b3f95c0c4..2ccbd2416 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -22,7 +22,7 @@ float decdepth(vec4 rgba) { void main() { vec2 texc = gl_FragCoord.xy / screen; - vec4 depthread = texture2D(dtex, texc); + vec4 depthread = texture(dtex, texc); float z = decdepth(vec4(depthread.xyz, 0.0)); if (z < 0.03) @@ -33,7 +33,7 @@ void main() { return; } - vec3 norm = texture2D(ntex, texc).xyz; + vec3 norm = texture(ntex, texc).xyz; norm = (norm - 0.5) * 2.0; // Normalized on the cpu @@ -55,7 +55,7 @@ void main() { if (hasclouds == 1) { vec2 cloudcoord = (xpos.xz * 0.00833333) + wind; - float cloud = texture2D(cloudtex, cloudcoord).x; + float cloud = texture(cloudtex, cloudcoord).x; //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y); outcol *= cloud; @@ -65,13 +65,13 @@ void main() { vec3 shadowcoord = (shadowmat * vec4(xpos.xyz, 1.0)).xyz; shadowcoord = (shadowcoord * 0.5) + vec3(0.5); - float movex = decdepth(texture2D(warpx, shadowcoord.xy)); - float movey = decdepth(texture2D(warpy, shadowcoord.xy)); + float movex = decdepth(texture(warpx, shadowcoord.xy)); + float movey = decdepth(texture(warpy, shadowcoord.xy)); float dx = movex * 2.0 - 1.0; float dy = movey * 2.0 - 1.0; shadowcoord.xy += vec2(dx, dy); - vec4 shadowread = texture2D(shadowtex, shadowcoord.xy); + vec4 shadowread = texture(shadowtex, shadowcoord.xy); float shadowmapz = decdepth(vec4(shadowread.xyz, 0.0)); float moved = (abs(dx) + abs(dy)) * 0.5; @@ -94,10 +94,10 @@ void main() { bias = clamp(bias, 0.001, abi); // This ID, and four IDs around this must match for a shadow pixel - float right = texture2D(shadowtex, shadowcoord.xy + vec2(shadowoffset, 0.0)).a; - float left = texture2D(shadowtex, shadowcoord.xy + vec2(-shadowoffset, 0.0)).a; - float up = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, shadowoffset)).a; - float down = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, -shadowoffset)).a; + float right = texture(shadowtex, shadowcoord.xy + vec2(shadowoffset, 0.0)).a; + float left = texture(shadowtex, shadowcoord.xy + vec2(-shadowoffset, 0.0)).a; + float up = texture(shadowtex, shadowcoord.xy + vec2(0.0, shadowoffset)).a; + float down = texture(shadowtex, shadowcoord.xy + vec2(0.0, -shadowoffset)).a; float matching = ((right + left + up + down) * 0.25) - shadowread.a; matching = abs(matching) * 400.0; diff --git a/data/shaders/texturedquad.frag b/data/shaders/texturedquad.frag index cf1aade40..7d950dc51 100644 --- a/data/shaders/texturedquad.frag +++ b/data/shaders/texturedquad.frag @@ -1,9 +1,9 @@ #version 130 -uniform sampler2D texture; +uniform sampler2D tex; in vec2 uv; void main() { - gl_FragColor = texture2D(texture, uv); + gl_FragColor = texture(tex, uv); } \ No newline at end of file diff --git a/data/shaders/water.frag b/data/shaders/water.frag index fad619ae5..5b2ae1b92 100644 --- a/data/shaders/water.frag +++ b/data/shaders/water.frag @@ -16,8 +16,8 @@ in vec2 uv; void main() { // lookup normal from normal map, move from [0,1] to [-1, 1] range, normalize - vec3 normal = 2.0 * texture2D (BumpTex1, uv + delta1).rgb - 1.0; - vec3 normal2 = 2.0 * texture2D (BumpTex2, uv + delta2).rgb - 1.0; + vec3 normal = 2.0 * texture (BumpTex1, uv + delta1).rgb - 1.0; + vec3 normal2 = 2.0 * texture (BumpTex2, uv + delta2).rgb - 1.0; // scale normals normal.y = 4.0*normal.y; @@ -30,7 +30,7 @@ void main() vec4 diffuseMaterial; vec4 diffuseLight; - diffuseMaterial = texture2D (DecalTex, uv + vec2(delta1.x, 0.0)); + diffuseMaterial = texture (DecalTex, uv + vec2(delta1.x, 0.0)); diffuseLight = vec4(1.0, 1.0, 1.0, 1.0); vec3 col = diffuseMaterial.xyz * (0.3 + lamberFactor*0.7); diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 042533b84..ec59db960 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -299,7 +299,7 @@ void bindUniformToTextureUnit(GLuint location, GLuint texid, unsigned textureUni static GLuint TexturedQuadShader; static GLuint TexturedQuadAttribPosition; static GLuint TexturedQuadAttribTexCoord; -static GLuint TexturedQuadUniformTexture; +static GLuint TexturedQuadUniformTex; static GLuint TexturedQuadUniformCenter; static GLuint TexturedQuadUniformSize; static GLuint TexturedQuadUniformTexcenter; @@ -311,7 +311,7 @@ static GLuint ColorTexturedQuadShader; static GLuint ColorTexturedQuadAttribPosition; static GLuint ColorTexturedQuadAttribTexCoord; static GLuint ColorTexturedQuadAttribColor; -static GLuint ColorTexturedQuadUniformTexture; +static GLuint ColorTexturedQuadUniformTex; static GLuint ColorTexturedQuadUniformCenter; static GLuint ColorTexturedQuadUniformSize; static GLuint ColorTexturedQuadUniformTexcenter; @@ -336,7 +336,7 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol ColorTexturedQuadAttribPosition = glGetAttribLocation(ColorTexturedQuadShader, "position"); ColorTexturedQuadAttribTexCoord = glGetAttribLocation(ColorTexturedQuadShader, "texcoord"); ColorTexturedQuadAttribColor = glGetAttribLocation(ColorTexturedQuadShader, "color"); - ColorTexturedQuadUniformTexture = glGetUniformLocation(ColorTexturedQuadShader, "texture"); + ColorTexturedQuadUniformTex = glGetUniformLocation(ColorTexturedQuadShader, "tex"); ColorTexturedQuadUniformCenter = glGetUniformLocation(ColorTexturedQuadShader, "center"); ColorTexturedQuadUniformSize = glGetUniformLocation(ColorTexturedQuadShader, "size"); ColorTexturedQuadUniformTexcenter = glGetUniformLocation(ColorTexturedQuadShader, "texcenter"); @@ -359,7 +359,7 @@ static void drawTexColoredQuad(const video::ITexture *texture, const video::SCol glBindVertexArray(CTQvao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); - glUniform1i(ColorTexturedQuadUniformTexture, 0); + glUniform1i(ColorTexturedQuadUniformTex, 0); glUniform2f(ColorTexturedQuadUniformCenter, center_pos_x, center_pos_y); glUniform2f(ColorTexturedQuadUniformSize, width, height); glUniform2f(ColorTexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); @@ -378,7 +378,7 @@ void drawTexQuad(const video::ITexture *texture, float width, float height, TexturedQuadAttribPosition = glGetAttribLocation(TexturedQuadShader, "position"); TexturedQuadAttribTexCoord = glGetAttribLocation(TexturedQuadShader, "texcoord"); - TexturedQuadUniformTexture = glGetUniformLocation(TexturedQuadShader, "texture"); + TexturedQuadUniformTex = glGetUniformLocation(TexturedQuadShader, "tex"); TexturedQuadUniformCenter = glGetUniformLocation(TexturedQuadShader, "center"); TexturedQuadUniformSize = glGetUniformLocation(TexturedQuadShader, "size"); TexturedQuadUniformTexcenter = glGetUniformLocation(TexturedQuadShader, "texcenter"); @@ -396,7 +396,7 @@ void drawTexQuad(const video::ITexture *texture, float width, float height, glBindVertexArray(TQvao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getOpenGLTextureName()); - glUniform1i(TexturedQuadUniformTexture, 0); + glUniform1i(TexturedQuadUniformTex, 0); glUniform2f(TexturedQuadUniformCenter, center_pos_x, center_pos_y); glUniform2f(TexturedQuadUniformSize, width, height); glUniform2f(TexturedQuadUniformTexcenter, tex_center_pos_x, tex_center_pos_y); diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d06de7e79..36d032d29 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -90,7 +90,7 @@ namespace SimpleParticleRender { GLuint Program; GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz; - GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_normal_and_depths, uniform_screen, uniform_invproj; void init() { @@ -105,7 +105,7 @@ namespace SimpleParticleRender uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix"); uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix"); - uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_tex = glGetUniformLocation(Program, "tex"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_normal_and_depths = glGetUniformLocation(Program, "normals_and_depth"); @@ -116,7 +116,7 @@ namespace FlipParticleRender { GLuint Program; GLuint attrib_pos, attrib_lf, attrib_quadcorner, attrib_texcoord, attrib_sz, attrib_rotationvec, attrib_anglespeed; - GLuint uniform_matrix, uniform_viewmatrix, uniform_texture, uniform_normal_and_depths, uniform_screen, uniform_invproj; + GLuint uniform_matrix, uniform_viewmatrix, uniform_tex, uniform_normal_and_depths, uniform_screen, uniform_invproj; void init() { @@ -132,7 +132,7 @@ namespace FlipParticleRender uniform_matrix = glGetUniformLocation(Program, "ProjectionMatrix"); uniform_viewmatrix = glGetUniformLocation(Program, "ViewMatrix"); - uniform_texture = glGetUniformLocation(Program, "texture"); + uniform_tex = glGetUniformLocation(Program, "tex"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_normal_and_depths = glGetUniformLocation(Program, "normals_and_depth"); @@ -592,7 +592,7 @@ void ParticleSystemProxy::drawFlip() (float)UserConfigParams::m_height }; - bindUniformToTextureUnit(FlipParticleRender::uniform_texture, texture, 0); + bindUniformToTextureUnit(FlipParticleRender::uniform_tex, texture, 0); bindUniformToTextureUnit(FlipParticleRender::uniform_normal_and_depths, normal_and_depth, 1); glUniformMatrix4fv(FlipParticleRender::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); @@ -661,7 +661,7 @@ void ParticleSystemProxy::drawNotFlip() (float)UserConfigParams::m_height }; - bindUniformToTextureUnit(SimpleParticleRender::uniform_texture, texture, 0); + bindUniformToTextureUnit(SimpleParticleRender::uniform_tex, texture, 0); bindUniformToTextureUnit(SimpleParticleRender::uniform_normal_and_depths, normal_and_depth, 1); glUniformMatrix4fv(SimpleParticleRender::uniform_invproj, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer()); From e4acf49e91ef822fd541630fa16941d0a068c061 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 18:54:00 +0100 Subject: [PATCH 366/412] Fix a crash with snow enabled tracks. --- src/graphics/glwrap.cpp | 2 +- src/graphics/gpuparticles.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index ec59db960..2fdf5a40a 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -59,7 +59,7 @@ static GLuint quad_buffer; static GLuint ColoredVertex; static bool is_gl_init = false; -//#define ARB_DEBUG_OUTPUT +#define ARB_DEBUG_OUTPUT #ifdef ARB_DEBUG_OUTPUT static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index 36d032d29..952af55b2 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -471,12 +471,12 @@ void ParticleSystemProxy::simulateHeightmap() glEnableVertexAttribArray(HeightmapSimulationShader::attrib_position); glEnableVertexAttribArray(HeightmapSimulationShader::attrib_lifetime); glEnableVertexAttribArray(HeightmapSimulationShader::attrib_velocity); - glEnableVertexAttribArray(HeightmapSimulationShader::attrib_size); +// glEnableVertexAttribArray(HeightmapSimulationShader::attrib_size); glBindBuffer(GL_ARRAY_BUFFER, tfb_buffers[0]); glVertexAttribPointer(HeightmapSimulationShader::attrib_position, 3, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)0); glVertexAttribPointer(HeightmapSimulationShader::attrib_lifetime, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(3 * sizeof(float))); glVertexAttribPointer(HeightmapSimulationShader::attrib_velocity, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(4 * sizeof(float))); - glVertexAttribPointer(HeightmapSimulationShader::attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); + //glVertexAttribPointer(HeightmapSimulationShader::attrib_size, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleData), (GLvoid*)(7 * sizeof(float))); glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_position); glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_lifetime); glEnableVertexAttribArray(HeightmapSimulationShader::attrib_initial_velocity); @@ -506,7 +506,7 @@ void ParticleSystemProxy::simulateHeightmap() glDisableVertexAttribArray(HeightmapSimulationShader::attrib_position); glDisableVertexAttribArray(HeightmapSimulationShader::attrib_lifetime); glDisableVertexAttribArray(HeightmapSimulationShader::attrib_velocity); - glDisableVertexAttribArray(HeightmapSimulationShader::attrib_size); +// glDisableVertexAttribArray(HeightmapSimulationShader::attrib_size); glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_position); glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_lifetime); glDisableVertexAttribArray(HeightmapSimulationShader::attrib_initial_velocity); From bf52c2abf86217460b092b4a3aafa6bf6fade802 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 19:00:59 +0100 Subject: [PATCH 367/412] Undefine ARB_DEBUG_OUTPUT --- src/graphics/glwrap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 2fdf5a40a..ec59db960 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -59,7 +59,7 @@ static GLuint quad_buffer; static GLuint ColoredVertex; static bool is_gl_init = false; -#define ARB_DEBUG_OUTPUT +//#define ARB_DEBUG_OUTPUT #ifdef ARB_DEBUG_OUTPUT static void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, From 859be83074a00a3315fc9092b1d50f15e1e1623c Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 19:31:00 +0100 Subject: [PATCH 368/412] Explicitly define fragment exported values. --- data/shaders/bloom.frag | 3 ++- data/shaders/bloomblend.frag | 3 ++- data/shaders/bloompower.frag | 4 +++- data/shaders/bubble.frag | 5 +++-- data/shaders/caustics.frag | 4 +++- data/shaders/collapse.frag | 4 +++- data/shaders/color_levels.frag | 3 ++- data/shaders/coloredquad.frag | 4 +++- data/shaders/colorize.frag | 4 +++- data/shaders/colorize_ref.frag | 4 +++- data/shaders/colortexturedquad.frag | 3 ++- data/shaders/displace.frag | 4 +++- data/shaders/fog.frag | 3 ++- data/shaders/gaussian3h.frag | 3 ++- data/shaders/gaussian3v.frag | 3 ++- data/shaders/gaussian6h.frag | 3 ++- data/shaders/gaussian6v.frag | 3 ++- data/shaders/glow.frag | 3 ++- data/shaders/godfade.frag | 3 ++- data/shaders/godray.frag | 4 +++- data/shaders/grass.frag | 9 ++++++--- data/shaders/gum_shield.frag | 3 ++- data/shaders/lightbeam.frag | 3 ++- data/shaders/lightblend.frag | 3 ++- data/shaders/mipviz.frag | 5 +++-- data/shaders/mlaa_blend2.frag | 4 +++- data/shaders/mlaa_color1.frag | 4 +++- data/shaders/mlaa_neigh3.frag | 3 ++- data/shaders/motion_blur.frag | 6 ++++-- data/shaders/multiply.frag | 4 +++- data/shaders/normalmap.frag | 3 ++- data/shaders/object_pass1.frag | 3 ++- data/shaders/object_pass2.frag | 3 ++- data/shaders/objectpass.frag | 9 ++++++--- data/shaders/objectpass_ref.frag | 11 +++++++---- data/shaders/objectpass_rimlit.frag | 9 ++++++--- data/shaders/objectpass_spheremap.frag | 3 ++- data/shaders/objectref_pass1.frag | 3 ++- data/shaders/objectref_pass2.frag | 3 ++- data/shaders/pass.frag | 4 +++- data/shaders/penumbrah.frag | 3 ++- data/shaders/penumbrav.frag | 4 +++- data/shaders/pointlight.frag | 6 ++++-- data/shaders/ppdisplace.frag | 5 +++-- data/shaders/rain.frag | 6 ++++-- data/shaders/shadowgen.frag | 3 ++- data/shaders/shadowimportance.frag | 3 ++- data/shaders/shadowpass.frag | 7 ++++--- data/shaders/shadowwarph.frag | 4 +++- data/shaders/shadowwarpv.frag | 4 +++- data/shaders/skybox.frag | 5 +++-- data/shaders/splatting.frag | 5 ++--- data/shaders/ssao.frag | 3 ++- data/shaders/sunlight.frag | 14 +++++++++----- data/shaders/sunlightshadow.frag | 11 +++++++---- data/shaders/texturedquad.frag | 3 ++- data/shaders/water.frag | 3 ++- data/shaders/white.frag | 3 ++- 58 files changed, 172 insertions(+), 85 deletions(-) diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index 43de30592..3376cdb4a 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -3,6 +3,7 @@ uniform sampler2D tex; uniform float low; in vec2 uv; +out vec4 FragColor; void main() { @@ -12,5 +13,5 @@ void main() col *= smoothstep(low, 0.9, luma); - gl_FragColor = vec4(col, 1.0); + FragColor = vec4(col, 1.0); } diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag index fcd033b0a..8e4031fa6 100644 --- a/data/shaders/bloomblend.frag +++ b/data/shaders/bloomblend.frag @@ -2,6 +2,7 @@ uniform sampler2D tex; in vec2 uv; +out vec4 FragColor; void main() { @@ -9,5 +10,5 @@ void main() col.xyz *= 10.0 * col.a; - gl_FragColor = vec4(col.xyz, 1.); + FragColor = vec4(col.xyz, 1.); } diff --git a/data/shaders/bloompower.frag b/data/shaders/bloompower.frag index 91dbf262c..f7d4ce4d3 100644 --- a/data/shaders/bloompower.frag +++ b/data/shaders/bloompower.frag @@ -2,11 +2,13 @@ uniform float power; uniform sampler2D tex; +out vec4 FragColor; + void main() { vec4 col = texture(tex, gl_TexCoord[0].xy); if (col.a < 0.5) discard; - gl_FragColor = vec4(col.xyz, power); + FragColor = vec4(col.xyz, power); } diff --git a/data/shaders/bubble.frag b/data/shaders/bubble.frag index d0e53a9a4..d344c64ed 100644 --- a/data/shaders/bubble.frag +++ b/data/shaders/bubble.frag @@ -18,9 +18,10 @@ uniform sampler2D tex; uniform float transparency; in vec2 uv; +out vec4 FragColor; void main() { - gl_FragColor = texture(tex, uv); - gl_FragColor.a *= transparency; + FragColor = texture(tex, uv); + FragColor.a *= transparency; } diff --git a/data/shaders/caustics.frag b/data/shaders/caustics.frag index 79478e0be..5e976a3c8 100644 --- a/data/shaders/caustics.frag +++ b/data/shaders/caustics.frag @@ -4,6 +4,8 @@ uniform sampler2D caustictex; uniform vec2 dir; uniform vec2 dir2; +out vec4 FragColor; + void main() { vec2 tc = gl_TexCoord[0].xy; @@ -14,5 +16,5 @@ void main() col += caustic * caustic2 * 10.0; - gl_FragColor = vec4(col, 1.0); + FragColor = vec4(col, 1.0); } diff --git a/data/shaders/collapse.frag b/data/shaders/collapse.frag index 9db482b33..3a7957a68 100644 --- a/data/shaders/collapse.frag +++ b/data/shaders/collapse.frag @@ -5,6 +5,8 @@ uniform vec2 pixel; uniform vec2 multi; uniform int size; +out vec4 FragColor; + void main() { float res = 0.0; @@ -22,5 +24,5 @@ void main() float old = texture(oldtex, gl_TexCoord[0].xy).x; - gl_FragColor = vec4(mix(old, res, 0.7)); + FragColor = vec4(mix(old, res, 0.7)); } diff --git a/data/shaders/color_levels.frag b/data/shaders/color_levels.frag index 90539fc2f..33bca9d06 100644 --- a/data/shaders/color_levels.frag +++ b/data/shaders/color_levels.frag @@ -4,6 +4,7 @@ uniform vec3 inlevel; uniform vec2 outlevel; in vec2 uv; +out vec4 FragColor; void main() { @@ -25,5 +26,5 @@ void main() col.rgb = (pow(((col.rgb * 255.0) - inBlack) / (inWhite - inBlack), vec3(1.0 / inGamma)) * (outWhite - outBlack) + outBlack) / 255.0; - gl_FragColor = vec4(col.rgb, 1.0); + FragColor = vec4(col.rgb, 1.0); } diff --git a/data/shaders/coloredquad.frag b/data/shaders/coloredquad.frag index 4d2c007c1..6afba1d06 100644 --- a/data/shaders/coloredquad.frag +++ b/data/shaders/coloredquad.frag @@ -1,7 +1,9 @@ #version 130 uniform ivec4 color; +out vec4 FragColor; + void main() { - gl_FragColor = vec4(color) / 255.; + FragColor = vec4(color) / 255.; } diff --git a/data/shaders/colorize.frag b/data/shaders/colorize.frag index d1a10a4c5..160fa4362 100644 --- a/data/shaders/colorize.frag +++ b/data/shaders/colorize.frag @@ -1,7 +1,9 @@ #version 130 uniform vec3 col; +out vec4 FragColor; + void main() { - gl_FragColor = vec4(col, 1.0); + FragColor = vec4(col, 1.0); } diff --git a/data/shaders/colorize_ref.frag b/data/shaders/colorize_ref.frag index f8f51cd06..743f32224 100644 --- a/data/shaders/colorize_ref.frag +++ b/data/shaders/colorize_ref.frag @@ -2,11 +2,13 @@ uniform vec3 col; uniform sampler2D tex; +out vec4 FragColor; + void main() { float alpha = texture(tex, gl_TexCoord[0].xy).a; if (alpha < 0.5) discard; - gl_FragColor = vec4(col, 1.0); + FragColor = vec4(col, 1.0); } diff --git a/data/shaders/colortexturedquad.frag b/data/shaders/colortexturedquad.frag index 4d5a36671..ec885322b 100644 --- a/data/shaders/colortexturedquad.frag +++ b/data/shaders/colortexturedquad.frag @@ -3,9 +3,10 @@ uniform sampler2D tex; in vec2 uv; in vec4 col; +out vec4 FragColor; void main() { vec4 res = texture(tex, uv); - gl_FragColor = vec4(res.xyz * col.xyz, res.a); + FragColor = vec4(res.xyz * col.xyz, res.a); } diff --git a/data/shaders/displace.frag b/data/shaders/displace.frag index cbfe1a255..0a071becb 100644 --- a/data/shaders/displace.frag +++ b/data/shaders/displace.frag @@ -8,6 +8,8 @@ in vec2 uv; in vec2 edger_uv; in float camdist; +out vec4 FragColor; + void main() { vec2 tc = uv; @@ -39,5 +41,5 @@ void main() col.b = step(offset.y, 0.0) * -offset.y; col.a = step(0.0, offset.y) * offset.y; - gl_FragColor = col; + FragColor = col; } diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag index 7d0bfb9c4..3fb5f39bb 100644 --- a/data/shaders/fog.frag +++ b/data/shaders/fog.frag @@ -11,6 +11,7 @@ uniform vec3 campos; uniform mat4 ipvmat; in vec2 uv; +out vec4 FragColor; void main() { @@ -29,5 +30,5 @@ void main() fog = min(fog, fogmax); - gl_FragColor = vec4(col, fog); + FragColor = vec4(col, fog); } diff --git a/data/shaders/gaussian3h.frag b/data/shaders/gaussian3h.frag index d044b214d..4e3e3f54d 100644 --- a/data/shaders/gaussian3h.frag +++ b/data/shaders/gaussian3h.frag @@ -5,6 +5,7 @@ uniform vec2 pixel; // Gaussian separated blur with radius 3. in vec2 uv; +out vec4 FragColor; void main() { @@ -18,5 +19,5 @@ void main() sum += texture(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125; sum += texture(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125; - gl_FragColor = sum; + FragColor = sum; } diff --git a/data/shaders/gaussian3v.frag b/data/shaders/gaussian3v.frag index 1eaafe1e9..f5617c9b7 100644 --- a/data/shaders/gaussian3v.frag +++ b/data/shaders/gaussian3v.frag @@ -5,6 +5,7 @@ uniform vec2 pixel; // Gaussian separated blur with radius 3. in vec2 uv; +out vec4 FragColor; void main() { @@ -18,5 +19,5 @@ void main() sum += texture(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125; sum += texture(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125; - gl_FragColor = sum; + FragColor = sum; } diff --git a/data/shaders/gaussian6h.frag b/data/shaders/gaussian6h.frag index 91b37e0e2..6530a9a1a 100644 --- a/data/shaders/gaussian6h.frag +++ b/data/shaders/gaussian6h.frag @@ -5,6 +5,7 @@ uniform vec2 pixel; // Gaussian separated blur with radius 6. in vec2 uv; +out vec4 FragColor; void main() { @@ -20,5 +21,5 @@ void main() sum += texture(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313; sum += texture(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869; - gl_FragColor = sum; + FragColor = sum; } diff --git a/data/shaders/gaussian6v.frag b/data/shaders/gaussian6v.frag index 691309aea..7a66dfe8c 100644 --- a/data/shaders/gaussian6v.frag +++ b/data/shaders/gaussian6v.frag @@ -5,6 +5,7 @@ uniform vec2 pixel; // Gaussian separated blur with radius 6. in vec2 uv; +out vec4 FragColor; void main() { @@ -20,5 +21,5 @@ void main() sum += texture(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313; sum += texture(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869; - gl_FragColor = sum; + FragColor = sum; } diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag index dc62670d9..ebf944a31 100644 --- a/data/shaders/glow.frag +++ b/data/shaders/glow.frag @@ -2,6 +2,7 @@ uniform sampler2D tex; in vec2 uv; +out vec4 FragColor; void main() { @@ -15,5 +16,5 @@ void main() col *= vec4(vec3(4.0), 1.5); col.a *= 0.6; - gl_FragColor = col; + FragColor = col; } diff --git a/data/shaders/godfade.frag b/data/shaders/godfade.frag index 0f297b333..f8166b1a6 100644 --- a/data/shaders/godfade.frag +++ b/data/shaders/godfade.frag @@ -1,6 +1,7 @@ #version 130 uniform sampler2D tex; uniform vec3 col; +out vec4 FragColor; void main() { @@ -13,5 +14,5 @@ void main() res = res * vec4(mul); - gl_FragColor = res; + FragColor = res; } diff --git a/data/shaders/godray.frag b/data/shaders/godray.frag index 812c1ce98..3e1c5aad6 100644 --- a/data/shaders/godray.frag +++ b/data/shaders/godray.frag @@ -6,6 +6,8 @@ uniform vec2 sunpos; const float decaystep = 0.88; +out vec4 FragColor; + void main() { vec2 texc = gl_TexCoord[0].xy; @@ -26,5 +28,5 @@ void main() decay *= decaystep; } - gl_FragColor = vec4(col, 1.0) * 0.8; + FragColor = vec4(col, 1.0) * 0.8; } diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag index b34b94b63..abd339b58 100644 --- a/data/shaders/grass.frag +++ b/data/shaders/grass.frag @@ -5,10 +5,13 @@ uniform sampler2D tex; noperspective in vec3 nor; in vec2 uv; +out vec4 Albedo; +out vec4 NormalDepth; +out vec4 Specular; void main() { - gl_FragData[0] = texture(tex, uv); - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(0.); + Albedo = texture(tex, uv); + NormalDepth = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + Specular = vec4(0.); } diff --git a/data/shaders/gum_shield.frag b/data/shaders/gum_shield.frag index 577c7d192..0c1459627 100644 --- a/data/shaders/gum_shield.frag +++ b/data/shaders/gum_shield.frag @@ -26,6 +26,7 @@ uniform float transparency; in vec2 uv; noperspective in vec3 eyeVec; noperspective in vec3 normal; +out vec4 FragColor; void main() { @@ -34,5 +35,5 @@ void main() inter = 1.0 - inter; float alpha = inter + 1.0;// * m; - gl_FragColor = vec4(0.8, 0.16, 0.48, alpha); + FragColor = vec4(0.8, 0.16, 0.48, alpha); } diff --git a/data/shaders/lightbeam.frag b/data/shaders/lightbeam.frag index 2004c62d2..069cccbf3 100644 --- a/data/shaders/lightbeam.frag +++ b/data/shaders/lightbeam.frag @@ -28,6 +28,7 @@ uniform float transparency; in vec2 uv; noperspective in vec3 eyeVec; noperspective in vec3 normal; +out vec4 FragColor; void main() { @@ -35,5 +36,5 @@ void main() float m = texture(tex, vec2(0.5, uv.y)).r; float alpha = inter * inter * inter * inter * m; - gl_FragColor = vec4(1.0, 1.0, 0.8, alpha); + FragColor = vec4(1.0, 1.0, 0.8, alpha); } diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag index 400c66fac..0cd68fe3b 100644 --- a/data/shaders/lightblend.frag +++ b/data/shaders/lightblend.frag @@ -6,6 +6,7 @@ uniform sampler2D specular_map; uniform vec3 ambient; in vec2 uv; +out vec4 FragColor; void main() { @@ -16,5 +17,5 @@ void main() float specmap = texture(specular_map, texc).x; float ao = texture(ambient_occlusion, texc).x; - gl_FragColor = vec4(diffuse + spec * specmap + ao * ambient, 1.0); + FragColor = vec4(diffuse + spec * specmap + ao * ambient, 1.0); } diff --git a/data/shaders/mipviz.frag b/data/shaders/mipviz.frag index 4e385ee1f..b329a49dc 100644 --- a/data/shaders/mipviz.frag +++ b/data/shaders/mipviz.frag @@ -3,6 +3,7 @@ uniform sampler2D tex; uniform vec2 texsize; uniform int notex; +out vec4 FragColor; float miplevel(in vec2 texture_coordinate) { @@ -19,7 +20,7 @@ float miplevel(in vec2 texture_coordinate) void main() { if (notex != 0) { - gl_FragColor = gl_Color; + FragColor = gl_Color; return; } @@ -48,5 +49,5 @@ void main() { vec3 col = mix(tcol.xyz, mixcol.xyz, mixcol.a); - gl_FragColor = vec4(col, tcol.a); + FragColor = vec4(col, tcol.a); } diff --git a/data/shaders/mlaa_blend2.frag b/data/shaders/mlaa_blend2.frag index 9660b3e8d..3ef21ca57 100644 --- a/data/shaders/mlaa_blend2.frag +++ b/data/shaders/mlaa_blend2.frag @@ -9,6 +9,8 @@ uniform sampler2D areaMap; uniform vec2 PIXEL_SIZE; +out vec4 FragColor; + /** * This one just returns the first level of a mip map chain, which allow us to * avoid the nasty ddx/ddy warnings, even improving the performance a little @@ -109,5 +111,5 @@ void main() { areas.ba = Area(abs(d), e1, e2); } - gl_FragColor = areas; + FragColor = areas; } diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag index b4724c1e5..49828738b 100644 --- a/data/shaders/mlaa_color1.frag +++ b/data/shaders/mlaa_color1.frag @@ -5,6 +5,8 @@ in vec2 uv; uniform sampler2D colorMapG; const float threshold = 0.1; +out vec4 FragColor; + void main() { vec3 weights = vec3(0.2126,0.7152, 0.0722); // ITU-R BT. 709 @@ -23,5 +25,5 @@ void main() { if (dot(edges, vec4(1.0)) == 0.0) discard; - gl_FragColor = edges; + FragColor = edges; } diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag index eb136e405..5bf5fdc22 100644 --- a/data/shaders/mlaa_neigh3.frag +++ b/data/shaders/mlaa_neigh3.frag @@ -1,6 +1,7 @@ #version 130 in vec4 offset[2]; in vec2 uv; +out vec4 FragColor; uniform sampler2D blendMap; uniform sampler2D colorMap; @@ -36,5 +37,5 @@ void main() { color = mix(C, Cright, a.a) * w.a + color; // Normalize the resulting color and we are finished! - gl_FragColor = color / sum; + FragColor = color / sum; } diff --git a/data/shaders/motion_blur.frag b/data/shaders/motion_blur.frag index 6fb3ea4ef..9521814ad 100644 --- a/data/shaders/motion_blur.frag +++ b/data/shaders/motion_blur.frag @@ -41,6 +41,8 @@ uniform float mask_radius; // Maximum height of texture used uniform float max_tex_height; +out vec4 FragColor; + // Number of samples used for blurring #define NB_SAMPLES 8 @@ -78,8 +80,8 @@ void main() blur_texcoords += inc_vec; } color /= vec3(NB_SAMPLES); - gl_FragColor = vec4(color, 1.0); + FragColor = vec4(color, 1.0); // Keep this commented line for debugging: - //gl_FragColor = vec4(blur_factor, blur_factor, blur_factor, 0.0); + //FragColor = vec4(blur_factor, blur_factor, blur_factor, 0.0); } diff --git a/data/shaders/multiply.frag b/data/shaders/multiply.frag index 8e4e0065a..ca9cbd8fa 100644 --- a/data/shaders/multiply.frag +++ b/data/shaders/multiply.frag @@ -2,10 +2,12 @@ uniform sampler2D tex1; uniform sampler2D tex2; +out vec4 FragColor; + void main() { vec4 col1 = texture(tex1, gl_TexCoord[0].xy); vec4 col2 = vec4(vec3(texture(tex2, gl_TexCoord[0].xy).x), 1.0); - gl_FragColor = col1 * col2; + FragColor = col1 * col2; } diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag index 2098c046d..97922296c 100644 --- a/data/shaders/normalmap.frag +++ b/data/shaders/normalmap.frag @@ -4,6 +4,7 @@ uniform sampler2D normalMap; noperspective in vec3 tangent; noperspective in vec3 bitangent; in vec2 uv; +out vec4 FragColor; void main() { @@ -17,5 +18,5 @@ void main() vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal; FragmentNormal = normalize(FragmentNormal); - gl_FragColor = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); + FragColor = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/object_pass1.frag b/data/shaders/object_pass1.frag index 46672cb9f..fb9dce400 100644 --- a/data/shaders/object_pass1.frag +++ b/data/shaders/object_pass1.frag @@ -1,7 +1,8 @@ #version 130 noperspective in vec3 nor; +out vec4 FragColor; void main(void) { - gl_FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index f72efc5e6..4ccb2ceea 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -6,6 +6,7 @@ uniform sampler2D SSAO; uniform vec2 screen; uniform vec3 ambient; in vec2 uv; +out vec4 FragColor; void main(void) { @@ -15,5 +16,5 @@ void main(void) vec3 SpecularComponent = texture(SpecularMap, tc).xyz; float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); - gl_FragColor = vec4(color.xyz * LightFactor, 1.); + FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag index 683b0033d..3ecc698ba 100644 --- a/data/shaders/objectpass.frag +++ b/data/shaders/objectpass.frag @@ -8,6 +8,9 @@ noperspective in vec3 nor; in vec4 color; in vec2 uv0; in vec2 uv1; +out vec4 Albedo; +out vec4 NormalDepth; +out vec4 Specular; void main() { vec4 light = vec4(1.0); @@ -22,8 +25,8 @@ void main() { else col = color; - gl_FragData[0] = vec4(col.xyz, 1.); - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - col.a); + Albedo = vec4(col.xyz, 1.); + NormalDepth = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + Specular = vec4(1. - col.a); } diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag index 5451d8584..43915ee90 100644 --- a/data/shaders/objectpass_ref.frag +++ b/data/shaders/objectpass_ref.frag @@ -6,6 +6,9 @@ uniform float objectid; noperspective in vec3 nor; in vec2 uv0; in vec2 uv1; +out vec4 Albedo; +out vec4 NormalDepth; +out vec4 Specular; void main() { @@ -15,12 +18,12 @@ void main() { if (col.a < 0.5) discard; - gl_FragData[0] = vec4(col.xyz, 1.); + Albedo = vec4(col.xyz, 1.); //} else { - // gl_FragData[0] = gl_Color; + // Albedo = gl_Color; //} - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - col.a); + NormalDepth = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + Specular = vec4(1. - col.a); } diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag index e74a153cd..ccb752e5b 100644 --- a/data/shaders/objectpass_rimlit.frag +++ b/data/shaders/objectpass_rimlit.frag @@ -6,6 +6,9 @@ uniform float objectid; noperspective in vec3 nor; noperspective in vec3 eyenor; noperspective in vec3 viewpos; +out vec4 Albedo; +out vec4 NormalDepth; +out vec4 Specular; void main() { float rim = 1.0 - dot(eyenor, viewpos); @@ -25,8 +28,8 @@ void main() { color = gl_Color + vec4(vec3(rim), 0.0); } - gl_FragData[0] = vec4(color.xyz, 1.); - gl_FragData[1] = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); - gl_FragData[2] = vec4(1. - color.a); + Albedo = vec4(color.xyz, 1.); + NormalDepth = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + Specular = vec4(1. - color.a); } diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index bac98032c..b46610199 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -2,6 +2,7 @@ uniform sampler2D tex; noperspective in vec3 nor; +out vec4 FragColor; void main() { // Calculate the spherical UV @@ -17,5 +18,5 @@ void main() { vec4 detail0 = texture(tex, 0.5 * vec2(sin_theta_x, sin_theta_y) + 0.5); - gl_FragColor = vec4(detail0.xyz, 1.); + FragColor = vec4(detail0.xyz, 1.); } diff --git a/data/shaders/objectref_pass1.frag b/data/shaders/objectref_pass1.frag index 29464c27d..5eb201f69 100644 --- a/data/shaders/objectref_pass1.frag +++ b/data/shaders/objectref_pass1.frag @@ -3,11 +3,12 @@ uniform sampler2D tex; noperspective in vec3 nor; in vec2 uv; +out vec4 NormalDepth; void main() { vec4 col = texture(tex, uv); if (col.a < 0.5) discard; - gl_FragColor = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); + NormalDepth = vec4(0.5 * normalize(nor) + 0.5, gl_FragCoord.z); } diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 6580063af..5c1589f98 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -6,6 +6,7 @@ uniform sampler2D SSAO; uniform vec2 screen; uniform vec3 ambient; in vec2 uv; +out vec4 FragColor; void main(void) { @@ -16,5 +17,5 @@ void main(void) vec3 SpecularComponent = texture(SpecularMap, tc).xyz; float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; - gl_FragColor = vec4(color.xyz * LightFactor, 1.); + FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/data/shaders/pass.frag b/data/shaders/pass.frag index 63775f6af..e736e2326 100644 --- a/data/shaders/pass.frag +++ b/data/shaders/pass.frag @@ -1,7 +1,9 @@ #version 130 uniform sampler2D tex; +out vec4 FragColor; + void main() { - gl_FragColor = texture(tex, gl_TexCoord[0].xy); + FragColor = texture(tex, gl_TexCoord[0].xy); } diff --git a/data/shaders/penumbrah.frag b/data/shaders/penumbrah.frag index 28890d27f..4f18e8f5a 100644 --- a/data/shaders/penumbrah.frag +++ b/data/shaders/penumbrah.frag @@ -2,6 +2,7 @@ uniform sampler2D tex; uniform vec2 pixel; +out vec4 FragColor; // Separated penumbra, horizontal void main() @@ -49,5 +50,5 @@ void main() width += tmp.y; float hasz = step(0.7, zsum); - gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0); + FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0); } diff --git a/data/shaders/penumbrav.frag b/data/shaders/penumbrav.frag index ff25e8c6d..790b86d02 100644 --- a/data/shaders/penumbrav.frag +++ b/data/shaders/penumbrav.frag @@ -2,6 +2,8 @@ uniform sampler2D tex; uniform vec2 pixel; +out vec4 FragColor; + // Separated penumbra, vertical void main() @@ -49,5 +51,5 @@ void main() width += tmp.y; float hasz = step(0.7, zsum); - gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0); + FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0); } diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 642210108..f900d763a 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -9,6 +9,8 @@ uniform mat4 invproj; uniform mat4 viewm; in vec2 uv; +out vec4 Diffuse; +out vec4 Specular; void main() { vec2 texc = uv; @@ -44,6 +46,6 @@ void main() { specular += Specular * light_col * spec_att; } - gl_FragData[0] = vec4(diffuse, 1.); - gl_FragData[1] = vec4(specular , 1.); + Diffuse = vec4(diffuse, 1.); + Specular = vec4(specular , 1.); } diff --git a/data/shaders/ppdisplace.frag b/data/shaders/ppdisplace.frag index 8c3802b30..4b2d13248 100644 --- a/data/shaders/ppdisplace.frag +++ b/data/shaders/ppdisplace.frag @@ -5,6 +5,7 @@ uniform sampler2D dtex; uniform int viz; in vec2 uv; +out vec4 FragColor; void main() { @@ -21,9 +22,9 @@ void main() if (viz < 1) { - gl_FragColor = newcol; + FragColor = newcol; } else { - gl_FragColor = shiftval * vec4(50.0); + FragColor = shiftval * vec4(50.0); } } diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag index 4117c8ece..493a63f6a 100644 --- a/data/shaders/rain.frag +++ b/data/shaders/rain.frag @@ -4,6 +4,8 @@ uniform sampler2D normals_and_depth; uniform mat4 invproj; uniform vec2 screen; +out vec4 FragColor; + void main() { vec2 xy = gl_FragCoord.xy / screen; @@ -15,6 +17,6 @@ void main() EnvPos /= EnvPos.w; float len = dot(vec3(1.0), abs(texture(normals_and_depth, xy).xyz)); float alpha = (len < 0.2) ? 1. : clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.); - gl_FragColor = texture(tex, gl_PointCoord.xy); - gl_FragColor.a *= alpha; + FragColor = texture(tex, gl_PointCoord.xy); + FragColor.a *= alpha; } diff --git a/data/shaders/shadowgen.frag b/data/shaders/shadowgen.frag index 9a2da3d9e..5ee4a2a93 100644 --- a/data/shaders/shadowgen.frag +++ b/data/shaders/shadowgen.frag @@ -2,6 +2,7 @@ uniform sampler2D halft; // half is a reserved word uniform sampler2D quarter; uniform sampler2D eighth; +out vec4 FragColor; void main() { @@ -41,5 +42,5 @@ void main() outval = 1.0 - mix(val[down].x, val[up].x, interp); } - gl_FragColor = vec4(vec3(outval), 1.0); + FragColor = vec4(vec3(outval), 1.0); } diff --git a/data/shaders/shadowimportance.frag b/data/shaders/shadowimportance.frag index 3d48a956f..50b2edc25 100644 --- a/data/shaders/shadowimportance.frag +++ b/data/shaders/shadowimportance.frag @@ -6,6 +6,7 @@ uniform int low; in vec3 wpos; in vec2 texc; +out vec4 FragColor; float luminanceImp() { @@ -66,6 +67,6 @@ void main() importance = ceil(importance) * low; importance /= steps; - gl_FragColor = vec4(importance); + FragColor = vec4(importance); gl_FragDepth = 1.0 - importance; } diff --git a/data/shaders/shadowpass.frag b/data/shaders/shadowpass.frag index 7f59b6889..a6bb31048 100644 --- a/data/shaders/shadowpass.frag +++ b/data/shaders/shadowpass.frag @@ -6,6 +6,7 @@ uniform int wireframe; uniform float objectid; in vec2 uv; +out vec4 FragColor; vec4 encdepth(float v) { vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; @@ -25,13 +26,13 @@ void main() { if (viz < 1) { - gl_FragColor = vec4(encdepth(gl_FragCoord.z).xyz, objectid); + FragColor = vec4(encdepth(gl_FragCoord.z).xyz, objectid); } else { if (wireframe > 0) - gl_FragColor = vec4(1.0); + FragColor = vec4(1.0); else - gl_FragColor = texture(tex, uv); + FragColor = texture(tex, uv); } } diff --git a/data/shaders/shadowwarph.frag b/data/shaders/shadowwarph.frag index 5d110e575..820c24d41 100644 --- a/data/shaders/shadowwarph.frag +++ b/data/shaders/shadowwarph.frag @@ -3,6 +3,8 @@ uniform sampler2D tex; uniform int size; uniform vec2 pixel; +out vec4 FragColor; + vec4 encdepth(float v) { vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; enc = fract(enc); @@ -51,5 +53,5 @@ void main() res = res * 0.5 + 0.5; res = clamp(res, 0.01, 0.99); - gl_FragColor = encdepth(res); + FragColor = encdepth(res); } diff --git a/data/shaders/shadowwarpv.frag b/data/shaders/shadowwarpv.frag index 49980e940..fb3a0b0fd 100644 --- a/data/shaders/shadowwarpv.frag +++ b/data/shaders/shadowwarpv.frag @@ -3,6 +3,8 @@ uniform sampler2D tex; uniform int size; uniform vec2 pixel; +out vec4 FragColor; + vec4 encdepth(float v) { vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v; enc = fract(enc); @@ -51,5 +53,5 @@ void main() res = res * 0.5 + 0.5; res = clamp(res, 0.01, 0.99); - gl_FragColor = encdepth(res); + FragColor = encdepth(res); } diff --git a/data/shaders/skybox.frag b/data/shaders/skybox.frag index 3c7e300be..ab9eda8f5 100644 --- a/data/shaders/skybox.frag +++ b/data/shaders/skybox.frag @@ -25,6 +25,7 @@ in vec2 uv; in vec2 uv_cl; in vec3 vertex; in vec2 uv_fast; +out vec4 FragColor; void main() { @@ -62,8 +63,8 @@ void main() col = cld_mask + col*(1. - cld_mask); col = cld_fast + col*(1. - cld_fast); - gl_FragColor = vec4( vec3(col * paint * paint2), 1.0); + FragColor = vec4( vec3(col * paint * paint2), 1.0); - //gl_FragColor = vec4(vec3(ou), 1.0); + //FragColor = vec4(vec3(ou), 1.0); } diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag index fd0f1cfbf..31bf34f71 100644 --- a/data/shaders/splatting.frag +++ b/data/shaders/splatting.frag @@ -12,6 +12,7 @@ uniform vec3 ambient; in vec2 uv; in vec2 uv_bis; +out vec4 FragColor; void main() { // Splatting part @@ -33,7 +34,5 @@ void main() { float ao = texture(SSAO, tc).x; vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; - gl_FragColor = vec4(splatted.xyz * LightFactor, 1.); - -// gl_FragData[2] = vec4(1. - splatted.a); + FragColor = vec4(splatted.xyz * LightFactor, 1.); } diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index e6d7a13bc..667be623c 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -6,6 +6,7 @@ uniform mat4 projm; uniform vec4 samplePoints[16]; in vec2 uv; +out vec4 FragColor; const float strengh = 4.; const float radius = .4f; @@ -62,5 +63,5 @@ void main(void) // output the result float ao = 1.0 - bl * invSamples; - gl_FragColor = vec4(ao); + FragColor = vec4(ao); } diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag index acabd1a6d..9b8a6d255 100644 --- a/data/shaders/sunlight.frag +++ b/data/shaders/sunlight.frag @@ -9,6 +9,10 @@ uniform mat4 invproj; uniform int hasclouds; uniform vec2 wind; +out vec4 Diff; +out vec4 Spec; +out vec4 SpecularMap; + void main() { vec2 texc = gl_FragCoord.xy / screen; @@ -20,8 +24,8 @@ void main() { if (z < 0.03) { // Skyboxes are fully lit - gl_FragData[0] = vec4(1.0); - gl_FragData[1] = vec4(1.0); + Diff = vec4(1.0); + Spec = vec4(1.0); return; } @@ -47,7 +51,7 @@ void main() { outcol *= cloud; } - gl_FragData[0] = vec4(NdotL * col, 1.); - gl_FragData[1] = vec4(Specular * col, 1.); - gl_FragData[2] = vec4(1.0); + Diff = vec4(NdotL * col, 1.); + Spec = vec4(Specular * col, 1.); + SpecularMap = vec4(1.0); } diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index 2ccbd2416..3151cfb7e 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -15,6 +15,9 @@ uniform int hasclouds; uniform vec2 wind; uniform float shadowoffset; +out vec4 FragColor; +out vec4 OtherOutput; + float decdepth(vec4 rgba) { return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0)); } @@ -28,8 +31,8 @@ void main() { if (z < 0.03) { // Skyboxes are fully lit - gl_FragData[0] = vec4(1.0); - gl_FragData[1] = vec4(0.0); + FragColor = vec4(1.0); + OtherOutput = vec4(0.0); return; } @@ -115,6 +118,6 @@ void main() { /* outcol.r = (shadowcoord.z - shadowmapz) * 50.0; outcol.g = moved;*/ - gl_FragData[0] = vec4(outcol, 0.05); - gl_FragData[1] = vec4(shadowed, penumbra, shadowed, shadowed); + FragColor = vec4(outcol, 0.05); + OtherOutput = vec4(shadowed, penumbra, shadowed, shadowed); } diff --git a/data/shaders/texturedquad.frag b/data/shaders/texturedquad.frag index 7d950dc51..6a83ac1fe 100644 --- a/data/shaders/texturedquad.frag +++ b/data/shaders/texturedquad.frag @@ -2,8 +2,9 @@ uniform sampler2D tex; in vec2 uv; +out vec4 FragColor; void main() { - gl_FragColor = texture(tex, uv); + FragColor = texture(tex, uv); } \ No newline at end of file diff --git a/data/shaders/water.frag b/data/shaders/water.frag index 5b2ae1b92..fc106fb29 100644 --- a/data/shaders/water.frag +++ b/data/shaders/water.frag @@ -12,6 +12,7 @@ noperspective in vec3 lightVec; noperspective in vec3 halfVec; noperspective in vec3 eyeVec; in vec2 uv; +out vec4 FragColor; void main() { @@ -53,5 +54,5 @@ void main() float summed = dot(vec3(1.0), col) / 3.0; float alpha = 0.9 + 0.1 * smoothstep(0.0, 1.0, summed); - gl_FragColor = vec4(col, alpha); + FragColor = vec4(col, alpha); } diff --git a/data/shaders/white.frag b/data/shaders/white.frag index e396c44e2..a22a4a9a4 100644 --- a/data/shaders/white.frag +++ b/data/shaders/white.frag @@ -1,5 +1,6 @@ #version 130 +out vec4 FragColor; void main() { - gl_FragColor = vec4(1.0); + FragColor = vec4(1.0); } From 99dad9c3043c676ed6665c4607ca2f1b640c5f3c Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 19:54:20 +0100 Subject: [PATCH 369/412] Remove unused normalmap/splatting providers --- src/graphics/callbacks.cpp | 67 -------------------------------------- src/graphics/callbacks.hpp | 24 -------------- src/graphics/shaders.cpp | 3 -- 3 files changed, 94 deletions(-) diff --git a/src/graphics/callbacks.cpp b/src/graphics/callbacks.cpp index 385219e48..f94b4b063 100644 --- a/src/graphics/callbacks.cpp +++ b/src/graphics/callbacks.cpp @@ -29,37 +29,6 @@ using namespace core; //------------------------------------- -void NormalMapProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); - ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); - ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); - core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW); - TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - - srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); - srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); - - if (!firstdone) - { - s32 texture = 0; - srv->setPixelShaderConstant("texture", &texture, 1); - - s32 normaltex = 1; - srv->setPixelShaderConstant("normalMap", &normaltex, 1); - - // We could calculate light direction as coming from the sun (then we'd need to - // transform it into camera space). But I find that pretending light - // comes from the camera gives good results - - firstdone = true; - } -} - -//------------------------------------- - void WaterShaderProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; @@ -179,42 +148,6 @@ void SkyboxProvider::OnSetConstants(IMaterialRendererServices *srv, int) //------------------------------------- -void SplattingProvider::OnSetConstants(IMaterialRendererServices *srv, int) -{ - core::matrix4 ModelViewProjectionMatrix = srv->getVideoDriver()->getTransform(ETS_PROJECTION); - ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_VIEW); - ModelViewProjectionMatrix *= srv->getVideoDriver()->getTransform(ETS_WORLD); - core::matrix4 TransposeInverseModelView = srv->getVideoDriver()->getTransform(ETS_VIEW); - TransposeInverseModelView *= srv->getVideoDriver()->getTransform(ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); - - srv->setVertexShaderConstant("ModelViewProjectionMatrix", ModelViewProjectionMatrix.pointer(), 16); - srv->setVertexShaderConstant("TransposeInverseModelView", TransposeInverseModelView.pointer(), 16); - - if (!firstdone) - { - s32 tex_layout = 1; - srv->setPixelShaderConstant("tex_layout", &tex_layout, 1); - - s32 tex_detail0 = 2; - srv->setPixelShaderConstant("tex_detail0", &tex_detail0, 1); - - s32 tex_detail1 = 3; - srv->setPixelShaderConstant("tex_detail1", &tex_detail1, 1); - - s32 tex_detail2 = 4; - srv->setPixelShaderConstant("tex_detail2", &tex_detail2, 1); - - s32 tex_detail3 = 5; - srv->setPixelShaderConstant("tex_detail3", &tex_detail3, 1); - - firstdone = true; - } -} - -//------------------------------------- - void BubbleEffectProvider::OnSetConstants(IMaterialRendererServices *srv, int) { const float start = fabsf(mat.MaterialTypeParam2); diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 84cdc5156..36be29442 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -50,22 +50,6 @@ protected: // -class NormalMapProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); - - NormalMapProvider(bool withLightmap) - { - m_with_lightmap = withLightmap; - } - -private: - bool m_with_lightmap; -}; - -// - class WaterShaderProvider: public CallBase { public: @@ -156,14 +140,6 @@ private: // -class SplattingProvider: public CallBase -{ -public: - virtual void OnSetConstants(video::IMaterialRendererServices *srv, int); -}; - -// - class BubbleEffectProvider: public CallBase { public: diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index bc8566961..c69387f09 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -32,10 +32,7 @@ Shaders::Shaders() // Callbacks memset(m_callbacks, 0, sizeof(m_callbacks)); - m_callbacks[ES_NORMAL_MAP_LIGHTMAP] = new NormalMapProvider(true); - m_callbacks[ES_NORMAL_MAP] = new NormalMapProvider(false); m_callbacks[ES_SKYBOX] = new SkyboxProvider(); - m_callbacks[ES_SPLATTING] = new SplattingProvider(); m_callbacks[ES_WATER] = new WaterShaderProvider(); m_callbacks[ES_GRASS] = new GrassShaderProvider(); m_callbacks[ES_BUBBLES] = new BubbleEffectProvider(); From 24443829db5167b0817596a55a76b1db92fa4b9f Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 20:38:05 +0100 Subject: [PATCH 370/412] STKMesh: Support grass shader --- data/shaders/grass_pass1.vert | 18 +++++ data/shaders/grass_pass2.vert | 14 ++++ src/graphics/callbacks.hpp | 10 +++ src/graphics/shaders.cpp | 88 ++++++++++++++++++--- src/graphics/shaders.hpp | 26 ++++++- src/graphics/stkmesh.cpp | 139 +++++++++++++++++++++++++++++++--- src/graphics/stkmesh.hpp | 2 + 7 files changed, 274 insertions(+), 23 deletions(-) create mode 100644 data/shaders/grass_pass1.vert create mode 100644 data/shaders/grass_pass2.vert diff --git a/data/shaders/grass_pass1.vert b/data/shaders/grass_pass1.vert new file mode 100644 index 000000000..49d6859c7 --- /dev/null +++ b/data/shaders/grass_pass1.vert @@ -0,0 +1,18 @@ +#version 130 +uniform vec3 windDir; +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 TransposeInverseModelView; + +in vec3 Position; +in vec3 Normal; +in vec2 Texcoord; +in vec4 Color; +noperspective out vec3 nor; +out vec2 uv; + +void main() +{ + uv = Texcoord; + nor = (TransposeInverseModelView * vec4(Normal, 1.)).xyz; + gl_Position = ModelViewProjectionMatrix * vec4(Position + windDir * Color.r, 1.); +} diff --git a/data/shaders/grass_pass2.vert b/data/shaders/grass_pass2.vert new file mode 100644 index 000000000..607caa7d0 --- /dev/null +++ b/data/shaders/grass_pass2.vert @@ -0,0 +1,14 @@ +#version 130 +uniform vec3 windDir; +uniform mat4 ModelViewProjectionMatrix; + +in vec3 Position; +in vec2 Texcoord; +in vec4 Color; +out vec2 uv; + +void main() +{ + uv = Texcoord; + gl_Position = ModelViewProjectionMatrix * vec4(Position + windDir * Color.r, 1.); +} diff --git a/src/graphics/callbacks.hpp b/src/graphics/callbacks.hpp index 36be29442..c666d8a6e 100644 --- a/src/graphics/callbacks.hpp +++ b/src/graphics/callbacks.hpp @@ -117,6 +117,16 @@ public: m_amplitude = amp; } + float getSpeed() const + { + return m_speed; + } + + float getAmplitude() const + { + return m_amplitude; + } + private: float m_amplitude, m_speed; }; diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index c69387f09..e24389b6b 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -113,9 +113,9 @@ void Shaders::loadShaders() m_shaders[ES_SPHERE_MAP] = glslmat(dir + "objectpass.vert", dir + "objectpass_spheremap.frag", m_callbacks[ES_OBJECTPASS], EMT_SOLID); - m_shaders[ES_GRASS] = glslmat(dir + "grass.vert", dir + "grass.frag", + m_shaders[ES_GRASS] = glslmat(dir + "grass.vert", dir + "grass.frag", m_callbacks[ES_GRASS], EMT_TRANSPARENT_ALPHA_CHANNEL); - m_shaders[ES_GRASS_REF] = glslmat(dir + "grass.vert", dir + "grass.frag", + m_shaders[ES_GRASS_REF] = glslmat(dir + "grass.vert", dir + "grass.frag", m_callbacks[ES_GRASS], EMT_TRANSPARENT_ALPHA_CHANNEL_REF); m_shaders[ES_BUBBLES] = glslmat(dir + "bubble.vert", dir + "bubble.frag", @@ -244,6 +244,8 @@ void Shaders::loadShaders() MeshShader::ObjectRefPass2Shader::init(); MeshShader::SphereMapShader::init(); MeshShader::SplattingShader::init(); + MeshShader::GrassPass1Shader::init(); + MeshShader::GrassPass2Shader::init(); } Shaders::~Shaders() @@ -282,7 +284,6 @@ namespace MeshShader void ObjectPass1Shader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/object_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); @@ -306,7 +307,6 @@ namespace MeshShader void ObjectRefPass1Shader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/objectref_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); @@ -327,7 +327,6 @@ namespace MeshShader GLuint ObjectPass2Shader::attrib_position; GLuint ObjectPass2Shader::attrib_texcoord; GLuint ObjectPass2Shader::uniform_MVP; - GLuint ObjectPass2Shader::uniform_TIMV; GLuint ObjectPass2Shader::uniform_Albedo; GLuint ObjectPass2Shader::uniform_DiffuseMap; GLuint ObjectPass2Shader::uniform_SpecularMap; @@ -337,7 +336,6 @@ namespace MeshShader void ObjectPass2Shader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/object_pass2.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); @@ -366,7 +364,6 @@ namespace MeshShader GLuint ObjectRefPass2Shader::attrib_position; GLuint ObjectRefPass2Shader::attrib_texcoord; GLuint ObjectRefPass2Shader::uniform_MVP; - GLuint ObjectRefPass2Shader::uniform_TIMV; GLuint ObjectRefPass2Shader::uniform_Albedo; GLuint ObjectRefPass2Shader::uniform_DiffuseMap; GLuint ObjectRefPass2Shader::uniform_SpecularMap; @@ -401,6 +398,79 @@ namespace MeshShader glUniform3f(uniform_ambient, s.r, s.g, s.b); } + GLuint GrassPass1Shader::Program; + GLuint GrassPass1Shader::attrib_position; + GLuint GrassPass1Shader::attrib_texcoord; + GLuint GrassPass1Shader::attrib_normal; + GLuint GrassPass1Shader::attrib_color; + GLuint GrassPass1Shader::uniform_MVP; + GLuint GrassPass1Shader::uniform_TIMV; + GLuint GrassPass1Shader::uniform_tex; + GLuint GrassPass1Shader::uniform_windDir; + + void GrassPass1Shader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/grass_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + attrib_color = glGetAttribLocation(Program, "Color"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_windDir = glGetUniformLocation(Program, "windDir"); + } + + void GrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); + glUniform1i(uniform_tex, TU_tex); + } + + GLuint GrassPass2Shader::Program; + GLuint GrassPass2Shader::attrib_position; + GLuint GrassPass2Shader::attrib_texcoord; + GLuint GrassPass2Shader::attrib_color; + GLuint GrassPass2Shader::uniform_MVP; + GLuint GrassPass2Shader::uniform_Albedo; + GLuint GrassPass2Shader::uniform_DiffuseMap; + GLuint GrassPass2Shader::uniform_SpecularMap; + GLuint GrassPass2Shader::uniform_SSAO; + GLuint GrassPass2Shader::uniform_screen; + GLuint GrassPass2Shader::uniform_ambient; + GLuint GrassPass2Shader::uniform_windDir; + + void GrassPass2Shader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/grass_pass2.vert").c_str(), file_manager->getAsset("shaders/objectref_pass2.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_color = glGetAttribLocation(Program, "Color"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_ambient = glGetUniformLocation(Program, "ambient"); + uniform_windDir = glGetUniformLocation(Program, "windDir"); + } + + void GrassPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); + glUniform1i(uniform_SpecularMap, TU_SpecularMap); + glUniform1i(uniform_SSAO, TU_SSAO); + glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); + const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); + glUniform3f(uniform_ambient, s.r, s.g, s.b); + glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); + } + GLuint NormalMapShader::Program; GLuint NormalMapShader::attrib_position; GLuint NormalMapShader::attrib_texcoord; @@ -412,7 +482,6 @@ namespace MeshShader void NormalMapShader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); @@ -439,7 +508,6 @@ namespace MeshShader void SphereMapShader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/object_pass1.vert").c_str(), file_manager->getAsset("shaders/objectpass_spheremap.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); @@ -473,7 +541,6 @@ namespace MeshShader void SplattingShader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/splatting.vert").c_str(), file_manager->getAsset("shaders/splatting.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); @@ -514,7 +581,6 @@ namespace MeshShader void ColorizeShader::init() { - initGL(); Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/colorize.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index f43b5272a..9f0f0fecd 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -53,7 +53,7 @@ class ObjectPass2Shader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; static void init(); static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); @@ -64,12 +64,34 @@ class ObjectRefPass2Shader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_TIMV, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; static void init(); static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); }; +class GrassPass1Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_normal, attrib_color; + static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_windDir; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex); +}; + +class GrassPass2Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_color; + static GLuint uniform_MVP, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient, uniform_windDir; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); +}; + class NormalMapShader { public: diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 4afedb374..858ce8197 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -4,9 +4,10 @@ #include #include "config/user_config.hpp" #include "graphics/callbacks.hpp" +#include "utils/helpers.hpp" static -GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, size_t stride) +GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, GLuint attrib_color, size_t stride) { GLuint vao; glGenVertexArrays(1, &vao); @@ -23,6 +24,8 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t glEnableVertexAttribArray(attrib_tangent); if ((GLint)attrib_bitangent != -1) glEnableVertexAttribArray(attrib_bitangent); + if ((GLint)attrib_color != -1) + glEnableVertexAttribArray(attrib_color); glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0); if ((GLint)attrib_texcoord != -1) glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28); @@ -47,6 +50,8 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t Log::error("material", "Bitangents not present in VBO"); glVertexAttribPointer(attrib_bitangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)48); } + if ((GLint)attrib_color != -1) + glVertexAttribPointer(attrib_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (GLvoid*)24); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); glBindVertexArray(0); @@ -237,6 +242,61 @@ void STKMesh::drawObjectRefPass1(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } +static +core::vector3df getWind() +{ + const core::vector3df pos = irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD).getTranslation(); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; + GrassShaderProvider *gsp = (GrassShaderProvider *)irr_driver->getCallback(ES_GRASS); + float m_speed = gsp->getSpeed(), m_amplitude = gsp->getAmplitude(); + + float strength = (pos.X + pos.Y + pos.Z) * 1.2f + time * m_speed; + strength = noise2d(strength / 10.0f) * m_amplitude * 5; + // * 5 is to work with the existing amplitude values. + + // Pre-multiply on the cpu + return irr_driver->getWind() * strength; +} + +void STKMesh::drawGrassPass1(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glUseProgram(MeshShader::GrassPass1Shader::Program); + MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, getWind(), 0); + + glBindVertexArray(mesh.vao_first_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); +} + void STKMesh::drawNormalPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -426,6 +486,48 @@ void STKMesh::drawObjectRefPass2(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } +void STKMesh::drawGrassPass2(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glUseProgram(MeshShader::GrassPass2Shader::Program); + MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, getWind(), 0, 1, 2, 3); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} + void STKMesh::drawSecondPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); @@ -498,6 +600,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) drawNormalPass(mesh); else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) drawObjectRefPass1(mesh); + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + drawGrassPass1(mesh); else drawFirstPass(mesh); break; @@ -508,6 +612,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) drawSplatting(mesh); else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) drawObjectRefPass2(mesh); + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + drawGrassPass2(mesh); else drawSecondPass(mesh); break; @@ -541,6 +647,10 @@ static bool isObject(video::E_MATERIAL_TYPE type) return true; if (type == irr_driver->getShader(ES_SPLATTING)) return true; + if (type == irr_driver->getShader(ES_GRASS)) + return true; + if (type == irr_driver->getShader(ES_GRASS_REF)) + return true; return false; } @@ -551,41 +661,50 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) if (type == irr_driver->getShader(ES_NORMAL_MAP)) { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, mesh.Stride); + MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, -1, mesh.Stride); } else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); + } + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride); } else { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); } if (type == irr_driver->getShader(ES_SPHERE_MAP)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, mesh.Stride); + MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, -1, mesh.Stride); } else if (type == irr_driver->getShader(ES_SPLATTING)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); + MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); } else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); - + MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + } + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride); } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); + MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); } - mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, mesh.Stride); + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); } void STKMesh::render() diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 959fff563..7cc3b49d8 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -32,12 +32,14 @@ protected: void drawFirstPass(const GLMesh &mesh); void drawNormalPass(const GLMesh &mesh); void drawObjectRefPass1(const GLMesh &mesh); + void drawGrassPass1(const GLMesh &mesh); // Pass 2 shader (ie shaders that outputs final color) void drawSphereMap(const GLMesh &mesh); void drawSplatting(const GLMesh &mesh); void drawSecondPass(const GLMesh &mesh); void drawObjectRefPass2(const GLMesh &mesh); + void STKMesh::drawGrassPass2(const GLMesh &mesh); // Pass 3 shader (glow) void drawGlow(const GLMesh &mesh, float r, float g, float b); From 32836cf93d530277a9883000e0cc20ce57b5db26 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 20:57:58 +0100 Subject: [PATCH 371/412] Use 8 samples instead of 16 --- 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 667be623c..64bbc3ef3 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -11,7 +11,7 @@ out vec4 FragColor; const float strengh = 4.; const float radius = .4f; -#define SAMPLES 16 +#define SAMPLES 8 const float invSamples = strengh / SAMPLES; From e26f8d4bc8aad293aa217cccf70f83ffd491b063 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 21:17:51 +0100 Subject: [PATCH 372/412] Some welcomed factorization. --- src/graphics/stkmesh.cpp | 144 +++++++++++---------------------------- src/graphics/stkmesh.hpp | 6 +- 2 files changed, 44 insertions(+), 106 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 858ce8197..b929f69f3 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -171,15 +171,8 @@ STKMesh::~STKMesh() } } -void STKMesh::drawFirstPass(const GLMesh &mesh) +void STKMesh::drawObjectPass1(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); - - glStencilFunc(GL_ALWAYS, 0, ~0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -197,21 +190,10 @@ void STKMesh::drawFirstPass(const GLMesh &mesh) glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 1, ~0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } void STKMesh::drawObjectRefPass1(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); - - glStencilFunc(GL_ALWAYS, 0, ~0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -236,10 +218,6 @@ void STKMesh::drawObjectRefPass1(const GLMesh &mesh) glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 1, ~0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } static @@ -260,13 +238,6 @@ core::vector3df getWind() void STKMesh::drawGrassPass1(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); - - glStencilFunc(GL_ALWAYS, 0, ~0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -291,21 +262,10 @@ void STKMesh::drawGrassPass1(const GLMesh &mesh) glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 1, ~0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } void STKMesh::drawNormalPass(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); - - glStencilFunc(GL_ALWAYS, 0, ~0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -331,20 +291,10 @@ void STKMesh::drawNormalPass(const GLMesh &mesh) glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glStencilFunc(GL_ALWAYS, 1, ~0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } void STKMesh::drawSphereMap(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -361,19 +311,10 @@ void STKMesh::drawSphereMap(const GLMesh &mesh) glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } void STKMesh::drawSplatting(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -439,19 +380,10 @@ void STKMesh::drawSplatting(const GLMesh &mesh) glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } void STKMesh::drawObjectRefPass2(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -481,19 +413,10 @@ void STKMesh::drawObjectRefPass2(const GLMesh &mesh) glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } void STKMesh::drawGrassPass2(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -523,19 +446,10 @@ void STKMesh::drawGrassPass2(const GLMesh &mesh) glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } -void STKMesh::drawSecondPass(const GLMesh &mesh) +void STKMesh::drawObjectPass2(const GLMesh &mesh) { - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); - - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDisable(GL_BLEND); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -565,9 +479,6 @@ void STKMesh::drawSecondPass(const GLMesh &mesh) glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } void STKMesh::drawGlow(const GLMesh &mesh, float r, float g, float b) @@ -596,6 +507,15 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) switch (irr_driver->getPhase()) { case 0: + { + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + if (type == irr_driver->getShader(ES_NORMAL_MAP)) drawNormalPass(mesh); else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) @@ -603,20 +523,38 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) drawGrassPass1(mesh); else - drawFirstPass(mesh); + drawObjectPass1(mesh); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); break; + } case 1: - if (type == irr_driver->getShader(ES_SPHERE_MAP)) - drawSphereMap(mesh); - else if (type == irr_driver->getShader(ES_SPLATTING)) - drawSplatting(mesh); - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - drawObjectRefPass2(mesh); - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - drawGrassPass2(mesh); - else - drawSecondPass(mesh); - break; + { + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + + if (type == irr_driver->getShader(ES_SPHERE_MAP)) + drawSphereMap(mesh); + else if (type == irr_driver->getShader(ES_SPLATTING)) + drawSplatting(mesh); + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + drawObjectRefPass2(mesh); + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + drawGrassPass2(mesh); + else + drawObjectPass2(mesh); + + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + break; + } case 2: { ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 7cc3b49d8..49e0b0b9e 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -29,7 +29,7 @@ protected: void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type); // Pass 1 shader (ie shaders that outputs normals and depth) - void drawFirstPass(const GLMesh &mesh); + void drawObjectPass1(const GLMesh &mesh); void drawNormalPass(const GLMesh &mesh); void drawObjectRefPass1(const GLMesh &mesh); void drawGrassPass1(const GLMesh &mesh); @@ -37,9 +37,9 @@ protected: // Pass 2 shader (ie shaders that outputs final color) void drawSphereMap(const GLMesh &mesh); void drawSplatting(const GLMesh &mesh); - void drawSecondPass(const GLMesh &mesh); + void drawObjectPass2(const GLMesh &mesh); void drawObjectRefPass2(const GLMesh &mesh); - void STKMesh::drawGrassPass2(const GLMesh &mesh); + void drawGrassPass2(const GLMesh &mesh); // Pass 3 shader (glow) void drawGlow(const GLMesh &mesh, float r, float g, float b); From dcfd55502c54e86a8e25d0973b13d57ce5254c55 Mon Sep 17 00:00:00 2001 From: Deve Date: Sun, 19 Jan 2014 21:31:54 +0100 Subject: [PATCH 373/412] Added experimental change which allow to use alt-tab and other shortcuts on linux when game is run in fullscreen mode. This method is used in many other projects and should work good. Currently modern games use window manager fullscreen rather than grab whole mouse and keyboard. Tested on Gnome, Unity and Openbox and it works well. Though it should be tested also on other desktop environments. Also performance impact should be tested. I added simple workaround for Gnome, which sometimes creates fullscreen window smaller than display. If some problems will occur, feel free to revert it. --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 5f6536196..692ab0984 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -663,8 +663,7 @@ bool CIrrDeviceLinux::createWindow() if (!CreationParams.WindowId) { // create new Window - // Remove window manager decoration in fullscreen - attributes.override_redirect = CreationParams.Fullscreen; + attributes.override_redirect = false; window = XCreateWindow(display, RootWindow(display, visual->screen), 0, 0, Width, Height, 0, visual->depth, @@ -676,16 +675,34 @@ bool CIrrDeviceLinux::createWindow() Atom wmDelete; wmDelete = XInternAtom(display, wmDeleteWindow, True); XSetWMProtocols(display, window, &wmDelete, 1); + if (CreationParams.Fullscreen) { - XSetInputFocus(display, window, RevertToParent, CurrentTime); - int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync, - GrabModeAsync, CurrentTime); - IrrPrintXGrabError(grabKb, "XGrabKeyboard"); - int grabPointer = XGrabPointer(display, window, True, ButtonPressMask, - GrabModeAsync, GrabModeAsync, window, None, CurrentTime); - IrrPrintXGrabError(grabPointer, "XGrabPointer"); - XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); + // Workaround for Gnome which sometimes creates window smaller than display + XSizeHints *hints = XAllocSizeHints(); + hints->flags=PMinSize; + hints->min_width=Width; + hints->min_height=Height; + XSetWMNormalHints(display, window, hints); + XFree(hints); + + // Set the fullscreen mode via the window manager. This allows alt-tabing, volume hot keys & others. + // Get the needed atom from there freedesktop names + Atom WMStateAtom = XInternAtom(display, "_NET_WM_STATE", true); + Atom WMFullscreenAtom = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", true); + // Set the fullscreen property + XChangeProperty(display, window, WMStateAtom, XA_ATOM, 32, PropModeReplace, reinterpret_cast(& WMFullscreenAtom), 1); + + // Notify the root window + XEvent xev = {0}; // The event should be filled with zeros before setting its attributes + + xev.type = ClientMessage; + xev.xclient.window = window; + xev.xclient.message_type = WMStateAtom; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = WMFullscreenAtom; + XSendEvent(display, DefaultRootWindow(display), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } } else From 0817ec4ee07971ac09545dd7cda97522ead414b4 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 19 Jan 2014 21:34:48 +0100 Subject: [PATCH 374/412] STKMesh:Another round of factorization. --- src/graphics/stkmesh.cpp | 215 ++++++++++++--------------------------- src/graphics/stkmesh.hpp | 1 + 2 files changed, 66 insertions(+), 150 deletions(-) diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index b929f69f3..f71338987 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -171,19 +171,31 @@ STKMesh::~STKMesh() } } +static +void computeMVP(core::matrix4 &ModelViewProjectionMatrix) +{ + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); +} + +static +void computeTIMV(core::matrix4 &TransposeInverseModelView) +{ + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); +} + void STKMesh::drawObjectPass1(const GLMesh &mesh) { GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); glUseProgram(MeshShader::ObjectPass1Shader::Program); MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); @@ -192,26 +204,27 @@ void STKMesh::drawObjectPass1(const GLMesh &mesh) glDrawElements(ptype, count, itype, 0); } +static void +setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter) +{ + glActiveTexture(GL_TEXTURE0 + TextureUnit); + glBindTexture(GL_TEXTURE_2D, TextureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +} + void STKMesh::drawObjectRefPass1(const GLMesh &mesh) { GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); glUseProgram(MeshShader::ObjectRefPass1Shader::Program); MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); @@ -241,24 +254,15 @@ void STKMesh::drawGrassPass1(const GLMesh &mesh) GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; + windDir = getWind(); - ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); glUseProgram(MeshShader::GrassPass1Shader::Program); - MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, getWind(), 0); + MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, windDir, 0); glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); @@ -270,21 +274,11 @@ void STKMesh::drawNormalPass(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); - TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - TransposeInverseModelView.makeInverse(); - TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); assert(mesh.textures[1]); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); glUseProgram(MeshShader::NormalMapShader::Program); MeshShader::NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); @@ -299,12 +293,7 @@ void STKMesh::drawSphereMap(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); glUseProgram(MeshShader::SphereMapShader::Program); MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); @@ -320,60 +309,28 @@ void STKMesh::drawSplatting(const GLMesh &mesh) size_t count = mesh.IndexCount; // Texlayout - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); //Tex detail0 - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, mesh.textures[2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(1, mesh.textures[2], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); //Tex detail1 - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mesh.textures[3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(2, mesh.textures[3], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); //Tex detail2 - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, mesh.textures[4]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(3, mesh.textures[4], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); //Tex detail3 - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, mesh.textures[5]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(4, mesh.textures[5], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); // Diffuse - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(5, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + // Specular - glActiveTexture(GL_TEXTURE6); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(6, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + // SSAO - glActiveTexture(GL_TEXTURE7); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(7, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); glUseProgram(MeshShader::SplattingShader::Program); MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); @@ -388,25 +345,11 @@ void STKMesh::drawObjectRefPass2(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(1, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(2, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(3, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); glUseProgram(MeshShader::ObjectRefPass2Shader::Program); MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); @@ -421,28 +364,14 @@ void STKMesh::drawGrassPass2(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(1, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(2, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(3, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); glUseProgram(MeshShader::GrassPass2Shader::Program); - MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, getWind(), 0, 1, 2, 3); + MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -454,25 +383,11 @@ void STKMesh::drawObjectPass2(const GLMesh &mesh) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + setTexture(1, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(2, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); + setTexture(3, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName(), GL_NEAREST, GL_NEAREST); glUseProgram(MeshShader::ObjectPass2Shader::Program); MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 49e0b0b9e..cdf85a198 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -26,6 +26,7 @@ class STKMesh : public irr::scene::CMeshSceneNode protected: std::vector GLmeshes; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; + core::vector3df windDir; void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type); // Pass 1 shader (ie shaders that outputs normals and depth) From 260f4f148d24da73427de0efd77ca2fa43de2698 Mon Sep 17 00:00:00 2001 From: hiker Date: Mon, 20 Jan 2014 21:39:59 +1100 Subject: [PATCH 375/412] Reworked the login and register dialog to be a screen - still work in progress (and guest login does not work yet). --- data/gui/online/guest_login.stkgui | 44 +++ data/gui/online/login.stkgui | 58 ++++ data/gui/online/login_dialog.stkgui | 12 +- data/gui/online/register.stkgui | 78 +++++ data/gui/online/registration_terms.stkgui | 9 +- sources.cmake | 6 + src/online/current_user.cpp | 30 +- src/online/current_user.hpp | 3 +- .../dialogs/registration_dialog.cpp | 301 ++---------------- .../dialogs/registration_dialog.hpp | 54 +--- src/states_screens/guest_login_screen.cpp | 66 ++++ src/states_screens/guest_login_screen.hpp | 47 +++ src/states_screens/login_screen.cpp | 173 ++++++++++ src/states_screens/login_screen.hpp | 63 ++++ src/states_screens/main_menu_screen.cpp | 14 +- src/states_screens/register_screen.cpp | 192 +++++++++++ src/states_screens/register_screen.hpp | 64 ++++ 17 files changed, 847 insertions(+), 367 deletions(-) create mode 100644 data/gui/online/guest_login.stkgui create mode 100644 data/gui/online/login.stkgui create mode 100644 data/gui/online/register.stkgui create mode 100644 src/states_screens/guest_login_screen.cpp create mode 100644 src/states_screens/guest_login_screen.hpp create mode 100644 src/states_screens/login_screen.cpp create mode 100644 src/states_screens/login_screen.hpp create mode 100644 src/states_screens/register_screen.cpp create mode 100644 src/states_screens/register_screen.hpp diff --git a/data/gui/online/guest_login.stkgui b/data/gui/online/guest_login.stkgui new file mode 100644 index 000000000..b69941132 --- /dev/null +++ b/data/gui/online/guest_login.stkgui @@ -0,0 +1,44 @@ + + + +
+ +
+ + + + + + + + + +
+ + +
+
+
+ + + + + + + +
+ + + +
diff --git a/data/gui/online/login.stkgui b/data/gui/online/login.stkgui new file mode 100644 index 000000000..2d7159f10 --- /dev/null +++ b/data/gui/online/login.stkgui @@ -0,0 +1,58 @@ + + + +
+ +
+ + + + + + + + + +
+ + +
+
+
+ +
+
+ +
+
+
+
+ + + +
diff --git a/data/gui/online/login_dialog.stkgui b/data/gui/online/login_dialog.stkgui index b60b8599e..d0b74ed7e 100644 --- a/data/gui/online/login_dialog.stkgui +++ b/data/gui/online/login_dialog.stkgui @@ -5,11 +5,11 @@
- +