diff --git a/data/gui/racesetup.stkgui b/data/gui/racesetup.stkgui
index dd52aa0ea..4865798fb 100644
--- a/data/gui/racesetup.stkgui
+++ b/data/gui/racesetup.stkgui
@@ -19,7 +19,7 @@
I18N="Difficulty" text="SuperTux"/>
-
+
diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp
index 2c7656863..d8e36019e 100644
--- a/src/graphics/gpuparticles.cpp
+++ b/src/graphics/gpuparticles.cpp
@@ -1,4 +1,5 @@
#include "graphics/irr_driver.hpp"
+#include "graphics/glwrap.hpp"
#include "gpuparticles.hpp"
#include "io/file_manager.hpp"
#include "config/user_config.hpp"
diff --git a/src/graphics/gpuparticles.hpp b/src/graphics/gpuparticles.hpp
index 94ca75f81..138734bb9 100644
--- a/src/graphics/gpuparticles.hpp
+++ b/src/graphics/gpuparticles.hpp
@@ -1,8 +1,6 @@
#ifndef GPUPARTICLES_H
#define GPUPARTICLES_H
-#include "graphics/glwrap.hpp"
-
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
#include
#include
diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp
index debda17e4..370cd79bb 100644
--- a/src/graphics/irr_driver.cpp
+++ b/src/graphics/irr_driver.cpp
@@ -506,27 +506,27 @@ void IrrDriver::initDevice()
// Default false value for hasVSLayer if --no-graphics argument is used
if (!ProfileWorld::isNoGraphics())
{
- if (GLEW_AMD_vertex_shader_layer) {
+ if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
hasVSLayer = true;
Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
}
- if (GLEW_ARB_buffer_storage) {
+ if (hasGLExtension("GL_ARB_buffer_storage")) {
hasBuffserStorage = true;
Log::info("GLDriver", "ARB Buffer Storage enabled");
}
- if (GLEW_ARB_base_instance) {
+ if (hasGLExtension("GL_ARB_base_instance")) {
hasBaseInstance = true;
Log::info("GLDriver", "ARB Base Instance enabled");
}
- if (GLEW_ARB_draw_indirect) {
+ if (hasGLExtension("GL_ARB_draw_indirect")) {
hasDrawIndirect = true;
Log::info("GLDriver", "ARB Draw Indirect enabled");
}
- if (GLEW_ARB_compute_shader) {
+ if (hasGLExtension("GL_ARB_compute_shader")) {
hasComputeShaders = true;
Log::info("GLDriver", "ARB Compute Shader enabled");
}
- if (GLEW_ARB_texture_storage) {
+ if (hasGLExtension("GL_ARB_texture_storage")) {
hasTextureStorage = true;
Log::info("GLDriver", "ARB Texture Storage enabled");
}
@@ -1746,19 +1746,8 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode)
{
- fpsString += _("FPS: ");
- fpsString += core::stringw(min);
- fpsString += _("/");
- fpsString += core::stringw(fps);
- fpsString += _("/");
- fpsString += core::stringw(max);
- fpsString += _(" PolyCount: ");
- fpsString += _(" (Solid) ");
- fpsString += core::stringw(poly_count[SOLID_NORMAL_AND_DEPTH_PASS]);
- fpsString += _(" (Shadows) ");
- fpsString += core::stringw(poly_count[SHADOW_PASS]);
- fpsString += _(" LightDist: ");
- fpsString += core::stringw(m_last_light_bucket_distance);
+ fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d"),
+ min, fps, max, poly_count[SOLID_NORMAL_AND_DEPTH_PASS], poly_count[SHADOW_PASS], m_last_light_bucket_distance);
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
poly_count[SHADOW_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
@@ -1766,17 +1755,7 @@ void IrrDriver::displayFPS()
object_count[TRANSPARENT_PASS] = 0;
}
else
- {
- fpsString += _("FPS: ");
- fpsString += core::stringw(min);
- fpsString += _("/");
- fpsString += core::stringw(fps);
- fpsString += _("/");
- fpsString += core::stringw(max);
- fpsString += _(" - ");
- fpsString += core::stringw((int)roundf(kilotris));
- fpsString += _("KTris");
- }
+ fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - %d KTris"), min, fps, max, (int)roundf(kilotris));
static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp
index 8c37a212b..a6b990432 100644
--- a/src/graphics/post_processing.hpp
+++ b/src/graphics/post_processing.hpp
@@ -22,7 +22,8 @@
#include "S3DVertex.h"
#include "SMaterial.h"
#include "graphics/camera.hpp"
-#include "graphics/glwrap.hpp"
+
+class FrameBuffer;
#include
diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp
index 5d10ecf62..c71e24a7a 100644
--- a/src/graphics/render.cpp
+++ b/src/graphics/render.cpp
@@ -47,6 +47,9 @@
#include "utils/log.hpp"
#include "utils/profiler.hpp"
#include "stkscenemanager.hpp"
+#include "items/powerup_manager.hpp"
+#include "../../lib/irrlicht/source/Irrlicht/CSceneManager.h"
+#include "../../lib/irrlicht/source/Irrlicht/os.h"
#include
#include
@@ -60,6 +63,27 @@ void IrrDriver::renderGLSL(float dt)
Track *track = world->getTrack();
+ for (unsigned i = 0; i < PowerupManager::POWERUP_MAX; i++)
+ {
+ scene::IMesh *mesh = powerup_manager->m_all_meshes[i];
+ if (!mesh)
+ continue;
+ for (unsigned j = 0; j < mesh->getMeshBufferCount(); j++)
+ {
+ scene::IMeshBuffer *mb = mesh->getMeshBuffer(j);
+ if (!mb)
+ continue;
+ for (unsigned k = 0; k < 4; k++)
+ {
+ video::ITexture *tex = mb->getMaterial().getTexture(k);
+ if (!tex)
+ continue;
+ compressTexture(tex, true);
+ }
+ }
+ }
+
+
// Overrides
video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial();
overridemat.EnablePasses = scene::ESNRP_SOLID | scene::ESNRP_TRANSPARENT;
@@ -572,7 +596,8 @@ core::matrix4 getTighestFitOrthoProj(const core::matrix4 &transform, const std::
void IrrDriver::computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height)
{
- m_scene_manager->drawAll(scene::ESNRP_CAMERA);
+ static_cast(m_scene_manager)->OnAnimate(os::Timer::getTime());
+ camnode->render();
irr_driver->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp
index 74c89078b..d79da6c42 100644
--- a/src/graphics/render_geometry.cpp
+++ b/src/graphics/render_geometry.cpp
@@ -208,6 +208,9 @@ void IrrDriver::renderSolidFirstPass()
glDisable(GL_BLEND);
glEnable(GL_CULL_FACE);
+ if (irr_driver->hasARB_draw_indirect())
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
+
if (!UserConfigParams::m_dynamic_lights)
return;
@@ -231,9 +234,6 @@ void IrrDriver::renderSolidFirstPass()
renderMeshes1stPass(object_pass1_texunits, ListMatSphereMap::getInstance()->SolidPass);
renderMeshes1stPass(object_pass1_texunits, ListMatDetails::getInstance()->SolidPass);
- if (irr_driver->hasARB_draw_indirect())
- glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
-
if (UserConfigParams::m_azdo)
{
#ifdef Multi_Draw_Indirect
diff --git a/src/graphics/render_skybox.cpp b/src/graphics/render_skybox.cpp
index 229d6935f..94d28fb2e 100644
--- a/src/graphics/render_skybox.cpp
+++ b/src/graphics/render_skybox.cpp
@@ -439,7 +439,7 @@ GLuint generateCubeMapFromTextures(const std::vector &texture
swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
}
}
- free(tmp);
+ delete[] tmp;
}
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
diff --git a/src/graphics/rtts.hpp b/src/graphics/rtts.hpp
index e93f1edf1..6dd1e7aa4 100644
--- a/src/graphics/rtts.hpp
+++ b/src/graphics/rtts.hpp
@@ -17,15 +17,19 @@
#ifndef HEADER_RTTS_HPP
#define HEADER_RTTS_HPP
-#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "utils/ptr_vector.hpp"
#include "utils/leak_check.hpp"
+class FrameBuffer;
+
namespace irr {
namespace video {
class ITexture;
};
+ namespace scene {
+ class ICameraSceneNode;
+ }
};
using irr::video::ITexture;
@@ -46,7 +50,7 @@ public:
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
- FrameBuffer* render(scene::ICameraSceneNode* camera, float dt);
+ FrameBuffer* render(irr::scene::ICameraSceneNode* camera, float dt);
private:
unsigned RenderTargetTextures[RTT_COUNT];
diff --git a/src/graphics/screenquad.hpp b/src/graphics/screenquad.hpp
index 478500946..dc2d7b2b2 100644
--- a/src/graphics/screenquad.hpp
+++ b/src/graphics/screenquad.hpp
@@ -17,8 +17,6 @@
#ifndef HEADER_SCREENQUAD_H
#define HEADER_SCREENQUAD_H
-#include "graphics/glwrap.hpp"
-
#include
#include
diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp
index 91d045275..8a31354c5 100644
--- a/src/graphics/stkanimatedmesh.cpp
+++ b/src/graphics/stkanimatedmesh.cpp
@@ -1,3 +1,4 @@
+#include "graphics/glwrap.hpp"
#include "graphics/stkanimatedmesh.hpp"
#include
#include
@@ -32,15 +33,10 @@ void STKAnimatedMesh::cleanGLMeshes()
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
- glDeleteBuffers(1, &(mesh.vertex_buffer));
- glDeleteBuffers(1, &(mesh.index_buffer));
-#ifdef Bindless_Texture_Support
- for (unsigned j = 0; j < 6; j++)
- {
- if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
- glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
- }
-#endif
+ if (mesh.vertex_buffer)
+ glDeleteBuffers(1, &(mesh.vertex_buffer));
+ if (mesh.index_buffer)
+ glDeleteBuffers(1, &(mesh.index_buffer));
}
}
diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp
index 562153dc1..06e925986 100644
--- a/src/graphics/stkmesh.cpp
+++ b/src/graphics/stkmesh.cpp
@@ -1,5 +1,6 @@
-#include "stkmesh.hpp"
+#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
+#include "graphics/stkmesh.hpp"
#include "tracks/track.hpp"
#include
#include
diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp
index 5d46ad6f8..dadeae82f 100644
--- a/src/graphics/stkmesh.hpp
+++ b/src/graphics/stkmesh.hpp
@@ -1,7 +1,6 @@
#ifndef STKMESH_H
#define STKMESH_H
-#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "utils/tuple.hpp"
diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp
index 0bc519032..b4e178f8b 100644
--- a/src/graphics/stkmeshscenenode.cpp
+++ b/src/graphics/stkmeshscenenode.cpp
@@ -1,6 +1,7 @@
#include "stkmeshscenenode.hpp"
#include "stkmesh.hpp"
#include "graphics/irr_driver.hpp"
+#include "graphics/glwrap.hpp"
#include "tracks/track.hpp"
#include
#include
@@ -58,13 +59,6 @@ void STKMeshSceneNode::cleanGLMeshes()
glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer)
glDeleteBuffers(1, &(mesh.index_buffer));
-#ifdef Bindless_Texture_Support
- for (unsigned j = 0; j < 6; j++)
- {
- if (mesh.TextureHandles[j] && glIsTextureHandleResidentARB(mesh.TextureHandles[j]))
- glMakeTextureHandleNonResidentARB(mesh.TextureHandles[j]);
- }
-#endif
}
GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++)
diff --git a/src/graphics/stkscenemanager.cpp b/src/graphics/stkscenemanager.cpp
index 74cece1b8..22d359b84 100644
--- a/src/graphics/stkscenemanager.cpp
+++ b/src/graphics/stkscenemanager.cpp
@@ -1,8 +1,7 @@
-#include "stkscenemanager.hpp"
-#include "stkmesh.hpp"
-#include "irr_driver.hpp"
-#include
-#include
+#include "graphics/glwrap.hpp"
+#include "graphics/stkscenemanager.hpp"
+#include "graphics/stkmesh.hpp"
+#include "graphics/irr_driver.hpp"
#include "stkanimatedmesh.hpp"
#include "stkmeshscenenode.hpp"
#include "utils/ptr_vector.hpp"
@@ -14,6 +13,10 @@
#include "tracks/track.hpp"
#include "lod_node.hpp"
#include "utils/profiler.hpp"
+
+#include
+#include
+
#include
#include
#include
@@ -183,9 +186,45 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed
ImmediateDraw->push_back(Node);
return;
}
+
+
+ // Transparent
+ GLMesh *mesh;
+ if (World::getWorld() && World::getWorld()->isFogEnabled())
+ {
+ const Track * const track = World::getWorld()->getTrack();
+
+ // Todo : put everything in a ubo
+ const float fogmax = track->getFogMax();
+ const float startH = track->getFogStartHeight();
+ const float endH = track->getFogEndHeight();
+ const float start = track->getFogStart();
+ const float end = track->getFogEnd();
+ const video::SColor tmpcol = track->getFogColor();
+
+ video::SColorf col(tmpcol.getRed() / 255.0f,
+ tmpcol.getGreen() / 255.0f,
+ tmpcol.getBlue() / 255.0f);
+
+ for_in(mesh, node->TransparentMesh[TM_DEFAULT])
+ pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
+ fogmax, startH, endH, start, end, col);
+ for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
+ pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
+ fogmax, startH, endH, start, end, col);
+ }
+ else
+ {
+ for_in(mesh, node->TransparentMesh[TM_DEFAULT])
+ pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
+ for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
+ pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
+ }
+ for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
+ pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
+
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
- GLMesh *mesh;
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
@@ -253,8 +292,11 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed
}
}
}
- if (!UserConfigParams::m_shadows)
- return;
+ }
+ if (!UserConfigParams::m_shadows)
+ return;
+ for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
+ {
for (unsigned cascade = 0; cascade < 4; ++cascade)
{
if (irr_driver->hasARB_draw_indirect())
@@ -298,8 +340,11 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed
}
}
}
- if (!UserConfigParams::m_gi)
- return;
+ }
+ if (!UserConfigParams::m_gi)
+ return;
+ for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
+ {
if (irr_driver->hasARB_draw_indirect())
{
for_in(mesh, node->MeshSolidMaterial[Mat])
@@ -349,40 +394,6 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed
}
}
}
- // Transparent
- GLMesh *mesh;
- if (World::getWorld() && World::getWorld()->isFogEnabled())
- {
- const Track * const track = World::getWorld()->getTrack();
-
- // Todo : put everything in a ubo
- const float fogmax = track->getFogMax();
- const float startH = track->getFogStartHeight();
- const float endH = track->getFogEndHeight();
- const float start = track->getFogStart();
- const float end = track->getFogEnd();
- const video::SColor tmpcol = track->getFogColor();
-
- video::SColorf col(tmpcol.getRed() / 255.0f,
- tmpcol.getGreen() / 255.0f,
- tmpcol.getBlue() / 255.0f);
-
- for_in(mesh, node->TransparentMesh[TM_DEFAULT])
- pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
- fogmax, startH, endH, start, end, col);
- for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
- pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix,
- fogmax, startH, endH, start, end, col);
- }
- else
- {
- for_in(mesh, node->TransparentMesh[TM_DEFAULT])
- pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
- for_in(mesh, node->TransparentMesh[TM_ADDITIVE])
- pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->TextureMatrix);
- }
- for_in(mesh, node->TransparentMesh[TM_DISPLACEMENT])
- pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
}
static void
@@ -503,8 +514,10 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
printf("Wait Failed\n");
break;
}*/
+ PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
for (unsigned i = 0; i < DeferredUpdate.size(); i++)
DeferredUpdate[i]->updateGL();
+ PROFILER_POP_CPU_MARKER();
if (!irr_driver->hasARB_draw_indirect())
return;
diff --git a/src/graphics/vaomanager.cpp b/src/graphics/vaomanager.cpp
index 70e49bf3f..a9f3f0051 100644
--- a/src/graphics/vaomanager.cpp
+++ b/src/graphics/vaomanager.cpp
@@ -6,11 +6,10 @@ VAOManager::VAOManager()
vao[0] = vao[1] = vao[2] = 0;
vbo[0] = vbo[1] = vbo[2] = 0;
ibo[0] = ibo[1] = ibo[2] = 0;
- vtx_cnt[0] = vtx_cnt[1] = vtx_cnt[2] = 0;
- idx_cnt[0] = idx_cnt[1] = idx_cnt[2] = 0;
- vtx_mirror[0] = vtx_mirror[1] = vtx_mirror[2] = NULL;
- idx_mirror[0] = idx_mirror[1] = idx_mirror[2] = NULL;
- instance_count[0] = 0;
+ last_vertex[0] = last_vertex[1] = last_vertex[2] = 0;
+ last_index[0] = last_index[1] = last_index[2] = 0;
+ RealVBOSize[0] = RealVBOSize[1] = RealVBOSize[2] = 0;
+ RealIBOSize[0] = RealIBOSize[1] = RealIBOSize[2] = 0;
for (unsigned i = 0; i < InstanceTypeCount; i++)
{
@@ -43,10 +42,6 @@ VAOManager::~VAOManager()
cleanInstanceVAOs();
for (unsigned i = 0; i < 3; i++)
{
- if (vtx_mirror[i])
- free(vtx_mirror[i]);
- if (idx_mirror[i])
- free(idx_mirror[i]);
if (vbo[i])
glDeleteBuffers(1, &vbo[i]);
if (ibo[i])
@@ -61,32 +56,63 @@ VAOManager::~VAOManager()
}
-void VAOManager::regenerateBuffer(enum VTXTYPE tp)
+void VAOManager::regenerateBuffer(enum VTXTYPE tp, size_t newlastvertex, size_t newlastindex)
{
glBindVertexArray(0);
- if (vbo[tp])
- glDeleteBuffers(1, &vbo[tp]);
- glGenBuffers(1, &vbo[tp]);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
-#ifdef Buffer_Storage
- if (irr_driver->hasBufferStorageExtension())
+
+ if (newlastindex >= RealVBOSize[tp])
{
- glBufferStorage(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
- VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, vtx_cnt[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
+ while (newlastindex >= RealVBOSize[tp])
+ RealVBOSize[tp] = 2 * RealVBOSize[tp] + 1;
+ GLuint newVBO;
+ glGenBuffers(1, &newVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, newVBO);
+ if (irr_driver->hasBufferStorageExtension())
+ {
+ glBufferStorage(GL_ARRAY_BUFFER, RealVBOSize[tp] * getVertexPitch(tp), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
+ VBOPtr[tp] = glMapBufferRange(GL_ARRAY_BUFFER, 0, RealVBOSize[tp] * getVertexPitch(tp), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
+ }
+ else
+ glBufferData(GL_ARRAY_BUFFER, RealVBOSize[tp] * getVertexPitch(tp), 0, GL_DYNAMIC_DRAW);
+
+ if (vbo[tp])
+ {
+ GLuint oldVBO = vbo[tp];
+ glBindBuffer(GL_COPY_WRITE_BUFFER, newVBO);
+ glBindBuffer(GL_COPY_READ_BUFFER, oldVBO);
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, last_vertex[tp] * getVertexPitch(tp));
+ glDeleteBuffers(1, &oldVBO);
+ }
+ vbo[tp] = newVBO;
}
- else
-#endif
- glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_DRAW);
+ last_vertex[tp] = newlastvertex;
+ if (newlastindex >= RealIBOSize[tp])
+ {
+ while (newlastindex >= RealIBOSize[tp])
+ RealIBOSize[tp] = 2 * RealIBOSize[tp] + 1;
+ GLuint newIBO;
+ glGenBuffers(1, &newIBO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newIBO);
+ if (irr_driver->hasBufferStorageExtension())
+ {
+ glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, RealIBOSize[tp] * sizeof(u16), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
+ IBOPtr[tp] = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, RealIBOSize[tp] * sizeof(u16), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
+ }
+ else
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, RealIBOSize[tp] * sizeof(u16), 0, GL_STATIC_DRAW);
- if (ibo[tp])
- glDeleteBuffers(1, &ibo[tp]);
- glGenBuffers(1, &ibo[tp]);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(u16)* idx_cnt[tp], idx_mirror[tp], GL_DYNAMIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ if (ibo[tp])
+ {
+ GLuint oldIBO = ibo[tp];
+ glBindBuffer(GL_COPY_WRITE_BUFFER, newIBO);
+ glBindBuffer(GL_COPY_READ_BUFFER, oldIBO);
+ glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, last_index[tp] * sizeof(u16));
+ glDeleteBuffers(1, &oldIBO);
+ }
+ ibo[tp] = newIBO;
+ }
+ last_index[tp] = newlastindex;
}
void VAOManager::regenerateVAO(enum VTXTYPE tp)
@@ -281,19 +307,32 @@ VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type)
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
{
- size_t old_vtx_cnt = vtx_cnt[tp];
- vtx_cnt[tp] += mb->getVertexCount();
- vtx_mirror[tp] = realloc(vtx_mirror[tp], vtx_cnt[tp] * getVertexPitch(tp));
- intptr_t dstptr = (intptr_t)vtx_mirror[tp] + (old_vtx_cnt * getVertexPitch(tp));
- memcpy((void *)dstptr, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp));
+ size_t old_vtx_cnt = last_vertex[tp];
+ size_t old_idx_cnt = last_index[tp];
+
+ regenerateBuffer(tp, old_vtx_cnt + mb->getVertexCount(), old_idx_cnt + mb->getIndexCount());
+ if (irr_driver->hasBufferStorageExtension())
+ {
+ void *tmp = (char*)VBOPtr[tp] + old_vtx_cnt * getVertexPitch(tp);
+ memcpy(tmp, mb->getVertices(), mb->getVertexCount() * getVertexPitch(tp));
+ }
+ else
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
+ glBufferSubData(GL_ARRAY_BUFFER, old_vtx_cnt * getVertexPitch(tp), mb->getVertexCount() * getVertexPitch(tp), mb->getVertices());
+ }
+ if (irr_driver->hasBufferStorageExtension())
+ {
+ void *tmp = (char*)IBOPtr[tp] + old_idx_cnt * sizeof(u16);
+ memcpy(tmp, mb->getIndices(), mb->getIndexCount() * sizeof(u16));
+ }
+ else
+ {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices());
+ }
+
mappedBaseVertex[tp][mb] = old_vtx_cnt;
-
- size_t old_idx_cnt = idx_cnt[tp];
- idx_cnt[tp] += mb->getIndexCount();
- idx_mirror[tp] = realloc(idx_mirror[tp], idx_cnt[tp] * sizeof(u16));
-
- dstptr = (intptr_t)idx_mirror[tp] + (old_idx_cnt * sizeof(u16));
- memcpy((void *)dstptr, mb->getIndices(), mb->getIndexCount() * sizeof(u16));
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
}
@@ -303,9 +342,7 @@ std::pair VAOManager::getBase(scene::IMeshBuffer *mb)
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
{
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
- storedCPUBuffer[tp].push_back(mb);
append(mb, tp);
- regenerateBuffer(tp);
regenerateVAO(tp);
regenerateInstancedVAO();
}
diff --git a/src/graphics/vaomanager.hpp b/src/graphics/vaomanager.hpp
index 39056c0aa..04cc4c5a7 100644
--- a/src/graphics/vaomanager.hpp
+++ b/src/graphics/vaomanager.hpp
@@ -83,17 +83,15 @@ class VAOManager : public Singleton
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
GLuint instance_vbo[InstanceTypeCount];
- size_t instance_count[InstanceTypeCount];
void *Ptr[InstanceTypeCount];
- void *VBOPtr[VTXTYPE_COUNT];
- std::vector storedCPUBuffer[VTXTYPE_COUNT];
- void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
- size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
+ void *VBOPtr[VTXTYPE_COUNT], *IBOPtr[VTXTYPE_COUNT];
+ size_t RealVBOSize[VTXTYPE_COUNT], RealIBOSize[VTXTYPE_COUNT];
+ size_t last_vertex[VTXTYPE_COUNT], last_index[VTXTYPE_COUNT];
std::unordered_map mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map, GLuint> InstanceVAO;
void cleanInstanceVAOs();
- void regenerateBuffer(enum VTXTYPE);
+ void regenerateBuffer(enum VTXTYPE, size_t, size_t);
void regenerateVAO(enum VTXTYPE);
void regenerateInstancedVAO();
size_t getVertexPitch(enum VTXTYPE) const;
diff --git a/src/items/powerup_manager.hpp b/src/items/powerup_manager.hpp
index ec6ce3c7c..4bb3d69d5 100644
--- a/src/items/powerup_manager.hpp
+++ b/src/items/powerup_manager.hpp
@@ -115,9 +115,11 @@ private:
/** Last time the bouncing ball was collected */
float m_rubber_ball_collect_time;
+public:
/** The mesh for each model (if the powerup has a model), e.g. a switch
has none. */
irr::scene::IMesh *m_all_meshes[POWERUP_MAX];
+private:
/** Size of the corresponding mesh. */
btVector3 m_all_extends[POWERUP_MAX];
diff --git a/src/modes/world.cpp b/src/modes/world.cpp
index 9b19ba181..9717b9ba9 100644
--- a/src/modes/world.cpp
+++ b/src/modes/world.cpp
@@ -917,35 +917,45 @@ void World::update(float dt)
}
#endif
+ PROFILER_PUSH_CPU_MARKER("World::update (sub-updates)", 0x20, 0x7F, 0x00);
history->update(dt);
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
if(history->replayHistory()) dt=history->getNextDelta();
WorldStatus::update(dt);
+ PROFILER_POP_CPU_MARKER();
if (!history->dontDoPhysics())
{
m_physics->update(dt);
}
+ PROFILER_PUSH_CPU_MARKER("World::update (AI)", 0x40, 0x7F, 0x00);
const int kart_amount = m_karts.size();
for (int i = 0 ; i < kart_amount; ++i)
{
// Update all karts that are not eliminated
if(!m_karts[i]->isEliminated()) m_karts[i]->update(dt) ;
}
+ PROFILER_POP_CPU_MARKER();
+ PROFILER_PUSH_CPU_MARKER("World::update (camera)", 0x60, 0x7F, 0x00);
for(unsigned int i=0; iupdate(dt);
}
-
+ PROFILER_POP_CPU_MARKER();
+
+ PROFILER_PUSH_CPU_MARKER("World::update (weather)", 0x80, 0x7F, 0x00);
if (UserConfigParams::m_graphical_effects && m_weather)
{
m_weather->update(dt);
}
+ PROFILER_POP_CPU_MARKER();
+ PROFILER_PUSH_CPU_MARKER("World::update (projectiles)", 0xa0, 0x7F, 0x00);
projectile_manager->update(dt);
+ PROFILER_POP_CPU_MARKER();
PROFILER_POP_CPU_MARKER();
diff --git a/src/states_screens/track_info_screen.cpp b/src/states_screens/track_info_screen.cpp
index 0e8914283..de3852755 100644
--- a/src/states_screens/track_info_screen.cpp
+++ b/src/states_screens/track_info_screen.cpp
@@ -193,6 +193,9 @@ void TrackInfoScreen::init()
getWidget("highscore2")->setVisible(false);
getWidget("highscore3")->setVisible(false);
}
+
+ RibbonWidget* bt_start = getWidget("buttons");
+ bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
} // init
@@ -325,3 +328,37 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
} // eventCallback
// ----------------------------------------------------------------------------
+GUIEngine::EventPropagation TrackInfoScreen::filterActions(PlayerAction action,
+ int deviceID,
+ const unsigned int value,
+ Input::InputType type,
+ int playerId)
+{
+ GUIEngine::EventPropagation result = EVENT_LET;
+ RibbonWidget* bt_start = getWidget("buttons");
+
+ switch (action)
+ {
+ case PA_MENU_LEFT:
+ case PA_MENU_RIGHT:
+ {
+ if (bt_start->isFocusedForPlayer(playerId))
+ {
+ result = EVENT_BLOCK;
+ }
+
+ break;
+ }
+ case PA_MENU_UP:
+ case PA_MENU_DOWN:
+ case PA_MENU_SELECT:
+ case PA_MENU_CANCEL:
+ break;
+ default:
+ break;
+ }
+
+ return result;
+} // filterActions
+
+// -----------------------------------------------------------------------------
diff --git a/src/states_screens/track_info_screen.hpp b/src/states_screens/track_info_screen.hpp
index 00387bc60..ee2668ad8 100644
--- a/src/states_screens/track_info_screen.hpp
+++ b/src/states_screens/track_info_screen.hpp
@@ -74,6 +74,14 @@ public:
virtual void loadedFromFile();
virtual void eventCallback(GUIEngine::Widget *,const std::string &name ,
const int player_id);
+
+ /** \brief implement callback from parent class GUIEngine::Screen */
+ virtual GUIEngine::EventPropagation filterActions( PlayerAction action,
+ int deviceID,
+ const unsigned int value,
+ Input::InputType type,
+ int playerId) OVERRIDE;
+
void onEnterPressedInternal();
void setTrack(Track *track);
};
diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp
index 4578c6899..ec7598cc3 100644
--- a/src/tracks/track.hpp
+++ b/src/tracks/track.hpp
@@ -605,37 +605,59 @@ public:
/** Returns true if the normals of this track can be smoothed. */
bool smoothNormals() const { return m_smooth_normals; }
// ------------------------------------------------------------------------
- TrackObjectManager* getTrackObjectManager() const {return m_track_object_manager;}
+ /** Returns the track object manager. */
+ TrackObjectManager* getTrackObjectManager() const
+ {
+ return m_track_object_manager;
+ } // getTrackObjectManager
+ // ------------------------------------------------------------------------
/** Get list of challenges placed on that world. Works only for overworld. */
const std::vector& getChallengeList() const
{ return m_challenges; }
+ // ------------------------------------------------------------------------
const std::vector& getSubtitles() const { return m_subtitles; }
+ // ------------------------------------------------------------------------
bool hasClouds() const { return m_clouds; }
+ // ------------------------------------------------------------------------
bool getBloom() const { return m_bloom; }
+
+ // ------------------------------------------------------------------------
float getBloomThreshold() const { return m_bloom_threshold; }
+ // ------------------------------------------------------------------------
/** Return the color levels for color correction shader */
core::vector3df getColorLevelIn() const { return m_color_inlevel; }
+ // ------------------------------------------------------------------------
core::vector2df getColorLevelOut() const { return m_color_outlevel; }
+ // ------------------------------------------------------------------------
bool hasLensFlare() const { return m_lensflare; }
+ // ------------------------------------------------------------------------
bool hasGodRays() const { return m_godrays; }
+ // ------------------------------------------------------------------------
core::vector3df getGodRaysPosition() const { return m_godrays_position; }
+ // ------------------------------------------------------------------------
float getGodRaysOpacity() const { return m_godrays_opacity; }
+ // ------------------------------------------------------------------------
video::SColor getGodRaysColor() const { return m_godrays_color; }
+ // ------------------------------------------------------------------------
bool hasShadows() const { return m_shadows; }
-
+ // ------------------------------------------------------------------------
void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); }
-
- float getDisplacementSpeed() const { return m_displacement_speed; }
- float getCausticsSpeed() const { return m_caustics_speed; }
+ // ------------------------------------------------------------------------
+ float getDisplacementSpeed() const { return m_displacement_speed; }
+ // ------------------------------------------------------------------------
+ float getCausticsSpeed() const { return m_caustics_speed; }
+ // ------------------------------------------------------------------------
const int getDefaultNumberOfLaps() const { return m_default_number_of_laps;}
- const int getActualNumberOfLap() const { return m_actual_number_of_laps; }
- void setActualNumberOfLaps(unsigned int laps)
+ // ------------------------------------------------------------------------
+ const int getActualNumberOfLap() const { return m_actual_number_of_laps; }
+ // ------------------------------------------------------------------------
+ void setActualNumberOfLaps(unsigned int laps)
{ m_actual_number_of_laps = laps; }
bool operator<(const Track &other) const;
}; // class Track
diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp
index 19d9f3fe5..423fcd9dd 100644
--- a/src/utils/string_utils.hpp
+++ b/src/utils/string_utils.hpp
@@ -250,88 +250,27 @@ namespace StringUtils
} // insertValues(s, v1)
// ------------------------------------------------------------------------
+ /** Intermediate struct to fill a vector using variadic templates */
+ struct __FillStringwVector
+ {
+ template
+ static void __Fill(std::vector &all_vals, T&& v, Args &&...args)
+ {
+ all_vals.push_back(irr::core::stringw(std::forward(v)));
+ __Fill(all_vals, std::forward(args)...);
+ }
+
+ static void __Fill(std::vector&) {}
+ };
+
/** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
- const T2 &v2, const T3 &v3, const T4 &v4,
- const T5 &v5, const T6 &v6)
+ template
+ irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
{
std::vector all_vals;
- all_vals.push_back( irr::core::stringw(v1) );
- all_vals.push_back( irr::core::stringw(v2) );
- all_vals.push_back( irr::core::stringw(v3) );
- all_vals.push_back( irr::core::stringw(v4) );
- all_vals.push_back( irr::core::stringw(v5) );
- all_vals.push_back( irr::core::stringw(v6) );
+ __FillStringwVector::__Fill(all_vals, std::forward(args)...);
return insertValues(s, all_vals);
- } // insertValues(s, v1, ..., v6)
-
-
- // ------------------------------------------------------------------------
- /** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
- const T2 &v2, const T3 &v3, const T4 &v4,
- const T5 &v5)
- {
- std::vector all_vals;
- all_vals.push_back( irr::core::stringw(v1) );
- all_vals.push_back( irr::core::stringw(v2) );
- all_vals.push_back( irr::core::stringw(v3) );
- all_vals.push_back( irr::core::stringw(v4) );
- all_vals.push_back( irr::core::stringw(v5) );
- return insertValues(s, all_vals);
- } // insertValues(s, v1, ..., v5)
-
- // ------------------------------------------------------------------------
- /** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
- const T2 &v2, const T3 &v3, const T4 &v4)
- {
- std::vector all_vals;
- all_vals.push_back( irr::core::stringw(v1) );
- all_vals.push_back( irr::core::stringw(v2) );
- all_vals.push_back( irr::core::stringw(v3) );
- all_vals.push_back( irr::core::stringw(v4) );
- return insertValues(s, all_vals);
- } // insertValues(s, v1, ..., v4)
-
- // ------------------------------------------------------------------------
- /** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
- const T2 &v2, const T3 &v3)
- {
- std::vector all_vals;
- irr::core::stringw dummy;
- all_vals.push_back( irr::core::stringw(v1) );
- all_vals.push_back( irr::core::stringw(v2) );
- all_vals.push_back( irr::core::stringw(v3) );
- return insertValues(s, all_vals);
- } // insertValues(s, v1, ..., v3)
-
- // ------------------------------------------------------------------------
- /** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
- const T2 &v2)
- {
- std::vector all_vals;
- all_vals.push_back( irr::core::stringw(v1) );
- all_vals.push_back( irr::core::stringw(v2) );
- return insertValues(s, all_vals);
- } // insertValues(s, v1, v2)
-
- // ------------------------------------------------------------------------
- /** Like the other ones above but for wide strings */
- template
- irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1)
- {
- std::vector all_vals;
- all_vals.push_back( irr::core::stringw(v1) );
- return insertValues(s, all_vals);
- } // insertValues(s, v1)
+ }
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */