Merge remote-tracking branch 'origin/master' into game_protocol

This commit is contained in:
hiker 2017-01-25 18:07:45 +11:00
commit 096d68c361
258 changed files with 27053 additions and 18475 deletions

BIN
data/CREDITS Executable file → Normal file

Binary file not shown.

View File

@ -19,7 +19,7 @@
<snowmountain goal="1"/> <snowmountain goal="1"/>
<snowtuxpeak goal="1"/> <snowtuxpeak goal="1"/>
<stk_enterprise goal="1"/> <stk_enterprise goal="1"/>
<subsea goal="1"/> <abyss goal="1"/>
<xr591 goal="1"/> <xr591 goal="1"/>
<zengarden goal="1"/> <zengarden goal="1"/>
</achievement> </achievement>

View File

@ -1,19 +1,19 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<challenge version="2"> <challenge version="2">
<track id="farm" laps="3"/> <track id="cornfield_crossing" laps="3"/>
<mode major="single" minor="quickrace"/> <mode major="single" minor="quickrace"/>
<requirements trophies="0"/> <requirements trophies="0"/>
<hard> <hard>
<karts number="5"/> <karts number="5"/>
<requirements position="1" time="110"/> <requirements position="1" time="165"/>
</hard> </hard>
<medium> <medium>
<karts number="4"/> <karts number="4"/>
<requirements time="125"/> <requirements time="195"/>
</medium> </medium>
<easy> <easy>
<karts number="4"/> <karts number="4"/>
<requirements time="155"/> <requirements time="275"/>
</easy> </easy>
</challenge> </challenge>

33
data/gfx/kart_exhaust.xml Normal file
View 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>

View File

@ -1,10 +1,10 @@
<supertuxkart_grand_prix name="Penguin Playground"> <supertuxkart_grand_prix name="Penguin Playground">
<track id="sandtrack" laps="3" reverse="false" /> <track id="sandtrack" laps="3" reverse="false" />
<track id="farm" laps="3" reverse="false" /> <track id="cornfield_crossing" laps="3" reverse="false" />
<track id="olivermath" laps="4" reverse="false" /> <track id="olivermath" laps="4" reverse="false" />
<track id="abyss" laps="3" reverse="false" /> <track id="abyss" laps="3" reverse="false" />
<track id="scotland" laps="3" reverse="false" /> <track id="scotland" laps="3" reverse="false" />
</supertuxkart_grand_prix> </supertuxkart_grand_prix>

View File

@ -31,4 +31,5 @@
<card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/> <card contains="ATI" os="windows" version="<=3.1.8787" disable="ForceLegacyDevice"/>
<card os="android" disable="TextureFormatBGRA8888"/> <card os="android" disable="TextureFormatBGRA8888"/>
<card os="android" disable="ColorBufferFloat"/> <card os="android" disable="ColorBufferFloat"/>
<card contains="Android Emulator" os="android" disable="ForceLegacyDevice"/>
</graphical-restrictions> </graphical-restrictions>

View File

@ -173,6 +173,14 @@
<gauge id="filtering" min_value="0" max_value="5" width="50%" /> <gauge id="filtering" min_value="0" max_value="5" width="50%" />
</div> </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" /> <spacer height="10" width="10" />
<label text="* Restart STK to apply new settings" width="100%" text_align="center" I18N="Video settings"/> <label text="* Restart STK to apply new settings" width="100%" text_align="center" I18N="Video settings"/>

View File

@ -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>

View 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>

View 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>

View File

@ -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

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,9 @@ void main(void)
#endif #endif
#endif #endif
vec4 detail = texture(Detail, uv_bis); 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; float specmap = texture(SpecMap, uv).g;
FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.); FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
} }

View File

@ -15,7 +15,7 @@ out vec2 uv_bis;
out float camdist; out float camdist;
void main() { void main() {
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(Position, 1.); gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
uv = Texcoord; uv = Texcoord;
uv_bis = SecondTexcoord; uv_bis = SecondTexcoord;
camdist = length(ViewMatrix * ModelMatrix * vec4(Position, 1.)); camdist = length(ViewMatrix * ModelMatrix * vec4(Position, 1.));

View File

@ -1,15 +1,16 @@
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position; 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 = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation; layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale; 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; flat out vec4 glowColor;
#stk_include "utils/getworldmatrix.vert" #stk_include "utils/getworldmatrix.vert"
@ -19,5 +20,5 @@ void main(void)
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale); mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix); mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.); gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
glowColor = GlowColor; glowColor = misc_data;
} }

View File

@ -28,7 +28,7 @@ void main()
// affects "nor" which is later only * 0.1 by scattering // affects "nor" which is later only * 0.1 by scattering
new_inverse_model_matrix[3].xyz -= windDir * Color.r; 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); mat4 TransposeInverseModelView = transpose(InverseViewMatrix * new_inverse_model_matrix);
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz; nor = (TransposeInverseModelView * vec4(Normal, 0.)).xyz;

View File

@ -63,5 +63,11 @@ layout (std140) uniform LightingData
float rL21; float rL21;
float rL22; float rL22;
}; };
layout (std140) uniform SkinningData
{
mat4 joint_matrices[MAX_BONES];
};
#endif #endif
#endif // HEADER_TXT #endif // HEADER_TXT

View File

@ -29,6 +29,8 @@ void main(void)
vec4 detail = texture(Detail, uv_bis); vec4 detail = texture(Detail, uv_bis);
float specmap = texture(SpecMap, uv).g; float specmap = texture(SpecMap, uv).g;
#endif #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.); FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
} }

View File

@ -30,7 +30,7 @@ in vec4 misc_data;
out vec3 nor; out vec3 nor;
out vec2 uv; out vec2 uv;
out vec2 color_change; flat out vec2 color_change;
#ifdef Use_Bindless_Texture #ifdef Use_Bindless_Texture
flat out sampler2D handle; flat out sampler2D handle;
flat out sampler2D secondhandle; flat out sampler2D secondhandle;

View File

@ -14,7 +14,7 @@ flat in sampler2D thirdhandle;
#endif #endif
in vec3 nor; in vec3 nor;
in vec2 uv; in vec2 uv;
in vec2 color_change; flat in vec2 color_change;
out vec4 FragColor; out vec4 FragColor;
#stk_include "utils/getLightFactor.frag" #stk_include "utils/getLightFactor.frag"

View File

@ -39,7 +39,7 @@ out vec3 bitangent;
out vec2 uv; out vec2 uv;
out vec2 uv_bis; out vec2 uv_bis;
out vec4 color; out vec4 color;
out vec2 color_change; flat out vec2 color_change;
#ifdef Use_Bindless_Texture #ifdef Use_Bindless_Texture
flat out sampler2D handle; flat out sampler2D handle;
flat out sampler2D secondhandle; flat out sampler2D secondhandle;

View File

@ -12,7 +12,7 @@ flat in sampler2D thirdhandle;
in vec2 uv; in vec2 uv;
in vec4 color; in vec4 color;
in vec2 color_change; flat in vec2 color_change;
out vec4 FragColor; out vec4 FragColor;
#stk_include "utils/getLightFactor.frag" #stk_include "utils/getLightFactor.frag"

View File

@ -11,7 +11,7 @@ flat in sampler2D thirdhandle;
#endif #endif
in vec2 uv; in vec2 uv;
in vec4 color; in vec4 color;
in vec2 color_change; flat in vec2 color_change;
out vec4 FragColor; out vec4 FragColor;
#stk_include "utils/getLightFactor.frag" #stk_include "utils/getLightFactor.frag"
@ -29,6 +29,7 @@ void main(void)
#else #else
vec4 col = texture(Albedo, uv); vec4 col = texture(Albedo, uv);
float specmap = texture(SpecMap, uv).g; float specmap = texture(SpecMap, uv).g;
float emitmap = texture(SpecMap, uv).b;
float mask = texture(colorization_mask, uv).a; float mask = texture(colorization_mask, uv).a;
#endif #endif
col.xyz *= pow(color.xyz, vec3(2.2)); 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); 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.);
} }

View 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
}

View 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
}

View File

@ -56,11 +56,6 @@ float SearchYUp(vec2 texcoord) {
return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS); 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) { vec2 Area(vec2 distance, float e1, float e2) {
// * By dividing by areaSize - 1.0 below we are implicitely offsetting to // * By dividing by areaSize - 1.0 below we are implicitely offsetting to
// always fall inside of a pixel // always fall inside of a pixel

View File

@ -1,9 +1,9 @@
#ifdef Use_Bindless_Texture #ifdef Use_Bindless_Texture
layout(bindless_sampler) uniform sampler2D normalMap; layout(bindless_sampler) uniform sampler2D normalMap;
layout(bindless_sampler) uniform sampler2D DiffuseForAlpha; layout(bindless_sampler) uniform sampler2D glossMap;
#else #else
uniform sampler2D normalMap; uniform sampler2D normalMap;
uniform sampler2D DiffuseForAlpha; uniform sampler2D glossMap;
#endif #endif
in vec3 tangent; in vec3 tangent;
@ -17,7 +17,7 @@ void main()
{ {
// normal in Tangent Space // normal in Tangent Space
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0; 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 // Because of interpolation, we need to renormalize
vec3 Frag_tangent = normalize(tangent); vec3 Frag_tangent = normalize(tangent);
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent)); 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; 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.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
EncodedNormal.z = 1. - alpha; EncodedNormal.z = gloss;
} }

View File

@ -46,7 +46,7 @@ out vec4 color;
void main(void) void main(void)
{ {
color = Color.zyxw; color = Color.zyxw;
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix; mat4 ModelViewProjectionMatrix = ProjectionViewMatrix * ModelMatrix;
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix); mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.); gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
// Keep orthogonality // Keep orthogonality

View File

@ -14,7 +14,7 @@ void main(void)
float gz = int(gl_VertexID >> 9) & (resolution.z - 1); float gz = int(gl_VertexID >> 9) & (resolution.z - 1);
uvw = vec3(gx, gy, gz) / vec3(resolution); uvw = vec3(gx, gy, gz) / vec3(resolution);
vec3 WorldPos = (2. * uvw - 1.) * extents; 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; gl_PointSize = 500. / gl_Position.w;
} }

View File

