Support custom texture on shapes drawing

By default, internal white texture was used to draw most of the shapes; some time ago, support for white font character from default internal font was added. That way, all basic drawing (shapes, text) could be performed without a texture change and in a single drawing pass.

Now, we move a step further and we allow configuring the texture (and rectangle) used to do the shapes drawing.
This commit is contained in:
Ray 2018-11-06 15:06:01 +01:00
parent c79b342f0b
commit e340517a73
2 changed files with 86 additions and 137 deletions

View File

@ -970,7 +970,7 @@ RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color);
RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color colors[static 4]); // Draw a color-filled rectangle with pro parameters
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
@ -982,6 +982,8 @@ RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Col
RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Define default texture used to draw shapes
// Basic shapes collision detection functions // Basic shapes collision detection functions
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles

View File

@ -54,12 +54,14 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// ... static Texture2D texShapes = { 0 };
static Rectangle recTexShapes = { 0 };
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static float EaseCubicInOut(float t, float b, float c, float d); // Cubic easing static float EaseCubicInOut(float t, float b, float c, float d); // Cubic easing
static Texture2D GetShapesTexture(void); // Get texture to draw shapes
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition // Module Functions Definition
@ -121,7 +123,7 @@ void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color)
float d = sqrtf(dx*dx + dy*dy); float d = sqrtf(dx*dx + dy*dy);
float angle = asinf(dy/d); float angle = asinf(dy/d);
rlEnableTexture(GetTextureDefault().id); rlEnableTexture(GetShapesTexture().id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef((float)startPos.x, (float)startPos.y, 0); rlTranslatef((float)startPos.x, (float)startPos.y, 0);
@ -195,16 +197,23 @@ void DrawCircleV(Vector2 center, float radius, Color color)
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(RL_QUADS, 4*(36/2))) rlglDraw(); if (rlCheckBufferLimit(RL_QUADS, 4*(36/2))) rlglDraw();
rlEnableTexture(GetTextureDefault().id); // Default white texture rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
for (int i = 0; i < 360; i += 20) for (int i = 0; i < 360; i += 20)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius); rlVertex2f(center.x + sinf(DEG2RAD*i)*radius, center.y + cosf(DEG2RAD*i)*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(i + 10))*radius, center.y + cosf(DEG2RAD*(i + 10))*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(center.x + sinf(DEG2RAD*(i + 20))*radius, center.y + cosf(DEG2RAD*(i + 20))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(i + 20))*radius, center.y + cosf(DEG2RAD*(i + 20))*radius);
} }
rlEnd(); rlEnd();
@ -246,104 +255,55 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
// Draw a color-filled rectangle // Draw a color-filled rectangle
void DrawRectangle(int posX, int posY, int width, int height, Color color) void DrawRectangle(int posX, int posY, int width, int height, Color color)
{ {
Vector2 position = { (float)posX, (float)posY }; DrawRectangleV((Vector2){ (float)posX, (float)posY }, (Vector2){ (float)width, (float)height }, color);
Vector2 size = { (float)width, (float)height };
DrawRectangleV(position, size, color);
} }
// Draw a color-filled rectangle (Vector version) // Draw a color-filled rectangle (Vector version)
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw) // NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw)
void DrawRectangleV(Vector2 position, Vector2 size, Color color) void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) Color colors[4] = { color, color, color, color };
#if defined(SUPPORT_FONT_TEXTURE)
// Draw rectangle using font texture white character
rlEnableTexture(GetFontDefault().texture.id);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 0.0f, 1.0f);
// NOTE: Default raylib font character 95 is a white square
rlTexCoord2f((float)GetFontDefault().chars[95].rec.x/GetFontDefault().texture.width,
(float)GetFontDefault().chars[95].rec.y/GetFontDefault().texture.height);
rlVertex2f(position.x, position.y);
rlTexCoord2f((float)GetFontDefault().chars[95].rec.x/GetFontDefault().texture.width,
(float)(GetFontDefault().chars[95].rec.y + GetFontDefault().chars[95].rec.height)/GetFontDefault().texture.height);
rlVertex2f(position.x, position.y + size.y);
rlTexCoord2f((float)(GetFontDefault().chars[95].rec.x + GetFontDefault().chars[95].rec.width)/GetFontDefault().texture.width,
(float)(GetFontDefault().chars[95].rec.y + GetFontDefault().chars[95].rec.height)/GetFontDefault().texture.height);
rlVertex2f(position.x + size.x, position.y + size.y);
rlTexCoord2f((float)(GetFontDefault().chars[95].rec.x + GetFontDefault().chars[95].rec.width)/GetFontDefault().texture.width,
(float)GetFontDefault().chars[95].rec.y/GetFontDefault().texture.height);
rlVertex2f(position.x + size.x, position.y);
rlEnd();
rlDisableTexture(); DrawRectanglePro((Rectangle){ position.x, position.y, size.x, size.y }, (Vector2){ 0.0f, 0.0f }, 0.0f, colors);
#else
rlEnableTexture(GetTextureDefault().id); // Default white texture
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
rlNormal3f(0.0f, 0.0f, 1.0f);
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(position.x, position.y);
rlTexCoord2f(0.0f, 1.0f);
rlVertex2f(position.x, position.y + size.y);
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f(position.x + size.x, position.y + size.y);
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f(position.x + size.x, position.y);
rlEnd();
rlDisableTexture();
#endif // SUPPORT_FONT_TEXTURE
#else
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x, position.y);
rlVertex2i(position.x + size.x, position.y + size.y);
rlVertex2i(position.x + size.x, position.y);
rlEnd();
#endif // SUPPORT_QUADS_DRAW_MODE
} }
// Draw a color-filled rectangle // Draw a color-filled rectangle
void DrawRectangleRec(Rectangle rec, Color color) void DrawRectangleRec(Rectangle rec, Color color)
{ {
DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, color); Color colors[4] = { color, color, color, color };
DrawRectanglePro(rec, (Vector2){ 0.0f, 0.0f }, 0.0f, colors);
} }
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color) // Draw a color-filled rectangle with pro parameters
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color colors[static 4])
{ {
rlEnableTexture(GetTextureDefault().id); rlEnableTexture(GetShapesTexture().id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(rec.x, rec.y, 0); //rlTranslatef(rec.x, rec.y, 0); // Already considered on vertex position
rlRotatef(rotation, 0, 0, 1); rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0); rlTranslatef(-origin.x, -origin.y, 0);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlNormal3f(0.0f, 0.0f, 1.0f);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
rlVertex2f(0.0f, 0.0f); // NOTE: Default raylib font character 95 is a white square
rlVertex2f(0.0f, rec.height); rlColor4ub(colors[0].r, colors[0].g, colors[0].b, colors[0].a);
rlVertex2f(rec.width, rec.height); rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(rec.width, 0.0f); rlVertex2f(rec.x, rec.y);
rlColor4ub(colors[1].r, colors[1].g, colors[1].b, colors[1].a);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(rec.x, rec.y + rec.height);
rlColor4ub(colors[2].r, colors[2].g, colors[2].b, colors[2].a);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(rec.x + rec.width, rec.y + rec.height);
rlColor4ub(colors[3].r, colors[3].g, colors[3].b, colors[3].a);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(rec.x + rec.width, rec.y);
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
@ -368,61 +328,9 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col
// NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise // NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4) void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4)
{ {
#if defined(SUPPORT_FONT_TEXTURE) Color colors[4] = { col1, col2, col3, col4 };
// Draw rectangle using font texture white character
rlEnableTexture(GetFontDefault().texture.id);
rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f);
// NOTE: Default raylib font character 95 is a white square
rlColor4ub(col1.r, col1.g, col1.b, col1.a);
rlTexCoord2f(GetFontDefault().chars[95].rec.x/GetFontDefault().texture.width,
GetFontDefault().chars[95].rec.y/GetFontDefault().texture.height);
rlVertex2f(rec.x, rec.y);
rlColor4ub(col2.r, col2.g, col2.b, col2.a);
rlTexCoord2f(GetFontDefault().chars[95].rec.x/GetFontDefault().texture.width,
(GetFontDefault().chars[95].rec.y + GetFontDefault().chars[95].rec.height)/GetFontDefault().texture.height);
rlVertex2f(rec.x, rec.y + rec.height);
rlColor4ub(col3.r, col3.g, col3.b, col3.a);
rlTexCoord2f((GetFontDefault().chars[95].rec.x + GetFontDefault().chars[95].rec.width)/GetFontDefault().texture.width,
(GetFontDefault().chars[95].rec.y + GetFontDefault().chars[95].rec.height)/GetFontDefault().texture.height);
rlVertex2f(rec.x + rec.width, rec.y + rec.height);
rlColor4ub(col4.r, col4.g, col4.b, col4.a);
rlTexCoord2f((GetFontDefault().chars[95].rec.x + GetFontDefault().chars[95].rec.width)/GetFontDefault().texture.width,
GetFontDefault().chars[95].rec.y/GetFontDefault().texture.height);
rlVertex2f(rec.x + rec.width, rec.y);
rlEnd();
rlDisableTexture(); DrawRectanglePro(rec, (Vector2){ 0.0f, 0.0f }, 0.0f, colors);
#else
rlEnableTexture(GetTextureDefault().id); // Default white texture
rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f);
rlColor4ub(col1.r, col1.g, col1.b, col1.a);
rlTexCoord2f(0.0f, 0.0f);
rlVertex2f(rec.x, rec.y);
rlColor4ub(col2.r, col2.g, col2.b, col2.a);
rlTexCoord2f(0.0f, 1.0f);
rlVertex2f(rec.x, rec.y + rec.height);
rlColor4ub(col3.r, col3.g, col3.b, col3.a);
rlTexCoord2f(1.0f, 1.0f);
rlVertex2f(rec.x + rec.width, rec.y + rec.height);
rlColor4ub(col4.r, col4.g, col4.b, col4.a);
rlTexCoord2f(1.0f, 0.0f);
rlVertex2f(rec.x + rec.width, rec.y);
rlEnd();
rlDisableTexture();
#endif
} }
// Draw rectangle outline // Draw rectangle outline
@ -471,13 +379,21 @@ void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color)
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlEnableTexture(GetTextureDefault().id); // Default white texture rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(v1.x, v1.y); rlVertex2f(v1.x, v1.y);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(v2.x, v2.y); rlVertex2f(v2.x, v2.y);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(v2.x, v2.y); rlVertex2f(v2.x, v2.y);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(v3.x, v3.y); rlVertex2f(v3.x, v3.y);
rlEnd(); rlEnd();
@ -520,16 +436,23 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
rlRotatef(rotation, 0, 0, 1); rlRotatef(rotation, 0, 0, 1);
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlEnableTexture(GetTextureDefault().id); // Default white texture rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
for (int i = 0; i < 360; i += 360/sides) for (int i = 0; i < 360; i += 360/sides)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(recTexShapes.x/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(0, 0); rlVertex2f(0, 0);
rlTexCoord2f(recTexShapes.x/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius); rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, (recTexShapes.y + recTexShapes.height)/texShapes.height);
rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius); rlVertex2f(sinf(DEG2RAD*i)*radius, cosf(DEG2RAD*i)*radius);
rlTexCoord2f((recTexShapes.x + recTexShapes.width)/texShapes.width, recTexShapes.y/texShapes.height);
rlVertex2f(sinf(DEG2RAD*(i + 360/sides))*radius, cosf(DEG2RAD*(i + 360/sides))*radius); rlVertex2f(sinf(DEG2RAD*(i + 360/sides))*radius, cosf(DEG2RAD*(i + 360/sides))*radius);
} }
rlEnd(); rlEnd();
@ -557,7 +480,7 @@ void DrawPolyEx(Vector2 *points, int pointsCount, Color color)
if (rlCheckBufferLimit(RL_QUADS, pointsCount)) rlglDraw(); if (rlCheckBufferLimit(RL_QUADS, pointsCount)) rlglDraw();
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlEnableTexture(GetTextureDefault().id); // Default white texture rlEnableTexture(GetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -605,6 +528,13 @@ void DrawPolyExLines(Vector2 *points, int pointsCount, Color color)
} }
} }
// Define default texture used to draw shapes
void SetShapesTexture(Texture2D texture, Rectangle source)
{
texShapes = texture;
recTexShapes = source;
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Definition - Collision Detection functions // Module Functions Definition - Collision Detection functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -771,3 +701,20 @@ static float EaseCubicInOut(float t, float b, float c, float d)
t -= 2; t -= 2;
return 0.5f*c*(t*t*t + 2.0f) + b; return 0.5f*c*(t*t*t + 2.0f) + b;
} }
// Get texture to draw shapes (RAII)
static Texture2D GetShapesTexture(void)
{
if (texShapes.id <= 0)
{
#if defined(SUPPORT_FONT_TEXTURE)
texShapes = GetFontDefault().texture; // Use font texture white character
recTexShapes = GetFontDefault().chars[95].rec;
#else
texShapes = GetTextureDefault(); // Use default white texture
recTexShapes = { 0.0f, 0.0f, 1.0f, 1.0f };
#endif
}
return texShapes;
}