texture.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "texture.h"
  2. #include <QDebug>
  3. #include <QImage>
  4. namespace Render::GL {
  5. Texture::Texture() {}
  6. Texture::~Texture() {
  7. if (m_texture != 0) {
  8. glDeleteTextures(1, &m_texture);
  9. }
  10. }
  11. bool Texture::loadFromFile(const QString &path) {
  12. initializeOpenGLFunctions();
  13. QImage image;
  14. if (!image.load(path)) {
  15. qWarning() << "Failed to load texture:" << path;
  16. return false;
  17. }
  18. image = image.convertToFormat(QImage::Format_RGBA8888).mirrored();
  19. m_width = image.width();
  20. m_height = image.height();
  21. m_format = Format::RGBA;
  22. bind();
  23. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA,
  24. GL_UNSIGNED_BYTE, image.constBits());
  25. setFilter(Filter::Linear, Filter::Linear);
  26. setWrap(Wrap::Repeat, Wrap::Repeat);
  27. glGenerateMipmap(GL_TEXTURE_2D);
  28. unbind();
  29. return true;
  30. }
  31. bool Texture::createEmpty(int width, int height, Format format) {
  32. initializeOpenGLFunctions();
  33. m_width = width;
  34. m_height = height;
  35. m_format = format;
  36. bind();
  37. GLenum glFormat = getGLFormat(format);
  38. GLenum internalFormat = glFormat;
  39. GLenum type = GL_UNSIGNED_BYTE;
  40. if (format == Format::Depth) {
  41. internalFormat = GL_DEPTH_COMPONENT;
  42. type = GL_FLOAT;
  43. }
  44. glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, glFormat,
  45. type, nullptr);
  46. setFilter(Filter::Linear, Filter::Linear);
  47. setWrap(Wrap::ClampToEdge, Wrap::ClampToEdge);
  48. unbind();
  49. return true;
  50. }
  51. void Texture::bind(int unit) {
  52. initializeOpenGLFunctions();
  53. if (!m_texture) {
  54. glGenTextures(1, &m_texture);
  55. }
  56. glActiveTexture(GL_TEXTURE0 + unit);
  57. glBindTexture(GL_TEXTURE_2D, m_texture);
  58. }
  59. void Texture::unbind() {
  60. initializeOpenGLFunctions();
  61. glBindTexture(GL_TEXTURE_2D, 0);
  62. }
  63. void Texture::setFilter(Filter minFilter, Filter magFilter) {
  64. bind();
  65. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLFilter(minFilter));
  66. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLFilter(magFilter));
  67. }
  68. void Texture::setWrap(Wrap sWrap, Wrap tWrap) {
  69. bind();
  70. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getGLWrap(sWrap));
  71. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getGLWrap(tWrap));
  72. }
  73. GLenum Texture::getGLFormat(Format format) const {
  74. switch (format) {
  75. case Format::RGB:
  76. return GL_RGB;
  77. case Format::RGBA:
  78. return GL_RGBA;
  79. case Format::Depth:
  80. return GL_DEPTH_COMPONENT;
  81. }
  82. return GL_RGBA;
  83. }
  84. GLenum Texture::getGLFilter(Filter filter) const {
  85. switch (filter) {
  86. case Filter::Nearest:
  87. return GL_NEAREST;
  88. case Filter::Linear:
  89. return GL_LINEAR;
  90. }
  91. return GL_LINEAR;
  92. }
  93. GLenum Texture::getGLWrap(Wrap wrap) const {
  94. switch (wrap) {
  95. case Wrap::Repeat:
  96. return GL_REPEAT;
  97. case Wrap::ClampToEdge:
  98. return GL_CLAMP_TO_EDGE;
  99. case Wrap::ClampToBorder:
  100. return GL_CLAMP_TO_BORDER;
  101. }
  102. return GL_REPEAT;
  103. }
  104. } // namespace Render::GL