💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.3 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "render/material.hpp"
  20. namespace render {
  21. material::material(gl::shader_program* program):
  22. program(program),
  23. flags(0),
  24. blend_mode(blend_mode::opaque),
  25. opacity_threshold(0.5f),
  26. two_sided(false),
  27. shadow_mode(shadow_mode::opaque)
  28. {}
  29. material::material():
  30. material(nullptr)
  31. {}
  32. material::material(const material& other)
  33. {
  34. *this = other;
  35. }
  36. material::~material()
  37. {
  38. for (material_property_base* property: properties)
  39. {
  40. delete property;
  41. }
  42. }
  43. material& material::operator=(const material& other)
  44. {
  45. // Remove all properties
  46. for (material_property_base* property: properties)
  47. {
  48. delete property;
  49. }
  50. properties.clear();
  51. property_map.clear();
  52. this->program = other.program;
  53. this->flags = other.flags;
  54. this->blend_mode = other.blend_mode;
  55. this->opacity_threshold = other.opacity_threshold;
  56. this->two_sided = other.two_sided;
  57. this->shadow_mode = other.shadow_mode;
  58. for (auto it = other.property_map.begin(); it != other.property_map.end(); ++it)
  59. {
  60. material_property_base* property = it->second->clone();
  61. properties.push_back(property);
  62. property_map[it->first] = property;
  63. }
  64. return *this;
  65. }
  66. void material::update_tweens()
  67. {
  68. for (material_property_base* property: properties)
  69. {
  70. property->update_tweens();
  71. }
  72. }
  73. std::size_t material::upload(double a) const
  74. {
  75. if (!program)
  76. {
  77. return false;
  78. }
  79. std::size_t failed_upload_count = 0;
  80. for (material_property_base* property: properties)
  81. {
  82. if (!property->upload(a))
  83. {
  84. ++failed_upload_count;
  85. }
  86. }
  87. return failed_upload_count;
  88. }
  89. void material::set_shader_program(gl::shader_program* program)
  90. {
  91. this->program = program;
  92. reconnect_properties();
  93. }
  94. void material::set_flags(std::uint32_t flags) noexcept
  95. {
  96. this->flags = flags;
  97. }
  98. void material::set_blend_mode(render::blend_mode mode) noexcept
  99. {
  100. blend_mode = mode;
  101. }
  102. void material::set_opacity_threshold(float threshold) noexcept
  103. {
  104. opacity_threshold = threshold;
  105. }
  106. void material::set_two_sided(bool two_sided) noexcept
  107. {
  108. this->two_sided = two_sided;
  109. }
  110. void material::set_shadow_mode(render::shadow_mode mode) noexcept
  111. {
  112. shadow_mode = mode;
  113. }
  114. std::size_t material::reconnect_properties()
  115. {
  116. std::size_t disconnected_property_count = properties.size();
  117. for (auto it = property_map.begin(); it != property_map.end(); ++it)
  118. {
  119. material_property_base* property = it->second;
  120. property->disconnect();
  121. if (program != nullptr)
  122. {
  123. if (property->connect(program->get_input(it->first)))
  124. {
  125. --disconnected_property_count;
  126. }
  127. }
  128. }
  129. return disconnected_property_count;
  130. }
  131. } // namespace render