You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
8.1 KiB

  1. /*
  2. Copyright 2005-2014 Intel Corporation. All Rights Reserved.
  3. This file is part of Threading Building Blocks.
  4. Threading Building Blocks is free software; you can redistribute it
  5. and/or modify it under the terms of the GNU General Public License
  6. version 2 as published by the Free Software Foundation.
  7. Threading Building Blocks is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  9. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with Threading Building Blocks; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14. As a special exception, you may use this file as part of a free software
  15. library without restriction. Specifically, if other files instantiate
  16. templates or use macros or inline functions from this file, or you compile
  17. this file and link it with other files to produce an executable, this
  18. file does not by itself cause the resulting executable to be covered by
  19. the GNU General Public License. This exception does not however
  20. invalidate any other reasons why the executable file might be covered by
  21. the GNU General Public License.
  22. */
  23. #ifndef __VIDEO_H__
  24. #define __VIDEO_H__
  25. #include <cassert>
  26. #if _MSC_VER
  27. #include <stddef.h> // for uintptr_t
  28. #else
  29. #include <stdint.h> // for uintptr_t
  30. #endif
  31. #if _WIN32 || _WIN64
  32. #include <windows.h>
  33. #else
  34. #include <unistd.h>
  35. #endif
  36. typedef unsigned int color_t;
  37. typedef unsigned char colorcomp_t;
  38. typedef signed char depth_t;
  39. //! Class for getting access to drawing memory
  40. class drawing_memory
  41. {
  42. #ifdef __TBB_MIC_OFFLOAD
  43. // The address is kept as uintptr_t since
  44. // the compiler could not offload a pointer
  45. #endif
  46. uintptr_t my_address;
  47. public:
  48. depth_t pixel_depth;
  49. int sizex, sizey;
  50. //! Get drawing memory
  51. inline char* get_address() const { return reinterpret_cast<char*>(my_address); }
  52. //! Get drawing memory size
  53. inline int get_size() const { return ((pixel_depth>16) ? 4:2) * sizex * sizey; }
  54. //! Set drawing memory
  55. inline void set_address(char *mem) { my_address = reinterpret_cast<uintptr_t>(mem); }
  56. friend class drawing_area;
  57. friend class video;
  58. };
  59. //! Simple proxy class for managing of different video systems
  60. class video
  61. {
  62. //! colorspace information
  63. depth_t depth, red_shift, green_shift, blue_shift;
  64. color_t red_mask, green_mask, blue_mask;
  65. friend class drawing_area;
  66. public:
  67. //! Constructor
  68. video();
  69. //! Destructor
  70. ~video();
  71. //! member to set window name
  72. const char *title;
  73. //! true is enable to show fps
  74. bool calc_fps;
  75. //! if true: on windows fork processing thread for on_process(), on non-windows note that next_frame() is called concurrently.
  76. bool threaded;
  77. //! true while running within main_loop()
  78. bool running;
  79. //! if true, do gui updating
  80. bool updating;
  81. //! initialize graphical video system
  82. bool init_window(int sizex, int sizey);
  83. //! initialize console. returns true if console is available
  84. bool init_console();
  85. //! terminate video system
  86. void terminate();
  87. //! Do standard event & processing loop. Use threaded = true to separate event/updating loop from frame processing
  88. void main_loop();
  89. //! Process next frame
  90. bool next_frame();
  91. //! Change window title
  92. void show_title();
  93. //! translate RGB components into packed type
  94. inline color_t get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const;
  95. //! Get drawing memory descriptor
  96. inline drawing_memory get_drawing_memory() const;
  97. //! code of the ESCape key
  98. static const int esc_key = 27;
  99. //! Mouse events handler.
  100. virtual void on_mouse(int x, int y, int key) { }
  101. //! Mouse events handler.
  102. virtual void on_key(int key) { }
  103. //! Main processing loop. Redefine with your own
  104. virtual void on_process() { while(next_frame()); }
  105. #ifdef _WINDOWS
  106. //! Windows specific members
  107. //! if VIDEO_WINMAIN isn't defined then set this just before init() by arguments of WinMain
  108. static HINSTANCE win_hInstance; static int win_iCmdShow;
  109. //! optionally call it just before init() to set own. Use ascii strings convention
  110. void win_set_class(WNDCLASSEX &);
  111. //! load and set accelerator table from resources
  112. void win_load_accelerators(int idc);
  113. #endif
  114. };
  115. //! Drawing class
  116. class drawing_area
  117. {
  118. const size_t base_index, max_index, index_stride;
  119. const depth_t pixel_depth;
  120. unsigned int * const ptr32;
  121. size_t index;
  122. public:
  123. const int start_x, start_y, size_x, size_y;
  124. //! constructors
  125. drawing_area(int x, int y, int sizex, int sizey);
  126. inline drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem);
  127. //! destructor
  128. inline ~drawing_area();
  129. //! update the image
  130. void update();
  131. //! set current position. local_x could be bigger then size_x
  132. inline void set_pos(int local_x, int local_y);
  133. //! put pixel in current position with incremental address calculating to next right pixel
  134. inline void put_pixel(color_t color);
  135. //! draw pixel at position by packed color
  136. void set_pixel(int localx, int localy, color_t color)
  137. { set_pos(localx, localy); put_pixel(color); }
  138. };
  139. extern int g_sizex;
  140. extern int g_sizey;
  141. extern unsigned int *g_pImg;
  142. inline drawing_memory video::get_drawing_memory() const
  143. {
  144. drawing_memory dmem;
  145. dmem.pixel_depth = depth;
  146. dmem.my_address = reinterpret_cast<uintptr_t>(g_pImg);
  147. dmem.sizex = g_sizex;
  148. dmem.sizey = g_sizey;
  149. return dmem;
  150. }
  151. inline color_t video::get_color(colorcomp_t red, colorcomp_t green, colorcomp_t blue) const
  152. {
  153. if(red_shift == 16) // only for depth == 24 && red_shift > blue_shift
  154. return (red<<16) | (green<<8) | blue;
  155. else if(depth >= 24)
  156. return (red<<red_shift) | (green<<green_shift) | (blue<<blue_shift);
  157. else if(depth > 0) {
  158. register depth_t bs = blue_shift, rs = red_shift;
  159. if(blue_shift < 0) blue >>= -bs, bs = 0;
  160. else /*red_shift < 0*/ red >>= -rs, rs = 0;
  161. return ((red<<rs)&red_mask) | ((green<<green_shift)&green_mask) | ((blue<<bs)&blue_mask);
  162. } else { // UYVY colorspace
  163. register unsigned y, u, v;
  164. y = red * 77 + green * 150 + blue * 29; // sum(77+150+29=256) * max(=255): limit->2^16
  165. u = (2048 + (blue << 3) - (y >> 5)) >> 4; // (limit->2^12)>>4
  166. v = (2048 + (red << 3) - (y >> 5)) >> 4;
  167. y = y >> 8;
  168. return u | (y << 8) | (v << 16) | (y << 24);
  169. }
  170. }
  171. inline drawing_area::drawing_area(int x, int y, int sizex, int sizey, const drawing_memory &dmem)
  172. : start_x(x), start_y(y), size_x(sizex), size_y(sizey), pixel_depth(dmem.pixel_depth),
  173. base_index(y*dmem.sizex + x), max_index(dmem.sizex*dmem.sizey), index_stride(dmem.sizex),
  174. ptr32(reinterpret_cast<unsigned int*>(dmem.my_address))
  175. {
  176. assert(x < dmem.sizex); assert(y < dmem.sizey);
  177. assert(x+sizex <= dmem.sizex); assert(y+sizey <= dmem.sizey);
  178. index = base_index; // current index
  179. }
  180. inline void drawing_area::set_pos(int local_x, int local_y)
  181. {
  182. index = base_index + local_x + local_y*index_stride;
  183. }
  184. inline void drawing_area::put_pixel(color_t color)
  185. {
  186. assert(index < max_index);
  187. if(pixel_depth > 16) ptr32[index++] = color;
  188. else if(pixel_depth > 0)
  189. ((unsigned short*)ptr32)[index++] = (unsigned short)color;
  190. else { // UYVY colorspace
  191. if(index&1) color >>= 16;
  192. ((unsigned short*)ptr32)[index++] = (unsigned short)color;
  193. }
  194. }
  195. inline drawing_area::~drawing_area()
  196. {
  197. #if ! __TBB_DEFINE_MIC
  198. update();
  199. #endif
  200. }
  201. #if defined(_WINDOWS) && (defined(VIDEO_WINMAIN) || defined(VIDEO_WINMAIN_ARGS) )
  202. #include <cstdlib>
  203. //! define WinMain for subsystem:windows.
  204. #ifdef VIDEO_WINMAIN_ARGS
  205. int main(int, char *[]);
  206. #else
  207. int main();
  208. #endif
  209. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR szCmdLine, int iCmdShow)
  210. {
  211. video::win_hInstance = hInstance; video::win_iCmdShow = iCmdShow;
  212. #ifdef VIDEO_WINMAIN_ARGS
  213. return main(__argc, __argv);
  214. #else
  215. return main();
  216. #endif
  217. }
  218. #endif
  219. #endif// __VIDEO_H__