SampleInterfaces.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. #define _USE_MATH_DEFINES
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdarg.h>
  5. #include "SampleInterfaces.h"
  6. #include "Recast.h"
  7. #include "RecastDebugDraw.h"
  8. #include "DetourDebugDraw.h"
  9. #include "PerfTimer.h"
  10. #include "SDL.h"
  11. #include "SDL_opengl.h"
  12. #ifdef WIN32
  13. # define snprintf _snprintf
  14. #endif
  15. ////////////////////////////////////////////////////////////////////////////////////////////////////
  16. BuildContext::BuildContext() :
  17. m_messageCount(0),
  18. m_textPoolSize(0)
  19. {
  20. memset(m_messages, 0, sizeof(char*) * MAX_MESSAGES);
  21. resetTimers();
  22. }
  23. // Virtual functions for custom implementations.
  24. void BuildContext::doResetLog()
  25. {
  26. m_messageCount = 0;
  27. m_textPoolSize = 0;
  28. }
  29. void BuildContext::doLog(const rcLogCategory category, const char* msg, const int len)
  30. {
  31. if (!len) return;
  32. if (m_messageCount >= MAX_MESSAGES)
  33. return;
  34. char* dst = &m_textPool[m_textPoolSize];
  35. int n = TEXT_POOL_SIZE - m_textPoolSize;
  36. if (n < 2)
  37. return;
  38. char* cat = dst;
  39. char* text = dst+1;
  40. const int maxtext = n-1;
  41. // Store category
  42. *cat = (char)category;
  43. // Store message
  44. const int count = rcMin(len+1, maxtext);
  45. memcpy(text, msg, count);
  46. text[count-1] = '\0';
  47. m_textPoolSize += 1 + count;
  48. m_messages[m_messageCount++] = dst;
  49. }
  50. void BuildContext::doResetTimers()
  51. {
  52. for (int i = 0; i < RC_MAX_TIMERS; ++i)
  53. m_accTime[i] = -1;
  54. }
  55. void BuildContext::doStartTimer(const rcTimerLabel label)
  56. {
  57. m_startTime[label] = getPerfTime();
  58. }
  59. void BuildContext::doStopTimer(const rcTimerLabel label)
  60. {
  61. const TimeVal endTime = getPerfTime();
  62. const TimeVal deltaTime = endTime - m_startTime[label];
  63. if (m_accTime[label] == -1)
  64. m_accTime[label] = deltaTime;
  65. else
  66. m_accTime[label] += deltaTime;
  67. }
  68. int BuildContext::doGetAccumulatedTime(const rcTimerLabel label) const
  69. {
  70. return getPerfTimeUsec(m_accTime[label]);
  71. }
  72. void BuildContext::dumpLog(const char* format, ...)
  73. {
  74. // Print header.
  75. va_list ap;
  76. va_start(ap, format);
  77. vprintf(format, ap);
  78. va_end(ap);
  79. printf("\n");
  80. // Print messages
  81. const int TAB_STOPS[4] = { 28, 36, 44, 52 };
  82. for (int i = 0; i < m_messageCount; ++i)
  83. {
  84. const char* msg = m_messages[i]+1;
  85. int n = 0;
  86. while (*msg)
  87. {
  88. if (*msg == '\t')
  89. {
  90. int count = 1;
  91. for (int j = 0; j < 4; ++j)
  92. {
  93. if (n < TAB_STOPS[j])
  94. {
  95. count = TAB_STOPS[j] - n;
  96. break;
  97. }
  98. }
  99. while (--count)
  100. {
  101. putchar(' ');
  102. n++;
  103. }
  104. }
  105. else
  106. {
  107. putchar(*msg);
  108. n++;
  109. }
  110. msg++;
  111. }
  112. putchar('\n');
  113. }
  114. }
  115. int BuildContext::getLogCount() const
  116. {
  117. return m_messageCount;
  118. }
  119. const char* BuildContext::getLogText(const int i) const
  120. {
  121. return m_messages[i]+1;
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////////////////////////
  124. class GLCheckerTexture
  125. {
  126. unsigned int m_texId;
  127. public:
  128. GLCheckerTexture() : m_texId(0)
  129. {
  130. }
  131. ~GLCheckerTexture()
  132. {
  133. if (m_texId != 0)
  134. glDeleteTextures(1, &m_texId);
  135. }
  136. void bind()
  137. {
  138. if (m_texId == 0)
  139. {
  140. // Create checker pattern.
  141. const unsigned int col0 = duRGBA(215,215,215,255);
  142. const unsigned int col1 = duRGBA(255,255,255,255);
  143. static const int TSIZE = 64;
  144. unsigned int data[TSIZE*TSIZE];
  145. glGenTextures(1, &m_texId);
  146. glBindTexture(GL_TEXTURE_2D, m_texId);
  147. int level = 0;
  148. int size = TSIZE;
  149. while (size > 0)
  150. {
  151. for (int y = 0; y < size; ++y)
  152. for (int x = 0; x < size; ++x)
  153. data[x+y*size] = (x==0 || y==0) ? col0 : col1;
  154. glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size,size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  155. size /= 2;
  156. level++;
  157. }
  158. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  159. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  160. }
  161. else
  162. {
  163. glBindTexture(GL_TEXTURE_2D, m_texId);
  164. }
  165. }
  166. };
  167. GLCheckerTexture g_tex;
  168. void DebugDrawGL::depthMask(bool state)
  169. {
  170. glDepthMask(state ? GL_TRUE : GL_FALSE);
  171. }
  172. void DebugDrawGL::texture(bool state)
  173. {
  174. if (state)
  175. {
  176. glEnable(GL_TEXTURE_2D);
  177. g_tex.bind();
  178. }
  179. else
  180. {
  181. glDisable(GL_TEXTURE_2D);
  182. }
  183. }
  184. void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
  185. {
  186. switch (prim)
  187. {
  188. case DU_DRAW_POINTS:
  189. glPointSize(size);
  190. glBegin(GL_POINTS);
  191. break;
  192. case DU_DRAW_LINES:
  193. glLineWidth(size);
  194. glBegin(GL_LINES);
  195. break;
  196. case DU_DRAW_TRIS:
  197. glBegin(GL_TRIANGLES);
  198. break;
  199. case DU_DRAW_QUADS:
  200. glBegin(GL_QUADS);
  201. break;
  202. };
  203. }
  204. void DebugDrawGL::vertex(const float* pos, unsigned int color)
  205. {
  206. glColor4ubv((GLubyte*)&color);
  207. glVertex3fv(pos);
  208. }
  209. void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color)
  210. {
  211. glColor4ubv((GLubyte*)&color);
  212. glVertex3f(x,y,z);
  213. }
  214. void DebugDrawGL::vertex(const float* pos, unsigned int color, const float* uv)
  215. {
  216. glColor4ubv((GLubyte*)&color);
  217. glTexCoord2fv(uv);
  218. glVertex3fv(pos);
  219. }
  220. void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v)
  221. {
  222. glColor4ubv((GLubyte*)&color);
  223. glTexCoord2f(u,v);
  224. glVertex3f(x,y,z);
  225. }
  226. void DebugDrawGL::end()
  227. {
  228. glEnd();
  229. glLineWidth(1.0f);
  230. glPointSize(1.0f);
  231. }
  232. ////////////////////////////////////////////////////////////////////////////////////////////////////
  233. FileIO::FileIO() :
  234. m_fp(0),
  235. m_mode(-1)
  236. {
  237. }
  238. FileIO::~FileIO()
  239. {
  240. if (m_fp) fclose(m_fp);
  241. }
  242. bool FileIO::openForWrite(const char* path)
  243. {
  244. if (m_fp) return false;
  245. m_fp = fopen(path, "wb");
  246. if (!m_fp) return false;
  247. m_mode = 1;
  248. return true;
  249. }
  250. bool FileIO::openForRead(const char* path)
  251. {
  252. if (m_fp) return false;
  253. m_fp = fopen(path, "rb");
  254. if (!m_fp) return false;
  255. m_mode = 2;
  256. return true;
  257. }
  258. bool FileIO::isWriting() const
  259. {
  260. return m_mode == 1;
  261. }
  262. bool FileIO::isReading() const
  263. {
  264. return m_mode == 2;
  265. }
  266. bool FileIO::write(const void* ptr, const size_t size)
  267. {
  268. if (!m_fp || m_mode != 1) return false;
  269. fwrite(ptr, size, 1, m_fp);
  270. return true;
  271. }
  272. bool FileIO::read(void* ptr, const size_t size)
  273. {
  274. if (!m_fp || m_mode != 2) return false;
  275. size_t readLen = fread(ptr, size, 1, m_fp);
  276. return readLen == 1;
  277. }