#include "client/item/block.hh" namespace client { namespace item { void block::regenerate_glo() noexcept { const auto make_vbo = [](const auto& data) -> GLuint { GLuint vbo = 0; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, std::size(data) * sizeof(client::world::block::glvert), std::data(data), GL_STATIC_DRAW); return vbo; }; const auto make_vao = []() -> GLuint { GLuint vao = 0; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // posiiton glEnableVertexAttribArray(0); glVertexAttribPointer(0, sizeof(glm::vec3) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(client::world::block::glvert), nullptr); // texture glEnableVertexAttribArray(1); glVertexAttribPointer(1, sizeof(glm::vec3) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(client::world::block::glvert), reinterpret_cast(sizeof(glm::vec3))); return vao; }; std::vector data; const float tex_yoff = static_cast(this->type) - 1.0f; for (const auto& face : client::world::block::get_glfaces(this->shared::item::block::type)) { std::ranges::transform(face, std::back_inserter(data), [&](auto vert) { vert.texture.z += tex_yoff * 6.0f; return vert; }); } const auto vbo = make_vbo(data); const auto vao = make_vao(); this->glo.emplace(vbo, vao, std::size(data)); } void block::draw(const glm::vec2& pos, const glm::vec2& size) noexcept { const auto make_matrix = [&]() -> glm::mat4 { const glm::vec2 window = client::render::get_window_size(); constexpr auto identity = glm::mat4{1.0f}; const auto proj = glm::ortho(0.0f, window.x, 0.0f, window.y); const auto scal = glm::scale(identity, glm::vec3{size.x * 0.5f, size.y * 0.5f, 0.0f}); const auto tran = glm::translate(identity, glm::vec3{pos.x + size.x / 2.0f, pos.y + size.y / 2.0f, 0.0f}); // hack for shurbs, which are already offset and look bad when rotated const auto rotey = client::world::block::get_draw_type(this->type) == client::world::block::draw_type::block ? glm::rotate(identity, glm::radians(45.0f), glm::vec3(0.0f, 1.0f, 0.0f)) : identity; const auto rotex = glm::rotate(identity, glm::radians(30.0f), glm::vec3(1.0f, 0.0f, 0.0f)); return proj * tran * scal * rotex * rotey; }; static const client::render::program program{"res/shaders/face.vs", "res/shaders/face.fs"}; static const GLint u_matrix = glGetUniformLocation(program, "_u_matrix"); if (!this->glo.has_value()) { this->regenerate_glo(); } glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glUseProgram(program); glBindVertexArray(this->glo->vao); glUniformMatrix4fv(u_matrix, 1, GL_FALSE, glm::value_ptr(make_matrix())); glDrawArrays(GL_TRIANGLES, 0, this->glo->elements); } } // namespace item } // namespace client