Merge branch 'master' of https://github.com/supertuxkart/stk-code.git
This commit is contained in:
62
INSTALL
62
INSTALL
@@ -1,62 +0,0 @@
|
||||
SUPERTUXKART INSTALLATION INSTRUCTIONS
|
||||
======================================
|
||||
|
||||
Note : If you obtained this source code from github, you also need to download the game assets from sourceforge using SVN.
|
||||
svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets
|
||||
Place the stk-assets folder next to the source root stk-code folder.
|
||||
See http://supertuxkart.sourceforge.net/Source_control for more information
|
||||
|
||||
|
||||
Building STK on Linux
|
||||
--------------------
|
||||
|
||||
First, make sure that you have the following packages installed:
|
||||
|
||||
* OpenGL (mesa)
|
||||
* OpenAL (recommended: openal-soft-devel)
|
||||
* Ogg (libogg-dev)
|
||||
* Vorbis (libvorbis-dev)
|
||||
* libcurl (libcurl-devel)
|
||||
* libbluetooth (bluez-devel)
|
||||
|
||||
Ubuntu command :
|
||||
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
|
||||
|
||||
Unpack the files from the tarball like this:
|
||||
|
||||
tar xzf supertuxkart-*.tar.gz
|
||||
cd supertuxkart-*
|
||||
|
||||
where '*' is the version of SuperTuxkart you downloaded - eg 0.8.0. Then:
|
||||
|
||||
|
||||
* Compile SuperTuxKart:
|
||||
mkdir cmake_build
|
||||
cd cmake_build
|
||||
cmake ..
|
||||
make VERBOSE=1 -j2
|
||||
To create a debug version of STK, use:
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
To test the compilation, supertuxkart can be run from the build
|
||||
directory by ./bin/supertuxkart
|
||||
|
||||
To install the file, as root execute:
|
||||
|
||||
make install
|
||||
|
||||
The default install location is /usr/local, i.e. the data files will
|
||||
be written to /usr/local/share/games/supertuxkart, the executable
|
||||
will be copied to /usr/local/bin. To change the default installation
|
||||
location, specify CMAKE_INSTALL_PREFIX when running cmake, e.g.:
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk
|
||||
|
||||
|
||||
Building STK on OS X
|
||||
--------------------
|
||||
See http://supertuxkart.sourceforge.net/Building_and_packaging_on_OSX
|
||||
|
||||
|
||||
Building STK on Windows
|
||||
-----------------------
|
||||
See http://supertuxkart.sourceforge.net/How_to_build_the_Windows_version
|
||||
71
INSTALL.md
Normal file
71
INSTALL.md
Normal file
@@ -0,0 +1,71 @@
|
||||
#SuperTuxKart Installation Instructions
|
||||
|
||||
Note : If you obtained this source code from github, you also need to download the game assets from sourceforge using SVN.
|
||||
|
||||
`svn checkout https://svn.code.sf.net/p/supertuxkart/code/stk-assets stk-assets`
|
||||
|
||||
Place the `stk-assets` folder next to the source root `stk-code` folder.
|
||||
See <http://supertuxkart.sourceforge.net/Source_control> for more information
|
||||
|
||||
|
||||
##Building STK on Linux
|
||||
|
||||
First, make sure that you have the following packages installed:
|
||||
|
||||
* OpenGL (mesa)
|
||||
* OpenAL (recommended: openal-soft-devel)
|
||||
* Ogg (libogg-dev)
|
||||
* Vorbis (libvorbis-dev)
|
||||
* libcurl (libcurl-devel)
|
||||
* libbluetooth (bluez-devel)
|
||||
|
||||
Ubuntu command:
|
||||
|
||||
```
|
||||
sudo apt-get install autoconf automake build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev \
|
||||
libgl1-mesa-dev libglu1-mesa-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev
|
||||
```
|
||||
|
||||
Unpack the files from the tarball like this:
|
||||
|
||||
```
|
||||
tar xzf supertuxkart-*.tar.gz
|
||||
cd supertuxkart-*
|
||||
```
|
||||
|
||||
where `*` is the version of SuperTuxkart you downloaded - eg `0.8.0`. Then:
|
||||
|
||||
|
||||
Compile SuperTuxKart:
|
||||
|
||||
```
|
||||
mkdir cmake_build
|
||||
cd cmake_build
|
||||
cmake ..
|
||||
make VERBOSE=1 -j2
|
||||
```
|
||||
|
||||
To create a debug version of STK, use:
|
||||
|
||||
`cmake .. -DCMAKE_BUILD_TYPE=Debug`
|
||||
|
||||
To test the compilation, supertuxkart can be run from the build
|
||||
directory by ./bin/supertuxkart
|
||||
|
||||
To install the file, as root execute:
|
||||
|
||||
`make install`
|
||||
|
||||
The default install location is `/usr/local`, i.e. the data files will
|
||||
be written to `/usr/local/share/games/supertuxkart`, the executable
|
||||
will be copied to `/usr/local/bin`. To change the default installation
|
||||
location, specify `CMAKE_INSTALL_PREFIX` when running cmake, e.g.:
|
||||
`cmake .. -DCMAKE_INSTALL_PREFIX=/opt/stk`
|
||||
|
||||
|
||||
##Building STK on OS X
|
||||
See <http://supertuxkart.sourceforge.net/Building_and_packaging_on_OSX>
|
||||
|
||||
|
||||
##Building STK on Windows
|
||||
See <http://supertuxkart.sourceforge.net/How_to_build_the_Windows_version>
|
||||
@@ -1,10 +1,11 @@
|
||||
#version 130
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 res;
|
||||
|
||||
in vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 coords = gl_FragCoord.xy / res;
|
||||
vec2 coords = uv;
|
||||
|
||||
vec4 col = texture2D(tex, coords);
|
||||
float alpha = col.a;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#version 130
|
||||
uniform sampler2D texture; //The texture
|
||||
uniform sampler2D normalMap; //The bump-map
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
noperspective in vec3 tangent;
|
||||
noperspective in vec3 bitangent;
|
||||
noperspective in vec3 normal;
|
||||
in vec2 uv;
|
||||
|
||||
void main()
|
||||
@@ -13,15 +11,11 @@ void main()
|
||||
vec3 TS_normal = 2.0 * texture2D (normalMap, uv).rgb - 1.0;
|
||||
// Because of interpolation, we need to renormalize
|
||||
vec3 Frag_tangent = normalize(tangent);
|
||||
vec3 Frag_bitangent = normalize(cross(normal, tangent));
|
||||
vec3 Frag_normal = cross(Frag_tangent, Frag_bitangent);
|
||||
vec3 Frag_normal = normalize(cross(Frag_tangent, bitangent));
|
||||
vec3 Frag_bitangent = cross(Frag_normal, Frag_tangent);
|
||||
|
||||
|
||||
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent + TS_normal.z * Frag_normal;
|
||||
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
|
||||
FragmentNormal = normalize(FragmentNormal);
|
||||
|
||||
|
||||
gl_FragData[0] = texture2D (texture, uv);
|
||||
gl_FragData[1] = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z);
|
||||
gl_FragData[2] = vec4(0.);
|
||||
gl_FragColor = vec4(0.5 * FragmentNormal + 0.5, gl_FragCoord.z);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform mat4 TransposeInverseModelView;
|
||||
|
||||
in vec3 Position;
|
||||
in vec2 Texcoord;
|
||||
in vec3 Tangent;
|
||||
in vec3 Bitangent;
|
||||
noperspective out vec3 tangent;
|
||||
noperspective out vec3 bitangent;
|
||||
noperspective out vec3 normal;
|
||||
out vec2 uv;
|
||||
|
||||
void main()
|
||||
{
|
||||
uv = gl_MultiTexCoord0.st;
|
||||
normal = (TransposeInverseModelView * vec4(gl_Normal, 1.)).xyz;
|
||||
tangent = (TransposeInverseModelView * gl_MultiTexCoord1).xyz;
|
||||
bitangent = (TransposeInverseModelView * gl_MultiTexCoord2).xyz;
|
||||
gl_Position = ModelViewProjectionMatrix * gl_Vertex;
|
||||
uv = Texcoord;
|
||||
tangent = (TransposeInverseModelView * vec4(Tangent, 1.)).xyz;
|
||||
bitangent = (TransposeInverseModelView * vec4(Bitangent, 1.)).xyz;
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(Position, 1.);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,66 +1,66 @@
|
||||
#version 130
|
||||
uniform sampler2D normals_and_depth;
|
||||
uniform mat4 invprojm;
|
||||
uniform mat4 projm;
|
||||
uniform vec4 samplePoints[16];
|
||||
|
||||
in vec2 uv;
|
||||
|
||||
const float strengh = 4.;
|
||||
const float radius = .4f;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = strengh / SAMPLES;
|
||||
|
||||
// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
#version 130
|
||||
uniform sampler2D normals_and_depth;
|
||||
uniform mat4 invprojm;
|
||||
uniform mat4 projm;
|
||||
uniform vec4 samplePoints[16];
|
||||
|
||||
in vec2 uv;
|
||||
|
||||
const float strengh = 4.;
|
||||
const float radius = .4f;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = strengh / SAMPLES;
|
||||
|
||||
// Found here : http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
float rand(vec2 co)
|
||||
{
|
||||
return fract(sin(dot(co.xy,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 cur = texture2D(normals_and_depth, uv);
|
||||
float curdepth = texture2D(normals_and_depth, uv).a;
|
||||
vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
FragPos /= FragPos.w;
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
|
||||
// Workaround for nvidia and skyboxes
|
||||
float len = dot(vec3(1.0), abs(cur.xyz));
|
||||
if (len < 0.2 || curdepth > 0.99) discard;
|
||||
// Make a tangent as random as possible
|
||||
vec3 randvect;
|
||||
randvect.x = rand(uv);
|
||||
randvect.y = rand(vec2(randvect.x, FragPos.z));
|
||||
randvect.z = rand(randvect.xy);
|
||||
vec3 tangent = normalize(cross(norm, randvect));
|
||||
vec3 bitangent = cross(norm, tangent);
|
||||
|
||||
float bl = 0.0;
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
vec3 sampleDir = samplePoints[i].x * tangent + samplePoints[i].y * bitangent + samplePoints[i].z * norm;
|
||||
sampleDir *= samplePoints[i].w;
|
||||
vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0);
|
||||
vec4 sampleProj = projm * samplePos;
|
||||
sampleProj /= sampleProj.w;
|
||||
|
||||
bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.);
|
||||
// get the depth of the occluder fragment
|
||||
float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a;
|
||||
// Position of the occluder fragment in worldSpace
|
||||
vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f);
|
||||
occluderPos /= occluderPos.w;
|
||||
|
||||
bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius);
|
||||
bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) : 0.;
|
||||
}
|
||||
|
||||
// output the result
|
||||
float ao = 1.0 - bl * invSamples;
|
||||
|
||||
gl_FragColor = vec4(ao);
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 cur = texture2D(normals_and_depth, uv);
|
||||
float curdepth = texture2D(normals_and_depth, uv).a;
|
||||
vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
FragPos /= FragPos.w;
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
|
||||
// Workaround for nvidia and skyboxes
|
||||
float len = dot(vec3(1.0), abs(cur.xyz));
|
||||
if (len < 0.2 || curdepth > 0.999) discard;
|
||||
// Make a tangent as random as possible
|
||||
vec3 randvect;
|
||||
randvect.x = rand(uv);
|
||||
randvect.y = rand(vec2(randvect.x, FragPos.z));
|
||||
randvect.z = rand(randvect.xy);
|
||||
vec3 tangent = normalize(cross(norm, randvect));
|
||||
vec3 bitangent = cross(norm, tangent);
|
||||
|
||||
float bl = 0.0;
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
vec3 sampleDir = samplePoints[i].x * tangent + samplePoints[i].y * bitangent + samplePoints[i].z * norm;
|
||||
sampleDir *= samplePoints[i].w;
|
||||
vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0);
|
||||
vec4 sampleProj = projm * samplePos;
|
||||
sampleProj /= sampleProj.w;
|
||||
|
||||
bool isInsideTexture = (sampleProj.x > -1.) && (sampleProj.x < 1.) && (sampleProj.y > -1.) && (sampleProj.y < 1.);
|
||||
// get the depth of the occluder fragment
|
||||
float occluderFragmentDepth = texture2D(normals_and_depth, (sampleProj.xy * 0.5) + 0.5).a;
|
||||
// Position of the occluder fragment in worldSpace
|
||||
vec4 occluderPos = invprojm * vec4(sampleProj.xy, 2.0 * occluderFragmentDepth - 1.0, 1.0f);
|
||||
occluderPos /= occluderPos.w;
|
||||
|
||||
bool isOccluded = isInsideTexture && (sampleProj.z > (2. * occluderFragmentDepth - 1.0)) && (distance(FragPos, occluderPos) < radius);
|
||||
bl += isOccluded ? smoothstep(radius, 0, distance(samplePos, FragPos)) : 0.;
|
||||
}
|
||||
|
||||
// output the result
|
||||
float ao = 1.0 - bl * invSamples;
|
||||
|
||||
gl_FragColor = vec4(ao);
|
||||
}
|
||||
|
||||
@@ -317,6 +317,21 @@ public:
|
||||
m_color[2] = b;
|
||||
}
|
||||
|
||||
float getRed() const
|
||||
{
|
||||
return m_color[0];
|
||||
}
|
||||
|
||||
float getGreen() const
|
||||
{
|
||||
return m_color[1];
|
||||
}
|
||||
|
||||
float getBlue() const
|
||||
{
|
||||
return m_color[2];
|
||||
}
|
||||
|
||||
private:
|
||||
float m_color[3];
|
||||
};
|
||||
|
||||
@@ -61,18 +61,6 @@ GlowNode::~GlowNode()
|
||||
|
||||
void GlowNode::render()
|
||||
{
|
||||
return;
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
|
||||
drv->setMaterial(mat);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
void GlowNode::OnRegisterSceneNode()
|
||||
|
||||
@@ -413,9 +413,12 @@ void IrrDriver::initDevice()
|
||||
m_scene_manager = m_device->getSceneManager();
|
||||
m_gui_env = m_device->getGUIEnvironment();
|
||||
m_video_driver = m_device->getVideoDriver();
|
||||
m_glsl = m_video_driver->queryFeature(video::EVDF_ARB_GLSL) &&
|
||||
m_video_driver->queryFeature(video::EVDF_TEXTURE_NPOT) &&
|
||||
UserConfigParams::m_pixel_shaders;
|
||||
|
||||
int GLMajorVersion;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion);
|
||||
printf("OPENGL VERSION IS %d\n", GLMajorVersion);
|
||||
m_glsl = (GLMajorVersion >= 3) && UserConfigParams::m_pixel_shaders;
|
||||
|
||||
|
||||
// This remaps the window, so it has to be done before the clear to avoid flicker
|
||||
m_device->setResizable(false);
|
||||
|
||||
@@ -762,6 +762,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
|
||||
if (mb->getVertexType() != video::EVT_TANGENTS)
|
||||
Log::error("material", "Requiring normal map without tangent enabled mesh");
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
if (m_is_heightmap)
|
||||
{
|
||||
|
||||
@@ -425,6 +425,22 @@ namespace PassThroughShader
|
||||
}
|
||||
}
|
||||
|
||||
namespace GlowShader
|
||||
{
|
||||
GLuint Program = 0;
|
||||
GLuint uniform_tex;
|
||||
|
||||
GLuint vao = 0;
|
||||
|
||||
void init()
|
||||
{
|
||||
initGL();
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/glow.frag").c_str());
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
vao = createVAO(Program);
|
||||
}
|
||||
}
|
||||
|
||||
namespace SSAOShader
|
||||
{
|
||||
GLuint Program = 0;
|
||||
@@ -771,6 +787,27 @@ void PostProcessing::renderPassThrough(ITexture *tex)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void PostProcessing::renderGlow(ITexture *tex)
|
||||
{
|
||||
if (!GlowShader::Program)
|
||||
GlowShader::init();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glUseProgram(GlowShader::Program);
|
||||
glBindVertexArray(GlowShader::vao);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName());
|
||||
glUniform1i(GlowShader::uniform_tex, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
|
||||
void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matrix4 &projm)
|
||||
{
|
||||
@@ -787,6 +824,10 @@ void PostProcessing::renderSSAO(const core::matrix4 &invprojm, const core::matri
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<irr::video::COpenGLTexture*>(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH))->getOpenGLTextureName());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glUniform1i(SSAOShader::uniform_normals_and_depth, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
@@ -890,15 +931,8 @@ void PostProcessing::render()
|
||||
renderBloom(in);
|
||||
}
|
||||
|
||||
// Do we have any forced bloom nodes? If so, draw them now
|
||||
const std::vector<IrrDriver::BloomData> &blooms = irr_driver->getForcedBloom();
|
||||
const u32 bloomsize = blooms.size();
|
||||
|
||||
if (!globalbloom && bloomsize)
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), true, false);
|
||||
|
||||
|
||||
if (globalbloom || bloomsize)
|
||||
if (globalbloom)
|
||||
{
|
||||
// Clear the alpha to a suitable value, stencil
|
||||
glClearColor(0, 0, 0, 0.1f);
|
||||
@@ -909,86 +943,6 @@ void PostProcessing::render()
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
|
||||
// The forced-bloom objects are drawn again, to know which pixels to pick.
|
||||
// While it's more drawcalls, there's a cost to using four MRTs over three,
|
||||
// and there shouldn't be many such objects in a track.
|
||||
// The stencil is already in use for the glow. The alpha channel is best
|
||||
// reserved for other use (specular, etc).
|
||||
//
|
||||
// They are drawn with depth and color writes off, giving 4x-8x drawing speed.
|
||||
if (bloomsize)
|
||||
{
|
||||
const core::aabbox3df &cambox = camnode->
|
||||
getViewFrustum()->
|
||||
getBoundingBox();
|
||||
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_SOLID);
|
||||
SOverrideMaterial &overridemat = drv->getOverrideMaterial();
|
||||
overridemat.EnablePasses = ESNRP_SOLID;
|
||||
overridemat.EnableFlags = EMF_MATERIAL_TYPE | EMF_ZWRITE_ENABLE | EMF_COLOR_MASK;
|
||||
overridemat.Enabled = true;
|
||||
|
||||
overridemat.Material.MaterialType = irr_driver->getShader(ES_BLOOM_POWER);
|
||||
overridemat.Material.ZWriteEnable = false;
|
||||
overridemat.Material.ColorMask = ECP_ALPHA;
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilFunc(GL_ALWAYS, 1, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
camnode->render();
|
||||
|
||||
for (u32 i = 0; i < bloomsize; i++)
|
||||
{
|
||||
scene::ISceneNode * const cur = blooms[i].node;
|
||||
|
||||
// Quick box-based culling
|
||||
const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
||||
if (!nodebox.intersectsWithBox(cambox))
|
||||
continue;
|
||||
|
||||
bloomcb->setPower(blooms[i].power);
|
||||
|
||||
cur->render();
|
||||
}
|
||||
|
||||
// Second pass for transparents. No-op for solids.
|
||||
irr_driver->getSceneManager()->setCurrentRendertime(ESNRP_TRANSPARENT);
|
||||
for (u32 i = 0; i < bloomsize; i++)
|
||||
{
|
||||
scene::ISceneNode * const cur = blooms[i].node;
|
||||
|
||||
// Quick box-based culling
|
||||
const core::aabbox3df nodebox = cur->getTransformedBoundingBox();
|
||||
if (!nodebox.intersectsWithBox(cambox))
|
||||
continue;
|
||||
|
||||
bloomcb->setPower(blooms[i].power);
|
||||
|
||||
cur->render();
|
||||
}
|
||||
|
||||
overridemat.Enabled = 0;
|
||||
overridemat.EnablePasses = 0;
|
||||
|
||||
// Ok, we have the stencil; now use it to blit from color to bloom tex
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_EQUAL, 1, ~0);
|
||||
m_material.MaterialType = EMT_SOLID;
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_COLOR));
|
||||
|
||||
// Just in case.
|
||||
glColorMask(1, 1, 1, 0);
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_TMP3), false, false);
|
||||
|
||||
m_material.ColorMask = ECP_RGB;
|
||||
drawQuad(cam, m_material);
|
||||
m_material.ColorMask = ECP_ALL;
|
||||
|
||||
glColorMask(1, 1, 1, 1);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
} // end forced bloom
|
||||
|
||||
// To half
|
||||
drv->setRenderTarget(irr_driver->getRTT(RTT_HALF1), true, false);
|
||||
renderPassThrough(irr_driver->getRTT(RTT_TMP3));
|
||||
|
||||
@@ -88,6 +88,8 @@ public:
|
||||
/** Render tex. Used for blit/texture resize */
|
||||
void renderPassThrough(video::ITexture *tex);
|
||||
|
||||
void renderGlow(video::ITexture *tex);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
void render();
|
||||
|
||||
|
||||
@@ -213,12 +213,6 @@ void IrrDriver::renderGLSL(float dt)
|
||||
// Used to cull glowing items & lights
|
||||
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
|
||||
|
||||
// Render anything glowing.
|
||||
if (!m_mipviz && !m_wireframe)
|
||||
{
|
||||
//renderGlow(overridemat, glows, cambox, cam);
|
||||
} // end glow
|
||||
|
||||
// Shadows
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_shadows &&
|
||||
World::getWorld()->getTrack()->hasShadows())
|
||||
@@ -236,6 +230,13 @@ void IrrDriver::renderGLSL(float dt)
|
||||
m_scene_manager->drawAll(m_renderpass);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
// Render anything glowing.
|
||||
if (!m_mipviz && !m_wireframe)
|
||||
{
|
||||
irr_driver->setPhase(2);
|
||||
renderGlow(overridemat, glows, cambox, cam);
|
||||
} // end glow
|
||||
|
||||
if (!bgnodes)
|
||||
{
|
||||
// If there are no BG nodes, it's more efficient to do the skybox here.
|
||||
@@ -665,10 +666,13 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat,
|
||||
// Blur it
|
||||
m_post_processing->renderGaussian6Blur(m_rtts->getRTT(RTT_QUARTER1), m_rtts->getRTT(RTT_QUARTER2), 4.f / UserConfigParams::m_width, 4.f / UserConfigParams::m_height);
|
||||
|
||||
// The glows will be rendered in the transparent phase
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, EBF_ONE_MINUS_SRC_ALPHA);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
m_video_driver->setRenderTarget(m_rtts->getRTT(RTT_COLOR), false, false);
|
||||
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
m_post_processing->renderGlow(m_rtts->getRTT(RTT_QUARTER1));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
#include <ISceneManager.h>
|
||||
#include <IMaterialRenderer.h>
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/callbacks.hpp"
|
||||
|
||||
static
|
||||
GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, size_t stride)
|
||||
GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, size_t stride)
|
||||
{
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
@@ -16,11 +17,28 @@ GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_t
|
||||
glEnableVertexAttribArray(attrib_texcoord);
|
||||
if ((GLint)attrib_normal != -1)
|
||||
glEnableVertexAttribArray(attrib_normal);
|
||||
if ((GLint)attrib_tangent != -1)
|
||||
glEnableVertexAttribArray(attrib_tangent);
|
||||
if ((GLint)attrib_bitangent != -1)
|
||||
glEnableVertexAttribArray(attrib_bitangent);
|
||||
glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, stride, 0);
|
||||
if ((GLint)attrib_texcoord != -1)
|
||||
glVertexAttribPointer(attrib_texcoord, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 28);
|
||||
if ((GLint)attrib_normal != -1)
|
||||
glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*) 12);
|
||||
if ((GLint)attrib_tangent != -1)
|
||||
{
|
||||
assert(stride >= 48);
|
||||
glVertexAttribPointer(attrib_tangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)36);
|
||||
}
|
||||
|
||||
if ((GLint)attrib_bitangent != -1)
|
||||
{
|
||||
printf("stride of is %d\n", stride);
|
||||
assert(stride >= 60);
|
||||
glVertexAttribPointer(attrib_bitangent, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)48);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx);
|
||||
glBindVertexArray(0);
|
||||
return vao;
|
||||
@@ -83,6 +101,55 @@ namespace ObjectPass2Shader
|
||||
}
|
||||
}
|
||||
|
||||
namespace NormalMapShader
|
||||
{
|
||||
GLuint Program;
|
||||
GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent;
|
||||
GLuint uniform_MVP, uniform_TIMV, uniform_normalMap;
|
||||
|
||||
void init()
|
||||
{
|
||||
initGL();
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
attrib_tangent = glGetAttribLocation(Program, "Tangent");
|
||||
attrib_bitangent = glGetAttribLocation(Program, "Bitangent");
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||
uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView");
|
||||
uniform_normalMap = glGetUniformLocation(Program, "normalMap");
|
||||
}
|
||||
|
||||
void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer());
|
||||
glUniform1i(uniform_normalMap, TU_normalMap);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ColorizeShader
|
||||
{
|
||||
GLuint Program;
|
||||
GLuint attrib_position;
|
||||
GLuint uniform_MVP, uniform_col;
|
||||
|
||||
void init()
|
||||
{
|
||||
initGL();
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/colorize.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||
uniform_col = glGetUniformLocation(Program, "col");
|
||||
}
|
||||
|
||||
void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, float r, float g, float b)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniform3f(uniform_col, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
{
|
||||
@@ -156,9 +223,14 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
}
|
||||
ITexture *tex = mb->getMaterial().getTexture(0);
|
||||
if (tex)
|
||||
result.textures = static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||
result.textures[0] = static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||
else
|
||||
result.textures = 0;
|
||||
result.textures[0] = 0;
|
||||
tex = mb->getMaterial().getTexture(1);
|
||||
if (tex)
|
||||
result.textures[1] = static_cast<irr::video::COpenGLTexture*>(tex)->getOpenGLTextureName();
|
||||
else
|
||||
result.textures[1] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -178,6 +250,8 @@ STKMesh::STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::IScene
|
||||
return;
|
||||
ObjectPass1Shader::init();
|
||||
ObjectPass2Shader::init();
|
||||
NormalMapShader::init();
|
||||
ColorizeShader::init();
|
||||
}
|
||||
|
||||
STKMesh::~STKMesh()
|
||||
@@ -187,7 +261,7 @@ STKMesh::~STKMesh()
|
||||
}
|
||||
|
||||
static
|
||||
void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void drawFirstPass(const GLMesh &mesh)
|
||||
{
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false);
|
||||
|
||||
@@ -220,7 +294,48 @@ void drawFirstPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
}
|
||||
|
||||
static
|
||||
void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void drawNormalPass(const GLMesh &mesh)
|
||||
{
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false);
|
||||
|
||||
glStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable(GL_BLEND);
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
core::matrix4 TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
TransposeInverseModelView.makeInverse();
|
||||
TransposeInverseModelView = TransposeInverseModelView.getTransposed();
|
||||
|
||||
assert(mesh.textures[1]);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh.textures[1]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glUseProgram(NormalMapShader::Program);
|
||||
NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0);
|
||||
|
||||
glBindVertexArray(mesh.vao_first_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glStencilFunc(GL_ALWAYS, 1, ~0);
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false);
|
||||
}
|
||||
|
||||
static
|
||||
void drawSecondPass(const GLMesh &mesh)
|
||||
{
|
||||
irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false);
|
||||
|
||||
@@ -237,7 +352,7 @@ void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh.textures);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh.textures[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
@@ -261,14 +376,52 @@ void drawSecondPass(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
}
|
||||
|
||||
static
|
||||
void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
void drawGlow(const GLMesh &mesh, float r, float g, float b)
|
||||
{
|
||||
if (!mesh.textures)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_BLEND);
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
core::matrix4 ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION);
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
|
||||
ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD);
|
||||
|
||||
glUseProgram(ColorizeShader::Program);
|
||||
ColorizeShader::setUniforms(ModelViewProjectionMatrix, r, g, b);
|
||||
|
||||
glBindVertexArray(mesh.vao_second_pass);
|
||||
glDrawElements(ptype, count, itype, 0);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (!mesh.textures[0])
|
||||
return;
|
||||
if (irr_driver->getPhase() == 0)
|
||||
drawFirstPass(mesh, type);
|
||||
else
|
||||
drawSecondPass(mesh, type);
|
||||
switch (irr_driver->getPhase())
|
||||
{
|
||||
case 0:
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
drawFirstPass(mesh);
|
||||
else if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
drawNormalPass(mesh);
|
||||
break;
|
||||
case 1:
|
||||
drawSecondPass(mesh);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
ColorizeProvider * const cb = (ColorizeProvider *)irr_driver->getCallback(ES_COLORIZE);
|
||||
drawGlow(mesh, cb->getRed(), cb->getGreen(), cb->getBlue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
video::SMaterial material;
|
||||
material.MaterialType = irr_driver->getShader(ES_RAIN);
|
||||
@@ -283,6 +436,8 @@ static bool isObject(video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
return true;
|
||||
if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -290,13 +445,20 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type)
|
||||
{
|
||||
if (mesh.vao_first_pass)
|
||||
return;
|
||||
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal,
|
||||
mesh.Stride);
|
||||
if (type == irr_driver->getShader(ES_OBJECTPASS))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
ObjectPass1Shader::attrib_position, -1, ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride);
|
||||
}
|
||||
else if (type == irr_driver->getShader(ES_NORMAL_MAP))
|
||||
{
|
||||
mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
NormalMapShader::attrib_position, NormalMapShader::attrib_texcoord, -1, NormalMapShader::attrib_tangent, NormalMapShader::attrib_bitangent, mesh.Stride);
|
||||
}
|
||||
mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer,
|
||||
ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1,
|
||||
mesh.Stride);
|
||||
ObjectPass2Shader::attrib_position, ObjectPass2Shader::attrib_texcoord, -1, -1, -1, mesh.Stride);
|
||||
|
||||
mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, ColorizeShader::attrib_position, -1, -1, -1, -1, mesh.Stride);
|
||||
}
|
||||
|
||||
void STKMesh::render()
|
||||
@@ -319,7 +481,7 @@ void STKMesh::render()
|
||||
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
|
||||
if (mb)
|
||||
{
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i];
|
||||
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType);
|
||||
bool transparent = (rnd && rnd->isTransparent());
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
struct GLMesh {
|
||||
GLuint vao_first_pass;
|
||||
GLuint vao_second_pass;
|
||||
GLuint vao_glow_pass;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
GLuint textures;
|
||||
GLuint textures[2];
|
||||
GLenum PrimitiveType;
|
||||
GLenum IndexType;
|
||||
size_t IndexCount;
|
||||
@@ -24,6 +25,7 @@ class STKMesh : public irr::scene::CMeshSceneNode
|
||||
{
|
||||
protected:
|
||||
std::vector<GLMesh> GLmeshes;
|
||||
void draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type);
|
||||
public:
|
||||
STKMesh(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
|
||||
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),
|
||||
|
||||
@@ -171,16 +171,16 @@ void FeatureUnlockedCutScene::addTrophy(RaceManager::Difficulty difficulty)
|
||||
switch (difficulty)
|
||||
{
|
||||
case RaceManager::DIFFICULTY_EASY:
|
||||
msg = _("You completed the easy challenge! This trophy is worth %i points",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY]);
|
||||
msg = _("You completed the easy challenge! Points earned on this level: %i/%i",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_EASY], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]);
|
||||
break;
|
||||
case RaceManager::DIFFICULTY_MEDIUM:
|
||||
msg = _("You completed the intermediate challenge! This trophy is worth %i points",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM]);
|
||||
msg = _("You completed the intermediate challenge! Points earned on this level: %i/%i",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_MEDIUM], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]);
|
||||
break;
|
||||
case RaceManager::DIFFICULTY_HARD:
|
||||
msg = _("You completed the difficult challenge! This trophy is worth %i points",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]);
|
||||
msg = _("You completed the difficult challenge! Points earned on this level: %i/%i",
|
||||
CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD], CHALLENGE_POINTS[RaceManager::DIFFICULTY_HARD]);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
|
||||
@@ -169,7 +169,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
|
||||
std::string render_pass;
|
||||
xml_node.get("renderpass", &render_pass);
|
||||
|
||||
if(render_pass == "skybox")
|
||||
bool skeletal_animation = true; // for backwards compatibility, if unspecified assume there is
|
||||
xml_node.get("skeletal-animation", &skeletal_animation);
|
||||
|
||||
if (render_pass == "skybox")
|
||||
{
|
||||
m_is_in_skybox = true;
|
||||
}
|
||||
@@ -177,8 +180,8 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
|
||||
//std::string full_path =
|
||||
// World::getWorld()->getTrack()->getTrackFile(model_name);
|
||||
|
||||
bool animated = (UserConfigParams::m_graphical_effects ||
|
||||
World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
||||
bool animated = skeletal_animation && (UserConfigParams::m_graphical_effects ||
|
||||
World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
||||
|
||||
|
||||
if (animated)
|
||||
@@ -232,7 +235,10 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(
|
||||
|
||||
void TrackObjectPresentationMesh::init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled)
|
||||
{
|
||||
bool animated = (UserConfigParams::m_graphical_effects ||
|
||||
bool skeletal_animation = true; // for backwards compatibility, if unspecified assume there is
|
||||
xml_node->get("skeletal-animation", &skeletal_animation);
|
||||
|
||||
bool animated = skeletal_animation && (UserConfigParams::m_graphical_effects ||
|
||||
World::getWorld()->getIdent() == IDENT_CUSTSCENE);
|
||||
|
||||
m_mesh->grab();
|
||||
|
||||
Reference in New Issue
Block a user