]> git.tdb.fi Git - libs/gl.git/blob - source/backends/opengl/sampler_backend.cpp
Add support for padding in vertex formats
[libs/gl.git] / source / backends / opengl / sampler_backend.cpp
1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_sampler_objects.h>
3 #include <msp/gl/extensions/arb_shadow.h>
4 #include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
5 #include <msp/gl/extensions/ext_texture3d.h>
6 #include <msp/gl/extensions/khr_debug.h>
7 #include "gl.h"
8 #include "sampler.h"
9 #include "sampler_backend.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 OpenGLSampler::OpenGLSampler()
17 {
18         static Require _req(ARB_sampler_objects);
19         static Require _req2(EXT_texture3D);
20         static Require _req3(ARB_shadow);
21
22         if(ARB_direct_state_access)
23                 glCreateSamplers(1, &id);
24         else
25                 glGenSamplers(1, &id);
26 }
27
28 OpenGLSampler::OpenGLSampler(OpenGLSampler &&other):
29         id(other.id)
30 {
31         other.id = 0;
32 }
33
34 OpenGLSampler::~OpenGLSampler()
35 {
36         if(id)
37                 glDeleteSamplers(1, &id);
38 }
39
40 bool OpenGLSampler::check_anisotropic(bool require)
41 {
42         if(require)
43                 static Require _req(EXT_texture_filter_anisotropic);
44         return EXT_texture_filter_anisotropic;
45 }
46
47 void OpenGLSampler::update(unsigned mask) const
48 {
49         const Sampler *self = static_cast<const Sampler *>(this);
50         if(mask&Sampler::MIN_FILTER)
51                 glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, get_gl_filter(self->min_filter));
52         if(mask&Sampler::MAG_FILTER)
53                 glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, get_gl_filter(self->mag_filter));
54         if(mask&Sampler::MAX_ANISOTROPY)
55                 glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, self->max_anisotropy);
56         if(mask&Sampler::WRAP_S)
57                 glSamplerParameteri(id, GL_TEXTURE_WRAP_S, get_gl_wrap(self->wrap_s));
58         if(mask&Sampler::WRAP_T)
59                 glSamplerParameteri(id, GL_TEXTURE_WRAP_T, get_gl_wrap(self->wrap_t));
60         if(mask&Sampler::WRAP_R)
61                 glSamplerParameteri(id, GL_TEXTURE_WRAP_R, get_gl_wrap(self->wrap_r));
62         if(mask&Sampler::BORDER_COLOR)
63                 glSamplerParameterfv(id, GL_TEXTURE_BORDER_COLOR, &self->border_color.r);
64         if(mask&Sampler::COMPARE)
65         {
66                 glSamplerParameteri(id, GL_TEXTURE_COMPARE_MODE, (self->compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
67                 if(self->compare)
68                         glSamplerParameteri(id, GL_TEXTURE_COMPARE_FUNC, get_gl_predicate(self->cmp_func));
69         }
70 }
71
72 void OpenGLSampler::set_debug_name(const string &name)
73 {
74 #ifdef DEBUG
75         if(KHR_debug)
76                 glObjectLabel(GL_SAMPLER, id, name.size(), name.c_str());
77 #else
78         (void)name;
79 #endif
80 }
81
82
83 unsigned get_gl_filter(unsigned filter)
84 {
85         switch(filter)
86         {
87         case NEAREST: return GL_NEAREST;
88         case LINEAR: return GL_LINEAR;
89         case NEAREST_MIPMAP_NEAREST: return GL_NEAREST_MIPMAP_NEAREST;
90         case NEAREST_MIPMAP_LINEAR: return GL_NEAREST_MIPMAP_LINEAR;
91         case LINEAR_MIPMAP_NEAREST: return GL_LINEAR_MIPMAP_NEAREST;
92         case LINEAR_MIPMAP_LINEAR: return GL_LINEAR_MIPMAP_LINEAR;
93         default: throw invalid_argument("get_gl_filter");
94         }
95 }
96
97 unsigned get_gl_wrap(unsigned wrap)
98 {
99         switch(wrap)
100         {
101         case REPEAT: return GL_REPEAT;
102         case CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE;
103         case CLAMP_TO_BORDER: return GL_CLAMP_TO_BORDER;
104         case MIRRORED_REPEAT: return GL_MIRRORED_REPEAT;
105         default: throw invalid_argument("get_gl_wrap");
106         }
107 }
108
109 } // namespace GL
110 } // namespace Msp