Renderer.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //
  2. // Created by jovian on 18/07/17.
  3. //
  4. #include <iostream>
  5. #include "Renderer.h"
  6. #define RAD_TO_DEG 57.2957795130f
  7. Renderer::Renderer()
  8. : m_screenWidth(0), m_screenHeight(0), m_window(nullptr), m_renderer(nullptr), m_font(nullptr) {}
  9. Renderer::~Renderer() {
  10. // Destroy textures
  11. while (!m_pictureTab.empty()) {
  12. if (m_pictureTab.back() != nullptr)
  13. SDL_DestroyTexture(m_pictureTab.back());
  14. m_pictureTab.pop_back();
  15. }
  16. // Destroy string textures
  17. for (auto it(m_stringTab.begin()); it != m_stringTab.end(); it++) {
  18. if (it->second != nullptr)
  19. SDL_DestroyTexture(it->second);
  20. it->second = nullptr;
  21. }
  22. m_stringTab.clear();
  23. // Destroy SDL renderer
  24. if (m_renderer != nullptr) {
  25. SDL_DestroyRenderer(m_renderer);
  26. m_renderer = nullptr;
  27. }
  28. // Destroy the beautiful window
  29. if (m_window != nullptr) {
  30. SDL_DestroyWindow(m_window);
  31. m_window = nullptr;
  32. }
  33. // Quit modules
  34. TTF_Quit();
  35. SDL_Quit();
  36. }
  37. bool Renderer::initialize() {
  38. // Announce
  39. std::cout << "Renderer::initialize() > ";
  40. // Already initialized
  41. if (m_window != nullptr) {
  42. std::cout << "Window already created." << std::endl << std::endl;
  43. return false;
  44. }
  45. // Default screen size
  46. m_screenWidth = WIN_W;
  47. m_screenHeight = WIN_H;
  48. // Init video
  49. if (SDL_Init(SDL_INIT_VIDEO) != 0) {
  50. std::cout << "SDL video failed : " << SDL_GetError() << std::endl << std::endl;
  51. return false;
  52. }
  53. // Init font
  54. if (TTF_Init() == -1) {
  55. std::cout << "TTF failed : " << TTF_GetError() << std::endl << std::endl;
  56. return false;
  57. }
  58. m_font = TTF_OpenFont("droid.ttf", 28);
  59. if (m_font == NULL) {
  60. std::cout << "Open droid.ttf failed : " << TTF_GetError() << std::endl << std::endl;
  61. return false;
  62. }
  63. // Opening window
  64. m_window = SDL_CreateWindow("MetaBalls visualizer - Jovian Hersemeule",
  65. SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  66. m_screenWidth, m_screenHeight,
  67. SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN_DESKTOP*/);
  68. if (m_window == nullptr) {
  69. std::cout << "Window creation failed : " << SDL_GetError() << std::endl << std::endl;
  70. SDL_Quit();
  71. return false;
  72. }
  73. // Hardware physical screen size
  74. SDL_GetWindowSize(m_window, &m_screenWidth, &m_screenHeight);
  75. // Create renderer
  76. m_renderer = SDL_CreateRenderer(m_window, -1,
  77. SDL_RENDERER_ACCELERATED |
  78. SDL_RENDERER_PRESENTVSYNC);
  79. if (m_renderer == nullptr) {
  80. SDL_DestroyWindow(m_window);
  81. std::cout << "SDL Renderer creation failed : " << SDL_GetError() << std::endl << std::endl;
  82. SDL_Quit();
  83. return false;
  84. }
  85. // End
  86. std::cout << "Done, no error detected." << std::endl;
  87. // Okay
  88. return true;
  89. }
  90. void Renderer::clearWindow() {
  91. // Clean up buffer
  92. SDL_SetRenderDrawColor(m_renderer, 0x00, 0x00, 0x00, 0x00);
  93. SDL_RenderClear(m_renderer);
  94. }
  95. /*void Renderer::renderScene(std::vector<Visual *> &scope, const b2Vec2 &center, float zoom) {
  96. // Texture existence
  97. if (m_pictureTab.empty())
  98. return;
  99. // Rect
  100. SDL_Rect dst;
  101. SDL_Texture *tex;
  102. b2Vec2 rel;
  103. float localZoom;
  104. // For each
  105. for (auto it(scope.begin()); it != scope.end(); it++) {
  106. // Skip if no invalid texture
  107. if ((*it)->getImgId() > m_pictureTab.size() || m_pictureTab[(*it)->getImgId()] == nullptr)
  108. tex = m_pictureTab[0];
  109. else
  110. tex = m_pictureTab[(*it)->getImgId()];
  111. // Adjusting local zoom
  112. localZoom = zoom * (*it)->getScale();
  113. // Rect set up
  114. rel = (*it)->getPos() - center;
  115. dst.x = (int) (rel.x * zoom) + m_screenWidth / 2;
  116. dst.y = (int) (rel.y * zoom) + m_screenHeight / 2;
  117. SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
  118. // Zoom correction
  119. dst.w = (int) (localZoom * dst.w / DEFAULT_ZOOM);
  120. dst.h = (int) (localZoom * dst.h / DEFAULT_ZOOM);
  121. // Center texture
  122. dst.x -= dst.w / 2;
  123. dst.y -= dst.h / 2;
  124. // SDL rendering
  125. SDL_RenderCopyEx(m_renderer, tex, NULL, &dst, (*it)->getAngle() * RAD_TO_DEG, NULL, SDL_FLIP_NONE);
  126. }
  127. }*/
  128. /*void Renderer::renderPlanetHUD(PlanetDef def) {
  129. // Variable
  130. SDL_Rect dst;
  131. // Line under color
  132. const Uint8 uncl(0xaf);
  133. // Render rect
  134. dst.x = 10;
  135. dst.y = 10;
  136. int w = m_screenWidth / 2 - 2*dst.x + 24;
  137. int h = m_screenHeight * 2 / 3 - 2*dst.y;
  138. dst.w = w;
  139. dst.h = h;
  140. SDL_SetRenderDrawColor(m_renderer, 0x66, 0x66, 0x66, 0xff);
  141. SDL_RenderFillRect(m_renderer, &dst);
  142. SDL_SetRenderDrawColor(m_renderer, 0xff, 0xff, 0xff, 0xff);
  143. SDL_RenderDrawRect(m_renderer, &dst);
  144. SDL_RenderDrawLine(m_renderer, dst.x, dst.y + 37, dst.x + dst.w - 1, dst.y + 37);
  145. // Render planet name
  146. dst.x = 11;
  147. dst.y = 11;
  148. renderName(dst, def.name);
  149. // Column
  150. dst.x = 20;
  151. // Jumps
  152. #define H_NEXT_BAR 32
  153. #define H_OFFSET_BAR 10
  154. // People
  155. dst.y = 60;
  156. SDL_SetRenderDrawColor(m_renderer, uncl, uncl, uncl, 0xff);
  157. SDL_RenderDrawLine(m_renderer, dst.x, dst.y + H_OFFSET_BAR + 8, dst.x + w - 12, dst.y + H_OFFSET_BAR + 8);
  158. renderName(dst, "People");
  159. renderBar(dst.y + H_OFFSET_BAR, def.stock.get(PEOPLE));
  160. }*/
  161. void Renderer::renderName(SDL_Rect &dst, std::string name) {
  162. // Seek an existing name texture
  163. auto it(m_stringTab.find(name));
  164. if (it == m_stringTab.end()) {
  165. // Not loaded yet, let's fix this !
  166. if (!loadStringTexture(name))
  167. return;
  168. SDL_QueryTexture(m_stringTab[name], NULL, NULL, &dst.w, &dst.h);
  169. SDL_RenderCopy(m_renderer, m_stringTab[name], NULL, &dst);
  170. } else {
  171. // Faster plot
  172. SDL_QueryTexture(it->second, NULL, NULL, &dst.w, &dst.h);
  173. SDL_RenderCopy(m_renderer, it->second, NULL, &dst);
  174. }
  175. }
  176. void Renderer::renderBoolMatrix(bool mat[WIN_H][WIN_W]) {
  177. SDL_SetRenderDrawColor(m_renderer, 255, 255, 0, 255);
  178. std::vector<SDL_Point> points;
  179. for (int i(0); i < WIN_H; i++)
  180. for (int j(0); j < WIN_W; j++) {
  181. if (mat[i][j])
  182. //SDL_RenderDrawPoint(m_renderer, j, i);
  183. points.push_back({j, i});
  184. }
  185. SDL_RenderDrawPoints(m_renderer, points.data(), (int)points.size());
  186. }
  187. /*void Renderer::renderBar(int y, const int &value) {
  188. // Set position
  189. SDL_Rect dst;
  190. dst.x = 208;
  191. dst.y = y;
  192. dst.h = 16;
  193. // Set color and scale
  194. if (value == 0) {
  195. SDL_SetRenderDrawColor(m_renderer, 0x00, 0x00, 0x00, 0xff);
  196. dst.w = dst.h;
  197. }
  198. else if (value < 400) {
  199. SDL_SetRenderDrawColor(m_renderer, 0x00, 0xff, 0x00, 0xff);
  200. dst.w = value;
  201. }
  202. else if (value < 4000) {
  203. SDL_SetRenderDrawColor(m_renderer, 0xff, 0xff, 0x00, 0xff);
  204. dst.w = value / 10;
  205. }
  206. else if (value < 400000) {
  207. SDL_SetRenderDrawColor(m_renderer, 0xff, 0xaa, 0x00, 0xff);
  208. dst.w = value / 1000;
  209. }
  210. else if (value < 40000000) {
  211. SDL_SetRenderDrawColor(m_renderer, 0xff, 0x55, 0x00, 0xff);
  212. dst.w = value / 100000;
  213. }
  214. else {
  215. SDL_SetRenderDrawColor(m_renderer, 0xff, 0x00, 0x00, 0xff);
  216. dst.w = value / 10000000;
  217. }
  218. // Draw
  219. SDL_RenderFillRect(m_renderer, &dst);
  220. SDL_SetRenderDrawColor(m_renderer, 0xaf, 0xaf, 0xaf, 0xff);
  221. if (value == 0) {
  222. SDL_RenderDrawLine(m_renderer, dst.x, dst.y, dst.x + dst.w - 1, dst.y + dst.h - 1);
  223. SDL_RenderDrawLine(m_renderer, dst.x, dst.y + dst.h - 1, dst.x + dst.w - 1, dst.y);
  224. } else {
  225. dst.w = 400;
  226. }
  227. SDL_RenderDrawRect(m_renderer, &dst);
  228. }*/
  229. void Renderer::presentWindow() {
  230. // Activate display
  231. SDL_RenderPresent(m_renderer);
  232. }
  233. bool Renderer::loadStringTexture(std::string name) {
  234. // Render text surface
  235. //SDL_Surface* textSurface = TTF_RenderText_Solid(m_font, name.c_str(), {0, 255, 0, 255});
  236. SDL_Surface *textSurface = TTF_RenderText_Shaded(m_font, name.c_str(), {0x00, 0xff, 0x00, 0xff},
  237. {0x66, 0x66, 0x66, 0xff});
  238. if (textSurface == NULL) {
  239. std::cout << "Renderer::loadStringTexture() [1] > " << TTF_GetError() << std::endl << std::endl;
  240. return false;
  241. }
  242. // Create texture from surface pixels
  243. SDL_Texture *texture(SDL_CreateTextureFromSurface(m_renderer, textSurface));
  244. SDL_FreeSurface(textSurface);
  245. if (texture == NULL) {
  246. std::cout << "Renderer::loadStringTexture() [2] > " << SDL_GetError() << std::endl << std::endl;
  247. return false;
  248. }
  249. m_stringTab[name] = texture;
  250. // All right
  251. return true;
  252. }
  253. SDL_Window *Renderer::getWindow() const {
  254. return m_window;
  255. }