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

This commit is contained in:
Sachith Hasaranga Seneviratne 2014-09-10 17:15:01 +05:30
commit b6a9e5be9c
42 changed files with 1574 additions and 1538 deletions

View File

@ -19,7 +19,7 @@
I18N="Difficulty" text="SuperTux"/>
</ribbon>
</box>
<spacer height="5%"" width="25"/>
<spacer height="5%" width="25"/>
<box width="95%" height="40%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a game mode" align="center" text_align="left" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <GL/glew.h>
}
@ -29,12 +35,6 @@ extern "C" {
# include <GL/glext.h>
#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
#endif

View File

@ -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<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> Map)
{
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, 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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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<unsigned, unsigned> 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<scene::IMeshBuffer*, unsigned>::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<unsigned, unsigned>(vtx, It->second);
}
size_t VAOManager::appendInstance(enum InstanceType, const std::vector<InstanceData> &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;

View File

@ -6,7 +6,7 @@
#include <vector>
#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<typename ... Types>
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<VAOManager>
{
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<scene::IMeshBuffer *> storedCPUBuffer[VTXTYPE_COUNT];
void *vtx_mirror[VTXTYPE_COUNT], *idx_mirror[VTXTYPE_COUNT];
size_t vtx_cnt[VTXTYPE_COUNT], idx_cnt[VTXTYPE_COUNT];
std::map<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, 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<unsigned, unsigned> getBase(scene::IMeshBuffer *);
size_t appendInstance(enum InstanceType, const std::vector<InstanceData> &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<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
~VAOManager();
};
void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color);

View File

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

View File

@ -1,8 +1,6 @@
#ifndef GPUPARTICLES_H
#define GPUPARTICLES_H
#include "graphics/glwrap.hpp"
#include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h"
#include <ISceneManager.h>
#include <IParticleSystemSceneNode.h>

View File

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

View File

@ -419,7 +419,7 @@ private:
void renderRSM();
void renderGlow(std::vector<GlowData>& glows);
void renderSSAO();
void renderLights(unsigned pointlightCount);
void renderLights(unsigned pointlightCount, bool hasShadow);
void renderShadowsDebug();
void doScreenShot();
void PrepareDrawCalls(scene::ICameraSceneNode *camnode);

View File

@ -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<m_detail.size(); n++)
{
if (dist < m_detail[n])
return n;
return n;
}
// If it's the shadow pass, and we would have otherwise hidden the item, show the min one
@ -108,7 +110,7 @@ void LODNode::forceLevelOfDetail(int n)
// ----------------------------------------------------------------------------
void LODNode::OnAnimate(u32 timeMs)
{
if (isVisible())
if (isVisible() && m_nodes.size() > 0)
{
// update absolute position
updateAbsolutePosition();

View File

@ -337,7 +337,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight());
float inv_width = 1.0f / in_fbo.getWidth(), inv_height = 1.0f / in_fbo.getHeight();
{
if (irr_driver->hasARBComputeShaders())
if (!irr_driver->hasARBComputeShaders())
{
auxiliary.Bind();
FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
@ -355,7 +355,7 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
}
}
{
if (irr_driver->hasARBComputeShaders())
if (!irr_driver->hasARBComputeShaders())
{
in_fbo.Bind();

View File

@ -22,7 +22,8 @@
#include "S3DVertex.h"
#include "SMaterial.h"
#include "graphics/camera.hpp"
#include "graphics/glwrap.hpp"
class FrameBuffer;
#include <vector>

View File

@ -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 <algorithm>
#include <limits>
@ -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;
@ -311,7 +335,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
// Lights
{
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
renderLights(pointlightcount);
renderLights(pointlightcount, hasShadow);
PROFILER_POP_CPU_MARKER();
}
@ -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<scene::CSceneManager *>(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();

View File

@ -32,6 +32,51 @@
#include <algorithm>
/**
\page render_geometry Geometry Rendering Overview
/**
\section adding_material Adding a solid material
You need to consider twice before adding a new material : in the worst case a material requires 8 shaders :
one for each solid pass, one for shadow pass, one for RSM pass, and you need to double that for instanced version.
You need to declare a new enum in MeshMaterial and to write the corresponding dispatch code in MaterialTypeToMeshMaterial
and to create 2 new List* structures (one for standard and one for instanced version).
Then you need to write the code in stkscenemanager.cpp that will add any mesh with the new material to their corresponding
lists : in handleSTKCommon for the standard version and in the body of PrepareDrawCalls for instanced version.
\section vertex_layout Available Vertex Layout
There are 3 different layout that comes from Irrlicht loading routines :
EVT_STANDARD, EVT_2TCOORDS, EVT_TANGENT.
Below are the attributes for each vertex layout and their predefined location.
\subsection EVT_STANDARD
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
\subsection EVT_2TCOORDS
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 4) in vec2 SecondTexcoord;
\subsection EVT_TANGENT
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec4 Color;
layout(location = 3) in vec2 Texcoord;
layout(location = 5) in vec3 Tangent;
layout(location = 6) in vec3 Bitangent;
*/
namespace RenderGeometry
{
struct TexUnit
@ -151,7 +196,6 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
}
}
#ifdef Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<GLMesh *> &meshes, Args...args)
{
@ -173,9 +217,7 @@ void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vec
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
}
}
#endif
#ifdef Multi_Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void multidraw1stPass(Args...args)
{
@ -190,7 +232,6 @@ void multidraw1stPass(Args...args)
sizeof(DrawElementsIndirectCommand));
}
}
#endif
static core::vector3df windDir;
@ -208,6 +249,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,12 +275,8 @@ void IrrDriver::renderSolidFirstPass()
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::getInstance()->SolidPass);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(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
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>();
@ -244,9 +284,7 @@ void IrrDriver::renderSolidFirstPass()
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>();
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_UNLIT, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(windDir);
#endif
}
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect())
{
// Default
@ -273,7 +311,6 @@ void IrrDriver::renderSolidFirstPass()
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
TexUnits(TexUnit(1, false), TexUnit(0, true)), ListInstancedMatNormalMap::getInstance()->SolidPass);
}
#endif
}
}
@ -315,7 +352,6 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
}
}
#ifdef Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, const std::vector<GLuint> &Prefilled_tex, std::vector<GLMesh *> &meshes, Args...args)
{
@ -332,9 +368,7 @@ void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, const st
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
}
}
#endif
#ifdef Multi_Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void multidraw2ndPass(const std::vector<uint64_t> &Handles, Args... args)
{
@ -350,7 +384,6 @@ void multidraw2ndPass(const std::vector<uint64_t> &Handles, Args... args)
sizeof(DrawElementsIndirectCommand));
}
}
#endif
void IrrDriver::renderSolidSecondPass()
{
@ -379,7 +412,6 @@ void IrrDriver::renderSolidSecondPass()
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
DiffuseHandle = glGetTextureSamplerHandleARB(m_rtts->getRenderTarget(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle);
@ -395,7 +427,6 @@ void IrrDriver::renderSolidSecondPass()
DepthHandle = glGetTextureSamplerHandleARB(getDepthStencilTexture(), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[3]);
if (!glIsTextureHandleResidentARB(DepthHandle))
glMakeTextureHandleResidentARB(DepthHandle);
#endif
}
{
@ -441,7 +472,6 @@ void IrrDriver::renderSolidSecondPass()
if (UserConfigParams::m_azdo)
{
#ifdef Multi_Draw_Indirect
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
multidraw2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
@ -450,9 +480,7 @@ void IrrDriver::renderSolidSecondPass()
multidraw2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
multidraw2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), windDir, cb->getPosition());
#endif
}
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect())
{
// Default
@ -481,7 +509,6 @@ void IrrDriver::renderSolidSecondPass()
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatGrass::getInstance()->SolidPass, windDir, cb->getPosition());
}
#endif
}
}
@ -537,12 +564,10 @@ void renderTransparenPass(const std::vector<TexUnit> &TexUnits, std::vector<STK:
compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[TexUnits[j].m_id])
mesh.TextureHandles[TexUnits[j].m_id] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[TexUnits[j].m_id]), Shader::getInstance()->SamplersId[Handles.size()]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]);
#endif
Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]);
}
else
@ -752,7 +777,6 @@ void renderShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, cons
}
}
#ifdef Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void renderInstancedShadow(const std::vector<GLuint> TextureUnits, unsigned cascade, const std::vector<GLMesh *> &t, Args ...args)
{
@ -773,9 +797,7 @@ void renderInstancedShadow(const std::vector<GLuint> TextureUnits, unsigned casc
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((tmp) * sizeof(DrawElementsIndirectCommand)));
}
}
#endif
#ifdef Multi_Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
static void multidrawShadow(unsigned i, Args ...args)
{
@ -787,7 +809,6 @@ static void multidrawShadow(unsigned i, Args ...args)
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(ShadowPassCmd::getInstance()->Offset[i][Mat] * sizeof(DrawElementsIndirectCommand)), ShadowPassCmd::getInstance()->Size[i][Mat], sizeof(DrawElementsIndirectCommand));
}
}
#endif
void IrrDriver::renderShadows()
{
@ -824,16 +845,13 @@ void IrrDriver::renderShadows()
if (UserConfigParams::m_azdo)
{
#ifdef Multi_Draw_Indirect
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DETAIL, video::EVT_2TCOORDS>(cascade);
multidrawShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(cascade);
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_ALPHA_REF, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_UNLIT, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(cascade, windDir);
#endif
}
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect())
{
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(noTexUnits, cascade, ListInstancedMatDefault::getInstance()->Shadows[cascade]);
@ -843,7 +861,6 @@ void IrrDriver::renderShadows()
renderInstancedShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, cascade, ListInstancedMatGrass::getInstance()->Shadows[cascade], windDir);
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(noTexUnits, cascade, ListInstancedMatNormalMap::getInstance()->Shadows[cascade]);
}
#endif
}
glDisable(GL_POLYGON_OFFSET_FILL);
@ -893,7 +910,6 @@ void drawRSM(const core::matrix4 & rsm_matrix, const std::vector<GLuint> &Textur
}
}
#ifdef Draw_Indirect
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void renderRSMShadow(const std::vector<GLuint> TextureUnits, const std::vector<GLMesh *> &t, Args ...args)
{
@ -913,9 +929,7 @@ void renderRSMShadow(const std::vector<GLuint> TextureUnits, const std::vector<G
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((RSMPassCmd::getInstance()->Offset[Mat] + i)* sizeof(DrawElementsIndirectCommand)));
}
}
#endif
#ifdef Multi_Draw_Indirect
template<typename Shader, MeshMaterial Mat, enum E_VERTEX_TYPE VertexType, typename... Args>
void multidrawRSM(Args...args)
{
@ -927,7 +941,6 @@ void multidrawRSM(Args...args)
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(RSMPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)), RSMPassCmd::getInstance()->Size[Mat], sizeof(DrawElementsIndirectCommand));
}
}
#endif
void IrrDriver::renderRSM()
{
@ -947,15 +960,12 @@ void IrrDriver::renderRSM()
if (UserConfigParams::m_azdo)
{
#ifdef Multi_Draw_Indirect
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DEFAULT, video::EVT_STANDARD>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_ALPHA_REF, video::EVT_STANDARD>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_UNLIT, video::EVT_STANDARD>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(rsm_matrix);
#endif
}
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect())
{
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_DEFAULT, video::EVT_STANDARD>(std::vector < GLuint > { 0 }, ListInstancedMatDefault::getInstance()->RSM, rsm_matrix);
@ -964,5 +974,4 @@ void IrrDriver::renderRSM()
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(std::vector < GLuint > { 0 }, ListInstancedMatNormalMap::getInstance()->RSM, rsm_matrix);
renderRSMShadow<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(std::vector < GLuint > { 0 }, ListInstancedMatDetails::getInstance()->RSM, rsm_matrix);
}
#endif
}

