mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
connecting the dots for a framebuffer GLBackend, need to be tested
This commit is contained in:
parent
05689c0413
commit
51ce3129b9
3 changed files with 119 additions and 23 deletions
|
@ -36,7 +36,7 @@ Framebuffer* Framebuffer::create( const Format& colorBufferFormat, const Format&
|
|||
auto depthTexture = TexturePointer(Texture::create2D(depthStencilBufferFormat, width, height));
|
||||
|
||||
framebuffer->setRenderBuffer(0, colorTexture);
|
||||
framebuffer->setDepthStencilBuffer(depthTexture);
|
||||
framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat);
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
@ -54,10 +54,6 @@ uint32 Framebuffer::getFrameCount() const {
|
|||
}
|
||||
}
|
||||
|
||||
bool Framebuffer::isEmpty() const {
|
||||
return (_buffersMask == 0);
|
||||
}
|
||||
|
||||
bool Framebuffer::validateTargetCompatibility(const Texture& texture, uint32 subresource) const {
|
||||
if (texture.getType() == Texture::TEX_1D) {
|
||||
return false;
|
||||
|
@ -161,9 +157,9 @@ int Framebuffer::setRenderBuffer(uint32 slot, const TexturePointer& texture, uin
|
|||
|
||||
// update the mask
|
||||
int mask = (1<<slot);
|
||||
_buffersMask = (_buffersMask & ~(mask));
|
||||
_bufferMask = (_bufferMask & ~(mask));
|
||||
if (texture) {
|
||||
_buffersMask |= mask;
|
||||
_bufferMask |= mask;
|
||||
}
|
||||
|
||||
return slot;
|
||||
|
@ -174,7 +170,7 @@ void Framebuffer::removeRenderBuffers() {
|
|||
return;
|
||||
}
|
||||
|
||||
_buffersMask = _buffersMask & BUFFER_DEPTHSTENCIL;
|
||||
_bufferMask = _bufferMask & BUFFER_DEPTHSTENCIL;
|
||||
|
||||
for (auto renderBuffer : _renderBuffers) {
|
||||
renderBuffer._texture.reset();
|
||||
|
@ -209,7 +205,7 @@ uint32 Framebuffer::getRenderBufferSubresource(uint32 slot) const {
|
|||
}
|
||||
}
|
||||
|
||||
bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, uint32 subresource) {
|
||||
bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource) {
|
||||
if (isSwapchain()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -224,11 +220,11 @@ bool Framebuffer::setDepthStencilBuffer(const TexturePointer& texture, uint32 su
|
|||
updateSize(texture);
|
||||
|
||||
// assign the new one
|
||||
_depthStencilBuffer = TextureView(texture, subresource);
|
||||
_depthStencilBuffer = TextureView(texture, subresource, format);
|
||||
|
||||
_buffersMask = ( _buffersMask & ~BUFFER_DEPTHSTENCIL);
|
||||
_bufferMask = ( _bufferMask & ~BUFFER_DEPTHSTENCIL);
|
||||
if (texture) {
|
||||
_buffersMask |= BUFFER_DEPTHSTENCIL;
|
||||
_bufferMask |= BUFFER_DEPTHSTENCIL;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -249,3 +245,12 @@ uint32 Framebuffer::getDepthStencilBufferSubresource() const {
|
|||
return _depthStencilBuffer._subresource;
|
||||
}
|
||||
}
|
||||
|
||||
Format Framebuffer::getDepthStencilBufferFormat() const {
|
||||
if (isSwapchain()) {
|
||||
// return getSwapchain()->getDepthStencilBufferFormat();
|
||||
return _depthStencilBuffer._element;
|
||||
} else {
|
||||
return _depthStencilBuffer._element;
|
||||
}
|
||||
}
|
|
@ -123,20 +123,24 @@ public:
|
|||
uint32 getFrameCount() const;
|
||||
|
||||
// Render buffers
|
||||
int32 setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource = 0);
|
||||
void removeRenderBuffers();
|
||||
uint32 getNumRenderBuffers() const;
|
||||
const TextureViews& getRenderBuffers() const { return _renderBuffers; }
|
||||
|
||||
int32 setRenderBuffer(uint32 slot, const TexturePointer& texture, uint32 subresource = 0);
|
||||
TexturePointer getRenderBuffer(uint32 slot) const;
|
||||
uint32 getRenderBufferSubresource(uint32 slot) const;
|
||||
|
||||
bool setDepthStencilBuffer(const TexturePointer& texture, uint32 subresource = 0);
|
||||
bool setDepthStencilBuffer(const TexturePointer& texture, const Format& format, uint32 subresource = 0);
|
||||
TexturePointer getDepthStencilBuffer() const;
|
||||
uint32 getDepthStencilBufferSubresource() const;
|
||||
Format getDepthStencilBufferFormat() const;
|
||||
|
||||
// Properties
|
||||
uint32 getBuffersMask() const { return _buffersMask; }
|
||||
bool isEmpty() const;
|
||||
uint32 getBufferMask() const { return _bufferMask; }
|
||||
bool isEmpty() const { return (_bufferMask == 0); }
|
||||
bool hasColor() const { return (getBufferMask() & BUFFER_COLORS); }
|
||||
bool hasDepthStencil() const { return (getBufferMask() & BUFFER_DEPTHSTENCIL); }
|
||||
|
||||
bool validateTargetCompatibility(const Texture& texture, uint32 subresource = 0) const;
|
||||
|
||||
|
@ -162,7 +166,7 @@ protected:
|
|||
uint16 _height;
|
||||
uint16 _numSamples;
|
||||
|
||||
uint32 _buffersMask;
|
||||
uint32 _bufferMask;
|
||||
|
||||
uint32 _frameCount;
|
||||
|
||||
|
|
|
@ -35,15 +35,102 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe
|
|||
|
||||
// need to have a gpu object?
|
||||
if (!object) {
|
||||
object = new GLFramebuffer();
|
||||
glGenFramebuffers(1, &object->_fbo);
|
||||
GLuint fbo;
|
||||
glGenFramebuffers(1, &fbo);
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
|
||||
unsigned int nbColorBuffers = 0;
|
||||
GLenum colorBuffers[16];
|
||||
if (framebuffer.hasColor()) {
|
||||
static const GLenum colorAttachments[] = {
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3,
|
||||
GL_COLOR_ATTACHMENT4,
|
||||
GL_COLOR_ATTACHMENT5,
|
||||
GL_COLOR_ATTACHMENT6,
|
||||
GL_COLOR_ATTACHMENT7,
|
||||
GL_COLOR_ATTACHMENT8,
|
||||
GL_COLOR_ATTACHMENT9,
|
||||
GL_COLOR_ATTACHMENT10,
|
||||
GL_COLOR_ATTACHMENT11,
|
||||
GL_COLOR_ATTACHMENT12,
|
||||
GL_COLOR_ATTACHMENT13,
|
||||
GL_COLOR_ATTACHMENT14,
|
||||
GL_COLOR_ATTACHMENT15 };
|
||||
|
||||
int unit = 0;
|
||||
for (auto& b : framebuffer.getRenderBuffers()) {
|
||||
auto surface = b._texture;
|
||||
if (surface) {
|
||||
auto gltexture = GLBackend::syncGPUObject(*surface);
|
||||
if (gltexture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
}
|
||||
colorBuffers[nbColorBuffers] = colorAttachments[unit];
|
||||
nbColorBuffers++;
|
||||
unit++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (framebuffer.hasDepthStencil()) {
|
||||
auto surface = framebuffer.getDepthStencilBuffer();
|
||||
if (surface) {
|
||||
auto gltexture = GLBackend::syncGPUObject(*surface);
|
||||
if (gltexture) {
|
||||
if (surface)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Last but not least, define where we draw
|
||||
if (nbColorBuffers > 0) {
|
||||
glDrawBuffers(nbColorBuffers, colorBuffers);
|
||||
} else {
|
||||
glDrawBuffer( GL_NONE );
|
||||
}
|
||||
|
||||
// Now check for completness
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
bool result = false;
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE :
|
||||
// Success !
|
||||
result = true;
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT :
|
||||
qCDebug(gpulogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT.";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
|
||||
qCDebug(gpulogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT.";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
|
||||
qCDebug(gpulogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER :
|
||||
qCDebug(gpulogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER.";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED :
|
||||
qCDebug(gpulogging) << "GLFramebuffer::syncGPUObject : Framebuffer not valid, GL_FRAMEBUFFER_UNSUPPORTED.";
|
||||
break;
|
||||
}
|
||||
if (!result && fbo) {
|
||||
glDeleteFramebuffers( 1, &fbo );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// All is green, assign the gpuobject to the Framebuffer
|
||||
object = new GLFramebuffer();
|
||||
object->_fbo = fbo;
|
||||
Backend::setGPUObject(framebuffer, object);
|
||||
}
|
||||
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -69,4 +156,4 @@ void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) {
|
|||
_output._framebuffer = framebuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue