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

Conflicts:
	src/online/http_request.cpp
This commit is contained in:
hiker 2014-12-10 11:25:16 +11:00
commit 83f49ec319
56 changed files with 1411 additions and 991 deletions

View File

@ -3,6 +3,7 @@
<card is="Intel(R) HD Graphics 3000" os="windows" version="<9.17.11" disable="a b c"/>
<card contains="NVIDIA" os="windows" version="<344.65" disable="BufferStorage"/>
<card contains="NVIDIA" os="linux" version="<343.22" disable="BufferStorage"/>
<card contains="Mesa" os="linux" version="<10.3" disable="BufferStorage"/>
<card is="Intel(R) HD Graphics 3000" os="osx" version="<=9.17.10" disable="a b c"/>
<card is="" os="bsd" version="<1.2.3" disable="a b c"/>

View File

@ -2,37 +2,37 @@
<stkgui>
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
<div proportion="1" width="100%" layout="horizontal-row">
<label id="Red" text="Red"/>
<label id="Red" raw_text="Red"/>
<spacer width="25"/>
<gauge id="red_slider" min_value="0" max_value="100" proportion="1"/>
</div>
<div proportion="1" width="100%" layout="horizontal-row">
<label id="Green" text="Green"/>
<label id="Green" raw_text="Green"/>
<spacer width="25"/>
<gauge id="green_slider" min_value="0" max_value="100" proportion="1"/>
</div>
<div proportion="1" width="100%" layout="horizontal-row">
<label id="Blue" text="Blue"/>
<label id="Blue" raw_text="Blue"/>
<spacer width="25"/>
<gauge id="blue_slider" min_value="0" max_value="100" proportion="1"/>
</div>
<div proportion="1" width="100%" layout="horizontal-row">
<label id="SSAO radius" text="SSAO Radius"/>
<label id="SSAO radius" raw_text="SSAO Radius"/>
<spacer width="50"/>
<gauge id="ssao_radius" min_value="0" max_value="100" proportion="1" />
</div>
<div proportion="1" width="100%" layout="horizontal-row">
<label id="SSAO k" text="SSAO K"/>
<label id="SSAO k" raw_text="SSAO K"/>
<spacer width="25"/>
<gauge id="ssao_k" min_value="0" max_value="100" proportion="1"/>
</div>
<div proportion="1" width="100%" layout="horizontal-row">
<label id="SSAO Sigma" text="SSAO sigma"/>
<label id="SSAO Sigma" raw_text="SSAO sigma"/>
<spacer width="50"/>
<gauge id="ssao_sigma" min_value="0" max_value="100" proportion="1"/>
</div>

View File

@ -40,17 +40,17 @@
<buttonbar id="menu_bottomrow" x="0" y="0" width="38%" height="100%" align="center">
<icon-button id="test_gpwin" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: GPWin" label_location="hover"/>
raw_text="TEST: GPWin" label_location="hover"/>
<icon-button id="test_gplose" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: GPLose" label_location="hover"/>
raw_text="TEST: GPLose" label_location="hover"/>
<icon-button id="test_unlocked" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: Unlocked" label_location="hover"/>
raw_text="TEST: Unlocked" label_location="hover"/>
<icon-button id="test_unlocked2" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: Unlocked 2" label_location="hover"/>
raw_text="TEST: Unlocked 2" label_location="hover"/>
<icon-button id="test_intro" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: Intro" label_location="hover"/>
raw_text="TEST: Intro" label_location="hover"/>
<icon-button id="test_outro" width="64" height="64" icon="gui/main_options.png" extend_label="50"
text="TEST: Outro" label_location="hover"/>
raw_text="TEST: Outro" label_location="hover"/>
<icon-button id="options" width="64" height="64" icon="gui/main_options.png" extend_label="50"
I18N="In the main screen" text="Options" label_location="hover"/>
<icon-button id="help" width="64" height="64" icon="gui/main_help.png" extend_label="50"

File diff suppressed because it is too large Load Diff

26
data/shaders/IBL.frag Normal file
View File

@ -0,0 +1,26 @@
uniform sampler2D ntex;
uniform sampler2D dtex;
out vec4 Diff;
out vec4 Spec;
vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 DiffuseIBL(vec3 normal);
vec3 SpecularIBL(vec3 normal, vec3 V, float roughness);
void main(void)
{
vec2 uv = gl_FragCoord.xy / screen;
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
Diff = vec4(0.25 * DiffuseIBL(normal), 1.);
float z = texture(dtex, uv).x;
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
vec3 eyedir = -normalize(xpos.xyz);
float specval = texture(ntex, uv).z;
Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval), 1.);
}

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(r32f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
float sum = local_src[x + 6][y] * g0;
g0 *= g1;
g1 *= g2;
float sum = local_src[x + 6][y] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[6 + x - i][y] * g0;
sum += local_src[6 + x + i][y] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[6 + x - i][y] * weights[i];
sum += local_src[6 + x + i][y] * weights[i];
}
imageStore(dest, iuv, vec4(sum));

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(r32f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
float sum = local_src[x][y + 6] * g0;
g0 *= g1;
g1 *= g2;
float sum = local_src[x][y + 6] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[x][6 + y - i] * g0;
sum += local_src[x][6 + y + i] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[x][6 + y - i] * weights[i];
sum += local_src[x][6 + y + i] * weights[i];
}
imageStore(dest, iuv, vec4(sum));

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(rgba16f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = local_src[x + 6][y] * g0;
g0 *= g1;
g1 *= g2;
vec4 sum = local_src[x + 6][y] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[6 + x - i][y] * g0;
sum += local_src[6 + x + i][y] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[6 + x - i][y] * weights[i];
sum += local_src[6 + x + i][y] * weights[i];
}
imageStore(dest, iuv, sum);

View File

@ -1,7 +1,7 @@
uniform sampler2D source;
uniform layout(rgba16f) restrict writeonly image2D dest;
uniform vec2 pixel;
uniform float sigma;
uniform float weights[7];
// Gaussian separated blur with radius 6.
@ -23,18 +23,10 @@ void main()
barrier();
float g0, g1, g2;
g0 = 1.0 / (sqrt(2.0 * 3.14) * sigma);
g1 = exp(-0.5 / (sigma * sigma));
g2 = g1 * g1;
vec4 sum = local_src[x][y + 6] * g0;
g0 *= g1;
g1 *= g2;
vec4 sum = local_src[x][y + 6] * weights[0];
for (int i = 1; i < 6; i++) {
sum += local_src[x][6 + y - i] * g0;
sum += local_src[x][6 + y + i] * g0;
g0 *= g1;
g1 *= g2;
sum += local_src[x][6 + y - i] * weights[i];
sum += local_src[x][6 + y + i] * weights[i];
}
imageStore(dest, iuv, sum);

View File

@ -9,7 +9,6 @@ uniform sampler3D SHR;
uniform sampler3D SHG;
uniform sampler3D SHB;
uniform float R_wcs = 10.;
uniform vec3 extents;
uniform mat4 RHMatrix;
uniform mat4 InvRHMatrix;

View File

@ -35,7 +35,7 @@ void main(void)
vec3 eyedir = normalize(xpos.xyz);
// Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html
float fEdotL = max(0., dot(SunDir, eyedir));
float fEdotL = clamp(dot(SunDir, eyedir), 0., 1.);
float fPowEdotL = pow(fEdotL, 4.);
float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4);

View File

@ -0,0 +1,33 @@
uniform samplerCube tex;
uniform samplerBuffer samples;
uniform float ViewportSize;
uniform mat4 PermutationMatrix;
out vec4 FragColor;
void main(void)
{
vec2 uv = gl_FragCoord.xy / ViewportSize;
vec3 RayDir = 2. * vec3(uv, 1.) - 1.;
RayDir = normalize((PermutationMatrix * vec4(RayDir, 0.)).xyz);
vec4 FinalColor = vec4(0.);
vec3 up = (RayDir.y < .99) ? vec3(0., 1., 0.) : vec3(0., 0., 1.);
vec3 Tangent = normalize(cross(up, RayDir));
vec3 Bitangent = cross(RayDir, Tangent);
float weight = 0.;
for (int i = 0; i < 1024; i++)
{
float Theta = texelFetch(samples, i).r;
float Phi = texelFetch(samples, i).g;
vec3 L = cos(Theta) * RayDir + sin(Theta) * cos(Phi) * Tangent + sin(Theta) * sin(Phi) * Bitangent;
float NdotL = clamp(dot(RayDir, L), 0., 1.);
FinalColor += textureLod(tex, L, 0.) * NdotL;
weight += NdotL;
}
FragColor = FinalColor / weight;
}

View File

@ -41,7 +41,7 @@ void main(void)
vec3 eyedir = normalize(xpos.xyz);
// Inspired from http://http.developer.nvidia.com/GPUGems3/gpugems3_ch16.html
float fEdotL = max(0., dot(SunDir, eyedir));
float fEdotL = clamp(dot(SunDir, eyedir), 0., 1.);
float fPowEdotL = pow(fEdotL, 4.);
float fLdotNBack = max(0., - dot(nor, SunDir) * 0.6 + 0.4);

View File

@ -31,5 +31,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 = exp2(10. * gloss + 1.);
EncodedNormal.z = gloss;
}

View File

@ -19,5 +19,5 @@ void main(void)
float glossmap = texture(glosstex, uv).x;
#endif
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * glossmap + 1.);
EncodedNormal.z = glossmap;
}

View File

@ -24,6 +24,6 @@ void main() {
if (col.a < 0.5)
discard;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * glossmap + 1.);
EncodedNormal.z = glossmap;
}

View File

@ -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 = exp2(10. * (1. - alpha) + 1.);
EncodedNormal.z = 1. - alpha;
}

View File

@ -19,5 +19,5 @@ void main(void)
{
float glossmap = texture(tex, uv).x;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * glossmap + 1.);
EncodedNormal.z = glossmap;
}

View File

@ -24,6 +24,6 @@ void main() {
discard;
float glossmap = texture(glosstex, uv).x;
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
EncodedNormal.z = exp2(10. * glossmap + 1.);
EncodedNormal.z = glossmap;
}

View File

@ -10,7 +10,7 @@ out vec4 Diffuse;
out vec4 Specular;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
void main()
@ -35,8 +35,8 @@ void main()
// Light Direction
vec3 L = -normalize(xpos.xyz - light_pos);
float NdotL = max(0., dot(norm, L));
float NdotL = clamp(dot(norm, L), 0., 1.);
Diffuse = vec4(NdotL * light_col * att, 1.);
Specular = vec4(getSpecular(norm, eyedir, L, light_col, roughness) * NdotL * att, 1.);
Specular = vec4(SpecularBRDF(norm, eyedir, L, light_col, roughness) * NdotL * att, 1.);
}

View File

@ -13,7 +13,7 @@ out vec4 Diff;
out vec4 Spec;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 getMostRepresentativePoint(vec3 direction, vec3 R, float angularRadius)
@ -46,13 +46,13 @@ void main() {
// Normalized on the cpu
vec3 L = direction;
float NdotL = max(0., dot(norm, L));
float NdotL = clamp(dot(norm, L), 0., 1.);
float angle = 3.14 * sunangle / 180.;
vec3 R = reflect(-eyedir, norm);
vec3 Lightdir = getMostRepresentativePoint(direction, R, angle);
vec3 Specular = getSpecular(norm, eyedir, Lightdir, col, roughness) * NdotL;
vec3 Specular = SpecularBRDF(norm, eyedir, Lightdir, col, roughness) * NdotL;
vec3 outcol = NdotL * col;

View File

@ -16,7 +16,7 @@ out vec4 Diff;
out vec4 Spec;
vec3 DecodeNormal(vec2 n);
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 getMostRepresentativePoint(vec3 direction, vec3 R, float angularRadius)
@ -60,13 +60,13 @@ void main() {
// Normalized on the cpu
vec3 L = direction;
float NdotL = max(0., dot(norm, L));
float NdotL = clamp(dot(norm, L), 0., 1.);
float angle = 3.14 * sunangle / 180.;
vec3 R = reflect(-eyedir, norm);
vec3 Lightdir = getMostRepresentativePoint(direction, R, angle);
vec3 Specular = getSpecular(norm, eyedir, Lightdir, col, roughness) * NdotL;
vec3 Specular = SpecularBRDF(norm, eyedir, Lightdir, col, roughness) * NdotL;
vec3 outcol = NdotL * col;

View File

@ -1,9 +1,4 @@
// From http://www.ceng.metu.edu.tr/~akyuz/files/hdrgpu.pdf
uniform sampler2D tex;
uniform sampler2D logluminancetex;
uniform float exposure = .09;
uniform float Lwhite = 1.;
uniform float vignette_weight;
out vec4 FragColor;
@ -11,25 +6,10 @@ out vec4 FragColor;
vec3 getCIEYxy(vec3 rgbColor);
vec3 getRGBFromCIEXxy(vec3 YxyColor);
float delta = .0001;
float saturation = 1.;
void main()
{
vec2 uv = gl_FragCoord.xy / screen;
vec4 col = texture(tex, uv);
float avgLw = textureLod(logluminancetex, uv, 10.).x;
avgLw = max(exp(avgLw) - delta, delta);
vec3 Cw = getCIEYxy(col.xyz);
float Lw = Cw.y;
/* Reinhard, for reference */
// float L = Lw * exposure / avgLw;
// float Ld = L * (1. + L / (Lwhite * Lwhite));
// Ld /= (1. + L);
// FragColor = vec4(Ld * pow(col.xyz / Lw, vec3(saturation)), 1.);
// Uncharted2 tonemap with Auria's custom coefficients
vec4 perChannel = (col * (6.9 * col + .5)) / (col * (5.2 * col + 1.7) + 0.06);
@ -38,7 +18,6 @@ void main()
vec2 inside = uv - 0.5;
float vignette = 1. - dot(inside, inside) * vignette_weight;
vignette = clamp(pow(vignette, 0.8), 0., 1.);
//vignette = clamp(vignette + vignette - 0.5, 0., 1.15);
FragColor = vec4(perChannel.xyz * vignette, col.a);
}

View File

@ -1,17 +1,12 @@
// From "An Efficient Representation for Irradiance Environment Maps" article
// See http://graphics.stanford.edu/papers/envmap/
// Coefficients are calculated in IBL.cpp
uniform float blueLmn[9];
uniform float greenLmn[9];
uniform float redLmn[9];
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform samplerCube tex;
uniform mat4 TransposeViewMatrix;
out vec4 Diff;
out vec4 Spec;
vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
mat4 getMatrix(float L[9])
{
float c1 = 0.429043, c2 = 0.511664, c3 = 0.743125, c4 = 0.886227, c5 = 0.247708;
@ -24,11 +19,8 @@ mat4 getMatrix(float L[9])
);
}
void main(void)
vec3 DiffuseIBL(vec3 normal)
{
vec2 uv = gl_FragCoord.xy / screen;
vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
// Convert normal in world space (where SH coordinates were computed)
vec4 extendednormal = TransposeViewMatrix * vec4(normal, 0.);
extendednormal.w = 1.;
@ -40,19 +32,5 @@ void main(void)
float g = dot(extendednormal, gmat * extendednormal);
float b = dot(extendednormal, bmat * extendednormal);
Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.));
float z = texture(dtex, uv).x;
vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix);
vec3 eyedir = -normalize(xpos.xyz);
vec3 sampleDirection = reflect(-eyedir, normal);
sampleDirection = (InverseViewMatrix * vec4(sampleDirection, 0.)).xyz;
float specval = texture(ntex, uv).z;
// From http://graphics.cs.williams.edu/papers/EnvMipReport2013/
int texSize = textureSize(tex, 0).x;
float lodval = clamp(log2(texSize * sqrt(3.)) - .5 * log2(specval + 1.), 0., 10.);
vec4 specular = textureLod(tex, sampleDirection, lodval);
Spec = max(specular, vec4(0.));
}
return max(vec3(r, g, b), vec3(0.));
}

View File

@ -0,0 +1,11 @@
// Blinn Phong with emulated fresnel factor
vec3 SpecularBRDF(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness)
{
float exponentroughness = exp2(10. * roughness + 1.);
// Half Light View direction
vec3 H = normalize(eyedir + lightdir);
float NdotH = clamp(dot(normal, H), 0., 1.);
float normalisationFactor = (exponentroughness + 2.) / 8.;
vec3 FresnelSchlick = color + (1.0f - color) * pow(1.0f - clamp(dot(eyedir, H), 0., 1.), 5);
return max(pow(NdotH, exponentroughness) * FresnelSchlick * normalisationFactor, vec3(0.));
}

View File

@ -0,0 +1,11 @@
uniform samplerCube probe;
vec3 SpecularIBL(vec3 normal, vec3 V, float roughness)
{
vec3 sampleDirection = reflect(-V, normal);
sampleDirection = (InverseViewMatrix * vec4(sampleDirection, 0.)).xyz;
// Assume 8 level of lod (ie 256x256 texture)
float lodval = 8. * (1. - roughness);
return max(textureLod(probe, sampleDirection, lodval).rgb, vec3(0.));
}

View File

@ -1,11 +0,0 @@
vec3 getSpecular(vec3 normal, vec3 eyedir, vec3 lightdir, vec3 color, float roughness)
{
// Half Light View direction
vec3 H = normalize(eyedir + lightdir);
float NdotH = max(0., dot(normal, H));
float normalisationFactor = (roughness + 2.) / 8.;
vec3 FresnelSchlick = color + (1.0f - color) * pow(1.0f - max(0., (dot(eyedir, H))), 5);
return max(pow(NdotH, roughness) * FresnelSchlick * normalisationFactor, vec3(0.));
}

View File

@ -794,6 +794,7 @@ void CSkinnedMesh::checkForAnimation()
AllJoints[i]->UseAnimationFrom->RotationKeys.size() )
{
HasAnimation = true;
break;
}
}
}
@ -803,8 +804,11 @@ void CSkinnedMesh::checkForAnimation()
{
for(i=0;i<AllJoints.size();++i)
{
if (AllJoints[i]->Weights.size())
HasAnimation = true;
if (AllJoints[i]->Weights.size())
{
HasAnimation = true;
break;
}
}
}
@ -1470,6 +1474,76 @@ void CSkinnedMesh::calculateTangents(
}
}
// ----------------------------------------------------------------------------
/** Copies a mesh.
*/
CSkinnedMesh *CSkinnedMesh::clone()
{
CSkinnedMesh* skinned_mesh = new CSkinnedMesh();
for (u32 i = 0; i < getMeshBuffers().size(); i++)
{
SSkinMeshBuffer * buffer = skinned_mesh->addMeshBuffer();
*buffer = *(getMeshBuffers()[i]);
}
for (u32 j = 0; j < getAllJoints().size(); ++j)
{
ISkinnedMesh::SJoint *joint = skinned_mesh->addJoint();
*joint = *(getAllJoints()[j]);
}
// fix children pointers (they still have old pointers)
core::array<ISkinnedMesh::SJoint*> & new_joints = skinned_mesh->getAllJoints();
for (u32 i = 0; i < new_joints.size(); ++i)
{
ISkinnedMesh::SJoint * joint = new_joints[i];
for (u32 c = 0; c < joint->Children.size(); ++c)
{
// the child is one of the oldJoints and must be replaced by the newjoint on the same index
bool found = false;
for (u32 k = 0; k < AllJoints.size(); ++k)
{
if (joint->Children[c] == AllJoints[k])
{
joint->Children[c] = new_joints[k];
found = true;
break;
}
} // k < old_joints.size
if (!found)
found = true;
} // c < joint->Children.size()
} // i < new_joints.size()
// In finalize the values from LocalBuffers are copied into
// Weights[].StaticPos. Since skinned_mesh already has the correct
// values in Weights, we have to copy the values from Weights
// into LocalBuffer (so that in the copy from LocalBuffer to weights
// no values are overwritten).
// FIXME: Not ideal, better would be not to copy the values in
// finalize().
for (unsigned int i = 0; i<AllJoints.size(); ++i)
{
SJoint *joint = AllJoints[i];
for (unsigned int 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;
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Pos = joint->Weights[j].StaticPos;
skinned_mesh->LocalBuffers[buffer_id]->getVertex(vertex_id)->Normal = joint->Weights[j].StaticNormal;
}
}
skinned_mesh->finalize();
return skinned_mesh;
} // clone
} // end namespace scene
} // end namespace irr

