Browse Source

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
pull/1657/head
Chris 4 years ago
committed by GitHub
parent
commit
45670fbf2d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 113 additions and 55 deletions
  1. +54
    -25
      src/shapes.c
  2. +59
    -30
      src/textures.c

+ 54
- 25
src/shapes.c View File

@ -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 View File

@ -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();
} }
} }

Loading…
Cancel
Save