diff --git a/src/graphics/draw_calls.cpp b/src/graphics/draw_calls.cpp index e79f45f70..35d6b58bd 100644 --- a/src/graphics/draw_calls.cpp +++ b/src/graphics/draw_calls.cpp @@ -96,12 +96,12 @@ namespace template - static void FillInstances_impl( DrawCalls::InstanceList instance_list, - T * InstanceBuffer, - DrawElementsIndirectCommand *CommandBuffer, - size_t &InstanceBufferOffset, - size_t &CommandBufferOffset, - size_t &PolyCount) + void FillInstances_impl(DrawCalls::InstanceList instance_list, + T * InstanceBuffer, + DrawElementsIndirectCommand *CommandBuffer, + size_t &InstanceBufferOffset, + size_t &CommandBufferOffset, + size_t &PolyCount) { // Should never be empty GLMesh *mesh = instance_list.front().first; @@ -126,13 +126,13 @@ namespace } template - static void FillInstances( const DrawCalls::MeshMap &GatheredGLMesh, - std::vector &InstancedList, - T *InstanceBuffer, - DrawElementsIndirectCommand *CommandBuffer, - size_t &InstanceBufferOffset, - size_t &CommandBufferOffset, - size_t &Polycount) + void FillInstances( const DrawCalls::MeshMap &GatheredGLMesh, + std::vector &InstancedList, + T *InstanceBuffer, + DrawElementsIndirectCommand *CommandBuffer, + size_t &InstanceBufferOffset, + size_t &CommandBufferOffset, + size_t &Polycount) { auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end(); for (; It != E; ++It) @@ -658,11 +658,40 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); } - + + //TODO: replace duplicated code with a loop + /* + Material::ShaderType dual_tex_materials[5] = {Material::SHADERTYPE_SOLID, + Material::SHADERTYPE_ALPHA_TEST, + Material::SHADERTYPE_SOLID_UNLIT, + Material::SHADERTYPE_SPHERE_MAP, + Material::SHADERTYPE_VEGETATION}; + + for(int i=0;i<1;i++) + { + SolidPassCmd::getInstance()->Offset[dual_tex_materials[i]] = current_cmd; + FillInstances(m_solid_pass_mesh[dual_tex_materials[i]], + ListInstancedMatDefault::getInstance()->SolidPass, //we need to change this line to something more generic + InstanceBufferDualTex, + CmdBuffer, + offset, + current_cmd, + SolidPoly); + SolidPassCmd::getInstance()->Size[dual_tex_materials[i]] = current_cmd - SolidPassCmd::getInstance()->Offset[dual_tex_materials[i]]; + }*/ + + // Default Material SolidPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID] = current_cmd; - FillInstances(m_solid_pass_mesh[Material::SHADERTYPE_SOLID], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly); + FillInstances(m_solid_pass_mesh[Material::SHADERTYPE_SOLID], + ListInstancedMatDefault::getInstance()->SolidPass, + InstanceBufferDualTex, + CmdBuffer, + offset, + current_cmd, + SolidPoly); SolidPassCmd::getInstance()->Size[Material::SHADERTYPE_SOLID] = current_cmd - SolidPassCmd::getInstance()->Offset[Material::SHADERTYPE_SOLID]; + // Alpha Ref SolidPassCmd::getInstance()->Offset[Material::SHADERTYPE_ALPHA_TEST] = current_cmd; FillInstances(m_solid_pass_mesh[Material::SHADERTYPE_ALPHA_TEST], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly); diff --git a/src/graphics/draw_tools.hpp b/src/graphics/draw_tools.hpp new file mode 100644 index 000000000..7b84a4151 --- /dev/null +++ b/src/graphics/draw_tools.hpp @@ -0,0 +1,230 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2015 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_DRAW_TOOLS_HPP +#define HEADER_DRAW_TOOLS_HPP + +#include "graphics/shader.hpp" +#include "graphics/irr_driver.hpp" +#include "graphics/stk_mesh.hpp" + + + + +// ---------------------------------------------------------------------------- +/** Draw a mesh using specified shader (require OpenGL 3.2) + * \param mesh The mesh to draw + * \param args The shader uniforms values + */ +template +void draw(const GLMesh *mesh, Uniforms... args) +{ + irr_driver->IncreaseObjectCount(); //TODO: move somewhere else + S::getInstance()->setUniforms(args...); + glDrawElementsBaseVertex(mesh->PrimitiveType, + (int)mesh->IndexCount, + mesh->IndexType, + (GLvoid *)mesh->vaoOffset, + (int)mesh->vaoBaseVertex); +} // draw + +// ---------------------------------------------------------------------------- +/** Variadic template to draw a mesh (using OpenGL 3.2 function) + * with per mesh custom uniforms.*/ +template +struct CustomUnrollArgs; + +// ---------------------------------------------------------------------------- +template +struct CustomUnrollArgs +{ + /** Draw a mesh using specified shader (require OpenGL 3.2) + * \param cascade The cascade shadow map index + * \param t First tuple element is the mesh to draw, next elements are uniforms values + * \param args The shader uniforms values + */ + template + static void drawMesh(const STK::Tuple &t, + Args... args) + { + CustomUnrollArgs::template drawMesh(t, STK::tuple_get(t), args...); + } // drawMesh + + // ---------------------------------------------------------------------------- + /** Draw shadow mesh using specified shader (require OpenGL 3.2) + * \param t First tuple element is the mesh to draw, next elements are uniforms values + * \param args The shader uniforms values + */ + template + static void drawShadow(unsigned cascade, + const STK::Tuple &t, + Args... args) + { + CustomUnrollArgs::template drawShadow(cascade, t, STK::tuple_get(t), args...); + } // drawShadow + + // ---------------------------------------------------------------------------- + /** Draw mesh reflective shadow map using specified shader (require OpenGL 3.2) + * \param rsm_matrix The reflective shadow map matrix + * \param t First tuple element is the mesh to draw, next elements are uniforms values + * \param args The shader uniforms values + */ + template + static void drawReflectiveShadowMap(const irr::core::matrix4 &rsm_matrix, + const STK::Tuple &t, + Args... args) + { + CustomUnrollArgs::template drawReflectiveShadowMap(rsm_matrix, t, STK::tuple_get(t), args...); + } // drawReflectiveShadowMap +}; // CustomUnrollArgs + +// ---------------------------------------------------------------------------- +/** Partial specialisation of CustomUnrollArgs to end the recursion */ +template<> +struct CustomUnrollArgs<> +{ + template + static void drawMesh(const STK::Tuple &t, + Args... args) + { + draw(STK::tuple_get<0>(t), args...); + } // drawMesh + + // ---------------------------------------------------------------------------- + template + static void drawShadow(unsigned cascade, + const STK::Tuple &t, + Args... args) + { + draw(STK::tuple_get<0>(t), cascade, args...); + } // drawShadow + + // ---------------------------------------------------------------------------- + template + static void drawReflectiveShadowMap(const irr::core::matrix4 &rsm_matrix, + const STK::Tuple &t, + Args... args) + { + draw(STK::tuple_get<0>(t), rsm_matrix, args...); + } // drawReflectiveShadowMap +}; // CustomUnrollArgs + + + +// ---------------------------------------------------------------------------- +/** Variadic template to apply textures parameters.*/ +template +struct TexExpander_impl +{ + template + static void ExpandTex(const GLMesh &mesh, + const STK::Tuple &TexSwizzle, + Args... args) + { + size_t idx = STK::tuple_get(TexSwizzle); + TexExpander_impl::template + ExpandTex(mesh, TexSwizzle, + args..., getTextureGLuint(mesh.textures[idx])); + } // ExpandTex +}; // TexExpander_impl + +// ---------------------------------------------------------------------------- +template +struct TexExpander_impl +{ + template + static void ExpandTex(const GLMesh &mesh, + const STK::Tuple &TexSwizzle, + Args... args) + { + T::getInstance()->setTextureUnits(args...); + } // ExpandTex +}; // TexExpander_impl + +// ---------------------------------------------------------------------------- +template +struct TexExpander +{ + template + static void ExpandTex(const GLMesh &mesh, + const STK::Tuple &TexSwizzle, + Args... args) + { + TexExpander_impl::ExpandTex(mesh, TexSwizzle, + args...); + } // ExpandTex +}; // TexExpander + + + + + +// ---------------------------------------------------------------------------- +template +struct HandleExpander_impl +{ + template + static void Expand(uint64_t *TextureHandles, + const STK::Tuple &TexSwizzle, Args... args) + { + size_t idx = STK::tuple_get(TexSwizzle); + HandleExpander_impl::template + Expand(TextureHandles, TexSwizzle, args..., TextureHandles[idx]); + } // Expand +}; // HandleExpander_impl + +// ---------------------------------------------------------------------------- +template +struct HandleExpander_impl +{ + template + static void Expand(uint64_t *TextureHandles, + const STK::Tuple &TexSwizzle, Args... args) + { + T::getInstance()->setTextureHandles(args...); + } // Expand +}; // HandleExpander_impl + +// ---------------------------------------------------------------------------- +template +struct HandleExpander +{ + template + static void Expand(uint64_t *TextureHandles, const STK::Tuple &TexSwizzle, Args... args) + { + HandleExpander_impl::Expand(TextureHandles, TexSwizzle, args...); + } // Expand +}; // HandleExpander + + + + + +#endif //HEADER_DRAW_TOOLS_HPP \ No newline at end of file diff --git a/src/graphics/geometry_first_pass.cpp b/src/graphics/geometry_first_pass.cpp new file mode 100644 index 000000000..6e5931a85 --- /dev/null +++ b/src/graphics/geometry_first_pass.cpp @@ -0,0 +1,18 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2015 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "graphics/geometry_first_pass.hpp" diff --git a/src/graphics/geometry_first_pass.hpp b/src/graphics/geometry_first_pass.hpp new file mode 100644 index 000000000..a3f81713f --- /dev/null +++ b/src/graphics/geometry_first_pass.hpp @@ -0,0 +1,22 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2015 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HEADER_GEOMETRY_PASSES_HPP +#define HEADER_GEOMETRY_PASSES_HPP + + +#endif //HEADER_GEOMETRY_PASSES_HPP \ No newline at end of file diff --git a/src/graphics/geometry_passes.cpp b/src/graphics/geometry_passes.cpp index 2ecddbb2b..18d6c456c 100644 --- a/src/graphics/geometry_passes.cpp +++ b/src/graphics/geometry_passes.cpp @@ -17,6 +17,7 @@ #include "graphics/geometry_passes.hpp" #include "graphics/callbacks.hpp" +#include "graphics/draw_tools.hpp" #include "graphics/glwrap.hpp" #include "graphics/post_processing.hpp" #include "graphics/rtts.hpp" @@ -976,123 +977,7 @@ namespace RenderGeometry using namespace RenderGeometry; -// ---------------------------------------------------------------------------- -template -void draw(const T *Shader, const GLMesh *mesh, uniforms... Args) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; - Shader->setUniforms(Args...); - glDrawElementsBaseVertex(ptype, (int)count, itype, - (GLvoid *)mesh->vaoOffset, - (int)mesh->vaoBaseVertex); -} // draw - -// ---------------------------------------------------------------------------- - -template -struct custom_unroll_args; - -template<> -struct custom_unroll_args<> -{ - template - static void exec(const T *Shader, const STK::Tuple &t, Args... args) - { - draw(Shader, STK::tuple_get<0>(t), args...); - } // exec -}; // custom_unroll_args - -// ---------------------------------------------------------------------------- -template -struct custom_unroll_args -{ - template - static void exec(const T *Shader, const STK::Tuple &t, Args... args) - { - custom_unroll_args::template exec(Shader, t, STK::tuple_get(t), args...); - } // exec -}; // custom_unroll_args - -// ---------------------------------------------------------------------------- -template -struct TexExpander_impl -{ - template - static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, - Args... args) - { - size_t idx = STK::tuple_get(TexSwizzle); - TexExpander_impl::template - ExpandTex(mesh, TexSwizzle, - args..., getTextureGLuint(mesh.textures[idx])); - } // ExpandTex -}; // TexExpander_impl - -// ---------------------------------------------------------------------------- -template -struct TexExpander_impl -{ - template - static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, - Args... args) - { - T::getInstance()->setTextureUnits(args...); - } // ExpandTex -}; // TexExpander_impl - -// ---------------------------------------------------------------------------- -template -struct TexExpander -{ - template - static void ExpandTex(GLMesh &mesh, const STK::Tuple &TexSwizzle, - Args... args) - { - TexExpander_impl::ExpandTex(mesh, TexSwizzle, - args...); - } // ExpandTex -}; // TexExpander - -// ---------------------------------------------------------------------------- -template -struct HandleExpander_impl -{ - template - static void Expand(uint64_t *TextureHandles, - const STK::Tuple &TexSwizzle, Args... args) - { - size_t idx = STK::tuple_get(TexSwizzle); - HandleExpander_impl::template - Expand(TextureHandles, TexSwizzle, args..., TextureHandles[idx]); - } // Expand -}; // HandleExpander_impl - -// ---------------------------------------------------------------------------- -template -struct HandleExpander_impl -{ - template - static void Expand(uint64_t *TextureHandles, - const STK::Tuple &TexSwizzle, Args... args) - { - T::getInstance()->setTextureHandles(args...); - } // Expand -}; // HandleExpander_impl - -// ---------------------------------------------------------------------------- -template -struct HandleExpander -{ - template - static void Expand(uint64_t *TextureHandles, const STK::Tuple &TexSwizzle, Args... args) - { - HandleExpander_impl::Expand(TextureHandles, TexSwizzle, args...); - } // Expand -}; // HandleExpander // ---------------------------------------------------------------------------- template @@ -1121,7 +1006,7 @@ void renderMeshes1stPass() HandleExpander::template Expand(mesh.TextureHandles, T::FirstPassTextures); else TexExpander::template ExpandTex(mesh, T::FirstPassTextures); - custom_unroll_args::template exec(T::FirstPassShader::getInstance(), meshes.at(i)); + CustomUnrollArgs::template drawMesh(meshes.at(i)); } } // renderMeshes1stPass @@ -1188,6 +1073,7 @@ void GeometryPasses::renderSolidFirstPass() for (unsigned i = 0; i < ImmediateDrawList::getInstance()->size(); i++) ImmediateDrawList::getInstance()->at(i)->render(); + //TODO: is it useful if AZDO enabled? renderMeshes1stPass(); renderMeshes1stPass(); renderMeshes1stPass(); @@ -1256,8 +1142,7 @@ void renderMeshes2ndPass( const std::vector &Prefilled_Handle, TexExpander::template ExpandTex(mesh, T::SecondPassTextures, Prefilled_Tex[0], Prefilled_Tex[1], Prefilled_Tex[2]); - custom_unroll_args::template - exec(T::SecondPassShader::getInstance(), meshes.at(i)); + CustomUnrollArgs::template drawMesh(meshes.at(i)); } } // renderMeshes2ndPass @@ -1356,6 +1241,7 @@ void GeometryPasses::renderSolidSecondPass( unsigned render_target_diffuse, render_target_specular, render_target_half_red); + //TODO: is it useful when AZDO enabled? renderMeshes2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); renderMeshes2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); renderMeshes2ndPass(createVector(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex); @@ -1510,7 +1396,7 @@ void renderTransparenPass(const std::vector &TexUnits, Shader::getInstance()->setTextureHandles(mesh.TextureHandles[0]); else Shader::getInstance()->setTextureUnits(getTextureGLuint(mesh.textures[0])); - custom_unroll_args::template exec(Shader::getInstance(), meshes->at(i)); + CustomUnrollArgs::template drawMesh(meshes->at(i)); } } // renderTransparenPass @@ -1652,45 +1538,6 @@ void GeometryPasses::renderTransparent(unsigned render_target) } // renderTransparent -// ---------------------------------------------------------------------------- -template -void drawShadow(const T *Shader, unsigned cascade, const GLMesh *mesh, uniforms... Args) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; - - Shader->setUniforms(cascade, Args...); - glDrawElementsBaseVertex(ptype, (int)count, itype, - (GLvoid *)mesh->vaoOffset, (int)mesh->vaoBaseVertex); -} // drawShadow - -// ---------------------------------------------------------------------------- -template -struct shadow_custom_unroll_args; - -template<> -struct shadow_custom_unroll_args<> -{ - template - static void exec(const T *Shader, unsigned cascade, const STK::Tuple &t, Args... args) - { - drawShadow(Shader, cascade, STK::tuple_get<0>(t), args...); - } // exec -}; // shadow_custom_unroll_args - -// ---------------------------------------------------------------------------- -template -struct shadow_custom_unroll_args -{ - template - static void exec(const T *Shader, unsigned cascade, const STK::Tuple &t, Args... args) - { - shadow_custom_unroll_args::template exec(Shader, cascade, t, STK::tuple_get(t), args...); - } // exec -}; // shadow_custom_unroll_args - // ---------------------------------------------------------------------------- template void renderShadow(unsigned cascade) @@ -1708,7 +1555,7 @@ void renderShadow(unsigned cascade) HandleExpander::template Expand(mesh->TextureHandles, T::ShadowTextures); else TexExpander::template ExpandTex(*mesh, T::ShadowTextures); - shadow_custom_unroll_args::template exec(T::ShadowPassShader::getInstance(), cascade, t.at(i)); + CustomUnrollArgs::template drawShadow(cascade, t.at(i)); } // for i } // renderShadow @@ -1838,34 +1685,6 @@ void GeometryPasses::renderShadows(const ShadowMatrices& shadow_matrices, } // renderShadows -// ---------------------------------------------------------------------------- -template -struct rsm_custom_unroll_args; - -template<> -struct rsm_custom_unroll_args<> -{ - template - static void exec(const core::matrix4 &rsm_matrix, - const STK::Tuple &t, Args... args) - { - draw(T::getInstance(), STK::tuple_get<0>(t), rsm_matrix, args...); - } -}; // rsm_custom_unroll_args - -// ---------------------------------------------------------------------------- -template -struct rsm_custom_unroll_args -{ - template - static void exec(const core::matrix4 &rsm_matrix, - const STK::Tuple &t, Args... args) - { - rsm_custom_unroll_args::template - exec(rsm_matrix, t, STK::tuple_get(t), args...); - } -}; // rsm_custom_unroll_args - // ---------------------------------------------------------------------------- template void drawRSM(const core::matrix4 & rsm_matrix) @@ -1884,7 +1703,7 @@ void drawRSM(const core::matrix4 & rsm_matrix) HandleExpander::template Expand(mesh->TextureHandles, T::RSMTextures); else TexExpander::template ExpandTex(*mesh, T::RSMTextures); - rsm_custom_unroll_args::template exec(rsm_matrix, t.at(i)); + CustomUnrollArgs::template drawReflectiveShadowMap(rsm_matrix, t.at(i)); } } // drawRSM diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index cea48fd6a..3b5ce480b 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -46,7 +46,7 @@ class Material : public NoCopy public: enum ShaderType { - SHADERTYPE_SOLID, + SHADERTYPE_SOLID = 0, SHADERTYPE_ALPHA_TEST, SHADERTYPE_ALPHA_BLEND, SHADERTYPE_ADDITIVE, diff --git a/src/graphics/stk_mesh.hpp b/src/graphics/stk_mesh.hpp index 44504baff..bc8671e1c 100644 --- a/src/graphics/stk_mesh.hpp +++ b/src/graphics/stk_mesh.hpp @@ -87,6 +87,16 @@ public: virtual bool isImmediateDraw() const { return false; } }; // STKMeshCommon +/* +// ---------------------------------------------------------------------------- +//TODO: template function in order to avoid duplicate code (clear method) +template +clearMeshList() +{ + +} +*/ + // ---------------------------------------------------------------------------- template class MeshList : public Singleton diff --git a/src/graphics/stk_scene_manager.hpp b/src/graphics/stk_scene_manager.hpp index 63639b1ba..1dfe2a222 100644 --- a/src/graphics/stk_scene_manager.hpp +++ b/src/graphics/stk_scene_manager.hpp @@ -29,12 +29,16 @@ #include "graphics/stk_mesh.hpp" #include "utils/singleton.hpp" -template +template class CommandBuffer : public Singleton { public: GLuint drawindirectcmd; DrawElementsIndirectCommand *Ptr; + + //size_t Offset[nb_cascades][nb_materials]; + //size_t Size[nb_cascades][nb_materials]; + CommandBuffer() { glGenBuffers(1, &drawindirectcmd); @@ -49,6 +53,11 @@ public: glBufferData(GL_DRAW_INDIRECT_BUFFER, 10000 * sizeof(DrawElementsIndirectCommand), 0, GL_STREAM_DRAW); } } + + void bind() + { + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd); + } }; class ImmediateDrawList : public Singleton, public std::vector @@ -61,25 +70,25 @@ class ParticlesList : public Singleton, public std::vector +class SolidPassCmd : public CommandBuffer(Material::SHADERTYPE_COUNT)> { public: size_t Offset[Material::SHADERTYPE_COUNT], Size[Material::SHADERTYPE_COUNT]; }; -class ShadowPassCmd : public CommandBuffer +class ShadowPassCmd : public CommandBuffer(Material::SHADERTYPE_COUNT)> { public: size_t Offset[4][Material::SHADERTYPE_COUNT], Size[4][Material::SHADERTYPE_COUNT]; }; -class RSMPassCmd : public CommandBuffer +class RSMPassCmd : public CommandBuffer(Material::SHADERTYPE_COUNT)> { public: size_t Offset[Material::SHADERTYPE_COUNT], Size[Material::SHADERTYPE_COUNT]; }; -class GlowPassCmd : public CommandBuffer +class GlowPassCmd : public CommandBuffer { public: size_t Offset, Size;