123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- // Copyright (C) 2002-2012 Nikolaus Gebhardt
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- #ifndef IRR_I_TEXTURE_H_INCLUDED
- #define IRR_I_TEXTURE_H_INCLUDED
- #include "IReferenceCounted.h"
- #include "IImage.h"
- #include "dimension2d.h"
- #include "EDriverTypes.h"
- #include "path.h"
- #include "matrix4.h"
- namespace irr
- {
- namespace video
- {
- //! Enumeration flags used to tell the video driver with setTextureCreationFlag in which format textures should be created.
- enum E_TEXTURE_CREATION_FLAG
- {
- /** Forces the driver to create 16 bit textures always, independent of
- which format the file on disk has. When choosing this you may lose
- some color detail, but gain much speed and memory. 16 bit textures can
- be transferred twice as fast as 32 bit textures and only use half of
- the space in memory.
- When using this flag, it does not make sense to use the flags
- ETCF_ALWAYS_32_BIT, ETCF_OPTIMIZED_FOR_QUALITY, or
- ETCF_OPTIMIZED_FOR_SPEED at the same time.
- Not all texture formats are affected (usually those up to ECF_A8R8G8B8). */
- ETCF_ALWAYS_16_BIT = 0x00000001,
- /** Forces the driver to create 32 bit textures always, independent of
- which format the file on disk has. Please note that some drivers (like
- the software device) will ignore this, because they are only able to
- create and use 16 bit textures.
- Default is true.
- When using this flag, it does not make sense to use the flags
- ETCF_ALWAYS_16_BIT, ETCF_OPTIMIZED_FOR_QUALITY, or
- ETCF_OPTIMIZED_FOR_SPEED at the same time.
- Not all texture formats are affected (usually those up to ECF_A8R8G8B8). */
- ETCF_ALWAYS_32_BIT = 0x00000002,
- /** Lets the driver decide in which format the textures are created and
- tries to make the textures look as good as possible. Usually it simply
- chooses the format in which the texture was stored on disk.
- When using this flag, it does not make sense to use the flags
- ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, or ETCF_OPTIMIZED_FOR_SPEED at
- the same time.
- Not all texture formats are affected (usually those up to ECF_A8R8G8B8). */
- ETCF_OPTIMIZED_FOR_QUALITY = 0x00000004,
- /** Lets the driver decide in which format the textures are created and
- tries to create them maximizing render speed.
- When using this flag, it does not make sense to use the flags
- ETCF_ALWAYS_16_BIT, ETCF_ALWAYS_32_BIT, or ETCF_OPTIMIZED_FOR_QUALITY,
- at the same time.
- Not all texture formats are affected (usually those up to ECF_A8R8G8B8). */
- ETCF_OPTIMIZED_FOR_SPEED = 0x00000008,
- /** Creates textures with mipmap levels.
- If disabled textures can not have mipmaps.
- Default is true. */
- ETCF_CREATE_MIP_MAPS = 0x00000010,
- /** Discard any alpha layer and use non-alpha color format.
- Warning: This may lead to getting 24-bit texture formats which
- are often badly supported by drivers. So it's generally
- not recommended to enable this flag. */
- ETCF_NO_ALPHA_CHANNEL = 0x00000020,
- //! Allow the Driver to use Non-Power-2-Textures
- /** BurningVideo can handle Non-Power-2 Textures in 2D (GUI), but not in 3D. */
- ETCF_ALLOW_NON_POWER_2 = 0x00000040,
- //! Allow the driver to keep a copy of the texture in memory
- /** Enabling this makes calls to ITexture::lock a lot faster, but costs main memory.
- Currently only used in combination with OpenGL drivers.
- NOTE: Disabling this does not yet work correctly with alpha-textures.
- So the default is on for now (but might change with Irrlicht 1.9 if we get the alpha-troubles fixed).
- */
- ETCF_ALLOW_MEMORY_COPY = 0x00000080,
- //! Enable automatic updating mip maps when the base texture changes.
- /** Default is true.
- This flag is only used when ETCF_CREATE_MIP_MAPS is also enabled and if the driver supports it.
- Please note:
- - On D3D (and maybe older OGL?) you can no longer manually set mipmap data when enabled
- (for example mips from image loading will be ignored).
- - On D3D (and maybe older OGL?) texture locking for mipmap levels usually won't work anymore.
- - On new OGL this flag is ignored.
- - When disabled you do _not_ get hardware mipmaps on D3D, so mipmap generation can be slower.
- - When disabled you can still update your mipmaps when the texture changed by manually calling regenerateMipMapLevels.
- - You can still call regenerateMipMapLevels when this flag is enabled (it will be a hint on d3d to update mips immediately)
- */
- ETCF_AUTO_GENERATE_MIP_MAPS = 0x00000100,
- //! Enable support for vertex shader texture sampling on some drivers
- /** Default is false.
- This adds a small costs to all texture switches.
- Currently only affects D3D9.
- On OpenGL vertex shaders use the same texture unit as pixel shaders, so support there only depends on GL version and not on this flag
- */
- ETCF_SUPPORT_VERTEXT_TEXTURE = 0x00000200,
- /** This flag is never used, it only forces the compiler to compile
- these enumeration values to 32 bit. */
- ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff
- };
- //! Enum for the mode for texture locking. Read-Only, write-only or read/write.
- enum E_TEXTURE_LOCK_MODE
- {
- //! The default mode. Texture can be read and written to.
- ETLM_READ_WRITE = 0,
- //! Read only. The texture is downloaded, but not uploaded again.
- /** Often used to read back shader generated textures. */
- ETLM_READ_ONLY,
- //! Write only. The texture is not downloaded and might be uninitialized.
- /** The updated texture is uploaded to the GPU.
- Used for initializing the shader from the CPU. */
- ETLM_WRITE_ONLY
- };
- //! Additional bitflags for ITexture::lock() call
- enum E_TEXTURE_LOCK_FLAGS
- {
- ETLF_NONE = 0,
- //! Flip left-bottom origin rendertarget textures upside-down
- /** Irrlicht usually has all textures with left-top as origin.
- And for drivers with a left-bottom origin coordinate system (OpenGL)
- Irrlicht modifies the texture-matrix in the fixed function pipeline to make
- the textures show up correctly (shader coders have to handle upside down
- textures themselves).
- But rendertarget textures (RTT's) are written by drivers the way the
- coordinate system of that driver works. So on OpenGL images tend to look
- upside down (aka Y coordinate going up) on lock() when this flag isn't set.
- When the flag is set it will flip such textures on lock() to make them look
- like non-rtt textures (origin left-top). Note that this also means the texture
- will be uploaded flipped on unlock. So mostly you want to have this flag set
- when you want to look at the texture or save it, but unset if you want to
- upload it again to the card.
- If you disable this flag you get the memory just as it is on the graphic card.
- For backward compatibility reasons this flag is enabled by default. */
- ETLF_FLIP_Y_UP_RTT = 1
- };
- //! Where did the last IVideoDriver::getTexture call find this texture
- enum E_TEXTURE_SOURCE
- {
- //! IVideoDriver::getTexture was never called (texture created otherwise)
- ETS_UNKNOWN,
- //! Texture has been found in cache
- ETS_FROM_CACHE,
- //! Texture had to be loaded
- ETS_FROM_FILE
- };
- //! Enumeration describing the type of ITexture.
- enum E_TEXTURE_TYPE
- {
- //! 2D texture.
- ETT_2D,
- //! Cubemap texture.
- ETT_CUBEMAP
- };
- //! Interface of a Video Driver dependent Texture.
- /** An ITexture is created by an IVideoDriver by using IVideoDriver::addTexture
- or IVideoDriver::getTexture. After that, the texture may only be used by this
- VideoDriver. As you can imagine, textures of the DirectX and the OpenGL device
- will, e.g., not be compatible. An exception is the Software device and the
- NULL device, their textures are compatible. If you try to use a texture
- created by one device with an other device, the device will refuse to do that
- and write a warning or an error message to the output buffer.
- */
- class ITexture : public virtual IReferenceCounted
- {
- public:
- //! constructor
- ITexture(const io::path& name, E_TEXTURE_TYPE type) : NamedPath(name), DriverType(EDT_NULL), OriginalColorFormat(ECF_UNKNOWN),
- ColorFormat(ECF_UNKNOWN), Pitch(0), HasMipMaps(false), IsRenderTarget(false), Source(ETS_UNKNOWN), Type(type)
- {
- }
- //! Lock function.
- /** Locks the Texture and returns a pointer to access the
- pixels. After lock() has been called and all operations on the pixels
- are done, you must call unlock(). Locks are not accumulating, hence one
- unlock will do for an arbitrary number of previous locks. You should avoid
- locking different levels without unlocking in between, because only the
- last level locked will be unlocked.
- The size of the i-th mipmap level is defined as max(getSize().Width>>i,1)
- and max(getSize().Height>>i,1).
- Except for textures of EDT_SOFTWARE driver which returns data for
- getOriginalSize(). Reason: Both original sized and modified sized textures are used
- in that driver depending on whether the texture is used in 2d or 3d.
- \param mode Specifies what kind of changes to the locked texture are
- allowed. Unspecified behavior will arise if texture is written in read
- only mode or read from in write only mode.
- Support for this feature depends on the driver, so don't rely on the
- texture being write-protected when locking with read-only, etc.
- \param mipmapLevel Number of the mipmapLevel to lock. 0 is main texture.
- Non-existing levels will silently fail and return 0.
- \param layer It determines which cubemap face or texture array layer should be locked.
- \param lockFlags See E_TEXTURE_LOCK_FLAGS documentation.
- \return Returns a pointer to the pixel data. The format of the pixel can
- be determined by using getColorFormat(). 0 is returned, if
- the texture cannot be locked. */
- virtual void* lock(E_TEXTURE_LOCK_MODE mode = ETLM_READ_WRITE, u32 mipmapLevel=0, u32 layer = 0, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) = 0;
- //! Unlock function. Must be called after a lock() to the texture.
- /** One should avoid to call unlock more than once before another lock.
- The last locked mip level will be unlocked.
- You may want to call regenerateMipMapLevels() after this when you changed any data. */
- virtual void unlock() = 0;
- //! Regenerates the mip map levels of the texture.
- /** Required after modifying the texture, usually after calling unlock().
- \param data Optional parameter to pass in image data which will be
- used instead of the previously stored or automatically generated mipmap
- data. The data has to be a continuous pixel data for all mipmaps until
- 1x1 pixel. Each mipmap has to be half the width and height of the previous
- level. At least one pixel will be always kept.
- \param layer It informs a texture about which cubemap or texture array layer
- needs mipmap regeneration. */
- virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) = 0;
- //! Get original size of the texture.
- /** The texture is usually scaled, if it was created with an unoptimal
- size. For example if the size was not a power of two. This method
- returns the size of the texture it had before it was scaled. Can be
- useful when drawing 2d images on the screen, which should have the
- exact size of the original texture. Use ITexture::getSize() if you want
- to know the real size it has now stored in the system.
- \return The original size of the texture. */
- const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; };
- //! Get dimension (=size) of the texture.
- /** \return The size of the texture. */
- const core::dimension2d<u32>& getSize() const { return Size; };
- //! Get driver type of texture.
- /** This is the driver, which created the texture. This method is used
- internally by the video devices, to check, if they may use a texture
- because textures may be incompatible between different devices.
- \return Driver type of texture. */
- E_DRIVER_TYPE getDriverType() const { return DriverType; };
- //! Get the color format of texture.
- /** \return The color format of texture. */
- ECOLOR_FORMAT getColorFormat() const { return ColorFormat; };
- //! Get the original color format
- /** When create textures from image data we will often use different color formats.
- For example depending on driver TextureCreationFlag's.
- This can give you the original format which the image used to create the texture had */
- ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; };
- //! Get pitch of the main texture (in bytes).
- /** The pitch is the amount of bytes used for a row of pixels in a
- texture.
- \return Pitch of texture in bytes. */
- u32 getPitch() const { return Pitch; };
- //! Check whether the texture has MipMaps
- /** \return True if texture has MipMaps, else false. */
- bool hasMipMaps() const { return HasMipMaps; }
- //! Check whether the texture is a render target
- /** Render targets can be set as such in the video driver, in order to
- render a scene into the texture. Once unbound as render target, they can
- be used just as usual textures again.
- \return True if this is a render target, otherwise false. */
- bool isRenderTarget() const { return IsRenderTarget; }
- //! Get name of texture (in most cases this is the filename)
- const io::SNamedPath& getName() const { return NamedPath; }
- //! Check where the last IVideoDriver::getTexture found this texture
- E_TEXTURE_SOURCE getSource() const { return Source; }
- //! Used internally by the engine to update Source status on IVideoDriver::getTexture calls.
- void updateSource(E_TEXTURE_SOURCE source) { Source = source; }
- //! Returns if the texture has an alpha channel
- bool hasAlpha() const
- {
- bool status = false;
- switch (ColorFormat)
- {
- case ECF_A8R8G8B8:
- case ECF_A1R5G5B5:
- case ECF_DXT1:
- case ECF_DXT2:
- case ECF_DXT3:
- case ECF_DXT4:
- case ECF_DXT5:
- case ECF_A16B16G16R16F:
- case ECF_A32B32G32R32F:
- status = true;
- break;
- default:
- break;
- }
- return status;
- }
- //! Returns the type of texture
- E_TEXTURE_TYPE getType() const { return Type; }
- protected:
- //! Helper function, helps to get the desired texture creation format from the flags.
- /** \return Either ETCF_ALWAYS_32_BIT, ETCF_ALWAYS_16_BIT,
- ETCF_OPTIMIZED_FOR_QUALITY, or ETCF_OPTIMIZED_FOR_SPEED. */
- inline E_TEXTURE_CREATION_FLAG getTextureFormatFromFlags(u32 flags)
- {
- if (flags & ETCF_OPTIMIZED_FOR_SPEED)
- return ETCF_OPTIMIZED_FOR_SPEED;
- if (flags & ETCF_ALWAYS_16_BIT)
- return ETCF_ALWAYS_16_BIT;
- if (flags & ETCF_ALWAYS_32_BIT)
- return ETCF_ALWAYS_32_BIT;
- if (flags & ETCF_OPTIMIZED_FOR_QUALITY)
- return ETCF_OPTIMIZED_FOR_QUALITY;
- return ETCF_OPTIMIZED_FOR_SPEED;
- }
- io::SNamedPath NamedPath;
- core::dimension2d<u32> OriginalSize;
- core::dimension2d<u32> Size;
- E_DRIVER_TYPE DriverType;
- ECOLOR_FORMAT OriginalColorFormat;
- ECOLOR_FORMAT ColorFormat;
- u32 Pitch;
- bool HasMipMaps;
- bool IsRenderTarget;
- E_TEXTURE_SOURCE Source;
- E_TEXTURE_TYPE Type;
- };
- } // end namespace video
- } // end namespace irr
- #endif
|