diff --git a/main.cpp b/main.cpp index 907ada23..ca4135a7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,3 @@ - #include #include "src/application_head.h" @@ -587,14 +586,14 @@ REFL_REGISTER_CLASS_DEF(::TestChamberFactory::ChamberType<>) void setupBaseDraw(){ ::Core::renderer->getListener().on([](const auto& e){ - Graphic::Batch::flush(); + Graphic::Draw::Overlay::getBatch().flush(); Core::uiRoot->drawCursor(); - Graphic::Batch::flush(); + Graphic::Draw::Overlay::getBatch().flush(); }); ::Core::renderer->getListener().on([]([[maybe_unused]] const auto& e){ Game::core->drawBeneathUI(e.renderer); - Graphic::Batch::flush(); + Graphic::Draw::Overlay::getBatch().flush(); }); } @@ -609,7 +608,7 @@ int main(const int argc, char* argv[]){ Core::audio->engine->setSoundVolume(0.5f); - ::Test::chamberFrame = std::make_unique>(); + ::Test::chamberFrame = std::make_unique>(); if(true){ Game::core->overlayManager->activate(); @@ -630,7 +629,7 @@ int main(const int argc, char* argv[]){ setupBaseDraw(); - ::Test::chamberFrame = std::make_unique>(); + ::Test::chamberFrame = std::make_unique>(); ::Test::loadChamberTest(); Core::uiRoot->registerScene(UI::Menu_Main); @@ -649,7 +648,7 @@ int main(const int argc, char* argv[]){ Assets::PostProcessors::blurX_World.get(), Assets::PostProcessors::blurY_World.get(), Assets::Shaders::merge }; - // merger.blur.setScale(0.5f); + merger.blur.setScale(0.5f); merger.blur.setProcessTimes(4); merger.setTargetState(GL::State::BLEND, true); @@ -672,10 +671,10 @@ int main(const int argc, char* argv[]){ // event.renderer->effectBuffer.bind(); event.renderer->frameBegin(&frameBuffer); - Draw::Line::setLineStroke(5); - Draw::color(Colors::GRAY); + Draw::Overlay::Line::setLineStroke(5); + Draw::Overlay::color(Colors::GRAY); Game::EntityManage::realEntities.quadTree->each([](decltype(Game::EntityManage::realEntities)::TreeType* t){ - Draw::Line::rectOrtho(t->getBoundary()); + Draw::Overlay::Line::rectOrtho(t->getBoundary()); }); Game::EntityManage::renderDebug(); @@ -712,7 +711,7 @@ int main(const int argc, char* argv[]){ Game::core->effectManager->render(Core::camera->getViewport()); - Graphic::Batch::flush(); + Graphic::Draw::World::getBatch().flush(); GL::disable(GL::Test::DEPTH); GL::setDepthMask(false); @@ -729,11 +728,11 @@ int main(const int argc, char* argv[]){ ::Test::chamberFrame->getLocalToWorld().scale(10.0f, 10.0f); Core::renderer->getListener().on([&](const auto& e){ - if(!drawDebug) return; + // if(!drawDebug) return; e.renderer->frameBegin(&frameBuffer); e.renderer->frameBegin(&multiSample); - Graphic::Batch::blend<>(); + Graphic::Draw::Overlay::getBatch().flush(); /*// chamberFrame->updateDrawTarget(Core::camera->getViewportRect()); ::Game::Draw::chamberFrameTile(*chamberFrame, Core::renderer, true); @@ -763,29 +762,26 @@ int main(const int argc, char* argv[]){ } */ - Graphic::Batch::blend(); - - Draw::Line::setLineStroke(4); + Graphic::Draw::Overlay::getBatch().switchBlending(); { - static Geom::Matrix3D mat{}; - - Graphic::Batch::beginPorj(mat.setOrthogonal(Core::renderer->getSize())); - Draw::color(); + Core::BatchGuard_Proj _{Graphic::Draw::Overlay::getBatch()}; + _.current.setOrthogonal(Core::renderer->getSize()); auto [x, y] = Core::renderer->getSize().scl(0.5f); - Draw::Line::square(x, y, 50, 45); - Draw::Line::poly(x, y, 64, 160, 0, Math::clamp(fmod(OS::updateTime() / 5.0f, 1.0f)), + + using Graphic::Draw::Overlay; + + Overlay::color(Graphic::Colors::PALE_GREEN); + Overlay::Line::setLineStroke(4.f); + Overlay::Line::square(x, y, 50, 45); + Overlay::Line::poly(x, y, 64, 160, 0, Math::clamp(fmod(OS::updateTime() / 5.0f, 1.0f)), Colors::SKY.copy().setA(0.55f), Colors::ROYAL.copy().setA(0.55f), Colors::SKY.copy().setA(0.55f), Colors::WHITE.copy().setA(0.55f), Colors::ROYAL.copy().setA(0.55f), Colors::SKY.copy().setA(0.55f) ); - - Graphic::Batch::endPorj(); } - Graphic::Batch::flush(); - e.renderer->frameEnd(Assets::PostProcessors::blendMulti.get()); e.renderer->frameEnd(Assets::PostProcessors::bloom.get()); }); diff --git a/src/SideTemp.cppm b/src/SideTemp.cppm index 8559e2d5..197f04e0 100644 --- a/src/SideTemp.cppm +++ b/src/SideTemp.cppm @@ -59,9 +59,9 @@ export struct TestChamberFactory : Game::ChamberFactory{ } void draw(const Game::Chamber* chamber, const EntityType& entity, const TraitDataType& data) const{ - Graphic::Draw::setZ(entity.zLayer); - Graphic::Draw::rectOrtho<&Core::BatchGroup::world>(Graphic::Draw::globalState.defaultSolidTexture, - chamber->getChamberBound()); + Graphic::Draw::World::setZ(entity.zLayer); + Graphic::Draw::World::Fill::rectOrtho(Graphic::Draw::World::defaultSolidTexture, + chamber->getEntityBound()); } } baseTraitTest; @@ -78,17 +78,17 @@ REFL_REGISTER_CLASS_DEF(::TestChamberFactory::ChamberType<>) export template <> -struct ::Core::IO::JsonSerializator> : Game::ChamberFrameData::JsonSrl{}; +struct ::Core::IO::JsonSerializator> : Game::ChamberGridData::JsonSrl{}; export template <> -struct ::Core::IO::JsonSerializator>{ - static void write(ext::json::JsonValue& jsonValue, const Game::ChamberFrame& data){ - ::Core::IO::JsonSerializator>::write(jsonValue, data); +struct ::Core::IO::JsonSerializator>{ + static void write(ext::json::JsonValue& jsonValue, const Game::ChamberGrid& data){ + ::Core::IO::JsonSerializator>::write(jsonValue, data); } - static void read(const ext::json::JsonValue& jsonValue, Game::ChamberFrame& data){ - ::Core::IO::JsonSerializator>::read(jsonValue, data); + static void read(const ext::json::JsonValue& jsonValue, Game::ChamberGrid& data){ + ::Core::IO::JsonSerializator>::read(jsonValue, data); data.reTree(); } }; @@ -97,7 +97,7 @@ export template<> struct ::Core::IO::JsonSerializator> : Game::ChamberJsonSrl{}; export namespace Test{ - std::unique_ptr> chamberFrame{}; + std::unique_ptr> chamberFrame{}; std::unique_ptr> testFactory{std::make_unique()}; void loadChamberTest(){ @@ -174,7 +174,7 @@ export namespace Test{ ptr->chambers.operator=(std::move(*chamberFrame)); ptr->chamberTrans.vec.x = 85; ptr->physicsBody.inertialMass = 4000; - chamberFrame = std::make_unique>(); + chamberFrame = std::make_unique>(); ptr->controller.reset(new Game::PlayerController{ptr.get()}); } diff --git a/src/Test.cppm b/src/Test.cppm index 830b1cb9..e89ab0a2 100644 --- a/src/Test.cppm +++ b/src/Test.cppm @@ -102,8 +102,9 @@ export namespace Test{ Core::renderer->registerSynchronizedResizableObject(Core::camera); }); - Graphic::Draw::setDefTexture(&Assets::Textures::whiteRegion); - Graphic::Draw::setTexture(); + Graphic::Draw::World::setDefTexture(&Assets::Textures::whiteRegion); + Graphic::Draw::Overlay::setDefTexture(&Assets::Textures::whiteRegion); + Graphic::Frame::rawMesh = Assets::Meshes::raw.get(); Graphic::Frame::blitter = Assets::Shaders::blit; @@ -198,12 +199,18 @@ export namespace Test{ texture2D->setScale(GL::TexParams::mipmap_linear_linear); } + Assets::Textures::whiteRegion = *event.manager->getAtlas().find("base-white-solid"); Assets::Textures::whiteRegion.shrinkEdge(15.0f); - Graphic::Draw::globalState.defaultSolidTexture = Graphic::Draw::getDefaultTexture(); auto lightRegion = event.manager->getAtlas().find("base-white-light"); - Graphic::Draw::globalState.defaultLightTexture = lightRegion; + + Graphic::Draw::Overlay::setDefTexture(&Assets::Textures::whiteRegion); + + Graphic::Draw::World::defaultSolidTexture = Graphic::Draw::Overlay::getDefaultTexture(); + Graphic::Draw::World::defaultLightTexture = lightRegion; + Graphic::Draw::World::setDefTexture(lightRegion); + const_cast(lightRegion)->shrinkEdge(15.0f); for(auto& texture : event.manager->getAtlas().getPage("ui").getTextures()){ @@ -214,9 +221,6 @@ export namespace Test{ texture->setScale(GL::TexParams::mipmap_linear_nearest, GL::TexParams::nearest); } - Graphic::Draw::setDefTexture(&Assets::Textures::whiteRegion); - Graphic::Draw::setTexture(); - UI::Styles::load(event.manager->getAtlas()); { diff --git a/src/arc-impl/Effect.cpp b/src/arc-impl/Effect.cpp index e3d1b3d8..9e339c2c 100644 --- a/src/arc-impl/Effect.cpp +++ b/src/arc-impl/Effect.cpp @@ -20,7 +20,7 @@ Graphic::Effect* Graphic::EffectShake::create(EffectManager* manager, Core::Came auto* eff = suspendOn(manager); fadeSpeed = fadeSpeed > 0 ? fadeSpeed : intensity / 32.f; eff->set({pos, intensity}, Graphic::Colors::CLEAR, intensity / fadeSpeed, camera); - eff->zOffset = fadeSpeed; + eff->zLayer = fadeSpeed; return eff; } @@ -32,6 +32,6 @@ Graphic::Effect* Graphic::EffectShake::create(const Geom::Vec2 pos, const float void Graphic::EffectShake::operator()(Effect& effect) const{ if(auto* camera = std::any_cast(effect.additionalData)){ const float dst = effect.trans.vec.dst(camera->getPosition()); - camera->shake(getIntensity(dst) * effect.trans.rot, effect.zOffset); + camera->shake(getIntensity(dst) * effect.trans.rot, effect.zLayer); } } diff --git a/src/arc-impl/GlyphArrangement.cpp b/src/arc-impl/GlyphArrangement.cpp index cf6e58c8..9a086217 100644 --- a/src/arc-impl/GlyphArrangement.cpp +++ b/src/arc-impl/GlyphArrangement.cpp @@ -23,8 +23,8 @@ void Font::GlyphLayout::render(const float alphaMask) const { if(empty()) return; const Geom::Vec2 off = getDrawOffset(); for (auto& glyph : glyphs){ - Graphic::Draw::color(glyph.fontColor, glyph.fontColor.a * alphaMask); - Graphic::Draw::quad( + Graphic::Draw::Overlay::color(glyph.fontColor, glyph.fontColor.a * alphaMask); + Graphic::Draw::Overlay::Fill::quad( glyph.region, glyph.v00().scl(scale) + off, glyph.v10().scl(scale) + off, @@ -49,9 +49,9 @@ void Font::GlyphLayout::render(const float alphaMask, float progress) const { const Geom::Vec2 off = getDrawOffset(); for (auto& glyph : this->glyphs | std::ranges::views::take(static_cast(progress * static_cast(glyphs.size())))){ - Graphic::Draw::color(glyph.fontColor, glyph.fontColor.a * alphaMask); + Graphic::Draw::Overlay::color(glyph.fontColor, glyph.fontColor.a * alphaMask); - Graphic::Draw::quad( + Graphic::Draw::Overlay::Fill::quad( glyph.region, glyph.v00().scl(scale) + off, glyph.v10().scl(scale) + off, @@ -64,7 +64,7 @@ void Font::GlyphLayout::render(const float alphaMask, float progress) const { Font::TypesettingContext::TypesettingContext(const FontFlags* const font): defaultFont(font), currentFont(font), fallbackFont(font) { if(!currentFont) throw ext::NullPointerException{}; - lineSpacing = currentFont->data->lineSpacingMin * 1.8f; + lineSpacing = currentFont->data->lineSpacingDef * 1.8f; paragraphSpacing = lineSpacing * 1.1f; } diff --git a/src/arc-impl/TextureNineRegion.cpp b/src/arc-impl/TextureNineRegion.cpp index a15f25f5..f9a35978 100644 --- a/src/arc-impl/TextureNineRegion.cpp +++ b/src/arc-impl/TextureNineRegion.cpp @@ -19,30 +19,30 @@ void GL::TextureNineRegion::render_RelativeExter(const float x, const float y, c tempEdge.top -= remain * 0.5f; } - Draw::rectOrtho(®ions[ID_center], x + tempEdge.left, y + tempEdge.bottom, width - tempEdge.getWidth(), height - tempEdge.getHeight()); + Draw::Overlay::Fill::rectOrtho(®ions[ID_center], x + tempEdge.left, y + tempEdge.bottom, width - tempEdge.getWidth(), height - tempEdge.getHeight()); - Draw::rectOrtho(®ions[ID_right], x + width - tempEdge.right, y + tempEdge.bottom, tempEdge.right, height - tempEdge.bottom - tempEdge.top); - Draw::rectOrtho(®ions[ID_top], x + tempEdge.left, y + height - tempEdge.top, width - tempEdge.left - tempEdge.right, tempEdge.top); - Draw::rectOrtho(®ions[ID_left], x, y + tempEdge.bottom, tempEdge.left, height - tempEdge.bottom - tempEdge.top); - Draw::rectOrtho(®ions[ID_bottom], x + tempEdge.left, y, width - tempEdge.left - tempEdge.right, tempEdge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_right], x + width - tempEdge.right, y + tempEdge.bottom, tempEdge.right, height - tempEdge.bottom - tempEdge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_top], x + tempEdge.left, y + height - tempEdge.top, width - tempEdge.left - tempEdge.right, tempEdge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_left], x, y + tempEdge.bottom, tempEdge.left, height - tempEdge.bottom - tempEdge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottom], x + tempEdge.left, y, width - tempEdge.left - tempEdge.right, tempEdge.bottom); - Draw::rectOrtho(®ions[ID_topRight], x + width - tempEdge.right, y + height - tempEdge.top, tempEdge.right, tempEdge.top); - Draw::rectOrtho(®ions[ID_topLeft], x, y + height - tempEdge.top, tempEdge.left, tempEdge.top); - Draw::rectOrtho(®ions[ID_bottomLeft], x, y, tempEdge.left, tempEdge.bottom); - Draw::rectOrtho(®ions[ID_bottomRight], x + width - tempEdge.right, y, tempEdge.right, tempEdge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_topRight], x + width - tempEdge.right, y + height - tempEdge.top, tempEdge.right, tempEdge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_topLeft], x, y + height - tempEdge.top, tempEdge.left, tempEdge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottomLeft], x, y, tempEdge.left, tempEdge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottomRight], x + width - tempEdge.right, y, tempEdge.right, tempEdge.bottom); } void GL::TextureNineRegion::render_RelativeInner(const float x, const float y, const float width, const float height) const { - Draw::rectOrtho(®ions[ID_center], x, y, width, height); + Draw::Overlay::Fill::rectOrtho(®ions[ID_center], x, y, width, height); - Draw::rectOrtho(®ions[ID_right], x + width, y, edge.right, height); - Draw::rectOrtho(®ions[ID_top], x, y + height, width, edge.top); - Draw::rectOrtho(®ions[ID_left], x - edge.left, y, edge.left, height); - Draw::rectOrtho(®ions[ID_bottom], x, y - edge.bottom, width, edge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_right], x + width, y, edge.right, height); + Draw::Overlay::Fill::rectOrtho(®ions[ID_top], x, y + height, width, edge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_left], x - edge.left, y, edge.left, height); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottom], x, y - edge.bottom, width, edge.bottom); - Draw::rectOrtho(®ions[ID_topRight], x + width, y + height, edge.right, edge.top); - Draw::rectOrtho(®ions[ID_topLeft], x - edge.left, y + height, edge.left, edge.top); - Draw::rectOrtho(®ions[ID_bottomLeft], x - edge.left, y - edge.bottom, edge.left, edge.bottom); - Draw::rectOrtho(®ions[ID_bottomRight], x + width, y - edge.bottom, edge.right, edge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_topRight], x + width, y + height, edge.right, edge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_topLeft], x - edge.left, y + height, edge.left, edge.top); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottomLeft], x - edge.left, y - edge.bottom, edge.left, edge.bottom); + Draw::Overlay::Fill::rectOrtho(®ions[ID_bottomRight], x + width, y - edge.bottom, edge.right, edge.bottom); } \ No newline at end of file diff --git a/src/arc-impl/graphic/Draw.cpp b/src/arc-impl/graphic/Draw.cpp index 374f85e9..40567f67 100644 --- a/src/arc-impl/graphic/Draw.cpp +++ b/src/arc-impl/graphic/Draw.cpp @@ -2,364 +2,401 @@ module Graphic.Draw; import Core; -void Graphic::World::vert(float* vertices, const float x1, const float y1, const float z1, const float u1, const float v1, const Color c1, const Color cm1, const float x2, - const float y2, const float z2, const float u2, const float v2, const Color c2, const Color cm2, const float x3, const float y3, const float z3, const float u3, const float v3, - const Color c3, - const Color cm3, const float x4, const float y4, const float z4, const float u4, const float v4, const Color c4, const Color cm4){ - vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.r; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.g; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.b; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.a; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.r; +void Graphic::Vertex::World::vert(float* vertices, const float x1, const float y1, const float z1, const float u1, + const float v1, const Color c1, const Color cm1, const float x2, + const float y2, const float z2, const float u2, const float v2, const Color c2, + const Color cm2, const float x3, const float y3, const float z3, const float u3, + const float v3, + const Color c3, + const Color cm3, const float x4, const float y4, const float z4, const float u4, + const float v4, const Color c4, const Color cm4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.r; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.g; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.b; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm1.a; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.r; vertices[10 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.g; vertices[11 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.b; vertices[12 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.a; - vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.r; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.g; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.b; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.a; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.r; + vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.r; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.g; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.b; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm2.a; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.r; vertices[10 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.g; vertices[11 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.b; vertices[12 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.a; - vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.r; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.g; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.b; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.a; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.r; + vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.r; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.g; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.b; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm3.a; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.r; vertices[10 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.g; vertices[11 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.b; vertices[12 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.a; - vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.r; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.g; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.b; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.a; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.r; + vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.r; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.g; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.b; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm4.a; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.r; vertices[10 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.g; vertices[11 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.b; vertices[12 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.a; } -void Graphic::World::vert_monochromeMix(float* vertices, const Color cm, const float x1, const float y1, const float z1, const float u1, const float v1, - const Color c1, const float x2, const float y2, const float z2, const float u2, const float v2, const Color c2, const float x3, const float y3, const float z3, const float u3, - const float v3, const Color c3, const float x4, - const float y4, const float z4, const float u4, const float v4, const Color c4){ - vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.r; +void Graphic::Vertex::World::vert_monochromeMix(float* vertices, const Color cm, const float x1, const float y1, + const float z1, const float u1, const float v1, + const Color c1, const float x2, const float y2, const float z2, + const float u2, const float v2, const Color c2, const float x3, + const float y3, const float z3, const float u3, + const float v3, const Color c3, const float x4, + const float y4, const float z4, const float u4, const float v4, + const Color c4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.r; vertices[10 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.g; vertices[11 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.b; vertices[12 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c1.a; - vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.r; + vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.r; vertices[10 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.g; vertices[11 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.b; vertices[12 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c2.a; - vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.r; + vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.r; vertices[10 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.g; vertices[11 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.b; vertices[12 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c3.a; - vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.r; + vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.r; vertices[10 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.g; vertices[11 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.b; vertices[12 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c4.a; } -void Graphic::World::vert_monochromeAll(float* vertices, const Color c, const Color cm, const float x1, const float y1, const float z1, const float u1, const float v1, - const float x2, const float y2, const float z2, const float u2, const float v2, const float x3, const float y3, const float z3, const float u3, const float v3, const float x4, - const float y4, const float z4, - const float u4, const float v4){ - - vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c.r; +void Graphic::Vertex::World::vert_monochromeAll(float* vertices, const Color c, const Color cm, const float x1, + const float y1, const float z1, const float u1, const float v1, + const float x2, const float y2, const float z2, const float u2, + const float v2, const float x3, const float y3, const float z3, + const float u3, const float v3, const float x4, + const float y4, const float z4, + const float u4, const float v4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_WORLD] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_WORLD] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_WORLD] = z1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_WORLD] = u1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_WORLD] = v1; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c.r; vertices[10 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c.g; vertices[11 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c.b; vertices[12 + 0 * GL::VERT_GROUP_SIZE_WORLD] = c.a; - vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c.r; + vertices[0 + 1 * GL::VERT_GROUP_SIZE_WORLD] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_WORLD] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_WORLD] = z2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_WORLD] = u2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_WORLD] = v2; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c.r; vertices[10 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c.g; vertices[11 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c.b; vertices[12 + 1 * GL::VERT_GROUP_SIZE_WORLD] = c.a; - vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c.r; + vertices[0 + 2 * GL::VERT_GROUP_SIZE_WORLD] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_WORLD] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_WORLD] = z3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_WORLD] = u3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_WORLD] = v3; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c.r; vertices[10 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c.g; vertices[11 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c.b; vertices[12 + 2 * GL::VERT_GROUP_SIZE_WORLD] = c.a; - vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c.r; + vertices[0 + 3 * GL::VERT_GROUP_SIZE_WORLD] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_WORLD] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_WORLD] = z4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_WORLD] = u4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_WORLD] = v4; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.r; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.g; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.b; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_WORLD] = cm.a; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c.r; vertices[10 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c.g; vertices[11 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c.b; vertices[12 + 3 * GL::VERT_GROUP_SIZE_WORLD] = c.a; } -void Graphic::Overlay::vert(float* vertices, const float x1, const float y1, const float u1, const float v1, const Color c1, const Color cm1, const float x2, const float y2, - const float u2, const float v2, const Color c2, const Color cm2, const float x3, const float y3, const float u3, const float v3, const Color c3, const Color cm3, const float x4, - const float y4, - const float u4, const float v4, const Color c4, const Color cm4){ - vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.r; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.g; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.b; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.a; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.r; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.g; - vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.b; - vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.a; - - vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.r; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.g; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.b; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.a; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.r; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.g; - vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.b; - vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.a; - - vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.r; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.g; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.b; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.a; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.r; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.g; - vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.b; - vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.a; - - vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.r; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.g; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.b; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.a; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.r; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.g; - vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.b; - vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.a; +void Graphic::Vertex::Overlay::vert(float* vertices, const float x1, const float y1, const float u1, const float v1, + const Color c1, const Color cm1, const float x2, const float y2, + const float u2, const float v2, const Color c2, const Color cm2, const float x3, + const float y3, const float u3, const float v3, const Color c3, const Color cm3, + const float x4, + const float y4, + const float u4, const float v4, const Color c4, const Color cm4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.r; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.g; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.b; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm1.a; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.r; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.g; + vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.b; + vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.a; + + vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.r; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.g; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.b; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm2.a; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.r; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.g; + vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.b; + vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.a; + + vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.r; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.g; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.b; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm3.a; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.r; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.g; + vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.b; + vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.a; + + vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.r; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.g; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.b; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm4.a; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.r; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.g; + vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.b; + vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.a; } -void Graphic::Overlay::vert_monochromeMix(float* vertices, const Color cm, const float x1, const float y1, const float u1, const float v1, const Color c1, - const float x2, const float y2, const float u2, const float v2, const Color c2, const float x3, const float y3, const float u3, const float v3, const Color c3, const float x4, - const float y4, const float u4, const float v4, - const Color c4){ - vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.r; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.g; - vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.b; - vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.a; - - vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.r; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.g; - vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.b; - vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.a; - - vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.r; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.g; - vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.b; - vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.a; - - vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.r; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.g; - vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.b; - vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.a; +void Graphic::Vertex::Overlay::vert_monochromeMix(float* vertices, const Color cm, const float x1, const float y1, + const float u1, const float v1, const Color c1, + const float x2, const float y2, const float u2, const float v2, + const Color c2, const float x3, const float y3, const float u3, + const float v3, const Color c3, const float x4, + const float y4, const float u4, const float v4, + const Color c4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.r; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.g; + vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.b; + vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c1.a; + + vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.r; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.g; + vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.b; + vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c2.a; + + vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.r; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.g; + vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.b; + vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c3.a; + + vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.r; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.g; + vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.b; + vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c4.a; } -void Graphic::Overlay::vert_monochromeAll(float* vertices, const Color c, const Color cm, const float x1, const float y1, const float u1, const float v1, - const float x2, const float y2, const float u2, const float v2, const float x3, const float y3, const float u3, const float v3, const float x4, const float y4, const float u4, - const float v4){ - vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; - vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; - vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; - vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; - vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; - vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; - vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; - vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; - - vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; - vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; - vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; - vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; - vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; - vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; - vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; - vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; - - vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; - vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; - vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; - vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; - vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; - vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; - vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; - vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; - - vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; - vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; - vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; - vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; - vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; - vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; - vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; - vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; - vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; - vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; - vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; - vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; +void Graphic::Vertex::Overlay::vert_monochromeAll(float* vertices, const Color c, const Color cm, const float x1, + const float y1, const float u1, const float v1, + const float x2, const float y2, const float u2, const float v2, + const float x3, const float y3, const float u3, const float v3, + const float x4, const float y4, const float u4, + const float v4){ + vertices[0 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = x1; + vertices[1 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = y1; + vertices[2 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = u1; + vertices[3 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = v1; + vertices[4 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; + vertices[9 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; + vertices[10 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; + vertices[11 + 0 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; + + vertices[0 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = x2; + vertices[1 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = y2; + vertices[2 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = u2; + vertices[3 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = v2; + vertices[4 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; + vertices[9 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; + vertices[10 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; + vertices[11 + 1 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; + + vertices[0 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = x3; + vertices[1 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = y3; + vertices[2 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = u3; + vertices[3 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = v3; + vertices[4 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; + vertices[9 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; + vertices[10 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; + vertices[11 + 2 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; + + vertices[0 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = x4; + vertices[1 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = y4; + vertices[2 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = u4; + vertices[3 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = v4; + vertices[4 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.r; + vertices[5 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.g; + vertices[6 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.b; + vertices[7 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = cm.a; + vertices[8 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.r; + vertices[9 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.g; + vertices[10 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.b; + vertices[11 + 3 * GL::VERT_GROUP_SIZE_LAYOUT] = c.a; } -Graphic::BatchPtr& Graphic::getBatch(BatchPtr Core::BatchGroup::* batchPtr){ +Graphic::Vertex::BatchPtr& Graphic::Vertex::getBatch(Graphic::Vertex::BatchPtr Core::BatchGroup::* batchPtr){ return Core::batchGroup.*batchPtr; } -float Graphic::Draw::getNormalizedDepth(const float z){ - return Math::curve(z, Graphic::Draw::DepthNear, Graphic::Draw::DepthFar);//(1 / z - 1 / DepthNear) / (1 / DepthFar - 1 / DepthNear); +// float Graphic::Draw::getNormalizedDepth(const float z){ +// return Math::curve(z, DepthNear, DepthFar); +// //(1 / z - 1 / DepthNear) / (1 / DepthFar - 1 / DepthNear); +// } + +float Graphic::Draw::WorldBase::getNormalizedDepth(const float z){ + return Math::curve(z, DepthNear, DepthFar); + //(1 / z - 1 / DepthNear) / (1 / DepthFar - 1 / DepthNear); +} + +// template Graphic::Vertex::VertexPasser<&Core::BatchGroup::overlay>; +// template Graphic::Vertex::VertexPasser<&Core::BatchGroup::world>; + +Core::Batch& Graphic::Vertex::OverlayPass::getBatch(){ + return *(Core::batchGroup.*batchPtr); +} + +Core::Batch& Graphic::Vertex::WorldPass::getBatch(){ + return *(Core::batchGroup.*batchPtr); } + diff --git a/src/arc-impl/graphic/Renderer.cpp b/src/arc-impl/graphic/Renderer.cpp index 4d879533..105bbf6e 100644 --- a/src/arc-impl/graphic/Renderer.cpp +++ b/src/arc-impl/graphic/Renderer.cpp @@ -18,7 +18,7 @@ using namespace Graphic; void Core::Renderer::frameBegin(GL::FrameBuffer* frameBuffer, const bool resize, const Graphic::Color& initColor, GLbitfield mask) { if (contextFrameBuffer == frameBuffer)throw ext::RuntimeException{ "Illegally Begin Twice!" }; - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); frameStack.push(contextFrameBuffer); @@ -38,7 +38,7 @@ void Core::Renderer::frameBegin(GL::FrameBuffer* frameBuffer, const bool resize, void Core::Renderer::frameBegin_Quiet(GL::FrameBuffer* frameBuffer, const bool resize){ if (contextFrameBuffer == frameBuffer)throw ext::RuntimeException{ "Illegally Begin Twice!" }; - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); frameStack.push(contextFrameBuffer); @@ -55,7 +55,7 @@ void Core::Renderer::frameBegin_Quiet(GL::FrameBuffer* frameBuffer, const bool r void Core::Renderer::frameEnd(const ::std::function& func) { GL::FrameBuffer* beneathFrameBuffer = frameBufferFallback(); - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); func(contextFrameBuffer, beneathFrameBuffer); @@ -65,7 +65,7 @@ void Core::Renderer::frameEnd(const ::std::functionapply(contextFrameBuffer, beneathFrameBuffer); @@ -74,7 +74,7 @@ void Core::Renderer::frameEnd(const Graphic::PostProcessor* processor) { void Core::Renderer::frameEnd(const GL::ShaderSource* shader){ GL::FrameBuffer* beneathFrameBuffer = frameBufferFallback(); - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); contextFrameBuffer->getColorAttachments().front()->active(0); Graphic::Frame::blit(beneathFrameBuffer, 0, shader, nullptr); @@ -85,7 +85,7 @@ void Core::Renderer::frameEnd(const GL::ShaderSource* shader){ void Core::Renderer::frameEnd() { GL::FrameBuffer* beneathFrameBuffer = frameBufferFallback(); - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); contextFrameBuffer->getColorAttachments().front()->active(0); contextFrameBuffer->bind(GL::FrameBuffer::READ); @@ -97,7 +97,7 @@ void Core::Renderer::frameEnd() { GL::FrameBuffer* Core::Renderer::frameEnd_Quiet(){ const auto cur = contextFrameBuffer; GL::FrameBuffer* beneathFrameBuffer = frameBufferFallback(); - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); contextFrameBuffer = beneathFrameBuffer; contextFrameBuffer->bind(); @@ -112,7 +112,7 @@ void Core::Renderer::processUISperateDraw(const UI::SeperateDrawable* drawable){ uiBlurMask.clearColor(); drawable->drawBase(); - Graphic::Batch::flush(); + Core::batchGroup.flushAll(); Assets::PostProcessors::frostedGlassBlur->apply(contextFrameBuffer, &effectBuffer); @@ -136,8 +136,8 @@ void Core::Renderer::processUISperateDraw(const UI::SeperateDrawable* drawable){ void Core::Renderer::renderUI() { if(Core::uiRoot->isHidden)return; - const Geom::Matrix3D* mat = Graphic::Batch::getPorj(); - Core::batchGroup.overlay->setProjection(Core::uiRoot->getPorj()); + + [[maybe_unused]] Core::BatchGuard_Proj batchGuard_proj{*Core::batchGroup.overlay, Core::uiRoot->getPorj()}; const auto times = Assets::PostProcessors::bloom->blur.getProcessTimes(); Assets::PostProcessors::bloom->blur.setProcessTimes(2); @@ -155,7 +155,6 @@ void Core::Renderer::renderUI() { processUISperateDraw(toDraw); } - batchGroup.overlay->setProjection(mat); Assets::PostProcessors::bloom->blur.setProcessTimes(times); } @@ -198,9 +197,6 @@ void Core::Renderer::draw(){ renderUI(); - Graphic::Draw::color(); - Graphic::Draw::mixColor(); - drawControlHook.fire(draw_overlay); glBlitNamedFramebuffer(defaultFrameBuffer.getID(), 0, diff --git a/src/arc-impl/graphic/Trail.cpp b/src/arc-impl/graphic/Trail.cpp index 75e271d1..f785829d 100644 --- a/src/arc-impl/graphic/Trail.cpp +++ b/src/arc-impl/graphic/Trail.cpp @@ -4,13 +4,13 @@ import Graphic.Draw; import Core.BatchGroup; void Graphic::Trail::DefDraw::operator()(const Geom::Vec2 v1, const Geom::Vec2 v2, const Geom::Vec2 v3, const Geom::Vec2 v4) const{ - Draw::quad<&Core::BatchGroup::world>(Draw::getContextTexture(), v1, src, v2, src, v3, src, v4, src); + Draw::World::Fill::quad(Draw::World::getContextTexture(), v1, src, v2, src, v3, src, v4, src); } void Graphic::Trail::DefDraw_WithLerp::operator()(const Geom::Vec2 v1, const Geom::Vec2 v2, const Geom::Vec2 v3, const Geom::Vec2 v4, const Math::Progress p1, const Math::Progress p2) const{ const Graphic::Color c1 = Graphic::Color::createLerp(p1, dst, src); const Graphic::Color c2 = Graphic::Color::createLerp(p2, dst, src); - Draw::quad<&Core::BatchGroup::world>(Draw::getContextTexture(), v1, c1, v2, c1, v3, c2, v4, c2); + Draw::World::Fill::quad(Draw::World::getContextTexture(), v1, c1, v2, c1, v3, c2, v4, c2); } diff --git a/src/arc-impl/ui/Drawer.cpp b/src/arc-impl/ui/Drawer.cpp index 77479b8f..4a16de05 100644 --- a/src/arc-impl/ui/Drawer.cpp +++ b/src/arc-impl/ui/Drawer.cpp @@ -8,46 +8,47 @@ import UI.ProgressBar; import UI.SliderBar; using namespace Graphic; +using Draw::Overlay; void UI::SliderBarDrawer::draw(const SliderBar* sliderBar) const{ //TODO trans these into the slide bar drawer Rect rect = sliderBar->getValidBound().move(sliderBar->getAbsSrc()); - Draw::color(Colors::LIGHT_GRAY); - Draw::alpha(0.15f + (sliderBar->isPressed() ? 0.1f : 0.0f)); - Draw::rectOrtho(Draw::getDefaultTexture(), rect); - Draw::alpha(); + Overlay::color(Colors::LIGHT_GRAY); + Overlay::alpha(0.15f + (sliderBar->isPressed() ? 0.1f : 0.0f)); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), rect); + Overlay::alpha(); - Draw::color(Colors::GRAY); + Overlay::color(Colors::GRAY); rect.setSize(sliderBar->getBarDrawSize()); rect.move(sliderBar->getBarCurPos()); - Draw::rectOrtho(Draw::getDefaultTexture(), rect); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), rect); - Draw::color(Colors::LIGHT_GRAY); + Overlay::color(Colors::LIGHT_GRAY); rect.setSrc(sliderBar->getAbsSrc() + sliderBar->getBorder().bot_lft() + sliderBar->getBarLastPos()); - Draw::rectOrtho(Draw::getDefaultTexture(), rect); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), rect); } void UI::ProgressBarDrawer::draw(const ProgressBar* progressBar) const{ Rect bound = progressBar->getValidBound().move(progressBar->getAbsSrc()); - Draw::color(Colors::DARK_GRAY); - Draw::rectOrtho(Draw::getDefaultTexture(), bound); + Overlay::color(Colors::DARK_GRAY); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), bound); bound.sclSize(progressBar->getDrawProgress(), 1.0f); - Draw::color(Colors::LIGHT_GRAY); - Draw::rectOrtho(Draw::getDefaultTexture(), bound); + Overlay::color(Colors::LIGHT_GRAY); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), bound); } void UI::TextureRegionRectDrawable::draw(const Geom::OrthoRectFloat rect) const { #ifdef _DEBUG - if(!texRegion)throw ext::NullPointerException{"Null Tex On Draw Call!"}; + if(!texRegion)throw ext::NullPointerException{"Null Tex On Overlay Call!"}; #endif - Draw::rectOrtho(texRegion, rect); + Overlay::Fill::rectOrtho(texRegion, rect); } void UI::DrawPair::draw(const UI::Elem* elem, const float alphaScl, const Geom::OrthoRectFloat rect) const { - Draw::color(color, alphaScl * color.a); + Overlay::color(color, alphaScl * color.a); region->draw(rect); } @@ -57,7 +58,7 @@ void UI::UIStyle::drawElem(const UI::Elem* elem) const { float alphaScl = elem->selfMaskOpacity * elem->maskOpacity; - Draw::mixColor(elem->tempColor); + Overlay::mixColor(elem->tempColor); const Rect rect = elem->getBound().setSrc(elem->getAbsSrc()); base.draw(elem, alphaScl, rect); edge.draw(elem, alphaScl, rect); @@ -94,22 +95,22 @@ void UI::EdgeDrawer::drawStyle(const UI::Elem* elem) const { elem->tempColor = elem->color; Color& color = elem->tempColor; elem->tempColor.a *= elem->maskOpacity; - Draw::mixColor(elem->tempColor); + Overlay::mixColor(elem->tempColor); if(elem->isCursorInbound()) { color.mul(1.1f).lerp(Colors::WHITE, 0.3f); - Draw::color(color); - Draw::alpha(elem->isPressed() ? 0.5f : 0.2f); - Draw::rectOrtho(Draw::getDefaultTexture(), elem->drawSrcX(), elem->drawSrcY(), elem->getWidth(), elem->getHeight()); + Overlay::color(color); + Overlay::alpha(elem->isPressed() ? 0.5f : 0.2f); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), elem->drawSrcX(), elem->drawSrcY(), elem->getWidth(), elem->getHeight()); } - Draw::color(color); - Draw::Line::setLineStroke(1.0f); - Draw::alpha(color.a * elem->maskOpacity); - Draw::Line::rectOrtho(elem->drawSrcX(), elem->drawSrcY(), elem->getWidth(), elem->getHeight()); + Overlay::color(color); + Overlay::Line::setLineStroke(1.0f); + Overlay::alpha(color.a * elem->maskOpacity); + Overlay::Line::rectOrtho(elem->drawSrcX(), elem->drawSrcY(), elem->getWidth(), elem->getHeight()); - Draw::reset(); + Overlay::reset(); } void UI::EmptyDrawer::applyToElem(UI::Elem* elem){ diff --git a/src/arc-impl/ui/Elem.cpp b/src/arc-impl/ui/Elem.cpp index a072ce84..64834425 100644 --- a/src/arc-impl/ui/Elem.cpp +++ b/src/arc-impl/ui/Elem.cpp @@ -47,13 +47,13 @@ void UI::Elem::draw() const { } - Graphic::Draw::mixColor(); - Graphic::Draw::color(color, color.a * maskOpacity * selfMaskOpacity); + Graphic::Draw::Overlay::mixColor(); + Graphic::Draw::Overlay::color(color, color.a * maskOpacity * selfMaskOpacity); drawContent(); drawStyle(); - Graphic::Draw::color(); + Graphic::Draw::Overlay::color(); } void UI::Elem::applyDefDrawer() noexcept{ diff --git a/src/arc-impl/ui/InputArea.cpp b/src/arc-impl/ui/InputArea.cpp index 596810ee..0adcdef6 100644 --- a/src/arc-impl/ui/InputArea.cpp +++ b/src/arc-impl/ui/InputArea.cpp @@ -17,12 +17,14 @@ void UI::InputArea::setTextUnfocused() const{ } void UI::InputArea::drawContent() const{ - Graphic::Draw::alpha(); + using namespace Graphic; + using Draw::Overlay; + Overlay::alpha(); if(showingHintText){ - Graphic::Draw::mixColor(UI::Pal::GRAY.copy().mul(color)); + Overlay::mixColor(UI::Pal::GRAY.copy().mul(color)); }else{ - Graphic::Draw::mixColor(color); + Overlay::mixColor(color); } if(!glyphLayout->empty()){ @@ -49,37 +51,37 @@ void UI::InputArea::drawContent() const{ curRow++; sectionEnd.set(glyphLayout->getRawBound().getWidth(), data.getBoundEnd().y).scl(glyphLayout->getScale()); } - Graphic::Draw::color(caret.selectionColor, 0.65f); - Graphic::Draw::rectOrtho(Graphic::Draw::getDefaultTexture(), rect.setVert(sectionBegin + off, sectionEnd + off)); + Overlay::color(caret.selectionColor, 0.65f); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), rect.setVert(sectionBegin + off, sectionEnd + off)); sectionBegin.setNaN(); } } Rect rect{}; sectionEnd.x = to->getBoundSrc().x * glyphLayout->getScale(); - Graphic::Draw::color(caret.selectionColor, 0.65f); - Graphic::Draw::rectOrtho(Graphic::Draw::getDefaultTexture(), rect.setVert(sectionBegin + off, sectionEnd + off)); + Overlay::color(caret.selectionColor, 0.65f); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), rect.setVert(sectionBegin + off, sectionEnd + off)); } } glyphLayout->render(maskOpacity); if(isTextFull()){ - Graphic::Draw::mixColor(Pal::RED_DUSK); + Overlay::mixColor(Pal::RED_DUSK); }else if(isTextNearlyFull()){ - Graphic::Draw::mixColor(Pal::KEY_WORD); + Overlay::mixColor(Pal::KEY_WORD); }else{ - Graphic::Draw::mixColor(); + Overlay::mixColor(); } - Graphic::Draw::Line::setLineStroke(2.0f); + Overlay::Line::setLineStroke(2.0f); if(isTextFocused() && Math::cycleStep<75, 40>(insertLineTimer)){ for (const auto & caret : carets){ - Graphic::Draw::color(caret.caretColor); + Overlay::color(caret.caretColor); const Geom::Vec2 src = caret.getDrawPos() * glyphLayout->getScale() + glyphLayout->offset; - Graphic::Draw::Line::line(src, {src.x, src.y + caret.getHeight() * glyphLayout->getScale()}); + Overlay::Line::line(src, {src.x, src.y + caret.getHeight() * glyphLayout->getScale()}); } } - Graphic::Draw::color(); + Overlay::color(); } diff --git a/src/arc-impl/ui/RegionDrawable.cpp b/src/arc-impl/ui/RegionDrawable.cpp index 57c9b856..6415f366 100644 --- a/src/arc-impl/ui/RegionDrawable.cpp +++ b/src/arc-impl/ui/RegionDrawable.cpp @@ -5,5 +5,5 @@ import Graphic.Draw; using namespace Graphic; void UI::UniqueRegionDrawable::draw(const Geom::OrthoRectFloat rect) const{ - Draw::rectOrtho(&wrapper, rect); + Draw::Overlay::Fill::rectOrtho(&wrapper, rect); } diff --git a/src/arc-impl/ui/Root.cpp b/src/arc-impl/ui/Root.cpp index 5092389d..106eed98 100644 --- a/src/arc-impl/ui/Root.cpp +++ b/src/arc-impl/ui/Root.cpp @@ -49,16 +49,18 @@ void UI::Root::drawCursor() const{ const auto& cursor = getCursor(currentCursorType); if(Core::input.cursorInbound()){ - Draw::mixColor(); - Draw::color(Colors::WHITE); - Batch::beginPorj(Geom::MAT3_IDT); - Batch::blend(GL::Blendings::Inverse); + //TODO not use normalized draw! + Draw::Overlay::mixColor(); + Draw::Overlay::color(Colors::WHITE); + Draw::Overlay::getBatch().beginTempProjection(Geom::MAT3_IDT); + Draw::Overlay::getBatch().switchBlending(GL::Blendings::Inverse); auto [x, y] = Core::renderer->getNormalized(cursorPos); cursor.draw(x, y, Core::renderer->getSize()); - Batch::endPorj(); - Batch::blend(); + Draw::Overlay::getBatch().endTempProjection(); + Draw::Overlay::getBatch().switchBlending(); + } } diff --git a/src/arc-impl/ui/ScrollPane.cpp b/src/arc-impl/ui/ScrollPane.cpp index 6da84983..855bb7c6 100644 --- a/src/arc-impl/ui/ScrollPane.cpp +++ b/src/arc-impl/ui/ScrollPane.cpp @@ -11,9 +11,9 @@ using UI::Root; void UI::ScrollBarDrawer::operator()(const ScrollPane* pane) const { if(pane->isPressed()){ - Graphic::Draw::color(pressedBarColor); + Graphic::Draw::Overlay::color(pressedBarColor); }else{ - Graphic::Draw::color(barColor); + Graphic::Draw::Overlay::color(barColor); } if(pane->enableHorizonScroll()) { @@ -106,7 +106,7 @@ void UI::ScrollPane::drawBase() const{ } void UI::ScrollPane::drawContent() const{ - Graphic::Batch::flush(); + Graphic::Draw::Overlay::getBatch().flush(); const auto lastRect = GL::getScissorRect(); @@ -123,7 +123,7 @@ void UI::ScrollPane::drawContent() const{ GL::setScissor(clip); drawChildren(); - Graphic::Batch::flush(); + Graphic::Draw::Overlay::getBatch().flush(); GL::forceSetScissor(lastRect); GL::scissorShrinkEnd(); diff --git a/src/arc-impl/ui/TextWidget.cpp b/src/arc-impl/ui/TextWidget.cpp index 7c415436..1b743d74 100644 --- a/src/arc-impl/ui/TextWidget.cpp +++ b/src/arc-impl/ui/TextWidget.cpp @@ -5,7 +5,7 @@ import Graphic.Draw; void UI::TextWidget::drawContent() const{ Elem::drawContent(); - Graphic::Draw::mixColor(color); + Graphic::Draw::Overlay::mixColor(color); glyphLayout->render(maskOpacity); // Graphic::Draw::tint(Graphic::Colors::YELLOW, .35f); diff --git a/src/arc/asset/LoaderRenderer.cppm b/src/arc/asset/LoaderRenderer.cppm index ef4c5d0f..d9a4de5f 100644 --- a/src/arc/asset/LoaderRenderer.cppm +++ b/src/arc/asset/LoaderRenderer.cppm @@ -22,15 +22,13 @@ import Font.GlyphArrangement; import std; import GL; -import ext.Encoding; - -using namespace Graphic; +import ext.Guard; export namespace Assets { class LoaderRenderer final : public Core::Renderer{ - Assets::AssetsLoader* loader{nullptr}; + AssetsLoader* loader{nullptr}; + Geom::Matrix3D mat{}; - const Geom::Matrix3D* defaultMat{nullptr}; const std::shared_ptr loadStatus = Font::obtainLayoutPtr(); const std::shared_ptr loadTasks = Font::obtainLayoutPtr(); @@ -38,32 +36,36 @@ export namespace Assets { std::stringstream ss{}; public: + //TODO remove these to settings float lastProgress = 0.0f; float lastThreshold = 0.0f; - [[nodiscard]] LoaderRenderer(const int w, const int h, Assets::AssetsLoader* const loader) + [[nodiscard]] LoaderRenderer(const int w, const int h, AssetsLoader* const loader) : Renderer(w, h), loader(loader) { - defaultMat = Graphic::Batch::getPorj(); - GL::setStencilOperation(GL::StencilOperation::KEEP, GL::StencilOperation::KEEP, GL::StencilOperation::REPLACE); - lastThreshold = Assets::PostProcessors::bloom->threshold; - Assets::PostProcessors::bloom->threshold = 0.0f; + lastThreshold = PostProcessors::bloom->threshold; + PostProcessors::bloom->threshold = 0.0f; + + mat.setOrthogonal(0.f, 0.f, getDrawWidth(), getDrawHeight()); } ~LoaderRenderer() override { // NOLINT(*-use-equals-default) - Core::batchGroup.overlay->setProjection(defaultMat); - Graphic::Batch::endShader(false); + //maybe should be set after load done + //Core::batchGroup.overlay->setProjection(defaultMat); + Graphic::Draw::Overlay::getBatch().clearCustomShader(false); - GL::bindFrameBuffer(GL_FRAMEBUFFER); + GL::bindFrameBuffer(GL::FrameBuffer::DEF, 0); GL::setStencilOperation(GL::StencilOperation::REPLACE, GL::StencilOperation::REPLACE, GL::StencilOperation::REPLACE); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); - Assets::PostProcessors::bloom->threshold = lastThreshold; + PostProcessors::bloom->threshold = lastThreshold; } void drawMain() override { + using namespace Graphic; + constexpr float stroke = 10.0f; const float y = static_cast(getHeight()) * 0.5f; const auto w = static_cast(getWidth()); @@ -73,11 +75,11 @@ export namespace Assets { constexpr float slideLineSize = 12.0f; constexpr float preBlockWidth = 32.0f; - mat.setOrthogonal(0.0f, 0.0f, getDrawWidth(), getDrawHeight()); - Core::batchGroup.overlay->setProjection(mat); + using Draw::Overlay; - Graphic::Batch::endShader(); - Draw::mixColor(Colors::DARK_GRAY); + [[maybe_unused]] Core::BatchGuard_Proj guard_proj{Overlay::getBatch(), mat}; + + Overlay::mixColor(Colors::DARK_GRAY); if(!loader->finished()) { Font::defGlyphParser->parseWith(loadTasks, loader->getTaskNames("$$", ">> ")); @@ -91,96 +93,97 @@ export namespace Assets { loadTasks->offset.set(w * 0.05f, y * 0.1f); loadTasks->render(); - Draw::mixColor(); + Overlay::mixColor(); - Draw::color(Colors::DARK_GRAY); + Overlay::color(Colors::DARK_GRAY); - Draw::alpha(0.177f); - Draw::Line::setLineStroke((stroke + slideLineSize) * 2.0f); - Draw::Line::line(0, y, w, y); + Overlay::alpha(0.177f); + Overlay::Line::setLineStroke((stroke + slideLineSize) * 2.0f); + Overlay::Line::line(0, y, w, y); - Draw::alpha(); - Draw::quad( + Overlay::alpha(); + Overlay::Fill::quad( x - preBlockWidth, y - stroke - slideLineSize, x + slideLineSize, y - stroke - slideLineSize, x + slideLineSize, y + stroke, x - preBlockWidth, y + stroke ); - Draw::quad( + Overlay::Fill::quad( x - preBlockWidth, y + stroke, x + slideLineSize, y + stroke, x + slideLineSize, y + stroke + slideLineSize, x - preBlockWidth + slideLineSize, y + stroke + slideLineSize ); - [[maybe_unused]] GL::UniformGuard guard{Shaders::slideLineShaderAngle, -135.0f}; - Graphic::Batch::beginShader(Assets::Shaders::sildeLines, true); - Draw::Line::setLineStroke(stroke); - Draw::color(Colors::GRAY); - - Graphic::Batch::flush(); - //Begin Mask Draw - GL::enable(GL::Test::STENCIL); - GL::setStencilFunc(GL::Func::ALWAYS, 0xFF, 0xFF); - GL::setStencilMask(0xFF); - - Draw::quad( - Draw::getDefaultTexture(), - x, y - stroke - slideLineSize, Colors::DARK_GRAY, - x + barWidth - slideLineSize, y - stroke - slideLineSize, Colors::GRAY, - x + barWidth, y - stroke, Colors::GRAY, - x, y + stroke, Colors::DARK_GRAY - ); - - Draw::quad( - Draw::getDefaultTexture(), - x, y + stroke, Colors::DARK_GRAY, - x + barWidth, y - stroke, Colors::GRAY, - x + barWidth, y + stroke + slideLineSize, Colors::GRAY, - x + slideLineSize, y + stroke + slideLineSize, Colors::DARK_GRAY - ); - - //End Mask Draw - Graphic::Batch::flush(); - GL::setStencilFunc(GL::Func::EQUAL, 0xFF, 0xFF); - GL::setStencilMask(0x00); - - Draw::Line::setLineStroke(stroke * 4); - Draw::alpha(0.9f); - - const Color& begin = loader->postedTasks.empty() ? Colors::ROYAL : Colors::RED; - Color end = begin; - end.lerp(loader->postedTasks.empty() ? Colors::SKY : Colors::ORANGE, lastProgress); - - Draw::quad( - Draw::getDefaultTexture(), - x, y - stroke, begin, - x + barWidth * lastProgress, y - stroke, end, - x + barWidth * lastProgress, y + stroke + slideLineSize, end, - x, y + stroke + slideLineSize, begin - ); - - Draw::quad( - Draw::getDefaultTexture(), - x, y - stroke - slideLineSize, begin, - x + barWidth * lastProgress - slideLineSize, y - stroke - slideLineSize, end, - x + barWidth * lastProgress, y - stroke, end, - x, y - stroke, begin - ); - - Graphic::Batch::flush(); - GL::disable(GL::Test::STENCIL); - //End Clip Layer Draw - Graphic::Batch::endShader(); + const Color begin = loader->postedTasks.empty() ? Colors::ROYAL : Colors::RED; + const Color end = begin.createLerp(loader->postedTasks.empty() ? Colors::SKY : Colors::ORANGE, lastProgress); + + { + Overlay::getBatch().flush(); + + [[maybe_unused]] GL::StateGurad stateGurad{}; + [[maybe_unused]] GL::UniformGuard guard{Shaders::slideLineShaderAngle, -135.0f}; + [[maybe_unused]] Core::BatchGuard_Shader guard_shader{Overlay::getBatch(), Shaders::sildeLines}; + + [[maybe_unused]] ext::GuardRef guard1{Overlay::Line::contextStroke, stroke}; + [[maybe_unused]] ext::GuardRef guard2{Overlay::contextColor, Colors::GRAY}; + + //Begin Mask Draw + GL::setStencilMask(0xFF); + GL::setStencilFunc(GL::Func::ALWAYS, 0xFF, 0xFF); + + Overlay::Fill::quad( + Overlay::getDefaultTexture(), + x, y - stroke - slideLineSize, Colors::DARK_GRAY, + x + barWidth - slideLineSize, y - stroke - slideLineSize, Colors::GRAY, + x + barWidth, y - stroke, Colors::GRAY, + x, y + stroke, Colors::DARK_GRAY + ); + + Overlay::Fill::quad( + Overlay::getDefaultTexture(), + x, y + stroke, Colors::DARK_GRAY, + x + barWidth, y - stroke, Colors::GRAY, + x + barWidth, y + stroke + slideLineSize, Colors::GRAY, + x + slideLineSize, y + stroke + slideLineSize, Colors::DARK_GRAY + ); + + //End Mask Draw + Overlay::getBatch().flush(); + + GL::setStencilFunc(GL::Func::EQUAL, 0xFF, 0xFF); + GL::setStencilMask(0x00); + + Overlay::Line::setLineStroke(stroke * 4); + Overlay::alpha(0.9f); + + Overlay::Fill::quad( + Overlay::getDefaultTexture(), + x, y - stroke, begin, + x + barWidth * lastProgress, y - stroke, end, + x + barWidth * lastProgress, y + stroke + slideLineSize, end, + x, y + stroke + slideLineSize, begin + ); + + Overlay::Fill::quad( + Overlay::getDefaultTexture(), + x, y - stroke - slideLineSize, begin, + x + barWidth * lastProgress - slideLineSize, y - stroke - slideLineSize, end, + x + barWidth * lastProgress, y - stroke, end, + x, y - stroke, begin + ); + + GL::setStencilMask(0xFF); + } ss.str(""); ss << "$Loading$: ($"; ss << std::fixed << std::setprecision(1) << lastProgress * 100.0f << "$%$$)"; ss << "\n$$" << static_cast(loader->getTimer().toMark().count()) / 1000.0f << "$sec."; - Font::defGlyphParser->parseWith(loadStatus, ss.str()); + Font::defGlyphParser->parseWith(loadStatus, std::move(ss).str()); loadStatus->offset.set(x, y - stroke - slideLineSize * 2.0f); loadStatus->setAlign(Align::Mode::top_left); @@ -193,28 +196,30 @@ export namespace Assets { effectBuffer.clearColor(); effectBuffer.clearRenderData(); effectBuffer.bind(); - glClear(GL_STENCIL_BUFFER_BIT); + effectBuffer.clearStencil(); GL::viewport(width, height); drawMain(); - const auto times = Assets::PostProcessors::bloom->blur.getProcessTimes(); - Assets::PostProcessors::bloom->blur.setProcessTimes(2); - Assets::PostProcessors::bloom->setIntensity(1.f, 1.f); + const auto times = PostProcessors::bloom->blur.getProcessTimes(); + PostProcessors::bloom->blur.setProcessTimes(2); + PostProcessors::bloom->setIntensity(1.f, 1.f); - Assets::PostProcessors::bloom->apply(&effectBuffer, &defaultFrameBuffer); + PostProcessors::bloom->apply(&effectBuffer, &defaultFrameBuffer); - Assets::PostProcessors::bloom->blur.setProcessTimes(times); + PostProcessors::bloom->blur.setProcessTimes(times); - glBindFramebuffer(GL_READ_FRAMEBUFFER, defaultFrameBuffer.getID()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBlitFramebuffer( - 0, 0, width, height, + GL::bindFrameBuffer(GL::FrameBuffer::READ, defaultFrameBuffer.getID()); + GL::bindFrameBuffer(GL::FrameBuffer::DRAW, 0); + + GL::blit(0, 0, width, height, 0, 0, width, height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); + GL_COLOR_BUFFER_BIT, GL::nearest); } void resize(const int w, const int h) override { + mat.setOrthogonal(0.0f, 0.0f, getDrawWidth(), getDrawHeight()); + Renderer::resize(w, h); } }; diff --git a/src/arc/asset/effect/Effects.cppm b/src/arc/asset/effect/Effects.cppm index 4dfdffdf..0f7e9f64 100644 --- a/src/arc/asset/effect/Effects.cppm +++ b/src/arc/asset/effect/Effects.cppm @@ -34,10 +34,7 @@ export namespace Assets::Effects{ using namespace Graphic; const auto& [trail] = std::any_cast(effect.additionalData); - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::setZ(effect.zOffset); + Draw::World::setZ(effect.zLayer); trail.each(effect.trans.rot, Graphic::Trail::DefDraw{effect.color}, trail.size() * effect.progress.get()); } @@ -61,10 +58,7 @@ export namespace Assets::Effects{ using namespace Graphic; const auto& [trail, endColor] = std::any_cast(effect.additionalData); - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::setZ(effect.zOffset); + Draw::World::setZ(effect.zLayer); trail.each(effect.trans.rot, Graphic::Trail::DefDraw_WithLerp{effect.color, endColor}, trail.size() * effect.progress.get()); } @@ -93,87 +87,84 @@ export namespace Assets::Effects{ std::unique_ptr circleOut = Graphic::makeEffect(60.0f, [](const Graphic::Effect& effect){ using namespace Graphic; + using Draw::World; - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::setZ(effect.zOffset); - Draw::color(Colors::WHITE, effect.color, effect.progress.getMargin(0.35f)); - Draw::Line::setLineStroke(effect.progress.getInv() * 4.5f); - Draw::Line::circle(effect.trans.vec.x, effect.trans.vec.y, - effect.progress.get(Math::Interp::pow2Out) * 120.0f); + World::setZ(effect.zLayer); + World::color(Colors::WHITE, effect.color, effect.progress.getMargin(0.35f)); + World::Line::setLineStroke(effect.progress.getInv() * 4.5f); + World::Line::circle(effect.trans.vec.x, effect.trans.vec.y, + effect.progress.get(Math::Interp::pow2Out) * 120.0f); }), squareOut = Graphic::makeEffect(60.0f, [](const Graphic::Effect& effect){ using namespace Graphic; + using Draw::World; - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::setZ(effect.zOffset); - Draw::color(Colors::WHITE, effect.color, effect.progress.getMargin(0.35f)); - Draw::Line::setLineStroke(effect.progress.getInv() * 4.5f); - Draw::Line::square(effect.trans.vec.x, effect.trans.vec.y, - effect.progress.get(Math::Interp::pow2Out) * 120.0f, 45); + World::setZ(effect.zLayer); + World::color(Colors::WHITE, effect.color, effect.progress.getMargin(0.35f)); + World::Line::setLineStroke(effect.progress.getInv() * 4.5f); + World::Line::square(effect.trans.vec.x, effect.trans.vec.y, + effect.progress.get(Math::Interp::pow2Out) * 120.0f, 45); }), sparkLarge = Graphic::makeEffect(60.0f, [](const Graphic::Effect& e){ using namespace Graphic; + using Draw::World; - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::color(e.color, Colors::WHITE, e.progress.getInv() * 0.3f); - Draw::Line::setLineStroke(e.progress.getInv() * 8.6f); + World::color(e.color, Colors::WHITE, e.progress.getInv() * 0.3f); + World::Line::setLineStroke(e.progress.getInv() * 8.6f); - Draw::setZ(e.zOffset); + World::setZ(e.zLayer); splashVec(e.handle, { .count = 18, .progress = e.progress.get(Math::Interp::pow2Out) * 27.0f, .radius = {3, 15} }, [vecSrc = e.trans.vec, progress = e.progress.getInv()](const auto vec2, auto& rand){ - Draw::Line::lineAngle( + World::Line::lineAngle( {vecSrc + vec2, vec2.angle()}, progress * rand.random(12.0f, 33.0f) + 2.0f ); }); }), - explode = Graphic::makeEffect(100.0f, 100.0f, [](const Graphic::Effect& e){ - using Math::Interp::operator|; - using namespace Graphic; - - [[maybe_unused]] ext::Guard< - Draw::TextureState, &Draw::TextureState::contextTexture> tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; - - Draw::color(e.color, Colors::WHITE, e.progress.getInv() * 0.3f); - Draw::setZ(e.zOffset); - - Draw::Line::setLineStroke(e.progress.getInv() * 7.f); - Draw::Line::circle(e.trans.vec.x, e.trans.vec.y, - e.progress.get(Math::Interp::pow3Out) * e.trans - .rot * 1.4f); - - splashVec(e.handle, { - .count = 18, .progress = e.progress.get(Math::Interp::pow2Out), - .radius = {e.trans.rot * 0.3f, e.trans.rot * 1.25f} - }, - [&e](const Geom::Vec2 vec2, Math::Rand& rand){ - const auto [x, y] = e.trans.vec + vec2; - Draw::color(Colors::DARK_GRAY, Colors::GRAY, - rand.random(0.1f, 0.5f)); - Draw::Fill::circle(x, y, - (e.progress.getInv() | Math::Interp::pow2In) * rand.random( - e.trans.rot * 0.2f, e.trans.rot * 0.6f) + 2.0f); - }); - }, [](const float clip, const Graphic::Effect& e){ - return Geom::OrthoRectFloat{ - Math::max( - clip, e.progress.get(Math::Interp::pow3Out) * e.trans.rot * 1.4f * - 2.0f) - }.setCenter(e.trans.vec); - }); + explode = Graphic::makeEffect( + 100.0f, + 100.0f, + [](const Graphic::Effect& e){ + using Math::Interp::operator|; + using namespace Graphic; + using Draw::World; + + World::color(e.color, Colors::WHITE, e.progress.getInv() * 0.3f); + World::setZ(e.zLayer); + + World::Line::setLineStroke(e.progress.getInv() * 7.f); + World::Line::circle(e.trans.vec.x, e.trans.vec.y, + e.progress.get(Math::Interp::pow3Out) * e.trans + .rot * 1.4f); + + splashVec(e.handle, { + .count = 18, .progress = e.progress.get(Math::Interp::pow2Out), + .radius = {e.trans.rot * 0.3f, e.trans.rot * 1.25f} + }, + [&e](const Geom::Vec2 vec2, Math::Rand& rand){ + const auto [x, y] = e.trans.vec + vec2; + World::color(Colors::DARK_GRAY, Colors::GRAY, + rand.random(0.1f, 0.5f)); + World::Fill::circle( + x, y, + (e.progress.getInv() | Math::Interp::pow2In) * rand.random( + e.trans.rot * 0.2f, + e.trans.rot * 0.6f + ) + 2.0f + ); + }); + }, [](const float clip, const Graphic::Effect& e){ + return Geom::OrthoRectFloat{ + e.trans.vec, + Math::max(clip, e.progress.get(Math::Interp::pow3Out) * e.trans.rot * 1.4f * 2.0f) + }; + }); // EffectDrawer_Func<[](const Graphic::Effect& effect){ // Draw::color(Colors::WHITE, effect.color, effect.progress.getMargin(0.35f)); diff --git a/src/arc/asset/font/Font.cppm b/src/arc/asset/font/Font.cppm index e707a6dc..8f02d94b 100644 --- a/src/arc/asset/font/Font.cppm +++ b/src/arc/asset/font/Font.cppm @@ -195,7 +195,7 @@ ext::MemberEqualTo>; export namespace Font{ struct FontData { std::unordered_map charDatas{}; - float lineSpacingMin{-1}; + float lineSpacingDef{-1}; explicit FontData(const PreloadDataSet& datas){ for (auto&& data : datas){ @@ -288,6 +288,8 @@ export namespace Font{ const FontFlags* fallback{nullptr}; + + [[nodiscard]] FontFlags( const OS::File& fontFile, const std::vector& segments, @@ -328,8 +330,6 @@ export namespace Font{ } } - FT_Set_Pixel_Sizes(face, 0, size); - if(const auto state = FT_Load_Char(face, charCode, loadFlags); state != 0) { if(state == FT_Err_Invalid_Glyph_Index) { if(fallback){ //Seriously I don't want to use const cast @@ -493,11 +493,8 @@ export namespace Font{ supportedFonts[i].insert(value->internalID); } - //Set font char texture region uv - for(auto& charData : value->data->charDatas | std::ranges::views::values) { - if(value->data->lineSpacingMin < 0) { - value->data->lineSpacingMin = Math::max(normalizeLen(charData.glyphMatrices.height), value->data->lineSpacingMin); - } + if(value->data->lineSpacingDef < 0) { + value->data->lineSpacingDef = normalizeLen(value->face->size->metrics.ascender); } //The pixmap data for a single font wont be needed anymore in all cases, release it if possible; @@ -593,6 +590,7 @@ export namespace Font{ PreloadDataSet fontDatas{}; // Graphic::Pixmap maxMap{}; + FT_Set_Pixel_Sizes(params.face, 0, params.size); if(needCache){ for (const CharCode i : params.segments){ @@ -721,11 +719,6 @@ export namespace Font{ assignID(); setProgress(0.8f); - //TODO is this necessary? - for (const auto& flag : flags) { - flag->freeFontFace(); - } - //Now only [loadTargets, mergedMap] matters. All remain operations should be done in the memory; //FontsManager obtain the texture from the total cache; before this no texture should be generated! if(quickInit) { @@ -736,7 +729,6 @@ export namespace Font{ }).get(); } - setProgress(0.95f); diff --git a/src/arc/graphic/Renderer.cppm b/src/arc/graphic/Renderer.cppm index 17a1f664..4d791af3 100644 --- a/src/arc/graphic/Renderer.cppm +++ b/src/arc/graphic/Renderer.cppm @@ -88,9 +88,9 @@ export namespace Core{ [[nodiscard]] Renderer(const int w, const int h): defaultFrameBuffer{w, h, 1, false}, - uiPostBuffer{w, h, 1, true}, - effectBuffer{w, h, 1, true}, - uiBlurMask{w, h, 1, false}{ + uiPostBuffer{w, h, 1, true}, + effectBuffer{w, h, 1, true}, + uiBlurMask{w, h, 1, false}{ contextFrameBuffer = &defaultFrameBuffer; frameStack.push(contextFrameBuffer); diff --git a/src/arc/graphic/batch/Batch.cppm b/src/arc/graphic/batch/Batch.cppm index cb4311b7..ba928b72 100644 --- a/src/arc/graphic/batch/Batch.cppm +++ b/src/arc/graphic/batch/Batch.cppm @@ -127,7 +127,7 @@ namespace Core{ generalShader->bind(); } - void switchBlending(const Blending blend){ + void switchBlending(const Blending blend = GL::Blendings::Normal){ if(blending != blend){ flush(); } @@ -227,6 +227,19 @@ namespace Core{ } }; + export struct BatchGuard_Blend : BatchGuard{ + const GL::Blending blending{}; + + [[nodiscard]] explicit BatchGuard_Blend(Batch& batch, const GL::Blending blending) + : BatchGuard{batch}, blending{blending}{ + batch.switchBlending(blending); + } + + ~BatchGuard_Blend(){ + batch.switchBlending(blending); + } + }; + /** * @brief L2W --- Local Coordinate To World Transformation Matrix(2D) */ diff --git a/src/arc/graphic/batch/BatchGroup.cppm b/src/arc/graphic/batch/BatchGroup.cppm index cc8e6404..f1c2f114 100644 --- a/src/arc/graphic/batch/BatchGroup.cppm +++ b/src/arc/graphic/batch/BatchGroup.cppm @@ -12,5 +12,10 @@ export namespace Core{ struct BatchGroup { std::unique_ptr overlay{nullptr}; std::unique_ptr world{nullptr}; + + void flushAll() const{ + if(overlay)overlay->flush(); + if(world)world->flush(); + } }; } diff --git a/src/arc/graphic/draw/Draw.cppm b/src/arc/graphic/draw/Draw.cppm index ceb0146c..e1ebf607 100644 --- a/src/arc/graphic/draw/Draw.cppm +++ b/src/arc/graphic/draw/Draw.cppm @@ -1,7 +1,3 @@ -// -// Created by Matrix on 2024/3/19. -// - export module Graphic.Draw; export import GL.Constants; @@ -11,1065 +7,11 @@ export import GL.Texture; export import GL.Texture.TextureRegion; export import GL.Texture.TextureRegionRect; -import GL.Mesh; -import GL.Shader; -import GL.Buffer.FrameBuffer; - - -export import Geom.Transform; -export import Geom.Shape.RectBox; -export import Geom.Rect_Orthogonal; -export import Geom.Matrix3D; -// -export import Graphic.Color; -// -import Math; -import std; -import ext.RuntimeException; -// -import Core.BatchGroup; - -namespace Graphic::Draw{ - using namespace Geom; - //TEMP! - thread_local Vec2 vec2_0{}; - thread_local Vec2 vec2_1{}; - thread_local Vec2 vec2_2{}; - thread_local Vec2 vec2_3{}; - thread_local Vec2 vec2_4{}; - thread_local Vec2 vec2_5{}; - thread_local Vec2 vec2_6{}; - - namespace Line{ - float contextStroke = 1.0f; - std::vector pointBuffer{}; - - bool buildingLine = false; - bool closedLine = false; - - inline Color beginColor{}; - inline Color endColor{}; - } -} - -export namespace Graphic{ - namespace World{ - void vert(float* vertices, - float x1, float y1, float z1, float u1, float v1, Color c1, Color cm1, - float x2, float y2, float z2, float u2, float v2, Color c2, Color cm2, - float x3, float y3, float z3, float u3, float v3, Color c3, Color cm3, - float x4, float y4, float z4, float u4, float v4, Color c4, Color cm4 - ); - - void vert_monochromeMix(float* vertices, Color cm, - float x1, float y1, float z1, float u1, float v1, Color c1, - float x2, float y2, float z2, float u2, float v2, Color c2, - float x3, float y3, float z3, float u3, float v3, Color c3, - float x4, float y4, float z4, float u4, float v4, Color c4 - ); - - void vert_monochromeAll(float* vertices, Color c, Color cm, - float x1, float y1, float z1, float u1, float v1, - float x2, float y2, float z2, float u2, float v2, - float x3, float y3, float z3, float u3, float v3, - float x4, float y4, float z4, float u4, float v4 - ); - } - - namespace Overlay{ - void vert(float* vertices, - float x1, float y1, float u1, float v1, Color c1, Color cm1, - float x2, float y2, float u2, float v2, Color c2, Color cm2, - float x3, float y3, float u3, float v3, Color c3, Color cm3, - float x4, float y4, float u4, float v4, Color c4, Color cm4 - ); - - void vert_monochromeMix(float* vertices, Color cm, - float x1, float y1, float u1, float v1, Color c1, - float x2, float y2, float u2, float v2, Color c2, - float x3, float y3, float u3, float v3, Color c3, - float x4, float y4, float u4, float v4, Color c4 - ); - - void vert_monochromeAll(float* vertices, Color c, Color cm, - float x1, float y1, float u1, float v1, - float x2, float y2, float u2, float v2, - float x3, float y3, float u3, float v3, - float x4, float y4, float u4, float v4 - ); - } - - using BatchPtr = std::unique_ptr; - - constexpr auto BatchOverlay = &Core::BatchGroup::overlay; - constexpr auto BatchWorld = &Core::BatchGroup::world; - constexpr auto DefBatch = BatchOverlay; - - BatchPtr& getBatch(BatchPtr Core::BatchGroup::* batchPtr); - - template - struct VertexPasser; - - template <> - struct VertexPasser<&Core::BatchGroup::world> { - static constexpr auto batchPtr = &Core::BatchGroup::world; - - static constexpr int size = GL::VERT_LENGTH_WORLD; - - inline static float vertices[size]{}; - - static void vert(const GL::Texture* texture, const auto... args){ - World::vert(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - - static void vert_monochromeMix(const GL::Texture* texture, const auto... args){ - World::vert_monochromeMix(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - - static void vert_monochromeAll(const GL::Texture* texture, const auto... args){ - World::vert_monochromeAll(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - }; - - template <> - struct VertexPasser<&Core::BatchGroup::overlay> { - static constexpr auto batchPtr = &Core::BatchGroup::overlay; - - static constexpr int size = GL::VERT_LENGTH_OVERLAY; - - inline static float vertices[size]{}; - - static void vert(const GL::Texture* texture, const auto... args){ - Overlay::vert(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - - static void vert_monochromeMix(const GL::Texture* texture, const auto... args){ - Overlay::vert_monochromeMix(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - - static void vert_monochromeAll(const GL::Texture* texture, const auto... args){ - Overlay::vert_monochromeAll(vertices, args...); - getBatch(batchPtr)->post(texture, vertices, 0, size); - } - }; - - template - constexpr auto vertGroupSize = VertexPasser::size; - - inline constexpr float circleVertPrecision{ 8 }; - - constexpr int getCircleVerts(const float radius){ - return Math::max(Math::ceil(radius * Math::PI / circleVertPrecision), 12); - } - - - inline std::stack formerMesh{}; - - // template - // void vert_raw(const Texture* texture, const auto... args){ - // HandleType::vert(args...); - // - // getBatch()->post(texture, HandleType::vertices, 0, HandleType::size); - // } - // - // template - // void vert_raw_monochromeMix(const Texture* texture, const auto... args){ - // HandleType::vert_monochromeMix(args...); - // - // getBatch()->post(texture, HandleType::vertices, 0, HandleType::size); - // } - // - // template - // void vert_raw_monochromeAll(const Texture* texture, const auto... args){ - // HandleType::vert_monochromeAll(args...); - // - // getBatch()->post(texture, HandleType::vertices, 0, HandleType::size); - // } - - - namespace Frame{ - inline const GL::Mesh* rawMesh{ nullptr }; - inline const GL::ShaderProgram* blitter{ nullptr }; - - template Func = std::nullptr_t> - void blit(const GL::FrameBuffer* const draw, const unsigned port = 0, const GL::ShaderProgram* shader = blitter, - Func&& f = nullptr){ - draw->bind(GL::FrameBuffer::DRAW); - draw->enableDrawAt(port); - - if(shader){ - shader->bind(); - shader->apply(); - if constexpr(!std::is_same_v){ - shader->applyDynamic(f, false); - } - } - - rawMesh->bind(); - rawMesh->render(GL_TRIANGLE_FAN, 0, GL::ELEMENTS_QUAD_STRIP_LENGTH); - } - - void blitCopyAll(const GL::FrameBuffer* const read, const GL::FrameBuffer* const draw, - const GLbitfield mask = GL_COLOR_BUFFER_BIT, const GLenum filter = GL_LINEAR){ - const unsigned int max = std::min(read->getColorAttachments().size(), draw->getColorAttachments().size()); - - read->bind(GL::FrameBuffer::READ); - draw->bind(GL::FrameBuffer::DRAW); - - for(unsigned i = 0; i < max; ++i){ - read->enableRead(i); - draw->enableDrawAt(i); - - GL::blit( - 0, 0, read->getWidth(), read->getHeight(), - 0, 0, draw->getWidth(), draw->getHeight(), - mask, filter); - } - } - - void blitCopy(const GL::FrameBuffer* const read, unsigned readAttachmentID, const GL::FrameBuffer* const draw, - unsigned drawAttachmentID, - const GLbitfield mask = GL_COLOR_BUFFER_BIT, const GLenum filter = GL_LINEAR){ - read->bind(GL::FrameBuffer::READ); - draw->bind(GL::FrameBuffer::DRAW); - - read->enableRead(readAttachmentID); - draw->enableDrawAt(drawAttachmentID); - - GL::blit( - 0, 0, read->getWidth(), read->getHeight(), - 0, 0, draw->getWidth(), draw->getHeight(), - mask, filter); - } - } - - namespace Batch{ - template - const Geom::Matrix3D* getPorj(){ - return getBatch(batchPtr)->getProjection(); - } - - template - void beginPorj(const Geom::Matrix3D& mat){ - getBatch(batchPtr)->beginTempProjection(mat); - } - - template - void endPorj(){ - getBatch(batchPtr)->endTempProjection(); - } - - template - void blend(const GL::Blending blending = GL::Blendings::Normal){ - getBatch(batchPtr)->switchBlending(blending); - } - - template - void flush(){ - getBatch(batchPtr)->flush(); - } - - template - void beginShader(GL::ShaderProgram* shader, const bool flushContext){ - if(flushContext) flush(); - - getBatch(batchPtr)->setCustomShader(shader); - } - - template - void endShader(const bool flushContext = true){ - getBatch(batchPtr)->clearCustomShader(flushContext); - } - } - - namespace Mesh{ - inline void meshBegin(const GL::Mesh* mesh = nullptr){ - if(!mesh)mesh = Frame::rawMesh; - mesh->bind(); - formerMesh.push(mesh); - } - - //Use this for safety! - inline void meshEnd(const GL::Mesh* const mesh, const bool render = false){ - if(render) mesh->render(); - if(mesh == formerMesh.top()){ - formerMesh.pop(); - - if(!formerMesh.empty()) formerMesh.top()->bind(); - } else{ - throw ext::RuntimeException{ "Cannot end incorredt mesh!" }; - } - } - - inline void meshEnd(const bool render = false, const GL::ShaderProgram* shader = nullptr){ - if(render){ - if(shader){ - shader->bind(); - shader->apply(); - } - formerMesh.top()->render(GL_TRIANGLE_FAN, 0, GL::ELEMENTS_QUAD_STRIP_LENGTH); - } - formerMesh.pop(); - - if(!formerMesh.empty()) formerMesh.top()->bind(); - } - } - - namespace Draw{ - constexpr float DepthNear = 1; - constexpr float DepthFar = 50; - - struct ColorState{ - Color contextColor = Colors::WHITE; - Color contextMixColor = Colors::CLEAR; - }; - - struct TextureState{ - const GL::TextureRegionRect* contextTexture = nullptr; - const GL::TextureRegionRect* defaultTexture = nullptr; - const GL::TextureRegionRect* defaultLightTexture = nullptr; - const GL::TextureRegionRect* defaultSolidTexture = nullptr; - }; - - struct DrawState : ColorState, TextureState{ - float contextNorZ = 1.0f; - } globalState; - - struct DrawStateGuard : DrawState{ - ~DrawStateGuard(){ - globalState = *this; - } - }; - - struct ColorStateGuard : ColorState{ - ~ColorStateGuard(){ - static_cast(globalState) = *this; - } - }; - - struct TextureStateGuard : TextureState{ - ~TextureStateGuard(){ - static_cast(globalState) = *this; - } - }; - - ColorStateGuard genColorGuard(){ - return {static_cast(globalState)}; - } - - - TextureStateGuard genTextureGuard(){ - return {static_cast(globalState)}; - } - - const GL::TextureRegionRect* getContextTexture() noexcept{ - return globalState.contextTexture; - } - - const GL::TextureRegionRect* getDefaultTexture() noexcept{ - return globalState.defaultTexture; - } - - float getNormalizedDepth(const float z); - - void setZ(const float z){ globalState.contextNorZ = getNormalizedDepth(z); } - - void setNorZ(const float z){ globalState.contextNorZ = z; } - - [[nodiscard]] float getNorZ(){ return globalState.contextNorZ; } - - template - void color(const Color color = Colors::WHITE){ - if constexpr(applyAlpha){ - globalState.contextColor = color; - }else{ - globalState.contextColor.set(color.r, color.g, color.b); - } - } - - void color(const Color color, const float alpha){ - globalState.contextColor.set(color.r, color.g, color.b, alpha); - } - - void tint(const Color color = Colors::WHITE, const float alpha = 0.0f){ - globalState.contextColor.set(color.r, color.g, color.b, alpha); - } - - template - void mixColor(const Color color = Colors::CLEAR){ - if constexpr(applyAlpha){ - globalState.contextMixColor = color; - }else{ - globalState.contextMixColor.set(color.r, color.g, color.b); - } - } - - void alpha(const float a = 1.0f){ globalState.contextColor.setA(a); } - - void mixAlpha(const float a){ globalState.contextMixColor.setA(a); } - - void mixMulAlpha(const float a){ globalState.contextMixColor.mulA(a); } - - void color(const Color c1, const Color c2, const float t){ globalState.contextColor.lerp(t, c1, c2); } - - void setDefTexture(const GL::TextureRegionRect* texture){ globalState.defaultTexture = texture; } - - void setTexture(const GL::TextureRegionRect* texture = globalState.defaultTexture){ globalState.contextTexture = texture; } - - inline void reset(){ - color(); - mixColor(); - setTexture(); - } - - template - void vert( - const GL::Texture* texture, - const float x1, const float y1, const float u1, const float v1, const Color c1, const Color cm1, - const float x2, const float y2, const float u2, const float v2, const Color c2, const Color cm2, - const float x3, const float y3, const float u3, const float v3, const Color c3, const Color cm3, - const float x4, const float y4, const float u4, const float v4, const Color c4, const Color cm4 - ){ - if constexpr(batchPtr == BatchWorld){ - VertexPasser::vert(texture, - x1, y1, globalState.contextNorZ, u1, v1, c1, cm1, x2, y2, globalState.contextNorZ, u2, v2, c2, cm2, - x3, y3, globalState.contextNorZ, u3, v3, c3, cm3, x4, y4, globalState.contextNorZ, u4, v4, c4, cm4 - ); - } else{ - VertexPasser::vert(texture, - x1, y1, u1, v1, c1, cm1, x2, y2, u2, v2, c2, cm2, - x3, y3, u3, v3, c3, cm3, x4, y4, u4, v4, c4, cm4 - ); - } - } - - template - void vert_monochromeMix( - const GL::Texture* texture, const Color cm, - const float x1, const float y1, const float u1, const float v1, const Color c1, - const float x2, const float y2, const float u2, const float v2, const Color c2, - const float x3, const float y3, const float u3, const float v3, const Color c3, - const float x4, const float y4, const float u4, const float v4, const Color c4 - ){ - if constexpr(batchPtr == BatchWorld){ - VertexPasser::vert_monochromeMix(texture, cm, - x1, y1, globalState.contextNorZ, u1, v1, c1, x2, y2, globalState.contextNorZ, u2, v2, c2, - x3, y3, globalState.contextNorZ, u3, v3, c3, x4, y4, globalState.contextNorZ, u4, v4, c4 - ); - } else{ - VertexPasser::vert_monochromeMix(texture, cm, - x1, y1, u1, v1, c1, x2, y2, u2, v2, c2, - x3, y3, u3, v3, c3, x4, y4, u4, v4, c4 - ); - } - } - - template - void vert_monochromeAll( - const GL::Texture* texture, const Color cm, const Color c, - const float x1, const float y1, const float u1, const float v1, - const float x2, const float y2, const float u2, const float v2, - const float x3, const float y3, const float u3, const float v3, - const float x4, const float y4, const float u4, const float v4 - ){ - if constexpr(batchPtr == BatchWorld){ - VertexPasser::vert_monochromeAll(texture, cm, c, - x1, y1, globalState.contextNorZ, u1, v1, x2, y2, globalState.contextNorZ, u2, v2, - x3, y3, globalState.contextNorZ, u3, v3, x4, y4, globalState.contextNorZ, u4, v4 - ); - } else{ - VertexPasser::vert_monochromeAll(texture, cm, c, - x1, y1, u1, v1, x2, y2, u2, v2, - x3, y3, u3, v3, x4, y4, u4, v4 - ); - } - } - - template - void quad(const GL::TextureRegion* region, - const float x1, const float y1, const Color c1, - const float x2, const float y2, const Color c2, - const float x3, const float y3, const Color c3, - const float x4, const float y4, const Color c4 - ){ - vert_monochromeMix( - region->getData(), globalState.contextMixColor, - x1, y1, region->u00(), region->v00(), c1, - x2, y2, region->u10(), region->v10(), c2, - x3, y3, region->u11(), region->v11(), c3, - x4, y4, region->u01(), region->v01(), c4 - ); - } - - template - void quad(const GL::TextureRegion* region, - const Vec2 v0, const Color c1, - const Vec2 v1, const Color c2, - const Vec2 v2, const Color c3, - const Vec2 v3, const Color c4 - ){ - ::Graphic::Draw::vert_monochromeMix( - region->getData(), globalState.contextMixColor, - v0.x, v0.y, region->u00(), region->v00(), c1, - v1.x, v1.y, region->u10(), region->v10(), c2, - v2.x, v2.y, region->u11(), region->v11(), c3, - v3.x, v3.y, region->u01(), region->v01(), c4 - ); - } - - template - void quad(const GL::TextureRegion* region, - const Concepts::Pos auto& v0, const Concepts::Pos auto& v1, - const Concepts::Pos auto& v2, const Concepts::Pos auto& v3 - ){ - ::Graphic::Draw::vert_monochromeAll( - region->getData(), globalState.contextColor, globalState.contextMixColor, - v0.getX(), v0.getY(), region->u00(), region->v00(), - v1.getX(), v1.getY(), region->u10(), region->v10(), - v2.getX(), v2.getY(), region->u11(), region->v11(), - v3.getX(), v3.getY(), region->u01(), region->v01() - ); - } - - template - void quad( - const Concepts::Pos auto& v0, const Concepts::Pos auto& v1, - const Concepts::Pos auto& v2, const Concepts::Pos auto& v3 - ){ - ::Graphic::Draw::vert_monochromeAll( - globalState.contextTexture->getData(), globalState.contextColor, globalState.contextMixColor, - v0.getX(), v0.getY(), globalState.contextTexture->u00(), globalState.contextTexture->v00(), - v1.getX(), v1.getY(), globalState.contextTexture->u10(), globalState.contextTexture->v10(), - v2.getX(), v2.getY(), globalState.contextTexture->u11(), globalState.contextTexture->v11(), - v3.getX(), v3.getY(), globalState.contextTexture->u01(), globalState.contextTexture->v01() - ); - } - - template - void quad(const GL::TextureRegion* region, - const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4 - ){ - ::Graphic::Draw::vert_monochromeAll( - region->getData(), globalState.contextColor, globalState.contextMixColor, - x1, y1, region->u00(), region->v00(), - x2, y2, region->u10(), region->v10(), - x3, y3, region->u11(), region->v11(), - x4, y4, region->u01(), region->v01() - ); - } - - template - void rectOrtho(const GL::TextureRegion* region, - const float x, const float y, - const float w, const float h - ){ - vert_monochromeAll( - region->getData(), globalState.contextColor, globalState.contextMixColor, - x, y, region->u00(), region->v00(), - x + w, y, region->u10(), region->v10(), - x + w, y + h, region->u11(), region->v11(), - x, y + h, region->u01(), region->v01() - ); - } - - template - void rectOrtho(const GL::TextureRegion* region, const Geom::OrthoRectFloat rect){ - rectOrtho(region, rect.getSrcX(), rect.getSrcY(), rect.getWidth(), rect.getHeight()); - } - - template - void rectPoint(const Geom::Vec2 pos, const float size){ - rectOrtho(globalState.contextTexture, pos.x - size * 0.5f, pos.y - size * 0.5f, size, size); - } - - template - void rect(const GL::TextureRegionRect* region, - const float x, const float y, const float ang, - const float width, const float height - ){ - const float sin = Math::sinDeg(ang); - const float cos = Math::cosDeg(ang); - const float w1 = cos * width * 0.5f; - const float h1 = sin * width * 0.5f; - - const float w2 = -sin * height * 0.5f; - const float h2 = cos * height * 0.5f; - vert_monochromeAll( - region->getData(), globalState.contextColor, globalState.contextMixColor, - x - w1 - w2, y - h1 - h2, region->u00(), region->v00(), - x + w1 - w2, y + h1 - h2, region->u10(), region->v10(), - x + w1 + w2, y + h1 + h2, region->u11(), region->v11(), - x - w1 + w2, y - h1 + h2, region->u01(), region->v01() - ); - } - - - template - void rect(const GL::TextureRegionRect* region, - const float x, const float y, - const float ang = 0, const Geom::Vec2 scl = Geom::norBaseVec2 - ){ - rect(region, x, y, ang, region->getWidth() * scl.x, region->getHeight() * scl.y); - } - - template - void rect(const GL::TextureRegionRect* region, Concepts::Derived auto trans, const Geom::Vec2 scl = Geom::norBaseVec2){ - ::Graphic::Draw::rect(region, trans.vec.x, trans.vec.y, trans.rot, scl); - } - - template - void rectOrtho(const float x, const float y, const float w, const float h){ - rectOrtho(globalState.contextTexture, x, y, w, h); - } - - template - void quad(const GL::TextureRegion* region, const Geom::OrthoRectFloat rect, const float x = 0, - const float y = 0){ - vert_monochromeAll( - region->getData(), globalState.contextColor, globalState.contextMixColor, - rect.getSrcX() + x, rect.getSrcY() + y, region->u00(), region->v00(), - rect.getSrcX() + x, rect.getEndY() + y, region->u10(), region->v10(), - rect.getEndX() + x, rect.getEndY() + y, region->u11(), region->v11(), - rect.getEndX() + x, rect.getSrcY() + y, region->u01(), region->v01() - ); - } - - template - void quad( - const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3, - const float x4, const float y4 - ){ - vert_monochromeAll( - globalState.contextTexture->getData(), globalState.contextColor, globalState.contextMixColor, - x1, y1, globalState.contextTexture->u00(), globalState.contextTexture->v00(), - x2, y2, globalState.contextTexture->u10(), globalState.contextTexture->v10(), - x3, y3, globalState.contextTexture->u11(), globalState.contextTexture->v11(), - x4, y4, globalState.contextTexture->u01(), globalState.contextTexture->v01() - ); - } - - namespace Fill{ - template - void square(const float x, const float y, const float radius, const float ang){ - vec2_0.setPolar(ang + 45.0f, radius / Math::SQRT2); - - vec2_1.set(x, y).add(vec2_0); - vec2_2.set(x, y).add(vec2_0.rotateRT()); - - vec2_3.set(x, y).add(vec2_0.rotateRT()); - vec2_4.set(x, y).add(vec2_0.rotateRT()); - - quad(globalState.contextTexture, vec2_1, vec2_2, vec2_3, vec2_4); - } - - template - void poly(const float x, const float y, const int sides, const float radius, const float angle, - const Color inner = globalState.contextColor, const Color exter = globalState.contextColor){ - const float space = 360.0f / static_cast(sides); - - for(int i = 0; i < sides; i++){ - const float a = space * static_cast(i) + angle; - const float cos1 = Math::cosDeg(a); - const float sin1 = Math::sinDeg(a); - const float cos2 = Math::cosDeg(a + space); - const float sin2 = Math::sinDeg(a + space); - quad( - globalState.contextTexture, - x, y, inner, - x, y, inner, - x + radius * cos2, y + radius * sin2, exter, - x + radius * cos1, y + radius * sin1, exter - ); - } - } - - template - void circle(const float x, const float y, const float radius, - const Color inner = globalState.contextColor, const Color exter = globalState.contextColor){ - poly(x, y, getCircleVerts(radius), radius, 0, inner, exter); - } - } - - namespace Line{ - template - void line(const GL::TextureRegion* region, const float x, const float y, const float x2, const float y2, - const Color& c1 = globalState.contextColor, const Color& c2 = globalState.contextColor, const bool cap = true){ - const float h_stroke = contextStroke / 2.0f; - const float len = Math::len(x2 - x, y2 - y); - const float diff_x = (x2 - x) / len * h_stroke; - const float diff_y = (y2 - y) / len * h_stroke; - - if(cap){ - quad( - region, - x - diff_x - diff_y, y - diff_y + diff_x, c1, - x - diff_x + diff_y, y - diff_y - diff_x, c1, - x2 + diff_x + diff_y, y2 + diff_y - diff_x, c2, - x2 + diff_x - diff_y, y2 + diff_y + diff_x, c2 - ); - } else{ - quad( - region, - x - diff_y, y + diff_x, c1, - x + diff_y, y - diff_x, c1, - x2 + diff_y, y2 - diff_x, c2, - x2 - diff_y, y2 + diff_x, c2 - ); - } - } - - template - void line(const float x, const float y, const float x2, const float y2, const bool cap = true){ - line(globalState.contextTexture, x, y, x2, y2, globalState.contextColor, globalState.contextColor, cap); - } - - template - void line(const Vec2 v1, const Vec2 v2, const Color& c1 = globalState.contextColor, - const Color& c2 = globalState.contextColor, - const bool cap = true){ - line(globalState.contextTexture, v1.x, v1.y, v2.x, v2.y, c1, c2, cap); - } - - - void setLineStroke(const float s){ - contextStroke = s; - } - - template - void lineAngleCenter(const float x, const float y, const float angle, const float length, - const bool cap = true){ - vec2_0.setPolar(angle, length * 0.5f); - - line(globalState.contextTexture, x - vec2_0.x, y - vec2_0.y, x + vec2_0.x, y + vec2_0.y, globalState.contextColor, - globalState.contextColor, - cap); - } - - template - void lineAngle(const float x, const float y, const float angle, const float length, - const bool cap = true){ - vec2_0.setPolar(angle, length); - - line(globalState.contextTexture, x, y, x + vec2_0.x, y + vec2_0.y, globalState.contextColor, globalState.contextColor, cap); - } - - template - void lineAngle(const Geom::Transform trans, const float length, - const bool cap = true){ - lineAngle(trans.vec.x, trans.vec.y, trans.rot, length, cap); - } - - template - void lineAngle(const float x, const float y, const float angle, const float length, - const float offset){ - vec2_0.setPolar(angle, 1.0f); - - line(globalState.contextTexture, x + vec2_0.x * offset, y + vec2_0.y * offset, - x + vec2_0.x * (length + offset), - y + vec2_0.y * (length + offset)); - } - - template - void quad(const Geom::QuadBox& box, const bool cap = true){ - for(int i = 0; i < 4; ++i) { - line(box[i], box[(i + 1) % 4], globalState.contextColor, globalState.contextColor, cap); - } - } - - template - void rectOrtho(const float srcx, const float srcy, const float width, const float height, const bool cap = true){ - line(globalState.contextTexture, srcx, srcy, srcx, srcy + height - contextStroke, globalState.contextColor, - globalState.contextColor, cap); - line(globalState.contextTexture, srcx, srcy + height, srcx + width - contextStroke, srcy + height, - globalState.contextColor, - globalState.contextColor, cap); - line(globalState.contextTexture, srcx + width, srcy + height, srcx + width, srcy + contextStroke, - globalState.contextColor, - globalState.contextColor, cap); - line(globalState.contextTexture, srcx + width, srcy, srcx + contextStroke, srcy, globalState.contextColor, - globalState.contextColor, cap); - } - - template - void rectOrtho(const Geom::OrthoRectFloat& rect, const bool cap = true, const Vec2& offset = Geom::ZERO){ - Line::rectOrtho(rect.getSrcX() + offset.getX(), rect.getSrcY() + offset.getY(), rect.getWidth(), - rect.getHeight(), - cap); - } - - template - void square(const float x, const float y, const float radius, float ang){ - ang += 45.000f; - const float dst = contextStroke / Math::SQRT2; - - vec2_0.setPolar(ang, 1); - - vec2_1.set(vec2_0); - vec2_2.set(vec2_0); - - vec2_1.scl(radius - dst); - vec2_2.scl(radius + dst); - - for(int i = 0; i < 4; ++i){ - vec2_0.rotateRT(); - - vec2_3.set(vec2_0).scl(radius - dst); - vec2_4.set(vec2_0).scl(radius + dst); - - ::Graphic::Draw::quad(vec2_1.x + x, vec2_1.y + y, vec2_2.x + x, vec2_2.y + y, vec2_4.x + x, vec2_4.y + y, - vec2_3.x + x, - vec2_3.y + y); - - vec2_1.set(vec2_3); - vec2_2.set(vec2_4); - } - } - - template - void poly(const float x, const float y, const int sides, const float radius, const float angle){ - const float space = 360.0f / static_cast(sides); - const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); - const float r1 = radius - h_step; - const float r2 = radius + h_step; - - for(int i = 0; i < sides; i++){ - const float a = space * static_cast(i) + angle; - const float cos1 = Math::cosDeg(a); - const float sin1 = Math::sinDeg(a); - const float cos2 = Math::cosDeg(a + space); - const float sin2 = Math::sinDeg(a + space); - ::Graphic::Draw::quad( - x + r1 * cos1, y + r1 * sin1, - x + r1 * cos2, y + r1 * sin2, - x + r2 * cos2, y + r2 * sin2, - x + r2 * cos1, y + r2 * sin1 - ); - } - } - - template - void poly(const float x, const float y, const int sides, const float radius, const float angle, - const float ratio, - const auto&... args){ - constexpr auto size = sizeof...(args); - const auto colors = std::make_tuple(args...); - - const auto fSides = static_cast(sides); - - const float space = 360.0f / fSides; - const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); - const float r1 = radius - h_step; - const float r2 = radius + h_step; - - float currentRatio = 0; - - float currentAng = angle; - float sin1 = Math::sinDeg(currentAng); - float cos1 = Math::cosDeg(currentAng); - float sin2, cos2; - - float progress = 0; - Color lerpColor1 = std::get<0>(colors); - Color lerpColor2 = std::get(colors); - - for(; progress < fSides * ratio - 1.0f; progress += 1.0f){ - // NOLINT(cert-flp30-c) - currentAng = angle + (progress + 1.0f) * space; - - sin2 = Math::sinDeg(currentAng); - cos2 = Math::cosDeg(currentAng); - - currentRatio = progress / fSides; - - lerpColor2.lerp(currentRatio, args...); - - ::Graphic::Draw::quad(globalState.contextTexture, - cos1 * r1 + x, sin1 * r1 + y, lerpColor1, - cos1 * r2 + x, sin1 * r2 + y, lerpColor1, - cos2 * r2 + x, sin2 * r2 + y, lerpColor2, - cos2 * r1 + x, sin2 * r1 + y, lerpColor2 - ); - - lerpColor1.set(lerpColor2); - - sin1 = sin2; - cos1 = cos2; - } - - currentRatio = ratio; - const float remainRatio = currentRatio * fSides - progress; - - currentAng = angle + (progress + 1.0f) * space; - - sin2 = Math::lerp(sin1, Math::sinDeg(currentAng), remainRatio); - cos2 = Math::lerp(cos1, Math::cosDeg(currentAng), remainRatio); - - lerpColor2.lerp(progress / fSides, args...).lerp(lerpColor1, 1.0f - remainRatio); - - ::Graphic::Draw::quad(globalState.contextTexture, - cos1 * r1 + x, sin1 * r1 + y, lerpColor1, - cos1 * r2 + x, sin1 * r2 + y, lerpColor1, - cos2 * r2 + x, sin2 * r2 + y, lerpColor2, - cos2 * r1 + x, sin2 * r1 + y, lerpColor2 - ); - } - - template - void poly(const float x, const float y, const int sides, const float radius, const float angle, - const float ratio, - const std::span& colorGroup){ - const auto size = colorGroup.size(); - - const auto fSides = static_cast(sides); - - const float space = 360.0f / fSides; - const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); - const float r1 = radius - h_step; - const float r2 = radius + h_step; - - float currentRatio = 0; - - float currentAng = angle; - float sin1 = Math::sinDeg(currentAng); - float cos1 = Math::cosDeg(currentAng); - float sin2, cos2; - - float progress = 0; - Color lerpColor1 = colorGroup[0x000000]; - Color lerpColor2 = colorGroup[size - 1]; - - for(; progress < fSides * ratio - 1.0f; progress += 1.0f){ - // NOLINT(cert-flp30-c) - currentAng = angle + (progress + 1.0f) * space; - - sin2 = Math::sinDeg(currentAng); - cos2 = Math::cosDeg(currentAng); - - currentRatio = progress / fSides; - - lerpColor2.lerp(currentRatio, colorGroup); - - ::Graphic::Draw::quad(globalState.contextTexture, - cos1 * r1 + x, sin1 * r1 + y, lerpColor1, - cos1 * r2 + x, sin1 * r2 + y, lerpColor1, - cos2 * r2 + x, sin2 * r2 + y, lerpColor2, - cos2 * r1 + x, sin2 * r1 + y, lerpColor2 - ); - - lerpColor1.set(lerpColor2); - - sin1 = sin2; - cos1 = cos2; - } - - currentRatio = ratio; - const float remainRatio = currentRatio * fSides - progress; - - currentAng = angle + (progress + 1.0f) * space; - - sin2 = Math::lerp(sin1, Math::sinDeg(currentAng), remainRatio); - cos2 = Math::lerp(cos1, Math::cosDeg(currentAng), remainRatio); - - lerpColor2.lerp(progress / fSides, colorGroup).lerp(lerpColor1, 1.0f - remainRatio); - - ::Graphic::Draw::quad(globalState.contextTexture, - cos1 * r1 + x, sin1 * r1 + y, lerpColor1, - cos1 * r2 + x, sin1 * r2 + y, lerpColor1, - cos2 * r2 + x, sin2 * r2 + y, lerpColor2, - cos2 * r1 + x, sin2 * r1 + y, lerpColor2 - ); - } - - template - void circle(const float x, const float y, const float radius){ - poly(x, y, getCircleVerts(radius), radius, 0); - } - - - void setLerpColor(const Color begin = globalState.contextColor, const Color end = globalState.contextColor){ - beginColor = begin; - endColor = end; - } - - //TODO support a color seq maybe in the future - void beginLineVert(const bool closed = false){ - pointBuffer.clear(); - buildingLine = true; - closedLine = closed; - } - - void push(const Geom::Vec2 vec2){ - pointBuffer.push_back(vec2); - } - - void push(const std::span verts){ - for(const auto vec2 : verts){ - pointBuffer.push_back(vec2); - } - } - - template Func = std::nullptr_t> - void endLineVert(Func&& func = nullptr){ - buildingLine = false; - if(pointBuffer.empty()) return; - - if(closedLine){ - pointBuffer.emplace_back(pointBuffer.front()); - } - - const auto size = pointBuffer.size() - 1; - const auto sizeF = static_cast(size); - - Color lineBeginLerp = beginColor; - Color lineEndLerp = endColor; - - const bool enableLerp = beginColor != endColor; - int currentIndex = 0; - for(; currentIndex < size; ++currentIndex){ - if(enableLerp){ - lineBeginLerp.lerp(static_cast(currentIndex) / sizeF, beginColor, endColor); - lineEndLerp.lerp(static_cast(currentIndex + 1) / sizeF, beginColor, endColor); - } - - line(pointBuffer[currentIndex], pointBuffer[currentIndex + 1], lineBeginLerp, - lineEndLerp); - if constexpr(!std::is_same_v){ - func(pointBuffer[currentIndex], lineBeginLerp); - } - } - - if constexpr(!std::is_same_v){ - func(pointBuffer[currentIndex], lineEndLerp); - } - } - - template - requires (std::is_same_v && ...) - void outline(const bool close, Args... args){ - beginLineVert(close); - (::Graphic::Draw::Line::push(args), ...); - endLineVert(); - } +export import Core.BatchGroup; - template - void outline(const std::span verts, const bool close = false){ - beginLineVert(close); - for(const auto p : verts){ - push(p); - } - endLineVert(); - } - } - } -} +export import :General; +export import :Frame; +export import :Mesh; +export import :Vertex; +export import :Base; +export import :Export; \ No newline at end of file diff --git a/src/arc/graphic/draw/Draw_Base.cppm b/src/arc/graphic/draw/Draw_Base.cppm new file mode 100644 index 00000000..22949da9 --- /dev/null +++ b/src/arc/graphic/draw/Draw_Base.cppm @@ -0,0 +1,730 @@ +// +// Created by Matrix on 2024/5/26. +// + +export module Graphic.Draw:Base; + +import ext.Concepts; + +export import Core.BatchGroup; +export import Graphic.Color; +export import GL.Texture; +export import GL.Texture.TextureRegionRect; +export import Math; + +import std; + +import :General; + +export namespace Graphic{ + struct HasBatch{ + [[noreturn]] static Core::Batch& getBatch(){ + std::unreachable(); + } + }; + + template + struct VertPostBase{ + using ImplTy = Identity; + inline static const GL::TextureRegionRect* contextTexture = nullptr; + inline static const GL::TextureRegionRect* defaultTexture = nullptr; + + //TODO provide a alpha mask override? + inline static Color contextColor = Colors::WHITE; + inline static Color contextMixColor = Colors::CLEAR; + + static Core::Batch& getBindedBatch(){ + return ImplTy::getBatch(); + } + + static constexpr float circleVertPrecision{8}; + + static constexpr int getCircleVerts(const float radius){ + return Math::max(Math::ceil(radius * Math::PI / circleVertPrecision), 12); + } + + static const GL::TextureRegionRect* getContextTexture() noexcept{ + return contextTexture; + } + + static const GL::TextureRegionRect* getDefaultTexture() noexcept{ + return defaultTexture; + } + + template + static void color(const Color color = Colors::WHITE) noexcept{ + if constexpr(applyAlpha){ + contextColor = color; + } else{ + contextColor.set(color.r, color.g, color.b); + } + } + + static void color(const Color color, const float alpha) noexcept{ + contextColor.set(color.r, color.g, color.b, alpha); + } + + static void tint(const Color color = Colors::WHITE, const float alpha = 0.0f) noexcept{ + contextColor.set(color.r, color.g, color.b, alpha); + } + + template + static void mixColor(const Color color = Colors::CLEAR) noexcept{ + if constexpr(applyAlpha){ + contextMixColor = color; + } else{ + contextMixColor.set(color.r, color.g, color.b); + } + } + + static void alpha(const float a = 1.0f) noexcept{ contextColor.setA(a); } + + static void mixAlpha(const float a) noexcept{ contextMixColor.setA(a); } + + static void mixMulAlpha(const float a) noexcept{ contextMixColor.mulA(a); } + + static void color(const Color c1, const Color c2, const float t) noexcept{ contextColor.lerp(t, c1, c2); } + + template + static void setDefTexture(const GL::TextureRegionRect* texture) noexcept{ + defaultTexture = texture; + + if constexpr(setContext){ + contextTexture = texture; + } + } + + static void setTexture(const GL::TextureRegionRect* texture = defaultTexture) noexcept{ + contextTexture = texture; + } + + static void reset() noexcept{ + color(); + mixColor(); + setTexture(); + } + + static void vert( + const GL::Texture* texture, + float x1, float y1, float u1, float v1, Color c1, Color cm1, + float x2, float y2, float u2, float v2, Color c2, Color cm2, + float x3, float y3, float u3, float v3, Color c3, Color cm3, + float x4, float y4, float u4, float v4, Color c4, Color cm4 + ) = delete; + + static void vert_monochromeMix( + const GL::Texture* texture, Color cm, + float x1, float y1, float u1, float v1, Color c1, + float x2, float y2, float u2, float v2, Color c2, + float x3, float y3, float u3, float v3, Color c3, + float x4, float y4, float u4, float v4, Color c4 + ) = delete; + + static void vert_monochromeAll( + const GL::Texture* texture, Color cm, Color c, + float x1, float y1, float u1, float v1, + float x2, float y2, float u2, float v2, + float x3, float y3, float u3, float v3, + float x4, float y4, float u4, float v4 + ) = delete; + }; + + using DefHolerBase = VertPostBase; + + template + struct DrawBase : VERT_POST_PROV_Ty{ + //Uses ptr/template arg to create a context data copy + using ProvTy = VERT_POST_PROV_Ty; + + struct Fill{ + static void quad(const GL::TextureRegion* region, + const float x1, const float y1, const Color c1, + const float x2, const float y2, const Color c2, + const float x3, const float y3, const Color c3, + const float x4, const float y4, const Color c4 + ){ + ProvTy::vert_monochromeMix( + region->getData(), ProvTy::contextMixColor, + x1, y1, region->u00(), region->v00(), c1, + x2, y2, region->u10(), region->v10(), c2, + x3, y3, region->u11(), region->v11(), c3, + x4, y4, region->u01(), region->v01(), c4 + ); + } + + + static void quad(const GL::TextureRegion* region, + const Geom::Vec2 v0, const Color c1, + const Geom::Vec2 v1, const Color c2, + const Geom::Vec2 v2, const Color c3, + const Geom::Vec2 v3, const Color c4 + ){ + ProvTy::vert_monochromeMix( + region->getData(), ProvTy::contextMixColor, + v0.x, v0.y, region->u00(), region->v00(), c1, + v1.x, v1.y, region->u10(), region->v10(), c2, + v2.x, v2.y, region->u11(), region->v11(), c3, + v3.x, v3.y, region->u01(), region->v01(), c4 + ); + } + + static void quad(const GL::TextureRegion* region, + Concepts::Pos auto&& v0, Concepts::Pos auto&& v1, + Concepts::Pos auto&& v2, Concepts::Pos auto&& v3 + ){ + ProvTy::vert_monochromeAll( + region->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + v0.getX(), v0.getY(), region->u00(), region->v00(), + v1.getX(), v1.getY(), region->u10(), region->v10(), + v2.getX(), v2.getY(), region->u11(), region->v11(), + v3.getX(), v3.getY(), region->u01(), region->v01() + ); + } + + static void quad( + Concepts::Pos auto&& v0, Concepts::Pos auto&& v1, + Concepts::Pos auto&& v2, Concepts::Pos auto&& v3 + ){ + ProvTy::vert_monochromeAll( + ProvTy::contextTexture->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + v0.getX(), v0.getY(), ProvTy::contextTexture->u00(), ProvTy::contextTexture->v00(), + v1.getX(), v1.getY(), ProvTy::contextTexture->u10(), ProvTy::contextTexture->v10(), + v2.getX(), v2.getY(), ProvTy::contextTexture->u11(), ProvTy::contextTexture->v11(), + v3.getX(), v3.getY(), ProvTy::contextTexture->u01(), ProvTy::contextTexture->v01() + ); + } + + static void quad(const GL::TextureRegion* region, + const float x1, const float y1, + const float x2, const float y2, + const float x3, const float y3, + const float x4, const float y4 + ){ + ProvTy::vert_monochromeAll( + region->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + x1, y1, region->u00(), region->v00(), + x2, y2, region->u10(), region->v10(), + x3, y3, region->u11(), region->v11(), + x4, y4, region->u01(), region->v01() + ); + } + + + + static void rectOrtho(const GL::TextureRegion* region, + const float x, const float y, + const float w, const float h + ){ + ProvTy::vert_monochromeAll( + region->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + x, y, region->u00(), region->v00(), + x + w, y, region->u10(), region->v10(), + x + w, y + h, region->u11(), region->v11(), + x, y + h, region->u01(), region->v01() + ); + } + + + static void rectOrtho(const GL::TextureRegion* region, const Geom::OrthoRectFloat rect){ + Fill::rectOrtho(region, rect.getSrcX(), rect.getSrcY(), rect.getWidth(), rect.getHeight()); + } + + + static void rectPoint(const Geom::Vec2 pos, const float size){ + Fill::rectOrtho(ProvTy::contextTexture, pos.x - size * 0.5f, pos.y - size * 0.5f, size, size); + } + + + static void rect(const GL::TextureRegionRect* region, + const float x, const float y, const float ang, + const float width, const float height + ){ + const float sin = Math::sinDeg(ang); + const float cos = Math::cosDeg(ang); + const float w1 = cos * width * 0.5f; + const float h1 = sin * width * 0.5f; + + const float w2 = -sin * height * 0.5f; + const float h2 = cos * height * 0.5f; + ProvTy::vert_monochromeAll( + region->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + x - w1 - w2, y - h1 - h2, region->u00(), region->v00(), + x + w1 - w2, y + h1 - h2, region->u10(), region->v10(), + x + w1 + w2, y + h1 + h2, region->u11(), region->v11(), + x - w1 + w2, y - h1 + h2, region->u01(), region->v01() + ); + } + + + + static void rect(const GL::TextureRegionRect* region, + const float x, const float y, + const float ang = 0, const Geom::Vec2 scl = Geom::norBaseVec2 + ){ + Fill::rect(region, x, y, ang, region->getWidth() * scl.x, region->getHeight() * scl.y); + } + + + static void rect(const GL::TextureRegionRect* region, Concepts::Derived auto trans, + const Geom::Vec2 scl = Geom::norBaseVec2){ + Fill::rect(region, trans.vec.x, trans.vec.y, trans.rot, scl); + } + + + static void rectOrtho(const float x, const float y, const float w, const float h){ + Fill::rectOrtho(ProvTy::contextTexture, x, y, w, h); + } + + + static void quad(const GL::TextureRegion* region, const Geom::OrthoRectFloat rect, const float x = 0, + const float y = 0){ + ProvTy::vert_monochromeAll( + region->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + rect.getSrcX() + x, rect.getSrcY() + y, region->u00(), region->v00(), + rect.getSrcX() + x, rect.getEndY() + y, region->u10(), region->v10(), + rect.getEndX() + x, rect.getEndY() + y, region->u11(), region->v11(), + rect.getEndX() + x, rect.getSrcY() + y, region->u01(), region->v01() + ); + } + + + static void quad( + const float x1, const float y1, + const float x2, const float y2, + const float x3, const float y3, + const float x4, const float y4 + ){ + ProvTy::vert_monochromeAll( + ProvTy::contextTexture->getData(), ProvTy::contextColor, ProvTy::contextMixColor, + x1, y1, ProvTy::contextTexture->u00(), ProvTy::contextTexture->v00(), + x2, y2, ProvTy::contextTexture->u10(), ProvTy::contextTexture->v10(), + x3, y3, ProvTy::contextTexture->u11(), ProvTy::contextTexture->v11(), + x4, y4, ProvTy::contextTexture->u01(), ProvTy::contextTexture->v01() + ); + } + + + static void square(const float x, const float y, const float radius, const float ang){ + vec2_0.setPolar(ang + 45.0f, radius / Math::SQRT2); + + vec2_1.set(x, y).add(vec2_0); + vec2_2.set(x, y).add(vec2_0.rotateRT()); + + vec2_3.set(x, y).add(vec2_0.rotateRT()); + vec2_4.set(x, y).add(vec2_0.rotateRT()); + + Fill::quad(ProvTy::contextTexture, vec2_1, vec2_2, vec2_3, vec2_4); + } + + + static void poly(const float x, const float y, const int sides, const float radius, const float angle, + const Color inner = ProvTy::contextColor, const Color exter = ProvTy::contextColor){ + const float space = 360.0f / static_cast(sides); + + for(int i = 0; i < sides; i++){ + const float a = space * static_cast(i) + angle; + const float cos1 = Math::cosDeg(a); + const float sin1 = Math::sinDeg(a); + const float cos2 = Math::cosDeg(a + space); + const float sin2 = Math::sinDeg(a + space); + Fill::quad( + ProvTy::contextTexture, + x, y, inner, + x, y, inner, + x + radius * cos2, y + radius * sin2, exter, + x + radius * cos1, y + radius * sin1, exter + ); + } + } + + + static void circle(const float x, const float y, const float radius, + const Color inner = ProvTy::contextColor, const Color exter = ProvTy::contextColor){ + Fill::poly(x, y, ProvTy::getCircleVerts(radius), radius, 0, inner, exter); + } + }; + + + struct Line{ + private: + inline static std::vector pointBuffer{}; + + inline static bool buildingLine = false; + inline static bool closedLine = false; + + inline static Color beginColor{}; + inline static Color endColor{}; + + public: + inline static float contextStroke = 1.0f; + + static void line(const GL::TextureRegion* region, const float x, const float y, const float x2, const float y2, + const Color c1 = ProvTy::contextColor, const Color c2 = ProvTy::contextColor, const bool cap = true){ + const float h_stroke = contextStroke / 2.0f; + const float len = Math::len(x2 - x, y2 - y); + const float diff_x = (x2 - x) / len * h_stroke; + const float diff_y = (y2 - y) / len * h_stroke; + + if(cap){ + Fill::quad( + region, + x - diff_x - diff_y, y - diff_y + diff_x, c1, + x - diff_x + diff_y, y - diff_y - diff_x, c1, + x2 + diff_x + diff_y, y2 + diff_y - diff_x, c2, + x2 + diff_x - diff_y, y2 + diff_y + diff_x, c2 + ); + } else{ + Fill::quad( + region, + x - diff_y, y + diff_x, c1, + x + diff_y, y - diff_x, c1, + x2 + diff_y, y2 - diff_x, c2, + x2 - diff_y, y2 + diff_x, c2 + ); + } + } + + + static void line(const float x, const float y, const float x2, const float y2, const bool cap = true){ + Line::line(ProvTy::contextTexture, x, y, x2, y2, ProvTy::contextColor, ProvTy::contextColor, cap); + } + + + static void line(const Geom::Vec2 v1, const Geom::Vec2 v2, const Color c1 = ProvTy::contextColor, + const Color c2 = ProvTy::contextColor, + const bool cap = true){ + Line::line(ProvTy::contextTexture, v1.x, v1.y, v2.x, v2.y, c1, c2, cap); + } + + + static void setLineStroke(const float s){ + contextStroke = s; + } + + + static void lineAngleCenter(const float x, const float y, const float angle, const float length, + const bool cap = true){ + vec2_0.setPolar(angle, length * 0.5f); + + Line::line(ProvTy::contextTexture, x - vec2_0.x, y - vec2_0.y, x + vec2_0.x, y + vec2_0.y, ProvTy::contextColor, + ProvTy::contextColor, + cap); + } + + + static void lineAngle(const float x, const float y, const float angle, const float length, + const bool cap = true){ + vec2_0.setPolar(angle, length); + + Line::line(ProvTy::contextTexture, x, y, x + vec2_0.x, y + vec2_0.y, ProvTy::contextColor, ProvTy::contextColor, cap); + } + + + static void lineAngle(const Geom::Transform trans, const float length, + const bool cap = true){ + lineAngle(trans.vec.x, trans.vec.y, trans.rot, length, cap); + } + + + static void lineAngle(const float x, const float y, const float angle, const float length, + const float offset){ + vec2_0.setPolar(angle, 1.0f); + + Line::line(ProvTy::contextTexture, x + vec2_0.x * offset, y + vec2_0.y * offset, + x + vec2_0.x * (length + offset), + y + vec2_0.y * (length + offset)); + } + + + static void quad(const Geom::QuadBox& box, const bool cap = true){ + for(int i = 0; i < 4; ++i) { + Line::line(box[i], box[(i + 1) % 4], ProvTy::contextColor, ProvTy::contextColor, cap); + } + } + + + static void rectOrtho(const float srcx, const float srcy, const float width, const float height, const bool cap = true){ + Line::line(ProvTy::contextTexture, srcx, srcy, srcx, srcy + height - contextStroke, ProvTy::contextColor, + ProvTy::contextColor, cap); + Line::line(ProvTy::contextTexture, srcx, srcy + height, srcx + width - contextStroke, srcy + height, + ProvTy::contextColor, + ProvTy::contextColor, cap); + Line::line(ProvTy::contextTexture, srcx + width, srcy + height, srcx + width, srcy + contextStroke, + ProvTy::contextColor, + ProvTy::contextColor, cap); + Line::line(ProvTy::contextTexture, srcx + width, srcy, srcx + contextStroke, srcy, ProvTy::contextColor, + ProvTy::contextColor, cap); + } + + + static void rectOrtho(const Geom::OrthoRectFloat& rect, const bool cap = true, const Geom::Vec2 offset = Geom::ZERO){ + Line::rectOrtho(rect.getSrcX() + offset.getX(), rect.getSrcY() + offset.getY(), rect.getWidth(), + rect.getHeight(), + cap); + } + + + static void square(const float x, const float y, const float radius, float ang){ + ang += 45.000f; + const float dst = contextStroke / Math::SQRT2; + + vec2_0.setPolar(ang, 1); + + vec2_1.set(vec2_0); + vec2_2.set(vec2_0); + + vec2_1.scl(radius - dst); + vec2_2.scl(radius + dst); + + for(int i = 0; i < 4; ++i){ + vec2_0.rotateRT(); + + vec2_3.set(vec2_0).scl(radius - dst); + vec2_4.set(vec2_0).scl(radius + dst); + + Fill::quad(vec2_1.x + x, vec2_1.y + y, vec2_2.x + x, vec2_2.y + y, vec2_4.x + x, vec2_4.y + y, + vec2_3.x + x, + vec2_3.y + y); + + vec2_1.set(vec2_3); + vec2_2.set(vec2_4); + } + } + + + static void poly(const float x, const float y, const int sides, const float radius, const float angle){ + const float space = 360.0f / static_cast(sides); + const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); + const float r1 = radius - h_step; + const float r2 = radius + h_step; + + for(int i = 0; i < sides; i++){ + const float a = space * static_cast(i) + angle; + const float cos1 = Math::cosDeg(a); + const float sin1 = Math::sinDeg(a); + const float cos2 = Math::cosDeg(a + space); + const float sin2 = Math::sinDeg(a + space); + Fill::quad( + x + r1 * cos1, y + r1 * sin1, + x + r1 * cos2, y + r1 * sin2, + x + r2 * cos2, y + r2 * sin2, + x + r2 * cos1, y + r2 * sin1 + ); + } + } + + + static void poly(const float x, const float y, const int sides, const float radius, const float angle, + const float ratio, + const auto&... args){ + constexpr auto size = sizeof...(args); + const auto colors = std::make_tuple(args...); + + const auto fSides = static_cast(sides); + + const float space = 360.0f / fSides; + const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); + const float r1 = radius - h_step; + const float r2 = radius + h_step; + + float currentRatio = 0; + + float currentAng = angle; + float sin1 = Math::sinDeg(currentAng); + float cos1 = Math::cosDeg(currentAng); + float sin2, cos2; + + float progress = 0; + Color lerpColor1 = std::get<0>(colors); + Color lerpColor2 = std::get(colors); + + for(; progress < fSides * ratio - 1.0f; progress += 1.0f){ + // NOLINT(cert-flp30-c) + currentAng = angle + (progress + 1.0f) * space; + + sin2 = Math::sinDeg(currentAng); + cos2 = Math::cosDeg(currentAng); + + currentRatio = progress / fSides; + + lerpColor2.lerp(currentRatio, args...); + + Fill::quad(ProvTy::contextTexture, + cos1 * r1 + x, sin1 * r1 + y, lerpColor1, + cos1 * r2 + x, sin1 * r2 + y, lerpColor1, + cos2 * r2 + x, sin2 * r2 + y, lerpColor2, + cos2 * r1 + x, sin2 * r1 + y, lerpColor2 + ); + + lerpColor1.set(lerpColor2); + + sin1 = sin2; + cos1 = cos2; + } + + currentRatio = ratio; + const float remainRatio = currentRatio * fSides - progress; + + currentAng = angle + (progress + 1.0f) * space; + + sin2 = Math::lerp(sin1, Math::sinDeg(currentAng), remainRatio); + cos2 = Math::lerp(cos1, Math::cosDeg(currentAng), remainRatio); + + lerpColor2.lerp(progress / fSides, args...).lerp(lerpColor1, 1.0f - remainRatio); + + Fill::quad(ProvTy::contextTexture, + cos1 * r1 + x, sin1 * r1 + y, lerpColor1, + cos1 * r2 + x, sin1 * r2 + y, lerpColor1, + cos2 * r2 + x, sin2 * r2 + y, lerpColor2, + cos2 * r1 + x, sin2 * r1 + y, lerpColor2 + ); + } + + + static void poly(const float x, const float y, const int sides, const float radius, const float angle, + const float ratio, + const std::span& colorGroup){ + const auto size = colorGroup.size(); + + const auto fSides = static_cast(sides); + + const float space = 360.0f / fSides; + const float h_step = contextStroke / 2.0f / Math::cosDeg(space / 2.0f); + const float r1 = radius - h_step; + const float r2 = radius + h_step; + + float currentRatio = 0; + + float currentAng = angle; + float sin1 = Math::sinDeg(currentAng); + float cos1 = Math::cosDeg(currentAng); + float sin2, cos2; + + float progress = 0; + Color lerpColor1 = colorGroup[0x000000]; + Color lerpColor2 = colorGroup[size - 1]; + + for(; progress < fSides * ratio - 1.0f; progress += 1.0f){ + // NOLINT(cert-flp30-c) + currentAng = angle + (progress + 1.0f) * space; + + sin2 = Math::sinDeg(currentAng); + cos2 = Math::cosDeg(currentAng); + + currentRatio = progress / fSides; + + lerpColor2.lerp(currentRatio, colorGroup); + + Fill::quad(ProvTy::contextTexture, + cos1 * r1 + x, sin1 * r1 + y, lerpColor1, + cos1 * r2 + x, sin1 * r2 + y, lerpColor1, + cos2 * r2 + x, sin2 * r2 + y, lerpColor2, + cos2 * r1 + x, sin2 * r1 + y, lerpColor2 + ); + + lerpColor1.set(lerpColor2); + + sin1 = sin2; + cos1 = cos2; + } + + currentRatio = ratio; + const float remainRatio = currentRatio * fSides - progress; + + currentAng = angle + (progress + 1.0f) * space; + + sin2 = Math::lerp(sin1, Math::sinDeg(currentAng), remainRatio); + cos2 = Math::lerp(cos1, Math::cosDeg(currentAng), remainRatio); + + lerpColor2.lerp(progress / fSides, colorGroup).lerp(lerpColor1, 1.0f - remainRatio); + + Fill::quad(ProvTy::contextTexture, + cos1 * r1 + x, sin1 * r1 + y, lerpColor1, + cos1 * r2 + x, sin1 * r2 + y, lerpColor1, + cos2 * r2 + x, sin2 * r2 + y, lerpColor2, + cos2 * r1 + x, sin2 * r1 + y, lerpColor2 + ); + } + + + static void circle(const float x, const float y, const float radius){ + poly(x, y, ProvTy::getCircleVerts(radius), radius, 0); + } + + + static void setLerpColor(const Color begin = ProvTy::contextColor, const Color end = ProvTy::contextColor){ + beginColor = begin; + endColor = end; + } + + //TODO support a color seq maybe in the future + static void beginLineVert(const bool closed = false){ + pointBuffer.clear(); + buildingLine = true; + closedLine = closed; + } + + static void push(const Geom::Vec2 vec2){ + pointBuffer.push_back(vec2); + } + + static void push(const std::span verts){ + for(const auto vec2 : verts){ + pointBuffer.push_back(vec2); + } + } + + template Func = std::nullptr_t> + static void endLineVert(Func&& func = nullptr){ + buildingLine = false; + if(pointBuffer.empty()) return; + + if(closedLine){ + pointBuffer.emplace_back(pointBuffer.front()); + } + + const auto size = pointBuffer.size() - 1; + const auto sizeF = static_cast(size); + + Color lineBeginLerp = beginColor; + Color lineEndLerp = endColor; + + const bool enableLerp = beginColor != endColor; + int currentIndex = 0; + for(; currentIndex < size; ++currentIndex){ + if(enableLerp){ + lineBeginLerp.lerp(static_cast(currentIndex) / sizeF, beginColor, endColor); + lineEndLerp.lerp(static_cast(currentIndex + 1) / sizeF, beginColor, endColor); + } + + Line::line(pointBuffer[currentIndex], pointBuffer[currentIndex + 1], lineBeginLerp, + lineEndLerp); + if constexpr(!std::is_same_v){ + func(pointBuffer[currentIndex], lineBeginLerp); + } + } + + if constexpr(!std::is_same_v){ + func(pointBuffer[currentIndex], lineEndLerp); + } + } + + template + requires (std::is_same_v && ...) + static void outline(const bool close, Args... args){ + beginLineVert(close); + (Line::push(args), ...); + endLineVert(); + } + + + static void outline(const std::span verts, const bool close = false){ + beginLineVert(close); + for(const auto p : verts){ + push(p); + } + endLineVert(); + } + }; + }; +} diff --git a/src/arc/graphic/draw/Draw_Export.cppm b/src/arc/graphic/draw/Draw_Export.cppm new file mode 100644 index 00000000..e5b99e46 --- /dev/null +++ b/src/arc/graphic/draw/Draw_Export.cppm @@ -0,0 +1,124 @@ +// +// Created by Matrix on 2024/5/27. +// + +export module Graphic.Draw:Export; + +import :Base; +import :Vertex; + +namespace Graphic::Draw{ + struct OverlayBase : VertPostBase, HasBatch{ + static Core::Batch& getBatch(){ + return Vertex::VertexPasser<&Core::BatchGroup::overlay>::getBatch(); + } + + static void vert( + const GL::Texture* texture, + const float x1, const float y1, const float u1, const float v1, const Color c1, const Color cm1, + const float x2, const float y2, const float u2, const float v2, const Color c2, const Color cm2, + const float x3, const float y3, const float u3, const float v3, const Color c3, const Color cm3, + const float x4, const float y4, const float u4, const float v4, const Color c4, const Color cm4 + ){ + Vertex::VertexPasser<&Core::BatchGroup::overlay>::vert(texture, + x1, y1, u1, v1, c1, cm1, x2, y2, u2, v2, c2, cm2, + x3, y3, u3, v3, c3, cm3, x4, y4, u4, v4, c4, cm4 + ); + } + + static void vert_monochromeMix( + const GL::Texture* texture, const Color cm, + const float x1, const float y1, const float u1, const float v1, const Color c1, + const float x2, const float y2, const float u2, const float v2, const Color c2, + const float x3, const float y3, const float u3, const float v3, const Color c3, + const float x4, const float y4, const float u4, const float v4, const Color c4 + ){ + Vertex::VertexPasser<&Core::BatchGroup::overlay>::vert_monochromeMix(texture, cm, + x1, y1, u1, v1, c1, x2, y2, u2, v2, c2, + x3, y3, u3, v3, c3, x4, y4, u4, v4, c4 + ); + } + + static void vert_monochromeAll( + const GL::Texture* texture, const Color cm, const Color c, + const float x1, const float y1, const float u1, const float v1, + const float x2, const float y2, const float u2, const float v2, + const float x3, const float y3, const float u3, const float v3, + const float x4, const float y4, const float u4, const float v4 + ){ + Vertex::VertexPasser<&Core::BatchGroup::overlay>::vert_monochromeAll(texture, cm, c, + x1, y1, u1, v1, x2, y2, u2, v2, + x3, y3, u3, v3, x4, y4, u4, v4 + ); + } + }; + struct WorldBase : VertPostBase, HasBatch{ + static constexpr float DepthNear = 1; + static constexpr float DepthFar = 50; + + inline static const GL::TextureRegionRect* defaultLightTexture = nullptr; + inline static const GL::TextureRegionRect* defaultSolidTexture = nullptr; + + static inline float contextNorZ; + + static float getNormalizedDepth(const float z); + + static void setZ(const float z){ contextNorZ = getNormalizedDepth(z); } + + static void setNorZ(const float z){ contextNorZ = z; } + + [[nodiscard]] static float getNorZ(){ return contextNorZ; } + + static Core::Batch& getBatch(){ + return Vertex::VertexPasser<&Core::BatchGroup::world>::getBatch(); + } + + static void vert( + const GL::Texture* texture, + const float x1, const float y1, const float u1, const float v1, const Color c1, const Color cm1, + const float x2, const float y2, const float u2, const float v2, const Color c2, const Color cm2, + const float x3, const float y3, const float u3, const float v3, const Color c3, const Color cm3, + const float x4, const float y4, const float u4, const float v4, const Color c4, const Color cm4 + ){ + Vertex::WorldPass::vert(texture, + x1, y1, contextNorZ, u1, v1, c1, cm1, x2, y2, contextNorZ, u2, v2, c2, + cm2, + x3, y3, contextNorZ, u3, v3, c3, cm3, x4, y4, contextNorZ, u4, v4, c4, + cm4 + ); + } + + static void vert_monochromeMix( + const GL::Texture* texture, const Color cm, + const float x1, const float y1, const float u1, const float v1, const Color c1, + const float x2, const float y2, const float u2, const float v2, const Color c2, + const float x3, const float y3, const float u3, const float v3, const Color c3, + const float x4, const float y4, const float u4, const float v4, const Color c4 + ){ + Vertex::VertexPasser<&Core::BatchGroup::world>::vert_monochromeMix(texture, cm, + x1, y1, contextNorZ, u1, v1, c1, x2, y2, contextNorZ, u2, + v2, c2, + x3, y3, contextNorZ, u3, v3, c3, x4, y4, contextNorZ, u4, + v4, c4 + ); + } + + static void vert_monochromeAll( + const GL::Texture* texture, const Color cm, const Color c, + const float x1, const float y1, const float u1, const float v1, + const float x2, const float y2, const float u2, const float v2, + const float x3, const float y3, const float u3, const float v3, + const float x4, const float y4, const float u4, const float v4 + ){ + Vertex::VertexPasser<&Core::BatchGroup::world>::vert_monochromeAll(texture, cm, c, + x1, y1, contextNorZ, u1, v1, x2, y2, contextNorZ, u2, v2, + x3, y3, contextNorZ, u3, v3, x4, y4, contextNorZ, u4, v4 + ); + } + }; + + export using Overlay = DrawBase; + export using World = DrawBase; + export using Void = DrawBase<>; + +} \ No newline at end of file diff --git a/src/arc/graphic/draw/Draw_Frame.cppm b/src/arc/graphic/draw/Draw_Frame.cppm new file mode 100644 index 00000000..63415aa0 --- /dev/null +++ b/src/arc/graphic/draw/Draw_Frame.cppm @@ -0,0 +1,68 @@ +// +// Created by Matrix on 2024/5/26. +// + +export module Graphic.Draw:Frame; + +export import std; +export import ext.Concepts; +export import GL.Mesh; +export import GL.Shader; +export import GL.Buffer.FrameBuffer; +export import GL.Constants; + +export namespace Graphic::Frame{ + inline const GL::Mesh* rawMesh{ nullptr }; + inline const GL::ShaderProgram* blitter{ nullptr }; + + template Func = std::nullptr_t> + void blit(const GL::FrameBuffer* const draw, const unsigned port = 0, const GL::ShaderProgram* shader = blitter, + Func&& f = nullptr){ + draw->bind(GL::FrameBuffer::DRAW); + draw->enableDrawAt(port); + + if(shader){ + shader->bind(); + shader->apply(); + if constexpr(!std::is_same_v){ + shader->applyDynamic(f, false); + } + } + + rawMesh->bind(); + rawMesh->render(GL_TRIANGLE_FAN, 0, GL::ELEMENTS_QUAD_STRIP_LENGTH); + } + + void blitCopyAll(const GL::FrameBuffer* const read, const GL::FrameBuffer* const draw, + const GLbitfield mask = GL_COLOR_BUFFER_BIT, const GLenum filter = GL_LINEAR){ + const unsigned int max = std::min(read->getColorAttachments().size(), draw->getColorAttachments().size()); + + read->bind(GL::FrameBuffer::READ); + draw->bind(GL::FrameBuffer::DRAW); + + for(unsigned i = 0; i < max; ++i){ + read->enableRead(i); + draw->enableDrawAt(i); + + GL::blit( + 0, 0, read->getWidth(), read->getHeight(), + 0, 0, draw->getWidth(), draw->getHeight(), + mask, filter); + } + } + + void blitCopy(const GL::FrameBuffer* const read, unsigned readAttachmentID, const GL::FrameBuffer* const draw, + unsigned drawAttachmentID, + const GLbitfield mask = GL_COLOR_BUFFER_BIT, const GLenum filter = GL_LINEAR){ + read->bind(GL::FrameBuffer::READ); + draw->bind(GL::FrameBuffer::DRAW); + + read->enableRead(readAttachmentID); + draw->enableDrawAt(drawAttachmentID); + + GL::blit( + 0, 0, read->getWidth(), read->getHeight(), + 0, 0, draw->getWidth(), draw->getHeight(), + mask, filter); + } +} diff --git a/src/arc/graphic/draw/Draw_General.cppm b/src/arc/graphic/draw/Draw_General.cppm new file mode 100644 index 00000000..75d9dc7f --- /dev/null +++ b/src/arc/graphic/draw/Draw_General.cppm @@ -0,0 +1,20 @@ +export module Graphic.Draw:General; + +export import Core.Batch; +export import Geom.Transform; +export import Geom.Shape.RectBox; +export import Geom.Rect_Orthogonal; +export import Geom.Matrix3D; +export import Math; +// +export import Graphic.Color; + +namespace Graphic{ + /*thread_local*/ Geom::Vec2 vec2_0{}; + /*thread_local*/ Geom::Vec2 vec2_1{}; + /*thread_local*/ Geom::Vec2 vec2_2{}; + /*thread_local*/ Geom::Vec2 vec2_3{}; + /*thread_local*/ Geom::Vec2 vec2_4{}; + /*thread_local*/ Geom::Vec2 vec2_5{}; + /*thread_local*/ Geom::Vec2 vec2_6{}; +} diff --git a/src/arc/graphic/draw/Draw_Mesh.cppm b/src/arc/graphic/draw/Draw_Mesh.cppm new file mode 100644 index 00000000..c15f9c32 --- /dev/null +++ b/src/arc/graphic/draw/Draw_Mesh.cppm @@ -0,0 +1,50 @@ +// +// Created by Matrix on 2024/5/26. +// + +export module Graphic.Draw:Mesh; + + +import std; +export import GL.Mesh; +export import GL.Shader; +export import GL.Constants; +export import ext.RuntimeException; + +import :Frame; + +export namespace Graphic::Mesh{ + inline std::stack formerMesh{}; + + inline void meshBegin(const GL::Mesh* mesh = nullptr){ + if(!mesh) mesh = Frame::rawMesh; + mesh->bind(); + formerMesh.push(mesh); + } + + //Use this for safety! + inline void meshEnd(const GL::Mesh* const mesh, const bool render = false){ + if(render) mesh->render(); + if(mesh == formerMesh.top()){ + formerMesh.pop(); + + if(!formerMesh.empty()) formerMesh.top()->bind(); + } else{ + throw ext::RuntimeException{"Cannot end incorredt mesh!"}; + } + } + + inline void meshEnd(const bool render = false, const GL::ShaderProgram* shader = nullptr){ + if(render){ + if(shader){ + shader->bind(); + shader->apply(); + } + formerMesh.top()->render(GL_TRIANGLE_FAN, 0, GL::ELEMENTS_QUAD_STRIP_LENGTH); + } + formerMesh.pop(); + + if(!formerMesh.empty()) formerMesh.top()->bind(); + } +} + diff --git a/src/arc/graphic/draw/Draw_Vertex.cppm b/src/arc/graphic/draw/Draw_Vertex.cppm new file mode 100644 index 00000000..1e620e4c --- /dev/null +++ b/src/arc/graphic/draw/Draw_Vertex.cppm @@ -0,0 +1,128 @@ +export module Graphic.Draw:Vertex; + +import Graphic.Color; +import Core.Batch; +export import Core.BatchGroup; +export import Core.Batch; +import std; +import GL.Constants; + +namespace Graphic::Vertex{ + namespace World{ + void vert(float* vertices, + float x1, float y1, float z1, float u1, float v1, Color c1, Color cm1, + float x2, float y2, float z2, float u2, float v2, Color c2, Color cm2, + float x3, float y3, float z3, float u3, float v3, Color c3, Color cm3, + float x4, float y4, float z4, float u4, float v4, Color c4, Color cm4 + ); + + void vert_monochromeMix(float* vertices, Color cm, + float x1, float y1, float z1, float u1, float v1, Color c1, + float x2, float y2, float z2, float u2, float v2, Color c2, + float x3, float y3, float z3, float u3, float v3, Color c3, + float x4, float y4, float z4, float u4, float v4, Color c4 + ); + + void vert_monochromeAll(float* vertices, Color c, Color cm, + float x1, float y1, float z1, float u1, float v1, + float x2, float y2, float z2, float u2, float v2, + float x3, float y3, float z3, float u3, float v3, + float x4, float y4, float z4, float u4, float v4 + ); + } + + + namespace Overlay{ + void vert(float* vertices, + float x1, float y1, float u1, float v1, Color c1, Color cm1, + float x2, float y2, float u2, float v2, Color c2, Color cm2, + float x3, float y3, float u3, float v3, Color c3, Color cm3, + float x4, float y4, float u4, float v4, Color c4, Color cm4 + ); + + void vert_monochromeMix(float* vertices, Color cm, + float x1, float y1, float u1, float v1, Color c1, + float x2, float y2, float u2, float v2, Color c2, + float x3, float y3, float u3, float v3, Color c3, + float x4, float y4, float u4, float v4, Color c4 + ); + + void vert_monochromeAll(float* vertices, Color c, Color cm, + float x1, float y1, float u1, float v1, + float x2, float y2, float u2, float v2, + float x3, float y3, float u3, float v3, + float x4, float y4, float u4, float v4 + ); + } + + + export{ + using BatchPtr = std::unique_ptr; + + constexpr auto BatchOverlay = &Core::BatchGroup::overlay; + constexpr auto BatchWorld = &Core::BatchGroup::world; + constexpr auto DefBatch = BatchOverlay; + + BatchPtr& getBatch(BatchPtr Core::BatchGroup::* batchPtr); + + template + struct VertexPasser; + } + + struct WorldPass{ + static constexpr auto batchPtr = &Core::BatchGroup::world; + + static constexpr int size = GL::VERT_LENGTH_WORLD; + + inline static float vertices[size]{}; + + static Core::Batch& getBatch(); + + static void vert(const GL::Texture* texture, const auto... args){ + World::vert(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + + static void vert_monochromeMix(const GL::Texture* texture, const auto... args){ + World::vert_monochromeMix(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + + static void vert_monochromeAll(const GL::Texture* texture, const auto... args){ + World::vert_monochromeAll(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + }; + + struct OverlayPass{ + static constexpr auto batchPtr = &Core::BatchGroup::overlay; + + static constexpr int size = GL::VERT_LENGTH_OVERLAY; + + inline static float vertices[size]{}; + + static Core::Batch& getBatch(); + + static void vert(const GL::Texture* texture, const auto... args){ + Overlay::vert(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + + static void vert_monochromeMix(const GL::Texture* texture, const auto... args){ + Overlay::vert_monochromeMix(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + + static void vert_monochromeAll(const GL::Texture* texture, const auto... args){ + Overlay::vert_monochromeAll(vertices, args...); + getBatch().post(texture, vertices, 0, size); + } + }; +} + + +template <> +struct Graphic::Vertex::VertexPasser<&Core::BatchGroup::world> : Graphic::Vertex::WorldPass{}; + +template <> +struct Graphic::Vertex::VertexPasser<&Core::BatchGroup::overlay> : Graphic::Vertex::OverlayPass{}; diff --git a/src/arc/graphic/fx/Effect.cppm b/src/arc/graphic/fx/Effect.cppm index dcb091e0..09fb40c2 100644 --- a/src/arc/graphic/fx/Effect.cppm +++ b/src/arc/graphic/fx/Effect.cppm @@ -143,7 +143,7 @@ export namespace Graphic{ Math::Timed progress{}; - float zOffset{3}; + float zLayer{3}; Geom::Transform trans{}; HandleType handle{}; diff --git a/src/arc/graphic/fx/EffectManager.cppm b/src/arc/graphic/fx/EffectManager.cppm index 419ff8af..0ed963d7 100644 --- a/src/arc/graphic/fx/EffectManager.cppm +++ b/src/arc/graphic/fx/EffectManager.cppm @@ -23,23 +23,26 @@ export namespace Graphic{ std::vector toRemove{}; std::stack waiting{}; - std::mutex suspendLock{}; + std::shared_mutex effectMtx{}; public: void update(const float delta){ toRemove.clear(); + //TODO parallar update support + //TODO uses map + itr in toRemove for(auto& effect : activatedEffects){ - if(effect->update(delta)){ + if(std::shared_lock guard{effectMtx}; effect->update(delta)){ toRemove.push_back(effect.get()); } } - for(const auto& effect : toRemove){ - if(const auto& itr = activatedEffects.extract(effect)){ - waiting.push(std::move(itr.value())); + if(!toRemove.empty()) + for(std::unique_lock guard{effectMtx}; const auto effect : toRemove){ + if(const auto& itr = activatedEffects.extract(effect)){ + waiting.push(std::move(itr.value())); + } } - } } [[nodiscard]] Effect* suspend(){ @@ -47,7 +50,7 @@ export namespace Graphic{ { PoolType::UniquePtr ptr; - std::scoped_lock gurad{suspendLock}; + std::unique_lock guard{effectMtx}; if(waiting.empty()){ ptr = effectPool.obtainUnique(); }else{ diff --git a/src/arc/graphic/gl/GL.cppm b/src/arc/graphic/gl/GL.cppm index f4f26e3d..75752146 100644 --- a/src/arc/graphic/gl/GL.cppm +++ b/src/arc/graphic/gl/GL.cppm @@ -358,5 +358,25 @@ export namespace GL { auto getCurFrameBuffer_Read(){ return currentReadFrameBufferID; } + + template + struct StateGurad{ + template + requires std::is_enum_v && std::same_as, GLenum> + [[nodiscard]] StateGurad(decltype(T)){ + enable(state); + } + + [[nodiscard]] StateGurad(){ + enable(state); + } + + ~StateGurad(){ + disable(state); + } + }; + + template + StateGurad(decltype(T)) -> StateGurad>(T)>; } diff --git a/src/arc/math/geom/Vector2D.cppm b/src/arc/math/geom/Vector2D.cppm index 050c66ff..ab1e3988 100644 --- a/src/arc/math/geom/Vector2D.cppm +++ b/src/arc/math/geom/Vector2D.cppm @@ -132,10 +132,12 @@ export namespace Geom{ return obj.hash_value(); } - constexpr std::size_t hash_value() const requires requires{sizeof(T) <= 4;}{ + constexpr std::size_t hash_value() const requires requires{sizeof(T) == 4;}{ + constexpr std::hash hasher{}; const std::size_t l = std::bit_cast(x); const std::size_t r = std::bit_cast(y); - return l << 32 | r; + const std::size_t raw = l << 32 | r; + return raw; } constexpr Vector2D& set(const T ox, const T oy) noexcept { @@ -739,7 +741,7 @@ export template<> struct std::hash{ size_t operator()(const Geom::Vec2& v) const noexcept { - return *reinterpret_cast(&v); + return v.hash_value(); } }; @@ -747,7 +749,7 @@ export template<> struct std::hash{ size_t operator()(const Geom::Point2& v) const noexcept { - return *reinterpret_cast(&v); + return v.hash_value(); } }; @@ -755,7 +757,7 @@ export template<> struct std::hash{ size_t operator()(const Geom::Point2U& v) const noexcept { - return *reinterpret_cast(&v); + return v.hash_value(); } }; diff --git a/src/arc/math/geom/shape/Rect_Orthogonal.cppm b/src/arc/math/geom/shape/Rect_Orthogonal.cppm index 6918c80d..759e2cad 100644 --- a/src/arc/math/geom/shape/Rect_Orthogonal.cppm +++ b/src/arc/math/geom/shape/Rect_Orthogonal.cppm @@ -37,6 +37,11 @@ export namespace Geom{ this->setSize(width, height); } + constexpr Rect_Orthogonal(const typename Vector2D::PassType center, const T size) noexcept{ + this->setSize(size, size); + this->setCenter(center.x, center.y); + } + constexpr explicit Rect_Orthogonal(const T size) noexcept{ this->setSize(size, size); } @@ -583,6 +588,14 @@ export namespace Geom{ } } + void each_jumpSrc(Concepts::Invokable)> auto&& pred) const requires std::is_integral_v{ + for(T x = srcX; x < getEndX(); ++x){ + for(T y = srcY; y < getEndY(); ++y){ + if(x != srcX && y != srcY)pred(Vector2D{x, y}); + } + } + } + struct iterator{ Vector2D cur{}; T srcX{}; diff --git a/src/arc/os/control/CtrlConstants.cppm b/src/arc/os/control/CtrlConstants.cppm index 3732dc5b..4cd2085d 100644 --- a/src/arc/os/control/CtrlConstants.cppm +++ b/src/arc/os/control/CtrlConstants.cppm @@ -48,7 +48,7 @@ export namespace Ctrl{ } [[nodiscard]] constexpr bool modeMatch(const int mode, const int expectedMode) noexcept{ - return (mode & Mask) == (expectedMode & Mask); + return (mode & Mask) == (expectedMode & Mask) || expectedMode == Ignore; } } diff --git a/src/arc/ui/GlyphArrangement.cppm b/src/arc/ui/GlyphArrangement.cppm index b8b7b210..493cb164 100644 --- a/src/arc/ui/GlyphArrangement.cppm +++ b/src/arc/ui/GlyphArrangement.cppm @@ -291,7 +291,7 @@ export namespace Font { void set(const FontFlags* const currentFont) { this->currentFont = currentFont; - lineSpacing = currentFont->data->lineSpacingMin * 1.8f; + lineSpacing = currentFont->data->lineSpacingDef * 1.8f; paragraphSpacing = lineSpacing * 1.1f; } diff --git a/src/arc/ui/components/Cursor.cppm b/src/arc/ui/components/Cursor.cppm index 4093db99..c5523314 100644 --- a/src/arc/ui/components/Cursor.cppm +++ b/src/arc/ui/components/Cursor.cppm @@ -7,8 +7,6 @@ import GL.Texture.TextureRegionRect; import std; -using namespace Graphic; - export namespace UI{ struct CursorThoroughSightDrawer : CursorAdditionalDrawer { float stroke{4}; @@ -20,13 +18,14 @@ export namespace UI{ } void operator()(const float x, const float y, const float w, const float h) override{ - Draw::Line::setLineStroke(h * 2); - Draw::Line::line(-1, y, x - w * margin, y); - Draw::Line::line(x + w * margin, y, 1, y); + using namespace Graphic; + Draw::Overlay::Line::setLineStroke(h * 2); + Draw::Overlay::Line::line(-1, y, x - w * margin, y); + Draw::Overlay::Line::line(x + w * margin, y, 1, y); - Draw::Line::setLineStroke(w * 2); - Draw::Line::line(x, -1, x, y - margin * h); - Draw::Line::line(x, y + margin * h, x, 1); + Draw::Overlay::Line::setLineStroke(w * 2); + Draw::Overlay::Line::line(x, -1, x, y - margin * h); + Draw::Overlay::Line::line(x, y + margin * h, x, 1); } }; @@ -56,7 +55,7 @@ export namespace UI{ if(drawer){ drawer->operator()(drawX, drawY, norX, norY); } - Draw::rectOrtho( + Graphic::Draw::Overlay::Fill::rectOrtho( image, drawX - width / 2, drawY - height / 2, width, height ); diff --git a/src/arc/ui/elements/Screen.cppm b/src/arc/ui/elements/Screen.cppm index 0eae5840..739ecb58 100644 --- a/src/arc/ui/elements/Screen.cppm +++ b/src/arc/ui/elements/Screen.cppm @@ -24,6 +24,7 @@ export namespace UI{ void endDraw_noContextFallback() const; public: + int requiredMode = Ctrl::Mode::Ignore; bool focusWhenInbound{true}; /** @brief Whether adapt ui bloom effect*/ bool usesUIEffect{true}; @@ -34,30 +35,30 @@ export namespace UI{ } [[nodiscard]] Screen(){ - inputListener.on([this](const auto&) { + inputListener.on([this](const auto&) { if(focusWhenInbound)endCameraFocus(); }); - inputListener.on([this](const auto&) { + inputListener.on([this](const auto&) { if(focusWhenInbound)beginCameraFocus(); }); - inputListener.on([this](const UI::MouseActionDoubleClick& event) { + inputListener.on([this](const MouseActionDoubleClick& event) { if(event.key == Ctrl::Mouse::LMB){ camera.setPosition(camera.getMouseToWorld(Geom::Vector2D(event), absoluteSrc)); } }); - inputListener.on([this](const UI::MouseActionRelease& event) { + inputListener.on([this](const MouseActionRelease& event) { if(event.key == Ctrl::Mouse::CMB){ lastPos.setNaN(); } }); - inputListener.on([this](const UI::MouseActionDrag& event) { + inputListener.on([this](const MouseActionDrag& event) { if(event.key == Ctrl::Mouse::CMB){ - if(event.mode == Ctrl::Mode::Shift){ + if(Ctrl::Mode::modeMatch(event.mode, requiredMode)){ if(lastPos.isNaN()){ lastPos.set(camera.getPosition()); }else{ diff --git a/src/arc/util/Guard.cppm b/src/arc/util/Guard.cppm index d7cab425..9186eb9f 100644 --- a/src/arc/util/Guard.cppm +++ b/src/arc/util/Guard.cppm @@ -17,7 +17,7 @@ export namespace ext{ T& tgt; DataType original{}; public: - [[nodiscard]] constexpr Guard(T& tgt, DataType& data) requires (!passByMove) : tgt{tgt}, original{std::invoke(mem, tgt)}{ + [[nodiscard]] constexpr Guard(T& tgt, const DataType& data) requires (!passByMove) : tgt{tgt}, original{std::invoke(mem, tgt)}{ std::invoke(mem, tgt) = data; } @@ -33,4 +33,32 @@ export namespace ext{ } } }; + + template + requires requires{ + requires + (passByMove && std::is_move_assignable_v) || + (!passByMove && std::is_copy_assignable_v); + } + class GuardRef{ + T& tgt; + T original; + + public: + [[nodiscard]] constexpr GuardRef(T& tgt, const T& data) requires (!passByMove) : tgt{tgt}, original{tgt}{ + this->tgt = data; + } + + [[nodiscard]] constexpr GuardRef(T& tgt, T&& data) requires (passByMove) : tgt{tgt}, original{std::move(tgt)}{ + this->tgt = std::move(data); + } + + constexpr ~GuardRef(){ + if constexpr (passByMove){ + tgt = std::move(original); + }else{ + tgt = original; + } + } + }; } diff --git a/src/arc/util/container/ObjectPool.cppm b/src/arc/util/container/ObjectPool.cppm index f56a92a4..50cb5b7d 100644 --- a/src/arc/util/container/ObjectPool.cppm +++ b/src/arc/util/container/ObjectPool.cppm @@ -129,12 +129,14 @@ export namespace ext{ } void store(std::unique_ptr&& ptr){ + ptr.get()->~T(); this->store(ptr.release()); } - void store(T* ptr) { + void store(ext::Owner ptr) { + ptr->~T(); + if(std::lock_guard guard{vaultLock}; vault.size() < maxSize){ - ptr->~T(); vault.push_back(ptr); return; } diff --git a/src/code-gen/SpecIO.cppm b/src/code-gen/SpecIO.cppm index bf09bca5..59b99da0 100644 --- a/src/code-gen/SpecIO.cppm +++ b/src/code-gen/SpecIO.cppm @@ -11,8 +11,8 @@ export import Game.Chamber.Frame; export template <> -struct ::Core::IO::JsonSerializator> : Game::ChamberFrame::JsonSrl{}; +struct ::Core::IO::JsonSerializator> : Game::ChamberGrid::JsonSrl{}; export template <> diff --git a/src/game-impl/TurretEntity.cpp b/src/game-impl/TurretEntity.cpp index 20ba1e0c..4d0d3d2a 100644 --- a/src/game-impl/TurretEntity.cpp +++ b/src/game-impl/TurretEntity.cpp @@ -4,5 +4,5 @@ import Graphic.Draw; void Game::TurretTrait::drawDebug(const TurretEntity* turret) const{ if(turret->shouldShoot()) - Graphic::Draw::Line::line(turret->trans.vec, turret->getTargetPos(), Graphic::Colors::PALE_GREEN.copy().setA(0.5f), Graphic::Colors::LIGHT_GRAY.copy().setA(0.5f)); + Graphic::Draw::Overlay::Line::line(turret->trans.vec, turret->getTargetPos(), Graphic::Colors::PALE_GREEN.copy().setA(0.5f), Graphic::Colors::LIGHT_GRAY.copy().setA(0.5f)); } \ No newline at end of file diff --git a/src/game/chamber/Chamber.cppm b/src/game/chamber/Chamber.cppm index dffcf1f0..07467f97 100644 --- a/src/game/chamber/Chamber.cppm +++ b/src/game/chamber/Chamber.cppm @@ -2,6 +2,7 @@ // Created by Matrix on 2024/4/18. // +// ReSharper disable CppDFAUnreachableCode export module Game.Chamber; export import Geom.Rect_Orthogonal; @@ -31,28 +32,31 @@ namespace Game{ export namespace Game{ constexpr float TileSize = 8.0f; + struct ChamberBase{ + Geom::OrthoRectInt gridBound{}; + unsigned id{}; + + [[nodiscard]] constexpr OrthoRectFloat getEntityBound() const noexcept{ + return gridBound.as().scl(TileSize, TileSize); + } + }; + template struct ChamberTile; template - struct Chamber : Core::IO::DynamicJsonSerializable{ + struct Chamber : ChamberBase, Core::IO::DynamicJsonSerializable{ using EntityType = Entity; - Geom::OrthoRectInt region{}; - unsigned id{}; std::vector proximity{}; - OrthoRectFloat getChamberBound() const{ - return region.as().scl(TileSize, TileSize); - } - void writeTo(ext::json::JsonValue& jval) const override{ writeType(jval); - jval.append(ChamberRegionFieldName, ext::json::getJsonOf(region)); + jval.append(ChamberRegionFieldName, ext::json::getJsonOf(gridBound)); } void readFrom(const ext::json::JsonValue& jval) override{ - ext::json::getValueTo(region, jval.asObject().at(ChamberRegionFieldName)); + ext::json::getValueTo(gridBound, jval.asObject().at(ChamberRegionFieldName)); } virtual ext::Owner copy(){ //TODO temp test impl, garbage @@ -85,106 +89,47 @@ export namespace Game{ template struct ChamberTile{ + // using EntityType = int; + using EntityType = Entity; Point2 pos{}; - /** Usage for multi tile*/ - ChamberTile* referenceTile{nullptr}; - - std::unique_ptr> chamber{}; - - [[nodiscard]] ChamberTile() = default; - - [[nodiscard]] explicit ChamberTile(const Point2& pos) - : pos{pos}{} - - [[nodiscard]] ChamberTile(const Point2& pos, ChamberTile* referenceTile) - : pos{pos}, - referenceTile{referenceTile}{} - - [[nodiscard]] ChamberTile(const Point2& pos, ChamberTile* referenceTile, - const std::unique_ptr>& chamber) - : pos{pos}, - referenceTile{referenceTile}, - chamber{chamber}{} - ChamberTile(const ChamberTile& other) - : pos{other.pos}, - chamber{std::unique_ptr>{other.chamber ? other.chamber->copy() : nullptr}}{} + std::shared_ptr> chamber{}; - ChamberTile& operator=(const ChamberTile& other){ - if(this == &other) return *this; - pos = other.pos; - chamber.reset(other.chamber->copy()); - return *this; + [[nodiscard]] bool valid() const noexcept{ + return chamber != nullptr; } - ChamberTile(ChamberTile&& other) noexcept - : pos{std::move(other.pos)}, - referenceTile{other.referenceTile}, - chamber{std::move(other.chamber)}{} - - ChamberTile& operator=(ChamberTile&& other) noexcept{ - if(this == &other) return *this; - pos = std::move(other.pos); - referenceTile = other.referenceTile; - chamber = std::move(other.chamber); - return *this; - } - - [[nodiscard]] bool valid() const { - //Not chain query, only one-depth reference is allowed - return ownsChamber() || (referenceTile && referenceTile->ownsChamber()); + [[nodiscard]] explicit operator bool() const noexcept{ + return valid(); } /** * @return Whether this tile works by its reference tile */ [[nodiscard]] bool refOnly() const { - //Not chain query, only one-depth reference is allowed - return !ownsChamber() && referenceTile && referenceTile->ownsChamber(); + return valid() && chamber->gridBound.getSrc() != pos; } - [[nodiscard]] bool ownsChamber() const{ - return !referenceTile && static_cast(chamber); + [[nodiscard]] bool isOwner() const { + return valid() && chamber->gridBound.getSrc() == pos; } - [[nodiscard]] bool isSubTile() const{ - return static_cast(referenceTile); - } + // void init() const{ + // if(!isOwner()) return; + // // chamber->init(this); + // } - template DrawPred = std::nullptr_t> - void draw(DrawPred&& fallbackDrawer = nullptr) const{ - if(!ownsChamber()){ - if constexpr(!std::same_as){ - fallbackDrawer(*this); - } - - return; + [[nodiscard]] Geom::Point2 getOffsetToRef() const noexcept{ + if(refOnly()){ + return pos - chamber->gridBound.getSrc(); } - chamber->draw(); - } - void init() const{ - if(!ownsChamber()) return; - chamber->init(this); - } - - void setReference(ChamberTile& referenceTile){ - if(ownsChamber() || !referenceTile.ownsChamber() || !referenceTile.chamber->region.containsPos_edgeInclusive(pos)){ - throw ext::IllegalArguments{std::format("Wrongly Set a refernece tile")}; - } - - this->referenceTile = &referenceTile; - chamber.reset(); - } - - void setReference(std::nullptr_t) noexcept{ - this->referenceTile = nullptr; - chamber.reset(); + return {}; } - [[nodiscard]] Geom::Point2 getOffsetToRef() const { - if(isSubTile()){ - return pos - referenceTile->pos; + [[nodiscard]] Geom::Point2 getPosOfRef() const noexcept{ + if(refOnly()){ + return chamber->gridBound.getSrc(); } return {}; @@ -194,12 +139,12 @@ export namespace Game{ return Geom::OrthoRectFloat{TileSize * pos.x, TileSize * pos.y, TileSize, TileSize}; } - [[nodiscard]] Geom::OrthoRectInt getChamberRegion() const noexcept{ - return ownsChamber() ? chamber->region : Geom::OrthoRectInt{pos.x, pos.y, 1, 1}; + [[nodiscard]] Geom::OrthoRectInt getChamberGridBound() const noexcept{ + return valid() ? chamber->gridBound : Geom::OrthoRectInt{pos.x, pos.y, 1, 1}; } - [[nodiscard]] Geom::OrthoRectFloat getChamberRealRegion() const noexcept{ - return ownsChamber() ? chamber->getChamberBound() : getTileBound(); + [[nodiscard]] Geom::OrthoRectFloat getChamberRegion() const noexcept{ + return valid() ? chamber->getEntityBound() : getTileBound(); } friend bool operator==(const ChamberTile& lhs, const ChamberTile& rhs) noexcept { return lhs.pos == rhs.pos; } @@ -287,7 +232,7 @@ export namespace Game{ tile.pos = region.getSrc(); if(tile.chamber){ - tile.chamber->region = region; + tile.chamber->gridBound = region; }else{ if(region.area() != 1){ throw ext::IllegalArguments{"Emply Tile Should Always Have Area of 1!"}; @@ -356,7 +301,7 @@ export namespace Game{ static void write(ext::json::JsonValue& jval, const Game::ChamberTile& data){ ext::json::append(jval, ext::json::keys::Pos, data.pos); - if(data.ownsChamber()){ + if(data.isOwner()){ ext::json::JsonValue chamberJval{}; chamberJval.asObject(); data.chamber->writeType(chamberJval); @@ -379,9 +324,9 @@ export namespace Game{ data.chamber = mockFactory.genChamber(); if(chamberJval.asObject().contains(Game::ChamberRegionFieldName)){ - ext::json::getValueTo(data.chamber->region, chamberJval.asObject().at(Game::ChamberRegionFieldName)); + ext::json::getValueTo(data.chamber->gridBound, chamberJval.asObject().at(Game::ChamberRegionFieldName)); }else{ - data.chamber->region.setSrc(data.pos); + data.chamber->gridBound.setSrc(data.pos); } } diff --git a/src/game/chamber/ChamberFrame.cppm b/src/game/chamber/ChamberGrid.cppm similarity index 69% rename from src/game/chamber/ChamberFrame.cppm rename to src/game/chamber/ChamberGrid.cppm index 9a44e3a5..0d9a8fc9 100644 --- a/src/game/chamber/ChamberFrame.cppm +++ b/src/game/chamber/ChamberGrid.cppm @@ -17,10 +17,10 @@ namespace Game{ [[nodiscard]] Geom::Point2 toChamberPos(Geom::Vec2 pos) noexcept{ return pos.div(TileSize).trac(); } - +// using Entity = int; export template - class ChamberFrameData{ + class ChamberGridData{ public: // using Entity = Geom::Vec2; using EntityType = Entity; @@ -51,52 +51,74 @@ namespace Game{ protected: [[nodiscard]] static Geom::OrthoRectFloat getBoundOf(const ChamberTile& ChamberTile){ - return ChamberTile.getChamberRealRegion(); + return ChamberTile.getChamberRegion(); } Geom::OrthoRectFloat bound{}; std::list data{}; + std::unordered_map positionRef{}; //TODO Is all these worth it to sustain this vector? //Maybe directly uses umap is a better choise - void eraseRef(const Geom::Point2 pos){ + + void eraseData(const Geom::Point2 pos){ if(const auto itr = positionRef.find(pos); itr != positionRef.end()){ + data.erase(itr->second); positionRef.erase(itr); } } - std::unordered_map positionRef{}; + void buildRef(){ + for(auto cur = data.begin(); cur != data.end(); ++cur){ + positionRef.try_emplace(cur->pos, cur); + } + } - bool shouldInsert(const Tile& tile) const { - if(const auto finded = find(tile.pos)){ - if(!tile.ownsChamber())return false; + bool checkOverlap(const Tile& tile) const { + if(const auto finded = this->find(tile.pos)){ + //Invalid tile should not replace the valid one + if(!tile.isOwner())return false; + //Valid tile can replace the invalid one if(!finded->valid()){ return true; } + //Place valid to valid should pop a exception throw ext::IllegalArguments{"Insertion Failed: Cannot Insert Two Valid Tile in the same pos!"}; } return true; } - void updateReference(){ - for(Tile& tile : data | std::ranges::views::filter(&Tile::ownsChamber)){ - tile.getChamberRegion().each([this, &tile](const Geom::Point2 pos){ - if(const auto itr = positionRef.find(pos); itr != positionRef.end()){ - itr->second->referenceTile = &tile; - } - }); - } + void appendBack(const Tile& tile){ + data.push_back(tile); + positionRef.insert_or_assign(tile.pos, std::prev(data.end())); } - void padReference(Tile& src){ - if(src.getChamberRegion().area() <= 1)return; - - src.getChamberRegion().each([this, &src](const Geom::Point2 pos){ - if(pos == src.pos)return; + void insertOrAssign(const Tile& tile){ + auto itr = findItrByPos(tile.pos); + if(itr != data.end()){ + itr->chamber = tile.chamber; + }else{ + this->appendBack(tile); + } + } + /** + * @brief Should always be state like this after pad: + * [..., owner, ref[1], ref[2], ..., ref[owner.area() - 1], ...] + * So owner should be the first of it's ref tiles + * + * @warning Notice that only owners should run this function + * + * @return true if src is owner and insert happens + */ + bool ownerInsert(const Tile& src){ + if(!src.isOwner())return false; + //Clear the original tiles in the bound + src.getChamberGridBound().each([this](const Geom::Point2 pos){ +#if DEBUG_CHECK const Tile* tile{nullptr}; auto itr = findItrByPos(pos); @@ -108,17 +130,21 @@ namespace Game{ } erase(pos); } +#else + erase(pos); +#endif }); - src.getChamberRegion().each([this, &src](const Geom::Point2 pos){ - if(pos == src.pos)return; - - this->insert(Tile{pos, &src}); + //Insert new tiles + src.getChamberGridBound().each([this, chamber = src.chamber](const Geom::Point2 pos){ + this->appendBack(Tile{pos, chamber}); }); + + return true; } - auto findItrByPos(const Geom::Point2 pos){ - auto itr = positionRef.find(pos); + ItrType findItrByPos(const Geom::Point2 pos){ + const auto itr = positionRef.find(pos); if(itr == positionRef.end()){ return std::ranges::find(data, pos, &Tile::pos); @@ -127,28 +153,34 @@ namespace Game{ } } public: - [[nodiscard]] ChamberFrameData() = default; + [[nodiscard]] ChamberGridData() = default; - ChamberFrameData(const ChamberFrameData& other){ - this->build(std::list{other.data} | std::ranges::views::filter(std::not_fn(&Tile::refOnly))); - } - ChamberFrameData(ChamberFrameData&& other) noexcept - : bound{std::move(other.bound)}, - data{std::move(other.data)}, - positionRef{std::move(other.positionRef)}{} + ChamberGridData(ChamberGridData&& other) noexcept + : bound{other.bound}, data{std::move(other.data)}{ + buildRef(); + } - ChamberFrameData& operator=(const ChamberFrameData& other){ + ChamberGridData& operator=(ChamberGridData&& other) noexcept{ if(this == &other) return *this; - this->build(std::list{other.data} | std::ranges::views::filter(std::not_fn(&Tile::refOnly))); + data = std::move(other.data); + bound = other.bound; + + buildRef(); return *this; } - ChamberFrameData& operator=(ChamberFrameData&& other) noexcept{ + ChamberGridData(const ChamberGridData& other) : bound{other.bound}, data{other.data}{ + buildRef(); + } + + ChamberGridData& operator=(const ChamberGridData& other){ if(this == &other) return *this; - bound = std::move(other.bound); - data = std::move(other.data); - positionRef = std::move(other.positionRef); + data = other.data; + bound = other.bound; + + buildRef(); + return *this; } @@ -156,7 +188,7 @@ namespace Game{ if(brief.dataValid)return; for (auto& chamberTile : data){ - if(chamberTile.ownsChamber()){ + if(chamberTile.isOwner()){ brief.owners.push_back(chamberTile.chamber.get()); } @@ -216,16 +248,14 @@ namespace Game{ [[nodiscard]] Chamber* findChamber(const Geom::Point2 pos){ if(const auto itr = positionRef.find(pos); itr != positionRef.end()){ - if(itr->second->ownsChamber())return itr->second->chamber.get(); - if(itr->second->referenceTile)return itr->second->referenceTile->chamber.get(); + return itr->second->chamber.get(); } return nullptr; } [[nodiscard]] const Chamber* findChamber(const Geom::Point2 pos) const{ if(const auto itr = positionRef.find(pos); itr != positionRef.end()){ - if(itr->second->ownsChamber())return itr->second->chamber.get(); - if(itr->second->referenceTile)return itr->second->referenceTile->chamber.get(); + return itr->second->chamber.get(); } return nullptr; } @@ -237,14 +267,11 @@ namespace Game{ void erase(const Geom::Point2 chamberPos, const bool setToInvalid = false){ resetBrief(); - //TODO optm this - auto itr = findItrByPos(chamberPos); - - if(itr != data.end()){ + if(auto itr = findItrByPos(chamberPos); itr != data.end()){ const Tile* chamber = itr.operator->(); - if(chamber->refOnly()){ - itr = findItrByPos(chamber->referenceTile->pos); + if(chamber->valid()){ + itr = this->findItrByPos(chamber->getPosOfRef()); if(itr == data.end()){ throw ext::IllegalArguments{"Failed to find ref tile!"}; } @@ -252,19 +279,18 @@ namespace Game{ chamber = itr.operator->(); } - const typename decltype(data)::iterator begin = itr; auto end = begin; - std::advance(end, chamber->getChamberRegion().area()); + + std::advance(end, chamber->getChamberGridBound().area()); if(setToInvalid){ - for(auto& element : std::ranges::subrange{begin, end}){ - element.setReference(nullptr); - element.chamber.reset(); + for(auto& [pos, chamberPtr] : std::ranges::subrange{begin, end}){ + chamberPtr.reset(); } }else{ - chamber->getChamberRegion().each([this](const Geom::Point2 subPos){ - eraseRef(subPos); + chamber->getChamberGridBound().each([this](const Geom::Point2 subPos){ + positionRef.erase(subPos); }); data.erase(begin, end); @@ -276,18 +302,18 @@ namespace Game{ * @brief * @param tile Tile to insert */ - void insert(Tile&& tile){ - if(!this->shouldInsert(tile))return; + void insert(const Tile& tile){ + if(!this->checkOverlap(tile))return; resetBrief(); + bound.expandBy(this->getBoundOf(tile)); - tile.init(); - this->erase(tile.pos); - data.push_back(std::move(tile)); - const auto& itr = std::prev(data.end()); + if(this->ownerInsert(tile))return; - positionRef.insert_or_assign(itr->pos, ItrType{itr}); - this->padReference(itr.operator*()); + auto itr = this->findItrByPos(tile.pos); + + this->erase(tile.pos); + this->appendBack(tile); } void erase(const Tile* val){ @@ -296,30 +322,20 @@ namespace Game{ template Range> void build(Range&& input){ + if(std::ranges::empty(input))return; + + resetBrief(); + + const Tile& front = std::ranges::begin(input).operator*(); positionRef.clear(); data.clear(); //TODO better bound allocation if the origin point of tilemap doesn't begin at (0, 0) [esp > (0, 0)] - bound.set(0, 0, 0, 0); + bound = getBoundOf(front); for(Tile& tile : input){ - if(!shouldInsert(tile))continue; - erase(tile.pos); - data.push_back(std::forward>(tile)); - positionRef.insert_or_assign(tile.pos, std::prev(data.end())); - - Tile& t = data.back(); - t.init(); - t.getChamberRegion().each([this, &t](const Geom::Point2 pos){ - if(pos == t.pos)return; - - erase(pos); - data.emplace_back(pos, &t); - positionRef.insert_or_assign(pos, std::prev(data.end())); - }); + insertOrAssign(tile); } - - reMap(true); } void resizeBound(){ @@ -392,7 +408,7 @@ namespace Game{ static constexpr std::string_view InvalidTiles = "it"; static constexpr std::string_view OwnerTiles = "ot"; - static void write(ext::json::JsonValue& jsonValue, const ChamberFrameData& data){ + static void write(ext::json::JsonValue& jsonValue, const ChamberGridData& data){ auto& map = jsonValue.asObject(); ext::json::JsonValue owners{}; @@ -404,7 +420,7 @@ namespace Game{ invalidsArray.reserve(data.getData().size() / 2); for(const auto& chamberTile : data.getData()){ - if(chamberTile.ownsChamber()){ + if(chamberTile.isOwner()){ ownersArray.push_back(ext::json::getJsonOf(chamberTile)); continue; } @@ -418,7 +434,7 @@ namespace Game{ map.insert_or_assign(InvalidTiles, std::move(invalids)); } - static void read(const ext::json::JsonValue& jsonValue, ChamberFrameData& data){ + static void read(const ext::json::JsonValue& jsonValue, ChamberGridData& data){ auto& map = jsonValue.asObject(); auto& owners = map.at(OwnerTiles).asArray(); @@ -442,26 +458,23 @@ namespace Game{ */ export template - class ChamberFrame : public ChamberFrameData{ + class ChamberGrid : public ChamberGridData{ public: - using ChamberFrameData::ChamberFrameData; - using typename ChamberFrameData::Tile; - using typename ChamberFrameData::EntityType; - using ChamberFrameData::positionRef; - using ChamberFrameData::data; - using ChamberFrameData::bound; + using ChamberGridData::ChamberGridData; + using typename ChamberGridData::Tile; + using typename ChamberGridData::EntityType; + using ChamberGridData::positionRef; + using ChamberGridData::data; + using ChamberGridData::bound; - using TreeType = Geom::QuadTree; + using TreeType = Geom::QuadTree; protected: - using ChamberFrameData::eraseRef; - using ChamberFrameData::padReference; - using ChamberFrameData::shouldInsert; TreeType quadTree{5}; public: - ChamberFrame(){ + ChamberGrid(){ quadTree.setStrict(false); } @@ -473,28 +486,27 @@ namespace Game{ * @param tile Tile to insert * @param noTreeInsertion whether to insert tile to the quad tree now, used for IO and editor when quad tree is not needed */ - void insert(Tile&& tile, const bool noTreeInsertion = false){ - ChamberFrameData::insert(std::move(tile)); + void insert(const Tile& tile, const bool noTreeInsertion = false){ + auto cur = data.end(); - auto& val = data.back(); - if(!noTreeInsertion)tryInsertTree(val, true); + ChamberGridData::insert(tile); + + if(!noTreeInsertion)for(auto& val : data + | std::ranges::views::reverse + | std::ranges::views::take(tile.getChamberGridBound().area())){ + this->tryInsertTree(val, true); + } } template Range> void build(Range&& input){ quadTree.clear(); - this->resetBrief(); - ChamberFrameData::build(std::move(input)); + ChamberGridData::build(std::move(input)); reTree(); } - void reMap(const bool resizeBound = false){ - quadTree.clearItemsOnly(); - ChamberFrameData::reMap(resizeBound); - } - void reTree(){ quadTree.clearItemsOnly(); quadTree.setBoundary(bound); diff --git a/src/game/chamber/ChamberFrameTrans.cppm b/src/game/chamber/ChamberGridTrans.cppm similarity index 94% rename from src/game/chamber/ChamberFrameTrans.cppm rename to src/game/chamber/ChamberGridTrans.cppm index 00aba4b5..0a1cd170 100644 --- a/src/game/chamber/ChamberFrameTrans.cppm +++ b/src/game/chamber/ChamberGridTrans.cppm @@ -20,13 +20,15 @@ export namespace Game{ * @brief This frame should be workable on a async thread */ //TODO using template maybe, to support different types + + // using Entity = int; template - class ChamberFrameTrans{ + class ChamberGridTrans{ static constexpr float ExtendSize{100}; - using FrameType = ChamberFrame; + using FrameType = ChamberGrid; Geom::Transform localTrans{}; - ChamberFrame frameData{}; + ChamberGrid frameData{}; typename FrameType::TileBrief drawable{}; /** @brief Local draw usage*/ @@ -36,7 +38,7 @@ export namespace Game{ Geom::QuadBox lastViewport{}; public: - [[nodiscard]] ChamberFrameTrans() = default; + [[nodiscard]] ChamberGridTrans() = default; void updateChamberFrameData(){ frameBound = frameData.getBound(); @@ -93,7 +95,7 @@ export namespace Game{ frameData.getQuadTree().intersectRegion(lastViewport, [](const auto& rect, const auto& quad){ return quad.overlapRough(rect) && quad.overlapExact(rect); }, [this](const ChamberTile* tile, const Geom::QuadBox& view){ - if(tile->ownsChamber()){ + if(tile->isOwner()){ drawable.owners.push_back(tile->chamber.get()); } diff --git a/src/game/chamber/ChamberUtil.cppm b/src/game/chamber/ChamberUtil.cppm index 03595030..4f94afbf 100644 --- a/src/game/chamber/ChamberUtil.cppm +++ b/src/game/chamber/ChamberUtil.cppm @@ -36,7 +36,7 @@ export namespace Game::ChamberUtil{ constexpr ChamberColorRef placed = Colors::WHITE; template - [[nodiscard]] Graphic::Pixmap saveToPixmap(const ChamberFrame& frame){ + [[nodiscard]] Graphic::Pixmap saveToPixmap(const ChamberGrid& frame){ const Geom::OrthoRectInt bound = frame.getTiledBound(); Graphic::Pixmap map{bound.getWidth(), bound.getHeight()}; @@ -50,8 +50,8 @@ export namespace Game::ChamberUtil{ } template - [[nodiscard]] ChamberFrame genFrameFromPixmap(const Graphic::Pixmap& map, const Geom::Point2 offset = {}){ - ChamberFrame frame{}; + [[nodiscard]] ChamberGrid genFrameFromPixmap(const Graphic::Pixmap& map, const Geom::Point2 offset = {}){ + ChamberGrid frame{}; map.each([&frame, offset](const Graphic::Pixmap& pixmap, const int x, const int y){ const auto color = pixmap.get(x, y); diff --git a/src/game/content/drawer/DrawComponents.cppm b/src/game/content/drawer/DrawComponents.cppm index 6b2eec05..8b853bf8 100644 --- a/src/game/content/drawer/DrawComponents.cppm +++ b/src/game/content/drawer/DrawComponents.cppm @@ -97,13 +97,14 @@ export namespace Game::Drawer{ void draw(const DrawParam& param, const T* entity) const override{ using namespace Graphic; + using Graphic::Draw::World; PartTrans cur = trans | param.trans; this->passTrans(param, cur); - Draw::color(lightColor); - Draw::setZ(cur.zOffset + entity->zLayer); - Draw::rect(mainRegion, cur, scl); + World::color(lightColor); + World::setZ(cur.zOffset + entity->zLayer); + World::Fill::rect(mainRegion, cur, scl); } }; diff --git a/src/game/content/types/bullet/BasicBulletType.cppm b/src/game/content/types/bullet/BasicBulletType.cppm index da09ec95..d42190bc 100644 --- a/src/game/content/types/bullet/BasicBulletType.cppm +++ b/src/game/content/types/bullet/BasicBulletType.cppm @@ -57,12 +57,9 @@ export namespace Game::Content{ using namespace Graphic; namespace Draw = Graphic::Draw; - [[maybe_unused]] ext::Guard tf - {Draw::globalState, Draw::globalState.defaultLightTexture}; bullet.trail.each(trailWidth, Graphic::Trail::DefDraw_WithLerp(trailBegin, trailEnd)); - - Draw::color(effectColor); - Game::Draw::hitbox(bullet.hitBox); + Draw::World::color(effectColor); + Game::Draw::hitbox(bullet.hitBox); } void despawn(Bullet& bullet) const override{ @@ -76,6 +73,7 @@ export namespace Game::Content{ } basicBulletType, basicBulletTypeSlow; } +//TODO remove this namespace _{ struct Temp{ [[nodiscard]] Temp(){ diff --git a/src/game/entity/types/space-craft/SpaceCraft.cppm b/src/game/entity/types/space-craft/SpaceCraft.cppm index 671d68ce..bf0a63c7 100644 --- a/src/game/entity/types/space-craft/SpaceCraft.cppm +++ b/src/game/entity/types/space-craft/SpaceCraft.cppm @@ -53,7 +53,7 @@ export namespace Game { class SpaceCraft : public RealityEntity{ public: Geom::Transform chamberTrans{}; - ChamberFrameTrans chambers{}; + ChamberGridTrans chambers{}; const SpaceCraftTrait* trait{nullptr}; @@ -265,6 +265,9 @@ export namespace Game { } void drawDebug() const override { + using namespace Graphic; + using Graphic::Draw::Overlay; + Game::Draw::chamberFrameTile(chambers); GL::setDepthMask(false); @@ -275,49 +278,49 @@ export namespace Game { // Graphic::Batch::flush(); GL::setDepthMask(true); - Graphic::Draw::alpha(); - Graphic::Draw::color(Graphic::Colors::RED); + Overlay::alpha(); + Overlay::color(Graphic::Colors::RED); for(const auto& data : intersectedPointWith | std::ranges::views::values) { - Graphic::Draw::rectOrtho(data.intersection.x - 2, data.intersection.y - 2, 4, 4); + Overlay::Fill::rectOrtho(data.intersection.x - 2, data.intersection.y - 2, 4, 4); } - Graphic::Draw::Line::setLineStroke(1.0f); - Graphic::Draw::color(Graphic::Colors::MAGENTA); - Graphic::Draw::Line::lineAngle(trans.vec.x, trans.vec.y, trans.rot, std::sqrt(hitBox.getAvgSizeSqr())); + Overlay::Line::setLineStroke(1.0f); + Overlay::color(Graphic::Colors::MAGENTA); + Overlay::Line::lineAngle(trans.vec.x, trans.vec.y, trans.rot, std::sqrt(hitBox.getAvgSizeSqr())); - Graphic::Draw::Line::setLineStroke(2.0f); + Overlay::Line::setLineStroke(2.0f); for (auto& boxData : hitBox.hitBoxGroup){ constexpr Graphic::Color colors[]{Graphic::Colors::ROYAL, Graphic::Colors::PINK, Graphic::Colors::GREEN, Graphic::Colors::PURPLE}; auto& cur = boxData.original; for(int i = 0; i < 4; ++i) { - Graphic::Draw::color(colors[i]); - Graphic::Draw::rectOrtho(cur[i].x - 2, cur[i].y - 2, 4, 4); + Overlay::color(colors[i]); + Overlay::Fill::rectOrtho(cur[i].x - 2, cur[i].y - 2, 4, 4); const Vec2 begin = cur[i]; const Vec2 end = cur[(i + 1) % 4]; const Vec2 center = (begin + end) / 2; - Graphic::Draw::Line::line(center, center + cur.getNormalVec(i).normalize().scl(25)); + Overlay::Line::line(center, center + cur.getNormalVec(i).normalize().scl(25)); } if(controller->selected) { - Graphic::Draw::color(Graphic::Colors::TAN); - }else Graphic::Draw::color(Graphic::Colors::LIGHT_GRAY); + Overlay::color(Graphic::Colors::TAN); + }else Overlay::color(Graphic::Colors::LIGHT_GRAY); - Graphic::Draw::Line::setLineStroke(2); - Graphic::Draw::Line::quad(cur); + Overlay::Line::setLineStroke(2); + Overlay::Line::quad(cur); - Graphic::Draw::Line::line(cur.v0, cur.originPoint, colors[0], Graphic::Colors::RED); + Overlay::Line::line(cur.v0, cur.originPoint, colors[0], Graphic::Colors::RED); - Graphic::Draw::color(Graphic::Colors::RED); - Graphic::Draw::rectOrtho(cur.originPoint.x - 2, cur.originPoint.y - 2, 4, 4); + Overlay::color(Graphic::Colors::RED); + Overlay::Fill::rectOrtho(cur.originPoint.x - 2, cur.originPoint.y - 2, 4, 4); } - Graphic::Draw::color(Graphic::Colors::PURPLE); - Graphic::Draw::rectOrtho(hitBox.trans.vec.x - 2, hitBox.trans.vec.y - 2, 4, 4); + Overlay::color(Graphic::Colors::PURPLE); + Overlay::Fill::rectOrtho(hitBox.trans.vec.x - 2, hitBox.trans.vec.y - 2, 4, 4); for(auto& turretEntity : turretEntities){ turretEntity->drawDebug(); diff --git a/src/game/graphic/GameDraw.cppm b/src/game/graphic/GameDraw.cppm index 0c8c3a6c..fc24955b 100644 --- a/src/game/graphic/GameDraw.cppm +++ b/src/game/graphic/GameDraw.cppm @@ -13,31 +13,35 @@ export import Graphic.Draw; export import GL.Shader.UniformWrapper; export import Assets.Graphic; +import ext.Guard; + namespace Game::Draw{ - namespace Draw = Graphic::Draw; namespace Colors = Graphic::Colors; + namespace Draw = Graphic::Draw; export - template Core::BatchGroup::* ptr = Graphic::BatchOverlay> void hitbox(const ::Game::HitBox& hitBox){ for(const auto& data : hitBox.hitBoxGroup){ - Graphic::Draw::quad(Graphic::Draw::getContextTexture(), - data.original.v0, data.original.v1, data.original.v2, data.original.v3); + Draw::World::Fill::quad(Draw::World::getContextTexture(), + data.original.v0, data.original.v1, data.original.v2, data.original.v3); } } export - template Core::BatchGroup::* ptr = Graphic::BatchOverlay> void hitbox(const ::Geom::QuadBox& hitBox){ - Graphic::Draw::quad(Graphic::Draw::getContextTexture(), + Draw::World::Fill::quad(Draw::World::getContextTexture(), hitBox.v0, hitBox.v1, hitBox.v2, hitBox.v3); } export template - void chamberFrameTile(const ChamberFrameTrans& chambers, Core::Renderer* renderer = Core::renderer, + void chamberFrameTile(const ChamberGridTrans& chambers, Core::Renderer* renderer = Core::renderer, const bool disableDrawLimit = false){ - [[maybe_unused]] auto guard = Draw::genColorGuard(); + using namespace Graphic; + using Draw::Overlay; + + [[maybe_unused]] ext::GuardRef guardRef1{Overlay::contextColor, Overlay::contextColor}; + [[maybe_unused]] ext::GuardRef guardRef2{Overlay::contextMixColor, Overlay::contextMixColor}; [[maybe_unused]] Core::BatchGuard_L2W batchGuard{*Core::batchGroup.overlay, chambers.getLocalToWorld()}; const float chamberTileAlpha = disableDrawLimit ? 1.0f : Math::curve(Core::camera->getScale(), 1.25f, 1.5f); @@ -45,10 +49,10 @@ namespace Game::Draw{ if(chamberTileAlpha > 0.0f){ if(renderer){ renderer->frameBegin(renderer->effectBuffer); - Draw::color(Colors::GRAY, chamberTileAlpha); + Overlay::color(Colors::GRAY, chamberTileAlpha); for(const auto* tile : chambers.getDrawable().invalids){ - Draw::rectOrtho(Draw::globalState.defaultTexture, tile->getTileBound()); + Overlay::Fill::rectOrtho(Overlay::defaultTexture, tile->getTileBound()); } [[maybe_unused]] GL::UniformGuard guard_outline @@ -60,21 +64,21 @@ namespace Game::Draw{ renderer->frameEnd(Assets::Shaders::outline_ortho); } - Draw::color(Colors::GRAY, 0.45f * chamberTileAlpha); - Draw::Line::setLineStroke(2.0f); + Overlay::color(Colors::GRAY, 0.45f * chamberTileAlpha); + Overlay::Line::setLineStroke(2.0f); for(const auto* tile : chambers.getDrawable().valids){ - Draw::Line::rectOrtho(tile->getTileBound()); + Overlay::Line::rectOrtho(tile->getTileBound()); } - Draw::color(Colors::LIGHT_GRAY, 0.85f * chamberTileAlpha); + Overlay::color(Colors::LIGHT_GRAY, 0.85f * chamberTileAlpha); for(const auto* tile : chambers.getDrawable().owners){ - Draw::Line::rectOrtho(tile->getChamberBound()); + Overlay::Line::rectOrtho(tile->getEntityBound()); } - Draw::color(Colors::WHITE, chamberTileAlpha); - Draw::mixColor(Colors::BLACK.createLerp(Colors::RED_DUSK, 0.3f)); + Overlay::color(Colors::WHITE, chamberTileAlpha); + Overlay::mixColor(Colors::BLACK.createLerp(Colors::RED_DUSK, 0.3f)); [[maybe_unused]] GL::UniformGuard guard_slideLine_1{ Assets::Shaders::slideLineShaderDrawArgs, 25.0f, 45.0f, Colors::CLEAR @@ -85,16 +89,19 @@ namespace Game::Draw{ for(const auto* tile : chambers.getDrawable().invalids){ - Draw::rectOrtho(Draw::getDefaultTexture(), tile->getTileBound()); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), tile->getTileBound()); } } } export template - void chamberFrame(const Entity& entity, const ChamberFrameTrans& chambers, + void chamberFrame(const Entity& entity, const ChamberGridTrans& chambers, Core::Renderer* renderer = Core::renderer){ - [[maybe_unused]] auto guard = Draw::genColorGuard(); + using Graphic::Draw::Overlay; + + [[maybe_unused]] ext::GuardRef guardRef1{Overlay::contextColor, Overlay::contextColor}; + [[maybe_unused]] ext::GuardRef guardRef2{Overlay::contextMixColor, Overlay::contextMixColor}; [[maybe_unused]] Core::BatchGuard_L2W batchGuard{*Core::batchGroup.world, chambers.getLocalToWorld()}; for(const auto* tile : chambers.getDrawable().owners){ diff --git a/src/game/ui/HitBoxEditor.cppm b/src/game/ui/HitBoxEditor.cppm index 1b19626c..f47aaf33 100644 --- a/src/game/ui/HitBoxEditor.cppm +++ b/src/game/ui/HitBoxEditor.cppm @@ -31,10 +31,10 @@ export namespace Game{ } void drawDebug() const override{ - Graphic::Draw::color(); + Graphic::Draw::Overlay::color(); Game::Draw::hitbox(tempHitbox.hitBoxGroup.back().original); - if(controller->selected)Graphic::Draw::color(Graphic::Colors::ORANGE); + if(controller->selected)Graphic::Draw::Overlay::color(Graphic::Colors::ORANGE); Game::Draw::hitbox(tempHitbox.hitBoxGroup.front().original); } @@ -309,19 +309,20 @@ export namespace Game{ } namespace Draw = Graphic::Draw; + using Draw::Overlay; if(hasOp()){ for (const auto entity : selected){ auto trans = entity->hitBox.hitBoxGroup.front().relaTrans; - Draw::Line::setLineStroke(2.0f); + Overlay::Line::setLineStroke(2.0f); if(!Math::zero(clamp.x)){ - Draw::color(Graphic::Colors::RED_DUSK); - Draw::Line::lineAngleCenter(trans.vec.x, trans.vec.y, 0, 50000); + Overlay::color(Graphic::Colors::RED_DUSK); + Overlay::Line::lineAngleCenter(trans.vec.x, trans.vec.y, 0, 50000); } if(!Math::zero(clamp.y)){ - Draw::color(Graphic::Colors::FOREST); - Draw::Line::lineAngleCenter(trans.vec.x, trans.vec.y, 90, 50000); + Overlay::color(Graphic::Colors::FOREST); + Overlay::Line::lineAngleCenter(trans.vec.x, trans.vec.y, 90, 50000); } } } @@ -330,12 +331,12 @@ export namespace Game{ Geom::OrthoRectFloat orthoRectBox{}; orthoRectBox.setVert(selectionBegin.x, selectionBegin.y, mouseWorldPos.x, mouseWorldPos.y); - Draw::color(Graphic::Colors::AQUA); - Draw::alpha(0.15f); - Draw::rectOrtho(Draw::getDefaultTexture(), orthoRectBox); + Overlay::color(Graphic::Colors::AQUA); + Overlay::alpha(0.15f); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), orthoRectBox); - Draw::alpha(); - Draw::Line::rectOrtho(orthoRectBox); + Overlay::alpha(); + Overlay::Line::rectOrtho(orthoRectBox); } diff --git a/src/game/ui/OverlayManager.cppm b/src/game/ui/OverlayManager.cppm index eba0c168..d8d5912e 100644 --- a/src/game/ui/OverlayManager.cppm +++ b/src/game/ui/OverlayManager.cppm @@ -115,19 +115,21 @@ export namespace Game { // } void drawBeneathUI(Core::Renderer* renderer) const override{ + using namespace Graphic; + using Draw::Overlay; static auto coordText = Font::obtainLayoutPtr(); renderer->frameBegin(&renderer->effectBuffer); for(auto& entity : selected){ if(!entity->controller->moveCommand.shouldDrawUI())continue; - Draw::Line::setLineStroke(3.0f + (entity->controller->moveCommand.isAssigningRoute() ? 0 : 3)); - Draw::color(Colors::SLATE); - - Draw::Line::setLerpColor(Colors::SLATE, Colors::AQUA); - Draw::Line::beginLineVert(); - Draw::Line::push(entity->controller->moveCommand.route); - Draw::Line::endLineVert([](const Geom::Vec2 p, const Graphic::Color color){ - Draw::color(color); - Draw::Fill::square(p.x, p.y, 14, 45); + Overlay::Line::setLineStroke(3.0f + (entity->controller->moveCommand.isAssigningRoute() ? 0 : 3)); + Overlay::color(Colors::SLATE); + + Overlay::Line::setLerpColor(Colors::SLATE, Colors::AQUA); + Overlay::Line::beginLineVert(); + Overlay::Line::push(entity->controller->moveCommand.route); + Overlay::Line::endLineVert([](const Geom::Vec2 p, const Graphic::Color color){ + Overlay::color(color); + Overlay::Fill::square(p.x, p.y, 14, 45); }); auto dest = entity->controller->moveCommand.destination; @@ -139,19 +141,19 @@ export namespace Game { coordText->render(); const auto next = entity->controller->moveCommand.nextDest(); - Draw::Line::square(next.x, next.y, 25, 45); + Overlay::Line::square(next.x, next.y, 25, 45); - Draw::Line::setLineStroke(5); - Draw::color(Colors::BRICK); - Draw::Line::line(entity->controller->moveCommand.curTrans.vec, entity->controller->moveCommand.destination); + Overlay::Line::setLineStroke(5); + Overlay::color(Colors::BRICK); + Overlay::Line::line(entity->controller->moveCommand.curTrans.vec, entity->controller->moveCommand.destination); } - Draw::color(Colors::RED_DUSK); - Draw::Line::setLineStroke(3); + Overlay::color(Colors::RED_DUSK); + Overlay::Line::setLineStroke(3); for(auto& realityEntity : selected){ for (auto turretTarget : realityEntity->controller->turretTargets){ - Draw::Line::square(turretTarget.x, turretTarget.y, 32, 45); + Overlay::Line::square(turretTarget.x, turretTarget.y, 32, 45); } } diff --git a/src/game/ui/comp/ChamberWorkshop.cppm b/src/game/ui/comp/ChamberWorkshop.cppm index c4508ac3..acbaaab6 100644 --- a/src/game/ui/comp/ChamberWorkshop.cppm +++ b/src/game/ui/comp/ChamberWorkshop.cppm @@ -39,7 +39,7 @@ export namespace Game::Scene{ } using Tile = ChamberTile; - using TileFrame = ChamberFrameData; + using TileFrame = ChamberGridData; //TODO maybe shared_ptr is better? TileFrame frame{}; @@ -113,6 +113,7 @@ export namespace Game::Scene{ .builder = [&bar](UI::Table& hint){ auto canvas = UI::makeCanvas([&bar](const UI::Elem& elem){ using namespace Graphic; + using Draw::Overlay; Geom::Vec2 offset{}; @@ -121,12 +122,12 @@ export namespace Game::Scene{ progress.as().scl(elem.getValidWidth() / MaxTileSize, elem.getValidHeight() / MaxTileSize), elem.getValidBound().copy().move(elem.getAbsSrc()) ); - Draw::Line::setLineStroke(2.f); - Draw::color(UI::Pal::LIGHT_GRAY, elem.maskOpacity); + Overlay::Line::setLineStroke(2.f); + Overlay::color(UI::Pal::LIGHT_GRAY, elem.maskOpacity); for(int x = 0; x < progress.x; ++x){ for(int y = 0; y < progress.y; ++y){ - Draw::Line::rectOrtho( + Overlay::Line::rectOrtho( srcX + offset.x, srcY + offset.y, elem.getValidWidth() / MaxTileSize, @@ -181,7 +182,7 @@ export namespace Game::Scene{ }).setSizeScale(0.8f, 1.0f).setMargin(4.0f).setAlign(Align::Mode::right).template as(); screen->getInputListener().on([this](const UI::MouseActionPress& e){ - switch(e.key){ + if(e.mode == Ctrl::Mode::None)switch(e.key){ case Ctrl::Mouse::_2 :{ if(!currentFactory)break; const auto pos = toChamberPos(screen->getCursorPosInScreen()); @@ -224,7 +225,7 @@ export namespace Game::Scene{ setLayoutByRelative(false); } - void build(const ChamberFrameData& data){ + void build(const ChamberGridData& data){ frame = data; buildElem(); @@ -234,6 +235,7 @@ export namespace Game::Scene{ Table::drawChildren(); using namespace Graphic; + using Draw::Overlay; screen->beginDraw(&Core::BatchGroup::overlay); const auto& brief = frame.getBrief(); @@ -251,11 +253,11 @@ export namespace Game::Scene{ Core::renderer->effectBuffer.bind(); Core::renderer->effectBuffer.enableDrawAll(); Core::renderer->effectBuffer.clearColorAll(); - Draw::color(Colors::GRAY); + Overlay::color(Colors::GRAY); for(const Tile* tile : brief.invalids){ - if(!screen->getCamera().getViewport().overlap(tile->getChamberRealRegion()))continue; - Draw::rectOrtho(Draw::globalState.defaultTexture, tile->getTileBound()); + if(!screen->getCamera().getViewport().overlap(tile->getTileBound()))continue; + Overlay::Fill::rectOrtho(Overlay::defaultTexture, tile->getTileBound()); } [[maybe_unused]] GL::UniformGuard guard_outline @@ -271,23 +273,9 @@ export namespace Game::Scene{ screen->lockViewport(); } - Draw::color(Colors::GRAY, 0.45f); - Draw::Line::setLineStroke(2.0f); - for(const auto tile : brief.valids){ - if(!screen->getCamera().getViewport().overlap(tile->getChamberRealRegion()))continue; - Draw::Line::rectOrtho(tile->getTileBound()); - } - - Draw::color(Colors::LIGHT_GRAY, 0.85f); - for(const auto tile : brief.owners){ - if(!screen->getCamera().getViewport().overlap(tile->getChamberBound()))continue; - Draw::Line::rectOrtho(tile->getChamberBound()); - } - - { - Draw::color(Colors::WHITE); - Draw::mixColor(Colors::BLACK.createLerp(Colors::RED_DUSK, 0.3f)); + Overlay::color(Colors::WHITE, 0.6f); + Overlay::mixColor(Colors::BLACK.createLerp(Colors::RED_DUSK, 0.3f)); [[maybe_unused]] GL::UniformGuard guard_slideLine_1{ Assets::Shaders::slideLineShaderDrawArgs, 25.0f, 45.0f, Colors::CLEAR @@ -300,34 +288,54 @@ export namespace Game::Scene{ }; for(const auto* tile : brief.invalids){ - if(!screen->getCamera().getViewport().overlap(tile->getChamberRealRegion()))continue; - Draw::rectOrtho(Draw::getDefaultTexture(), tile->getTileBound()); + if(!screen->getCamera().getViewport().overlap(tile->getChamberRegion()))continue; + Overlay::Fill::rectOrtho(Overlay::defaultTexture, tile->getTileBound()); } } - Draw::mixColor(); + Overlay::mixColor(); + Overlay::color(Colors::GRAY, 0.45f); + Overlay::Line::setLineStroke(1.0f); + for(const auto tile : brief.valids){ + if(!screen->getCamera().getViewport().overlap(tile->getTileBound()))continue; + Overlay::Line::rectOrtho(tile->getTileBound()); + } + + Overlay::Line::setLineStroke(1.0f); + Overlay::color(Colors::LIGHT_GRAY, 0.85f); + for(const auto tile : brief.owners){ + if(!screen->getCamera().getViewport().overlap(tile->getEntityBound()))continue; + Overlay::Line::rectOrtho(tile->getEntityBound()); + } + + Overlay::Line::setLineStroke(1.2f); + Overlay::color(Colors::AQUA_SKY, 0.85f); + for(const Tile& tile : selected | std::ranges::views::values | std::ranges::views::transform(&TileFrame::ItrType::operator*)){ + if(!screen->getCamera().getViewport().overlap(tile.getTileBound()))continue; + Overlay::Line::rectOrtho(tile.getTileBound()); + } const auto pos = toChamberPos(screen->getCursorPosInScreen()); Geom::OrthoRectInt bound = getTileBound(); bound.setCenter(pos); if(const auto finded = frame.find(pos)){ - Draw::color(Colors::LIGHT_GRAY); - Draw::rectOrtho(Draw::getDefaultTexture(), finded->getTileBound()); + Overlay::color(Colors::LIGHT_GRAY); + Overlay::Fill::rectOrtho(Overlay::getDefaultTexture(), finded->getTileBound()); } if(frame.placementValid(bound)){ - Draw::color(Colors::PALE_GREEN); + Overlay::color(Colors::PALE_GREEN); } else{ - Draw::color(Colors::RED_DUSK); + Overlay::color(Colors::RED_DUSK); } - Draw::Line::setLineStroke(2.f); - Draw::Line::rectOrtho(bound.as().scl(TileSize, TileSize)); + Overlay::Line::setLineStroke(2.f); + Overlay::Line::rectOrtho(bound.as().scl(TileSize, TileSize)); if(isBoxSelecting()){ - Draw::color(Colors::AQUA_SKY); - Draw::Line::rectOrtho(getSelectionRange().as().scl(TileSize, TileSize)); + Overlay::color(Colors::AQUA_SKY); + Overlay::Line::rectOrtho(getSelectionRange().as().scl(TileSize, TileSize)); } screen->endDraw();