guiBitmapCtrl.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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. mTextureHandle.setFilter(GL_LINEAR);
  118. // Resize the control to fit the bitmap
  119. if (resize) {
  120. TextureObject* texture = (TextureObject *) mTextureHandle;
  121. mBounds.extent.x = texture->getBitmapWidth();
  122. mBounds.extent.y = texture->getBitmapHeight();
  123. GuiControl *parent = getParent();
  124. if( !parent ) {
  125. Con::errorf( "GuiBitmapCtrl::setBitmap( %s ), trying to resize but object has no parent.", name ) ;
  126. } else {
  127. Point2I extent = parent->getExtent();
  128. parentResized(extent,extent);
  129. }
  130. }
  131. }
  132. else
  133. mTextureHandle = NULL;
  134. setUpdate();
  135. }
  136. void GuiBitmapCtrl::setBitmap(const TextureHandle &handle, bool resize)
  137. {
  138. mTextureHandle = handle;
  139. // Resize the control to fit the bitmap
  140. if (resize) {
  141. TextureObject* texture = (TextureObject *) mTextureHandle;
  142. mBounds.extent.x = texture->getBitmapWidth();
  143. mBounds.extent.y = texture->getBitmapHeight();
  144. Point2I extent = getParent()->getExtent();
  145. parentResized(extent,extent);
  146. }
  147. }
  148. void GuiBitmapCtrl::onRender(Point2I offset, const RectI &updateRect)
  149. {
  150. if (mTextureHandle)
  151. {
  152. dglClearBitmapModulation();
  153. if(mWrap)
  154. {
  155. // We manually draw each repeat because non power of two textures will
  156. // not tile correctly when rendered with dglDrawBitmapTile(). The non POT
  157. // bitmap will be padded by the hardware, and we'll see lots of slack
  158. // in the texture. So... lets do what we must: draw each repeat by itself:
  159. TextureObject* texture = (TextureObject *) mTextureHandle;
  160. RectI srcRegion;
  161. RectI dstRegion;
  162. float xdone = ((float)mBounds.extent.x/(float)texture->getBitmapWidth())+1;
  163. float ydone = ((float)mBounds.extent.y/(float)texture->getBitmapHeight())+1;
  164. int xshift = startPoint.x%texture->getBitmapWidth();
  165. int yshift = startPoint.y%texture->getBitmapHeight();
  166. for(int y = 0; y < ydone; ++y)
  167. for(int x = 0; x < xdone; ++x)
  168. {
  169. //Luma: ability to specify source rect for image UVs
  170. if(mUseSourceRect && mSourceRect.isValidRect())
  171. {
  172. srcRegion = mSourceRect;
  173. }
  174. else
  175. {
  176. srcRegion.set(0,0,texture->getBitmapWidth(),texture->getBitmapHeight());
  177. }
  178. dstRegion.set( ((texture->getBitmapWidth()*x)+offset.x)-xshift,
  179. ((texture->getBitmapHeight()*y)+offset.y)-yshift,
  180. texture->getBitmapWidth(),
  181. texture->getBitmapHeight());
  182. dglDrawBitmapStretchSR(texture,dstRegion, srcRegion, false);
  183. }
  184. }
  185. else
  186. {
  187. RectI rect(offset, mBounds.extent);
  188. //Luma: ability to specify source rect for image UVs
  189. if(mUseSourceRect && mSourceRect.isValidRect() )
  190. {
  191. RectI srcRegion;
  192. srcRegion = mSourceRect;
  193. dglDrawBitmapStretchSR(mTextureHandle,rect, srcRegion, false);
  194. }
  195. else
  196. {
  197. dglDrawBitmapStretch(mTextureHandle, rect);
  198. }
  199. }
  200. }
  201. if (mProfile->mBorder || !mTextureHandle)
  202. {
  203. RectI rect(offset.x, offset.y, mBounds.extent.x, mBounds.extent.y);
  204. dglDrawRect(rect, mProfile->mBorderColor);
  205. }
  206. renderChildControls(offset, updateRect);
  207. }
  208. void GuiBitmapCtrl::setValue(S32 x, S32 y)
  209. {
  210. if (mTextureHandle)
  211. {
  212. TextureObject* texture = (TextureObject *) mTextureHandle;
  213. x+=texture->getBitmapWidth()/2;
  214. y+=texture->getBitmapHeight()/2;
  215. }
  216. while (x < 0)
  217. x += 256;
  218. startPoint.x = x % 256;
  219. while (y < 0)
  220. y += 256;
  221. startPoint.y = y % 256;
  222. }
  223. //Luma: ability to specify source rect for image UVs
  224. void GuiBitmapCtrl::setSourceRect(U32 x, U32 y, U32 width, U32 height)
  225. {
  226. mSourceRect.set(x, y, width, height);
  227. }
  228. void GuiBitmapCtrl::setUseSourceRect(bool bUse)
  229. {
  230. mUseSourceRect = bUse;
  231. }