Gamp v0.0.7-54-gccdc599
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
TextureData.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11#ifndef GAMP_RENDER_GL_TEXTURE_TEXTUREDATA_HPP_
12#define GAMP_RENDER_GL_TEXTURE_TEXTUREDATA_HPP_
13
14#include <cstdint>
15#include <vector>
16
17#include <jau/basic_types.hpp>
18#include <jau/int_math.hpp>
19#include <jau/math/recti.hpp>
20#include <jau/math/vec2i.hpp>
21#include <jau/string_util.hpp>
22
23#include <gamp/GampTypes.hpp>
29
31 /** \addtogroup Gamp_GL
32 *
33 * @{
34 */
35
37
38 /**
39 * Represents the data for an OpenGL texture. This is separated from
40 * the notion of a Texture to support things like streaming in of
41 * textures in a background thread without requiring an OpenGL context
42 * to be current on that thread.
43 */
44 class TextureData {
45 public:
46 /** ColorSpace of pixel data. */
47 enum class ColorSpace : uint8_t { RGB, YCbCr, YCCK, CMYK };
48 typedef std::vector<uint8_t> bytes_t;
49
50 private:
51 Point2u32 m_size;
52 unsigned m_border;
53 // GLPixelAttributes pixelAttributes;
54 GLenum m_internalFormat; // perhaps inferred from pixelFormat?
55 bool m_mipmap; // indicates whether mipmaps should be generated
56 // (ignored if mipmaps are supplied from the file)
57 bool m_dataIsCompressed;
58 bool m_mustFlipVertically; // Must flip texture coordinates
59 // vertically to get OpenGL output
60 // to look correct
61 bytes_t m_buffer; // the actual data...
62 std::vector<bytes_t> m_mipmapData; // ...or a series of mipmaps
63 unsigned m_rowLength;
64 unsigned m_alignment; // 1, 2, or 4 bytes
65 unsigned m_estimatedMemorySize;
66
67 ColorSpace m_pixelCS = ColorSpace::RGB;
68
69 public:
70 /**
71 * Constructs a new TextureData object with the specified parameters
72 * and data contained in the given Buffer. The optional Flusher can
73 * be used to clean up native resources associated with this
74 * TextureData when processing is complete; for example, closing of
75 * memory-mapped files that might otherwise require a garbage
76 * collection to reclaim and close.
77 *
78 * @param glp the OpenGL Profile this texture data should be
79 * created for.
80 * @param internalFormat the OpenGL internal format for the
81 * resulting texture; must be specified, may
82 * not be 0
83 * @param width the width in pixels of the texture
84 * @param height the height in pixels of the texture
85 * @param border the number of pixels of border this texture
86 * data has (0 or 1)
87 * @param pixelFormat the OpenGL pixel format for the
88 * resulting texture; must be specified, may
89 * not be 0
90 * @param pixelType the OpenGL type of the pixels of the texture
91 * @param mipmap indicates whether mipmaps should be
92 * autogenerated (using GLU) for the resulting
93 * texture. Currently if mipmap is true then
94 * dataIsCompressed may not be true.
95 * @param dataIsCompressed indicates whether the texture data is in
96 * compressed form
97 * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
98 * @param mustFlipVertically indicates whether the texture
99 * coordinates must be flipped vertically
100 * in order to properly display the
101 * texture
102 * @param buffer the buffer containing the texture data
103 * @param flusher optional flusher to perform cleanup tasks
104 * upon call to flush()
105 *
106 * @throws IllegalArgumentException if any parameters of the texture
107 * data were invalid, such as requesting mipmap generation for a
108 * compressed texture
109 */
110 TextureData(const GLProfile& glp, GLenum internalFormat,
111 Point2u32& size,
112 unsigned border,
113 GLenum pixelFormat,
114 GLenum pixelType,
115 bool mipmap,
116 bool dataIsCompressed,
117 bool mustFlipVertically,
118 bytes_t& buffer)
119 : TextureData(glp, internalFormat, size, border, GLPixelAttributes(pixelFormat, pixelType),
120 mipmap, dataIsCompressed, mustFlipVertically, buffer, flusher) {}
121
122 /**
123 * Constructs a new TextureData object with the specified parameters
124 * and data contained in the given Buffer. The optional Flusher can
125 * be used to clean up native resources associated with this
126 * TextureData when processing is complete; for example, closing of
127 * memory-mapped files that might otherwise require a garbage
128 * collection to reclaim and close.
129 *
130 * @param glp the OpenGL Profile this texture data should be
131 * created for.
132 * @param internalFormat the OpenGL internal format for the
133 * resulting texture; must be specified, may
134 * not be 0
135 * @param width the width in pixels of the texture
136 * @param height the height in pixels of the texture
137 * @param border the number of pixels of border this texture
138 * data has (0 or 1)
139 * @param pixelAttributes the OpenGL pixel format and type for the
140 * resulting texture; must be specified, may
141 * not be 0
142 * @param mipmap indicates whether mipmaps should be
143 * autogenerated (using GLU) for the resulting
144 * texture. Currently if mipmap is true then
145 * dataIsCompressed may not be true.
146 * @param dataIsCompressed indicates whether the texture data is in
147 * compressed form
148 * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
149 * @param mustFlipVertically indicates whether the texture
150 * coordinates must be flipped vertically
151 * in order to properly display the
152 * texture
153 * @param buffer the buffer containing the texture data
154 * @param flusher optional flusher to perform cleanup tasks
155 * upon call to flush()
156 *
157 * @throws IllegalArgumentException if any parameters of the texture
158 * data were invalid, such as requesting mipmap generation for a
159 * compressed texture
160 */
161 public TextureData(const GLProfile& glp,
162 int internalFormat,
163 Point2u32& size,
164 int border,
165 GLPixelAttributes pixelAttributes,
166 bool mipmap,
167 bool dataIsCompressed,
168 bool mustFlipVertically,
169 bytes_t& buffer) {
170 if (mipmap && dataIsCompressed) {
171 throw jau::IllegalArgumentError("Can not generate mipmaps for compressed textures", E_FILE_LINE);
172 }
173 this.glProfile = glp;
174 this.width = width;
175 this.height = height;
176 this.border = border;
177 this.pixelAttributes = pixelAttributes;
178 this.internalFormat = internalFormat;
179 this.mipmap = mipmap;
180 this.dataIsCompressed = dataIsCompressed;
181 this.mustFlipVertically = mustFlipVertically;
182 this.buffer = buffer;
183 this.flusher = flusher;
184 alignment = 1; // FIXME: is this correct enough in all situations?
186 }
187
188 /**
189 * Constructs a new TextureData object with the specified parameters
190 * and data for multiple mipmap levels contained in the given array
191 * of Buffers. The optional Flusher can be used to clean up native
192 * resources associated with this TextureData when processing is
193 * complete; for example, closing of memory-mapped files that might
194 * otherwise require a garbage collection to reclaim and close.
195 *
196 * @param glp the OpenGL Profile this texture data should be
197 * created for.
198 * @param internalFormat the OpenGL internal format for the
199 * resulting texture; must be specified, may
200 * not be 0
201 * @param width the width in pixels of the topmost mipmap
202 * level of the texture
203 * @param height the height in pixels of the topmost mipmap
204 * level of the texture
205 * @param border the number of pixels of border this texture
206 * data has (0 or 1)
207 * @param pixelFormat the OpenGL pixel format for the
208 * resulting texture; must be specified, may
209 * not be 0
210 * @param pixelType the OpenGL type of the pixels of the texture
211 * @param dataIsCompressed indicates whether the texture data is in
212 * compressed form
213 * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
214 * @param mustFlipVertically indicates whether the texture
215 * coordinates must be flipped vertically
216 * in order to properly display the
217 * texture
218 * @param mipmapData the buffers containing all mipmap levels
219 * of the texture's data
220 * @param flusher optional flusher to perform cleanup tasks
221 * upon call to flush()
222 *
223 * @throws IllegalArgumentException if any parameters of the texture
224 * data were invalid, such as requesting mipmap generation for a
225 * compressed texture
226 */
227 public TextureData(final GLProfile glp,
228 final int internalFormat,
229 final int width,
230 final int height,
231 final int border,
232 final int pixelFormat,
233 final int pixelType,
234 final boolean dataIsCompressed,
235 final boolean mustFlipVertically,
236 final Buffer[] mipmapData,
237 final Flusher flusher) throws IllegalArgumentException {
238 this(glp, internalFormat, width, height, border, new GLPixelAttributes(pixelFormat, pixelType),
239 dataIsCompressed, mustFlipVertically, mipmapData, flusher);
240 }
241
242 /**
243 * Constructs a new TextureData object with the specified parameters
244 * and data for multiple mipmap levels contained in the given array
245 * of Buffers. The optional Flusher can be used to clean up native
246 * resources associated with this TextureData when processing is
247 * complete; for example, closing of memory-mapped files that might
248 * otherwise require a garbage collection to reclaim and close.
249 *
250 * @param glp the OpenGL Profile this texture data should be
251 * created for.
252 * @param internalFormat the OpenGL internal format for the
253 * resulting texture; must be specified, may
254 * not be 0
255 * @param width the width in pixels of the topmost mipmap
256 * level of the texture
257 * @param height the height in pixels of the topmost mipmap
258 * level of the texture
259 * @param border the number of pixels of border this texture
260 * data has (0 or 1)
261 * @param pixelAttributes the OpenGL pixel format and type for the
262 * resulting texture; must be specified, may
263 * not be 0
264 * @param dataIsCompressed indicates whether the texture data is in
265 * compressed form
266 * (e.g. GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
267 * @param mustFlipVertically indicates whether the texture
268 * coordinates must be flipped vertically
269 * in order to properly display the
270 * texture
271 * @param mipmapData the buffers containing all mipmap levels
272 * of the texture's data
273 * @param flusher optional flusher to perform cleanup tasks
274 * upon call to flush()
275 *
276 * @throws IllegalArgumentException if any parameters of the texture
277 * data were invalid, such as requesting mipmap generation for a
278 * compressed texture
279 */
280 public TextureData(final GLProfile glp,
281 final int internalFormat,
282 final int width,
283 final int height,
284 final int border,
285 final GLPixelAttributes pixelAttributes,
286 final boolean dataIsCompressed,
287 final boolean mustFlipVertically,
288 final Buffer[] mipmapData,
289 final Flusher flusher) throws IllegalArgumentException {
290 this.glProfile = glp;
291 this.width = width;
292 this.height = height;
293 this.border = border;
294 this.pixelAttributes = pixelAttributes;
295 this.internalFormat = internalFormat;
296 this.dataIsCompressed = dataIsCompressed;
297 this.mustFlipVertically = mustFlipVertically;
298 this.mipmapData = mipmapData.clone();
299 this.flusher = flusher;
300 alignment = 1; // FIXME: is this correct enough in all situations?
301 for (int i = 0; i < mipmapData.length; i++) {
303 }
304 }
305
306 /**
307 * Returns the color space of the pixel data.
308 * @see #setColorSpace(ColorSpace)
309 */
310 public ColorSpace getColorSpace() { return pixelCS; }
311
312 /**
313 * Set the color space of the pixel data, which defaults to {@link ColorSpace#RGB}.
314 * @see #getColorSpace()
315 */
316 public void setColorSpace(final ColorSpace cs) { pixelCS = cs; }
317
318 /** Used only by subclasses */
319 protected TextureData(final GLProfile glp) { this.glProfile = glp; this.pixelAttributes = GLPixelAttributes.UNDEF; }
320
321 /**
322 * Returns the source {@link ImageType} if applicable and known, otherwise {@code null}.
323 * @since 2.3.2
324 */
325 public final ImageType getSourceImageType() {
326 return srcImageType;
327 }
328
329 /** Returns the width in pixels of the texture data. */
330 public int getWidth() { return width; }
331 /** Returns the height in pixels of the texture data. */
332 public int getHeight() { return height; }
333 /** Returns the border in pixels of the texture data. */
334 public int getBorder() {
335 return border;
336 }
337 /** Returns the intended OpenGL {@link GLPixelAttributes} of the texture data, i.e. format and type. */
338 public GLPixelAttributes getPixelAttributes() {
339 return pixelAttributes;
340 }
341 /** Returns the intended OpenGL pixel format of the texture data using {@link #getPixelAttributes()}. */
342 public int getPixelFormat() {
343 return pixelAttributes.format;
344 }
345 /** Returns the intended OpenGL pixel type of the texture data using {@link #getPixelAttributes()}. */
346 public int getPixelType() {
347 return pixelAttributes.type;
348 }
349 /** Returns the intended OpenGL internal format of the texture data. */
350 public int getInternalFormat() {
351 return internalFormat;
352 }
353 /** Returns whether mipmaps should be generated for the texture data. */
354 public boolean getMipmap() {
355 return mipmap;
356 }
357 /** Indicates whether the texture data is in compressed form. */
358 public boolean isDataCompressed() {
359 return dataIsCompressed;
360 }
361 /** Indicates whether the texture coordinates must be flipped
362 vertically for proper display. */
363 public boolean getMustFlipVertically() {
364 return mustFlipVertically;
365 }
366 /** Returns the texture data, or null if it is specified as a set of mipmaps. */
367 public Buffer getBuffer() {
368 return buffer;
369 }
370 /** Returns all mipmap levels for the texture data, or null if it is
371 specified as a single image. */
372 public Buffer[] getMipmapData() {
373 return mipmapData;
374 }
375 /** Returns the required byte alignment for the texture data. */
376 public int getAlignment() {
377 return alignment;
378 }
379 /** Returns the row length needed for correct GL_UNPACK_ROW_LENGTH
380 specification. This is currently only supported for
381 non-mipmapped, non-compressed textures. */
382 public int getRowLength() {
383 return rowLength;
384 }
385
386 /** Sets the width in pixels of the texture data. */
387 public void setWidth(final int width) { this.width = width; }
388 /** Sets the height in pixels of the texture data. */
389 public void setHeight(final int height) { this.height = height; }
390 /** Sets the border in pixels of the texture data. */
391 public void setBorder(final int border) { this.border = border; }
392 /** Sets the intended OpenGL pixel format of the texture data. */
393 public void setPixelAttributes(final GLPixelAttributes pixelAttributes) { this.pixelAttributes = pixelAttributes; }
394 /**
395 * Sets the intended OpenGL pixel format component of {@link GLPixelAttributes} of the texture data.
396 * <p>
397 * Use {@link #setPixelAttributes(GLPixelAttributes)}, if setting format and type.
398 * </p>
399 */
400 public void setPixelFormat(final int pixelFormat) {
401 if( pixelAttributes.format != pixelFormat ) {
402 pixelAttributes = new GLPixelAttributes(pixelFormat, pixelAttributes.type);
403 }
404 }
405 /**
406 * Sets the intended OpenGL pixel type component of {@link GLPixelAttributes} of the texture data.
407 * <p>
408 * Use {@link #setPixelAttributes(GLPixelAttributes)}, if setting format and type.
409 * </p>
410 */
411 public void setPixelType(final int pixelType) {
412 if( pixelAttributes.type != pixelType) {
413 pixelAttributes = new GLPixelAttributes(pixelAttributes.format, pixelType);
414 }
415 }
416 /** Sets the intended OpenGL internal format of the texture data. */
417 public void setInternalFormat(final int internalFormat) { this.internalFormat = internalFormat; }
418 /** Sets whether mipmaps should be generated for the texture data. */
419 public void setMipmap(final boolean mipmap) { this.mipmap = mipmap; }
420 /** Sets whether the texture data is in compressed form. */
421 public void setIsDataCompressed(final boolean compressed) { this.dataIsCompressed = compressed; }
422 /** Sets whether the texture coordinates must be flipped vertically
423 for proper display. */
424 public void setMustFlipVertically(final boolean mustFlipVertically) { this.mustFlipVertically = mustFlipVertically; }
425 /** Sets the texture data. */
426 public void setBuffer(final Buffer buffer) {
427 this.buffer = buffer;
429 }
430 /** Sets the required byte alignment for the texture data. */
431 public void setAlignment(final int alignment) { this.alignment = alignment; }
432 /** Sets the row length needed for correct GL_UNPACK_ROW_LENGTH
433 specification. This is currently only supported for
434 non-mipmapped, non-compressed textures. */
435 public void setRowLength(final int rowLength) { this.rowLength = rowLength; }
436 /** Indicates to this TextureData whether the GL_EXT_abgr extension
437 is available. Used for optimization along some code paths to
438 avoid data copies. */
439 public void setHaveEXTABGR(final boolean haveEXTABGR) {
440 this.haveEXTABGR = haveEXTABGR;
441 }
442 /** Indicates to this TextureData whether OpenGL version 1.2 is
443 available. If not, falls back to relatively inefficient code
444 paths for several input data types (several kinds of packed
445 pixel formats, in particular). */
446 public void setHaveGL12(final boolean haveGL12) {
447 this.haveGL12 = haveGL12;
448 }
449
450 /** Returns the GLProfile this texture data is intended and created for. */
451 public GLProfile getGLProfile() { return glProfile; }
452
453 /** Returns an estimate of the amount of memory in bytes this
454 TextureData will consume once uploaded to the graphics card. It
455 should only be treated as an estimate; most applications should
456 not need to query this but instead let the OpenGL implementation
457 page textures in and out as necessary. */
459 return estimatedMemorySize;
460 }
461
462 /** Flushes resources associated with this TextureData by calling
463 Flusher.flush(). */
464 public void flush() {
465 if (flusher != null) {
466 flusher.flush();
467 flusher = null;
468 }
469 }
470
471 /** Calls flush()
472 * @see #flush()
473 */
474 public void destroy() {
475 flush();
476 }
477
478 /** Defines a callback mechanism to allow the user to explicitly
479 deallocate native resources (memory-mapped files, etc.)
480 associated with a particular TextureData. */
481 public static interface Flusher {
482 /** Flushes any native resources associated with this
483 TextureData. */
484 public void flush();
485 }
486
487 @Override
488 public String toString() {
489 final String optImageType = null != srcImageType ? ", "+srcImageType : "";
490 return "TextureData["+width+"x"+height+", y-flip "+mustFlipVertically+", internFormat 0x"+Integer.toHexString(internalFormat)+", "+
491 pixelAttributes+", border "+border+", estSize "+estimatedMemorySize+", alignment "+alignment+", rowlen "+rowLength+optImageType;
492 }
493
494 //----------------------------------------------------------------------
495 // Internals only below this point
496 //
497
498 protected static int estimatedMemorySize(final Buffer buffer) {
499 if (buffer == null) {
500 return 0;
501 }
502 return buffer.capacity() * Buffers.sizeOfBufferElem(buffer);
503 }
504 };
505
506 /**@}*/
507
508} // namespace gamp::render::gl
509
510#endif /* GAMP_RENDER_GL_TEXTURE_TEXTUREDATA_HPP_ */
#define E_FILE_LINE
Specifies the OpenGL profile.
Definition GLContext.hpp:42
Point2I< uint32_t > Point2u32
Definition vec2i.hpp:348
Represents the data for an OpenGL texture.
Definition Texture.hpp:35
boolean getMustFlipVertically()
Indicates whether the texture coordinates must be flipped vertically for proper display.
int getBorder()
Returns the border in pixels of the texture data.
final ImageType getSourceImageType()
Returns the source ImageType if applicable and known, otherwise null.
Buffer[] getMipmapData()
Returns all mipmap levels for the texture data, or null if it is specified as a single image.
void setAlignment(final int alignment)
Sets the required byte alignment for the texture data.
int getInternalFormat()
Returns the intended OpenGL internal format of the texture data.
GLProfile getGLProfile()
Returns the GLProfile this texture data is intended and created for.
int getPixelType()
Returns the intended OpenGL pixel type of the texture data using getPixelAttributes().
int getWidth()
Returns the width in pixels of the texture data.
TextureData(const GLProfile &glp, GLenum internalFormat, Point2u32 &size, unsigned border, GLenum pixelFormat, GLenum pixelType, bool mipmap, bool dataIsCompressed, bool mustFlipVertically, bytes_t &buffer)
Constructs a new TextureData object with the specified parameters and data contained in the given Buf...
void setHaveEXTABGR(final boolean haveEXTABGR)
Indicates to this TextureData whether the GL_EXT_abgr extension is available.
void setWidth(final int width)
Sets the width in pixels of the texture data.
void setMipmap(final boolean mipmap)
Sets whether mipmaps should be generated for the texture data.
int getHeight()
Returns the height in pixels of the texture data.
void setRowLength(final int rowLength)
Sets the row length needed for correct GL_UNPACK_ROW_LENGTH specification.
void setPixelFormat(final int pixelFormat)
Sets the intended OpenGL pixel format component of GLPixelAttributes of the texture data.
ColorSpace getColorSpace()
Returns the color space of the pixel data.
static int estimatedMemorySize(final Buffer buffer)
void setHaveGL12(final boolean haveGL12)
Indicates to this TextureData whether OpenGL version 1.2 is available.
void setColorSpace(final ColorSpace cs)
Set the color space of the pixel data, which defaults to ColorSpace#RGB.
GLPixelAttributes getPixelAttributes()
Returns the intended OpenGL GLPixelAttributes of the texture data, i.e.
int getEstimatedMemorySize()
Returns an estimate of the amount of memory in bytes this TextureData will consume once uploaded to t...
TextureData(final GLProfile glp)
Used only by subclasses.
void setPixelType(final int pixelType)
Sets the intended OpenGL pixel type component of GLPixelAttributes of the texture data.
void setMustFlipVertically(final boolean mustFlipVertically)
Sets whether the texture coordinates must be flipped vertically for proper display.
TextureData(final GLProfile glp, final int internalFormat, final int width, final int height, final int border, final int pixelFormat, final int pixelType, final boolean dataIsCompressed, final boolean mustFlipVertically, final Buffer[] mipmapData, final Flusher flusher)
Constructs a new TextureData object with the specified parameters and data for multiple mipmap levels...
void setHeight(final int height)
Sets the height in pixels of the texture data.
static interface Flusher
Defines a callback mechanism to allow the user to explicitly deallocate native resources (memory-mapp...
ColorSpace
ColorSpace of pixel data.
void setIsDataCompressed(final boolean compressed)
Sets whether the texture data is in compressed form.
void flush()
Flushes resources associated with this TextureData by calling Flusher.flush().
void setBorder(final int border)
Sets the border in pixels of the texture data.
TextureData(final GLProfile glp, final int internalFormat, final int width, final int height, final int border, final GLPixelAttributes pixelAttributes, final boolean dataIsCompressed, final boolean mustFlipVertically, final Buffer[] mipmapData, final Flusher flusher)
Constructs a new TextureData object with the specified parameters and data for multiple mipmap levels...
int getRowLength()
Returns the row length needed for correct GL_UNPACK_ROW_LENGTH specification.
int getAlignment()
Returns the required byte alignment for the texture data.
boolean getMipmap()
Returns whether mipmaps should be generated for the texture data.
void setBuffer(final Buffer buffer)
Sets the texture data.
void setInternalFormat(final int internalFormat)
Sets the intended OpenGL internal format of the texture data.
void setPixelAttributes(final GLPixelAttributes pixelAttributes)
Sets the intended OpenGL pixel format of the texture data.
int getPixelFormat()
Returns the intended OpenGL pixel format of the texture data using getPixelAttributes().
Buffer getBuffer()
Returns the texture data, or null if it is specified as a set of mipmaps.
TextureData(const GLProfile &glp, int internalFormat, Point2u32 &size, int border, GLPixelAttributes pixelAttributes, bool mipmap, bool dataIsCompressed, bool mustFlipVertically, bytes_t &buffer)
Constructs a new TextureData object with the specified parameters and data contained in the given Buf...
boolean isDataCompressed()
Indicates whether the texture data is in compressed form.