Merge branch 'master' of https://github.com/supertuxkart/stk-code
This commit is contained in:
commit
37a6f464b9
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<graphical-restrictions>
|
||||
<card is="Intel(R) HD Graphics" os="windows" version="<9.0" disable="ForceLegacyDevice"/>
|
||||
<card is="Intel(R) HD Graphics" os="windows" version="<9.0" disable="HighDefinitionTextures"/>
|
||||
<card is="Intel(R) HD Graphics" os="windows" version="<10.0" disable="ForceLegacyDevice"/>
|
||||
<card is="Intel(R) HD Graphics" os="windows" version="<10.0" disable="HighDefinitionTextures"/>
|
||||
<card is="Intel(R) HD Graphics 2000" os="windows" disable="ForceLegacyDevice"/>
|
||||
<card is="Intel(R) HD Graphics 2000" os="windows" disable="HighDefinitionTextures"/>
|
||||
<card is="Intel(R) HD Graphics 3000" os="windows" disable="ForceLegacyDevice"/>
|
||||
@ -35,5 +35,6 @@
|
||||
<card os="android" disable="ColorBufferFloat"/>
|
||||
<card contains="Adreno" os="android" version="<=19" disable="VertexIdWorking"/>
|
||||
<card contains="Android Emulator" os="android" disable="ForceLegacyDevice"/>
|
||||
<card contains="Android Emulator" os="android" disable="NpotTextures"/>
|
||||
<card vendor="Broadcom" os="linux" disable="HighDefinitionTextures256"/>
|
||||
</graphical-restrictions>
|
||||
|
@ -39,7 +39,7 @@ void main(void)
|
||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0);
|
||||
tc = Texcoord;
|
||||
|
||||
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
pc = particle_color;
|
||||
|
@ -1,8 +1,8 @@
|
||||
uniform ivec4 color;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(color) / 255.;
|
||||
}
|
||||
uniform ivec4 color;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(color) / 255.;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec2 Position;
|
||||
#else
|
||||
in vec2 Position;
|
||||
#endif
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location = 0) in vec2 Position;
|
||||
#else
|
||||
in vec2 Position;
|
||||
#endif
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 col;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture(tex, uv);
|
||||
FragColor = res * col;
|
||||
}
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 col;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 res = texture(tex, uv);
|
||||
FragColor = res * col;
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
uniform vec2 texcenter;
|
||||
uniform vec2 texsize;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location=0) in vec2 Position;
|
||||
layout(location=3) in vec2 Texcoord;
|
||||
layout(location=2) in vec4 Color;
|
||||
#else
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec4 Color;
|
||||
#endif
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 col;
|
||||
|
||||
void main()
|
||||
{
|
||||
col = Color.zyxw;
|
||||
uv = Texcoord * texsize + texcenter;
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
uniform vec2 center;
|
||||
uniform vec2 size;
|
||||
uniform vec2 texcenter;
|
||||
uniform vec2 texsize;
|
||||
|
||||
#ifdef Explicit_Attrib_Location_Usable
|
||||
layout(location=0) in vec2 Position;
|
||||
layout(location=3) in vec2 Texcoord;
|
||||
layout(location=2) in vec4 Color;
|
||||
#else
|
||||
in vec2 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec4 Color;
|
||||
#endif
|
||||
|
||||
out vec2 uv;
|
||||
out vec4 col;
|
||||
|
||||
void main()
|
||||
{
|
||||
col = Color.zyxw;
|
||||
uv = Texcoord * texsize + texcenter;
|
||||
gl_Position = vec4(Position * size + center, 0., 1.);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void main(void)
|
||||
vec4 particle_color = vec4(color_lifetime.zyx, 1.0) * alpha;
|
||||
tc = Texcoord;
|
||||
|
||||
#if !defined(sRGB_Framebuffer_Usable) && !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
particle_color.rgb = pow(particle_color.rgb, vec3(1.0 / 2.2));
|
||||
#endif
|
||||
pc = particle_color;
|
||||
|
@ -14,7 +14,7 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (col.a * color.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
@ -30,17 +30,10 @@ void main(void)
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz * color.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_2 = sampleTextureSlot2(uv);
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(normal)) + 0.5;
|
||||
o_normal_depth.z = layer_2.x;
|
||||
o_gloss_map = layer_2.yz;
|
||||
|
@ -11,22 +11,15 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = sampleTextureSlot0(uv);
|
||||
vec4 layer_two_tex = sampleTextureSlot1(uv_two);
|
||||
vec4 color = sampleTextureLayer0(uv);
|
||||
vec4 layer_two_tex = sampleTextureLayer1(uv_two);
|
||||
layer_two_tex.rgb = layer_two_tex.a * layer_two_tex.rgb;
|
||||
|
||||
vec3 final_color = layer_two_tex.rgb + color.rgb * (1.0 - layer_two_tex.a);
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_2 = sampleTextureSlot2(uv);
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(normal)) + 0.5;
|
||||
o_normal_depth.z = layer_2.x;
|
||||
o_gloss_map = layer_2.yz;
|
||||
|
@ -41,7 +41,7 @@ void main()
|
||||
tc += (mask < 1.) ? vec2(0.) : shift;
|
||||
|
||||
vec4 col = texture(color_tex, tc);
|
||||
vec4 blend_tex = sampleTextureSlot0(uv);
|
||||
vec4 blend_tex = sampleTextureLayer0(uv);
|
||||
col.rgb = blend_tex.rgb * blend_tex.a + (1. - blend_tex.a) * col.rgb;
|
||||
o_diffuse_color = vec4(col.rgb, 1.);
|
||||
}
|
||||
|
@ -11,14 +11,15 @@ out vec4 o_diffuse_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (hue_change > 0.0)
|
||||
{
|
||||
float mask = col.a;
|
||||
vec3 old_hsv = rgbToHsv(col.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
float saturation = mask * 2.1;
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
@ -29,13 +30,5 @@ void main()
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz * color.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
o_diffuse_color = vec4((final_color * custom_alpha), custom_alpha);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (col.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
@ -28,17 +28,10 @@ void main(void)
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_2 = sampleTextureSlot2(uv);
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(normal)) + 0.5;
|
||||
o_normal_depth.z = layer_2.x;
|
||||
o_gloss_map = 0.1 * layer_2.yz;
|
||||
|
@ -16,14 +16,15 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (hue_change > 0.0)
|
||||
{
|
||||
float mask = col.a;
|
||||
vec3 old_hsv = rgbToHsv(col.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
float saturation = mask * 2.1;
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
@ -34,17 +35,10 @@ void main()
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz * color.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_3 = sampleTextureSlot3(uv);
|
||||
vec4 layer_3 = sampleTextureLayer3(uv);
|
||||
vec3 tangent_space_normal = 2.0 * layer_3.xyz - 1.0;
|
||||
vec3 frag_tangent = normalize(tangent);
|
||||
vec3 frag_bitangent = normalize(bitangent);
|
||||
@ -52,7 +46,7 @@ void main()
|
||||
mat3 t_b_n = mat3(frag_tangent, frag_bitangent, frag_normal);
|
||||
vec3 world_normal = t_b_n * tangent_space_normal;
|
||||
|
||||
vec4 layer_2 = sampleTextureSlot2(uv);
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(world_normal)) + 0.5;
|
||||
o_normal_depth.z = layer_2.x;
|
||||
o_gloss_map = layer_2.yz;
|
||||
|
@ -5,7 +5,7 @@ out vec4 o_frag_color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (col.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
|
@ -14,14 +14,15 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (hue_change > 0.0)
|
||||
{
|
||||
float mask = col.a;
|
||||
vec3 old_hsv = rgbToHsv(col.rgb);
|
||||
float mask_step = step(mask, 0.5);
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
float saturation = mask * 2.1;
|
||||
// For similar color
|
||||
float saturation = mask * 1.825; // 2.5 * 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
float saturation = mask * 2.5;
|
||||
#endif
|
||||
@ -32,17 +33,10 @@ void main(void)
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz * color.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
vec4 layer_2 = sampleTextureSlot2(uv);
|
||||
vec4 layer_2 = sampleTextureLayer2(uv);
|
||||
o_normal_depth.xy = 0.5 * EncodeNormal(normalize(normal)) + 0.5;
|
||||
o_normal_depth.z = layer_2.x;
|
||||
o_gloss_map = layer_2.yz;
|
||||
|
@ -9,7 +9,7 @@ out vec4 o_diffuse_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 diffusecolor = sampleTextureSlot0(uv);
|
||||
vec4 diffusecolor = sampleTextureLayer0(uv);
|
||||
vec4 finalcolor = vec4(0.);
|
||||
if (fog_enabled == 0)
|
||||
{
|
||||
|
@ -11,20 +11,13 @@ layout(location = 2) out vec2 o_gloss_map;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = sampleTextureSlot0(uv);
|
||||
vec4 col = sampleTextureLayer0(uv);
|
||||
if (col.a < 0.5)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 final_color = col.xyz * color.xyz;
|
||||
#if !defined(Advanced_Lighting_Enabled)
|
||||
#if !defined(sRGB_Framebuffer_Usable)
|
||||
final_color = final_color * 0.73; // 0.5 ^ (1. / 2.2)
|
||||
#else
|
||||
final_color = final_color * 0.5;
|
||||
#endif
|
||||
#endif
|
||||
o_diffuse_color = vec4(final_color, 1.0);
|
||||
|
||||
#if defined(Advanced_Lighting_Enabled)
|
||||
|
135
data/shaders/sps_0_solid.xml
Normal file
135
data/shaders/sps_0_solid.xml
Normal file
@ -0,0 +1,135 @@
|
||||
<spshader>
|
||||
<!--
|
||||
Notice: boolean Y or N here is case-sensitive
|
||||
|
||||
name: The name of the shader (cannot be empty), you have to make sure
|
||||
no duplicated name will be introduced, and "_skinned" word is
|
||||
reserved for automatic skinned mesh shader adding.
|
||||
|
||||
fallback-shader: The name of the shader to be used when advanced
|
||||
lighting is off, make sure that shader is loaded first
|
||||
(default is empty). STK will load list of sps*.xml
|
||||
files in ascending order from a directory.
|
||||
|
||||
transparent: If Y, than this shader will be used in transparent pass
|
||||
(default N).
|
||||
|
||||
drawing-priority: The larger this number, the later the meshes using
|
||||
this shader will be drawn. Only useful in transparent
|
||||
shader where drawing order matters because of alpha
|
||||
blending (default 0 which means order doesn't
|
||||
matter).
|
||||
|
||||
use-alpha-channel: If Y, this shader is going to access alpha channel
|
||||
from mesh texture layers. It's used to hint STK not
|
||||
to encode colorization mask for this material using
|
||||
this shader which it will overwrite the alpha
|
||||
channel (default N).
|
||||
|
||||
use-tangents: If Y, than meshes using this shader will have tangents
|
||||
and bitangents defined and you can access them in shader
|
||||
(default N).
|
||||
|
||||
srgb: Sample mesh texture layers in srgb or not (in 6 Ys / Ns), when
|
||||
advanced lighting is off, srgb will always be false,
|
||||
default (Y Y N N N N), even if any texture layer is unused in
|
||||
shader, you cannot skip it from the above Y / N array.
|
||||
|
||||
You can only specific 1st and shadow pass of shader in .xml
|
||||
-->
|
||||
<shader-info name="solid" fallback-shader="" transparent="N"
|
||||
drawing-priority="0" use-alpha-channel="N" use-tangents="N"
|
||||
srgb="Y Y N N N N"/>
|
||||
<!--
|
||||
use-function: Specify function to be run before drawing meshes with
|
||||
this shader:
|
||||
|
||||
alphaBlendUse will be suitable for drawing alpha blend material.
|
||||
|
||||
additiveUse will be suitable for drawing additive material.
|
||||
|
||||
ghostUse will be suitable for drawing object with translucent
|
||||
effect with face culling and depth buffer writing on.
|
||||
|
||||
unuse-function: Specify function to be run after drawing meshes with
|
||||
this shader (none at the moment).
|
||||
|
||||
vertex-shader: Specify the vertex shader, it will search in the
|
||||
directory of the location of this xml file first, if not
|
||||
found it will search in the official shader directory.
|
||||
Notice: if you use #stk_include in your shader file, STK
|
||||
will only search the include header in official shader
|
||||
directory.
|
||||
|
||||
fragment-shader: Specify the fragment shader, searching rule is the
|
||||
same as above.
|
||||
|
||||
skinned-mesh-shader: Specify the skinned mesh version of the vertex
|
||||
shader, searching rule is the same as above. You
|
||||
have to make sure the uniforms and the textures
|
||||
used in both skinned mesh / non-skinned mesh
|
||||
shader are the same.
|
||||
-->
|
||||
<first-pass use-function="" unuse-function="" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_solid.frag" skinned-mesh-shader="sp_skinning.vert">
|
||||
<prefilled-textures>
|
||||
<!--
|
||||
prefilled-textures: Define the prefilled textures used in
|
||||
shaders, they will be the same for all
|
||||
meshes drawn using this shader.
|
||||
|
||||
name: Name of the texture used in shader (cannot be empty).
|
||||
|
||||
file: Filename of the texture, it will search using the order
|
||||
in pushed texture searching directory
|
||||
(cannot be empty).
|
||||
|
||||
srgb: Sample in srgb or not (specify in Y/N, default is N).
|
||||
When advanced lighting is off, srgb will always be
|
||||
false.
|
||||
|
||||
sampler: nearest, nearest_clamped, bilinear,
|
||||
bilinear_clamped, trilinear, trilinear_clamped
|
||||
and semi_trilinear are possible right now, default
|
||||
is trilinear.
|
||||
Example:
|
||||
<prefilled-texture name="name_used_in_shader" file="texture.png"
|
||||
srgb="Y" sampler="trilinear"/>-->
|
||||
</prefilled-textures>
|
||||
</first-pass>
|
||||
<shadow-pass use-function="" unuse-function=""
|
||||
vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<!--
|
||||
uniforms: Define the uniforms in shader with the name of the
|
||||
type (int, float, mat4, vec4, vec3, vec2).
|
||||
-->
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<!--
|
||||
uniform-assigners: List of uniform assigners functions to be auto-run
|
||||
when "use" the shader which set the above uniforms,
|
||||
currently there are:
|
||||
|
||||
shadowCascadeUniformAssigner will set the current shadow
|
||||
cascade being drawn.
|
||||
|
||||
windDirectionUniformAssigner will set the wind direction.
|
||||
|
||||
zeroAlphaUniformAssigner should be used in transparent shader.
|
||||
|
||||
fogUniformAssigner will set 0 / 1 if fog is enabled in track.
|
||||
|
||||
ghostAlphaUniformAssigner will set ghost (kart) color based on sun
|
||||
color of track.
|
||||
|
||||
You have to specify the uniform name in shader together with the
|
||||
bundled uniform-assigners.
|
||||
-->
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
18
data/shaders/sps_1_normalmap.xml
Normal file
18
data/shaders/sps_1_normalmap.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<spshader>
|
||||
<shader-info name="normalmap" fallback-shader="solid" use-tangents="Y"/>
|
||||
<first-pass vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_normal_map.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
18
data/shaders/sps_2_alphatest.xml
Normal file
18
data/shaders/sps_2_alphatest.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<spshader>
|
||||
<shader-info name="alphatest" use-alpha-channel="Y"/>
|
||||
<first-pass vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_alpha_test.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
16
data/shaders/sps_3_decal.xml
Normal file
16
data/shaders/sps_3_decal.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<spshader>
|
||||
<shader-info name="decal"/>
|
||||
<first-pass vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_decal.frag" skinned-mesh-shader="sp_skinning.vert">
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_shadow.vert" fragment-shader="white.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
22
data/shaders/sps_4_grass.xml
Normal file
22
data/shaders/sps_4_grass.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<spshader>
|
||||
<shader-info name="grass" use-alpha-channel="Y"/>
|
||||
<first-pass vertex-shader="sp_grass_pass.vert"
|
||||
fragment-shader="sp_grass.frag">
|
||||
<uniforms>
|
||||
<uniform name="wind_direction" type="vec3"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_grass_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag">
|
||||
<uniforms>
|
||||
<uniform name="wind_direction" type="vec3"/>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
<uniform-assigner name="wind_direction"
|
||||
function="windDirectionUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
17
data/shaders/sps_5_unlit.xml
Normal file
17
data/shaders/sps_5_unlit.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<spshader>
|
||||
<shader-info name="unlit" fallback-shader="alphatest" use-alpha-channel="Y"/>
|
||||
<first-pass vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_unlit.frag" skinned-mesh-shader="sp_skinning.vert">
|
||||
</first-pass>
|
||||
<shadow-pass vertex-shader="sp_shadow.vert"
|
||||
fragment-shader="sp_shadow_alpha_test.frag"
|
||||
skinned-mesh-shader="sp_skinning_shadow.vert">
|
||||
<uniforms>
|
||||
<uniform name="layer" type="int"/>
|
||||
</uniforms>
|
||||
</shadow-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="layer"
|
||||
function="shadowCascadeUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
17
data/shaders/sps_6_alphablend.xml
Normal file
17
data/shaders/sps_6_alphablend.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<spshader>
|
||||
<shader-info name="alphablend" transparent="Y" use-alpha-channel="Y"/>
|
||||
<first-pass use-function="alphaBlendUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_transparent.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="fog_enabled" type="int"/>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="fog_enabled"
|
||||
function="fogUniformAssigner"/>
|
||||
<uniform-assigner name="custom_alpha"
|
||||
function="zeroAlphaUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
17
data/shaders/sps_7_additive.xml
Normal file
17
data/shaders/sps_7_additive.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<spshader>
|
||||
<shader-info name="additive" transparent="Y" use-alpha-channel="Y"/>
|
||||
<first-pass use-function="additiveUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_transparent.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="fog_enabled" type="int"/>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="fog_enabled"
|
||||
function="fogUniformAssigner"/>
|
||||
<uniform-assigner name="custom_alpha"
|
||||
function="zeroAlphaUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
14
data/shaders/sps_8_ghost.xml
Normal file
14
data/shaders/sps_8_ghost.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<spshader>
|
||||
<shader-info name="ghost" transparent="Y" drawing-priority="900"/>
|
||||
<first-pass use-function="ghostUse" vertex-shader="sp_pass.vert"
|
||||
fragment-shader="sp_ghost.frag"
|
||||
skinned-mesh-shader="sp_skinning.vert">
|
||||
<uniforms>
|
||||
<uniform name="custom_alpha" type="float"/>
|
||||
</uniforms>
|
||||
</first-pass>
|
||||
<uniform-assigners>
|
||||
<uniform-assigner name="custom_alpha"
|
||||
function="ghostAlphaUniformAssigner"/>
|
||||
</uniform-assigners>
|
||||
</spshader>
|
@ -1,9 +1,9 @@
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(tex, uv);
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 uv;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(tex, uv);
|
||||
}
|
@ -13,10 +13,6 @@ void main()
|
||||
|
||||
// Uncharted2 tonemap with Auria's custom coefficients
|
||||
vec4 perChannel = (col * (6.9 * col + .5)) / (col * (5.2 * col + 1.7) + 0.06);
|
||||
#if !(!defined(sRGB_Framebuffer_Usable) && defined(Advanced_Lighting_Enabled))
|
||||
perChannel = pow(perChannel, vec4(2.2));
|
||||
#endif
|
||||
|
||||
vec2 inside = uv - 0.5;
|
||||
float vignette = 1. - dot(inside, inside) * vignette_weight;
|
||||
vignette = clamp(pow(vignette, 0.8), 0., 1.);
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Wrapper to allow easy sampling for material texture slots
|
||||
// Wrapper to allow easy sampling for material texture layers
|
||||
uniform sampler2D tex_layer_0;
|
||||
uniform sampler2D tex_layer_1;
|
||||
uniform sampler2D tex_layer_2;
|
||||
@ -6,32 +6,32 @@ uniform sampler2D tex_layer_3;
|
||||
uniform sampler2D tex_layer_4;
|
||||
uniform sampler2D tex_layer_5;
|
||||
|
||||
vec4 sampleTextureSlot0(vec2 uv)
|
||||
vec4 sampleTextureLayer0(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_0, uv);
|
||||
}
|
||||
|
||||
vec4 sampleTextureSlot1(vec2 uv)
|
||||
vec4 sampleTextureLayer1(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_1, uv);
|
||||
}
|
||||
|
||||
vec4 sampleTextureSlot2(vec2 uv)
|
||||
vec4 sampleTextureLayer2(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_2, uv);
|
||||
}
|
||||
|
||||
vec4 sampleTextureSlot3(vec2 uv)
|
||||
vec4 sampleTextureLayer3(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_3, uv);
|
||||
}
|
||||
|
||||
vec4 sampleTextureSlot4(vec2 uv)
|
||||
vec4 sampleTextureLayer4(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_4, uv);
|
||||
}
|
||||
|
||||
vec4 sampleTextureSlot5(vec2 uv)
|
||||
vec4 sampleTextureLayer5(vec2 uv)
|
||||
{
|
||||
return texture(tex_layer_5, uv);
|
||||
}
|
||||
|
@ -286,6 +286,7 @@ bool CIrrDeviceLinux::restoreResolution()
|
||||
XRROutputInfo* output = XRRGetOutputInfo(display, res, output_id);
|
||||
if (!output || !output->crtc || output->connection == RR_Disconnected)
|
||||
{
|
||||
XRRFreeScreenResources(res);
|
||||
XRRFreeOutputInfo(output);
|
||||
return false;
|
||||
}
|
||||
@ -293,6 +294,7 @@ bool CIrrDeviceLinux::restoreResolution()
|
||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo(display, res, output->crtc);
|
||||
if (!crtc)
|
||||
{
|
||||
XRRFreeScreenResources(res);
|
||||
XRRFreeOutputInfo(output);
|
||||
return false;
|
||||
}
|
||||
@ -946,6 +948,8 @@ bool CIrrDeviceLinux::createWindow()
|
||||
ButtonPressMask | KeyPressMask |
|
||||
ButtonReleaseMask | KeyReleaseMask;
|
||||
|
||||
bool netWM = false;
|
||||
|
||||
Atom *list;
|
||||
Atom type;
|
||||
int form;
|
||||
@ -956,8 +960,13 @@ bool CIrrDeviceLinux::createWindow()
|
||||
WMCheck, 0L, 1L, False, XA_WINDOW,
|
||||
&type, &form, &len, &remain,
|
||||
(unsigned char **)&list);
|
||||
XFree(list);
|
||||
bool netWM = (s == Success) && len;
|
||||
|
||||
|
||||
if (s == Success)
|
||||
{
|
||||
XFree(list);
|
||||
netWM = (len > 0);
|
||||
}
|
||||
|
||||
if (!CreationParams.WindowId)
|
||||
{
|
||||
@ -1014,17 +1023,15 @@ bool CIrrDeviceLinux::createWindow()
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long numItems, bytesAfter;
|
||||
unsigned char* data = NULL;
|
||||
Atom* atoms = NULL;
|
||||
|
||||
int s = XGetWindowProperty(display, window, WMStateAtom,
|
||||
0l, 1024, False, XA_ATOM, &type,
|
||||
&format, &numItems, &bytesAfter,
|
||||
&data);
|
||||
(unsigned char**)&atoms);
|
||||
|
||||
if (s == Success)
|
||||
{
|
||||
Atom* atoms = (Atom*)data;
|
||||
|
||||
for (unsigned int i = 0; i < numItems; ++i)
|
||||
{
|
||||
if (atoms[i] == WMFullscreenAtom)
|
||||
@ -1033,9 +1040,9 @@ bool CIrrDeviceLinux::createWindow()
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XFree(data);
|
||||
XFree(atoms);
|
||||
}
|
||||
|
||||
if (fullscreen == true)
|
||||
break;
|
||||
@ -1770,13 +1777,20 @@ bool CIrrDeviceLinux::run()
|
||||
|
||||
case ClientMessage:
|
||||
{
|
||||
char *atom = XGetAtomName(display, event.xclient.message_type);
|
||||
if (*atom == *wmDeleteWindow)
|
||||
char* atom = XGetAtomName(display, event.xclient.message_type);
|
||||
|
||||
if (atom != NULL)
|
||||
{
|
||||
os::Printer::log("Quit message received.", ELL_INFORMATION);
|
||||
Close = true;
|
||||
if (strcmp(atom, "WM_PROTOCOLS") == 0)
|
||||
{
|
||||
os::Printer::log("Quit message received.", ELL_INFORMATION);
|
||||
Close = true;
|
||||
}
|
||||
|
||||
XFree(atom);
|
||||
}
|
||||
else
|
||||
|
||||
if (!Close)
|
||||
{
|
||||
// we assume it's a user message
|
||||
irrevent.EventType = irr::EET_USER_EVENT;
|
||||
@ -1784,7 +1798,6 @@ bool CIrrDeviceLinux::run()
|
||||
irrevent.UserEvent.UserData2 = (s32)event.xclient.data.l[1];
|
||||
postEventFromUser(irrevent);
|
||||
}
|
||||
XFree(atom);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2808,9 +2821,11 @@ const c8* CIrrDeviceLinux::getTextFromClipboard() const
|
||||
&numItems, &dummy, &data);
|
||||
|
||||
if (result == Success)
|
||||
{
|
||||
Clipboard = (irr::c8*)data;
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
XFree (data);
|
||||
return Clipboard.c_str();
|
||||
#else
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -247,19 +247,19 @@ void CPUParticleManager::drawAll()
|
||||
[](const std::pair<Material*, std::string>& a,
|
||||
const std::pair<Material*, std::string>& b)->bool
|
||||
{
|
||||
return a.first->getShaderType() > b.first->getShaderType();
|
||||
return a.first->getShaderName() > b.first->getShaderName();
|
||||
});
|
||||
|
||||
Material::ShaderType st = Material::SHADERTYPE_COUNT;
|
||||
std::string shader_name;
|
||||
for (auto& p : particle_drawn)
|
||||
{
|
||||
const bool flips = isFlipsMaterial(p.second);
|
||||
const float billboard = p.second.substr(0, 4) == "_bb_" ? 1.0f : 0.0f;
|
||||
Material* cur_mat = p.first;
|
||||
if (cur_mat->getShaderType() != st)
|
||||
if (cur_mat->getShaderName() != shader_name)
|
||||
{
|
||||
st = cur_mat->getShaderType();
|
||||
if (cur_mat->getShaderType() == Material::SHADERTYPE_ADDITIVE)
|
||||
shader_name = cur_mat->getShaderName();
|
||||
if (cur_mat->getShaderName() == "additive")
|
||||
{
|
||||
ParticleRenderer::getInstance()->use();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -270,8 +270,7 @@ void CPUParticleManager::drawAll()
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
}
|
||||
else if (cur_mat
|
||||
->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND)
|
||||
else if (cur_mat->getShaderName() == "alphablend")
|
||||
{
|
||||
ParticleRenderer::getInstance()->use();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -293,8 +292,8 @@ void CPUParticleManager::drawAll()
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_mat->getShaderType() == Material::SHADERTYPE_ADDITIVE ||
|
||||
cur_mat->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND)
|
||||
if (cur_mat->getShaderName() == "additive" ||
|
||||
cur_mat->getShaderName() == "alphablend")
|
||||
{
|
||||
ParticleRenderer::getInstance()->setTextureUnits
|
||||
(cur_mat->getTexture()->getOpenGLTextureName(),
|
||||
|
@ -145,13 +145,6 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
|
||||
if (LODNode *node = dynamic_cast<LODNode *>(*I))
|
||||
{
|
||||
node->updateVisibility();
|
||||
if (SP::sp_first_frame)
|
||||
{
|
||||
for (auto* child_node : node->getAllNodes())
|
||||
{
|
||||
child_node->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
(*I)->updateAbsolutePosition();
|
||||
if (!(*I)->isVisible())
|
||||
@ -159,8 +152,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
|
||||
|
||||
if (STKParticle *node = dynamic_cast<STKParticle*>(*I))
|
||||
{
|
||||
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) ||
|
||||
SP::sp_first_frame)
|
||||
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()))
|
||||
CPUParticleManager::getInstance()->addParticleNode(node);
|
||||
continue;
|
||||
}
|
||||
@ -168,7 +160,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
|
||||
if (scene::IBillboardSceneNode *node =
|
||||
dynamic_cast<scene::IBillboardSceneNode*>(*I))
|
||||
{
|
||||
if (!isCulledPrecise(cam, *I) || SP::sp_first_frame)
|
||||
if (!isCulledPrecise(cam, *I))
|
||||
CPUParticleManager::getInstance()->addBillboardNode(node);
|
||||
continue;
|
||||
}
|
||||
@ -176,8 +168,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
|
||||
if (STKTextBillboard *tb =
|
||||
dynamic_cast<STKTextBillboard*>(*I))
|
||||
{
|
||||
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) ||
|
||||
SP::sp_first_frame)
|
||||
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()))
|
||||
TextBillboardDrawer::addTextBillboard(tb);
|
||||
continue;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace GraphicsRestrictions
|
||||
/** The list of names used in the XML file for the graphics
|
||||
* restriction types. They must be in the same order as the types. */
|
||||
|
||||
std::array<std::string, 29> m_names_of_restrictions =
|
||||
std::array<std::string, 30> m_names_of_restrictions =
|
||||
{
|
||||
{
|
||||
"UniformBufferObject",
|
||||
@ -75,7 +75,8 @@ namespace GraphicsRestrictions
|
||||
"GI",
|
||||
"ForceLegacyDevice",
|
||||
"VertexIdWorking",
|
||||
"HardwareSkinning"
|
||||
"HardwareSkinning",
|
||||
"NpotTextures"
|
||||
}
|
||||
};
|
||||
} // namespace Private
|
||||
|
@ -63,6 +63,7 @@ namespace GraphicsRestrictions
|
||||
GR_FORCE_LEGACY_DEVICE,
|
||||
GR_VERTEX_ID_WORKING,
|
||||
GR_HARDWARE_SKINNING,
|
||||
GR_NPOT_TEXTURES,
|
||||
GR_COUNT /** MUST be last entry. */
|
||||
} ;
|
||||
|
||||
|
@ -1015,35 +1015,15 @@ void IrrDriver::setAllMaterialFlags(scene::IMesh *mesh) const
|
||||
{
|
||||
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
|
||||
video::SMaterial &irr_material = mb->getMaterial();
|
||||
|
||||
// special case : for splatting, the main material is on layer 1.
|
||||
// it was done this way to provide a fallback for computers
|
||||
// where shaders are not supported
|
||||
video::ITexture* t2 = irr_material.getTexture(1);
|
||||
bool is_splatting = false;
|
||||
if (t2)
|
||||
video::ITexture* t = irr_material.getTexture(0);
|
||||
if (t)
|
||||
{
|
||||
Material* mat = material_manager->getMaterialFor(t2, mb);
|
||||
if (mat != NULL && mat->getShaderType() == Material::SHADERTYPE_SPLATTING)
|
||||
{
|
||||
material_manager->setAllMaterialFlags(t2, mb);
|
||||
is_splatting = true;
|
||||
}
|
||||
material_manager->setAllMaterialFlags(t, mb);
|
||||
}
|
||||
|
||||
if (!is_splatting)
|
||||
else
|
||||
{
|
||||
video::ITexture* t = irr_material.getTexture(0);
|
||||
if (t)
|
||||
{
|
||||
material_manager->setAllMaterialFlags(t, mb);
|
||||
}
|
||||
else
|
||||
{
|
||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||
}
|
||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||
}
|
||||
|
||||
} // for i<getMeshBufferCount()
|
||||
} // setAllMaterialFlags
|
||||
|
||||
@ -1209,17 +1189,17 @@ scene::ISceneNode *IrrDriver::addBillboard(const core::dimension2d< f32 > size,
|
||||
/*strip_path*/full_path, /*install*/false);
|
||||
|
||||
video::ITexture* tex = m->getTexture(true/*srgb*/,
|
||||
m->getShaderType() == Material::SHADERTYPE_ADDITIVE ||
|
||||
m->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND ?
|
||||
m->getShaderName() == "additive" ||
|
||||
m->getShaderName() == "alphablend" ?
|
||||
true : false/*premul_alpha*/);
|
||||
|
||||
assert(node->getMaterialCount() > 0);
|
||||
node->setMaterialTexture(0, tex);
|
||||
if (!(m->getShaderType() == Material::SHADERTYPE_ADDITIVE ||
|
||||
m->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND))
|
||||
if (!(m->getShaderName() == "additive" ||
|
||||
m->getShaderName() == "alphablend"))
|
||||
{
|
||||
// Alpha test for billboard otherwise
|
||||
m->setShaderType(Material::SHADERTYPE_ALPHA_TEST);
|
||||
m->setShaderName("alphatest");
|
||||
}
|
||||
m->setMaterialProperties(&(node->getMaterial(0)), NULL);
|
||||
return node;
|
||||
@ -1929,16 +1909,6 @@ bool IrrDriver::OnEvent(const irr::SEvent &event)
|
||||
return false;
|
||||
} // OnEvent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool IrrDriver::supportsSplatting()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
return CVS->isGLSL();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
} // supportsSplatting
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos,
|
||||
float energy, float radius,
|
||||
|
@ -289,7 +289,6 @@ public:
|
||||
core::position2di getMouseLocation();
|
||||
|
||||
void printRenderStats();
|
||||
bool supportsSplatting();
|
||||
void requestScreenshot();
|
||||
class GPUTimer &getGPUTimer(unsigned);
|
||||
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
|
||||
@ -196,19 +194,6 @@ void LODNode::OnRegisterSceneNode()
|
||||
assert(node != NULL);
|
||||
mesh = node->getMesh();
|
||||
}
|
||||
|
||||
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
|
||||
video::ITexture* t = mb->getMaterial().getTexture(0);
|
||||
if (t == NULL) continue;
|
||||
|
||||
Material* m = material_manager->getMaterialFor(t, mb);
|
||||
if (m != NULL)
|
||||
{
|
||||
m->onMadeVisible(mb);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_previous_visibility == WAS_SHOWN && !shown)
|
||||
{
|
||||
@ -228,17 +213,6 @@ void LODNode::OnRegisterSceneNode()
|
||||
mesh = node->getMesh();
|
||||
}
|
||||
|
||||
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
|
||||
video::ITexture* t = mb->getMaterial().getTexture(0);
|
||||
if (t == NULL) continue;
|
||||
Material* m = material_manager->getMaterialFor(t, mb);
|
||||
if (m != NULL)
|
||||
{
|
||||
m->onHidden(mb);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_previous_visibility == FIRST_PASS && !shown)
|
||||
{
|
||||
@ -257,18 +231,6 @@ void LODNode::OnRegisterSceneNode()
|
||||
assert(node != NULL);
|
||||
mesh = node->getMesh();
|
||||
}
|
||||
|
||||
for (unsigned int n=0; n<mesh->getMeshBufferCount(); n++)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(n);
|
||||
video::ITexture* t = mb->getMaterial().getTexture(0);
|
||||
if(!t) continue;
|
||||
Material* m = material_manager->getMaterialFor(t, mb);
|
||||
if (m != NULL)
|
||||
{
|
||||
m->isInitiallyHidden(mb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,6 @@ const unsigned int VCLAMP = 2;
|
||||
Material::Material(const XMLNode *node, bool deprecated)
|
||||
{
|
||||
m_shader_name = "solid";
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
m_deprecated = deprecated;
|
||||
m_installed = false;
|
||||
|
||||
@ -154,12 +153,9 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
|
||||
node->get("max-speed", &m_max_speed_fraction );
|
||||
node->get("slowdown-time", &m_slowdown_time );
|
||||
node->get("backface-culling", &m_backface_culling );
|
||||
node->get("disable-z-write", &m_disable_z_write );
|
||||
node->get("colorizable", &m_colorizable );
|
||||
node->get("colorization-factor", &m_colorization_factor);
|
||||
node->get("hue-settings", &m_hue_settings );
|
||||
node->get("fog", &m_fog );
|
||||
|
||||
node->get("mask", &m_mask );
|
||||
node->get("colorization-mask", &m_colorization_mask );
|
||||
@ -195,50 +191,7 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
s = "solid";
|
||||
std::string normal_map_tex;
|
||||
node->get("normal-map", &normal_map_tex);
|
||||
if (node->get("shader", &s))
|
||||
{
|
||||
if (s == "solid")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
}
|
||||
else if (s == "unlit")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID_UNLIT;
|
||||
}
|
||||
else if (s == "additive")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
}
|
||||
else if (s == "alphatest")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
else if (s == "alphablend")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
}
|
||||
else if (s == "spheremap")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
else if (s == "water_shader")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
}
|
||||
else if (s == "grass")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_VEGETATION;
|
||||
}
|
||||
else if (s == "splatting")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPLATTING;
|
||||
node->get("splatting-texture-1", &m_sampler_path[2]);
|
||||
node->get("splatting-texture-2", &m_sampler_path[3]);
|
||||
node->get("splatting-texture-3", &m_sampler_path[4]);
|
||||
node->get("splatting-texture-4", &m_sampler_path[5]);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!node->get("shader", &s))
|
||||
{
|
||||
// BACKWARS COMPATIBILITY, EVENTUALLY REMOVE
|
||||
|
||||
@ -247,7 +200,6 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
if (b)
|
||||
{
|
||||
m_shader_name = "alphablend";
|
||||
m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
}
|
||||
|
||||
b = false;
|
||||
@ -255,7 +207,6 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
if (b)
|
||||
{
|
||||
m_shader_name = "alphatest";
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
|
||||
//node->get("lightmap", &m_lightmap);
|
||||
@ -265,7 +216,6 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
if (b)
|
||||
{
|
||||
m_shader_name = "alphablend";
|
||||
m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
}
|
||||
|
||||
b = true;
|
||||
@ -273,36 +223,24 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
if (!b)
|
||||
{
|
||||
m_shader_name = "unlit";
|
||||
m_shader_type = SHADERTYPE_SOLID_UNLIT;
|
||||
}
|
||||
|
||||
b = false;
|
||||
node->get("smooth-reflection", &b);
|
||||
if (b)
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
|
||||
|
||||
if (node->get("compositing", &s))
|
||||
{
|
||||
if (s == "blend")
|
||||
{
|
||||
m_shader_name = "alphablend";
|
||||
m_shader_type = SHADERTYPE_ALPHA_BLEND;
|
||||
}
|
||||
else if (s == "test")
|
||||
{
|
||||
m_shader_name = "alphatest";
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
else if (s == "additive")
|
||||
{
|
||||
m_shader_name = "additive";
|
||||
m_shader_type = SHADERTYPE_ADDITIVE;
|
||||
}
|
||||
else if (s == "coverage")
|
||||
{
|
||||
m_shader_name = "alphatest";
|
||||
m_shader_type = SHADERTYPE_ALPHA_TEST;
|
||||
}
|
||||
else if (s != "none")
|
||||
Log::warn("material", "Unknown compositing mode '%s'", s.c_str());
|
||||
@ -311,31 +249,10 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
s = "";
|
||||
node->get("graphical-effect", &s);
|
||||
|
||||
if (s == "grass")
|
||||
if (s == "normal_map")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_VEGETATION;
|
||||
}
|
||||
else if (s == "water_shader")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
}
|
||||
else if (s == "normal_map")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
node->get("normal-map", &normal_map_tex);
|
||||
}
|
||||
else if (s == "spheremap")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
else if (s == "splatting")
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPLATTING;
|
||||
node->get("splatting-texture-1", &m_sampler_path[2]);
|
||||
node->get("splatting-texture-2", &m_sampler_path[3]);
|
||||
node->get("splatting-texture-3", &m_sampler_path[4]);
|
||||
node->get("splatting-texture-4", &m_sampler_path[5]);
|
||||
}
|
||||
else if (s == "none")
|
||||
{
|
||||
}
|
||||
@ -361,21 +278,6 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
"Could not find normal map image in materials.xml");
|
||||
}
|
||||
}
|
||||
|
||||
bool sphere_map = false;
|
||||
node->get("sphere", &sphere_map);
|
||||
if (sphere_map)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SPHERE_MAP;
|
||||
}
|
||||
|
||||
bool water_shader = false;
|
||||
node->get("water-shader", &water_shader);
|
||||
if (water_shader)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_WATER;
|
||||
}
|
||||
|
||||
// ---- End backwards compatibility
|
||||
}
|
||||
|
||||
@ -434,29 +336,12 @@ Material::Material(const XMLNode *node, bool deprecated)
|
||||
m_sampler_path[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (ProfileWorld::isNoGraphics() || !CVS->isDefferedEnabled())
|
||||
{
|
||||
for (int i = 2; i < 6; i++)
|
||||
{
|
||||
// When advanced pipeline is off only .spm uv textures are used
|
||||
m_sampler_path[i] = "";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
loadContainerId();
|
||||
|
||||
core::stringc texfname(m_texname.c_str());
|
||||
texfname.make_lower();
|
||||
m_texname = texfname.c_str();
|
||||
|
||||
if (m_disable_z_write && m_shader_type != SHADERTYPE_ALPHA_BLEND && m_shader_type != SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
Log::debug("material", "Disabling writes to z buffer only makes sense when compositing is blending or additive (for %s)", m_texname.c_str());
|
||||
m_disable_z_write = false;
|
||||
}
|
||||
|
||||
// Terrain-specifc sound effect
|
||||
const unsigned int children_count = node->getNumNodes();
|
||||
for (unsigned int i=0; i<children_count; i++)
|
||||
@ -519,7 +404,7 @@ void Material::loadContainerId()
|
||||
if (!file_manager->searchTextureContainerId(m_container_id, m_texname))
|
||||
{
|
||||
Log::warn("Material", "Missing container id for %s, no texture"
|
||||
" compression for it will be done", m_texname.c_str());
|
||||
" compression for it will be done.", m_texname.c_str());
|
||||
}
|
||||
}
|
||||
} // loadContainerId
|
||||
@ -587,8 +472,6 @@ void Material::init()
|
||||
{
|
||||
m_texture = NULL;
|
||||
m_clamp_tex = 0;
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
m_backface_culling = true;
|
||||
m_high_tire_adhesion = false;
|
||||
m_below_surface = false;
|
||||
m_falling_effect = false;
|
||||
@ -597,11 +480,9 @@ void Material::init()
|
||||
m_drive_reset = false;
|
||||
m_mirror_axis_when_reverse = ' ';
|
||||
m_collision_reaction = NORMAL;
|
||||
m_disable_z_write = false;
|
||||
m_colorizable = false;
|
||||
m_colorization_factor = 0.0f;
|
||||
m_colorization_mask = "";
|
||||
m_fog = true;
|
||||
m_max_speed_fraction = 1.0f;
|
||||
m_slowdown_time = 1.0f;
|
||||
m_sfx_name = "";
|
||||
@ -878,10 +759,8 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m_texname.c_str());
|
||||
}
|
||||
|
||||
// Backface culling
|
||||
if(!m_backface_culling)
|
||||
m->setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||
|
||||
// Default solid
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
if (race_manager->getReverseTrack() &&
|
||||
m_mirror_axis_when_reverse != ' ')
|
||||
{
|
||||
@ -900,20 +779,19 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
} // reverse track and texture needs mirroring
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID_UNLIT)
|
||||
if (m_shader_name == "unlit")
|
||||
{
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_TEST)
|
||||
else if (m_shader_name == "alphatest")
|
||||
{
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_BLEND)
|
||||
else if (m_shader_name == "alphablend" || m_shader_name == "displace")
|
||||
{
|
||||
// EMT_TRANSPARENT_ALPHA_CHANNEL doesn't include vertex color alpha into
|
||||
// account, which messes up fading in/out effects. So we use the more
|
||||
@ -925,8 +803,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ADDITIVE)
|
||||
else if (m_shader_name == "additive")
|
||||
{
|
||||
// EMT_TRANSPARENT_ADD_COLOR doesn't include vertex color alpha into
|
||||
// account, which messes up fading in/out effects. So we use the
|
||||
@ -938,31 +815,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
video::EAS_TEXTURE |
|
||||
video::EAS_VERTEX_COLOR);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPHERE_MAP)
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPLATTING)
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
|
||||
|
||||
// Modify lightmap materials so that vertex colors are taken into account.
|
||||
// But disable lighting because we assume all lighting is already part
|
||||
// of the lightmap
|
||||
if (m->MaterialType == video::EMT_LIGHTMAP)
|
||||
{
|
||||
m->MaterialType = video::EMT_LIGHTMAP_LIGHTING;
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_VEGETATION)
|
||||
else if (m_shader_name == "grass")
|
||||
{
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
|
||||
@ -979,9 +832,10 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_disable_z_write)
|
||||
if (isTransparent())
|
||||
{
|
||||
m->ZWriteEnable = false;
|
||||
m->BackfaceCulling = false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -1039,66 +893,3 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
#endif
|
||||
|
||||
} // setMaterialProperties
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Material::adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
bool use_fog) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
// to disable fog in the new pipeline, we slightly abuse the steps :
|
||||
// moving an object into the transparent pass will make it rendered
|
||||
// above fog and thus unaffected by it
|
||||
if (use_fog && !m_fog && m_shader_type != SHADERTYPE_ALPHA_BLEND && m_shader_type != SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
//m->ZWriteEnable = true;
|
||||
//m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
//m->MaterialTypeParam =
|
||||
// pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
// video::EBF_ONE_MINUS_SRC_ALPHA,
|
||||
// video::EMFN_MODULATE_1X,
|
||||
// video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m->setFlag(video::EMF_FOG_ENABLE, m_fog && use_fog);
|
||||
|
||||
if (parent != NULL)
|
||||
parent->setMaterialFlag(video::EMF_FOG_ENABLE, m_fog && use_fog);
|
||||
}
|
||||
#endif
|
||||
} // adjustForFog
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onMadeVisible(scene::IMeshBuffer* who)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!CVS->isGLSL()) return;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Callback from LOD nodes to create some effects */
|
||||
void Material::onHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!CVS->isGLSL()) return;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Material::isInitiallyHidden(scene::IMeshBuffer* who)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!CVS->isGLSL()) return;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -46,23 +46,6 @@ class ParticleKind;
|
||||
class Material : public NoCopy
|
||||
{
|
||||
public:
|
||||
enum ShaderType
|
||||
{
|
||||
SHADERTYPE_SOLID = 0,
|
||||
SHADERTYPE_ALPHA_TEST,
|
||||
SHADERTYPE_ALPHA_BLEND,
|
||||
SHADERTYPE_ADDITIVE,
|
||||
SHADERTYPE_SOLID_UNLIT,
|
||||
/** Effect that makes grass wave as in the wind */
|
||||
SHADERTYPE_VEGETATION,
|
||||
SHADERTYPE_WATER,
|
||||
SHADERTYPE_SPHERE_MAP,
|
||||
SHADERTYPE_NORMAL_MAP,
|
||||
SHADERTYPE_DETAIL_MAP,
|
||||
SHADERTYPE_SPLATTING,
|
||||
SHADERTYPE_COUNT,
|
||||
};
|
||||
|
||||
enum ParticleConditions
|
||||
{
|
||||
EMIT_ON_DRIVE = 0,
|
||||
@ -93,8 +76,6 @@ private:
|
||||
* "" if no special sfx exists. */
|
||||
std::string m_sfx_name;
|
||||
|
||||
ShaderType m_shader_type;
|
||||
|
||||
/** Either ' ' (no mirroring), 'U' or 'V' if a texture needs to be
|
||||
* mirrored when driving in reverse. Typically used for arrows indicating
|
||||
* the direction. */
|
||||
@ -135,14 +116,6 @@ private:
|
||||
* plants that a kart can just drive through. */
|
||||
bool m_ignore;
|
||||
|
||||
bool m_fog;
|
||||
|
||||
/** True if backface culliing should be enabled. */
|
||||
bool m_backface_culling;
|
||||
|
||||
/** Set to true to disable writing to the Z buffer. Usually to be used with alpha blending */
|
||||
bool m_disable_z_write;
|
||||
|
||||
/** True if the material shouldn't be "slippy" at an angle */
|
||||
bool m_high_tire_adhesion;
|
||||
|
||||
@ -250,11 +223,6 @@ public:
|
||||
|
||||
void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const;
|
||||
void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb);
|
||||
void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m,
|
||||
bool use_fog) const;
|
||||
void onMadeVisible(scene::IMeshBuffer* who);
|
||||
void onHidden(scene::IMeshBuffer* who);
|
||||
void isInitiallyHidden(scene::IMeshBuffer* who);
|
||||
|
||||
/** Returns the ITexture associated with this material. */
|
||||
video::ITexture *getTexture(bool srgb = true, bool premul_alpha = false);
|
||||
@ -276,6 +244,8 @@ public:
|
||||
*/
|
||||
float getColorizationFactor () const { return m_colorization_factor; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool hasRandomHue() const { return !m_hue_settings.empty(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a random hue when colorized.
|
||||
*/
|
||||
float getRandomHue()
|
||||
@ -306,9 +276,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
bool isTransparent () const
|
||||
{
|
||||
return m_shader_type == SHADERTYPE_ADDITIVE ||
|
||||
m_shader_type == SHADERTYPE_ALPHA_BLEND ||
|
||||
m_shader_type == SHADERTYPE_ALPHA_TEST;
|
||||
return m_shader_name == "additive" || m_shader_name == "alphablend" ||
|
||||
m_shader_name == "displace";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -334,11 +303,6 @@ public:
|
||||
/** Returns the name of a special sfx to play while a kart is on this
|
||||
* terrain. The string will be "" if no special sfx exists. */
|
||||
const std::string &getSFXName() const { return m_sfx_name; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if fog is enabled. */
|
||||
bool isFogEnabled() const { return m_fog; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Get the kind of particles that are to be used on this material,
|
||||
* in the given conditions.
|
||||
@ -380,9 +344,6 @@ public:
|
||||
* on lower speeds. A negative value indicates no minimum speed. */
|
||||
float getZipperMinSpeed() const { return m_zipper_min_speed; }
|
||||
// ------------------------------------------------------------------------
|
||||
ShaderType getShaderType() const { return m_shader_type; }
|
||||
void setShaderType(ShaderType st) { m_shader_type = st; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** True if this texture should have the U coordinates mirrored. */
|
||||
char getMirrorAxisInReverse() const { return m_mirror_axis_when_reverse; }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -391,14 +352,14 @@ public:
|
||||
const std::string& getColorizationMask() const
|
||||
{ return m_colorization_mask; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setShaderName(const std::string& name) { m_shader_name = name; }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getShaderName() const { return m_shader_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
/* This is used for finding correct material for spm*/
|
||||
const std::string& getUVTwoTexture() const
|
||||
{ return m_uv_two_tex; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool backFaceCulling() const { return m_backface_culling; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool use2UV() const { return !m_uv_two_tex.empty(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getSamplerPath(unsigned layer) const
|
||||
|
@ -220,28 +220,7 @@ Material* MaterialManager::getDefaultSPMaterial(const std::string& shader_name,
|
||||
return m;
|
||||
} // getDefaultSPMaterial
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MaterialManager::adjustForFog(video::ITexture* t,
|
||||
scene::IMeshBuffer *mb,
|
||||
scene::ISceneNode* parent,
|
||||
bool use_fog) const
|
||||
{
|
||||
const std::string image = StringUtils::getBasename(core::stringc(t->getName()).c_str());
|
||||
// Search backward so that temporary (track) textures are found first
|
||||
for(int i = (int)m_materials.size()-1; i>=0; i-- )
|
||||
{
|
||||
if (m_materials[i]->getTexFname()==image)
|
||||
{
|
||||
m_materials[i]->adjustForFog(parent, &(mb->getMaterial()), use_fog);
|
||||
return;
|
||||
}
|
||||
} // for i
|
||||
} // adjustForFog
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb)
|
||||
{
|
||||
irr::video::SMaterial& material = mb->getMaterial();
|
||||
@ -257,6 +236,7 @@ void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int MaterialManager::addEntity(Material *m)
|
||||
{
|
||||
|
@ -66,11 +66,6 @@ public:
|
||||
const std::string& def_shader_name = "solid");
|
||||
void setAllMaterialFlags(video::ITexture* t,
|
||||
scene::IMeshBuffer *mb);
|
||||
void adjustForFog(video::ITexture* t,
|
||||
scene::IMeshBuffer *mb,
|
||||
scene::ISceneNode* parent,
|
||||
bool use_fog) const;
|
||||
|
||||
void setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb);
|
||||
|
||||
int addEntity (Material *m);
|
||||
|
@ -33,6 +33,7 @@ MovingTexture::MovingTexture(core::matrix4 *matrix, const XMLNode &node)
|
||||
m_x = 0.0f;
|
||||
m_y = 0.0f;
|
||||
m_count = 0.0f;
|
||||
m_sp_tm = NULL;
|
||||
|
||||
if (m_matrix)
|
||||
{
|
||||
@ -49,8 +50,6 @@ MovingTexture::MovingTexture(core::matrix4 *matrix, const XMLNode &node)
|
||||
node.get("dt", &m_dt);
|
||||
|
||||
node.get("animByStep", &m_isAnimatedByStep);
|
||||
m_sp_tm[0].reset(new float(0.0f));
|
||||
m_sp_tm[1].reset(new float(0.0f));
|
||||
} // MovingTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -71,8 +70,8 @@ MovingTexture::MovingTexture(core::matrix4 *matrix, float dx, float dy)
|
||||
core::vector3df v = m_matrix->getTranslation();
|
||||
m_x = v.X;
|
||||
m_y = v.Y;
|
||||
m_sp_tm[0].reset(new float(0.0f));
|
||||
m_sp_tm[1].reset(new float(0.0f));
|
||||
m_count = 0.0f;
|
||||
m_sp_tm = NULL;
|
||||
} // MovingTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -85,9 +84,9 @@ MovingTexture::MovingTexture(float dx, float dy)
|
||||
m_dy = dy;
|
||||
m_x = 0;
|
||||
m_y = 0;
|
||||
m_count = 0.0f;
|
||||
m_matrix = NULL;
|
||||
m_sp_tm[0].reset(new float(0.0f));
|
||||
m_sp_tm[1].reset(new float(0.0f));
|
||||
m_sp_tm = NULL;
|
||||
} // MovingTexture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -103,12 +102,15 @@ MovingTexture::~MovingTexture()
|
||||
void MovingTexture::reset()
|
||||
{
|
||||
m_x = m_y = 0;
|
||||
*m_sp_tm[0] = 0;
|
||||
*m_sp_tm[1] = 0;
|
||||
if (m_matrix)
|
||||
{
|
||||
m_matrix->setTextureTranslate(m_x, m_y);
|
||||
}
|
||||
else if (m_sp_tm)
|
||||
{
|
||||
m_sp_tm[0] = 0.0f;
|
||||
m_sp_tm[1] = 0.0f;
|
||||
}
|
||||
} // reset
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -134,10 +136,10 @@ void MovingTexture::update(float dt)
|
||||
{
|
||||
m_matrix->setTextureTranslate(m_x, m_y);
|
||||
}
|
||||
else
|
||||
else if (m_sp_tm)
|
||||
{
|
||||
*m_sp_tm[0] = m_x;
|
||||
*m_sp_tm[1] = m_y;
|
||||
m_sp_tm[0] = m_x;
|
||||
m_sp_tm[1] = m_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,10 +153,10 @@ void MovingTexture::update(float dt)
|
||||
{
|
||||
m_matrix->setTextureTranslate(m_x, m_y);
|
||||
}
|
||||
else
|
||||
else if (m_sp_tm)
|
||||
{
|
||||
*m_sp_tm[0] = m_x;
|
||||
*m_sp_tm[1] = m_y;
|
||||
m_sp_tm[0] = m_x;
|
||||
m_sp_tm[1] = m_y;
|
||||
}
|
||||
}
|
||||
} // update
|
||||
|
@ -20,8 +20,6 @@
|
||||
#define MOVING_TEXTURE_HPP
|
||||
|
||||
#include "utils/no_copy.hpp"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <matrix4.h>
|
||||
using namespace irr;
|
||||
@ -49,7 +47,7 @@ private:
|
||||
core::matrix4 *m_matrix;
|
||||
|
||||
// For sp
|
||||
std::array<std::shared_ptr<float>, 2> m_sp_tm;
|
||||
float* m_sp_tm;
|
||||
|
||||
public:
|
||||
MovingTexture(core::matrix4 *matrix, const XMLNode &node);
|
||||
@ -61,7 +59,7 @@ public:
|
||||
void setSpeed(float dx, float dy) {m_dx = dx; m_dy = dy;}
|
||||
/** Sets the texture matrix. */
|
||||
void setTextureMatrix(core::matrix4 *matrix) {m_matrix=matrix;}
|
||||
std::array<std::shared_ptr<float>, 2> getSPTM() const { return m_sp_tm; }
|
||||
void setSPTM(float* sp_tm) { m_sp_tm = sp_tm; }
|
||||
virtual void update (float dt);
|
||||
virtual void reset ();
|
||||
}
|
||||
|
@ -232,8 +232,8 @@ Material* ParticleKind::getMaterial() const
|
||||
Material* material = material_manager->getMaterial(m_material_file);
|
||||
if (material == NULL ||
|
||||
material->getTexture(true/*srgb*/,
|
||||
material->getShaderType() == Material::SHADERTYPE_ADDITIVE ||
|
||||
material->getShaderType() == Material::SHADERTYPE_ALPHA_BLEND ?
|
||||
material->getShaderName() == "additive" ||
|
||||
material->getShaderName() == "alphablend" ?
|
||||
true : false/*premul_alpha*/) == NULL)
|
||||
{
|
||||
throw std::runtime_error("[ParticleKind] Cannot locate file " + m_material_file);
|
||||
|
@ -248,9 +248,7 @@ void Referee::selectReadySetGo(int rsg)
|
||||
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_scene_node);
|
||||
if (spmn)
|
||||
{
|
||||
spmn->setTextureMatrix(m_st_traffic_buffer,
|
||||
{{ std::make_shared<float>(0.0f),
|
||||
std::make_shared<float>(rsg * 0.333f) }});
|
||||
spmn->setTextureMatrix(m_st_traffic_buffer, {{ 0.0f, rsg * 0.333f }});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -54,6 +54,7 @@ protected:
|
||||
|
||||
/** OpenGL's program id. */
|
||||
GLuint m_program;
|
||||
std::vector<std::shared_ptr<GLuint> > m_shaders;
|
||||
|
||||
// ========================================================================
|
||||
/** Ends recursion. */
|
||||
@ -67,13 +68,13 @@ protected:
|
||||
void loadAndAttachShader(GLint shader_type, const std::string &name,
|
||||
Types ... args)
|
||||
{
|
||||
GLint shader_id = ShaderFilesManager::getInstance()
|
||||
auto shader_id = ShaderFilesManager::getInstance()
|
||||
->getShaderFile(name, shader_type);
|
||||
glAttachShader(m_program, shader_id);
|
||||
GLint is_deleted = GL_TRUE;
|
||||
glGetShaderiv(shader_id, GL_DELETE_STATUS, &is_deleted);
|
||||
if (is_deleted == GL_FALSE)
|
||||
glDeleteShader(shader_id);
|
||||
if (shader_id)
|
||||
{
|
||||
m_shaders.push_back(shader_id);
|
||||
glAttachShader(m_program, *shader_id);
|
||||
}
|
||||
loadAndAttachShader(args...);
|
||||
} // loadAndAttachShader
|
||||
// ------------------------------------------------------------------------
|
||||
@ -87,6 +88,10 @@ protected:
|
||||
|
||||
public:
|
||||
ShaderBase();
|
||||
~ShaderBase()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
}
|
||||
int loadTFBProgram(const std::string &vertex_file_path,
|
||||
const char **varyings,
|
||||
unsigned varyingscount);
|
||||
@ -346,7 +351,8 @@ public:
|
||||
|
||||
GLint Result = GL_FALSE;
|
||||
glGetProgramiv(m_program, GL_LINK_STATUS, &Result);
|
||||
if (Result == GL_FALSE) {
|
||||
if (Result == GL_FALSE)
|
||||
{
|
||||
int info_length;
|
||||
Log::error("Shader", "Error when linking these shaders :");
|
||||
printFileList(args...);
|
||||
@ -356,10 +362,12 @@ public:
|
||||
Log::error("Shader", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
// After linking all shaders can be detached
|
||||
for (auto shader : m_shaders)
|
||||
{
|
||||
glDetachShader(m_program, *shader);
|
||||
}
|
||||
} // loadProgram
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void bindCustomTextures() {}
|
||||
// ------------------------------------------------------------------------
|
||||
void drawFullScreenEffect(Args...args)
|
||||
{
|
||||
|
@ -383,7 +383,7 @@ void ShaderBasedRenderer::renderSceneDeferred(scene::ICameraSceneNode * const ca
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT));
|
||||
SP::draw(SP::RP_1ST, SP::DCT_TRANSPARENT);
|
||||
SP::draw(SP::RP_2ND, SP::DCT_TRANSPARENT);
|
||||
SP::draw(SP::RP_RESERVED, SP::DCT_TRANSPARENT);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
@ -493,7 +493,7 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TRANSPARENT));
|
||||
SP::draw(SP::RP_1ST, SP::DCT_TRANSPARENT);
|
||||
SP::draw(SP::RP_2ND, SP::DCT_TRANSPARENT);
|
||||
SP::draw(SP::RP_RESERVED, SP::DCT_TRANSPARENT);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
@ -639,9 +639,9 @@ ShaderBasedRenderer::~ShaderBasedRenderer()
|
||||
delete m_spherical_harmonics;
|
||||
delete m_skybox;
|
||||
delete m_rtts;
|
||||
ShaderFilesManager::kill();
|
||||
ShaderBase::killShaders();
|
||||
SP::destroy();
|
||||
ShaderFilesManager::kill();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -886,15 +886,15 @@ void ShaderBasedRenderer::renderToTexture(GL3RenderTarget *render_target,
|
||||
if (CVS->isDefferedEnabled())
|
||||
{
|
||||
renderSceneDeferred(camera, dt, false, true);
|
||||
render_target->setFrameBuffer(m_post_processing
|
||||
->render(camera, false, m_rtts));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderScene(camera, dt, false, true);
|
||||
render_target->setFrameBuffer(&m_rtts->getFBO(FBO_COLORS));
|
||||
}
|
||||
|
||||
render_target->setFrameBuffer(m_post_processing
|
||||
->render(camera, false, m_rtts));
|
||||
|
||||
// reset
|
||||
glViewport(0, 0,
|
||||
irr_driver->getActualScreenSize().Width,
|
||||
|
@ -54,16 +54,18 @@ const std::string& ShaderFilesManager::getHeader()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ShaderFilesManager::readFile(const std::string& file,
|
||||
std::ostringstream& code)
|
||||
std::ostringstream& code, bool not_header)
|
||||
{
|
||||
std::ifstream stream(file_manager->getShader(file), std::ios::in);
|
||||
|
||||
std::ifstream stream(((file.find('/') != std::string::npos ||
|
||||
file.find('\\') != std::string::npos) && not_header) ?
|
||||
file : file_manager->getShader(file), std::ios::in);
|
||||
|
||||
if (!stream.is_open())
|
||||
{
|
||||
Log::error("ShaderFilesManager", "Can not open '%s'.", file.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const std::string stk_include = "#stk_include";
|
||||
std::string line;
|
||||
|
||||
@ -72,6 +74,7 @@ void ShaderFilesManager::readFile(const std::string& file,
|
||||
const std::size_t pos = line.find(stk_include);
|
||||
|
||||
// load the custom file pointed by the #stk_include directive
|
||||
// we only look for #stk_include in official shader directory
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
// find the start "
|
||||
@ -97,7 +100,7 @@ void ShaderFilesManager::readFile(const std::string& file,
|
||||
filename = filename.substr(0, pos);
|
||||
|
||||
// read the whole include file
|
||||
readFile(filename, code);
|
||||
readFile(filename, code, false/*not_header*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -113,9 +116,16 @@ void ShaderFilesManager::readFile(const std::string& file,
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
|
||||
ShaderFilesManager::SharedShader ShaderFilesManager::loadShader
|
||||
(const std::string& full_path, unsigned type)
|
||||
{
|
||||
const GLuint id = glCreateShader(type);
|
||||
GLuint* ss_ptr = new GLuint;
|
||||
*ss_ptr = glCreateShader(type);
|
||||
SharedShader ss(ss_ptr, [](GLuint* ss)
|
||||
{
|
||||
glDeleteShader(*ss);
|
||||
delete ss;
|
||||
});
|
||||
|
||||
std::ostringstream code;
|
||||
#if !defined(USE_GLES2)
|
||||
@ -156,7 +166,7 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
|
||||
code << "#define Converts_10bit_Vector\n";
|
||||
}
|
||||
|
||||
code << "//" << file << "\n";
|
||||
code << "//" << full_path << "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (CVS->needsVertexIdWorkaround())
|
||||
@ -191,34 +201,37 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
|
||||
|
||||
code << getHeader();
|
||||
|
||||
readFile(file, code);
|
||||
readFile(full_path, code);
|
||||
|
||||
Log::info("ShaderFilesManager", "Compiling shader : %s", file.c_str());
|
||||
Log::info("ShaderFilesManager", "Compiling shader: %s",
|
||||
full_path.c_str());
|
||||
const std::string &source = code.str();
|
||||
char const *source_pointer = source.c_str();
|
||||
int len = (int)source.size();
|
||||
glShaderSource(id, 1, &source_pointer, &len);
|
||||
glCompileShader(id);
|
||||
glShaderSource(*ss, 1, &source_pointer, &len);
|
||||
glCompileShader(*ss);
|
||||
|
||||
GLint result = GL_FALSE;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
glGetShaderiv(*ss, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
// failed to compile
|
||||
int info_length;
|
||||
Log::error("ShaderFilesManager", "Error in shader %s", file.c_str());
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_length);
|
||||
Log::error("ShaderFilesManager", "Error in shader %s",
|
||||
full_path.c_str());
|
||||
glGetShaderiv(*ss, GL_INFO_LOG_LENGTH, &info_length);
|
||||
if (info_length < 0)
|
||||
info_length = 1024;
|
||||
char *error_message = new char[info_length];
|
||||
error_message[0] = 0;
|
||||
glGetShaderInfoLog(id, info_length, NULL, error_message);
|
||||
glGetShaderInfoLog(*ss, info_length, NULL, error_message);
|
||||
Log::error("ShaderFilesManager", error_message);
|
||||
delete[] error_message;
|
||||
return NULL;
|
||||
}
|
||||
glGetError();
|
||||
|
||||
return id;
|
||||
return ss;
|
||||
} // loadShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -226,34 +239,40 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderFilesManager::addShaderFile(const std::string &file, unsigned type)
|
||||
ShaderFilesManager::SharedShader ShaderFilesManager::addShaderFile
|
||||
(const std::string& full_path, unsigned type)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Make sure no duplicated shader is added somewhere else
|
||||
std::unordered_map<std::string, GLuint>::const_iterator i =
|
||||
m_shader_files_loaded.find(file);
|
||||
auto i = m_shader_files_loaded.find(full_path);
|
||||
assert(i == m_shader_files_loaded.end());
|
||||
#endif
|
||||
|
||||
const GLuint id = loadShader(file, type);
|
||||
m_shader_files_loaded[file] = id;
|
||||
return id;
|
||||
SharedShader ss = loadShader(full_path, type);
|
||||
m_shader_files_loaded[full_path] = ss;
|
||||
return ss;
|
||||
} // addShaderFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Get a shader file. If the shader is not already in the cache it will be loaded and cached.
|
||||
/** Get a shader file. If the shader is not already in the cache it will be
|
||||
* loaded and cached.
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderFilesManager::getShaderFile(const std::string &file, unsigned type)
|
||||
ShaderFilesManager::SharedShader ShaderFilesManager::getShaderFile
|
||||
(const std::string &file, unsigned type)
|
||||
{
|
||||
const std::string full_path = (file.find('/') != std::string::npos ||
|
||||
file.find('\\') != std::string::npos) ?
|
||||
file : std::string(file_manager->getFileSystem()->getAbsolutePath
|
||||
(file_manager->getShadersDir().c_str()).c_str()) + file;
|
||||
// found in cache
|
||||
auto it = m_shader_files_loaded.find(file);
|
||||
auto it = m_shader_files_loaded.find(full_path);
|
||||
if (it != m_shader_files_loaded.end())
|
||||
return it->second;
|
||||
|
||||
// add to the cache now
|
||||
return addShaderFile(file, type);
|
||||
// add to the cache now
|
||||
return addShaderFile(full_path, type);
|
||||
} // getShaderFile
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -21,38 +21,74 @@
|
||||
#define HEADER_SHADER_FILES_MANAGER_HPP
|
||||
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
class ShaderFilesManager : public Singleton<ShaderFilesManager>, NoCopy
|
||||
{
|
||||
private:
|
||||
typedef std::shared_ptr<GLuint> SharedShader;
|
||||
/**
|
||||
* Map from a filename to a shader indentifier. Used for caching shaders.
|
||||
* Map from a filename in full path to a shader indentifier.
|
||||
* Used for caching shaders.
|
||||
*/
|
||||
std::unordered_map<std::string, GLuint> m_shader_files_loaded;
|
||||
std::unordered_map<std::string, SharedShader> m_shader_files_loaded;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getHeader();
|
||||
void readFile(const std::string& file, std::ostringstream& code);
|
||||
// ------------------------------------------------------------------------
|
||||
void readFile(const std::string& file, std::ostringstream& code,
|
||||
bool not_header = true);
|
||||
// ------------------------------------------------------------------------
|
||||
SharedShader addShaderFile(const std::string& full_path, unsigned type);
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
ShaderFilesManager() {}
|
||||
// ------------------------------------------------------------------------
|
||||
~ShaderFilesManager() { clean(); }
|
||||
~ShaderFilesManager()
|
||||
{
|
||||
removeAllShaderFiles();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void clean() { m_shader_files_loaded.clear(); }
|
||||
void removeAllShaderFiles()
|
||||
{
|
||||
removeUnusedShaderFiles();
|
||||
if (!m_shader_files_loaded.empty())
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("ShaderFilesManager", "Some shader file > 1 ref_count");
|
||||
#endif
|
||||
m_shader_files_loaded.clear();
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
GLuint loadShader(const std::string &file, unsigned type);
|
||||
void removeUnusedShaderFiles()
|
||||
{
|
||||
for (auto it = m_shader_files_loaded.begin();
|
||||
it != m_shader_files_loaded.end();)
|
||||
{
|
||||
if (it->second.use_count() == 1 || !it->second)
|
||||
{
|
||||
it = m_shader_files_loaded.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
GLuint addShaderFile(const std::string &file, unsigned type);
|
||||
SharedShader loadShader(const std::string& full_path, unsigned type);
|
||||
// ------------------------------------------------------------------------
|
||||
GLuint getShaderFile(const std::string &file, unsigned type);
|
||||
SharedShader getShaderFile(const std::string& file, unsigned type);
|
||||
|
||||
}; // ShaderFilesManager
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "graphics/shadow.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
@ -31,7 +31,8 @@ Shadow::Shadow(Material* shadow_mat, const AbstractKart& kart)
|
||||
: m_dy_dc(NULL), m_shadow_enabled(false), m_kart(kart)
|
||||
{
|
||||
m_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("alphablend"), shadow_mat);
|
||||
(scene::EPT_TRIANGLE_STRIP,
|
||||
SP::SPShaderManager::get()->getSPShader("alphablend"), shadow_mat);
|
||||
|
||||
m_dy_dc->getVerticesVector().resize(4);
|
||||
video::S3DVertexSkinnedMesh* v = m_dy_dc->getVerticesVector().data();
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
#include "graphics/show_curve.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
@ -33,7 +33,8 @@ ShowCurve::ShowCurve(float width, float height,
|
||||
m_first_vertices(true), m_visible(true)
|
||||
{
|
||||
m_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(irr::scene::EPT_TRIANGLES, SP::getSPShader("alphablend"),
|
||||
(irr::scene::EPT_TRIANGLES,
|
||||
SP::SPShaderManager::get()->getSPShader("alphablend"),
|
||||
material_manager->getDefaultSPMaterial("alphablend"));
|
||||
SP::addDynamicDrawCall(m_dy_dc);
|
||||
} // ShowCurve
|
||||
|
@ -25,10 +25,9 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/skidding.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_per_object_uniform.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "physics/btKart.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
@ -45,8 +44,8 @@ SkidMarks::SkidMarks(const AbstractKart& kart, float width) : m_kart(kart)
|
||||
m_width = width;
|
||||
m_material = material_manager->getMaterialSPM("skidmarks.png", "",
|
||||
"alphablend");
|
||||
m_shader = SP::getSPShader("alphablend");
|
||||
assert(m_shader != NULL);
|
||||
m_shader = SP::SPShaderManager::get()->getSPShader("alphablend");
|
||||
assert(m_shader);
|
||||
m_skid_marking = false;
|
||||
} // SkidMark
|
||||
|
||||
@ -201,7 +200,7 @@ SkidMarks::SkidMarkQuads::SkidMarkQuads(const Vec3 &left,
|
||||
const Vec3 &right,
|
||||
const Vec3 &normal,
|
||||
Material* material,
|
||||
SP::SPShader* shader,
|
||||
std::shared_ptr<SP::SPShader> shader,
|
||||
float z_offset,
|
||||
video::SColor* custom_color)
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ private:
|
||||
Material* m_material;
|
||||
|
||||
/** Shader(alphablend) to use for the skid marks. */
|
||||
SP::SPShader* m_shader;
|
||||
std::shared_ptr<SP::SPShader> m_shader;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class SkidMarkQuads : public NoCopy
|
||||
@ -88,7 +88,7 @@ private:
|
||||
public:
|
||||
SkidMarkQuads (const Vec3 &left, const Vec3 &right,
|
||||
const Vec3 &normal, Material* material,
|
||||
SP::SPShader* shader,
|
||||
std::shared_ptr<SP::SPShader> shader,
|
||||
float z_offset, video::SColor* custom_color = NULL);
|
||||
~SkidMarkQuads();
|
||||
void add (const Vec3 &left,
|
||||
|
@ -21,10 +21,10 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_mesh.hpp"
|
||||
#include "graphics/sp/sp_mesh_node.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
@ -59,7 +59,7 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
m_node->setVisible(false);
|
||||
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(m_node);
|
||||
assert(spmn);
|
||||
spmn->setTextureMatrix(0, getSPTM());
|
||||
setSPTM(spmn->getTextureMatrix(0).data());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -80,7 +80,8 @@ SlipStream::SlipStream(AbstractKart* kart) : MovingTexture(0, 0), m_kart(kart)
|
||||
if (UserConfigParams::m_slipstream_debug)
|
||||
{
|
||||
m_debug_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("additive"),
|
||||
(scene::EPT_TRIANGLE_STRIP,
|
||||
SP::SPShaderManager::get()->getSPShader("additive"),
|
||||
material_manager->getDefaultSPMaterial("additive"));
|
||||
m_debug_dc->getVerticesVector().resize(4);
|
||||
video::S3DVertexSkinnedMesh* v =
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "graphics/sp/sp_mesh_buffer.hpp"
|
||||
#include "graphics/sp/sp_mesh_node.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_texture.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
@ -68,7 +69,7 @@ bool sp_culling = true;
|
||||
// ----------------------------------------------------------------------------
|
||||
bool g_handle_shadow = false;
|
||||
// ----------------------------------------------------------------------------
|
||||
std::unordered_map<std::string, SPShader*> g_shaders;
|
||||
SPShader* g_normal_visualizer = NULL;
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShader* g_glow_shader = NULL;
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -94,8 +95,6 @@ std::array<GLuint, 1> sp_prefilled_tex;
|
||||
// ----------------------------------------------------------------------------
|
||||
std::vector<float> g_bounding_boxes;
|
||||
// ----------------------------------------------------------------------------
|
||||
core::vector3df g_wind_dir;
|
||||
// ----------------------------------------------------------------------------
|
||||
std::vector<std::shared_ptr<SPDynamicDrawCall> > g_dy_dc;
|
||||
// ----------------------------------------------------------------------------
|
||||
float g_frustums[5][24] = { { } };
|
||||
@ -121,82 +120,15 @@ void initSTKRenderer(ShaderBasedRenderer* sbr)
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3] = {};
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sp_first_frame = false;
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint sp_fog_ubo = 0;
|
||||
// ----------------------------------------------------------------------------
|
||||
core::vector3df sp_wind_dir;
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint g_skinning_tex;
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint g_skinning_buf;
|
||||
// ----------------------------------------------------------------------------
|
||||
unsigned g_skinning_size;
|
||||
// ----------------------------------------------------------------------------
|
||||
void shadowCascadeUniformAssigner(SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(sp_cur_shadow_cascade);
|
||||
} // shadowCascadeUniformAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void fogUniformAssigner(SPUniformAssigner* ua)
|
||||
{
|
||||
int fog_enable = Track::getCurrentTrack() ?
|
||||
Track::getCurrentTrack()->isFogEnabled() ? 1 : 0 : 0;
|
||||
ua->setValue(fog_enable);
|
||||
} // fogUniformAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void zeroAlphaUniformAssigner(SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(0.0f);
|
||||
} // zeroAlphaUniformAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ghostAlphaAssigner(SPUniformAssigner* ua)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
if (Track::getCurrentTrack())
|
||||
{
|
||||
const video::SColor& c = Track::getCurrentTrack()->getSunColor();
|
||||
float y = 0.2126f * c.getRed() + 0.7152f * c.getGreen() +
|
||||
0.0722f * c.getBlue();
|
||||
alpha = y > 128.0f ? 0.5f : 0.35f;
|
||||
}
|
||||
ua->setValue(alpha);
|
||||
} // ghostAlphaAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void alphaBlendUse()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} // alphaBlendUse
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void additiveUse()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
} // additiveUse
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ghostUse()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} // ghostUse
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void displaceUniformAssigner(SP::SPUniformAssigner* ua)
|
||||
{
|
||||
@ -227,6 +159,77 @@ void displaceUniformAssigner(SP::SPUniformAssigner* ua)
|
||||
ua->setValue(g_direction);
|
||||
} // displaceUniformAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void displaceShaderInit(SPShader* shader)
|
||||
{
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->setUseFunction([]()->void
|
||||
{
|
||||
assert(g_stk_sbr->getRTTs() != NULL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_TMP1_WITH_DS).bind(),
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}, RP_1ST);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_RESERVED);
|
||||
shader->addShaderFile("sp_displace.frag", GL_FRAGMENT_SHADER, RP_RESERVED);
|
||||
shader->linkShaderFiles(RP_RESERVED);
|
||||
shader->use(RP_RESERVED);
|
||||
shader->addBasicUniforms(RP_RESERVED);
|
||||
shader->addUniform("direction", typeid(std::array<float, 4>), RP_RESERVED);
|
||||
shader->setUseFunction([]()->void
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_DISPLACE).bind(),
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}, RP_RESERVED);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "displacement_tex", []()->GLuint
|
||||
{
|
||||
return irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"displace.png")->getOpenGLTextureName();
|
||||
}, RP_RESERVED);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "mask_tex", []()->GLuint
|
||||
{
|
||||
return g_stk_sbr->getRTTs()->getFBO(FBO_TMP1_WITH_DS).getRTT()[0];
|
||||
}, RP_RESERVED);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "color_tex", []()->GLuint
|
||||
{
|
||||
return g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getRTT()[0];
|
||||
}, RP_RESERVED);
|
||||
shader->addAllTextures(RP_RESERVED);
|
||||
shader->setUnuseFunction([]()->void
|
||||
{
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).bind();
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
g_stk_sbr->getPostProcessing()->renderPassThrough
|
||||
(g_stk_sbr->getRTTs()->getFBO(FBO_DISPLACE).getRTT()[0],
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getWidth(),
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getHeight());
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}, RP_RESERVED);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("direction", displaceUniformAssigner);
|
||||
} // displaceShaderInit
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void resizeSkinning(unsigned number)
|
||||
{
|
||||
@ -317,466 +320,75 @@ void initSkinning()
|
||||
sp_prefilled_tex[0] = g_skinning_tex;
|
||||
} // initSkinning
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void addShader(SPShader* shader)
|
||||
{
|
||||
g_shaders[shader->getName()] = shader;
|
||||
} // addShader
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void loadShaders()
|
||||
{
|
||||
// ========================================================================
|
||||
SPShader* shader = new SPShader("solid");
|
||||
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_solid.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("solid_skinned");
|
||||
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_solid.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_skinning_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
shader = new SPShader("decal");
|
||||
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_decal.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("decal_skinned");
|
||||
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_decal.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_skinning_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
shader = new SPShader("alphatest", 3, false, 0, true);
|
||||
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_alpha_test.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("sp_shadow_alpha_test.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("alphatest_skinned", 3, false, 0, true);
|
||||
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_alpha_test.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_skinning_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("sp_shadow_alpha_test.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
shader = new SPShader("unlit", 3, false, 0, true);
|
||||
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_unlit.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("sp_shadow_alpha_test.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("unlit_skinned", 3, false, 0, true);
|
||||
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_unlit.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_skinning_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("sp_shadow_alpha_test.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
shader = new SPShader("normalmap");
|
||||
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_normal_map.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("normalmap_skinned", 3, false);
|
||||
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_normal_map.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_skinning_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
shader = new SPShader("grass", 3, false, 0, true);
|
||||
shader->addShaderFile("sp_grass_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_grass.frag", GL_FRAGMENT_SHADER,
|
||||
RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("wind_direction", typeid(core::vector3df), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
shader->addShaderFile("sp_grass_shadow.vert", GL_VERTEX_SHADER, RP_SHADOW);
|
||||
shader->addShaderFile("sp_shadow_alpha_test.frag", GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
shader->addUniform("wind_direction", typeid(core::vector3df), RP_SHADOW);
|
||||
shader->addUniform("layer", typeid(int), RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
static_cast<SPPerObjectUniform*>(shader)->addAssignerFunction("layer",
|
||||
shadowCascadeUniformAssigner);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("wind_direction", [](SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(g_wind_dir);
|
||||
});
|
||||
|
||||
addShader(shader);
|
||||
|
||||
// ========================================================================
|
||||
// Transparent shader
|
||||
// ========================================================================
|
||||
shader = new SPShader("alphablend_skinned", 1, true);
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_transparent.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("fog_enabled", typeid(int), RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(alphaBlendUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("fog_enabled", fogUniformAssigner);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", zeroAlphaUniformAssigner);
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("alphablend", 1, true);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_transparent.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("fog_enabled", typeid(int), RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(alphaBlendUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("fog_enabled", fogUniformAssigner);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", zeroAlphaUniformAssigner);
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("additive_skinned", 1, true);
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_transparent.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("fog_enabled", typeid(int), RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(additiveUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("fog_enabled", fogUniformAssigner);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", zeroAlphaUniformAssigner);
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("additive", 1, true);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_transparent.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("fog_enabled", typeid(int), RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(additiveUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("fog_enabled", fogUniformAssigner);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", zeroAlphaUniformAssigner);
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("ghost_skinned", 1, true/*transparent_shader*/,
|
||||
900/*drawing_priority*/);
|
||||
shader->addShaderFile("sp_skinning.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_ghost.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(ghostUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", ghostAlphaAssigner);
|
||||
addShader(shader);
|
||||
|
||||
shader = new SPShader("ghost", 1, true/*transparent_shader*/,
|
||||
900/*drawing_priority*/);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_ghost.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("custom_alpha", typeid(float), RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
shader->setUseFunction(ghostUse);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("custom_alpha", ghostAlphaAssigner);
|
||||
addShader(shader);
|
||||
SPShaderManager::get()->loadSPShaders(file_manager->getShadersDir());
|
||||
|
||||
// Displace shader is not specifiable in XML due to complex callback
|
||||
std::shared_ptr<SPShader> sps;
|
||||
if (CVS->isDefferedEnabled())
|
||||
{
|
||||
// This displace shader will be drawn the last in transparent pass
|
||||
shader = new SPShader("displace", 2, true/*transparent_shader*/,
|
||||
999/*drawing_priority*/);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER,
|
||||
RP_1ST);
|
||||
shader->addShaderFile("white.frag", GL_FRAGMENT_SHADER,
|
||||
RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->setUseFunction([]()->void
|
||||
{
|
||||
assert(g_stk_sbr->getRTTs() != NULL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_TMP1_WITH_DS).bind(),
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}, RP_1ST);
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER,
|
||||
RP_2ND);
|
||||
shader->addShaderFile("sp_displace.frag", GL_FRAGMENT_SHADER,
|
||||
RP_2ND);
|
||||
shader->linkShaderFiles(RP_2ND);
|
||||
shader->use(RP_2ND);
|
||||
shader->addBasicUniforms(RP_2ND);
|
||||
shader->addUniform("direction", typeid(std::array<float, 4>),
|
||||
RP_2ND);
|
||||
shader->setUseFunction([]()->void
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_DISPLACE).bind(),
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}, RP_2ND);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "displacement_tex", []()->GLuint
|
||||
{
|
||||
return irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"displace.png")->getOpenGLTextureName();
|
||||
}, RP_2ND);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "mask_tex", []()->GLuint
|
||||
{
|
||||
return g_stk_sbr->getRTTs()->getFBO(FBO_TMP1_WITH_DS).getRTT()[0];
|
||||
}, RP_2ND);
|
||||
shader->addCustomPrefilledTextures(ST_BILINEAR,
|
||||
GL_TEXTURE_2D, "color_tex", []()->GLuint
|
||||
{
|
||||
return g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getRTT()[0];
|
||||
}, RP_2ND);
|
||||
shader->addAllTextures(RP_2ND);
|
||||
shader->setUnuseFunction([]()->void
|
||||
{
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).bind();
|
||||
glStencilFunc(GL_EQUAL, 1, 0xFF);
|
||||
g_stk_sbr->getPostProcessing()->renderPassThrough
|
||||
(g_stk_sbr->getRTTs()->getFBO(FBO_DISPLACE).getRTT()[0],
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getWidth(),
|
||||
g_stk_sbr->getRTTs()->getFBO(FBO_COLORS).getHeight());
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}, RP_2ND);
|
||||
static_cast<SPPerObjectUniform*>(shader)
|
||||
->addAssignerFunction("direction", displaceUniformAssigner);
|
||||
addShader(shader);
|
||||
sps = std::make_shared<SPShader>("displace", displaceShaderInit,
|
||||
true/*transparent_shader*/, 999/*drawing_priority*/,
|
||||
true/*use_alpha_channel*/);
|
||||
SPShaderManager::get()->addSPShader(sps->getName(), sps);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback shader
|
||||
SPShaderManager::get()->addSPShader("displace",
|
||||
SPShaderManager::get()->getSPShader("alphablend"));
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Glow shader
|
||||
// ========================================================================
|
||||
g_glow_shader = new SPShader("sp_glow_shader", 1);
|
||||
g_glow_shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER, RP_1ST);
|
||||
g_glow_shader->addShaderFile("colorize.frag", GL_FRAGMENT_SHADER, RP_1ST);
|
||||
g_glow_shader->linkShaderFiles(RP_1ST);
|
||||
g_glow_shader->use(RP_1ST);
|
||||
g_glow_shader->addBasicUniforms(RP_1ST);
|
||||
g_glow_shader->addUniform("col", typeid(irr::video::SColorf), RP_1ST);
|
||||
addShader(g_glow_shader);
|
||||
|
||||
// ========================================================================
|
||||
// Normal visualizer
|
||||
// ========================================================================
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBGeometryShadersUsable())
|
||||
if (CVS->isDefferedEnabled())
|
||||
{
|
||||
shader = new SPShader("sp_normal_visualizer", 1);
|
||||
shader->addShaderFile("sp_normal_visualizer.vert", GL_VERTEX_SHADER,
|
||||
RP_1ST);
|
||||
shader->addShaderFile("sp_normal_visualizer.geom", GL_GEOMETRY_SHADER,
|
||||
RP_1ST);
|
||||
shader->addShaderFile("sp_normal_visualizer.frag", GL_FRAGMENT_SHADER,
|
||||
RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
addShader(shader);
|
||||
}
|
||||
sps = std::make_shared<SPShader>
|
||||
("sp_glow_shader", [](SPShader* shader)
|
||||
{
|
||||
shader->addShaderFile("sp_pass.vert", GL_VERTEX_SHADER,
|
||||
RP_1ST);
|
||||
shader->addShaderFile("colorize.frag", GL_FRAGMENT_SHADER,
|
||||
RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addUniform("col", typeid(irr::video::SColorf), RP_1ST);
|
||||
});
|
||||
SPShaderManager::get()->addSPShader(sps->getName(), sps);
|
||||
g_glow_shader = sps.get();
|
||||
|
||||
// ====================================================================
|
||||
// Normal visualizer
|
||||
// ====================================================================
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBGeometryShadersUsable())
|
||||
{
|
||||
sps = std::make_shared<SPShader>
|
||||
("sp_normal_visualizer", [](SPShader* shader)
|
||||
{
|
||||
shader->addShaderFile("sp_normal_visualizer.vert",
|
||||
GL_VERTEX_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_normal_visualizer.geom",
|
||||
GL_GEOMETRY_SHADER, RP_1ST);
|
||||
shader->addShaderFile("sp_normal_visualizer.frag",
|
||||
GL_FRAGMENT_SHADER, RP_1ST);
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
});
|
||||
SPShaderManager::get()->addSPShader(sps->getName(), sps);
|
||||
g_normal_visualizer = sps.get();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SPShaderManager::get()->setOfficialShaders();
|
||||
|
||||
} // loadShaders
|
||||
|
||||
@ -960,12 +572,9 @@ void init()
|
||||
void destroy()
|
||||
{
|
||||
g_dy_dc.clear();
|
||||
for (auto& p : g_shaders)
|
||||
{
|
||||
delete p.second;
|
||||
}
|
||||
g_shaders.clear();
|
||||
|
||||
SPShaderManager::destroy();
|
||||
g_glow_shader = NULL;
|
||||
g_normal_visualizer = NULL;
|
||||
SPTextureManager::destroy();
|
||||
|
||||
#ifndef USE_GLES2
|
||||
@ -1005,15 +614,10 @@ SPShader* getGlowShader()
|
||||
} // getGlowShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShader* getSPShader(const std::string& name)
|
||||
SPShader* getNormalVisualizer()
|
||||
{
|
||||
auto ret = g_shaders.find(name);
|
||||
if (ret != g_shaders.end())
|
||||
{
|
||||
return ret->second;
|
||||
}
|
||||
return NULL;
|
||||
} // getSPShader
|
||||
return g_normal_visualizer;
|
||||
} // getNormalVisualizer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline void mathPlaneNormf(float *p)
|
||||
@ -1128,7 +732,7 @@ void prepareDrawCalls()
|
||||
return;
|
||||
}
|
||||
g_bounding_boxes.clear();
|
||||
g_wind_dir = core::vector3df(1.0f, 0.0f, 0.0f) *
|
||||
sp_wind_dir = core::vector3df(1.0f, 0.0f, 0.0f) *
|
||||
(irr_driver->getDevice()->getTimer()->getTime() / 1000.0f) * 1.5f;
|
||||
sp_solid_poly_count = sp_shadow_poly_count = 0;
|
||||
// 1st one is identity
|
||||
@ -1189,9 +793,10 @@ void addObject(SPMeshNode* node)
|
||||
core::aabbox3df bb = mb->getBoundingBox();
|
||||
model_matrix.transformBoxEx(bb);
|
||||
std::vector<bool> discard;
|
||||
discard.resize((g_handle_shadow ? 5 : 1), false);
|
||||
for (int dc_type = 0; dc_type <
|
||||
(g_handle_shadow ? 5 : sp_first_frame ? 0 : 1); dc_type++)
|
||||
const bool handle_shadow =
|
||||
g_handle_shadow && shader->hasShader(RP_SHADOW);
|
||||
discard.resize((handle_shadow ? 5 : 1), false);
|
||||
for (int dc_type = 0; dc_type < (handle_shadow ? 5 : 1); dc_type++)
|
||||
{
|
||||
for (int i = 0; i < 24; i += 4)
|
||||
{
|
||||
@ -1216,7 +821,7 @@ void addObject(SPMeshNode* node)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sp_first_frame || g_handle_shadow ?
|
||||
if (handle_shadow ?
|
||||
(discard[0] && discard[1] && discard[2] && discard[3] &&
|
||||
discard[4]) : discard[0])
|
||||
{
|
||||
@ -1241,8 +846,7 @@ void addObject(SPMeshNode* node)
|
||||
|
||||
mb->uploadGLMesh();
|
||||
// For first frame only need the vbo to be initialized
|
||||
if (!added_for_skinning && node->getAnimationState() &&
|
||||
!sp_first_frame)
|
||||
if (!added_for_skinning && node->getAnimationState())
|
||||
{
|
||||
added_for_skinning = true;
|
||||
int skinning_offset = g_skinning_offset + node->getTotalJoints();
|
||||
@ -1260,21 +864,14 @@ void addObject(SPMeshNode* node)
|
||||
|
||||
float hue = node->getRenderInfo(m) ?
|
||||
node->getRenderInfo(m)->getHue() : 0.0f;
|
||||
float tm_x = 0.0f;
|
||||
float tm_y = 0.0f;
|
||||
const auto& ret = node->getTextureMatrix(m);
|
||||
if (ret[0] && ret[1])
|
||||
{
|
||||
tm_x = *ret[0];
|
||||
tm_y = *ret[1];
|
||||
}
|
||||
SPInstancedData id = SPInstancedData
|
||||
(node->getAbsoluteTransformation(), tm_x, tm_y, hue,
|
||||
(node->getAbsoluteTransformation(), node->getTextureMatrix(m)[0],
|
||||
node->getTextureMatrix(m)[1], hue,
|
||||
(short)node->getSkinningOffset());
|
||||
|
||||
for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++)
|
||||
for (int dc_type = 0; dc_type < (handle_shadow ? 5 : 1); dc_type++)
|
||||
{
|
||||
if (!sp_first_frame && discard[dc_type])
|
||||
if (discard[dc_type])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1364,8 +961,10 @@ void handleDynamicDrawCall()
|
||||
core::aabbox3df bb = dydc->getBoundingBox();
|
||||
dydc->getAbsoluteTransformation().transformBoxEx(bb);
|
||||
std::vector<bool> discard;
|
||||
discard.resize((g_handle_shadow ? 5 : 1), false);
|
||||
for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++)
|
||||
const bool handle_shadow =
|
||||
g_handle_shadow && shader->hasShader(RP_SHADOW);
|
||||
discard.resize((handle_shadow ? 5 : 1), false);
|
||||
for (int dc_type = 0; dc_type < (handle_shadow ? 5 : 1); dc_type++)
|
||||
{
|
||||
for (int i = 0; i < 24; i += 4)
|
||||
{
|
||||
@ -1390,7 +989,7 @@ void handleDynamicDrawCall()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (g_handle_shadow ?
|
||||
if (handle_shadow ?
|
||||
(discard[0] && discard[1] && discard[2] && discard[3] &&
|
||||
discard[4]) : discard[0])
|
||||
{
|
||||
@ -1413,7 +1012,7 @@ void handleDynamicDrawCall()
|
||||
addEdgeForViz(getCorner(bb, 4), getCorner(bb, 6));
|
||||
}
|
||||
|
||||
for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++)
|
||||
for (int dc_type = 0; dc_type < (handle_shadow ? 5 : 1); dc_type++)
|
||||
{
|
||||
if (discard[dc_type])
|
||||
{
|
||||
@ -1472,7 +1071,6 @@ void updateModelMatrix()
|
||||
{
|
||||
// Make sure all textures (with handles) are loaded
|
||||
SPTextureManager::get()->checkForGLCommand(true/*before_scene*/);
|
||||
SP::sp_first_frame = false;
|
||||
if (!sp_culling)
|
||||
{
|
||||
return;
|
||||
@ -1620,13 +1218,12 @@ void uploadAll()
|
||||
// ----------------------------------------------------------------------------
|
||||
void drawNormal()
|
||||
{
|
||||
SPShader* nv = getSPShader("sp_normal_visualizer");
|
||||
if (nv == NULL)
|
||||
if (g_normal_visualizer == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
nv->use();
|
||||
nv->bindPrefilledTextures();
|
||||
g_normal_visualizer->use();
|
||||
g_normal_visualizer->bindPrefilledTextures();
|
||||
for (unsigned i = 0; i < g_final_draw_calls[0].size(); i++)
|
||||
{
|
||||
auto& p = g_final_draw_calls[0][i];
|
||||
@ -1659,12 +1256,16 @@ void drawNormal()
|
||||
}
|
||||
}
|
||||
}
|
||||
nv->unuse();
|
||||
g_normal_visualizer->unuse();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void drawGlow()
|
||||
{
|
||||
if (g_glow_meshes.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_glow_shader->use();
|
||||
SPUniformAssigner* glow_color_assigner =
|
||||
g_glow_shader->getUniformAssigner("col");
|
||||
@ -1793,6 +1394,24 @@ SPMesh* convertEVTStandard(irr::scene::IMesh* mesh,
|
||||
return spm;
|
||||
} // convertEVTStandard
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void uploadSPM(irr::scene::IMesh* mesh)
|
||||
{
|
||||
if (!CVS->isGLSL())
|
||||
{
|
||||
return;
|
||||
}
|
||||
SP::SPMesh* spm = dynamic_cast<SP::SPMesh*>(mesh);
|
||||
if (spm)
|
||||
{
|
||||
for (u32 i = 0; i < spm->getMeshBufferCount(); i++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb = spm->getSPMeshBuffer(i);
|
||||
mb->uploadGLMesh();
|
||||
}
|
||||
}
|
||||
} // uploadSPM
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include "irrMath.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
@ -86,7 +87,6 @@ class SPMeshBuffer;
|
||||
|
||||
extern GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3];
|
||||
extern GLuint sp_fog_ubo;
|
||||
extern bool sp_first_frame;
|
||||
extern std::array<GLuint, 1> sp_prefilled_tex;
|
||||
extern unsigned sp_solid_poly_count;
|
||||
extern unsigned sp_shadow_poly_count;
|
||||
@ -94,19 +94,17 @@ extern int sp_cur_shadow_cascade;
|
||||
extern bool sp_culling;
|
||||
extern unsigned sp_cur_player;
|
||||
extern unsigned sp_cur_buf_id[MAX_PLAYER_COUNT];
|
||||
|
||||
extern irr::core::vector3df sp_wind_dir;
|
||||
// ----------------------------------------------------------------------------
|
||||
void init();
|
||||
// ----------------------------------------------------------------------------
|
||||
void addShader(SPShader*);
|
||||
// ----------------------------------------------------------------------------
|
||||
void destroy();
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint getSampler(SamplerType);
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShader* getGlowShader();
|
||||
SPShader* getNormalVisualizer();
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShader* getSPShader(const std::string& name);
|
||||
SPShader* getGlowShader();
|
||||
// ----------------------------------------------------------------------------
|
||||
void prepareDrawCalls();
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -137,6 +135,8 @@ void drawBoundingBoxes();
|
||||
SPMesh* convertEVTStandard(irr::scene::IMesh* mesh,
|
||||
const irr::video::SColor* color = NULL);
|
||||
// ----------------------------------------------------------------------------
|
||||
void uploadSPM(irr::scene::IMesh* mesh);
|
||||
// ----------------------------------------------------------------------------
|
||||
inline uint8_t srgbToLinear(float color_srgb)
|
||||
{
|
||||
int ret;
|
||||
|
@ -16,10 +16,10 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_texture.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/graphics_restrictions.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_texture.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -28,20 +28,22 @@ namespace SP
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
SPDynamicDrawCall::SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
|
||||
SPShader* shader, Material* m)
|
||||
std::shared_ptr<SPShader> shader,
|
||||
Material* m)
|
||||
: SPMeshBuffer()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_primitive_type = pt;
|
||||
m_shader = shader;
|
||||
m_shaders[0] = shader;
|
||||
m_stk_material[0] = std::make_tuple(0u, 0u, m);
|
||||
m_textures.resize(m_stk_material.size());
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
m_textures[0][j] = SPTextureManager::get()->getTexture
|
||||
(std::get<2>(m_stk_material[0])->getSamplerPath(j),
|
||||
m_textures[0][j] = SPTextureManager::get()->getTexture(
|
||||
m_shaders[0] && m_shaders[0]->hasTextureLayer(j) ?
|
||||
std::get<2>(m_stk_material[0])->getSamplerPath(j) : "",
|
||||
j == 0 ? std::get<2>(m_stk_material[0]) : NULL,
|
||||
j < 2 && CVS->isDefferedEnabled(),
|
||||
m_shaders[0] && m_shaders[0]->isSrgbForTextureLayer(j),
|
||||
std::get<2>(m_stk_material[0])->getContainerId());
|
||||
}
|
||||
m_tex_cmp[m_textures[0][0]->getPath() + m_textures[0][1]->getPath()] = 0;
|
||||
@ -133,7 +135,7 @@ SPDynamicDrawCall::SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
|
||||
glVertexAttribDivisorARB(10, 1);
|
||||
// Texture translation
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribPointer(11, 2, GL_HALF_FLOAT, GL_FALSE, 32, (void*)24);
|
||||
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 32, (void*)24);
|
||||
glVertexAttribDivisorARB(11, 1);
|
||||
// Misc data (skinning offset and hue change)
|
||||
glEnableVertexAttribArray(12);
|
||||
|
@ -43,8 +43,6 @@ class SPDynamicDrawCall : public SPMeshBuffer
|
||||
private:
|
||||
core::matrix4 m_trans;
|
||||
|
||||
SPShader* m_shader;
|
||||
|
||||
scene::ISceneNode* m_parent = NULL;
|
||||
|
||||
core::vector2df m_texture_trans;
|
||||
@ -65,8 +63,8 @@ private:
|
||||
bool initTextureDyDc();
|
||||
|
||||
public:
|
||||
SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt, SPShader* shader,
|
||||
Material* m);
|
||||
SPDynamicDrawCall(scene::E_PRIMITIVE_TYPE pt,
|
||||
std::shared_ptr<SPShader> shader, Material* m);
|
||||
// ------------------------------------------------------------------------
|
||||
~SPDynamicDrawCall() {}
|
||||
// ------------------------------------------------------------------------
|
||||
@ -130,8 +128,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void enableTextureMatrix(unsigned mat_id) {}
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader* getShader() const { return m_shader; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<video::S3DVertexSkinnedMesh>& getVerticesVector()
|
||||
{ return m_vertices; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -71,7 +71,11 @@ public:
|
||||
short s[4] = { toFloat16(scale.X), toFloat16(scale.Y),
|
||||
toFloat16(scale.Z), toFloat16(rotation.W) };
|
||||
memcpy(m_data + 16, s, 8);
|
||||
short tm[2] = { toFloat16(texture_trans_x), toFloat16(texture_trans_y) };
|
||||
short tm[2] =
|
||||
{
|
||||
short(texture_trans_x * 32767.0f),
|
||||
short(texture_trans_y * 32767.0f)
|
||||
};
|
||||
memcpy(m_data + 24, tm, 4);
|
||||
memcpy(m_data + 28, &skinning_offset, 2);
|
||||
short hue_packed = short(core::clamp(int(hue * 100.0f), 0, 100));
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/graphics_restrictions.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/mini_glm.hpp"
|
||||
@ -111,28 +113,32 @@ void SPMeshBuffer::uploadGLMesh()
|
||||
}
|
||||
m_uploaded_gl = true;
|
||||
#ifndef SERVER_ONLY
|
||||
if (!m_shaders[0])
|
||||
{
|
||||
Log::warn("SPMeshBuffer", "%s shader is missing",
|
||||
std::get<2>(m_stk_material[0])->getShaderName().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_textures.resize(m_stk_material.size());
|
||||
for (unsigned i = 0; i < m_stk_material.size(); i++)
|
||||
{
|
||||
for (unsigned j = 0; j < 6; j++)
|
||||
{
|
||||
// Undo the effect of srgb on 0 and 1 channel of textures
|
||||
// which is the uv textures from .spm when advanced lighting
|
||||
m_textures[i][j] = SPTextureManager::get()->getTexture
|
||||
(std::get<2>(m_stk_material[i])->getSamplerPath(j),
|
||||
(m_shaders[0]->hasTextureLayer(j) ?
|
||||
std::get<2>(m_stk_material[i])->getSamplerPath(j) : "",
|
||||
j == 0 ? std::get<2>(m_stk_material[i]) : NULL,
|
||||
j < 2 && CVS->isDefferedEnabled(),
|
||||
m_shaders[0]->isSrgbForTextureLayer(j),
|
||||
std::get<2>(m_stk_material[i])->getContainerId());
|
||||
}
|
||||
// Use .spm uv texture 1 and 2 for compare in scene manager
|
||||
m_tex_cmp[m_textures[i][0]->getPath() + m_textures[i][1]->getPath()] =
|
||||
i;
|
||||
// Use the original spm uv texture 1 and 2 for compare in scene manager
|
||||
m_tex_cmp[std::get<2>(m_stk_material[i])->getSamplerPath(0) +
|
||||
std::get<2>(m_stk_material[i])->getSamplerPath(1)] = i;
|
||||
}
|
||||
|
||||
bool use_2_uv = std::get<2>(m_stk_material[0])->use2UV();
|
||||
bool use_tangents =
|
||||
std::get<2>(m_stk_material[0])->getShaderName() == "normalmap" &&
|
||||
CVS->isDefferedEnabled();
|
||||
bool use_tangents = m_shaders[0]->useTangents();
|
||||
const unsigned pitch = 48 - (use_tangents ? 0 : 4) - (use_2_uv ? 0 : 4) -
|
||||
(m_skinned ? 0 : 16);
|
||||
m_pitch = pitch;
|
||||
@ -212,10 +218,12 @@ void SPMeshBuffer::uploadGLMesh()
|
||||
void SPMeshBuffer::recreateVAO(unsigned i)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!m_shaders[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool use_2_uv = std::get<2>(m_stk_material[0])->use2UV();
|
||||
bool use_tangents =
|
||||
std::get<2>(m_stk_material[0])->getShaderName() == "normalmap" &&
|
||||
CVS->isDefferedEnabled();
|
||||
bool use_tangents = m_shaders[0]->useTangents();
|
||||
const unsigned pitch = m_pitch;
|
||||
|
||||
size_t offset = 0;
|
||||
@ -353,7 +361,7 @@ void SPMeshBuffer::recreateVAO(unsigned i)
|
||||
glVertexAttribDivisorARB(10, 1);
|
||||
// Texture translation
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribPointer(11, 2, GL_HALF_FLOAT, GL_FALSE, 32, (void*)24);
|
||||
glVertexAttribPointer(11, 2, GL_SHORT, GL_TRUE, 32, (void*)24);
|
||||
glVertexAttribDivisorARB(11, 1);
|
||||
// Misc data (skinning offset and hue change)
|
||||
glEnableVertexAttribArray(12);
|
||||
@ -458,4 +466,14 @@ void SPMeshBuffer::reloadTextureCompare()
|
||||
}
|
||||
} // reloadTextureCompare
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPMeshBuffer::setSTKMaterial(Material* m)
|
||||
{
|
||||
m_stk_material[0] = std::make_tuple(0u, getIndexCount(), m);
|
||||
m_shaders[0] = SPShaderManager::get()->getSPShader(
|
||||
std::get<2>(m_stk_material[0])->getShaderName());
|
||||
m_shaders[1] = SPShaderManager::get()->getSPShader(
|
||||
std::get<2>(m_stk_material[0])->getShaderName() + "_skinned");
|
||||
} // setSTKMaterial
|
||||
|
||||
}
|
||||
|
@ -41,11 +41,14 @@ class Material;
|
||||
|
||||
namespace SP
|
||||
{
|
||||
class SPShader;
|
||||
class SPTexture;
|
||||
|
||||
class SPMeshBuffer : public IMeshBuffer, public SPPerObjectUniform
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<SPShader> m_shaders[2];
|
||||
|
||||
std::vector<std::tuple<size_t/*first_index_id*/,
|
||||
unsigned/*indices_count*/, Material*> > m_stk_material;
|
||||
|
||||
@ -270,10 +273,7 @@ public:
|
||||
m_indices = std::move(indices);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setSTKMaterial(Material* m)
|
||||
{
|
||||
m_stk_material[0] = std::make_tuple(0u, getIndexCount(), m);
|
||||
}
|
||||
void setSTKMaterial(Material* m);
|
||||
// ------------------------------------------------------------------------
|
||||
void reloadTextureCompare();
|
||||
// ------------------------------------------------------------------------
|
||||
@ -283,6 +283,9 @@ public:
|
||||
m_indices.shrink_to_fit();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader* getShader(bool skinned = false) const
|
||||
{ return skinned ? m_shaders[1].get() : m_shaders[0].get(); }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual const video::SMaterial& getMaterial() const
|
||||
{
|
||||
static video::SMaterial unused;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "graphics/sp/sp_mesh.hpp"
|
||||
#include "graphics/sp/sp_mesh_buffer.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/graphics_restrictions.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
@ -88,7 +89,8 @@ void SPMeshNode::setMesh(irr::scene::IAnimatedMesh* mesh)
|
||||
cleanRenderInfo();
|
||||
if (m_mesh)
|
||||
{
|
||||
m_texture_matrices.resize(m_mesh->getMeshBufferCount());
|
||||
m_texture_matrices.resize(m_mesh->getMeshBufferCount(),
|
||||
{{ 0.0f, 0.0f }});
|
||||
if (!m_mesh->isStatic())
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
@ -190,11 +192,8 @@ SPShader* SPMeshNode::getShader(unsigned mesh_buffer_id) const
|
||||
#ifndef SERVER_ONLY
|
||||
if (!m_mesh || mesh_buffer_id < m_mesh->getMeshBufferCount())
|
||||
{
|
||||
const std::string sn = (m_shader_override.empty() ?
|
||||
m_mesh->getSPMeshBuffer(mesh_buffer_id)->getSTKMaterial()
|
||||
->getShaderName() : m_shader_override) +
|
||||
(m_animated ? "_skinned" : "");
|
||||
SPShader* shader = SP::getSPShader(sn);
|
||||
SPShader* shader =
|
||||
m_mesh->getSPMeshBuffer(mesh_buffer_id)->getShader(m_animated);
|
||||
if (shader && shader->isTransparent())
|
||||
{
|
||||
// Use real transparent shader first
|
||||
@ -202,8 +201,8 @@ SPShader* SPMeshNode::getShader(unsigned mesh_buffer_id) const
|
||||
}
|
||||
if (m_first_render_info && m_first_render_info->isTransparent())
|
||||
{
|
||||
return SP::getSPShader
|
||||
(std::string("ghost") + (m_animated ? "_skinned" : ""));
|
||||
return SPShaderManager::get()->getSPShader
|
||||
(std::string("ghost") + (m_animated ? "_skinned" : "")).get();
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
@ -52,11 +52,9 @@ private:
|
||||
|
||||
std::vector<std::array<float, 16> > m_skinning_matrices;
|
||||
|
||||
std::string m_shader_override;
|
||||
|
||||
video::SColorf m_glow_color;
|
||||
|
||||
std::vector<std::array<std::shared_ptr<float>, 2> > m_texture_matrices;
|
||||
std::vector<std::array<float, 2> > m_texture_matrices;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void cleanRenderInfo();
|
||||
@ -119,8 +117,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader* getShader(unsigned mesh_buffer_id) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void setShaderOverride(const std::string& so) { m_shader_override = so; }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::array<float, 16>* getSkinningMatrices() const
|
||||
{ return m_skinning_matrices.data(); }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -143,14 +139,13 @@ public:
|
||||
m_glow_color.b == 0.0f);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
std::array<std::shared_ptr<float>, 2>& getTextureMatrix(unsigned mb_id)
|
||||
std::array<float, 2>& getTextureMatrix(unsigned mb_id)
|
||||
{
|
||||
assert(mb_id < m_texture_matrices.size());
|
||||
return m_texture_matrices[mb_id];
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setTextureMatrix(unsigned mb_id,
|
||||
std::array<std::shared_ptr<float>, 2> tm)
|
||||
void setTextureMatrix(unsigned mb_id, const std::array<float, 2>& tm)
|
||||
{
|
||||
assert(mb_id < m_texture_matrices.size());
|
||||
m_texture_matrices[mb_id] = tm;
|
||||
|
@ -16,15 +16,12 @@
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/shader_files_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <ITexture.h>
|
||||
#include <string>
|
||||
|
||||
namespace SP
|
||||
{
|
||||
std::unordered_map<std::string, std::pair<unsigned, SamplerType> >
|
||||
@ -37,36 +34,22 @@ std::unordered_map<std::string, std::pair<unsigned, SamplerType> >
|
||||
#endif
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShader::~SPShader()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (unsigned rp = RP_1ST; rp < RP_COUNT; rp++)
|
||||
{
|
||||
if (m_program[rp] != 0)
|
||||
{
|
||||
glDeleteProgram(m_program[rp]);
|
||||
}
|
||||
for (auto& p : m_uniforms[rp])
|
||||
{
|
||||
delete p.second;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // ~SPShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::addShaderFile(const std::string& name, GLint shader_type,
|
||||
RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
GLint shader_id = ShaderFilesManager::getInstance()
|
||||
if (m_program[rp] == 0)
|
||||
{
|
||||
m_program[rp] = glCreateProgram();
|
||||
}
|
||||
auto shader_file = ShaderFilesManager::getInstance()
|
||||
->getShaderFile(name, shader_type);
|
||||
glAttachShader(m_program[rp], shader_id);
|
||||
GLint is_deleted = GL_TRUE;
|
||||
glGetShaderiv(shader_id, GL_DELETE_STATUS, &is_deleted);
|
||||
if (is_deleted == GL_FALSE)
|
||||
glDeleteShader(shader_id);
|
||||
if (shader_file)
|
||||
{
|
||||
m_shader_files.push_back(shader_file);
|
||||
glAttachShader(m_program[rp], *shader_file);
|
||||
}
|
||||
#endif
|
||||
} // addShaderFile
|
||||
|
||||
@ -88,6 +71,19 @@ void SPShader::linkShaderFiles(RenderPass rp)
|
||||
Log::error("SPShader", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
// After linking all shaders can be detached
|
||||
GLuint shaders[10] = {};
|
||||
GLsizei count = 0;
|
||||
glGetAttachedShaders(m_program[rp], 10, &count, shaders);
|
||||
for (unsigned i = 0; i < (unsigned)count; i++)
|
||||
{
|
||||
glDetachShader(m_program[rp], shaders[i]);
|
||||
}
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
glDeleteProgram(m_program[rp]);
|
||||
m_program[rp] = 0;
|
||||
}
|
||||
#endif
|
||||
} // linkShaderFiles
|
||||
|
||||
@ -131,7 +127,7 @@ void SPShader::addAllTextures(RenderPass rp)
|
||||
const unsigned idx =
|
||||
unsigned(m_prefilled_samplers[rp].size() + m_samplers[rp].size());
|
||||
glUniform1i(loc, idx);
|
||||
m_samplers[rp].emplace_back(i, idx);
|
||||
m_samplers[rp][i] = idx;
|
||||
}
|
||||
#endif
|
||||
} // addPrefilledTextures
|
||||
@ -161,7 +157,7 @@ void SPShader::addCustomPrefilledTextures(SamplerType st, GLuint texture_type,
|
||||
} // addCustomPrefilledTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::bindPrefilledTextures(RenderPass rp)
|
||||
void SPShader::bindPrefilledTextures(RenderPass rp) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (auto& p : m_prefilled_samplers[rp])
|
||||
@ -184,7 +180,8 @@ void SPShader::bindPrefilledTextures(RenderPass rp)
|
||||
} // bindPrefilledTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::bindTextures(const std::array<GLuint, 6>& tex, RenderPass rp)
|
||||
void SPShader::bindTextures(const std::array<GLuint, 6>& tex,
|
||||
RenderPass rp) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (auto& p : m_samplers[rp])
|
||||
@ -197,7 +194,7 @@ void SPShader::bindTextures(const std::array<GLuint, 6>& tex, RenderPass rp)
|
||||
} // bindTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::addUniform(const std::string& name, const std::type_info& ti,
|
||||
void SPShader::addUniform(const std::string& name, const std::type_index& ti,
|
||||
RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
@ -234,7 +231,7 @@ void SPShader::setUniformsPerObject(SPPerObjectUniform* sppou,
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
SPUniformAssigner* SPShader::getUniformAssigner(const std::string& name,
|
||||
RenderPass rp)
|
||||
RenderPass rp) const
|
||||
{
|
||||
auto ret = m_uniforms[rp].find(name);
|
||||
if (ret == m_uniforms[rp].end())
|
||||
@ -244,4 +241,43 @@ SPUniformAssigner* SPShader::getUniformAssigner(const std::string& name,
|
||||
return ret->second;
|
||||
} // getUniformAssigner
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::unload()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (unsigned rp = RP_1ST; rp < RP_COUNT; rp++)
|
||||
{
|
||||
if (m_program[rp] != 0)
|
||||
{
|
||||
glDeleteProgram(m_program[rp]);
|
||||
m_program[rp] = 0;
|
||||
}
|
||||
for (auto& p : m_uniforms[rp])
|
||||
{
|
||||
delete p.second;
|
||||
}
|
||||
m_uniforms[rp].clear();
|
||||
m_custom_prefilled_getter[rp].clear();
|
||||
m_prefilled_samplers[rp].clear();
|
||||
m_samplers[rp].clear();
|
||||
m_use_function[rp] = nullptr;
|
||||
m_unuse_function[rp] = nullptr;
|
||||
}
|
||||
m_shader_files.clear();
|
||||
#endif
|
||||
} // unload
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool SPShader::isSrgbForTextureLayer(unsigned layer) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (!CVS->isDefferedEnabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
assert(layer < 6);
|
||||
return m_srgb[layer];
|
||||
} // isSrgbForTextureLayer
|
||||
|
||||
}
|
||||
|
@ -27,12 +27,14 @@
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <SMaterial.h>
|
||||
|
||||
namespace SP
|
||||
{
|
||||
|
||||
@ -53,8 +55,8 @@ enum SamplerType: unsigned int
|
||||
enum RenderPass: unsigned int
|
||||
{
|
||||
RP_1ST = 0,
|
||||
RP_2ND,
|
||||
RP_SHADOW,
|
||||
RP_RESERVED,
|
||||
RP_COUNT
|
||||
};
|
||||
|
||||
@ -64,10 +66,10 @@ inline std::ostream& operator<<(std::ostream& os, const RenderPass& rp)
|
||||
{
|
||||
case RP_1ST:
|
||||
return os << "first pass";
|
||||
case RP_2ND:
|
||||
return os << "second pass";
|
||||
case RP_SHADOW:
|
||||
return os << "shadow pass";
|
||||
case RP_RESERVED:
|
||||
return os << "reserved pass";
|
||||
default:
|
||||
return os;
|
||||
}
|
||||
@ -80,46 +82,56 @@ class SPShader : public NoCopy, public SPPerObjectUniform
|
||||
private:
|
||||
std::string m_name;
|
||||
|
||||
std::vector<std::shared_ptr<GLuint> > m_shader_files;
|
||||
|
||||
GLuint m_program[RP_COUNT];
|
||||
|
||||
std::vector<std::pair<unsigned, unsigned> > m_samplers[RP_COUNT];
|
||||
std::map<unsigned, unsigned> m_samplers[RP_COUNT];
|
||||
|
||||
std::vector<std::tuple<unsigned, std::string, SamplerType,
|
||||
GLuint> >m_prefilled_samplers[RP_COUNT];
|
||||
|
||||
std::unordered_map<std::string, SPUniformAssigner*>
|
||||
m_uniforms[RP_COUNT];
|
||||
std::unordered_map<std::string, SPUniformAssigner*> m_uniforms[RP_COUNT];
|
||||
|
||||
std::unordered_map<std::string, std::function<GLuint()> >
|
||||
m_custom_prefilled_getter[RP_COUNT];
|
||||
|
||||
std::function<void()> m_use_function[RP_COUNT], m_unuse_function[RP_COUNT];
|
||||
|
||||
const std::function<void(SPShader*)> m_init_function;
|
||||
|
||||
const int m_drawing_priority;
|
||||
|
||||
const bool m_transparent_shader;
|
||||
|
||||
const bool m_use_alpha_channel;
|
||||
|
||||
const bool m_use_tangents;
|
||||
|
||||
const std::array<bool, 6> m_srgb;
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader(const std::string& name, unsigned pass_count = 3,
|
||||
SPShader(const std::string& name,
|
||||
const std::function<void(SPShader*)>& init_func,
|
||||
bool transparent_shader = false, int drawing_priority = 0,
|
||||
bool use_alpha_channel = false)
|
||||
: m_name(name), m_drawing_priority(drawing_priority),
|
||||
bool use_alpha_channel = false, bool use_tangents = false,
|
||||
const std::array<bool, 6>& srgb =
|
||||
{{ true, true, false, false, false, false }})
|
||||
: m_name(name), m_init_function(init_func),
|
||||
m_drawing_priority(drawing_priority),
|
||||
m_transparent_shader(transparent_shader),
|
||||
m_use_alpha_channel(use_alpha_channel || transparent_shader)
|
||||
m_use_alpha_channel(use_alpha_channel),
|
||||
m_use_tangents(use_tangents), m_srgb(srgb)
|
||||
{
|
||||
memset(m_program, 0, 12);
|
||||
#ifndef SERVER_ONLY
|
||||
for (unsigned rp = RP_1ST; rp < pass_count; rp++)
|
||||
{
|
||||
m_program[rp] = glCreateProgram();
|
||||
}
|
||||
#endif
|
||||
m_init_function(this);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
~SPShader();
|
||||
~SPShader()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
bool hasShader(RenderPass rp) { return m_program[rp] != 0; }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -154,10 +166,10 @@ public:
|
||||
std::function<GLuint()> func,
|
||||
RenderPass rp = RP_1ST);
|
||||
// ------------------------------------------------------------------------
|
||||
void bindPrefilledTextures(RenderPass rp = RP_1ST);
|
||||
void bindPrefilledTextures(RenderPass rp = RP_1ST) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void bindTextures(const std::array<GLuint, 6>& tex,
|
||||
RenderPass rp = RP_1ST);
|
||||
RenderPass rp = RP_1ST) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void addBasicUniforms(RenderPass rp = RP_1ST)
|
||||
{
|
||||
@ -170,21 +182,15 @@ public:
|
||||
block_index = glGetUniformBlockIndex(m_program[rp], "SPFogData");
|
||||
if (block_index != GL_INVALID_INDEX)
|
||||
glUniformBlockBinding(m_program[rp], block_index, 2);
|
||||
#ifndef USE_GLES2
|
||||
// Assign framebuffer output
|
||||
glBindFragDataLocation(m_program[rp], 0, "o_diffuse_color");
|
||||
glBindFragDataLocation(m_program[rp], 1, "o_normal_depth");
|
||||
glBindFragDataLocation(m_program[rp], 2, "o_gloss_map");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getName() const { return m_name; }
|
||||
// ------------------------------------------------------------------------
|
||||
SPUniformAssigner* getUniformAssigner(const std::string& name,
|
||||
RenderPass rp = RP_1ST);
|
||||
RenderPass rp = RP_1ST) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void addUniform(const std::string& name, const std::type_info& ti,
|
||||
void addUniform(const std::string& name, const std::type_index& ti,
|
||||
RenderPass rp = RP_1ST);
|
||||
// ------------------------------------------------------------------------
|
||||
void setUniformsPerObject(SPPerObjectUniform* sppou,
|
||||
@ -209,7 +215,33 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
bool samplerLess(RenderPass rp = RP_1ST) const
|
||||
{ return m_samplers[rp].empty(); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void unload();
|
||||
// ------------------------------------------------------------------------
|
||||
void init()
|
||||
{
|
||||
if (!m_shader_files.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_init_function(this);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
bool isSrgbForTextureLayer(unsigned layer) const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool useTangents() const { return m_use_tangents; }
|
||||
// ------------------------------------------------------------------------
|
||||
bool hasTextureLayer(unsigned layer)
|
||||
{
|
||||
for (unsigned rp = RP_1ST; rp < RP_COUNT; rp++)
|
||||
{
|
||||
if (m_samplers[rp].find(layer) != m_samplers[rp].end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
611
src/graphics/sp/sp_shader_manager.cpp
Normal file
611
src/graphics/sp/sp_shader_manager.cpp
Normal file
@ -0,0 +1,611 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 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 "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_texture.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "graphics/sp/sp_uniform_assigner.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace SP
|
||||
{
|
||||
SPShaderManager* SPShaderManager::m_spsm = NULL;
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShaderManager::SPShaderManager()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_official_types =
|
||||
{
|
||||
{ "int", std::type_index(typeid(int)) },
|
||||
{ "float", std::type_index(typeid(float)) },
|
||||
{ "mat4", std::type_index(typeid(irr::core::matrix4)) },
|
||||
{ "vec4", std::type_index(typeid(std::array<float, 4>)) },
|
||||
{ "vec3", std::type_index(typeid(irr::core::vector3df)) },
|
||||
{ "vec2", std::type_index(typeid(irr::core::vector2df)) }
|
||||
};
|
||||
|
||||
m_official_sampler_types =
|
||||
{
|
||||
{ "nearest", ST_NEAREST },
|
||||
{ "nearest_clamped", ST_NEAREST_CLAMPED },
|
||||
{ "bilinear", ST_BILINEAR },
|
||||
{ "bilinear_clamped", ST_BILINEAR_CLAMPED },
|
||||
{ "trilinear", ST_TRILINEAR },
|
||||
{ "trilinear_clamped", ST_TRILINEAR_CLAMPED },
|
||||
{ "semi_trilinear", ST_SEMI_TRILINEAR }
|
||||
};
|
||||
|
||||
m_official_uniform_assigner_functions =
|
||||
{
|
||||
{ "shadowCascadeUniformAssigner", [](SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(sp_cur_shadow_cascade);
|
||||
}
|
||||
},
|
||||
{ "windDirectionUniformAssigner", [](SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(sp_wind_dir);
|
||||
}
|
||||
},
|
||||
{ "zeroAlphaUniformAssigner", [](SPUniformAssigner* ua)
|
||||
{
|
||||
ua->setValue(0.0f);
|
||||
}
|
||||
},
|
||||
{ "fogUniformAssigner", [](SPUniformAssigner* ua)
|
||||
{
|
||||
int fog_enable = Track::getCurrentTrack() ?
|
||||
Track::getCurrentTrack()->isFogEnabled() ? 1 : 0 : 0;
|
||||
ua->setValue(fog_enable);
|
||||
}
|
||||
},
|
||||
{ "ghostAlphaUniformAssigner", [](SPUniformAssigner* ua)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
if (Track::getCurrentTrack())
|
||||
{
|
||||
const video::SColor& c = Track::getCurrentTrack()
|
||||
->getSunColor();
|
||||
float y = 0.2126f * c.getRed() + 0.7152f * c.getGreen() +
|
||||
0.0722f * c.getBlue();
|
||||
alpha = y > 128.0f ? 0.5f : 0.35f;
|
||||
}
|
||||
ua->setValue(alpha);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
m_official_use_functions =
|
||||
{
|
||||
{ "alphaBlendUse", []()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
},
|
||||
{ "additiveUse", []()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
}
|
||||
},
|
||||
{ "ghostUse", []()
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
} // SPShaderManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
SPShaderManager::~SPShaderManager()
|
||||
{
|
||||
m_official_shaders.clear();
|
||||
removeUnusedShaders();
|
||||
#ifdef DEBUG
|
||||
for (auto p : m_shaders)
|
||||
{
|
||||
Log::error("SPShaderManager", "%s > 1 ref_count", p.first.c_str());
|
||||
}
|
||||
#endif
|
||||
} // ~SPShaderManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::loadEachShader(const std::string& file_name)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
std::unique_ptr<XMLNode> xml(file_manager->createXMLTree(file_name));
|
||||
if (!xml || xml->getName() != "spshader")
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid SPShader file %s",
|
||||
file_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
ShaderInfo si;
|
||||
|
||||
const XMLNode* shader_info = xml->getNode("shader-info");
|
||||
if (!shader_info)
|
||||
{
|
||||
Log::error("SPShaderManager", "Missing shader-info header in file %s",
|
||||
file_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
shader_info->get("name", &si.m_shader_name);
|
||||
if (si.m_shader_name.empty())
|
||||
{
|
||||
Log::error("SPShaderManager", "Empty shader name in file %s",
|
||||
file_name.c_str());
|
||||
return;
|
||||
}
|
||||
else if (si.m_shader_name.find("_skinned") != std::string::npos)
|
||||
{
|
||||
Log::error("SPShaderManager", "_skinned name is reserved for auto"
|
||||
" skinned mesh shader adding");
|
||||
return;
|
||||
}
|
||||
else if (getSPShader(si.m_shader_name))
|
||||
{
|
||||
Log::error("SPShaderManager", "%s shader already exists",
|
||||
si.m_shader_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
shader_info->get("fallback-shader", &si.m_fallback_name);
|
||||
shader_info->get("transparent", &si.m_transparent_shader);
|
||||
shader_info->get("drawing-priority", &si.m_drawing_priority);
|
||||
shader_info->get("use-alpha-channel", &si.m_use_alpha_channel);
|
||||
shader_info->get("use-tangents", &si.m_use_tangents);
|
||||
std::string srgb_prop;
|
||||
shader_info->get("srgb", &srgb_prop);
|
||||
std::vector<std::string> srgb_props = StringUtils::split(srgb_prop, ' ');
|
||||
if (srgb_props.size() == 6)
|
||||
{
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
si.m_srgb[i] = srgb_props[i] == "Y";
|
||||
}
|
||||
}
|
||||
else if (!srgb_prop.empty())
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid srgb properties in shader");
|
||||
}
|
||||
|
||||
std::array<PassInfo, 2> pi;
|
||||
loadPassInfo(xml->getNode("first-pass"), pi[0]);
|
||||
if (!si.m_transparent_shader && CVS->isDefferedEnabled())
|
||||
{
|
||||
loadPassInfo(xml->getNode("shadow-pass"), pi[1]);
|
||||
}
|
||||
if (pi[0].m_vertex_shader.empty())
|
||||
{
|
||||
Log::error("SPShaderManager", "Missing first pass vertex shader in"
|
||||
" file %s", file_name.c_str());
|
||||
return;
|
||||
}
|
||||
if (!si.m_fallback_name.empty() && !CVS->isDefferedEnabled())
|
||||
{
|
||||
std::shared_ptr<SPShader> fallback_shader =
|
||||
getSPShader(si.m_fallback_name);
|
||||
if (!fallback_shader)
|
||||
{
|
||||
Log::error("SPShaderManager", "%s fallback shader missing",
|
||||
si.m_fallback_name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
addSPShader(si.m_shader_name, fallback_shader);
|
||||
if (!pi[0].m_skinned_mesh_shader.empty())
|
||||
{
|
||||
std::shared_ptr<SPShader> fallback_skinned_shader =
|
||||
getSPShader(si.m_fallback_name + "_skinned");
|
||||
if (!fallback_skinned_shader)
|
||||
{
|
||||
Log::error("SPShaderManager", "%s fallback skinned mesh"
|
||||
" shader missing", si.m_fallback_name.c_str());
|
||||
}
|
||||
addSPShader(si.m_shader_name + "_skinned",
|
||||
fallback_skinned_shader);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
UniformAssigners ua;
|
||||
const XMLNode* uniform_assigners = xml->getNode("uniform-assigners");
|
||||
if (uniform_assigners)
|
||||
{
|
||||
for (unsigned i = 0; i < uniform_assigners->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* uniform_assigner = uniform_assigners->getNode(i);
|
||||
if (uniform_assigner->getName() == "uniform-assigner")
|
||||
{
|
||||
std::string name, function;
|
||||
uniform_assigner->get("name", &name);
|
||||
uniform_assigner->get("function", &function);
|
||||
if (!name.empty() && !function.empty() &&
|
||||
m_official_uniform_assigner_functions.find(function) !=
|
||||
m_official_uniform_assigner_functions.end())
|
||||
{
|
||||
ua.emplace_back(name, m_official_uniform_assigner_functions
|
||||
.at(function));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid uniform assigner"
|
||||
" %s", function.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addSPShader(si.m_shader_name, buildSPShader(si, pi, ua, false/*skinned*/));
|
||||
if (!pi[0].m_skinned_mesh_shader.empty())
|
||||
{
|
||||
addSPShader(si.m_shader_name + "_skinned", buildSPShader(si, pi, ua,
|
||||
true/*skinned*/));
|
||||
}
|
||||
#endif
|
||||
} // loadEachShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::loadPassInfo(const XMLNode* pass, PassInfo& pi)
|
||||
{
|
||||
if (!pass)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string use_function, unuse_function;
|
||||
pass->get("use-function", &use_function);
|
||||
if (!use_function.empty() && m_official_use_functions.find(use_function) !=
|
||||
m_official_use_functions.end())
|
||||
{
|
||||
pi.m_use_function = m_official_use_functions.at(use_function);
|
||||
}
|
||||
|
||||
pass->get("unuse-function", &unuse_function);
|
||||
if (!unuse_function.empty() &&
|
||||
m_official_unuse_functions.find(unuse_function) !=
|
||||
m_official_unuse_functions.end())
|
||||
{
|
||||
pi.m_unuse_function = m_official_unuse_functions.at(unuse_function);
|
||||
}
|
||||
|
||||
pass->get("vertex-shader", &pi.m_vertex_shader);
|
||||
pi.m_vertex_shader = getShaderFullPath(pi.m_vertex_shader);
|
||||
|
||||
pass->get("fragment-shader", &pi.m_fragment_shader);
|
||||
pi.m_fragment_shader = getShaderFullPath(pi.m_fragment_shader);
|
||||
|
||||
pass->get("skinned-mesh-shader", &pi.m_skinned_mesh_shader);
|
||||
pi.m_skinned_mesh_shader = getShaderFullPath(pi.m_skinned_mesh_shader);
|
||||
|
||||
const XMLNode* uniforms = pass->getNode("uniforms");
|
||||
if (uniforms)
|
||||
{
|
||||
for (unsigned i = 0; i < uniforms->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* uniform = uniforms->getNode(i);
|
||||
if (uniform->getName() == "uniform")
|
||||
{
|
||||
std::string name, type;
|
||||
uniform->get("name", &name);
|
||||
uniform->get("type", &type);
|
||||
if (!name.empty() && !type.empty() &&
|
||||
m_official_types.find(type) != m_official_types.end())
|
||||
{
|
||||
pi.m_uniforms.emplace_back(name,
|
||||
m_official_types.at(type));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid uniform type %s",
|
||||
type.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const XMLNode* prefilled_textures = pass->getNode("prefilled-textures");
|
||||
if (prefilled_textures)
|
||||
{
|
||||
for (unsigned i = 0; i < prefilled_textures->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* prefilled_texture = prefilled_textures->getNode(i);
|
||||
if (prefilled_texture->getName() == "prefilled-texture")
|
||||
{
|
||||
bool srgb = false;
|
||||
SamplerType st = ST_TRILINEAR;
|
||||
std::string name, file, srgb_props, sampler_props;
|
||||
prefilled_texture->get("name", &name);
|
||||
prefilled_texture->get("file", &file);
|
||||
prefilled_texture->get("srgb", &srgb_props);
|
||||
#ifndef SERVER_ONLY
|
||||
if (!srgb_props.empty())
|
||||
{
|
||||
srgb = srgb_props == "Y" && CVS->isDefferedEnabled();
|
||||
}
|
||||
#endif
|
||||
prefilled_texture->get("sampler", &sampler_props);
|
||||
if (!sampler_props.empty() &&
|
||||
m_official_sampler_types.find(sampler_props) !=
|
||||
m_official_sampler_types.end())
|
||||
{
|
||||
st = m_official_sampler_types.at(sampler_props);
|
||||
}
|
||||
if (!name.empty() && !file.empty())
|
||||
{
|
||||
pi.m_prefilled_textures.emplace_back(name, file, srgb, st);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("SPShaderManager", "Invalid prefilled texture");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // loadPassInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string SPShaderManager::getShaderFullPath(const std::string& name)
|
||||
{
|
||||
if (name.empty())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
std::string cur_location = m_shader_directory + name;
|
||||
if (file_manager->fileExists(cur_location))
|
||||
{
|
||||
return cur_location;
|
||||
}
|
||||
cur_location = file_manager->getAssetChecked(FileManager::SHADER, name);
|
||||
if (cur_location.empty())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return file_manager->getFileSystem()->getAbsolutePath(cur_location.c_str())
|
||||
.c_str();
|
||||
} // getShaderFullPath
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
std::shared_ptr<SPShader> SPShaderManager::buildSPShader(const ShaderInfo& si,
|
||||
const std::array<PassInfo, 2>& pi, const UniformAssigners& ua,
|
||||
bool skinned)
|
||||
{
|
||||
std::shared_ptr<SPShader> sps;
|
||||
#ifndef SERVER_ONLY
|
||||
sps = std::make_shared<SPShader>(si.m_shader_name,
|
||||
[pi, ua, skinned](SPShader* shader)
|
||||
{
|
||||
// First pass
|
||||
assert(!pi[0].m_vertex_shader.empty() ||
|
||||
(skinned && !pi[0].m_skinned_mesh_shader.empty()));
|
||||
|
||||
SPPerObjectUniform* pou = static_cast<SPPerObjectUniform*>(shader);
|
||||
for (auto& p : ua)
|
||||
{
|
||||
pou->addAssignerFunction(p.first, p.second);
|
||||
}
|
||||
|
||||
shader->addShaderFile(skinned ?
|
||||
pi[0].m_skinned_mesh_shader : pi[0].m_vertex_shader,
|
||||
GL_VERTEX_SHADER, RP_1ST);
|
||||
if (!pi[0].m_fragment_shader.empty())
|
||||
{
|
||||
shader->addShaderFile(pi[0].m_fragment_shader,
|
||||
GL_FRAGMENT_SHADER, RP_1ST);
|
||||
}
|
||||
shader->linkShaderFiles(RP_1ST);
|
||||
shader->use(RP_1ST);
|
||||
shader->addBasicUniforms(RP_1ST);
|
||||
addUniformsToShader(shader, pi[0].m_uniforms, RP_1ST);
|
||||
if (pi[0].m_use_function)
|
||||
{
|
||||
shader->setUseFunction(pi[0].m_use_function, RP_1ST);
|
||||
}
|
||||
if (pi[0].m_unuse_function)
|
||||
{
|
||||
shader->setUnuseFunction(pi[0].m_unuse_function, RP_1ST);
|
||||
}
|
||||
addPrefilledTexturesToShader(shader, pi[0].m_prefilled_textures,
|
||||
RP_1ST);
|
||||
shader->addAllTextures(RP_1ST);
|
||||
|
||||
if (pi[1].m_vertex_shader.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Shadow pass
|
||||
if (skinned && pi[1].m_skinned_mesh_shader.empty())
|
||||
{
|
||||
Log::warn("SPShader", "Missing skinned mesh vertex shader in"
|
||||
" shadow pass");
|
||||
return;
|
||||
}
|
||||
shader->addShaderFile(skinned ?
|
||||
pi[1].m_skinned_mesh_shader : pi[1].m_vertex_shader,
|
||||
GL_VERTEX_SHADER, RP_SHADOW);
|
||||
if (!pi[1].m_fragment_shader.empty())
|
||||
{
|
||||
shader->addShaderFile(pi[1].m_fragment_shader,
|
||||
GL_FRAGMENT_SHADER, RP_SHADOW);
|
||||
}
|
||||
shader->linkShaderFiles(RP_SHADOW);
|
||||
shader->use(RP_SHADOW);
|
||||
shader->addBasicUniforms(RP_SHADOW);
|
||||
addUniformsToShader(shader, pi[1].m_uniforms, RP_SHADOW);
|
||||
if (pi[1].m_use_function)
|
||||
{
|
||||
shader->setUseFunction(pi[1].m_use_function, RP_SHADOW);
|
||||
}
|
||||
if (pi[1].m_unuse_function)
|
||||
{
|
||||
shader->setUnuseFunction(pi[1].m_unuse_function, RP_SHADOW);
|
||||
}
|
||||
addPrefilledTexturesToShader(shader, pi[1].m_prefilled_textures,
|
||||
RP_SHADOW);
|
||||
shader->addAllTextures(RP_SHADOW);
|
||||
}, si.m_transparent_shader, si.m_drawing_priority,
|
||||
si.m_use_alpha_channel, si.m_use_tangents, si.m_srgb);
|
||||
#endif
|
||||
return sps;
|
||||
} // buildSPShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::addUniformsToShader(SPShader* s,
|
||||
const std::vector<std::pair<std::string, std::type_index> >& u,
|
||||
RenderPass rp)
|
||||
{
|
||||
for (auto& p : u)
|
||||
{
|
||||
s->addUniform(p.first, p.second, rp);
|
||||
}
|
||||
} // addUniformsToShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::addPrefilledTexturesToShader(SPShader* s,
|
||||
const std::vector<std::tuple<std::string, std::string, bool, SamplerType> >
|
||||
&t, RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
for (auto& p : t)
|
||||
{
|
||||
std::string full_path;
|
||||
const std::string& relative_path =
|
||||
file_manager->searchTexture(std::get<1>(p)/*filename*/);
|
||||
if (relative_path.empty())
|
||||
{
|
||||
Log::warn("SPShader", "Cannot determine prefilled texture full"
|
||||
" path: %s", std::get<1>(p).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
full_path = file_manager->getFileSystem()->getAbsolutePath
|
||||
(relative_path.c_str()).c_str();
|
||||
}
|
||||
if (!full_path.empty())
|
||||
{
|
||||
std::string cid;
|
||||
if (!file_manager->searchTextureContainerId(cid, std::get<1>(p)))
|
||||
{
|
||||
Log::warn("SPShader", "Missing container id for %s, no texture"
|
||||
" compression for it will be done.",
|
||||
std::get<1>(p).c_str());
|
||||
}
|
||||
std::shared_ptr<SPTexture> pt = SPTextureManager::get()
|
||||
->getTexture(full_path, NULL/*material*/, std::get<2>(p), cid);
|
||||
s->addCustomPrefilledTextures(std::get<3>(p)/*sampler_type*/,
|
||||
GL_TEXTURE_2D, std::get<0>(p)/*name_in_shader*/, [pt]()->GLuint
|
||||
{
|
||||
return pt->getOpenGLTextureName();
|
||||
}, rp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // addPrefilledTexturesToShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::loadSPShaders(const std::string& directory_name)
|
||||
{
|
||||
std::set<std::string> shaders;
|
||||
file_manager->listFiles(shaders, directory_name);
|
||||
for (auto it = shaders.begin(); it != shaders.end();)
|
||||
{
|
||||
if ((*it).find("sps") == std::string::npos ||
|
||||
(*it).find(".xml") == std::string::npos)
|
||||
{
|
||||
it = shaders.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
if (shaders.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_shader_directory = file_manager->getFileSystem()->getAbsolutePath
|
||||
(directory_name.c_str()).c_str();
|
||||
for (const std::string& file_name : shaders)
|
||||
{
|
||||
loadEachShader(m_shader_directory + file_name);
|
||||
}
|
||||
m_shader_directory = "";
|
||||
} // loadSPShaders
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::unloadAll()
|
||||
{
|
||||
for (auto& p : m_shaders)
|
||||
{
|
||||
p.second->unload();
|
||||
}
|
||||
} // unloadAll
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::initAll()
|
||||
{
|
||||
for (auto& p : m_shaders)
|
||||
{
|
||||
p.second->init();
|
||||
}
|
||||
} // initAll
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShaderManager::removeUnusedShaders()
|
||||
{
|
||||
for (auto it = m_shaders.begin(); it != m_shaders.end();)
|
||||
{
|
||||
if (it->second.use_count() == 1)
|
||||
{
|
||||
it = m_shaders.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
} // removeUnusedShaders
|
||||
|
||||
}
|
182
src/graphics/sp/sp_shader_manager.hpp
Normal file
182
src/graphics/sp/sp_shader_manager.hpp
Normal file
@ -0,0 +1,182 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2018 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.
|
||||
|
||||
#ifndef HEADER_SP_SHADER_MANAGER_HPP
|
||||
#define HEADER_SP_SHADER_MANAGER_HPP
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
class XMLNode;
|
||||
namespace SP
|
||||
{
|
||||
class SPShader;
|
||||
class SPUniformAssigner;
|
||||
|
||||
enum SamplerType: unsigned int;
|
||||
enum RenderPass: unsigned int;
|
||||
|
||||
class SPShaderManager : public NoCopy
|
||||
{
|
||||
public:
|
||||
|
||||
struct PassInfo
|
||||
{
|
||||
std::function<void()> m_use_function;
|
||||
|
||||
std::function<void()> m_unuse_function;
|
||||
|
||||
std::string m_vertex_shader;
|
||||
|
||||
std::string m_fragment_shader;
|
||||
|
||||
std::string m_skinned_mesh_shader;
|
||||
|
||||
std::vector<std::pair<std::string, std::type_index> > m_uniforms;
|
||||
|
||||
std::vector<std::tuple<std::string, std::string, bool, SamplerType> >
|
||||
m_prefilled_textures;
|
||||
};
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair< std::string, std::function<void
|
||||
(SPUniformAssigner*)> > > UniformAssigners;
|
||||
struct ShaderInfo
|
||||
{
|
||||
std::string m_shader_name, m_fallback_name;
|
||||
|
||||
int m_drawing_priority = 0;
|
||||
|
||||
bool m_transparent_shader = false;
|
||||
|
||||
bool m_use_alpha_channel = false;
|
||||
|
||||
bool m_use_tangents = false;
|
||||
|
||||
std::array<bool, 6> m_srgb =
|
||||
{{
|
||||
true, true, false, false, false, false
|
||||
}};
|
||||
};
|
||||
|
||||
static SPShaderManager* m_spsm;
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<SPShader> > m_shaders;
|
||||
|
||||
std::vector<std::shared_ptr<SPShader> > m_official_shaders;
|
||||
|
||||
std::unordered_map<std::string, std::type_index> m_official_types;
|
||||
|
||||
std::unordered_map<std::string, SamplerType> m_official_sampler_types;
|
||||
|
||||
std::unordered_map<std::string, std::function<void(SPUniformAssigner*)> >
|
||||
m_official_uniform_assigner_functions;
|
||||
|
||||
std::unordered_map<std::string, std::function<void()> >
|
||||
m_official_use_functions;
|
||||
|
||||
std::unordered_map<std::string, std::function<void()> >
|
||||
m_official_unuse_functions;
|
||||
|
||||
std::string m_shader_directory;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
std::string getShaderFullPath(const std::string& name);
|
||||
// ------------------------------------------------------------------------
|
||||
void loadPassInfo(const XMLNode* pass, PassInfo& pi);
|
||||
// ------------------------------------------------------------------------
|
||||
void loadEachShader(const std::string& file_name);
|
||||
// ------------------------------------------------------------------------
|
||||
std::shared_ptr<SPShader> buildSPShader(const ShaderInfo& si,
|
||||
const std::array<PassInfo, 2>& pi,
|
||||
const UniformAssigners& ua,
|
||||
bool skinned);
|
||||
// ------------------------------------------------------------------------
|
||||
static void addUniformsToShader(SPShader* s,
|
||||
const std::vector<std::pair<std::string, std::type_index> >& u,
|
||||
RenderPass rp);
|
||||
// ------------------------------------------------------------------------
|
||||
static void addPrefilledTexturesToShader(SPShader* s,
|
||||
const std::vector<std::tuple<std::string, std::string, bool,
|
||||
SamplerType> >& t, RenderPass rp);
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
static SPShaderManager* get()
|
||||
{
|
||||
if (m_spsm == NULL)
|
||||
{
|
||||
m_spsm = new SPShaderManager();
|
||||
}
|
||||
return m_spsm;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
static void destroy()
|
||||
{
|
||||
delete m_spsm;
|
||||
m_spsm = NULL;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
SPShaderManager();
|
||||
// ------------------------------------------------------------------------
|
||||
~SPShaderManager();
|
||||
// ------------------------------------------------------------------------
|
||||
std::shared_ptr<SPShader> getSPShader(const std::string& name)
|
||||
{
|
||||
auto ret = m_shaders.find(name);
|
||||
if (ret != m_shaders.end())
|
||||
{
|
||||
return ret->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void loadSPShaders(const std::string& directory_name);
|
||||
// ------------------------------------------------------------------------
|
||||
void addSPShader(const std::string& name,
|
||||
std::shared_ptr<SPShader> shader)
|
||||
{
|
||||
m_shaders[name] = shader;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void unloadAll();
|
||||
// ------------------------------------------------------------------------
|
||||
void initAll();
|
||||
// ------------------------------------------------------------------------
|
||||
void removeUnusedShaders();
|
||||
// ------------------------------------------------------------------------
|
||||
void setOfficialShaders()
|
||||
{
|
||||
for (auto& p : m_shaders)
|
||||
{
|
||||
m_official_shaders.push_back(p.second);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -19,9 +19,10 @@
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_shader.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
@ -121,6 +122,7 @@ std::shared_ptr<video::IImage> SPTexture::getImageFromPath
|
||||
if (img_loader == NULL)
|
||||
{
|
||||
Log::error("SPTexture", "No image loader for %s", path.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
io::IReadFile* file = irr::io::createReadFile(path.c_str());
|
||||
@ -440,17 +442,19 @@ bool SPTexture::threadedLoad()
|
||||
}
|
||||
|
||||
std::shared_ptr<video::IImage> image = getTextureImage();
|
||||
if (!image)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::shared_ptr<video::IImage> mask = getMask(image->getDimension());
|
||||
if (mask && image)
|
||||
if (mask)
|
||||
{
|
||||
applyMask(image.get(), mask.get());
|
||||
}
|
||||
std::shared_ptr<video::IImage> mipmaps;
|
||||
|
||||
if (!m_cache_directory.empty() &&
|
||||
CVS->isTextureCompressionEnabled() && image &&
|
||||
image->getDimension().Width >= 4 &&
|
||||
image->getDimension().Height >= 4)
|
||||
if (!m_cache_directory.empty() && CVS->isTextureCompressionEnabled() &&
|
||||
image->getDimension().Width >= 4 && image->getDimension().Height >= 4)
|
||||
{
|
||||
auto r = compressTexture(image);
|
||||
SPTextureManager::get()->increaseGLCommandFunctionCount(1);
|
||||
@ -469,8 +473,7 @@ bool SPTexture::threadedLoad()
|
||||
else
|
||||
{
|
||||
#ifndef USE_GLES2
|
||||
if (UserConfigParams::m_hq_mipmap && image &&
|
||||
image->getDimension().Width > 1 &&
|
||||
if (UserConfigParams::m_hq_mipmap && image->getDimension().Width > 1 &&
|
||||
image->getDimension().Height > 1)
|
||||
{
|
||||
std::vector<std::pair<core::dimension2du, unsigned> >
|
||||
@ -522,7 +525,9 @@ std::shared_ptr<video::IImage>
|
||||
{
|
||||
// Load colorization mask
|
||||
std::shared_ptr<video::IImage> mask;
|
||||
if (SP::getSPShader(m_material->getShaderName())->useAlphaChannel())
|
||||
std::shared_ptr<SPShader> sps =
|
||||
SPShaderManager::get()->getSPShader(m_material->getShaderName());
|
||||
if (sps && sps->useAlphaChannel())
|
||||
{
|
||||
Log::debug("SPTexture", "Don't use colorization mask or factor"
|
||||
" with shader using alpha channel for %s", m_path.c_str());
|
||||
@ -675,7 +680,7 @@ void SPTexture::generateHQMipmap(void* in,
|
||||
imMipmapCascade cascade;
|
||||
imReduceOptions options;
|
||||
imReduceSetOptions(&options,
|
||||
m_path.find("_nm.") != std::string::npos ?
|
||||
m_path.find("_Normal.") != std::string::npos ?
|
||||
IM_REDUCE_FILTER_NORMALMAP: IM_REDUCE_FILTER_LINEAR/*filter*/,
|
||||
2/*hopcount*/, 2.0f/*alpha*/, 1.0f/*amplifynormal*/,
|
||||
0.0f/*normalsustainfactor*/);
|
||||
|
@ -77,8 +77,6 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void applyMask(video::IImage* texture, video::IImage* mask);
|
||||
// ------------------------------------------------------------------------
|
||||
void addTextureHandle();
|
||||
// ------------------------------------------------------------------------
|
||||
void createTransparent()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
|
@ -88,6 +88,13 @@ SPTextureManager::~SPTextureManager()
|
||||
t.join();
|
||||
}
|
||||
m_threaded_load_obj.clear();
|
||||
removeUnusedTextures();
|
||||
#ifdef DEBUG
|
||||
for (auto p : m_textures)
|
||||
{
|
||||
Log::error("SPTextureManager", "%s > 1 ref_count", p.first.c_str());
|
||||
}
|
||||
#endif
|
||||
} // ~SPTextureManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -169,14 +176,68 @@ void SPTextureManager::removeUnusedTextures()
|
||||
} // removeUnusedTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPTextureManager::dumpAllTexture()
|
||||
void SPTextureManager::dumpAllTextures()
|
||||
{
|
||||
for (auto p : m_textures)
|
||||
{
|
||||
Log::info("STKTexManager", "%s size: %0.2fK", p.first.c_str(),
|
||||
(p.second->getWidth() * p.second->getHeight() * 4) / 1024.0f);
|
||||
Log::info("SPTextureManager", "%s", p.first.c_str());
|
||||
}
|
||||
} // dumpAllTexture
|
||||
} // dumpAllTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
core::stringw SPTextureManager::reloadTexture(const core::stringw& name)
|
||||
{
|
||||
core::stringw result;
|
||||
#ifndef SERVER_ONLY
|
||||
if (name.empty())
|
||||
{
|
||||
for (auto p : m_textures)
|
||||
{
|
||||
if (p.second->getPath().empty() ||
|
||||
p.second->getPath() == "unicolor_white")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
addThreadedFunction(std::bind(&SPTexture::threadedLoad, p.second));
|
||||
Log::info("SPTextureManager", "%s reloaded",
|
||||
p.second->getPath().c_str());
|
||||
}
|
||||
return L"All textures reloaded.";
|
||||
}
|
||||
|
||||
core::stringw list = name;
|
||||
list.make_lower().replace(L'\u005C', L'\u002F');
|
||||
std::vector<std::string> names =
|
||||
StringUtils::split(StringUtils::wideToUtf8(list), ';');
|
||||
for (const std::string& fname : names)
|
||||
{
|
||||
for (auto p : m_textures)
|
||||
{
|
||||
if (p.second->getPath().empty() ||
|
||||
p.second->getPath() == "unicolor_white")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
std::string tex_path =
|
||||
StringUtils::toLowerCase(p.second->getPath());
|
||||
std::string tex_name = StringUtils::getBasename(tex_path);
|
||||
if (fname == tex_name || fname == tex_path)
|
||||
{
|
||||
addThreadedFunction(std::bind(&SPTexture::threadedLoad,
|
||||
p.second));
|
||||
result += tex_name.c_str();
|
||||
result += L" ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.empty())
|
||||
{
|
||||
return L"Texture(s) not found!";
|
||||
}
|
||||
#endif // !SERVER_ONLY
|
||||
return result + "reloaded.";
|
||||
} // reloadTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}
|
||||
|
@ -29,12 +29,13 @@
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "irrString.h"
|
||||
|
||||
class Material;
|
||||
|
||||
@ -47,7 +48,7 @@ class SPTextureManager : public NoCopy
|
||||
private:
|
||||
static SPTextureManager* m_sptm;
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<SPTexture> > m_textures;
|
||||
std::map<std::string, std::shared_ptr<SPTexture> > m_textures;
|
||||
|
||||
std::atomic_uint m_max_threaded_load_obj;
|
||||
|
||||
@ -108,9 +109,9 @@ public:
|
||||
Material* m, bool undo_srgb,
|
||||
const std::string& container_id);
|
||||
// ------------------------------------------------------------------------
|
||||
int dumpTextureUsage();
|
||||
void dumpAllTextures();
|
||||
// ------------------------------------------------------------------------
|
||||
void dumpAllTexture();
|
||||
irr::core::stringw reloadTexture(const irr::core::stringw& name);
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "utils/log.hpp"
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
#include <array>
|
||||
#include <string>
|
||||
@ -49,7 +50,7 @@ private:
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
SPUniformAssigner(const std::type_info& ti, GLuint location)
|
||||
SPUniformAssigner(const std::type_index& ti, GLuint location)
|
||||
: m_location(location), m_type(ti), m_assigned(false) {}
|
||||
// ------------------------------------------------------------------------
|
||||
bool rumtimeChecking(const std::type_info& ti) const
|
||||
@ -186,6 +187,10 @@ public:
|
||||
{
|
||||
glUniform1i(m_location, 0);
|
||||
}
|
||||
else if (m_type == typeid(std::array<float, 4>))
|
||||
{
|
||||
glUniform4f(m_location, 0.0f, 0.0f, 0.0f,0.0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -152,81 +152,6 @@ void STKTexManager::removeTexture(STKTexture* texture, bool remove_all)
|
||||
#endif
|
||||
} // removeTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTexManager::dumpAllTexture(bool mesh_texture)
|
||||
{
|
||||
for (auto p : m_all_textures)
|
||||
{
|
||||
if (!p.second || (mesh_texture && !p.second->isMeshTexture()))
|
||||
continue;
|
||||
Log::info("STKTexManager", "%s size: %0.2fK", p.first.c_str(),
|
||||
float(p.second->getTextureSize()) / 1024);
|
||||
}
|
||||
} // dumpAllTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int STKTexManager::dumpTextureUsage()
|
||||
{
|
||||
int size = 0;
|
||||
for (auto p : m_all_textures)
|
||||
{
|
||||
if (p.second == NULL)
|
||||
continue;
|
||||
size += p.second->getTextureSize() / 1024 / 1024;
|
||||
}
|
||||
Log::info("STKTexManager", "Total %dMB", size);
|
||||
return size;
|
||||
} // dumpAllTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
core::stringw STKTexManager::reloadTexture(const irr::core::stringw& name)
|
||||
{
|
||||
core::stringw result;
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isTextureCompressionEnabled())
|
||||
return L"Please disable texture compression for reloading textures.";
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
for (auto p : m_all_textures)
|
||||
{
|
||||
if (p.second == NULL || !p.second->isMeshTexture())
|
||||
continue;
|
||||
p.second->reload();
|
||||
Log::info("STKTexManager", "%s reloaded",
|
||||
p.second->getName().getPtr());
|
||||
}
|
||||
return L"All textures reloaded.";
|
||||
}
|
||||
|
||||
core::stringw list = name;
|
||||
list.make_lower().replace(L'\u005C', L'\u002F');
|
||||
std::vector<std::string> names =
|
||||
StringUtils::split(StringUtils::wideToUtf8(list), ';');
|
||||
for (const std::string& fname : names)
|
||||
{
|
||||
for (auto p : m_all_textures)
|
||||
{
|
||||
if (p.second == NULL || !p.second->isMeshTexture())
|
||||
continue;
|
||||
std::string tex_path =
|
||||
StringUtils::toLowerCase(p.second->getName().getPtr());
|
||||
std::string tex_name = StringUtils::getBasename(tex_path);
|
||||
if (fname == tex_name || fname == tex_path)
|
||||
{
|
||||
p.second->reload();
|
||||
result += tex_name.c_str();
|
||||
result += L" ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result.empty())
|
||||
return L"Texture(s) not found!";
|
||||
#endif // !SERVER_ONLY
|
||||
return result + "reloaded.";
|
||||
} // reloadTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets an error message to be displayed when a texture is not found. This
|
||||
* error message is shown before the "Texture %s not found or invalid"
|
||||
@ -244,3 +169,17 @@ void STKTexManager::setTextureErrorMessage(const std::string &error,
|
||||
else
|
||||
m_texture_error_message = StringUtils::insertValues(error, detail);
|
||||
} // setTextureErrorMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int STKTexManager::dumpTextureUsage()
|
||||
{
|
||||
int size = 0;
|
||||
for (auto p : m_all_textures)
|
||||
{
|
||||
if (p.second == NULL)
|
||||
continue;
|
||||
size += p.second->getTextureSize() / 1024 / 1024;
|
||||
}
|
||||
Log::info("STKTexManager", "Total %dMB", size);
|
||||
return size;
|
||||
} // dumpTextureUsage
|
||||
|
@ -83,12 +83,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
void removeTexture(STKTexture* texture, bool remove_all = false);
|
||||
// ------------------------------------------------------------------------
|
||||
void dumpAllTexture(bool mesh_texture);
|
||||
// ------------------------------------------------------------------------
|
||||
int dumpTextureUsage();
|
||||
// ------------------------------------------------------------------------
|
||||
irr::core::stringw reloadTexture(const irr::core::stringw& name);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the currently defined texture error message, which is used
|
||||
* by event_handler.cpp to print additional info about irrlicht
|
||||
* internal errors or warnings. If no error message is currently
|
||||
|
@ -18,8 +18,11 @@
|
||||
#include "graphics/stk_texture.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/graphics_restrictions.hpp"
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "modes/profile_world.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -122,6 +125,7 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
|
||||
return;
|
||||
}
|
||||
orig_img = resizeImage(orig_img, &m_orig_size, &m_size);
|
||||
applyMask(orig_img);
|
||||
data = orig_img ? (uint8_t*)orig_img->lock() : NULL;
|
||||
}
|
||||
|
||||
@ -235,11 +239,18 @@ video::IImage* STKTexture::resizeImage(video::IImage* orig_img,
|
||||
#ifndef SERVER_ONLY
|
||||
if (image == NULL)
|
||||
assert(orig_size && orig_size->Width > 0 && orig_size->Height > 0);
|
||||
|
||||
video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
|
||||
core::dimension2du img_size = image ? image->getDimension() : *orig_size;
|
||||
core::dimension2du tex_size = img_size.getOptimalSize
|
||||
(!irr_driver->getVideoDriver()->queryFeature(video::EVDF_TEXTURE_NPOT));
|
||||
const core::dimension2du& max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
|
||||
bool has_npot = !GraphicsRestrictions::isDisabled(
|
||||
GraphicsRestrictions::GR_NPOT_TEXTURES) &&
|
||||
driver->queryFeature(video::EVDF_TEXTURE_NPOT);
|
||||
|
||||
core::dimension2du tex_size = img_size.getOptimalSize(!has_npot);
|
||||
const core::dimension2du& max_size = driver->getDriverAttributes().
|
||||
getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
|
||||
if (tex_size.Width > max_size.Width)
|
||||
tex_size.Width = max_size.Width;
|
||||
@ -257,8 +268,8 @@ video::IImage* STKTexture::resizeImage(video::IImage* orig_img,
|
||||
if (image->getColorFormat() != video::ECF_A8R8G8B8 ||
|
||||
tex_size != img_size)
|
||||
{
|
||||
video::IImage* new_texture = irr_driver
|
||||
->getVideoDriver()->createImage(video::ECF_A8R8G8B8, tex_size);
|
||||
video::IImage* new_texture = driver->createImage(video::ECF_A8R8G8B8,
|
||||
tex_size);
|
||||
if (tex_size != img_size)
|
||||
image->copyToScaling(new_texture);
|
||||
else
|
||||
@ -271,6 +282,46 @@ video::IImage* STKTexture::resizeImage(video::IImage* orig_img,
|
||||
return image;
|
||||
} // resizeImage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTexture::applyMask(video::IImage* orig_img)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
Material* material = NULL;
|
||||
if (material_manager)
|
||||
{
|
||||
material = material_manager->getMaterialFor(this);
|
||||
}
|
||||
if (material && !material->getAlphaMask().empty())
|
||||
{
|
||||
video::IImage* converted_mask = irr_driver->getVideoDriver()
|
||||
->createImageFromFile(material->getAlphaMask().c_str());
|
||||
if (converted_mask == NULL)
|
||||
{
|
||||
Log::warn("STKTexture", "Applying mask failed for '%s'!",
|
||||
material->getAlphaMask().c_str());
|
||||
return;
|
||||
}
|
||||
converted_mask = resizeImage(converted_mask);
|
||||
if (converted_mask->lock())
|
||||
{
|
||||
const core::dimension2du& dim = orig_img->getDimension();
|
||||
for (unsigned int x = 0; x < dim.Width; x++)
|
||||
{
|
||||
for (unsigned int y = 0; y < dim.Height; y++)
|
||||
{
|
||||
video::SColor col = orig_img->getPixel(x, y);
|
||||
video::SColor alpha = converted_mask->getPixel(x, y);
|
||||
col.setAlpha(alpha.getRed());
|
||||
orig_img->setPixel(x, y, col, false);
|
||||
} // for y
|
||||
} // for x
|
||||
}
|
||||
converted_mask->unlock();
|
||||
converted_mask->drop();
|
||||
}
|
||||
#endif // !SERVER_ONLY
|
||||
} // applyMask
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool STKTexture::hasMipMaps() const
|
||||
{
|
||||
|
@ -54,6 +54,9 @@ private:
|
||||
bool isSrgb() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isPremulAlpha() const;
|
||||
// ------------------------------------------------------------------------
|
||||
void applyMask(video::IImage* orig_img);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -177,7 +177,6 @@ public:
|
||||
template<int N, typename... TexIds>
|
||||
void setTextureUnitsImpl(GLuint tex_id, TexIds... args)
|
||||
{
|
||||
static_assert(N != 15, "15 is reserved for skinning texture");
|
||||
if (CVS->isARBSamplerObjectsUsable())
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + m_texture_units[N]);
|
||||
@ -250,18 +249,6 @@ public:
|
||||
for (unsigned i = 0; i < m_sampler_ids.size(); i++)
|
||||
glDeleteSamplers(1, &m_sampler_ids[i]);
|
||||
} // ~TextureShader
|
||||
// ------------------------------------------------------------------------
|
||||
/** For AZDO to remove the old texture handles, according to specification,
|
||||
* they can only be removed when the underlying texture or sampler objects
|
||||
* are finally deleted. This deletion will happen only when no handle
|
||||
* using the texture or sampler object is resident on any context.
|
||||
*/
|
||||
void recreateTrilinearSampler(int sampler_id)
|
||||
{
|
||||
glDeleteSamplers(1, &m_sampler_ids[sampler_id]);
|
||||
m_sampler_ids[sampler_id] =
|
||||
createSamplers(ST_TRILINEAR_ANISOTROPIC_FILTERED);
|
||||
} // recreateTrilinearSampler
|
||||
|
||||
}; // class TextureShader
|
||||
|
||||
|
@ -388,6 +388,16 @@ InputDevice *DeviceManager::mapGamepadInput(Input::InputType type,
|
||||
|
||||
if (gPad != NULL)
|
||||
{
|
||||
// Ignore deadzone events if this isn't the latest used device in
|
||||
// single-player mode (allowing the player to switch device at any time)
|
||||
int dz = static_cast<GamepadConfig*>(gPad->getConfiguration())->getDeadzone();
|
||||
if (m_single_player != NULL && m_latest_used_device != gPad
|
||||
&& *value > -dz && *value < dz)
|
||||
{
|
||||
*player = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (gPad->processAndMapInput(type, button_id, mode, action, value))
|
||||
{
|
||||
if (m_single_player != NULL)
|
||||
|
@ -104,7 +104,8 @@ bool GamePadDevice::isButtonPressed(const int i)
|
||||
|
||||
void GamePadDevice::setButtonPressed(const int i, bool isButtonPressed)
|
||||
{
|
||||
m_button_pressed[i] = isButtonPressed;
|
||||
if (i < m_button_pressed.size())
|
||||
m_button_pressed[i] = isButtonPressed;
|
||||
} // setButtonPressed
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -566,7 +566,8 @@ void Attachment::update(float dt)
|
||||
// Everything is done in the plugin.
|
||||
break;
|
||||
case ATTACH_NOLOKS_SWATTER:
|
||||
// Should never be called, this symbols is only used as an index for
|
||||
case ATTACH_SWATTER_ANIM:
|
||||
// Should never be called, these symbols are only used as an index for
|
||||
// the model, Nolok's attachment type is ATTACH_SWATTER
|
||||
assert(false);
|
||||
break;
|
||||
@ -597,9 +598,6 @@ void Attachment::update(float dt)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ATTACH_TINYTUX:
|
||||
// Nothing to do for tinytux, this is all handled in EmergencyAnimation
|
||||
break;
|
||||
case ATTACH_BUBBLEGUM_SHIELD:
|
||||
case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
|
||||
if (m_time_left < 0)
|
||||
|
@ -60,10 +60,10 @@ public:
|
||||
ATTACH_BOMB,
|
||||
ATTACH_ANVIL,
|
||||
ATTACH_SWATTER,
|
||||
// Note that the next symbol is only used as an index into the mesh
|
||||
// Note that the next 2 symbols are only used as an index into the mesh
|
||||
// array; it will NEVER be actually assigned as an attachment type
|
||||
ATTACH_NOLOKS_SWATTER,
|
||||
ATTACH_TINYTUX,
|
||||
ATTACH_SWATTER_ANIM,
|
||||
ATTACH_BUBBLEGUM_SHIELD,
|
||||
ATTACH_NOLOK_BUBBLEGUM_SHIELD,
|
||||
ATTACH_MAX,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
|
||||
AttachmentManager *attachment_manager = 0;
|
||||
@ -53,7 +54,7 @@ static const initAttachmentType iat[]=
|
||||
{Attachment::ATTACH_ANVIL, "anchor.spm", "anchor-attach-icon.png" },
|
||||
{Attachment::ATTACH_SWATTER, "swatter.spm", "swatter-icon.png" },
|
||||
{Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.spm", "swatter-icon.png" },
|
||||
{Attachment::ATTACH_TINYTUX, "reset-button.spm", "reset-attach-icon.png" },
|
||||
{Attachment::ATTACH_SWATTER_ANIM, "swatter_anim.spm", "swatter-icon.png" },
|
||||
{Attachment::ATTACH_BUBBLEGUM_SHIELD, "bubblegum_shield.spm", "shield-icon.png" },
|
||||
{Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, "bubblegum_shield_nolok.spm", "shield-icon.png" },
|
||||
{Attachment::ATTACH_MAX, "", "" },
|
||||
@ -76,23 +77,18 @@ AttachmentManager::~AttachmentManager()
|
||||
}
|
||||
} // ~AttachmentManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AttachmentManager::removeTextures()
|
||||
{
|
||||
for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++)
|
||||
{
|
||||
// FIXME: free attachment textures
|
||||
} // for
|
||||
} // removeTextures
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void AttachmentManager::loadModels()
|
||||
{
|
||||
for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++)
|
||||
{
|
||||
std::string full_path = file_manager->getAsset(FileManager::MODEL,iat[i].file);
|
||||
m_attachments[iat[i].attachment]=irr_driver->getAnimatedMesh(full_path);
|
||||
m_attachments[iat[i].attachment]->grab();
|
||||
scene::IAnimatedMesh* mesh = irr_driver->getAnimatedMesh(full_path);
|
||||
mesh->grab();
|
||||
#ifndef SERVER_ONLY
|
||||
SP::uploadSPM(mesh);
|
||||
#endif
|
||||
m_attachments[iat[i].attachment] = mesh;
|
||||
if(iat[i].icon_file)
|
||||
{
|
||||
std::string full_icon_path =
|
||||
|
@ -39,7 +39,6 @@ private:
|
||||
public:
|
||||
AttachmentManager() {};
|
||||
~AttachmentManager();
|
||||
void removeTextures ();
|
||||
void loadModels ();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the mest for a certain attachment.
|
||||
|
@ -78,7 +78,6 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
debug_name += m_type;
|
||||
m_node->setName(debug_name.c_str());
|
||||
#endif
|
||||
Track::getCurrentTrack()->adjustForFog(m_node);
|
||||
m_node->setAutomaticCulling(scene::EAC_FRUSTUM_BOX);
|
||||
m_node->setPosition(xyz.toIrrVector());
|
||||
Vec3 hpr;
|
||||
@ -192,8 +191,6 @@ void Item::switchTo(ItemType type, scene::IMesh *mesh, scene::IMesh *lowmesh)
|
||||
m_original_type = m_type;
|
||||
setMesh(mesh, lowmesh);
|
||||
setType(type);
|
||||
|
||||
Track::getCurrentTrack()->adjustForFog(m_node);
|
||||
} // switchTo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -214,7 +211,6 @@ void Item::switchBack()
|
||||
setType(m_original_type);
|
||||
m_original_type = ITEM_NONE;
|
||||
|
||||
Track::getCurrentTrack()->adjustForFog(m_node);
|
||||
Vec3 hpr;
|
||||
hpr.setHPR(m_original_rotation);
|
||||
m_node->setRotation(hpr.toIrrHPR());
|
||||
|
@ -25,8 +25,7 @@
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/spare_tire_ai.hpp"
|
||||
@ -36,6 +35,7 @@
|
||||
#include "tracks/arena_graph.hpp"
|
||||
#include "tracks/arena_node.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <IMesh.h>
|
||||
@ -104,6 +104,9 @@ void ItemManager::loadDefaultItemMeshes()
|
||||
"- aborting", name.c_str());
|
||||
exit(-1);
|
||||
}
|
||||
#ifndef SERVER_ONLY
|
||||
SP::uploadSPM(mesh);
|
||||
#endif
|
||||
mesh->grab();
|
||||
m_item_mesh[i] = mesh;
|
||||
node->get("glow", &(m_glow_color[i]));
|
||||
@ -114,7 +117,13 @@ void ItemManager::loadDefaultItemMeshes()
|
||||
? NULL
|
||||
: irr_driver->getMesh(lowres_model_filename);
|
||||
|
||||
if (m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->grab();
|
||||
if (m_item_lowres_mesh[i])
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
SP::uploadSPM(m_item_lowres_mesh[i]);
|
||||
#endif
|
||||
m_item_lowres_mesh[i]->grab();
|
||||
}
|
||||
} // for i
|
||||
delete root;
|
||||
} // loadDefaultItemMeshes
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "items/plunger.hpp"
|
||||
#include "items/projectile_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
@ -59,8 +59,8 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
color.setBlue(SP::srgb255ToLinear(color.getBlue()));
|
||||
}
|
||||
m_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("unlit"),
|
||||
material_manager->getDefaultSPMaterial("unlit"));
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::SPShaderManager::get()->getSPShader
|
||||
("unlit"), material_manager->getDefaultSPMaterial("unlit"));
|
||||
m_dy_dc->getVerticesVector().resize(4);
|
||||
// Set the vertex colors properly, as the new pipeline doesn't use the old
|
||||
// light values
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "graphics/explosion.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "items/attachment.hpp"
|
||||
#include "items/attachment_manager.hpp"
|
||||
#include "items/projectile_manager.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/explosion_animation.hpp"
|
||||
@ -74,8 +74,8 @@ Swatter::Swatter(AbstractKart *kart, bool was_bomb,
|
||||
|
||||
if (m_removing_bomb)
|
||||
{
|
||||
m_scene_node->setMesh(irr_driver->getAnimatedMesh(
|
||||
file_manager->getAsset(FileManager::MODEL,"swatter_anim.spm") ) );
|
||||
m_scene_node->setMesh(attachment_manager
|
||||
->getMesh(Attachment::ATTACH_SWATTER_ANIM));
|
||||
m_scene_node->setRotation(core::vector3df(0.0, -180.0, 0.0));
|
||||
m_scene_node->setAnimationSpeed(0.9f);
|
||||
m_scene_node->setCurrentFrame(0.0f);
|
||||
|
@ -217,8 +217,7 @@ void LocalPlayerController::update(float dt)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (m_kart->getKartAnimation() && m_sound_schedule == false &&
|
||||
m_kart->getAttachment()->getType() != Attachment::ATTACH_TINYTUX)
|
||||
if (m_kart->getKartAnimation() && m_sound_schedule == false)
|
||||
{
|
||||
m_sound_schedule = true;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "karts/explosion_animation.hpp"
|
||||
#include "karts/kart_gfx.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "karts/kart_rewinder.hpp"
|
||||
#include "karts/max_speed.hpp"
|
||||
@ -3019,10 +3020,15 @@ const Vec3& Kart::getNormal() const
|
||||
} // getNormal
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void Kart::playSound(SFXBuffer* buffer)
|
||||
{
|
||||
getNextEmitter()->play(getXYZ(), buffer);
|
||||
}
|
||||
} // playSound
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
const video::SColor& Kart::getColor() const
|
||||
{
|
||||
return m_kart_properties->getColor();
|
||||
} // getColor
|
||||
|
||||
/* EOF */
|
||||
|
@ -30,9 +30,10 @@
|
||||
|
||||
#include "items/powerup_manager.hpp" // For PowerupType
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <SColor.h>
|
||||
|
||||
class AbstractKartAnimation;
|
||||
class Attachment;
|
||||
class btKart;
|
||||
@ -347,8 +348,7 @@ public:
|
||||
virtual btTransform getAlignedTransform(const float customPitch=-1);
|
||||
// -------------------------------------------------------------------------
|
||||
/** Returns the color used for this kart. */
|
||||
const video::SColor &getColor() const
|
||||
{return m_kart_properties->getColor();}
|
||||
const irr::video::SColor &getColor() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time till full steering is reached for this kart.
|
||||
* \param steer Current steer value (must be >=0), on which the time till
|
||||
|
@ -678,16 +678,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
std::string full_name = kart_properties.getKartDir() + obj.getFilename();
|
||||
obj.setModel(irr_driver->getMesh(full_name));
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
for (u32 j = 0; j < obj.getModel()->getMeshBufferCount(); j++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
|
||||
(obj.getModel()->getMeshBuffer(j));
|
||||
// Pre-upload gl meshes and textures for kart screen
|
||||
mb->uploadGLMesh();
|
||||
}
|
||||
}
|
||||
SP::uploadSPM(obj.getModel());
|
||||
#endif
|
||||
obj.getModel()->grab();
|
||||
irr_driver->grabAllTextures(obj.getModel());
|
||||
@ -725,16 +716,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
|
||||
kart_properties.getKartDir()+m_wheel_filename[i];
|
||||
m_wheel_model[i] = irr_driver->getMesh(full_wheel);
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
for (u32 j = 0; j < m_wheel_model[i]->getMeshBufferCount(); j++)
|
||||
{
|
||||
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
|
||||
(m_wheel_model[i]->getMeshBuffer(j));
|
||||
// Pre-upload gl meshes and textures for kart screen
|
||||
mb->uploadGLMesh();
|
||||
}
|
||||
}
|
||||
SP::uploadSPM(m_wheel_model[i]);
|
||||
#endif
|
||||
// Grab all textures. This is done for the master only, so
|
||||
// the destructor will only free the textures if a master
|
||||
@ -1135,13 +1117,8 @@ void KartModel::update(float dt, float distance, float steer, float speed,
|
||||
for (unsigned i = 0; i < spmn->getSPM()->getMeshBufferCount(); i++)
|
||||
{
|
||||
auto& ret = spmn->getTextureMatrix(i);
|
||||
if (!ret[0] || !ret[1])
|
||||
{
|
||||
ret[0].reset(new float);
|
||||
ret[1].reset(new float);
|
||||
}
|
||||
*ret[0] = obj.m_texture_cur_offset.X;
|
||||
*ret[1] = obj.m_texture_cur_offset.Y;
|
||||
ret[0] = obj.m_texture_cur_offset.X;
|
||||
ret[1] = obj.m_texture_cur_offset.Y;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -21,8 +21,12 @@
|
||||
#include "addons/addon.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/shader_files_manager.hpp"
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "graphics/sp/sp_texture_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/cached_characteristic.hpp"
|
||||
#include "karts/combined_characteristic.hpp"
|
||||
@ -97,7 +101,10 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < RaceManager::DIFFICULTY_COUNT; i++)
|
||||
m_ai_properties[i].reset(new AIProperties((RaceManager::Difficulty) i));
|
||||
{
|
||||
m_ai_properties[i] =
|
||||
std::make_shared<AIProperties>((RaceManager::Difficulty) i);
|
||||
}
|
||||
}
|
||||
} // KartProperties
|
||||
|
||||
@ -105,6 +112,15 @@ KartProperties::KartProperties(const std::string &filename)
|
||||
/** Destructor, dereferences the kart model. */
|
||||
KartProperties::~KartProperties()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL() && m_kart_model.use_count() == 1)
|
||||
{
|
||||
m_kart_model = nullptr;
|
||||
SP::SPShaderManager::get()->removeUnusedShaders();
|
||||
ShaderFilesManager::getInstance()->removeUnusedShaderFiles();
|
||||
SP::SPTextureManager::get()->removeUnusedTextures();
|
||||
}
|
||||
#endif
|
||||
} // ~KartProperties
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -125,7 +141,7 @@ void KartProperties::copyForPlayer(const KartProperties *source)
|
||||
if (source->m_characteristic)
|
||||
{
|
||||
// Remove the shared reference by creating a new pointer
|
||||
m_characteristic.reset(new XmlCharacteristic());
|
||||
m_characteristic = std::make_shared<XmlCharacteristic>();
|
||||
m_characteristic->copyFrom(source->getCharacteristic());
|
||||
|
||||
// Combine the characteristics for this object. We can't copy it because
|
||||
@ -149,7 +165,8 @@ void KartProperties::copyFrom(const KartProperties *source)
|
||||
// (but not for each player).
|
||||
for (unsigned int i = 0; i < RaceManager::DIFFICULTY_COUNT; i++)
|
||||
{
|
||||
m_ai_properties[i].reset(new AIProperties((RaceManager::Difficulty) i));
|
||||
m_ai_properties[i] =
|
||||
std::make_shared<AIProperties>((RaceManager::Difficulty) i);
|
||||
assert(m_ai_properties);
|
||||
*m_ai_properties[i] = *source->m_ai_properties[i];
|
||||
}
|
||||
@ -186,7 +203,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
// m_kart_model must be initialised after assigning the default
|
||||
// values from stk_config (otherwise all kart_properties will
|
||||
// share the same KartModel
|
||||
m_kart_model.reset(new KartModel(/*is_master*/true));
|
||||
m_kart_model = std::make_shared<KartModel>(/*is_master*/true);
|
||||
|
||||
m_root = StringUtils::getPath(filename)+"/";
|
||||
m_ident = StringUtils::getBasename(StringUtils::getPath(filename));
|
||||
@ -206,7 +223,7 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
getAllData(root);
|
||||
m_characteristic.reset(new XmlCharacteristic(root));
|
||||
m_characteristic = std::make_shared<XmlCharacteristic>(root);
|
||||
combineCharacteristics();
|
||||
}
|
||||
catch(std::exception& err)
|
||||
@ -227,6 +244,12 @@ void KartProperties::load(const std::string &filename, const std::string &node)
|
||||
std::string unique_id = StringUtils::insertValues("karts/%s", m_ident.c_str());
|
||||
file_manager->pushModelSearchPath(m_root);
|
||||
file_manager->pushTextureSearchPath(m_root, unique_id);
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->isGLSL())
|
||||
{
|
||||
SP::SPShaderManager::get()->loadSPShaders(m_root);
|
||||
}
|
||||
#endif
|
||||
|
||||
STKTexManager::getInstance()
|
||||
->setTextureErrorMessage("Error while loading kart '%s':", m_name);
|
||||
@ -322,7 +345,7 @@ void KartProperties::setHatMeshName(const std::string &hat_name)
|
||||
//-----------------------------------------------------------------------------
|
||||
void KartProperties::combineCharacteristics()
|
||||
{
|
||||
m_combined_characteristic.reset(new CombinedCharacteristic());
|
||||
m_combined_characteristic = std::make_shared<CombinedCharacteristic>();
|
||||
m_combined_characteristic->addCharacteristic(kart_properties_manager->
|
||||
getBaseCharacteristic());
|
||||
m_combined_characteristic->addCharacteristic(kart_properties_manager->
|
||||
@ -340,7 +363,8 @@ void KartProperties::combineCharacteristics()
|
||||
m_combined_characteristic->addCharacteristic(characteristic);
|
||||
|
||||
m_combined_characteristic->addCharacteristic(m_characteristic.get());
|
||||
m_cached_characteristic.reset(new CachedCharacteristic(m_combined_characteristic.get()));
|
||||
m_cached_characteristic = std::make_shared<CachedCharacteristic>
|
||||
(m_combined_characteristic.get());
|
||||
} // combineCharacteristics
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -75,7 +75,8 @@ RescueAnimation::RescueAnimation(AbstractKart *kart, bool is_auto_rescue)
|
||||
// up direction to the right up direction it should have according to
|
||||
// the last vaild quad of the kart
|
||||
WorldWithRank* wwr = dynamic_cast<WorldWithRank*>(World::getWorld());
|
||||
if (DriveGraph::get() && wwr)
|
||||
if (DriveGraph::get() && wwr &&
|
||||
wwr->getTrackSector(m_kart->getWorldKartId())->getCurrentGraphNode() > -1)
|
||||
{
|
||||
const int sector = wwr->getTrackSector(m_kart->getWorldKartId())
|
||||
->getCurrentGraphNode();
|
||||
|
@ -730,7 +730,6 @@ void ThreeStrikesBattle::loadCustomModels()
|
||||
|
||||
m_karts.push_back(sta);
|
||||
race_manager->addSpareTireKart(sta_list[i]);
|
||||
Track::getCurrentTrack()->adjustForFog(sta->getNode());
|
||||
|
||||
// Copy STA pointer to m_spare_tire_karts array, allowing them
|
||||
// to respawn easily
|
||||
|
@ -215,7 +215,6 @@ void World::init()
|
||||
race_manager->getKartType(i),
|
||||
race_manager->getPlayerDifficulty(i));
|
||||
m_karts.push_back(newkart);
|
||||
track->adjustForFog(newkart->getNode());
|
||||
|
||||
} // for i
|
||||
|
||||
@ -730,7 +729,8 @@ void World::resetAllKarts()
|
||||
for (KartList::iterator i = m_karts.begin(); i != m_karts.end(); i++)
|
||||
{
|
||||
if ((*i)->isGhostKart()) continue;
|
||||
(*i)->getBody()->setGravity((*i)->getMaterial()->hasGravity() ?
|
||||
(*i)->getBody()->setGravity(
|
||||
(*i)->getMaterial() && (*i)->getMaterial()->hasGravity() ?
|
||||
(*i)->getNormal() * -g : Vec3(0, -g, 0));
|
||||
}
|
||||
for(int i=0; i<60; i++) Physics::getInstance()->update(1.f/60.f);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "graphics/material.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_model.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "physics/triangle_mesh.hpp"
|
||||
#include "tracks/terrain_info.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "script_kart.hpp"
|
||||
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "scriptvec3.hpp"
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/show_curve.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "items/flyable.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
@ -68,7 +68,8 @@ CheckCannon::CheckCannon(const XMLNode &node, unsigned int index)
|
||||
if (UserConfigParams::m_check_debug)
|
||||
{
|
||||
m_debug_target_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("additive"),
|
||||
(scene::EPT_TRIANGLE_STRIP,
|
||||
SP::SPShaderManager::get()->getSPShader("additive"),
|
||||
material_manager->getDefaultSPMaterial("additive"));
|
||||
SP::addDynamicDrawCall(m_debug_target_dy_dc);
|
||||
m_debug_target_dy_dc->getVerticesVector().resize(4);
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
#include "graphics/sp/sp_base.hpp"
|
||||
#include "graphics/sp/sp_dynamic_draw_call.hpp"
|
||||
#include "graphics/sp/sp_shader_manager.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
@ -77,7 +77,8 @@ CheckLine::CheckLine(const XMLNode &node, unsigned int index)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
m_debug_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
|
||||
(scene::EPT_TRIANGLE_STRIP, SP::getSPShader("additive"),
|
||||
(scene::EPT_TRIANGLE_STRIP,
|
||||
SP::SPShaderManager::get()->getSPShader("additive"),
|
||||
material_manager->getDefaultSPMaterial("additive"));
|
||||
SP::addDynamicDrawCall(m_debug_dy_dc);
|
||||
m_debug_dy_dc->getVerticesVector().resize(4);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user