sampler.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * Copyright 2015-2017 ARM Limited
  3. * SPDX-License-Identifier: Apache-2.0
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #ifndef SPIRV_CROSS_SAMPLER_HPP
  18. #define SPIRV_CROSS_SAMPLER_HPP
  19. #include <vector>
  20. namespace spirv_cross
  21. {
  22. struct spirv_cross_sampler_2d
  23. {
  24. inline virtual ~spirv_cross_sampler_2d()
  25. {
  26. }
  27. };
  28. template <typename T>
  29. struct sampler2DBase : spirv_cross_sampler_2d
  30. {
  31. sampler2DBase(const spirv_cross_sampler_info *info)
  32. {
  33. mips.insert(mips.end(), info->mipmaps, info->mipmaps + info->num_mipmaps);
  34. format = info->format;
  35. wrap_s = info->wrap_s;
  36. wrap_t = info->wrap_t;
  37. min_filter = info->min_filter;
  38. mag_filter = info->mag_filter;
  39. mip_filter = info->mip_filter;
  40. }
  41. inline virtual T sample(glm::vec2 uv, float bias)
  42. {
  43. return sampleLod(uv, bias);
  44. }
  45. inline virtual T sampleLod(glm::vec2 uv, float lod)
  46. {
  47. if (mag_filter == SPIRV_CROSS_FILTER_NEAREST)
  48. {
  49. uv.x = wrap(uv.x, wrap_s, mips[0].width);
  50. uv.y = wrap(uv.y, wrap_t, mips[0].height);
  51. glm::vec2 uv_full = uv * glm::vec2(mips[0].width, mips[0].height);
  52. int x = int(uv_full.x);
  53. int y = int(uv_full.y);
  54. return sample(x, y, 0);
  55. }
  56. else
  57. {
  58. return T(0, 0, 0, 1);
  59. }
  60. }
  61. inline float wrap(float v, spirv_cross_wrap wrap, unsigned size)
  62. {
  63. switch (wrap)
  64. {
  65. case SPIRV_CROSS_WRAP_REPEAT:
  66. return v - glm::floor(v);
  67. case SPIRV_CROSS_WRAP_CLAMP_TO_EDGE:
  68. {
  69. float half = 0.5f / size;
  70. return glm::clamp(v, half, 1.0f - half);
  71. }
  72. default:
  73. return 0.0f;
  74. }
  75. }
  76. std::vector<spirv_cross_miplevel> mips;
  77. spirv_cross_format format;
  78. spirv_cross_wrap wrap_s;
  79. spirv_cross_wrap wrap_t;
  80. spirv_cross_filter min_filter;
  81. spirv_cross_filter mag_filter;
  82. spirv_cross_mipfilter mip_filter;
  83. };
  84. typedef sampler2DBase<glm::vec4> sampler2D;
  85. typedef sampler2DBase<glm::ivec4> isampler2D;
  86. typedef sampler2DBase<glm::uvec4> usampler2D;
  87. template <typename T>
  88. inline T texture(const sampler2DBase<T> &samp, const glm::vec2 &uv, float bias = 0.0f)
  89. {
  90. return samp.sample(uv, bias);
  91. }
  92. }
  93. #endif