Commit df8f9c8c authored by Christopher Tenter's avatar Christopher Tenter
Browse files

refactoring textures

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20048 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 3607a75a
......@@ -57,7 +57,106 @@ namespace ACG {
//-----------------------------------------------------------------------------
Texture::Texture( GLenum tgt, GLenum _unit )
: target(tgt), unit(_unit), valid(false), texture(0u), internalFormat_(0)
{
}
void Texture::bindAsImage(GLuint _index, GLenum _access)
{
#if defined(GL_ARB_shader_image_load_store)
if (is_valid())
glBindImageTexture(_index, id(), 0, GL_FALSE, 0, _access, getInternalFormat());
else
std::cerr << "Texture::bindAsImage - error: texture not initialized!" << std::endl;
#else
std::cerr << "Texture::bindAsImage - glBindImageTexture symbol not loaded!" << std::endl;
#endif
}
GLint Texture::getInternalFormat()
{
if (!internalFormat_)
{
bind();
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat_);
}
return internalFormat_;
}
//
// bool Texture::clear( float _color )
// {
// #ifdef GL_ARB_clear_texture
// if (supportsClearTexture() && texture)
// {
// glClearTexImage(texture, 0, GL_R32F, GL_FLOAT, &_color);
// return true;
// }
// #endif
// return false;
// }
//
// bool Texture::clear( const ACG::Vec2f& _color )
// {
// #ifdef GL_ARB_clear_texture
// if (supportsClearTexture() && texture)
// {
// glClearTexImage(texture, 0, GL_RG32F, GL_FLOAT, _color.data());
// return true;
// }
// #endif
// return false;
// }
//
// bool Texture::clear( const ACG::Vec3f& _color )
// {
// #ifdef GL_ARB_clear_texture
// if (supportsClearTexture() && texture)
// {
// glClearTexImage(texture, 0, GL_RGB32F, GL_FLOAT, _color.data());
// return true;
// }
// #endif
// return false;
// }
bool Texture::clear( const ACG::Vec4f& _color )
{
#ifdef GL_ARB_clear_texture
if (supportsClearTexture() && texture)
{
glClearTexImage(texture, 0, GL_RGBA, GL_FLOAT, _color.data());
return true;
}
#endif
return false;
}
bool Texture::clear( const ACG::Vec4ui& _color )
{
#ifdef GL_ARB_clear_texture
if (supportsClearTexture() && texture)
{
glClearTexImage(texture, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, _color.data());
return true;
}
#endif
return false;
}
bool Texture::clear( const ACG::Vec4i& _color )
{
#ifdef GL_ARB_clear_texture
if (supportsClearTexture() && texture)
{
glClearTexImage(texture, 0, GL_RGBA_INTEGER, GL_INT, _color.data());
return true;
}
#endif
return false;
}
bool Texture::supportsImageLoadStore()
{
......@@ -97,12 +196,106 @@ bool Texture::supportsTextureBuffer()
}
bool Texture::supportsClearTexture()
{
static int status = -1;
if (status < 0)
{
#if defined(GL_ARB_clear_texture)
status = checkExtensionSupported("ARB_clear_texture");
#else
// symbol missing, install latest glew version
status = 0;
#endif
}
return status > 0;
}
//-----------------------------------------------------------------------------
Texture1D::Texture1D( GLenum unit ) : Texture(GL_TEXTURE_1D, unit),
width_(0),
format_(0), type_(0)
{}
void Texture1D::setData(GLint _level,
GLint _internalFormat,
GLsizei _width,
GLenum _format,
GLenum _type,
const GLvoid* _data) {
bind();
glTexImage1D(GL_TEXTURE_1D, _level, _internalFormat, _width, 0, _format, _type, _data);
width_ = _width;
internalFormat_ = _internalFormat;
format_ = _format;
type_ = _type;
}
void Texture1D::setStorage( GLsizei _levels, GLenum _internalFormat, GLsizei _width ) {
#ifdef GL_ARB_texture_storage
bind();
glTexStorage1D(GL_TEXTURE_1D, _levels, _internalFormat, _width);
width_ = _width;
internalFormat_ = _internalFormat;
GLFormatInfo finfo(_internalFormat);
format_ = finfo.format();
type_ = finfo.type();
#endif // GL_ARB_texture_storage
}
bool Texture1D::getData( GLint _level, void* _dst ) {
if (is_valid()) {
GLint curTex = 0;
glGetIntegerv(GL_TEXTURE_BINDING_1D, &curTex);
bind();
glGetTexImage(GL_TEXTURE_1D, _level, format_, type_, _dst);
glBindTexture(GL_TEXTURE_1D, curTex);
return true;
}
return false;
}
bool Texture1D::getData( GLint _level, std::vector<char>& _dst ) {
if (is_valid()) {
GLFormatInfo finfo(internalFormat_);
if (finfo.isValid()) {
size_t bufSize = finfo.elemSize() * width_;
if (_dst.size() < bufSize)
_dst.resize(bufSize);
if (!_dst.empty())
return getData(_level, &_dst[0]);
}
}
return false;
}
//-----------------------------------------------------------------------------
Texture2D::Texture2D(GLenum unit)
: Texture(GL_TEXTURE_2D, unit),
width_(0), height_(0),
internalFormat_(0),
format_(0), type_(0)
{}
......@@ -181,18 +374,6 @@ bool Texture2D::getData( GLint _level, std::vector<char>& _dst ) {
void Texture2D::bindAsImage(GLuint _index, GLenum _access){
#if defined(GL_ARB_shader_image_load_store)
if (is_valid())
glBindImageTexture(_index, id(), 0, GL_FALSE, 0, _access, internalFormat_);
else
std::cerr << "Texture2D::bindAsImage - error: texture not initialized!" << std::endl;
#else
std::cerr << "Texture2D::bindAsImage - glBindImageTexture symbol not loaded!" << std::endl;
#endif
}
bool Texture2D::loadFromFile( const std::string& _filename, GLenum _minFilter, GLenum _magFilter )
{
bool success = false;
......@@ -296,6 +477,57 @@ bool Texture2D::loadFromFile( const std::string& _filename, GLenum _minFilter, G
}
void Texture2D::loadRandom( GLint _internalFormat, GLsizei _width, GLsizei _height )
{
ACG::GLFormatInfo finfo(_internalFormat);
if (finfo.isValid() && _width && _height)
{
int n = _width * _height * finfo.channelCount();
GLvoid* dataPtr = 0;
std::vector<float> randF;
std::vector<int> randI;
GLenum gltype = 0;
if (finfo.isFloat() || finfo.isNormalized())
{
randF.resize(n);
bool isSigned = finfo.isInt();
for (int i = 0; i < n; ++i)
{
float r = float(rand()) / float(RAND_MAX);
if (isSigned)
r = r * 2.0f - 1.0f;
randF[i] = r;
}
dataPtr = &randF[0];
gltype = GL_FLOAT;
}
else
{
randI.resize(n);
for (int i = 0; i < n; ++i)
randI[i] = rand();
dataPtr = &randI[0];
gltype = GL_INT;
}
bind();
setData(0, _internalFormat, _width, _height, finfo.format(), gltype, dataPtr);
}
}
//-----------------------------------------------------------------------------
......@@ -411,22 +643,6 @@ bool TextureBuffer::getBufferData(std::vector<char>& _dst) {
return false;
}
void TextureBuffer::bindAsImage(GLuint _index, GLenum _access){
#if defined(GL_ARB_texture_buffer_object)
#if defined(GL_ARB_shader_image_load_store)
if (id())
glBindImageTexture(_index, id(), 0, GL_FALSE, 0, _access, fmt_);
else
std::cerr << "TextureBuffer::bindAsImage - error: texture not initialized!" << std::endl;
#else
std::cerr << "TextureBuffer::bindAsImage - glBindImageTexture symbol not loaded!" << std::endl;
#endif
#endif
}
//-----------------------------------------------------------------------------
......
......@@ -237,9 +237,7 @@ class ACGDLLEXPORT Texture
{
public:
Texture(GLenum tgt, GLenum _unit=GL_NONE)
: target(tgt), unit(_unit), valid(false), texture(0u)
{}
Texture(GLenum tgt, GLenum _unit=GL_NONE);
virtual ~Texture() { del(); }
......@@ -312,28 +310,77 @@ public:
GLenum getUnit() const { return unit; }
GLenum getTarget() const {return target;}
// note: might bind the texture in order to find the format
GLint getInternalFormat();
// check supportsClearTexture to find out whether clear is supported (ARB_clear_texture)
// clear does not work for buffer textures!
// clear normalized / floating point texture
bool clear(const ACG::Vec4f& _color);
// clear integer texture
bool clear(const ACG::Vec4i& _color);
bool clear(const ACG::Vec4ui& _color);
// use texture as image load/store (equivalent of unordered access buffers in dx11)
// allows data scattering operations in shader ie. random read/write access
// ref: https://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt
// _index zero-based image unit
// _access access operations in shader: GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY
// requires opengl 4.2
void bindAsImage(GLuint _index, GLenum _access);
// test for shader_image_load_store support
static bool supportsImageLoadStore();
// test for texture buffer support
static bool supportsTextureBuffer();
// test for clear_texture support
static bool supportsClearTexture();
private:
GLenum target, unit;
bool valid;
GLuint texture;
protected:
GLint internalFormat_;
};
//-----------------------------------------------------------------------------
class Texture1D : public Texture
class ACGDLLEXPORT Texture1D : public Texture
{
public:
Texture1D(GLenum unit=GL_NONE) : Texture(GL_TEXTURE_1D, unit) {}
Texture1D(GLenum unit=GL_NONE);
// initialize and set texture data via glTexImage1D
void setData(GLint _level, GLint _internalFormat, GLsizei _width, GLenum _format, GLenum _type, const GLvoid* _data);
// specify storage of texture (OpenGL 4.2)
// use setData with a nullptr instead if 4.2 is not available
void setStorage(GLsizei _levels, GLenum _internalFormat, GLsizei _width);
// get params from glTexImage1D
GLsizei getWidth() const {return width_;}
GLenum getFormat() const {return format_;}
GLenum getType() const {return type_;}
// read data back to sysmem
bool getData(GLint _level, void* _dst);
bool getData(GLint _level, std::vector<char>& _dst);
private:
GLsizei width_;
GLenum format_, type_;
};
......@@ -357,18 +404,12 @@ public:
// additionally supports dds if the gli library is available while building ACG
bool loadFromFile(const std::string& _filename, GLenum _minFilter = GL_NEAREST_MIPMAP_LINEAR, GLenum _magFilter = GL_LINEAR);
// use texture as image load/store (equivalent of unordered access buffers in dx11)
// allows data scattering operations in shader ie. random read/write access
// ref: https://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt
// _index zero-based image unit
// _access access operations in shader: GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY
// requires opengl 4.2
void bindAsImage(GLuint _index, GLenum _access);
// initialize and fill with uniform random data in [0,1] (or [-1,1] for signed formats)
void loadRandom(GLint _internalFormat, GLsizei _width, GLsizei _height);
// get params from glTexImage2D
GLsizei getWidth() const {return width_;}
GLsizei getHeight() const {return height_;}
GLint getInternalFormat() const {return internalFormat_;}
GLenum getFormat() const {return format_;}
GLenum getType() const {return type_;}
......@@ -379,7 +420,6 @@ public:
private:
GLsizei width_, height_;
GLint internalFormat_;
GLenum format_, type_;
};
......@@ -457,14 +497,6 @@ public:
// _usage buffer usage hint - https://www.opengl.org/sdk/docs/man3/xhtml/glBufferData.xml
void setBufferData(int _size, const void* _data, GLenum _internalFormat, GLenum _usage = GL_STATIC_DRAW);
// use buffer as image load/store (equivalent of unordered access buffers in dx11)
// allows data scattering operations in shader
// ref: https://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt
// _index image unit
// _access access operations in shader: GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY
// requires opengl 4.2
void bindAsImage(GLuint _index, GLenum _access);
int getBufferSize() const {return bufferSize_;}
GLuint getBufferId() const {return buffer_;}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment