CircularBar.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #include "CircularBar.h"
  2. #include "..\utils\InterfaceUtils.h"
  3. const int segment_count = 32;
  4. CircularBar:: CircularBar()
  5. {
  6. buffer = null;
  7. texture = null;
  8. m_drawPriority = 0;
  9. Circular_id = null;
  10. BarTexture = null;
  11. }
  12. CircularBar::~CircularBar()
  13. {
  14. RELEASE(buffer)
  15. RELEASE(texture)
  16. BarTexture = NULL;
  17. }
  18. void CircularBar::Restart()
  19. {
  20. ReCreate();
  21. }
  22. bool CircularBar::Create(MOPReader &reader)
  23. {
  24. if( !BarTexture )
  25. BarTexture = Render().GetTechniqueGlobalVariable("CircularTexture",_FL_);
  26. if( !Circular_id )
  27. Render().GetShaderId("Circular",Circular_id);
  28. if( !buffer )
  29. CreateBuffer();
  30. InitParams(reader);
  31. Show(true);
  32. return true;
  33. }
  34. bool CircularBar::EditMode_Update(MOPReader &reader)
  35. {
  36. InitParams(reader);
  37. return true;
  38. }
  39. void CircularBar::Activate(bool isActive)
  40. {
  41. //
  42. }
  43. void CircularBar::Show(bool isShow)
  44. {
  45. MissionObject::Show(isShow);
  46. if( isShow )
  47. SetUpdate(&CircularBar::Draw,ML_GUI1 + m_drawPriority);
  48. else
  49. DelUpdate(&CircularBar::Draw);
  50. if( isShow )
  51. LogicDebug("Show");
  52. else
  53. LogicDebug("Hide");
  54. }
  55. void _cdecl CircularBar::Draw(float dltTime, long level)
  56. {
  57. if( InterfaceUtils::IsHide())
  58. return;
  59. float m_w = this->m_w*m_aspect;
  60. float p = m_pos/m_max*segment_count;
  61. int n = ffloor(p);
  62. float u = p - n;
  63. Vertex *v = (Vertex *)buffer->Lock(0,0,LOCK_DISCARD);
  64. float b = 0.0f;
  65. for( int i = 0 ; i < n + 2 ; i++, b += 1.0f )
  66. {
  67. if( i > segment_count )
  68. break;
  69. float a = 2*PI*i/segment_count;
  70. float x = sinf(a);
  71. float y = cosf(a);
  72. if( i > n )
  73. {
  74. a = 2*PI*(i - 1)/segment_count;
  75. float d = sinf(a);
  76. float e = cosf(a);
  77. x = Lerp(d,x,u);
  78. y = Lerp(e,y,u);
  79. // a = 2*PI*(i - 1 + u)/segment_count;
  80. b = b - 1.0f + u;
  81. }
  82. v->p = Vector(
  83. x*m_outer*m_w + (m_x + m_w*0.5f)*2.0f - 1.0f,
  84. y*m_outer*m_h + 1.0f - (m_y + m_h*0.5f)*2.0f,0.0f);
  85. v->tu = b;
  86. v->tv = 0.0f;
  87. v->al = 1.0f;
  88. v++;
  89. v->p = Vector(
  90. x*m_inner*m_w + (m_x + m_w*0.5f)*2.0f - 1.0f,
  91. y*m_inner*m_h + 1.0f - (m_y + m_h*0.5f)*2.0f,0.0f);
  92. v->tu = b;
  93. v->tv = 1.0f;
  94. v->al = 1.0f;
  95. v++;
  96. }
  97. buffer->Unlock();
  98. if( n > 0 )
  99. {
  100. Render().SetStreamSource(0,buffer);
  101. if( BarTexture && texture )
  102. BarTexture->SetTexture(texture);
  103. if( n <= segment_count && u > 0.0f )
  104. n++;
  105. Render().DrawPrimitive(Circular_id,
  106. PT_TRIANGLESTRIP,0,n*2);
  107. }
  108. }
  109. void CircularBar::Command(const char *id, dword numParams, const char **params)
  110. {
  111. if( string::IsEmpty(id))
  112. return;
  113. if( string::IsEqual(id,"set_max"))
  114. {
  115. if( numParams < 1 )
  116. {
  117. LogicDebugError("Command <set_max> error. Not enought parameters.");
  118. return;
  119. }
  120. m_max = (float)atof(params[0]);
  121. LogicDebug("Command <set_max>. Max pos = %.",m_max);
  122. }
  123. else
  124. if( string::IsEqual(id,"set_pos"))
  125. {
  126. if( numParams < 1 )
  127. {
  128. LogicDebugError("Command <set_pos> error. Not enought parameters.");
  129. return;
  130. }
  131. m_pos = (float)atof(params[0]);
  132. if( m_pos > m_max )
  133. m_pos = m_max;
  134. LogicDebug("Command <set_pos>. Cur pos = %.",m_pos);
  135. }
  136. else
  137. if( string::IsEqual(id,"restart"))
  138. {
  139. Restart();
  140. LogicDebug("Command <restart>. Bar was restarted.",m_pos);
  141. }
  142. else
  143. {
  144. LogicDebugError("Unknown command \"%s\".",id);
  145. }
  146. }
  147. void CircularBar::SetPos(float val)
  148. {
  149. m_pos = val;
  150. if( m_pos > m_max )
  151. m_pos = m_max;
  152. }
  153. void CircularBar::CreateBuffer()
  154. {
  155. // if( buffer )
  156. // buffer->Release();
  157. buffer = Render().CreateVertexBuffer(
  158. sizeof(Vertex)*(segment_count + 1)*2,
  159. sizeof(Vertex),
  160. _FL_,USAGE_WRITEONLY|USAGE_DYNAMIC,POOL_DEFAULT);
  161. Assert(buffer)
  162. }
  163. void CircularBar::InitAspect()
  164. {
  165. // все элементы создаются из расчета этого аспекта
  166. const float def_aspect = 16.0f/9.0f;
  167. float cx;
  168. float cy;
  169. if( EditMode_IsOn())
  170. {
  171. // cx = (float)Render().GetViewport().Width;
  172. // cy = (float)Render().GetViewport().Height;
  173. cx = (float)Render().GetFullScreenViewPort_2D().Width;
  174. cy = (float)Render().GetFullScreenViewPort_2D().Height;
  175. }
  176. else
  177. {
  178. cx = (float)Render().GetFullScreenViewPort_2D().Width;
  179. cy = (float)Render().GetFullScreenViewPort_2D().Height;
  180. }
  181. // аспект разрешения экрана
  182. float scr_aspect = cx/cy;
  183. // api->Trace("");
  184. // api->Trace(" WINDOW: asp = %f res = %.0fx%.0f",scr_aspect,cx,cy);
  185. // аспект пикселя
  186. float dot_aspect = InterfaceUtils::AspectRatio(Render());
  187. // api->Trace(" DOT: asp = %f",dot_aspect);
  188. // api->Trace("");
  189. // реальный аспект
  190. float cur_aspect = scr_aspect/dot_aspect;
  191. // m_aspect = def_aspect/cur_aspect;
  192. // m_aspect_native = cur_aspect;
  193. m_aspect = def_aspect/cur_aspect;
  194. }
  195. void CircularBar::InitParams(MOPReader &reader)
  196. {
  197. // m_aspect = InterfaceUtils::AspectRatio(Render());
  198. InitAspect();
  199. const char *t = reader.String().c_str();
  200. if( !texture || !string::IsEqual(texture->GetName(),t))
  201. {
  202. if( texture )
  203. texture->Release();
  204. // texture = Render().CreateTexture(_FL_,t);
  205. texture = Render().CreateTextureFullQuality(_FL_,t);
  206. }
  207. m_x = reader.Float()*0.01f;
  208. m_y = reader.Float()*0.01f;
  209. m_w = reader.Float()*0.01f;
  210. m_h = reader.Float()*0.01f;
  211. m_inner = reader.Float();
  212. m_outer = reader.Float();
  213. m_max = reader.Float();
  214. m_pos = reader.Float();
  215. if( m_pos > m_max )
  216. m_pos = m_max;
  217. m_drawPriority = reader.Long();
  218. }
  219. MOP_BEGINLISTCG(CircularBar, "CircularBar", '1.00', 100, "CircularBar\n\n Circular progress bar\n\nAviable commands list:\n\n set_max - set max value\n\n param[0] - new value\n\n set_pos - set position\n\n param[0] - new value", "Interface")
  220. MOP_STRING("texture", "")
  221. MOP_FLOAT("x", 0.0f)
  222. MOP_FLOAT("y", 0.0f)
  223. MOP_FLOAT("w", 1.0f)
  224. MOP_FLOAT("h", 1.0f)
  225. MOP_FLOAT("inner", 0.7f)
  226. MOP_FLOAT("outer", 1.0f)
  227. MOP_FLOAT("max", 1.0f)
  228. MOP_FLOAT("pos", 0.0f)
  229. MOP_LONG("Draw priority", 0)
  230. MOP_ENDLIST(CircularBar)