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>
7 #include "texture2d_backend.h"
14 OpenGLTexture2D::OpenGLTexture2D():
15 Texture(GL_TEXTURE_2D)
18 void OpenGLTexture2D::allocate()
20 const Texture2D &self = *static_cast<const Texture2D *>(this);
25 GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
26 if(ARB_texture_storage)
28 if(ARB_direct_state_access)
29 glTextureStorage2D(id, n_levels, gl_fmt, self.width, self.height);
33 glTexStorage2D(target, n_levels, gl_fmt, self.width, self.height);
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)
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);
52 void OpenGLTexture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
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);
61 glTexSubImage2D(target, level, x, y, wd, ht, comp, type, data);
65 uint64_t OpenGLTexture2D::get_data_size() const
70 const Texture2D &self = *static_cast<const Texture2D *>(this);
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;
79 void OpenGLTexture2D::unload()
81 glDeleteTextures(1, &id);
86 OpenGLTexture2D::AsyncTransfer::AsyncTransfer(AsyncTransfer &&other):
87 pixel_buffer(other.pixel_buffer)
89 other.pixel_buffer = 0;
92 OpenGLTexture2D::AsyncTransfer &OpenGLTexture2D::AsyncTransfer::operator=(AsyncTransfer &&other)
95 pixel_buffer = other.pixel_buffer;
96 other.pixel_buffer = 0;
101 OpenGLTexture2D::AsyncTransfer::~AsyncTransfer()
106 void *OpenGLTexture2D::AsyncTransfer::allocate()
108 const Texture2D::AsyncTransfer &self = *static_cast<const Texture2D::AsyncTransfer *>(this);
110 pixel_buffer = new Buffer;
111 pixel_buffer->storage(self.data_size, STREAMING);
112 return pixel_buffer->map();
115 void OpenGLTexture2D::AsyncTransfer::finalize()
117 const Texture2D::AsyncTransfer &self = *static_cast<const Texture2D::AsyncTransfer *>(this);
119 pixel_buffer->unmap();
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);