]> git.tdb.fi Git - libs/gl.git/blobdiff - source/framebuffer.cpp
Explicitly define the number of mipmap levels in textures
[libs/gl.git] / source / framebuffer.cpp
index a3197f5947cced462fa8c12d7c5ac9b4f68ed2f8..cf478ce29b686d842ce2074078952633b2e47b02 100644 (file)
@@ -2,12 +2,15 @@
 #include <msp/gl/extensions/arb_direct_state_access.h>
 #include <msp/gl/extensions/ext_framebuffer_blit.h>
 #include <msp/gl/extensions/ext_framebuffer_object.h>
-#include <msp/gl/extensions/msp_draw_buffer.h>
+#include <msp/gl/extensions/ext_texture_array.h>
+#include <msp/gl/extensions/ext_texture3d.h>
+#include <msp/gl/extensions/msp_buffer_control.h>
 #include "error.h"
 #include "framebuffer.h"
 #include "misc.h"
 #include "renderbuffer.h"
 #include "texture2d.h"
+#include "texture3d.h"
 
 using namespace std;
 
@@ -36,6 +39,15 @@ void operator<<(LexicalConverter &conv, FramebufferStatus status)
        case FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
                conv.result("missing read buffer attachment");
                break;
+       case FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+               conv.result("mismatched attachment sample counts");
+               break;
+       case FRAMEBUFFER_INCOMPLETE_LAYER_COUNT:
+               conv.result("mismatched attachment layer counts");
+               break;
+       case FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+               conv.result("mismatched attachment layering");
+               break;
        case FRAMEBUFFER_UNSUPPORTED:
                conv.result("unsupported");
                break;
@@ -113,6 +125,16 @@ void Framebuffer::update_attachment(unsigned mask) const
                                else
                                        glFramebufferTexture2D(GL_FRAMEBUFFER, attch.attachment, attch.type, attch.tex->get_id(), attch.level);
                        }
+                       else if(attch.type==GL_TEXTURE_3D || attch.type==GL_TEXTURE_2D_ARRAY)
+                       {
+                               static_cast<Texture3D *>(attch.tex)->allocate(attch.level);
+                               if(ARB_direct_state_access)
+                                       glNamedFramebufferTextureLayer(id, attch.attachment, attch.tex->get_id(), attch.level, attch.layer);
+                               else if(attch.type==GL_TEXTURE_2D_ARRAY)
+                                       glFramebufferTextureLayer(GL_FRAMEBUFFER, attch.attachment, attch.tex->get_id(), attch.level, attch.layer);
+                               else
+                                       glFramebufferTexture3D(GL_FRAMEBUFFER, attch.attachment, attch.type, attch.tex->get_id(), attch.level, attch.layer);
+                       }
                        else if(attch.type==GL_TEXTURE_CUBE_MAP)
                        {
                                static_cast<TextureCube *>(attch.tex)->allocate(attch.level);
@@ -146,10 +168,10 @@ void Framebuffer::update_attachment(unsigned mask) const
        {
                if(ARB_draw_buffers)
                        glDrawBuffers(color_bufs.size(), &color_bufs[0]);
-               else if(MSP_draw_buffer)
+               else if(MSP_buffer_control)
                        glDrawBuffer(first_buffer);
 
-               if(MSP_draw_buffer)
+               if(MSP_buffer_control)
                        glReadBuffer(first_buffer);
        }
 }
@@ -171,6 +193,12 @@ void Framebuffer::check_size()
                                width = max(tex->get_width()>>i->level, 1U);
                                height = max(tex->get_height()>>i->level, 1U);
                        }
+                       else if(i->type==GL_TEXTURE_3D || i->type==GL_TEXTURE_2D_ARRAY)
+                       {
+                               Texture3D *tex = static_cast<Texture3D *>(i->tex);
+                               width = max(tex->get_width()>>i->level, 1U);
+                               height = max(tex->get_height()>>i->level, 1U);
+                       }
                        else if(i->type==GL_TEXTURE_CUBE_MAP)
                        {
                                width = max(static_cast<TextureCube *>(i->tex)->get_size()>>i->level, 1U);
@@ -213,6 +241,17 @@ void Framebuffer::attach(FramebufferAttachment attch, Texture2D &tex, unsigned l
        check_size();
 }
 
+void Framebuffer::attach(FramebufferAttachment attch, Texture3D &tex, unsigned layer, unsigned level)
+{
+       if(!id)
+               throw invalid_operation("Framebuffer::attach");
+
+       unsigned i = get_attachment_index(attch);
+       attachments[i].set(tex, level, layer);
+       update_attachment(1<<i);
+       check_size();
+}
+
 void Framebuffer::attach(FramebufferAttachment attch, TextureCube &tex, TextureCubeFace face, unsigned level)
 {
        if(!id)