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

- workaround for memory corruption, when a multisampled FBO is resized

- new TextureBuffer class in ACG for opengl texture buffers
- ACG Textures can now be bound to any texture slot by passing the texture unit to bind()

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@18398 383ad7c9-94d9-4d36-a494-682f7c89f535
parent af8f1470
......@@ -356,6 +356,17 @@ void FBO::resize( GLsizei _width, GLsizei _height, bool _forceResize )
{
rt->target = GL_TEXTURE_2D_MULTISAMPLE;
reattachTextures = true;
glDeleteTextures(1, &rt->id);
glGenTextures(1, &rt->id);
}
else if (rt->target == GL_TEXTURE_2D_MULTISAMPLE && samples_ == 0)
{
rt->target = GL_TEXTURE_2D;
reattachTextures = true;
glDeleteTextures(1, &rt->id);
glGenTextures(1, &rt->id);
}
#endif // GL_ARB_texture_multisample
......@@ -366,14 +377,37 @@ void FBO::resize( GLsizei _width, GLsizei _height, bool _forceResize )
if (!samples_)
glTexImage2D(rt->target, 0, rt->internalFormat, _width, _height, 0, rt->format, rt->format == GL_DEPTH_STENCIL ? GL_UNSIGNED_INT_24_8 : GL_FLOAT, 0);
else
glTexImage2DMultisample(rt->target, samples_, rt->internalFormat, _width, _height, fixedsamplelocation_);
{
// Resizing directly by calling glTexImage2DMultisample leads to corrupted memory and weird runtime behaviour.
// Workaround: delete and alloc texture buffer manually and reattach to fbo.
// Maybe caused by unfinished render jobs or opengl driver bug
glDeleteTextures(1, &rt->id);
glGenTextures(1, &rt->id);
glBindTexture(rt->target, rt->id);
glTexImage2DMultisample(rt->target, samples_, rt->internalFormat, _width, _height, fixedsamplelocation_);
reattachTextures = true;
}
#else
glTexImage2D(rt->target, 0, rt->internalFormat, _width, _height, 0, rt->format, rt->format == GL_DEPTH_STENCIL ? GL_UNSIGNED_INT_24_8 : GL_FLOAT, 0);
#endif // GL_ARB_texture_multisample
}
// resize depth renderbuffer
if (depthbuffer_)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer_);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, _width, _height);
}
// resize stencil renderbuffer
if (stencilbuffer_)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencilbuffer_);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, _width, _height);
}
// store new size
width_ = _width;
height_ = _height;
......@@ -406,7 +440,7 @@ void FBO::setMultisampling( GLsizei _samples, GLboolean _fixedsamplelocations /*
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
if (_samples > maxSamples) _samples = maxSamples;
if (_samples >= maxSamples) _samples = maxSamples - 1;
// issue texture reloading when params changed
bool reloadTextures = (samples_ != _samples || fixedsamplelocation_ != _fixedsamplelocations);
......
......@@ -57,6 +57,7 @@
// GL
#include <ACG/GL/gl.hh>
#include <ACG/GL/GLState.hh>
// C++
#include <iostream>
......@@ -187,18 +188,23 @@ public:
virtual ~Texture() { del(); }
void bind()
void bind(GLenum _unit)
{
if(!valid) gen();
activate();
activate(_unit);
ACG::GLState::bindTexture(target, texture);
}
void activate()
void activate(GLenum _unit)
{
if (unit != GL_NONE) ACG::GLState::activeTexture(unit);
if (_unit != GL_NONE) ACG::GLState::activeTexture(_unit);
}
void bind() { bind(unit); }
void activate() { activate(unit); }
void parameter(GLenum pname, GLint i)
{
activate();
......@@ -247,6 +253,7 @@ public:
GLuint id() const { return texture; }
void setUnit(GLenum u) {unit = u;}
GLenum getUnit() const { return unit; }
private:
......@@ -336,6 +343,58 @@ public:
#endif
#if defined(GL_ARB_texture_buffer_object)
class TextureBuffer : public Texture
{
public:
TextureBuffer(GLenum u=GL_NONE)
: Texture(GL_TEXTURE_BUFFER, u), buffer_(0), bufferSize_(0) {}
~TextureBuffer()
{
if (buffer_)
glDeleteBuffers(1, &buffer_);
}
// _size size in bytes of buffer data
// _data buffer data
// _internalFormat format of buffer - http://www.opengl.org/sdk/docs/man3/xhtml/glTexBuffer.xml
// _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)
{
// setup buffer object
if (!buffer_)
glGenBuffers(1, &buffer_);
glBindBuffer(GL_TEXTURE_BUFFER, buffer_);
glBufferData(GL_TEXTURE_BUFFER, _size, _data, _usage);
// bind buffer to texture
if (getUnit() == GL_NONE)
setUnit(GL_TEXTURE0);
bind();
glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, buffer_);
bufferSize_ = _size;
}
int getBufferSize() const {return bufferSize_;}
GLuint getBufferId() const {return buffer_;}
private:
int bufferSize_;
GLuint buffer_;
};
#endif
//== CLASS DEFINITION =========================================================
......
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