Skip to content

Commit 5c3772e

Browse files
committed
Fix box2d-v3 shape instancing draw for metal render backend
1 parent 63c0adc commit 5c3772e

File tree

5 files changed

+115
-52
lines changed

5 files changed

+115
-52
lines changed

tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ static void b2DrawCircle(b2Vec2 center, float radius, b2HexColor color, Box2DTes
5656
{
5757
auto ratio = context->getPTMRatio();
5858
auto offset = context->getWorldOffset();
59-
context->AddCircle(CircleData{b2Vec2{center.x * ratio + offset.x, center.y * ratio + offset.y}, radius * ratio,
60-
PhysicsHelper::toColor(color)});
59+
context->AddCircle(CircleData{PhysicsHelper::toColor(color), b2Vec2{center.x * ratio + offset.x, center.y * ratio + offset.y}, radius * ratio});
6160
}
6261

6362
static void b2DrawSolidCircle(b2Transform t, float radius, b2HexColor color, Box2DTestDebugDrawNode* context)
@@ -67,8 +66,7 @@ static void b2DrawSolidCircle(b2Transform t, float radius, b2HexColor color, Box
6766
auto ratio = context->getPTMRatio();
6867
auto offset = context->getWorldOffset();
6968
context->AddCircle({{t.p.x * ratio + offset.x, t.p.y * ratio + offset.y, t.q.c, t.q.s},
70-
radius * ratio,
71-
PhysicsHelper::toColor(color)});
69+
PhysicsHelper::toColor(color), radius * ratio});
7270
}
7371

7472
static void b2DrawSolidCapsule(b2Vec2 pt1, b2Vec2 pt2, float radius, b2HexColor c, Box2DTestDebugDrawNode* context)
@@ -94,9 +92,10 @@ static void b2DrawSolidCapsule(b2Vec2 pt1, b2Vec2 pt2, float radius, b2HexColor
9492
auto rgba = PhysicsHelper::toColor(c);
9593

9694
context->AddCapsule({{transform.p.x + offset.x, transform.p.y + offset.y, transform.q.c, transform.q.s},
95+
rgba,
9796
radius * ratio,
98-
length,
99-
rgba});
97+
length
98+
});
10099
}
101100

102101
bool Box2DTestDebugDrawNode::initWithWorld(b2WorldId worldId)
@@ -140,12 +139,11 @@ bool Box2DTestDebugDrawNode::initWithWorld(b2WorldId worldId)
140139

141140
// instanced attributes
142141
auto vfmtInstanced = pipelinePS->getMutableVertexLayout(true);
143-
vfmtInstanced->setAttrib("a_instanceTransform", program->getAttributeLocation("a_instancePosition"),
144-
backend::VertexFormat::FLOAT2, offsetof(CircleData, position), false);
145-
vfmtInstanced->setAttrib("a_instanceRadius", program->getAttributeLocation("a_instanceRadius"),
146-
backend::VertexFormat::FLOAT, offsetof(CircleData, radius), false);
142+
147143
vfmtInstanced->setAttrib("a_instanceColor", program->getAttributeLocation("a_instanceColor"),
148144
backend::VertexFormat::FLOAT4, offsetof(CircleData, rgba), false);
145+
vfmtInstanced->setAttrib("a_instancePosAndRadius", program->getAttributeLocation("a_instancePosAndRadius"),
146+
backend::VertexFormat::FLOAT4, offsetof(CircleData, position), false);
149147
vfmtInstanced->setStride(sizeof(CircleData));
150148

151149
cmd.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
@@ -176,10 +174,10 @@ bool Box2DTestDebugDrawNode::initWithWorld(b2WorldId worldId)
176174
auto vfmtInstanced = pipelinePS->getMutableVertexLayout(true);
177175
vfmtInstanced->setAttrib("a_instanceTransform", program->getAttributeLocation("a_instanceTransform"),
178176
backend::VertexFormat::FLOAT4, offsetof(SolidCircleData, transform), false);
179-
vfmtInstanced->setAttrib("a_instanceRadius", program->getAttributeLocation("a_instanceRadius"),
180-
backend::VertexFormat::FLOAT, offsetof(SolidCircleData, radius), false);
181177
vfmtInstanced->setAttrib("a_instanceColor", program->getAttributeLocation("a_instanceColor"),
182178
backend::VertexFormat::FLOAT4, offsetof(SolidCircleData, rgba), false);
179+
vfmtInstanced->setAttrib("a_instanceRadius", program->getAttributeLocation("a_instanceRadius"),
180+
backend::VertexFormat::FLOAT4, offsetof(SolidCircleData, radius), false);
183181
vfmtInstanced->setStride(sizeof(SolidCircleData));
184182

