88import com .mojang .blaze3d .vertex .Tesselator ;
99import com .mojang .blaze3d .vertex .VertexFormat ;
1010import com .mojang .math .Matrix4f ;
11+ import com .mojang .math .Quaternion ;
12+ import com .mojang .math .Vector3f ;
1113import de .srendi .advancedperipherals .client .RenderUtil ;
1214import de .srendi .advancedperipherals .common .smartglasses .modules .overlay .objects .two_dim .CircleObject ;
13- import de .srendi .advancedperipherals .common .smartglasses .modules .overlay .objects .two_dim . RenderableObject ;
15+ import de .srendi .advancedperipherals .common .smartglasses .modules .overlay .objects .RenderableObject ;
1416import net .minecraft .client .renderer .GameRenderer ;
1517import net .minecraftforge .client .gui .overlay .ForgeGui ;
1618
@@ -29,31 +31,159 @@ public void renderBatch(List<RenderableObject> objects, ForgeGui gui, PoseStack
2931 float green = RenderUtil .getGreen (circle .color );
3032 float blue = RenderUtil .getBlue (circle .color );
3133
32- drawCircle (poseStack , circle . x , circle . y , circle . radius , 120 , red , green , blue , alpha );
34+ drawCircle (poseStack , circle , red , green , blue , alpha );
3335 }
3436 }
3537
36- public void drawCircle (PoseStack poseStack , float cx , float cy , float r , int numSegments , float red , float green , float blue , float alpha ) {
38+ public void drawCircle (PoseStack t , CircleObject circle , float red , float green , float blue , float alpha ) {
39+ float r = circle .radius ;
40+ float cx = circle .x ;
41+ float cy = circle .y ;
42+ float cz = circle .z ;
43+ float rotX = circle .rotX ;
44+ float rotY = circle .rotY ;
45+ float rotZ = circle .rotZ ;
46+ float borderWidth = circle .borderWidth ;
47+ int segments = circle .segments ;
48+
49+ boolean isFilled = circle .filled ;
50+ boolean isPixelated = circle .pixelated ;
51+
52+ PoseStack poseStack = new PoseStack ();
53+
54+ poseStack .translate (cx , cy , cz );
55+
56+ poseStack .pushPose ();
57+
58+ poseStack .mulPose (Vector3f .XP .rotationDegrees (rotX ));
59+ poseStack .mulPose (Vector3f .YP .rotationDegrees (rotY ));
60+ poseStack .mulPose (Vector3f .ZP .rotationDegrees (rotZ ));
61+
62+ RenderSystem .disableCull ();
63+
3764 RenderSystem .setShader (GameRenderer ::getPositionColorShader );
3865 BufferBuilder bufferbuilder = Tesselator .getInstance ().getBuilder ();
3966
4067 Matrix4f matrix = poseStack .last ().pose ();
41- bufferbuilder .begin (VertexFormat .Mode .TRIANGLE_FAN , DefaultVertexFormat .POSITION_COLOR );
4268
43- bufferbuilder .vertex (matrix , cx , cy , 1f ).color (red , green , blue , alpha ).endVertex ();
69+ // Normal, smooth lines
70+ if (!isPixelated ) {
71+ if (isFilled ) {
72+
73+ bufferbuilder .begin (VertexFormat .Mode .TRIANGLE_FAN , DefaultVertexFormat .POSITION_COLOR );
74+
75+ bufferbuilder .vertex (matrix , 0 , 0 , 0f ).color (red , green , blue , alpha ).endVertex ();
76+
77+ double angleStep = Math .PI * 2 / segments ;
78+
79+ for (int i = 0 ; i <= segments ; i ++) {
80+ double angle = i * angleStep ;
81+ double x = r * Math .sin (angle );
82+ double y = r * Math .cos (angle );
83+
84+ bufferbuilder .vertex (matrix , (float ) x , (float ) y , 0 ).color (red , green , blue , alpha ).endVertex ();
85+ }
4486
45- double angle = Math .PI * 2 / numSegments ;
87+ } else {
88+ float outerRadius = r ;
89+ float innerRadius = r - borderWidth ;
4690
47- for (int i = 0 ; i <= numSegments ; i ++) {
48- double x = cx + r * Math .sin (i * angle );
49- double y = cy + r * Math .cos (i * angle );
91+ bufferbuilder .begin (VertexFormat .Mode .TRIANGLE_STRIP , DefaultVertexFormat .POSITION_COLOR );
5092
51- bufferbuilder .vertex (matrix , (float ) x , (float ) y , 0f ).color (red , green , blue , alpha ).endVertex ();
93+ double angleStep = Math .PI * 2 / segments ;
94+
95+ for (int i = 0 ; i <= segments ; i ++) {
96+ double angle = i * angleStep ;
97+
98+ // Outer circle vertex
99+ double outerX = innerRadius * Math .sin (angle );
100+ double outerY = innerRadius * Math .cos (angle );
101+ bufferbuilder .vertex (matrix , (float ) outerX , (float ) outerY , 0f ).color (red , green , blue , alpha ).endVertex ();
102+
103+ // Inner circle vertex
104+ double innerX = outerRadius * Math .sin (angle );
105+ double innerY = outerRadius * Math .cos (angle );
106+ bufferbuilder .vertex (matrix , (float ) innerX , (float ) innerY , 0f ).color (red , green , blue , alpha ).endVertex ();
107+ }
108+ }
109+
110+ BufferUploader .drawWithShader (bufferbuilder .end ());
111+
112+ return ;
52113 }
53114
115+ // Pixelated lines
116+ bufferbuilder .begin (VertexFormat .Mode .QUADS , DefaultVertexFormat .POSITION_COLOR );
117+
118+ final float PIXEL_SIZE = borderWidth ; // Defines the size of each "pixel" square
119+
120+ // The thickness of the hollow line in terms of pixel units.
121+ // A value of 1.0f means the line will be roughly one pixel thick.
122+ final float LINE_THICKNESS_PIXELS = 1f ;
123+
124+ // Calculate the effective min/max coordinates in the relative space
125+ float effectiveMinX = -r - PIXEL_SIZE ;
126+ float effectiveMaxX = r + PIXEL_SIZE ;
127+ float effectiveMinY = -r - PIXEL_SIZE ;
128+ float effectiveMaxY = r + PIXEL_SIZE ;
129+
130+ // Start the loop at the first multiple of PIXEL_SIZE that is less than or equal to effectiveMinX/Y
131+ float startX = (float ) Math .floor (effectiveMinX / PIXEL_SIZE ) * PIXEL_SIZE ;
132+ float startY = (float ) Math .floor (effectiveMinY / PIXEL_SIZE ) * PIXEL_SIZE ;
133+
134+
135+ for (float x = startX ; x <= effectiveMaxX ; x += PIXEL_SIZE ) {
136+ for (float y = startY ; y <= effectiveMaxY ; y += PIXEL_SIZE ) {
137+ // Calculate the center of the current pixel cell.
138+ // This is where you determine if the *center* of this block should be drawn.
139+ float pixelCenterX = x + (PIXEL_SIZE / 2.0F );
140+ float pixelCenterY = y + (PIXEL_SIZE / 2.0F );
141+
142+ // Distance is calculated from (pixelCenterX, pixelCenterY) to (0,0)
143+ double distanceToCenter = Math .sqrt (
144+ Math .pow (pixelCenterX , 2 ) + Math .pow (pixelCenterY , 2 )
145+ );
146+
147+ boolean shouldDrawPixel ;
148+
149+ if (!isFilled ) {
150+ float outerRadius = r + (LINE_THICKNESS_PIXELS * (PIXEL_SIZE / 2.0F ));
151+ float innerRadius = r - (LINE_THICKNESS_PIXELS * (PIXEL_SIZE / 2.0F ));
152+
153+ if (innerRadius < 0 ) innerRadius = 0 ;
154+
155+ shouldDrawPixel = (distanceToCenter <= outerRadius ) && (distanceToCenter >= innerRadius );
156+ } else {
157+ shouldDrawPixel = distanceToCenter <= r + (PIXEL_SIZE / 2.0F );
158+ }
159+
160+ if (shouldDrawPixel ) {
161+ // Vertices for the QUAD (a PIXEL_SIZE x PIXEL_SIZE square)
162+ // These coordinates are now relative to the current origin (0,0,0)
163+ float p_x1 = x ;
164+ float p_y1 = y ;
165+ float p_z = 0f ; // z-coordinate is relative to cz, so 0 in this space
166+
167+ float p_x2 = x + PIXEL_SIZE ;
168+ float p_y2 = y + PIXEL_SIZE ;
169+
170+ // Vertices for the QUAD
171+ // Ensure proper winding order (counter-clockwise for front face)
172+ bufferbuilder .vertex (matrix , p_x1 , p_y2 , p_z ).color (red , green , blue , alpha ).endVertex (); // Bottom-left
173+ bufferbuilder .vertex (matrix , p_x2 , p_y2 , p_z ).color (red , green , blue , alpha ).endVertex (); // Bottom-right
174+ bufferbuilder .vertex (matrix , p_x2 , p_y1 , p_z ).color (red , green , blue , alpha ).endVertex (); // Top-right
175+ bufferbuilder .vertex (matrix , p_x1 , p_y1 , p_z ).color (red , green , blue , alpha ).endVertex (); // Top-left
176+ }
177+ }
178+ }
179+
180+ RenderSystem .enableCull ();
181+
54182 BufferUploader .drawWithShader (bufferbuilder .end ());
55- }
56183
57184
185+ poseStack .popPose ();
58186
187+ }
59188}
189+
0 commit comments