diff options
Diffstat (limited to 'source/blender/gpu/opengl/gl_framebuffer.hh')
-rw-r--r-- | source/blender/gpu/opengl/gl_framebuffer.hh | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh new file mode 100644 index 00000000000..a83bc1f6cae --- /dev/null +++ b/source/blender/gpu/opengl/gl_framebuffer.hh @@ -0,0 +1,142 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * Encapsulation of Framebuffer states (attached textures, viewport, scissors). + */ + +#pragma once + +#include "MEM_guardedalloc.h" + +#include "glew-mx.h" + +#include "gpu_framebuffer_private.hh" + +namespace blender::gpu { + +/** + * Implementation of FrameBuffer object using OpenGL. + **/ +class GLFrameBuffer : public FrameBuffer { + private: + /** OpenGL handle. */ + GLuint fbo_id_ = 0; + /** Context the handle is from. Framebuffers are not shared accros contexts. */ + GLContext *context_ = NULL; + /** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */ + GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT]; + /** Internal framebuffers are immutable. */ + bool immutable_; + /** True is the framebuffer has it's first color target using the GPU_SRGB8_A8 format. */ + bool srgb_; + + public: + /** + * Create a conventional framebuffer to attach texture to. + **/ + GLFrameBuffer(const char *name); + + /** + * Special Framebuffer encapsulating internal window framebuffer. + * (i.e.: GL_FRONT_LEFT, GL_BACK_RIGHT, ...) + * @param ctx context the handle is from. + * @param target the internal GL name (i.e: GL_BACK_LEFT). + * @param fbo the (optional) already created object for some implementation. Default is 0. + * @param w buffer width. + * @param h buffer height. + **/ + GLFrameBuffer(const char *name, GLContext *ctx, GLenum target, GLuint fbo, int w, int h); + + ~GLFrameBuffer(); + + void bind(bool enabled_srgb) override; + + bool check(char err_out[256]) override; + + void clear(eGPUFrameBufferBits buffers, + const float clear_col[4], + float clear_depth, + uint clear_stencil) override; + void clear_multi(const float (*clear_cols)[4]) override; + + void read(eGPUFrameBufferBits planes, + eGPUDataFormat format, + const int area[4], + int channel_len, + int slot, + void *r_data) override; + + void blit_to(eGPUFrameBufferBits planes, + int src_slot, + FrameBuffer *dst, + int dst_slot, + int dst_offset_x, + int dst_offset_y) override; + + private: + void init(void); + void update_attachments(void); + void update_drawbuffers(void); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLFrameBuffer"); +}; + +/* -------------------------------------------------------------------- */ +/** \name Enums Conversion + * \{ */ + +static inline GLenum to_gl(const GPUAttachmentType type) +{ +#define ATTACHMENT(X) \ + case GPU_FB_##X: { \ + return GL_##X; \ + } \ + ((void)0) + + switch (type) { + ATTACHMENT(DEPTH_ATTACHMENT); + ATTACHMENT(DEPTH_STENCIL_ATTACHMENT); + ATTACHMENT(COLOR_ATTACHMENT0); + ATTACHMENT(COLOR_ATTACHMENT1); + ATTACHMENT(COLOR_ATTACHMENT2); + ATTACHMENT(COLOR_ATTACHMENT3); + ATTACHMENT(COLOR_ATTACHMENT4); + ATTACHMENT(COLOR_ATTACHMENT5); + default: + BLI_assert(0); + return GL_COLOR_ATTACHMENT0; + } +#undef ATTACHMENT +} + +static inline GLbitfield to_gl(const eGPUFrameBufferBits bits) +{ + GLbitfield mask = 0; + mask |= (bits & GPU_DEPTH_BIT) ? GL_DEPTH_BUFFER_BIT : 0; + mask |= (bits & GPU_STENCIL_BIT) ? GL_STENCIL_BUFFER_BIT : 0; + mask |= (bits & GPU_COLOR_BIT) ? GL_COLOR_BUFFER_BIT : 0; + return mask; +} + +/** \} */ + +} // namespace blender::gpu |