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"/> I18N="Difficulty" text="SuperTux"/>
</ribbon> </ribbon>
</box> </box>
<spacer height="5%"" width="25"/> <spacer height="5%" width="25"/>
<box width="95%" height="40%" padding="10" layout="vertical-row"> <box width="95%" height="40%" padding="10" layout="vertical-row">
<bright width="100%" text="Select a game mode" align="center" text_align="left" /> <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_from;
uniform vec3 color_to; uniform vec3 color_to;
#if __VERSION__ >= 330
layout(location=0) in vec3 Position; layout(location=0) in vec3 Position;
layout(location = 1) in float lifetime; layout(location = 1) in float lifetime;
layout(location = 2) in float size; layout(location = 2) in float size;
layout(location=3) in vec2 Texcoord; layout(location=3) in vec2 Texcoord;
layout(location = 4) in vec2 quadcorner; 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 float lf;
out vec2 tc; out vec2 tc;

View File

@ -9,6 +9,7 @@ uniform float track_x_len;
uniform float track_z_len; uniform float track_z_len;
uniform samplerBuffer heightmap; uniform samplerBuffer heightmap;
#if __VERSION__ >= 330
layout (location = 4) in vec3 particle_position_initial; layout (location = 4) in vec3 particle_position_initial;
layout (location = 5) in float lifetime_initial; layout (location = 5) in float lifetime_initial;
layout (location = 6) in vec3 particle_velocity_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 = 1) in float lifetime;
layout (location = 2) in vec3 particle_velocity; layout (location = 2) in vec3 particle_velocity;
layout (location = 3) in float size; 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 vec3 new_particle_position;
out float new_lifetime; out float new_lifetime;

View File

@ -3,6 +3,7 @@ uniform mat4 sourcematrix;
uniform int level; uniform int level;
uniform float size_increase_factor; uniform float size_increase_factor;
#if __VERSION__ >= 330
layout (location = 4) in vec3 particle_position_initial; layout (location = 4) in vec3 particle_position_initial;
layout (location = 5) in float lifetime_initial; layout (location = 5) in float lifetime_initial;
layout (location = 6) in vec3 particle_velocity_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 = 1) in float lifetime;
layout (location = 2) in vec3 particle_velocity; layout (location = 2) in vec3 particle_velocity;
layout (location = 3) in float size; 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 vec3 new_particle_position;
out float new_lifetime; out float new_lifetime;

View File

@ -3,6 +3,8 @@
// This file is part of the "Irrlicht Engine". // This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
extern bool GLContextDebugBit;
#include "CIrrDeviceLinux.h" #include "CIrrDeviceLinux.h"
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ #ifdef _IRR_COMPILE_WITH_X11_DEVICE_
@ -497,7 +499,7 @@ void IrrPrintXGrabError(int grabResult, const c8 * grabCommand )
static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig) static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig)
{ {
GLXContext Context; GLXContext Context;
int compat33ctx[] = int compat33ctxdebug[] =
{ {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3,
@ -505,11 +507,33 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig)
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None None
}; };
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,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None
};
int core33ctx[] = int core33ctx[] =
{ {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 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, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None None
}; };
@ -518,7 +542,6 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig)
GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
None None
}; };
int legacyctx[] = int legacyctx[] =
@ -532,19 +555,19 @@ static GLXContext getMeAGLContext(Display *display, GLXFBConfig glxFBConfig)
glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
// create compat 3.3 context (for proprietary drivers) // 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) if (!XErrorSignaled)
return Context; return Context;
XErrorSignaled = false; XErrorSignaled = false;
// create core 3.3 context (for mesa) // 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) if (!XErrorSignaled)
return Context; return Context;
XErrorSignaled = false; XErrorSignaled = false;
// create core 3.1 context (for older mesa) // 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) if (!XErrorSignaled)
return Context; return Context;

View File

