[1] | 1 | /* |
---|
| 2 | ----------------------------------------------------------------------------- |
---|
| 3 | This source file is part of OGRE |
---|
| 4 | (Object-oriented Graphics Rendering Engine) |
---|
| 5 | For the latest info, see http://www.ogre3d.org |
---|
| 6 | |
---|
| 7 | Copyright (c) 2000-2006 Torus Knot Software Ltd |
---|
| 8 | Also see acknowledgements in Readme.html |
---|
| 9 | |
---|
| 10 | This program is free software; you can redistribute it and/or modify it under |
---|
| 11 | the terms of the GNU Lesser General Public License as published by the Free Software |
---|
| 12 | Foundation; either version 2 of the License, or (at your option) any later |
---|
| 13 | version. |
---|
| 14 | |
---|
| 15 | This program is distributed in the hope that it will be useful, but WITHOUT |
---|
| 16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
---|
| 17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. |
---|
| 18 | |
---|
| 19 | You should have received a copy of the GNU Lesser General Public License along with |
---|
| 20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
---|
| 21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to |
---|
| 22 | http://www.gnu.org/copyleft/lesser.txt. |
---|
| 23 | |
---|
| 24 | You may alternatively use this source under the terms of a specific version of |
---|
| 25 | the OGRE Unrestricted License provided you have obtained such a license from |
---|
| 26 | Torus Knot Software Ltd. |
---|
| 27 | ----------------------------------------------------------------------------- |
---|
| 28 | */ |
---|
| 29 | #include "OgreStableHeaders.h" |
---|
| 30 | #include "OgreHardwarePixelBuffer.h" |
---|
| 31 | #include "OgreImage.h" |
---|
| 32 | #include "OgreException.h" |
---|
| 33 | |
---|
| 34 | namespace Ogre |
---|
| 35 | { |
---|
| 36 | |
---|
| 37 | //----------------------------------------------------------------------------- |
---|
| 38 | HardwarePixelBuffer::HardwarePixelBuffer(size_t width, size_t height, size_t depth, |
---|
| 39 | PixelFormat format, |
---|
| 40 | HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer): |
---|
| 41 | HardwareBuffer(usage, useSystemMemory, useShadowBuffer), |
---|
| 42 | mWidth(width), mHeight(height), mDepth(depth), |
---|
| 43 | mFormat(format) |
---|
| 44 | { |
---|
| 45 | // Default |
---|
| 46 | mRowPitch = mWidth; |
---|
| 47 | mSlicePitch = mHeight*mWidth; |
---|
| 48 | mSizeInBytes = mHeight*mWidth*PixelUtil::getNumElemBytes(mFormat); |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | //----------------------------------------------------------------------------- |
---|
| 52 | HardwarePixelBuffer::~HardwarePixelBuffer() |
---|
| 53 | { |
---|
| 54 | } |
---|
| 55 | |
---|
| 56 | //----------------------------------------------------------------------------- |
---|
| 57 | void* HardwarePixelBuffer::lock(size_t offset, size_t length, LockOptions options) |
---|
| 58 | { |
---|
| 59 | assert(!isLocked() && "Cannot lock this buffer, it is already locked!"); |
---|
| 60 | assert(offset == 0 && length == mSizeInBytes && "Cannot lock memory region, most lock box or entire buffer"); |
---|
| 61 | |
---|
| 62 | Image::Box myBox(0, 0, 0, mWidth, mHeight, mDepth); |
---|
| 63 | const PixelBox &rv = lock(myBox, options); |
---|
| 64 | return rv.data; |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | //----------------------------------------------------------------------------- |
---|
| 68 | const PixelBox& HardwarePixelBuffer::lock(const Image::Box& lockBox, LockOptions options) |
---|
| 69 | { |
---|
| 70 | if (mUseShadowBuffer) |
---|
| 71 | { |
---|
| 72 | if (options != HBL_READ_ONLY) |
---|
| 73 | { |
---|
| 74 | // we have to assume a read / write lock so we use the shadow buffer |
---|
| 75 | // and tag for sync on unlock() |
---|
| 76 | mShadowUpdated = true; |
---|
| 77 | } |
---|
| 78 | |
---|
| 79 | mCurrentLock = static_cast<HardwarePixelBuffer*>(mpShadowBuffer)->lock(lockBox, options); |
---|
| 80 | } |
---|
| 81 | else |
---|
| 82 | { |
---|
| 83 | // Lock the real buffer if there is no shadow buffer |
---|
| 84 | mCurrentLock = lockImpl(lockBox, options); |
---|
| 85 | mIsLocked = true; |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | return mCurrentLock; |
---|
| 89 | } |
---|
| 90 | |
---|
| 91 | //----------------------------------------------------------------------------- |
---|
| 92 | const PixelBox& HardwarePixelBuffer::getCurrentLock() |
---|
| 93 | { |
---|
| 94 | assert(isLocked() && "Cannot get current lock: buffer not locked"); |
---|
| 95 | |
---|
| 96 | return mCurrentLock; |
---|
| 97 | } |
---|
| 98 | |
---|
| 99 | //----------------------------------------------------------------------------- |
---|
| 100 | /// Internal implementation of lock() |
---|
| 101 | void* HardwarePixelBuffer::lockImpl(size_t offset, size_t length, LockOptions options) |
---|
| 102 | { |
---|
| 103 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "lockImpl(offset,length) is not valid for PixelBuffers and should never be called", |
---|
| 104 | "HardwarePixelBuffer::lockImpl"); |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | //----------------------------------------------------------------------------- |
---|
| 108 | |
---|
| 109 | void HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox) |
---|
| 110 | { |
---|
| 111 | if(isLocked() || src->isLocked()) |
---|
| 112 | { |
---|
| 113 | OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, |
---|
| 114 | "Source and destination buffer may not be locked!", |
---|
| 115 | "HardwarePixelBuffer::blit"); |
---|
| 116 | } |
---|
| 117 | if(src.getPointer() == this) |
---|
| 118 | { |
---|
| 119 | OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, |
---|
| 120 | "Source must not be the same object", |
---|
| 121 | "HardwarePixelBuffer::blit" ) ; |
---|
| 122 | } |
---|
| 123 | const PixelBox &srclock = src->lock(srcBox, HBL_READ_ONLY); |
---|
| 124 | |
---|
| 125 | LockOptions method = HBL_NORMAL; |
---|
| 126 | if(dstBox.left == 0 && dstBox.top == 0 && dstBox.front == 0 && |
---|
| 127 | dstBox.right == mWidth && dstBox.bottom == mHeight && |
---|
| 128 | dstBox.back == mDepth) |
---|
| 129 | // Entire buffer -- we can discard the previous contents |
---|
| 130 | method = HBL_DISCARD; |
---|
| 131 | |
---|
| 132 | const PixelBox &dstlock = lock(dstBox, method); |
---|
| 133 | if(dstlock.getWidth() != srclock.getWidth() || |
---|
| 134 | dstlock.getHeight() != srclock.getHeight() || |
---|
| 135 | dstlock.getDepth() != srclock.getDepth()) |
---|
| 136 | { |
---|
| 137 | // Scaling desired |
---|
| 138 | Image::scale(srclock, dstlock); |
---|
| 139 | } |
---|
| 140 | else |
---|
| 141 | { |
---|
| 142 | // No scaling needed |
---|
| 143 | PixelUtil::bulkPixelConversion(srclock, dstlock); |
---|
| 144 | } |
---|
| 145 | |
---|
| 146 | unlock(); |
---|
| 147 | src->unlock(); |
---|
| 148 | } |
---|
| 149 | //----------------------------------------------------------------------------- |
---|
| 150 | void HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &src) |
---|
| 151 | { |
---|
| 152 | blit(src, |
---|
| 153 | Box(0,0,0,src->getWidth(),src->getHeight(),src->getDepth()), |
---|
| 154 | Box(0,0,0,mWidth,mHeight,mDepth) |
---|
| 155 | ); |
---|
| 156 | } |
---|
| 157 | //----------------------------------------------------------------------------- |
---|
| 158 | void HardwarePixelBuffer::readData(size_t offset, size_t length, void* pDest) |
---|
| 159 | { |
---|
| 160 | // TODO |
---|
| 161 | OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, |
---|
| 162 | "Reading a byte range is not implemented. Use blitToMemory.", |
---|
| 163 | "HardwarePixelBuffer::readData"); |
---|
| 164 | } |
---|
| 165 | //----------------------------------------------------------------------------- |
---|
| 166 | |
---|
| 167 | void HardwarePixelBuffer::writeData(size_t offset, size_t length, const void* pSource, |
---|
| 168 | bool discardWholeBuffer) |
---|
| 169 | { |
---|
| 170 | // TODO |
---|
| 171 | OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, |
---|
| 172 | "Writing a byte range is not implemented. Use blitFromMemory.", |
---|
| 173 | "HardwarePixelBuffer::writeData"); |
---|
| 174 | } |
---|
| 175 | //----------------------------------------------------------------------------- |
---|
| 176 | |
---|
| 177 | RenderTexture *HardwarePixelBuffer::getRenderTarget(size_t) |
---|
| 178 | { |
---|
| 179 | OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, |
---|
| 180 | "Not yet implemented for this rendersystem.", |
---|
| 181 | "HardwarePixelBuffer::getRenderTarget"); |
---|
| 182 | } |
---|
| 183 | |
---|
| 184 | //----------------------------------------------------------------------------- |
---|
| 185 | |
---|
| 186 | HardwarePixelBufferSharedPtr::HardwarePixelBufferSharedPtr(HardwarePixelBuffer* buf) |
---|
| 187 | : SharedPtr<HardwarePixelBuffer>(buf) |
---|
| 188 | { |
---|
| 189 | |
---|
| 190 | } |
---|
| 191 | //----------------------------------------------------------------------------- |
---|
| 192 | |
---|
| 193 | void HardwarePixelBuffer::_clearSliceRTT(size_t zoffset) |
---|
| 194 | { |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | }; |
---|