View File

@ -126,10 +126,10 @@ unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, fl
return lightnum;
}
void IrrDriver::renderLights(unsigned pointlightcount)
void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
{
//RH
if (UserConfigParams::m_gi)
if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
glDisable(GL_BLEND);
@ -171,7 +171,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
return;
m_rtts->getFBO(FBO_DIFFUSE).Bind();
if (UserConfigParams::m_gi)
if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);

View File

@ -439,7 +439,7 @@ GLuint generateCubeMapFromTextures(const std::vector<video::ITexture *> &texture
swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
}
}
free(tmp);
delete[] tmp;
}
glBindTexture(GL_TEXTURE_CUBE_MAP, result);
@ -574,4 +574,4 @@ void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
glDrawElements(GL_TRIANGLES, 6 * 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
}

View File

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

View File

@ -17,8 +17,6 @@
#ifndef HEADER_SCREENQUAD_H
#define HEADER_SCREENQUAD_H
#include "graphics/glwrap.hpp"
#include <SMaterial.h>
#include <IVideoDriver.h>

File diff suppressed because it is too large Load Diff

View File

@ -19,11 +19,9 @@
#include <IShaderConstantSetCallBack.h>
#include <IMeshSceneNode.h>
#include <vector>
#include "config/user_config.hpp"
#include "utils/singleton.hpp"
#include "gl_headers.hpp"
#include "shaders_util.hpp"
using namespace irr;
class ParticleSystemProxy;
@ -52,429 +50,6 @@ public:
};
}
bool needsUBO();
unsigned getGLSLVersion();
struct UniformHelper
{
template<unsigned N = 0>
static void setUniformsHelper(const std::vector<GLuint> &uniforms)
{
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::matrix4 &mat, Args... arg)
{
glUniformMatrix4fv(uniforms[N], 1, GL_FALSE, mat.pointer());
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const video::SColorf &col, Args... arg)
{
glUniform3f(uniforms[N], col.r, col.g, col.b);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const video::SColor &col, Args... arg)
{
glUniform4i(uniforms[N], col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::vector3df &v, Args... arg)
{
glUniform3f(uniforms[N], v.X, v.Y, v.Z);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::vector2df &v, Args... arg)
{
glUniform2f(uniforms[N], v.X, v.Y);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const core::dimension2df &v, Args... arg)
{
glUniform2f(uniforms[N], v.Width, v.Height);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg)
{
glUniform1f(uniforms[N], f);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, int f, Args... arg)
{
glUniform1i(uniforms[N], f);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const std::vector<float> &v, Args... arg)
{
glUniform1fv(uniforms[N], v.size(), v.data());
setUniformsHelper<N + 1>(uniforms, arg...);
}
};
void bypassUBO(GLuint Program);
extern std::vector<void(*)()> CleanTable;
template<typename T, typename... Args>
class ShaderHelperSingleton : public Singleton<T>
{
protected:
std::vector<GLuint> uniforms;
void AssignUniforms_impl()
{
}
template<typename... U>
void AssignUniforms_impl(const char* name, U... rest)
{
uniforms.push_back(glGetUniformLocation(Program, name));
AssignUniforms_impl(rest...);
}
template<typename... U>
void AssignUniforms(U... rest)
{
static_assert(sizeof...(rest) == sizeof...(Args), "Count of Uniform's name mismatch");
AssignUniforms_impl(rest...);
}
public:
GLuint Program;
ShaderHelperSingleton()
{
CleanTable.push_back(this->kill);
}
~ShaderHelperSingleton()
{
glDeleteProgram(Program);
}
void setUniforms(const Args & ... args) const
{
if (needsUBO())
bypassUBO(Program);
UniformHelper::setUniformsHelper(uniforms, args...);
}
};
enum SamplerType {
Trilinear_Anisotropic_Filtered,
Semi_trilinear,
Bilinear_Filtered,
Bilinear_Clamped_Filtered,
Nearest_Filtered,
Shadow_Sampler,
Volume_Linear_Filtered,
Trilinear_cubemap,
};
void setTextureSampler(GLenum, GLuint, GLuint, GLuint);
template<SamplerType...tp>
struct CreateSamplers;
template<SamplerType...tp>
struct BindTexture;
template<>
struct CreateSamplers<>
{
static void exec(std::vector<unsigned> &, std::vector<GLenum> &e)
{}
};
template<>
struct BindTexture<>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{}
};
GLuint createNearestSampler();
template<SamplerType...tp>
struct CreateSamplers<Nearest_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createNearestSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureNearest(unsigned TU, unsigned tid);
template<SamplerType...tp>
struct BindTexture<Nearest_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureNearest(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createBilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Bilinear_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureBilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Bilinear_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureBilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createBilinearClampedSampler();
template<SamplerType...tp>
struct CreateSamplers<Bilinear_Clamped_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearClampedSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureBilinearClamped(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Bilinear_Clamped_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureBilinearClamped(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createSemiTrilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Semi_trilinear, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createSemiTrilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureSemiTrilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Semi_trilinear, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureSemiTrilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createTrilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Trilinear_Anisotropic_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createTrilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureTrilinearAnisotropic(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct CreateSamplers<Trilinear_cubemap, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createTrilinearSampler());
e.push_back(GL_TEXTURE_CUBE_MAP);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindCubemapTrilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Trilinear_cubemap, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindCubemapTrilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
struct BindTexture<Trilinear_Anisotropic_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureTrilinearAnisotropic(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
struct CreateSamplers<Volume_Linear_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearSampler());
e.push_back(GL_TEXTURE_3D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureVolume(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Volume_Linear_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureVolume(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createShadowSampler();
template<SamplerType...tp>
struct CreateSamplers<Shadow_Sampler, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createShadowSampler());
e.push_back(GL_TEXTURE_2D_ARRAY);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureShadow(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Shadow_Sampler, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureShadow(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
class TextureRead
{
private:
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint)
{
static_assert(N == sizeof...(tp), "Wrong number of texture name");
}
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint Program, GLuint TexUnit, const char *name, Args...args)
{
GLuint location = glGetUniformLocation(Program, name);
TextureLocation.push_back(location);
glUniform1i(location, TexUnit);
TextureUnits.push_back(TexUnit);
AssignTextureNames_impl<N + 1>(Program, args...);
}
protected:
std::vector<GLuint> TextureUnits;
std::vector<GLenum> TextureType;
std::vector<GLenum> TextureLocation;
template<typename...Args>
void AssignSamplerNames(GLuint Program, Args...args)
{
CreateSamplers<tp...>::exec(SamplersId, TextureType);
glUseProgram(Program);
AssignTextureNames_impl<0>(Program, args...);
glUseProgram(0);
}
public:
std::vector<GLuint> SamplersId;
void SetTextureUnits(const std::vector<GLuint> &args)
{
assert(args.size() == sizeof...(tp) && "Too much texture unit provided");
if (getGLSLVersion() >= 330)
{
for (unsigned i = 0; i < args.size(); i++)
{
setTextureSampler(TextureType[i], TextureUnits[i], args[i], SamplersId[i]);
}
}
else
BindTexture<tp...>::exec(TextureUnits, args, 0);
}
~TextureRead()
{
for (unsigned i = 0; i < SamplersId.size(); i++)
glDeleteSamplers(1, &SamplersId[i]);
}
void SetTextureHandles(const std::vector<uint64_t> &args)
{
assert(args.size() == TextureLocation.size() && "Wrong Handle count");
for (unsigned i = 0; i < args.size(); i++)
{
#ifdef Bindless_Texture_Support
if (args[i])
glUniformHandleui64ARB(TextureLocation[i], args[i]);
#endif
}
}
};
namespace MeshShader
{

View File

@ -0,0 +1,435 @@
#ifndef SHADERS_UTIL_HPP
#define SHADERS_UTIL_HPP
#include "utils/singleton.hpp"
#include <vector>
#include <matrix4.h>
#include <SColor.h>
#include <vector3d.h>
#include "gl_headers.hpp"
bool needsUBO();
unsigned getGLSLVersion();
struct UniformHelper
{
template<unsigned N = 0>
static void setUniformsHelper(const std::vector<GLuint> &uniforms)
{
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::core::matrix4 &mat, Args... arg)
{
glUniformMatrix4fv(uniforms[N], 1, GL_FALSE, mat.pointer());
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::video::SColorf &col, Args... arg)
{
glUniform3f(uniforms[N], col.r, col.g, col.b);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::video::SColor &col, Args... arg)
{
glUniform4i(uniforms[N], col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::core::vector3df &v, Args... arg)
{
glUniform3f(uniforms[N], v.X, v.Y, v.Z);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::core::vector2df &v, Args... arg)
{
glUniform2f(uniforms[N], v.X, v.Y);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const irr::core::dimension2df &v, Args... arg)
{
glUniform2f(uniforms[N], v.Width, v.Height);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, float f, Args... arg)
{
glUniform1f(uniforms[N], f);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, int f, Args... arg)
{
glUniform1i(uniforms[N], f);
setUniformsHelper<N + 1>(uniforms, arg...);
}
template<unsigned N = 0, typename... Args>
static void setUniformsHelper(const std::vector<GLuint> &uniforms, const std::vector<float> &v, Args... arg)
{
glUniform1fv(uniforms[N], v.size(), v.data());
setUniformsHelper<N + 1>(uniforms, arg...);
}
};
void bypassUBO(GLuint Program);
extern std::vector<void(*)()> CleanTable;
template<typename T, typename... Args>
class ShaderHelperSingleton : public Singleton<T>
{
protected:
std::vector<GLuint> uniforms;
void AssignUniforms_impl()
{
GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData");
if (uniform_ViewProjectionMatrixesUBO != GL_INVALID_INDEX)
glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0);
}
template<typename... U>
void AssignUniforms_impl(const char* name, U... rest)
{
uniforms.push_back(glGetUniformLocation(Program, name));
AssignUniforms_impl(rest...);
}
template<typename... U>
void AssignUniforms(U... rest)
{
static_assert(sizeof...(rest) == sizeof...(Args), "Count of Uniform's name mismatch");
AssignUniforms_impl(rest...);
}
public:
GLuint Program;
ShaderHelperSingleton()
{
CleanTable.push_back(this->kill);
}
~ShaderHelperSingleton()
{
glDeleteProgram(Program);
}
void setUniforms(const Args & ... args) const
{
if (needsUBO())
bypassUBO(Program);
UniformHelper::setUniformsHelper(uniforms, args...);
}
};
enum SamplerType {
Trilinear_Anisotropic_Filtered,
Semi_trilinear,
Bilinear_Filtered,
Bilinear_Clamped_Filtered,
Nearest_Filtered,
Shadow_Sampler,
Volume_Linear_Filtered,
Trilinear_cubemap,
};
void setTextureSampler(GLenum, GLuint, GLuint, GLuint);
template<SamplerType...tp>
struct CreateSamplers;
template<SamplerType...tp>
struct BindTexture;
template<>
struct CreateSamplers<>
{
static void exec(std::vector<unsigned> &, std::vector<GLenum> &e)
{}
};
template<>
struct BindTexture<>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{}
};
GLuint createNearestSampler();
template<SamplerType...tp>
struct CreateSamplers<Nearest_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createNearestSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureNearest(unsigned TU, unsigned tid);
template<SamplerType...tp>
struct BindTexture<Nearest_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureNearest(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createBilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Bilinear_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureBilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Bilinear_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureBilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createBilinearClampedSampler();
template<SamplerType...tp>
struct CreateSamplers<Bilinear_Clamped_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearClampedSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureBilinearClamped(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Bilinear_Clamped_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureBilinearClamped(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createSemiTrilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Semi_trilinear, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createSemiTrilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureSemiTrilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Semi_trilinear, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureSemiTrilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createTrilinearSampler();
template<SamplerType...tp>
struct CreateSamplers<Trilinear_Anisotropic_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createTrilinearSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureTrilinearAnisotropic(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct CreateSamplers<Trilinear_cubemap, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createTrilinearSampler());
e.push_back(GL_TEXTURE_CUBE_MAP);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindCubemapTrilinear(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Trilinear_cubemap, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindCubemapTrilinear(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
struct BindTexture<Trilinear_Anisotropic_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureTrilinearAnisotropic(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
struct CreateSamplers<Volume_Linear_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createBilinearSampler());
e.push_back(GL_TEXTURE_3D);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureVolume(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Volume_Linear_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureVolume(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createShadowSampler();
template<SamplerType...tp>
struct CreateSamplers<Shadow_Sampler, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
v.push_back(createShadowSampler());
e.push_back(GL_TEXTURE_2D_ARRAY);
CreateSamplers<tp...>::exec(v, e);
}
};
void BindTextureShadow(unsigned TU, unsigned tex);
template<SamplerType...tp>
struct BindTexture<Shadow_Sampler, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
BindTextureShadow(TU[N], TexId[N]);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
template<SamplerType...tp>
class TextureRead
{
private:
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint)
{
static_assert(N == sizeof...(tp), "Wrong number of texture name");
}
template<unsigned N, typename...Args>
void AssignTextureNames_impl(GLuint Program, GLuint TexUnit, const char *name, Args...args)
{
GLuint location = glGetUniformLocation(Program, name);
TextureLocation.push_back(location);
glUniform1i(location, TexUnit);
TextureUnits.push_back(TexUnit);
AssignTextureNames_impl<N + 1>(Program, args...);
}
protected:
std::vector<GLuint> TextureUnits;
std::vector<GLenum> TextureType;
std::vector<GLenum> TextureLocation;
template<typename...Args>
void AssignSamplerNames(GLuint Program, Args...args)
{
CreateSamplers<tp...>::exec(SamplersId, TextureType);
glUseProgram(Program);
AssignTextureNames_impl<0>(Program, args...);
glUseProgram(0);
}
public:
std::vector<GLuint> SamplersId;
void SetTextureUnits(const std::vector<GLuint> &args)
{
assert(args.size() == sizeof...(tp) && "Too much texture unit provided");
if (getGLSLVersion() >= 330)
{
for (unsigned i = 0; i < args.size(); i++)
{
setTextureSampler(TextureType[i], TextureUnits[i], args[i], SamplersId[i]);
}
}
else
BindTexture<tp...>::exec(TextureUnits, args, 0);
}
~TextureRead()
{
for (unsigned i = 0; i < SamplersId.size(); i++)
glDeleteSamplers(1, &SamplersId[i]);
}
void SetTextureHandles(const std::vector<uint64_t> &args)
{
assert(args.size() == TextureLocation.size() && "Wrong Handle count");
for (unsigned i = 0; i < args.size(); i++)
{
if (args[i])
glUniformHandleui64ARB(TextureLocation[i], args[i]);
}
}
};
#endif

View File

@ -1,3 +1,4 @@
#include "graphics/glwrap.hpp"
#include "graphics/stkanimatedmesh.hpp"
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
@ -19,7 +20,8 @@ const core::vector3df& rotation,
const core::vector3df& scale) :
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
firstTime = true;
isGLInitialized = false;
isMaterialInitialized = false;
}
void STKAnimatedMesh::cleanGLMeshes()
@ -31,32 +33,25 @@ void STKAnimatedMesh::cleanGLMeshes()
continue;
if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao));
glDeleteBuffers(1, &(mesh.vertex_buffer));
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_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));
}
}
void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
{
firstTime = true;
isGLInitialized = false;
isMaterialInitialized = false;
GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++)
MeshSolidMaterial[i].clearWithoutDeleting();
CAnimatedMeshSceneNode::setMesh(mesh);
}
void STKAnimatedMesh::update()
void STKAnimatedMesh::updateNoGL()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
scene::IMesh* m = getMeshForCurrentFrame();
if (m)
@ -67,8 +62,9 @@ void STKAnimatedMesh::update()
return;
}
if (firstTime)
if (!isMaterialInitialized)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
@ -100,6 +96,32 @@ void STKAnimatedMesh::update()
{
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
MeshSolidMaterial[MatType].push_back(&mesh);
}
}
isMaterialInitialized = true;
}
}
void STKAnimatedMesh::updateGL()
{
scene::IMesh* m = getMeshForCurrentFrame();
if (!isGLInitialized)
{
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::IVideoDriver* driver = SceneManager->getVideoDriver();
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
GLMesh &mesh = GLmeshes[i];
if (!rnd->isTransparent())
{
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
InitTextures(mesh, MatType);
}
@ -116,8 +138,8 @@ void STKAnimatedMesh::update()
glBindVertexArray(0);
}
}
isGLInitialized = true;
}
firstTime = false;
for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
{
@ -163,71 +185,6 @@ void STKAnimatedMesh::render()
++PassCount;
update();
/* if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
core::matrix4 invmodel;
AbsoluteTransformation.getInverse(invmodel);
GLMesh* mesh;
for_in(mesh, MeshSolidMaterial[MAT_DEFAULT])
pushVector(ListMatDefault::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_ALPHA_REF])
pushVector(ListMatAlphaRef::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_DETAIL])
pushVector(ListMatDetails::getInstance(), mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix);
for_in(mesh, MeshSolidMaterial[MAT_UNLIT])
pushVector(ListMatUnlit::getInstance(), mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY, mesh->TextureMatrix);
return;
}*/
if (irr_driver->getPhase() == TRANSPARENT_PASS)
{
ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation);
if (!TransparentMesh[TM_BUBBLE].empty())
glUseProgram(MeshShader::BubbleShader::Program);
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, TransparentMesh[TM_DEFAULT])
ListBlendTransparentFog::getInstance()->push_back(
STK::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col));
for_in(mesh, TransparentMesh[TM_ADDITIVE])
ListAdditiveTransparentFog::getInstance()->push_back(
STK::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix,
fogmax, startH, endH, start, end, col));
}
else
{
for_in(mesh, TransparentMesh[TM_DEFAULT])
pushVector(ListBlendTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
for_in(mesh, TransparentMesh[TM_ADDITIVE])
pushVector(ListAdditiveTransparent::getInstance(), mesh, AbsoluteTransformation, mesh->TextureMatrix);
}
return;
}
updateNoGL();
updateGL();
}