@ -1,81 +1,80 @@
// SuperTuxKart - a fun racing game with go-kart #ifdef GL_ES
// Copyright (C) 2013 the SuperTuxKart team uniform mat4 ModelMatrix;
// uniform mat4 InverseModelMatrix;
// This program is free software; you can redistribute it and/or uniform vec2 texture_trans;
// modify it under the terms of the GNU General Public License #else
// as published by the Free Software Foundation; either version 3 uniform mat4 ModelMatrix =
// of the License, or (at your option) any later version. mat4(1., 0., 0., 0.,
// 0., 1., 0., 0.,
// This program is distributed in the hope that it will be useful, 0., 0., 1., 0.,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 0., 0., 0., 1.);
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the uniform mat4 InverseModelMatrix =
// GNU General Public License for more details. mat4(1., 0., 0., 0.,
// 0., 1., 0., 0.,
// You should have received a copy of the GNU General Public License 0., 0., 1., 0.,
// along with this program; if not, write to the Free Software 0., 0., 0., 1.);
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// skinning.vert uniform vec2 texture_trans = vec2(0., 0.);
#version 330 compatibility #endif
#define MAX_JOINT_NUM 36 uniform int skinning_offset;
#define MAX_LIGHT_NUM 8
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; mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
vec4 ecPos; vec4 idle_position = vec4(Position, 1.);
vec3 normal; vec4 idle_normal = vec4(Normal, 0.);
vec3 light_dir; vec4 idle_tangent = vec4(Data1.z, Data1.w, Data2.x, 0.);
float n_dot_l; vec4 idle_bitangent = vec4(Data2.y, Data2.z, Data2.w, 0.);
float dist; 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; gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
// Keep orthogonality
index = int(gl_Color.r * 255.99); nor = (TransposeInverseModelView * skinned_normal).xyz;
mat4 vertTran = JointTransform[index - 1]; // Keep direction
tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz;
index = int(gl_Color.g * 255.99); bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz;
if(index > 0) uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
vertTran += JointTransform[index - 1]; color = Color.zyxw;
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;
*/
} }

View 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
}

View File

@ -72,8 +72,10 @@
delta-angle="0.5" /> delta-angle="0.5" />
<!-- Skidmark data: maximum number of skid marks, and <!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. --> time for skidmarks to fade out. Maximum number will over
<skid-marks max-number="100" fadeout-time="60"/> 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 <!-- Defines when the upright constraint should be active, it's
disabled when the kart is more than this value from the track. --> disabled when the kart is more than this value from the track. -->

View File

@ -923,7 +923,7 @@
#endif #endif
// Free BSD // Free BSD
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
#define AS_BSD #define AS_BSD
#if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__) #if (defined(i386) || defined(__i386) || defined(__i386__)) && !defined(__LP64__)
#undef COMPLEX_MASK #undef COMPLEX_MASK

View File

@ -38,7 +38,8 @@
#include <stdlib.h> #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> #include <malloc.h>
#endif #endif

View File

@ -78,8 +78,10 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
int getTriangleIndex() const int getTriangleIndex() const
{ {
btAssert(isLeafNode()); 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 // 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 int getPartId() const
{ {

View File

@ -30,6 +30,11 @@ if(APPLE)
endif() endif()
add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES) 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) if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_) add_definitions(/D_IRR_STATIC_LIB_)
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
@ -59,7 +64,6 @@ endif()
set(IRRLICHT_SOURCES set(IRRLICHT_SOURCES
source/Irrlicht/CAnimatedMeshSceneNode.cpp source/Irrlicht/CAnimatedMeshSceneNode.cpp
source/Irrlicht/CAttributes.cpp source/Irrlicht/CAttributes.cpp
source/Irrlicht/CB3DMeshFileLoader.cpp
source/Irrlicht/CBillboardSceneNode.cpp source/Irrlicht/CBillboardSceneNode.cpp
source/Irrlicht/CBoneSceneNode.cpp source/Irrlicht/CBoneSceneNode.cpp
source/Irrlicht/CCameraSceneNode.cpp source/Irrlicht/CCameraSceneNode.cpp
@ -187,11 +191,9 @@ source/Irrlicht/Irrlicht.cpp
source/Irrlicht/irrXML.cpp source/Irrlicht/irrXML.cpp
source/Irrlicht/os.cpp source/Irrlicht/os.cpp
source/Irrlicht/COpenGLNormalMapRenderer.cpp source/Irrlicht/COpenGLNormalMapRenderer.cpp
source/Irrlicht/BuiltInFont.h
source/Irrlicht/CAnimatedMeshSceneNode.h source/Irrlicht/CAnimatedMeshSceneNode.h
source/Irrlicht/CAttributeImpl.h source/Irrlicht/CAttributeImpl.h
source/Irrlicht/CAttributes.h source/Irrlicht/CAttributes.h
source/Irrlicht/CB3DMeshFileLoader.h
source/Irrlicht/CBillboardSceneNode.h source/Irrlicht/CBillboardSceneNode.h
source/Irrlicht/CBlit.h source/Irrlicht/CBlit.h
source/Irrlicht/CBoneSceneNode.h source/Irrlicht/CBoneSceneNode.h

View File

@ -116,6 +116,8 @@ namespace scene
NewVertices=new CSpecificVertexList<video::S3DVertexTangents>; NewVertices=new CSpecificVertexList<video::S3DVertexTangents>;
break; break;
} }
default:
break;
} }
if (Vertices) if (Vertices)
{ {

View File

@ -8,6 +8,8 @@
#include "aabbox3d.h" #include "aabbox3d.h"
#include "IMesh.h" #include "IMesh.h"
typedef void (*SkinningCallback)(const irr::core::matrix4& m, int joint, int offset);
namespace irr namespace irr
{ {
namespace scene namespace scene

View File

@ -178,6 +178,9 @@ namespace scene
\return The newly created clone of this node. */ \return The newly created clone of this node. */
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) = 0; 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 } // end namespace scene

View File

@ -95,8 +95,6 @@ public:
\param s String of symbols which are not send down to the videodriver \param s String of symbols which are not send down to the videodriver
*/ */
virtual void setInvisibleCharacters( const wchar_t *s ) = 0; virtual void setInvisibleCharacters( const wchar_t *s ) = 0;
virtual u32 addLazyLoadCharacters(const wchar_t *s) { return 0; }
}; };
} // end namespace gui } // end namespace gui

View File

@ -371,6 +371,8 @@ protected:
func(verts[i]); func(verts[i]);
} }
break; break;
default:
break;
} }
if (boundingBoxUpdate) if (boundingBoxUpdate)
{ {

View File

@ -69,11 +69,11 @@ namespace scene
virtual void animateMesh(f32 frame, f32 blend)=0; virtual void animateMesh(f32 frame, f32 blend)=0;
//! Preforms a software skin on this mesh based of joint positions //! 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. //! converts the vertex type of all meshbuffers to tangents.
/** E.g. used for bump mapping. */ /** E.g. used for bump mapping. */
virtual void convertMeshToTangents() = 0; virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*)) = 0;
//! Allows to enable hardware skinning. //! Allows to enable hardware skinning.
/* This feature is not implementated in Irrlicht yet */ /* This feature is not implementated in Irrlicht yet */

View File

@ -104,6 +104,8 @@ public:
{ {
} }
virtual ~ITexture() {}
//! Lock function. //! Lock function.
/** Locks the Texture and returns a pointer to access the /** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels 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) //! Get name of texture (in most cases this is the filename)
const io::SNamedPath& getName() const { return NamedPath; } 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: protected:
//! Helper function, helps to get the desired texture creation format from the flags. //! Helper function, helps to get the desired texture creation format from the flags.

View File

@ -26,7 +26,9 @@ enum E_VERTEX_TYPE
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents. //! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
/** Usually used for tangent space normal mapping. */ /** Usually used for tangent space normal mapping. */
EVT_TANGENTS EVT_TANGENTS,
EVT_SKINNED_MESH
}; };
//! Array holding the built in vertex type names //! 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) inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
@ -261,6 +279,8 @@ inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
return sizeof(video::S3DVertex2TCoords); return sizeof(video::S3DVertex2TCoords);
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return sizeof(video::S3DVertexTangents); return sizeof(video::S3DVertexTangents);
case video::EVT_SKINNED_MESH:
return sizeof(video::S3DVertexSkinnedMesh);
default: default:
return sizeof(video::S3DVertex); return sizeof(video::S3DVertex);
} }

View File

@ -50,6 +50,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return (video::S3DVertex*)&Vertices_2TCoords[index]; return (video::S3DVertex*)&Vertices_2TCoords[index];
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return (video::S3DVertex*)&Vertices_Tangents[index]; return (video::S3DVertex*)&Vertices_Tangents[index];
case video::EVT_SKINNED_MESH:
return (video::S3DVertex*)&Vertices_SkinnedMesh[index];
default: default:
return &Vertices_Standard[index]; return &Vertices_Standard[index];
} }
@ -64,6 +66,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.const_pointer(); return Vertices_2TCoords.const_pointer();
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents.const_pointer(); return Vertices_Tangents.const_pointer();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.const_pointer();
default: default:
return Vertices_Standard.const_pointer(); return Vertices_Standard.const_pointer();
} }
@ -78,6 +82,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.pointer(); return Vertices_2TCoords.pointer();
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents.pointer(); return Vertices_Tangents.pointer();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.pointer();
default: default:
return Vertices_Standard.pointer(); return Vertices_Standard.pointer();
} }
@ -92,6 +98,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.size(); return Vertices_2TCoords.size();
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents.size(); return Vertices_Tangents.size();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.size();
default: default:
return Vertices_Standard.size(); return Vertices_Standard.size();
} }
@ -180,6 +188,20 @@ struct SSkinMeshBuffer : public IMeshBuffer
} }
break; 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 //! Convert to tangents vertex type
virtual void convertToTangents() virtual void convertToTangents()
{ {
@ -250,6 +320,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos; return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos; return Vertices_Tangents[i].Pos;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Pos;
default: default:
return Vertices_Standard[i].Pos; return Vertices_Standard[i].Pos;
} }
@ -264,6 +336,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos; return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos; return Vertices_Tangents[i].Pos;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Pos;
default: default:
return Vertices_Standard[i].Pos; return Vertices_Standard[i].Pos;
} }
@ -278,6 +352,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal; return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal; return Vertices_Tangents[i].Normal;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Normal;
default: default:
return Vertices_Standard[i].Normal; return Vertices_Standard[i].Normal;
} }
@ -292,6 +368,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal; return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal; return Vertices_Tangents[i].Normal;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Normal;
default: default:
return Vertices_Standard[i].Normal; return Vertices_Standard[i].Normal;
} }
@ -306,6 +384,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].TCoords; return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords; return Vertices_Tangents[i].TCoords;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].TCoords;
default: default:
return Vertices_Standard[i].TCoords; return Vertices_Standard[i].TCoords;
} }
@ -320,6 +400,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].TCoords; return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords; return Vertices_Tangents[i].TCoords;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].TCoords;
default: default:
return Vertices_Standard[i].TCoords; return Vertices_Standard[i].TCoords;
} }
@ -381,6 +463,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
core::array<video::S3DVertexTangents> Vertices_Tangents; core::array<video::S3DVertexTangents> Vertices_Tangents;
core::array<video::S3DVertex2TCoords> Vertices_2TCoords; core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
core::array<video::S3DVertexSkinnedMesh> Vertices_SkinnedMesh;
core::array<video::S3DVertex> Vertices_Standard; core::array<video::S3DVertex> Vertices_Standard;
core::array<u16> Indices; core::array<u16> Indices;

