SuperTuxKart
Loading...
Searching...
No Matches
texture_shader.hpp
1// SuperTuxKart - a fun racing game with go-kart
2// Copyright (C) 2014-2015 SuperTuxKart-Team
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License
6// as published by the Free Software Foundation; either version 3
7// of the License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#ifndef SHADER_ONLY
19
20#ifndef HEADER_TEXTURE_SHADER_HPP
21#define HEADER_TEXTURE_SHADER_HPP
22
23#include "graphics/central_settings.hpp"
24#include "graphics/gl_headers.hpp"
25#include "graphics/shader.hpp"
26#include "utils/cpp2011.hpp"
27
28#include <assert.h>
29#include <functional>
30#include <vector>
31
32
33enum SamplerTypeNew
34{
35 ST_MIN,
36 ST_NEAREST_FILTERED = ST_MIN,
37 ST_TRILINEAR_ANISOTROPIC_FILTERED,
38 ST_TRILINEAR_CUBEMAP,
39 ST_BILINEAR_FILTERED,
40 ST_SHADOW_SAMPLER,
41 ST_TRILINEAR_CLAMPED_ARRAY2D,
42 ST_VOLUME_LINEAR_FILTERED,
43 ST_NEARED_CLAMPED_FILTERED,
44 ST_BILINEAR_CLAMPED_FILTERED,
45 ST_SEMI_TRILINEAR,
46#ifdef USE_GLES2
47 ST_MAX = ST_SEMI_TRILINEAR
48#else
49 ST_TEXTURE_BUFFER,
50 ST_MAX = ST_TEXTURE_BUFFER
51#endif
52}; // SamplerTypeNew
53
54// ============================================================================
61{
62public:
63 typedef std::function<void(GLuint, GLuint)> BindFunction;
64
65protected:
66 static void bindTextureNearest(GLuint tex_unit, GLuint tex_id);
67 static void bindTextureBilinear(GLuint texture_unit, GLuint tex_id);
68 static void bindTextureBilinearClamped(GLuint tex_unit, GLuint tex_id);
69 static void bindTextureNearestClamped(GLuint tex_unit, GLuint tex_id);
70 static void bindTextureTrilinearAnisotropic(GLuint tex_unit, GLuint tex_id);
71 static void bindTextureSemiTrilinear(GLuint tex_unit, GLuint tex_id);
72 static void bindCubemapTrilinear(GLuint tex_unit, GLuint tex_id);
73 static void bindTextureShadow(GLuint tex_unit, GLuint tex_id);
74 static void bindTrilinearClampedArrayTexture(GLuint tex_unit, GLuint tex_id);
75 static void bindTextureVolume(GLuint tex_unit, GLuint tex_id);
76 static void bindTextureBuffer(GLuint tex_unit, GLuint tex_id);
77
78 GLuint createSamplers(SamplerTypeNew sampler_type);
79private:
80
81 static GLuint createNearestSampler();
82 static GLuint createTrilinearSampler();
83 static GLuint createBilinearSampler();
84 static GLuint createShadowSampler();
85 static GLuint createTrilinearClampedArray();
86 static GLuint createBilinearClampedSampler();
87 static GLuint createSemiTrilinearSampler();
88protected:
89 static BindFunction m_all_bind_functions[];
90 std::vector<BindFunction> m_bind_functions;
91 static GLuint m_all_texture_types[];
92}; // TextureshaderBase
93
94// ========================================================================
100template<class C, int NUM_TEXTURES, typename...tp>
102 , public Shader<C, tp...>
103{
104
105private:
106
107 std::vector<GLuint> m_texture_units;
108 std::vector<GLenum> m_texture_type;
109 std::vector<GLenum> m_texture_location;
110
111public:
112 std::vector<GLuint> m_sampler_ids;
113
114 // A variadic template to assign texture names
115 // ===========================================
116private:
119 template<unsigned N, typename...Args>
121 {
122 static_assert(N == NUM_TEXTURES, "Wrong number of texture names");
123 } // assignTextureNamesImpl
124
125 // ------------------------------------------------------------------------
129 template<unsigned N, typename...Args>
130 void assignTextureNamesImpl(GLuint tex_unit, const char *name,
131 SamplerTypeNew sampler_type, Args...args)
132 {
133
134 m_sampler_ids.push_back(createSamplers(sampler_type));
135
136 assert(sampler_type >= ST_MIN && sampler_type <= ST_MAX);
137 m_texture_type.push_back(m_all_texture_types[sampler_type]);
138
139 GLuint location = this->getUniformLocation(name);
140 m_texture_location.push_back(location);
141 glUniform1i(location, tex_unit);
142 m_texture_units.push_back(tex_unit);
143
144 // Duplicated assert
145 assert(sampler_type >= ST_MIN && sampler_type <= ST_MAX);
146 m_bind_functions.push_back( m_all_bind_functions[sampler_type]);
147
148 assignTextureNamesImpl<N + 1>(args...);
149 } // assignTextureNamesImpl
150
151 // ------------------------------------------------------------------------
152public:
156 template<typename...Args>
157 void assignSamplerNames(Args...args)
158 {
159 this->use();
160 assignTextureNamesImpl<0>(args...);
161 glUseProgram(0);
162 } // AssignSamplerNames
163
164
165 // Variadic template implementation of setTextureUnits
166 // ===================================================
168 template<int N>
170 {
171 static_assert(N == NUM_TEXTURES, "Not enough texture set");
172 } // setTextureUnitsImpl
173
174 // ------------------------------------------------------------------------
177 template<int N, typename... TexIds>
178 void setTextureUnitsImpl(GLuint tex_id, TexIds... args)
179 {
180 if (CVS->isARBSamplerObjectsUsable())
181 {
182 glActiveTexture(GL_TEXTURE0 + m_texture_units[N]);
183 glBindTexture(m_texture_type[N], tex_id);
184 glBindSampler(m_texture_units[N], m_sampler_ids[N]);
185 }
186 else
187 {
188 m_bind_functions[N](m_texture_units[N], tex_id);
189 }
190 setTextureUnitsImpl<N + 1>(args...);
191 } // setTextureUnitsImpl
192
193 // ------------------------------------------------------------------------
194public:
197 template<typename... TexIds>
198 void setTextureUnits(TexIds... args)
199 {
200 setTextureUnitsImpl<0>(args...);
201 } // setTextureUnits
202
203
204 // ========================================================================
205 // Variadic template implementation of setTextureHandles.
206
210 template<int N>
212 {
213 static_assert(N == NUM_TEXTURES, "Not enough handles set");
214 } // setTextureHandlesImpl
215
216 // ------------------------------------------------------------------------
222 template<int N, typename... HandlesId>
223 void setTextureHandlesImpl(uint64_t handle, HandlesId... args)
224 {
225#if !defined(USE_GLES2)
226 if (handle)
227 glUniformHandleui64ARB(m_texture_location[N], handle);
228#endif
229 setTextureHandlesImpl<N + 1>(args...);
230 } // setTextureHandlesImpl
231
232 // ------------------------------------------------------------------------
233public:
237 template<typename... HandlesId>
238 void setTextureHandles(HandlesId... ids)
239 {
240 setTextureHandlesImpl<0>(ids...);
241 } // SetTextureHandles
242
243public:
244 // ------------------------------------------------------------------------
248 {
249 for (unsigned i = 0; i < m_sampler_ids.size(); i++)
250 glDeleteSamplers(1, &m_sampler_ids[i]);
251 } // ~TextureShader
252
253}; // class TextureShader
254
255#endif
256
257#endif // SHADER_ONLY
void use()
Activates the shader calling glUseProgram.
Definition: shader.hpp:103
The main templated base class for all shaders that do not use textures.
Definition: shader.hpp:119
A simple non-templated base class for a shader that uses textures.
Definition: texture_shader.hpp:61
Class C needs to be the newly declared shaders class (necessary for the instance template).
Definition: texture_shader.hpp:103
void assignSamplerNames(Args...args)
The protected interface for setting sampler names - it is only called from instances.
Definition: texture_shader.hpp:157
void setTextureHandlesImpl()
End of recursion, just checks at compile time if number of arguments is correct.
Definition: texture_shader.hpp:211
void setTextureHandles(HandlesId... ids)
The protected interface.
Definition: texture_shader.hpp:238
void setTextureHandlesImpl(uint64_t handle, HandlesId... args)
Recursive implementation of setTextureHandles.
Definition: texture_shader.hpp:223
void setTextureUnitsImpl(GLuint tex_id, TexIds... args)
The recursive implementation.
Definition: texture_shader.hpp:178
void assignTextureNamesImpl(GLuint tex_unit, const char *name, SamplerTypeNew sampler_type, Args...args)
Recursive implementation, peeling the texture unit and name off the list of arguments.
Definition: texture_shader.hpp:130
void setTextureUnitsImpl()
End of recursion, just check if number of arguments is correct.
Definition: texture_shader.hpp:169
void setTextureUnits(TexIds... args)
Public implementation of setTextureUnits.
Definition: texture_shader.hpp:198
~TextureShader()
Destructor which frees al lsampler ids.
Definition: texture_shader.hpp:247
void assignTextureNamesImpl()
End of recursive variadic template AssigTextureNames.
Definition: texture_shader.hpp:120