View File

@ -10,12 +10,14 @@
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
{
protected:
bool firstTime;
bool isMaterialInitialized;
bool isGLInitialized;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes();
public:
virtual void update();
virtual void updateNoGL();
virtual void updateGL();
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0),

View File

@ -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 <ISceneManager.h>
#include <IMaterialRenderer.h>
@ -302,7 +303,6 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
if (!mesh.textures[i])
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[i], isSrgb);
#ifdef Bindless_Texture_Support
if (UserConfigParams::m_azdo)
{
if (!mesh.TextureHandles[i])
@ -310,7 +310,6 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
}
#endif
}
void InitTextures(GLMesh &mesh, MeshMaterial Mat)

View File

@ -1,7 +1,6 @@
#ifndef STKMESH_H
#define STKMESH_H
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "utils/tuple.hpp"
@ -37,7 +36,6 @@ struct GLMesh {
GLuint vao;
GLuint vertex_buffer;
GLuint index_buffer;
GLuint instance_buffer;
video::ITexture *textures[6];
GLenum PrimitiveType;
GLenum IndexType;
@ -70,7 +68,8 @@ protected:
public:
PtrVector<GLMesh, REF> MeshSolidMaterial[MAT_COUNT];
PtrVector<GLMesh, REF> TransparentMesh[TM_COUNT];
virtual void update() = 0;
virtual void updateNoGL() = 0;
virtual void updateGL() = 0;
virtual bool glow() const = 0;
virtual bool isImmediateDraw() const { return false; }
bool isCulledForPlayerCam() const { return m_culledForPlayerCam; }

View File

@ -1,6 +1,7 @@
#include "stkmeshscenenode.hpp"
#include "stkmesh.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/glwrap.hpp"
#include "tracks/track.hpp"
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
@ -42,63 +43,7 @@ void STKMeshSceneNode::createGLMeshes()
GLmeshes.push_back(allocateMeshBuffer(mb));
}
isMaterialInitialized = false;
}
void STKMeshSceneNode::setFirstTimeMaterial()
{
if (isMaterialInitialized)
return;
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
if (!isObject(type))
{
#ifdef DEBUG
Log::warn("material", "Unhandled (static) material type : %d", type);
#endif
continue;
}
GLMesh &mesh = GLmeshes[i];
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
if (!immediate_draw)
TransparentMesh[TranspMat].push_back(&mesh);
}
else
{
assert(!isDisplacement);
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
if (!immediate_draw)
{
InitTextures(mesh, MatType);
MeshSolidMaterial[MatType].push_back(&mesh);
}
}
if (!immediate_draw && irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
}
isMaterialInitialized = true;
isGLInitialized = false;
}
void STKMeshSceneNode::cleanGLMeshes()
@ -114,15 +59,6 @@ void STKMeshSceneNode::cleanGLMeshes()
glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer)
glDeleteBuffers(1, &(mesh.index_buffer));
if (mesh.instance_buffer)
glDeleteBuffers(1, &(mesh.instance_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++)
@ -169,11 +105,47 @@ void STKMeshSceneNode::updatevbo()
}
}
void STKMeshSceneNode::update()
void STKMeshSceneNode::updateNoGL()
{
Box = Mesh->getBoundingBox();
setFirstTimeMaterial();
if (!isMaterialInitialized)
{
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
if (!isObject(type))
{
#ifdef DEBUG
Log::warn("material", "Unhandled (static) material type : %d", type);
#endif
continue;
}
GLMesh &mesh = GLmeshes[i];
if (rnd->isTransparent())
{
TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type, MaterialTypeParam);
if (!immediate_draw)
TransparentMesh[TranspMat].push_back(&mesh);
}
else
{
assert(!isDisplacement);
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
if (!immediate_draw)
MeshSolidMaterial[MatType].push_back(&mesh);
}
}
isMaterialInitialized = true;
}
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{
@ -184,6 +156,45 @@ void STKMeshSceneNode::update()
}
}
void STKMeshSceneNode::updateGL()
{
if (isGLInitialized)
return;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
if (!mb)
continue;
GLMesh &mesh = GLmeshes[i];
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
if (!rnd->isTransparent())
{
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
if (!immediate_draw)
InitTextures(mesh, MatType);
}
if (!immediate_draw && irr_driver->hasARB_base_instance())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}
else
{
fillLocalBuffer(mesh, mb);
mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, mb->getVertexType());
glBindVertexArray(0);
}
}
isGLInitialized = true;
}
void STKMeshSceneNode::OnRegisterSceneNode()
{
@ -204,7 +215,8 @@ void STKMeshSceneNode::render()
++PassCount;
update();
updateNoGL();
updateGL();
bool isTransparent;
@ -244,13 +256,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
@ -292,7 +302,6 @@ void STKMeshSceneNode::render()
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle);
@ -310,7 +319,6 @@ void STKMeshSceneNode::render()
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
#endif
}
else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
@ -397,13 +405,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
@ -430,13 +436,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo)
{
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
}
else
MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });

View File

@ -19,13 +19,15 @@ protected:
void setFirstTimeMaterial();
void updatevbo();
bool isMaterialInitialized;
bool isGLInitialized;
bool immediate_draw;
bool update_each_frame;
bool isDisplacement;
bool isGlow;
video::SColor glowcolor;
public:
virtual void update();
virtual void updateNoGL();
virtual void updateGL();
void setReloadEachFrame(bool);
STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0),

View File

@ -1,8 +1,7 @@
#include "stkscenemanager.hpp"
#include "stkmesh.hpp"
#include "irr_driver.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#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"
@ -10,11 +9,14 @@
#include <SViewFrustum.h>
#include "callbacks.hpp"
#include "utils/cpp2011.hpp"
#include <omp.h>
#include "modes/world.hpp"
#include "tracks/track.hpp"
#include "lod_node.hpp"
#include "utils/profiler.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#include <unordered_map>
#include <SViewFrustum.h>
#include <functional>
@ -176,6 +178,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
if (!node)
return;
node->updateNoGL();
DeferredUpdate.push_back(node);
if (node->isImmediateDraw())
@ -183,9 +186,45 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *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<scene::ISceneNode *> *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<scene::ISceneNode *> *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<scene::ISceneNode *> *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]->update();
DeferredUpdate[i]->updateGL();
PROFILER_POP_CPU_MARKER();
if (!irr_driver->hasARB_draw_indirect())
return;
@ -706,5 +719,6 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly;
poly_count[SHADOW_PASS] += ShadowPoly;
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
if (irr_driver->hasBufferStorageExtension())
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
}

