Removed several singletons and added a CommandBuffer class
This commit is contained in:
parent
4452661533
commit
6ba82eaac9
358
src/graphics/command_buffer.cpp
Normal file
358
src/graphics/command_buffer.cpp
Normal file
@ -0,0 +1,358 @@
|
||||
// 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/command_buffer.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataSingleTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataSingleTex &instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataSingleTex>(node, instance);
|
||||
instance.Texture = mesh->TextureHandles[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataDualTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataDualTex &instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataDualTex>(node, instance);
|
||||
instance.Texture = mesh->TextureHandles[0];
|
||||
instance.SecondTexture = mesh->TextureHandles[1];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataThreeTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataThreeTex &instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataThreeTex>(node, instance);
|
||||
instance.Texture = mesh->TextureHandles[0];
|
||||
instance.SecondTexture = mesh->TextureHandles[1];
|
||||
instance.ThirdTexture = mesh->TextureHandles[2];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<GlowInstanceData>::add(GLMesh *mesh, scene::ISceneNode *node, GlowInstanceData &instance)
|
||||
{
|
||||
fillOriginOrientationScale<GlowInstanceData>(node, instance);
|
||||
STKMeshSceneNode *nd = dynamic_cast<STKMeshSceneNode*>(node);
|
||||
instance.Color = nd->getGlowColor().color;
|
||||
}
|
||||
|
||||
|
||||
CommandBuffer::CommandBuffer():
|
||||
m_offset(NULL), m_size(NULL), m_poly_count(0)
|
||||
{
|
||||
glGenBuffers(1, &m_draw_indirect_cmd_id);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
if (CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glBufferStorage(GL_DRAW_INDIRECT_BUFFER,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
0, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||
m_draw_indirect_cmd = (DrawElementsIndirectCommand *)
|
||||
glMapBufferRange(GL_DRAW_INDIRECT_BUFFER,
|
||||
0, 10000 * sizeof(DrawElementsIndirectCommand),
|
||||
GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_DRAW_INDIRECT_BUFFER,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
0, GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
CommandBuffer::~CommandBuffer()
|
||||
{
|
||||
glDeleteBuffers(1, &m_draw_indirect_cmd_id);
|
||||
delete[] m_offset;
|
||||
delete[] m_size;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void CommandBuffer::fillMaterial(int material_id,
|
||||
MeshMap *mesh_map,
|
||||
std::vector<GLMesh *> &instanced_list,
|
||||
T *instance_buffer)
|
||||
{
|
||||
m_offset[material_id] = m_instance_buffer_offset;
|
||||
FillInstances<T>(mesh_map[material_id],
|
||||
instanced_list,
|
||||
instance_buffer,
|
||||
m_draw_indirect_cmd,
|
||||
m_instance_buffer_offset,
|
||||
m_command_buffer_offset,
|
||||
m_poly_count);
|
||||
|
||||
m_size[material_id] = m_command_buffer_offset - m_instance_buffer_offset;
|
||||
}
|
||||
|
||||
SolidCommandBuffer::SolidCommandBuffer(): CommandBuffer()
|
||||
{
|
||||
m_offset = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
m_size = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
}
|
||||
|
||||
void SolidCommandBuffer::fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[])
|
||||
{
|
||||
m_instance_buffer_offset = 0;
|
||||
m_command_buffer_offset = 0;
|
||||
m_poly_count = 0;
|
||||
|
||||
//Dual textures materials
|
||||
InstanceDataDualTex *instance_buffer_dual_tex;
|
||||
|
||||
if (CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
instance_buffer_dual_tex =
|
||||
(InstanceDataDualTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDualTex);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDualTex));
|
||||
instance_buffer_dual_tex =
|
||||
(InstanceDataDualTex*) glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
10000 * sizeof(InstanceDataDualTex),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
|
||||
|
||||
m_draw_indirect_cmd =
|
||||
(DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
Material::ShaderType dual_tex_materials[5] =
|
||||
{
|
||||
Material::SHADERTYPE_SOLID,
|
||||
Material::SHADERTYPE_ALPHA_TEST,
|
||||
Material::SHADERTYPE_SOLID_UNLIT,
|
||||
Material::SHADERTYPE_SPHERE_MAP,
|
||||
Material::SHADERTYPE_VEGETATION
|
||||
};
|
||||
|
||||
int material_id;
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
material_id = static_cast<int>(dual_tex_materials[i]);
|
||||
fillMaterial( material_id,
|
||||
mesh_map,
|
||||
instanced_lists[material_id],
|
||||
instance_buffer_dual_tex);
|
||||
}
|
||||
|
||||
|
||||
//Three textures materials
|
||||
InstanceDataThreeTex *instance_buffer_three_tex;
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeThreeTex));
|
||||
instance_buffer_three_tex = (InstanceDataThreeTex*)
|
||||
glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
10000 * sizeof(InstanceDataSingleTex),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
Material::ShaderType three_tex_materials[2] =
|
||||
{
|
||||
Material::SHADERTYPE_DETAIL_MAP,
|
||||
Material::SHADERTYPE_NORMAL_MAP
|
||||
};
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
material_id = static_cast<int>(three_tex_materials[i]);
|
||||
fillMaterial( material_id,
|
||||
mesh_map,
|
||||
instanced_lists[material_id],
|
||||
instance_buffer_three_tex);
|
||||
}
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
} //SolidCommandBuffer::fill
|
||||
|
||||
ShadowCommandBuffer::ShadowCommandBuffer(): CommandBuffer()
|
||||
{
|
||||
m_offset = new size_t[4 * static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
m_size = new size_t[4 * static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
}
|
||||
|
||||
void ShadowCommandBuffer::fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[])
|
||||
{
|
||||
m_instance_buffer_offset = 0;
|
||||
m_command_buffer_offset = 0;
|
||||
m_poly_count = 0;
|
||||
InstanceDataSingleTex *shadow_instance_buffer;
|
||||
|
||||
if (CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
shadow_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
|
||||
shadow_instance_buffer =
|
||||
(InstanceDataSingleTex*) glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
10000 * sizeof(InstanceDataDualTex),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
m_draw_indirect_cmd =
|
||||
(DrawElementsIndirectCommand*) glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
Material::ShaderType materials[7] =
|
||||
{
|
||||
Material::SHADERTYPE_SOLID,
|
||||
Material::SHADERTYPE_ALPHA_TEST,
|
||||
Material::SHADERTYPE_SOLID_UNLIT,
|
||||
Material::SHADERTYPE_NORMAL_MAP,
|
||||
Material::SHADERTYPE_SPHERE_MAP,
|
||||
Material::SHADERTYPE_DETAIL_MAP,
|
||||
Material::SHADERTYPE_VEGETATION
|
||||
};
|
||||
int material_id;
|
||||
|
||||
for(int cascade=0;cascade<4;cascade++)
|
||||
{
|
||||
for(int i=0;i<7;i++)
|
||||
{
|
||||
material_id = cascade * 7 + static_cast<int>(materials[i]);
|
||||
fillMaterial( material_id,
|
||||
mesh_map,
|
||||
instanced_lists[material_id],
|
||||
shadow_instance_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
|
||||
} //ShadowCommandBuffer::fill
|
||||
|
||||
ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer(): CommandBuffer()
|
||||
{
|
||||
m_offset = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
m_size = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
|
||||
}
|
||||
|
||||
|
||||
void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[])
|
||||
{
|
||||
m_instance_buffer_offset = 0;
|
||||
m_command_buffer_offset = 0;
|
||||
m_poly_count = 0;
|
||||
InstanceDataSingleTex *rsm_instance_buffer;
|
||||
|
||||
if (CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
rsm_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER,
|
||||
VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
|
||||
rsm_instance_buffer =
|
||||
(InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
10000 * sizeof(InstanceDataDualTex),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
m_draw_indirect_cmd =
|
||||
(DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
Material::ShaderType materials[5] =
|
||||
{
|
||||
Material::SHADERTYPE_SOLID,
|
||||
Material::SHADERTYPE_ALPHA_TEST,
|
||||
Material::SHADERTYPE_SOLID_UNLIT,
|
||||
Material::SHADERTYPE_DETAIL_MAP,
|
||||
Material::SHADERTYPE_NORMAL_MAP,
|
||||
};
|
||||
int material_id;
|
||||
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
material_id = static_cast<int>(materials[i]);
|
||||
fillMaterial( material_id,
|
||||
mesh_map,
|
||||
instanced_lists[material_id],
|
||||
rsm_instance_buffer);
|
||||
}
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
|
||||
} //ReflectiveShadowMapCommandBuffer::fill
|
||||
|
||||
GlowCommandBuffer::GlowCommandBuffer()
|
||||
{
|
||||
m_offset = new size_t[1];
|
||||
m_size = new size_t[1];
|
||||
}
|
||||
|
||||
void GlowCommandBuffer::fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[])
|
||||
{
|
||||
m_instance_buffer_offset = 0;
|
||||
m_command_buffer_offset = 0;
|
||||
m_poly_count = 0;
|
||||
GlowInstanceData *glow_instance_buffer;
|
||||
|
||||
if (CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glow_instance_buffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER,
|
||||
VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
|
||||
glow_instance_buffer =
|
||||
(GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
||||
10000 * sizeof(InstanceDataDualTex),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
m_draw_indirect_cmd =
|
||||
(DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0,
|
||||
10000 * sizeof(DrawElementsIndirectCommand),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
fillMaterial( 0,
|
||||
mesh_map,
|
||||
instanced_lists[0],
|
||||
glow_instance_buffer);
|
||||
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
||||
}
|
||||
} //GlowCommandBuffer::fill
|
188
src/graphics/command_buffer.hpp
Normal file
188
src/graphics/command_buffer.hpp
Normal file
@ -0,0 +1,188 @@
|
||||
// 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_COMMAND_BUFFER_HPP
|
||||
#define HEADER_COMMAND_BUFFER_HPP
|
||||
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "graphics/material.hpp"
|
||||
|
||||
#include "graphics/stk_mesh_scene_node.hpp"
|
||||
#include "graphics/vao_manager.hpp"
|
||||
#include <irrlicht.h>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
typedef std::vector<std::pair<GLMesh *, irr::scene::ISceneNode*> > InstanceList;
|
||||
typedef std::unordered_map <irr::scene::IMeshBuffer *, InstanceList > MeshMap;
|
||||
|
||||
|
||||
template<typename InstanceData>
|
||||
void fillOriginOrientationScale(scene::ISceneNode *node, InstanceData &instance)
|
||||
{
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
instance.Origin.X = Origin.X;
|
||||
instance.Origin.Y = Origin.Y;
|
||||
instance.Origin.Z = Origin.Z;
|
||||
instance.Orientation.X = Orientation.X;
|
||||
instance.Orientation.Y = Orientation.Y;
|
||||
instance.Orientation.Z = Orientation.Z;
|
||||
instance.Scale.X = Scale.X;
|
||||
instance.Scale.Y = Scale.Y;
|
||||
instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
template<typename InstanceData>
|
||||
struct InstanceFiller
|
||||
{
|
||||
static void add(GLMesh *, scene::ISceneNode *, InstanceData &);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void FillInstances_impl(InstanceList instance_list,
|
||||
T * instance_buffer,
|
||||
DrawElementsIndirectCommand *command_buffer,
|
||||
size_t &instance_buffer_offset,
|
||||
size_t &command_buffer_offset,
|
||||
size_t &poly_count)
|
||||
{
|
||||
// Should never be empty
|
||||
GLMesh *mesh = instance_list.front().first;
|
||||
size_t initial_offset = instance_buffer_offset;
|
||||
|
||||
for (unsigned i = 0; i < instance_list.size(); i++)
|
||||
{
|
||||
auto &Tp = instance_list[i];
|
||||
scene::ISceneNode *node = Tp.second;
|
||||
InstanceFiller<T>::add(mesh, node, instance_buffer[instance_buffer_offset++]);
|
||||
assert(instance_buffer_offset * sizeof(T) < 10000 * sizeof(InstanceDataDualTex)); //TODO
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = command_buffer[command_buffer_offset++];
|
||||
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||
CurrentCommand.count = mesh->IndexCount;
|
||||
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||
CurrentCommand.baseInstance = initial_offset;
|
||||
CurrentCommand.instanceCount = instance_buffer_offset - initial_offset;
|
||||
|
||||
poly_count += (instance_buffer_offset - initial_offset) * mesh->IndexCount / 3;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void FillInstances( const MeshMap &gathered_GL_mesh,
|
||||
std::vector<GLMesh *> &instanced_list,
|
||||
T *instance_buffer,
|
||||
DrawElementsIndirectCommand *command_buffer,
|
||||
size_t &instance_buffer_offset,
|
||||
size_t &command_buffer_offset,
|
||||
size_t &poly_count)
|
||||
{
|
||||
auto It = gathered_GL_mesh.begin(), E = gathered_GL_mesh.end();
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstances_impl<T>(It->second, instance_buffer, command_buffer, instance_buffer_offset, command_buffer_offset, poly_count);
|
||||
if (!CVS->isAZDOEnabled())
|
||||
instanced_list.push_back(It->second.front().first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CommandBuffer
|
||||
{
|
||||
protected:
|
||||
GLuint m_draw_indirect_cmd_id;
|
||||
DrawElementsIndirectCommand *m_draw_indirect_cmd;
|
||||
size_t *m_offset;
|
||||
size_t *m_size;
|
||||
size_t m_poly_count;
|
||||
size_t m_instance_buffer_offset;
|
||||
size_t m_command_buffer_offset;
|
||||
|
||||
template<typename T>
|
||||
void fillMaterial(int material_id,
|
||||
MeshMap *mesh_map,
|
||||
std::vector<GLMesh *> &instanced_list,
|
||||
T *instance_buffer);
|
||||
|
||||
public:
|
||||
CommandBuffer();
|
||||
virtual ~CommandBuffer();
|
||||
|
||||
inline size_t getPolyCount() {return m_poly_count;}
|
||||
|
||||
inline void bind()
|
||||
{
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
|
||||
}
|
||||
|
||||
/** Draw the i-th mesh with the specified material
|
||||
* (require GL_ARB_base_instance and GL_ARB_draw_indirect extensions)
|
||||
* \param shader_type Only render meshes with the specified material
|
||||
*/
|
||||
inline void drawIndirect(Material::ShaderType shader_type, int i)
|
||||
{
|
||||
glDrawElementsIndirect(GL_TRIANGLES,
|
||||
GL_UNSIGNED_SHORT,
|
||||
(const void*)(m_offset[static_cast<int>(shader_type) + i] * sizeof(DrawElementsIndirectCommand)));
|
||||
}
|
||||
|
||||
/** Draw the meshes with the specified material
|
||||
* (require AZDO extensions)
|
||||
* \param shader_type Only render meshes with the specified material
|
||||
*/
|
||||
inline void multidrawIndirect(Material::ShaderType shader_type)
|
||||
{
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES,
|
||||
GL_UNSIGNED_SHORT,
|
||||
(const void*)(m_offset[static_cast<int>(shader_type)] * sizeof(DrawElementsIndirectCommand)),
|
||||
(int) m_size[static_cast<int>(shader_type)],
|
||||
sizeof(DrawElementsIndirectCommand));
|
||||
}
|
||||
};
|
||||
|
||||
class SolidCommandBuffer: public CommandBuffer
|
||||
{
|
||||
public:
|
||||
SolidCommandBuffer();
|
||||
void fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[]);
|
||||
};
|
||||
|
||||
class ShadowCommandBuffer: public CommandBuffer
|
||||
{
|
||||
public:
|
||||
ShadowCommandBuffer();
|
||||
void fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[]);
|
||||
};
|
||||
|
||||
class ReflectiveShadowMapCommandBuffer: public CommandBuffer
|
||||
{
|
||||
public:
|
||||
ReflectiveShadowMapCommandBuffer();
|
||||
void fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[]);
|
||||
};
|
||||
|
||||
class GlowCommandBuffer: public CommandBuffer
|
||||
{
|
||||
public:
|
||||
GlowCommandBuffer();
|
||||
void fill(MeshMap *mesh_map, std::vector<GLMesh *> instanced_lists[]);
|
||||
};
|
||||
|
||||
#endif //HEADER_COMMAND_BUFFER_HPP
|
@ -28,63 +28,6 @@ using namespace irr;
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename InstanceData>
|
||||
void fillOriginOrientationScale(scene::ISceneNode *node, InstanceData &instance)
|
||||
{
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
instance.Origin.X = Origin.X;
|
||||
instance.Origin.Y = Origin.Y;
|
||||
instance.Origin.Z = Origin.Z;
|
||||
instance.Orientation.X = Orientation.X;
|
||||
instance.Orientation.Y = Orientation.Y;
|
||||
instance.Orientation.Z = Orientation.Z;
|
||||
instance.Scale.X = Scale.X;
|
||||
instance.Scale.Y = Scale.Y;
|
||||
instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
template<typename InstanceData>
|
||||
struct InstanceFiller
|
||||
{
|
||||
static void add(GLMesh *, scene::ISceneNode *, InstanceData &);
|
||||
};
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataSingleTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataSingleTex &Instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataSingleTex>(node, Instance);
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataDualTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataDualTex &Instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataDualTex>(node, Instance);
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataThreeTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataThreeTex &Instance)
|
||||
{
|
||||
fillOriginOrientationScale<InstanceDataThreeTex>(node, Instance);
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
Instance.ThirdTexture = mesh->TextureHandles[2];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<GlowInstanceData>::add(GLMesh *mesh, scene::ISceneNode *node, GlowInstanceData &Instance)
|
||||
{
|
||||
fillOriginOrientationScale<GlowInstanceData>(node, Instance);
|
||||
STKMeshSceneNode *nd = dynamic_cast<STKMeshSceneNode*>(node);
|
||||
Instance.Color = nd->getGlowColor().color;
|
||||
}
|
||||
|
||||
|
||||
void FixBoundingBoxes(scene::ISceneNode* node)
|
||||
{
|
||||
for (scene::ISceneNode *child : node->getChildren())
|
||||
@ -94,58 +37,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
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;
|
||||
size_t InitialOffset = InstanceBufferOffset;
|
||||
|
||||
for (unsigned i = 0; i < instance_list.size(); i++)
|
||||
{
|
||||
auto &Tp = instance_list[i];
|
||||
scene::ISceneNode *node = Tp.second;
|
||||
InstanceFiller<T>::add(mesh, node, InstanceBuffer[InstanceBufferOffset++]);
|
||||
assert(InstanceBufferOffset * sizeof(T) < 10000 * sizeof(InstanceDataDualTex));
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||
CurrentCommand.count = mesh->IndexCount;
|
||||
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||
CurrentCommand.baseInstance = InitialOffset;
|
||||
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
|
||||
|
||||
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void FillInstances( const DrawCalls::MeshMap &GatheredGLMesh,
|
||||
std::vector<GLMesh *> &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)
|
||||
{
|
||||
FillInstances_impl<T>(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount);
|
||||
if (!CVS->isAZDOEnabled())
|
||||
InstancedList.push_back(It->second.front().first);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} //namespace
|
||||
|
||||
|
||||
@ -653,6 +545,21 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
|
||||
{
|
||||
#pragma omp section
|
||||
{
|
||||
|
||||
//TODO
|
||||
/*std::vector<GLMesh *> instanced_lists[Material::SHADERTYPE_COUNT];
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_SOLID)] = ListInstancedMatDefault::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_ALPHA_TEST)] = ListInstancedMatAlphaRef::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_SOLID_UNLIT)] = ListInstancedMatUnlit::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_SPHERE_MAP)] = ListInstancedMatSphereMap::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_VEGETATION)] = ListInstancedMatGrass::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_DETAIL_MAP)] = ListInstancedMatDetails::getInstance()->SolidPass;
|
||||
instanced_lists[static_cast<int>(Material::SHADERTYPE_NORMAL_MAP)] = ListInstancedMatNormalMap::getInstance()->SolidPass;
|
||||
|
||||
m_solid_cmd_buffer.fill(m_solid_pass_mesh, instanced_lists);*/
|
||||
|
||||
|
||||
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
if (!CVS->supportsAsyncInstanceUpload())
|
||||
{
|
||||
@ -661,28 +568,6 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
||||
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
|
||||
|
@ -18,18 +18,21 @@
|
||||
#ifndef HEADER_DRAW_CALLS_HPP
|
||||
#define HEADER_DRAW_CALLS_HPP
|
||||
|
||||
#include "graphics/command_buffer.hpp"
|
||||
#include "graphics/draw_tools.hpp"
|
||||
#include "graphics/gpu_particles.hpp"
|
||||
#include "graphics/shadow_matrices.hpp"
|
||||
#include "graphics/stk_billboard.hpp"
|
||||
#include "graphics/stk_mesh.hpp"
|
||||
#include <irrlicht.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
class DrawCalls
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<GLMesh *, irr::scene::ISceneNode*> > InstanceList;
|
||||
typedef std::unordered_map <irr::scene::IMeshBuffer *, InstanceList > MeshMap;
|
||||
|
||||
|
||||
|
||||
GLsync m_sync = 0; //TODO: make it private. Should it be in shader_based_renderer?
|
||||
@ -41,6 +44,12 @@ private:
|
||||
std::vector<STKBillboard *> m_billboard_list;
|
||||
std::vector<ParticleSystemProxy *> m_particles_list;
|
||||
|
||||
SolidCommandBuffer m_solid_cmd_buffer;
|
||||
ShadowCommandBuffer m_shadow_cmd_buffer;
|
||||
ReflectiveShadowMapCommandBuffer m_reflective_shadow_map_cmd_buffer;
|
||||
GlowCommandBuffer m_glow_cmd_buffer;
|
||||
|
||||
|
||||
irr::core::vector3df windDir; //TODO: same member in geometry_passes
|
||||
|
||||
MeshMap m_solid_pass_mesh [Material::SHADERTYPE_COUNT] ;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "graphics/shader.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/stk_mesh.hpp"
|
||||
#include "graphics/texture_manager.hpp"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
19
src/graphics/material_type.cpp
Normal file
19
src/graphics/material_type.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
// 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/material_type.hpp"
|
||||
|
66
src/graphics/material_type.hpp
Normal file
66
src/graphics/material_type.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
// 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_MATERIAL_TYPE_HPP
|
||||
#define HEADER_MATERIAL_TYPE_HPP
|
||||
|
||||
#include "graphics/shader.hpp"
|
||||
|
||||
/*
|
||||
struct MaterialType
|
||||
{
|
||||
Shader *m_first_pass_shader;
|
||||
Shader *m_second_pass_shader;
|
||||
Shader *m_shadow_shader;
|
||||
Shader *m_reflective_shadow_map_shader;
|
||||
|
||||
Material::ShaderType m_shader_type;
|
||||
};*/
|
||||
|
||||
/*
|
||||
// ============================================================================
|
||||
struct DefaultMaterial
|
||||
{
|
||||
typedef InstancedObjectPass1Shader InstancedFirstPassShader;
|
||||
typedef InstancedObjectPass2Shader InstancedSecondPassShader;
|
||||
typedef InstancedShadowShader InstancedShadowPassShader;
|
||||
typedef CInstancedRSMShader InstancedRSMShader;
|
||||
typedef ListInstancedMatDefault InstancedList;
|
||||
typedef Shaders::ObjectPass1Shader FirstPassShader;
|
||||
typedef Shaders::ObjectPass2Shader SecondPassShader;
|
||||
typedef ShadowShader ShadowPassShader;
|
||||
typedef CRSMShader RSMShader;
|
||||
typedef ListMatDefault List;
|
||||
static const enum video::E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum Material::ShaderType MaterialType
|
||||
= Material::SHADERTYPE_SOLID;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const STK::Tuple<size_t> FirstPassTextures;
|
||||
static const STK::Tuple<size_t, size_t> SecondPassTextures;
|
||||
static const STK::Tuple<> ShadowTextures;
|
||||
static const STK::Tuple<size_t> RSMTextures;
|
||||
}; // struct DefaultMaterial
|
||||
|
||||
const STK::Tuple<size_t> DefaultMaterial::FirstPassTextures
|
||||
= STK::Tuple<size_t>(1);
|
||||
const STK::Tuple<size_t, size_t> DefaultMaterial::SecondPassTextures
|
||||
= STK::Tuple<size_t, size_t>(0, 1);
|
||||
const STK::Tuple<> DefaultMaterial::ShadowTextures;
|
||||
const STK::Tuple<size_t> DefaultMaterial::RSMTextures = STK::Tuple<size_t>(0);
|
||||
*/
|
||||
|
||||
#endif //HEADER_MATERIAL_TYPE_HPP
|
@ -491,17 +491,17 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
|
||||
|
||||
ShaderBasedRenderer::ShaderBasedRenderer()
|
||||
{
|
||||
if (CVS->isAZDOEnabled())
|
||||
/*if (CVS->isAZDOEnabled())
|
||||
m_solid_first_pass = new AZDOSolidFirstPass();
|
||||
else if (CVS->supportsIndirectInstancingRendering())
|
||||
m_solid_first_pass = new IndirectInstancedSolidFirstPass();
|
||||
else
|
||||
m_solid_first_pass = new GL3SolidFirstPass();
|
||||
m_solid_first_pass = new GL3SolidFirstPass();*/
|
||||
}
|
||||
|
||||
ShaderBasedRenderer::~ShaderBasedRenderer()
|
||||
{
|
||||
delete m_solid_first_pass;
|
||||
//delete m_solid_first_pass;
|
||||
}
|
||||
|
||||
void ShaderBasedRenderer::addSunLight(const core::vector3df &pos) {
|
||||
|
@ -37,7 +37,7 @@ private:
|
||||
ShadowMatrices m_shadow_matrices;
|
||||
|
||||
irr::core::vector3df m_wind_dir;
|
||||
SolidFirstPass *m_solid_first_pass;
|
||||
//SolidFirstPass *m_solid_first_pass;
|
||||
|
||||
void compressPowerUpTextures();
|
||||
void setOverrideMaterial();
|
||||
|
@ -15,6 +15,8 @@
|
||||
// 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/solid_first_pass.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
@ -55,6 +57,7 @@ void AZDOSolidFirstPass::render(const DrawCalls& draw_calls, irr::core::vector3d
|
||||
|
||||
draw_calls.renderImmediateDrawList();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
@ -29,24 +29,24 @@ public:
|
||||
};
|
||||
|
||||
/** This class only uses OpenGL3.x functions */
|
||||
class GL3SolidFirstPass: public SolidFirstPass
|
||||
/*class GL3SolidFirstPass: public SolidFirstPass
|
||||
{
|
||||
void render(const DrawCalls& draw_calls, irr::core::vector3df wind_dir);
|
||||
};
|
||||
};*/
|
||||
|
||||
/** Require GL_ARB_base_instance and GL_ARB_draw_indirect extensions */
|
||||
class IndirectInstancedSolidFirstPass: public SolidFirstPass
|
||||
/*class IndirectInstancedSolidFirstPass: public SolidFirstPass
|
||||
{
|
||||
void render(const DrawCalls& draw_calls, irr::core::vector3df wind_dir);
|
||||
};
|
||||
};*/
|
||||
|
||||
/** AZDO: Approaching Zero Driver Overhead
|
||||
* Require GL_ARB_base_instance, GL_ARB_draw_indirect,
|
||||
* GL_ARB_bindless_texture and GL_ARB_multi_draw_indirect extensions */
|
||||
class AZDOSolidFirstPass: public SolidFirstPass
|
||||
/*class AZDOSolidFirstPass: public SolidFirstPass
|
||||
{
|
||||
void render(const DrawCalls& draw_calls, irr::core::vector3df wind_dir);
|
||||
};
|
||||
};*/
|
||||
|
||||
|
||||
#endif //HEADER_SOLID_FIRST_PASS_HPP
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
template<typename T, int nb_cascades, int nb_materials>
|
||||
class CommandBuffer : public Singleton<T>
|
||||
class CommandBufferOld : public Singleton<T>
|
||||
{
|
||||
public:
|
||||
GLuint drawindirectcmd;
|
||||
@ -39,7 +39,7 @@ public:
|
||||
//size_t Offset[nb_cascades][nb_materials];
|
||||
//size_t Size[nb_cascades][nb_materials];
|
||||
|
||||
CommandBuffer()
|
||||
CommandBufferOld()
|
||||
{
|
||||
glGenBuffers(1, &drawindirectcmd);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, drawindirectcmd);
|
||||
@ -61,25 +61,25 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class SolidPassCmd : public CommandBuffer<SolidPassCmd, 1, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
class SolidPassCmd : public CommandBufferOld<SolidPassCmd, 1, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
{
|
||||
public:
|
||||
size_t Offset[Material::SHADERTYPE_COUNT], Size[Material::SHADERTYPE_COUNT];
|
||||
};
|
||||
|
||||
class ShadowPassCmd : public CommandBuffer<ShadowPassCmd, 4, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
class ShadowPassCmd : public CommandBufferOld<ShadowPassCmd, 4, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
{
|
||||
public:
|
||||
size_t Offset[4][Material::SHADERTYPE_COUNT], Size[4][Material::SHADERTYPE_COUNT];
|
||||
};
|
||||
|
||||
class RSMPassCmd : public CommandBuffer<RSMPassCmd, 1, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
class RSMPassCmd : public CommandBufferOld<RSMPassCmd, 1, static_cast<int>(Material::SHADERTYPE_COUNT)>
|
||||
{
|
||||
public:
|
||||
size_t Offset[Material::SHADERTYPE_COUNT], Size[Material::SHADERTYPE_COUNT];
|
||||
};
|
||||
|
||||
class GlowPassCmd : public CommandBuffer<GlowPassCmd, 1, 1>
|
||||
class GlowPassCmd : public CommandBufferOld<GlowPassCmd, 1, 1>
|
||||
{
|
||||
public:
|
||||
size_t Offset, Size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user