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/data/shaders/particle.vert b/data/shaders/particle.vert index 99d38137c..78d32ef29 100644 --- a/data/shaders/particle.vert +++ b/data/shaders/particle.vert @@ -1,12 +1,21 @@ uniform vec3 color_from; uniform vec3 color_to; +#if __VERSION__ >= 330 layout(location=0) in vec3 Position; layout(location = 1) in float lifetime; layout(location = 2) in float size; layout(location=3) in vec2 Texcoord; layout(location = 4) in vec2 quadcorner; +#else +in vec3 Position; +in float lifetime; +in float size; + +in vec2 Texcoord; +in vec2 quadcorner; +#endif out float lf; out vec2 tc; diff --git a/data/shaders/particlesimheightmap.vert b/data/shaders/particlesimheightmap.vert index dc5241719..eec3151c1 100644 --- a/data/shaders/particlesimheightmap.vert +++ b/data/shaders/particlesimheightmap.vert @@ -9,6 +9,7 @@ uniform float track_x_len; uniform float track_z_len; uniform samplerBuffer heightmap; +#if __VERSION__ >= 330 layout (location = 4) in vec3 particle_position_initial; layout (location = 5) in float lifetime_initial; layout (location = 6) in vec3 particle_velocity_initial; @@ -18,6 +19,17 @@ layout (location = 0) in vec3 particle_position; layout (location = 1) in float lifetime; layout (location = 2) in vec3 particle_velocity; layout (location = 3) in float size; +#else +in vec3 particle_position_initial; +in float lifetime_initial; +in vec3 particle_velocity_initial; +in float size_initial; + +in vec3 particle_position; +in float lifetime; +in vec3 particle_velocity; +in float size; +#endif out vec3 new_particle_position; out float new_lifetime; diff --git a/data/shaders/pointemitter.vert b/data/shaders/pointemitter.vert index 003c128d6..3203d965b 100644 --- a/data/shaders/pointemitter.vert +++ b/data/shaders/pointemitter.vert @@ -3,6 +3,7 @@ uniform mat4 sourcematrix; uniform int level; uniform float size_increase_factor; +#if __VERSION__ >= 330 layout (location = 4) in vec3 particle_position_initial; layout (location = 5) in float lifetime_initial; layout (location = 6) in vec3 particle_velocity_initial; @@ -12,6 +13,17 @@ layout (location = 0) in vec3 particle_position; layout (location = 1) in float lifetime; layout (location = 2) in vec3 particle_velocity; layout (location = 3) in float size; +#else +in vec3 particle_position_initial; +in float lifetime_initial; +in vec3 particle_velocity_initial; +in float size_initial; + +in vec3 particle_position; +in float lifetime; +in vec3 particle_velocity; +in float size; +#endif out vec3 new_particle_position; out float new_lifetime; diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index b5423ca57..00353a264 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -3,6 +3,8 @@ // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h +extern bool GLContextDebugBit; + #include "CIrrDeviceLinux.h" #ifdef _IRR_COMPILE_WITH_X11_DEVICE_ @@ -497,7 +499,7 @@ void IrrPrintXGrabError(int grabResult, const c8 * grabCommand ) static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig) { GLXContext Context; - int compat33ctx[] = + int compat33ctxdebug[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, @@ -505,7 +507,14 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig) GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, None }; - int core33ctx[] = + int compat33ctx[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + None + }; + int core33ctxdebug[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, @@ -513,12 +522,26 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig) GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, None }; + int core33ctx[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + }; + int core31ctxdebug[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + None + }; int core31ctx[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, None }; int legacyctx[] = @@ -532,19 +555,19 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); // create compat 3.3 context (for proprietary drivers) - Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, compat33ctx); + Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? compat33ctxdebug : compat33ctx); if (!XErrorSignaled) return Context; XErrorSignaled = false; // create core 3.3 context (for mesa) - Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, core33ctx); + Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core33ctxdebug : core33ctx); if (!XErrorSignaled) return Context; XErrorSignaled = false; // create core 3.1 context (for older mesa) - Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, core31ctx); + Context = glXCreateContextAttribsARB(display, glxFBConfig, 0, True, GLContextDebugBit ? core31ctxdebug : core31ctx); if (!XErrorSignaled) return Context; diff --git a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp index 0c07edcc4..451cd60af 100644 --- a/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp +++ b/lib/irrlicht/source/Irrlicht/COpenGLDriver.cpp @@ -2,6 +2,9 @@ // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h + +extern bool GLContextDebugBit; + #include "COpenGLDriver.h" // needed here also because of the create methods' parameters #include "CNullDriver.h" @@ -89,7 +92,7 @@ static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB; static HGLRC getMeAGLContext(HDC HDc) { HGLRC hrc = 0; - int ctx44[] = + int ctx44debug[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 3, @@ -98,11 +101,19 @@ static HGLRC getMeAGLContext(HDC HDc) 0 }; - hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx44); + int ctx44[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + + hrc = wglCreateContextAttribs_ARB(HDc, 0, GLContextDebugBit ? ctx44debug : ctx44); if (hrc) return hrc; - int ctx40[] = + int ctx40debug[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 0, @@ -111,11 +122,19 @@ static HGLRC getMeAGLContext(HDC HDc) 0 }; - hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx40); + int ctx40[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 0, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + + hrc = wglCreateContextAttribs_ARB(HDc, 0, GLContextDebugBit ? ctx40debug : ctx40); if (hrc) return hrc; - int ctx33[] = + int ctx33debug[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, @@ -124,11 +143,19 @@ static HGLRC getMeAGLContext(HDC HDc) 0 }; - hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx33); + int ctx33[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + + hrc = wglCreateContextAttribs_ARB(HDc, 0, GLContextDebugBit ? ctx33debug : ctx33); if (hrc) return hrc; - int ctx31[] = + int ctx31debug[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 1, @@ -136,7 +163,15 @@ static HGLRC getMeAGLContext(HDC HDc) WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; - hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx31); + + int ctx31[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 3, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0 + }; + hrc = wglCreateContextAttribs_ARB(HDc, 0, GLContextDebugBit ? ctx31debug : ctx31); if (hrc) return hrc; diff --git a/src/graphics/gl_headers.hpp b/src/graphics/gl_headers.hpp index 50069f23f..a30fabc67 100644 --- a/src/graphics/gl_headers.hpp +++ b/src/graphics/gl_headers.hpp @@ -1,7 +1,13 @@ #ifndef GL_HEADER_HPP #define GL_HEADER_HPP -#define GLEW_STATIC +#if defined(WIN32) && !defined(__CYGWIN__) + // glew in the binary distribution only comes as dynamic library. +# undef GLEW_STATIC +#else +# define GLEW_STATIC +#endif + extern "C" { #include } @@ -29,12 +35,6 @@ extern "C" { # include #endif -#define Bindless_Texture_Support -#define Base_Instance_Support -#define Buffer_Storage -#define Multi_Draw_Indirect -#define Draw_Indirect - struct DrawElementsIndirectCommand{ GLuint count; GLuint instanceCount; @@ -43,4 +43,4 @@ struct DrawElementsIndirectCommand{ GLuint baseInstance; }; -#endif \ No newline at end of file +#endif diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 7c7975fbd..f6eae07f1 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -11,6 +11,12 @@ static bool is_gl_init = false; +#if DEBUG +bool GLContextDebugBit = true; +#else +bool GLContextDebugBit = false; +#endif + #ifdef DEBUG #if !defined(__APPLE__) #define ARB_DEBUG_OUTPUT @@ -181,10 +187,46 @@ GLuint LoadShader(const char * file, unsigned type) return Id; } +void setAttribute(AttributeType Tp, GLuint ProgramID) +{ + switch (Tp) + { + case OBJECT: + glBindAttribLocation(ProgramID, 0, "Position"); + glBindAttribLocation(ProgramID, 1, "Normal"); + glBindAttribLocation(ProgramID, 2, "Color"); + glBindAttribLocation(ProgramID, 3, "Texcoord"); + glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); + glBindAttribLocation(ProgramID, 5, "Tangent"); + glBindAttribLocation(ProgramID, 6, "Bitangent"); + glBindAttribLocation(ProgramID, 7, "Origin"); + glBindAttribLocation(ProgramID, 8, "Orientation"); + glBindAttribLocation(ProgramID, 9, "Scale"); + break; + case PARTICLES_SIM: + glBindAttribLocation(ProgramID, 0, "particle_position"); + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "particle_velocity"); + glBindAttribLocation(ProgramID, 3, "size"); + glBindAttribLocation(ProgramID, 4, "particle_position_initial"); + glBindAttribLocation(ProgramID, 5, "lifetime_initial"); + glBindAttribLocation(ProgramID, 6, "particle_velocity_initial"); + glBindAttribLocation(ProgramID, 7, "size_initial"); + break; + case PARTICLES_RENDERING: + glBindAttribLocation(ProgramID, 1, "lifetime"); + glBindAttribLocation(ProgramID, 2, "size"); + glBindAttribLocation(ProgramID, 4, "quadcorner"); + break; + } +} + GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount) { GLuint Program = glCreateProgram(); loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); + if (irr_driver->getGLSLVersion() < 330) + setAttribute(PARTICLES_SIM, Program); glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(Program); @@ -397,340 +439,6 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum glGetError(); } -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; - - for (unsigned i = 0; i < InstanceTypeCount; i++) - { - glGenBuffers(1, &instance_vbo[i]); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]); -#ifdef Buffer_Storage - if (irr_driver->hasBufferStorageExtension()) - { - glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); - Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); - } - else -#endif - { - glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW); - } - } -} - -static void cleanVAOMap(std::map, GLuint> Map) -{ - std::map, GLuint>::iterator It = Map.begin(), E = Map.end(); - for (; It != E; It++) - { - glDeleteVertexArrays(1, &(It->second)); - } -} - -void VAOManager::cleanInstanceVAOs() -{ - cleanVAOMap(InstanceVAO); - InstanceVAO.clear(); -} - -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]) - glDeleteBuffers(1, &ibo[i]); - if (vao[i]) - glDeleteVertexArrays(1, &vao[i]); - } - for (unsigned i = 0; i < InstanceTypeCount; i++) - { - glDeleteBuffers(1, &instance_vbo[i]); - } - -} - -void VAOManager::regenerateBuffer(enum VTXTYPE tp) -{ - 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()) - { - 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); - } - else -#endif - glBufferData(GL_ARRAY_BUFFER, vtx_cnt[tp] * getVertexPitch(tp), vtx_mirror[tp], GL_DYNAMIC_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); -} - -void VAOManager::regenerateVAO(enum VTXTYPE tp) -{ - if (vao[tp]) - glDeleteVertexArrays(1, &vao[tp]); - glGenVertexArrays(1, &vao[tp]); - glBindVertexArray(vao[tp]); - glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]); - switch (tp) - { - case VTXTYPE_STANDARD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - break; - case VTXTYPE_TCOORD: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // SecondTexcoord - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - break; - case VTXTYPE_TANGENT: - // Position - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), 0); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)12); - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitch(tp), (GLvoid*)24); - // Texcoord - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)28); - // Tangent - glEnableVertexAttribArray(5); - glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)36); - // Bitangent - glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitch(tp), (GLvoid*)48); - break; - } - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[tp]); - glBindVertexArray(0); -} - -void VAOManager::regenerateInstancedVAO() -{ - cleanInstanceVAOs(); - - enum video::E_VERTEX_TYPE IrrVT[] = { video::EVT_STANDARD, video::EVT_2TCOORDS, video::EVT_TANGENTS }; - for (unsigned i = 0; i < VTXTYPE_COUNT; i++) - { - video::E_VERTEX_TYPE tp = IrrVT[i]; - if (!vbo[tp] || !ibo[tp]) - continue; - GLuint vao = createVAO(vbo[tp], ibo[tp], tp); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]); - - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); - glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float))); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); - glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned))); - glVertexAttribDivisor(11, 1); - InstanceVAO[std::pair(tp, InstanceTypeDefault)] = vao; - - vao = createVAO(vbo[tp], ibo[tp], tp); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]); - - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); - glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float))); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); - glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned))); - glVertexAttribDivisor(11, 1); - InstanceVAO[std::pair(tp, InstanceTypeShadow)] = vao; - - vao = createVAO(vbo[tp], ibo[tp], tp); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]); - - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(10); - glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float))); - glVertexAttribDivisor(10, 1); - glEnableVertexAttribArray(11); - glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned))); - glVertexAttribDivisor(11, 1); - InstanceVAO[std::pair(tp, InstanceTypeRSM)] = vao; - - vao = createVAO(vbo[tp], ibo[tp], tp); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]); - - glEnableVertexAttribArray(7); - glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0); - glVertexAttribDivisor(7, 1); - glEnableVertexAttribArray(8); - glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float))); - glVertexAttribDivisor(8, 1); - glEnableVertexAttribArray(9); - glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float))); - glVertexAttribDivisor(9, 1); - glEnableVertexAttribArray(12); - glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float))); - glVertexAttribDivisor(12, 1); - InstanceVAO[std::pair(tp, InstanceTypeGlow)] = vao; - glBindVertexArray(0); - } - - - -} - -size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const -{ - switch (tp) - { - case VTXTYPE_STANDARD: - return getVertexPitchFromType(video::EVT_STANDARD); - case VTXTYPE_TCOORD: - return getVertexPitchFromType(video::EVT_2TCOORDS); - case VTXTYPE_TANGENT: - return getVertexPitchFromType(video::EVT_TANGENTS); - default: - assert(0 && "Wrong vtxtype"); - return -1; - } -} - -VAOManager::VTXTYPE VAOManager::getVTXTYPE(video::E_VERTEX_TYPE type) -{ - switch (type) - { - default: - assert(0 && "Wrong vtxtype"); - case video::EVT_STANDARD: - return VTXTYPE_STANDARD; - case video::EVT_2TCOORDS: - return VTXTYPE_TCOORD; - case video::EVT_TANGENTS: - return VTXTYPE_TANGENT; - } -}; - -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)); - 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); -} - -std::pair VAOManager::getBase(scene::IMeshBuffer *mb) -{ - VTXTYPE tp = getVTXTYPE(mb->getVertexType()); - 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(); - } - - std::map::iterator It; - It = mappedBaseVertex[tp].find(mb); - assert(It != mappedBaseVertex[tp].end()); - unsigned vtx = It->second; - It = mappedBaseIndex[tp].find(mb); - assert(It != mappedBaseIndex[tp].end()); - return std::pair(vtx, It->second); -} - -size_t VAOManager::appendInstance(enum InstanceType, const std::vector &instance_data) -{ - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[0]); - glBufferSubData(GL_ARRAY_BUFFER, instance_count[0] * sizeof(InstanceData), instance_data.size() * sizeof(InstanceData), instance_data.data()); - size_t result = instance_count[0]; - instance_count[0] += instance_data.size(); - return result; -} - ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t) { if (!UserConfigParams::m_profiler_enabled) return; diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index cd4da2a20..8fa49c6c4 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -6,7 +6,7 @@ #include #include "irr_driver.hpp" #include "utils/log.hpp" - +#include "vaomanager.hpp" void initGL(); GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); @@ -42,24 +42,22 @@ void printFileList(GLint ShaderType, const char *filepath, Types ... args) printFileList(args...); } +enum AttributeType +{ + OBJECT, + PARTICLES_SIM, + PARTICLES_RENDERING, +}; + +void setAttribute(AttributeType Tp, GLuint ProgramID); + template -GLint LoadProgram(Types ... args) +GLint LoadProgram(AttributeType Tp, Types ... args) { GLint ProgramID = glCreateProgram(); loadAndAttach(ProgramID, args...); if (irr_driver->getGLSLVersion() < 330) - { - glBindAttribLocation(ProgramID, 0, "Position"); - glBindAttribLocation(ProgramID, 1, "Normal"); - glBindAttribLocation(ProgramID, 2, "Color"); - glBindAttribLocation(ProgramID, 3, "Texcoord"); - glBindAttribLocation(ProgramID, 4, "SecondTexcoord"); - glBindAttribLocation(ProgramID, 5, "Tangent"); - glBindAttribLocation(ProgramID, 6, "Bitangent"); - glBindAttribLocation(ProgramID, 7, "Origin"); - glBindAttribLocation(ProgramID, 8, "Orientation"); - glBindAttribLocation(ProgramID, 9, "Scale"); - } + setAttribute(Tp, ProgramID); glLinkProgram(ProgramID); GLint Result = GL_FALSE; @@ -139,110 +137,6 @@ void compressTexture(irr::video::ITexture *tex, bool srgb, bool premul_alpha = f bool loadCompressedTexture(const std::string& compressed_tex); void saveCompressedTexture(const std::string& compressed_tex); -enum InstanceType -{ - InstanceTypeDefault, - InstanceTypeShadow, - InstanceTypeRSM, - InstanceTypeGlow, - InstanceTypeCount, -}; - -#ifdef WIN32 -#pragma pack(push, 1) -#endif -struct InstanceData -{ - struct - { - float X; - float Y; - float Z; - } Origin; - struct - { - float X; - float Y; - float Z; - } Orientation; - struct - { - float X; - float Y; - float Z; - } Scale; - uint64_t Texture; - uint64_t SecondTexture; -#ifdef WIN32 -}; -#else -} __attribute__((packed)); -#endif - -struct GlowInstanceData -{ - struct - { - float X; - float Y; - float Z; - } Origin; - struct - { - float X; - float Y; - float Z; - } Orientation; - struct - { - float X; - float Y; - float Z; - } Scale; - unsigned Color; -#ifdef WIN32 -}; -#else -} __attribute__((packed)); -#endif -#ifdef WIN32 -#pragma pack(pop) -#endif - -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]; - std::map mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT]; - std::map, GLuint> InstanceVAO; - - void cleanInstanceVAOs(); - void regenerateBuffer(enum VTXTYPE); - void regenerateVAO(enum VTXTYPE); - void regenerateInstancedVAO(); - size_t getVertexPitch(enum VTXTYPE) const; - VTXTYPE getVTXTYPE(video::E_VERTEX_TYPE type); - void append(scene::IMeshBuffer *, VTXTYPE tp); -public: - VAOManager(); - std::pair getBase(scene::IMeshBuffer *); - size_t appendInstance(enum InstanceType, const std::vector &instance_data); - GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; } - void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; } - unsigned getVBO(video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; } - void *getVBOPtr(video::E_VERTEX_TYPE type) { return VBOPtr[getVTXTYPE(type)]; } - unsigned getVAO(video::E_VERTEX_TYPE type) { return vao[getVTXTYPE(type)]; } - unsigned getInstanceVAO(video::E_VERTEX_TYPE vt, enum InstanceType it) { return InstanceVAO[std::pair(vt, it)]; } - ~VAOManager(); -}; - void draw3DLine(const core::vector3df& start, const core::vector3df& end, irr::video::SColor color); 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 15d911208..8e7ed3c75 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -504,34 +504,35 @@ void IrrDriver::initDevice() hasComputeShaders = false; hasTextureStorage = false; // Default false value for hasVSLayer if --no-graphics argument is used +#if !defined(__APPLE__) 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"); } } - +#endif // This remaps the window, so it has to be done before the clear to avoid flicker @@ -1742,17 +1743,12 @@ void IrrDriver::displayFPS() if (low > kilotris) low = kilotris; if (high < kilotris) high = kilotris; - static char buffer[128]; + core::stringw fpsString; if (UserConfigParams::m_artist_debug_mode) { - sprintf( - buffer, "FPS: %i/%i/%i - PolyCount (Solid:%d Shadows:%d) - LightDst : ~%d", - min, fps, max, - poly_count[SOLID_NORMAL_AND_DEPTH_PASS], - poly_count[SHADOW_PASS], - 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; @@ -1760,12 +1756,7 @@ void IrrDriver::displayFPS() object_count[TRANSPARENT_PASS] = 0; } else - { - sprintf(buffer, "FPS: %i/%i/%i - %i KTris", min, fps, max, - (int)roundf(kilotris)); - } - - core::stringw fpsString = buffer; + 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/irr_driver.hpp b/src/graphics/irr_driver.hpp index f324b1dcd..95da8891b 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -419,7 +419,7 @@ private: void renderRSM(); void renderGlow(std::vector& glows); void renderSSAO(); - void renderLights(unsigned pointlightCount); + void renderLights(unsigned pointlightCount, bool hasShadow); void renderShadowsDebug(); void doScreenShot(); void PrepareDrawCalls(scene::ICameraSceneNode *camnode); diff --git a/src/graphics/lod_node.cpp b/src/graphics/lod_node.cpp index 6a4e0ddf7..a044906db 100644 --- a/src/graphics/lod_node.cpp +++ b/src/graphics/lod_node.cpp @@ -68,6 +68,9 @@ void LODNode::render() */ int LODNode::getLevel() { + if (m_nodes.size() == 0) + return -1; + // If a level is forced, use it if(m_forced_lod>-1) return m_forced_lod; @@ -79,14 +82,13 @@ int LODNode::getLevel() AbstractKart* kart = camera->getKart(); const Vec3 &pos = kart->getFrontXYZ(); - // Assumes all children are at the same location const int dist = - (int)((getPosition() + m_nodes[0]->getPosition()).getDistanceFromSQ( core::vector3df(pos.getX(), pos.getY(), pos.getZ()))); + (int)((m_nodes[0]->getAbsolutePosition()).getDistanceFromSQ( core::vector3df(pos.getX(), pos.getY(), pos.getZ()))); for (unsigned int n=0; n