@ -2,6 +2,9 @@
// This file is part of the "Irrlicht Engine". // This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h // For conditions of distribution and use, see copyright notice in irrlicht.h
extern bool GLContextDebugBit;
#include "COpenGLDriver.h" #include "COpenGLDriver.h"
// needed here also because of the create methods' parameters // needed here also because of the create methods' parameters
#include "CNullDriver.h" #include "CNullDriver.h"
@ -89,7 +92,7 @@ static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB;
static HGLRC getMeAGLContext(HDC HDc) static HGLRC getMeAGLContext(HDC HDc)
{ {
HGLRC hrc = 0; HGLRC hrc = 0;
int ctx44[] = int ctx44debug[] =
{ {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
@ -98,11 +101,19 @@ static HGLRC getMeAGLContext(HDC HDc)
0 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) if (hrc)
return hrc; return hrc;
int ctx40[] = int ctx40debug[] =
{ {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_MINOR_VERSION_ARB, 0,
@ -111,11 +122,19 @@ static HGLRC getMeAGLContext(HDC HDc)
0 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) if (hrc)
return hrc; return hrc;
int ctx33[] = int ctx33debug[] =
{ {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3,
@ -124,11 +143,19 @@ static HGLRC getMeAGLContext(HDC HDc)
0 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) if (hrc)
return hrc; return hrc;
int ctx31[] = int ctx31debug[] =
{ {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 1, 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, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0 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) if (hrc)
return hrc; return hrc;

View File

@ -1,7 +1,13 @@
#ifndef GL_HEADER_HPP #ifndef GL_HEADER_HPP
#define GL_HEADER_HPP #define GL_HEADER_HPP
#if defined(WIN32) && !defined(__CYGWIN__)
// glew in the binary distribution only comes as dynamic library.
# undef GLEW_STATIC
#else
# define GLEW_STATIC # define GLEW_STATIC
#endif
extern "C" { extern "C" {
#include <GL/glew.h> #include <GL/glew.h>
} }
@ -29,12 +35,6 @@ extern "C" {
# include <GL/glext.h> # include <GL/glext.h>
#endif #endif
#define Bindless_Texture_Support
#define Base_Instance_Support
#define Buffer_Storage
#define Multi_Draw_Indirect
#define Draw_Indirect
struct DrawElementsIndirectCommand{ struct DrawElementsIndirectCommand{
GLuint count; GLuint count;
GLuint instanceCount; GLuint instanceCount;

View File

@ -11,6 +11,12 @@
static bool is_gl_init = false; static bool is_gl_init = false;
#if DEBUG
bool GLContextDebugBit = true;
#else
bool GLContextDebugBit = false;
#endif
#ifdef DEBUG #ifdef DEBUG
#if !defined(__APPLE__) #if !defined(__APPLE__)
#define ARB_DEBUG_OUTPUT #define ARB_DEBUG_OUTPUT
@ -181,10 +187,46 @@ GLuint LoadShader(const char * file, unsigned type)
return Id; 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 LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount)
{ {
GLuint Program = glCreateProgram(); GLuint Program = glCreateProgram();
loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path); loadAndAttach(Program, GL_VERTEX_SHADER, vertex_file_path);
if (irr_driver->getGLSLVersion() < 330)
setAttribute(PARTICLES_SIM, Program);
glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS); glTransformFeedbackVaryings(Program, varyingscount, varyings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(Program); glLinkProgram(Program);
@ -397,340 +439,6 @@ void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum
glGetError(); 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) ScopedGPUTimer::ScopedGPUTimer(GPUTimer &t) : timer(t)
{ {
if (!UserConfigParams::m_profiler_enabled) return; if (!UserConfigParams::m_profiler_enabled) return;

View File

@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include "irr_driver.hpp" #include "irr_driver.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "vaomanager.hpp"
void initGL(); void initGL();
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount); 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...); printFileList(args...);
} }
enum AttributeType
{
OBJECT,
PARTICLES_SIM,
PARTICLES_RENDERING,
};
void setAttribute(AttributeType Tp, GLuint ProgramID);
template<typename ... Types> template<typename ... Types>
GLint LoadProgram(Types ... args) GLint LoadProgram(AttributeType Tp, Types ... args)
{ {
GLint ProgramID = glCreateProgram(); GLint ProgramID = glCreateProgram();
loadAndAttach(ProgramID, args...); loadAndAttach(ProgramID, args...);
if (irr_driver->getGLSLVersion() < 330) if (irr_driver->getGLSLVersion() < 330)
{ setAttribute(Tp, ProgramID);
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");
}
glLinkProgram(ProgramID); glLinkProgram(ProgramID);
GLint Result = GL_FALSE; 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); bool loadCompressedTexture(const std::string& compressed_tex);
void saveCompressedTexture(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, void draw3DLine(const core::vector3df& start,
const core::vector3df& end, irr::video::SColor color); const core::vector3df& end, irr::video::SColor color);

View File

@ -1,4 +1,5 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/glwrap.hpp"
#include "gpuparticles.hpp" #include "gpuparticles.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"

View File

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

View File

@ -504,34 +504,35 @@ void IrrDriver::initDevice()
hasComputeShaders = false; hasComputeShaders = false;
hasTextureStorage = false; hasTextureStorage = false;
// Default false value for hasVSLayer if --no-graphics argument is used // Default false value for hasVSLayer if --no-graphics argument is used
#if !defined(__APPLE__)
if (!ProfileWorld::isNoGraphics()) if (!ProfileWorld::isNoGraphics())
{ {
if (GLEW_AMD_vertex_shader_layer) { if (hasGLExtension("GL_AMD_vertex_shader_layer")) {
hasVSLayer = true; hasVSLayer = true;
Log::info("GLDriver", "AMD Vertex Shader Layer enabled"); Log::info("GLDriver", "AMD Vertex Shader Layer enabled");
} }
if (GLEW_ARB_buffer_storage) { if (hasGLExtension("GL_ARB_buffer_storage")) {
hasBuffserStorage = true; hasBuffserStorage = true;
Log::info("GLDriver", "ARB Buffer Storage enabled"); Log::info("GLDriver", "ARB Buffer Storage enabled");
} }
if (GLEW_ARB_base_instance) { if (hasGLExtension("GL_ARB_base_instance")) {
hasBaseInstance = true; hasBaseInstance = true;
Log::info("GLDriver", "ARB Base Instance enabled"); Log::info("GLDriver", "ARB Base Instance enabled");
} }
if (GLEW_ARB_draw_indirect) { if (hasGLExtension("GL_ARB_draw_indirect")) {
hasDrawIndirect = true; hasDrawIndirect = true;
Log::info("GLDriver", "ARB Draw Indirect enabled"); Log::info("GLDriver", "ARB Draw Indirect enabled");
} }
if (GLEW_ARB_compute_shader) { if (hasGLExtension("GL_ARB_compute_shader")) {
hasComputeShaders = true; hasComputeShaders = true;
Log::info("GLDriver", "ARB Compute Shader enabled"); Log::info("GLDriver", "ARB Compute Shader enabled");
} }
if (GLEW_ARB_texture_storage) { if (hasGLExtension("GL_ARB_texture_storage")) {
hasTextureStorage = true; hasTextureStorage = true;
Log::info("GLDriver", "ARB Texture Storage enabled"); Log::info("GLDriver", "ARB Texture Storage enabled");
} }
} }
#endif
// This remaps the window, so it has to be done before the clear to avoid flicker // 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 (low > kilotris) low = kilotris;
if (high < kilotris) high = kilotris; if (high < kilotris) high = kilotris;
static char buffer[128]; core::stringw fpsString;
if (UserConfigParams::m_artist_debug_mode) if (UserConfigParams::m_artist_debug_mode)
{ {
sprintf( fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d"),
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);
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[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
poly_count[SHADOW_PASS] = 0; poly_count[SHADOW_PASS] = 0;
object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0; object_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
@ -1760,12 +1756,7 @@ void IrrDriver::displayFPS()
object_count[TRANSPARENT_PASS] = 0; object_count[TRANSPARENT_PASS] = 0;
} }
else else
{ fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - %d KTris"), min, fps, max, (int)roundf(kilotris));
sprintf(buffer, "FPS: %i/%i/%i - %i KTris", min, fps, max,
(int)roundf(kilotris));
}
core::stringw fpsString = buffer;
static video::SColor fpsColor = video::SColor(255, 0, 0, 0); static video::SColor fpsColor = video::SColor(255, 0, 0, 0);

View File

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

View File

@ -68,6 +68,9 @@ void LODNode::render()
*/ */
int LODNode::getLevel() int LODNode::getLevel()
{ {
if (m_nodes.size() == 0)
return -1;
// If a level is forced, use it // If a level is forced, use it
if(m_forced_lod>-1) if(m_forced_lod>-1)
return m_forced_lod; return m_forced_lod;
@ -79,9 +82,8 @@ int LODNode::getLevel()
AbstractKart* kart = camera->getKart(); AbstractKart* kart = camera->getKart();
const Vec3 &pos = kart->getFrontXYZ(); const Vec3 &pos = kart->getFrontXYZ();
// Assumes all children are at the same location
const int dist = 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++) for (unsigned int n=0; n<m_detail.size(); n++)
{ {
@ -108,7 +110,7 @@ void LODNode::forceLevelOfDetail(int n)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void LODNode::OnAnimate(u32 timeMs) void LODNode::OnAnimate(u32 timeMs)
{ {
if (isVisible()) if (isVisible() && m_nodes.size() > 0)
{ {
// update absolute position // update absolute position
updateAbsolutePosition(); 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()); 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(); 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(); auxiliary.Bind();
FullScreenShader::Gaussian17TapHShader::getInstance()->SetTextureUnits(createVector<GLuint>(in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0])); 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(); in_fbo.Bind();

View File

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

View File

@ -47,6 +47,9 @@
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/profiler.hpp" #include "utils/profiler.hpp"
#include "stkscenemanager.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 <algorithm>
#include <limits> #include <limits>
@ -60,6 +63,27 @@ void IrrDriver::renderGLSL(float dt)
Track *track = world->getTrack(); 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 // Overrides
video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial(); video::SOverrideMaterial &overridemat = m_video_driver->getOverrideMaterial();
overridemat.EnablePasses = scene::ESNRP_SOLID | scene::ESNRP_TRANSPARENT; overridemat.EnablePasses = scene::ESNRP_SOLID | scene::ESNRP_TRANSPARENT;
@ -311,7 +335,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
// Lights // Lights
{ {
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
renderLights(pointlightcount); renderLights(pointlightcount, hasShadow);
PROFILER_POP_CPU_MARKER(); 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) 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->setProjMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION));
irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW)); irr_driver->setViewMatrix(irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix(); irr_driver->genProjViewMatrix();

View File

@ -32,6 +32,51 @@
#include <algorithm> #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 namespace RenderGeometry
{ {
struct TexUnit 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> 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) 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))); 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> template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void multidraw1stPass(Args...args) void multidraw1stPass(Args...args)
{ {
@ -190,7 +232,6 @@ void multidraw1stPass(Args...args)
sizeof(DrawElementsIndirectCommand)); sizeof(DrawElementsIndirectCommand));
} }
} }
#endif
static core::vector3df windDir; static core::vector3df windDir;
@ -208,6 +249,9 @@ void IrrDriver::renderSolidFirstPass()
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
if (irr_driver->hasARB_draw_indirect())
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
if (!UserConfigParams::m_dynamic_lights) if (!UserConfigParams::m_dynamic_lights)
return; 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_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::getInstance()->SolidPass);
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::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) if (UserConfigParams::m_azdo)
{ {
#ifdef Multi_Draw_Indirect
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>(); multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(); multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(); 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::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>();
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_UNLIT, video::EVT_STANDARD>(); multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_UNLIT, video::EVT_STANDARD>();
multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(windDir); multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(windDir);
#endif
} }
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect()) else if (irr_driver->hasARB_draw_indirect())
{ {
// Default // Default
@ -273,7 +311,6 @@ void IrrDriver::renderSolidFirstPass()
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>( renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
TexUnits(TexUnit(1, false), TexUnit(0, true)), ListInstancedMatNormalMap::getInstance()->SolidPass); 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> 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) 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))); 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> template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
void multidraw2ndPass(const std::vector<uint64_t> &Handles, Args... 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)); sizeof(DrawElementsIndirectCommand));
} }
} }
#endif
void IrrDriver::renderSolidSecondPass() void IrrDriver::renderSolidSecondPass()
{ {
@ -379,7 +412,6 @@ void IrrDriver::renderSolidSecondPass()
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
DiffuseHandle = glGetTextureSamplerHandleARB(m_rtts->getRenderTarget(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]); DiffuseHandle = glGetTextureSamplerHandleARB(m_rtts->getRenderTarget(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle)) if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle); glMakeTextureHandleResidentARB(DiffuseHandle);
@ -395,7 +427,6 @@ void IrrDriver::renderSolidSecondPass()
DepthHandle = glGetTextureSamplerHandleARB(getDepthStencilTexture(), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[3]); DepthHandle = glGetTextureSamplerHandleARB(getDepthStencilTexture(), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[3]);
if (!glIsTextureHandleResidentARB(DepthHandle)) if (!glIsTextureHandleResidentARB(DepthHandle))
glMakeTextureHandleResidentARB(DepthHandle); glMakeTextureHandleResidentARB(DepthHandle);
#endif
} }
{ {
@ -441,7 +472,6 @@ void IrrDriver::renderSolidSecondPass()
if (UserConfigParams::m_azdo) 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_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::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)); 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)); multidraw2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT); 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()); 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()) else if (irr_driver->hasARB_draw_indirect())
{ {
// Default // Default
@ -481,7 +509,6 @@ void IrrDriver::renderSolidSecondPass()
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>( renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatGrass::getInstance()->SolidPass, windDir, cb->getPosition()); 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); compressTexture(mesh.textures[TexUnits[j].m_id], TexUnits[j].m_premul_alpha);
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[TexUnits[j].m_id]) 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()]); 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])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]); glMakeTextureHandleResidentARB(mesh.TextureHandles[TexUnits[j].m_id]);
#endif
Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]); Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]);
} }
else 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> 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) 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))); 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> template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
static void multidrawShadow(unsigned i, Args ...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)); 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() void IrrDriver::renderShadows()
{ {
@ -824,16 +845,13 @@ void IrrDriver::renderShadows()
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Multi_Draw_Indirect
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(cascade); multidrawShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedShadowShader, MAT_DETAIL, video::EVT_2TCOORDS>(cascade); multidrawShadow<MeshShader::InstancedShadowShader, MAT_DETAIL, video::EVT_2TCOORDS>(cascade);
multidrawShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(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_ALPHA_REF, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_UNLIT, video::EVT_STANDARD>(cascade); multidrawShadow<MeshShader::InstancedRefShadowShader, MAT_UNLIT, video::EVT_STANDARD>(cascade);
multidrawShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(cascade, windDir); multidrawShadow<MeshShader::InstancedGrassShadowShader, MAT_GRASS, video::EVT_STANDARD>(cascade, windDir);
#endif
} }
#ifdef Draw_Indirect
else if (irr_driver->hasARB_draw_indirect()) else if (irr_driver->hasARB_draw_indirect())
{ {
renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_DEFAULT, video::EVT_STANDARD>(noTexUnits, cascade, ListInstancedMatDefault::getInstance()->Shadows[cascade]); 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::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]); renderInstancedShadow<MeshShader::InstancedShadowShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(noTexUnits, cascade, ListInstancedMatNormalMap::getInstance()->Shadows[cascade]);
} }
#endif
} }
glDisable(GL_POLYGON_OFFSET_FILL); 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> 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) 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))); 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> template<typename Shader, MeshMaterial Mat, enum E_VERTEX_TYPE VertexType, typename... Args>
void multidrawRSM(Args...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)); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)(RSMPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)), RSMPassCmd::getInstance()->Size[Mat], sizeof(DrawElementsIndirectCommand));
} }
} }
#endif
void IrrDriver::renderRSM() void IrrDriver::renderRSM()
{ {
@ -947,15 +960,12 @@ void IrrDriver::renderRSM()
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Multi_Draw_Indirect
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DEFAULT, video::EVT_STANDARD>(rsm_matrix); 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_NORMAL_MAP, video::EVT_TANGENTS>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_ALPHA_REF, video::EVT_STANDARD>(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_UNLIT, video::EVT_STANDARD>(rsm_matrix);
multidrawRSM<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(rsm_matrix); multidrawRSM<MeshShader::InstancedRSMShader, MAT_DETAIL, video::EVT_2TCOORDS>(rsm_matrix);
#endif
} }
#ifdef Draw_Indirect
else if (irr_driver->hasARB_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); 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_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); 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; return lightnum;
} }
void IrrDriver::renderLights(unsigned pointlightcount) void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
{ {
//RH //RH
if (UserConfigParams::m_gi) if (UserConfigParams::m_gi && UserConfigParams::m_shadows && hasShadow)
{ {
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH)); ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_RH));
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -171,7 +171,7 @@ void IrrDriver::renderLights(unsigned pointlightcount)
return; return;
m_rtts->getFBO(FBO_DIFFUSE).Bind(); 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)); 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]); 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); swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x);
} }
} }
free(tmp); delete[] tmp;
} }
glBindTexture(GL_TEXTURE_CUBE_MAP, result); glBindTexture(GL_TEXTURE_CUBE_MAP, result);

View File

@ -17,15 +17,19 @@
#ifndef HEADER_RTTS_HPP #ifndef HEADER_RTTS_HPP
#define HEADER_RTTS_HPP #define HEADER_RTTS_HPP
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
class FrameBuffer;
namespace irr { namespace irr {
namespace video { namespace video {
class ITexture; class ITexture;
}; };
namespace scene {
class ICameraSceneNode;
}
}; };
using irr::video::ITexture; using irr::video::ITexture;
@ -46,7 +50,7 @@ public:
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; } unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; } FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
FrameBuffer* render(scene::ICameraSceneNode* camera, float dt); FrameBuffer* render(irr::scene::ICameraSceneNode* camera, float dt);
private: private:
unsigned RenderTargetTextures[RTT_COUNT]; unsigned RenderTargetTextures[RTT_COUNT];

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -19,11 +19,9 @@
#include <IShaderConstantSetCallBack.h> #include <IShaderConstantSetCallBack.h>
#include <IMeshSceneNode.h> #include <IMeshSceneNode.h>
#include <vector>
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "utils/singleton.hpp"
#include "gl_headers.hpp" #include "shaders_util.hpp"
using namespace irr; using namespace irr;
class ParticleSystemProxy; 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 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 "graphics/stkanimatedmesh.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
#include <IMaterialRenderer.h> #include <IMaterialRenderer.h>
@ -19,7 +20,8 @@ const core::vector3df& rotation,
const core::vector3df& scale) : const core::vector3df& scale) :
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale) CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{ {
firstTime = true; isGLInitialized = false;
isMaterialInitialized = false;
} }
void STKAnimatedMesh::cleanGLMeshes() void STKAnimatedMesh::cleanGLMeshes()
@ -31,32 +33,25 @@ void STKAnimatedMesh::cleanGLMeshes()
continue; continue;
if (mesh.vao) if (mesh.vao)
glDeleteVertexArrays(1, &(mesh.vao)); glDeleteVertexArrays(1, &(mesh.vao));
if (mesh.vertex_buffer)
glDeleteBuffers(1, &(mesh.vertex_buffer)); glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer)
glDeleteBuffers(1, &(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
} }
} }
void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh) void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
{ {
firstTime = true; isGLInitialized = false;
isMaterialInitialized = false;
GLmeshes.clear(); GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++) for (unsigned i = 0; i < MAT_COUNT; i++)
MeshSolidMaterial[i].clearWithoutDeleting(); MeshSolidMaterial[i].clearWithoutDeleting();
CAnimatedMeshSceneNode::setMesh(mesh); CAnimatedMeshSceneNode::setMesh(mesh);
} }
void STKAnimatedMesh::update() void STKAnimatedMesh::updateNoGL()
{ {
video::IVideoDriver* driver = SceneManager->getVideoDriver();
scene::IMesh* m = getMeshForCurrentFrame(); scene::IMesh* m = getMeshForCurrentFrame();
if (m) if (m)
@ -67,8 +62,9 @@ void STKAnimatedMesh::update()
return; return;
} }
if (firstTime) if (!isMaterialInitialized)
{ {
video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (u32 i = 0; i < m->getMeshBufferCount(); ++i) for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
@ -100,6 +96,32 @@ void STKAnimatedMesh::update()
{ {
MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType());
MeshSolidMaterial[MatType].push_back(&mesh); 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); InitTextures(mesh, MatType);
} }
@ -116,8 +138,8 @@ void STKAnimatedMesh::update()
glBindVertexArray(0); glBindVertexArray(0);
} }
} }
isGLInitialized = true;
} }
firstTime = false;
for (u32 i = 0; i<m->getMeshBufferCount(); ++i) for (u32 i = 0; i<m->getMeshBufferCount(); ++i)
{ {
@ -163,71 +185,6 @@ void STKAnimatedMesh::render()
++PassCount; ++PassCount;
update(); updateNoGL();
updateGL();
/* 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;
}
} }

View File

@ -10,12 +10,14 @@
class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMeshCommon
{ {
protected: protected:
bool firstTime; bool isMaterialInitialized;
bool isGLInitialized;
std::vector<GLMesh> GLmeshes; std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix; core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes(); void cleanGLMeshes();
public: public:
virtual void update(); virtual void updateNoGL();
virtual void updateGL();
STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent, STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent,
irr::scene::ISceneManager* mgr, irr::s32 id, irr::scene::ISceneManager* mgr, irr::s32 id,
const irr::core::vector3df& position = irr::core::vector3df(0,0,0), 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/irr_driver.hpp"
#include "graphics/stkmesh.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
#include <IMaterialRenderer.h> #include <IMaterialRenderer.h>
@ -302,7 +303,6 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
if (!mesh.textures[i]) if (!mesh.textures[i])
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
compressTexture(mesh.textures[i], isSrgb); compressTexture(mesh.textures[i], isSrgb);
#ifdef Bindless_Texture_Support
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
if (!mesh.TextureHandles[i]) if (!mesh.TextureHandles[i])
@ -310,7 +310,6 @@ SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[i]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[i]); glMakeTextureHandleResidentARB(mesh.TextureHandles[i]);
} }
#endif
} }
void InitTextures(GLMesh &mesh, MeshMaterial Mat) void InitTextures(GLMesh &mesh, MeshMaterial Mat)

View File

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

View File

@ -1,6 +1,7 @@
#include "stkmeshscenenode.hpp" #include "stkmeshscenenode.hpp"
#include "stkmesh.hpp" #include "stkmesh.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/glwrap.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include <ISceneManager.h> #include <ISceneManager.h>
#include <IMaterialRenderer.h> #include <IMaterialRenderer.h>
@ -42,63 +43,7 @@ void STKMeshSceneNode::createGLMeshes()
GLmeshes.push_back(allocateMeshBuffer(mb)); GLmeshes.push_back(allocateMeshBuffer(mb));
} }
isMaterialInitialized = false; isMaterialInitialized = false;
} isGLInitialized = 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;
} }
void STKMeshSceneNode::cleanGLMeshes() void STKMeshSceneNode::cleanGLMeshes()
@ -114,15 +59,6 @@ void STKMeshSceneNode::cleanGLMeshes()
glDeleteBuffers(1, &(mesh.vertex_buffer)); glDeleteBuffers(1, &(mesh.vertex_buffer));
if (mesh.index_buffer) if (mesh.index_buffer)
glDeleteBuffers(1, &(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(); GLmeshes.clear();
for (unsigned i = 0; i < MAT_COUNT; i++) for (unsigned i = 0; i < MAT_COUNT; i++)
@ -169,11 +105,47 @@ void STKMeshSceneNode::updatevbo()
} }
} }
void STKMeshSceneNode::update() void STKMeshSceneNode::updateNoGL()
{ {
Box = Mesh->getBoundingBox(); 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) 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() void STKMeshSceneNode::OnRegisterSceneNode()
{ {
@ -204,7 +215,8 @@ void STKMeshSceneNode::render()
++PassCount; ++PassCount;
update(); updateNoGL();
updateGL();
bool isTransparent; bool isTransparent;
@ -244,13 +256,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true); compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
} }
else else
MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) }); MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) });
@ -292,7 +302,6 @@ void STKMeshSceneNode::render()
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]); GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(DiffuseHandle)) if (!glIsTextureHandleResidentARB(DiffuseHandle))
glMakeTextureHandleResidentARB(DiffuseHandle); glMakeTextureHandleResidentARB(DiffuseHandle);
@ -310,7 +319,6 @@ void STKMeshSceneNode::render()
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0])); MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
#endif
} }
else else
MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>( MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>(
@ -397,13 +405,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true); compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
} }
else else
MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });
@ -430,13 +436,11 @@ void STKMeshSceneNode::render()
compressTexture(mesh.textures[0], true); compressTexture(mesh.textures[0], true);
if (UserConfigParams::m_azdo) if (UserConfigParams::m_azdo)
{ {
#ifdef Bindless_Texture_Support
if (!mesh.TextureHandles[0]) if (!mesh.TextureHandles[0])
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]); mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]);
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0]));
#endif
} }
else else
MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) });

View File

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

View File

@ -1,8 +1,7 @@
#include "stkscenemanager.hpp" #include "graphics/glwrap.hpp"
#include "stkmesh.hpp" #include "graphics/stkscenemanager.hpp"
#include "irr_driver.hpp" #include "graphics/stkmesh.hpp"
#include <ISceneManager.h> #include "graphics/irr_driver.hpp"
#include <ISceneNode.h>
#include "stkanimatedmesh.hpp" #include "stkanimatedmesh.hpp"
#include "stkmeshscenenode.hpp" #include "stkmeshscenenode.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
@ -10,11 +9,14 @@
#include <SViewFrustum.h> #include <SViewFrustum.h>
#include "callbacks.hpp" #include "callbacks.hpp"
#include "utils/cpp2011.hpp" #include "utils/cpp2011.hpp"
#include <omp.h>
#include "modes/world.hpp" #include "modes/world.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "lod_node.hpp" #include "lod_node.hpp"
#include "utils/profiler.hpp" #include "utils/profiler.hpp"
#include <ISceneManager.h>
#include <ISceneNode.h>
#include <unordered_map> #include <unordered_map>
#include <SViewFrustum.h> #include <SViewFrustum.h>
#include <functional> #include <functional>
@ -176,6 +178,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node); STKMeshCommon *node = dynamic_cast<STKMeshCommon*>(Node);
if (!node) if (!node)
return; return;
node->updateNoGL();
DeferredUpdate.push_back(node); DeferredUpdate.push_back(node);
if (node->isImmediateDraw()) if (node->isImmediateDraw())
@ -183,9 +186,45 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
ImmediateDraw->push_back(Node); ImmediateDraw->push_back(Node);
return; 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) for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{ {
GLMesh *mesh;
if (irr_driver->hasARB_draw_indirect()) if (irr_driver->hasARB_draw_indirect())
{ {
for_in(mesh, node->MeshSolidMaterial[Mat]) for_in(mesh, node->MeshSolidMaterial[Mat])
@ -253,8 +292,11 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
} }
} }
} }
}
if (!UserConfigParams::m_shadows) if (!UserConfigParams::m_shadows)
return; return;
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
for (unsigned cascade = 0; cascade < 4; ++cascade) for (unsigned cascade = 0; cascade < 4; ++cascade)
{ {
if (irr_driver->hasARB_draw_indirect()) if (irr_driver->hasARB_draw_indirect())
@ -298,8 +340,11 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
} }
} }
} }
}
if (!UserConfigParams::m_gi) if (!UserConfigParams::m_gi)
return; return;
for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat)
{
if (irr_driver->hasARB_draw_indirect()) if (irr_driver->hasARB_draw_indirect())
{ {
for_in(mesh, node->MeshSolidMaterial[Mat]) 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 static void
@ -503,8 +514,10 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
printf("Wait Failed\n"); printf("Wait Failed\n");
break; break;
}*/ }*/
PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
for (unsigned i = 0; i < DeferredUpdate.size(); i++) for (unsigned i = 0; i < DeferredUpdate.size(); i++)
DeferredUpdate[i]->update(); DeferredUpdate[i]->updateGL();
PROFILER_POP_CPU_MARKER();
if (!irr_driver->hasARB_draw_indirect()) if (!irr_driver->hasARB_draw_indirect())
return; return;
@ -706,5 +719,6 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly; poly_count[SOLID_NORMAL_AND_DEPTH_PASS] += SolidPoly;
poly_count[SHADOW_PASS] += ShadowPoly; poly_count[SHADOW_PASS] += ShadowPoly;
if (irr_driver->hasBufferStorageExtension())
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
} }