View File

@ -12,18 +12,25 @@ namespace irr
namespace core namespace core
{ {
//! Sinks an element into the heap. //! Function object which can be used for sorting (default)
template<class T> 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 while ((element<<1) < max) // there is a left child
{ {
s32 j = (element<<1); 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 j = j+1; // take right child
if (array[element] < array[j]) if (cmp(array[element], array[j]))
{ {
T t = array[j]; // swap elements T t = array[j]; // swap elements
array[j] = array[element]; 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 with a custom compare function
//! Sorts an array with size 'size' using heapsort. template<class T, class Compare>
template<class T> inline void heapsort(T* array_, s32 size, Compare cmp)
inline void heapsort(T* array_, s32 size)
{ {
// for heapsink we pretent this is not c++, where // for heapsink we pretent this is not c++, where
// arrays start with index 0. So we decrease the array pointer, // arrays start with index 0. So we decrease the array pointer,
@ -51,7 +57,7 @@ inline void heapsort(T* array_, s32 size)
// build heap // build heap
for (i=((size-1)/2); i>=0; --i) 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) // sort array, leave out the last element (0)
for (i=size-1; i>0; --i) for (i=size-1; i>0; --i)
@ -59,7 +65,7 @@ inline void heapsort(T* array_, s32 size)
T t = array_[0]; T t = array_[0];
array_[0] = array_[i]; array_[0] = array_[i];
array_[i] = t; array_[i] = t;
heapsink(virtualArray, 1, i + 1); heapsink(virtualArray, 1, i + 1, cmp);
} }
} }

View File

@ -394,10 +394,17 @@ public:
void sort() void sort()
{ {
if (!is_sorted && used>1) if (!is_sorted && used>1)
heapsort(data, used); heapsort(data, used, sortless<T>);
is_sorted = true; 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. //! 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 /** The array will be sorted before the binary search if it is not

View File

@ -66,6 +66,10 @@ struct SNamedPath
{ {
return core::stringw(getPath()); return core::stringw(getPath());
} }
const c8* getPtr() const
{
return getPath().c_str();
}
protected: protected:
// convert the given path string to a name string. // convert the given path string to a name string.

File diff suppressed because it is too large Load Diff

View File

@ -178,7 +178,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
} }
} }
IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame() IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame(SkinningCallback sc, int offset)
{ {
if(Mesh->getMeshType() != EAMT_SKINNED) if(Mesh->getMeshType() != EAMT_SKINNED)
{ {
@ -203,7 +203,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
skinnedMesh->animateMesh(getFrameNr(), 1.0f); skinnedMesh->animateMesh(getFrameNr(), 1.0f);
// Update the skinned mesh for the current joint transforms. // Update the skinned mesh for the current joint transforms.
skinnedMesh->skinMesh(AnimationStrength); skinnedMesh->skinMesh(AnimationStrength, sc, offset);
if (JointMode == EJUOR_READ)//read from mesh if (JointMode == EJUOR_READ)//read from mesh
{ {
@ -992,6 +992,15 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
return newNode; 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 scene
} // end namespace irr } // end namespace irr

View File

@ -19,6 +19,8 @@ namespace scene
class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode
{ {
private:
core::array<u32> m_animation_set;
public: public:
//! constructor //! constructor
@ -158,10 +160,18 @@ namespace scene
\return The newly created clone of this node. */ \return The newly created clone of this node. */
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); 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: protected:
//! Get a static mesh for the current frame of this animated mesh //! 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 buildFrameNr(u32 timeMs);
void checkJoints(); void checkJoints();

File diff suppressed because it is too large Load Diff

View File

@ -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__

View File

@ -40,7 +40,6 @@
#include "IWriteFile.h" #include "IWriteFile.h"
#include "IXMLWriter.h" #include "IXMLWriter.h"
#include "BuiltInFont.h"
#include "os.h" #include "os.h"
namespace irr namespace irr
@ -78,8 +77,6 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
registerGUIElementFactory(factory); registerGUIElementFactory(factory);
factory->drop(); factory->drop();
loadBuiltInFont();
IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC ); IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC );
setSkin(skin); setSkin(skin);
skin->drop(); 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 //! draws all gui elements
void CGUIEnvironment::drawAll() void CGUIEnvironment::drawAll()
{ {

View File

@ -262,8 +262,6 @@ private:
void updateHoveredElement(core::position2d<s32> mousePos); void updateHoveredElement(core::position2d<s32> mousePos);
void loadBuiltInFont();
struct SFont struct SFont
{ {
io::SNamedPath NamedPath; io::SNamedPath NamedPath;

View File

@ -569,29 +569,29 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig, boo
glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
if(!force_legacy_context) if(!force_legacy_context)
{ {
// create core 4.3 context // create core 4.3 context
os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION); os::Printer::log("Creating OpenGL 4.3 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx); Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core43ctxdebug : core43ctx);
if (!XErrorSignaled) if (!XErrorSignaled)
return Context; return Context;
XErrorSignaled = false; XErrorSignaled = false;
// create core 3.3 context // create core 3.3 context
os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION); os::Printer::log("Creating OpenGL 3.3 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx); Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx);
if (!XErrorSignaled) if (!XErrorSignaled)
return Context; return Context;
XErrorSignaled = false; XErrorSignaled = false;
// create core 3.1 context (for older mesa) // create core 3.1 context (for older mesa)
os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION); os::Printer::log("Creating OpenGL 3.1 context...", ELL_INFORMATION);
Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx); Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx);
if (!XErrorSignaled) if (!XErrorSignaled)
return Context; return Context;
} // if(force_legacy_context) } // if(force_legacy_context)
XErrorSignaled = false; XErrorSignaled = false;
irr::video::useCoreContext = false; irr::video::useCoreContext = false;
@ -626,7 +626,7 @@ bool CIrrDeviceLinux::createWindow()
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
GLXFBConfig glxFBConfig; GLXFBConfig glxFBConfig = NULL;
int major, minor; int major, minor;
bool isAvailableGLX=false; bool isAvailableGLX=false;
if (CreationParams.DriverType==video::EDT_OPENGL) if (CreationParams.DriverType==video::EDT_OPENGL)
@ -1044,7 +1044,9 @@ bool CIrrDeviceLinux::createWindow()
glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); glxWin=glXCreateWindow(display,glxFBConfig,window,NULL);
if (glxWin) if (glxWin)
{ {
getLogger()->setLogLevel(ELL_NONE);
Context = getMeAGLContext(display, glxFBConfig, CreationParams.ForceLegacyDevice); Context = getMeAGLContext(display, glxFBConfig, CreationParams.ForceLegacyDevice);
getLogger()->setLogLevel(CreationParams.LoggingLevel);
if (Context) if (Context)
{ {
if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) if (!glXMakeContextCurrent(display, glxWin, glxWin, Context))
@ -2390,7 +2392,7 @@ bool CIrrDeviceLinux::activateJoysticks(core::array<SJoystickInfo> & joystickInf
returnInfo.Axes = info.axes; returnInfo.Axes = info.axes;
returnInfo.Buttons = info.buttons; returnInfo.Buttons = info.buttons;
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
char name[80]; char name[80];
ioctl( info.fd, JSIOCGNAME(80), name); ioctl( info.fd, JSIOCGNAME(80), name);
returnInfo.Name = name; returnInfo.Name = name;

View File

@ -646,6 +646,8 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
buffer->drop(); buffer->drop();
} }
break; break;
default:
break;
}// end switch }// end switch
}// end for all mesh buffers }// end for all mesh buffers
@ -751,6 +753,8 @@ IMesh* CMeshManipulator::createMeshUniquePrimitives(IMesh* mesh) const
buffer->drop(); buffer->drop();
} }
break; break;
default:
break;
}// end switch }// end switch
}// end for all mesh buffers }// end for all mesh buffers
@ -987,6 +991,8 @@ IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNor
vNew = v[idx[i]]; vNew = v[idx[i]];
} }
break; break;
default:
break;
} }
core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew); core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew);
if (n) 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); v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
} }
break; break;
default:
break;
} }
core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew); core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew);
if (n) 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); v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
} }
break; break;
default:
break;
} }
core::map<video::S3DVertex, int>::Node* n = vertMap.find(vNew); core::map<video::S3DVertex, int>::Node* n = vertMap.find(vNew);
if (n) if (n)
@ -1805,6 +1815,8 @@ IMesh* CMeshManipulator::createForsythOptimizedMesh(const IMesh *mesh) const
buf->drop(); buf->drop();
} }
break; break;
default:
break;
} }
delete [] vc; delete [] vc;

View File

@ -744,6 +744,8 @@ namespace video
virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; } virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; }
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; }; virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; };
virtual u32 getPitch() const { return 0; } virtual u32 getPitch() const { return 0; }
virtual u32 getOpenGLTextureName() const { return 0; }
virtual u64 getHandle() { return 0; }
virtual void regenerateMipMapLevels(void* mipmapData=0) {}; virtual void regenerateMipMapLevels(void* mipmapData=0) {};
core::dimension2d<u32> size; core::dimension2d<u32> size;
}; };

View File