185183
cmd.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);
@@ -210,12 +208,10 @@ bool Box2DTestDebugDrawNode::initWithWorld(b2WorldId worldId)
210208
auto vfmtInstanced = pipelinePS->getMutableVertexLayout(true);
211209
vfmtInstanced->setAttrib("a_instanceTransform", program->getAttributeLocation("a_instanceTransform"),
212210
backend::VertexFormat::FLOAT4, offsetof(CapsuleData, transform), false);
213-
vfmtInstanced->setAttrib("a_instanceRadius", program->getAttributeLocation("a_instanceRadius"),
214-
backend::VertexFormat::FLOAT, offsetof(CapsuleData, radius), false);
215-
vfmtInstanced->setAttrib("a_instanceLength", program->getAttributeLocation("a_instanceLength"),
216-
backend::VertexFormat::FLOAT, offsetof(CapsuleData, length), false);
217211
vfmtInstanced->setAttrib("a_instanceColor", program->getAttributeLocation("a_instanceColor"),
218212
backend::VertexFormat::FLOAT4, offsetof(CapsuleData, rgba), false);
213+
vfmtInstanced->setAttrib("a_instanceRadiusAndLength", program->getAttributeLocation("a_instanceRadiusAndLength"),
214+
backend::VertexFormat::FLOAT4, offsetof(CapsuleData, radius), false);
219215
vfmtInstanced->setStride(sizeof(CapsuleData));
220216

221217
cmd.setPrimitiveType(CustomCommand::PrimitiveType::TRIANGLE);

tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ struct ImFont;
99

1010
struct CircleData
1111
{
12+
ax::Color rgba;
1213
b2Vec2 position;
1314
float radius;
14-
ax::Color rgba;
15+
float padding;
1516
};
1617

1718
struct SolidCircleData
1819
{
1920
b2Transform transform;
20-
float radius;
2121
ax::Color rgba;
22+
float radius;
23+
float padding[3];
2224
};
2325

2426
struct CapsuleData
2527
{
2628
b2Transform transform;
29+
ax::Color rgba;
2730
float radius;
2831
float length;
29-
ax::Color rgba;
32+
float padding[2];
3033
};
3134

3235
class Box2DTestDebugDrawNode : public ax::extension::PhysicsDebugNode
Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
// SPDX-FileCopyrightText: 2024 Erin Catto
2-
// SPDX-License-Identifier: MIT
3-
4-
#version 420
1+
#version 310 es
52

63
layout(location = 0) in vec2 a_localPosition;
7-
layout(location = 1) in vec2 a_instancePosition;
8-
layout(location = 2) in float a_instanceRadius;
9-
layout(location = 3) in vec4 a_instanceColor;
4+
5+
#if !defined(METAL)
6+
layout(location = 1) in vec4 a_instanceColor;
7+
// pos: xy, radius: z, due to metal alignment is 16
8+
layout(location = 2) in vec4 a_instancePosAndRadius;
9+
#endif
1010

1111
layout(location = 0) out vec2 v_position;
1212
layout(location = 1) out vec4 v_color;
@@ -17,15 +17,34 @@ layout(std140) uniform vs_ub {
1717
mat4 u_MVPMatrix;
1818
};
1919

20+
#if defined(METAL)
21+
struct instance_data_st {
22+
vec4 color;
23+
vec2 pos;
24+
float radius;
25+
};
26+
layout(std140, binding = 1) buffer vs_inst {
27+
instance_data_st instances[];
28+
};
29+
#endif
30+
2031
void main()
2132
{
2233
v_position = a_localPosition;
34+
35+
#if !defined(METAL)
2336
v_color = a_instanceColor;
24-
float radius = a_instanceRadius;
37+
vec2 instancePos = a_instancePosAndRadius.xy;
38+
float radius = a_instancePosAndRadius.z;
39+
#else
40+
v_color = instances[gl_InstanceIndex].color;
41+
vec2 instancePos = instances[gl_InstanceIndex].pos;
42+
float radius = instances[gl_InstanceIndex].radius;
43+
#endif
2544

2645
// resolution.y = pixelScale * radius
2746
v_thickness = 3.0f / (u_pixelScale * radius);
2847

29-
vec2 p = vec2(radius * a_localPosition.x, radius * a_localPosition.y) + a_instancePosition;
48+
vec2 p = vec2(radius * a_localPosition.x, radius * a_localPosition.y) + instancePos;
3049
gl_Position = u_MVPMatrix * vec4(p, 0.0f, 1.0f);
3150
}

tests/cpp-tests/Source/shaders/solid_capsule.vs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// SPDX-FileCopyrightText: 2024 Erin Catto
2-
// SPDX-License-Identifier: MIT
3-
4-
#version 420
1+
#version 310 es
52

63
layout(location=0) in vec2 a_localPosition;
4+
5+
#if !defined(METAL)
76
layout(location=1) in vec4 a_instanceTransform;
8-
layout(location=2) in float a_instanceRadius;
9-
layout(location=3) in float a_instanceLength;
10-
layout(location=4) in vec4 a_instanceColor;
7+
layout(location=2) in vec4 a_instanceColor;
8+
// radius: x, length: y, due to metal alignment is 16
9+
layout(location=3) in vec4 a_instanceRadiusAndLength;
10+
#endif
1111