View File

@ -159,7 +159,7 @@ namespace scene
void addJoints(core::array<IBoneSceneNode*> &jointChildSceneNodes,
IAnimatedMeshSceneNode* node,
ISceneManager* smgr);
CSkinnedMesh *clone();
private:
void checkForAnimation();

View File

@ -749,8 +749,9 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_always_show_login_screen
PARAM_DEFAULT( BoolUserConfigParam(false, "always_show_login_screen",
"Always show the login screen even if last player's session was saved."));
// ---- Online gameplay related
// ---- Online gameplay related
PARAM_PREFIX GroupUserConfigParam m_online_group
PARAM_DEFAULT( GroupUserConfigParam("OnlineServer",
"Everything related to online play.") );
@ -767,6 +768,12 @@ namespace UserConfigParams
&m_online_group,
"Version of the server API to use."));
PARAM_PREFIX BoolUserConfigParam m_verify_peer
PARAM_DEFAULT(BoolUserConfigParam(1, "verify-peer", &m_online_group,
"If curl should check peer address. Should always be enabled,"
"unless there are authentication problems."));
// ---- Addon server related entries
PARAM_PREFIX GroupUserConfigParam m_addon_group
PARAM_DEFAULT( GroupUserConfigParam("AddonServer",

334
src/graphics/IBL.cpp Normal file
View File

@ -0,0 +1,334 @@
#include "IBL.hpp"
#include "gl_headers.hpp"
#include "shaders.hpp"
#include <cmath>
#include <set>
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
{
switch (face)
{
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
x = 1.;
y = -i;
z = -j;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
x = -1.;
y = -i;
z = j;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
x = j;
y = 1.;
z = i;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
x = j;
y = -1;
z = -i;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
x = j;
y = -i;
z = 1;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
x = -j;
y = -i;
z = -1;
break;
}
float norm = sqrt(x * x + y * y + z * z);
x /= norm, y /= norm, z /= norm;
return;
}
static void getYml(GLenum face, size_t edge_size,
float *Y00,
float *Y1minus1, float *Y10, float *Y11,
float *Y2minus2, float *Y2minus1, float *Y20, float *Y21, float *Y22)
{
#pragma omp parallel for
for (int i = 0; i < int(edge_size); i++)
{
for (unsigned j = 0; j < edge_size; j++)
{
float x, y, z;
float fi = float(i), fj = float(j);
fi /= edge_size, fj /= edge_size;
fi = 2 * fi - 1, fj = 2 * fj - 1;
getXYZ(face, fi, fj, x, y, z);
// constant part of Ylm
float c00 = 0.282095f;
float c1minus1 = 0.488603f;
float c10 = 0.488603f;
float c11 = 0.488603f;
float c2minus2 = 1.092548f;
float c2minus1 = 1.092548f;
float c21 = 1.092548f;
float c20 = 0.315392f;
float c22 = 0.546274f;
size_t idx = i * edge_size + j;
Y00[idx] = c00;
Y1minus1[idx] = c1minus1 * y;
Y10[idx] = c10 * z;
Y11[idx] = c11 * x;
Y2minus2[idx] = c2minus2 * x * y;
Y2minus1[idx] = c2minus1 * y * z;
Y21[idx] = c21 * x * z;
Y20[idx] = c20 * (3 * z * z - 1);
Y22[idx] = c22 * (x * x - y * y);
}
}
}
static void projectSH(Color *CubemapFace[6], size_t edge_size,
float *Y00[],
float *Y1minus1[], float *Y10[], float *Y11[],
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
)
{
for (unsigned i = 0; i < 9; i++)
{
blueSHCoeff[i] = 0;
greenSHCoeff[i] = 0;
redSHCoeff[i] = 0;
}
float wh = float(edge_size * edge_size);
for (unsigned face = 0; face < 6; face++)
{
#pragma omp parallel for
for (int i = 0; i < int(edge_size); i++)
{
for (unsigned j = 0; j < edge_size; j++)
{
int idx = i * edge_size + j;
float fi = float(i), fj = float(j);
fi /= edge_size, fj /= edge_size;
fi = 2 * fi - 1, fj = 2 * fj - 1;
float d = sqrt(fi * fi + fj * fj + 1);
// Constant obtained by projecting unprojected ref values
float solidangle = 2.75f / (wh * pow(d, 1.5f));
// pow(., 2.2) to convert from srgb
float b = CubemapFace[face][edge_size * i + j].Blue;
float g = CubemapFace[face][edge_size * i + j].Green;
float r = CubemapFace[face][edge_size * i + j].Red;
blueSHCoeff[0] += b * Y00[face][idx] * solidangle;
blueSHCoeff[1] += b * Y1minus1[face][idx] * solidangle;
blueSHCoeff[2] += b * Y10[face][idx] * solidangle;
blueSHCoeff[3] += b * Y11[face][idx] * solidangle;
blueSHCoeff[4] += b * Y2minus2[face][idx] * solidangle;
blueSHCoeff[5] += b * Y2minus1[face][idx] * solidangle;
blueSHCoeff[6] += b * Y20[face][idx] * solidangle;
blueSHCoeff[7] += b * Y21[face][idx] * solidangle;
blueSHCoeff[8] += b * Y22[face][idx] * solidangle;
greenSHCoeff[0] += g * Y00[face][idx] * solidangle;
greenSHCoeff[1] += g * Y1minus1[face][idx] * solidangle;
greenSHCoeff[2] += g * Y10[face][idx] * solidangle;
greenSHCoeff[3] += g * Y11[face][idx] * solidangle;
greenSHCoeff[4] += g * Y2minus2[face][idx] * solidangle;
greenSHCoeff[5] += g * Y2minus1[face][idx] * solidangle;
greenSHCoeff[6] += g * Y20[face][idx] * solidangle;
greenSHCoeff[7] += g * Y21[face][idx] * solidangle;
greenSHCoeff[8] += g * Y22[face][idx] * solidangle;
redSHCoeff[0] += r * Y00[face][idx] * solidangle;
redSHCoeff[1] += r * Y1minus1[face][idx] * solidangle;
redSHCoeff[2] += r * Y10[face][idx] * solidangle;
redSHCoeff[3] += r * Y11[face][idx] * solidangle;
redSHCoeff[4] += r * Y2minus2[face][idx] * solidangle;
redSHCoeff[5] += r * Y2minus1[face][idx] * solidangle;
redSHCoeff[6] += r * Y20[face][idx] * solidangle;
redSHCoeff[7] += r * Y21[face][idx] * solidangle;
redSHCoeff[8] += r * Y22[face][idx] * solidangle;
}
}
}
}
void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
{
float *Y00[6];
float *Y1minus1[6];
float *Y10[6];
float *Y11[6];
float *Y2minus2[6];
float *Y2minus1[6];
float *Y20[6];
float *Y21[6];
float *Y22[6];
for (unsigned face = 0; face < 6; face++)
{
Y00[face] = new float[edge_size * edge_size];
Y1minus1[face] = new float[edge_size * edge_size];
Y10[face] = new float[edge_size * edge_size];
Y11[face] = new float[edge_size * edge_size];
Y2minus2[face] = new float[edge_size * edge_size];
Y2minus1[face] = new float[edge_size * edge_size];
Y20[face] = new float[edge_size * edge_size];
Y21[face] = new float[edge_size * edge_size];
Y22[face] = new float[edge_size * edge_size];
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, edge_size, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
}
projectSH(CubemapFace, edge_size,
Y00,
Y1minus1, Y10, Y11,
Y2minus2, Y2minus1, Y20, Y21, Y22,
blueSHCoeff, greenSHCoeff, redSHCoeff
);
for (unsigned face = 0; face < 6; face++)
{
delete[] Y00[face];
delete[] Y1minus1[face];
delete[] Y10[face];
delete[] Y11[face];
delete[] Y2minus2[face];
delete[] Y2minus1[face];
delete[] Y20[face];
delete[] Y21[face];
delete[] Y22[face];
}
}
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
/** Returns the index-th pair from Hammersley set of pseudo random set.
Hammersley set is a uniform distribution between 0 and 1 for 2 components.
We use the natural indexation on the set to avoid storing the whole set.
\param index of the pair
\param size of the set. */
std::pair<float, float> HammersleySequence(int index, int samples)
{
float InvertedBinaryRepresentation = 0.;
for (size_t i = 0; i < 32; i++)
{
InvertedBinaryRepresentation += ((index >> i) & 0x1) * powf(.5, (float) (i + 1.));
}
return std::make_pair(float(index) / float(samples), InvertedBinaryRepresentation);
}
/** Returns a pseudo random (theta, phi) generated from a probability density function modeled after Phong function.
\param a pseudo random float pair from a uniform density function between 0 and 1.
\param exponent from the Phong formula. */
std::pair<float, float> ImportanceSamplingPhong(std::pair<float, float> Seeds, float exponent)
{
return std::make_pair(acosf(powf(Seeds.first, 1.f / (exponent + 1.f))), 2.f * 3.14f * Seeds.second);
}
static
core::matrix4 getPermutationMatrix(size_t indexX, float valX, size_t indexY, float valY, size_t indexZ, float valZ)
{
core::matrix4 resultMat;
float *M = resultMat.pointer();
memset(M, 0, 16 * sizeof(float));
assert(indexX < 4);
assert(indexY < 4);
assert(indexZ < 4);
M[indexX] = valX;
M[4 + indexY] = valY;
M[8 + indexZ] = valZ;
return resultMat;
}
GLuint generateSpecularCubemap(GLuint probe)
{
GLuint cubemap_texture;
glGenTextures(1, &cubemap_texture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap_texture);
size_t cubemap_size = 256;
for (int i = 0; i < 6; i++)
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA16F, cubemap_size, cubemap_size, 0, GL_BGRA, GL_FLOAT, 0);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, cubemap_size, cubemap_size);
GLenum bufs[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, bufs);
glUseProgram(UtilShader::SpecularIBLGenerator::getInstance()->Program);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
core::matrix4 M[6] = {
getPermutationMatrix(2, -1., 1, -1., 0, 1.),
getPermutationMatrix(2, 1., 1, -1., 0, -1.),
getPermutationMatrix(0, 1., 2, 1., 1, 1.),
getPermutationMatrix(0, 1., 2, -1., 1, -1.),
getPermutationMatrix(0, 1., 1, -1., 2, 1.),
getPermutationMatrix(0, -1., 1, -1., 2, -1.),
};
for (unsigned level = 0; level < 8; level++)
{
// Blinn Phong can be approximated by Phong with 4x the specular coefficient
// See http://seblagarde.wordpress.com/2012/03/29/relationship-between-phong-and-blinn-lighting-model/
// NOTE : Removed because it makes too sharp reflexion
float roughness = (8 - level) * pow(2.f, 10.f) / 8.f;
float viewportSize = float(1 << (8 - level));
float *tmp = new float[2048];
for (unsigned i = 0; i < 1024; i++)
{
std::pair<float, float> sample = ImportanceSamplingPhong(HammersleySequence(i, 1024), roughness);
tmp[2 * i] = sample.first;
tmp[2 * i + 1] = sample.second;
}
glBindVertexArray(0);
glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples);
GLuint sampleTex, sampleBuffer;
glGenBuffers(1, &sampleBuffer);
glBindBuffer(GL_TEXTURE_BUFFER, sampleBuffer);
glBufferData(GL_TEXTURE_BUFFER, 2048 * sizeof(float), tmp, GL_STATIC_DRAW);
glGenTextures(1, &sampleTex);
glBindTexture(GL_TEXTURE_BUFFER, sampleTex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, sampleBuffer);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
for (unsigned face = 0; face < 6; face++)
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap_texture, level);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status == GL_FRAMEBUFFER_COMPLETE);
UtilShader::SpecularIBLGenerator::getInstance()->SetTextureUnits(probe);
UtilShader::SpecularIBLGenerator::getInstance()->setUniforms(M[face], viewportSize);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glActiveTexture(GL_TEXTURE0 + UtilShader::SpecularIBLGenerator::getInstance()->TU_Samples);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, 0);
delete[] tmp;
glDeleteTextures(1, &sampleTex);
glDeleteBuffers(1, &sampleBuffer);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &fbo);
return cubemap_texture;
}