@ -505,7 +505,6 @@ namespace video
core::stringc FPVSPath = shaders_path; core::stringc FPVSPath = shaders_path;
FPVSPath += "COGLES2FixedPipeline.vsh"; FPVSPath += "COGLES2FixedPipeline.vsh";
os::Printer::log(FPVSPath.c_str());
core::stringc FPFSPath = shaders_path; core::stringc FPFSPath = shaders_path;
FPFSPath += "COGLES2FixedPipeline.fsh"; FPFSPath += "COGLES2FixedPipeline.fsh";
@ -516,7 +515,7 @@ namespace video
c8* FPVSData = 0; c8* FPVSData = 0;
c8* FPFSData = 0; c8* FPFSData = 0;
long Size = FPVSFile->getSize(); long Size = FPVSFile ? FPVSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -525,7 +524,7 @@ namespace video
FPVSData[Size] = 0; FPVSData[Size] = 0;
} }
Size = FPFSFile->getSize(); Size = FPFSFile ? FPFSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -558,7 +557,7 @@ namespace video
c8* NMVSData = 0; c8* NMVSData = 0;
c8* NMFSData = 0; c8* NMFSData = 0;
Size = NMVSFile->getSize(); Size = NMVSFile ? NMVSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -567,7 +566,7 @@ namespace video
NMVSData[Size] = 0; NMVSData[Size] = 0;
} }
Size = NMFSFile->getSize(); Size = NMFSFile ? NMFSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -600,7 +599,7 @@ namespace video
c8* PMVSData = 0; c8* PMVSData = 0;
c8* PMFSData = 0; c8* PMFSData = 0;
Size = PMVSFile->getSize(); Size = PMVSFile ? PMVSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -609,7 +608,7 @@ namespace video
PMVSData[Size] = 0; PMVSData[Size] = 0;
} }
Size = PMFSFile->getSize(); Size = PMFSFile ? PMFSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -672,7 +671,7 @@ namespace video
c8* R2DVSData = 0; c8* R2DVSData = 0;
c8* R2DFSData = 0; c8* R2DFSData = 0;
Size = R2DVSFile->getSize(); Size = R2DVSFile ? R2DVSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -681,7 +680,7 @@ namespace video
R2DVSData[Size] = 0; R2DVSData[Size] = 0;
} }
Size = R2DFSFile->getSize(); Size = R2DFSFile ? R2DFSFile->getSize() : 0;
if (Size) if (Size)
{ {
@ -3120,7 +3119,7 @@ namespace video
setActiveTexture(GL_TEXTURE0 + stage); setActiveTexture(GL_TEXTURE0 + stage);
if(Driver->CurrentTexture[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]; Texture[stage] = Driver->CurrentTexture[stage];
} }

View File

@ -118,6 +118,9 @@ void COGLES2MaterialRenderer::init(s32& outMaterialTypeNr,
{ {
outMaterialTypeNr = -1; outMaterialTypeNr = -1;
if (!vertexShaderProgram || !pixelShaderProgram)
return;
Program = glCreateProgram(); Program = glCreateProgram();
if (!Program) if (!Program)

View File

@ -81,7 +81,9 @@ public:
virtual u32 getPitch() const; virtual u32 getPitch() const;
//! return open gl texture name //! return open gl texture name
GLuint getOpenGLTextureName() const; virtual u32 getOpenGLTextureName() const;
virtual u64 getHandle() { return 0; }
//! return whether this texture has mipmaps //! return whether this texture has mipmaps
virtual bool hasMipMaps() const; virtual bool hasMipMaps() const;
@ -109,6 +111,13 @@ public:
//! Get an access to texture states cache. //! Get an access to texture states cache.
SStatesCache& getStatesCache() const; SStatesCache& getStatesCache() const;
void setImage(IImage* new_image)
{
if (Image)
Image->drop();
Image = new_image;
}
protected: protected:
//! protected constructor with basic setup, no GL texture name created, for derived classes //! protected constructor with basic setup, no GL texture name created, for derived classes

View File

@ -276,6 +276,8 @@ void COctreeSceneNode::render()
} }
} }
break; break;
default:
break;
} }
} }
@ -371,6 +373,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
for (v=0; v<b->getVertexCount(); ++v) for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
break; break;
default:
break;
} }
polyCount += b->getIndexCount(); polyCount += b->getIndexCount();
@ -424,6 +428,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
for (v=0; v<b->getVertexCount(); ++v) for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
break; break;
default:
break;
} }
polyCount += b->getIndexCount(); polyCount += b->getIndexCount();
@ -474,6 +480,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
for (v=0; v<b->getVertexCount(); ++v) for (v=0; v<b->getVertexCount(); ++v)
nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]); nchunk.Vertices.push_back(((video::S3DVertexTangents*)b->getVertices())[v]);
break; break;
default:
break;
} }
polyCount += b->getIndexCount(); polyCount += b->getIndexCount();
@ -487,6 +495,8 @@ bool COctreeSceneNode::createTree(IMesh* mesh)
nodeCount = TangentsOctree->getNodeCount(); nodeCount = TangentsOctree->getNodeCount();
} }
break; break;
default:
break;
} }
} }

View File

@ -1581,6 +1581,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
case EVT_TANGENTS: case EVT_TANGENTS:
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color); glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
break; break;
default:
break;
} }
} }
else else
@ -1676,6 +1678,8 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48));
} }
break; break;
default:
break;
} }
renderArray(indexList, primitiveCount, pType, iType); renderArray(indexList, primitiveCount, pType, iType);
@ -1740,6 +1744,8 @@ void COpenGLDriver::getColorBuffer(const void* vertices, u32 vertexCount, E_VERT
} }
} }
break; break;
default:
break;
} }
} }
@ -1913,6 +1919,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
case EVT_TANGENTS: case EVT_TANGENTS:
glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color); glColorPointer(colorSize, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Color);
break; break;
default:
break;
} }
} }
else else
@ -1984,6 +1992,8 @@ void COpenGLDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCo
glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); glVertexPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0));
} }
break;
default:
break; break;
} }
@ -2555,8 +2565,7 @@ bool COpenGLDriver::setActiveTexture(u32 stage, const video::ITexture* texture)
if (!useCoreContext) if (!useCoreContext)
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, glBindTexture(GL_TEXTURE_2D, texture->getOpenGLTextureName());
static_cast<const COpenGLTexture*>(texture)->getOpenGLTextureName());
} }
return true; return true;
} }

View File

