]> git.tdb.fi Git - libs/gl.git/blob - source/backends/opengl/texture_backend.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / backends / opengl / texture_backend.cpp
1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_texture_swizzle.h>
3 #include <msp/gl/extensions/ext_framebuffer_object.h>
4 #include <msp/gl/extensions/khr_debug.h>
5 #include "device.h"
6 #include "gl.h"
7 #include "error.h"
8 #include "texture.h"
9 #include "texture_backend.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 OpenGLTexture::OpenGLTexture(unsigned t):
17         target(t)
18 {
19         static bool alignment_init = false;
20         if(!alignment_init)
21         {
22                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
23                 alignment_init = true;
24         }
25 }
26
27 OpenGLTexture::OpenGLTexture(OpenGLTexture &&other):
28         id(other.id),
29         target(other.target),
30         debug_name(move(other.debug_name))
31 {
32         other.id = 0;
33 }
34
35 OpenGLTexture::~OpenGLTexture()
36 {
37         if(this==Device::get_current().get_state().scratch_texture)
38                 unbind_scratch();
39         if(id)
40                 glDeleteTextures(1, &id);
41 }
42
43 void OpenGLTexture::create()
44 {
45         if(id)
46                 throw invalid_operation("OpenGLTexture::create");
47         if(ARB_direct_state_access)
48                 glCreateTextures(target, 1, &id);
49         else
50                 glGenTextures(1, &id);
51
52 #ifdef DEBUG
53         if(!debug_name.empty() && KHR_debug)
54                 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
55 #endif
56 }
57
58 void OpenGLTexture::require_swizzle()
59 {
60         static Require _req(ARB_texture_swizzle);
61 }
62
63 void OpenGLTexture::apply_swizzle()
64 {
65         ComponentSwizzle swizzle = static_cast<const Texture *>(this)->swizzle;
66         if(swizzle==NO_SWIZZLE)
67                 return;
68
69         const int *swizzle_order = get_gl_swizzle(swizzle);
70         if(get_backend_api()==OPENGL_ES)
71         {
72                 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_order[0]);
73                 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_order[1]);
74                 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_order[2]);
75                 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_order[3]);
76         }
77         else
78         {
79                 if(ARB_direct_state_access)
80                         glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_order);
81                 else
82                         glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_order);
83         }
84 }
85
86 void OpenGLTexture::set_parameter_i(unsigned param, int value) const
87 {
88         if(ARB_direct_state_access)
89                 glTextureParameteri(id, param, value);
90         else
91                 glTexParameteri(target, param, value);
92 }
93
94 void OpenGLTexture::generate_mipmap()
95 {
96         // glGenerateMipmap is defined here
97         static Require _req(EXT_framebuffer_object);
98
99         if(ARB_direct_state_access)
100                 glGenerateTextureMipmap(id);
101         else
102         {
103                 bind_scratch();
104                 glGenerateMipmap(target);
105         }
106 }
107
108 void OpenGLTexture::set_debug_name(const string &name)
109 {
110 #ifdef DEBUG
111         debug_name = name;
112         if(id && KHR_debug)
113                 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
114 #else
115         (void)name;
116 #endif
117 }
118
119 void OpenGLTexture::bind_scratch()
120 {
121         const OpenGLTexture *&scratch_binding = Device::get_current().get_state().scratch_texture;
122         if(!scratch_binding)
123                 glActiveTexture(GL_TEXTURE0);
124         if(scratch_binding!=this)
125         {
126                 if(scratch_binding && scratch_binding->target!=target)
127                         glBindTexture(scratch_binding->target, 0);
128                 glBindTexture(target, id);
129                 scratch_binding = this;
130         }
131 }
132
133 void OpenGLTexture::unbind_scratch()
134 {
135         const OpenGLTexture *&scratch_binding = Device::get_current().get_state().scratch_texture;
136         if(scratch_binding)
137         {
138                 glBindTexture(scratch_binding->target, 0);
139                 scratch_binding = 0;
140         }
141 }
142
143 } // namespace GL
144 } // namespace Msp