21
src/graphics/IBL.hpp Normal file
View File

@ -0,0 +1,21 @@
#ifndef IBL_HPP
#define IBL_HPP
#include "gl_headers.hpp"
struct Color
{
float Red;
float Green;
float Blue;
};
/** Generate the 9 first SH coefficients for each color channel
using the cubemap provided by CubemapFace.
* \param textures sequence of 6 square textures.
* \param row/columns count of textures.
*/
void SphericalHarmonics(Color *CubemapFace[6], size_t edge_size, float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff);
GLuint generateSpecularCubemap(GLuint probe);
#endif

View File

@ -46,17 +46,6 @@ debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei le
return;
}
// Suppress warnings about GL_ARB_bindless_texture not being supported
// when we're not even using it
if (UserConfigParams::m_azdo == false &&
source == GL_DEBUG_SOURCE_SHADER_COMPILER_ARB && msg != NULL &&
std::string(msg).find("GL_ARB_bindless_texture") != std::string::npos)
{
Log::debug("GLWrap", "Suppressed warning: %s", msg);
return;
}
switch(source)
{
case GL_DEBUG_SOURCE_API_ARB:

View File

@ -67,6 +67,7 @@
#include "utils/vs.hpp"
#include <irrlicht.h>
#include "../lib/irrlicht/source/Irrlicht/CSkinnedMesh.h"
/* Build-time check that the Irrlicht we're building against works for us.
* Should help prevent distros building against an incompatible library.
@ -533,6 +534,7 @@ void IrrDriver::initDevice()
hasComputeShaders = false;
hasTextureStorage = false;
hasTextureView = false;
hasBindlessTexture = false;
// Default false value for hasVSLayer if --no-graphics argument is used
#if !defined(__APPLE__)
if (!ProfileWorld::isNoGraphics())
@ -565,6 +567,10 @@ void IrrDriver::initDevice()
hasTextureView = true;
Log::info("GLDriver", "ARB Texture View enabled");
}
if (hasGLExtension("GL_ARB_bindless_texture")) {
hasBindlessTexture = true;
Log::info("GLDriver", "ARB Bindless Texture enabled");
}
m_support_sdsm = m_support_sdsm && hasComputeShaders && hasBuffserStorage;
std::string driver((char*)(glGetString(GL_VERSION)));
@ -990,6 +996,26 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
return am->getMesh(0);
} // getMesh
// ----------------------------------------------------------------------------
/** Create a skinned mesh which has copied all meshbuffers and joints of the
* original mesh. Note, that this will not copy any other information like
* joints data.
* \param mesh Original mesh
* \return Newly created skinned mesh. You should call drop() when you don't
* need it anymore.
*/
scene::IAnimatedMesh *IrrDriver::copyAnimatedMesh(scene::IAnimatedMesh *orig)
{
using namespace scene;
CSkinnedMesh *mesh = dynamic_cast<CSkinnedMesh*>(orig);
if (!mesh)
{
Log::error("copyAnimatedMesh", "Given mesh was not a skinned mesh.");
return NULL;
}
return mesh->clone();
} // copyAnimatedMesh
// ----------------------------------------------------------------------------
/** Sets the material flags in this mesh depending on the settings in
* material_manager.
@ -1365,6 +1391,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
SkyboxTextures = texture;
SphericalHarmonicsTextures = sphericalHarmonics;
SkyboxCubeMap = 0;
SkyboxSpecularProbe = 0;
m_SH_dirty = true;
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
texture[2], texture[3],
@ -1377,8 +1404,12 @@ void IrrDriver::suppressSkyBox()
SphericalHarmonicsTextures.clear();
m_SH_dirty = true;
if ((SkyboxCubeMap) && (!ProfileWorld::isNoGraphics()))
{
glDeleteTextures(1, &SkyboxCubeMap);
glDeleteTextures(1, &SkyboxSpecularProbe);
}
SkyboxCubeMap = 0;
SkyboxSpecularProbe = 0;
}
// ----------------------------------------------------------------------------

View File

@ -191,6 +191,7 @@ private:
bool hasComputeShaders;
bool hasTextureStorage;
bool hasTextureView;
bool hasBindlessTexture;
bool m_support_sdsm;
bool m_support_texture_compression;
bool m_need_ubo_workaround;
@ -254,6 +255,7 @@ private:
public:
GLuint SkyboxCubeMap;
GLuint SkyboxSpecularProbe;
/** A simple class to store video resolutions. */
class VideoMode
{
@ -296,6 +298,11 @@ public:
return UserConfigParams::m_texture_compression && m_support_texture_compression;
}
bool useAZDO() const
{
return hasBindlessTexture && UserConfigParams::m_azdo;
}
bool needUBOWorkaround() const
{
return m_need_ubo_workaround;
@ -346,6 +353,11 @@ public:
return hasTextureView;
}
bool hasARBBindlessTexture() const
{
return hasBindlessTexture;
}
video::SColorf getAmbientLight() const;
struct GlowData {
@ -459,6 +471,7 @@ public:
void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name);
scene::IAnimatedMesh *copyAnimatedMesh(scene::IAnimatedMesh *orig);
video::ITexture *applyMask(video::ITexture* texture,
const std::string& mask_path);
void displayFPS();

View File

@ -228,12 +228,12 @@ void PostProcessing::renderEnvMap(const float *bSHCoeff, const float *gSHCoeff,
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glUseProgram(FullScreenShader::EnvMapShader::getInstance()->Program);
glUseProgram(FullScreenShader::IBLShader::getInstance()->Program);
glBindVertexArray(SharedObject::FullScreenQuadVAO);
FullScreenShader::EnvMapShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox);
FullScreenShader::IBLShader::getInstance()->SetTextureUnits(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox);
core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed();
FullScreenShader::EnvMapShader::getInstance()->setUniforms(TVM, std::vector<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
FullScreenShader::IBLShader::getInstance()->setUniforms(TVM, std::vector<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
@ -329,20 +329,43 @@ void PostProcessing::renderGaussian6BlurLayer(FrameBuffer &in_fbo, size_t layer,
}
else
{
float g0, g1, g2;
std::vector<float> weightsV;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaV);
g1 = exp(-.5f / (sigmaV * sigmaV));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsV.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeShadowBlurVShader::getInstance()->Program);
FullScreenShader::ComputeShadowBlurVShader::getInstance()->SetTextureUnits(LayerTex);
glBindSampler(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeShadowBlurVShader::getInstance()->TU_dest, irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R32F);
FullScreenShader::ComputeShadowBlurVShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), sigmaV);
FullScreenShader::ComputeShadowBlurVShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), weightsV);
glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1);
std::vector<float> weightsH;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaH);
g1 = exp(-.5f / (sigmaH * sigmaH));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsH.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeShadowBlurHShader::getInstance()->Program);
FullScreenShader::ComputeShadowBlurHShader::getInstance()->SetTextureUnits(irr_driver->getFBO(FBO_SCALAR_1024).getRTT()[0]);
glBindSampler(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeShadowBlurHShader::getInstance()->TU_dest, LayerTex, 0, false, 0, GL_WRITE_ONLY, GL_R32F);
FullScreenShader::ComputeShadowBlurHShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), sigmaH);
FullScreenShader::ComputeShadowBlurHShader::getInstance()->setUniforms(core::vector2df(1.f / 1024.f, 1.f / 1024.f), weightsH);
glDispatchCompute((int)1024 / 8 + 1, (int)1024 / 8 + 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
@ -353,45 +376,63 @@ void PostProcessing::renderGaussian6Blur(FrameBuffer &in_fbo, FrameBuffer &auxil
{
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
if (!irr_driver->hasARBComputeShaders())
{
auxiliary.Bind();
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height), sigmaV);
}
else
{
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), sigmaV);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
}
}
if (!irr_driver->hasARBComputeShaders())
{
if (!irr_driver->hasARBComputeShaders())
{
in_fbo.Bind();
auxiliary.Bind();
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height), sigmaH);
}
else
{
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), sigmaH);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
FullScreenShader::Gaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6VBlurShader>(core::vector2df(inv_width, inv_height), sigmaV);
in_fbo.Bind();
FullScreenShader::Gaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
DrawFullScreenEffect<FullScreenShader::Gaussian6HBlurShader>(core::vector2df(inv_width, inv_height), sigmaH);
}
else
{
float g0, g1, g2;
std::vector<float> weightsV;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaV);
g1 = exp(-.5f / (sigmaV * sigmaV));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsV.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->SetTextureUnits(in_fbo.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6VBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), weightsV);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
std::vector<float> weightsH;
g0 = 1.f / (sqrtf(2.f * 3.14f) * sigmaH);
g1 = exp(-.5f / (sigmaH * sigmaH));
g2 = g1 * g1;
for (unsigned i = 0; i < 7; i++)
{
weightsH.push_back(g0);
g0 *= g1;
g1 *= g2;
}
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->Program);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->SetTextureUnits(auxiliary.getRTT()[0]);
glBindSampler(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_RGBA16F);
FullScreenShader::ComputeGaussian6HBlurShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height), weightsH);
glDispatchCompute((int)in_fbo.getWidth() / 8 + 1, (int)in_fbo.getHeight() / 8 + 1, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
}
void PostProcessing::renderHorizontalBlur(FrameBuffer &in_fbo, FrameBuffer &auxiliary)