@ -16,7 +16,7 @@ namespace irr
{ {
namespace video namespace video
{ {
extern bool useCoreContext;
//! Constructor //! Constructor
COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver, COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDriver* driver,
@ -91,6 +91,9 @@ void COpenGLShaderMaterialRenderer::init(s32& outMaterialTypeNr,
{ {
outMaterialTypeNr = -1; outMaterialTypeNr = -1;
if (useCoreContext)
return;
bool success; bool success;
// create vertex shader // create vertex shader

View File

@ -78,7 +78,9 @@ public:
virtual u32 getPitch() const; virtual u32 getPitch() const;
//! return open gl texture name //! return open gl texture name
GLuint getOpenGLTextureName() const; virtual u32 getOpenGLTextureName() const;
virtual u64 getHandle() { return 0; }
//! return whether this texture has mipmaps //! return whether this texture has mipmaps
virtual bool hasMipMaps() const; virtual bool hasMipMaps() const;
@ -103,6 +105,13 @@ public:
//! sets whether this texture is intended to be used as a render target. //! sets whether this texture is intended to be used as a render target.
void setIsRenderTarget(bool isTarget); void setIsRenderTarget(bool isTarget);
void setImage(IImage* new_image)
{
if (Image)
Image->drop();
Image = new_image;
}
protected: protected:
//! protected constructor with basic setup, no GL texture name created, for derived classes //! protected constructor with basic setup, no GL texture name created, for derived classes

View File

@ -24,10 +24,6 @@
#include "CSkinnedMesh.h" #include "CSkinnedMesh.h"
#endif #endif
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
#include "CB3DMeshFileLoader.h"
#endif
#include "CCubeSceneNode.h" #include "CCubeSceneNode.h"
#include "CSphereSceneNode.h" #include "CSphereSceneNode.h"
#include "CAnimatedMeshSceneNode.h" #include "CAnimatedMeshSceneNode.h"
@ -121,13 +117,6 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
// create geometry creator // create geometry creator
GeometryCreator = new CGeometryCreator(); 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 // factories
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this); ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
registerSceneNodeFactory(factory); registerSceneNodeFactory(factory);
@ -1427,11 +1416,6 @@ void CSceneManager::drawAll(u32 flags)
void CSceneManager::setLightManager(ILightManager* lightManager) void CSceneManager::setLightManager(ILightManager* lightManager)
{ {
if (lightManager)
lightManager->grab();
if (LightManager)
LightManager->drop();
LightManager = lightManager; LightManager = lightManager;
} }

View File

@ -9,6 +9,7 @@
#include "CBoneSceneNode.h" #include "CBoneSceneNode.h"
#include "IAnimatedMeshSceneNode.h" #include "IAnimatedMeshSceneNode.h"
#include "os.h" #include "os.h"
#include "irrMap.h"
namespace irr namespace irr
{ {
@ -22,12 +23,12 @@ CSkinnedMesh::CSkinnedMesh()
LastAnimatedFrame(-1), SkinnedLastFrame(false), LastAnimatedFrame(-1), SkinnedLastFrame(false),
InterpolationMode(EIM_LINEAR), InterpolationMode(EIM_LINEAR),
HasAnimation(false), PreparedForSkinning(false), HasAnimation(false), PreparedForSkinning(false),
AnimateNormals(true), HardwareSkinning(false) AnimateNormals(true), HardwareSkinning(false), m_total_joints(0),
m_current_joint(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSkinnedMesh"); setDebugName("CSkinnedMesh");
#endif #endif
SkinningBuffers=&LocalBuffers; 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. //! 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) 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); //animate(frame,startFrameLoop, endFrameLoop);
if (frame==-1) if (frame==-1)
return this; return this;
animateMesh((f32)frame, 1.0f); animateMesh((f32)frame, 1.0f);
skinMesh(); skinMesh();
if (is_hw_skinning_before)
HardwareSkinning = true;
return this; return this;
} }
@ -93,6 +101,12 @@ IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32
//! blend: {0-old position, 1-New position} //! blend: {0-old position, 1-New position}
void CSkinnedMesh::animateMesh(f32 frame, f32 blend) void CSkinnedMesh::animateMesh(f32 frame, f32 blend)
{ {
if (HardwareSkinning && LastAnimatedFrame==frame)
{
SkinnedLastFrame=false;
return;
}
if (!HasAnimation || LastAnimatedFrame==frame) if (!HasAnimation || LastAnimatedFrame==frame)
return; return;
@ -445,7 +459,7 @@ void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint,
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
//! Preforms a software skin on this mesh based of joint positions //! 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) if (!HasAnimation || SkinnedLastFrame)
return; return;
@ -456,7 +470,13 @@ void CSkinnedMesh::skinMesh(f32 strength)
//----------------- //-----------------
SkinnedLastFrame=true; 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.... //Software skin....
u32 i; u32 i;
@ -486,65 +506,73 @@ void CSkinnedMesh::skinMesh(f32 strength)
updateBoundingBox(); 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()) if (joint->Weights.size())
{ {
//Find this joints pull on vertices... //Find this joints pull on vertices...
core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING); core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING);
jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix); jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix);
if (HardwareSkinning)
core::vector3df thisVertexMove, thisNormalMove;
core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
//Skin Vertices Positions and Normals...
for (u32 i=0; i<joint->Weights.size(); ++i)
{ {
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... core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
if (AnimateNormals) //Skin Vertices Positions and Normals...
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal); for (u32 i=0; i<joint->Weights.size(); ++i)
// Apply animation strength
if(strength != 1.f)
{ {
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength); SWeight& weight = joint->Weights[i];
if(AnimateNormals)
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
}
if (! (*(weight.Moved)) ) // Pull this vertex...
{ jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
*(weight.Moved) = true;
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength;
if (AnimateNormals) 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 //Skin all children
for (u32 j=0; j<joint->Children.size(); ++j) 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 (HardwareSkinning!=on)
{ {
if (on) if (on)
{ toStaticPose();
//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();
}
}
}
HardwareSkinning=on; HardwareSkinning=on;
} }
return HardwareSkinning; 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) void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint)
{ {
@ -1139,7 +1167,7 @@ void CSkinnedMesh::finalize()
void CSkinnedMesh::updateBoundingBox(void) void CSkinnedMesh::updateBoundingBox(void)
{ {
if(!SkinningBuffers) if(HardwareSkinning || !SkinningBuffers)
return; return;
core::array<SSkinMeshBuffer*> & buffer = *SkinningBuffers; core::array<SSkinMeshBuffer*> & buffer = *SkinningBuffers;
@ -1382,26 +1410,137 @@ void CSkinnedMesh::addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
SkinnedLastFrame=false; SkinnedLastFrame=false;
} }
bool CSkinnedMesh::sortJointInfluenceFunc(const JointInfluence& a,
void CSkinnedMesh::convertMeshToTangents() const JointInfluence& b)
{ {
// now calculate tangents return a.weight > b.weight;
for (u32 b=0; b < LocalBuffers.size(); ++b) }
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]) 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(); for (u32 j = 0; j < joint->Children.size(); j++)
video::S3DVertexTangents* v = computeWeightInfluence(joint->Children[j], index, wi);
(video::S3DVertexTangents*)LocalBuffers[b]->getVertices(); }
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( calculateTangents(
v[idx[i+0]].Normal, local_normal,
v[idx[i+0]].Tangent, v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal, v[idx[i+0]].Binormal,
v[idx[i+0]].Pos, v[idx[i+0]].Pos,
@ -1412,7 +1551,7 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+2]].TCoords); v[idx[i+2]].TCoords);
calculateTangents( calculateTangents(
v[idx[i+1]].Normal, local_normal,
v[idx[i+1]].Tangent, v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal, v[idx[i+1]].Binormal,
v[idx[i+1]].Pos, v[idx[i+1]].Pos,
@ -1423,7 +1562,7 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+0]].TCoords); v[idx[i+0]].TCoords);
calculateTangents( calculateTangents(
v[idx[i+2]].Normal, local_normal,
v[idx[i+2]].Tangent, v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal, v[idx[i+2]].Binormal,
v[idx[i+2]].Pos, v[idx[i+2]].Pos,
@ -1433,11 +1572,38 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+0]].TCoords, v[idx[i+0]].TCoords,
v[idx[i+1]].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( void CSkinnedMesh::calculateTangents(
core::vector3df& normal, core::vector3df& normal,
core::vector3df& tangent, core::vector3df& tangent,

View File

@ -14,6 +14,16 @@
#include "matrix4.h" #include "matrix4.h"
#include "quaternion.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 irr
{ {
namespace scene namespace scene
@ -25,7 +35,6 @@ namespace scene
class CSkinnedMesh: public ISkinnedMesh class CSkinnedMesh: public ISkinnedMesh
{ {
public: public:
//! constructor //! constructor
CSkinnedMesh(); CSkinnedMesh();
@ -52,7 +61,7 @@ namespace scene
virtual void animateMesh(f32 frame, f32 blend); virtual void animateMesh(f32 frame, f32 blend);
//! Preforms a software skin on this mesh based of joint positions //! 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. //! returns amount of mesh buffers.
virtual u32 getMeshBufferCount() const; virtual u32 getMeshBufferCount() const;
@ -105,7 +114,7 @@ namespace scene
virtual void setInterpolationMode(E_INTERPOLATION_MODE mode); virtual void setInterpolationMode(E_INTERPOLATION_MODE mode);
//! Convertes the mesh to contain tangent information //! Convertes the mesh to contain tangent information
virtual void convertMeshToTangents(); virtual void convertMeshToTangents(bool(*predicate)(IMeshBuffer*));
//! Does the mesh have no animation //! Does the mesh have no animation
virtual bool isStatic(); virtual bool isStatic();
@ -159,7 +168,16 @@ namespace scene
void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes, void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
IAnimatedMeshSceneNode* node, IAnimatedMeshSceneNode* node,
ISceneManager* smgr); ISceneManager* smgr);
void convertForSkinning();
void computeWeightInfluence(SJoint *joint, size_t &index, WeightInfluence& wi);
u32 getTotalJoints() const { return m_total_joints; }
private: private:
void toStaticPose();
void checkForAnimation(); void checkForAnimation();
void normalizeWeights(); void normalizeWeights();
@ -175,13 +193,17 @@ private:
void calculateGlobalMatrices(SJoint *Joint,SJoint *ParentJoint); 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, void calculateTangents(core::vector3df& normal,
core::vector3df& tangent, core::vector3df& binormal, core::vector3df& tangent, core::vector3df& binormal,
core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3, core::vector3df& vt1, core::vector3df& vt2, core::vector3df& vt3,
core::vector2df& tc1, core::vector2df& tc2, core::vector2df& tc3); 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 core::array<SSkinMeshBuffer*> *SkinningBuffers; //Meshbuffer to skin, default is to skin localBuffers
core::array<SSkinMeshBuffer*> LocalBuffers; core::array<SSkinMeshBuffer*> LocalBuffers;
@ -205,6 +227,8 @@ private:
bool PreparedForSkinning; bool PreparedForSkinning;
bool AnimateNormals; bool AnimateNormals;
bool HardwareSkinning; bool HardwareSkinning;
u32 m_total_joints;
u32 m_current_joint;
}; };
} // end namespace scene } // end namespace scene

View File

@ -114,12 +114,10 @@ CBillboardTextSceneNode::CBillboardTextSceneNode(ISceneNode* parent, ISceneManag
{ {
Font = (gui::IGUIFontBitmap*)font; Font = (gui::IGUIFontBitmap*)font;
Font->grab(); Font->grab();
u32 texture_count = Font->addLazyLoadCharacters(text);
_IRR_DEBUG_BREAK_IF(texture_count==0);
// mesh with one buffer per texture // mesh with one buffer per texture
Mesh = new SMesh(); Mesh = new SMesh();
for (u32 i=0; i<texture_count; ++i) for (u32 i=0; i<Font->getSpriteBank()->getTextureCount(); ++i)
{ {
SMeshBuffer *mb = new SMeshBuffer(); SMeshBuffer *mb = new SMeshBuffer();
mb->Material = Material; mb->Material = Material;

View File

@ -719,7 +719,7 @@ bool CIrrDeviceMacOSX::createWindow()
if (!CreationParams.WindowId) if (!CreationParams.WindowId)
{ {
[Window center]; [Window center];
[(NSFileManager *)Window setDelegate:[NSApp delegate]]; [(NSFileManager *)Window setDelegate:[(NSFileManager *)NSApp delegate]];
if(CreationParams.DriverType == video::EDT_OPENGL) if(CreationParams.DriverType == video::EDT_OPENGL)
[OGLContext setView:[Window contentView]]; [OGLContext setView:[Window contentView]];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -23,6 +23,7 @@
#include "challenges/challenge_data.hpp" #include "challenges/challenge_data.hpp"
#include "challenges/unlock_manager.hpp" #include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "io/utf_writer.hpp" #include "io/utf_writer.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
@ -67,6 +68,9 @@ void StoryModeStatus::addStatus(ChallengeStatus *cs)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool StoryModeStatus::isLocked(const std::string& feature) bool StoryModeStatus::isLocked(const std::string& feature)
{ {
if (UserConfigParams::m_everything_unlocked)
return false;
return m_locked_features.find(feature)!=m_locked_features.end(); return m_locked_features.find(feature)!=m_locked_features.end();
} // featureIsLocked } // featureIsLocked

View File

@ -279,6 +279,16 @@ enum AnimType {ANIMS_NONE = 0,
ANIMS_PLAYERS_ONLY = 1, ANIMS_PLAYERS_ONLY = 1,
ANIMS_ALL = 2 }; 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 /** Using X-macros for setting-possible values is not very pretty, but it's a
* no-maintenance case : * no-maintenance case :
* when you want to add a new parameter, just add one signle line below and * when you want to add a new parameter, just add one signle line below and
@ -417,6 +427,11 @@ namespace UserConfigParams
"A parameter in range [0.5, 1.5] that determines the scale of the " "A parameter in range [0.5, 1.5] that determines the scale of the "
"multitouch interface.")); "multitouch interface."));
PARAM_PREFIX BoolUserConfigParam m_screen_keyboard
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
&m_multitouch_group,
"Enable screen keyboard.") );
// ---- GP start order // ---- GP start order
PARAM_PREFIX GroupUserConfigParam m_gp_start_order PARAM_PREFIX GroupUserConfigParam m_gp_start_order
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder", PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
@ -583,6 +598,8 @@ namespace UserConfigParams
PARAM_PREFIX bool m_race_now PARAM_DEFAULT( false ); 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 & /** True to test funky ambient/diffuse/specularity in RGB &
* all anisotropic */ * all anisotropic */
PARAM_PREFIX bool m_rendering_debug PARAM_DEFAULT( false ); PARAM_PREFIX bool m_rendering_debug PARAM_DEFAULT( false );
@ -673,6 +690,13 @@ namespace UserConfigParams
"steering_animations", &m_graphics_quality, "steering_animations", &m_graphics_quality,
"Whether to display kart animations (0=disabled for all; " "Whether to display kart animations (0=disabled for all; "
"1=enabled for humans, disabled for AIs; 2=enabled 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_PREFIX IntUserConfigParam m_anisotropic
PARAM_DEFAULT( IntUserConfigParam(4, "anisotropic", PARAM_DEFAULT( IntUserConfigParam(4, "anisotropic",
&m_graphics_quality, &m_graphics_quality,
@ -892,6 +916,10 @@ namespace UserConfigParams
PARAM_DEFAULT( BoolUserConfigParam(false, "artist_debug_mode", PARAM_DEFAULT( BoolUserConfigParam(false, "artist_debug_mode",
"Whether to enable track debugging features") ); "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 // TODO? implement blacklist for new irrlicht device and GUI
PARAM_PREFIX std::vector<std::string> m_blacklist_res; PARAM_PREFIX std::vector<std::string> m_blacklist_res;

View File

@ -29,6 +29,8 @@ class FaceTTF;
class DigitFace : public FontWithFace class DigitFace : public FontWithFace
{ {
private: private:
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
// ------------------------------------------------------------------------
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; } virtual unsigned int getGlyphPageSize() const OVERRIDE { return 256; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; } virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
@ -43,8 +45,6 @@ public:
virtual void init() OVERRIDE; virtual void init() OVERRIDE;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void reset() OVERRIDE; virtual void reset() OVERRIDE;
// ------------------------------------------------------------------------
virtual bool supportLazyLoadChar() const OVERRIDE { return false; }
}; // DigitFace }; // DigitFace

View File

@ -22,7 +22,10 @@
#include "font/font_manager.hpp" #include "font/font_manager.hpp"
#include "font/font_settings.hpp" #include "font/font_settings.hpp"
#include "graphics/2dutils.hpp" #include "graphics/2dutils.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/skin.hpp" #include "guiengine/skin.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
@ -50,8 +53,11 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
*/ */
FontWithFace::~FontWithFace() FontWithFace::~FontWithFace()
{ {
m_page->drop(); for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
m_page = NULL; {
STKTexManager::getInstance()->removeTexture(
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
}
m_spritebank->drop(); m_spritebank->drop();
m_spritebank = NULL; m_spritebank = NULL;
@ -66,9 +72,6 @@ FontWithFace::~FontWithFace()
void FontWithFace::init() void FontWithFace::init()
{ {
setDPI(); setDPI();
m_page = irr_driver->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
core::dimension2du(getGlyphPageSize(), getGlyphPageSize()));
// Get the max height for this face // Get the max height for this face
assert(m_face_ttf->getTotalFaces() > 0); assert(m_face_ttf->getTotalFaces() > 0);
FT_Face cur_face = m_face_ttf->getFace(0); FT_Face cur_face = m_face_ttf->getFace(0);
@ -100,6 +103,11 @@ void FontWithFace::reset()
m_new_char_holder.clear(); m_new_char_holder.clear();
m_character_area_map.clear(); m_character_area_map.clear();
m_character_glyph_info_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(); m_spritebank->clear();
createNewGlyphPage(); createNewGlyphPage();
} // reset } // reset
@ -129,32 +137,25 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
*/ */
void FontWithFace::createNewGlyphPage() 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_current_height = 0;
m_used_width = 0; m_used_width = 0;
m_used_height = 0; m_used_height = 0;
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
// Font textures can not be resized (besides the impact on quality in StringUtils::toString(m_spritebank->getTextureCount()),
// this case, the rectangles in spritebank would become wrong). getGlyphPageSize(),
core::dimension2du old_max_size = irr_driver->getVideoDriver() #ifndef SERVER_ONLY
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE"); CVS->isARBTextureSwizzleUsable()
irr_driver->getVideoDriver()->getNonConstDriverAttributes() #else
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0)); false
#endif
video::ITexture* page_texture = irr_driver->getVideoDriver() );
->addTexture("Glyph_page", m_page); m_spritebank->addTexture(STKTexManager::getInstance()->addTexture(stkt));
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);
} // createNewGlyphPage } // createNewGlyphPage
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -184,80 +185,17 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
"rendering a glyph to bitmap"); "rendering a glyph to bitmap");
// Convert to an anti-aliased bitmap // Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap; FT_Bitmap* bits = &(slot->bitmap);
core::dimension2du texture_size(bits->width + 1, bits->rows + 1);
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);
if ((m_used_width + texture_size.Width > getGlyphPageSize() && if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
m_used_height + m_current_height + texture_size.Height > m_used_height + m_current_height + texture_size.Height >
getGlyphPageSize()) || getGlyphPageSize()) ||
m_used_height + texture_size.Height > getGlyphPageSize()) m_used_height + texture_size.Height > getGlyphPageSize())
{ {
// Current glyph page is full: // Add a new glyph page if current one 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
createNewGlyphPage(); 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 // Determine the linebreak location
if (m_used_width + texture_size.Width > getGlyphPageSize()) 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; m_current_height = 0;
} }
// Copy to the full glyph page const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
glyph->copyTo(m_page, core::position2di(m_used_width, m_used_height)); #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 // Store the rectangle of current glyph
gui::SGUISpriteFrame f; gui::SGUISpriteFrame f;
gui::SGUISprite s; gui::SGUISprite s;
core::rect<s32> rectangle(m_used_width, m_used_height, 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.rectNumber = m_spritebank->getPositions().size();
f.textureNumber = m_spritebank->getTextureCount() - 1; f.textureNumber = cur_tex;
// Add frame to sprite // Add frame to sprite
s.Frames.push_back(f); s.Frames.push_back(f);
@ -295,10 +256,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
a.spriteno = f.rectNumber; a.spriteno = f.rectNumber;
m_character_area_map[c] = a; m_character_area_map[c] = a;
// Clean the temporary glyph
glyph->drop();
glyph = NULL;
// Store used area // Store used area
m_used_width += texture_size.Width; m_used_width += texture_size.Width;
if (m_current_height < texture_size.Height) if (m_current_height < texture_size.Height)
@ -321,23 +278,6 @@ void FontWithFace::updateCharactersList()
} }
m_new_char_holder.clear(); 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 } // updateCharactersList
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -353,10 +293,9 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
core::dimension2d<u32> size = tex->getSize(); core::dimension2d<u32> size = tex->getSize();
video::ECOLOR_FORMAT col_format = tex->getColorFormat(); video::ECOLOR_FORMAT col_format = tex->getColorFormat();
void* data = tex->lock(); void* data = tex->lock();
video::IImage* image = irr_driver->getVideoDriver() video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(col_format, size, data, false/*copy mem*/); ->createImageFromData(col_format, size, data,
true/*ownForeignMemory*/);
tex->unlock(); tex->unlock();
irr_driver->getVideoDriver()->writeImageToFile(image, std::string irr_driver->getVideoDriver()->writeImageToFile(image, std::string
(name + "_" + StringUtils::toString(i) + ".png").c_str()); (name + "_" + StringUtils::toString(i) + ".png").c_str());
@ -618,28 +557,6 @@ void FontWithFace::render(const core::stringw& text,
} }
else 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 // Billboard text specific, use offset_y_bt instead
float glyph_offset_x = area.bearing_x * float glyph_offset_x = area.bearing_x *
(fallback[i] ? m_fallback_font_scale : scale); (fallback[i] ? m_fallback_font_scale : scale);

View File

@ -92,6 +92,39 @@ protected:
/** Used in top side bearing calculation. */ /** Used in top side bearing calculation. */
int m_glyph_max_height; 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 /** 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. * this font, it will use that fallback font to try rendering it.
@ -129,9 +162,6 @@ private:
/** Sprite bank to store each glyph. */ /** Sprite bank to store each glyph. */
gui::IGUISpriteBank* m_spritebank; 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. */ /** The current max height at current drawing line in glyph page. */
unsigned int m_current_height; unsigned int m_current_height;
@ -206,6 +236,8 @@ private:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void loadGlyphInfo(wchar_t c); void loadGlyphInfo(wchar_t c);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
/** Add a character into \ref m_new_char_holder for lazy loading later. */ /** Add a character into \ref m_new_char_holder for lazy loading later. */
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); } void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -213,6 +245,9 @@ private:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setDPI(); 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 /** Defined by sub-class about the texture size of glyph page, it should be
* a power of two. */ * a power of two. */
virtual unsigned int getGlyphPageSize() const = 0; virtual unsigned int getGlyphPageSize() const = 0;
@ -266,44 +301,6 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Return the dpi of this face. */ /** Return the dpi of this face. */
unsigned int getDPI() const { return m_face_dpi; } 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 }; // FontWithFace

View File

@ -24,18 +24,9 @@
#include "graphics/shader.hpp" #include "graphics/shader.hpp"
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/shared_gpu_objects.hpp" #include "graphics/shared_gpu_objects.hpp"
#include "graphics/texture_manager.hpp"
#include "graphics/texture_shader.hpp" #include "graphics/texture_shader.hpp"
#include "utils/cpp2011.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> class Primitive2DList : public TextureShader<Primitive2DList, 1, float>
{ {
@ -186,16 +177,8 @@ static void drawTexColoredQuad(const video::ITexture *texture,
ColoredTextureRectShader::getInstance()->use(); ColoredTextureRectShader::getInstance()->use();
glBindVertexArray(ColoredTextureRectShader::getInstance()->m_vao); 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() ColoredTextureRectShader::getInstance()
->setTextureUnits(t->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
ColoredTextureRectShader::getInstance() ColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
core::vector2df(width, height), core::vector2df(width, height),
@ -367,16 +350,8 @@ void draw2DImage(const video::ITexture* texture,
UniformColoredTextureRectShader::getInstance()->use(); UniformColoredTextureRectShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getUI_VAO()); 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() UniformColoredTextureRectShader::getInstance()
->setTextureUnits(c_texture->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
@ -450,16 +425,8 @@ void draw2DImage(const video::ITexture* texture,
UniformColoredTextureRectShader::getInstance()->use(); UniformColoredTextureRectShader::getInstance()->use();
glBindVertexArray(SharedGPUObjects::getUI_VAO()); 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() UniformColoredTextureRectShader::getInstance()
->setTextureUnits(c_texture->getOpenGLTextureName()); ->setTextureUnits(texture->getOpenGLTextureName());
UniformColoredTextureRectShader::getInstance() UniformColoredTextureRectShader::getInstance()
->setUniforms(core::vector2df(center_pos_x, center_pos_y), ->setUniforms(core::vector2df(center_pos_x, center_pos_y),
@ -574,14 +541,7 @@ void draw2DImage(const video::ITexture* texture,
} }
else else
{ {
#if !defined(USE_GLES2) drawTexQuad(texture->getOpenGLTextureName(), width, height,
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,
center_pos_x, center_pos_y, tex_center_pos_x, center_pos_x, center_pos_y, tex_center_pos_x,
tex_center_pos_y, tex_width, tex_height); tex_center_pos_y, tex_width, tex_height);
} }
@ -657,14 +617,7 @@ void draw2DImage(const video::ITexture* texture,
} }
else else
{ {
#if !defined(USE_GLES2) drawTexQuad(texture->getOpenGLTextureName(), width, height,
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,
center_pos_x, center_pos_y, tex_center_pos_x, center_pos_x, center_pos_y, tex_center_pos_x,
tex_center_pos_y, tex_width, tex_height); 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()->use();
Primitive2DList::getInstance()->setUniforms(1.0f); Primitive2DList::getInstance()->setUniforms(1.0f);
compressTexture(tex, false); Primitive2DList::getInstance()->setTextureUnits(tex->getOpenGLTextureName());
Primitive2DList::getInstance()->setTextureUnits(getTextureGLuint(tex));
glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0);
glDeleteVertexArrays(1, &tmpvao); glDeleteVertexArrays(1, &tmpvao);

View File

@ -400,6 +400,8 @@ void CBatchingMesh::recalculateDestBufferBoundingBox(u32 i)
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
((SMeshBufferTangents*)DestBuffers[i].Buffer)->recalculateBoundingBox(); ((SMeshBufferTangents*)DestBuffers[i].Buffer)->recalculateBoundingBox();
break; break;
default:
break;
} }
} }

View File

@ -51,6 +51,7 @@ void CentralVideoSettings::init()
hasExplicitAttribLocation = false; hasExplicitAttribLocation = false;
hasGS = false; hasGS = false;
hasTextureFilterAnisotropic = false; hasTextureFilterAnisotropic = false;
hasTextureSwizzle = false;
#if defined(USE_GLES2) #if defined(USE_GLES2)
hasBGRA = false; hasBGRA = false;
@ -91,6 +92,11 @@ void CentralVideoSettings::init()
std::string card((char*)(glGetString(GL_RENDERER))); std::string card((char*)(glGetString(GL_RENDERER)));
GraphicsRestrictions::init(driver, card); GraphicsRestrictions::init(driver, card);
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
{
m_glsl = false;
}
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
if (hasGLExtension("GL_AMD_vertex_shader_layer")) { if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
hasVSLayer = true; hasVSLayer = true;
@ -158,9 +164,12 @@ void CentralVideoSettings::init()
Log::info("GLDriver", "ARB Multi Draw Indirect Present"); Log::info("GLDriver", "ARB Multi Draw Indirect Present");
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) && 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; hasTextureCompression = true;
Log::info("GLDriver", "EXT Texture Compression S3TC Present"); Log::info("GLDriver", "EXT Texture Compression S3TC Present");
Log::info("GLDriver", "ARB Texture Compression RGTC Present");
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) && if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
hasGLExtension("GL_ARB_uniform_buffer_object")) { hasGLExtension("GL_ARB_uniform_buffer_object")) {
@ -182,7 +191,11 @@ void CentralVideoSettings::init()
hasGS = true; hasGS = true;
Log::info("GLDriver", "Geometry Shaders Present"); 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 // 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. // user has enabled them (bit 1 set), then leave them enabled.
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) && if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
@ -222,13 +235,8 @@ void CentralVideoSettings::init()
#else #else
if (m_glsl == true) if (m_glsl == true)
{ {
hasArraysOfArrays = true;
hasTextureStorage = true; hasTextureStorage = true;
hasTextureView = true; hasTextureSwizzle = true;
hasBindlessTexture = true;
hasImageLoadStore = true;
hasAtomics = true;
hasSSBO = true;
} }
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) && 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); 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 #endif // !SERVER_ONLY

