Prechádzať zdrojové kódy

Optimize DrawTexturePro and DrawRectanglePro transformations (#1632)

* Optimize DrawTexturePro and DrawRectanglePro transformations
- Add check so rotation is only applied if rotation != 0.0f.
- Replace matrix usage by calculating the vertex data directly.

* Fix error with windows build and trim whitespace
Chris 4 rokov pred
rodič
commit
45670fbf2d
2 zmenil súbory, kde vykonal 113 pridanie a 55 odobranie
  1. 54 25
      src/shapes.c
  2. 59 30
      src/textures.c

+ 54 - 25
src/shapes.c

@@ -119,11 +119,11 @@ void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color)
     Vector2 delta = {endPos.x-startPos.x, endPos.y-startPos.y};
     Vector2 delta = {endPos.x-startPos.x, endPos.y-startPos.y};
     float   length = sqrtf(delta.x*delta.x + delta.y*delta.y);
     float   length = sqrtf(delta.x*delta.x + delta.y*delta.y);
 
 
-    if (length > 0  &&  thick > 0) 
+    if (length > 0  &&  thick > 0)
     {
     {
         float   scale = thick/(2*length);
         float   scale = thick/(2*length);
         Vector2 radius = {-scale*delta.y, scale*delta.x};
         Vector2 radius = {-scale*delta.y, scale*delta.x};
-        Vector2 strip[] = {{startPos.x-radius.x, startPos.y-radius.y}, {startPos.x+radius.x, startPos.y+radius.y}, 
+        Vector2 strip[] = {{startPos.x-radius.x, startPos.y-radius.y}, {startPos.x+radius.x, startPos.y+radius.y},
                            {endPos.x-radius.x, endPos.y-radius.y}, {endPos.x+radius.x, endPos.y+radius.y}};
                            {endPos.x-radius.x, endPos.y-radius.y}, {endPos.x+radius.x, endPos.y+radius.y}};
 
 
         DrawTriangleStrip(strip, 4, color);
         DrawTriangleStrip(strip, 4, color);
@@ -157,24 +157,24 @@ void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
 void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color)
 void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color)
 {
 {
     const float step = 1.0f/BEZIER_LINE_DIVISIONS;
     const float step = 1.0f/BEZIER_LINE_DIVISIONS;
-    
+
     Vector2 previous = startPos;
     Vector2 previous = startPos;
     Vector2 current = { 0 };
     Vector2 current = { 0 };
     float t = 0.0f;
     float t = 0.0f;
-    
+
     for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++)
     for (int i = 0; i <= BEZIER_LINE_DIVISIONS; i++)
     {
     {
         t = step*i;
         t = step*i;
         float a = powf(1 - t, 2);
         float a = powf(1 - t, 2);
         float b = 2*(1 - t)*t;
         float b = 2*(1 - t)*t;
         float c = powf(t, 2);
         float c = powf(t, 2);
-        
+
         // NOTE: The easing functions aren't suitable here because they don't take a control point
         // NOTE: The easing functions aren't suitable here because they don't take a control point
         current.y = a*startPos.y + b*controlPos.y + c*endPos.y;
         current.y = a*startPos.y + b*controlPos.y + c*endPos.y;
         current.x = a*startPos.x + b*controlPos.x + c*endPos.x;
         current.x = a*startPos.x + b*controlPos.x + c*endPos.x;
-        
+
         DrawLineEx(previous,current,thick,color);
         DrawLineEx(previous,current,thick,color);
-        
+
         previous = current;
         previous = current;
     }
     }
 }
 }
@@ -619,31 +619,60 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
 {
 {
     if (rlCheckBufferLimit(4)) rlglDraw();
     if (rlCheckBufferLimit(4)) rlglDraw();
 
 
-    rlEnableTexture(GetShapesTexture().id);
+    Vector2 bl = { 0 };
+    Vector2 br = { 0 };
+    Vector2 tr = { 0 };
+    Vector2 tl = { 0 };
 
 
-    rlPushMatrix();
-        rlTranslatef(rec.x, rec.y, 0.0f);
-        rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
-        rlTranslatef(-origin.x, -origin.y, 0.0f);
+    // Only calculate rotation if needed
+    if (rotation == 0.0f)
+    {
+        float x = rec.x - origin.x;
+        float y = rec.y - origin.y;
+        bl = (Vector2){ x, y };
+        br = (Vector2){ x, y + rec.height };
+        tr = (Vector2){ x + rec.width, y + rec.height };
+        tl = (Vector2){ x + rec.width, y };
+    }
+    else
+    {
+        float sinRotation = sinf(rotation * DEG2RAD);
+        float cosRotation = cosf(rotation * DEG2RAD);
+        float x = rec.x;
+        float y = rec.y;
+        float dx = -origin.x;
+        float dy = -origin.y;
 
 
-        rlBegin(RL_QUADS);
-            rlNormal3f(0.0f, 0.0f, 1.0f);
-            rlColor4ub(color.r, color.g, color.b, color.a);
+        bl.x = x + dx * cosRotation - (dy + rec.height) * sinRotation;
+        bl.y = y + dx * sinRotation + (dy + rec.height) * cosRotation;
 
 
-            rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height);
-            rlVertex2f(0.0f, 0.0f);
+        br.x = x + (dx + rec.width) * cosRotation - (dy + rec.height) * sinRotation;
+        br.y = y + (dx + rec.width) * sinRotation + (dy + rec.height) * cosRotation;
 
 
-            rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height);
-            rlVertex2f(0.0f, rec.height);
+        tr.x = x + (dx + rec.width) * cosRotation - dy * sinRotation;
+        tr.y = y + (dx + rec.width) * sinRotation + dy * cosRotation;
 
 
-            rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height);
-            rlVertex2f(rec.width, rec.height);
+        tl.x = x + dx * cosRotation - dy * sinRotation;
+        tl.y = y + dx * sinRotation + dy * cosRotation;
+    }
 
 
-            rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height);
-            rlVertex2f(rec.width, 0.0f);
-        rlEnd();
-    rlPopMatrix();
+    rlEnableTexture(GetShapesTexture().id);
+    rlBegin(RL_QUADS);
+        rlNormal3f(0.0f, 0.0f, 1.0f);
+        rlColor4ub(color.r, color.g, color.b, color.a);
 
 
+        rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height);
+        rlVertex2f(bl.x, bl.y);
+
+        rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height);
+        rlVertex2f(br.x, br.y);
+
+        rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height);
+        rlVertex2f(tr.x, tr.y);
+
+        rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height);
+        rlVertex2f(tl.x, tl.y);
+    rlEnd();
     rlDisableTexture();
     rlDisableTexture();
 }
 }
 
 