View File

@ -440,12 +440,14 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
if (getRH())
{
glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).Bind();
m_post_processing->renderRHDebug(m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2], rh_matrix, rh_extend);
}
if (getGI())
{
glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).Bind();
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
}
@ -1029,7 +1031,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
glUseProgram(MeshShader::InstancedColorizeShader::getInstance()->Program);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(video::EVT_STANDARD, InstanceTypeGlow));
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (GlowPassCmd::getInstance()->Size)
{

View File

@ -427,7 +427,7 @@ void renderMeshes1stPass()
continue;
}
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
HandleExpander<typename T::FirstPassShader>::template Expand(mesh.TextureHandles, T::FirstPassTextures);
else
TexExpander<typename T::FirstPassShader>::template ExpandTex(mesh, T::FirstPassTextures);
@ -500,7 +500,7 @@ void IrrDriver::renderSolidFirstPass()
renderMeshes1stPass<SphereMap, 2, 1>();
renderMeshes1stPass<DetailMat, 2, 1>();
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
multidraw1stPass<DefaultMaterial>();
multidraw1stPass<AlphaRef>();
@ -546,7 +546,7 @@ void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
continue;
}
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
HandleExpander<typename T::SecondPassShader>::template Expand(mesh.TextureHandles, T::SecondPassTextures, Prefilled_Handle[0], Prefilled_Handle[1], Prefilled_Handle[2]);
else
TexExpander<typename T::SecondPassShader>::template ExpandTex(mesh, T::SecondPassTextures, Prefilled_Tex[0], Prefilled_Tex[1], Prefilled_Tex[2]);
@ -595,7 +595,7 @@ void IrrDriver::renderSolidSecondPass()
uint64_t DiffuseHandle = 0, SpecularHandle = 0, SSAOHandle = 0, DepthHandle = 0;
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
DiffuseHandle = glGetTextureSamplerHandleARB(m_rtts->getRenderTarget(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
@ -633,7 +633,7 @@ void IrrDriver::renderSolidSecondPass()
renderMeshes2ndPass<GrassMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
renderMeshes2ndPass<NormalMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
multidraw2ndPass<DefaultMaterial>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0));
multidraw2ndPass<AlphaRef>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0));
@ -714,7 +714,7 @@ static void renderMultiMeshNormals()
void IrrDriver::renderNormalsVisualisation()
{
if (UserConfigParams::m_azdo) {
if (irr_driver->useAZDO()) {
renderMultiMeshNormals<DefaultMaterial>();
renderMultiMeshNormals<AlphaRef>();
renderMultiMeshNormals<UnlitMat>();
@ -752,7 +752,7 @@ void renderTransparenPass(const std::vector<TexUnit> &TexUnits, std::vector<STK:
continue;
}
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
Shader::getInstance()->SetTextureHandles(mesh.TextureHandles[0]);
else
Shader::getInstance()->SetTextureUnits(getTextureGLuint(mesh.textures[0]));
@ -932,7 +932,7 @@ void renderShadow(unsigned cascade)
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
if (!irr_driver->hasARB_base_instance())
glBindVertexArray(mesh->vao);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
HandleExpander<typename T::ShadowPassShader>::template Expand(mesh->TextureHandles, T::ShadowTextures);
else
TexExpander<typename T::ShadowPassShader>::template ExpandTex(*mesh, T::ShadowTextures);
@ -1004,7 +1004,7 @@ void IrrDriver::renderShadows()
if (irr_driver->hasARB_draw_indirect())
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
multidrawShadow<DefaultMaterial>(cascade);
multidrawShadow<DetailMat>(cascade);
@ -1081,7 +1081,7 @@ void drawRSM(const core::matrix4 & rsm_matrix)
GLMesh *mesh = STK::tuple_get<0>(t.at(i));
if (!irr_driver->hasARB_base_instance())
glBindVertexArray(mesh->vao);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
HandleExpander<typename T::RSMShader>::template Expand(mesh->TextureHandles, T::RSMTextures);
else
TexExpander<typename T::RSMShader>::template ExpandTex(*mesh, T::RSMTextures);
@ -1138,7 +1138,7 @@ void IrrDriver::renderRSM()
if (irr_driver->hasARB_draw_indirect())
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
multidrawRSM<DefaultMaterial>(rsm_matrix);
multidrawRSM<NormalMat>(rsm_matrix);

View File

@ -155,7 +155,7 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff, SkyboxCubeMap);
m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff, SkyboxSpecularProbe);
}
// Render sunlight if and only if track supports shadow

View File

