Merge remote-tracking branch 'origin/master' into game_protocol
This commit is contained in:
commit
096d68c361
BIN
data/CREDITS
Executable file → Normal file
BIN
data/CREDITS
Executable file → Normal file
Binary file not shown.
@ -19,7 +19,7 @@
|
||||
<snowmountain goal="1"/>
|
||||
<snowtuxpeak goal="1"/>
|
||||
<stk_enterprise goal="1"/>
|
||||
<subsea goal="1"/>
|
||||
<abyss goal="1"/>
|
||||
<xr591 goal="1"/>
|
||||
<zengarden goal="1"/>
|
||||
</achievement>
|
||||
|
@ -1,19 +1,19 @@
|
||||
<?xml version="1.0"?>
|
||||
<challenge version="2">
|
||||
<track id="farm" laps="3"/>
|
||||
<track id="cornfield_crossing" laps="3"/>
|
||||
<mode major="single" minor="quickrace"/>
|
||||
<requirements trophies="0"/>
|
||||
|
||||
<hard>
|
||||
<karts number="5"/>
|
||||
<requirements position="1" time="110"/>
|
||||
<requirements position="1" time="165"/>
|
||||
</hard>
|
||||
<medium>
|
||||
<karts number="4"/>
|
||||
<requirements time="125"/>
|
||||
<requirements time="195"/>
|
||||
</medium>
|
||||
<easy>
|
||||
<karts number="4"/>
|
||||
<requirements time="155"/>
|
||||
<requirements time="275"/>
|
||||
</easy>
|
||||
</challenge>
|
33
data/gfx/kart_exhaust.xml
Normal file
33
data/gfx/kart_exhaust.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="box" box_x="0.05" box_y="0.05" box_z="0.10">
|
||||
|
||||
<spreading angle="2" />
|
||||
|
||||
<velocity x="0.0"
|
||||
y="0.005"
|
||||
z="-0.01" />
|
||||
|
||||
<material file="smoke.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="200"
|
||||
max="300" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="10"
|
||||
max="40" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.05"
|
||||
max="0.1"
|
||||
x-increase-factor="5"
|
||||
y-increase-factor="5"
|
||||
/>
|
||||
|
||||
<color min="255 255 255"
|
||||
max="0 0 0" />
|
||||
|
||||
<!-- How much time in milliseconds before the particle is fully faded out -->
|
||||
<fadeout time="500" />
|
||||
|
||||
</particles>
|
@ -1,10 +1,10 @@
|
||||
|
||||
<supertuxkart_grand_prix name="Penguin Playground">
|
||||
|
||||
<track id="sandtrack" laps="3" reverse="false" />
|
||||
<track id="farm" laps="3" reverse="false" />
|
||||
<track id="olivermath" laps="4" reverse="false" />
|
||||
<track id="abyss" laps="3" reverse="false" />
|
||||
<track id="scotland" laps="3" reverse="false" />
|
||||
<track id="sandtrack" laps="3" reverse="false" />
|
||||
<track id="cornfield_crossing" laps="3" reverse="false" />
|
||||
<track id="olivermath" laps="4" reverse="false" />
|
||||
<track id="abyss" laps="3" reverse="false" />
|
||||
<track id="scotland" laps="3" reverse="false" />
|
||||
|
||||
</supertuxkart_grand_prix>
|
||||
|
@ -31,4 +31,5 @@
|
||||
<card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/>
|
||||
<card os="android" disable="TextureFormatBGRA8888"/>
|
||||
<card os="android" disable="ColorBufferFloat"/>
|
||||
<card contains="Android Emulator" os="android" disable="ForceLegacyDevice"/>
|
||||
</graphical-restrictions>
|
||||
|
@ -173,6 +173,14 @@
|
||||
<gauge id="filtering" min_value="0" max_value="5" width="50%" />
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" proportion="1">
|
||||
<label text="Geometry detail" I18N="Video settings" width="40%"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<gauge id="geometry_detail" min_value="0" max_value="2" width="50%" />
|
||||
</div>
|
||||
|
||||
<spacer height="10" width="10" />
|
||||
|
||||
<label text="* Restart STK to apply new settings" width="100%" text_align="center" I18N="Video settings"/>
|
||||
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
|
||||
|
||||
<label id="title" width="100%" text_align="center" word_wrap="true"
|
||||
I18N="In the 'add new grand prix' dialog"
|
||||
text="Please enter the name of the grand prix" proportion="1" />
|
||||
|
||||
<spacer height="25" width="10" />
|
||||
|
||||
<textbox id="textfield" width="75%" I18N="In the 'add new grand prix' dialog" align="center"/>
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
|
||||
<button id="accept" I18N="In the 'add new grand prix' dialog" text="OK" align="center" proportion="1"/>
|
||||
<spacer height="15" width="20" />
|
||||
<button id="cancel" I18N="In the 'add new grand prix' dialog" text="Cancel" align="center" proportion="1"/>
|
||||
|
||||
</div>
|
||||
</stkgui>
|
15
data/gui/general_text_field_dialog.stkgui
Normal file
15
data/gui/general_text_field_dialog.stkgui
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
|
||||
<label id="title" raw_text="Text" proportion="1"/>
|
||||
|
||||
<spacer height="25" width="10" />
|
||||
<textbox id="textfield" width="75%" align="center"/>
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
<button id="ok" I18N="In the general textfield dialog" text="OK" align="center" proportion="1"/>
|
||||
|
||||
<spacer height="15" width="20" />
|
||||
<button id="cancel" I18N="In the general textfield dialog" text="Cancel" align="center" proportion="1"/>
|
||||
</div>
|
||||
</stkgui>
|
52
data/gui/multitouch_settings.stkgui
Normal file
52
data/gui/multitouch_settings.stkgui
Normal file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="1%" width="96%" height="98%" layout="vertical-row" >
|
||||
<header id="title" width="100%" height="fit" text_align="center" word_wrap="true" text="Touch Device Settings" />
|
||||
|
||||
<spacer height="30" width="10" />
|
||||
|
||||
<label width="100%" I18N="In the multitouch settings screen" text="General"/>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the multitouch settings screen" text="Buttons scale"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="scale" proportion="1" min_value="50" max_value="150"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="45" width="10"/>
|
||||
|
||||
<label width="100%" I18N="In the multitouch settings screen" text="Advanced"/>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the multitouch settings screen" text="Deadzone center"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="deadzone_center" proportion="1" min_value="0" max_value="50"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<div width="75%" height="fit" layout="horizontal-row" >
|
||||
<label proportion="1" height="100%" text_align="right" I18N="In the multitouch settings screen" text="Deadzone edge"/>
|
||||
<div proportion="1" height="fit" layout="horizontal-row" >
|
||||
<spacer width="40" height="100%" />
|
||||
<gauge id="deadzone_edge" proportion="1" min_value="0" max_value="50"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="45" width="10"/>
|
||||
|
||||
<button id="restore" text="Restore defaults" align="center"/>
|
||||
|
||||
<spacer height="15" width="10"/>
|
||||
|
||||
<button id="close" text="Apply" align="center"/>
|
||||
</div>
|
||||
</stkgui>
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<stkgui>
|
||||
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
|
||||
|
||||
<label raw_text="Run script"/>
|
||||
|
||||
<textbox id="textfield" width="75%" I18N="In the 'add new grand prix' dialog" align="center"/>
|
||||
|
||||
<spacer height="20" width="20" />
|
||||
|
||||
<div align="center" height="fit" width="100%" layout="horizontal-row">
|
||||
<button id="run" raw_text="Run" align="center" proportion="1"/>
|
||||
<spacer height="20" width="20" />
|
||||
<button id="close" raw_text="Close" align="center" proportion="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</stkgui>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2397
data/replay/standard_expert_scotland.replay
Normal file
2397
data/replay/standard_expert_scotland.replay
Normal file
File diff suppressed because it is too large
Load Diff
2320
data/replay/standard_expert_snowmountain.replay
Normal file
2320
data/replay/standard_expert_snowmountain.replay
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3569
data/replay/standard_intermediate_volcano_island.replay
Normal file
3569
data/replay/standard_intermediate_volcano_island.replay
Normal file
File diff suppressed because it is too large
Load Diff
3371
data/replay/standard_novice_olivermath.replay
Normal file
3371
data/replay/standard_novice_olivermath.replay
Normal file
File diff suppressed because it is too large
Load Diff
2096
data/replay/standard_supertux_mines.replay
Normal file
2096
data/replay/standard_supertux_mines.replay
Normal file
File diff suppressed because it is too large
Load Diff
2359
data/replay/standard_supertux_stkenterprise.replay
Normal file
2359
data/replay/standard_supertux_stkenterprise.replay
Normal file
File diff suppressed because it is too large
Load Diff
2075
data/replay/standard_supertux_xr591.replay
Normal file
2075
data/replay/standard_supertux_xr591.replay
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,9 @@ void main(void)
|
||||
#endif
|
||||
#endif
|
||||
vec4 detail = texture(Detail, uv_bis);
|
||||
color *= detail;
|
||||
detail.xyz = pow(detail.xyz, vec3(2.2));
|
||||
detail.rgb = detail.a * detail.rgb;
|
||||
color.rgb = detail.rgb + color.rgb * (1. - detail.a);
|
||||
float specmap = texture(SpecMap, uv).g;
|
||||
FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ out vec2 uv_bis;
|
||||
out float camdist;
|
||||
|
||||
void main() {
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
uv = Texcoord;
|
||||
uv_bis = SecondTexcoord;
|
||||
camdist = length(ViewMatrix * ModelMatrix * vec4(Position, 1.));
|
||||
|
@ -1,15 +1,16 @@
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec2 Texcoord;
|
||||
layout(location = 5) in vec3 Tangent;
|
||||
layout(location = 6) in vec3 Bitangent;
|
||||
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
layout(location = 15) in vec4 GlowColor;
|
||||
|
||||
layout(location = 10) in vec4 misc_data;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
in vec3 Scale;
|
||||
in vec4 misc_data;
|
||||
#endif
|
||||
flat out vec4 glowColor;
|
||||
|
||||
#stk_include "utils/getworldmatrix.vert"
|
||||
@ -19,5 +20,5 @@ void main(void)
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
|
||||
glowColor = GlowColor;
|
||||
glowColor = misc_data;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ void main()
|
||||
// affects "nor" which is later only * 0.1 by scattering
|
||||
new_inverse_model_matrix[3].xyz -= windDir * Color.r;
|
||||
|
||||
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ViewMatrix * new_model_matrix;
|
||||
mat4 ModelViewProjectionMatrix = ProjectionViewMatrix * new_model_matrix;
|
||||
mat4 TransposeInverseModelView = transpose(InverseViewMatrix * new_inverse_model_matrix);
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;
|
||||
|
@ -63,5 +63,11 @@ layout (std140) uniform LightingData
|
||||
float rL21;
|
||||
float rL22;
|
||||
};
|
||||
|
||||
layout (std140) uniform SkinningData
|
||||
{
|
||||
mat4 joint_matrices[MAX_BONES];
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // HEADER_TXT
|
||||
|
@ -29,6 +29,8 @@ void main(void)
|
||||
vec4 detail = texture(Detail, uv_bis);
|
||||
float specmap = texture(SpecMap, uv).g;
|
||||
#endif
|
||||
color *= detail;
|
||||
detail.xyz = pow(detail.xyz, vec3(2.2));
|
||||
detail.rgb = detail.a * detail.rgb;
|
||||
color.rgb = detail.rgb + color.rgb * (1. - detail.a);
|
||||
FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ in vec4 misc_data;
|
||||
|
||||
out vec3 nor;
|
||||
out vec2 uv;
|
||||
out vec2 color_change;
|
||||
flat out vec2 color_change;
|
||||
#ifdef Use_Bindless_Texture
|
||||
flat out sampler2D handle;
|
||||
flat out sampler2D secondhandle;
|
||||
|
@ -14,7 +14,7 @@ flat in sampler2D thirdhandle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
in vec2 color_change;
|
||||
flat in vec2 color_change;
|
||||
out vec4 FragColor;
|
||||
|
||||
#stk_include "utils/getLightFactor.frag"
|
||||
|
@ -39,7 +39,7 @@ out vec3 bitangent;
|
||||
out vec2 uv;
|
||||
out vec2 uv_bis;
|
||||
out vec4 color;
|
||||
out vec2 color_change;
|
||||
flat out vec2 color_change;
|
||||
#ifdef Use_Bindless_Texture
|
||||
flat out sampler2D handle;
|
||||
flat out sampler2D secondhandle;
|
||||
|
@ -12,7 +12,7 @@ flat in sampler2D thirdhandle;
|
||||
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
in vec2 color_change;
|
||||
flat in vec2 color_change;
|
||||
out vec4 FragColor;
|
||||
|
||||
#stk_include "utils/getLightFactor.frag"
|
||||
|
@ -11,7 +11,7 @@ flat in sampler2D thirdhandle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec4 color;
|
||||
in vec2 color_change;
|
||||
flat in vec2 color_change;
|
||||
out vec4 FragColor;
|
||||
|
||||
#stk_include "utils/getLightFactor.frag"
|
||||
@ -29,6 +29,7 @@ void main(void)
|
||||
#else
|
||||
vec4 col = texture(Albedo, uv);
|
||||
float specmap = texture(SpecMap, uv).g;
|
||||
float emitmap = texture(SpecMap, uv).b;
|
||||
float mask = texture(colorization_mask, uv).a;
|
||||
#endif
|
||||
col.xyz *= pow(color.xyz, vec3(2.2));
|
||||
@ -43,5 +44,5 @@ void main(void)
|
||||
col = vec4(new_color.r, new_color.g, new_color.b, col.a);
|
||||
}
|
||||
|
||||
FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap, 0.), 1.);
|
||||
FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap, emitmap), 1.);
|
||||
}
|
||||
|
93
data/shaders/instanced_skinning.vert
Normal file
93
data/shaders/instanced_skinning.vert
Normal file
@ -0,0 +1,93 @@
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec4 Data1;
|
||||
layout(location = 4) in vec4 Data2;
|
||||
layout(location = 5) in ivec4 Joint;
|
||||
layout(location = 6) in vec4 Weight;
|
||||
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
layout(location = 10) in vec4 misc_data;
|
||||
#ifdef Use_Bindless_Texture
|
||||
layout(location = 11) in sampler2D Handle;
|
||||
layout(location = 12) in sampler2D SecondHandle;
|
||||
layout(location = 13) in sampler2D ThirdHandle;
|
||||
layout(location = 14) in sampler2D FourthHandle;
|
||||
#endif
|
||||
layout(location = 15) in int skinning_offset;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec4 Color;
|
||||
in vec4 Data1;
|
||||
in vec4 Data2;
|
||||
in ivec4 Joint;
|
||||
in vec4 Weight;
|
||||
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
in vec3 Scale;
|
||||
in vec4 misc_data;
|
||||
in int skinning_offset;
|
||||
#endif
|
||||
|
||||
out vec3 nor;
|
||||
out vec3 tangent;
|
||||
out vec3 bitangent;
|
||||
out vec2 uv;
|
||||
out vec4 color;
|
||||
flat out vec2 color_change;
|
||||
#ifdef Use_Bindless_Texture
|
||||
flat out sampler2D handle;
|
||||
flat out sampler2D secondhandle;
|
||||
flat out sampler2D thirdhandle;
|
||||
flat out sampler2D fourthhandle;
|
||||
#endif
|
||||
|
||||
#stk_include "utils/getworldmatrix.vert"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
|
||||
vec4 idle_position = vec4(Position, 1.);
|
||||
vec4 idle_normal = vec4(Normal, 0.);
|
||||
vec4 idle_tangent = vec4(Data1.z, Data1.w, Data2.x, 0.);
|
||||
vec4 idle_bitangent = vec4(Data2.y, Data2.z, Data2.w, 0.);
|
||||
vec4 skinned_position = vec4(0.);
|
||||
vec4 skinned_normal = vec4(0.);
|
||||
vec4 skinned_tangent = vec4(0.);
|
||||
vec4 skinned_bitangent = vec4(0.);
|
||||
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||
vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||
vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent;
|
||||
vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent;
|
||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
||||
skinned_normal += Weight[i] * single_bone_influenced_normal;
|
||||
skinned_tangent += Weight[i] * single_bone_influenced_tangent;
|
||||
skinned_bitangent += Weight[i] * single_bone_influenced_bitangent;
|
||||
}
|
||||
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
||||
// Keep orthogonality
|
||||
nor = (TransposeInverseModelView * skinned_normal).xyz;
|
||||
// Keep direction
|
||||
tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz;
|
||||
bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz;
|
||||
uv = vec2(Data1.x + misc_data.x, Data1.y + misc_data.y);
|
||||
color = Color.zyxw;
|
||||
color_change = misc_data.zw;
|
||||
#ifdef Use_Bindless_Texture
|
||||
handle = Handle;
|
||||
secondhandle = SecondHandle;
|
||||
thirdhandle = ThirdHandle;
|
||||
fourthhandle = FourthHandle;
|
||||
#endif
|
||||
}
|
68
data/shaders/instanced_skinning_shadow.vert
Normal file
68
data/shaders/instanced_skinning_shadow.vert
Normal file
@ -0,0 +1,68 @@
|
||||
uniform int layer;
|
||||
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 3) in vec4 Data1;
|
||||
layout(location = 5) in ivec4 Joint;
|
||||
layout(location = 6) in vec4 Weight;
|
||||
layout(location = 7) in vec3 Origin;
|
||||
layout(location = 8) in vec3 Orientation;
|
||||
layout(location = 9) in vec3 Scale;
|
||||
#ifdef Use_Bindless_Texture
|
||||
layout(location = 11) in uvec2 Handle;
|
||||
#endif
|
||||
layout(location = 15) in int skinning_offset;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec4 Data1;
|
||||
in ivec4 Joint;
|
||||
in vec4 Weight;
|
||||
in vec3 Origin;
|
||||
in vec3 Orientation;
|
||||
in vec3 Scale;
|
||||
in int skinning_offset;
|
||||
#endif
|
||||
|
||||
#ifdef VSLayer
|
||||
out vec2 uv;
|
||||
#ifdef Use_Bindless_Texture
|
||||
flat out uvec2 handle;
|
||||
#endif
|
||||
#else
|
||||
out vec2 tc;
|
||||
out int layerId;
|
||||
#ifdef Use_Bindless_Texture
|
||||
flat out uvec2 hdle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#stk_include "utils/getworldmatrix.vert"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
|
||||
vec4 idle_position = vec4(Position, 1.);
|
||||
vec4 skinned_position = vec4(0.);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
||||
}
|
||||
|
||||
#ifdef VSLayer
|
||||
gl_Layer = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * skinned_position;
|
||||
uv = Data1.xy;
|
||||
#ifdef Use_Bindless_Texture
|
||||
handle = Handle;
|
||||
#endif
|
||||
#else
|
||||
layerId = layer;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * skinned_position;
|
||||
tc = Data1.xy;
|
||||
#ifdef Use_Bindless_Texture
|
||||
hdle = Handle;
|
||||
#endif
|
||||
#endif
|
||||
}
|
@ -56,11 +56,6 @@ float SearchYUp(vec2 texcoord) {
|
||||
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
|
||||
}
|
||||
|
||||
|
||||
vec2 round(vec2 invec) {
|
||||
return vec2(floor(abs(invec) + vec2(0.5)) * sign(invec));
|
||||
}
|
||||
|
||||
vec2 Area(vec2 distance, float e1, float e2) {
|
||||
// * By dividing by areaSize - 1.0 below we are implicitely offsetting to
|
||||
// always fall inside of a pixel
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifdef Use_Bindless_Texture
|
||||
layout(bindless_sampler) uniform sampler2D normalMap;
|
||||
layout(bindless_sampler) uniform sampler2D DiffuseForAlpha;
|
||||
layout(bindless_sampler) uniform sampler2D glossMap;
|
||||
#else
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D DiffuseForAlpha;
|
||||
uniform sampler2D glossMap;
|
||||
#endif
|
||||
|
||||
in vec3 tangent;
|
||||
@ -17,7 +17,7 @@ void main()
|
||||
{
|
||||
// normal in Tangent Space
|
||||
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
|
||||
float alpha = texture(DiffuseForAlpha, uv).a;
|
||||
float gloss = texture(glossMap, uv).x;
|
||||
// Because of interpolation, we need to renormalize
|
||||
vec3 Frag_tangent = normalize(tangent);
|
||||
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
|
||||
@ -25,5 +25,5 @@ void main()
|
||||
|
||||
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
|
||||
EncodedNormal.z = 1. - alpha;
|
||||
EncodedNormal.z = gloss;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ out vec4 color;
|
||||
void main(void)
|
||||
{
|
||||
color = Color.zyxw;
|
||||
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix;
|
||||
mat4 ModelViewProjectionMatrix = ProjectionViewMatrix * ModelMatrix;
|
||||
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
// Keep orthogonality
|
||||
|
@ -14,7 +14,7 @@ void main(void)
|
||||
float gz = int(gl_VertexID >> 9) & (resolution.z - 1);
|
||||
uvw = vec3(gx, gy, gz) / vec3(resolution);
|
||||
vec3 WorldPos = (2. * uvw - 1.) * extents;
|
||||
gl_Position = ProjectionMatrix * ViewMatrix * RHMatrix * vec4(WorldPos, 1.);
|
||||
gl_Position = ProjectionViewMatrix * RHMatrix * vec4(WorldPos, 1.);
|
||||
gl_PointSize = 500. / gl_Position.w;
|
||||
|
||||
}
|
@ -1,81 +1,80 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2013 the SuperTuxKart team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#ifdef GL_ES
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 InverseModelMatrix;
|
||||
uniform vec2 texture_trans;
|
||||
#else
|
||||
uniform mat4 ModelMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
uniform mat4 InverseModelMatrix =
|
||||
mat4(1., 0., 0., 0.,
|
||||
0., 1., 0., 0.,
|
||||
0., 0., 1., 0.,
|
||||
0., 0., 0., 1.);
|
||||
|
||||
// skinning.vert
|
||||
#version 330 compatibility
|
||||
#define MAX_JOINT_NUM 36
|
||||
#define MAX_LIGHT_NUM 8
|
||||
uniform vec2 texture_trans = vec2(0., 0.);
|
||||
#endif
|
||||
uniform int skinning_offset;
|
||||
|
||||
uniform mat4 JointTransform[MAX_JOINT_NUM];
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec3 Normal;
|
||||
layout(location = 2) in vec4 Color;
|
||||
layout(location = 3) in vec4 Data1;
|
||||
layout(location = 4) in vec4 Data2;
|
||||
layout(location = 5) in ivec4 Joint;
|
||||
layout(location = 6) in vec4 Weight;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec4 Color;
|
||||
in vec4 Data1;
|
||||
in vec4 Data2;
|
||||
in ivec4 Joint;
|
||||
in vec4 Weight;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
out vec3 nor;
|
||||
out vec3 tangent;
|
||||
out vec3 bitangent;
|
||||
out vec2 uv;
|
||||
out vec4 color;
|
||||
|
||||
#stk_include "utils/getworldmatrix.vert"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int index;
|
||||
vec4 ecPos;
|
||||
vec3 normal;
|
||||
vec3 light_dir;
|
||||
float n_dot_l;
|
||||
float dist;
|
||||
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
|
||||
vec4 idle_position = vec4(Position, 1.);
|
||||
vec4 idle_normal = vec4(Normal, 0.);
|
||||
vec4 idle_tangent = vec4(Data1.z, Data1.w, Data2.x, 0.);
|
||||
vec4 idle_bitangent = vec4(Data2.y, Data2.z, Data2.w, 0.);
|
||||
vec4 skinned_position = vec4(0.);
|
||||
vec4 skinned_normal = vec4(0.);
|
||||
vec4 skinned_tangent = vec4(0.);
|
||||
vec4 skinned_bitangent = vec4(0.);
|
||||
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||
vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal;
|
||||
vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent;
|
||||
vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent;
|
||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
||||
skinned_normal += Weight[i] * single_bone_influenced_normal;
|
||||
skinned_tangent += Weight[i] * single_bone_influenced_tangent;
|
||||
skinned_bitangent += Weight[i] * single_bone_influenced_bitangent;
|
||||
}
|
||||
|
||||
mat4 ModelTransform = gl_ModelViewProjectionMatrix;
|
||||
|
||||
index = int(gl_Color.r * 255.99);
|
||||
mat4 vertTran = JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.g * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.b * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
index = int(gl_Color.a * 255.99);
|
||||
if(index > 0)
|
||||
vertTran += JointTransform[index - 1];
|
||||
|
||||
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
|
||||
|
||||
normal = (vertTran * vec4(gl_Normal, 0.0)).xyz;
|
||||
normal = normalize(gl_NormalMatrix * normal);
|
||||
|
||||
gl_FrontColor = vec4(0,0,0,0);
|
||||
for(int i = 0;i < MAX_LIGHT_NUM;i++)
|
||||
{
|
||||
light_dir = vec3(gl_LightSource[i].position-ecPos);
|
||||
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
|
||||
dist = length(light_dir);
|
||||
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
|
||||
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
|
||||
}
|
||||
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
|
||||
|
||||
|
||||
ModelTransform *= vertTran;
|
||||
|
||||
gl_Position = ModelTransform * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
|
||||
|
||||
/*
|
||||
// Reflections.
|
||||
vec3 r = reflect( ecPos.xyz , normal );
|
||||
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
|
||||
gl_TexCoord[1].s = r.x/m + 0.5;
|
||||
gl_TexCoord[1].t = r.y/m + 0.5;
|
||||
*/
|
||||
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
|
||||
// Keep orthogonality
|
||||
nor = (TransposeInverseModelView * skinned_normal).xyz;
|
||||
// Keep direction
|
||||
tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz;
|
||||
bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz;
|
||||
uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
|
||||
color = Color.zyxw;
|
||||
}
|
||||
|
44
data/shaders/skinning_shadow.vert
Normal file
44
data/shaders/skinning_shadow.vert
Normal file
@ -0,0 +1,44 @@
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform int skinning_offset;
|
||||
uniform int layer;
|
||||
|
||||
#if __VERSION__ >= 330
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 3) in vec4 Data1;
|
||||
layout(location = 5) in ivec4 Joint;
|
||||
layout(location = 6) in vec4 Weight;
|
||||
#else
|
||||
in vec3 Position;
|
||||
in vec4 Data1;
|
||||
in ivec4 Joint;
|
||||
in vec4 Weight;
|
||||
#endif
|
||||
|
||||
#ifdef VSLayer
|
||||
out vec2 uv;
|
||||
#else
|
||||
out vec2 tc;
|
||||
out int layerId;
|
||||
#endif
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 idle_position = vec4(Position, 1.);
|
||||
vec4 skinned_position = vec4(0.);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
|
||||
single_bone_influenced_position /= single_bone_influenced_position.w;
|
||||
skinned_position += Weight[i] * single_bone_influenced_position;
|
||||
}
|
||||
|
||||
#ifdef VSLayer
|
||||
gl_Layer = layer;
|
||||
uv = Data1.xy;
|
||||
gl_Position = ShadowViewProjMatrixes[gl_Layer] * ModelMatrix * skinned_position;
|
||||
#else
|
||||
layerId = layer;
|
||||
tc = Data1.xy;
|
||||
gl_Position = ShadowViewProjMatrixes[layerId] * ModelMatrix * skinned_position;
|
||||
#endif
|
||||
}
|
@ -72,8 +72,10 @@
|
||||
delta-angle="0.5" />
|
||||
|
||||
<!-- Skidmark data: maximum number of skid marks, and
|
||||
time for skidmarks to fade out. -->
|
||||
<skid-marks max-number="100" fadeout-time="60"/>
|
||||
time for skidmarks to fade out. Maximum number will over
|
||||
current number of karts, so the more karts, the less
|
||||
skidmark is on track. -->
|
||||
<skid-marks max-number="500" fadeout-time="60"/>
|
||||
|
||||
<!-- Defines when the upright constraint should be active, it's
|
||||
disabled when the kart is more than this value from the track. -->
|
||||
|
@ -923,7 +923,7 @@
|
||||
#endif
|
||||
|
||||
// Free BSD
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#define AS_BSD
|
||||
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
|
||||
#undef COMPLEX_MASK
|
||||
|
@ -38,7 +38,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ ) && !defined(__FreeBSD__)
|
||||
#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ ) \
|
||||
&& !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
@ -78,8 +78,10 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
|
||||
int getTriangleIndex() const
|
||||
{
|
||||
btAssert(isLeafNode());
|
||||
unsigned int x = 0;
|
||||
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
|
||||
// Get only the lower bits where the triangle index is stored
|
||||
return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
|
||||
return (m_escapeIndexOrTriangleIndex&~(y));
|
||||
}
|
||||
int getPartId() const
|
||||
{
|
||||
|
@ -30,6 +30,11 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES)
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(/D_IRR_STATIC_LIB_)
|
||||
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
|
||||
@ -59,7 +64,6 @@ endif()
|
||||
set(IRRLICHT_SOURCES
|
||||
source/Irrlicht/CAnimatedMeshSceneNode.cpp
|
||||
source/Irrlicht/CAttributes.cpp
|
||||
source/Irrlicht/CB3DMeshFileLoader.cpp
|
||||
source/Irrlicht/CBillboardSceneNode.cpp
|
||||
source/Irrlicht/CBoneSceneNode.cpp
|
||||
source/Irrlicht/CCameraSceneNode.cpp
|
||||
@ -187,11 +191,9 @@ source/Irrlicht/Irrlicht.cpp
|
||||
source/Irrlicht/irrXML.cpp
|
||||
source/Irrlicht/os.cpp
|
||||
source/Irrlicht/COpenGLNormalMapRenderer.cpp
|
||||
source/Irrlicht/BuiltInFont.h
|
||||
source/Irrlicht/CAnimatedMeshSceneNode.h
|
||||
source/Irrlicht/CAttributeImpl.h
|
||||
source/Irrlicht/CAttributes.h
|
||||
source/Irrlicht/CB3DMeshFileLoader.h
|
||||
source/Irrlicht/CBillboardSceneNode.h
|
||||
source/Irrlicht/CBlit.h
|
||||
source/Irrlicht/CBoneSceneNode.h
|
||||
|
@ -116,6 +116,8 @@ namespace scene
|
||||
NewVertices=new CSpecificVertexList<video::S3DVertexTangents>;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (Vertices)
|
||||
{
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "aabbox3d.h"
|
||||
#include "IMesh.h"
|
||||
|
||||
typedef void (*SkinningCallback)(const irr::core::matrix4& m, int joint, int offset);
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
|
@ -178,6 +178,9 @@ namespace scene
|
||||
\return The newly created clone of this node. */
|
||||
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) = 0;
|
||||
|
||||
virtual u32 getAnimationSetNum() = 0;
|
||||
virtual void addAnimationSet(u32 start, u32 end) = 0;
|
||||
virtual void useAnimationSet(u32 set_num) = 0;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
@ -95,8 +95,6 @@ public:
|
||||
\param s String of symbols which are not send down to the videodriver
|
||||
*/
|
||||
virtual void setInvisibleCharacters( const wchar_t *s ) = 0;
|
||||
|
||||
virtual u32 addLazyLoadCharacters(const wchar_t *s) { return 0; }
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
|
@ -371,6 +371,8 @@ protected:
|
||||
func(verts[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (boundingBoxUpdate)
|
||||
{
|
||||
|
@ -69,11 +69,11 @@ namespace scene
|
||||
virtual void animateMesh(f32 frame, f32 blend)=0;
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
virtual void skinMesh(f32 strength=1.f) = 0;
|
||||
virtual void skinMesh(f32 strength=1.f, SkinningCallback sc = NULL, int offset = -1) = 0;
|
||||
|
||||
//! converts the vertex type of all meshbuffers to tangents.
|
||||
/** E.g. used for bump mapping. */
|
||||
virtual void convertMeshToTangents() = 0;
|
||||
virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*)) = 0;
|
||||
|
||||
//! Allows to enable hardware skinning.
|
||||
/* This feature is not implementated in Irrlicht yet */
|
||||
|
@ -104,6 +104,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ITexture() {}
|
||||
|
||||
//! Lock function.
|
||||
/** Locks the Texture and returns a pointer to access the
|
||||
pixels. After lock() has been called and all operations on the pixels
|
||||
@ -190,6 +192,12 @@ public:
|
||||
//! Get name of texture (in most cases this is the filename)
|
||||
const io::SNamedPath& getName() const { return NamedPath; }
|
||||
|
||||
//! return open gl texture name
|
||||
virtual u32 getOpenGLTextureName() const = 0;
|
||||
|
||||
virtual u64 getHandle() = 0;
|
||||
|
||||
virtual void unloadHandle() {}
|
||||
protected:
|
||||
|
||||
//! Helper function, helps to get the desired texture creation format from the flags.
|
||||
|
@ -26,7 +26,9 @@ enum E_VERTEX_TYPE
|
||||
|
||||
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
|
||||
/** Usually used for tangent space normal mapping. */
|
||||
EVT_TANGENTS
|
||||
EVT_TANGENTS,
|
||||
|
||||
EVT_SKINNED_MESH
|
||||
};
|
||||
|
||||
//! Array holding the built in vertex type names
|
||||
@ -251,6 +253,22 @@ struct S3DVertexTangents : public S3DVertex
|
||||
}
|
||||
};
|
||||
|
||||
struct S3DVertexSkinnedMesh : public S3DVertexTangents
|
||||
{
|
||||
s32 m_joint_idx1;
|
||||
s32 m_joint_idx2;
|
||||
s32 m_joint_idx3;
|
||||
s32 m_joint_idx4;
|
||||
f32 m_weight1;
|
||||
f32 m_weight2;
|
||||
f32 m_weight3;
|
||||
f32 m_weight4;
|
||||
|
||||
E_VERTEX_TYPE getType() const
|
||||
{
|
||||
return EVT_SKINNED_MESH;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
|
||||
@ -261,6 +279,8 @@ inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
|
||||
return sizeof(video::S3DVertex2TCoords);
|
||||
case video::EVT_TANGENTS:
|
||||
return sizeof(video::S3DVertexTangents);
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return sizeof(video::S3DVertexSkinnedMesh);
|
||||
default:
|
||||
return sizeof(video::S3DVertex);
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return (video::S3DVertex*)&Vertices_2TCoords[index];
|
||||
case video::EVT_TANGENTS:
|
||||
return (video::S3DVertex*)&Vertices_Tangents[index];
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return (video::S3DVertex*)&Vertices_SkinnedMesh[index];
|
||||
default:
|
||||
return &Vertices_Standard[index];
|
||||
}
|
||||
@ -64,6 +66,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords.const_pointer();
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents.const_pointer();
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh.const_pointer();
|
||||
default:
|
||||
return Vertices_Standard.const_pointer();
|
||||
}
|
||||
@ -78,6 +82,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords.pointer();
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents.pointer();
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh.pointer();
|
||||
default:
|
||||
return Vertices_Standard.pointer();
|
||||
}
|
||||
@ -92,6 +98,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords.size();
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents.size();
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh.size();
|
||||
default:
|
||||
return Vertices_Standard.size();
|
||||
}
|
||||
@ -180,6 +188,20 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
}
|
||||
break;
|
||||
}
|
||||
case video::EVT_SKINNED_MESH:
|
||||
{
|
||||
if (Vertices_SkinnedMesh.empty())
|
||||
BoundingBox.reset(0,0,0);
|
||||
else
|
||||
{
|
||||
BoundingBox.reset(Vertices_SkinnedMesh[0].Pos);
|
||||
for (u32 i=1; i<Vertices_SkinnedMesh.size(); ++i)
|
||||
BoundingBox.addInternalPoint(Vertices_SkinnedMesh[i].Pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,6 +230,54 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
}
|
||||
}
|
||||
|
||||
void convertForSkinning()
|
||||
{
|
||||
if (VertexType==video::EVT_STANDARD)
|
||||
{
|
||||
for(u32 n=0;n<Vertices_Standard.size();++n)
|
||||
{
|
||||
video::S3DVertexSkinnedMesh Vertex;
|
||||
Vertex.Color=Vertices_Standard[n].Color;
|
||||
Vertex.Pos=Vertices_Standard[n].Pos;
|
||||
Vertex.Normal=Vertices_Standard[n].Normal;
|
||||
Vertex.TCoords=Vertices_Standard[n].TCoords;
|
||||
Vertex.Tangent=core::vector3df(0.0f, 0.0f, 0.0f);
|
||||
Vertex.Binormal=core::vector3df(0.0f, 0.0f, 0.0f);
|
||||
Vertex.m_joint_idx1 = 0;
|
||||
Vertex.m_joint_idx2 = 0;
|
||||
Vertex.m_joint_idx3 = 0;
|
||||
Vertex.m_joint_idx4 = 0;
|
||||
Vertex.m_weight1 = 0;
|
||||
Vertex.m_weight2 = 0;
|
||||
Vertex.m_weight3 = 0;
|
||||
Vertex.m_weight4 = 0;
|
||||
Vertices_SkinnedMesh.push_back(Vertex);
|
||||
}
|
||||
}
|
||||
else if (VertexType==video::EVT_TANGENTS)
|
||||
{
|
||||
for(u32 n=0;n<Vertices_Tangents.size();++n)
|
||||
{
|
||||
video::S3DVertexSkinnedMesh Vertex;
|
||||
Vertex.Color=Vertices_Tangents[n].Color;
|
||||
Vertex.Pos=Vertices_Tangents[n].Pos;
|
||||
Vertex.Normal=Vertices_Tangents[n].Normal;
|
||||
Vertex.TCoords=Vertices_Tangents[n].TCoords;
|
||||
Vertex.Tangent=Vertices_Tangents[n].Tangent;
|
||||
Vertex.Binormal=Vertices_Tangents[n].Binormal;
|
||||
Vertex.m_joint_idx1 = 0;
|
||||
Vertex.m_joint_idx2 = 0;
|
||||
Vertex.m_joint_idx3 = 0;
|
||||
Vertex.m_joint_idx4 = 0;
|
||||
Vertex.m_weight1 = 0;
|
||||
Vertex.m_weight2 = 0;
|
||||
Vertex.m_weight3 = 0;
|
||||
Vertex.m_weight4 = 0;
|
||||
Vertices_SkinnedMesh.push_back(Vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Convert to tangents vertex type
|
||||
virtual void convertToTangents()
|
||||
{
|
||||
@ -250,6 +320,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].Pos;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].Pos;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].Pos;
|
||||
default:
|
||||
return Vertices_Standard[i].Pos;
|
||||
}
|
||||
@ -264,6 +336,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].Pos;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].Pos;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].Pos;
|
||||
default:
|
||||
return Vertices_Standard[i].Pos;
|
||||
}
|
||||
@ -278,6 +352,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].Normal;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].Normal;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].Normal;
|
||||
default:
|
||||
return Vertices_Standard[i].Normal;
|
||||
}
|
||||
@ -292,6 +368,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].Normal;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].Normal;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].Normal;
|
||||
default:
|
||||
return Vertices_Standard[i].Normal;
|
||||
}
|
||||
@ -306,6 +384,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].TCoords;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].TCoords;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].TCoords;
|
||||
default:
|
||||
return Vertices_Standard[i].TCoords;
|
||||
}
|
||||
@ -320,6 +400,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
return Vertices_2TCoords[i].TCoords;
|
||||
case video::EVT_TANGENTS:
|
||||
return Vertices_Tangents[i].TCoords;
|
||||
case video::EVT_SKINNED_MESH:
|
||||
return Vertices_SkinnedMesh[i].TCoords;
|
||||
default:
|
||||
return Vertices_Standard[i].TCoords;
|
||||
}
|
||||
@ -381,6 +463,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
||||
|
||||
core::array<video::S3DVertexTangents> Vertices_Tangents;
|
||||
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
|
||||
core::array<video::S3DVertexSkinnedMesh> Vertices_SkinnedMesh;
|
||||
core::array<video::S3DVertex> Vertices_Standard;
|
||||
core::array<u16> Indices;
|
||||
|
||||
|
@ -12,18 +12,25 @@ namespace irr
|
||||
namespace core
|
||||
{
|
||||
|
||||
//! Sinks an element into the heap.
|
||||
//! Function object which can be used for sorting (default)
|
||||
template<class T>
|
||||
inline void heapsink(T*array, s32 element, s32 max)
|
||||
inline bool sortless(const T& a, const T& b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
//! Sinks an element into the heap with a custom compare function
|
||||
template<class T, class Compare>
|
||||
inline void heapsink(T*array, s32 element, s32 max, Compare cmp)
|
||||
{
|
||||
while ((element<<1) < max) // there is a left child
|
||||
{
|
||||
s32 j = (element<<1);
|
||||
|
||||
if (j+1 < max && array[j] < array[j+1])
|
||||
if (j+1 < max && cmp(array[j], array[j+1]))
|
||||
j = j+1; // take right child
|
||||
|
||||
if (array[element] < array[j])
|
||||
if (cmp(array[element], array[j]))
|
||||
{
|
||||
T t = array[j]; // swap elements
|
||||
array[j] = array[element];
|
||||
@ -35,10 +42,9 @@ inline void heapsink(T*array, s32 element, s32 max)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Sorts an array with size 'size' using heapsort.
|
||||
template<class T>
|
||||
inline void heapsort(T* array_, s32 size)
|
||||
//! Sorts an array with size 'size' using heapsort with a custom compare function
|
||||
template<class T, class Compare>
|
||||
inline void heapsort(T* array_, s32 size, Compare cmp)
|
||||
{
|
||||
// for heapsink we pretent this is not c++, where
|
||||
// arrays start with index 0. So we decrease the array pointer,
|
||||
@ -51,7 +57,7 @@ inline void heapsort(T* array_, s32 size)
|
||||
// build heap
|
||||
|
||||
for (i=((size-1)/2); i>=0; --i)
|
||||
heapsink(virtualArray, i+1, virtualSize-1);
|
||||
heapsink(virtualArray, i+1, virtualSize-1, cmp);
|
||||
|
||||
// sort array, leave out the last element (0)
|
||||
for (i=size-1; i>0; --i)
|
||||
@ -59,7 +65,7 @@ inline void heapsort(T* array_, s32 size)
|
||||
T t = array_[0];
|
||||
array_[0] = array_[i];
|
||||
array_[i] = t;
|
||||
heapsink(virtualArray, 1, i + 1);
|
||||
heapsink(virtualArray, 1, i + 1, cmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,10 +394,17 @@ public:
|
||||
void sort()
|
||||
{
|
||||
if (!is_sorted && used>1)
|
||||
heapsort(data, used);
|
||||
heapsort(data, used, sortless<T>);
|
||||
is_sorted = true;
|
||||
}
|
||||
|
||||
template<class Compare>
|
||||
void sort(Compare cmp)
|
||||
{
|
||||
if (!is_sorted && used>1)
|
||||
heapsort(data, used, cmp);
|
||||
is_sorted = true;
|
||||
}
|
||||
|
||||
//! Performs a binary search for an element, returns -1 if not found.
|
||||
/** The array will be sorted before the binary search if it is not
|
||||
|
@ -66,6 +66,10 @@ struct SNamedPath
|
||||
{
|
||||
return core::stringw(getPath());
|
||||
}
|
||||
const c8* getPtr() const
|
||||
{
|
||||
return getPath().c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
// convert the given path string to a name string.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
|
||||
}
|
||||
}
|
||||
|
||||
IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
|
||||
IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame(SkinningCallback sc, int offset)
|
||||
{
|
||||
if(Mesh->getMeshType() != EAMT_SKINNED)
|
||||
{
|
||||
@ -203,7 +203,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
|
||||
skinnedMesh->animateMesh(getFrameNr(), 1.0f);
|
||||
|
||||
// Update the skinned mesh for the current joint transforms.
|
||||
skinnedMesh->skinMesh(AnimationStrength);
|
||||
skinnedMesh->skinMesh(AnimationStrength, sc, offset);
|
||||
|
||||
if (JointMode == EJUOR_READ)//read from mesh
|
||||
{
|
||||
@ -992,6 +992,15 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
|
||||
return newNode;
|
||||
}
|
||||
|
||||
void CAnimatedMeshSceneNode::useAnimationSet(u32 set_num)
|
||||
{
|
||||
if (m_animation_set.empty())
|
||||
{
|
||||
setFrameLoop(getStartFrame(), getEndFrame());
|
||||
return;
|
||||
}
|
||||
setFrameLoop(m_animation_set[set_num * 2], m_animation_set[set_num * 2 + 1]);
|
||||
}
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
@ -19,6 +19,8 @@ namespace scene
|
||||
|
||||
class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode
|
||||
{
|
||||
private:
|
||||
core::array<u32> m_animation_set;
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
@ -158,10 +160,18 @@ namespace scene
|
||||
\return The newly created clone of this node. */
|
||||
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0);
|
||||
|
||||
virtual u32 getAnimationSetNum() { return m_animation_set.size() / 2; }
|
||||
virtual void addAnimationSet(u32 start, u32 end)
|
||||
{
|
||||
m_animation_set.push_back(start);
|
||||
m_animation_set.push_back(end);
|
||||
}
|
||||
virtual void useAnimationSet(u32 set_num);
|
||||
|
||||
protected:
|
||||
|
||||
//! Get a static mesh for the current frame of this animated mesh
|
||||
IMesh* getMeshForCurrentFrame();
|
||||
virtual IMesh* getMeshForCurrentFrame(SkinningCallback sc = NULL, int offset = -1);
|
||||
|
||||
void buildFrameNr(u32 timeMs);
|
||||
void checkJoints();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,140 +0,0 @@
|
||||
// Copyright (C) 2006-2012 Luke Hoschke
|
||||
// This file is part of the "Irrlicht Engine".
|
||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
|
||||
|
||||
// B3D Mesh loader
|
||||
// File format designed by Mark Sibly for the Blitz3D engine and has been
|
||||
// declared public domain
|
||||
|
||||
#include "IrrCompileConfig.h"
|
||||
|
||||
#ifndef __C_B3D_MESH_LOADER_H_INCLUDED__
|
||||
#define __C_B3D_MESH_LOADER_H_INCLUDED__
|
||||
|
||||
#include "IMeshLoader.h"
|
||||
#include "ISceneManager.h"
|
||||
#include "CSkinnedMesh.h"
|
||||
#include "IReadFile.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
||||
namespace scene
|
||||
{
|
||||
|
||||
//! Meshloader for B3D format
|
||||
class CB3DMeshFileLoader : public IMeshLoader
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor
|
||||
CB3DMeshFileLoader(scene::ISceneManager* smgr);
|
||||
|
||||
//! returns true if the file maybe is able to be loaded by this class
|
||||
//! based on the file extension (e.g. ".bsp")
|
||||
virtual bool isALoadableFileExtension(const io::path& filename) const;
|
||||
|
||||
//! creates/loads an animated mesh from the file.
|
||||
//! \return Pointer to the created mesh. Returns 0 if loading failed.
|
||||
//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
|
||||
//! See IReferenceCounted::drop() for more information.
|
||||
virtual IAnimatedMesh* createMesh(io::IReadFile* file);
|
||||
|
||||
private:
|
||||
|
||||
struct SB3dChunkHeader
|
||||
{
|
||||
c8 name[4];
|
||||
s32 size;
|
||||
};
|
||||
|
||||
struct SB3dChunk
|
||||
{
|
||||
SB3dChunk(const SB3dChunkHeader& header, long sp)
|
||||
: length(header.size+8), startposition(sp)
|
||||
{
|
||||
name[0]=header.name[0];
|
||||
name[1]=header.name[1];
|
||||
name[2]=header.name[2];
|
||||
name[3]=header.name[3];
|
||||
}
|
||||
|
||||
c8 name[4];
|
||||
s32 length;
|
||||
long startposition;
|
||||
};
|
||||
|
||||
struct SB3dTexture
|
||||
{
|
||||
core::stringc TextureName;
|
||||
s32 Flags;
|
||||
s32 Blend;
|
||||
f32 Xpos;
|
||||
f32 Ypos;
|
||||
f32 Xscale;
|
||||
f32 Yscale;
|
||||
f32 Angle;
|
||||
};
|
||||
|
||||
struct SB3dMaterial
|
||||
{
|
||||
SB3dMaterial() : red(1.0f), green(1.0f),
|
||||
blue(1.0f), alpha(1.0f), shininess(0.0f), blend(1),
|
||||
fx(0)
|
||||
{
|
||||
for (u32 i=0; i<video::MATERIAL_MAX_TEXTURES; ++i)
|
||||
Textures[i]=0;
|
||||
}
|
||||
video::SMaterial Material;
|
||||
f32 red, green, blue, alpha;
|
||||
f32 shininess;
|
||||
s32 blend,fx;
|
||||
SB3dTexture *Textures[video::MATERIAL_MAX_TEXTURES];
|
||||
};
|
||||
|
||||
bool load();
|
||||
bool readChunkNODE(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkMESH(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkVRTS(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkTRIS(scene::SSkinMeshBuffer *MeshBuffer, u32 MeshBufferID, s32 Vertices_Start);
|
||||
bool readChunkBONE(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkKEYS(CSkinnedMesh::SJoint* InJoint);
|
||||
bool readChunkANIM();
|
||||
bool readChunkTEXS();
|
||||
bool readChunkBRUS();
|
||||
|
||||
void loadTextures(SB3dMaterial& material) const;
|
||||
|
||||
void readString(core::stringc& newstring);
|
||||
void readFloats(f32* vec, u32 count);
|
||||
|
||||
core::array<SB3dChunk> B3dStack;
|
||||
|
||||
core::array<SB3dMaterial> Materials;
|
||||
core::array<SB3dTexture> Textures;
|
||||
|
||||
core::array<s32> AnimatedVertices_VertexID;
|
||||
|
||||
core::array<s32> AnimatedVertices_BufferID;
|
||||
|
||||
core::array<video::S3DVertex2TCoords> BaseVertices;
|
||||
|
||||
ISceneManager* SceneManager;
|
||||
CSkinnedMesh* AnimatedMesh;
|
||||
io::IReadFile* B3DFile;
|
||||
|
||||
//B3Ds have Vertex ID's local within the mesh I don't want this
|
||||
// Variable needs to be class member due to recursion in calls
|
||||
u32 VerticesStart;
|
||||
|
||||
bool NormalsInFile;
|
||||
bool HasVertexColors;
|
||||
bool ShowWarning;
|
||||
};
|
||||
|
||||
|
||||
} // end namespace scene
|
||||
} // end namespace irr
|
||||
|
||||
#endif // __C_B3D_MESH_LOADER_H_INCLUDED__
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "IWriteFile.h"
|
||||
#include "IXMLWriter.h"
|
||||
|
||||
#include "BuiltInFont.h"
|
||||
#include "os.h"
|
||||
|
||||
namespace irr
|
||||
@ -78,8 +77,6 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
|
||||
registerGUIElementFactory(factory);
|
||||
factory->drop();
|
||||
|
||||
loadBuiltInFont();
|
||||
|
||||
IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC );
|
||||
setSkin(skin);
|
||||
skin->drop();
|
||||
@ -165,29 +162,6 @@ CGUIEnvironment::~CGUIEnvironment()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGUIEnvironment::loadBuiltInFont()
|
||||
{
|
||||
io::IReadFile* file = io::createMemoryReadFile(BuiltInFontData, BuiltInFontDataSize, DefaultFontName, false);
|
||||
|
||||
CGUIFont* font = new CGUIFont(this, DefaultFontName );
|
||||
if (!font->load(file))
|
||||
{
|
||||
os::Printer::log("Error: Could not load built-in Font. Did you compile without the BMP loader?", ELL_ERROR);
|
||||
font->drop();
|
||||
file->drop();
|
||||
return;
|
||||
}
|
||||
|
||||
SFont f;
|
||||
f.NamedPath.setPath(DefaultFontName);
|
||||
f.Font = font;
|
||||
Fonts.push_back(f);
|
||||
|
||||
file->drop();
|
||||
}
|
||||
|
||||
|
||||
//! draws all gui elements
|
||||
void CGUIEnvironment::drawAll()
|
||||
{
|
||||
|
@ -262,8 +262,6 @@ private:
|
||||
|
||||
void updateHoveredElement(core::position2d<s32> mousePos);
|
||||
|
||||
void loadBuiltInFont();
|
||||
|
||||
struct SFont
|
||||
{
|
||||
io::SNamedPath NamedPath;
|
||||
|
@ -568,30 +568,30 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig, boo
|
||||
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = 0;
|
||||
glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
|
||||
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
|
||||
|
||||
if(!force_legacy_context)
|
||||
{
|
||||
// create core 4.3 context
|
||||
os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
|
||||
XErrorSignaled = false;
|
||||
// create core 3.3 context
|
||||
os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
|
||||
XErrorSignaled = false;
|
||||
// create core 3.1 context (for older mesa)
|
||||
os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
if(!force_legacy_context)
|
||||
{
|
||||
// create core 4.3 context
|
||||
os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
|
||||
} // if(force_legacy_context)
|
||||
XErrorSignaled = false;
|
||||
// create core 3.3 context
|
||||
os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
|
||||
XErrorSignaled = false;
|
||||
// create core 3.1 context (for older mesa)
|
||||
os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION);
|
||||
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx);
|
||||
if (!XErrorSignaled)
|
||||
return Context;
|
||||
|
||||
} // if(force_legacy_context)
|
||||
|
||||
XErrorSignaled = false;
|
||||
irr::video::useCoreContext = false;
|
||||
@ -626,7 +626,7 @@ bool CIrrDeviceLinux::createWindow()
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
|
||||
|
||||
GLXFBConfig glxFBConfig;
|
||||
GLXFBConfig glxFBConfig = NULL;
|
||||
int major, minor;
|
||||
bool isAvailableGLX=false;
|
||||
if (CreationParams.DriverType==video::EDT_OPENGL)
|
||||
@ -1044,7 +1044,9 @@ bool CIrrDeviceLinux::createWindow()
|
||||
glxWin=glXCreateWindow(display,glxFBConfig,window,NULL);
|
||||
if (glxWin)
|
||||
{
|
||||
getLogger()->setLogLevel(ELL_NONE);
|
||||
Context = getMeAGLContext(display, glxFBConfig, CreationParams.ForceLegacyDevice);
|
||||
getLogger()->setLogLevel(CreationParams.LoggingLevel);
|
||||
if (Context)
|
||||
{
|
||||
if (!glXMakeContextCurrent(display, glxWin, glxWin, Context))
|
||||
@ -2390,7 +2392,7 @@ bool CIrrDeviceLinux::activateJoysticks(core::array<SJoystickInfo> & joystickInf
|
||||
returnInfo.Axes = info.axes;
|
||||
returnInfo.Buttons = info.buttons;
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
|
||||
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
char name[80];
|
||||
ioctl( info.fd, JSIOCGNAME(80), name);
|
||||
returnInfo.Name = name;
|
||||
|
@ -646,6 +646,8 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
|
||||
buffer->drop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}// end switch
|
||||
|
||||
}// end for all mesh buffers
|
||||
@ -751,6 +753,8 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
|
||||
buffer->drop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}// end switch
|
||||
|
||||
}// end for all mesh buffers
|
||||
@ -987,6 +991,8 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
|
||||
vNew = v[idx[i]];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
@ -1075,6 +1081,8 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
@ -1158,6 +1166,8 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertex, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
@ -1805,6 +1815,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
|
||||
buf->drop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delete [] vc;
|
||||
|
@ -744,6 +744,8 @@ namespace video
|
||||
virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; }
|
||||
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; };
|
||||
virtual u32 getPitch() const { return 0; }
|
||||
virtual u32 getOpenGLTextureName() const { return 0; }
|
||||
virtual u64 getHandle() { return 0; }
|
||||
virtual void regenerateMipMapLevels(void* mipmapData=0) {};
|
||||
core::dimension2d<u32> size;
|
||||
};
|
||||
|
@ -505,7 +505,6 @@ namespace video
|
||||
|
||||
core::stringc FPVSPath = shaders_path;
|
||||
FPVSPath += "COGLES2FixedPipeline.vsh";
|
||||
os::Printer::log(FPVSPath.c_str());
|
||||
|
||||
core::stringc FPFSPath = shaders_path;
|
||||
FPFSPath += "COGLES2FixedPipeline.fsh";
|
||||
@ -516,7 +515,7 @@ namespace video
|
||||
c8* FPVSData = 0;
|
||||
c8* FPFSData = 0;
|
||||
|
||||
long Size = FPVSFile->getSize();
|
||||
long Size = FPVSFile ? FPVSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -525,7 +524,7 @@ namespace video
|
||||
FPVSData[Size] = 0;
|
||||
}
|
||||
|
||||
Size = FPFSFile->getSize();
|
||||
Size = FPFSFile ? FPFSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -558,7 +557,7 @@ namespace video
|
||||
c8* NMVSData = 0;
|
||||
c8* NMFSData = 0;
|
||||
|
||||
Size = NMVSFile->getSize();
|
||||
Size = NMVSFile ? NMVSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -567,7 +566,7 @@ namespace video
|
||||
NMVSData[Size] = 0;
|
||||
}
|
||||
|
||||
Size = NMFSFile->getSize();
|
||||
Size = NMFSFile ? NMFSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -600,7 +599,7 @@ namespace video
|
||||
c8* PMVSData = 0;
|
||||
c8* PMFSData = 0;
|
||||
|
||||
Size = PMVSFile->getSize();
|
||||
Size = PMVSFile ? PMVSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -609,7 +608,7 @@ namespace video
|
||||
PMVSData[Size] = 0;
|
||||
}
|
||||
|
||||
Size = PMFSFile->getSize();
|
||||
Size = PMFSFile ? PMFSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -672,7 +671,7 @@ namespace video
|
||||
c8* R2DVSData = 0;
|
||||
c8* R2DFSData = 0;
|
||||
|
||||
Size = R2DVSFile->getSize();
|
||||
Size = R2DVSFile ? R2DVSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -681,7 +680,7 @@ namespace video
|
||||
R2DVSData[Size] = 0;
|
||||
}
|
||||
|
||||
Size = R2DFSFile->getSize();
|
||||
Size = R2DFSFile ? R2DFSFile->getSize() : 0;
|
||||
|
||||
if (Size)
|
||||
{
|
||||
@ -3120,7 +3119,7 @@ namespace video
|
||||
setActiveTexture(GL_TEXTURE0 + stage);
|
||||
|
||||
if(Driver->CurrentTexture[stage])
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<const COGLES2Texture*>(Driver->CurrentTexture[stage])->getOpenGLTextureName());
|
||||
glBindTexture(GL_TEXTURE_2D, Driver->CurrentTexture[stage]->getOpenGLTextureName());
|
||||
|
||||
Texture[stage] = Driver->CurrentTexture[stage];
|
||||
}
|
||||
|
@ -117,6 +117,9 @@ void COGLES2MaterialRenderer::init(s32& outMaterialTypeNr,
|
||||
bool addMaterial)
|
||||
{
|
||||
outMaterialTypeNr = -1;
|
||||
|
||||
if (!vertexShaderProgram || !pixelShaderProgram)
|
||||
return;
|
||||
|
||||
Program = glCreateProgram();
|
||||
|
||||
|
@ -81,7 +81,9 @@ public:
|
||||
virtual u32 getPitch() const;
|
||||
|
||||
//! return open gl texture name
|
||||
GLuint getOpenGLTextureName() const;
|
||||
virtual u32 getOpenGLTextureName() const;
|
||||
|
||||
virtual u64 getHandle() { return 0; }
|
||||
|
||||
//! return whether this texture has mipmaps
|
||||
virtual bool hasMipMaps() const;
|
||||
@ -109,6 +111,13 @@ public:
|
||||
//! Get an access to texture states cache.
|
||||
SStatesCache& getStatesCache() const;
|
||||
|
||||
void setImage(IImage* new_image)
|
||||
{
|
||||
if (Image)
|
||||
Image->drop();
|
||||
Image = new_image;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! protected constructor with basic setup, no GL texture name created, for derived classes
|
||||
|
@ -276,6 +276,8 @@ void COctreeSceneNode::render()
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,6 +373,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
@ -424,6 +428,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
@ -474,6 +480,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
|
||||
for (v=0; v<b->getVertexCount(); ++v)
|
||||
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
polyCount += b->getIndexCount();
|
||||
@ -487,6 +495,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
|
||||
nodeCount = TangentsOctree->getNodeCount();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1581,6 +1581,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
|
||||
case EVT_TANGENTS:
|
||||
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1676,6 +1678,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
renderArray(indexList, primitiveCount, pType, iType);
|
||||
@ -1740,6 +1744,8 @@ void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERT
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1913,6 +1919,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
|
||||
case EVT_TANGENTS:
|
||||
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1984,6 +1992,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0));
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2555,8 +2565,7 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
|
||||
|
||||
if (!useCoreContext)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D,
|
||||
static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getOpenGLTextureName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace irr
|
||||
{
|
||||
namespace video
|
||||
{
|
||||
|
||||
extern bool useCoreContext;
|
||||
|
||||
//! Constructor
|
||||
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver,
|
||||
@ -91,6 +91,9 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr,
|
||||
{
|
||||
outMaterialTypeNr = -1;
|
||||
|
||||
if (useCoreContext)
|
||||
return;
|
||||
|
||||
bool success;
|
||||
|
||||
// create vertex shader
|
||||
|
@ -78,7 +78,9 @@ public:
|
||||
virtual u32 getPitch() const;
|
||||
|
||||
//! return open gl texture name
|
||||
GLuint getOpenGLTextureName() const;
|
||||
virtual u32 getOpenGLTextureName() const;
|
||||
|
||||
virtual u64 getHandle() { return 0; }
|
||||
|
||||
//! return whether this texture has mipmaps
|
||||
virtual bool hasMipMaps() const;
|
||||
@ -103,6 +105,13 @@ public:
|
||||
//! sets whether this texture is intended to be used as a render target.
|
||||
void setIsRenderTarget(bool isTarget);
|
||||
|
||||
void setImage(IImage* new_image)
|
||||
{
|
||||
if (Image)
|
||||
Image->drop();
|
||||
Image = new_image;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! protected constructor with basic setup, no GL texture name created, for derived classes
|
||||
|
@ -24,10 +24,6 @@
|
||||
#include "CSkinnedMesh.h"
|
||||
#endif
|
||||
|
||||
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
|
||||
#include "CB3DMeshFileLoader.h"
|
||||
#endif
|
||||
|
||||
#include "CCubeSceneNode.h"
|
||||
#include "CSphereSceneNode.h"
|
||||
#include "CAnimatedMeshSceneNode.h"
|
||||
@ -121,13 +117,6 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
|
||||
// create geometry creator
|
||||
GeometryCreator = new CGeometryCreator();
|
||||
|
||||
// add file format loaders. add the least commonly used ones first,
|
||||
// as these are checked last
|
||||
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
|
||||
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
|
||||
#endif
|
||||
|
||||
|
||||
// factories
|
||||
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
|
||||
registerSceneNodeFactory(factory);
|
||||
@ -1427,11 +1416,6 @@ void CSceneManager::drawAll(u32 flags)
|
||||
|
||||
void CSceneManager::setLightManager(ILightManager* lightManager)
|
||||
{
|
||||
if (lightManager)
|
||||
lightManager->grab();
|
||||
if (LightManager)
|
||||
LightManager->drop();
|
||||
|
||||
LightManager = lightManager;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "CBoneSceneNode.h"
|
||||
#include "IAnimatedMeshSceneNode.h"
|
||||
#include "os.h"
|
||||
#include "irrMap.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -22,12 +23,12 @@ CSkinnedMesh::CSkinnedMesh()
|
||||
LastAnimatedFrame(-1), SkinnedLastFrame(false),
|
||||
InterpolationMode(EIM_LINEAR),
|
||||
HasAnimation(false), PreparedForSkinning(false),
|
||||
AnimateNormals(true), HardwareSkinning(false)
|
||||
AnimateNormals(true), HardwareSkinning(false), m_total_joints(0),
|
||||
m_current_joint(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CSkinnedMesh");
|
||||
#endif
|
||||
|
||||
SkinningBuffers=&LocalBuffers;
|
||||
}
|
||||
|
||||
@ -74,12 +75,19 @@ void CSkinnedMesh::setAnimationSpeed(f32 fps)
|
||||
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
|
||||
IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
|
||||
{
|
||||
const bool is_hw_skinning_before = HardwareSkinning;
|
||||
if (is_hw_skinning_before)
|
||||
HardwareSkinning = false;
|
||||
//animate(frame,startFrameLoop, endFrameLoop);
|
||||
if (frame==-1)
|
||||
return this;
|
||||
|
||||
animateMesh((f32)frame, 1.0f);
|
||||
skinMesh();
|
||||
|
||||
if (is_hw_skinning_before)
|
||||
HardwareSkinning = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -93,6 +101,12 @@ IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32
|
||||
//! blend: {0-old position, 1-New position}
|
||||
void CSkinnedMesh::animateMesh(f32 frame, f32 blend)
|
||||
{
|
||||
if (HardwareSkinning && LastAnimatedFrame==frame)
|
||||
{
|
||||
SkinnedLastFrame=false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAnimation || LastAnimatedFrame==frame)
|
||||
return;
|
||||
|
||||
@ -445,7 +459,7 @@ void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint,
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
void CSkinnedMesh::skinMesh(f32 strength)
|
||||
void CSkinnedMesh::skinMesh(f32 strength, SkinningCallback sc, int offset)
|
||||
{
|
||||
if (!HasAnimation || SkinnedLastFrame)
|
||||
return;
|
||||
@ -456,7 +470,13 @@ void CSkinnedMesh::skinMesh(f32 strength)
|
||||
//-----------------
|
||||
|
||||
SkinnedLastFrame=true;
|
||||
if (!HardwareSkinning)
|
||||
m_current_joint = 0;
|
||||
if (HardwareSkinning)
|
||||
{
|
||||
for (u32 i = 0; i < RootJoints.size(); i++)
|
||||
skinJoint(RootJoints[i], 0, strength, sc, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Software skin....
|
||||
u32 i;
|
||||
@ -486,65 +506,73 @@ void CSkinnedMesh::skinMesh(f32 strength)
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength)
|
||||
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength,
|
||||
SkinningCallback sc, int offset)
|
||||
{
|
||||
if (joint->Weights.size())
|
||||
{
|
||||
//Find this joints pull on vertices...
|
||||
core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING);
|
||||
jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix);
|
||||
|
||||
core::vector3df thisVertexMove, thisNormalMove;
|
||||
|
||||
core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
|
||||
|
||||
//Skin Vertices Positions and Normals...
|
||||
for (u32 i=0; i<joint->Weights.size(); ++i)
|
||||
if (HardwareSkinning)
|
||||
{
|
||||
SWeight& weight = joint->Weights[i];
|
||||
if (sc != NULL) sc(jointVertexPull, m_current_joint, offset);
|
||||
m_current_joint++;
|
||||
}
|
||||
else
|
||||
{
|
||||
core::vector3df thisVertexMove, thisNormalMove;
|
||||
|
||||
// Pull this vertex...
|
||||
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
|
||||
core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
|
||||
|
||||
if (AnimateNormals)
|
||||
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal);
|
||||
|
||||
// Apply animation strength
|
||||
if(strength != 1.f)
|
||||
//Skin Vertices Positions and Normals...
|
||||
for (u32 i=0; i<joint->Weights.size(); ++i)
|
||||
{
|
||||
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength);
|
||||
if(AnimateNormals)
|
||||
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
|
||||
}
|
||||
SWeight& weight = joint->Weights[i];
|
||||
|
||||
if (! (*(weight.Moved)) )
|
||||
{
|
||||
*(weight.Moved) = true;
|
||||
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength;
|
||||
// Pull this vertex...
|
||||
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
|
||||
|
||||
if (AnimateNormals)
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = thisNormalMove * weight.strength;
|
||||
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal);
|
||||
|
||||
//*(weight._Pos) = thisVertexMove * weight.strength;
|
||||
// Apply animation strength
|
||||
if(strength != 1.f)
|
||||
{
|
||||
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength);
|
||||
if(AnimateNormals)
|
||||
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
|
||||
}
|
||||
|
||||
if (! (*(weight.Moved)) )
|
||||
{
|
||||
*(weight.Moved) = true;
|
||||
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength;
|
||||
|
||||
if (AnimateNormals)
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = thisNormalMove * weight.strength;
|
||||
|
||||
//*(weight._Pos) = thisVertexMove * weight.strength;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += thisVertexMove * weight.strength;
|
||||
|
||||
if (AnimateNormals)
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += thisNormalMove * weight.strength;
|
||||
|
||||
//*(weight._Pos) += thisVertexMove * weight.strength;
|
||||
}
|
||||
|
||||
buffersUsed[weight.buffer_id]->boundingBoxNeedsRecalculated();
|
||||
}
|
||||
else
|
||||
{
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += thisVertexMove * weight.strength;
|
||||
|
||||
if (AnimateNormals)
|
||||
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += thisNormalMove * weight.strength;
|
||||
|
||||
//*(weight._Pos) += thisVertexMove * weight.strength;
|
||||
}
|
||||
|
||||
buffersUsed[weight.buffer_id]->boundingBoxNeedsRecalculated();
|
||||
}
|
||||
}
|
||||
|
||||
//Skin all children
|
||||
for (u32 j=0; j<joint->Children.size(); ++j)
|
||||
skinJoint(joint->Children[j], joint, strength);
|
||||
skinJoint(joint->Children[j], joint, strength, sc, offset);
|
||||
}
|
||||
|
||||
|
||||
@ -724,28 +752,28 @@ bool CSkinnedMesh::setHardwareSkinning(bool on)
|
||||
if (HardwareSkinning!=on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
|
||||
//set mesh to static pose...
|
||||
for (u32 i=0; i<AllJoints.size(); ++i)
|
||||
{
|
||||
SJoint *joint=AllJoints[i];
|
||||
for (u32 j=0; j<joint->Weights.size(); ++j)
|
||||
{
|
||||
const u16 buffer_id=joint->Weights[j].buffer_id;
|
||||
const u32 vertex_id=joint->Weights[j].vertex_id;
|
||||
LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
|
||||
LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
|
||||
LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated();
|
||||
}
|
||||
}
|
||||
}
|
||||
toStaticPose();
|
||||
|
||||
HardwareSkinning=on;
|
||||
}
|
||||
return HardwareSkinning;
|
||||
}
|
||||
|
||||
void CSkinnedMesh::toStaticPose()
|
||||
{
|
||||
for (u32 i=0; i<AllJoints.size(); ++i)
|
||||
{
|
||||
SJoint *joint=AllJoints[i];
|
||||
for (u32 j=0; j<joint->Weights.size(); ++j)
|
||||
{
|
||||
const u16 buffer_id=joint->Weights[j].buffer_id;
|
||||
const u32 vertex_id=joint->Weights[j].vertex_id;
|
||||
LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
|
||||
LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
|
||||
LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint)
|
||||
{
|
||||
@ -1139,7 +1167,7 @@ void CSkinnedMesh::finalize()
|
||||
|
||||
void CSkinnedMesh::updateBoundingBox(void)
|
||||
{
|
||||
if(!SkinningBuffers)
|
||||
if(HardwareSkinning || !SkinningBuffers)
|
||||
return;
|
||||
|
||||
core::array<SSkinMeshBuffer*> & buffer = *SkinningBuffers;
|
||||
@ -1382,26 +1410,137 @@ void CSkinnedMesh::addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
|
||||
SkinnedLastFrame=false;
|
||||
}
|
||||
|
||||
|
||||
void CSkinnedMesh::convertMeshToTangents()
|
||||
bool CSkinnedMesh::sortJointInfluenceFunc(const JointInfluence& a,
|
||||
const JointInfluence& b)
|
||||
{
|
||||
// now calculate tangents
|
||||
for (u32 b=0; b < LocalBuffers.size(); ++b)
|
||||
return a.weight > b.weight;
|
||||
}
|
||||
|
||||
void CSkinnedMesh::convertForSkinning()
|
||||
{
|
||||
if (HardwareSkinning) return;
|
||||
|
||||
setHardwareSkinning(true);
|
||||
WeightInfluence wi;
|
||||
for (u32 b = 0; b < LocalBuffers.size(); b++)
|
||||
{
|
||||
if (LocalBuffers[b])
|
||||
LocalBuffers[b]->convertForSkinning();
|
||||
|
||||
wi.push_back(core::array<core::array<JointInfluence> > ());
|
||||
for (u32 i = 0; i < LocalBuffers[b]->getVertexCount(); i++)
|
||||
wi[b].push_back(core::array<JointInfluence>());
|
||||
}
|
||||
|
||||
size_t idx = 0;
|
||||
for (u32 i = 0; i < RootJoints.size(); i++)
|
||||
computeWeightInfluence(RootJoints[i], idx, wi);
|
||||
|
||||
for (u32 b = 0; b < LocalBuffers.size(); b++)
|
||||
{
|
||||
if (LocalBuffers[b])
|
||||
{
|
||||
LocalBuffers[b]->convertToTangents();
|
||||
const u32 total = wi[b].size();
|
||||
_IRR_DEBUG_BREAK_IF(LocalBuffers[b]->getVertexCount() != total);
|
||||
for (u32 i = 0; i < total; i++)
|
||||
{
|
||||
core::array<JointInfluence> this_influence;
|
||||
core::array<JointInfluence> reported_weight = wi[b][i];
|
||||
reported_weight.sort(sortJointInfluenceFunc);
|
||||
float remaining_weight = 1.0f;
|
||||
for (u32 j = 0; j < 4; j++)
|
||||
{
|
||||
JointInfluence influence;
|
||||
if (reported_weight.size() > j)
|
||||
influence = reported_weight[j];
|
||||
else
|
||||
{
|
||||
influence.joint_idx = -100000;
|
||||
influence.weight = remaining_weight;
|
||||
}
|
||||
remaining_weight -= influence.weight;
|
||||
this_influence.push_back(influence);
|
||||
}
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx1 = this_influence[0].joint_idx;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx2 = this_influence[1].joint_idx;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx3 = this_influence[2].joint_idx;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx4 = this_influence[3].joint_idx;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight1 = this_influence[0].weight;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight2 = this_influence[1].weight;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight3 = this_influence[2].weight;
|
||||
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight4 = this_influence[3].weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
SkinnedLastFrame = false;
|
||||
skinMesh();
|
||||
m_total_joints = m_current_joint;
|
||||
}
|
||||
|
||||
const s32 idxCnt = LocalBuffers[b]->getIndexCount();
|
||||
void CSkinnedMesh::computeWeightInfluence(SJoint *joint, size_t &index, WeightInfluence& wi)
|
||||
{
|
||||
if (!joint->Weights.empty())
|
||||
{
|
||||
for (u32 i = 0; i < joint->Weights.size(); i++)
|
||||
{
|
||||
SWeight& weight = joint->Weights[i];
|
||||
JointInfluence tmp;
|
||||
tmp.joint_idx = index;
|
||||
tmp.weight = weight.strength;
|
||||
wi[weight.buffer_id][weight.vertex_id].push_back(tmp);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
u16* idx = LocalBuffers[b]->getIndices();
|
||||
video::S3DVertexTangents* v =
|
||||
(video::S3DVertexTangents*)LocalBuffers[b]->getVertices();
|
||||
for (u32 j = 0; j < joint->Children.size(); j++)
|
||||
computeWeightInfluence(joint->Children[j], index, wi);
|
||||
}
|
||||
|
||||
for (s32 i=0; i<idxCnt; i+=3)
|
||||
void CSkinnedMesh::convertMeshToTangents(bool(*predicate)(IMeshBuffer*))
|
||||
{
|
||||
bool recalculate_animation = false;
|
||||
toStaticPose();
|
||||
for (u32 b = 0; b < LocalBuffers.size(); b++)
|
||||
{
|
||||
bool recalculate_joints = false;
|
||||
core::map<u32, u32> vert_loc_map;
|
||||
SSkinMeshBuffer* ssmb = LocalBuffers[b];
|
||||
if (ssmb)
|
||||
{
|
||||
if (!predicate(ssmb)) continue;
|
||||
|
||||
recalculate_joints = true;
|
||||
recalculate_animation = true;
|
||||
core::map<video::S3DVertexTangents, u32> vert_map;
|
||||
core::array<u16> tmp_indices;
|
||||
for (u32 i = 0; i < ssmb->Indices.size(); i++)
|
||||
{
|
||||
u32 vert_location = 0;
|
||||
const u32 cur_ver_loc = ssmb->Indices[i];
|
||||
const video::S3DVertex& v_old = ssmb->Vertices_Standard[cur_ver_loc];
|
||||
video::S3DVertexTangents v(v_old.Pos, v_old.Normal, v_old.Color, v_old.TCoords);
|
||||
core::map<video::S3DVertexTangents, u32>::Node *n = vert_map.find(v);
|
||||
if (n)
|
||||
{
|
||||
vert_location = n->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
vert_location = ssmb->Vertices_Tangents.size();
|
||||
ssmb->Vertices_Tangents.push_back(v);
|
||||
vert_map.insert(v, vert_location);
|
||||
}
|
||||
vert_loc_map[cur_ver_loc] = vert_location;
|
||||
tmp_indices.push_back(vert_location);
|
||||
}
|
||||
const s32 index_count = tmp_indices.size();
|
||||
u16* idx = tmp_indices.pointer();
|
||||
video::S3DVertexTangents* v = ssmb->Vertices_Tangents.pointer();
|
||||
core::vector3df local_normal;
|
||||
for (s32 i = 0; i < index_count; i += 3)
|
||||
{
|
||||
calculateTangents(
|
||||
v[idx[i+0]].Normal,
|
||||
local_normal,
|
||||
v[idx[i+0]].Tangent,
|
||||
v[idx[i+0]].Binormal,
|
||||
v[idx[i+0]].Pos,
|
||||
@ -1412,7 +1551,7 @@ void CSkinnedMesh::convertMeshToTangents()
|
||||
v[idx[i+2]].TCoords);
|
||||
|
||||
calculateTangents(
|
||||
v[idx[i+1]].Normal,
|
||||
local_normal,
|
||||
v[idx[i+1]].Tangent,
|
||||
v[idx[i+1]].Binormal,
|
||||
v[idx[i+1]].Pos,
|
||||
@ -1423,7 +1562,7 @@ void CSkinnedMesh::convertMeshToTangents()
|
||||
v[idx[i+0]].TCoords);
|
||||
|
||||
calculateTangents(
|
||||
v[idx[i+2]].Normal,
|
||||
local_normal,
|
||||
v[idx[i+2]].Tangent,
|
||||
v[idx[i+2]].Binormal,
|
||||
v[idx[i+2]].Pos,
|
||||
@ -1433,11 +1572,38 @@ void CSkinnedMesh::convertMeshToTangents()
|
||||
v[idx[i+0]].TCoords,
|
||||
v[idx[i+1]].TCoords);
|
||||
}
|
||||
ssmb->Indices = tmp_indices;
|
||||
ssmb->Vertices_Standard.clear();
|
||||
ssmb->VertexType = video::EVT_TANGENTS;
|
||||
}
|
||||
if (recalculate_joints)
|
||||
{
|
||||
Vertices_Moved[b].set_used(ssmb->getVertexCount());
|
||||
for (u32 i = 0; i < AllJoints.size(); i++)
|
||||
{
|
||||
SJoint *joint = AllJoints[i];
|
||||
for (u32 j = 0; j <joint->Weights.size(); j++)
|
||||
{
|
||||
if (joint->Weights[j].buffer_id == b)
|
||||
{
|
||||
core::map<u32, u32>::Node *n =
|
||||
vert_loc_map.find(joint->Weights[j].vertex_id);
|
||||
if (n)
|
||||
{
|
||||
joint->Weights[j].vertex_id = n->getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (recalculate_animation)
|
||||
{
|
||||
PreparedForSkinning = false;
|
||||
checkForAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSkinnedMesh::calculateTangents(
|
||||
core::vector3df& normal,
|
||||
core::vector3df& tangent,
|
||||
|
@ -14,6 +14,16 @@
|
||||
#include "matrix4.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
class JointInfluence
|
||||
{
|
||||
public:
|
||||
int joint_idx;
|
||||
float weight;
|
||||
};
|
||||
|
||||
typedef irr::core::array<irr::core::array
|
||||
<irr::core::array<JointInfluence> > > WeightInfluence;
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
@ -25,7 +35,6 @@ namespace scene
|
||||
class CSkinnedMesh: public ISkinnedMesh
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
CSkinnedMesh();
|
||||
|
||||
@ -52,7 +61,7 @@ namespace scene
|
||||
virtual void animateMesh(f32 frame, f32 blend);
|
||||
|
||||
//! Preforms a software skin on this mesh based of joint positions
|
||||
virtual void skinMesh(f32 strength=1.f);
|
||||
virtual void skinMesh(f32 strength=1.f, SkinningCallback sc = NULL, int offset = -1);
|
||||
|
||||
//! returns amount of mesh buffers.
|
||||
virtual u32 getMeshBufferCount() const;
|
||||
@ -105,7 +114,7 @@ namespace scene
|
||||
virtual void setInterpolationMode(E_INTERPOLATION_MODE mode);
|
||||
|
||||
//! Convertes the mesh to contain tangent information
|
||||
virtual void convertMeshToTangents();
|
||||
virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*));
|
||||
|
||||
//! Does the mesh have no animation
|
||||
virtual bool isStatic();
|
||||
@ -159,7 +168,16 @@ namespace scene
|
||||
void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
|
||||
IAnimatedMeshSceneNode* node,
|
||||
ISceneManager* smgr);
|
||||
|
||||
void convertForSkinning();
|
||||
|
||||
void computeWeightInfluence(SJoint *joint, size_t &index, WeightInfluence& wi);
|
||||
|
||||
u32 getTotalJoints() const { return m_total_joints; }
|
||||
|
||||
private:
|
||||
void toStaticPose();
|
||||
|
||||
void checkForAnimation();
|
||||
|
||||
void normalizeWeights();
|
||||
@ -175,12 +193,16 @@ private:
|
||||
|
||||
void calculateGlobalMatrices(SJoint *Joint,SJoint *ParentJoint);
|
||||
|
||||
void skinJoint(SJoint *Joint, SJoint *ParentJoint, f32 strength=1.f);
|
||||
void skinJoint(SJoint *Joint, SJoint *ParentJoint, f32 strength=1.f,
|
||||
SkinningCallback sc = NULL, int offset = -1);
|
||||
|
||||
void calculateTangents(core::vector3df& normal,
|
||||
core::vector3df& tangent, core::vector3df& binormal,
|
||||
core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3,
|
||||
core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3);
|
||||
|
||||
static bool sortJointInfluenceFunc(const JointInfluence& a,
|
||||
const JointInfluence& b);
|
||||
|
||||
core::array<SSkinMeshBuffer*> *SkinningBuffers; //Meshbuffer to skin, default is to skin localBuffers
|
||||
|
||||
@ -205,6 +227,8 @@ private:
|
||||
bool PreparedForSkinning;
|
||||
bool AnimateNormals;
|
||||
bool HardwareSkinning;
|
||||
u32 m_total_joints;
|
||||
u32 m_current_joint;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
@ -114,12 +114,10 @@ CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManag
|
||||
{
|
||||
Font = (gui::IGUIFontBitmap*)font;
|
||||
Font->grab();
|
||||
u32 texture_count = Font->addLazyLoadCharacters(text);
|
||||
_IRR_DEBUG_BREAK_IF(texture_count==0);
|
||||
|
||||
// mesh with one buffer per texture
|
||||
Mesh = new SMesh();
|
||||
for (u32 i=0; i<texture_count; ++i)
|
||||
for (u32 i=0; i<Font->getSpriteBank()->getTextureCount(); ++i)
|
||||
{
|
||||
SMeshBuffer *mb = new SMeshBuffer();
|
||||
mb->Material = Material;
|
||||
|
@ -719,7 +719,7 @@ bool CIrrDeviceMacOSX::createWindow()
|
||||
if (!CreationParams.WindowId)
|
||||
{
|
||||
[Window center];
|
||||
[(NSFileManager *)Window setDelegate:[NSApp delegate]];
|
||||
[(NSFileManager *)Window setDelegate:[(NSFileManager *)NSApp delegate]];
|
||||
|
||||
if(CreationParams.DriverType == video::EDT_OPENGL)
|
||||
[OGLContext setView:[Window contentView]];
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.1 KiB |
@ -3,4 +3,4 @@
|
||||
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/*")
|
||||
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")
|
||||
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "challenges/challenge_data.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/utf_writer.hpp"
|
||||
#include "io/xml_node.hpp"
|
||||
|
||||
@ -67,6 +68,9 @@ void StoryModeStatus::addStatus(ChallengeStatus *cs)
|
||||
//-----------------------------------------------------------------------------
|
||||
bool StoryModeStatus::isLocked(const std::string& feature)
|
||||
{
|
||||
if (UserConfigParams::m_everything_unlocked)
|
||||
return false;
|
||||
|
||||
return m_locked_features.find(feature)!=m_locked_features.end();
|
||||
} // featureIsLocked
|
||||
|
||||
|
@ -279,6 +279,16 @@ enum AnimType {ANIMS_NONE = 0,
|
||||
ANIMS_PLAYERS_ONLY = 1,
|
||||
ANIMS_ALL = 2 };
|
||||
|
||||
enum GeometryLevel
|
||||
{
|
||||
/** Display everything */
|
||||
GEOLEVEL_0 = 0,
|
||||
/** a few details are displayed */
|
||||
GEOLEVEL_1 = 1,
|
||||
/** Lowest level, no details are displayed. */
|
||||
GEOLEVEL_2 = 2
|
||||
};
|
||||
|
||||
/** Using X-macros for setting-possible values is not very pretty, but it's a
|
||||
* no-maintenance case :
|
||||
* when you want to add a new parameter, just add one signle line below and
|
||||
@ -410,13 +420,18 @@ namespace UserConfigParams
|
||||
&m_multitouch_group,
|
||||
"A parameter in range [0, 0.5] that determines the zone that is "
|
||||
"considered as max value in steering button."));
|
||||
|
||||
|
||||
PARAM_PREFIX FloatUserConfigParam m_multitouch_scale
|
||||
PARAM_DEFAULT( FloatUserConfigParam(1.0f, "multitouch_scale",
|
||||
&m_multitouch_group,
|
||||
"A parameter in range [0.5, 1.5] that determines the scale of the "
|
||||
"multitouch interface."));
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_screen_keyboard
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
|
||||
&m_multitouch_group,
|
||||
"Enable screen keyboard.") );
|
||||
|
||||
// ---- GP start order
|
||||
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
|
||||
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
|
||||
@ -481,7 +496,7 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_texture_compression
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
|
||||
&m_video_group, "Enable Texture Compression"));
|
||||
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
|
||||
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
|
||||
* Bit 1: setting done by default(0), or by user choice (2). This allows
|
||||
* to e.g. disable h.d. textures on hd3000 as default, but still allow the
|
||||
* user to enable it. */
|
||||
@ -583,6 +598,8 @@ namespace UserConfigParams
|
||||
|
||||
PARAM_PREFIX bool m_race_now PARAM_DEFAULT( false );
|
||||
|
||||
PARAM_PREFIX bool m_enforce_current_player PARAM_DEFAULT( false );
|
||||
|
||||
/** True to test funky ambient/diffuse/specularity in RGB &
|
||||
* all anisotropic */
|
||||
PARAM_PREFIX bool m_rendering_debug PARAM_DEFAULT( false );
|
||||
@ -673,6 +690,13 @@ namespace UserConfigParams
|
||||
"steering_animations", &m_graphics_quality,
|
||||
"Whether to display kart animations (0=disabled for all; "
|
||||
"1=enabled for humans, disabled for AIs; 2=enabled for all") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_geometry_level
|
||||
PARAM_DEFAULT( IntUserConfigParam(GEOLEVEL_0,
|
||||
"geometry_level", &m_graphics_quality,
|
||||
"Geometry quality 0=everything is displayed; "
|
||||
"1=a few details are displayed; 2=lowest level, no details") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_anisotropic
|
||||
PARAM_DEFAULT( IntUserConfigParam(4, "anisotropic",
|
||||
&m_graphics_quality,
|
||||
@ -892,6 +916,10 @@ namespace UserConfigParams
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "artist_debug_mode",
|
||||
"Whether to enable track debugging features") );
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_everything_unlocked
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "everything_unlocked",
|
||||
"Enable all karts and tracks") );
|
||||
|
||||
// TODO? implement blacklist for new irrlicht device and GUI
|
||||
PARAM_PREFIX std::vector<std::string> m_blacklist_res;
|
||||
|
||||
|
@ -29,6 +29,8 @@ class FaceTTF;
|
||||
class DigitFace : public FontWithFace
|
||||
{
|
||||
private:
|
||||
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
|
||||
@ -43,8 +45,6 @@ public:
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
|
||||
|
||||
}; // DigitFace
|
||||
|
||||
|
@ -22,7 +22,10 @@
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "graphics/2dutils.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/stk_texture.hpp"
|
||||
#include "graphics/stk_tex_manager.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/skin.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
@ -50,8 +53,11 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
|
||||
*/
|
||||
FontWithFace::~FontWithFace()
|
||||
{
|
||||
m_page->drop();
|
||||
m_page = NULL;
|
||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||
{
|
||||
STKTexManager::getInstance()->removeTexture(
|
||||
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
|
||||
}
|
||||
m_spritebank->drop();
|
||||
m_spritebank = NULL;
|
||||
|
||||
@ -66,9 +72,6 @@ FontWithFace::~FontWithFace()
|
||||
void FontWithFace::init()
|
||||
{
|
||||
setDPI();
|
||||
m_page = irr_driver->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
|
||||
core::dimension2du(getGlyphPageSize(), getGlyphPageSize()));
|
||||
|
||||
// Get the max height for this face
|
||||
assert(m_face_ttf->getTotalFaces() > 0);
|
||||
FT_Face cur_face = m_face_ttf->getFace(0);
|
||||
@ -100,6 +103,11 @@ void FontWithFace::reset()
|
||||
m_new_char_holder.clear();
|
||||
m_character_area_map.clear();
|
||||
m_character_glyph_info_map.clear();
|
||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||
{
|
||||
STKTexManager::getInstance()->removeTexture(
|
||||
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
|
||||
}
|
||||
m_spritebank->clear();
|
||||
createNewGlyphPage();
|
||||
} // reset
|
||||
@ -129,32 +137,25 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
*/
|
||||
void FontWithFace::createNewGlyphPage()
|
||||
{
|
||||
m_page->fill(video::SColor(0, 255, 255, 255));
|
||||
#ifndef SERVER_ONLY
|
||||
uint8_t* data = new uint8_t[getGlyphPageSize() * getGlyphPageSize() *
|
||||
(CVS->isARBTextureSwizzleUsable() ? 1 : 4)]();
|
||||
#else
|
||||
uint8_t* data = NULL;
|
||||
#endif
|
||||
m_current_height = 0;
|
||||
m_used_width = 0;
|
||||
m_used_height = 0;
|
||||
|
||||
// Font textures can not be resized (besides the impact on quality in
|
||||
// this case, the rectangles in spritebank would become wrong).
|
||||
core::dimension2du old_max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
|
||||
|
||||
video::ITexture* page_texture = irr_driver->getVideoDriver()
|
||||
->addTexture("Glyph_page", m_page);
|
||||
m_spritebank->addTexture(NULL);
|
||||
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
|
||||
page_texture);
|
||||
|
||||
// Doing so to make sure the texture inside the sprite bank has only 1
|
||||
// reference, so they can be removed or updated on-the-fly
|
||||
irr_driver->getVideoDriver()->removeTexture(page_texture);
|
||||
assert(page_texture->getReferenceCount() == 1);
|
||||
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
|
||||
|
||||
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
|
||||
StringUtils::toString(m_spritebank->getTextureCount()),
|
||||
getGlyphPageSize(),
|
||||
#ifndef SERVER_ONLY
|
||||
CVS->isARBTextureSwizzleUsable()
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
m_spritebank->addTexture(STKTexManager::getInstance()->addTexture(stkt));
|
||||
} // createNewGlyphPage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -184,80 +185,17 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
"rendering a glyph to bitmap");
|
||||
|
||||
// Convert to an anti-aliased bitmap
|
||||
FT_Bitmap bits = slot->bitmap;
|
||||
|
||||
core::dimension2du d(bits.width + 1, bits.rows + 1);
|
||||
core::dimension2du texture_size;
|
||||
texture_size = d.getOptimalSize(!(irr_driver->getVideoDriver()
|
||||
->queryFeature(video::EVDF_TEXTURE_NPOT)), !(irr_driver
|
||||
->getVideoDriver()->queryFeature(video::EVDF_TEXTURE_NSQUARE)),
|
||||
true, 0);
|
||||
|
||||
FT_Bitmap* bits = &(slot->bitmap);
|
||||
core::dimension2du texture_size(bits->width + 1, bits->rows + 1);
|
||||
if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
|
||||
m_used_height + m_current_height + texture_size.Height >
|
||||
getGlyphPageSize()) ||
|
||||
m_used_height + texture_size.Height > getGlyphPageSize())
|
||||
{
|
||||
// Current glyph page is full:
|
||||
// Save the old glyph page
|
||||
core::dimension2du old_max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d
|
||||
("MAX_TEXTURE_SIZE");
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
|
||||
video::ITexture* page_texture = irr_driver->getVideoDriver()
|
||||
->addTexture("Glyph_page", m_page);
|
||||
|
||||
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
|
||||
page_texture);
|
||||
irr_driver->getVideoDriver()->removeTexture(page_texture);
|
||||
assert(page_texture->getReferenceCount() == 1);
|
||||
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
|
||||
|
||||
// Clear and add a new one
|
||||
// Add a new glyph page if current one is full
|
||||
createNewGlyphPage();
|
||||
}
|
||||
|
||||
video::IImage* glyph = NULL;
|
||||
switch (bits.pixel_mode)
|
||||
{
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
{
|
||||
// Create our blank image.
|
||||
glyph = irr_driver->getVideoDriver()
|
||||
->createImage(video::ECF_A8R8G8B8, texture_size);
|
||||
glyph->fill(video::SColor(0, 255, 255, 255));
|
||||
|
||||
// Load the grayscale data in.
|
||||
const float gray_count = static_cast<float>(bits.num_grays);
|
||||
const unsigned int image_pitch =
|
||||
glyph->getPitch() / sizeof(unsigned int);
|
||||
unsigned int* image_data = (unsigned int*)glyph->lock();
|
||||
unsigned char* glyph_data = bits.buffer;
|
||||
|
||||
for (unsigned int y = 0; y < (unsigned int)bits.rows; y++)
|
||||
{
|
||||
unsigned char* row = glyph_data;
|
||||
for (unsigned int x = 0; x < (unsigned)bits.width; x++)
|
||||
{
|
||||
image_data[y * image_pitch + x] |=
|
||||
static_cast<unsigned int>(255.0f *
|
||||
(static_cast<float>(*row++) / gray_count)) << 24;
|
||||
}
|
||||
glyph_data += bits.pitch;
|
||||
}
|
||||
glyph->unlock();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
if (!glyph)
|
||||
Log::fatal("FontWithFace", "Failed to load a glyph");
|
||||
|
||||
// Done creating a single glyph, now copy to the glyph page...
|
||||
// Determine the linebreak location
|
||||
if (m_used_width + texture_size.Width > getGlyphPageSize())
|
||||
{
|
||||
@ -266,16 +204,39 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
m_current_height = 0;
|
||||
}
|
||||
|
||||
// Copy to the full glyph page
|
||||
glyph->copyTo(m_page, core::position2di(m_used_width, m_used_height));
|
||||
const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
|
||||
#ifndef SERVER_ONLY
|
||||
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
|
||||
assert(bits->pixel_mode == FT_PIXEL_MODE_GRAY);
|
||||
if (CVS->isARBTextureSwizzleUsable())
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
|
||||
bits->width, bits->rows, GL_RED, GL_UNSIGNED_BYTE, bits->buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int size = bits->width * bits->rows;
|
||||
uint8_t* image_data = new uint8_t[size * 4];
|
||||
memset(image_data, 255, size * 4);
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
image_data[4 * i + 3] = bits->buffer[i];
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
|
||||
bits->width, bits->rows, GL_BGRA, GL_UNSIGNED_BYTE, image_data);
|
||||
delete[] image_data;
|
||||
}
|
||||
if (tex->hasMipMaps())
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#endif
|
||||
|
||||
// Store the rectangle of current glyph
|
||||
gui::SGUISpriteFrame f;
|
||||
gui::SGUISprite s;
|
||||
core::rect<s32> rectangle(m_used_width, m_used_height,
|
||||
m_used_width + bits.width, m_used_height + bits.rows);
|
||||
m_used_width + bits->width, m_used_height + bits->rows);
|
||||
f.rectNumber = m_spritebank->getPositions().size();
|
||||
f.textureNumber = m_spritebank->getTextureCount() - 1;
|
||||
f.textureNumber = cur_tex;
|
||||
|
||||
// Add frame to sprite
|
||||
s.Frames.push_back(f);
|
||||
@ -295,10 +256,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
a.spriteno = f.rectNumber;
|
||||
m_character_area_map[c] = a;
|
||||
|
||||
// Clean the temporary glyph
|
||||
glyph->drop();
|
||||
glyph = NULL;
|
||||
|
||||
// Store used area
|
||||
m_used_width += texture_size.Width;
|
||||
if (m_current_height < texture_size.Height)
|
||||
@ -321,23 +278,6 @@ void FontWithFace::updateCharactersList()
|
||||
}
|
||||
m_new_char_holder.clear();
|
||||
|
||||
// Update last glyph page
|
||||
core::dimension2du old_max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
|
||||
|
||||
video::ITexture* page_texture = irr_driver->getVideoDriver()
|
||||
->addTexture("Glyph_page", m_page);
|
||||
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
|
||||
page_texture);
|
||||
|
||||
irr_driver->getVideoDriver()->removeTexture(page_texture);
|
||||
assert(page_texture->getReferenceCount() == 1);
|
||||
|
||||
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
|
||||
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
|
||||
|
||||
} // updateCharactersList
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -353,10 +293,9 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
|
||||
core::dimension2d<u32> size = tex->getSize();
|
||||
video::ECOLOR_FORMAT col_format = tex->getColorFormat();
|
||||
void* data = tex->lock();
|
||||
|
||||
video::IImage* image = irr_driver->getVideoDriver()
|
||||
->createImageFromData(col_format, size, data, false/*copy mem*/);
|
||||
|
||||
->createImageFromData(col_format, size, data,
|
||||
true/*ownForeignMemory*/);
|
||||
tex->unlock();
|
||||
irr_driver->getVideoDriver()->writeImageToFile(image, std::string
|
||||
(name + "_" + StringUtils::toString(i) + ".png").c_str());
|
||||
@ -618,28 +557,6 @@ void FontWithFace::render(const core::stringw& text,
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prevent overwriting texture used by billboard text when
|
||||
// using lazy loading characters
|
||||
if (supportLazyLoadChar() && fallback[i])
|
||||
{
|
||||
const int cur_texno = m_fallback_font->getSpriteBank()
|
||||
->getSprites()[area.spriteno].Frames[0].textureNumber;
|
||||
if (cur_texno == int(m_fallback_font->getSpriteBank()
|
||||
->getTextureCount() - 1))
|
||||
{
|
||||
m_fallback_font->createNewGlyphPage();
|
||||
}
|
||||
}
|
||||
else if (supportLazyLoadChar())
|
||||
{
|
||||
const int cur_texno = m_spritebank
|
||||
->getSprites()[area.spriteno].Frames[0].textureNumber;
|
||||
if (cur_texno == int(m_spritebank->getTextureCount() - 1))
|
||||
{
|
||||
createNewGlyphPage();
|
||||
}
|
||||
}
|
||||
|
||||
// Billboard text specific, use offset_y_bt instead
|
||||
float glyph_offset_x = area.bearing_x *
|
||||
(fallback[i] ? m_fallback_font_scale : scale);
|
||||
|
@ -92,6 +92,39 @@ protected:
|
||||
/** Used in top side bearing calculation. */
|
||||
int m_glyph_max_height;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Check characters to see if they are loaded in font, if not load them.
|
||||
* For font that doesn't need lazy loading, nothing will be done.
|
||||
* \param in_ptr Characters to check.
|
||||
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
|
||||
* which is called in \ref reset. */
|
||||
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
|
||||
{
|
||||
if (!supportLazyLoadChar() && !first_load) return;
|
||||
|
||||
for (const wchar_t* p = in_ptr; *p; ++p)
|
||||
{
|
||||
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
|
||||
continue;
|
||||
if (!loadedChar(*p))
|
||||
{
|
||||
loadGlyphInfo(*p);
|
||||
if (supportChar(*p))
|
||||
addLazyLoadChar(*p);
|
||||
else if (m_fallback_font != NULL)
|
||||
{
|
||||
if (!m_fallback_font->loadedChar(*p))
|
||||
{
|
||||
m_fallback_font->loadGlyphInfo(*p);
|
||||
if (m_fallback_font->supportChar(*p))
|
||||
m_fallback_font->addLazyLoadChar(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void updateCharactersList();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the fallback font for this font, so if some character is missing in
|
||||
* this font, it will use that fallback font to try rendering it.
|
||||
@ -129,9 +162,6 @@ private:
|
||||
/** Sprite bank to store each glyph. */
|
||||
gui::IGUISpriteBank* m_spritebank;
|
||||
|
||||
/** A full glyph page for this font. */
|
||||
video::IImage* m_page;
|
||||
|
||||
/** The current max height at current drawing line in glyph page. */
|
||||
unsigned int m_current_height;
|
||||
|
||||
@ -206,6 +236,8 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void loadGlyphInfo(wchar_t c);
|
||||
// ------------------------------------------------------------------------
|
||||
void createNewGlyphPage();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a character into \ref m_new_char_holder for lazy loading later. */
|
||||
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
|
||||
// ------------------------------------------------------------------------
|
||||
@ -213,6 +245,9 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void setDPI();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Override it if sub-class should not do lazy loading characters. */
|
||||
virtual bool supportLazyLoadChar() const { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Defined by sub-class about the texture size of glyph page, it should be
|
||||
* a power of two. */
|
||||
virtual unsigned int getGlyphPageSize() const = 0;
|
||||
@ -266,44 +301,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the dpi of this face. */
|
||||
unsigned int getDPI() const { return m_face_dpi; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Override it if sub-class should not do lazy loading characters. */
|
||||
virtual bool supportLazyLoadChar() const { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Check characters to see if they are loaded in font, if not load them.
|
||||
* For font that doesn't need lazy loading, nothing will be done.
|
||||
* \param in_ptr Characters to check.
|
||||
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
|
||||
* which is called in \ref reset. */
|
||||
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
|
||||
{
|
||||
if (!supportLazyLoadChar() && !first_load) return;
|
||||
|
||||
for (const wchar_t* p = in_ptr; *p; ++p)
|
||||
{
|
||||
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
|
||||
continue;
|
||||
if (!loadedChar(*p))
|
||||
{
|
||||
loadGlyphInfo(*p);
|
||||
if (supportChar(*p))
|
||||
addLazyLoadChar(*p);
|
||||
else if (m_fallback_font != NULL)
|
||||
{
|
||||
if (!m_fallback_font->loadedChar(*p))
|
||||
{
|
||||
m_fallback_font->loadGlyphInfo(*p);
|
||||
if (m_fallback_font->supportChar(*p))
|
||||
m_fallback_font->addLazyLoadChar(*p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void updateCharactersList();
|
||||
// ------------------------------------------------------------------------
|
||||
void createNewGlyphPage();
|
||||
|
||||
}; // FontWithFace
|
||||
|
||||
|
@ -24,18 +24,9 @@
|
||||
#include "graphics/shader.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/shared_gpu_objects.hpp"
|
||||
#include "graphics/texture_manager.hpp"
|
||||
#include "graphics/texture_shader.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
#if defined(USE_GLES2)
|
||||
# define _IRR_COMPILE_WITH_OGLES2_
|
||||
# include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h"
|
||||
#else
|
||||
# include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
|
||||
#endif
|
||||
|
||||
|
||||
// ============================================================================
|
||||
class Primitive2DList : public TextureShader<Primitive2DList, 1, float>
|
||||
{
|
||||
@ -186,16 +177,8 @@ static void drawTexColoredQuad(const video::ITexture *texture,
|
||||
|
||||
ColoredTextureRectShader::getInstance()->use();
|
||||
glBindVertexArray(ColoredTextureRectShader::getInstance()->m_vao);
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
const irr::video::COpenGLTexture *t =
|
||||
static_cast<const irr::video::COpenGLTexture*>(texture);
|
||||
#else
|
||||
const irr::video::COGLES2Texture *t =
|
||||
static_cast<const irr::video::COGLES2Texture*>(texture);
|
||||
#endif
|
||||
ColoredTextureRectShader::getInstance()
|
||||
->setTextureUnits(t->getOpenGLTextureName());
|
||||
->setTextureUnits(texture->getOpenGLTextureName());
|
||||
ColoredTextureRectShader::getInstance()
|
||||
->setUniforms(core::vector2df(center_pos_x, center_pos_y),
|
||||
core::vector2df(width, height),
|
||||
@ -367,16 +350,8 @@ void draw2DImage(const video::ITexture* texture,
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()->use();
|
||||
glBindVertexArray(SharedGPUObjects::getUI_VAO());
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
const video::COpenGLTexture *c_texture =
|
||||
static_cast<const video::COpenGLTexture*>(texture);
|
||||
#else
|
||||
const video::COGLES2Texture *c_texture =
|
||||
static_cast<const video::COGLES2Texture*>(texture);
|
||||
#endif
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setTextureUnits(c_texture->getOpenGLTextureName());
|
||||
->setTextureUnits(texture->getOpenGLTextureName());
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setUniforms(core::vector2df(center_pos_x, center_pos_y),
|
||||
@ -450,16 +425,8 @@ void draw2DImage(const video::ITexture* texture,
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()->use();
|
||||
glBindVertexArray(SharedGPUObjects::getUI_VAO());
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
const video::COpenGLTexture *c_texture =
|
||||
static_cast<const video::COpenGLTexture*>(texture);
|
||||
#else
|
||||
const video::COGLES2Texture *c_texture =
|
||||
static_cast<const video::COGLES2Texture*>(texture);
|
||||
#endif
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setTextureUnits(c_texture->getOpenGLTextureName());
|
||||
->setTextureUnits(texture->getOpenGLTextureName());
|
||||
|
||||
UniformColoredTextureRectShader::getInstance()
|
||||
->setUniforms(core::vector2df(center_pos_x, center_pos_y),
|
||||
@ -574,14 +541,7 @@ void draw2DImage(const video::ITexture* texture,
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(USE_GLES2)
|
||||
const video::COpenGLTexture *c_texture =
|
||||
static_cast<const video::COpenGLTexture*>(texture);
|
||||
#else
|
||||
const video::COGLES2Texture *c_texture =
|
||||
static_cast<const video::COGLES2Texture*>(texture);
|
||||
#endif
|
||||
drawTexQuad(c_texture->getOpenGLTextureName(), width, height,
|
||||
drawTexQuad(texture->getOpenGLTextureName(), width, height,
|
||||
center_pos_x, center_pos_y, tex_center_pos_x,
|
||||
tex_center_pos_y, tex_width, tex_height);
|
||||
}
|
||||
@ -657,14 +617,7 @@ void draw2DImage(const video::ITexture* texture,
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(USE_GLES2)
|
||||
const video::COpenGLTexture *c_texture =
|
||||
static_cast<const video::COpenGLTexture*>(texture);
|
||||
#else
|
||||
const video::COGLES2Texture *c_texture =
|
||||
static_cast<const video::COGLES2Texture*>(texture);
|
||||
#endif
|
||||
drawTexQuad(c_texture->getOpenGLTextureName(), width, height,
|
||||
drawTexQuad(texture->getOpenGLTextureName(), width, height,
|
||||
center_pos_x, center_pos_y, tex_center_pos_x,
|
||||
tex_center_pos_y, tex_width, tex_height);
|
||||
}
|
||||
@ -707,8 +660,7 @@ void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices,
|
||||
|
||||
Primitive2DList::getInstance()->use();
|
||||
Primitive2DList::getInstance()->setUniforms(1.0f);
|
||||
compressTexture(tex, false);
|
||||
Primitive2DList::getInstance()->setTextureUnits(getTextureGLuint(tex));
|
||||
Primitive2DList::getInstance()->setTextureUnits(tex->getOpenGLTextureName());
|
||||
glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
glDeleteVertexArrays(1, &tmpvao);
|
||||
|
@ -400,6 +400,8 @@ void CBatchingMesh::recalculateDestBufferBoundingBox(u32 i)
|
||||
case video::EVT_TANGENTS:
|
||||
((SMeshBufferTangents*)DestBuffers[i].Buffer)->recalculateBoundingBox();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ void CentralVideoSettings::init()
|
||||
hasExplicitAttribLocation = false;
|
||||
hasGS = false;
|
||||
hasTextureFilterAnisotropic = false;
|
||||
hasTextureSwizzle = false;
|
||||
|
||||
#if defined(USE_GLES2)
|
||||
hasBGRA = false;
|
||||
@ -90,6 +91,11 @@ void CentralVideoSettings::init()
|
||||
std::string driver((char*)(glGetString(GL_VERSION)));
|
||||
std::string card((char*)(glGetString(GL_RENDERER)));
|
||||
GraphicsRestrictions::init(driver, card);
|
||||
|
||||
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
|
||||
{
|
||||
m_glsl = false;
|
||||
}
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
|
||||
@ -158,9 +164,12 @@ void CentralVideoSettings::init()
|
||||
Log::info("GLDriver", "ARB Multi Draw Indirect Present");
|
||||
}
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
|
||||
hasGLExtension("GL_EXT_texture_compression_s3tc")) {
|
||||
hasGLExtension("GL_EXT_texture_compression_s3tc") &&
|
||||
hasGLExtension("GL_ARB_texture_compression_rgtc"))
|
||||
{
|
||||
hasTextureCompression = true;
|
||||
Log::info("GLDriver", "EXT Texture Compression S3TC Present");
|
||||
Log::info("GLDriver", "ARB Texture Compression RGTC Present");
|
||||
}
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
|
||||
hasGLExtension("GL_ARB_uniform_buffer_object")) {
|
||||
@ -182,7 +191,11 @@ void CentralVideoSettings::init()
|
||||
hasGS = true;
|
||||
Log::info("GLDriver", "Geometry Shaders Present");
|
||||
}
|
||||
|
||||
if (hasGLExtension("GL_ARB_texture_swizzle"))
|
||||
{
|
||||
hasTextureSwizzle = true;
|
||||
Log::info("GLDriver", "ARB Texture Swizzle Present");
|
||||
}
|
||||
// Only unset the high def textures if they are set as default. If the
|
||||
// user has enabled them (bit 1 set), then leave them enabled.
|
||||
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
|
||||
@ -222,13 +235,8 @@ void CentralVideoSettings::init()
|
||||
#else
|
||||
if (m_glsl == true)
|
||||
{
|
||||
hasArraysOfArrays = true;
|
||||
hasTextureStorage = true;
|
||||
hasTextureView = true;
|
||||
hasBindlessTexture = true;
|
||||
hasImageLoadStore = true;
|
||||
hasAtomics = true;
|
||||
hasSSBO = true;
|
||||
hasTextureSwizzle = true;
|
||||
}
|
||||
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
||||
@ -444,4 +452,14 @@ bool CentralVideoSettings::isDefferedEnabled() const
|
||||
return UserConfigParams::m_dynamic_lights && !GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_ADVANCED_PIPELINE);
|
||||
}
|
||||
|
||||
bool CentralVideoSettings::supportsHardwareSkinning() const
|
||||
{
|
||||
return isARBUniformBufferObjectUsable();
|
||||
}
|
||||
|
||||
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
|
||||
{
|
||||
return m_glsl && hasTextureSwizzle;
|
||||
}
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
bool hasImageLoadStore;
|
||||
bool hasMultiDrawIndirect;
|
||||
bool hasTextureFilterAnisotropic;
|
||||
bool hasTextureSwizzle;
|
||||
|
||||
#if defined(USE_GLES2)
|
||||
bool hasBGRA;
|
||||
@ -82,6 +83,7 @@ public:
|
||||
bool isARBMultiDrawIndirectUsable() const;
|
||||
bool isARBExplicitAttribLocationUsable() const;
|
||||
bool isEXTTextureFilterAnisotropicUsable() const;
|
||||
bool isARBTextureSwizzleUsable() const;
|
||||
|
||||
#if defined(USE_GLES2)
|
||||
bool isEXTTextureFormatBGRA8888Usable() const;
|
||||
@ -95,6 +97,7 @@ public:
|
||||
bool supportsIndirectInstancingRendering() const;
|
||||
bool supportsComputeShadersFiltering() const;
|
||||
bool supportsAsyncInstanceUpload() const;
|
||||
bool supportsHardwareSkinning() const;
|
||||
|
||||
// "Macro" around feature support and user config
|
||||
bool isShadowEnabled() const;
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "graphics/command_buffer.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/stk_mesh_scene_node.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -29,6 +30,7 @@ void InstanceFiller<InstanceDataSingleTex>::add(GLMesh* mesh,
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataSingleTex>(STK::tuple_get<0>(is), instance);
|
||||
instance.Texture = mesh->TextureHandles[0];
|
||||
instance.skinning_offset = STK::tuple_get<3>(is);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -45,6 +47,7 @@ void InstanceFiller<InstanceDataThreeTex>::add(GLMesh* mesh,
|
||||
instance.Texture = mesh->TextureHandles[0];
|
||||
instance.SecondTexture = mesh->TextureHandles[1];
|
||||
instance.ThirdTexture = mesh->TextureHandles[2];
|
||||
instance.skinning_offset = STK::tuple_get<3>(is);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -62,6 +65,7 @@ void InstanceFiller<InstanceDataFourTex>::add(GLMesh* mesh,
|
||||
instance.SecondTexture = mesh->TextureHandles[1];
|
||||
instance.ThirdTexture = mesh->TextureHandles[2];
|
||||
instance.FourthTexture = mesh->TextureHandles[3];
|
||||
instance.skinning_offset = STK::tuple_get<3>(is);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -155,7 +159,7 @@ SolidCommandBuffer::SolidCommandBuffer(): CommandBuffer()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void SolidCommandBuffer::fill(SolidPassMeshMap *mesh_map)
|
||||
void SolidCommandBuffer::fill(MeshMap *mesh_map)
|
||||
{
|
||||
clearMeshes();
|
||||
|
||||
@ -167,16 +171,20 @@ void SolidCommandBuffer::fill(SolidPassMeshMap *mesh_map)
|
||||
Material::SHADERTYPE_ALPHA_TEST,
|
||||
Material::SHADERTYPE_SOLID_UNLIT,
|
||||
Material::SHADERTYPE_SPHERE_MAP,
|
||||
Material::SHADERTYPE_VEGETATION);
|
||||
Material::SHADERTYPE_VEGETATION,
|
||||
Material::SHADERTYPE_SOLID_SKINNED_MESH,
|
||||
Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH,
|
||||
Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH);
|
||||
|
||||
fillInstanceData<InstanceDataThreeTex, SolidPassMeshMap>
|
||||
fillInstanceData<InstanceDataThreeTex, MeshMap>
|
||||
(mesh_map, three_tex_material_list, InstanceTypeThreeTex);
|
||||
|
||||
std::vector<int> four_tex_material_list =
|
||||
createVector<int>(Material::SHADERTYPE_DETAIL_MAP,
|
||||
Material::SHADERTYPE_NORMAL_MAP);
|
||||
Material::SHADERTYPE_NORMAL_MAP,
|
||||
Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH);
|
||||
|
||||
fillInstanceData<InstanceDataFourTex, SolidPassMeshMap>
|
||||
fillInstanceData<InstanceDataFourTex, MeshMap>
|
||||
(mesh_map, four_tex_material_list, InstanceTypeFourTex);
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
@ -189,7 +197,7 @@ ShadowCommandBuffer::ShadowCommandBuffer(): CommandBuffer()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map)
|
||||
void ShadowCommandBuffer::fill(MeshMap *mesh_map)
|
||||
{
|
||||
clearMeshes();
|
||||
|
||||
@ -215,9 +223,17 @@ void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map)
|
||||
+ Material::SHADERTYPE_VEGETATION);
|
||||
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
|
||||
+ Material::SHADERTYPE_SPLATTING);
|
||||
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
|
||||
+ Material::SHADERTYPE_SOLID_SKINNED_MESH);
|
||||
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
|
||||
+ Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH);
|
||||
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
|
||||
+ Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH);
|
||||
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
|
||||
+ Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH);
|
||||
}
|
||||
|
||||
fillInstanceData<InstanceDataSingleTex, OtherMeshMap>
|
||||
fillInstanceData<InstanceDataSingleTex, MeshMap>
|
||||
(mesh_map, shadow_tex_material_list, InstanceTypeShadow);
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
@ -231,7 +247,7 @@ ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ReflectiveShadowMapCommandBuffer::fill(OtherMeshMap *mesh_map)
|
||||
void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
|
||||
{
|
||||
clearMeshes();
|
||||
|
||||
@ -245,7 +261,7 @@ void ReflectiveShadowMapCommandBuffer::fill(OtherMeshMap *mesh_map)
|
||||
Material::SHADERTYPE_DETAIL_MAP,
|
||||
Material::SHADERTYPE_NORMAL_MAP);
|
||||
|
||||
fillInstanceData<InstanceDataSingleTex, OtherMeshMap>
|
||||
fillInstanceData<InstanceDataSingleTex, MeshMap>
|
||||
(mesh_map, rsm_material_list, InstanceTypeRSM);
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
@ -259,14 +275,14 @@ GlowCommandBuffer::GlowCommandBuffer()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GlowCommandBuffer::fill(OtherMeshMap *mesh_map)
|
||||
void GlowCommandBuffer::fill(MeshMap *mesh_map)
|
||||
{
|
||||
clearMeshes();
|
||||
|
||||
if(!CVS->supportsAsyncInstanceUpload())
|
||||
mapIndirectBuffer();
|
||||
|
||||
fillInstanceData<GlowInstanceData, OtherMeshMap>
|
||||
fillInstanceData<GlowInstanceData, MeshMap>
|
||||
(mesh_map, createVector<int>(0), InstanceTypeGlow);
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
|
@ -24,26 +24,11 @@
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/materials.hpp"
|
||||
#include "graphics/render_info.hpp"
|
||||
#include "graphics/stk_mesh_scene_node.hpp"
|
||||
#include "graphics/vao_manager.hpp"
|
||||
#include <irrlicht.h>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
typedef STK::Tuple<scene::ISceneNode*, core::vector2df, core::vector2df> InstanceSettings;
|
||||
|
||||
struct InstanceList
|
||||
{
|
||||
GLMesh *m_mesh;
|
||||
std::vector<InstanceSettings> m_instance_settings;
|
||||
};
|
||||
|
||||
typedef std::unordered_map <std::pair<scene::IMeshBuffer*, RenderInfo*>, InstanceList,
|
||||
MeshRenderInfoHash, MeshRenderInfoEquals> SolidPassMeshMap;
|
||||
|
||||
typedef std::unordered_map <irr::scene::IMeshBuffer *, InstanceList > OtherMeshMap;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Fill origin, orientation and scale attributes
|
||||
* \param node The scene node of the mesh
|
||||
@ -271,7 +256,7 @@ class SolidCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADER
|
||||
{
|
||||
public:
|
||||
SolidCommandBuffer();
|
||||
void fill(SolidPassMeshMap *mesh_map);
|
||||
void fill(MeshMap *mesh_map);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** First rendering pass; draw all meshes associated with the same material
|
||||
@ -458,7 +443,7 @@ class ShadowCommandBuffer: public CommandBuffer<4*static_cast<int>(Material::SHA
|
||||
{
|
||||
public:
|
||||
ShadowCommandBuffer();
|
||||
void fill(OtherMeshMap *mesh_map);
|
||||
void fill(MeshMap *mesh_map);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Draw shadowmaps for meshes with the same material
|
||||
@ -532,7 +517,7 @@ class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Ma
|
||||
{
|
||||
public:
|
||||
ReflectiveShadowMapCommandBuffer();
|
||||
void fill(OtherMeshMap *mesh_map);
|
||||
void fill(MeshMap *mesh_map);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Draw reflective shadow map for meshes with the same material
|
||||
@ -615,7 +600,7 @@ class GlowCommandBuffer: public CommandBuffer<1>
|
||||
{
|
||||
public:
|
||||
GlowCommandBuffer();
|
||||
void fill(OtherMeshMap *mesh_map);
|
||||
void fill(MeshMap *mesh_map);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Draw glowing meshes.
|
||||
|
@ -19,23 +19,28 @@
|
||||
#include "graphics/draw_calls.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/command_buffer.hpp"
|
||||
#include "graphics/draw_tools.hpp"
|
||||
#include "graphics/gpu_particles.hpp"
|
||||
#include "graphics/lod_node.hpp"
|
||||
#include "graphics/materials.hpp"
|
||||
#include "graphics/render_info.hpp"
|
||||
#include "graphics/shadow_matrices.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include "graphics/stk_animated_mesh.hpp"
|
||||
#include "graphics/stk_billboard.hpp"
|
||||
#include "graphics/stk_mesh.hpp"
|
||||
#include "graphics/stk_mesh_scene_node.hpp"
|
||||
#include "graphics/vao_manager.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/profiler.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void DrawCalls::clearLists()
|
||||
{
|
||||
ListBlendTransparent::getInstance()->clear();
|
||||
ListAdditiveTransparent::getInstance()->clear();
|
||||
ListTranslucentSkinned::getInstance()->clear();
|
||||
ListTranslucentStandard::getInstance()->clear();
|
||||
ListTranslucentTangents::getInstance()->clear();
|
||||
ListTranslucent2TCoords::getInstance()->clear();
|
||||
@ -43,6 +48,10 @@ void DrawCalls::clearLists()
|
||||
ListAdditiveTransparentFog::getInstance()->clear();
|
||||
ListDisplacement::getInstance()->clear();
|
||||
|
||||
ListSkinnedSolid::getInstance()->clear();
|
||||
ListSkinnedAlphaRef::getInstance()->clear();
|
||||
ListSkinnedNormalMap::getInstance()->clear();
|
||||
ListSkinnedUnlit::getInstance()->clear();
|
||||
ListMatDefault::getInstance()->clear();
|
||||
ListMatAlphaRef::getInstance()->clear();
|
||||
ListMatSphereMap::getInstance()->clear();
|
||||
@ -172,7 +181,8 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
|
||||
if (node->isImmediateDraw())
|
||||
{
|
||||
ImmediateDraw->push_back(Node);
|
||||
if (!isCulledPrecise(cam, Node, irr_driver->getBoundingBoxesViz()))
|
||||
ImmediateDraw->push_back(Node);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,8 +253,34 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
|
||||
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
|
||||
|
||||
int32_t skinning_offset = 0;
|
||||
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(Node);
|
||||
if (am && am->useHardwareSkinning() &&
|
||||
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
|
||||
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
|
||||
{
|
||||
skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
|
||||
if (skinning_offset + am->getTotalJoints() >
|
||||
SharedGPUObjects::getMaxMat4Size())
|
||||
{
|
||||
Log::error("DrawCalls", "Don't have enough space to render skinned"
|
||||
" mesh %s! Max joints can hold: %d",
|
||||
am->getMeshDebugName().c_str(),
|
||||
SharedGPUObjects::getMaxMat4Size());
|
||||
return;
|
||||
}
|
||||
m_mesh_for_skinning.insert(am);
|
||||
am->setSkinningOffset(skinning_offset * 16 * sizeof(float));
|
||||
}
|
||||
|
||||
if (!culled_for_cams[0])
|
||||
{
|
||||
for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_SKN])
|
||||
{
|
||||
pushVector(ListTranslucentSkinned::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans,
|
||||
skinning_offset, (mesh->m_render_info && mesh->m_render_info->isTransparent() ? custom_alpha : 1.0f));
|
||||
}
|
||||
|
||||
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
|
||||
{
|
||||
if (CVS->supportsIndirectInstancingRendering())
|
||||
@ -255,7 +291,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
m_glow_pass_mesh[mesh->mb].m_mesh = mesh;
|
||||
m_glow_pass_mesh[mesh->mb].m_instance_settings
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
}
|
||||
if (Mat == Material::SHADERTYPE_SPLATTING)
|
||||
{
|
||||
@ -267,15 +303,11 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only take render info into account if the node is not static (animated)
|
||||
// So they can have different animation
|
||||
std::pair<scene::IMeshBuffer*, RenderInfo*> mesh_render_info(mesh->mb,
|
||||
dynamic_cast<STKMeshSceneNode*>(Node) == NULL ? mesh->m_render_info : NULL);
|
||||
m_solid_pass_mesh[Mat][mesh_render_info].m_mesh = mesh;
|
||||
m_solid_pass_mesh[Mat][mesh_render_info].m_instance_settings.emplace_back(Node, mesh->texture_trans,
|
||||
m_solid_pass_mesh[Mat][mesh->mb].m_mesh = mesh;
|
||||
m_solid_pass_mesh[Mat][mesh->mb].m_instance_settings.emplace_back(Node, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||
core::vector2df(0.0f, 0.0f)));
|
||||
core::vector2df(0.0f, 0.0f)), skinning_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,6 +320,28 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
|
||||
ListSkinnedSolid::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||
core::vector2df(0.0f, 0.0f)), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
|
||||
ListSkinnedAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||
core::vector2df(0.0f, 0.0f)), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
|
||||
ListSkinnedUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
|
||||
ListSkinnedNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
|
||||
core::vector2df(0.0f, 0.0f)), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_SOLID:
|
||||
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
(mesh->m_render_info && mesh->m_material ?
|
||||
@ -351,7 +405,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_mesh = mesh;
|
||||
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -363,6 +417,22 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
|
||||
ListSkinnedSolid::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
|
||||
ListSkinnedAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
|
||||
ListSkinnedUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
|
||||
ListSkinnedNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
|
||||
core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
break;
|
||||
case Material::SHADERTYPE_SOLID:
|
||||
ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
|
||||
break;
|
||||
@ -419,7 +489,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
m_reflective_shadow_map_mesh[Mat][mesh->mb].m_mesh = mesh;
|
||||
m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
|
||||
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -432,6 +502,12 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
|
||||
{
|
||||
switch (Mat)
|
||||
{
|
||||
// Todo: RSMs
|
||||
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
|
||||
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
|
||||
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
|
||||
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
|
||||
break;
|
||||
case Material::SHADERTYPE_SOLID:
|
||||
ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
|
||||
break;
|
||||
@ -551,7 +627,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
|
||||
{
|
||||
m_wind_dir = getWindDir();
|
||||
clearLists();
|
||||
|
||||
m_mesh_for_skinning.clear();
|
||||
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
|
||||
{
|
||||
m_solid_pass_mesh[Mat].clear();
|
||||
@ -569,6 +645,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
|
||||
&m_immediate_draw_list, camnode, shadow_matrices);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
irr_driver->setSkinningJoint(getSkinningOffset());
|
||||
// Add a 1 s timeout
|
||||
if (!m_sync)
|
||||
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
@ -688,7 +765,13 @@ void DrawCalls::drawIndirectSolidFirstPass() const
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<SphereMap>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<GrassMat>(m_wind_dir);
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<DetailMat>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<NormalMat>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<NormalMat>();
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedSolid>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedAlphaRef>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedUnlitMat>();
|
||||
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedNormalMat>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -704,7 +787,13 @@ void DrawCalls::multidrawSolidFirstPass() const
|
||||
m_solid_cmd_buffer->multidrawFirstPass<UnlitMat>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<GrassMat>(m_wind_dir);
|
||||
m_solid_cmd_buffer->multidrawFirstPass<NormalMat>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<DetailMat>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<DetailMat>();
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_solid_cmd_buffer->multidrawFirstPass<SkinnedSolid>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<SkinnedAlphaRef>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<SkinnedUnlitMat>();
|
||||
m_solid_cmd_buffer->multidrawFirstPass<SkinnedNormalMat>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -724,6 +813,12 @@ void DrawCalls::drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<GrassMat>(prefilled_tex, m_wind_dir);
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<DetailMat>(prefilled_tex);
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<NormalMat>(prefilled_tex);
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedSolid>(prefilled_tex);
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedAlphaRef>(prefilled_tex);
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedUnlitMat>(prefilled_tex);
|
||||
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedNormalMat>(prefilled_tex);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -742,6 +837,12 @@ void DrawCalls::multidrawSolidSecondPass(const std::vector<uint64_t> &handles) c
|
||||
m_solid_cmd_buffer->multidraw2ndPass<NormalMat>(handles);
|
||||
m_solid_cmd_buffer->multidraw2ndPass<DetailMat>(handles);
|
||||
m_solid_cmd_buffer->multidraw2ndPass<GrassMat>(handles, m_wind_dir);
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_solid_cmd_buffer->multidraw2ndPass<SkinnedSolid>(handles);
|
||||
m_solid_cmd_buffer->multidraw2ndPass<SkinnedAlphaRef>(handles);
|
||||
m_solid_cmd_buffer->multidraw2ndPass<SkinnedUnlitMat>(handles);
|
||||
m_solid_cmd_buffer->multidraw2ndPass<SkinnedNormalMat>(handles);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -792,6 +893,12 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const
|
||||
m_shadow_cmd_buffer->drawIndirect<NormalMat>(cascade);
|
||||
m_shadow_cmd_buffer->drawIndirect<SplattingMat>(cascade);
|
||||
m_shadow_cmd_buffer->drawIndirect<SphereMap>(cascade);
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_shadow_cmd_buffer->drawIndirect<SkinnedSolid>(cascade);
|
||||
m_shadow_cmd_buffer->drawIndirect<SkinnedAlphaRef>(cascade);
|
||||
m_shadow_cmd_buffer->drawIndirect<SkinnedUnlitMat>(cascade);
|
||||
m_shadow_cmd_buffer->drawIndirect<SkinnedNormalMat>(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -810,6 +917,12 @@ void DrawCalls::multidrawShadows(unsigned cascade) const
|
||||
m_shadow_cmd_buffer->multidrawShadow<GrassMat,irr::core::vector3df>(cascade, m_wind_dir);
|
||||
m_shadow_cmd_buffer->multidrawShadow<SplattingMat>(cascade);
|
||||
m_shadow_cmd_buffer->multidrawShadow<SphereMap>(cascade);
|
||||
|
||||
if (!CVS->supportsHardwareSkinning()) return;
|
||||
m_shadow_cmd_buffer->multidrawShadow<SkinnedSolid>(cascade);
|
||||
m_shadow_cmd_buffer->multidrawShadow<SkinnedAlphaRef>(cascade);
|
||||
m_shadow_cmd_buffer->multidrawShadow<SkinnedUnlitMat>(cascade);
|
||||
m_shadow_cmd_buffer->multidrawShadow<SkinnedNormalMat>(cascade);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -866,4 +979,12 @@ void DrawCalls::multidrawGlow() const
|
||||
}
|
||||
#endif // !defined(USE_GLES2)
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
// ----------------------------------------------------------------------------
|
||||
int32_t DrawCalls::getSkinningOffset() const
|
||||
{
|
||||
return std::accumulate(m_mesh_for_skinning.begin(),
|
||||
m_mesh_for_skinning.end(), 0, []
|
||||
(const size_t previous, const STKAnimatedMesh* m)
|
||||
{ return previous + m->getTotalJoints(); });
|
||||
} // getSkinningOffset
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -19,13 +19,21 @@
|
||||
#define HEADER_DRAW_CALLS_HPP
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include "graphics/command_buffer.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
#include "graphics/vao_manager.hpp"
|
||||
#include <irrlicht.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
class GlowCommandBuffer;
|
||||
class ParticleSystemProxy;
|
||||
class ReflectiveShadowMapCommandBuffer;
|
||||
class ShadowMatrices;
|
||||
class ShadowCommandBuffer;
|
||||
class SolidCommandBuffer;
|
||||
class STKAnimatedMesh;
|
||||
class STKBillboard;
|
||||
class STKMeshCommon;
|
||||
|
||||
class DrawCalls
|
||||
{
|
||||
@ -37,14 +45,15 @@ private:
|
||||
std::vector<irr::scene::ISceneNode *> m_immediate_draw_list;
|
||||
std::vector<STKBillboard *> m_billboard_list;
|
||||
std::vector<ParticleSystemProxy *> m_particles_list;
|
||||
std::set<STKAnimatedMesh*> m_mesh_for_skinning;
|
||||
|
||||
std::vector<float> m_bounding_boxes;
|
||||
|
||||
/** meshes to draw */
|
||||
SolidPassMeshMap m_solid_pass_mesh [ Material::SHADERTYPE_COUNT];
|
||||
OtherMeshMap m_shadow_pass_mesh [4 * Material::SHADERTYPE_COUNT];
|
||||
OtherMeshMap m_reflective_shadow_map_mesh [ Material::SHADERTYPE_COUNT];
|
||||
OtherMeshMap m_glow_pass_mesh;
|
||||
MeshMap m_solid_pass_mesh [ Material::SHADERTYPE_COUNT];
|
||||
MeshMap m_shadow_pass_mesh [4 * Material::SHADERTYPE_COUNT];
|
||||
MeshMap m_reflective_shadow_map_mesh [ Material::SHADERTYPE_COUNT];
|
||||
MeshMap m_glow_pass_mesh;
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
/** meshes data in VRAM */
|
||||
@ -106,6 +115,7 @@ public:
|
||||
void drawIndirectGlow() const;
|
||||
void multidrawGlow() const;
|
||||
void renderBoundingBoxes();
|
||||
int32_t getSkinningOffset() const;
|
||||
};
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
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