Skip to content

Commit d05caac

Browse files
committed
update
1 parent 1461ca8 commit d05caac

1 file changed

Lines changed: 32 additions & 27 deletions

File tree

gframe/drawing.cpp

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cmath>
2+
#include <vector>
23
#include "game.h"
34
#include "client_card.h"
45
#include "materials.h"
@@ -8,30 +9,6 @@
89
#include "sound_manager.h"
910
#include "duelclient.h"
1011

11-
namespace {
12-
13-
// Draws a camera-facing quad between two world-space points.
14-
void DrawThickLine3D(irr::video::IVideoDriver* driver,
15-
const irr::core::vector3df& start, const irr::core::vector3df& end,
16-
const irr::core::vector3df& camFwd, irr::f32 halfThick,
17-
irr::video::SColor color) {
18-
irr::core::vector3df perp = (end - start).crossProduct(camFwd);
19-
const irr::f32 len = perp.getLength();
20-
if(len < 1e-6f) return;
21-
perp *= halfThick / len;
22-
irr::video::S3DVertex v[4];
23-
static const irr::u16 idx[6] = {0, 2, 1, 1, 2, 3};
24-
for(int i = 0; i < 4; ++i) { v[i].Color = color; v[i].Normal = {0, 0, -1}; }
25-
v[0].Pos = start + perp;
26-
v[1].Pos = start - perp;
27-
v[2].Pos = end + perp;
28-
v[3].Pos = end - perp;
29-
driver->drawVertexPrimitiveList(v, 4, idx, 2,
30-
irr::video::EVT_STANDARD, irr::scene::EPT_TRIANGLES);
31-
}
32-
33-
}
34-
3512
namespace ygo {
3613

3714
void Game::Draw2DImageQuad(irr::video::IVideoDriver* driver, irr::video::ITexture* texture,
@@ -96,17 +73,40 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool stipple, irr::vide
9673
const irr::core::matrix4& view = driver->getTransform(irr::video::ETS_VIEW);
9774
const irr::core::vector3df camFwd(view(0,2), view(1,2), view(2,2));
9875
const irr::f32 halfThick = matManager.mOutLine.Thickness * 0.005f;
76+
std::vector<irr::video::S3DVertex> vertices;
77+
std::vector<irr::u16> indices;
78+
vertices.reserve(64);
79+
indices.reserve(96);
80+
constexpr size_t MAX_THICK_LINE_BATCH_VERTICES = (1 << (sizeof(irr::u16) * 8)) - 4;
81+
const auto appendThickLine = [&](const irr::core::vector3df& start, const irr::core::vector3df& end) {
82+
if(vertices.size() > MAX_THICK_LINE_BATCH_VERTICES)
83+
return;
84+
const auto direction = end - start;
85+
irr::core::vector3df perp = direction.crossProduct(camFwd);
86+
const irr::f32 lenSq = perp.getLengthSQ();
87+
if(lenSq < 1e-12f) return;
88+
perp *= halfThick / std::sqrt(lenSq);
89+
const auto base = static_cast<irr::u16>(vertices.size());
90+
static const irr::u16 idx[6] = {0, 2, 1, 1, 2, 3};
91+
const irr::core::vector3df normal(0.0f, 0.0f, -1.0f);
92+
vertices.emplace_back(start + perp, normal, color, irr::core::vector2df());
93+
vertices.emplace_back(start - perp, normal, color, irr::core::vector2df());
94+
vertices.emplace_back(end + perp, normal, color, irr::core::vector2df());
95+
vertices.emplace_back(end - perp, normal, color, irr::core::vector2df());
96+
for(int i = 0; i < 6; ++i)
97+
indices.push_back(base + idx[i]);
98+
};
9999
driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
100100
if(!stipple) {
101101
for(int i = 0; i < 4; ++i)
102-
DrawThickLine3D(driver, wp[edgeStart[i]], wp[edgeEnd[i]], camFwd, halfThick, color);
102+
appendThickLine(wp[edgeStart[i]], wp[edgeEnd[i]]);
103103
} else if(gameConf.solid_selection_line) {
104104
const irr::f32 t0 = (linePattern < 15) ? 0.0f : (linePattern - 14) / 15.0f;
105105
const irr::f32 t1 = (linePattern < 15) ? (linePattern + 1) / 15.0f : 1.0f;
106106
for(int i = 0; i < 4; ++i) {
107107
const auto& s = wp[edgeStart[i]];
108108
const auto d = wp[edgeEnd[i]] - s;
109-
DrawThickLine3D(driver, s + d * t0, s + d * t1, camFwd, halfThick, color);
109+
appendThickLine(s + d * t0, s + d * t1);
110110
}
111111
} else {
112112
// Project edge endpoints to screen space to get pixel length for pattern tiling.
@@ -137,12 +137,17 @@ void Game::DrawSelectionLine(irr::video::S3DVertex* vec, bool stipple, irr::vide
137137
runEnd += 1.0f;
138138
if(runEnd > screenLen)
139139
runEnd = screenLen;
140-
DrawThickLine3D(driver, s + d * (cursor / screenLen), s + d * (runEnd / screenLen), camFwd, halfThick, color);
140+
appendThickLine(s + d * (cursor / screenLen), s + d * (runEnd / screenLen));
141141
cursor = runEnd;
142142
}
143143
patternCursor = std::fmod(patternCursor + screenLen, 16.0f);
144144
}
145145
}
146+
if(!indices.empty()) {
147+
driver->drawVertexPrimitiveList(vertices.data(), static_cast<irr::u32>(vertices.size()),
148+
indices.data(), static_cast<irr::u32>(indices.size() / 3),
149+
irr::video::EVT_STANDARD, irr::scene::EPT_TRIANGLES);
150+
}
146151
driver->setTransform(irr::video::ETS_WORLD, oldWorld);
147152
}
148153
void Game::DrawSelectionLine(irr::gui::IGUIElement* element, int width, irr::video::SColor color) {

0 commit comments

Comments
 (0)