1 // 2 // Copyright 2016 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 #ifndef PXR_IMAGING_GLF_DRAW_TARGET_H 25 #define PXR_IMAGING_GLF_DRAW_TARGET_H 26 27 /// \file glf/drawTarget.h 28 29 #include "pxr/pxr.h" 30 #include "pxr/imaging/glf/api.h" 31 #include "pxr/imaging/glf/texture.h" 32 #include "pxr/imaging/garch/glApi.h" 33 34 #include "pxr/base/gf/vec2i.h" 35 #include "pxr/base/gf/matrix4d.h" 36 #include "pxr/base/tf/declarePtrs.h" 37 #include "pxr/base/tf/refBase.h" 38 #include "pxr/base/tf/weakBase.h" 39 40 #include <map> 41 #include <memory> 42 #include <set> 43 #include <string> 44 45 46 PXR_NAMESPACE_OPEN_SCOPE 47 48 49 TF_DECLARE_WEAK_AND_REF_PTRS(GlfDrawTarget); 50 typedef std::shared_ptr<class GlfGLContext> GlfGLContextSharedPtr; 51 52 /// \class GlfDrawTarget 53 /// 54 /// A class representing a GL render target with mutliple image attachments. 55 /// 56 /// A DrawTarget is essentially a custom render pass into which several 57 /// arbitrary variables can be output into. These can later be used as 58 /// texture samplers by GLSL shaders. 59 /// 60 /// The DrawTarget maintains a map of named attachments that correspond 61 /// to GL_TEXTURE_2D mages. By default, DrawTargets also create a depth 62 /// component that is used both as a depth buffer during the draw pass, 63 /// and can later be accessed as a regular GL_TEXTURE_2D data. Stencils 64 /// are also available (by setting the format to GL_DEPTH_STENCIL and 65 /// the internalFormat to GL_DEPTH24_STENCIL8) 66 /// 67 class GlfDrawTarget : public TfRefBase, public TfWeakBase { 68 public: 69 typedef GlfDrawTarget This; 70 71 public: 72 73 /// Returns a new instance. 74 GLF_API 75 static GlfDrawTargetRefPtr New( GfVec2i const & size, 76 bool requestMSAA = false ); 77 78 /// Returns a new instance. 79 /// GL framebuffers cannot be shared across contexts, but texture 80 /// attachments can. In order to reflect this, GlfDrawTargets hold 81 /// onto their maps of attachments through a RefPtr that can be shared 82 /// by multiple GlfDrawTargets, one for each of the active GL contexts 83 /// (ex. one for each active QT viewer). 84 /// This constructor creates a new framebuffer, but populates its map of 85 /// attachments by sharing the RefPtr of the source GlfDrawTarget. 86 GLF_API 87 static GlfDrawTargetRefPtr New( GlfDrawTargetPtr const & drawtarget ); 88 89 class Attachment : public GlfTexture { 90 public: 91 typedef TfDeclarePtrs<class Attachment>::RefPtr AttachmentRefPtr; 92 93 GLF_API 94 static AttachmentRefPtr New(int glIndex, GLenum format, GLenum type, 95 GLenum internalFormat, GfVec2i size, 96 unsigned int numSamples); 97 98 GLF_API 99 ~Attachment() override; 100 101 /// Returns the GL texture index (can be used as any regular GL texture) 102 GLuint GetGlTextureName() override; 103 104 /// Returns the GL texture index multisampled of this attachment GetGlTextureMSName()105 GLuint GetGlTextureMSName() const { return _textureNameMS; } 106 107 /// Returns the GL format of the texture (GL_RGB, GL_DEPTH_COMPONENT...) GetFormat()108 GLenum GetFormat() const { return _format; } 109 110 /// Returns the GL type of the texture (GL_BYTE, GL_INT, GL_FLOAT...) GetType()111 GLenum GetType() const { return _type; } 112 113 /// Returns the GL internalFormat of the texture GetInternalFormat()114 GLenum GetInternalFormat() const { return _internalFormat; } 115 116 /// Returns the GL attachment point index in the framebuffer. GetAttach()117 int GetAttach() const { return _glIndex; } 118 119 /// Resize the attachment recreating the texture 120 GLF_API 121 void ResizeTexture(const GfVec2i &size); 122 123 // GlfTexture overrides 124 GLF_API 125 BindingVector GetBindings(TfToken const & identifier, 126 GLuint samplerName) override; 127 GLF_API 128 VtDictionary GetTextureInfo(bool forceLoad) override; 129 130 /// Updates the contents signature for the underlying texture 131 /// to allow downstream consumers to know that the texture image 132 /// data may have changed. 133 GLF_API 134 void TouchContents(); 135 136 private: 137 Attachment(int glIndex, GLenum format, GLenum type, 138 GLenum internalFormat, GfVec2i size, 139 unsigned int numSamples); 140 141 void _GenTexture(); 142 void _DeleteTexture(); 143 144 GLuint _textureName; 145 GLuint _textureNameMS; 146 147 GLenum _format, 148 _type, 149 _internalFormat; 150 151 int _glIndex; 152 153 GfVec2i _size; 154 155 unsigned int _numSamples; 156 }; 157 158 typedef TfDeclarePtrs<class Attachment>::RefPtr AttachmentRefPtr; 159 160 typedef std::map<std::string, AttachmentRefPtr> AttachmentsMap; 161 162 /// Add an attachment to the DrawTarget. 163 GLF_API 164 void AddAttachment( std::string const & name, 165 GLenum format, GLenum type, GLenum internalFormat ); 166 167 /// Removes the named attachment from the DrawTarget. 168 GLF_API 169 void DeleteAttachment( std::string const & name ); 170 171 /// Clears all the attachments for this DrawTarget. 172 GLF_API 173 void ClearAttachments(); 174 175 /// Copies the list of attachments from DrawTarget. 176 GLF_API 177 void CloneAttachments( GlfDrawTargetPtr const & drawtarget ); 178 179 /// Returns the list of Attachments for this DrawTarget. 180 GLF_API 181 AttachmentsMap const & GetAttachments() const; 182 183 /// Returns the attachment with a given name or TfNullPtr; 184 GLF_API 185 AttachmentRefPtr GetAttachment(std::string const & name); 186 187 /// Write the Attachment buffer to an image file (debugging). 188 GLF_API 189 bool WriteToFile(std::string const & name, 190 std::string const & filename, 191 GfMatrix4d const & viewMatrix = GfMatrix4d(1), 192 GfMatrix4d const & projectionMatrix = GfMatrix4d(1)); 193 194 /// Resize the DrawTarget. 195 GLF_API 196 void SetSize( GfVec2i ); 197 198 /// Returns the size of the DrawTarget. GetSize()199 GfVec2i const & GetSize() const { return _size; } 200 201 /// Returns if the draw target uses msaa HasMSAA()202 bool HasMSAA() const { return (_numSamples > 1); } 203 204 /// Returns the framebuffer object Id. 205 GLF_API 206 GLuint GetFramebufferId() const; 207 208 /// Returns the id of the framebuffer object with MSAA buffers. 209 GLF_API 210 GLuint GetFramebufferMSId() const; 211 212 /// Binds the framebuffer. 213 GLF_API 214 void Bind(); 215 216 /// Unbinds the framebuffer. 217 GLF_API 218 void Unbind(); 219 220 /// Returns whether the framebuffer is currently bound. 221 GLF_API 222 bool IsBound() const; 223 224 /// Resolve the MSAA framebuffer to a regular framebuffer. If there 225 /// is no MSAA enabled, this function does nothing. 226 GLF_API 227 void Resolve(); 228 229 /// Resolve several MSAA framebuffers at once. If any framebuffers don't 230 /// have MSAA enabled, nothing happens to them. 231 GLF_API 232 static void Resolve(const std::vector<GlfDrawTarget*>& drawTargets); 233 234 /// Updates the contents signature for attached textures 235 /// to allow downstream consumers to know that the texture image 236 /// data may have changed. 237 GLF_API 238 void TouchContents(); 239 240 /// Returns whether the enclosed framebuffer object is complete. 241 /// If \a reason is non-NULL, and this framebuffer is not valid, 242 /// sets \a reason to the reason why not. 243 GLF_API 244 bool IsValid(std::string * reason = NULL); 245 246 protected: 247 248 /// Weak/Ref-based container for the the map of texture attachments. 249 /// Multiple GlfDrawTargets can jointly share their attachment textures : 250 /// this construction allows the use of a RefPtr on the map of attachments. 251 class AttachmentsContainer : public TfRefBase, public TfWeakBase { 252 public: 253 AttachmentsMap attachments; 254 }; 255 256 GLF_API 257 GlfDrawTarget( GfVec2i const & size, bool requestMSAA ); 258 259 GLF_API 260 GlfDrawTarget( GlfDrawTargetPtr const & drawtarget ); 261 262 GLF_API 263 virtual ~GlfDrawTarget(); 264 265 private: 266 void _GenFrameBuffer(); 267 268 void _BindAttachment( GlfDrawTarget::AttachmentRefPtr const & a ); 269 270 GLuint _AllocAttachment( GLenum format, GLenum type ); 271 272 AttachmentsMap & _GetAttachments() const; 273 274 void _DeleteAttachments( ); 275 276 void _AllocDepth( ); 277 278 bool _Validate(std::string * reason = NULL); 279 280 void _SaveBindingState(); 281 282 void _RestoreBindingState(); 283 284 void _Resolve(); 285 286 GLuint _framebuffer; 287 GLuint _framebufferMS; 288 289 GLuint _unbindRestoreReadFB, 290 _unbindRestoreDrawFB; 291 292 int _bindDepth; 293 294 GfVec2i _size; 295 296 unsigned int _numSamples; 297 298 TfRefPtr<AttachmentsContainer> _attachmentsPtr; 299 GlfGLContextSharedPtr _owningContext; 300 }; 301 302 303 PXR_NAMESPACE_CLOSE_SCOPE 304 305 #endif // GLF_DRAW_TARGET_H 306