Răsfoiți Sursa

Graphics.DrawLine, DrawBatch fixes

Brian Fiete 2 ani în urmă
părinte
comite
40f3baf127

+ 3 - 0
BeefLibs/Beefy2D/src/geom/Point.bf

@@ -14,5 +14,8 @@ namespace Beefy.geom
             this.x = x;
             this.y = y;
         }
+
+		public static Point operator-(Self lhs, Self rhs) => .(lhs.x - rhs.x, lhs.y - rhs.y);
+		public static Point operator+(Self lhs, Self rhs) => .(lhs.x + rhs.x, lhs.y + rhs.y);
     }
 }

+ 36 - 1
BeefLibs/Beefy2D/src/gfx/Graphics.bf

@@ -47,6 +47,7 @@ namespace Beefy.gfx
         public RenderState mDefaultRenderState ~ delete _;
         public Font mFont;
         public Image mWhiteDot ~ delete _;
+		public List<Image> mWhiteBorderedSquares = new .() ~ DeleteContainerAndItems!(_);
         public float ZDepth { get; set; }
         
         protected DisposeProxy mMatrixDisposeProxy ~ delete _;
@@ -512,6 +513,15 @@ namespace Beefy.gfx
             Gfx_SetRenderState(mRenderStateStack[--mRenderStateStackIdx].mNativeRenderState);            
         }
 
+		public Image GetBorderedWhiteSquare(int borderSize)
+		{
+			if (borderSize >= mWhiteBorderedSquares.Count)
+				mWhiteBorderedSquares.Count = borderSize + 1;
+			if (mWhiteBorderedSquares[borderSize] == null)
+				mWhiteBorderedSquares[borderSize] = Image.LoadFromFile(scope $"!square{borderSize}");
+			return mWhiteBorderedSquares[borderSize];
+		}
+
         public void Draw(RenderCmd renderCmd)
         {
             Gfx_QueueRenderCmd(renderCmd.mNativeRenderCmd);
@@ -919,7 +929,32 @@ namespace Beefy.gfx
             Gfx_CopyDrawVertex(4, 1);
             Gfx_SetDrawVertex(5, m.tx + (m.a + m.c), m.ty + (m.b + m.d), 0, 0, 0, Color.Mult(mColor, colorBotRight));
         }
-        
+
+		public void DrawLine(float x0, float y0, float x1, float y1, float width = 1.0f)
+		{
+			Image img = GetBorderedWhiteSquare(Math.Max((int)width, 1));
+
+			float ang = Math.Atan2(y1 - y0, x1 - x0);
+
+			// Add 1 pixel to account for transparent border
+			float radius = (width / 2) + 1;
+
+			float xOfs = Math.Cos(ang + Math.PI_f / 2) * radius;
+			float yOfs = Math.Sin(ang + Math.PI_f / 2) * radius;
+
+			//TODO: Multiply color
+
+			Gfx_AllocTris(img.mNativeTextureSegment, 6);
+
+			Gfx_SetDrawVertex(0, x0 - xOfs, y0 - yOfs, 0, 0, 0.5f, mColor);
+			Gfx_SetDrawVertex(1, x0 + xOfs, y0 + yOfs, 0, 1.0f, 0.5f, mColor);
+			Gfx_SetDrawVertex(2, x1 - xOfs, y1 - yOfs, 0, 0, 0.5f, mColor);
+
+			Gfx_CopyDrawVertex(3, 2);
+			Gfx_CopyDrawVertex(4, 1);
+			Gfx_SetDrawVertex(5, x1 + xOfs, y1 + yOfs, 0, 1.0f, 0.5f, mColor);
+		}
+
         public void PolyStart(Image image, int32 vertices)
         {
             Gfx_AllocTris(image.mNativeTextureSegment, vertices);            

+ 13 - 13
BeefySysLib/gfx/DrawLayer.cpp

@@ -68,11 +68,12 @@ void* DrawBatch::AllocTris(int vtxCount)
 {
 	int idxCount = vtxCount;
 
-	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx >= mAllocatedIndices))
+	bool fits = (idxCount + mIdxIdx <= mAllocatedIndices) && (vtxCount + mVtxIdx <= mAllocatedVertices);
+	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (!fits))
 	{
-		if (mVtxIdx > 0)
+		if ((mVtxIdx > 0) || (!fits))
 		{
-			DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
+			DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);
 			return nextBatch->AllocTris(vtxCount);
 		}
 
@@ -95,11 +96,12 @@ void* DrawBatch::AllocStrip(int vtxCount)
 {
 	int idxCount = (vtxCount - 2) * 3;
 
-	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx >= mAllocatedIndices))
+	bool fits = (idxCount + mIdxIdx <= mAllocatedIndices) && (vtxCount + mVtxIdx <= mAllocatedVertices);
+	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (!fits))
 	{
-		if (mVtxIdx > 0)
+		if ((mVtxIdx > 0) || (!fits))
 		{
-			DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
+			DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);
 			return nextBatch->AllocStrip(vtxCount);
 		}
 
@@ -126,9 +128,10 @@ void* DrawBatch::AllocStrip(int vtxCount)
 
 void DrawBatch::AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut)
 {
-	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx > mAllocatedIndices))
+	bool fits = (idxCount + mIdxIdx <= mAllocatedIndices) && (vtxCount + mVtxIdx <= mAllocatedVertices);
+	if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (!fits))
 	{
-		if (mVtxIdx > 0)
+		if ((mVtxIdx > 0) || (!fits))
 		{
 			DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);
 			return nextBatch->AllocIndexed(vtxCount, idxCount, verticesOut, indicesOut, idxOfsOut);
@@ -190,11 +193,8 @@ DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
 	BF_ASSERT(mRenderDevice->mCurRenderState->mShader != NULL);
 	int vtxSize = mRenderDevice->mCurRenderState->mShader->mVertexSize;
 
-	if (minIdxCount == 0)
-	{
-		minIdxCount = 512;
-		minVtxCount = minIdxCount;
-	}
+	minIdxCount = BF_MAX(minIdxCount, 512);
+	minVtxCount = BF_MAX(minIdxCount, 512);
 
 	BF_ASSERT(minIdxCount * sizeof(uint16) <= DRAWBUFFER_IDXBUFFER_SIZE);
 	BF_ASSERT(minVtxCount * vtxSize <= DRAWBUFFER_VTXBUFFER_SIZE);

+ 14 - 0
BeefySysLib/gfx/RenderDevice.cpp

@@ -120,6 +120,20 @@ Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
 		imageData->mBits[0] = 0xFFFFFFFF;
 		handled = true;
 	}
+	else if (fileName.StartsWith("!square"))
+	{
+		int squareSize = atoi(fileName.c_str() + 7);
+		imageData = new ImageData();
+		imageData->CreateNew(squareSize + 2, squareSize + 2, true);
+		for (int y = 0; y < squareSize; y++)
+		{
+			for (int x = 0; x < squareSize; x++)
+			{
+				imageData->mBits[(y + 1) * (squareSize + 2) + x + 1] = 0xFFFFFFFF;
+			}
+		}
+		handled = true;
+	}
 	else if (ext == ".tga")
 		imageData = new TGAData();
 	else if (ext == ".png")