TextureUtil.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. //#Ident "$Id: TextureUtil.cpp,v 1.15 2003/06/18 10:43:45 henqvist Exp $"
  2. /***************************************************************************
  3. TextureUtil.cpp - description
  4. -------------------
  5. begin : Mon Nov 27 2000
  6. copyright : (C) 2000 by Henrik Enqvist
  7. email : henqvist@excite.com
  8. ***************************************************************************/
  9. // TODO free textures and image memory on exit/clear function
  10. #include "Private.h"
  11. #include "TextureUtil.h"
  12. #include "Config.h"
  13. #include <iostream>
  14. #if EM_USE_SDL
  15. #include <SDL_opengl.h> //should fix GL portability ; instead of <OpenGL/gl.h>
  16. // TODO remove glu
  17. #if EM_DEBUG
  18. #include <GL/glu.h>
  19. #endif
  20. #include <SDL.h>
  21. #include <SDL_image.h>
  22. extern "C" {
  23. struct_image* loadP(const char * filename);
  24. struct_image* loadP(const char * filename) {
  25. SDL_Surface* surface = IMG_Load(filename);
  26. if (surface == NULL) {
  27. cerr << "::loadP could not load: " << filename << endl;
  28. return NULL;
  29. }
  30. struct_image* image = (struct_image*) malloc(sizeof(struct_image));
  31. image->width = surface->w;
  32. image->height = surface->h;
  33. // asume 24 bits are 3*8 and 32 are 4*8
  34. if (surface->format->BitsPerPixel == 24) {
  35. image->channels = 3;
  36. } else if (surface->format->BitsPerPixel == 32) {
  37. image->channels = 4;
  38. } else {
  39. cerr << "::loadP Only 32 bit RGBA and 24 bit RGB images supported"<<endl;
  40. // TODO free surface struct
  41. free(image);
  42. return NULL;
  43. }
  44. image->pixels = (unsigned char*) surface->pixels;
  45. return image;
  46. }
  47. }
  48. #endif // EM_USE_SDLIMAGE
  49. #if EM_USE_ALLEGRO
  50. #include <allegro.h>
  51. BITMAP * backbuffer = NULL;
  52. ZBUFFER * zbuffer = NULL;
  53. #endif // EM_USE_ALLEGRO
  54. TextureUtil* TextureUtil::p_TextureUtil = NULL;
  55. TextureUtil::TextureUtil() {
  56. m_colClear.r = 0.0f;
  57. m_colClear.g = 0.0f;
  58. m_colClear.b = 0.0f;
  59. m_colClear.a = 0.0f;
  60. }
  61. TextureUtil::~TextureUtil() {
  62. //freeTextures(); // TODO: check mem leaks here //!rzr
  63. //EM_COUT("TextureUtil::~TextureUtil",0);
  64. }
  65. TextureUtil* TextureUtil::getInstance() {
  66. if (p_TextureUtil == NULL) {
  67. p_TextureUtil = new TextureUtil();
  68. }
  69. return p_TextureUtil;
  70. }
  71. //!+rzr : this workaround a WIN32 bug // TODO: check (bugs possible)
  72. void TextureUtil::freeTextures() {
  73. #if EM_USE_SDL
  74. //EM_COUT("+ TextureUtil::freeTextures",1);
  75. map<string,EmTexture*>::iterator i;
  76. for ( i = m_hEmTexture.begin();
  77. i != m_hEmTexture.end();
  78. i++) {
  79. glDeleteTextures (1, (GLuint*) ((*i).second) ); //is that correct ?
  80. free((*i).second); // malloc -> free
  81. (*i).second = 0;
  82. }
  83. m_hEmTexture.clear();
  84. /// same pointers
  85. m_hImageName.clear();
  86. #endif // TODO ALLEGRO
  87. }
  88. // may solve the w32 bug on resize //TODO check it @w32
  89. void TextureUtil::reloadTextures() {
  90. //cout<<"+ TextureUtil::reloadTextures"<<endl;
  91. #if EM_USE_SDL
  92. m_hImageName.clear();
  93. map<string,EmTexture*>::iterator i;
  94. for ( i = m_hEmTexture.begin();
  95. i != m_hEmTexture.end();
  96. i++) {
  97. glDeleteTextures (1, (GLuint*) ((*i).second) ); //is that correct ?
  98. genTexture( (*i).first.c_str() , (*i).second );
  99. m_hImageName.insert(pair<EmTexture*,string>( (*i).second, (*i).first ));
  100. }
  101. #endif // TODO ALLEGRO
  102. //EM_CERR("- TextureUtil::reloadTextures");
  103. //cout<<"- TextureUtil::reloadTextures"<<endl;
  104. }
  105. void TextureUtil::getFilename(list<string> & files) {
  106. map<EmTexture*,string>::iterator i;
  107. for ( i = m_hImageName.begin();
  108. i != m_hImageName.end();
  109. i++) {
  110. files.push_back( (*i).second);
  111. }
  112. }
  113. //!-rzr
  114. void TextureUtil::initGrx() {
  115. Config * config = Config::getInstance();
  116. #if EM_USE_SDL
  117. cerr << "Initing SDL" << endl << endl;
  118. if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
  119. cerr << "Couldn't initialize SDL video" << SDL_GetError() << endl;
  120. exit(1);
  121. }
  122. if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
  123. cerr << "Couldn't initialize SDL joystick: " << SDL_GetError() << endl << endl;
  124. } else {
  125. int njoystick = SDL_NumJoysticks();
  126. cerr << njoystick << " joysticks were found." << endl;
  127. if (njoystick != 0) {
  128. cerr << "The names of the joysticks are:" << endl;
  129. for(int a=0; a<njoystick; a++ ) {
  130. cerr << " " << SDL_JoystickName(a) << endl;
  131. }
  132. cerr << "Using " << SDL_JoystickName(0) << endl << endl;
  133. SDL_JoystickOpen(0);
  134. SDL_JoystickEventState(SDL_ENABLE);
  135. }
  136. }
  137. // See if we should detect the display depth
  138. if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
  139. SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 2 );
  140. SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 3 );
  141. SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 3 );
  142. } else if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 16 ) {
  143. SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
  144. SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
  145. SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
  146. } else {
  147. SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
  148. SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
  149. SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
  150. }
  151. SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
  152. SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
  153. /* Initialize the display */
  154. SDL_Surface* screen =
  155. SDL_SetVideoMode(config->getWidth(), config->getHeight(), config->getBpp(),
  156. SDL_OPENGL
  157. | (config->useFullScreen() ? SDL_FULLSCREEN : 0));
  158. // if (config->useFullScreen()) {
  159. SDL_ShowCursor(SDL_DISABLE);
  160. // }
  161. SDL_WM_SetCaption("Emilia Pinball", NULL);
  162. if (screen == NULL) {
  163. cerr << "Couldn't set video mode: " << SDL_GetError() << endl;
  164. exit(1);
  165. }
  166. cerr << "Vendor : " << glGetString( GL_VENDOR ) << endl;
  167. cerr << "Renderer : " << glGetString( GL_RENDERER ) << endl;
  168. cerr << "Version : " << glGetString( GL_VERSION ) << endl;
  169. cerr << "Extensions : " << glGetString( GL_EXTENSIONS ) << endl << endl;
  170. //TODO: that would be usefull to report CPU/RAM specs also //!rzr
  171. int value;
  172. SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
  173. cerr << "SDL_GL_RED_SIZE: " << value << endl;
  174. SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
  175. cerr << "SDL_GL_GREEN_SIZE: " << value << endl;
  176. SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
  177. cerr << "SDL_GL_BLUE_SIZE: " << value << endl;
  178. SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
  179. cerr << "SDL_GL_DEPTH_SIZE: " << value << endl;
  180. SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
  181. cerr << "SDL_GL_DOUBLEBUFFER: " << value << endl << endl;
  182. this->resizeView(config->getWidth(), config->getHeight());
  183. #endif // EM_USE_SDL
  184. #if EM_USE_ALLEGRO
  185. //config->setSize(320, 240);
  186. allegro_init();
  187. install_keyboard();
  188. install_timer();
  189. install_mouse();
  190. COLOR_MAP colorMap;
  191. RGB_MAP rgbMap;
  192. COLOR_MAP transMap;
  193. RGB* paPalette = (RGB*) calloc(256, sizeof(RGB));
  194. generate_332_palette(paPalette);
  195. // create rgb table
  196. create_rgb_table(&rgbMap, paPalette, NULL);
  197. rgb_map = &rgbMap;
  198. // create light table and setup the truecolor blending functions.
  199. create_light_table(&colorMap, paPalette, 0, 0, 0, NULL);
  200. color_map = &colorMap;
  201. // texture and flat polygons are 50% transparent
  202. create_trans_table(&transMap, paPalette, 128, 128, 128, NULL);
  203. set_trans_blender(0, 0, 0, 128);
  204. // set the graphics mode
  205. int tc = GFX_AUTODETECT_WINDOWED, tw = config->getWidth();
  206. int th = config->getHeight(), tbpp = 16;
  207. /*
  208. set_gfx_mode(GFX_SAFE, 320, 200, 0, 0);
  209. set_palette(desktop_palette);
  210. if (!gfx_mode_select_ex(&tc, &tw, &th, &tbpp)) {
  211. allegro_exit();
  212. cerr << "Error setting safe graphics mode" << endl;
  213. }
  214. */
  215. set_color_depth(tbpp);
  216. if (set_gfx_mode(tc, tw, th, 0, 0) != 0) {
  217. allegro_exit();
  218. cerr << "Error setting graphics mode " << endl << allegro_error << endl;
  219. }
  220. set_palette(paPalette);
  221. config->setSize(tw, th);
  222. set_projection_viewport(0, 0, tw, th);
  223. // Create back buffer.
  224. backbuffer = create_bitmap(tw, th);
  225. clear(backbuffer);
  226. zbuffer = create_zbuffer(backbuffer);
  227. set_zbuffer(zbuffer);
  228. clear_zbuffer(zbuffer, 0);
  229. #endif // EM_USE_ALLEGRO
  230. }
  231. void TextureUtil::stopGrx() {
  232. cerr << "Stopping graphics...";
  233. #if EM_USE_SDL
  234. SDL_Quit();
  235. #endif
  236. #if EM_USE_ALLEGRO
  237. allegro_exit();
  238. #endif
  239. cerr << "ok." << endl;
  240. }
  241. void TextureUtil::setClearColor(float r, float g, float b, float a) {
  242. m_colClear.r = r;
  243. m_colClear.g = g;
  244. m_colClear.b = b;
  245. m_colClear.a = a;
  246. #if EM_USE_SDL
  247. glClearColor(m_colClear.r, m_colClear.g, m_colClear.b, m_colClear.a);
  248. #endif
  249. }
  250. void TextureUtil::resizeView(unsigned int w, unsigned int h) {
  251. #if EM_USE_SDL
  252. glViewport(0, 0, (GLsizei) w, (GLsizei) h);
  253. glClearColor(m_colClear.r, m_colClear.g, m_colClear.b, m_colClear.a);
  254. glClearDepth(1.0);
  255. glShadeModel(GL_SMOOTH);
  256. glEnable(GL_CULL_FACE);
  257. glCullFace(GL_BACK);
  258. glFrontFace(GL_CW);
  259. // glDisable(GL_DITHER);
  260. glDisable(GL_LIGHTING);
  261. glMatrixMode(GL_PROJECTION);
  262. glLoadIdentity();
  263. glFrustum(-EM_RIGHT*EM_NEAR, EM_RIGHT*EM_NEAR, -EM_UP*EM_NEAR, EM_UP*EM_NEAR,
  264. EM_NEAR, EM_FAR);
  265. glMatrixMode(GL_MODELVIEW);
  266. #if OPENGL_LIGHTS
  267. glEnable(GL_LIGHTING);
  268. #endif
  269. #endif // EM_USE_SDL
  270. }
  271. EmImage* TextureUtil::loadImage(const char* filename) {
  272. #if EM_USE_SDL
  273. struct_image * image = loadP(filename);
  274. if (image == NULL) {
  275. cerr << "TextureUtil::loadImage unable to load " << filename << endl;
  276. }
  277. return image;
  278. #endif // EM_USE_SDL
  279. #if EM_USE_ALLEGRO
  280. RGB pal[256];
  281. BITMAP * bm = load_bitmap(filename, pal);
  282. if (bm == NULL) {
  283. cerr << "TextareUtil::loadImage unable to load " << filename << " : " << allegro_error << endl;
  284. }
  285. return bm;
  286. #endif // EM_USE_ALLEGRO
  287. }
  288. int TextureUtil::genTexture( char const * const filename,
  289. EmTexture * const texture)
  290. {
  291. //cout<<"+ Texture::genTexture : "<<filename<<endl;
  292. *texture = 0;
  293. #if EM_USE_SDL
  294. // Load Texture
  295. struct_image* image = 0;
  296. // load the texture
  297. image = loadP(filename);
  298. if (image == NULL) {
  299. cerr << "TextureUtil::loadTexture error loading file " << filename << endl;
  300. return -1;
  301. }
  302. //TODO : Pad texture != 2^n x 2^n //!rzr
  303. //cout<<" Create Texture"<<endl;
  304. glGenTextures(1, texture);
  305. glBindTexture(GL_TEXTURE_2D, *texture);
  306. // 2d texture, level of detail 0 (normal), 3 components (red, green, blue),
  307. // x size from image, y size from image,
  308. // border 0 (normal), rgb color data, unsigned byte data,
  309. // and finally the data itself.x
  310. GLenum comp;
  311. switch (image->channels) {
  312. case 3: comp = GL_RGB; break;
  313. case 4: comp = GL_RGBA; break;
  314. default: comp = GL_RGB;
  315. cerr << "TextureUtil::loadTexture unknown image format" << endl;
  316. return -1;
  317. }
  318. glTexImage2D(GL_TEXTURE_2D, 0, comp, image->width, image->height, 0, comp,
  319. GL_UNSIGNED_BYTE, image->pixels);
  320. EM_COUT("loaded texture: " << filename, 1);
  321. EM_COUT("size " << image->width <<" "<< image->height, 1);
  322. // EM_COUT("bytes per pixel " << (int)image->format->BytesPerPixel, 1);
  323. // EM_COUT("bits per pixel " << (int)image->format->BitsPerPixel, 1);
  324. #endif
  325. EM_COUT("- Texture::genTexture : "<<filename<<hex<<texture,0);
  326. return 1;
  327. }
  328. EmTexture* TextureUtil::loadTexture(const char* filename) {
  329. EmTexture* texture = 0;
  330. #if EM_USE_SDL
  331. // look if the texture is already loaded
  332. if (m_hEmTexture.find(string(filename)) != m_hEmTexture.end()) {
  333. EM_COUT("TextureUtil::loadTexture found texture "
  334. << filename << " in cache", 0);
  335. map<string, EmTexture*>::iterator element
  336. = m_hEmTexture.find(string(filename));
  337. return (*element).second;
  338. }
  339. texture = new EmTexture;
  340. int t = genTexture( filename, texture); //!rzr {
  341. if ( t < 0 ) { delete texture; return 0; } // could have been written better
  342. //EM_GLERROR(" In TextureUtil::loadTexture ");
  343. // insert the texture into the cache
  344. m_hEmTexture.insert(pair<string, EmTexture*>(string(filename), texture));
  345. m_hImageName.insert(pair<EmTexture*, string>(texture, string(filename)));
  346. //cout<<"- TextureUtil::loadTexture"<<endl;
  347. return texture;
  348. #endif // EM_USE_SDL
  349. #if EM_USE_ALLEGRO
  350. RGB pal[256];
  351. BITMAP * bm = load_bitmap(filename, pal);
  352. if (bm == NULL) {
  353. cerr << "TextureUtil::loadTexture Unable to load "
  354. << filename << " : " << allegro_error << endl;
  355. }
  356. return bm;
  357. #endif // EM_USE_ALLEGRO
  358. return texture;
  359. }
  360. const char * TextureUtil::getTextureName(EmTexture * tex) {
  361. map<EmTexture*, string>::iterator element = m_hImageName.find(tex);
  362. if (element != m_hImageName.end()) {
  363. return (*element).second.c_str();
  364. }
  365. cerr << "TextureUtil::getTextureName could not find image name" << endl;
  366. return NULL;
  367. }
  368. /*
  369. void TextureUtil::load(list<string> & files)
  370. {
  371. list<string>::iterator is = files.begin();
  372. for ( ; is != files.end() ; is++ )
  373. loadTexture( (*is).c_str() );
  374. }
  375. */
  376. //EOF: $Id: TextureUtil.cpp,v 1.15 2003/06/18 10:43:45 henqvist Exp $