Start to re-implement TextureRead without variadic templates for

BindTexture and CreateSampler. VERY MESSY ATM, work in progress.
This commit is contained in:
hiker 2015-05-06 16:51:54 +10:00
parent 0ace0aeb5b
commit dfe4f09ed5
5 changed files with 378 additions and 6 deletions

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -52,8 +52,8 @@ public:
*/
class SimpleParticleRender : public Shader<SimpleParticleRender, video::SColorf,
video::SColorf>,
public TextureRead<Trilinear_Anisotropic_Filtered,
Nearest_Filtered>
public TextureReadNew<ST_TRILINEAR_ANISOTROPIC_FILTERED,
ST_NEAREST_FILTERED>
{
public:
SimpleParticleRender()
@ -64,7 +64,8 @@ public:
GL_FRAGMENT_SHADER, "particle.frag");
assignUniforms("color_from", "color_to");
assignSamplerNames(m_program, 0, "tex", 1, "dtex");
assignSamplerNames(m_program, 0, "tex", ST_TRILINEAR_ANISOTROPIC_FILTERED,
1, "dtex", ST_NEAREST_FILTERED);
} // SimpleParticleRender
}; // SimpleParticleRender

View File

@ -531,7 +531,7 @@ void setTextureSampler(GLenum tp, GLuint texunit, GLuint tid, GLuint sid)
}
GLuint createNearestSampler()
GLuint XXXcreateNearestSampler()
{
#ifdef GL_VERSION_3_3
unsigned id;
@ -631,7 +631,7 @@ void BindTextureSemiTrilinear(GLuint TU, GLuint tex)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
}
GLuint createTrilinearSampler()
GLuint XXXcreateTrilinearSampler()
{
#ifdef GL_VERSION_3_3
unsigned id;

View File

@ -0,0 +1,159 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
// (C) 2015 Joerg Henrichs
//
// 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/texture_read.hpp"
#include "config/user_config.hpp"
TextureReadBaseNew::BindFunction TextureReadBaseNew::m_all_bind_functions[] =
{ &bindTextureNearest,
&bindTextureTrilinearAnisotropic };
GLuint TextureReadBaseNew::m_all_texture_types[] = { GL_TEXTURE_2D, GL_TEXTURE_2D };
// ----------------------------------------------------------------------------
GLuint TextureReadBaseNew::createSamplers(SamplerTypeNew sampler_type)
{
switch (sampler_type)
{
case ST_NEAREST_FILTERED:
return createNearestSampler();
case ST_TRILINEAR_ANISOTROPIC_FILTERED:
return createTrilinearSampler();
default:
assert(false);
} // switch
} // createSamplers
// ----------------------------------------------------------------------------
void bindTextureNearest(GLuint texture_unit, GLuint tex)
{
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureNearest
// ----------------------------------------------------------------------------
void bindTextureTrilinearAnisotropic(GLuint TU, GLuint tex)
{
glActiveTexture(GL_TEXTURE0 + TU);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
} // bindTextureTrilinearAnisotropic
// ----------------------------------------------------------------------------
GLuint createNearestSampler()
{
#ifdef GL_VERSION_3_3
unsigned id;
glGenSamplers(1, &id);
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
return id;
#endif
} // createNearestSampler
// ----------------------------------------------------------------------------
void bindTextureNearesClamped(GLuint texture_unit,
GLuint tex_id)
{
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureNearesClamped
// ----------------------------------------------------------------------------
void bindTextureBilinear(GLuint texture_unit, GLuint tex)
{
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureBilinear
// ----------------------------------------------------------------------------
void bindTextureBilinearClamped(GLuint TU, GLuint tex)
{
glActiveTexture(GL_TEXTURE0 + TU);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureBilinearClamped
// ----------------------------------------------------------------------------
void bindTextureSemiTrilinear(GLuint TU, GLuint tex)
{
glActiveTexture(GL_TEXTURE0 + TU);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
} // bindTextureSemiTrilinear
// ----------------------------------------------------------------------------
GLuint createTrilinearSampler()
{
#ifdef GL_VERSION_3_3
unsigned id;
glGenSamplers(1, &id);
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_REPEAT);
int aniso = UserConfigParams::m_anisotropic;
if (aniso == 0) aniso = 1;
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)aniso);
return id;
#endif
} // createTrilinearSampler
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

View File

@ -20,6 +20,218 @@
#include "shaders_util.hpp"
void bindTextureNearest(unsigned TU, unsigned tid);
GLuint createNearestSampler();
void bindTextureTrilinearAnisotropic(unsigned, unsigned);
GLuint createTrilinearSampler();
void bindTextureNearesClamped(GLuint texture_unit, GLuint tex);
enum SamplerTypeNew {
ST_NEAREST_FILTERED,
ST_TRILINEAR_ANISOTROPIC_FILTERED,
ST_SEMI_TRILINEAR,
ST_BILINEAR_FILTERED,
ST_BILINEAR_CLAMPED_FILTERED,
ST_NEARED_CLAMPED_FILTERED,
ST_SHADOW_SAMPLER,
ST_VOLUME_LINEAR_FILTERED,
ST_TRILINEAR_CUBEMAP,
ST_TRILINEAR_CLAMPED_ARRAY2D,
};
class TextureReadBaseNew
{
protected:
private:
typedef void(*BindFunction)(unsigned, unsigned);
protected:
static BindFunction m_all_bind_functions[2];
std::vector<BindFunction> m_bind_functions;
static GLuint m_all_texture_types[];
GLuint createSamplers(SamplerTypeNew);
}; // TextureReadBaseNew
// ============================================================================
template<SamplerTypeNew...tp>
class TextureReadNew : public TextureReadBaseNew
{
private:
static void bindTextureNearest(unsigned TU, unsigned tid);
// static void bindTextureTrilinearAnisotropic(unsigned , unsigned );
//typedef void(TextureReadBaseNew::*BindFunction)(unsigned, unsigned);
//static void(*)(unsigned, unsigned) m_all_bind_functions[2];
// std::vector<BindFunction> m_bind_functions;
std::vector<GLuint> m_texture_units;
std::vector<GLenum> m_texture_type;
std::vector<GLenum> m_texture_location;
public:
std::vector<GLuint> m_sampler_ids;
// A variadic template to assign texture names
// ===========================================
private:
/** End of recursive variadic template AssigTextureNames. It just
* checks if the number of arguments is correct.*/
template<unsigned N, typename...Args>
void assignTextureNamesImpl(GLuint)
{
static_assert(N == sizeof...(tp), "Wrong number of texture name");
} // assignTextureNamesImpl
// ------------------------------------------------------------------------
/** Recursive implementation, peeling the texture unit and name off the
* list of arguments.
*/
template<unsigned N, typename...Args>
void assignTextureNamesImpl(GLuint program, GLuint tex_unit,
const char *name, SamplerTypeNew sampler_type,
Args...args)
{
m_sampler_ids.push_back(createSamplers(sampler_type));
m_texture_type.push_back(m_all_texture_types[sampler_type]);
GLuint location = glGetUniformLocation(program, name);
m_texture_location.push_back(location);
glUniform1i(location, tex_unit);
m_texture_units.push_back(tex_unit);
m_bind_functions.push_back( m_all_bind_functions[sampler_type]);
assignTextureNamesImpl<N + 1>(program, args...);
} // assignTextureNamesImpl
// ------------------------------------------------------------------------
public:
/** The protected interface for setting sampler names - it is only called
* from instances.
*/
template<typename...Args>
void assignSamplerNames(GLuint program, Args...args)
{
glUseProgram(program);
assignTextureNamesImpl<0>(program, args...);
glUseProgram(0);
} // AssignSamplerNames
// Variadic template implementation of setTextureUnits
// ===================================================
/** End of recursion, just check if number of arguments is correct. */
template<int N>
void setTextureUnitsImpl()
{
static_assert(N == sizeof...(tp), "Not enough texture set");
} // setTextureUnitsImpl
// ------------------------------------------------------------------------
/** The recursive implementation.
*/
template<int N, typename... TexIds>
void setTextureUnitsImpl(GLuint texid, TexIds... args)
{
if (getGLSLVersion() >= 330)
{
setTextureSampler(m_texture_type[N], m_texture_units[N], texid,
m_sampler_ids[N]);
}
else
{
m_bind_functions[N](m_texture_units[N], texid);
}
setTextureUnitsImpl<N + 1>(args...);
} // setTextureUnitsImpl
// ------------------------------------------------------------------------
public:
/** Public implementation of setTextureUnits.
*/
template<typename... TexIds>
void setTextureUnits(TexIds... args)
{
setTextureUnitsImpl<0>(args...);
} // setTextureUnits
// ========================================================================
// Variadic template implementation of setTextureHandles.
/** End of recursion, just checks at compile time if number of arguments
* is correct.
* \param N number of arguments. */
template<int N>
void setTextureHandlesImpl()
{
static_assert(N == sizeof...(tp), "Not enough handle set");
} // setTextureHandlesImpl
// ------------------------------------------------------------------------
/** Recursive implementation of setTextureHandles.
* \param N The number of the current argument in the recursion (or the
* recursion depth).
* \param handle The texture handle to set.
*/
template<int N, typename... HandlesId>
void setTextureHandlesImpl(uint64_t handle, HandlesId... args)
{
if (handle)
glUniformHandleui64ARB(m_texture_location[N], handle);
setTextureHandlesImpl<N + 1>(args...);
} // setTextureHandlesImpl
// ------------------------------------------------------------------------
public:
/** The protected interface.
* \param ids The ids of all texture handls.
*/
template<typename... HandlesId>
void setTextureHandles(HandlesId... ids)
{
setTextureHandlesImpl<0>(ids...);
} // SetTextureHandles
public:
// ------------------------------------------------------------------------
/** Destructor which frees al lsampler ids.
*/
~TextureReadNew()
{
for (unsigned i = 0; i < m_sampler_ids.size(); i++)
glDeleteSamplers(1, &m_sampler_ids[i]);
} // ~TextureReadNew
}; // class TextureReadNew
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
template<SamplerType...tp>
class TextureRead
{