buffers. Renderbuffers and Textures can be attached to the logical buffers. At
least one image must be attached for the framebuffer to be usable.
-Requires the GL_EXT_framebuffer_object extension.
+Requires the GL_EXT_framebuffer_object extension. The blit functions require
+the GL_EXT_framebuffer_blit extension.
*/
class Framebuffer: public Bindable<Framebuffer>
{
void attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level = 0);
void detach(FramebufferAttachment attch);
- /**
- Checks the completeness status of the framebuffer. Returns
- FRAMEBUFFER_COMPLETE if the framebuffer is complate and can be rendered to,
- or one of the error status codes otherwise.
- */
+ /** Checks the completeness of the framebuffer. Returns
+ FRAMEBUFFER_COMPLETE if the framebuffer is complete and can be rendered to,
+ or one of the error status codes otherwise. */
FramebufferStatus check_status() const;
void clear(BufferBits);
- void blit_from(const Framebuffer &, int, int, int, int, int, int, int, int, BufferBits, bool);
- void blit_from(const Framebuffer &, int, int, unsigned, unsigned, int, int, BufferBits);
- void blit_from(const Framebuffer &, BufferBits, bool);
+
+ /** Blits a region from another framebuffer into this one. If the source
+ and destination regions have different dimensions, the contents will be
+ stretched. If filter is true, linear interpolation will be used, otherwise
+ no interpolation is done. */
+ void blit_from(const Framebuffer &other, int sx0, int sy0, int sx1, int sy1,
+ int dx0, int dy0, int dx1, int dy1, BufferBits bits, bool filter);
+
+ /** Blits a region from another framebuffer into this one, retaining its
+ dimensions. */
+ void blit_from(const Framebuffer & other, int sx, int sy,
+ unsigned wd, unsigned ht, int dx, int dy, BufferBits bits);
+
+ /** Blits the entire contents of another framebuffer into this one. */
+ void blit_from(const Framebuffer &other, BufferBits bits, bool filter);
void bind() const;
glDeleteRenderbuffersEXT(1, &id);
}
-void Renderbuffer::storage(PixelFormat fmt, unsigned w, unsigned h)
+void Renderbuffer::storage(PixelFormat fmt, unsigned wd, unsigned ht)
{
Bind _bind(this, true);
- width = w;
- height = h;
+ width = wd;
+ height = ht;
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, fmt, width, height);
}
-void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsigned w, unsigned h)
+void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsigned wd, unsigned ht)
{
static RequireExtension _ext("GL_EXT_framebuffer_multisample");
Bind _bind(this, true);
- width = w;
- height = h;
+ width = wd;
+ height = ht;
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, fmt, width, height);
}
/**
A Renderbuffer contains a single renderable image. It can be attached to a
Framebuffer to provide a logical buffer that is required to render the scene
-correctly but that is not needed as a texture later.
+correctly but that is not needed as a texture later. Renderbuffers also
+provide a capability for multisampling, which is not available in textures.
-Requires the GL_EXT_framebuffer_object extension.
+Requires the GL_EXT_framebuffer_object extension. Multisample renderbuffers
+additionally require the GL_EXT_framebuffer_multisample extension.
*/
class Renderbuffer: public Bindable<Renderbuffer>
{
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
- void storage(PixelFormat fmt, unsigned width, unsigned height);
- void storage_multisample(unsigned, PixelFormat fmt, unsigned, unsigned);
+ /** Allocates storage for the renderbuffer. */
+ void storage(PixelFormat fmt, unsigned wd, unsigned ht);
+
+ /** Allocates multisample storage for the renderbuffer. All attachments in
+ a framebuffer must have the same number of samples. To transfer the
+ contents to a texture for furter processing, use the framebuffer blit
+ functions.*/
+ void storage_multisample(unsigned samples, PixelFormat fmt, unsigned wd, unsigned ht);
void bind() const;
enum TextureFilter
{
- NEAREST = GL_NEAREST,
- LINEAR = GL_LINEAR,
+ /// No filtering
+ NEAREST = GL_NEAREST,
+
+ /// Bilinear filtering
+ LINEAR = GL_LINEAR,
+
+ /// Mipmapping without filtering
NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
- NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
- LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
- LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
+
+ /// Linear filtering between two mipmap levels
+ NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
+
+ /// Bilinear filtering on the closest mipmap level
+ LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
+
+ /// Trilinear filtering between two mipmap levels
+ LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
};
enum TextureWrap
{
- REPEAT = GL_REPEAT,
- CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
+ /// Tile the texture infinitely
+ REPEAT = GL_REPEAT,
+
+ /// Extend the texels at the edge of the texture to infinity
+ CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
+
+ /// Tile the texture, with every other repetition mirrored
MIRRORED_REPEAT = GL_MIRRORED_REPEAT
};
Base class for textures. This class only defines operations common for all
texture types and is not instantiable. For specifying images for textures, see
one of the dimensioned texture classes.
+
+A texture is generally rendered at a size that's either smaller or larger than
+its native size, so that the texture coordinates do not exactly correspond to
+the texels of the texture. The kind of filtering used, if any, is determined
+by the minification and magnification filter parameters. The default is LINEAR
+for magnification and NEAREST_MIPMAP_LINEAR for minification.
+
+When a mipmapped filter is in use, the texture consists of a stack of mipmap
+images. Level 0 is the base image. Each level above 0 has half the size of
+the previous level, rounded down and clamped to 1. The level with size 1 in
+all dimensions is the last mipmap level. All levels must be allocated for the
+texture to be usable.
+
+If texture coordinates fall outside of the principal range of the texture,
+wrapping is applied. The default for all directions is REPEAT.
*/
class Texture
{
public:
void set_min_filter(TextureFilter);
void set_mag_filter(TextureFilter);
+
+ /** Sets the wrapping mode for all coordinates. */
void set_wrap(TextureWrap);
+
void set_wrap_s(TextureWrap);
void set_wrap_t(TextureWrap);
void set_wrap_r(TextureWrap);
+
+ /** Sets automatic mipmap generation. If enabled, mipmaps are generated
+ when a texture image is uploaded. */
void set_generate_mipmap(bool);
+
+ /** Sets depth texture comparison. Has no effect on other formats. When
+ comparison is enabled, the third component of the texture coordinate is
+ compared against the texel value, and the result is returned as the texture
+ sample. */
void set_compare_enabled(bool);
+
+ /** Sets the function to use for depth comparison. */
void set_compare_func(Predicate);
+
GLenum get_target() const { return target; }
unsigned get_id() const { return id; }
namespace GL {
/**
-Two-dimensional texture class. This is the most common type of texture.
+Two-dimensional texture. Consists of an array of texels in the shape of a
+rectangle. Texture coordinate have a principal range of [0, 1]. This is the
+most common type of texture.
*/
class Texture2D: public Texture
{
public:
Texture2D();
- /**
- Defines the texture storage. This function may only be successfully called
- once.
- */
+ /** Defines storage structure for the texture. Must be called before an
+ image can be uploaded. Once storage is defined, it can't be changed. */
void storage(PixelFormat fmt, unsigned wd, unsigned ht);
- /** Allocates texture storage. If storage has already been allocated, this
- function does nothing. */
+ /** Allocates storage for the texture. The contents are initially
+ undefined. If storage has already been allocated, does nothing. */
void allocate(unsigned level);
- /** Uploads an image to the texture. storage() must have been called prior to
- this, and the image must have dimensions conforming to the specified
- storage. For level>0, mipmapping rules apply to the image dimensions. */
+ /** Uploads an image to the texture. Storage must be defined beforehand.
+ The image data must have dimensions and format compatible with the defined
+ storage. */
void image(unsigned level, PixelFormat fmt, DataType type, const void *data);
- /**
- Uploads a sub-image into the texture. Unlike full image upload, there are
- no constraints on the size of the sub-image.
- */
- void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data);
+ /** Updates a rectangular region of the texture. Storage must be defined
+ and allocated beforehand. The update region must be fully inside the
+ texture. */
+ void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht,
+ PixelFormat fmt, DataType type, const void *data);
- /**
- Loads an image from a file and uploads it to the texture. If storage() has
- not been called, the storage format will be set to match the loaded image.
- */
+ /** Loads an image from a file and uploads it to the texture. If storage
+ has not been defined, it will be set to match the loaded image. Otherwise
+ the image must be compatible with the defined storage. */
void load_image(const std::string &fn);
unsigned get_width() const { return width; }
static RequireVersion _ver(1, 2);
}
-void Texture3D::storage(PixelFormat f, unsigned w, unsigned h, unsigned d)
+void Texture3D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp)
{
if(width>0)
throw invalid_operation("Texture3D::storage");
- if(w==0 || h==0 || d==0)
+ if(wd==0 || ht==0 || dp==0)
throw invalid_argument("Texture3D::storage");
- width = w;
- height = h;
- depth = d;
- ifmt = f;
+ width = wd;
+ height = ht;
+ depth = dp;
+ ifmt = fmt;
}
void Texture3D::allocate(unsigned level)
namespace Msp {
namespace GL {
+/**
+Three-dimensional texture. Consists of an array of texels in the shape of a
+right cuboid. Texture coordinates have a principal range of [0, 1].
+*/
class Texture3D: public Texture
{
private:
public:
Texture3D();
- void storage(PixelFormat, unsigned, unsigned, unsigned);
- void allocate(unsigned);
- void image(unsigned, PixelFormat, DataType, const void *);
- void sub_image(unsigned, int, int, int, unsigned, unsigned, unsigned, PixelFormat, DataType, const void *);
+
+ /** Defines storage structure for the texture. Must be called before an
+ image can be uploaded. Once storage is defined, it can't be changed. */
+ void storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp);
+
+ /** Allocates storage for the texture. The contents are initially
+ undefined. If storage has already been allocated, does nothing. */
+ void allocate(unsigned level);
+
+ /** Uploads an image to the texture. Storage must be defined beforehand.
+ The image data must have dimensions and format compatible with the defined
+ storage. */
+ void image(unsigned level, PixelFormat fmt, DataType type, const void *data);
+
+ /** Updates a cuboid-shaped region of the texture. Storage must be defined
+ and allocated beforehand. The update region must be fully inside the
+ texture. */
+ void sub_image(unsigned level,
+ int x, int y, int z, unsigned wd, unsigned ht, unsigned dp,
+ PixelFormat fmt, DataType type, const void *data);
+
+ /** Loads an image from a file and uploads it to the texture. If storage
+ has not been defined, it will be set to match the loaded image. To
+ construct a three-dimensional texture from a two-dimensional image, the
+ image is interpreted as an array of consecutive images. If dp is -1, the
+ texture's width and height are equal. If dp is -2, the texture's height and
+ depth are equal. Otherwise, dp must be positive and determines the
+ texture's depth. In all cases, the image's height must equal the texture's
+ height times its depth. */
void load_image(const std::string &fn, int dp = -1);
+
unsigned get_width() const { return width; }
unsigned get_height() const { return height; }
unsigned get_depth() const { return depth; }
/**
Cube map texture, consisting of six square faces. All of the faces must be of
the same size. A cube map texture is addressed by three-dimensional texture
-coordinates. The face is first selected according to the largest coordinate,
-and the remaining two coordinates are used to sample the face image.
+coordinates, with a principal range of [-1, 1]. The face is first selected
+according to the largest coordinate, and the remaining two coordinates are used
+to sample the face image.
All faces of a cube map texture must be allocated for it to be usable.