Panda3D
samplerState.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file samplerState.cxx
10  * @author rdb
11  * @date 2014-12-09
12  */
13 
14 #include "samplerState.h"
15 #include "indent.h"
16 #include "datagram.h"
17 #include "datagramIterator.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
20 #include "samplerContext.h"
22 
23 using std::string;
24 
25 TypeHandle SamplerState::_type_handle;
26 SamplerState SamplerState::_default;
27 
29 ("texture-minfilter", SamplerState::FT_linear,
30  PRC_DESC("This specifies the default minfilter that is applied to a texture "
31  "in the absence of a specific minfilter setting. Normally this "
32  "is either 'linear' to disable mipmapping by default, or "
33  "'mipmap', to enable trilinear mipmapping by default. This "
34  "does not apply to depth textures. Note if this variable is "
35  "changed at runtime, you may need to reload textures explicitly "
36  "in order to change their visible properties."));
37 
39 ("texture-magfilter", SamplerState::FT_linear,
40  PRC_DESC("This specifies the default magfilter that is applied to a texture "
41  "in the absence of a specific magfilter setting. Normally this "
42  "is 'linear' (since mipmapping does not apply to magfilters). This "
43  "does not apply to depth textures. Note if this variable is "
44  "changed at runtime, you may need to reload textures explicitly "
45  "in order to change their visible properties."));
46 
47 ConfigVariableInt texture_anisotropic_degree
48 ("texture-anisotropic-degree", 1,
49  PRC_DESC("This specifies the default anisotropic degree that is applied "
50  "to a texture in the absence of a particular anisotropic degree "
51  "setting (that is, a texture for which the anisotropic degree "
52  "is 0, meaning the default setting). It should be 1 to disable "
53  "anisotropic filtering, or a higher number to enable it. "
54  "Note if this variable is "
55  "changed at runtime, you may need to reload textures explicitly "
56  "in order to change their visible properties."));
57 
58 /**
59  * Returns the filter mode of the texture for minification, with special
60  * treatment for FT_default. This will normally not return FT_default, unless
61  * there is an error in the config file.
62  */
63 SamplerState::FilterType SamplerState::
65  if (_minfilter != FT_default) {
66  return _minfilter;
67  }
68  return texture_minfilter;
69 }
70 
71 /**
72  * Returns the filter mode of the texture for magnification, with special
73  * treatment for FT_default. This will normally not return FT_default, unless
74  * there is an error in the config file.
75  */
76 SamplerState::FilterType SamplerState::
78  if (_magfilter != FT_default) {
79  return _magfilter;
80  }
81  return texture_magfilter;
82 }
83 
84 /**
85  * Returns the indicated FilterType converted to a string word.
86  */
88 format_filter_type(FilterType ft) {
89  switch (ft) {
90  case FT_nearest:
91  return "nearest";
92  case FT_linear:
93  return "linear";
94 
95  case FT_nearest_mipmap_nearest:
96  return "nearest_mipmap_nearest";
97  case FT_linear_mipmap_nearest:
98  return "linear_mipmap_nearest";
99  case FT_nearest_mipmap_linear:
100  return "nearest_mipmap_linear";
101  case FT_linear_mipmap_linear:
102  return "linear_mipmap_linear";
103 
104  case FT_shadow:
105  return "shadow";
106 
107  case FT_default:
108  return "default";
109 
110  case FT_invalid:
111  return "invalid";
112  }
113  return "**invalid**";
114 }
115 
116 /**
117  * Returns the FilterType value associated with the given string
118  * representation, or FT_invalid if the string does not match any known
119  * FilterType value.
120  */
121 SamplerState::FilterType SamplerState::
122 string_filter_type(const string &string) {
123  if (cmp_nocase_uh(string, "nearest") == 0) {
124  return FT_nearest;
125  } else if (cmp_nocase_uh(string, "linear") == 0) {
126  return FT_linear;
127  } else if (cmp_nocase_uh(string, "nearest_mipmap_nearest") == 0) {
128  return FT_nearest_mipmap_nearest;
129  } else if (cmp_nocase_uh(string, "linear_mipmap_nearest") == 0) {
130  return FT_linear_mipmap_nearest;
131  } else if (cmp_nocase_uh(string, "nearest_mipmap_linear") == 0) {
132  return FT_nearest_mipmap_linear;
133  } else if (cmp_nocase_uh(string, "linear_mipmap_linear") == 0) {
134  return FT_linear_mipmap_linear;
135  } else if (cmp_nocase_uh(string, "mipmap") == 0) {
136  return FT_linear_mipmap_linear;
137  } else if (cmp_nocase_uh(string, "shadow") == 0) {
138  return FT_shadow;
139  } else if (cmp_nocase_uh(string, "default") == 0) {
140  return FT_default;
141  } else {
142  return FT_invalid;
143  }
144 }
145 
146 /**
147  * Returns the indicated WrapMode converted to a string word.
148  */
150 format_wrap_mode(WrapMode wm) {
151  switch (wm) {
152  case WM_clamp:
153  return "clamp";
154  case WM_repeat:
155  return "repeat";
156  case WM_mirror:
157  return "mirror";
158  case WM_mirror_once:
159  return "mirror_once";
160  case WM_border_color:
161  return "border_color";
162 
163  case WM_invalid:
164  return "invalid";
165  }
166 
167  return "**invalid**";
168 }
169 
170 /**
171  * Returns the WrapMode value associated with the given string representation,
172  * or WM_invalid if the string does not match any known WrapMode value.
173  */
174 SamplerState::WrapMode SamplerState::
175 string_wrap_mode(const string &string) {
176  if (cmp_nocase_uh(string, "repeat") == 0 ||
177  cmp_nocase_uh(string, "wrap") == 0) {
178  return WM_repeat;
179  } else if (cmp_nocase_uh(string, "clamp") == 0) {
180  return WM_clamp;
181  } else if (cmp_nocase_uh(string, "mirror") == 0 ||
182  cmp_nocase_uh(string, "mirrored_repeat") == 0) {
183  return WM_mirror;
184  } else if (cmp_nocase_uh(string, "mirror_once") == 0) {
185  return WM_mirror_once;
186  } else if (cmp_nocase_uh(string, "border_color") == 0 ||
187  cmp_nocase_uh(string, "border") == 0) {
188  return WM_border_color;
189  } else {
190  return WM_invalid;
191  }
192 }
193 
194 /**
195  * Indicates that the sampler should be enqueued to be prepared in the
196  * indicated prepared_objects at the beginning of the next frame.
197  *
198  * Use this function instead of prepare_now() to preload samplers from a user
199  * interface standpoint.
200  */
202 prepare(PreparedGraphicsObjects *prepared_objects) const {
203  prepared_objects->enqueue_sampler(*this);
204 }
205 
206 /**
207  * Returns true if the sampler has already been prepared or enqueued for
208  * preparation on the indicated GSG, false otherwise.
209  */
211 is_prepared(PreparedGraphicsObjects *prepared_objects) const {
212  return prepared_objects->is_sampler_queued(*this)
213  || prepared_objects->is_sampler_prepared(*this);
214 }
215 
216 /**
217  * Frees the texture context only on the indicated object, if it exists there.
218  * Returns true if it was released, false if it had not been prepared.
219  */
221 release(PreparedGraphicsObjects *prepared_objects) const {
222  prepared_objects->release_sampler(*this);
223 }
224 
225 /**
226  * Creates a context for the sampler on the particular GSG, if it does not
227  * already exist. Returns the new (or old) SamplerContext. This assumes that
228  * the GraphicsStateGuardian is the currently active rendering context and
229  * that it is ready to accept new textures. If this is not necessarily the
230  * case, you should use prepare() instead.
231  *
232  * Normally, this is not called directly except by the GraphicsStateGuardian;
233  * a sampler does not need to be explicitly prepared by the user before it may
234  * be rendered.
235  */
237 prepare_now(PreparedGraphicsObjects *prepared_objects,
238  GraphicsStateGuardianBase *gsg) const {
239  return prepared_objects->prepare_sampler_now(*this, gsg);
240 }
241 
242 /**
243  * Returns a number less than zero if this sampler sorts before the other one,
244  * greater than zero if it sorts after, or zero if they are equivalent. The
245  * sorting order is arbitrary and largely meaningless, except to differentiate
246  * different sampler states.
247  */
249 compare_to(const SamplerState &other) const {
250  if (_wrap_u != other._wrap_u) {
251  return (_wrap_u < other._wrap_u) ? -1 : 1;
252  }
253  if (_wrap_v != other._wrap_v) {
254  return (_wrap_v < other._wrap_v) ? -1 : 1;
255  }
256  if (_wrap_w != other._wrap_w) {
257  return (_wrap_w < other._wrap_w) ? -1 : 1;
258  }
259  if (_minfilter != other._minfilter) {
260  return (_minfilter < other._minfilter) ? -1 : 1;
261  }
262  if (_magfilter != other._magfilter) {
263  return (_magfilter < other._magfilter) ? -1 : 1;
264  }
265  if (_anisotropic_degree != other._anisotropic_degree) {
266  return (_anisotropic_degree < other._anisotropic_degree) ? -1 : 1;
267  }
268  if (_border_color != other._border_color) {
269  return (_border_color < other._border_color) ? -1 : 1;
270  }
271  if (_min_lod != other._min_lod) {
272  return (_min_lod < other._min_lod) ? -1 : 1;
273  }
274  if (_max_lod != other._max_lod) {
275  return (_max_lod < other._max_lod) ? -1 : 1;
276  }
277  if (_lod_bias != other._lod_bias) {
278  return (_lod_bias < other._lod_bias) ? -1 : 1;
279  }
280 
281  return 0;
282 }
283 
284 /**
285  *
286  */
287 void SamplerState::
288 output(std::ostream &out) const {
289  out
290  << "sampler"
291  << " wrap(u=" << _wrap_u << ", v=" << _wrap_v << ", w=" << _wrap_w
292  << ", border=" << _border_color << ")"
293  << " filter(min=" << _minfilter << ", mag=" << _magfilter
294  << ", aniso=" << _anisotropic_degree << ")"
295  << " lod(min=" << _min_lod << ", max=" << _max_lod
296  << ", bias=" << _lod_bias << ")";
297 }
298 
299 /**
300  *
301  */
302 void SamplerState::
303 write(std::ostream &out, int indent_level) const {
304  indent(out, indent_level) << "SamplerState\n";
305  indent(out, indent_level) << " wrap_u = " << _wrap_u << "\n";
306  indent(out, indent_level) << " wrap_v = " << _wrap_v << "\n";
307  indent(out, indent_level) << " wrap_w = " << _wrap_w << "\n";
308  indent(out, indent_level) << " minfilter = " << _minfilter << "\n";
309  indent(out, indent_level) << " magfilter = " << _magfilter << "\n";
310  indent(out, indent_level) << " anisotropic_degree = " << _anisotropic_degree << "\n";
311  indent(out, indent_level) << " border_color = " << _border_color << "\n";
312  indent(out, indent_level) << " min_lod = " << _min_lod << "\n";
313  indent(out, indent_level) << " max_lod = " << _max_lod << "\n";
314  indent(out, indent_level) << " lod_bias = " << _lod_bias << "\n";
315 }
316 
317 /**
318  * Encodes the sampler state into a datagram.
319  */
321 write_datagram(Datagram &me) const {
322  me.add_uint8(_wrap_u);
323  me.add_uint8(_wrap_v);
324  me.add_uint8(_wrap_w);
325  me.add_uint8(_minfilter);
326  me.add_uint8(_magfilter);
327  me.add_int16(_anisotropic_degree);
328  _border_color.write_datagram(me);
329  me.add_stdfloat(_min_lod);
330  me.add_stdfloat(_max_lod);
331  me.add_stdfloat(_lod_bias);
332 }
333 
334 /**
335  * Reads the sampler state from the datagram that has been previously written
336  * using write_datagram.
337  */
339 read_datagram(DatagramIterator &scan, BamReader *manager) {
340  _wrap_u = (WrapMode)scan.get_uint8();
341  _wrap_v = (WrapMode)scan.get_uint8();
342  _wrap_w = (WrapMode)scan.get_uint8();
343  _minfilter = (FilterType)scan.get_uint8();
344  _magfilter = (FilterType)scan.get_uint8();
345  _anisotropic_degree = scan.get_int16();
346  _border_color.read_datagram(scan);
347 
348  if (manager->get_file_minor_ver() >= 36) {
349  // These were added with the introduction of SamplerState. Since
350  // Texture::do_fillin_body calls this, we still have to preserve backward
351  // compatibility here.
352  _min_lod = scan.get_stdfloat();
353  _max_lod = scan.get_stdfloat();
354  _lod_bias = scan.get_stdfloat();
355  } else {
356  _min_lod = -1000;
357  _max_lod = 1000;
358  _lod_bias = 0;
359  }
360 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
This class specializes ConfigVariable as an enumerated type.
This is a convenience class to specialize ConfigVariable as an integer type.
A class to retrieve the individual data elements previously stored in a Datagram.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
int16_t get_int16()
Extracts a signed 16-bit integer.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_int16(int16_t value)
Adds a signed 16-bit integer to the datagram.
Definition: datagram.I:58
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
Definition: datagram.I:50
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:133
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A table of objects that are saved within the graphics context for reference by handle later.
void release_sampler(SamplerContext *sc)
Indicates that a sampler context, created by a previous call to prepare_sampler(),...
void enqueue_sampler(const SamplerState &sampler)
Indicates that a sampler would like to be put on the list to be prepared when the GSG is next ready t...
SamplerContext * prepare_sampler_now(const SamplerState &sampler, GraphicsStateGuardianBase *gsg)
Immediately creates a new SamplerContext for the indicated sampler and returns it.
bool is_sampler_prepared(const SamplerState &sampler) const
Returns true if the sampler has been prepared on this GSG, false otherwise.
bool is_sampler_queued(const SamplerState &sampler) const
Returns true if the sampler has been queued on this GSG, false otherwise.
This is a special class object that holds a handle to the sampler state object given by the graphics ...
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
void prepare(PreparedGraphicsObjects *prepared_objects) const
Indicates that the sampler should be enqueued to be prepared in the indicated prepared_objects at the...
static FilterType string_filter_type(const std::string &str)
Returns the FilterType value associated with the given string representation, or FT_invalid if the st...
void write_datagram(Datagram &destination) const
Encodes the sampler state into a datagram.
void release(PreparedGraphicsObjects *prepared_objects) const
Frees the texture context only on the indicated object, if it exists there.
void read_datagram(DatagramIterator &source, BamReader *manager)
Reads the sampler state from the datagram that has been previously written using write_datagram.
get_effective_magfilter
Returns the filter mode of the texture for magnification, with special treatment for FT_default.
Definition: samplerState.h:118
static std::string format_filter_type(FilterType ft)
Returns the indicated FilterType converted to a string word.
SamplerContext * prepare_now(PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg) const
Creates a context for the sampler on the particular GSG, if it does not already exist.
int compare_to(const SamplerState &other) const
Returns a number less than zero if this sampler sorts before the other one, greater than zero if it s...
get_effective_minfilter
Returns the filter mode of the texture for minification, with special treatment for FT_default.
Definition: samplerState.h:117
static WrapMode string_wrap_mode(const std::string &str)
Returns the WrapMode value associated with the given string representation, or WM_invalid if the stri...
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const
Returns true if the sampler has already been prepared or enqueued for preparation on the indicated GS...
static std::string format_wrap_mode(WrapMode wm)
Returns the indicated WrapMode converted to a string word.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.