View File

@ -19,14 +19,12 @@ public:
{
glGenBuffers(1, &drawindirectcmd);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension())
{
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
}
else
#endif
{
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW);
}

355
src/graphics/vaomanager.cpp Normal file
View File

@ -0,0 +1,355 @@
#include "vaomanager.hpp"
#include "stkmesh.hpp"
VAOManager::VAOManager()
{
vao[0] = vao[1] = vao[2] = 0;
vbo[0] = vbo[1] = vbo[2] = 0;
ibo[0] = ibo[1] = ibo[2] = 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++)
{
glGenBuffers(1, &instance_vbo[i]);
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
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
{
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
}
}
}
void VAOManager::cleanInstanceVAOs()
{
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint>::iterator It = InstanceVAO.begin(), E = InstanceVAO.end();
for (; It != E; It++)
glDeleteVertexArrays(1, &(It->second));
InstanceVAO.clear();
}
VAOManager::~VAOManager()
{
cleanInstanceVAOs();
for (unsigned i = 0; i < 3; 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, size_t newlastvertex, size_t newlastindex)
{
glBindVertexArray(0);
if (newlastindex >= RealVBOSize[tp])
{
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;
}
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])
{
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)
{
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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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<video::E_VERTEX_TYPE, InstanceType>(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 = 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;
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
}
std::pair<unsigned, unsigned> 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());
append(mb, tp);
regenerateVAO(tp);
regenerateInstancedVAO();
}
std::unordered_map<scene::IMeshBuffer*, unsigned>::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<unsigned, unsigned>(vtx, It->second);
}

