Merge branch 'master' of https://github.com/supertuxkart/stk-code into random-gp

This commit is contained in:
konstin
2014-05-11 17:16:21 +02:00
28 changed files with 807 additions and 217 deletions

View File

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

View File

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

View File

@@ -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);
}

View File

@@ -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);
}

View File

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

View File

@@ -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"));

View File

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

View File

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

View File

@@ -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));
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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).
*/

View File

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

View File

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

View File

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

View File

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

View File

@@ -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();

View File

@@ -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 ();

View File

@@ -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));
}
}