您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

179 行
4.8 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #include <lol/engine-internal.h>
  11. #include "lolgl.h"
  12. namespace lol
  13. {
  14. //
  15. // The TextureData class
  16. // ---------------------
  17. //
  18. class TextureData
  19. {
  20. friend class Texture;
  21. ivec2 m_size;
  22. PixelFormat m_format;
  23. GLuint m_texture;
  24. GLint m_internal_format;
  25. GLenum m_gl_format, m_gl_type;
  26. int m_bytes_per_elem;
  27. };
  28. //
  29. // The Texture class
  30. // -----------------
  31. //
  32. #define GET_CLAMPED(array, index) \
  33. array[std::max(0, std::min((int)(index), \
  34. (int)sizeof(array) / (int)sizeof(*array)))]
  35. Texture::Texture(ivec2 size, PixelFormat format)
  36. : m_data(new TextureData)
  37. {
  38. m_data->m_size = size;
  39. m_data->m_format = format;
  40. static struct
  41. {
  42. GLint internal_format;
  43. GLenum format, type;
  44. int bytes;
  45. }
  46. const gl_formats[] =
  47. {
  48. { 0, 0, 0, 0 }, /* Unknown */
  49. /* FIXME: this is all mixed up for the RGBA/ARGB combinations */
  50. #if defined __native_client__ || defined HAVE_GLES_2X
  51. { GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1 },
  52. { GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, 3 },
  53. { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
  54. /* FIXME: if GL_RGBA is not available, we should advertise
  55. * this format as "not available" on this platform. */
  56. #else
  57. { GL_R8, GL_RED, GL_UNSIGNED_BYTE, 1 }, /* A8 */
  58. { GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 3 }, /* RGB_8 */
  59. /* Seems efficient for little endian textures */
  60. { GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4 }, /* ARGB_8 */
  61. #endif
  62. { 0, 0, 0, 0 }, /* Y_F32 */
  63. { 0, 0, 0, 0 }, /* RGB_F32 */
  64. { 0, 0, 0, 0 }, /* RGBA_F32 */
  65. };
  66. m_data->m_internal_format = GET_CLAMPED(gl_formats, format).internal_format;
  67. m_data->m_gl_format = GET_CLAMPED(gl_formats, format).format;
  68. m_data->m_gl_type = GET_CLAMPED(gl_formats, format).type;
  69. m_data->m_bytes_per_elem = GET_CLAMPED(gl_formats, format).bytes;
  70. glGenTextures(1, &m_data->m_texture);
  71. glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
  72. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  73. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  74. }
  75. TextureUniform Texture::GetTextureUniform() const
  76. {
  77. TextureUniform ret;
  78. ret.m_flags = m_data->m_texture;
  79. return ret;
  80. }
  81. void Texture::Bind()
  82. {
  83. #if !defined HAVE_GLES_2X
  84. glEnable(GL_TEXTURE_2D);
  85. #endif
  86. glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
  87. }
  88. void Texture::SetData(void *data)
  89. {
  90. glTexImage2D(GL_TEXTURE_2D, 0, m_data->m_internal_format,
  91. m_data->m_size.x, m_data->m_size.y, 0,
  92. m_data->m_gl_format, m_data->m_gl_type, data);
  93. }
  94. void Texture::SetSubData(ivec2 origin, ivec2 size, void *data)
  95. {
  96. glTexSubImage2D(GL_TEXTURE_2D, 0, origin.x, origin.y, size.x, size.y,
  97. m_data->m_gl_format, m_data->m_gl_type, data);
  98. }
  99. void Texture::SetMagFiltering(TextureMagFilter filter)
  100. {
  101. glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
  102. GLenum gl_filter;
  103. switch (filter)
  104. {
  105. case TextureMagFilter::LINEAR_TEXEL:
  106. gl_filter = GL_LINEAR;
  107. break;
  108. case TextureMagFilter::NEAREST_TEXEL:
  109. default:
  110. gl_filter = GL_NEAREST;
  111. break;
  112. }
  113. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter);
  114. }
  115. void Texture::SetMinFiltering(TextureMinFilter filter)
  116. {
  117. glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
  118. GLenum gl_filter;
  119. switch (filter)
  120. {
  121. case TextureMinFilter::LINEAR_TEXEL_NO_MIPMAP:
  122. gl_filter = GL_LINEAR;
  123. break;
  124. case TextureMinFilter::NEAREST_TEXEL_NEAREST_MIPMAP:
  125. gl_filter = GL_NEAREST_MIPMAP_NEAREST;
  126. break;
  127. case TextureMinFilter::NEAREST_TEXEL_LINEAR_MIPMAP:
  128. gl_filter = GL_NEAREST_MIPMAP_LINEAR;
  129. break;
  130. case TextureMinFilter::LINEAR_TEXEL_NEAREST_MIPMAP:
  131. gl_filter = GL_LINEAR_MIPMAP_NEAREST;
  132. break;
  133. case TextureMinFilter::LINEAR_TEXEL_LINEAR_MIPMAP:
  134. gl_filter = GL_LINEAR_MIPMAP_LINEAR;
  135. break;
  136. case TextureMinFilter::NEAREST_TEXEL_NO_MIPMAP:
  137. default:
  138. gl_filter = GL_NEAREST;
  139. break;
  140. }
  141. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter);
  142. }
  143. void Texture::GenerateMipmaps()
  144. {
  145. glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
  146. glGenerateMipmap(GL_TEXTURE_2D);
  147. }
  148. Texture::~Texture()
  149. {
  150. glDeleteTextures(1, &m_data->m_texture);
  151. delete m_data;
  152. }
  153. } /* namespace lol */