View File

@ -19,14 +19,12 @@ public:
{ {
glGenBuffers(1, &drawindirectcmd); glGenBuffers(1, &drawindirectcmd);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
#ifdef Buffer_Storage
if (irr_driver->hasBufferStorageExtension()) if (irr_driver->hasBufferStorageExtension())
{ {
glBufferStorage(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT); 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); Ptr = (DrawElementsIndirectCommand *)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
} }
else else
#endif
{ {
glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW); 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()]; char *b = new char[content.size()];
memcpy(b, content.c_str(), 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); io::IXMLReader * reader = m_file_system->createXMLReader(ireadfile);
XMLNode* node = new XMLNode(reader); XMLNode* node = new XMLNode(reader);
reader->drop(); reader->drop();

View File

@ -115,9 +115,11 @@ private:
/** Last time the bouncing ball was collected */ /** Last time the bouncing ball was collected */
float m_rubber_ball_collect_time; float m_rubber_ball_collect_time;
public:
/** The mesh for each model (if the powerup has a model), e.g. a switch /** The mesh for each model (if the powerup has a model), e.g. a switch
has none. */ has none. */
irr::scene::IMesh *m_all_meshes[POWERUP_MAX]; irr::scene::IMesh *m_all_meshes[POWERUP_MAX];
private:
/** Size of the corresponding mesh. */ /** Size of the corresponding mesh. */
btVector3 m_all_extends[POWERUP_MAX]; btVector3 m_all_extends[POWERUP_MAX];

View File

@ -914,35 +914,45 @@ void World::update(float dt)
} }
#endif #endif
PROFILER_PUSH_CPU_MARKER("World::update (sub-updates)", 0x20, 0x7F, 0x00);
history->update(dt); history->update(dt);
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt); if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
if(ReplayPlay::get()) ReplayPlay::get()->update(dt); if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
if(history->replayHistory()) dt=history->getNextDelta(); if(history->replayHistory()) dt=history->getNextDelta();
WorldStatus::update(dt); WorldStatus::update(dt);
PROFILER_POP_CPU_MARKER();
if (!history->dontDoPhysics()) if (!history->dontDoPhysics())
{ {
m_physics->update(dt); m_physics->update(dt);
} }
PROFILER_PUSH_CPU_MARKER("World::update (AI)", 0x40, 0x7F, 0x00);
const int kart_amount = m_karts.size(); const int kart_amount = m_karts.size();
for (int i = 0 ; i < kart_amount; ++i) for (int i = 0 ; i < kart_amount; ++i)
{ {
// Update all karts that are not eliminated // Update all karts that are not eliminated
if(!m_karts[i]->isEliminated()) m_karts[i]->update(dt) ; 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++) for(unsigned int i=0; i<Camera::getNumCameras(); i++)
{ {
Camera::getCamera(i)->update(dt); 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) if (UserConfigParams::m_graphical_effects && m_weather)
{ {
m_weather->update(dt); m_weather->update(dt);
} }
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("World::update (projectiles)", 0xa0, 0x7F, 0x00);
projectile_manager->update(dt); projectile_manager->update(dt);
PROFILER_POP_CPU_MARKER();
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(), ITexture* screenshot = irr_driver->getTexture(m_track->getScreenshotFile(),
"While loading screenshot for track '%s':", "While loading screenshot for track '%s':",
m_track->getFilename() ); m_track->getFilename() );
if(!screenshot)
{
screenshot = irr_driver->getTexture("main_help.png",
"While loading screenshot for track '%s':",
m_track->getFilename());
}
if (screenshot != NULL) if (screenshot != NULL)
m_screenshot->setImage(screenshot); m_screenshot->setImage(screenshot);
@ -194,6 +200,9 @@ void TrackInfoScreen::init()
getWidget<LabelWidget>("highscore3")->setVisible(false); getWidget<LabelWidget>("highscore3")->setVisible(false);
} }
RibbonWidget* bt_start = getWidget<GUIEngine::RibbonWidget>("buttons");
bt_start->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
} // init } // init
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -325,3 +334,37 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
} // eventCallback } // 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 loadedFromFile();
virtual void eventCallback(GUIEngine::Widget *,const std::string &name , virtual void eventCallback(GUIEngine::Widget *,const std::string &name ,
const int player_id); 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 onEnterPressedInternal();
void setTrack(Track *track); void setTrack(Track *track);
}; };

