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