1212
layout(location=0) out vec2 v_position;
1313
layout(location=1) out vec4 v_color;
@@ -19,13 +19,41 @@ layout(std140) uniform vs_ub {
1919
mat4 u_MVPMatrix;
2020
};
2121

22+
#if defined(METAL)
23+
struct instance_data_st {
24+
vec4 trans;
25+
vec4 color;
26+
float radius;
27+
float len;
28+
};
29+
layout(std140, binding = 1) buffer vs_inst {
30+
instance_data_st instances[];
31+
};
32+
#endif
33+
2234
void main()
2335
{
2436
v_position = a_localPosition;
37+
38+
#if !defined(METAL)
2539
v_color = a_instanceColor;
2640

27-
float radius = a_instanceRadius;
28-
float length = a_instanceLength;
41+
float radius = a_instanceRadiusAndLength.x;
42+
float length = a_instanceRadiusAndLength.y;
43+
float x = a_instanceTransform.x;
44+
float y = a_instanceTransform.y;
45+
float c = a_instanceTransform.z;
46+
float s = a_instanceTransform.w;
47+
#else
48+
v_color = instances[gl_InstanceIndex].color;
49+
50+
float radius = instances[gl_InstanceIndex].radius;
51+
float length = instances[gl_InstanceIndex].len;
52+
float x = instances[gl_InstanceIndex].trans.x;
53+
float y = instances[gl_InstanceIndex].trans.y;
54+
float c = instances[gl_InstanceIndex].trans.z;
55+
float s = instances[gl_InstanceIndex].trans.w;
56+
#endif
2957

3058
// scale quad large enough to hold capsule
3159
float scale = radius + 0.5 * length;
@@ -36,10 +64,6 @@ void main()
3664
// resolution.y = pixelScale * scale
3765
v_thickness = 3.0f / (u_pixelScale * scale);
3866

39-
float x = a_instanceTransform.x;
40-
float y = a_instanceTransform.y;
41-
float c = a_instanceTransform.z;
42-
float s = a_instanceTransform.w;
4367
vec2 p = vec2(scale * a_localPosition.x, scale * a_localPosition.y);
4468
p = vec2((c * p.x - s * p.y) + x, (s * p.x + c * p.y) + y);
4569
gl_Position = u_MVPMatrix * vec4(p, 0.0, 1.0);

tests/cpp-tests/Source/shaders/solid_circle.vs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
// SPDX-FileCopyrightText: 2024 Erin Catto
2-
// SPDX-License-Identifier: MIT
3-
4-
#version 420
1+
#version 310 es
52

63
layout(location = 0) in vec2 a_localPosition;
4+
5+
#if !defined(METAL)
76
layout(location = 1) in vec4 a_instanceTransform;
8-
layout(location = 2) in float a_instanceRadius;
9-
layout(location = 3) in vec4 a_instanceColor;
7+
layout(location = 2) in vec4 a_instanceColor;
8+
// radius: x, due to metal alignment is 16
9+
layout(location = 3) in vec4 a_instanceRadius;
10+
#endif
1011

1112
layout(location = 0) out vec2 v_position;
1213
layout(location = 1) out vec4 v_color;
@@ -17,19 +18,39 @@ layout(std140) uniform vs_ub {
1718
mat4 u_MVPMatrix;
1819
};
1920

21+
#if defined(METAL)
22+
struct instance_data_st {
23+
vec4 trans;
24+
vec4 color;
25+
float radius;
26+
};
27+
layout(std140, binding = 1) buffer vs_inst {
28+
instance_data_st instances[];
29+
};
30+
#endif
31+
2032
void main()
2133
{
2234
v_position = a_localPosition;
23-
v_color = a_instanceColor;
24-
float radius = a_instanceRadius;
2535

26-
// resolution.y = pixelScale * radius
27-
v_thickness = 3.0f / (u_pixelScale * radius);
28-
36+
#if !defined(METAL)
37+
v_color = a_instanceColor;
38+
float radius = a_instanceRadius.x;
2939
float x = a_instanceTransform.x;
3040
float y = a_instanceTransform.y;
3141
float c = a_instanceTransform.z;
3242
float s = a_instanceTransform.w;
43+
#else
44+
v_color = instances[gl_InstanceIndex].color;
45+
float radius = instances[gl_InstanceIndex].radius;
46+
float x = instances[gl_InstanceIndex].trans.x;
47+
float y = instances[gl_InstanceIndex].trans.y;
48+
float c = instances[gl_InstanceIndex].trans.z;
49+
float s = instances[gl_InstanceIndex].trans.w;
50+
#endif
51+
52+
// resolution.y = pixelScale * radius
53+
v_thickness = 3.0f / (u_pixelScale * radius);
3354
vec2 p = vec2(radius * a_localPosition.x, radius * a_localPosition.y);
3455
p = vec2((c * p.x - s * p.y) + x, (s * p.x + c * p.y) + y);
3556
gl_Position = u_MVPMatrix * vec4(p, 0.0f, 1.0f);

0 commit comments

Comments
 (0)