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"/>
<snowtuxpeak goal="1"/>
<stk_enterprise goal="1"/>
<subsea goal="1"/>
<abyss goal="1"/>
<xr591 goal="1"/>
<zengarden goal="1"/>
</achievement>

View File

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

33
data/gfx/kart_exhaust.xml Normal file
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">
<track id="sandtrack" laps="3" reverse="false" />
<track id="farm" laps="3" reverse="false" />
<track id="olivermath" laps="4" reverse="false" />
<track id="abyss" laps="3" reverse="false" />
<track id="scotland" laps="3" reverse="false" />
<track id="sandtrack" laps="3" reverse="false" />
<track id="cornfield_crossing" laps="3" reverse="false" />
<track id="olivermath" laps="4" reverse="false" />
<track id="abyss" laps="3" reverse="false" />
<track id="scotland" laps="3" reverse="false" />
</supertuxkart_grand_prix>

View File

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

View File

@ -173,6 +173,14 @@
<gauge id="filtering" min_value="0" max_value="5" width="50%" />
</div>
<spacer height="4" width="10" />
<div layout="horizontal-row" width="100%" proportion="1">
<label text="Geometry detail" I18N="Video settings" width="40%"/>
<spacer width="10" height="10"/>
<gauge id="geometry_detail" min_value="0" max_value="2" width="50%" />
</div>
<spacer height="10" width="10" />
<label text="* Restart STK to apply new settings" width="100%" text_align="center" I18N="Video settings"/>

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
vec4 detail = texture(Detail, uv_bis);
color *= detail;
detail.xyz = pow(detail.xyz, vec3(2.2));
detail.rgb = detail.a * detail.rgb;
color.rgb = detail.rgb + color.rgb * (1. - detail.a);
float specmap = texture(SpecMap, uv).g;
FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
}

View File

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

View File

@ -1,15 +1,16 @@
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 5) in vec3 Tangent;
layout(location = 6) in vec3 Bitangent;
layout(location = 7) in vec3 Origin;
layout(location = 8) in vec3 Orientation;
layout(location = 9) in vec3 Scale;
layout(location = 15) in vec4 GlowColor;
layout(location = 10) in vec4 misc_data;
#else
in vec3 Position;
in vec3 Origin;
in vec3 Orientation;
in vec3 Scale;
in vec4 misc_data;
#endif
flat out vec4 glowColor;
#stk_include "utils/getworldmatrix.vert"
@ -19,5 +20,5 @@ void main(void)
mat4 ModelMatrix = getWorldMatrix(Origin, Orientation, Scale);
mat4 TransposeInverseModelView = transpose(getInverseWorldMatrix(Origin, Orientation, Scale) * InverseViewMatrix);
gl_Position = ProjectionViewMatrix * ModelMatrix * vec4(Position, 1.);
glowColor = GlowColor;
glowColor = misc_data;
}

View File

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

View File

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

View File

@ -29,6 +29,8 @@ void main(void)
vec4 detail = texture(Detail, uv_bis);
float specmap = texture(SpecMap, uv).g;
#endif
color *= detail;
detail.xyz = pow(detail.xyz, vec3(2.2));
detail.rgb = detail.a * detail.rgb;
color.rgb = detail.rgb + color.rgb * (1. - detail.a);
FragColor = vec4(getLightFactor(color.xyz, vec3(1.), specmap, 0.), 1.);
}

View File

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

View File

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

View File

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

View File

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

View File

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

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);
}
vec2 round(vec2 invec) {
return vec2(floor(abs(invec) + vec2(0.5)) * sign(invec));
}
vec2 Area(vec2 distance, float e1, float e2) {
// * By dividing by areaSize - 1.0 below we are implicitely offsetting to
// always fall inside of a pixel

View File

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

View File

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

View File

@ -14,7 +14,7 @@ void main(void)
float gz = int(gl_VertexID >> 9) & (resolution.z - 1);
uvw = vec3(gx, gy, gz) / vec3(resolution);
vec3 WorldPos = (2. * uvw - 1.) * extents;
gl_Position = ProjectionMatrix * ViewMatrix * RHMatrix * vec4(WorldPos, 1.);
gl_Position = ProjectionViewMatrix * RHMatrix * vec4(WorldPos, 1.);
gl_PointSize = 500. / gl_Position.w;
}

View File

