]> git.tdb.fi Git - libs/gl.git/blob - source/backends/opengl/texture3d_backend.cpp
Add support for padding in vertex formats
[libs/gl.git] / source / backends / opengl / texture3d_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/ext_texture3d.h>
4 #include <msp/gl/extensions/ext_texture_array.h>
5 #include "gl.h"
6 #include "texture3d.h"
7 #include "texture3d_backend.h"
8
9 namespace Msp {
10 namespace GL {
11
12 OpenGLTexture3D::OpenGLTexture3D():
13         Texture(GL_TEXTURE_3D)
14 {
15         static Require _req(EXT_texture3D);
16 }
17
18 OpenGLTexture3D::OpenGLTexture3D(unsigned t):
19         Texture(t)
20 { }
21
22 void OpenGLTexture3D::allocate()
23 {
24         unsigned width = static_cast<const Texture3D *>(this)->width;
25         unsigned height = static_cast<const Texture3D *>(this)->height;
26         unsigned depth = static_cast<const Texture3D *>(this)->depth;
27         unsigned levels = static_cast<const Texture3D *>(this)->levels;
28
29         if(!id)
30                 create();
31
32         GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
33         if(ARB_texture_storage)
34         {
35                 if(ARB_direct_state_access)
36                         glTextureStorage3D(id, levels, gl_fmt, width, height, depth);
37                 else
38                 {
39                         bind_scratch();
40                         glTexStorage3D(target, levels, gl_fmt, width, height, depth);
41                 }
42         }
43         else
44         {
45                 bind_scratch();
46                 GLenum comp = get_gl_components(get_components(storage_fmt));
47                 GLenum type = get_gl_type(get_component_type(storage_fmt));
48                 for(unsigned i=0; i<levels; ++i)
49                 {
50                         auto lv_size = static_cast<const Texture3D *>(this)->get_level_size(i);
51                         glTexImage3D(target, i, gl_fmt, lv_size.x, lv_size.y, lv_size.z, 0, comp, type, 0);
52                 }
53                 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
54         }
55
56         apply_swizzle();
57 }
58
59 void OpenGLTexture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, const void *data)
60 {
61         GLenum comp = get_gl_components(get_components(storage_fmt));
62         GLenum type = get_gl_type(get_component_type(storage_fmt));
63         if(ARB_direct_state_access)
64                 glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, comp, type, data);
65         else
66         {
67                 bind_scratch();
68                 glTexSubImage3D(target, level, x, y, z, wd, ht, dp, comp, type, data);
69         }
70 }
71
72 bool OpenGLTexture3D::is_array() const
73 {
74         return target==GL_TEXTURE_2D_ARRAY;
75 }
76
77 size_t OpenGLTexture3D::get_data_size() const
78 {
79         if(!id)
80                 return 0;
81
82         unsigned width = static_cast<const Texture3D *>(this)->width;
83         unsigned height = static_cast<const Texture3D *>(this)->height;
84         unsigned depth = static_cast<const Texture3D *>(this)->depth;
85         unsigned levels = static_cast<const Texture3D *>(this)->levels;
86
87         size_t level_size = width*height*depth*get_pixel_size(format);
88         size_t total_size = level_size;
89         for(unsigned i=0; i<levels; ++i, level_size>>=2)
90                 total_size += level_size;
91         return total_size;
92 }
93
94 } // namespace GL
95 } // namespace Msp