]> git.tdb.fi Git - libs/gl.git/blob - source/backends/opengl/texturecube_backend.cpp
142e343dd9984bb881148ee3dd66739c9cddf3e3
[libs/gl.git] / source / backends / opengl / texturecube_backend.cpp
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>
5 #include "gl.h"
6 #include "texturecube.h"
7 #include "texturecube_backend.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace GL {
13
14 OpenGLTextureCube::OpenGLTextureCube():
15         Texture(GL_TEXTURE_CUBE_MAP)
16 {
17         static Require _req(ARB_texture_cube_map);
18         if(ARB_seamless_cube_map)
19         {
20                 static bool seamless_init = false;
21                 if(!seamless_init)
22                 {
23                         glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
24                         seamless_init = true;
25                 }
26         }
27 }
28
29 void OpenGLTextureCube::allocate()
30 {
31         const TextureCube &self = *static_cast<const TextureCube *>(this);
32
33         if(!id)
34                 create();
35
36         GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
37         if(ARB_texture_storage)
38         {
39                 if(ARB_direct_state_access)
40                         glTextureStorage2D(id, self.levels, gl_fmt, self.size, self.size);
41                 else
42                 {
43                         bind_scratch();
44                         glTexStorage2D(target, self.levels, gl_fmt, self.size, self.size);
45                 }
46         }
47         else
48         {
49                 bind_scratch();
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)
53                 {
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);
57                 }
58                 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, self.levels-1);
59         }
60
61         apply_swizzle();
62 }
63
64 void OpenGLTextureCube::sub_image(unsigned face, unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
65 {
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);
70         else
71         {
72                 bind_scratch();
73                 glTexSubImage2D(get_gl_cube_face(face), level, x, y, wd, ht, comp, type, data);
74         }
75 }
76
77 size_t OpenGLTextureCube::get_data_size() const
78 {
79         if(!id)
80                 return 0;
81
82         const TextureCube &self = *static_cast<const TextureCube *>(this);
83
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;
88         return total_size;
89 }
90
91
92 unsigned get_gl_cube_face(unsigned face)
93 {
94         switch(static_cast<TextureCubeFace>(face))
95         {
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");
103         }
104 }
105
106 } // namespace GL
107 } // namespace Msp