View File

@ -43,6 +43,7 @@ private:
bool hasImageLoadStore; bool hasImageLoadStore;
bool hasMultiDrawIndirect; bool hasMultiDrawIndirect;
bool hasTextureFilterAnisotropic; bool hasTextureFilterAnisotropic;
bool hasTextureSwizzle;
#if defined(USE_GLES2) #if defined(USE_GLES2)
bool hasBGRA; bool hasBGRA;
@ -82,6 +83,7 @@ public:
bool isARBMultiDrawIndirectUsable() const; bool isARBMultiDrawIndirectUsable() const;
bool isARBExplicitAttribLocationUsable() const; bool isARBExplicitAttribLocationUsable() const;
bool isEXTTextureFilterAnisotropicUsable() const; bool isEXTTextureFilterAnisotropicUsable() const;
bool isARBTextureSwizzleUsable() const;
#if defined(USE_GLES2) #if defined(USE_GLES2)
bool isEXTTextureFormatBGRA8888Usable() const; bool isEXTTextureFormatBGRA8888Usable() const;
@ -95,6 +97,7 @@ public:
bool supportsIndirectInstancingRendering() const; bool supportsIndirectInstancingRendering() const;
bool supportsComputeShadersFiltering() const; bool supportsComputeShadersFiltering() const;
bool supportsAsyncInstanceUpload() const; bool supportsAsyncInstanceUpload() const;
bool supportsHardwareSkinning() const;
// "Macro" around feature support and user config // "Macro" around feature support and user config
bool isShadowEnabled() const; bool isShadowEnabled() const;