View File

@ -612,36 +612,58 @@ public:
/** Returns true if the normals of this track can be smoothed. */ /** Returns true if the normals of this track can be smoothed. */
bool smoothNormals() const { return m_smooth_normals; } 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. */ /** Get list of challenges placed on that world. Works only for overworld. */
const std::vector<OverworldChallenge>& getChallengeList() const const std::vector<OverworldChallenge>& getChallengeList() const
{ return m_challenges; } { return m_challenges; }
// ------------------------------------------------------------------------
const std::vector<Subtitle>& getSubtitles() const { return m_subtitles; } const std::vector<Subtitle>& getSubtitles() const { return m_subtitles; }
// ------------------------------------------------------------------------
bool hasClouds() const { return m_clouds; } bool hasClouds() const { return m_clouds; }
// ------------------------------------------------------------------------
bool getBloom() const { return m_bloom; } bool getBloom() const { return m_bloom; }
// ------------------------------------------------------------------------
float getBloomThreshold() const { return m_bloom_threshold; } float getBloomThreshold() const { return m_bloom_threshold; }
// ------------------------------------------------------------------------
/** Return the color levels for color correction shader */ /** Return the color levels for color correction shader */
core::vector3df getColorLevelIn() const { return m_color_inlevel; } core::vector3df getColorLevelIn() const { return m_color_inlevel; }
// ------------------------------------------------------------------------
core::vector2df getColorLevelOut() const { return m_color_outlevel; } core::vector2df getColorLevelOut() const { return m_color_outlevel; }
// ------------------------------------------------------------------------
bool hasLensFlare() const { return m_lensflare; } bool hasLensFlare() const { return m_lensflare; }
// ------------------------------------------------------------------------
bool hasGodRays() const { return m_godrays; } bool hasGodRays() const { return m_godrays; }
// ------------------------------------------------------------------------
core::vector3df getGodRaysPosition() const { return m_godrays_position; } core::vector3df getGodRaysPosition() const { return m_godrays_position; }
// ------------------------------------------------------------------------
float getGodRaysOpacity() const { return m_godrays_opacity; } float getGodRaysOpacity() const { return m_godrays_opacity; }
// ------------------------------------------------------------------------
video::SColor getGodRaysColor() const { return m_godrays_color; } video::SColor getGodRaysColor() const { return m_godrays_color; }
// ------------------------------------------------------------------------
bool hasShadows() const { return m_shadows; } bool hasShadows() const { return m_shadows; }
// ------------------------------------------------------------------------
void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); } void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); }
// ------------------------------------------------------------------------
float getDisplacementSpeed() const { return m_displacement_speed; } float getDisplacementSpeed() const { return m_displacement_speed; }
// ------------------------------------------------------------------------
float getCausticsSpeed() const { return m_caustics_speed; } float getCausticsSpeed() const { return m_caustics_speed; }
// ------------------------------------------------------------------------
const int getDefaultNumberOfLaps() const { return m_default_number_of_laps;} const int getDefaultNumberOfLaps() const { return m_default_number_of_laps;}
// ------------------------------------------------------------------------
const int getActualNumberOfLap() const { return m_actual_number_of_laps; } const int getActualNumberOfLap() const { return m_actual_number_of_laps; }
// ------------------------------------------------------------------------
void setActualNumberOfLaps(unsigned int laps) void setActualNumberOfLaps(unsigned int laps)
{ m_actual_number_of_laps = laps; } { m_actual_number_of_laps = laps; }
bool operator<(const Track &other) const; bool operator<(const Track &other) const;

View File

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