Texture.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "Texture.h"
  2. #include "GameEngine.h"
  3. #include <png.h>
  4. using namespace std;
  5. GLuint Texture::boundTexture = 0;
  6. Texture::Texture(const char* path)
  7. {
  8. if(!load(path))
  9. {
  10. loaded = true;
  11. cout << "cannot load texture " << path << endl;
  12. }
  13. }
  14. Texture::Texture(const Texture& orig)
  15. {
  16. }
  17. Texture::~Texture()
  18. {
  19. if(data != nullptr)
  20. {
  21. delete[] data;
  22. }
  23. if(texture != 0)
  24. {
  25. glDeleteTextures(1, &texture);
  26. }
  27. }
  28. bool Texture::load(const char* path)
  29. {
  30. FILE* file = fopen(path, "r");
  31. if(file == NULL)
  32. {
  33. cerr << "image '" << path << "' does not exist" << endl;
  34. return false;
  35. }
  36. bool b = load(path, file);
  37. fclose(file);
  38. if(b)
  39. {
  40. initGL();
  41. }
  42. return b;
  43. }
  44. bool Texture::load(const char* path, FILE* file)
  45. {
  46. // check signature of png
  47. unsigned char buffer[8];
  48. if(fread(buffer, sizeof(char), 8, file) != 8)
  49. {
  50. cerr << "cannot read signature of image '" << path << "'" << endl;
  51. return false;
  52. }
  53. if(png_sig_cmp(buffer, 0, 8))
  54. {
  55. cerr << "file '" << path << "' is not an image" << endl;
  56. return false;
  57. }
  58. // create structures for data
  59. png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  60. if(png == NULL)
  61. {
  62. cerr << "cannot create image data structure" << endl;
  63. return false;
  64. }
  65. png_infop info = png_create_info_struct(png);
  66. if(info == NULL)
  67. {
  68. cerr << "cannot create image info structure" << endl;
  69. return false;
  70. }
  71. unsigned int** rowPointers = NULL;
  72. // set callback for errors
  73. if(setjmp(png_jmpbuf(png)))
  74. {
  75. if(rowPointers != NULL)
  76. {
  77. png_free(png, rowPointers);
  78. }
  79. png_destroy_read_struct(&png, &info, NULL);
  80. cerr << "image '" << path << "' has used error callback" << endl;
  81. return false;
  82. }
  83. // set reading function
  84. png_init_io(png, file);
  85. // notify about already used signature bytes
  86. png_set_sig_bytes(png, 8);
  87. // read info data
  88. png_read_info(png, info);
  89. width = png_get_image_width(png, info);
  90. height = png_get_image_height(png, info);
  91. // read image data
  92. data = new unsigned int[width * height];
  93. // allocate and set row pointer to correct places in block
  94. rowPointers = (unsigned int**) png_malloc(png, height * (sizeof(unsigned int*)));
  95. for(int i = 0; i < height; i++)
  96. {
  97. rowPointers[i] = (data + i * width);
  98. }
  99. png_set_rows(png, info, (png_bytepp) rowPointers);
  100. png_read_image(png, (png_bytepp) rowPointers);
  101. png_free(png, rowPointers);
  102. png_destroy_read_struct(&png, &info, NULL);
  103. return true;
  104. }
  105. void Texture::initGL()
  106. {
  107. glActiveTexture(GL_TEXTURE0);
  108. glGenTextures(1, &texture);
  109. glBindTexture(GL_TEXTURE_2D, texture);
  110. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  111. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  112. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  113. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  114. /*for(int i = 0; i < width * height; i++)
  115. {
  116. if(data[i] != 0)
  117. {
  118. cout << "X";
  119. }
  120. else
  121. {
  122. cout << " ";
  123. }
  124. if(i != 0 && i % width == 0)
  125. {
  126. cout << endl;
  127. }
  128. }*/
  129. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
  130. delete[] data;
  131. data = nullptr;
  132. glGenerateMipmap(GL_TEXTURE_2D);
  133. }
  134. void Texture::bind()
  135. {
  136. if(boundTexture != texture)
  137. {
  138. boundTexture = texture;
  139. glBindTexture(GL_TEXTURE_2D, texture);
  140. }
  141. }
  142. bool Texture::isLoaded()
  143. {
  144. return loaded;
  145. }