summaryrefslogtreecommitdiffhomepage
path: root/src/textures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/textures.c')
-rw-r--r--src/textures.c119
1 files changed, 57 insertions, 62 deletions
diff --git a/src/textures.c b/src/textures.c
index 43453f73..3a1934b9 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -52,9 +52,9 @@
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
-#include "config.h"
-#include "raylib.h"
+#include "config.h" // Defines module configuration flags
+#include "raylib.h" // Declares module functions
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strcmp(), strrchr(), strncmp()
@@ -568,6 +568,7 @@ void ExportImage(const char *fileName, Image image)
// NOTE: Getting Color array as RGBA unsigned char values
unsigned char *imgData = (unsigned char *)GetImageData(image);
SavePNG(fileName, imgData, image.width, image.height, 4);
+ // FIXME ^ this fails on PLATFORM_WEB, what should we do?
free(imgData);
}
@@ -713,7 +714,7 @@ void ImageFormat(Image *image, int newFormat)
{
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
- for (int i = 0; i < image->width*image->height*3; i += 3, k++)
+ for (int i = 0, k = 0; i < image->width*image->height*3; i += 3, k++)
{
((unsigned char *)image->data)[i] = pixels[k].r;
((unsigned char *)image->data)[i + 1] = pixels[k].g;
@@ -766,7 +767,7 @@ void ImageFormat(Image *image, int newFormat)
{
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
- for (int i = 0; i < image->width*image->height*3; i += 3, k++)
+ for (int i = 0, k = 0; i < image->width*image->height*4; i += 4, k++)
{
((unsigned char *)image->data)[i] = pixels[k].r;
((unsigned char *)image->data)[i + 1] = pixels[k].g;
@@ -787,7 +788,7 @@ void ImageFormat(Image *image, int newFormat)
{
image->data = (float *)malloc(image->width*image->height*3*sizeof(float));
- for (int i = 0; i < image->width*image->height*3; i += 3, k++)
+ for (int i = 0, k = 0; i < image->width*image->height*3; i += 3, k++)
{
((float *)image->data)[i] = (float)pixels[k].r/255.0f;
((float *)image->data)[i + 1] = (float)pixels[k].g/255.0f;
@@ -798,7 +799,7 @@ void ImageFormat(Image *image, int newFormat)
{
image->data = (float *)malloc(image->width*image->height*4*sizeof(float));
- for (int i = 0; i < image->width*image->height*4; i += 4, k++)
+ for (int i = 0, k = 0; i < image->width*image->height*4; i += 4, k++)
{
((float *)image->data)[i] = (float)pixels[k].r/255.0f;
((float *)image->data)[i + 1] = (float)pixels[k].g/255.0f;
@@ -977,13 +978,13 @@ void ImageCrop(Image *image, Rectangle crop)
{
// Start the cropping process
Color *pixels = GetImageData(*image); // Get data as Color pixels array
- Color *cropPixels = (Color *)malloc(crop.width*crop.height*sizeof(Color));
+ Color *cropPixels = (Color *)malloc((int)crop.width*(int)crop.height*sizeof(Color));
- for (int j = crop.y; j < (crop.y + crop.height); j++)
+ for (int j = (int)crop.y; j < (int)(crop.y + crop.height); j++)
{
- for (int i = crop.x; i < (crop.x + crop.width); i++)
+ for (int i = (int)crop.x; i < (int)(crop.x + crop.width); i++)
{
- cropPixels[(j - crop.y)*crop.width + (i - crop.x)] = pixels[j*image->width + i];
+ cropPixels[(j - (int)crop.y)*(int)crop.width + (i - (int)crop.x)] = pixels[j*image->width + i];
}
}
@@ -993,7 +994,7 @@ void ImageCrop(Image *image, Rectangle crop)
UnloadImage(*image);
- *image = LoadImageEx(cropPixels, crop.width, crop.height);
+ *image = LoadImageEx(cropPixels, (int)crop.width, (int)crop.height);
free(cropPixels);
@@ -1312,44 +1313,38 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
UnloadImage(srcCopy); // Source copy not required any more...
- Color srcCol, dstCol;
-
+ Vector4 fsrc, fdst, fout; // float based versions of pixel data
+
// Blit pixels, copy source image into destination
// TODO: Probably out-of-bounds blitting could be considered here instead of so much cropping...
- for (int j = dstRec.y; j < (dstRec.y + dstRec.height); j++)
+ for (int j = (int)dstRec.y; j < (int)(dstRec.y + dstRec.height); j++)
{
- for (int i = dstRec.x; i < (dstRec.x + dstRec.width); i++)
+ for (int i = (int)dstRec.x; i < (int)(dstRec.x + dstRec.width); i++)
{
- // Alpha blending implementation
- dstCol = dstPixels[j*dst->width + i];
- srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
-
- /*
- // Pre-multiply alpha
- Vector3 dstColf = { (float)dstCol.r/255.0f, (float)dstCol.g/255.0f, (float)dstCol.b/255.0f };
- dstColf = Vector3Multiply(dstColf, (float)dstCol.a/255.0f);
- Vector3 srcColf = { (float)srcCol.r/255.0f, (float)srcCol.g/255.0f, (float)srcCol.b/255.0f };
- srcColf = Vector3Multiply(srcColf, (float)srcCol.a/255.0f);
+ // Alpha blending (https://en.wikipedia.org/wiki/Alpha_compositing)
- dstColf = Vector3Add(dstColf, srcColf);
-
- if (dstColf.x > 1.0f) dstColf.x = 1.0f;
- if (dstColf.y > 1.0f) dstColf.y = 1.0f;
- if (dstColf.z > 1.0f) dstColf.z = 1.0f;
-
- dstCol.r = (unsigned char)(dstColf.x*255.0f);
- dstCol.g = (unsigned char)(dstColf.y*255.0f);
- dstCol.b = (unsigned char)(dstColf.z*255.0f);
- dstCol.a = srcCol.a;
- */
+ fdst = ColorNormalize(dstPixels[j*(int)dst->width + i]);
+ fsrc = ColorNormalize(srcPixels[(j - (int)dstRec.y)*(int)dstRec.width + (i - (int)dstRec.x)]);
- dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
- dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
- dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
- //dstCol.a = ((srcCol.a*(srcCol.a - dstCol.a)) >> 8) + dstCol.a;
- dstCol.a = srcCol.a;
+ fout.w = fsrc.w + fdst.w*(1.0f - fsrc.w);
+
+ if (fout.w <= 0.0f)
+ {
+ fout.x = 0.0f;
+ fout.y = 0.0f;
+ fout.z = 0.0f;
+ }
+ else
+ {
+ fout.x = (fsrc.x*fsrc.w + fdst.x*fdst.w*(1 - fsrc.w))/fout.w;
+ fout.y = (fsrc.y*fsrc.w + fdst.y*fdst.w*(1 - fsrc.w))/fout.w;
+ fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w;
+ }
- dstPixels[j*dst->width + i] = dstCol;
+ dstPixels[j*(int)dst->width + i] = (Color){ (unsigned char)(fout.x*255.0f),
+ (unsigned char)(fout.y*255.0f),
+ (unsigned char)(fout.z*255.0f),
+ (unsigned char)(fout.w*255.0f) };
// TODO: Support other blending options
}
@@ -1357,7 +1352,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
UnloadImage(*dst); // NOTE: Only dst->data is unloaded
- *dst = LoadImageEx(dstPixels, dst->width, dst->height);
+ *dst = LoadImageEx(dstPixels, (int)dst->width, (int)dst->height);
ImageFormat(dst, dst->format);
free(srcPixels);
@@ -1369,15 +1364,15 @@ Image ImageText(const char *text, int fontSize, Color color)
{
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
- int spacing = fontSize/defaultFontSize;
+ int spacing = (float)fontSize/defaultFontSize;
- Image imText = ImageTextEx(GetDefaultFont(), text, (float)fontSize, spacing, color);
+ Image imText = ImageTextEx(GetDefaultFont(), text, (float)fontSize, (float)spacing, color);
return imText;
}
// Create an image from text (custom sprite font)
-Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint)
+Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint)
{
int length = strlen(text);
int posX = 0;
@@ -1391,7 +1386,7 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing
// NOTE: glGetTexImage() not available in OpenGL ES
// TODO: This is horrible, retrieving font texture from GPU!!!
- // Define ImageFont struct? or include Image spritefont in SpriteFont struct?
+ // Define ImageFont struct? or include Image spritefont in Font struct?
Image imFont = GetTextureData(font.texture);
ImageColorTint(&imFont, tint); // Apply color tint to font
@@ -1457,7 +1452,7 @@ void ImageDrawRectangle(Image *dst, Vector2 position, Rectangle rec, Color color
{
Image imRec = GenImageColor(rec.width, rec.height, color);
- Rectangle dstRec = { (int)position.x, (int)position.y, imRec.width, imRec.height };
+ Rectangle dstRec = { position.x, position.y, imRec.width, imRec.height };
ImageDraw(dst, imRec, rec, dstRec);
@@ -1468,16 +1463,16 @@ void ImageDrawRectangle(Image *dst, Vector2 position, Rectangle rec, Color color
void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color)
{
// NOTE: For default font, sapcing is set to desired font size / default font size (10)
- ImageDrawTextEx(dst, position, GetDefaultFont(), text, (float)fontSize, fontSize/10, color);
+ ImageDrawTextEx(dst, position, GetDefaultFont(), text, (float)fontSize, (float)fontSize/10, color);
}
// Draw text (custom sprite font) within an image (destination)
-void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color)
+void ImageDrawTextEx(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color)
{
Image imText = ImageTextEx(font, text, fontSize, spacing, color);
Rectangle srcRec = { 0, 0, imText.width, imText.height };
- Rectangle dstRec = { (int)position.x, (int)position.y, imText.width, imText.height };
+ Rectangle dstRec = { position.x, position.y, imText.width, imText.height };
ImageDraw(dst, imText, srcRec, dstRec);
@@ -2026,7 +2021,7 @@ void DrawTextureV(Texture2D texture, Vector2 position, Color tint)
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
{
Rectangle sourceRec = { 0, 0, texture.width, texture.height };
- Rectangle destRec = { (int)position.x, (int)position.y, texture.width*scale, texture.height*scale };
+ Rectangle destRec = { position.x, position.y, texture.width*scale, texture.height*scale };
Vector2 origin = { 0, 0 };
DrawTexturePro(texture, sourceRec, destRec, origin, rotation, tint);
@@ -2035,7 +2030,7 @@ void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float sc
// Draw a part of a texture (defined by a rectangle)
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
{
- Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) };
+ Rectangle destRec = { position.x, position.y, sourceRec.width, fabsf(sourceRec.height) };
Vector2 origin = { 0, 0 };
DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
@@ -2054,7 +2049,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
rlEnableTexture(texture.id);
rlPushMatrix();
- rlTranslatef((float)destRec.x, (float)destRec.y, 0);
+ rlTranslatef(destRec.x, destRec.y, 0);
rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0);
@@ -2063,20 +2058,20 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x/texture.width, (float)sourceRec.y/texture.height);
+ rlTexCoord2f(sourceRec.x/texture.width, sourceRec.y/texture.height);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
- rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
- rlVertex2f(0.0f, (float)destRec.height);
+ rlTexCoord2f(sourceRec.x/texture.width, (sourceRec.y + sourceRec.height)/texture.height);
+ rlVertex2f(0.0f, destRec.height);
// Top-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
- rlVertex2f((float)destRec.width, (float)destRec.height);
+ rlTexCoord2f((sourceRec.x + sourceRec.width)/texture.width, (sourceRec.y + sourceRec.height)/texture.height);
+ rlVertex2f(destRec.width, destRec.height);
// Top-left corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height);
- rlVertex2f((float)destRec.width, 0.0f);
+ rlTexCoord2f((sourceRec.x + sourceRec.width)/texture.width, sourceRec.y/texture.height);
+ rlVertex2f(destRec.width, 0.0f);
rlEnd();
rlPopMatrix();
@@ -2680,7 +2675,7 @@ static Image LoadASTC(const char *fileName)
fread(image.data, dataSize, 1, astcFile);
if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;
- else if (bpp == 2) image.format = COMPRESSED_ASTC_4x4_RGBA;
+ else if (bpp == 2) image.format = COMPRESSED_ASTC_8x8_RGBA;
}
else TraceLog(LOG_WARNING, "[%s] ASTC block size configuration not supported", fileName);
}