Added a getModeUsage() method that prevents any mode being automatically associated...
[openscenegraph:osg.git] / include / osg / Texture2DArray
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * OpenSceneGraph Public License for more details.
12 */
13
14 #ifndef OSG_TEXTURE2DARRAY
15 #define OSG_TEXTURE2DARRAY 1
16
17 #include <osg/Texture>
18 #include <list>
19
20 namespace osg {
21
22 /** Texture2DArray state class which encapsulates OpenGL 2D array texture functionality.
23  * Texture arrays were introduced with Shader Model 4.0 hardware.
24  *
25  * A 2D texture array does contain textures sharing the same properties (e.g. size, bitdepth,...)
26  * in a layered structure. See http://www.opengl.org/registry/specs/EXT/texture_array.txt for more info.
27  */
28 class OSG_EXPORT Texture2DArray : public Texture
29 {
30
31     public :
32
33         Texture2DArray();
34
35         /** Copy constructor using CopyOp to manage deep vs shallow copy. */
36         Texture2DArray(const Texture2DArray& cm,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
37
38         META_StateAttribute(osg, Texture2DArray, TEXTURE);
39
40         /** Return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
41         virtual int compare(const StateAttribute& rhs) const;
42
43         virtual GLenum getTextureTarget() const { return GL_TEXTURE_2D_ARRAY_EXT; }
44
45         /** Texture2DArray is related to non fixed pipeline usage only so isn't appropriate to enable/disable.*/
46         virtual bool getModeUsage(StateAttribute::ModeUsage&) const { return false; }
47
48         /** Set the texture image for specified layer. */
49         virtual void setImage(unsigned int layer, Image* image);
50
51         /** Get the texture image for specified layer. */
52         virtual Image* getImage(unsigned int layer);
53
54         /** Get the const texture image for specified layer. */
55         virtual const Image* getImage(unsigned int layer) const;
56
57         /** Get the number of images that are assigned to the Texture.
58          * The number is equal to the texture depth. To get the maximum possible
59          * image/layer count, you have to use the extension subclass, since it provides
60          * graphic context dependent information.
61          */
62         virtual unsigned int getNumImages() const { return getTextureDepth(); }
63
64         /** Check how often was a certain layer in the given context modified */
65         inline unsigned int& getModifiedCount(unsigned int layer, unsigned int contextID) const
66         {
67             // get the modified count for the current contextID.
68             return _modifiedCount[layer][contextID];
69         }
70
71         /** Set the texture width and height. If width or height are zero then
72           * the respective size value is calculated from the source image sizes.
73           * Depth parameter specifies the number of layers to be used.
74         */
75         void setTextureSize(int width, int height, int depth);
76
77         void setTextureWidth(int width) { _textureWidth=width; }
78         void setTextureHeight(int height) { _textureHeight=height; }
79         void setTextureDepth(int depth);
80
81         virtual int getTextureWidth() const { return _textureWidth; }
82         virtual int getTextureHeight() const { return _textureHeight; }
83         virtual int getTextureDepth() const { return _textureDepth; }
84
85         class OSG_EXPORT SubloadCallback : public Referenced
86         {
87             public:
88                 virtual void load(const Texture2DArray& texture,State& state) const = 0;
89                 virtual void subload(const Texture2DArray& texture,State& state) const = 0;
90         };
91
92
93         void setSubloadCallback(SubloadCallback* cb) { _subloadCallback = cb;; }
94
95         SubloadCallback* getSubloadCallback() { return _subloadCallback.get(); }
96
97         const SubloadCallback* getSubloadCallback() const { return _subloadCallback.get(); }
98
99
100
101         /** Set the number of mip map levels the the texture has been created with.
102           * Should only be called within an osg::Texture::apply() and custom OpenGL texture load.
103         */
104         void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
105
106         /** Get the number of mip map levels the the texture has been created with. */
107         unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
108
109         /** Copies a two-dimensional texture subimage, as per
110           * glCopyTexSubImage3D. Updates a portion of an existing OpenGL
111           * texture object from the current OpenGL background framebuffer
112           * contents at position \a x, \a y with width \a width and height
113           * \a height. Loads framebuffer data into the texture using offsets
114           * \a xoffset and \a yoffset. \a zoffset specifies the layer of the texture
115           * array to which the result is copied.
116           */
117         void copyTexSubImage2DArray(State& state, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height );
118
119         /** Bind the texture if already compiled. Otherwise recompile.
120         */
121         virtual void apply(State& state) const;
122
123
124         /** Extensions class which encapsulates the querying of extensions and
125           * associated function pointers, and provides convenience wrappers to
126           * check for the extensions or use the associated functions.
127         */
128         class OSG_EXPORT Extensions : public osg::Referenced
129         {
130             public:
131                 Extensions(unsigned int contextID);
132
133                 Extensions(const Extensions& rhs);
134
135                 void lowestCommonDenominator(const Extensions& rhs);
136
137                 void setupGLExtensions(unsigned int contextID);
138
139                 void setTexture2DArraySupported(bool flag) { _isTexture2DArraySupported=flag; }
140                 bool isTexture2DArraySupported() const { return _isTexture2DArraySupported; }
141
142                 void setTexture3DSupported(bool flag) { _isTexture3DSupported=flag; }
143                 bool isTexture3DSupported() const { return _isTexture3DSupported; }
144
145                 void setMaxLayerCount(GLint count) { _maxLayerCount = count; }
146                 GLint maxLayerCount() const { return _maxLayerCount; }
147
148                 void setMax2DSize(GLint size) { _max2DSize = size; }
149                 GLint max2DSize() const { return _max2DSize; }
150
151                 void glTexImage3D( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) const;
152
153                 void glTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) const;
154
155                 void glCopyTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ) const;
156
157                 bool isCompressedTexImage3DSupported() const { return _glCompressedTexImage3D!=0; }
158                 void glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) const;
159
160                 bool isCompressedTexSubImage3DSupported() const { return _glCompressedTexSubImage3D!=0; }
161                 void glCompressedTexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data ) const;
162
163             protected:
164
165                 ~Extensions() {}
166
167                 bool    _isTexture2DArraySupported;
168                 bool    _isTexture3DSupported;
169
170                 GLint   _maxLayerCount;
171                 GLint   _max2DSize;
172
173                 typedef void (GL_APIENTRY * GLTexImage3DProc)      ( GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
174                 typedef void (GL_APIENTRY * GLTexSubImage3DProc)   ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
175                 typedef void (GL_APIENTRY * CompressedTexImage3DArbProc) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
176                 typedef void (GL_APIENTRY * CompressedTexSubImage3DArbProc) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
177                 typedef void (GL_APIENTRY * GLCopyTexSubImageProc) ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height );
178
179                 GLTexImage3DProc                _glTexImage3D;
180                 GLTexSubImage3DProc             _glTexSubImage3D;
181                 CompressedTexImage3DArbProc     _glCompressedTexImage3D;
182                 CompressedTexSubImage3DArbProc  _glCompressedTexSubImage3D;
183                 GLCopyTexSubImageProc           _glCopyTexSubImage3D;
184
185         };
186
187         /** Function to call to get the extension of a specified context.
188           * If the Extension object for that context has not yet been created
189           * and the 'createIfNotInitalized' flag been set to false then returns NULL.
190           * If 'createIfNotInitalized' is true then the Extensions object is
191           * automatically created. However, in this case the extension object will
192           * only be created with the graphics context associated with ContextID.
193         */
194         static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
195
196         /** The setExtensions method allows users to override the extensions across graphics contexts.
197           * Typically used when you have different extensions supported across graphics pipes
198           * but need to ensure that they all use the same low common denominator extensions.
199         */
200         static void setExtensions(unsigned int contextID,Extensions* extensions);
201
202
203     protected :
204
205         virtual ~Texture2DArray();
206
207         bool imagesValid() const;
208
209         virtual void computeInternalFormat() const;
210         void allocateMipmap(State& state) const;
211
212         void applyTexImage2DArray_subload(State& state, Image* image, GLsizei inwidth, GLsizei inheight, GLsizei indepth, GLint inInternalFormat, GLsizei& numMipmapLevels) const;
213
214         /**
215          * Use std::vector to encapsulate referenced pointers to images of different layers.
216          * Vectors gives us a random access iterator. The overhead of non-used elements is negligible */
217         std::vector<ref_ptr<Image> > _images;
218
219         // subloaded images can have different texture and image sizes.
220         mutable GLsizei _textureWidth, _textureHeight, _textureDepth;
221
222         // number of mip map levels the the texture has been created with,
223         mutable GLsizei _numMipmapLevels;
224
225         ref_ptr<SubloadCallback> _subloadCallback;
226
227         typedef buffered_value<unsigned int> ImageModifiedCount;
228         mutable std::vector<ImageModifiedCount> _modifiedCount;
229 };
230
231 }
232
233 #endif