1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_seamless_cube_map.h>
3 #include <msp/gl/extensions/arb_texture_cube_map.h>
4 #include <msp/gl/extensions/arb_texture_storage.h>
6 #include "texturecube.h"
7 #include "texturecube_backend.h"
14 OpenGLTextureCube::OpenGLTextureCube():
15 Texture(GL_TEXTURE_CUBE_MAP)
17 static Require _req(ARB_texture_cube_map);
18 if(ARB_seamless_cube_map)
20 static bool seamless_init = false;
23 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
29 void OpenGLTextureCube::allocate()
31 const TextureCube &self = *static_cast<const TextureCube *>(this);
36 GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
37 if(ARB_texture_storage)
39 if(ARB_direct_state_access)
40 glTextureStorage2D(id, self.levels, gl_fmt, self.size, self.size);
44 glTexStorage2D(target, self.levels, gl_fmt, self.size, self.size);
50 GLenum comp = get_gl_components(get_components(storage_fmt));
51 GLenum type = get_gl_type(get_component_type(storage_fmt));
52 for(unsigned i=0; i<self.levels; ++i)
54 unsigned lv_size = static_cast<const TextureCube *>(this)->get_level_size(i);
55 for(unsigned j=0; j<6; ++j)
56 glTexImage2D(get_gl_cube_face(j), i, gl_fmt, lv_size, lv_size, 0, comp, type, 0);
58 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, self.levels-1);
64 void OpenGLTextureCube::sub_image(unsigned face, unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
66 GLenum comp = get_gl_components(get_components(storage_fmt));
67 GLenum type = get_gl_type(get_component_type(storage_fmt));
68 if(ARB_direct_state_access)
69 glTextureSubImage3D(id, level, x, y, face, wd, ht, 1, comp, type, data);
73 glTexSubImage2D(get_gl_cube_face(face), level, x, y, wd, ht, comp, type, data);
77 size_t OpenGLTextureCube::get_data_size() const
82 const TextureCube &self = *static_cast<const TextureCube *>(this);
84 size_t level_size = self.size*self.size*get_pixel_size(storage_fmt);
85 size_t total_size = level_size;
86 for(unsigned i=0; i<self.levels; ++i, level_size>>=2)
87 total_size += level_size;
92 unsigned get_gl_cube_face(unsigned face)
94 switch(static_cast<TextureCubeFace>(face))
96 case POSITIVE_X: return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
97 case NEGATIVE_X: return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
98 case POSITIVE_Y: return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
99 case NEGATIVE_Y: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
100 case POSITIVE_Z: return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
101 case NEGATIVE_Z: return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
102 default: throw invalid_argument("get_gl_cube_face");