@@ -5,12 +5,20 @@ C2Di_Context __C2Di_Context;
55static C3D_Mtx s_projTop , s_projBot ;
66static int uLoc_mdlvMtx , uLoc_projMtx ;
77
8+ static inline bool C2Di_CheckBufSpace (C2Di_Context * ctx , unsigned idx , unsigned vtx )
9+ {
10+ size_t free_idx = ctx -> idxBufSize - ctx -> idxBufPos ;
11+ size_t free_vtx = ctx -> vtxBufSize - ctx -> vtxBufPos ;
12+ return free_idx >= idx && free_vtx >= vtx ;
13+ }
14+
815static void C2Di_FrameEndHook (void * unused )
916{
1017 C2Di_Context * ctx = C2Di_GetContext ();
1118 C2Di_FlushVtxBuf ();
1219 ctx -> vtxBufPos = 0 ;
13- ctx -> vtxBufLastPos = 0 ;
20+ ctx -> idxBufPos = 0 ;
21+ ctx -> idxBufLastPos = 0 ;
1422}
1523
1624bool C2D_Init (size_t maxObjects )
@@ -19,14 +27,23 @@ bool C2D_Init(size_t maxObjects)
1927 if (ctx -> flags & C2DiF_Active )
2028 return false;
2129
22- ctx -> vtxBufSize = 6 * maxObjects ;
30+ ctx -> vtxBufSize = 4 * maxObjects ;
2331 ctx -> vtxBuf = (C2Di_Vertex * )linearAlloc (ctx -> vtxBufSize * sizeof (C2Di_Vertex ));
2432 if (!ctx -> vtxBuf )
2533 return false;
2634
35+ ctx -> idxBufSize = 6 * maxObjects ;
36+ ctx -> idxBuf = (u16 * )linearAlloc (ctx -> idxBufSize * sizeof (u16 ));
37+ if (!ctx -> idxBuf )
38+ {
39+ linearFree (ctx -> vtxBuf );
40+ return false;
41+ }
42+
2743 ctx -> shader = DVLB_ParseFile ((u32 * )render2d_shbin , render2d_shbin_size );
2844 if (!ctx -> shader )
2945 {
46+ linearFree (ctx -> idxBuf );
3047 linearFree (ctx -> vtxBuf );
3148 return false;
3249 }
@@ -75,7 +92,8 @@ bool C2D_Init(size_t maxObjects)
7592
7693 ctx -> flags = C2DiF_Active | (C2DiF_Mode_ImageSolid << (C2DiF_TintMode_Shift - C2DiF_Mode_Shift ));
7794 ctx -> vtxBufPos = 0 ;
78- ctx -> vtxBufLastPos = 0 ;
95+ ctx -> idxBufPos = 0 ;
96+ ctx -> idxBufLastPos = 0 ;
7997 Mtx_Identity (& ctx -> projMtx );
8098 Mtx_Identity (& ctx -> mdlvMtx );
8199 ctx -> fadeClr = 0 ;
@@ -94,6 +112,7 @@ void C2D_Fini(void)
94112 C3D_FrameEndHook (NULL , NULL );
95113 shaderProgramFree (& ctx -> program );
96114 DVLB_Free (ctx -> shader );
115+ linearFree (ctx -> idxBuf );
97116 linearFree (ctx -> vtxBuf );
98117}
99118
@@ -370,7 +389,7 @@ bool C2D_DrawImage(C2D_Image img, const C2D_DrawParams* params, const C2D_ImageT
370389 C2Di_Context * ctx = C2Di_GetContext ();
371390 if (!(ctx -> flags & C2DiF_Active ))
372391 return false;
373- if (6 > (ctx -> vtxBufSize - ctx -> vtxBufPos ))
392+ if (! C2Di_CheckBufSpace (ctx , 6 , 4 ))
374393 return false;
375394
376395 C2Di_SetMode ((ctx -> flags & C2DiF_TintMode_Mask ) >> (C2DiF_TintMode_Shift - C2DiF_Mode_Shift ));
@@ -407,15 +426,11 @@ bool C2D_DrawImage(C2D_Image img, const C2D_DrawParams* params, const C2D_ImageT
407426 const C2D_Tint * tintBotLeft = tint ? & tint -> corners [C2D_BotLeft ] : & s_defaultTint ;
408427 const C2D_Tint * tintBotRight = tint ? & tint -> corners [C2D_BotRight ] : & s_defaultTint ;
409428
410- // Draw triangles
429+ C2Di_AppendQuad ();
411430 C2Di_AppendVtx (quad .topLeft [0 ], quad .topLeft [1 ], params -> depth , tcTopLeft [0 ], tcTopLeft [1 ], 0 , tintTopLeft -> blend , tintTopLeft -> color );
431+ C2Di_AppendVtx (quad .topRight [0 ], quad .topRight [1 ], params -> depth , tcTopRight [0 ], tcTopRight [1 ], 0 , tintTopRight -> blend , tintTopRight -> color );
412432 C2Di_AppendVtx (quad .botLeft [0 ], quad .botLeft [1 ], params -> depth , tcBotLeft [0 ], tcBotLeft [1 ], 0 , tintBotLeft -> blend , tintBotLeft -> color );
413433 C2Di_AppendVtx (quad .botRight [0 ], quad .botRight [1 ], params -> depth , tcBotRight [0 ], tcBotRight [1 ], 0 , tintBotRight -> blend , tintBotRight -> color );
414-
415- C2Di_AppendVtx (quad .topLeft [0 ], quad .topLeft [1 ], params -> depth , tcTopLeft [0 ], tcTopLeft [1 ], 0 , tintTopLeft -> blend , tintTopLeft -> color );
416- C2Di_AppendVtx (quad .botRight [0 ], quad .botRight [1 ], params -> depth , tcBotRight [0 ], tcBotRight [1 ], 0 , tintBotRight -> blend , tintBotRight -> color );
417- C2Di_AppendVtx (quad .topRight [0 ], quad .topRight [1 ], params -> depth , tcTopRight [0 ], tcTopRight [1 ], 0 , tintTopRight -> blend , tintTopRight -> color );
418-
419434 return true;
420435}
421436
@@ -424,12 +439,13 @@ bool C2D_DrawTriangle(float x0, float y0, u32 clr0, float x1, float y1, u32 clr1
424439 C2Di_Context * ctx = C2Di_GetContext ();
425440 if (!(ctx -> flags & C2DiF_Active ))
426441 return false;
427- if (3 > (ctx -> vtxBufSize - ctx -> vtxBufPos ))
442+ if (! C2Di_CheckBufSpace (ctx , 3 , 3 ))
428443 return false;
429444
430445 C2Di_SetMode (C2DiF_Mode_Solid );
431446 C2Di_Update ();
432447
448+ C2Di_AppendTri ();
433449 C2Di_AppendVtx (x0 , y0 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
434450 C2Di_AppendVtx (x1 , y1 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
435451 C2Di_AppendVtx (x2 , y2 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr2 );
@@ -441,7 +457,7 @@ bool C2D_DrawLine(float x0, float y0, u32 clr0, float x1, float y1, u32 clr1, fl
441457 C2Di_Context * ctx = C2Di_GetContext ();
442458 if (!(ctx -> flags & C2DiF_Active ))
443459 return false;
444- if (6 > (ctx -> vtxBufSize - ctx -> vtxBufPos ))
460+ if (! C2Di_CheckBufSpace (ctx , 6 , 4 ))
445461 return false;
446462
447463 float dx = x1 - x0 , dy = y1 - y0 , len = sqrtf (dx * dx + dy * dy ), th = thickness /2 ;
@@ -451,13 +467,11 @@ bool C2D_DrawLine(float x0, float y0, u32 clr0, float x1, float y1, u32 clr1, fl
451467 C2Di_SetMode (C2DiF_Mode_Solid );
452468 C2Di_Update ();
453469
470+ C2Di_AppendQuad ();
454471 C2Di_AppendVtx (px0 , py0 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
472+ C2Di_AppendVtx (px3 , py3 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
455473 C2Di_AppendVtx (px1 , py1 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
456474 C2Di_AppendVtx (px2 , py2 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
457-
458- C2Di_AppendVtx (px2 , py2 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
459- C2Di_AppendVtx (px3 , py3 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
460- C2Di_AppendVtx (px0 , py0 , depth , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
461475 return true;
462476}
463477
@@ -466,19 +480,17 @@ bool C2D_DrawRectangle(float x, float y, float z, float w, float h, u32 clr0, u3
466480 C2Di_Context * ctx = C2Di_GetContext ();
467481 if (!(ctx -> flags & C2DiF_Active ))
468482 return false;
469- if (6 > (ctx -> vtxBufSize - ctx -> vtxBufPos ))
483+ if (! C2Di_CheckBufSpace (ctx , 6 , 4 ))
470484 return false;
471485
472486 C2Di_SetMode (C2DiF_Mode_Solid );
473487 C2Di_Update ();
474488
489+ C2Di_AppendQuad ();
475490 C2Di_AppendVtx (x , y , z , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
491+ C2Di_AppendVtx (x + w , y , z , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
476492 C2Di_AppendVtx (x , y + h , z , 0.0f , 0.0f , 0.0f , 0.0f , clr2 );
477493 C2Di_AppendVtx (x + w , y + h , z , 0.0f , 0.0f , 0.0f , 0.0f , clr3 );
478-
479- C2Di_AppendVtx (x , y , z , 0.0f , 0.0f , 0.0f , 0.0f , clr0 );
480- C2Di_AppendVtx (x + w , y + h , z , 0.0f , 0.0f , 0.0f , 0.0f , clr3 );
481- C2Di_AppendVtx (x + w , y , z , 0.0f , 0.0f , 0.0f , 0.0f , clr1 );
482494 return true;
483495}
484496
@@ -487,22 +499,45 @@ bool C2D_DrawEllipse(float x, float y, float z, float w, float h, u32 clr0, u32
487499 C2Di_Context * ctx = C2Di_GetContext ();
488500 if (!(ctx -> flags & C2DiF_Active ))
489501 return false;
490- if (6 > (ctx -> vtxBufSize - ctx -> vtxBufPos ))
502+ if (! C2Di_CheckBufSpace (ctx , 6 , 4 ))
491503 return false;
492504
493505 C2Di_SetMode (C2DiF_Mode_Circle );
494506 C2Di_Update ();
495507
508+ C2Di_AppendQuad ();
496509 C2Di_AppendVtx (x , y , z , 0.0f , 0.0f , -1.0f , -1.0f , clr0 );
510+ C2Di_AppendVtx (x + w , y , z , 0.0f , 0.0f , 1.0f , -1.0f , clr1 );
497511 C2Di_AppendVtx (x , y + h , z , 0.0f , 0.0f , -1.0f , 1.0f , clr2 );
498512 C2Di_AppendVtx (x + w , y + h , z , 0.0f , 0.0f , 1.0f , 1.0f , clr3 );
499-
500- C2Di_AppendVtx (x , y , z , 0.0f , 0.0f , -1.0f , -1.0f , clr0 );
501- C2Di_AppendVtx (x + w , y + h , z , 0.0f , 0.0f , 1.0f , 1.0f , clr3 );
502- C2Di_AppendVtx (x + w , y , z , 0.0f , 0.0f , 1.0f , -1.0f , clr1 );
503513 return true;
504514}
505515
516+ void C2Di_AppendTri (void )
517+ {
518+ C2Di_Context * ctx = C2Di_GetContext ();
519+ u16 * idx = & ctx -> idxBuf [ctx -> idxBufPos ];
520+ ctx -> idxBufPos += 3 ;
521+
522+ * idx ++ = ctx -> vtxBufPos + 0 ;
523+ * idx ++ = ctx -> vtxBufPos + 1 ;
524+ * idx ++ = ctx -> vtxBufPos + 2 ;
525+ }
526+
527+ void C2Di_AppendQuad (void )
528+ {
529+ C2Di_Context * ctx = C2Di_GetContext ();
530+ u16 * idx = & ctx -> idxBuf [ctx -> idxBufPos ];
531+ ctx -> idxBufPos += 6 ;
532+
533+ * idx ++ = ctx -> vtxBufPos + 0 ;
534+ * idx ++ = ctx -> vtxBufPos + 2 ;
535+ * idx ++ = ctx -> vtxBufPos + 1 ;
536+ * idx ++ = ctx -> vtxBufPos + 1 ;
537+ * idx ++ = ctx -> vtxBufPos + 2 ;
538+ * idx ++ = ctx -> vtxBufPos + 3 ;
539+ }
540+
506541void C2Di_AppendVtx (float x , float y , float z , float u , float v , float ptx , float pty , u32 color )
507542{
508543 C2Di_Context * ctx = C2Di_GetContext ();
@@ -520,10 +555,10 @@ void C2Di_AppendVtx(float x, float y, float z, float u, float v, float ptx, floa
520555void C2Di_FlushVtxBuf (void )
521556{
522557 C2Di_Context * ctx = C2Di_GetContext ();
523- size_t len = ctx -> vtxBufPos - ctx -> vtxBufLastPos ;
558+ size_t len = ctx -> idxBufPos - ctx -> idxBufLastPos ;
524559 if (!len ) return ;
525- C3D_DrawArrays (GPU_TRIANGLES , ctx -> vtxBufLastPos , len );
526- ctx -> vtxBufLastPos = ctx -> vtxBufPos ;
560+ C3D_DrawElements (GPU_TRIANGLES , len , C3D_UNSIGNED_SHORT , & ctx -> idxBuf [ ctx -> idxBufLastPos ] );
561+ ctx -> idxBufLastPos = ctx -> idxBufPos ;
527562}
528563
529564void C2Di_Update (void )
0 commit comments