@ -1,81 +1,80 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 the SuperTuxKart team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef GL_ES
uniform mat4 ModelMatrix;
uniform mat4 InverseModelMatrix;
uniform vec2 texture_trans;
#else
uniform mat4 ModelMatrix =
mat4(1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.);
uniform mat4 InverseModelMatrix =
mat4(1., 0., 0., 0.,
0., 1., 0., 0.,
0., 0., 1., 0.,
0., 0., 0., 1.);
// skinning.vert
#version 330 compatibility
#define MAX_JOINT_NUM 36
#define MAX_LIGHT_NUM 8
uniform vec2 texture_trans = vec2(0., 0.);
#endif
uniform int skinning_offset;
uniform mat4 JointTransform[MAX_JOINT_NUM];
#if __VERSION__ >= 330
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec4 Data1;
layout(location = 4) in vec4 Data2;
layout(location = 5) in ivec4 Joint;
layout(location = 6) in vec4 Weight;
#else
in vec3 Position;
in vec3 Normal;
in vec4 Color;
in vec4 Data1;
in vec4 Data2;
in ivec4 Joint;
in vec4 Weight;
#endif
void main()
out vec3 nor;
out vec3 tangent;
out vec3 bitangent;
out vec2 uv;
out vec4 color;
#stk_include "utils/getworldmatrix.vert"
void main(void)
{
int index;
vec4 ecPos;
vec3 normal;
vec3 light_dir;
float n_dot_l;
float dist;
mat4 TransposeInverseModelView = transpose(InverseModelMatrix * InverseViewMatrix);
vec4 idle_position = vec4(Position, 1.);
vec4 idle_normal = vec4(Normal, 0.);
vec4 idle_tangent = vec4(Data1.z, Data1.w, Data2.x, 0.);
vec4 idle_bitangent = vec4(Data2.y, Data2.z, Data2.w, 0.);
vec4 skinned_position = vec4(0.);
vec4 skinned_normal = vec4(0.);
vec4 skinned_tangent = vec4(0.);
vec4 skinned_bitangent = vec4(0.);
// Note : For normal we assume no scale factor in bone (otherwise we'll have to compute inversematrix for each bones...)
for (int i = 0; i < 4; i++)
{
vec4 single_bone_influenced_position = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_position;
single_bone_influenced_position /= single_bone_influenced_position.w;
vec4 single_bone_influenced_normal = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_normal;
vec4 single_bone_influenced_tangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_tangent;
vec4 single_bone_influenced_bitangent = joint_matrices[clamp(Joint[i] + skinning_offset, 0, MAX_BONES)] * idle_bitangent;
skinned_position += Weight[i] * single_bone_influenced_position;
skinned_normal += Weight[i] * single_bone_influenced_normal;
skinned_tangent += Weight[i] * single_bone_influenced_tangent;
skinned_bitangent += Weight[i] * single_bone_influenced_bitangent;
}
mat4 ModelTransform = gl_ModelViewProjectionMatrix;
index = int(gl_Color.r * 255.99);
mat4 vertTran = JointTransform[index - 1];
index = int(gl_Color.g * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
index = int(gl_Color.b * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
index = int(gl_Color.a * 255.99);
if(index > 0)
vertTran += JointTransform[index - 1];
ecPos = gl_ModelViewMatrix * vertTran * gl_Vertex;
normal = (vertTran * vec4(gl_Normal, 0.0)).xyz;
normal = normalize(gl_NormalMatrix * normal);
gl_FrontColor = vec4(0,0,0,0);
for(int i = 0;i < MAX_LIGHT_NUM;i++)
{
light_dir = vec3(gl_LightSource[i].position-ecPos);
n_dot_l = max(dot(normal, normalize(light_dir)), 0.0);
dist = length(light_dir);
n_dot_l *= 1.0 / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist);
gl_FrontColor += gl_LightSource[i].diffuse * n_dot_l;
}
gl_FrontColor = clamp(gl_FrontColor,0.3,1.0);
ModelTransform *= vertTran;
gl_Position = ModelTransform * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
/*
// Reflections.
vec3 r = reflect( ecPos.xyz , normal );
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
gl_TexCoord[1].s = r.x/m + 0.5;
gl_TexCoord[1].t = r.y/m + 0.5;
*/
gl_Position = ProjectionViewMatrix * ModelMatrix * skinned_position;
// Keep orthogonality
nor = (TransposeInverseModelView * skinned_normal).xyz;
// Keep direction
tangent = (ViewMatrix * ModelMatrix * skinned_tangent).xyz;
bitangent = (ViewMatrix * ModelMatrix * skinned_bitangent).xyz;
uv = vec2(Data1.x + texture_trans.x, Data1.y + texture_trans.y);
color = Color.zyxw;
}

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" />
<!-- Skidmark data: maximum number of skid marks, and
time for skidmarks to fade out. -->
<skid-marks max-number="100" fadeout-time="60"/>
time for skidmarks to fade out. Maximum number will over
current number of karts, so the more karts, the less
skidmark is on track. -->
<skid-marks max-number="500" fadeout-time="60"/>
<!-- Defines when the upright constraint should be active, it's
disabled when the kart is more than this value from the track. -->

View File

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

View File

@ -38,7 +38,8 @@
#include <stdlib.h>
#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ ) && !defined(__FreeBSD__)
#if !defined(__APPLE__) && !defined( __SNC__ ) && !defined( __ghs__ ) \
&& !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
#include <malloc.h>
#endif

View File

@ -78,8 +78,10 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
int getTriangleIndex() const
{
btAssert(isLeafNode());
unsigned int x = 0;
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
// Get only the lower bits where the triangle index is stored
return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
return (m_escapeIndexOrTriangleIndex&~(y));
}
int getPartId() const
{

View File

@ -30,6 +30,11 @@ if(APPLE)
endif()
add_definitions(-DNDEBUG=1 -DIRRLICHT_EXPORTS=1 -DPNG_THREAD_UNSAFE_OK -DPNG_NO_MMX_CODE -DPNG_NO_MNG_FEATURES)
if(UNIX OR MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
endif()
if(MSVC)
add_definitions(/D_IRR_STATIC_LIB_)
add_definitions(/D_CRT_SECURE_NO_WARNINGS) # Shut up about unsafe stuff
@ -59,7 +64,6 @@ endif()
set(IRRLICHT_SOURCES
source/Irrlicht/CAnimatedMeshSceneNode.cpp
source/Irrlicht/CAttributes.cpp
source/Irrlicht/CB3DMeshFileLoader.cpp
source/Irrlicht/CBillboardSceneNode.cpp
source/Irrlicht/CBoneSceneNode.cpp
source/Irrlicht/CCameraSceneNode.cpp
@ -187,11 +191,9 @@ source/Irrlicht/Irrlicht.cpp
source/Irrlicht/irrXML.cpp
source/Irrlicht/os.cpp
source/Irrlicht/COpenGLNormalMapRenderer.cpp
source/Irrlicht/BuiltInFont.h
source/Irrlicht/CAnimatedMeshSceneNode.h
source/Irrlicht/CAttributeImpl.h
source/Irrlicht/CAttributes.h
source/Irrlicht/CB3DMeshFileLoader.h
source/Irrlicht/CBillboardSceneNode.h
source/Irrlicht/CBlit.h
source/Irrlicht/CBoneSceneNode.h

View File

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

View File

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

View File

@ -178,6 +178,9 @@ namespace scene
\return The newly created clone of this node. */
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0) = 0;
virtual u32 getAnimationSetNum() = 0;
virtual void addAnimationSet(u32 start, u32 end) = 0;
virtual void useAnimationSet(u32 set_num) = 0;
};
} // end namespace scene

View File

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

View File

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

View File

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

View File

@ -104,6 +104,8 @@ public:
{
}
virtual ~ITexture() {}
//! Lock function.
/** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels
@ -190,6 +192,12 @@ public:
//! Get name of texture (in most cases this is the filename)
const io::SNamedPath& getName() const { return NamedPath; }
//! return open gl texture name
virtual u32 getOpenGLTextureName() const = 0;
virtual u64 getHandle() = 0;
virtual void unloadHandle() {}
protected:
//! Helper function, helps to get the desired texture creation format from the flags.

View File

@ -26,7 +26,9 @@ enum E_VERTEX_TYPE
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
/** Usually used for tangent space normal mapping. */
EVT_TANGENTS
EVT_TANGENTS,
EVT_SKINNED_MESH
};
//! Array holding the built in vertex type names
@ -251,6 +253,22 @@ struct S3DVertexTangents : public S3DVertex
}
};
struct S3DVertexSkinnedMesh : public S3DVertexTangents
{
s32 m_joint_idx1;
s32 m_joint_idx2;
s32 m_joint_idx3;
s32 m_joint_idx4;
f32 m_weight1;
f32 m_weight2;
f32 m_weight3;
f32 m_weight4;
E_VERTEX_TYPE getType() const
{
return EVT_SKINNED_MESH;
}
};
inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
@ -261,6 +279,8 @@ inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
return sizeof(video::S3DVertex2TCoords);
case video::EVT_TANGENTS:
return sizeof(video::S3DVertexTangents);
case video::EVT_SKINNED_MESH:
return sizeof(video::S3DVertexSkinnedMesh);
default:
return sizeof(video::S3DVertex);
}

View File

@ -50,6 +50,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return (video::S3DVertex*)&Vertices_2TCoords[index];
case video::EVT_TANGENTS:
return (video::S3DVertex*)&Vertices_Tangents[index];
case video::EVT_SKINNED_MESH:
return (video::S3DVertex*)&Vertices_SkinnedMesh[index];
default:
return &Vertices_Standard[index];
}
@ -64,6 +66,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.const_pointer();
case video::EVT_TANGENTS:
return Vertices_Tangents.const_pointer();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.const_pointer();
default:
return Vertices_Standard.const_pointer();
}
@ -78,6 +82,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.pointer();
case video::EVT_TANGENTS:
return Vertices_Tangents.pointer();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.pointer();
default:
return Vertices_Standard.pointer();
}
@ -92,6 +98,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords.size();
case video::EVT_TANGENTS:
return Vertices_Tangents.size();
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh.size();
default:
return Vertices_Standard.size();
}
@ -180,6 +188,20 @@ struct SSkinMeshBuffer : public IMeshBuffer
}
break;
}
case video::EVT_SKINNED_MESH:
{
if (Vertices_SkinnedMesh.empty())
BoundingBox.reset(0,0,0);
else
{
BoundingBox.reset(Vertices_SkinnedMesh[0].Pos);
for (u32 i=1; i<Vertices_SkinnedMesh.size(); ++i)
BoundingBox.addInternalPoint(Vertices_SkinnedMesh[i].Pos);
}
break;
}
default:
break;
}
}
@ -208,6 +230,54 @@ struct SSkinMeshBuffer : public IMeshBuffer
}
}
void convertForSkinning()
{
if (VertexType==video::EVT_STANDARD)
{
for(u32 n=0;n<Vertices_Standard.size();++n)
{
video::S3DVertexSkinnedMesh Vertex;
Vertex.Color=Vertices_Standard[n].Color;
Vertex.Pos=Vertices_Standard[n].Pos;
Vertex.Normal=Vertices_Standard[n].Normal;
Vertex.TCoords=Vertices_Standard[n].TCoords;
Vertex.Tangent=core::vector3df(0.0f, 0.0f, 0.0f);
Vertex.Binormal=core::vector3df(0.0f, 0.0f, 0.0f);
Vertex.m_joint_idx1 = 0;
Vertex.m_joint_idx2 = 0;
Vertex.m_joint_idx3 = 0;
Vertex.m_joint_idx4 = 0;
Vertex.m_weight1 = 0;
Vertex.m_weight2 = 0;
Vertex.m_weight3 = 0;
Vertex.m_weight4 = 0;
Vertices_SkinnedMesh.push_back(Vertex);
}
}
else if (VertexType==video::EVT_TANGENTS)
{
for(u32 n=0;n<Vertices_Tangents.size();++n)
{
video::S3DVertexSkinnedMesh Vertex;
Vertex.Color=Vertices_Tangents[n].Color;
Vertex.Pos=Vertices_Tangents[n].Pos;
Vertex.Normal=Vertices_Tangents[n].Normal;
Vertex.TCoords=Vertices_Tangents[n].TCoords;
Vertex.Tangent=Vertices_Tangents[n].Tangent;
Vertex.Binormal=Vertices_Tangents[n].Binormal;
Vertex.m_joint_idx1 = 0;
Vertex.m_joint_idx2 = 0;
Vertex.m_joint_idx3 = 0;
Vertex.m_joint_idx4 = 0;
Vertex.m_weight1 = 0;
Vertex.m_weight2 = 0;
Vertex.m_weight3 = 0;
Vertex.m_weight4 = 0;
Vertices_SkinnedMesh.push_back(Vertex);
}
}
}
//! Convert to tangents vertex type
virtual void convertToTangents()
{
@ -250,6 +320,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Pos;
default:
return Vertices_Standard[i].Pos;
}
@ -264,6 +336,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Pos;
default:
return Vertices_Standard[i].Pos;
}
@ -278,6 +352,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Normal;
default:
return Vertices_Standard[i].Normal;
}
@ -292,6 +368,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].Normal;
default:
return Vertices_Standard[i].Normal;
}
@ -306,6 +384,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].TCoords;
default:
return Vertices_Standard[i].TCoords;
}
@ -320,6 +400,8 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].TCoords;
case video::EVT_TANGENTS:
return Vertices_Tangents[i].TCoords;
case video::EVT_SKINNED_MESH:
return Vertices_SkinnedMesh[i].TCoords;
default:
return Vertices_Standard[i].TCoords;
}
@ -381,6 +463,7 @@ struct SSkinMeshBuffer : public IMeshBuffer
core::array<video::S3DVertexTangents> Vertices_Tangents;
core::array<video::S3DVertex2TCoords> Vertices_2TCoords;
core::array<video::S3DVertexSkinnedMesh> Vertices_SkinnedMesh;
core::array<video::S3DVertex> Vertices_Standard;
core::array<u16> Indices;