@ -1,3 +1,4 @@
#include "graphics/IBL.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/shaders.hpp"
#include "modes/world.hpp"
@ -6,88 +7,6 @@
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
{
switch (face)
{
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
x = 1.;
y = -i;
z = -j;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
x = -1.;
y = -i;
z = j;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
x = j;
y = 1.;
z = i;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
x = j;
y = -1;
z = -i;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
x = j;
y = -i;
z = 1;
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
x = -j;
y = -i;
z = -1;
break;
}
float norm = sqrt(x * x + y * y + z * z);
x /= norm, y /= norm, z /= norm;
return;
}
static void getYml(GLenum face, size_t width, size_t height,
float *Y00,
float *Y1minus1, float *Y10, float *Y11,
float *Y2minus2, float *Y2minus1, float *Y20, float *Y21, float *Y22)
{
for (unsigned i = 0; i < width; i++)
{
for (unsigned j = 0; j < height; j++)
{
float x, y, z;
float fi = float(i), fj = float(j);
fi /= width, fj /= height;
fi = 2 * fi - 1, fj = 2 * fj - 1;
getXYZ(face, fi, fj, x, y, z);
// constant part of Ylm
float c00 = 0.282095f;
float c1minus1 = 0.488603f;
float c10 = 0.488603f;
float c11 = 0.488603f;
float c2minus2 = 1.092548f;
float c2minus1 = 1.092548f;
float c21 = 1.092548f;
float c20 = 0.315392f;
float c22 = 0.546274f;
size_t idx = i * height + j;
Y00[idx] = c00;
Y1minus1[idx] = c1minus1 * y;
Y10[idx] = c10 * z;
Y11[idx] = c11 * x;
Y2minus2[idx] = c2minus2 * x * y;
Y2minus1[idx] = c2minus1 * y * z;
Y21[idx] = c21 * x * z;
Y20[idx] = c20 * (3 * z * z - 1);
Y22[idx] = c22 * (x * x - y * y);
}
}
}
static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, float *Coeff, float *Y00, float *Y1minus1, float *Y10, float *Y11,
float *Y2minus2, float * Y2minus1, float * Y20, float *Y21, float *Y22)
{
@ -130,77 +49,6 @@ static void unprojectSH(float *output[], size_t width, size_t height,
}
}
static void projectSH(float *color[], size_t width, size_t height,
float *Y00[],
float *Y1minus1[], float *Y10[], float *Y11[],
float *Y2minus2[], float *Y2minus1[], float * Y20[], float *Y21[], float *Y22[],
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff
)
{
for (unsigned i = 0; i < 9; i++)
{
blueSHCoeff[i] = 0;
greenSHCoeff[i] = 0;
redSHCoeff[i] = 0;
}
float wh = float(width * height);
for (unsigned face = 0; face < 6; face++)
{
for (unsigned i = 0; i < width; i++)
{
for (unsigned j = 0; j < height; j++)
{
size_t idx = i * height + j;
float fi = float(i), fj = float(j);
fi /= width, fj /= height;
fi = 2 * fi - 1, fj = 2 * fj - 1;
float d = sqrt(fi * fi + fj * fj + 1);
// Constant obtained by projecting unprojected ref values
float solidangle = 2.75f / (wh * pow(d, 1.5f));
// pow(., 2.2) to convert from srgb
float b = pow(color[face][4 * height * i + 4 * j] / 255.f, 2.2f);
float g = pow(color[face][4 * height * i + 4 * j + 1] / 255.f, 2.2f);
float r = pow(color[face][4 * height * i + 4 * j + 2] / 255.f, 2.2f);
assert(b >= 0.);
blueSHCoeff[0] += b * Y00[face][idx] * solidangle;
blueSHCoeff[1] += b * Y1minus1[face][idx] * solidangle;
blueSHCoeff[2] += b * Y10[face][idx] * solidangle;
blueSHCoeff[3] += b * Y11[face][idx] * solidangle;
blueSHCoeff[4] += b * Y2minus2[face][idx] * solidangle;
blueSHCoeff[5] += b * Y2minus1[face][idx] * solidangle;
blueSHCoeff[6] += b * Y20[face][idx] * solidangle;
blueSHCoeff[7] += b * Y21[face][idx] * solidangle;
blueSHCoeff[8] += b * Y22[face][idx] * solidangle;
greenSHCoeff[0] += g * Y00[face][idx] * solidangle;
greenSHCoeff[1] += g * Y1minus1[face][idx] * solidangle;
greenSHCoeff[2] += g * Y10[face][idx] * solidangle;
greenSHCoeff[3] += g * Y11[face][idx] * solidangle;
greenSHCoeff[4] += g * Y2minus2[face][idx] * solidangle;
greenSHCoeff[5] += g * Y2minus1[face][idx] * solidangle;
greenSHCoeff[6] += g * Y20[face][idx] * solidangle;
greenSHCoeff[7] += g * Y21[face][idx] * solidangle;
greenSHCoeff[8] += g * Y22[face][idx] * solidangle;
redSHCoeff[0] += r * Y00[face][idx] * solidangle;
redSHCoeff[1] += r * Y1minus1[face][idx] * solidangle;
redSHCoeff[2] += r * Y10[face][idx] * solidangle;
redSHCoeff[3] += r * Y11[face][idx] * solidangle;
redSHCoeff[4] += r * Y2minus2[face][idx] * solidangle;
redSHCoeff[5] += r * Y2minus1[face][idx] * solidangle;
redSHCoeff[6] += r * Y20[face][idx] * solidangle;
redSHCoeff[7] += r * Y21[face][idx] * solidangle;
redSHCoeff[8] += r * Y22[face][idx] * solidangle;
}
}
}
}
static void displayCoeff(float *SHCoeff)
{
@ -210,7 +58,7 @@ static void displayCoeff(float *SHCoeff)
}
// Only for 9 coefficients
static void testSH(unsigned char *color[6], size_t width, size_t height,
/*static void testSH(unsigned char *color[6], size_t width, size_t height,
float *blueSHCoeff, float *greenSHCoeff, float *redSHCoeff)
{
float *Y00[6];
@ -250,7 +98,7 @@ static void testSH(unsigned char *color[6], size_t width, size_t height,
getYml(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, width, height, Y00[face], Y1minus1[face], Y10[face], Y11[face], Y2minus2[face], Y2minus1[face], Y20[face], Y21[face], Y22[face]);
}
/* blueSHCoeff[0] = 0.54,
blueSHCoeff[0] = 0.54,
blueSHCoeff[1] = .6, blueSHCoeff[2] = -.27, blueSHCoeff[3] = .01,
blueSHCoeff[4] = -.12, blueSHCoeff[5] = -.47, blueSHCoeff[6] = -.15, blueSHCoeff[7] = .14, blueSHCoeff[8] = -.3;
greenSHCoeff[0] = .44,
@ -267,12 +115,12 @@ static void testSH(unsigned char *color[6], size_t width, size_t height,
printf("Red:\n");
displayCoeff(redSHCoeff);*/
projectSH(testoutput, width, height,
/* projectSH(testoutput, width, height,
Y00,
Y1minus1, Y10, Y11,
Y2minus2, Y2minus1, Y20, Y21, Y22,
blueSHCoeff, greenSHCoeff, redSHCoeff
);
);*/
//printf("Blue:\n");
//displayCoeff(blueSHCoeff);
@ -319,7 +167,7 @@ static void testSH(unsigned char *color[6], size_t width, size_t height,
printf("Red:\n");
displayCoeff(redSHCoeff);
printf("\nAfter projection\n\n");*/
printf("\nAfter projection\n\n");
@ -346,7 +194,7 @@ static void testSH(unsigned char *color[6], size_t width, size_t height,
delete[] Y21[face];
delete[] Y22[face];
}
}
}*/
void swapPixels(char *old_img, char *new_img, unsigned stride, unsigned old_i, unsigned old_j, unsigned new_i, unsigned new_j)
{
@ -356,6 +204,7 @@ void swapPixels(char *old_img, char *new_img, unsigned stride, unsigned old_i, u
new_img[4 * (stride * new_i + new_j) + 3] = old_img[4 * (stride * old_i + old_j) + 3];
}
/** Generate an opengl cubemap texture from 6 2d textures.
Out of legacy the sequence of textures maps to :
- 1st texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Y
@ -431,6 +280,7 @@ void IrrDriver::generateSkyboxCubemap()
assert(SkyboxTextures.size() == 6);
SkyboxCubeMap = generateCubeMapFromTextures(SkyboxTextures);
SkyboxSpecularProbe = generateSpecularCubemap(SkyboxCubeMap);
}
void IrrDriver::generateDiffuseCoefficients()
@ -440,16 +290,18 @@ void IrrDriver::generateDiffuseCoefficients()
m_SH_dirty = false;
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
unsigned sh_w = 0, sh_h = 0;
unsigned char *sh_rgba[6];
if (SphericalHarmonicsTextures.size() == 6)
{
unsigned sh_w = 0, sh_h = 0;
for (unsigned i = 0; i < 6; i++)
{
sh_w = MAX2(sh_w, SphericalHarmonicsTextures[i]->getOriginalSize().Width);
sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getOriginalSize().Height);
}
unsigned char *sh_rgba[6];
for (unsigned i = 0; i < 6; i++)
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
for (unsigned i = 0; i < 6; i++)
@ -468,24 +320,19 @@ void IrrDriver::generateDiffuseCoefficients()
delete image;
}
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
for (unsigned i = 0; i < 6; i++)
delete[] sh_rgba[i];
}
else
{
int sh_w = 16;
int sh_h = 16;
sh_w = 16;
sh_h = 16;
video::SColor ambient = m_scene_manager->getAmbientLight().toSColor();
unsigned char *sh_rgba[6];
for (unsigned i = 0; i < 6; i++)
{
sh_rgba[i] = new unsigned char[sh_w * sh_h * 4];
for (int j = 0; j < sh_w * sh_h * 4; j += 4)
for (unsigned j = 0; j < sh_w * sh_h * 4; j += 4)
{
sh_rgba[i][j] = ambient.getBlue();
sh_rgba[i][j + 1] = ambient.getGreen();
@ -493,9 +340,31 @@ void IrrDriver::generateDiffuseCoefficients()
sh_rgba[i][j + 3] = 255;
}
}
}
testSH(sh_rgba, sh_w, sh_h, blueSHCoeff, greenSHCoeff, redSHCoeff);
// Convert to float texture
Color *FloatTexCube[6];
for (unsigned i = 0; i < 6; i++)
{
FloatTexCube[i] = new Color[sh_w * sh_h];
for (unsigned j = 0; j < sh_w * sh_h; j++)
{
FloatTexCube[i][j].Blue = powf(float(0xFF & sh_rgba[i][4 * j]) / 255.f, 2.2f);
FloatTexCube[i][j].Green = powf(float(0xFF & sh_rgba[i][4 * j + 1]) / 255.f, 2.2f);
FloatTexCube[i][j].Red = powf(float(0xFF & sh_rgba[i][4 * j + 2]) / 255.f, 2.2f);
}
}
SphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff);
for (unsigned i = 0; i < 6; i++)
{
delete[] sh_rgba[i];
delete[] FloatTexCube[i];
}
if (SphericalHarmonicsTextures.size() != 6)
{
// Diffuse env map is x 0.25, compensate
for (unsigned i = 0; i < 9; i++)
{
@ -503,19 +372,7 @@ void IrrDriver::generateDiffuseCoefficients()
greenSHCoeff[i] *= 4;
redSHCoeff[i] *= 4;
}
for (unsigned i = 0; i < 6; i++)
delete[] sh_rgba[i];
}
/*for (unsigned i = 0; i < 6; i++)
{
glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);*/
}
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)

View File

