Allow to use skinning without tbo
This commit is contained in:
parent
fee6866c6d
commit
9ad3ba1fe2
@ -1,4 +1,4 @@
|
||||
#ifdef GL_ES
|
||||
#ifdef TBO_DISABLED
|
||||
uniform sampler2D skinning_tex;
|
||||
#else
|
||||
uniform samplerBuffer skinning_tex;
|
||||
@ -56,7 +56,7 @@ void main()
|
||||
vec4 skinned_tangent = vec4(0.0);
|
||||
int skinning_offset = i_misc_data.x;
|
||||
|
||||
#ifdef GL_ES
|
||||
#ifdef TBO_DISABLED
|
||||
mat4 joint_matrix =
|
||||
i_weight[0] * mat4(
|
||||
texelFetch(skinning_tex, ivec2(0, clamp(i_joint[0] + skinning_offset, 0, MAX_BONES)), 0),
|
||||
|
@ -56,6 +56,7 @@ void CentralVideoSettings::init()
|
||||
hasInstancedArrays = false;
|
||||
hasBGRA = false;
|
||||
hasColorBufferFloat = false;
|
||||
hasTextureBufferObject = false;
|
||||
m_need_vertex_id_workaround = false;
|
||||
|
||||
// Call to glGetIntegerv should not be made if --no-graphics is used
|
||||
@ -157,6 +158,12 @@ void CentralVideoSettings::init()
|
||||
hasGS = true;
|
||||
Log::info("GLDriver", "Geometry Shaders Present");
|
||||
}
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_BUFFER_OBJECT) &&
|
||||
m_glsl == true)
|
||||
{
|
||||
hasTextureBufferObject = true;
|
||||
Log::info("GLDriver", "ARB Texture Buffer Object Present");
|
||||
}
|
||||
if (hasGLExtension("GL_ARB_texture_swizzle"))
|
||||
{
|
||||
hasTextureSwizzle = true;
|
||||
@ -216,7 +223,7 @@ void CentralVideoSettings::init()
|
||||
hasUBO = true;
|
||||
Log::info("GLDriver", "ARB Uniform Buffer Object Present");
|
||||
}
|
||||
|
||||
|
||||
if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_TEXTURE_FORMAT_BGRA8888) &&
|
||||
(hasGLExtension("GL_IMG_texture_format_BGRA8888") ||
|
||||
hasGLExtension("GL_EXT_texture_format_BGRA8888")))
|
||||
@ -449,4 +456,9 @@ bool CentralVideoSettings::isARBInstancedArraysUsable() const
|
||||
(m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 2));
|
||||
}
|
||||
|
||||
bool CentralVideoSettings::isARBTextureBufferObjectUsable() const
|
||||
{
|
||||
return hasTextureBufferObject;
|
||||
}
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -48,6 +48,7 @@ private:
|
||||
bool hasInstancedArrays;
|
||||
bool hasBGRA;
|
||||
bool hasColorBufferFloat;
|
||||
bool hasTextureBufferObject;
|
||||
bool m_need_vertex_id_workaround;
|
||||
public:
|
||||
static bool m_supports_sp;
|
||||
@ -81,6 +82,7 @@ public:
|
||||
bool isARBInstancedArraysUsable() const;
|
||||
bool isEXTTextureFormatBGRA8888Usable() const;
|
||||
bool isEXTColorBufferFloatUsable() const;
|
||||
bool isARBTextureBufferObjectUsable() const;
|
||||
|
||||
// Are all required extensions available for feature support
|
||||
bool supportsComputeShadersFiltering() const;
|
||||
|
@ -44,7 +44,7 @@ namespace GraphicsRestrictions
|
||||
/** The list of names used in the XML file for the graphics
|
||||
* restriction types. They must be in the same order as the types. */
|
||||
|
||||
std::array<std::string, 30> m_names_of_restrictions =
|
||||
std::array<std::string, 31> m_names_of_restrictions =
|
||||
{
|
||||
{
|
||||
"UniformBufferObject",
|
||||
@ -76,7 +76,8 @@ namespace GraphicsRestrictions
|
||||
"ForceLegacyDevice",
|
||||
"VertexIdWorking",
|
||||
"HardwareSkinning",
|
||||
"NpotTextures"
|
||||
"NpotTextures",
|
||||
"TextureBufferObject"
|
||||
}
|
||||
};
|
||||
} // namespace Private
|
||||
|
@ -64,6 +64,7 @@ namespace GraphicsRestrictions
|
||||
GR_VERTEX_ID_WORKING,
|
||||
GR_HARDWARE_SKINNING,
|
||||
GR_NPOT_TEXTURES,
|
||||
GR_TEXTURE_BUFFER_OBJECT,
|
||||
GR_COUNT /** MUST be last entry. */
|
||||
} ;
|
||||
|
||||
|
@ -171,6 +171,8 @@ ShaderFilesManager::SharedShader ShaderFilesManager::loadShader
|
||||
code << "//" << full_path << "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
code << "#define TBO_DISABLED\n";
|
||||
if (CVS->needsVertexIdWorkaround())
|
||||
code << "#define Needs_Vertex_Id_Workaround\n";
|
||||
if (CVS->isDeferredEnabled())
|
||||
|
@ -237,43 +237,47 @@ void resizeSkinning(unsigned number)
|
||||
const irr::core::matrix4 m;
|
||||
g_skinning_size = number;
|
||||
|
||||
#ifdef USE_GLES2
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, number, 0, GL_RGBA,
|
||||
GL_FLOAT, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT,
|
||||
m.pointer());
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
static std::vector<std::array<float, 16> >
|
||||
tmp_buf(stk_config->m_max_skinning_bones);
|
||||
g_joint_ptr = tmp_buf.data();
|
||||
|
||||
#else
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glBufferStorage(GL_TEXTURE_BUFFER, number << 6, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 0, 64,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
memcpy(g_joint_ptr, m.pointer(), 64);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 64, (number - 1) << 6,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 4, number, 0, GL_RGBA,
|
||||
GL_FLOAT, NULL);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT,
|
||||
m.pointer());
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
static std::vector<std::array<float, 16> >
|
||||
tmp_buf(stk_config->m_max_skinning_bones);
|
||||
g_joint_ptr = tmp_buf.data();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_TEXTURE_BUFFER, number << 6, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, 64, m.pointer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_BUFFER, g_skinning_tex);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, g_skinning_buf);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#ifndef USE_GLES2
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBufferStorage(GL_TEXTURE_BUFFER, number << 6, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 0, 64,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
memcpy(g_joint_ptr, m.pointer(), 64);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
g_joint_ptr = (std::array<float, 16>*)glMapBufferRange(
|
||||
GL_TEXTURE_BUFFER, 64, (number - 1) << 6,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_TEXTURE_BUFFER, number << 6, NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferSubData(GL_TEXTURE_BUFFER, 0, 64, m.pointer());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_BUFFER, g_skinning_tex);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, g_skinning_buf);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // resizeSkinning
|
||||
|
||||
@ -283,30 +287,35 @@ void initSkinning()
|
||||
static_assert(sizeof(std::array<float, 16>) == 64, "No padding");
|
||||
|
||||
int max_size = 0;
|
||||
#ifdef USE_GLES2
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
|
||||
|
||||
if (stk_config->m_max_skinning_bones > (unsigned)max_size)
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size);
|
||||
stk_config->m_max_skinning_bones = max_size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size);
|
||||
|
||||
if (stk_config->m_max_skinning_bones > (unsigned)max_size)
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size);
|
||||
stk_config->m_max_skinning_bones = max_size;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: %u"
|
||||
" (max bones) * 16 RGBA float texture",
|
||||
stk_config->m_max_skinning_bones);
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: %u"
|
||||
" (max bones) * 16 RGBA float texture",
|
||||
stk_config->m_max_skinning_bones);
|
||||
#else
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
|
||||
if (stk_config->m_max_skinning_bones << 6 > (unsigned)max_size)
|
||||
else
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size >> 6);
|
||||
stk_config->m_max_skinning_bones = max_size >> 6;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: TBO, "
|
||||
"max bones: %u", stk_config->m_max_skinning_bones);
|
||||
#ifndef USE_GLES2
|
||||
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size);
|
||||
if (stk_config->m_max_skinning_bones << 6 > (unsigned)max_size)
|
||||
{
|
||||
Log::warn("SharedGPUObjects", "Too many bones for skinning, max: %d",
|
||||
max_size >> 6);
|
||||
stk_config->m_max_skinning_bones = max_size >> 6;
|
||||
}
|
||||
Log::info("SharedGPUObjects", "Hardware Skinning enabled, method: TBO, "
|
||||
"max bones: %u", stk_config->m_max_skinning_bones);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Reserve 1 identity matrix for non-weighted vertices
|
||||
@ -314,7 +323,10 @@ void initSkinning()
|
||||
const irr::core::matrix4 m;
|
||||
glGenTextures(1, &g_skinning_tex);
|
||||
#ifndef USE_GLES2
|
||||
glGenBuffers(1, &g_skinning_buf);
|
||||
if (CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glGenBuffers(1, &g_skinning_buf);
|
||||
}
|
||||
#endif
|
||||
resizeSkinning(stk_config->m_max_skinning_bones);
|
||||
|
||||
@ -581,7 +593,8 @@ void destroy()
|
||||
SPTextureManager::destroy();
|
||||
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBBufferStorageUsable())
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
@ -1160,7 +1173,8 @@ void uploadSkinningMatrices()
|
||||
|
||||
unsigned buffer_offset = 0;
|
||||
#ifndef USE_GLES2
|
||||
if (!CVS->isARBBufferStorageUsable())
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
!CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, g_skinning_buf);
|
||||
g_joint_ptr = (std::array<float, 16>*)
|
||||
@ -1178,13 +1192,17 @@ void uploadSkinningMatrices()
|
||||
buffer_offset += g_skinning_mesh[i]->getTotalJoints();
|
||||
}
|
||||
|
||||
#ifdef USE_GLES2
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 4, buffer_offset, GL_RGBA,
|
||||
GL_FLOAT, g_joint_ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#else
|
||||
if (!CVS->isARBBufferStorageUsable())
|
||||
if (!CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, g_skinning_tex);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1, 4, buffer_offset, GL_RGBA,
|
||||
GL_FLOAT, g_joint_ptr);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
#ifndef USE_GLES2
|
||||
if (CVS->isARBTextureBufferObjectUsable() &&
|
||||
!CVS->isARBBufferStorageUsable())
|
||||
{
|
||||
glUnmapBuffer(GL_TEXTURE_BUFFER);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
|
@ -28,17 +28,37 @@
|
||||
|
||||
namespace SP
|
||||
{
|
||||
const std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
g_prefilled_names =
|
||||
{
|
||||
#ifdef USE_GLES2
|
||||
{ "skinning_tex", { 0, ST_NEAREST_CLAMPED } }
|
||||
#else
|
||||
{ "skinning_tex", { 0, ST_TEXTURE_BUFFER } }
|
||||
#endif
|
||||
};
|
||||
std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
SPShader::m_prefilled_names;
|
||||
bool SPShader::m_sp_shader_debug = false;
|
||||
|
||||
SPShader::SPShader(const std::string& name,
|
||||
const std::function<void(SPShader*)>& init_func,
|
||||
bool transparent_shader, int drawing_priority,
|
||||
bool use_alpha_channel, bool use_tangents,
|
||||
const std::array<bool, 6>& srgb)
|
||||
: m_name(name), m_init_function(init_func),
|
||||
m_drawing_priority(drawing_priority),
|
||||
m_transparent_shader(transparent_shader),
|
||||
m_use_alpha_channel(use_alpha_channel),
|
||||
m_use_tangents(use_tangents), m_srgb(srgb)
|
||||
{
|
||||
if (CVS->isARBTextureBufferObjectUsable())
|
||||
{
|
||||
#ifndef USE_GLES2
|
||||
m_prefilled_names["skinning_tex"] = std::make_pair<unsigned,
|
||||
SamplerType>(0, ST_TEXTURE_BUFFER);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
m_prefilled_names["skinning_tex"] = std::make_pair<unsigned,
|
||||
SamplerType>(0, ST_NEAREST_CLAMPED);
|
||||
}
|
||||
|
||||
memset(m_program, 0, 12);
|
||||
m_init_function(this);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void SPShader::addShaderFile(const std::string& name, GLint shader_type,
|
||||
RenderPass rp)
|
||||
@ -104,7 +124,7 @@ void SPShader::addAllTextures(RenderPass rp)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
// Built-in prefilled shaders first
|
||||
for (auto &p : g_prefilled_names)
|
||||
for (auto &p : m_prefilled_names)
|
||||
{
|
||||
const char* s = p.first.c_str();
|
||||
GLuint loc = glGetUniformLocation(m_program[rp], s);
|
||||
@ -175,8 +195,8 @@ void SPShader::bindPrefilledTextures(RenderPass rp) const
|
||||
for (auto& p : m_prefilled_samplers[rp])
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + std::get<0>(p));
|
||||
auto it = g_prefilled_names.find(std::get<1>(p));
|
||||
if (it != g_prefilled_names.end())
|
||||
auto it = m_prefilled_names.find(std::get<1>(p));
|
||||
if (it != m_prefilled_names.end())
|
||||
{
|
||||
glBindTexture(std::get<3>(p), sp_prefilled_tex[it->second.first]);
|
||||
glBindSampler(std::get<0>(p), getSampler(std::get<2>(p)));
|
||||
|
@ -113,22 +113,15 @@ private:
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
static bool m_sp_shader_debug;
|
||||
static std::map<std::string, std::pair<unsigned, SamplerType> >
|
||||
m_prefilled_names;
|
||||
// ------------------------------------------------------------------------
|
||||
SPShader(const std::string& name,
|
||||
const std::function<void(SPShader*)>& init_func,
|
||||
bool transparent_shader = false, int drawing_priority = 0,
|
||||
bool use_alpha_channel = false, bool use_tangents = false,
|
||||
const std::array<bool, 6>& srgb =
|
||||
{{ true, true, false, false, false, false }})
|
||||
: m_name(name), m_init_function(init_func),
|
||||
m_drawing_priority(drawing_priority),
|
||||
m_transparent_shader(transparent_shader),
|
||||
m_use_alpha_channel(use_alpha_channel),
|
||||
m_use_tangents(use_tangents), m_srgb(srgb)
|
||||
{
|
||||
memset(m_program, 0, 12);
|
||||
m_init_function(this);
|
||||
}
|
||||
{{ true, true, false, false, false, false }});
|
||||
// ------------------------------------------------------------------------
|
||||
~SPShader()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user