View File

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

View File

@ -394,10 +394,17 @@ public:
void sort()
{
if (!is_sorted && used>1)
heapsort(data, used);
heapsort(data, used, sortless<T>);
is_sorted = true;
}
template<class Compare>
void sort(Compare cmp)
{
if (!is_sorted && used>1)
heapsort(data, used, cmp);
is_sorted = true;
}
//! Performs a binary search for an element, returns -1 if not found.
/** The array will be sorted before the binary search if it is not

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -178,7 +178,7 @@ void CAnimatedMeshSceneNode::OnRegisterSceneNode()
}
}
IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame(SkinningCallback sc, int offset)
{
if(Mesh->getMeshType() != EAMT_SKINNED)
{
@ -203,7 +203,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame()
skinnedMesh->animateMesh(getFrameNr(), 1.0f);
// Update the skinned mesh for the current joint transforms.
skinnedMesh->skinMesh(AnimationStrength);
skinnedMesh->skinMesh(AnimationStrength, sc, offset);
if (JointMode == EJUOR_READ)//read from mesh
{
@ -992,6 +992,15 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
return newNode;
}
void CAnimatedMeshSceneNode::useAnimationSet(u32 set_num)
{
if (m_animation_set.empty())
{
setFrameLoop(getStartFrame(), getEndFrame());
return;
}
setFrameLoop(m_animation_set[set_num * 2], m_animation_set[set_num * 2 + 1]);
}
} // end namespace scene
} // end namespace irr

View File

@ -19,6 +19,8 @@ namespace scene
class CAnimatedMeshSceneNode : public IAnimatedMeshSceneNode
{
private:
core::array<u32> m_animation_set;
public:
//! constructor
@ -158,10 +160,18 @@ namespace scene
\return The newly created clone of this node. */
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0);
virtual u32 getAnimationSetNum() { return m_animation_set.size() / 2; }
virtual void addAnimationSet(u32 start, u32 end)
{
m_animation_set.push_back(start);
m_animation_set.push_back(end);
}
virtual void useAnimationSet(u32 set_num);
protected:
//! Get a static mesh for the current frame of this animated mesh
IMesh* getMeshForCurrentFrame();
virtual IMesh* getMeshForCurrentFrame(SkinningCallback sc = NULL, int offset = -1);
void buildFrameNr(u32 timeMs);
void checkJoints();

File diff suppressed because it is too large Load Diff

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 "IXMLWriter.h"
#include "BuiltInFont.h"
#include "os.h"
namespace irr
@ -78,8 +77,6 @@ CGUIEnvironment::CGUIEnvironment(io::IFileSystem* fs, video::IVideoDriver* drive
registerGUIElementFactory(factory);
factory->drop();
loadBuiltInFont();
IGUISkin* skin = createSkin( gui::EGST_WINDOWS_METALLIC );
setSkin(skin);
skin->drop();
@ -165,29 +162,6 @@ CGUIEnvironment::~CGUIEnvironment()
}
}
void CGUIEnvironment::loadBuiltInFont()
{
io::IReadFile* file = io::createMemoryReadFile(BuiltInFontData, BuiltInFontDataSize, DefaultFontName, false);
CGUIFont* font = new CGUIFont(this, DefaultFontName );
if (!font->load(file))
{
os::Printer::log("Error: Could not load built-in Font. Did you compile without the BMP loader?", ELL_ERROR);
font->drop();
file->drop();
return;
}
SFont f;
f.NamedPath.setPath(DefaultFontName);
f.Font = font;
Fonts.push_back(f);
file->drop();
}
//! draws all gui elements
void CGUIEnvironment::drawAll()
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,10 +24,6 @@
#include "CSkinnedMesh.h"
#endif
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
#include "CB3DMeshFileLoader.h"
#endif
#include "CCubeSceneNode.h"
#include "CSphereSceneNode.h"
#include "CAnimatedMeshSceneNode.h"
@ -121,13 +117,6 @@ CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
// create geometry creator
GeometryCreator = new CGeometryCreator();
// add file format loaders. add the least commonly used ones first,
// as these are checked last
#ifdef _IRR_COMPILE_WITH_B3D_LOADER_
MeshLoaderList.push_back(new CB3DMeshFileLoader(this));
#endif
// factories
ISceneNodeFactory* factory = new CDefaultSceneNodeFactory(this);
registerSceneNodeFactory(factory);
@ -1427,11 +1416,6 @@ void CSceneManager::drawAll(u32 flags)
void CSceneManager::setLightManager(ILightManager* lightManager)
{
if (lightManager)
lightManager->grab();
if (LightManager)
LightManager->drop();
LightManager = lightManager;
}

View File