@ -147,11 +147,9 @@ GLuint LoadShader(const char * file, unsigned type)
char versionString[20];
sprintf(versionString, "#version %d\n", irr_driver->getGLSLVersion());
std::string Code = versionString;
if (irr_driver->hasVSLayerExtension())
Code += "#extension GL_AMD_vertex_shader_layer : enable\n";
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
Code += "#extension GL_ARB_bindless_texture : enable\n";
else
else if (irr_driver->hasARBBindlessTexture())
{
Code += "#extension GL_ARB_bindless_texture : disable\n";
Code += "#undef GL_ARB_bindless_texture\n";
@ -851,8 +849,8 @@ GLuint createShadowSampler()
glGenSamplers(1, &id);
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
@ -867,8 +865,8 @@ void BindTextureShadow(GLuint TU, GLuint tex)
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
}
@ -889,6 +887,20 @@ unsigned getGLSLVersion()
return irr_driver->getGLSLVersion();
}
namespace UtilShader
{
SpecularIBLGenerator::SpecularIBLGenerator()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/importance_sampling_specular.frag").c_str());
AssignUniforms("PermutationMatrix", "ViewportSize");
TU_Samples = 1;
AssignSamplerNames(Program, 0, "tex");
AssignTextureUnit(Program, TexUnit(TU_Samples, "samples"));
}
}
namespace MeshShader
{
// Solid Normal and depth pass shaders
@ -1426,7 +1438,7 @@ namespace LightShader
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/pointlight.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularBRDF.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/pointlight.frag").c_str());
@ -1625,7 +1637,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularBRDF.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlight.frag").c_str());
@ -1633,15 +1645,17 @@ namespace FullScreenShader
AssignUniforms("direction", "col");
}
EnvMapShader::EnvMapShader()
IBLShader::IBLShader()
{
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/diffuseenvmap.frag").c_str());
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/DiffuseIBL.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularIBL.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/IBL.frag").c_str());
AssignUniforms("TransposeViewMatrix", "blueLmn[0]", "greenLmn[0]", "redLmn[0]");
AssignSamplerNames(Program, 0, "ntex", 1, "dtex", 2, "tex");
AssignSamplerNames(Program, 0, "ntex", 1, "dtex", 2, "probe");
}
ShadowedSunLightShader::ShadowedSunLightShader()
@ -1649,7 +1663,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getSpecular.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/SpecularBRDF.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/sunlightshadow.frag").c_str());
@ -1738,7 +1752,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussian6h.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}
@ -1748,7 +1762,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/blurshadowH.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}
@ -1808,7 +1822,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/gaussian6v.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}
@ -1818,7 +1832,7 @@ namespace FullScreenShader
Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/blurshadowV.comp").c_str());
TU_dest = 1;
AssignUniforms("pixel", "sigma");
AssignUniforms("pixel", "weights");
AssignSamplerNames(Program, 0, "source");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
}
@ -1850,7 +1864,7 @@ namespace FullScreenShader
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/texturedquad.frag").c_str());
AssignUniforms();
AssignSamplerNames(Program, 0, "texture");
AssignSamplerNames(Program, 0, "tex");
vao = createVAO(Program);
}

View File

@ -48,6 +48,13 @@ public:
static void init();
static void setUniforms(const irr::video::SColor &);
};
class SpecularIBLGenerator : public ShaderHelperSingleton<SpecularIBLGenerator, core::matrix4, float >, public TextureRead<Trilinear_cubemap>
{
public:
GLuint TU_Samples;
SpecularIBLGenerator();
};
}
@ -411,10 +418,10 @@ public:
SunLightShader();
};
class EnvMapShader : public ShaderHelperSingleton<EnvMapShader, core::matrix4, std::vector<float>, std::vector<float>, std::vector<float> >, public TextureRead<Nearest_Filtered, Nearest_Filtered, Trilinear_cubemap>
class IBLShader : public ShaderHelperSingleton<IBLShader, core::matrix4, std::vector<float>, std::vector<float>, std::vector<float> >, public TextureRead<Nearest_Filtered, Nearest_Filtered, Trilinear_cubemap>
{
public:
EnvMapShader();
IBLShader();
};
class ShadowedSunLightShader : public ShaderHelperSingleton<ShadowedSunLightShader, float, float, float, float, core::vector3df, video::SColorf>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Shadow_Sampler>
@ -464,14 +471,14 @@ public:
ComputeGaussian17TapHShader();
};
class ComputeGaussian6HBlurShader : public ShaderHelperSingleton<ComputeGaussian6HBlurShader, core::vector2df, float>, public TextureRead<Bilinear_Clamped_Filtered>
class ComputeGaussian6HBlurShader : public ShaderHelperSingleton<ComputeGaussian6HBlurShader, core::vector2df, std::vector<float> >, public TextureRead<Bilinear_Clamped_Filtered>
{
public:
GLuint TU_dest;
ComputeGaussian6HBlurShader();
};
class ComputeShadowBlurHShader : public ShaderHelperSingleton<ComputeShadowBlurHShader, core::vector2df, float>, public TextureRead<Neared_Clamped_Filtered>
class ComputeShadowBlurHShader : public ShaderHelperSingleton<ComputeShadowBlurHShader, core::vector2df, std::vector<float> >, public TextureRead<Neared_Clamped_Filtered>
{
public:
GLuint TU_dest;
@ -510,14 +517,14 @@ public:
ComputeGaussian17TapVShader();
};
class ComputeGaussian6VBlurShader : public ShaderHelperSingleton<ComputeGaussian6VBlurShader, core::vector2df, float>, public TextureRead<Bilinear_Clamped_Filtered>
class ComputeGaussian6VBlurShader : public ShaderHelperSingleton<ComputeGaussian6VBlurShader, core::vector2df, std::vector<float> >, public TextureRead<Bilinear_Clamped_Filtered>
{
public:
GLuint TU_dest;
ComputeGaussian6VBlurShader();
};
class ComputeShadowBlurVShader : public ShaderHelperSingleton<ComputeShadowBlurVShader, core::vector2df, float>, public TextureRead<Neared_Clamped_Filtered>
class ComputeShadowBlurVShader : public ShaderHelperSingleton<ComputeShadowBlurVShader, core::vector2df, std::vector<float> >, public TextureRead<Neared_Clamped_Filtered>
{
public:
GLuint TU_dest;

View File

@ -34,11 +34,7 @@ TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE typ
{
if (type == irr_driver->getShader(ES_DISPLACE))
return TM_DISPLACEMENT;
video::E_BLEND_FACTOR srcFact, DstFact;
video::E_MODULATE_FUNC mod;
u32 alpha;
unpack_textureBlendFunc(srcFact, DstFact, mod, alpha, MaterialTypeParam);
if (DstFact == video::EBF_ONE || type == video::EMT_TRANSPARENT_ADD_COLOR)
if (material->getShaderType() == Material::SHADERTYPE_ADDITIVE)
return TM_ADDITIVE;
return TM_DEFAULT;
}
@ -290,7 +286,7 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb, const std::string &matname)
return;
}
compressTexture(mesh.textures[i], isSrgb);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (!mesh.TextureHandles[i])
mesh.TextureHandles[i] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[i]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);
@ -363,7 +359,7 @@ void InitTexturesTransparent(GLMesh &mesh)
return;
}
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);

View File

@ -142,6 +142,8 @@ void STKMeshSceneNode::updateNoGL()
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam, material);
if (!immediate_draw)
TransparentMesh[TranspMat].push_back(&mesh);
else
additive = (TranspMat == TM_ADDITIVE);
}
else
{
@ -267,7 +269,7 @@ void STKMeshSceneNode::render()
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::ObjectPass1Shader::getInstance()->SamplersId[0]);
@ -305,7 +307,7 @@ void STKMeshSceneNode::render()
GLenum itype = mesh.IndexType;
size_t count = mesh.IndexCount;
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
@ -370,7 +372,10 @@ void STKMeshSceneNode::render()
{
if (update_each_frame)
updatevbo();
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (additive)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
if (World::getWorld() && World::getWorld()->isFogEnabled())
{
@ -398,7 +403,7 @@ void STKMeshSceneNode::render()
tmpcol.getBlue() / 255.0f);
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
@ -428,7 +433,7 @@ void STKMeshSceneNode::render()
size_t count = mesh.IndexCount;
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
{
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]);

View File

@ -21,6 +21,7 @@ protected:
bool isMaterialInitialized;
bool isGLInitialized;
bool immediate_draw;
bool additive;
bool update_each_frame;
bool isDisplacement;
bool isGlow;

View File

@ -143,7 +143,7 @@ void FillInstances(const std::unordered_map<scene::IMeshBuffer *, std::vector<st
for (; It != E; ++It)
{
FillInstances_impl<T>(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount);
if (!UserConfigParams::m_azdo)
if (!irr_driver->useAZDO())
InstancedList.push_back(It->second.front().first);
}
}
@ -527,7 +527,7 @@ GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
if (irr_driver->hasARB_draw_indirect())
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
FillInstances<T>(MeshForShadowPass[Mat][cascade], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount);
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
}
@ -734,11 +734,11 @@ PROFILER_POP_CPU_MARKER();
{
size_t Polycnt = 0;
FillInstances_impl<GlowInstanceData>(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, Polycnt);
if (!UserConfigParams::m_azdo)
if (!irr_driver->useAZDO())
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
}
if (UserConfigParams::m_azdo)
if (irr_driver->useAZDO())
GlowPassCmd::getInstance()->Size = current_cmd - GlowPassCmd::getInstance()->Offset;
if (!irr_driver->hasBufferStorageExtension())

View File

@ -288,7 +288,7 @@ namespace GUIEngine
\n
\subsection prop2 PROP_TEXT
<em> Name in XML files: </em> \c "text"
<em> Name in XML files: </em> \c "text" or "raw_text" ("text" is translated, "raw_text" is not)
gives text (a label) to the widget where supported. Ribbon-grids give a
special meaning to this parameter, see ribbon-grid docs above.

View File