View File

@ -19,6 +19,7 @@
#include "graphics/command_buffer.hpp" #include "graphics/command_buffer.hpp"
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
#include "utils/cpp2011.hpp" #include "utils/cpp2011.hpp"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -29,6 +30,7 @@ void InstanceFiller<InstanceDataSingleTex>::add(GLMesh* mesh,
{ {
fillOriginOrientationScale<InstanceDataSingleTex>(STK::tuple_get<0>(is), instance); fillOriginOrientationScale<InstanceDataSingleTex>(STK::tuple_get<0>(is), instance);
instance.Texture = mesh->TextureHandles[0]; 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.Texture = mesh->TextureHandles[0];
instance.SecondTexture = mesh->TextureHandles[1]; instance.SecondTexture = mesh->TextureHandles[1];
instance.ThirdTexture = mesh->TextureHandles[2]; 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.SecondTexture = mesh->TextureHandles[1];
instance.ThirdTexture = mesh->TextureHandles[2]; instance.ThirdTexture = mesh->TextureHandles[2];
instance.FourthTexture = mesh->TextureHandles[3]; 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(); clearMeshes();
@ -167,16 +171,20 @@ void SolidCommandBuffer::fill(SolidPassMeshMap *mesh_map)
Material::SHADERTYPE_ALPHA_TEST, Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT, Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_SPHERE_MAP, 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); (mesh_map, three_tex_material_list, InstanceTypeThreeTex);
std::vector<int> four_tex_material_list = std::vector<int> four_tex_material_list =
createVector<int>(Material::SHADERTYPE_DETAIL_MAP, 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); (mesh_map, four_tex_material_list, InstanceTypeFourTex);
if (!CVS->supportsAsyncInstanceUpload()) if (!CVS->supportsAsyncInstanceUpload())
@ -189,7 +197,7 @@ ShadowCommandBuffer::ShadowCommandBuffer(): CommandBuffer()
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map) void ShadowCommandBuffer::fill(MeshMap *mesh_map)
{ {
clearMeshes(); clearMeshes();
@ -215,9 +223,17 @@ void ShadowCommandBuffer::fill(OtherMeshMap *mesh_map)
+ Material::SHADERTYPE_VEGETATION); + Material::SHADERTYPE_VEGETATION);
shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT shadow_tex_material_list.push_back(cascade * Material::SHADERTYPE_COUNT
+ Material::SHADERTYPE_SPLATTING); + 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); (mesh_map, shadow_tex_material_list, InstanceTypeShadow);
if (!CVS->supportsAsyncInstanceUpload()) if (!CVS->supportsAsyncInstanceUpload())
@ -231,7 +247,7 @@ ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer()
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ReflectiveShadowMapCommandBuffer::fill(OtherMeshMap *mesh_map) void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
{ {
clearMeshes(); clearMeshes();
@ -245,7 +261,7 @@ void ReflectiveShadowMapCommandBuffer::fill(OtherMeshMap *mesh_map)
Material::SHADERTYPE_DETAIL_MAP, Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP); Material::SHADERTYPE_NORMAL_MAP);
fillInstanceData<InstanceDataSingleTex, OtherMeshMap> fillInstanceData<InstanceDataSingleTex, MeshMap>
(mesh_map, rsm_material_list, InstanceTypeRSM); (mesh_map, rsm_material_list, InstanceTypeRSM);
if (!CVS->supportsAsyncInstanceUpload()) if (!CVS->supportsAsyncInstanceUpload())
@ -259,14 +275,14 @@ GlowCommandBuffer::GlowCommandBuffer()
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GlowCommandBuffer::fill(OtherMeshMap *mesh_map) void GlowCommandBuffer::fill(MeshMap *mesh_map)
{ {
clearMeshes(); clearMeshes();
if(!CVS->supportsAsyncInstanceUpload()) if(!CVS->supportsAsyncInstanceUpload())
mapIndirectBuffer(); mapIndirectBuffer();
fillInstanceData<GlowInstanceData, OtherMeshMap> fillInstanceData<GlowInstanceData, MeshMap>
(mesh_map, createVector<int>(0), InstanceTypeGlow); (mesh_map, createVector<int>(0), InstanceTypeGlow);
if (!CVS->supportsAsyncInstanceUpload()) if (!CVS->supportsAsyncInstanceUpload())
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER); glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);

View File

