| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
| 3 | #pragma once |
| 4 | |
| 5 | #include "BsGLPrerequisites.h" |
| 6 | #include "RenderAPI/BsHardwareBuffer.h" |
| 7 | #include "Image/BsPixelUtil.h" |
| 8 | |
| 9 | namespace bs { namespace ct |
| 10 | { |
| 11 | /** @addtogroup GL |
| 12 | * @{ |
| 13 | */ |
| 14 | |
| 15 | class GLTextureBuffer; |
| 16 | |
| 17 | /** |
| 18 | * Represents a hardware buffer that stores a single pixel surface. This may be a 1D, 2D or 3D surface, but unlike a |
| 19 | * texture it consists only of a single surface (no mip maps, cube map faces or similar). |
| 20 | */ |
| 21 | class GLPixelBuffer |
| 22 | { |
| 23 | public: |
| 24 | /** |
| 25 | * Constructs a new pixel buffer with the provided settings. |
| 26 | * |
| 27 | * @param[in] width Width of the pixel buffer in pixels. |
| 28 | * @param[in] height Height of the pixel buffer in pixels. |
| 29 | * @param[in] depth Depth of the pixel buffer in pixels (number of 2D slices). |
| 30 | * @param[in] format Format of each pixel in the buffer. |
| 31 | * @param[in] usage Usage signaling the render system how we plan on using the buffer. |
| 32 | */ |
| 33 | GLPixelBuffer(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, GpuBufferUsage usage); |
| 34 | virtual ~GLPixelBuffer(); |
| 35 | |
| 36 | /** Returns width of the surface in pixels. */ |
| 37 | UINT32 getWidth() const { return mWidth; } |
| 38 | |
| 39 | /** Returns height of the surface in pixels. */ |
| 40 | UINT32 getHeight() const { return mHeight; } |
| 41 | |
| 42 | /** Returns depth of the surface in pixels. */ |
| 43 | UINT32 getDepth() const { return mDepth; } |
| 44 | |
| 45 | /** Returns format of the pixels in the surface. */ |
| 46 | PixelFormat getFormat() const { return mFormat; } |
| 47 | |
| 48 | /** |
| 49 | * Locks a certain region of the pixel buffer for reading and returns a pointer to the locked region. |
| 50 | * |
| 51 | * @param[in] lockBox Region of the surface to lock. |
| 52 | * @param[in] options Lock options that hint the hardware on what you intend to do with the locked data. |
| 53 | * |
| 54 | * @note Returned object is only valid while the lock is active. |
| 55 | */ |
| 56 | const PixelData& lock(const PixelVolume& lockBox, GpuLockOptions options); |
| 57 | |
| 58 | /** |
| 59 | * Locks a portion of the buffer and returns pointer to the locked area. You must call unlock() when done. |
| 60 | * |
| 61 | * @param[in] offset Offset in bytes from which to lock the buffer. |
| 62 | * @param[in] length Length of the area you want to lock, in bytes. |
| 63 | * @param[in] options Signifies what you want to do with the returned pointer. Caller must ensure not to do |
| 64 | * anything he hasn't requested (for example don't try to read from the buffer unless you |
| 65 | * requested it here). |
| 66 | */ |
| 67 | void* lock(UINT32 offset, UINT32 length, GpuLockOptions options); |
| 68 | |
| 69 | /** |
| 70 | * Locks the entire buffer and returns pointer to the locked area. You must call unlock() when done. |
| 71 | * |
| 72 | * @param[in] options Signifies what you want to do with the returned pointer. Caller must ensure not to do |
| 73 | * anything he hasn't requested (for example don't try to read from the buffer unless you |
| 74 | * requested it here). |
| 75 | */ |
| 76 | void* lock(GpuLockOptions options) |
| 77 | { |
| 78 | return lock(0, mSizeInBytes, options); |
| 79 | } |
| 80 | |
| 81 | /** Releases the lock on this buffer. */ |
| 82 | void unlock(); |
| 83 | |
| 84 | /** |
| 85 | * Upload some pixel data to the buffer. |
| 86 | * |
| 87 | * @param[in] data Data to upload. |
| 88 | * @param[in] dest Coordinates to which to upload the data. |
| 89 | */ |
| 90 | virtual void upload(const PixelData& data, const PixelVolume& dest); |
| 91 | |
| 92 | /** |
| 93 | * Reads data from the pixel buffer into the provided object. Caller must ensure the data object is of adequate |
| 94 | * size. |
| 95 | */ |
| 96 | virtual void download(const PixelData& data); |
| 97 | |
| 98 | /** |
| 99 | * Binds the buffers to a frame buffer object at the specified attachment point. |
| 100 | * |
| 101 | * @param[in] attachment Attachment point index in the range [0, BS_MAX_MULTIPLE_RENDER_TARGETS). |
| 102 | * @param[in] zoffset Depth slice to bind, in the case of a 3D texture. |
| 103 | * @param[in] allLayers Should all layers of the texture be bound, or just one (zoffset is ignored if true). |
| 104 | */ |
| 105 | virtual void bindToFramebuffer(GLenum attachment, UINT32 zoffset, bool allLayers); |
| 106 | |
| 107 | /** |
| 108 | * Blits the contents of the provided buffer into this pixel buffer. Data is bilinearily interpolated in case buffer |
| 109 | * sizes don't match. |
| 110 | */ |
| 111 | virtual void blitFromTexture(GLTextureBuffer* src); |
| 112 | |
| 113 | /** |
| 114 | * Blits contents of a sub-region of the provided buffer into a sub-region of this pixel buffer. Data is bilinearily |
| 115 | * interpolated in case source and destination sizes don't match. |
| 116 | */ |
| 117 | virtual void blitFromTexture(GLTextureBuffer* src, const PixelVolume& srcBox, const PixelVolume& dstBox); |
| 118 | |
| 119 | protected: |
| 120 | /** Allocates an internal buffer on the CPU, the size of the hardware buffer. */ |
| 121 | void allocateBuffer(); |
| 122 | |
| 123 | /** Deallocates the internal CPU buffer. */ |
| 124 | void freeBuffer(); |
| 125 | |
| 126 | protected: |
| 127 | UINT32 mSizeInBytes; |
| 128 | GpuBufferUsage mUsage; |
| 129 | bool mIsLocked = false; |
| 130 | |
| 131 | UINT32 mWidth, mHeight, mDepth; |
| 132 | PixelFormat mFormat; |
| 133 | |
| 134 | PixelData mCurrentLock; |
| 135 | PixelVolume mLockedBox; |
| 136 | |
| 137 | PixelData mBuffer; |
| 138 | GpuLockOptions mCurrentLockOptions; |
| 139 | }; |
| 140 | |
| 141 | /** Pixel buffer specialization that represents a single surface in a texture. */ |
| 142 | class GLTextureBuffer : public GLPixelBuffer |
| 143 | { |
| 144 | public: |
| 145 | /** |
| 146 | * Constructs a new texture buffer from a specific surface in the provided texture. |
| 147 | * |
| 148 | * @param[in] target OpenGL type of the texture to retrieve the surface from. |
| 149 | * @param[in] id OpenGL handle to the texture to retrieve the surface from. |
| 150 | * @param[in] face Face index of the texture in the case of cube textures or texture arrays. |
| 151 | * @param[in] level Mip level of the texture. |
| 152 | * @param[in] format Format of each pixel in the buffer. |
| 153 | * @param[in] usage Usage signaling the render system how we plan on using the buffer. |
| 154 | * @param[in] hwGamma True if buffer colors are assumed to be in sRGB space. |
| 155 | * @param[in] multisampleCount Number of samples the parent texture was created with. |
| 156 | */ |
| 157 | GLTextureBuffer(GLenum target, GLuint id, GLint face, |
| 158 | GLint level, PixelFormat format, GpuBufferUsage usage, bool hwGamma, UINT32 multisampleCount); |
| 159 | ~GLTextureBuffer() = default; |
| 160 | |
| 161 | /** @copydoc GLPixelBuffer::bindToFramebuffer */ |
| 162 | void bindToFramebuffer(GLenum attachment, UINT32 zoffset, bool allLayers) override; |
| 163 | |
| 164 | /** @copydoc GLPixelBuffer::upload */ |
| 165 | void upload(const PixelData &data, const PixelVolume &dest) override; |
| 166 | |
| 167 | /** @copydoc GLPixelBuffer::download */ |
| 168 | void download(const PixelData &data) override; |
| 169 | |
| 170 | /** @copydoc GLPixelBuffer::blitFromTexture */ |
| 171 | void blitFromTexture(GLTextureBuffer *src) override; |
| 172 | |
| 173 | /** @copydoc GLPixelBuffer::blitFromTexture */ |
| 174 | void blitFromTexture(GLTextureBuffer *src, const PixelVolume &srcBox, const PixelVolume &dstBox) override; |
| 175 | |
| 176 | /** |
| 177 | * Populate texture buffer with the data in the currently attached frame buffer. |
| 178 | * |
| 179 | * @param[in] zoffset 3D slice of the texture to copy to. 0 if texture is not 3D. |
| 180 | */ |
| 181 | void copyFromFramebuffer(UINT32 zoffset); |
| 182 | |
| 183 | protected: |
| 184 | GLenum mTarget; |
| 185 | GLenum mFaceTarget = 0; |
| 186 | GLuint mTextureID; |
| 187 | GLint mFace; |
| 188 | GLint mLevel; |
| 189 | UINT32 mMultisampleCount; |
| 190 | bool mHwGamma; |
| 191 | }; |
| 192 | |
| 193 | /** @} */ |
| 194 | }} |