Merge branch 'master' of https://github.com/supertuxkart/stk-code into random-gp
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<particles emitter="point">
|
||||
<particles emitter="box" box_x="12.0" box_y="0.5" box_z="12.0">
|
||||
|
||||
<spreading angle="24" />
|
||||
|
||||
@@ -10,21 +10,23 @@
|
||||
<material file="waterparticles.png" />
|
||||
|
||||
<!-- Amount of particles emitted per second -->
|
||||
<rate min="10"
|
||||
max="30" />
|
||||
<rate min="5"
|
||||
max="20" />
|
||||
|
||||
<!-- Minimal and maximal lifetime of a particle, in milliseconds. -->
|
||||
<lifetime min="500"
|
||||
max="1000" />
|
||||
<lifetime min="1000"
|
||||
max="4000" />
|
||||
|
||||
<!-- Size of the particles -->
|
||||
<size min="0.6"
|
||||
max="6.2" />
|
||||
<size min="5.0"
|
||||
max="10.0"
|
||||
x-increase-factor="2.6"
|
||||
y-increase-factor="2.6" />
|
||||
|
||||
<color min="255 255 255"
|
||||
max="255 255 255" />
|
||||
|
||||
<fadeout time="300" />
|
||||
<fadeout time="5000" />
|
||||
|
||||
|
||||
</particles>
|
||||
|
||||
@@ -131,6 +131,25 @@
|
||||
<label text="Depth of field" I18N="Video settings"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
|
||||
<div layout="horizontal-row" width="100%" height="fit">
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="hd-textures"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Use high definition textures" I18N="Video settings"/>
|
||||
</div>
|
||||
|
||||
<spacer height="4" width="10" />
|
||||
<!--
|
||||
<div layout="horizontal-row" proportion="1" height="fit">
|
||||
<checkbox id="anim_gfx"/>
|
||||
<spacer width="10" height="10"/>
|
||||
<label text="Animated Scenery" I18N="Video settings"/>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
<spacer height="20" width="10" />
|
||||
|
||||
|
||||
@@ -12,5 +12,5 @@ varying vec2 uv;
|
||||
void main(void)
|
||||
{
|
||||
vec4 color = texture(tex, uv);
|
||||
FragColor = vec4(color.rgb * color.a, color.a);
|
||||
FragColor = vec4(color.rgb, color.a);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,5 @@ void main(void)
|
||||
EnvPos /= EnvPos.w;
|
||||
float alpha = clamp((EnvPos.z - FragmentPos.z) * 0.3, 0., 1.);
|
||||
vec4 color = texture(tex, tc) * vec4(pc, 1.0);
|
||||
color.a *= alpha * smoothstep(1., 0.8, lf);
|
||||
FragColor = vec4(color.rgb * color.a, color.a);
|
||||
FragColor = color * alpha * smoothstep(1., 0.8, lf);
|
||||
}
|
||||
|
||||
@@ -544,12 +544,12 @@ B3D, MS3D or X meshes */
|
||||
#endif
|
||||
|
||||
//! Define _IRR_COMPILE_WITH_BMP_WRITER_ if you want to write .bmp files
|
||||
//#define _IRR_COMPILE_WITH_BMP_WRITER_
|
||||
#define _IRR_COMPILE_WITH_BMP_WRITER_
|
||||
#ifdef NO_IRR_COMPILE_WITH_BMP_WRITER_
|
||||
#undef _IRR_COMPILE_WITH_BMP_WRITER_
|
||||
#endif
|
||||
//! Define _IRR_COMPILE_WITH_JPG_WRITER_ if you want to write .jpg files
|
||||
//#define _IRR_COMPILE_WITH_JPG_WRITER_
|
||||
#define _IRR_COMPILE_WITH_JPG_WRITER_
|
||||
#ifdef NO_IRR_COMPILE_WITH_JPG_WRITER_
|
||||
#undef _IRR_COMPILE_WITH_JPG_WRITER_
|
||||
#endif
|
||||
|
||||
@@ -443,6 +443,9 @@ namespace UserConfigParams
|
||||
PARAM_PREFIX BoolUserConfigParam m_texture_compression
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_texture_compression",
|
||||
&m_video_group, "Enable Texture Compression"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_high_definition_textures
|
||||
PARAM_DEFAULT(BoolUserConfigParam(true, "enable_high_definition_textures",
|
||||
&m_video_group, "Enable high definition textures"));
|
||||
PARAM_PREFIX BoolUserConfigParam m_ubo_disabled
|
||||
PARAM_DEFAULT(BoolUserConfigParam(false, "disable_ubo_support",
|
||||
&m_video_group, "Disable UBO support"));
|
||||
|
||||
@@ -69,6 +69,8 @@ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
|
||||
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
|
||||
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
PFNGLBLENDCOLORPROC glBlendColor;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
#endif
|
||||
|
||||
static bool is_gl_init = false;
|
||||
@@ -216,6 +218,8 @@ void initGL()
|
||||
glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex");
|
||||
glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding");
|
||||
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
|
||||
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
|
||||
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
|
||||
#ifdef DEBUG
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
|
||||
#endif
|
||||
@@ -306,28 +310,56 @@ GLuint getDepthTexture(irr::video::ITexture *tex)
|
||||
}
|
||||
|
||||
std::set<irr::video::ITexture *> AlreadyTransformedTexture;
|
||||
|
||||
void resetTextureTable()
|
||||
{
|
||||
AlreadyTransformedTexture.clear();
|
||||
}
|
||||
|
||||
void compressTexture(irr::video::ITexture *tex, bool srgb)
|
||||
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha)
|
||||
{
|
||||
if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end())
|
||||
return;
|
||||
AlreadyTransformedTexture.insert(tex);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
|
||||
|
||||
std::string cached_file;
|
||||
if (UserConfigParams::m_texture_compression)
|
||||
{
|
||||
// Try to retrieve the compressed texture in cache
|
||||
std::string tex_name = irr_driver->getTextureName(tex);
|
||||
if (!tex_name.empty()) {
|
||||
cached_file = file_manager->getTextureCacheLocation(tex_name) + ".gltz";
|
||||
if (!file_manager->fileIsNewer(tex_name, cached_file)) {
|
||||
if (loadCompressedTexture(cached_file))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t w = tex->getSize().Width, h = tex->getSize().Height;
|
||||
char *data = new char[w * h * 4];
|
||||
unsigned char *data = new unsigned char[w * h * 4];
|
||||
memcpy(data, tex->lock(), w * h * 4);
|
||||
tex->unlock();
|
||||
glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex));
|
||||
unsigned internalFormat, Format;
|
||||
if (tex->hasAlpha())
|
||||
Format = GL_BGRA;
|
||||
else
|
||||
Format = GL_BGR;
|
||||
|
||||
if (premul_alpha)
|
||||
{
|
||||
for (unsigned i = 0; i < w * h; i++)
|
||||
{
|
||||
float alpha = data[4 * i + 3];
|
||||
if (alpha > 0.)
|
||||
alpha = pow(alpha / 255., 1. / 2.2);
|
||||
data[4 * i] *= alpha;
|
||||
data[4 * i + 1] *= alpha;
|
||||
data[4 * i + 2] *= alpha;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UserConfigParams::m_texture_compression)
|
||||
{
|
||||
if (srgb)
|
||||
@@ -338,13 +370,94 @@ void compressTexture(irr::video::ITexture *tex, bool srgb)
|
||||
else
|
||||
{
|
||||
if (srgb)
|
||||
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA : GL_COMPRESSED_SRGB;
|
||||
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
|
||||
else
|
||||
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA : GL_COMPRESSED_RGB;
|
||||
internalFormat = (tex->hasAlpha()) ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, w, h, 0, Format, GL_UNSIGNED_BYTE, (GLvoid *)data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
delete[] data;
|
||||
|
||||
if (UserConfigParams::m_texture_compression && !cached_file.empty())
|
||||
{
|
||||
// Save the compressed texture in the cache for later use.
|
||||
saveCompressedTexture(cached_file);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Try to load a compressed texture from the given file name.
|
||||
* Data in the specified file need to have a specific format. See the
|
||||
* saveCompressedTexture() function for a description of the format.
|
||||
* \return true if the loading succeeded, false otherwise.
|
||||
* \see saveCompressedTexture
|
||||
*/
|
||||
bool loadCompressedTexture(const std::string& compressed_tex)
|
||||
{
|
||||
std::ifstream ifs(compressed_tex.c_str(), std::ios::in | std::ios::binary);
|
||||
if (!ifs.is_open())
|
||||
return false;
|
||||
|
||||
int internal_format;
|
||||
int w, h;
|
||||
int size = -1;
|
||||
ifs.read((char*)&internal_format, sizeof(int));
|
||||
ifs.read((char*)&w, sizeof(int));
|
||||
ifs.read((char*)&h, sizeof(int));
|
||||
ifs.read((char*)&size, sizeof(int));
|
||||
|
||||
if (ifs.fail() || size == -1)
|
||||
return false;
|
||||
|
||||
char *data = new char[size];
|
||||
ifs.read(data, size);
|
||||
if (!ifs.fail())
|
||||
{
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, internal_format,
|
||||
w, h, 0, size, (GLvoid*)data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
delete[] data;
|
||||
ifs.close();
|
||||
return true;
|
||||
}
|
||||
delete[] data;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Try to save the last texture sent to glTexImage2D in a file of the given
|
||||
* file name. This function should only be used for textures sent to
|
||||
* glTexImage2D with a compressed internal format as argument.<br>
|
||||
* \note The following format is used to save the compressed texture:<br>
|
||||
* <internal-format><width><height><size><data> <br>
|
||||
* The first four elements are integers and the last one is stored
|
||||
* on \c size bytes.
|
||||
* \see loadCompressedTexture
|
||||
*/
|
||||
void saveCompressedTexture(const std::string& compressed_tex)
|
||||
{
|
||||
int internal_format, width, height, size, compressionSuccessful;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&internal_format);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint *)&width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint *)&height);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, (GLint *)&compressionSuccessful);
|
||||
if (!compressionSuccessful)
|
||||
return;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&size);
|
||||
|
||||
char *data = new char[size];
|
||||
glGetCompressedTexImage(GL_TEXTURE_2D, 0, (GLvoid*)data);
|
||||
std::ofstream ofs(compressed_tex.c_str(), std::ios::out | std::ios::binary);
|
||||
if (ofs.is_open())
|
||||
{
|
||||
ofs.write((char*)&internal_format, sizeof(int));
|
||||
ofs.write((char*)&width, sizeof(int));
|
||||
ofs.write((char*)&height, sizeof(int));
|
||||
ofs.write((char*)&size, sizeof(int));
|
||||
ofs.write(data, size);
|
||||
ofs.close();
|
||||
}
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF)
|
||||
@@ -408,6 +521,30 @@ unsigned GPUTimer::elapsedTimeus()
|
||||
return result / 1000;
|
||||
}
|
||||
|
||||
void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, irr::video::SColor color)
|
||||
{
|
||||
if (!irr_driver->isGLSL()) {
|
||||
irr_driver->getVideoDriver()->draw3DLine(start, end, color);
|
||||
return;
|
||||
}
|
||||
|
||||
float vertex[6] = {
|
||||
start.X, start.Y, start.Z,
|
||||
end.X, end.Y, end.Z
|
||||
};
|
||||
|
||||
glBindVertexArray(UtilShader::ColoredLine::vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, 6 * sizeof(float), vertex);
|
||||
|
||||
glUseProgram(UtilShader::ColoredLine::Program);
|
||||
UtilShader::ColoredLine::setUniforms(color);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
|
||||
glGetError();
|
||||
}
|
||||
|
||||
static void drawTexColoredQuad(const video::ITexture *texture, const video::SColor *col, float width, float height,
|
||||
float center_pos_x, float center_pos_y, float tex_center_pos_x, float tex_center_pos_y,
|
||||
float tex_width, float tex_height)
|
||||
|
||||
@@ -85,6 +85,8 @@ extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
|
||||
extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;
|
||||
extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
|
||||
extern PFNGLBLENDCOLORPROC glBlendColor;
|
||||
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
|
||||
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
|
||||
#ifdef DEBUG
|
||||
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
||||
#endif
|
||||
@@ -179,9 +181,14 @@ public:
|
||||
GLuint getTextureGLuint(irr::video::ITexture *tex);
|
||||
GLuint getDepthTexture(irr::video::ITexture *tex);
|
||||
void resetTextureTable();
|
||||
void compressTexture(irr::video::ITexture *tex, bool srgb);
|
||||
void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = false);
|
||||
bool loadCompressedTexture(const std::string& compressed_tex);
|
||||
void saveCompressedTexture(const std::string& compressed_tex);
|
||||
void blitFBO(GLuint Src, GLuint Dst, size_t width, size_t height);
|
||||
|
||||
void draw3DLine(const core::vector3df& start,
|
||||
const core::vector3df& end, irr::video::SColor color);
|
||||
|
||||
void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect<s32>& destRect,
|
||||
const irr::core::rect<s32>& sourceRect, const irr::core::rect<s32>* clipRect,
|
||||
const irr::video::SColor &color, bool useAlphaChannelOfTexture);
|
||||
|
||||
@@ -360,7 +360,7 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
video::ITexture *tex = getMaterial(0).getTexture(0);
|
||||
compressTexture(tex, true);
|
||||
compressTexture(tex, true, true);
|
||||
texture = getTextureGLuint(getMaterial(0).getTexture(0));
|
||||
}
|
||||
|
||||
|
||||
@@ -841,7 +841,8 @@ scene::IMesh *IrrDriver::getMesh(const std::string &filename)
|
||||
filename.c_str());
|
||||
return NULL;
|
||||
}
|
||||
return am->getMesh(0);
|
||||
scene::IMeshManipulator *mani = irr_driver->getVideoDriver()->getMeshManipulator();
|
||||
return mani->createMeshWelded(am->getMesh(0));
|
||||
} // getMesh
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1254,6 +1255,74 @@ void IrrDriver::unsetTextureErrorMessage()
|
||||
m_texture_error_message = "";
|
||||
} // unsetTextureErrorMessage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Retrieve all textures in the specified directory, generate a smaller
|
||||
* version for each of them and save them in the cache. Smaller textures are
|
||||
* generated only if they do not already exist or if their original version
|
||||
* is newer than the cached one.
|
||||
* \param dir Directory from where textures will be retrieved.
|
||||
* Must end with '/'.
|
||||
* \return Directory where smaller textures were cached.
|
||||
*/
|
||||
std::string IrrDriver::generateSmallerTextures(const std::string& dir)
|
||||
{
|
||||
std::set<std::string> files;
|
||||
file_manager->listFiles(files, dir, true);
|
||||
|
||||
std::set<std::string>::const_iterator it;
|
||||
for (it = files.begin(); it != files.end(); ++it)
|
||||
{
|
||||
std::string ext = StringUtils::toLowerCase(StringUtils::getExtension(*it));
|
||||
if (ext == "png" || ext == "jpg" || ext == "jpeg" || ext == "bmp")
|
||||
{
|
||||
getSmallerTexture(*it);
|
||||
}
|
||||
} // for it in files
|
||||
|
||||
return file_manager->getTextureCacheLocation(dir);
|
||||
} // generateSmallerTextures
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return the filename for the cached smaller version of the texture. Also,
|
||||
* generate the smaller version of the texture if it does not already
|
||||
* exist or if the original version is newer than the cached one.
|
||||
* \param filename File name of the original texture.
|
||||
* \return File name of the cached texture.
|
||||
*/
|
||||
std::string IrrDriver::getSmallerTexture(const std::string& filename)
|
||||
{
|
||||
// Retrieve the filename of the cached texture
|
||||
std::string cached_file = file_manager->getTextureCacheLocation(filename);
|
||||
|
||||
// If the cached texture does not exist, we generate it.
|
||||
if (!file_manager->fileExists(cached_file) ||
|
||||
file_manager->fileIsNewer(filename, cached_file))
|
||||
{
|
||||
video::IVideoDriver* video_driver = irr_driver->getVideoDriver();
|
||||
video::IImage* img =
|
||||
video_driver->createImageFromFile(filename.c_str());
|
||||
|
||||
if (img != NULL)
|
||||
{
|
||||
core::dimension2d<u32> dim = img->getDimension();
|
||||
core::dimension2d<u32> new_dim; // Dimension of the cached texture
|
||||
const int scale_factor = 2;
|
||||
// Resize the texture only if it can be done properly
|
||||
if (dim.Width < scale_factor || dim.Height < scale_factor)
|
||||
new_dim = dim;
|
||||
else
|
||||
new_dim = dim / scale_factor;
|
||||
|
||||
video::IImage* scaled =
|
||||
video_driver->createImage(img->getColorFormat(), new_dim);
|
||||
img->copyToScaling(scaled);
|
||||
|
||||
video_driver->writeImageToFile(scaled, cached_file.c_str());
|
||||
} // if img != NULL
|
||||
} // if !file_manager->fileExists(cached_file)
|
||||
return cached_file;
|
||||
} // getSmallerTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a texture from a file and returns the texture object. This is just
|
||||
* a convenient wrapper which loads the texture from a STK asset directory.
|
||||
@@ -1365,9 +1434,34 @@ video::ITexture *IrrDriver::getTexture(const std::string &filename,
|
||||
Log::error("irr_driver", "Texture '%s' not found.", filename.c_str());
|
||||
}
|
||||
|
||||
m_texturesFileName[out] = filename;
|
||||
|
||||
return out;
|
||||
} // getTexture
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Clear the texture-filename reminder.
|
||||
*/
|
||||
void IrrDriver::clearTexturesFileName()
|
||||
{
|
||||
m_texturesFileName.clear();
|
||||
} // clearTexturesFileName
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Get the texture file name using a texture pointer.
|
||||
* \param tex Pointer on the texture for which we want to find the file name.
|
||||
* \return Filename of the texture if found, or an empty string otherwise.
|
||||
*/
|
||||
std::string IrrDriver::getTextureName(video::ITexture* tex)
|
||||
{
|
||||
std::map<video::ITexture*, std::string>::iterator it;
|
||||
it = m_texturesFileName.find(tex);
|
||||
if (it != m_texturesFileName.end())
|
||||
return it->second;
|
||||
else
|
||||
return "";
|
||||
} // getTextureName
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Appends a pointer to each texture used in this mesh to the vector.
|
||||
* \param mesh The mesh from which the textures are being determined.
|
||||
@@ -1858,6 +1952,16 @@ void IrrDriver::update(float dt)
|
||||
else
|
||||
renderFixed(dt);
|
||||
|
||||
|
||||
if (world != NULL && world->getPhysics() != NULL)
|
||||
{
|
||||
IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer();
|
||||
if (debug_drawer != NULL && debug_drawer->debugEnabled())
|
||||
{
|
||||
debug_drawer->beginNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_request_screenshot) doScreenShot();
|
||||
|
||||
// Enable this next print statement to get render information printed
|
||||
|
||||
@@ -77,9 +77,17 @@ enum STKRenderingPass
|
||||
enum QueryPerf
|
||||
{
|
||||
Q_SOLID_PASS1,
|
||||
Q_SOLID_PASS2,
|
||||
Q_LIGHT,
|
||||
Q_SHADOWS,
|
||||
Q_LIGHT,
|
||||
Q_SSAO,
|
||||
Q_SOLID_PASS2,
|
||||
Q_TRANSPARENT,
|
||||
Q_PARTICLES,
|
||||
Q_DISPLACEMENT,
|
||||
Q_GODRAYS,
|
||||
Q_BLOOM,
|
||||
Q_TONEMAP,
|
||||
Q_MOTIONBLUR,
|
||||
Q_LAST
|
||||
};
|
||||
|
||||
@@ -134,6 +142,8 @@ private:
|
||||
float greenSHCoeff[9];
|
||||
float redSHCoeff[9];
|
||||
|
||||
/** Keep a trace of the origin file name of a texture. */
|
||||
std::map<video::ITexture*, std::string> m_texturesFileName;
|
||||
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
* acted upon in the next update). None means no change, yes means
|
||||
@@ -269,7 +279,8 @@ private:
|
||||
void computeCameraMatrix(scene::ICameraSceneNode * const camnode);
|
||||
void renderShadows();
|
||||
void renderGlow(std::vector<GlowData>& glows);
|
||||
void renderLights(float dt);
|
||||
void renderSSAO();
|
||||
void renderLights(scene::ICameraSceneNode * const camnode, float dt);
|
||||
void renderDisplacement();
|
||||
void doScreenShot();
|
||||
public:
|
||||
@@ -296,6 +307,8 @@ public:
|
||||
void displayFPS();
|
||||
bool OnEvent(const irr::SEvent &event);
|
||||
void setAmbientLight(const video::SColor &light);
|
||||
std::string generateSmallerTextures(const std::string& dir);
|
||||
std::string getSmallerTexture(const std::string& texture);
|
||||
video::ITexture *getTexture(FileManager::AssetType type,
|
||||
const std::string &filename,
|
||||
bool is_premul=false,
|
||||
@@ -305,6 +318,8 @@ public:
|
||||
bool is_premul=false,
|
||||
bool is_prediv=false,
|
||||
bool complain_if_not_found=true);
|
||||
void clearTexturesFileName();
|
||||
std::string getTextureName(video::ITexture* tex);
|
||||
void grabAllTextures(const scene::IMesh *mesh);
|
||||
void dropAllTextures(const scene::IMesh *mesh);
|
||||
scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL,
|
||||
|
||||
@@ -624,10 +624,8 @@ void PostProcessing::applyMLAA()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render the post-processed scene */
|
||||
void PostProcessing::render()
|
||||
void PostProcessing::render(scene::ICameraSceneNode * const camnode)
|
||||
{
|
||||
if (!irr_driver->isGLSL()) return;
|
||||
|
||||
IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
MotionBlurProvider * const mocb = (MotionBlurProvider *) irr_driver->
|
||||
@@ -635,29 +633,25 @@ void PostProcessing::render()
|
||||
GaussianBlurProvider * const gacb = (GaussianBlurProvider *) irr_driver->
|
||||
getCallback(ES_GAUSSIAN3H);
|
||||
|
||||
const u32 cams = Camera::getNumCameras();
|
||||
for(u32 cam = 0; cam < cams; cam++)
|
||||
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS);
|
||||
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
|
||||
// Each effect uses these as named, and sets them up for the next effect.
|
||||
// This allows chaining effects where some may be disabled.
|
||||
|
||||
// As the original color shouldn't be touched, the first effect can't be disabled.
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (UserConfigParams::m_dof)
|
||||
{
|
||||
scene::ICameraSceneNode * const camnode =
|
||||
Camera::getCamera(cam)->getCameraSceneNode();
|
||||
mocb->setCurrentCamera(cam);
|
||||
GLuint in_rtt = irr_driver->getRenderTargetTexture(RTT_COLOR), in_fbo = irr_driver->getFBO(FBO_COLORS);
|
||||
GLuint out_rtt = irr_driver->getRenderTargetTexture(RTT_TMP1), out_fbo = irr_driver->getFBO(FBO_TMP1_WITH_DS);
|
||||
// Each effect uses these as named, and sets them up for the next effect.
|
||||
// This allows chaining effects where some may be disabled.
|
||||
|
||||
// As the original color shouldn't be touched, the first effect can't be disabled.
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (UserConfigParams::m_dof)
|
||||
{
|
||||
renderDoF(out_fbo, in_rtt);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
}
|
||||
renderDoF(out_fbo, in_rtt);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
}
|
||||
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Godrays", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_GODRAYS));
|
||||
const bool hasgodrays = World::getWorld()->getTrack()->hasGodRays();
|
||||
if (UserConfigParams::m_light_shaft && m_sunpixels > 30 && hasgodrays)
|
||||
{
|
||||
@@ -665,7 +659,7 @@ void PostProcessing::render()
|
||||
// Grab the sky
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, out_fbo);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// irr_driver->renderSkybox();
|
||||
irr_driver->renderSkybox(camnode);
|
||||
|
||||
// Set the sun's color
|
||||
const SColor col = World::getWorld()->getTrack()->getSunColor();
|
||||
@@ -700,8 +694,8 @@ void PostProcessing::render()
|
||||
|
||||
trans.transformVect(ndc, pos);
|
||||
|
||||
const float texh = m_vertices[cam].v1.TCoords.Y - m_vertices[cam].v0.TCoords.Y;
|
||||
const float texw = m_vertices[cam].v3.TCoords.X - m_vertices[cam].v0.TCoords.X;
|
||||
const float texh = m_vertices[0].v1.TCoords.Y - m_vertices[0].v0.TCoords.Y;
|
||||
const float texw = m_vertices[0].v3.TCoords.X - m_vertices[0].v0.TCoords.X;
|
||||
|
||||
const float sunx = ((ndc[0] / ndc[3]) * 0.5f + 0.5f) * texw;
|
||||
const float suny = ((ndc[1] / ndc[3]) * 0.5f + 0.5f) * texh;
|
||||
@@ -727,10 +721,13 @@ void PostProcessing::render()
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
// Simulate camera defects from there
|
||||
// Simulate camera defects from there
|
||||
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Bloom", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_BLOOM));
|
||||
if (UserConfigParams::m_bloom)
|
||||
{
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
@@ -785,52 +782,60 @@ void PostProcessing::render()
|
||||
glDisable(GL_BLEND);
|
||||
} // end if bloom
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
computeLogLuminance(in_rtt);
|
||||
//computeLogLuminance(in_rtt);
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Tonemap", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_TONEMAP));
|
||||
toneMap(out_fbo, in_rtt);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MOTIONBLUR));
|
||||
if (UserConfigParams::m_motionblur && m_any_boost) // motion blur
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Motion blur", 0xFF, 0x00, 0x00);
|
||||
renderMotionBlur(cam, in_rtt, out_fbo);
|
||||
renderMotionBlur(0, in_rtt, out_fbo);
|
||||
std::swap(in_fbo, out_fbo);
|
||||
std::swap(in_rtt, out_rtt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
if (irr_driver->getNormals())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (irr_driver->getSSAOViz())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
|
||||
renderPassThrough(in_rtt);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
applyMLAA();
|
||||
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(in_rtt);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
if (irr_driver->getNormals())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (irr_driver->getSSAOViz())
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(irr_driver->getRenderTargetTexture(RTT_SSAO));
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
else if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_MLAA_COLORS));
|
||||
renderPassThrough(in_rtt);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
applyMLAA();
|
||||
blitFBO(irr_driver->getFBO(FBO_MLAA_COLORS), 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
renderPassThrough(in_rtt);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
} // render
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "IShaderConstantSetCallBack.h"
|
||||
#include "S3DVertex.h"
|
||||
#include "SMaterial.h"
|
||||
#include "graphics/camera.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -92,7 +93,7 @@ public:
|
||||
void renderGlow(unsigned tex);
|
||||
|
||||
/** Render the post-processed scene */
|
||||
void render();
|
||||
void render(scene::ICameraSceneNode * const camnode);
|
||||
|
||||
/** Use motion blur for a short time */
|
||||
void giveBoost(unsigned int cam_index);
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
|
||||
STKInstancedSceneNode *InstancedBox = 0;
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
void IrrDriver::renderGLSL(float dt)
|
||||
{
|
||||
World *world = World::getWorld(); // Never NULL.
|
||||
@@ -139,9 +142,16 @@ void IrrDriver::renderGLSL(float dt)
|
||||
#endif
|
||||
camera->activate();
|
||||
rg->preRenderCallback(camera); // adjusts start referee
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
|
||||
renderScene(camnode, glows, dt, track->hasShadows());
|
||||
|
||||
// Render the post-processed scene
|
||||
if (UserConfigParams::m_dynamic_lights)
|
||||
m_post_processing->render(camnode);
|
||||
else
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Note that drawAll must be called before rendering
|
||||
@@ -152,14 +162,6 @@ void IrrDriver::renderGLSL(float dt)
|
||||
World::getWorld()->getPhysics()->draw();
|
||||
} // for i<world->getNumKarts()
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Postprocessing", 0xFF, 0xFF, 0x00);
|
||||
// Render the post-processed scene
|
||||
if (UserConfigParams::m_dynamic_lights)
|
||||
m_post_processing->render();
|
||||
else
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@@ -198,6 +200,37 @@ void IrrDriver::renderGLSL(float dt)
|
||||
drawDebugMeshes();
|
||||
#endif
|
||||
|
||||
|
||||
if (world != NULL && world->getPhysics() != NULL)
|
||||
{
|
||||
IrrDebugDrawer* debug_drawer = world->getPhysics()->getDebugDrawer();
|
||||
if (debug_drawer != NULL && debug_drawer->debugEnabled())
|
||||
{
|
||||
const std::map<video::SColor, std::vector<float> >& lines = debug_drawer->getLines();
|
||||
std::map<video::SColor, std::vector<float> >::const_iterator it;
|
||||
|
||||
|
||||
glUseProgram(UtilShader::ColoredLine::Program);
|
||||
glBindVertexArray(UtilShader::ColoredLine::vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, UtilShader::ColoredLine::vbo);
|
||||
for (it = lines.begin(); it != lines.end(); it++)
|
||||
{
|
||||
UtilShader::ColoredLine::setUniforms(it->first);
|
||||
const std::vector<float> &vertex = it->second;
|
||||
const float *tmp = vertex.data();
|
||||
for (int i = 0; i < vertex.size(); i += 1024 * 6)
|
||||
{
|
||||
unsigned count = MIN2(vertex.size() - i, 1024 * 6);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, count * sizeof(float), &tmp[i]);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, count / 3);
|
||||
}
|
||||
}
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("EndSccene", 0x45, 0x75, 0x45);
|
||||
m_video_driver->endScene();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
@@ -216,20 +249,35 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
|
||||
const core::aabbox3df cambox = camnode->getViewFrustum()->getBoundingBox();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||
// Shadows
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
|
||||
UserConfigParams::m_shadows && hasShadow)
|
||||
{
|
||||
renderShadows();
|
||||
PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
|
||||
// To avoid wrong culling, use the largest view possible
|
||||
m_scene_manager->setActiveCamera(m_suncam);
|
||||
if (!m_mipviz && !m_wireframe && UserConfigParams::m_dynamic_lights &&
|
||||
UserConfigParams::m_shadows && hasShadow)
|
||||
renderShadows();
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
|
||||
|
||||
// Lights
|
||||
renderLights(dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
|
||||
renderLights(camnode, dt);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
// Handle SSAO
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_SSAO));
|
||||
if (UserConfigParams::m_ssao)
|
||||
renderSSAO();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Solid Pass 2", 0x00, 0x00, 0xFF);
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
@@ -268,18 +316,29 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
|
||||
computeSunVisibility();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// We need to re-render camera due to the per-cam-node hack.
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
renderTransparent();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
// Render transparent
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Transparent Pass", 0xFF, 0x00, 0x00);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_TRANSPARENT));
|
||||
renderTransparent();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
|
||||
renderParticles();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
// Render particles
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Particles", 0xFF, 0xFF, 0x00);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_PARTICLES));
|
||||
renderParticles();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
|
||||
renderDisplacement();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
// Render displacement
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("- Displacement", 0x00, 0x00, 0xFF);
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_DISPLACEMENT));
|
||||
renderDisplacement();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
@@ -591,11 +650,18 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
|
||||
|
||||
core::matrix4 tmp_matrix;
|
||||
|
||||
// Prevent Matrix without extend
|
||||
if (left == right || up == down)
|
||||
{
|
||||
Log::error("Shadows", "Shadows Near/Far plane have a 0 area");
|
||||
sun_ortho_matrix.push_back(tmp_matrix);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_matrix.buildProjectionMatrixOrthoLH(left, right,
|
||||
up, down,
|
||||
30, z);
|
||||
m_suncam->setProjectionMatrix(tmp_matrix, true);
|
||||
m_scene_manager->setActiveCamera(m_suncam);
|
||||
m_suncam->render();
|
||||
|
||||
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
|
||||
@@ -603,7 +669,6 @@ void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode)
|
||||
assert(sun_ortho_matrix.size() == 4);
|
||||
camnode->setNearValue(oldnear);
|
||||
camnode->setFarValue(oldfar);
|
||||
// camnode->render();
|
||||
|
||||
float *tmp = new float[16 * 8];
|
||||
|
||||
@@ -632,13 +697,9 @@ void IrrDriver::renderShadows()
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
||||
{
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
|
||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
||||
}
|
||||
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
}
|
||||
|
||||
@@ -708,8 +769,7 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
static LightShader::PointLightInfo PointLightsInfo[MAXLIGHT];
|
||||
|
||||
static void renderPointLights(unsigned count)
|
||||
@@ -735,7 +795,7 @@ static void renderPointLights(unsigned count)
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
|
||||
}
|
||||
|
||||
void IrrDriver::renderLights(float dt)
|
||||
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
|
||||
{
|
||||
|
||||
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
|
||||
@@ -757,92 +817,87 @@ void IrrDriver::renderLights(float dt)
|
||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||
|
||||
const u32 lightcount = m_lights.size();
|
||||
const core::vector3df &campos =
|
||||
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
||||
const core::vector3df &campos = camnode->getAbsolutePosition();
|
||||
|
||||
std::vector<LightNode *> BucketedLN[15];
|
||||
for (unsigned int i = 0; i < lightcount; i++)
|
||||
{
|
||||
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
|
||||
|
||||
std::vector<LightNode *> BucketedLN[15];
|
||||
for (unsigned int i = 0; i < lightcount; i++)
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
if (!m_lights[i]->isPointLight())
|
||||
{
|
||||
m_lights[i]->render();
|
||||
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
else
|
||||
m_post_processing->renderSunlight();
|
||||
continue;
|
||||
}
|
||||
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
|
||||
unsigned idx = (unsigned)(lightpos.getLength() / 10);
|
||||
if (idx > 14)
|
||||
idx = 14;
|
||||
BucketedLN[idx].push_back(m_lights[i]);
|
||||
m_lights[i]->render();
|
||||
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
|
||||
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
||||
else
|
||||
m_post_processing->renderSunlight();
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned lightnum = 0;
|
||||
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
||||
{
|
||||
if (++lightnum >= MAXLIGHT)
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
light_node->setEnergyMultiplier(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
|
||||
float em = light_node->getEnergyMultiplier();
|
||||
if (em < 1.0f)
|
||||
{
|
||||
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
||||
}
|
||||
|
||||
const core::vector3df &pos = light_node->getAbsolutePosition();
|
||||
PointLightsInfo[lightnum].posX = pos.X;
|
||||
PointLightsInfo[lightnum].posY = pos.Y;
|
||||
PointLightsInfo[lightnum].posZ = pos.Z;
|
||||
|
||||
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
||||
|
||||
const core::vector3df &col = light_node->getColor();
|
||||
PointLightsInfo[lightnum].red = col.X;
|
||||
PointLightsInfo[lightnum].green = col.Y;
|
||||
PointLightsInfo[lightnum].blue = col.Z;
|
||||
}
|
||||
}
|
||||
if (lightnum > MAXLIGHT)
|
||||
{
|
||||
irr_driver->setLastLightBucketDistance(i * 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lightnum++;
|
||||
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
|
||||
unsigned idx = (unsigned)(lightpos.getLength() / 10);
|
||||
if (idx > 14)
|
||||
idx = 14;
|
||||
BucketedLN[idx].push_back(m_lights[i]);
|
||||
}
|
||||
|
||||
unsigned lightnum = 0;
|
||||
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
{
|
||||
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
||||
{
|
||||
if (++lightnum >= MAXLIGHT)
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
light_node->setEnergyMultiplier(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
LightNode* light_node = BucketedLN[i].at(j);
|
||||
|
||||
float em = light_node->getEnergyMultiplier();
|
||||
if (em < 1.0f)
|
||||
{
|
||||
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
||||
}
|
||||
|
||||
const core::vector3df &pos = light_node->getAbsolutePosition();
|
||||
PointLightsInfo[lightnum].posX = pos.X;
|
||||
PointLightsInfo[lightnum].posY = pos.Y;
|
||||
PointLightsInfo[lightnum].posZ = pos.Z;
|
||||
|
||||
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
||||
|
||||
const core::vector3df &col = light_node->getColor();
|
||||
PointLightsInfo[lightnum].red = col.X;
|
||||
PointLightsInfo[lightnum].green = col.Y;
|
||||
PointLightsInfo[lightnum].blue = col.Z;
|
||||
}
|
||||
}
|
||||
if (lightnum > MAXLIGHT)
|
||||
{
|
||||
irr_driver->setLastLightBucketDistance(i * 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lightnum++;
|
||||
|
||||
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
||||
if (SkyboxCubeMap)
|
||||
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
||||
gl_driver->extGlDrawBuffers(1, bufs);
|
||||
// Handle SSAO
|
||||
if (UserConfigParams::m_ssao)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
|
||||
m_post_processing->renderSSAO();
|
||||
// Blur it to reduce noise.
|
||||
m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
|
||||
irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
}
|
||||
}
|
||||
|
||||
void IrrDriver::renderSSAO()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_rtts->getFBO(FBO_SSAO));
|
||||
glClearColor(1., 1., 1., 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
|
||||
m_post_processing->renderSSAO();
|
||||
// Blur it to reduce noise.
|
||||
m_post_processing->renderGaussian6Blur(irr_driver->getFBO(FBO_SSAO), irr_driver->getRenderTargetTexture(RTT_SSAO),
|
||||
irr_driver->getFBO(FBO_HALF1), irr_driver->getRenderTargetTexture(RTT_HALF1), UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
|
||||
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
|
||||
}
|
||||
|
||||
static void getXYZ(GLenum face, float i, float j, float &x, float &y, float &z)
|
||||
|
||||
@@ -364,6 +364,7 @@ void Shaders::loadShaders()
|
||||
UIShader::ColoredTextureRectShader::init();
|
||||
UIShader::TextureRectShader::init();
|
||||
UIShader::UniformColoredTextureRectShader::init();
|
||||
UtilShader::ColoredLine::init();
|
||||
}
|
||||
|
||||
Shaders::~Shaders()
|
||||
@@ -404,6 +405,38 @@ static void bypassUBO(GLint Program)
|
||||
glUniformMatrix4fv(IPM, 1, GL_FALSE, irr_driver->getInvProjMatrix().pointer());
|
||||
}
|
||||
|
||||
namespace UtilShader
|
||||
{
|
||||
GLuint ColoredLine::Program;
|
||||
GLuint ColoredLine::uniform_color;
|
||||
GLuint ColoredLine::vao;
|
||||
GLuint ColoredLine::vbo;
|
||||
|
||||
void ColoredLine::init()
|
||||
{
|
||||
Program = LoadProgram(
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/object_pass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/coloredquad.frag").c_str());
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
glGenBuffers(1, &vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, 6 * 1024 * sizeof(float), 0, GL_DYNAMIC_DRAW);
|
||||
GLuint attrib_position = glGetAttribLocation(Program, "Position");
|
||||
glEnableVertexAttribArray(attrib_position);
|
||||
glVertexAttribPointer(attrib_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||
uniform_color = glGetUniformLocation(Program, "color");
|
||||
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
|
||||
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
|
||||
}
|
||||
|
||||
void ColoredLine::setUniforms(const irr::video::SColor &col)
|
||||
{
|
||||
glUniform4i(uniform_color, col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
|
||||
glUniformMatrix4fv(glGetUniformLocation(Program, "ModelMatrix"), 1, GL_FALSE, core::IdentityMatrix.pointer());
|
||||
}
|
||||
}
|
||||
|
||||
namespace MeshShader
|
||||
{
|
||||
|
||||
|
||||
@@ -32,6 +32,21 @@ public:
|
||||
static GLuint cubevbo, cubeindexes;
|
||||
static GLuint ViewProjectionMatrixesUBO;
|
||||
};
|
||||
|
||||
namespace UtilShader
|
||||
{
|
||||
class ColoredLine
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint uniform_color;
|
||||
static GLuint vao, vbo;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const irr::video::SColor &);
|
||||
};
|
||||
}
|
||||
|
||||
namespace MeshShader
|
||||
{
|
||||
class ObjectPass1Shader
|
||||
|
||||
@@ -35,7 +35,7 @@ void STKBillboard::render()
|
||||
core::vector3df pos = getAbsolutePosition();
|
||||
glBindVertexArray(billboardvao);
|
||||
video::ITexture *tex = Material.getTexture(0);
|
||||
compressTexture(tex, true);
|
||||
compressTexture(tex, true, true);
|
||||
GLuint texid = getTextureGLuint(tex);
|
||||
setTexture(0, texid, GL_LINEAR, GL_LINEAR);
|
||||
glUseProgram(MeshShader::BillboardShader::Program);
|
||||
|
||||
@@ -1048,7 +1048,12 @@ namespace GUIEngine
|
||||
const int screen_width = irr_driver->getFrameSize().Width;
|
||||
const int screen_height = irr_driver->getFrameSize().Height;
|
||||
float scale = std::max(0, screen_width - 640)/564.0f;
|
||||
if (screen_height < 700) scale = std::min(scale, 0.25f); // attempt to compensate for small screens
|
||||
|
||||
// attempt to compensate for small screens
|
||||
if (screen_width < 1200) scale = std::max(0, screen_width - 640) / 750.0f;
|
||||
if (screen_width < 900 || screen_height < 700) scale = std::min(scale, 0.05f);
|
||||
|
||||
Log::info("GUIEngine", "scale: %f", scale);
|
||||
|
||||
float normal_text_scale = 0.7f + 0.2f*scale;
|
||||
float title_text_scale = 0.2f + 0.2f*scale;
|
||||
|
||||
@@ -159,8 +159,12 @@ bool EventHandler::OnEvent (const SEvent &event)
|
||||
event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
||||
{
|
||||
// Remember the mouse position
|
||||
m_mouse_pos.X = event.MouseInput.X;
|
||||
m_mouse_pos.Y = event.MouseInput.Y;
|
||||
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
|
||||
event.MouseInput.Event == EMIE_MOUSE_MOVED)
|
||||
{
|
||||
m_mouse_pos.X = event.MouseInput.X;
|
||||
m_mouse_pos.Y = event.MouseInput.Y;
|
||||
}
|
||||
|
||||
// Notify the profiler of mouse events
|
||||
if(UserConfigParams::m_profiler_enabled &&
|
||||
|
||||
@@ -192,6 +192,7 @@ FileManager::FileManager()
|
||||
checkAndCreateConfigDir();
|
||||
checkAndCreateAddonsDir();
|
||||
checkAndCreateScreenshotDir();
|
||||
checkAndCreateCachedTexturesDir();
|
||||
checkAndCreateGPDir();
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -596,6 +597,14 @@ std::string FileManager::getScreenshotDir() const
|
||||
return m_screenshot_dir;
|
||||
} // getScreenshotDir
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the directory in which resized textures should be cached.
|
||||
*/
|
||||
std::string FileManager::getCachedTexturesDir() const
|
||||
{
|
||||
return m_cached_textures_dir;
|
||||
} // getCachedTexturesDir
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the directory in which user-defined grand prix should be stored.
|
||||
*/
|
||||
@@ -852,6 +861,31 @@ void FileManager::checkAndCreateScreenshotDir()
|
||||
|
||||
} // checkAndCreateScreenshotDir
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Creates the directories for cached textures. This will set
|
||||
* m_cached_textures_dir with the appropriate path.
|
||||
*/
|
||||
void FileManager::checkAndCreateCachedTexturesDir()
|
||||
{
|
||||
#if defined(WIN32) || defined(__CYGWIN__)
|
||||
m_cached_textures_dir = m_user_config_dir + "cached-textures/";
|
||||
#elif defined(__APPLE__)
|
||||
m_cached_textures_dir = getenv("HOME");
|
||||
m_cached_textures_dir += "/Library/Application Support/SuperTuxKart/CachedTextures/";
|
||||
#else
|
||||
m_cached_textures_dir = checkAndCreateLinuxDir("XDG_CACHE_HOME", "supertuxkart", ".cache/", ".");
|
||||
m_cached_textures_dir += "cached-textures/";
|
||||
#endif
|
||||
|
||||
if (!checkAndCreateDirectory(m_cached_textures_dir))
|
||||
{
|
||||
Log::error("FileManager", "Can not create cached textures directory '%s', "
|
||||
"falling back to '.'.", m_cached_textures_dir.c_str());
|
||||
m_cached_textures_dir = ".";
|
||||
}
|
||||
|
||||
} // checkAndCreateCachedTexturesDir
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Creates the directories for user-defined grand prix. This will set m_gp_dir
|
||||
* with the appropriate path.
|
||||
@@ -976,6 +1010,35 @@ void FileManager::redirectOutput()
|
||||
Log::openOutputFiles(logoutfile);
|
||||
} // redirectOutput
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the theoretical location of the cached version of a texture
|
||||
* depending of the current config. (This function also works for directories:
|
||||
* in this case the returned directory will be the cache location for all
|
||||
* textures that you will find in the specified directory. The specified
|
||||
* directory must end with '/')
|
||||
* \note The returned location is where the cached data should be read or
|
||||
* written but the file itseft does not necessarity exist. However, the
|
||||
* directory structure is automatically created if it does not exist.
|
||||
*/
|
||||
std::string FileManager::getTextureCacheLocation(const std::string& filename)
|
||||
{
|
||||
std::string file = StringUtils::getBasename(filename);
|
||||
|
||||
std::string parent_dir = StringUtils::getPath(filename);
|
||||
if (StringUtils::hasSuffix(parent_dir, "/"))
|
||||
parent_dir = parent_dir.substr(0, parent_dir.size() - 1);
|
||||
parent_dir = StringUtils::getBasename(parent_dir);
|
||||
|
||||
std::string cache_subdir = UserConfigParams::m_high_definition_textures
|
||||
? "hd/"
|
||||
: "resized/";
|
||||
std::string cached_file =
|
||||
getCachedTexturesDir() + cache_subdir + parent_dir + "/";
|
||||
checkAndCreateDirectoryP(cached_file);
|
||||
cached_file += file;
|
||||
return cached_file;
|
||||
} // getTextureCacheLocation
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the directory for addon files. */
|
||||
const std::string &FileManager::getAddonsDir() const
|
||||
@@ -1150,3 +1213,17 @@ bool FileManager::removeDirectory(const std::string &name) const
|
||||
#endif
|
||||
} // remove directory
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns true if the first file is newer than the second. The comparison is
|
||||
* based on the modification time of the two files.
|
||||
*/
|
||||
bool FileManager::fileIsNewer(const std::string& f1, const std::string& f2) const
|
||||
{
|
||||
struct stat stat1;
|
||||
struct stat stat2;
|
||||
stat(f1.c_str(), &stat1);
|
||||
stat(f2.c_str(), &stat2);
|
||||
return stat1.st_mtime > stat2.st_mtime;
|
||||
} // fileIsNewer
|
||||
|
||||
|
||||
@@ -72,6 +72,9 @@ private:
|
||||
/** Directory to store screenshots in. */
|
||||
std::string m_screenshot_dir;
|
||||
|
||||
/** Directory where resized textures are cached. */
|
||||
std::string m_cached_textures_dir;
|
||||
|
||||
/** Directory where user-defined grand prix are stored. */
|
||||
std::string m_gp_dir;
|
||||
|
||||
@@ -91,6 +94,7 @@ private:
|
||||
bool isDirectory(const std::string &path) const;
|
||||
void checkAndCreateAddonsDir();
|
||||
void checkAndCreateScreenshotDir();
|
||||
void checkAndCreateCachedTexturesDir();
|
||||
void checkAndCreateGPDir();
|
||||
#if !defined(WIN32) && !defined(__CYGWIN__) && !defined(__APPLE__)
|
||||
std::string checkAndCreateLinuxDir(const char *env_name,
|
||||
@@ -110,7 +114,9 @@ public:
|
||||
XMLNode *createXMLTreeFromString(const std::string & content);
|
||||
|
||||
std::string getScreenshotDir() const;
|
||||
std::string getCachedTexturesDir() const;
|
||||
std::string getGPDir() const;
|
||||
std::string getTextureCacheLocation(const std::string& filename);
|
||||
bool checkAndCreateDirectoryP(const std::string &path);
|
||||
const std::string &getAddonsDir() const;
|
||||
std::string getAddonsFile(const std::string &name);
|
||||
@@ -137,6 +143,9 @@ public:
|
||||
void popModelSearchPath();
|
||||
void popMusicSearchPath();
|
||||
void redirectOutput();
|
||||
|
||||
bool fileIsNewer(const std::string& f1, const std::string& f2) const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Adds a directory to the music search path (or stack).
|
||||
*/
|
||||
|
||||
@@ -621,8 +621,14 @@ void World::resetAllKarts()
|
||||
// Stil wait will all karts are in rest (and handle the case that a kart
|
||||
// fell through the ground, which can happen if a kart falls for a long
|
||||
// time, therefore having a high speed when hitting the ground.
|
||||
int count = 0;
|
||||
while(!all_finished)
|
||||
{
|
||||
if (count++ > 100)
|
||||
{
|
||||
Log::error("World", "Infitine loop waiting for all_finished?");
|
||||
break;
|
||||
}
|
||||
m_physics->update(1.f/60.f);
|
||||
all_finished=true;
|
||||
for ( KartList::iterator i=m_karts.begin(); i!=m_karts.end(); i++)
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "modes/world.hpp"
|
||||
|
||||
#include <ISceneManager.h>
|
||||
#include <ISceneNode.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
|
||||
IrrDebugDrawer::IrrDebugDrawer()
|
||||
{
|
||||
@@ -58,8 +60,32 @@ void IrrDebugDrawer::drawLine(const btVector3& from, const btVector3& to,
|
||||
{
|
||||
video::SColor c(255, (int)(color.getX()*255), (int)(color.getY()*255),
|
||||
(int)(color.getZ()*255) );
|
||||
irr_driver->getVideoDriver()->draw3DLine((const core::vector3df&)from,
|
||||
(const core::vector3df&)to, c);
|
||||
|
||||
//World::getWorld()->getCa
|
||||
|
||||
if (from.distance2(m_camera_pos) > 10000) return;
|
||||
|
||||
std::vector<float>& v = m_lines[c];
|
||||
v.push_back(from.getX());
|
||||
v.push_back(from.getY());
|
||||
v.push_back(from.getZ());
|
||||
v.push_back(to.getX());
|
||||
v.push_back(to.getY());
|
||||
v.push_back(to.getZ());
|
||||
//draw3DLine((const core::vector3df&)from, (const core::vector3df&)to, c);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void IrrDebugDrawer::beginNextFrame()
|
||||
{
|
||||
for (std::map<video::SColor, std::vector<float> >::iterator it = m_lines.begin(); it != m_lines.end(); it++)
|
||||
{
|
||||
it->second.clear();
|
||||
}
|
||||
|
||||
scene::ICameraSceneNode* camera = irr_driver->getSceneManager()->getActiveCamera();
|
||||
m_camera_pos = camera->getPosition();
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
#define HEADER_IRR_DEBUG_DRAWER_HPP
|
||||
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "graphics/glwrap.hpp"
|
||||
|
||||
#include "utils/vec3.hpp"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* \ingroup physics
|
||||
@@ -38,6 +41,11 @@ public:
|
||||
DM_NO_KARTS_GRAPHICS = 0x02
|
||||
};
|
||||
DebugModeType m_debug_mode;
|
||||
|
||||
std::map<video::SColor, std::vector<float> > m_lines;
|
||||
|
||||
Vec3 m_camera_pos;
|
||||
|
||||
protected:
|
||||
virtual void setDebugMode(int debug_mode) {}
|
||||
/** Callback for bullet: if debug drawing should be done or not.
|
||||
@@ -65,6 +73,9 @@ public:
|
||||
bool debugEnabled() const {return m_debug_mode!=0;}
|
||||
void nextDebugMode();
|
||||
void setDebugMode(DebugModeType mode);
|
||||
|
||||
void beginNextFrame();
|
||||
const std::map<video::SColor, std::vector<float> >& getLines() const { return m_lines; }
|
||||
}; // IrrDebugDrawer
|
||||
|
||||
#endif
|
||||
|
||||
@@ -165,6 +165,7 @@ public:
|
||||
void setDebugMode(IrrDebugDrawer::DebugModeType mode) { m_debug_drawer->setDebugMode(mode); }
|
||||
/** Returns true if the debug drawer is enabled. */
|
||||
bool isDebug() const {return m_debug_drawer->debugEnabled(); }
|
||||
IrrDebugDrawer* getDebugDrawer() { return m_debug_drawer; }
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
|
||||
btPersistentManifold** manifold,int numManifolds,
|
||||
btTypedConstraint** constraints,int numConstraints,
|
||||
|
||||
@@ -53,6 +53,7 @@ void CustomVideoSettingsDialog::beforeAddingWidgets()
|
||||
getWidget<CheckBoxWidget>("weather_gfx")->setState( UserConfigParams::m_weather_effects );
|
||||
getWidget<CheckBoxWidget>("ubo")->setState(!UserConfigParams::m_ubo_disabled);
|
||||
getWidget<CheckBoxWidget>("dof")->setState(UserConfigParams::m_dof);
|
||||
getWidget<CheckBoxWidget>("hd-textures")->setState(UserConfigParams::m_high_definition_textures);
|
||||
|
||||
SpinnerWidget* kart_anim = getWidget<SpinnerWidget>("steering_animations");
|
||||
kart_anim->addLabel( _("Disabled") ); // 0
|
||||
@@ -107,10 +108,12 @@ GUIEngine::EventPropagation CustomVideoSettingsDialog::processEvent(const std::s
|
||||
getWidget<CheckBoxWidget>("anim_gfx")->getState();
|
||||
UserConfigParams::m_weather_effects =
|
||||
getWidget<CheckBoxWidget>("weather_gfx")->getState();
|
||||
UserConfigParams::m_ubo_disabled =
|
||||
UserConfigParams::m_ubo_disabled =
|
||||
!getWidget<CheckBoxWidget>("ubo")->getState();
|
||||
UserConfigParams::m_dof =
|
||||
getWidget<CheckBoxWidget>("dof")->getState();
|
||||
UserConfigParams::m_high_definition_textures =
|
||||
getWidget<CheckBoxWidget>("hd-textures")->getState();
|
||||
|
||||
UserConfigParams::m_motionblur =
|
||||
getWidget<CheckBoxWidget>("motionblur")->getState();
|
||||
|
||||
@@ -207,8 +207,10 @@ void Track::cleanup()
|
||||
ItemManager::destroy();
|
||||
|
||||
ParticleKindManager::get()->cleanUpTrackSpecificGfx();
|
||||
// Clear remainder of transformed textures
|
||||
// Clear reminder of transformed textures
|
||||
resetTextureTable();
|
||||
// Clear reminder of the link between textures and file names.
|
||||
irr_driver->clearTexturesFileName();
|
||||
|
||||
for(unsigned int i=0; i<m_animated_textures.size(); i++)
|
||||
{
|
||||
@@ -832,7 +834,31 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
std::string model_name;
|
||||
track_node->get("model", &model_name);
|
||||
std::string full_path = m_root+model_name;
|
||||
scene::IMesh *mesh = irr_driver->getMesh(full_path);
|
||||
|
||||
scene::IMesh *mesh;
|
||||
// If the hd texture option is disabled, we generate smaller textures
|
||||
// and configure the path to them before loading the mesh.
|
||||
if (!UserConfigParams::m_high_definition_textures)
|
||||
{
|
||||
std::string cached_textures_dir =
|
||||
irr_driver->generateSmallerTextures(m_root);
|
||||
|
||||
irr::io::IAttributes* scene_params =
|
||||
irr_driver->getSceneManager()->getParameters();
|
||||
// Before changing the texture path, we retrieve the older one to restore it later
|
||||
std::string texture_default_path =
|
||||
scene_params->getAttributeAsString(scene::B3D_TEXTURE_PATH).c_str();
|
||||
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, cached_textures_dir.c_str());
|
||||
|
||||
mesh = irr_driver->getMesh(full_path);
|
||||
|
||||
scene_params->setAttribute(scene::B3D_TEXTURE_PATH, texture_default_path.c_str());
|
||||
}
|
||||
else // Load mesh with default (hd) textures
|
||||
{
|
||||
mesh = irr_driver->getMesh(full_path);
|
||||
}
|
||||
|
||||
if(!mesh)
|
||||
{
|
||||
Log::fatal("track",
|
||||
@@ -1474,6 +1500,15 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
file_manager->pushTextureSearchPath(m_root);
|
||||
file_manager->pushModelSearchPath (m_root);
|
||||
|
||||
// If the hd texture option is disabled, we generate smaller textures
|
||||
// and we also add the cache directory to the texture search path
|
||||
if (!UserConfigParams::m_high_definition_textures)
|
||||
{
|
||||
std::string cached_textures_dir =
|
||||
irr_driver->generateSmallerTextures(m_root);
|
||||
file_manager->pushTextureSearchPath(cached_textures_dir);
|
||||
}
|
||||
|
||||
// First read the temporary materials.xml file if it exists
|
||||
try
|
||||
{
|
||||
@@ -1666,7 +1701,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
World::getWorld()->setClearbackBufferColor(m_sky_color);
|
||||
}
|
||||
|
||||
|
||||
if (!UserConfigParams::m_high_definition_textures)
|
||||
{
|
||||
file_manager->popTextureSearchPath();
|
||||
}
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath ();
|
||||
|
||||
|
||||
@@ -389,8 +389,23 @@ void Profiler::draw()
|
||||
|
||||
if (hovered_gpu_marker != Q_LAST)
|
||||
{
|
||||
static const char *Phase[Q_LAST] =
|
||||
{
|
||||
"Solid Pass 1",
|
||||
"Shadows",
|
||||
"Lights",
|
||||
"SSAO",
|
||||
"Solid Pass 2",
|
||||
"Transparent",
|
||||
"Particles",
|
||||
"Displacement",
|
||||
"Godrays",
|
||||
"Bloom",
|
||||
"Tonemap",
|
||||
"Motion Blur"
|
||||
};
|
||||
std::ostringstream oss;
|
||||
oss << "GPU marker " << hovered_gpu_marker << " : " << hovered_gpu_marker_elapsed << " us";
|
||||
oss << Phase[hovered_gpu_marker] << " : " << hovered_gpu_marker_elapsed << " us";
|
||||
font->draw(oss.str().c_str(), GPU_MARKERS_NAMES_POS, video::SColor(0xFF, 0xFF, 0x00, 0x00));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user