@ -24,26 +24,11 @@
#include "graphics/gl_headers.hpp" #include "graphics/gl_headers.hpp"
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/materials.hpp" #include "graphics/materials.hpp"
#include "graphics/render_info.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/vao_manager.hpp" #include "graphics/vao_manager.hpp"
#include <irrlicht.h> #include <irrlicht.h>
#include <array> #include <array>
#include <unordered_map> #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 /** Fill origin, orientation and scale attributes
* \param node The scene node of the mesh * \param node The scene node of the mesh
@ -271,7 +256,7 @@ class SolidCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADER
{ {
public: public:
SolidCommandBuffer(); SolidCommandBuffer();
void fill(SolidPassMeshMap *mesh_map); void fill(MeshMap *mesh_map);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** First rendering pass; draw all meshes associated with the same material /** 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: public:
ShadowCommandBuffer(); ShadowCommandBuffer();
void fill(OtherMeshMap *mesh_map); void fill(MeshMap *mesh_map);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Draw shadowmaps for meshes with the same material /** Draw shadowmaps for meshes with the same material
@ -532,7 +517,7 @@ class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Ma
{ {
public: public:
ReflectiveShadowMapCommandBuffer(); ReflectiveShadowMapCommandBuffer();
void fill(OtherMeshMap *mesh_map); void fill(MeshMap *mesh_map);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Draw reflective shadow map for meshes with the same material /** Draw reflective shadow map for meshes with the same material
@ -615,7 +600,7 @@ class GlowCommandBuffer: public CommandBuffer<1>
{ {
public: public:
GlowCommandBuffer(); GlowCommandBuffer();
void fill(OtherMeshMap *mesh_map); void fill(MeshMap *mesh_map);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Draw glowing meshes. /** Draw glowing meshes.

View File

@ -19,23 +19,28 @@
#include "graphics/draw_calls.hpp" #include "graphics/draw_calls.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/command_buffer.hpp"
#include "graphics/draw_tools.hpp" #include "graphics/draw_tools.hpp"
#include "graphics/gpu_particles.hpp" #include "graphics/gpu_particles.hpp"
#include "graphics/lod_node.hpp" #include "graphics/lod_node.hpp"
#include "graphics/materials.hpp" #include "graphics/materials.hpp"
#include "graphics/render_info.hpp"
#include "graphics/shadow_matrices.hpp" #include "graphics/shadow_matrices.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stk_animated_mesh.hpp"
#include "graphics/stk_billboard.hpp" #include "graphics/stk_billboard.hpp"
#include "graphics/stk_mesh.hpp" #include "graphics/stk_mesh.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/vao_manager.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "utils/profiler.hpp" #include "utils/profiler.hpp"
#include <numeric>
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void DrawCalls::clearLists() void DrawCalls::clearLists()
{ {
ListBlendTransparent::getInstance()->clear(); ListBlendTransparent::getInstance()->clear();
ListAdditiveTransparent::getInstance()->clear(); ListAdditiveTransparent::getInstance()->clear();
ListTranslucentSkinned::getInstance()->clear();
ListTranslucentStandard::getInstance()->clear(); ListTranslucentStandard::getInstance()->clear();
ListTranslucentTangents::getInstance()->clear(); ListTranslucentTangents::getInstance()->clear();
ListTranslucent2TCoords::getInstance()->clear(); ListTranslucent2TCoords::getInstance()->clear();
@ -43,6 +48,10 @@ void DrawCalls::clearLists()
ListAdditiveTransparentFog::getInstance()->clear(); ListAdditiveTransparentFog::getInstance()->clear();
ListDisplacement::getInstance()->clear(); ListDisplacement::getInstance()->clear();
ListSkinnedSolid::getInstance()->clear();
ListSkinnedAlphaRef::getInstance()->clear();
ListSkinnedNormalMap::getInstance()->clear();
ListSkinnedUnlit::getInstance()->clear();
ListMatDefault::getInstance()->clear(); ListMatDefault::getInstance()->clear();
ListMatAlphaRef::getInstance()->clear(); ListMatAlphaRef::getInstance()->clear();
ListMatSphereMap::getInstance()->clear(); ListMatSphereMap::getInstance()->clear();
@ -172,7 +181,8 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
if (node->isImmediateDraw()) if (node->isImmediateDraw())
{ {
ImmediateDraw->push_back(Node); if (!isCulledPrecise(cam, Node, irr_driver->getBoundingBoxesViz()))
ImmediateDraw->push_back(Node);
return; return;
} }
@ -243,8 +253,34 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT]) for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation()); 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]) 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) for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
{ {
if (CVS->supportsIndirectInstancingRendering()) 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_mesh = mesh;
m_glow_pass_mesh[mesh->mb].m_instance_settings 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) if (Mat == Material::SHADERTYPE_SPLATTING)
{ {
@ -267,15 +303,11 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
} }
else else
{ {
// Only take render info into account if the node is not static (animated) m_solid_pass_mesh[Mat][mesh->mb].m_mesh = mesh;
// So they can have different animation m_solid_pass_mesh[Mat][mesh->mb].m_instance_settings.emplace_back(Node, mesh->texture_trans,
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,
(mesh->m_render_info && mesh->m_material ? (mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : 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) 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: case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ? (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_mesh = mesh;
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings 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 else
@ -363,6 +417,22 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{ {
switch (Mat) 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: case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
break; 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_mesh = mesh;
m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings 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) 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: case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
break; break;
@ -551,7 +627,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
{ {
m_wind_dir = getWindDir(); m_wind_dir = getWindDir();
clearLists(); clearLists();
m_mesh_for_skinning.clear();
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat) for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
{ {
m_solid_pass_mesh[Mat].clear(); m_solid_pass_mesh[Mat].clear();
@ -569,6 +645,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
&m_immediate_draw_list, camnode, shadow_matrices); &m_immediate_draw_list, camnode, shadow_matrices);
PROFILER_POP_CPU_MARKER(); PROFILER_POP_CPU_MARKER();
irr_driver->setSkinningJoint(getSkinningOffset());
// Add a 1 s timeout // Add a 1 s timeout
if (!m_sync) if (!m_sync)
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
@ -689,6 +766,12 @@ void DrawCalls::drawIndirectSolidFirstPass() const
m_solid_cmd_buffer->drawIndirectFirstPass<GrassMat>(m_wind_dir); m_solid_cmd_buffer->drawIndirectFirstPass<GrassMat>(m_wind_dir);
m_solid_cmd_buffer->drawIndirectFirstPass<DetailMat>(); 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>();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -705,6 +788,12 @@ void DrawCalls::multidrawSolidFirstPass() const
m_solid_cmd_buffer->multidrawFirstPass<GrassMat>(m_wind_dir); m_solid_cmd_buffer->multidrawFirstPass<GrassMat>(m_wind_dir);
m_solid_cmd_buffer->multidrawFirstPass<NormalMat>(); 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<GrassMat>(prefilled_tex, m_wind_dir);
m_solid_cmd_buffer->drawIndirectSecondPass<DetailMat>(prefilled_tex); m_solid_cmd_buffer->drawIndirectSecondPass<DetailMat>(prefilled_tex);
m_solid_cmd_buffer->drawIndirectSecondPass<NormalMat>(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<NormalMat>(handles);
m_solid_cmd_buffer->multidraw2ndPass<DetailMat>(handles); m_solid_cmd_buffer->multidraw2ndPass<DetailMat>(handles);
m_solid_cmd_buffer->multidraw2ndPass<GrassMat>(handles, m_wind_dir); 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<NormalMat>(cascade);
m_shadow_cmd_buffer->drawIndirect<SplattingMat>(cascade); m_shadow_cmd_buffer->drawIndirect<SplattingMat>(cascade);
m_shadow_cmd_buffer->drawIndirect<SphereMap>(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<GrassMat,irr::core::vector3df>(cascade, m_wind_dir);
m_shadow_cmd_buffer->multidrawShadow<SplattingMat>(cascade); m_shadow_cmd_buffer->multidrawShadow<SplattingMat>(cascade);
m_shadow_cmd_buffer->multidrawShadow<SphereMap>(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 // !defined(USE_GLES2)
// ----------------------------------------------------------------------------
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 #endif // !SERVER_ONLY

View File

@ -19,13 +19,21 @@
#define HEADER_DRAW_CALLS_HPP #define HEADER_DRAW_CALLS_HPP
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
#include "graphics/command_buffer.hpp" #include "graphics/material.hpp"
#include "graphics/vao_manager.hpp"
#include <irrlicht.h> #include <irrlicht.h>
#include <set>
#include <unordered_map> #include <unordered_map>
class GlowCommandBuffer;
class ParticleSystemProxy; class ParticleSystemProxy;
class ReflectiveShadowMapCommandBuffer;
class ShadowMatrices; class ShadowMatrices;
class ShadowCommandBuffer;
class SolidCommandBuffer;
class STKAnimatedMesh;
class STKBillboard; class STKBillboard;
class STKMeshCommon;
class DrawCalls class DrawCalls
{ {
@ -37,14 +45,15 @@ private:
std::vector<irr::scene::ISceneNode *> m_immediate_draw_list; std::vector<irr::scene::ISceneNode *> m_immediate_draw_list;
std::vector<STKBillboard *> m_billboard_list; std::vector<STKBillboard *> m_billboard_list;
std::vector<ParticleSystemProxy *> m_particles_list; std::vector<ParticleSystemProxy *> m_particles_list;
std::set<STKAnimatedMesh*> m_mesh_for_skinning;
std::vector<float> m_bounding_boxes; std::vector<float> m_bounding_boxes;
/** meshes to draw */ /** meshes to draw */
SolidPassMeshMap m_solid_pass_mesh [ Material::SHADERTYPE_COUNT]; MeshMap m_solid_pass_mesh [ Material::SHADERTYPE_COUNT];
OtherMeshMap m_shadow_pass_mesh [4 * Material::SHADERTYPE_COUNT]; MeshMap m_shadow_pass_mesh [4 * Material::SHADERTYPE_COUNT];
OtherMeshMap m_reflective_shadow_map_mesh [ Material::SHADERTYPE_COUNT]; MeshMap m_reflective_shadow_map_mesh [ Material::SHADERTYPE_COUNT];
OtherMeshMap m_glow_pass_mesh; MeshMap m_glow_pass_mesh;
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
/** meshes data in VRAM */ /** meshes data in VRAM */
@ -106,6 +115,7 @@ public:
void drawIndirectGlow() const; void drawIndirectGlow() const;
void multidrawGlow() const; void multidrawGlow() const;
void renderBoundingBoxes(); void renderBoundingBoxes();
int32_t getSkinningOffset() const;
}; };
#endif // !SERVER_ONLY #endif // !SERVER_ONLY

View File

@ -18,6 +18,7 @@
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
#include "graphics/draw_policies.hpp" #include "graphics/draw_policies.hpp"
#include "graphics/draw_calls.hpp"
#include "graphics/draw_tools.hpp" #include "graphics/draw_tools.hpp"
#include "graphics/materials.hpp" #include "graphics/materials.hpp"
@ -185,6 +186,12 @@ void GL3DrawPolicy::drawSolidFirstPass(const DrawCalls& draw_calls) const
renderMeshes1stPass<NormalMat, 2, 1>(); renderMeshes1stPass<NormalMat, 2, 1>();
renderMeshes1stPass<SphereMap, 2, 1>(); renderMeshes1stPass<SphereMap, 2, 1>();
renderMeshes1stPass<DetailMat, 2, 1>(); renderMeshes1stPass<DetailMat, 2, 1>();
if (!CVS->supportsHardwareSkinning()) return;
renderMeshes1stPass<SkinnedSolid, 5, 2, 1>();
renderMeshes1stPass<SkinnedAlphaRef, 5, 3, 2, 1>();
renderMeshes1stPass<SkinnedUnlitMat, 5, 3, 2, 1>();
renderMeshes1stPass<SkinnedNormalMat, 5, 2, 1>();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -200,6 +207,12 @@ void GL3DrawPolicy::drawSolidSecondPass (const DrawCalls& draw_calls,
renderMeshes2ndPass<DetailMat, 1 > (handles, prefilled_tex); renderMeshes2ndPass<DetailMat, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<GrassMat, 4, 3, 1> (handles, prefilled_tex); renderMeshes2ndPass<GrassMat, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<NormalMat, 4, 3, 1> (handles, prefilled_tex); renderMeshes2ndPass<NormalMat, 4, 3, 1> (handles, prefilled_tex);
if (!CVS->supportsHardwareSkinning()) return;
renderMeshes2ndPass<SkinnedSolid, 5, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<SkinnedAlphaRef, 5, 4, 3, 1> (handles, prefilled_tex);
renderMeshes2ndPass<SkinnedUnlitMat, 5, 3, 1 > (handles, prefilled_tex);
renderMeshes2ndPass<SkinnedNormalMat, 5, 4, 3, 1> (handles, prefilled_tex);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -222,6 +235,12 @@ void GL3DrawPolicy::drawShadows(const DrawCalls& draw_calls, unsigned cascade) c
renderShadow<AlphaRef, 1>(cascade); renderShadow<AlphaRef, 1>(cascade);
renderShadow<UnlitMat, 1>(cascade); renderShadow<UnlitMat, 1>(cascade);
renderShadow<GrassMat, 3, 1>(cascade); renderShadow<GrassMat, 3, 1>(cascade);
if (!CVS->supportsHardwareSkinning()) return;
renderShadow<SkinnedSolid, 5, 1>(cascade);
renderShadow<SkinnedAlphaRef, 5, 1>(cascade);
renderShadow<SkinnedUnlitMat, 5, 1>(cascade);
renderShadow<SkinnedNormalMat, 5, 1>(cascade);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -270,12 +289,7 @@ void IndirectDrawPolicy::drawGlow(const DrawCalls& draw_calls,
const std::vector<GlowData>& glows) const const std::vector<GlowData>& glows) const
{ {
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
//to draw Glow with indirect commands, we also need GL_ARB_explicit_attrib_location extension draw_calls.drawIndirectGlow();
//TODO: add a way to render glow without explicit attrib
if(CVS->isARBExplicitAttribLocationUsable())
{
draw_calls.drawIndirectGlow();
}
#endif // !defined(USE_GLES2) #endif // !defined(USE_GLES2)
} }

Some files were not shown because too many files have changed in this diff Show More