Start to re-implement TextureRead without variadic templates for
BindTexture and CreateSampler. VERY MESSY ATM, work in progress.
This commit is contained in:
parent
0ace0aeb5b
commit
dfe4f09ed5
@ -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/*")
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
159
src/graphics/texture_read.cpp
Normal file
159
src/graphics/texture_read.cpp
Normal 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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user