@ -9,6 +9,7 @@
#include "CBoneSceneNode.h"
#include "IAnimatedMeshSceneNode.h"
#include "os.h"
#include "irrMap.h"
namespace irr
{
@ -22,12 +23,12 @@ CSkinnedMesh::CSkinnedMesh()
LastAnimatedFrame(-1), SkinnedLastFrame(false),
InterpolationMode(EIM_LINEAR),
HasAnimation(false), PreparedForSkinning(false),
AnimateNormals(true), HardwareSkinning(false)
AnimateNormals(true), HardwareSkinning(false), m_total_joints(0),
m_current_joint(0)
{
#ifdef _DEBUG
setDebugName("CSkinnedMesh");
#endif
SkinningBuffers=&LocalBuffers;
}
@ -74,12 +75,19 @@ void CSkinnedMesh::setAnimationSpeed(f32 fps)
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{
const bool is_hw_skinning_before = HardwareSkinning;
if (is_hw_skinning_before)
HardwareSkinning = false;
//animate(frame,startFrameLoop, endFrameLoop);
if (frame==-1)
return this;
animateMesh((f32)frame, 1.0f);
skinMesh();
if (is_hw_skinning_before)
HardwareSkinning = true;
return this;
}
@ -93,6 +101,12 @@ IMesh* CSkinnedMesh::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32
//! blend: {0-old position, 1-New position}
void CSkinnedMesh::animateMesh(f32 frame, f32 blend)
{
if (HardwareSkinning && LastAnimatedFrame==frame)
{
SkinnedLastFrame=false;
return;
}
if (!HasAnimation || LastAnimatedFrame==frame)
return;
@ -445,7 +459,7 @@ void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint,
//--------------------------------------------------------------------------
//! Preforms a software skin on this mesh based of joint positions
void CSkinnedMesh::skinMesh(f32 strength)
void CSkinnedMesh::skinMesh(f32 strength, SkinningCallback sc, int offset)
{
if (!HasAnimation || SkinnedLastFrame)
return;
@ -456,7 +470,13 @@ void CSkinnedMesh::skinMesh(f32 strength)
//-----------------
SkinnedLastFrame=true;
if (!HardwareSkinning)
m_current_joint = 0;
if (HardwareSkinning)
{
for (u32 i = 0; i < RootJoints.size(); i++)
skinJoint(RootJoints[i], 0, strength, sc, offset);
}
else
{
//Software skin....
u32 i;
@ -486,65 +506,73 @@ void CSkinnedMesh::skinMesh(f32 strength)
updateBoundingBox();
}
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength)
void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength,
SkinningCallback sc, int offset)
{
if (joint->Weights.size())
{
//Find this joints pull on vertices...
core::matrix4 jointVertexPull(core::matrix4::EM4CONST_NOTHING);
jointVertexPull.setbyproduct(joint->GlobalAnimatedMatrix, joint->GlobalInversedMatrix);
core::vector3df thisVertexMove, thisNormalMove;
core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
//Skin Vertices Positions and Normals...
for (u32 i=0; i<joint->Weights.size(); ++i)
if (HardwareSkinning)
{
SWeight& weight = joint->Weights[i];
if (sc != NULL) sc(jointVertexPull, m_current_joint, offset);
m_current_joint++;
}
else
{
core::vector3df thisVertexMove, thisNormalMove;
// Pull this vertex...
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
core::array<scene::SSkinMeshBuffer*> &buffersUsed=*SkinningBuffers;
if (AnimateNormals)
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal);
// Apply animation strength
if(strength != 1.f)
//Skin Vertices Positions and Normals...
for (u32 i=0; i<joint->Weights.size(); ++i)
{
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength);
if(AnimateNormals)
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
}
SWeight& weight = joint->Weights[i];
if (! (*(weight.Moved)) )
{
*(weight.Moved) = true;
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength;
// Pull this vertex...
jointVertexPull.transformVect(thisVertexMove, weight.StaticPos);
if (AnimateNormals)
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = thisNormalMove * weight.strength;
jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal);
//*(weight._Pos) = thisVertexMove * weight.strength;
// Apply animation strength
if(strength != 1.f)
{
thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength);
if(AnimateNormals)
thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength);
}
if (! (*(weight.Moved)) )
{
*(weight.Moved) = true;
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos = thisVertexMove * weight.strength;
if (AnimateNormals)
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal = thisNormalMove * weight.strength;
//*(weight._Pos) = thisVertexMove * weight.strength;
}
else
{
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += thisVertexMove * weight.strength;
if (AnimateNormals)
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += thisNormalMove * weight.strength;
//*(weight._Pos) += thisVertexMove * weight.strength;
}
buffersUsed[weight.buffer_id]->boundingBoxNeedsRecalculated();
}
else
{
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Pos += thisVertexMove * weight.strength;
if (AnimateNormals)
buffersUsed[weight.buffer_id]->getVertex(weight.vertex_id)->Normal += thisNormalMove * weight.strength;
//*(weight._Pos) += thisVertexMove * weight.strength;
}
buffersUsed[weight.buffer_id]->boundingBoxNeedsRecalculated();
}
}
//Skin all children
for (u32 j=0; j<joint->Children.size(); ++j)
skinJoint(joint->Children[j], joint, strength);
skinJoint(joint->Children[j], joint, strength, sc, offset);
}
@ -724,28 +752,28 @@ bool CSkinnedMesh::setHardwareSkinning(bool on)
if (HardwareSkinning!=on)
{
if (on)
{
//set mesh to static pose...
for (u32 i=0; i<AllJoints.size(); ++i)
{
SJoint *joint=AllJoints[i];
for (u32 j=0; j<joint->Weights.size(); ++j)
{
const u16 buffer_id=joint->Weights[j].buffer_id;
const u32 vertex_id=joint->Weights[j].vertex_id;
LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated();
}
}
}
toStaticPose();
HardwareSkinning=on;
}
return HardwareSkinning;
}
void CSkinnedMesh::toStaticPose()
{
for (u32 i=0; i<AllJoints.size(); ++i)
{
SJoint *joint=AllJoints[i];
for (u32 j=0; j<joint->Weights.size(); ++j)
{
const u16 buffer_id=joint->Weights[j].buffer_id;
const u32 vertex_id=joint->Weights[j].vertex_id;
LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
LocalBuffers[buffer_id]->boundingBoxNeedsRecalculated();
}
}
}
void CSkinnedMesh::calculateGlobalMatrices(SJoint *joint,SJoint *parentJoint)
{
@ -1139,7 +1167,7 @@ void CSkinnedMesh::finalize()
void CSkinnedMesh::updateBoundingBox(void)
{
if(!SkinningBuffers)
if(HardwareSkinning || !SkinningBuffers)
return;
core::array<SSkinMeshBuffer*> & buffer = *SkinningBuffers;
@ -1382,26 +1410,137 @@ void CSkinnedMesh::addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
SkinnedLastFrame=false;
}
void CSkinnedMesh::convertMeshToTangents()
bool CSkinnedMesh::sortJointInfluenceFunc(const JointInfluence& a,
const JointInfluence& b)
{
// now calculate tangents
for (u32 b=0; b < LocalBuffers.size(); ++b)
return a.weight > b.weight;
}
void CSkinnedMesh::convertForSkinning()
{
if (HardwareSkinning) return;
setHardwareSkinning(true);
WeightInfluence wi;
for (u32 b = 0; b < LocalBuffers.size(); b++)
{
if (LocalBuffers[b])
LocalBuffers[b]->convertForSkinning();
wi.push_back(core::array<core::array<JointInfluence> > ());
for (u32 i = 0; i < LocalBuffers[b]->getVertexCount(); i++)
wi[b].push_back(core::array<JointInfluence>());
}
size_t idx = 0;
for (u32 i = 0; i < RootJoints.size(); i++)
computeWeightInfluence(RootJoints[i], idx, wi);
for (u32 b = 0; b < LocalBuffers.size(); b++)
{
if (LocalBuffers[b])
{
LocalBuffers[b]->convertToTangents();
const u32 total = wi[b].size();
_IRR_DEBUG_BREAK_IF(LocalBuffers[b]->getVertexCount() != total);
for (u32 i = 0; i < total; i++)
{
core::array<JointInfluence> this_influence;
core::array<JointInfluence> reported_weight = wi[b][i];
reported_weight.sort(sortJointInfluenceFunc);
float remaining_weight = 1.0f;
for (u32 j = 0; j < 4; j++)
{
JointInfluence influence;
if (reported_weight.size() > j)
influence = reported_weight[j];
else
{
influence.joint_idx = -100000;
influence.weight = remaining_weight;
}
remaining_weight -= influence.weight;
this_influence.push_back(influence);
}
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx1 = this_influence[0].joint_idx;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx2 = this_influence[1].joint_idx;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx3 = this_influence[2].joint_idx;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_joint_idx4 = this_influence[3].joint_idx;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight1 = this_influence[0].weight;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight2 = this_influence[1].weight;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight3 = this_influence[2].weight;
LocalBuffers[b]->Vertices_SkinnedMesh[i].m_weight4 = this_influence[3].weight;
}
}
}
SkinnedLastFrame = false;
skinMesh();
m_total_joints = m_current_joint;
}
const s32 idxCnt = LocalBuffers[b]->getIndexCount();
void CSkinnedMesh::computeWeightInfluence(SJoint *joint, size_t &index, WeightInfluence& wi)
{
if (!joint->Weights.empty())
{
for (u32 i = 0; i < joint->Weights.size(); i++)
{
SWeight& weight = joint->Weights[i];
JointInfluence tmp;
tmp.joint_idx = index;
tmp.weight = weight.strength;
wi[weight.buffer_id][weight.vertex_id].push_back(tmp);
}
index++;
}
u16* idx = LocalBuffers[b]->getIndices();
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)LocalBuffers[b]->getVertices();
for (u32 j = 0; j < joint->Children.size(); j++)
computeWeightInfluence(joint->Children[j], index, wi);
}
for (s32 i=0; i<idxCnt; i+=3)
void CSkinnedMesh::convertMeshToTangents(bool(*predicate)(IMeshBuffer*))
{
bool recalculate_animation = false;
toStaticPose();
for (u32 b = 0; b < LocalBuffers.size(); b++)
{
bool recalculate_joints = false;
core::map<u32, u32> vert_loc_map;
SSkinMeshBuffer* ssmb = LocalBuffers[b];
if (ssmb)
{
if (!predicate(ssmb)) continue;
recalculate_joints = true;
recalculate_animation = true;
core::map<video::S3DVertexTangents, u32> vert_map;
core::array<u16> tmp_indices;
for (u32 i = 0; i < ssmb->Indices.size(); i++)
{
u32 vert_location = 0;
const u32 cur_ver_loc = ssmb->Indices[i];
const video::S3DVertex& v_old = ssmb->Vertices_Standard[cur_ver_loc];
video::S3DVertexTangents v(v_old.Pos, v_old.Normal, v_old.Color, v_old.TCoords);
core::map<video::S3DVertexTangents, u32>::Node *n = vert_map.find(v);
if (n)
{
vert_location = n->getValue();
}
else
{
vert_location = ssmb->Vertices_Tangents.size();
ssmb->Vertices_Tangents.push_back(v);
vert_map.insert(v, vert_location);
}
vert_loc_map[cur_ver_loc] = vert_location;
tmp_indices.push_back(vert_location);
}
const s32 index_count = tmp_indices.size();
u16* idx = tmp_indices.pointer();
video::S3DVertexTangents* v = ssmb->Vertices_Tangents.pointer();
core::vector3df local_normal;
for (s32 i = 0; i < index_count; i += 3)
{
calculateTangents(
v[idx[i+0]].Normal,
local_normal,
v[idx[i+0]].Tangent,
v[idx[i+0]].Binormal,
v[idx[i+0]].Pos,
@ -1412,7 +1551,7 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+2]].TCoords);
calculateTangents(
v[idx[i+1]].Normal,
local_normal,
v[idx[i+1]].Tangent,
v[idx[i+1]].Binormal,
v[idx[i+1]].Pos,
@ -1423,7 +1562,7 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+0]].TCoords);
calculateTangents(
v[idx[i+2]].Normal,
local_normal,
v[idx[i+2]].Tangent,
v[idx[i+2]].Binormal,
v[idx[i+2]].Pos,
@ -1433,11 +1572,38 @@ void CSkinnedMesh::convertMeshToTangents()
v[idx[i+0]].TCoords,
v[idx[i+1]].TCoords);
}
ssmb->Indices = tmp_indices;
ssmb->Vertices_Standard.clear();
ssmb->VertexType = video::EVT_TANGENTS;
}
if (recalculate_joints)
{
Vertices_Moved[b].set_used(ssmb->getVertexCount());
for (u32 i = 0; i < AllJoints.size(); i++)
{
SJoint *joint = AllJoints[i];
for (u32 j = 0; j <joint->Weights.size(); j++)
{
if (joint->Weights[j].buffer_id == b)
{
core::map<u32, u32>::Node *n =
vert_loc_map.find(joint->Weights[j].vertex_id);
if (n)
{
joint->Weights[j].vertex_id = n->getValue();
}
}
}
}
}
}
if (recalculate_animation)
{
PreparedForSkinning = false;
checkForAnimation();
}
}
void CSkinnedMesh::calculateTangents(
core::vector3df& normal,
core::vector3df& tangent,

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -3,4 +3,4 @@
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")
file(GLOB_RECURSE STK_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${PROJECT_BINARY_DIR}/tmp/*.rc")

View File

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

View File

@ -279,6 +279,16 @@ enum AnimType {ANIMS_NONE = 0,
ANIMS_PLAYERS_ONLY = 1,
ANIMS_ALL = 2 };
enum GeometryLevel
{
/** Display everything */
GEOLEVEL_0 = 0,
/** a few details are displayed */
GEOLEVEL_1 = 1,
/** Lowest level, no details are displayed. */
GEOLEVEL_2 = 2
};
/** Using X-macros for setting-possible values is not very pretty, but it's a
* no-maintenance case :
* when you want to add a new parameter, just add one signle line below and
@ -410,13 +420,18 @@ namespace UserConfigParams
&m_multitouch_group,
"A parameter in range [0, 0.5] that determines the zone that is "
"considered as max value in steering button."));
PARAM_PREFIX FloatUserConfigParam m_multitouch_scale
PARAM_DEFAULT( FloatUserConfigParam(1.0f, "multitouch_scale",
&m_multitouch_group,
"A parameter in range [0.5, 1.5] that determines the scale of the "
"multitouch interface."));
PARAM_PREFIX BoolUserConfigParam m_screen_keyboard
PARAM_DEFAULT( BoolUserConfigParam(false, "screen_keyboard",
&m_multitouch_group,
"Enable screen keyboard.") );
// ---- GP start order
PARAM_PREFIX GroupUserConfigParam m_gp_start_order
PARAM_DEFAULT( GroupUserConfigParam("GpStartOrder",
@ -481,7 +496,7 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_texture_compression
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
&m_video_group, "Enable Texture Compression"));
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
/** This is a bit flag: bit 0: enabled (1) or disabled(0).
* Bit 1: setting done by default(0), or by user choice (2). This allows
* to e.g. disable h.d. textures on hd3000 as default, but still allow the
* user to enable it. */
@ -583,6 +598,8 @@ namespace UserConfigParams
PARAM_PREFIX bool m_race_now PARAM_DEFAULT( false );
PARAM_PREFIX bool m_enforce_current_player PARAM_DEFAULT( false );
/** True to test funky ambient/diffuse/specularity in RGB &
* all anisotropic */
PARAM_PREFIX bool m_rendering_debug PARAM_DEFAULT( false );
@ -673,6 +690,13 @@ namespace UserConfigParams
"steering_animations", &m_graphics_quality,
"Whether to display kart animations (0=disabled for all; "
"1=enabled for humans, disabled for AIs; 2=enabled for all") );
PARAM_PREFIX IntUserConfigParam m_geometry_level
PARAM_DEFAULT( IntUserConfigParam(GEOLEVEL_0,
"geometry_level", &m_graphics_quality,
"Geometry quality 0=everything is displayed; "
"1=a few details are displayed; 2=lowest level, no details") );
PARAM_PREFIX IntUserConfigParam m_anisotropic
PARAM_DEFAULT( IntUserConfigParam(4, "anisotropic",
&m_graphics_quality,
@ -892,6 +916,10 @@ namespace UserConfigParams
PARAM_DEFAULT( BoolUserConfigParam(false, "artist_debug_mode",
"Whether to enable track debugging features") );
PARAM_PREFIX BoolUserConfigParam m_everything_unlocked
PARAM_DEFAULT( BoolUserConfigParam(false, "everything_unlocked",
"Enable all karts and tracks") );
// TODO? implement blacklist for new irrlicht device and GUI
PARAM_PREFIX std::vector<std::string> m_blacklist_res;

View File

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

View File

@ -22,7 +22,10 @@
#include "font/font_manager.hpp"
#include "font/font_settings.hpp"
#include "graphics/2dutils.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/skin.hpp"
#include "utils/string_utils.hpp"
@ -50,8 +53,11 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
*/
FontWithFace::~FontWithFace()
{
m_page->drop();
m_page = NULL;
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
{
STKTexManager::getInstance()->removeTexture(
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
}
m_spritebank->drop();
m_spritebank = NULL;
@ -66,9 +72,6 @@ FontWithFace::~FontWithFace()
void FontWithFace::init()
{
setDPI();
m_page = irr_driver->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
core::dimension2du(getGlyphPageSize(), getGlyphPageSize()));
// Get the max height for this face
assert(m_face_ttf->getTotalFaces() > 0);
FT_Face cur_face = m_face_ttf->getFace(0);
@ -100,6 +103,11 @@ void FontWithFace::reset()
m_new_char_holder.clear();
m_character_area_map.clear();
m_character_glyph_info_map.clear();
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
{
STKTexManager::getInstance()->removeTexture(
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
}
m_spritebank->clear();
createNewGlyphPage();
} // reset
@ -129,32 +137,25 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
*/
void FontWithFace::createNewGlyphPage()
{
m_page->fill(video::SColor(0, 255, 255, 255));
#ifndef SERVER_ONLY
uint8_t* data = new uint8_t[getGlyphPageSize() * getGlyphPageSize() *
(CVS->isARBTextureSwizzleUsable() ? 1 : 4)]();
#else
uint8_t* data = NULL;
#endif
m_current_height = 0;
m_used_width = 0;
m_used_height = 0;
// Font textures can not be resized (besides the impact on quality in
// this case, the rectangles in spritebank would become wrong).
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page);
m_spritebank->addTexture(NULL);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
// Doing so to make sure the texture inside the sprite bank has only 1
// reference, so they can be removed or updated on-the-fly
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
STKTexture* stkt = new STKTexture(data, typeid(*this).name() +
StringUtils::toString(m_spritebank->getTextureCount()),
getGlyphPageSize(),
#ifndef SERVER_ONLY
CVS->isARBTextureSwizzleUsable()
#else
false
#endif
);
m_spritebank->addTexture(STKTexManager::getInstance()->addTexture(stkt));
} // createNewGlyphPage
// ----------------------------------------------------------------------------
@ -184,80 +185,17 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
"rendering a glyph to bitmap");
// Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap;
core::dimension2du d(bits.width + 1, bits.rows + 1);
core::dimension2du texture_size;
texture_size = d.getOptimalSize(!(irr_driver->getVideoDriver()
->queryFeature(video::EVDF_TEXTURE_NPOT)), !(irr_driver
->getVideoDriver()->queryFeature(video::EVDF_TEXTURE_NSQUARE)),
true, 0);
FT_Bitmap* bits = &(slot->bitmap);
core::dimension2du texture_size(bits->width + 1, bits->rows + 1);
if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
m_used_height + m_current_height + texture_size.Height >
getGlyphPageSize()) ||
m_used_height + texture_size.Height > getGlyphPageSize())
{
// Current glyph page is full:
// Save the old glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d
("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
// Clear and add a new one
// Add a new glyph page if current one is full
createNewGlyphPage();
}
video::IImage* glyph = NULL;
switch (bits.pixel_mode)
{
case FT_PIXEL_MODE_GRAY:
{
// Create our blank image.
glyph = irr_driver->getVideoDriver()
->createImage(video::ECF_A8R8G8B8, texture_size);
glyph->fill(video::SColor(0, 255, 255, 255));
// Load the grayscale data in.
const float gray_count = static_cast<float>(bits.num_grays);
const unsigned int image_pitch =
glyph->getPitch() / sizeof(unsigned int);
unsigned int* image_data = (unsigned int*)glyph->lock();
unsigned char* glyph_data = bits.buffer;
for (unsigned int y = 0; y < (unsigned int)bits.rows; y++)
{
unsigned char* row = glyph_data;
for (unsigned int x = 0; x < (unsigned)bits.width; x++)
{
image_data[y * image_pitch + x] |=
static_cast<unsigned int>(255.0f *
(static_cast<float>(*row++) / gray_count)) << 24;
}
glyph_data += bits.pitch;
}
glyph->unlock();
break;
}
default:
assert(false);
}
if (!glyph)
Log::fatal("FontWithFace", "Failed to load a glyph");
// Done creating a single glyph, now copy to the glyph page...
// Determine the linebreak location
if (m_used_width + texture_size.Width > getGlyphPageSize())
{
@ -266,16 +204,39 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
m_current_height = 0;
}
// Copy to the full glyph page
glyph->copyTo(m_page, core::position2di(m_used_width, m_used_height));
const unsigned int cur_tex = m_spritebank->getTextureCount() -1;
#ifndef SERVER_ONLY
video::ITexture* tex = m_spritebank->getTexture(cur_tex);
glBindTexture(GL_TEXTURE_2D, tex->getOpenGLTextureName());
assert(bits->pixel_mode == FT_PIXEL_MODE_GRAY);
if (CVS->isARBTextureSwizzleUsable())
{
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
bits->width, bits->rows, GL_RED, GL_UNSIGNED_BYTE, bits->buffer);
}
else
{
const unsigned int size = bits->width * bits->rows;
uint8_t* image_data = new uint8_t[size * 4];
memset(image_data, 255, size * 4);
for (unsigned int i = 0; i < size; i++)
image_data[4 * i + 3] = bits->buffer[i];
glTexSubImage2D(GL_TEXTURE_2D, 0, m_used_width, m_used_height,
bits->width, bits->rows, GL_BGRA, GL_UNSIGNED_BYTE, image_data);
delete[] image_data;
}
if (tex->hasMipMaps())
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
#endif
// Store the rectangle of current glyph
gui::SGUISpriteFrame f;
gui::SGUISprite s;
core::rect<s32> rectangle(m_used_width, m_used_height,
m_used_width + bits.width, m_used_height + bits.rows);
m_used_width + bits->width, m_used_height + bits->rows);
f.rectNumber = m_spritebank->getPositions().size();
f.textureNumber = m_spritebank->getTextureCount() - 1;
f.textureNumber = cur_tex;
// Add frame to sprite
s.Frames.push_back(f);
@ -295,10 +256,6 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
a.spriteno = f.rectNumber;
m_character_area_map[c] = a;
// Clean the temporary glyph
glyph->drop();
glyph = NULL;
// Store used area
m_used_width += texture_size.Width;
if (m_current_height < texture_size.Height)
@ -321,23 +278,6 @@ void FontWithFace::updateCharactersList()
}
m_new_char_holder.clear();
// Update last glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // updateCharactersList
// ----------------------------------------------------------------------------
@ -353,10 +293,9 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
core::dimension2d<u32> size = tex->getSize();
video::ECOLOR_FORMAT col_format = tex->getColorFormat();
void* data = tex->lock();
video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(col_format, size, data, false/*copy mem*/);
->createImageFromData(col_format, size, data,
true/*ownForeignMemory*/);
tex->unlock();
irr_driver->getVideoDriver()->writeImageToFile(image, std::string
(name + "_" + StringUtils::toString(i) + ".png").c_str());
@ -618,28 +557,6 @@ void FontWithFace::render(const core::stringw& text,
}
else
{
// Prevent overwriting texture used by billboard text when
// using lazy loading characters
if (supportLazyLoadChar() && fallback[i])
{
const int cur_texno = m_fallback_font->getSpriteBank()
->getSprites()[area.spriteno].Frames[0].textureNumber;
if (cur_texno == int(m_fallback_font->getSpriteBank()
->getTextureCount() - 1))
{
m_fallback_font->createNewGlyphPage();
}
}
else if (supportLazyLoadChar())
{
const int cur_texno = m_spritebank
->getSprites()[area.spriteno].Frames[0].textureNumber;
if (cur_texno == int(m_spritebank->getTextureCount() - 1))
{
createNewGlyphPage();
}
}
// Billboard text specific, use offset_y_bt instead
float glyph_offset_x = area.bearing_x *
(fallback[i] ? m_fallback_font_scale : scale);

View File

@ -92,6 +92,39 @@ protected:
/** Used in top side bearing calculation. */
int m_glyph_max_height;
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
/** Set the fallback font for this font, so if some character is missing in
* this font, it will use that fallback font to try rendering it.
@ -129,9 +162,6 @@ private:
/** Sprite bank to store each glyph. */
gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font. */
video::IImage* m_page;
/** The current max height at current drawing line in glyph page. */
unsigned int m_current_height;
@ -206,6 +236,8 @@ private:
// ------------------------------------------------------------------------
void loadGlyphInfo(wchar_t c);
// ------------------------------------------------------------------------
void createNewGlyphPage();
// ------------------------------------------------------------------------
/** Add a character into \ref m_new_char_holder for lazy loading later. */
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
// ------------------------------------------------------------------------
@ -213,6 +245,9 @@ private:
// ------------------------------------------------------------------------
void setDPI();
// ------------------------------------------------------------------------
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Defined by sub-class about the texture size of glyph page, it should be
* a power of two. */
virtual unsigned int getGlyphPageSize() const = 0;
@ -266,44 +301,6 @@ public:
// ------------------------------------------------------------------------
/** Return the dpi of this face. */
unsigned int getDPI() const { return m_face_dpi; }
// ------------------------------------------------------------------------
/** Override it if sub-class should not do lazy loading characters. */
virtual bool supportLazyLoadChar() const { return true; }
// ------------------------------------------------------------------------
/** Check characters to see if they are loaded in font, if not load them.
* For font that doesn't need lazy loading, nothing will be done.
* \param in_ptr Characters to check.
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
* which is called in \ref reset. */
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
{
if (!supportLazyLoadChar() && !first_load) return;
for (const wchar_t* p = in_ptr; *p; ++p)
{
if (*p == L'\r' || *p == L'\n' || *p < (wchar_t)32)
continue;
if (!loadedChar(*p))
{
loadGlyphInfo(*p);
if (supportChar(*p))
addLazyLoadChar(*p);
else if (m_fallback_font != NULL)
{
if (!m_fallback_font->loadedChar(*p))
{
m_fallback_font->loadGlyphInfo(*p);
if (m_fallback_font->supportChar(*p))
m_fallback_font->addLazyLoadChar(*p);
}
}
}
}
}
// ------------------------------------------------------------------------
void updateCharactersList();
// ------------------------------------------------------------------------
void createNewGlyphPage();
}; // FontWithFace