112
src/graphics/vaomanager.hpp Normal file
View File

@ -0,0 +1,112 @@
#ifndef VAOMANAGER_HPP
#define VAOMANAGER_HPP
#include "gl_headers.hpp"
#include "utils/singleton.hpp"
#include "irr_driver.hpp"
#include <vector>
#include <map>
#include <unordered_map>
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<VAOManager>
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
GLuint vbo[VTXTYPE_COUNT], ibo[VTXTYPE_COUNT], vao[VTXTYPE_COUNT];
GLuint instance_vbo[InstanceTypeCount];
void *Ptr[InstanceTypeCount];
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<scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
void cleanInstanceVAOs();
void regenerateBuffer(enum VTXTYPE, size_t, size_t);
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<unsigned, unsigned> getBase(scene::IMeshBuffer *);
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<video::E_VERTEX_TYPE, InstanceType>(vt, it)]; }
~VAOManager();
};
#endif

View File

@ -423,7 +423,7 @@ XMLNode *FileManager::createXMLTreeFromString(const std::string & content)
{
char *b = new char[content.size()];
memcpy(b, content.c_str(), content.size());
io::IReadFile * ireadfile = m_file_system->createMemoryReadFile(b, strlen(b), "tempfile", true);
io::IReadFile * ireadfile = m_file_system->createMemoryReadFile(b, content.size(), "tempfile", true);
io::IXMLReader * reader = m_file_system->createXMLReader(ireadfile);
XMLNode* node = new XMLNode(reader);
reader->drop();
@ -792,7 +792,7 @@ void FileManager::checkAndCreateConfigDir()
{
m_user_config_dir = getenv("HOME");
checkAndCreateDirectory(m_user_config_dir);
m_user_config_dir += "/.config";
if(!checkAndCreateDirectory(m_user_config_dir))
{

View File

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

View File

@ -914,35 +914,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; i<Camera::getNumCameras(); i++)
{
Camera::getCamera(i)->update(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();

View File

@ -117,6 +117,12 @@ void TrackInfoScreen::init()
ITexture* screenshot = irr_driver->getTexture(m_track->getScreenshotFile(),
"While loading screenshot for track '%s':",
m_track->getFilename() );
if(!screenshot)
{
screenshot = irr_driver->getTexture("main_help.png",
"While loading screenshot for track '%s':",
m_track->getFilename());
}
if (screenshot != NULL)
m_screenshot->setImage(screenshot);
@ -193,6 +199,9 @@ void TrackInfoScreen::init()
getWidget<LabelWidget>("highscore2")->setVisible(false);
getWidget<LabelWidget>("highscore3")->setVisible(false);
}
RibbonWidget* bt_start = getWidget<GUIEngine::RibbonWidget>("buttons");
bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
} // init
@ -325,3 +334,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<GUIEngine::RibbonWidget>("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
// -----------------------------------------------------------------------------

View File

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

View File

@ -612,37 +612,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<OverworldChallenge>& getChallengeList() const
{ return m_challenges; }
// ------------------------------------------------------------------------
const std::vector<Subtitle>& 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

View File

@ -250,88 +250,27 @@ namespace StringUtils
} // insertValues(s, v1)
// ------------------------------------------------------------------------
/** Intermediate struct to fill a vector using variadic templates */
struct __FillStringwVector
{
template<typename T, typename...Args>
static void __Fill(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
{
all_vals.push_back(irr::core::stringw(std::forward<T>(v)));
__Fill(all_vals, std::forward<Args>(args)...);
}
static void __Fill(std::vector<irr::core::stringw>&) {}
};
/** Like the other ones above but for wide strings */
template <class T1, class T2, class T3, class T4, class T5, class T6>
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 <typename...Args>
irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
{
std::vector<irr::core::stringw> 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>(args)...);
return insertValues(s, all_vals);
} // insertValues(s, v1, ..., v6)
// ------------------------------------------------------------------------
/** Like the other ones above but for wide strings */
template <class T1, class T2, class T3, class T4, class T5>
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<irr::core::stringw> 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 <class T1, class T2, class T3, class T4>
irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
const T2 &v2, const T3 &v3, const T4 &v4)
{
std::vector<irr::core::stringw> 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 <class T1, class T2, class T3>
irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
const T2 &v2, const T3 &v3)
{
std::vector<irr::core::stringw> 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 <class T1, class T2>
irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1,
const T2 &v2)
{
std::vector<irr::core::stringw> 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 <class T1>
irr::core::stringw insertValues(const irr::core::stringw &s, const T1 &v1)
{
std::vector<irr::core::stringw> 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 */