+ 59 - 30
src/textures.c

@@ -3200,39 +3200,68 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
         if (source.width < 0) { flipX = true; source.width *= -1; }
         if (source.width < 0) { flipX = true; source.width *= -1; }
         if (source.height < 0) source.y -= source.height;
         if (source.height < 0) source.y -= source.height;
 
 
-        rlEnableTexture(texture.id);
+        Vector2 bl = { 0 };
+        Vector2 br = { 0 };
+        Vector2 tr = { 0 };
+        Vector2 tl = { 0 };
 
 
-        rlPushMatrix();
-            rlTranslatef(dest.x, dest.y, 0.0f);
-            rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
-            rlTranslatef(-origin.x, -origin.y, 0.0f);
+        // Only calculate rotation if needed
+        if (rotation == 0.0f)
+        {
+            float x = dest.x - origin.x;
+            float y = dest.y - origin.y;
+            bl = (Vector2){ x, y };
+            br = (Vector2){ x, y + dest.height };
+            tr = (Vector2){ x + dest.width, y + dest.height };
+            tl = (Vector2){ x + dest.width, y };
+        }
+        else
+        {
+            float sinRotation = sinf(rotation * DEG2RAD);
+            float cosRotation = cosf(rotation * DEG2RAD);
+            float x = dest.x;
+            float y = dest.y;
+            float dx = -origin.x;
+            float dy = -origin.y;
 
 
-            rlBegin(RL_QUADS);
-                rlColor4ub(tint.r, tint.g, tint.b, tint.a);
-                rlNormal3f(0.0f, 0.0f, 1.0f);                          // Normal vector pointing towards viewer
-
-                // Bottom-left corner for texture and quad
-                if (flipX) rlTexCoord2f((source.x + source.width)/width, source.y/height);
-                else rlTexCoord2f(source.x/width, source.y/height);
-                rlVertex2f(0.0f, 0.0f);
-
-                // Bottom-right corner for texture and quad
-                if (flipX) rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
-                else rlTexCoord2f(source.x/width, (source.y + source.height)/height);
-                rlVertex2f(0.0f, dest.height);
-
-                // Top-right corner for texture and quad
-                if (flipX) rlTexCoord2f(source.x/width, (source.y + source.height)/height);
-                else rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
-                rlVertex2f(dest.width, dest.height);
-
-                // Top-left corner for texture and quad
-                if (flipX) rlTexCoord2f(source.x/width, source.y/height);
-                else rlTexCoord2f((source.x + source.width)/width, source.y/height);
-                rlVertex2f(dest.width, 0.0f);
-            rlEnd();
-        rlPopMatrix();
+            bl.x = x + dx * cosRotation - (dy + dest.height) * sinRotation;
+            bl.y = y + dx * sinRotation + (dy + dest.height) * cosRotation;
+
+            br.x = x + (dx + dest.width) * cosRotation - (dy + dest.height) * sinRotation;
+            br.y = y + (dx + dest.width) * sinRotation + (dy + dest.height) * cosRotation;
 
 
+            tr.x = x + (dx + dest.width) * cosRotation - dy * sinRotation;
+            tr.y = y + (dx + dest.width) * sinRotation + dy * cosRotation;
+
+            tl.x = x + dx * cosRotation - dy * sinRotation;
+            tl.y = y + dx * sinRotation + dy * cosRotation;
+        }
+
+        rlEnableTexture(texture.id);
+        rlBegin(RL_QUADS);
+            rlColor4ub(tint.r, tint.g, tint.b, tint.a);
+            rlNormal3f(0.0f, 0.0f, 1.0f);                          // Normal vector pointing towards viewer
+
+            // Bottom-left corner for texture and quad
+            if (flipX) rlTexCoord2f((source.x + source.width)/width, source.y/height);
+            else rlTexCoord2f(source.x/width, source.y/height);
+            rlVertex2f(bl.x, bl.y);
+
+            // Bottom-right corner for texture and quad
+            if (flipX) rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
+            else rlTexCoord2f(source.x/width, (source.y + source.height)/height);
+            rlVertex2f(br.x, br.y);
+
+            // Top-right corner for texture and quad
+            if (flipX) rlTexCoord2f(source.x/width, (source.y + source.height)/height);
+            else rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
+            rlVertex2f(tr.x, tr.y);
+
+            // Top-left corner for texture and quad
+            if (flipX) rlTexCoord2f(source.x/width, source.y/height);
+            else rlTexCoord2f((source.x + source.width)/width, source.y/height);
+            rlVertex2f(tl.x, tl.y);
+        rlEnd();
         rlDisableTexture();
         rlDisableTexture();
     }
     }
 }
 }