]> git.tdb.fi Git - libs/gl.git/blob - source/backends/opengl/texture2d_backend.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / backends / opengl / texture2d_backend.cpp
1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_texture_storage.h>
3 #include <msp/gl/extensions/arb_vertex_buffer_object.h>
4 #include "buffer.h"
5 #include "gl.h"
6 #include "texture2d.h"
7 #include "texture2d_backend.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace GL {
13
14 OpenGLTexture2D::OpenGLTexture2D():
15         Texture(GL_TEXTURE_2D)
16 { }
17
18 void OpenGLTexture2D::allocate()
19 {
20         const Texture2D &self = *static_cast<const Texture2D *>(this);
21
22         if(!id)
23                 create();
24
25         GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
26         if(ARB_texture_storage)
27         {
28                 if(ARB_direct_state_access)
29                         glTextureStorage2D(id, n_levels, gl_fmt, self.width, self.height);
30                 else
31                 {
32                         bind_scratch();
33                         glTexStorage2D(target, n_levels, gl_fmt, self.width, self.height);
34                 }
35         }
36         else
37         {
38                 bind_scratch();
39                 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, n_levels-1);
40                 GLenum comp = get_gl_components(get_components(storage_fmt));
41                 GLenum type = get_gl_type(get_component_type(storage_fmt));
42                 for(unsigned i=0; i<n_levels; ++i)
43                 {
44                         auto lv_size = self.get_level_size(i);
45                         glTexImage2D(target, i, gl_fmt, lv_size.x, lv_size.y, 0, comp, type, 0);
46                 }
47         }
48
49         apply_swizzle();
50 }
51
52 void OpenGLTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
53 {
54         GLenum comp = get_gl_components(get_components(storage_fmt));
55         GLenum type = get_gl_type(get_component_type(storage_fmt));
56         if(ARB_direct_state_access)
57                 glTextureSubImage2D(id, level, x, y, wd, ht, comp, type, data);
58         else
59         {
60                 bind_scratch();
61                 glTexSubImage2D(target, level, x, y, wd, ht, comp, type, data);
62         }
63 }
64
65 uint64_t OpenGLTexture2D::get_data_size() const
66 {
67         if(!id)
68                 return 0;
69
70         const Texture2D &self = *static_cast<const Texture2D *>(this);
71
72         size_t level_size = self.width*self.height*get_pixel_size(format);
73         size_t total_size = level_size;
74         for(unsigned i=0; i<n_levels; ++i, level_size>>=2)
75                 total_size += level_size;
76         return total_size;
77 }
78
79 void OpenGLTexture2D::unload()
80 {
81         glDeleteTextures(1, &id);
82         id = 0;
83 }
84
85
86 OpenGLTexture2D::AsyncTransfer::AsyncTransfer(AsyncTransfer &&other):
87         pixel_buffer(other.pixel_buffer)
88 {
89         other.pixel_buffer = 0;
90 }
91
92 OpenGLTexture2D::AsyncTransfer &OpenGLTexture2D::AsyncTransfer::operator=(AsyncTransfer &&other)
93 {
94         delete pixel_buffer;
95         pixel_buffer = other.pixel_buffer;
96         other.pixel_buffer = 0;
97
98         return *this;
99 }
100
101 OpenGLTexture2D::AsyncTransfer::~AsyncTransfer()
102 {
103         delete pixel_buffer;
104 }
105
106 void *OpenGLTexture2D::AsyncTransfer::allocate()
107 {
108         const Texture2D::AsyncTransfer &self = *static_cast<const Texture2D::AsyncTransfer *>(this);
109
110         pixel_buffer = new Buffer;
111         pixel_buffer->storage(self.data_size, STREAMING);
112         return pixel_buffer->map();
113 }
114
115 void OpenGLTexture2D::AsyncTransfer::finalize()
116 {
117         const Texture2D::AsyncTransfer &self = *static_cast<const Texture2D::AsyncTransfer *>(this);
118
119         pixel_buffer->unmap();
120
121         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixel_buffer->id);
122         self.texture->OpenGLTexture2D::sub_image(self.level, self.x, self.y, self.width, self.height, 0);
123         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
124 }
125
126 } // namespace GL
127 } // namespace Msp