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