00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_TileRect.h"
00025 #include "MyGUI_RenderItem.h"
00026 #include "MyGUI_SkinManager.h"
00027 #include "MyGUI_LanguageManager.h"
00028 #include "MyGUI_LayerNode.h"
00029 #include "MyGUI_CommonStateInfo.h"
00030 #include "MyGUI_RenderManager.h"
00031 #include "MyGUI_TextureUtility.h"
00032
00033 namespace MyGUI
00034 {
00035
00036 const size_t TILERECT_COUNT_VERTEX = 16 * VertexQuad::VertexCount;
00037
00038 TileRect::TileRect() :
00039 mEmptyView(false),
00040 mCurrentColour(0xFFFFFFFF),
00041 mNode(nullptr),
00042 mRenderItem(nullptr),
00043 mCountVertex(TILERECT_COUNT_VERTEX),
00044 mRealTileWidth(0),
00045 mRealTileHeight(0),
00046 mTextureHeightOne(0),
00047 mTextureWidthOne(0),
00048 mTileH(true),
00049 mTileV(true)
00050 {
00051 }
00052
00053 TileRect::~TileRect()
00054 {
00055 }
00056
00057 void TileRect::setVisible(bool _visible)
00058 {
00059 if (mVisible == _visible) return;
00060 mVisible = _visible;
00061
00062 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00063 }
00064
00065 void TileRect::setAlpha(float _alpha)
00066 {
00067 uint32 alpha = ((uint8)(_alpha*255) << 24);
00068 mCurrentColour = (mCurrentColour & 0x00FFFFFF) | (alpha & 0xFF000000);
00069
00070 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00071 }
00072
00073 void TileRect::_correctView()
00074 {
00075 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00076 }
00077
00078 void TileRect::_setAlign(const IntCoord& _oldcoord, bool _update)
00079 {
00080 _setAlign(_oldcoord.size(), _update);
00081 }
00082
00083 void TileRect::_setAlign(const IntSize& _oldsize, bool _update)
00084 {
00085
00086 bool need_update = true;
00087
00088
00089 if (mAlign.isHStretch())
00090 {
00091
00092 mCoord.width = mCoord.width + (mCroppedParent->getWidth() - _oldsize.width);
00093 need_update = true;
00094 mIsMargin = true;
00095 }
00096 else if (mAlign.isRight())
00097 {
00098
00099 mCoord.left = mCoord.left + (mCroppedParent->getWidth() - _oldsize.width);
00100 need_update = true;
00101 }
00102 else if (mAlign.isHCenter())
00103 {
00104
00105 mCoord.left = (mCroppedParent->getWidth() - mCoord.width) / 2;
00106 need_update = true;
00107 }
00108
00109 if (mAlign.isVStretch())
00110 {
00111
00112 mCoord.height = mCoord.height + (mCroppedParent->getHeight() - _oldsize.height);
00113 need_update = true;
00114 mIsMargin = true;
00115 }
00116 else if (mAlign.isBottom())
00117 {
00118
00119 mCoord.top = mCoord.top + (mCroppedParent->getHeight() - _oldsize.height);
00120 need_update = true;
00121 }
00122 else if (mAlign.isVCenter())
00123 {
00124
00125 mCoord.top = (mCroppedParent->getHeight() - mCoord.height) / 2;
00126 need_update = true;
00127 }
00128
00129 if (need_update)
00130 {
00131 mCurrentCoord = mCoord;
00132 if (!mTileH) mTileSize.width = mCoord.width;
00133 if (!mTileV) mTileSize.height = mCoord.height;
00134 _updateView();
00135 }
00136
00137 }
00138
00139 void TileRect::_updateView()
00140 {
00141 bool margin = _checkMargin();
00142
00143 mEmptyView = ((0 >= _getViewWidth()) || (0 >= _getViewHeight()));
00144
00145 mCurrentCoord.left = mCoord.left + mMargin.left;
00146 mCurrentCoord.top = mCoord.top + mMargin.top;
00147 mCurrentCoord.width = _getViewWidth();
00148 mCurrentCoord.height = _getViewHeight();
00149
00150
00151 if (!mEmptyView)
00152 {
00153 size_t count = 0;
00154 if (!mTileSize.empty())
00155 {
00156 size_t count_x = mCoord.width / mTileSize.width;
00157 if ((mCoord.width % mTileSize.width) > 0) count_x ++;
00158 size_t count_y = mCoord.height / mTileSize.height;
00159 if ((mCoord.height % mTileSize.height) > 0) count_y ++;
00160 count = count_y * count_x * VertexQuad::VertexCount;
00161 }
00162
00163
00164 if (count > mCountVertex)
00165 {
00166 mCountVertex = count + TILERECT_COUNT_VERTEX;
00167 if (nullptr != mRenderItem) mRenderItem->reallockDrawItem(this, mCountVertex);
00168 }
00169 }
00170
00171
00172 if (margin)
00173 {
00174
00175 if (_checkOutside())
00176 {
00177
00178 mIsMargin = margin;
00179
00180
00181 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00182 return;
00183 }
00184 }
00185
00186
00187 mIsMargin = margin;
00188
00189 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00190 }
00191
00192 void TileRect::_setUVSet(const FloatRect& _rect)
00193 {
00194 mCurrentTexture = _rect;
00195 if (nullptr != mNode) mNode->outOfDate(mRenderItem);
00196 }
00197
00198 void TileRect::doRender()
00199 {
00200 if (!mVisible || mEmptyView || mTileSize.empty()) return;
00201
00202 VertexQuad* quad = (VertexQuad*)mRenderItem->getCurrentVertextBuffer();
00203
00204 const RenderTargetInfo& info = mRenderItem->getRenderTarget()->getInfo();
00205
00206
00207 mRealTileWidth = info.pixScaleX * (float)(mTileSize.width) * 2;
00208 mRealTileHeight = info.pixScaleY * (float)(mTileSize.height) * 2;
00209
00210 mTextureHeightOne = (mCurrentTexture.bottom - mCurrentTexture.top) / mRealTileHeight;
00211 mTextureWidthOne = (mCurrentTexture.right - mCurrentTexture.left) / mRealTileWidth;
00212
00213 float vertex_z = info.maximumDepth;
00214
00215
00216 float window_left = ((info.pixScaleX * (float)(mCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) + info.hOffset) * 2) - 1;
00217 float window_top = -(((info.pixScaleY * (float)(mCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) * 2) - 1);
00218
00219
00220 float real_left = ((info.pixScaleX * (float)(mCurrentCoord.left + mCroppedParent->getAbsoluteLeft() - info.leftOffset) + info.hOffset) * 2) - 1;
00221 float real_right = real_left + (info.pixScaleX * (float)mCurrentCoord.width * 2);
00222 float real_top = -(((info.pixScaleY * (float)(mCurrentCoord.top + mCroppedParent->getAbsoluteTop() - info.topOffset) + info.vOffset) * 2) - 1);
00223 float real_bottom = real_top - (info.pixScaleY * (float)mCurrentCoord.height * 2);
00224
00225 size_t count = 0;
00226
00227 float left = window_left;
00228 float right = window_left;
00229 float top = window_top;
00230 float bottom = window_top;
00231
00232 for (int y=0; y<mCoord.height; y+=mTileSize.height)
00233 {
00234 top = bottom;
00235 bottom -= mRealTileHeight;
00236 right = window_left;
00237
00238 float vertex_top = top;
00239 float vertex_bottom = bottom;
00240 bool texture_crop_height = false;
00241
00242 if (vertex_top > real_top)
00243 {
00244
00245 if (vertex_bottom > real_top)
00246 {
00247 continue;
00248 }
00249
00250 vertex_top = real_top;
00251 texture_crop_height = true;
00252 }
00253 if (vertex_bottom < real_bottom)
00254 {
00255
00256 if (vertex_top < real_bottom)
00257 {
00258 continue;
00259 }
00260
00261 vertex_bottom = real_bottom;
00262 texture_crop_height = true;
00263 }
00264
00265 for (int x=0; x<mCoord.width; x+=mTileSize.width)
00266 {
00267 left = right;
00268 right += mRealTileWidth;
00269
00270 float vertex_left = left;
00271 float vertex_right = right;
00272 bool texture_crop_width = false;
00273
00274
00275 if (vertex_left < real_left)
00276 {
00277
00278 if (vertex_right < real_left)
00279 {
00280 continue;
00281 }
00282
00283 vertex_left = real_left;
00284 texture_crop_width = true;
00285 }
00286
00287 if (vertex_right > real_right)
00288 {
00289
00290 if (vertex_left > real_right)
00291 {
00292 continue;
00293 }
00294
00295 vertex_right = real_right;
00296 texture_crop_width = true;
00297 }
00298
00299
00300 float texture_left = mCurrentTexture.left;
00301 float texture_right = mCurrentTexture.right;
00302 float texture_top = mCurrentTexture.top;
00303 float texture_bottom = mCurrentTexture.bottom;
00304
00305
00306 if (texture_crop_height)
00307 {
00308
00309 texture_top += (top - vertex_top) * mTextureHeightOne;
00310
00311 texture_bottom -= (vertex_bottom - bottom) * mTextureHeightOne;
00312 }
00313
00314
00315 if (texture_crop_width)
00316 {
00317
00318 texture_left += (vertex_left - left) * mTextureWidthOne;
00319
00320 texture_right -= (right - vertex_right) * mTextureWidthOne;
00321 }
00322
00323 quad[count].set(
00324 vertex_left,
00325 vertex_top,
00326 vertex_right,
00327 vertex_bottom,
00328 vertex_z,
00329 texture_left,
00330 texture_top,
00331 texture_right,
00332 texture_bottom,
00333 mCurrentColour
00334 );
00335
00336 count ++;
00337 }
00338 }
00339
00340 mRenderItem->setLastVertexCount(VertexQuad::VertexCount * count);
00341 }
00342
00343 void TileRect::createDrawItem(ITexture* _texture, ILayerNode * _node)
00344 {
00345 MYGUI_ASSERT(!mRenderItem, "mRenderItem must be nullptr");
00346
00347 mNode = _node;
00348 mRenderItem = mNode->addToRenderItem(_texture, this);
00349 mRenderItem->addDrawItem(this, mCountVertex);
00350 }
00351
00352 void TileRect::destroyDrawItem()
00353 {
00354 MYGUI_ASSERT(mRenderItem, "mRenderItem must be not nullptr");
00355
00356 mNode = nullptr;
00357 mRenderItem->removeDrawItem(this);
00358 mRenderItem = nullptr;
00359 }
00360
00361 void TileRect::setStateData(IStateInfo* _data)
00362 {
00363 TileRectStateInfo* data = _data->castType<TileRectStateInfo>();
00364
00365 mTileSize = data->getTileSize();
00366 mTileH = data->getTileH();
00367 mTileV = data->getTileV();
00368 _setUVSet(data->getRect());
00369 }
00370
00371 void TileRect::_setColour(const Colour& _value)
00372 {
00373 uint32 colour = texture_utility::toColourARGB(_value);
00374 texture_utility::convertColour(colour, RenderManager::getInstance().getVertexFormat());
00375 mCurrentColour = (colour & 0x00FFFFFF) | (mCurrentColour & 0xFF000000);
00376
00377 if (nullptr != mNode)
00378 mNode->outOfDate(mRenderItem);
00379 }
00380
00381 }