@ -232,6 +232,13 @@ if(prop_name != NULL) widget.m_properties[prop_flag] = core::stringc(prop_name).
widget.m_is_text_rtl = (translations->isRTLLanguage() && widget.m_text != text);
}
const wchar_t* raw_text = xml->getAttributeValue(L"raw_text");
if (raw_text != NULL)
{
widget.m_text = raw_text;
}
if (parent != NULL)
{
widget.setParent(parent);

View File

@ -241,18 +241,22 @@ KartModel::~KartModel()
}
}
if(m_is_master && m_mesh)
// In case of the master, the mesh must be dropped. A non-master KartModel
// has a copy of the master's mesh, so it needs to be dropped, too.
if (m_mesh)
{
m_mesh->drop();
// If there is only one copy left, it's the copy in irrlicht's
// mesh cache, so it can be remove.
if(m_mesh && m_mesh->getReferenceCount()==1)
if (m_is_master)
{
irr_driver->dropAllTextures(m_mesh);
irr_driver->removeMeshFromCache(m_mesh);
// If there is only one copy left, it's the copy in irrlicht's
// mesh cache, so it can be removed.
if (m_mesh && m_mesh->getReferenceCount() == 1)
{
irr_driver->dropAllTextures(m_mesh);
irr_driver->removeMeshFromCache(m_mesh);
}
}
}
#ifdef DEBUG
#if SKELETON_DEBUG
irr_driver->clearDebugMeshes();
@ -280,7 +284,7 @@ KartModel* KartModel::makeCopy()
km->m_kart_height = m_kart_height;
km->m_kart_highest_point= m_kart_highest_point;
km->m_kart_lowest_point = m_kart_lowest_point;
km->m_mesh = m_mesh;
km->m_mesh = irr_driver->copyAnimatedMesh(m_mesh);
km->m_model_filename = m_model_filename;
km->m_animation_speed = m_animation_speed;
km->m_current_animation = AF_DEFAULT;
@ -894,7 +898,8 @@ void KartModel::update(float dt, float rotation_dt, float steer, float speed)
m_animated_node->setCurrentFrame(frame);
} // update
//-----------------------------------------------------------------------------
void KartModel::attachHat(){
void KartModel::attachHat()
{
m_hat_node = NULL;
if(m_hat_name.size()>0)
{

View File

@ -186,7 +186,14 @@ namespace Online
Log::error("HTTPRequest", "Error %d: '%s'.", error,
curl_easy_strerror(error));
}
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 1L);
// In case that there are authentication problems (e.g. on osx)
// disable peer verification. Not ideal, but still better than
// no encryption.
if (UserConfigParams::m_verify_peer)
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 1L);
else
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(m_curl_session, CURLOPT_SSL_VERIFYHOST, 1L);
}
} // prepareOperation

View File

@ -68,25 +68,28 @@ MessageDialog::~MessageDialog()
// ------------------------------------------------------------------------------------------------------
void MessageDialog::doInit(MessageDialogType type,
IConfirmDialogListener* listener, bool own_listener)
IConfirmDialogListener* listener, bool own_listener)
{
if (StateManager::get()->getGameState() == GUIEngine::GAME)
{
World::getWorld()->schedulePause(World::IN_GAME_MENU_PHASE);
}
loadFromFile("confirm_dialog.stkgui");
m_type = type;
m_listener = listener;
m_own_listener = own_listener;
loadFromFile("confirm_dialog.stkgui");
}
void MessageDialog::loadedFromFile()
{
LabelWidget* message = getWidget<LabelWidget>("title");
message->setText( m_msg.c_str(), false );
// If the dialog is a simple 'OK' dialog, then hide the "Yes" button and
// change "Cancel" to "OK"
if (type == MessageDialog::MESSAGE_DIALOG_OK)
if (m_type == MessageDialog::MESSAGE_DIALOG_OK)
{
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm");
yesbtn->setVisible(false);
@ -95,13 +98,13 @@ void MessageDialog::doInit(MessageDialogType type,
cancelbtn->setText(_("OK"));
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
}
else if (type == MessageDialog::MESSAGE_DIALOG_YESNO)
else if (m_type == MessageDialog::MESSAGE_DIALOG_YESNO)
{
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("cancel");
cancelbtn->setText(_("No"));
}
else if (type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL)
else if (m_type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL)
{
// In case of a OK_CANCEL dialog, change the text from 'Yes' to 'Ok'
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm");
@ -109,7 +112,6 @@ void MessageDialog::doInit(MessageDialogType type,
}
}
// ------------------------------------------------------------------------------------------------------
void MessageDialog::onEnterPressedInternal()

View File

@ -64,6 +64,8 @@ public:
enum MessageDialogType { MESSAGE_DIALOG_OK, MESSAGE_DIALOG_CONFIRM,
MESSAGE_DIALOG_OK_CANCEL, MESSAGE_DIALOG_YESNO };
MessageDialogType m_type;
private:
IConfirmDialogListener* m_listener;
@ -96,6 +98,8 @@ public:
virtual void load();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual void loadedFromFile();
};

View File

@ -144,7 +144,7 @@ void OnlineProfileBase::eventCallback(Widget* widget, const std::string& name,
if (selection == m_friends_tab->m_properties[PROP_ID])
sm->replaceTopMostScreen(OnlineProfileFriends::getInstance());
else if (selection == m_achievements_tab->m_properties[PROP_ID])
sm->replaceTopMostScreen(OnlineProfileAchievements::getInstance());
sm->replaceTopMostScreen(TabOnlineProfileAchievements::getInstance());
else if (selection == m_settings_tab->m_properties[PROP_ID])
sm->replaceTopMostScreen(OnlineProfileSettings::getInstance());
}

View File

@ -111,8 +111,14 @@ void BaseUserScreen::init()
// Select the current player. That can only be done after
// updateItemDisplay is called.
if(current_player_index != -1)
selectUser(current_player_index);
if (current_player_index != -1)
{
// Only set focus in case of non-tabbed version (so that keyboard
// or gamepad navigation with tabs works as expected, i.e. you can
// select the next tab without having to go up to the tab list first.
if(!getWidget<RibbonWidget>("options_choice"))
selectUser(current_player_index);
}
// no current player found
// The first player is the most frequently used, so select it
else if (PlayerManager::get()->getNumPlayers() > 0)
@ -586,8 +592,8 @@ void BaseUserScreen::unloaded()
*/
void TabbedUserScreen::init()
{
RibbonWidget* tab_bar = this->getWidget<RibbonWidget>("options_choice");
if (tab_bar != NULL) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
RibbonWidget* tab_bar = getWidget<RibbonWidget>("options_choice");
if (tab_bar) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") );
tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") );
tab_bar->getRibbonChildren()[2].setTooltip(_("User Interface"));

View File

@ -45,13 +45,13 @@ void ModelDefinitionLoader::addModelDefinition(const XMLNode* xml)
std::string lodgroup;
xml->get("lod_group", &lodgroup);
bool tangent = false;
xml->get("tangents", &tangent);
bool skeletal_animation = false;
xml->get("skeletal-animation", &skeletal_animation);
std::string model_name;
xml->get("model", &model_name);
m_lod_groups[lodgroup].push_back(ModelDefinition(xml, (int)lod_distance, model_name, tangent));
m_lod_groups[lodgroup].push_back(ModelDefinition(xml, (int)lod_distance, model_name, false, skeletal_animation));
}
// ----------------------------------------------------------------------------
@ -72,28 +72,51 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc
lod_node->updateAbsolutePosition();
for (unsigned int m=0; m<group.size(); m++)
{
// TODO: check whether the mesh contains animations or not?
scene::IMesh* a_mesh = irr_driver->getMesh(group[m].m_model_file);
if (!a_mesh)
if (group[m].m_skeletal_animation)
{
Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n",
group[m].m_model_file.c_str());
continue;
scene::IAnimatedMesh* a_mesh = irr_driver->getAnimatedMesh(group[m].m_model_file);
if (!a_mesh)
{
Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n",
group[m].m_model_file.c_str());
continue;
}
irr_driver->setAllMaterialFlags(a_mesh);
a_mesh->grab();
//cache.push_back(a_mesh);
irr_driver->grabAllTextures(a_mesh);
m_track->addCachedMesh(a_mesh);
scene::IAnimatedMeshSceneNode* scene_node = irr_driver->addAnimatedMesh(a_mesh, group[m].m_model_file);
m_track->handleAnimatedTextures(scene_node, *group[m].m_xml);
lod_node->add(group[m].m_distance, scene_node, true);
}
else
{
scene::IMesh* a_mesh = irr_driver->getMesh(group[m].m_model_file);
if (!a_mesh)
{
Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n",
group[m].m_model_file.c_str());
continue;
}
a_mesh = MeshTools::createMeshWithTangents(a_mesh, &MeshTools::isNormalMap);
irr_driver->setAllMaterialFlags(a_mesh);
a_mesh = MeshTools::createMeshWithTangents(a_mesh, &MeshTools::isNormalMap);
irr_driver->setAllMaterialFlags(a_mesh);
a_mesh->grab();
//cache.push_back(a_mesh);
irr_driver->grabAllTextures(a_mesh);
m_track->addCachedMesh(a_mesh);
scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh, group[m].m_model_file);
a_mesh->grab();
//cache.push_back(a_mesh);
irr_driver->grabAllTextures(a_mesh);
m_track->addCachedMesh(a_mesh);
scene::IMeshSceneNode* scene_node = irr_driver->addMesh(a_mesh, group[m].m_model_file);
m_track->handleAnimatedTextures( scene_node, *group[m].m_xml );
m_track->handleAnimatedTextures(scene_node, *group[m].m_xml);
lod_node->add( group[m].m_distance, scene_node, true );
lod_node->add(group[m].m_distance, scene_node, true);
}
}
#ifdef DEBUG

View File

@ -42,26 +42,30 @@ namespace irr
struct ModelDefinition
{
std::string m_model_file;
bool m_tangent;
bool m_tangent; // obsolete, TODO remove
const XMLNode* m_xml;
/** For LOD */
int m_distance;
bool m_skeletal_animation;
/** Constructor to allow storing this in STL containers */
ModelDefinition()
{
m_tangent = false;
m_skeletal_animation = false;
m_distance = 0;
m_xml = NULL;
}
ModelDefinition(const XMLNode* xml, int distance, std::string& model, bool tangent)
ModelDefinition(const XMLNode* xml, int distance, std::string& model, bool tangent, bool skeletal_animation)
{
m_model_file = model;
m_tangent = tangent;
m_xml = xml;
m_distance = distance;
m_skeletal_animation = skeletal_animation;
}
~ModelDefinition()