guiBitmapCtrl.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "console/console.h"
  23. #include "console/consoleTypes.h"
  24. #include "graphics/dgl.h"
  25. #include "gui/guiBitmapCtrl.h"
  26. IMPLEMENT_CONOBJECT(GuiBitmapCtrl);
  27. GuiBitmapCtrl::GuiBitmapCtrl(void)
  28. {
  29. mBitmapName = StringTable->EmptyString;
  30. startPoint.set(0, 0);
  31. mWrap = false;
  32. //Luma: Ability to specify source rect for image UVs
  33. mUseSourceRect = false;
  34. mSourceRect.set(0, 0, 0, 0);
  35. }
  36. bool GuiBitmapCtrl::setBitmapName( void *obj, const char *data )
  37. {
  38. // Prior to this, you couldn't do bitmap.bitmap = "foo.jpg" and have it work.
  39. // With protected console types you can now call the setBitmap function and
  40. // make it load the image.
  41. static_cast<GuiBitmapCtrl *>( obj )->setBitmap( data );
  42. // Return false because the setBitmap method will assign 'mBitmapName' to the
  43. // argument we are specifying in the call.
  44. return false;
  45. }
  46. void GuiBitmapCtrl::initPersistFields()
  47. {
  48. Parent::initPersistFields();
  49. addGroup("GuiBitmapCtrl");
  50. addProtectedField( "bitmap", TypeFilename, Offset( mBitmapName, GuiBitmapCtrl ), &setBitmapName, &defaultProtectedGetFn, "" );
  51. //addField("bitmap", TypeFilename, Offset(mBitmapName, GuiBitmapCtrl));
  52. addField("wrap", TypeBool, Offset(mWrap, GuiBitmapCtrl));
  53. endGroup("GuiBitmapCtrl");
  54. //Luma: ability to specify source rect for image UVs
  55. addGroup("Misc");
  56. //ability to specify source rect for image UVs
  57. addField( "useSourceRect", TypeBool, Offset( mUseSourceRect, GuiBitmapCtrl ));
  58. addField( "sourceRect", TypeRectI, Offset( mSourceRect, GuiBitmapCtrl ));
  59. endGroup("Misc");
  60. }
  61. ConsoleMethod( GuiBitmapCtrl, setValue, void, 4, 4, "(int xAxis, int yAxis)"
  62. "Set the offset of the bitmap.\n"
  63. "@return No return value."
  64. )
  65. {
  66. object->setValue(dAtoi(argv[2]), dAtoi(argv[3]));
  67. }
  68. ConsoleMethod( GuiBitmapCtrl, setBitmap, void, 3, 3, "( pathName ) Use the setBitmap method to change the bitmap this control uses.\n"
  69. "@param pathName A path to a new texture for this control. Limited to 256x256.\n"
  70. "@return No return value")
  71. {
  72. object->setBitmap(argv[2]);
  73. }
  74. ConsoleMethod(GuiBitmapCtrl, getTextureWidth, S32, 2, 2, "Gets the Width of the Texture.\n"
  75. "@return Texture Width"
  76. )
  77. {
  78. return object->getWidth();
  79. }
  80. ConsoleMethod(GuiBitmapCtrl, getTextureHeight, S32, 2, 2, "Gets the Height of the Texture.\n"
  81. "@return Texture Height"
  82. )
  83. {
  84. return object->getHeight();
  85. }
  86. bool GuiBitmapCtrl::onWake()
  87. {
  88. if (! Parent::onWake())
  89. return false;
  90. setActive(true);
  91. setBitmap(mBitmapName);
  92. return true;
  93. }
  94. void GuiBitmapCtrl::onSleep()
  95. {
  96. mTextureHandle = NULL;
  97. Parent::onSleep();
  98. }
  99. //-------------------------------------
  100. void GuiBitmapCtrl::inspectPostApply()
  101. {
  102. // if the extent is set to (0,0) in the gui editor and appy hit, this control will
  103. // set it's extent to be exactly the size of the bitmap (if present)
  104. Parent::inspectPostApply();
  105. if (!mWrap && (mBounds.extent.x == 0) && (mBounds.extent.y == 0) && mTextureHandle)
  106. {
  107. TextureObject *texture = (TextureObject *) mTextureHandle;
  108. mBounds.extent.x = texture->getBitmapWidth();
  109. mBounds.extent.y = texture->getBitmapHeight();
  110. }
  111. }
  112. void GuiBitmapCtrl::setBitmap(const char *name, bool resize)
  113. {
  114. mBitmapName = StringTable->insert(name);
  115. if (*mBitmapName) {
  116. mTextureHandle = TextureHandle(mBitmapName, TextureHandle::BitmapTexture, true);
  117. // Resize the control to fit the bitmap
  118. if (resize) {
  119. TextureObject* texture = (TextureObject *) mTextureHandle;
  120. mBounds.extent.x = texture->getBitmapWidth();
  121. mBounds.extent.y = texture->getBitmapHeight();
  122. GuiControl *parent = getParent();
  123. if( !parent ) {
  124. Con::errorf( "GuiBitmapCtrl::setBitmap( %s ), trying to resize but object has no parent.", name ) ;
  125. } else {
  126. Point2I extent = parent->getExtent();
  127. parentResized(extent,extent);
  128. }
  129. }
  130. }
  131. else
  132. mTextureHandle = NULL;
  133. setUpdate();
  134. }
  135. void GuiBitmapCtrl::setBitmap(const TextureHandle &handle, bool resize)
  136. {
  137. mTextureHandle = handle;
  138. // Resize the control to fit the bitmap
  139. if (resize) {
  140. TextureObject* texture = (TextureObject *) mTextureHandle;
  141. mBounds.extent.x = texture->getBitmapWidth();
  142. mBounds.extent.y = texture->getBitmapHeight();
  143. Point2I extent = getParent()->getExtent();
  144. parentResized(extent,extent);
  145. }
  146. }
  147. void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
  148. {
  149. if (mTextureHandle)
  150. {
  151. dglClearBitmapModulation();
  152. if(mWrap)
  153. {
  154. // We manually draw each repeat because non power of two textures will
  155. // not tile correctly when rendered with dglDrawBitmapTile(). The non POT
  156. // bitmap will be padded by the hardware, and we'll see lots of slack
  157. // in the texture. So... lets do what we must: draw each repeat by itself:
  158. TextureObject* texture = (TextureObject *) mTextureHandle;
  159. RectI srcRegion;
  160. RectI dstRegion;
  161. float xdone = ((float)mBounds.extent.x/(float)texture->getBitmapWidth())+1;
  162. float ydone = ((float)mBounds.extent.y/(float)texture->getBitmapHeight())+1;
  163. int xshift = startPoint.x%texture->getBitmapWidth();
  164. int yshift = startPoint.y%texture->getBitmapHeight();
  165. for(int y = 0; y < ydone; ++y)
  166. for(int x = 0; x < xdone; ++x)
  167. {
  168. //Luma: ability to specify source rect for image UVs
  169. if(mUseSourceRect && mSourceRect.isValidRect())
  170. {
  171. srcRegion = mSourceRect;
  172. }
  173. else
  174. {
  175. srcRegion.set(0,0,texture->getBitmapWidth(),texture->getBitmapHeight());
  176. }
  177. dstRegion.set( ((texture->getBitmapWidth()*x)+offset.x)-xshift,
  178. ((texture->getBitmapHeight()*y)+offset.y)-yshift,
  179. texture->getBitmapWidth(),
  180. texture->getBitmapHeight());
  181. dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
  182. }
  183. }
  184. else
  185. {
  186. RectI rect(offset, mBounds.extent);
  187. //Luma: ability to specify source rect for image UVs
  188. if(mUseSourceRect && mSourceRect.isValidRect() )
  189. {
  190. RectI srcRegion;
  191. srcRegion = mSourceRect;
  192. dglDrawBitmapStretchSR(mTextureHandle,rect, srcRegion, false);
  193. }
  194. else
  195. {
  196. dglDrawBitmapStretch(mTextureHandle, rect);
  197. }
  198. }
  199. }
  200. if (mProfile->mBorder || !mTextureHandle)
  201. {
  202. RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
  203. dglDrawRect(rect, mProfile->mBorderColor);
  204. }
  205. renderChildControls(offset, updateRect);
  206. }
  207. void GuiBitmapCtrl::setValue(S32 x, S32 y)
  208. {
  209. if (mTextureHandle)
  210. {
  211. TextureObject* texture = (TextureObject *) mTextureHandle;
  212. x+=texture->getBitmapWidth()/2;
  213. y+=texture->getBitmapHeight()/2;
  214. }
  215. while (x < 0)
  216. x += 256;
  217. startPoint.x = x % 256;
  218. while (y < 0)
  219. y += 256;
  220. startPoint.y = y % 256;
  221. }
  222. //Luma: ability to specify source rect for image UVs
  223. void GuiBitmapCtrl::setSourceRect(U32 x, U32 y, U32 width, U32 height)
  224. {
  225. mSourceRect.set(x, y, width, height);
  226. }
  227. void GuiBitmapCtrl::setUseSourceRect(bool bUse)
  228. {
  229. mUseSourceRect = bUse;
  230. }