Texture.cpp 3.7 KB

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