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