MxEngine
FrameBuffer.h
1 // Copyright(c) 2019 - 2020, #Momo
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met :
6 //
7 // 1. Redistributions of source code must retain the above copyright notice, this
8 // list of conditions and the following disclaimer.
9 //
10 // 2. Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and /or other materials provided with the distribution.
13 //
14 // 3. Neither the name of the copyright holder nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include "Core/Macro/Macro.h"
32 #include "Platform/OpenGL/Texture.h"
33 #include "Platform/OpenGL/CubeMap.h"
34 
35 namespace MxEngine
36 {
37  enum class Attachment
38  {
39  COLOR_ATTACHMENT0,
40  COLOR_ATTACHMENT1,
41  COLOR_ATTACHMENT2,
42  COLOR_ATTACHMENT3,
43  COLOR_ATTACHMENT4,
44  COLOR_ATTACHMENT5,
45  COLOR_ATTACHMENT6,
46  COLOR_ATTACHMENT9,
47  COLOR_ATTACHMENT10,
48  COLOR_ATTACHMENT11,
49  COLOR_ATTACHMENT12,
50  COLOR_ATTACHMENT13,
51  COLOR_ATTACHMENT14,
52  COLOR_ATTACHMENT15,
53  DEPTH_ATTACHMENT,
54  STENCIL_ATTACHMENT,
55  DEPTH_STENCIL_ATTACHMENT,
56  };
57 
59  {
60  enum class AttachmentType : uint8_t
61  {
62  NONE,
63  TEXTURE,
64  CUBEMAP,
65  };
66 
67  using BindableId = unsigned int;
68 
69  BindableId id = 0;
70  AttachmentType currentAttachment = AttachmentType::NONE;
71  #if defined(MXENGINE_DEBUG)
72  std::aligned_storage_t<32> attachmentStorage;
73  #else
74  std::aligned_storage_t<24> attachmentStorage;
75  #endif
76 
77  #if defined(MXENGINE_DEBUG)
78  mutable const Texture* _texturePtr = nullptr;
79  mutable const CubeMap* _cubemapPtr = nullptr;
80  #endif
81 
82  void OnTextureAttach(const Texture& texture, Attachment attachment);
83  void OnCubeMapAttach(const CubeMap& cubemap, Attachment attachment);
84  public:
85  FrameBuffer();
86  ~FrameBuffer();
87  FrameBuffer(const FrameBuffer&) = delete;
88  FrameBuffer(FrameBuffer&&) noexcept;
89  FrameBuffer& operator=(const FrameBuffer&) = delete;
90  FrameBuffer& operator=(FrameBuffer&&) noexcept;
91  void CopyFrameBufferContents(const FrameBuffer& framebuffer) const;
92  void CopyFrameBufferContents(int screenWidth, int screenHeight) const;
93  void Validate() const;
94  void DetachRenderTarget();
95  bool HasTextureAttached() const;
96  bool HasCubeMapAttached() const;
97  void UseDrawBuffers(size_t count) const;
98  size_t GetWidth() const;
99  size_t GetHeight() const;
100  void Bind() const;
101  void Unbind() const;
102  BindableId GetNativeHandle() const;
103 
104  template<template<typename, typename> typename Resource, typename Factory>
105  void AttachTexture(const Resource<Texture, Factory>& texture, Attachment attachment = Attachment::COLOR_ATTACHMENT0)
106  {
107  static_assert(sizeof(this->attachmentStorage) == sizeof(Resource<Texture, Factory>), "storage size must match object size");
108 
109  this->DetachRenderTarget();
110  auto* attachedTexture = new(&this->attachmentStorage) Resource<Texture, Factory>(texture);
111  this->currentAttachment = AttachmentType::TEXTURE;
112  this->OnTextureAttach(**attachedTexture, attachment);
113 
114  #if defined(MXENGINE_DEBUG)
115  this->_texturePtr = attachedTexture->GetUnchecked();
116  this->_cubemapPtr = nullptr;
117  #endif
118  }
119 
120  template<template<typename, typename> typename Resource, typename Factory>
121  void AttachTextureExtra(const Resource<Texture, Factory>& texture, Attachment attachment)
122  {
123  MX_ASSERT(this->currentAttachment != AttachmentType::NONE);
124  this->OnTextureAttach(*texture, attachment);
125  }
126 
127  template<template<typename, typename> typename Resource, typename Factory>
128  void AttachCubeMapExtra(const Resource<CubeMap, Factory>& cubemap, Attachment attachment)
129  {
130  MX_ASSERT(this->currentAttachment != AttachmentType::NONE);
131  this->OnCubeMapAttach(*cubemap, attachment);
132  }
133 
134  template<template<typename, typename> typename Resource, typename Factory>
135  void AttachCubeMap(const Resource<CubeMap, Factory>& cubemap, Attachment attachment = Attachment::COLOR_ATTACHMENT0)
136  {
137  static_assert(sizeof(this->attachmentStorage) == sizeof(Resource<CubeMap, Factory>), "storage size must match object size");
138 
139  this->DetachRenderTarget();
140  auto* attachedCubeMap = new(&this->attachmentStorage) Resource<CubeMap, Factory>(cubemap);
141  this->currentAttachment = AttachmentType::CUBEMAP;
142  this->OnCubeMapAttach(**attachedCubeMap, attachment);
143 
144  #if defined(MXENGINE_DEBUG)
145  this->_cubemapPtr = attachedCubeMap->GetUnchecked();
146  this->_texturePtr = nullptr;
147  #endif
148  }
149 
150  template<template<typename, typename> typename Resource, typename Factory>
151  Resource<Texture, Factory> GetAttachedTexture() const
152  {
153  if (!this->HasTextureAttached())
154  return Resource<Texture, Factory>{ };
155 
156  const auto& texture = *reinterpret_cast<const Resource<Texture, Factory>*>(&this->attachmentStorage);
157 
158  #if defined(MXENGINE_DEBUG)
159  this->_texturePtr = texture.GetUnchecked();
160  #endif
161 
162  return texture;
163  }
164 
165  template<template<typename, typename> typename Resource, typename Factory>
166  Resource<CubeMap, Factory> GetAttachedCubeMap() const
167  {
168  if (!this->HasCubeMapAttached())
169  return Resource<CubeMap, Factory>{ };
170 
171  const auto& cubemap = *reinterpret_cast<const Resource<CubeMap, Factory>*>(&this->attachmentStorage);
172 
173  #if defined(MXENGINE_DEBUG)
174  this->_cubemapPtr = cubemap.GetUnchecked();
175  #endif
176 
177  return cubemap;
178  }
179  };
180 }
Definition: AbstractFactory.h:61
Definition: FrameBuffer.h:58
Definition: Texture.h:67
Definition: CubeMap.h:35
Definition: Application.cpp:49