View File

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

View File

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

View File

@ -51,6 +51,7 @@ void CentralVideoSettings::init()
hasExplicitAttribLocation = false;
hasGS = false;
hasTextureFilterAnisotropic = false;
hasTextureSwizzle = false;
#if defined(USE_GLES2)
hasBGRA = false;
@ -90,6 +91,11 @@ void CentralVideoSettings::init()
std::string driver((char*)(glGetString(GL_VERSION)));
std::string card((char*)(glGetString(GL_RENDERER)));
GraphicsRestrictions::init(driver, card);
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
{
m_glsl = false;
}
#if !defined(USE_GLES2)
if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
@ -158,9 +164,12 @@ void CentralVideoSettings::init()
Log::info("GLDriver", "ARB Multi Draw Indirect Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_EXT_TEXTURE_COMPRESSION_S3TC) &&
hasGLExtension("GL_EXT_texture_compression_s3tc")) {
hasGLExtension("GL_EXT_texture_compression_s3tc") &&
hasGLExtension("GL_ARB_texture_compression_rgtc"))
{
hasTextureCompression = true;
Log::info("GLDriver", "EXT Texture Compression S3TC Present");
Log::info("GLDriver", "ARB Texture Compression RGTC Present");
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_UNIFORM_BUFFER_OBJECT) &&
hasGLExtension("GL_ARB_uniform_buffer_object")) {
@ -182,7 +191,11 @@ void CentralVideoSettings::init()
hasGS = true;
Log::info("GLDriver", "Geometry Shaders Present");
}
if (hasGLExtension("GL_ARB_texture_swizzle"))
{
hasTextureSwizzle = true;
Log::info("GLDriver", "ARB Texture Swizzle Present");
}
// Only unset the high def textures if they are set as default. If the
// user has enabled them (bit 1 set), then leave them enabled.
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) &&
@ -222,13 +235,8 @@ void CentralVideoSettings::init()
#else
if (m_glsl == true)
{
hasArraysOfArrays = true;
hasTextureStorage = true;
hasTextureView = true;
hasBindlessTexture = true;
hasImageLoadStore = true;
hasAtomics = true;
hasSSBO = true;
hasTextureSwizzle = true;
}
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
@ -444,4 +452,14 @@ bool CentralVideoSettings::isDefferedEnabled() const
return UserConfigParams::m_dynamic_lights && !GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_ADVANCED_PIPELINE);
}
bool CentralVideoSettings::supportsHardwareSkinning() const
{
return isARBUniformBufferObjectUsable();
}
bool CentralVideoSettings::isARBTextureSwizzleUsable() const
{
return m_glsl && hasTextureSwizzle;
}
#endif // !SERVER_ONLY

View File

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

View File

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

View File

@ -24,26 +24,11 @@
#include "graphics/gl_headers.hpp"
#include "graphics/material.hpp"
#include "graphics/materials.hpp"
#include "graphics/render_info.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/vao_manager.hpp"
#include <irrlicht.h>
#include <array>
#include <unordered_map>
typedef STK::Tuple<scene::ISceneNode*, core::vector2df, core::vector2df> InstanceSettings;
struct InstanceList
{
GLMesh *m_mesh;
std::vector<InstanceSettings> m_instance_settings;
};
typedef std::unordered_map <std::pair<scene::IMeshBuffer*, RenderInfo*>, InstanceList,
MeshRenderInfoHash, MeshRenderInfoEquals> SolidPassMeshMap;
typedef std::unordered_map <irr::scene::IMeshBuffer *, InstanceList > OtherMeshMap;
// ----------------------------------------------------------------------------
/** Fill origin, orientation and scale attributes
* \param node The scene node of the mesh
@ -271,7 +256,7 @@ class SolidCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADER
{
public:
SolidCommandBuffer();
void fill(SolidPassMeshMap *mesh_map);
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
/** First rendering pass; draw all meshes associated with the same material
@ -458,7 +443,7 @@ class ShadowCommandBuffer: public CommandBuffer<4*static_cast<int>(Material::SHA
{
public:
ShadowCommandBuffer();
void fill(OtherMeshMap *mesh_map);
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
/** Draw shadowmaps for meshes with the same material
@ -532,7 +517,7 @@ class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Ma
{
public:
ReflectiveShadowMapCommandBuffer();
void fill(OtherMeshMap *mesh_map);
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
/** Draw reflective shadow map for meshes with the same material
@ -615,7 +600,7 @@ class GlowCommandBuffer: public CommandBuffer<1>
{
public:
GlowCommandBuffer();
void fill(OtherMeshMap *mesh_map);
void fill(MeshMap *mesh_map);
// ----------------------------------------------------------------------------
/** Draw glowing meshes.

View File

@ -19,23 +19,28 @@
#include "graphics/draw_calls.hpp"
#include "config/user_config.hpp"
#include "graphics/command_buffer.hpp"
#include "graphics/draw_tools.hpp"
#include "graphics/gpu_particles.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/materials.hpp"
#include "graphics/render_info.hpp"
#include "graphics/shadow_matrices.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stk_animated_mesh.hpp"
#include "graphics/stk_billboard.hpp"
#include "graphics/stk_mesh.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
#include "graphics/vao_manager.hpp"
#include "tracks/track.hpp"
#include "utils/profiler.hpp"
#include <numeric>
// ----------------------------------------------------------------------------
void DrawCalls::clearLists()
{
ListBlendTransparent::getInstance()->clear();
ListAdditiveTransparent::getInstance()->clear();
ListTranslucentSkinned::getInstance()->clear();
ListTranslucentStandard::getInstance()->clear();
ListTranslucentTangents::getInstance()->clear();
ListTranslucent2TCoords::getInstance()->clear();
@ -43,6 +48,10 @@ void DrawCalls::clearLists()
ListAdditiveTransparentFog::getInstance()->clear();
ListDisplacement::getInstance()->clear();
ListSkinnedSolid::getInstance()->clear();
ListSkinnedAlphaRef::getInstance()->clear();
ListSkinnedNormalMap::getInstance()->clear();
ListSkinnedUnlit::getInstance()->clear();
ListMatDefault::getInstance()->clear();
ListMatAlphaRef::getInstance()->clear();
ListMatSphereMap::getInstance()->clear();
@ -172,7 +181,8 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
if (node->isImmediateDraw())
{
ImmediateDraw->push_back(Node);
if (!isCulledPrecise(cam, Node, irr_driver->getBoundingBoxesViz()))
ImmediateDraw->push_back(Node);
return;
}
@ -243,8 +253,34 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
int32_t skinning_offset = 0;
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(Node);
if (am && am->useHardwareSkinning() &&
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
{
skinning_offset = getSkinningOffset() + 1/*reserved identity matrix*/;
if (skinning_offset + am->getTotalJoints() >
SharedGPUObjects::getMaxMat4Size())
{
Log::error("DrawCalls", "Don't have enough space to render skinned"
" mesh %s! Max joints can hold: %d",
am->getMeshDebugName().c_str(),
SharedGPUObjects::getMaxMat4Size());
return;
}
m_mesh_for_skinning.insert(am);
am->setSkinningOffset(skinning_offset * 16 * sizeof(float));
}
if (!culled_for_cams[0])
{
for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_SKN])
{
pushVector(ListTranslucentSkinned::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans,
skinning_offset, (mesh->m_render_info && mesh->m_render_info->isTransparent() ? custom_alpha : 1.0f));
}
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
{
if (CVS->supportsIndirectInstancingRendering())
@ -255,7 +291,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
m_glow_pass_mesh[mesh->mb].m_mesh = mesh;
m_glow_pass_mesh[mesh->mb].m_instance_settings
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
}
if (Mat == Material::SHADERTYPE_SPLATTING)
{
@ -267,15 +303,11 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
}
else
{
// Only take render info into account if the node is not static (animated)
// So they can have different animation
std::pair<scene::IMeshBuffer*, RenderInfo*> mesh_render_info(mesh->mb,
dynamic_cast<STKMeshSceneNode*>(Node) == NULL ? mesh->m_render_info : NULL);
m_solid_pass_mesh[Mat][mesh_render_info].m_mesh = mesh;
m_solid_pass_mesh[Mat][mesh_render_info].m_instance_settings.emplace_back(Node, mesh->texture_trans,
m_solid_pass_mesh[Mat][mesh->mb].m_mesh = mesh;
m_solid_pass_mesh[Mat][mesh->mb].m_instance_settings.emplace_back(Node, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)));
core::vector2df(0.0f, 0.0f)), skinning_offset);
}
}
}
@ -288,6 +320,28 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
switch (Mat)
{
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
ListSkinnedSolid::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)), skinning_offset);
break;
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
ListSkinnedAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)), skinning_offset);
break;
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
ListSkinnedUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
core::vector2df(0.0f, 0.0f), skinning_offset);
break;
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
ListSkinnedNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) :
core::vector2df(0.0f, 0.0f)), skinning_offset);
break;
case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
(mesh->m_render_info && mesh->m_material ?
@ -351,7 +405,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_mesh = mesh;
m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
}
}
else
@ -363,6 +417,22 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
switch (Mat)
{
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
ListSkinnedSolid::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
core::vector2df(0.0f, 0.0f), skinning_offset);
break;
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
ListSkinnedAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
core::vector2df(0.0f, 0.0f), skinning_offset);
break;
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
ListSkinnedUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
core::vector2df(0.0f, 0.0f), skinning_offset);
break;
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
ListSkinnedNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans,
core::vector2df(0.0f, 0.0f), skinning_offset);
break;
case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
break;
@ -419,7 +489,7 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
m_reflective_shadow_map_mesh[Mat][mesh->mb].m_mesh = mesh;
m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f));
.emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f), skinning_offset);
}
}
}
@ -432,6 +502,12 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
{
switch (Mat)
{
// Todo: RSMs
case Material::SHADERTYPE_SOLID_SKINNED_MESH:
case Material::SHADERTYPE_ALPHA_TEST_SKINNED_MESH:
case Material::SHADERTYPE_SOLID_UNLIT_SKINNED_MESH:
case Material::SHADERTYPE_NORMAL_MAP_SKINNED_MESH:
break;
case Material::SHADERTYPE_SOLID:
ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f));
break;
@ -551,7 +627,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
{
m_wind_dir = getWindDir();
clearLists();
m_mesh_for_skinning.clear();
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
{
m_solid_pass_mesh[Mat].clear();
@ -569,6 +645,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
&m_immediate_draw_list, camnode, shadow_matrices);
PROFILER_POP_CPU_MARKER();
irr_driver->setSkinningJoint(getSkinningOffset());
// Add a 1 s timeout
if (!m_sync)
m_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
@ -688,7 +765,13 @@ void DrawCalls::drawIndirectSolidFirstPass() const
m_solid_cmd_buffer->drawIndirectFirstPass<SphereMap>();
m_solid_cmd_buffer->drawIndirectFirstPass<GrassMat>(m_wind_dir);
m_solid_cmd_buffer->drawIndirectFirstPass<DetailMat>();
m_solid_cmd_buffer->drawIndirectFirstPass<NormalMat>();
m_solid_cmd_buffer->drawIndirectFirstPass<NormalMat>();
if (!CVS->supportsHardwareSkinning()) return;
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedSolid>();
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedAlphaRef>();
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedUnlitMat>();
m_solid_cmd_buffer->drawIndirectFirstPass<SkinnedNormalMat>();
}
// ----------------------------------------------------------------------------
@ -704,7 +787,13 @@ void DrawCalls::multidrawSolidFirstPass() const
m_solid_cmd_buffer->multidrawFirstPass<UnlitMat>();
m_solid_cmd_buffer->multidrawFirstPass<GrassMat>(m_wind_dir);
m_solid_cmd_buffer->multidrawFirstPass<NormalMat>();
m_solid_cmd_buffer->multidrawFirstPass<DetailMat>();
m_solid_cmd_buffer->multidrawFirstPass<DetailMat>();
if (!CVS->supportsHardwareSkinning()) return;
m_solid_cmd_buffer->multidrawFirstPass<SkinnedSolid>();
m_solid_cmd_buffer->multidrawFirstPass<SkinnedAlphaRef>();
m_solid_cmd_buffer->multidrawFirstPass<SkinnedUnlitMat>();
m_solid_cmd_buffer->multidrawFirstPass<SkinnedNormalMat>();
}
// ----------------------------------------------------------------------------
@ -724,6 +813,12 @@ void DrawCalls::drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled
m_solid_cmd_buffer->drawIndirectSecondPass<GrassMat>(prefilled_tex, m_wind_dir);
m_solid_cmd_buffer->drawIndirectSecondPass<DetailMat>(prefilled_tex);
m_solid_cmd_buffer->drawIndirectSecondPass<NormalMat>(prefilled_tex);
if (!CVS->supportsHardwareSkinning()) return;
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedSolid>(prefilled_tex);
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedAlphaRef>(prefilled_tex);
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedUnlitMat>(prefilled_tex);
m_solid_cmd_buffer->drawIndirectSecondPass<SkinnedNormalMat>(prefilled_tex);
}
// ----------------------------------------------------------------------------
@ -742,6 +837,12 @@ void DrawCalls::multidrawSolidSecondPass(const std::vector<uint64_t> &handles) c
m_solid_cmd_buffer->multidraw2ndPass<NormalMat>(handles);
m_solid_cmd_buffer->multidraw2ndPass<DetailMat>(handles);
m_solid_cmd_buffer->multidraw2ndPass<GrassMat>(handles, m_wind_dir);
if (!CVS->supportsHardwareSkinning()) return;
m_solid_cmd_buffer->multidraw2ndPass<SkinnedSolid>(handles);
m_solid_cmd_buffer->multidraw2ndPass<SkinnedAlphaRef>(handles);
m_solid_cmd_buffer->multidraw2ndPass<SkinnedUnlitMat>(handles);
m_solid_cmd_buffer->multidraw2ndPass<SkinnedNormalMat>(handles);
}
// ----------------------------------------------------------------------------
@ -792,6 +893,12 @@ void DrawCalls::drawIndirectShadows(unsigned cascade) const
m_shadow_cmd_buffer->drawIndirect<NormalMat>(cascade);
m_shadow_cmd_buffer->drawIndirect<SplattingMat>(cascade);
m_shadow_cmd_buffer->drawIndirect<SphereMap>(cascade);
if (!CVS->supportsHardwareSkinning()) return;
m_shadow_cmd_buffer->drawIndirect<SkinnedSolid>(cascade);
m_shadow_cmd_buffer->drawIndirect<SkinnedAlphaRef>(cascade);
m_shadow_cmd_buffer->drawIndirect<SkinnedUnlitMat>(cascade);
m_shadow_cmd_buffer->drawIndirect<SkinnedNormalMat>(cascade);
}
// ----------------------------------------------------------------------------
@ -810,6 +917,12 @@ void DrawCalls::multidrawShadows(unsigned cascade) const
m_shadow_cmd_buffer->multidrawShadow<GrassMat,irr::core::vector3df>(cascade, m_wind_dir);
m_shadow_cmd_buffer->multidrawShadow<SplattingMat>(cascade);
m_shadow_cmd_buffer->multidrawShadow<SphereMap>(cascade);
if (!CVS->supportsHardwareSkinning()) return;
m_shadow_cmd_buffer->multidrawShadow<SkinnedSolid>(cascade);
m_shadow_cmd_buffer->multidrawShadow<SkinnedAlphaRef>(cascade);
m_shadow_cmd_buffer->multidrawShadow<SkinnedUnlitMat>(cascade);
m_shadow_cmd_buffer->multidrawShadow<SkinnedNormalMat>(cascade);
}
// ----------------------------------------------------------------------------
@ -866,4 +979,12 @@ void DrawCalls::multidrawGlow() const
}
#endif // !defined(USE_GLES2)
#endif // !SERVER_ONLY
// ----------------------------------------------------------------------------
int32_t DrawCalls::getSkinningOffset() const
{
return std::accumulate(m_mesh_for_skinning.begin(),
m_mesh_for_skinning.end(), 0, []
(const size_t previous, const STKAnimatedMesh* m)
{ return previous + m->getTotalJoints(); });
} // getSkinningOffset
#endif // !SERVER_ONLY

View File

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

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