mitsuba/include/mitsuba/hw/gputexture.h

376 lines
11 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2011 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__GPUTEXTURE_H)
#define __GPUTEXTURE_H
#include <mitsuba/core/bitmap.h>
#include <set>
MTS_NAMESPACE_BEGIN
/** \brief A data structure for 1/2/3D and cube texture mapping. Also
* has optional render-to-texture functionality.
* \ingroup libhw
*/
class MTS_EXPORT_HW GPUTexture : public Object {
public:
/// Available texture types
enum ETextureType {
/**
* \brief 1-D texture, useful for the storage of pre-calculated functions
* in conjunction with pixel shaders. Needs 1D texture coordinates
*/
ETexture1D = 0,
/// Default 2D texture format, needs 2D texture coordinates
ETexture2D,
/// 3D volume texture format, needs 3D texture coordinates
ETexture3D,
/// 3D cube map texture format, needs 3D texture coordinates
ETextureCubeMap
};
/** \brief If the texture type is set to EFrameBuffer, the
* configuration must be one of the following constants */
enum EFrameBufferType {
/// This is not a framebuffer
ENone = 0x00,
/**
* \brief Color framebuffer (\a including an internal depth
* buffer that cannot be accessed as a texture)
*/
EColorBuffer = 0x01,
/// Depth-only framebuffer (e.g. for shadow mapping)
EDepthBuffer = 0x02,
/// Color and texture framebuffer (both exposed as textures)
EColorAndDepthBuffer = 0x03
};
/// A texture has one more slots into which bitmaps can be placed
enum ETexturePosition {
/// Default slot for 1,2,3D textures
EDefaultPosition = 0,
/// Cube map: +X plane, Right
ECubeMapPositiveX = 0,
/// Cube map: -X plane, Left
ECubeMapNegativeX,
/// Cube map: +Y plane, Top
ECubeMapPositiveY,
/// Cube map: -Y plane, Bottom
ECubeMapNegativeY,
/// Cube map: +Z plane, Front
ECubeMapPositiveZ,
/// Cube map: -Z plane, Back
ECubeMapNegativeZ,
ELastPosition
};
/** \brief Texture wrapping mode when texture coordinates
* exit the [0, 1] range
*/
enum EWrapType {
/// Clamp the coordinates to [0, 1]
EClamp = 0,
/// Similar to EClamp, but prevents mixing at the edges
EClampToEdge,
/// Similar to EClamp
EClampToBorder,
/// Modulo 1 operation (default)
ERepeat,
/// Mirror the coordinates at the edges
EMirroredRepeat
};
/// The texture pixel format
enum ETextureFormat {
/// RGB color values (each 8 bit)
ER8G8B8 = 0,
/// RGBA color values (each 8 bit)
ER8G8B8A8,
/// 8-bit luminance
EL8,
/// 8-bit luminance + alpha
EL8A8,
/// Depth component
EDepth,
/// Floating point luminance (16 bit)
EFloat16L,
/// Floating point RGB (16 bit)
EFloat16RGB,
/// Floating point RGBA (16 bit)
EFloat16RGBA,
/// Floating point luminance (32 bit)
EFloat32L,
/// Floating point RGB (32 bit)
EFloat32RGB,
/// Floating point RGBA (32 bit)
EFloat32RGBA
};
/** \brief The interpolation filter determines which texture
* pixels are considered when shading a fragment
*/
enum EFilterType {
/// Use the color value of the closest pixel
ENearest = 0,
/// Use 4 surrounding pixels and weigh them
ELinear,
/**
* Blend the color values of the closest matching
* mipmaps and use nearest filtering
*/
EMipMapNearest,
/**
* Blend the color values of the closest matching
* mipmaps and use linear filtering (aka. bilinear)
*/
EMipMapLinear
};
/**
* \brief When this texture contains a depth buffer, the
* following modes control the read behavior of the
* associated texture unit. 'ENormal' means that texture
* values are returned as with any other texture, whereas
* 'ECompare' causes a depth comparison to take place
* (this is the default).
*/
enum EDepthMode {
ENormal,
ECompare
};
/** \brief Construct a new texture.
*
* If bitmap is non-NULL, the texture type, format
* will be automatically set
*
* \param name A human-readable name (for debugging)
* \param bitmap An bitmap to be put into the first
* slot. A NULL value will be ignored.
*/
GPUTexture(const std::string &name, Bitmap *bitmap);
/// Set the texture name
inline void setName(const std::string &name) { m_name = name; }
/// Get the texture name
inline const std::string &getName() const { return m_name; }
/// Set the texture type
inline void setType(ETextureType textureType) { m_type = textureType; }
/// Return the texture type
inline ETextureType getType() const { return m_type; }
/// Set the framebuffer type (applies only if type==EFrameBuffer)
void setFrameBufferType(EFrameBufferType frameBufferType);
/// Return the framebuffer type (applies only if type==EFrameBuffer)
inline EFrameBufferType getFrameBufferType() const { return m_fbType; }
/// Set the texture format
inline void setFormat(ETextureFormat textureFormat) { m_format = textureFormat; }
/// Return the texture format
inline ETextureFormat getFormat() const { return m_format; }
/// Set the filter type
inline void setFilterType(EFilterType filterType) { m_filterType = filterType; }
/// Return the filter type
inline EFilterType getFilterType() const { return m_filterType; }
/// Set the wrap type
inline void setWrapType(EWrapType wrapType) { m_wrapType = wrapType; }
/// Return the wrap type
inline EWrapType getWrapType() const { return m_wrapType; }
/// Return the size in pixels
inline Point3i getSize() const { return m_size; }
/// Set the size in pixels
inline void setSize(const Point3i &size) { m_size = size; }
/// Get the maximal anisotropy
inline Float getMaxAnisotropy() const { return m_maxAnisotropy; }
/** \brief Set the maximal anisotropy.
*
* A value of 1 will result in isotropic
* texture filtering. A value of 0 (default) will
* use the global max. anisotropy value
*/
inline void setMaxAnisotropy(Float maxAnisotropy) { m_maxAnisotropy = maxAnisotropy; }
/// Return whether mipmapping is enabled
inline bool isMipMapped() const { return m_mipmapped; }
/// Define whether mipmapping is enabled
inline void setMipMapped(bool mipMapped) { m_mipmapped = mipMapped; }
/// Return the depth map read mode
inline EDepthMode getDepthMode() const { return m_depthMode; }
/// Set the depth map read mode
inline void setDepthMode(EDepthMode mode) { m_depthMode = mode; }
/// Store a bitmap in a bitmap slot
void setBitmap(unsigned int slot, Bitmap *bitmap);
/// Retrieve a bitmap from the given slot
Bitmap *getBitmap(unsigned int slot = EDefaultPosition);
/// Retrieve a bitmap from the given slot
const Bitmap *getBitmap(unsigned int slot = EDefaultPosition) const;
/// Return the number of stored bitmaps
inline int getBitmapCount() const { return (int) m_bitmaps.size(); }
/// Upload the texture
virtual void init() = 0;
/// Refresh (re-upload) the texture
virtual void refresh() = 0;
/**
* This following applies only when textures are
* shared between threads while doing multi-context
* rendering. In this case, disassociate() needs to
* be called once by each thread that used this
* texture before finally freeing it using cleanup().
*/
void disassociate();
/// Free the texture from GPU memory
virtual void cleanup() = 0;
/**
* \brief Bind the texture and enable texturing
*
* \param textureUnit
* Specifies the unit to which this texture should be bound
* \param textureIndex
* When this texture has multiple sub-textures (e.g.
* a color and depth map in the case of a
* \ref EColorAndDepthBuffer texture), this parameter
* specifies the one to be bound
*/
virtual void bind(int textureUnit = 0, int textureIndex = 0) const = 0;
/// Unbind the texture and disable texturing
virtual void unbind() const = 0;
/**
* Download the texture (only for render target textures).
* When the 'bitmap' parameter is NULL, the destination is
* the internal bitmap given by getTexture(0)
*/
virtual void download(Bitmap *bitmap = NULL) = 0;
/// Activate the render target
virtual void activateTarget() = 0;
/// Activate a certain face of a cube map as render target
virtual void activateSide(int side) = 0;
/// Restrict rendering to a sub-region of the texture
virtual void setTargetRegion(const Point2i &offset, const Vector2i &size) = 0;
/// Deactivate the render target
virtual void releaseTarget() = 0;
/// Return the texture units, to which this texture is currently bound
inline const std::set<int> &getTextureUnits() const { return m_textureUnits.get(); }
/// Set the number of samples (for multisample color render targets)
inline void setSampleCount(int samples) { m_samples = samples; }
/// Return the number of samples (for multisample color render targets)
inline int getSampleCount() const { return m_samples; }
/**
* \brief Blit a render buffer into another render buffer
*
* \param target
* Specifies the target render buffer
* \param what
* A bitwise-OR of the components in \ref EFrameBufferType to copy
*/
virtual void blit(GPUTexture *target, int what) const = 0;
/**
* \brief Blit a render buffer into another render buffer
*
* \param target
* Specifies the target render buffer (or NULL for the framebuffer)
* \param what
* A bitwise-OR of the components in \ref EFrameBufferType to copy
* \param sourceOffset
* Offset in the source render buffer
* \param sourceOffset
* Size of the region to be copied from the source render buffer
* \param destOffset
* Offset in the destination render buffer
* \param destOffset
* Size of the region to be copied into the dest destination buffer
*/
virtual void blit(GPUTexture *target, int what, const Point2i &sourceOffset,
const Vector2i &sourceSize, const Point2i &destOffset,
const Vector2i &destSize) const = 0;
/// Clear (assuming that this is a render buffer)
virtual void clear() = 0;
/// Assuming that this is a 2D RGB framebuffer, read a single pixel from the GPU
virtual Spectrum getPixel(int x, int y) const = 0;
/// Return a string representation
std::string toString() const;
MTS_DECLARE_CLASS()
protected:
/// Virtual destructor
virtual ~GPUTexture();
protected:
std::string m_name;
ETextureType m_type;
ETextureFormat m_format;
EFilterType m_filterType;
EWrapType m_wrapType;
EFrameBufferType m_fbType;
EDepthMode m_depthMode;
bool m_mipmapped;
mutable PrimitiveThreadLocal<std::set<int> > m_textureUnits;
Float m_maxAnisotropy;
int m_samples;
std::vector<Bitmap *> m_bitmaps;
Point3i m_size;
};
MTS_NAMESPACE_END
#endif /* __GPUTEXTURE_H */