aboutsummaryrefslogtreecommitdiff
path: root/src/textures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/textures.c')
-rw-r--r--src/textures.c354
1 files changed, 178 insertions, 176 deletions
diff --git a/src/textures.c b/src/textures.c
index 1a7e23a7..fc342a80 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -1,36 +1,36 @@
/*********************************************************************************************
*
-* raylib.textures
+* raylib.textures
*
-* Basic functions to load and draw Textures (2d)
-*
-* Uses external lib:
-* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
+* Basic functions to load and draw Textures (2d)
+*
+* Uses external lib:
+* stb_image - Multiple formats image loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
*
-* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
-*
-* This software is provided "as-is", without any express or implied warranty. In no event
-* will the authors be held liable for any damages arising from the use of this software.
+* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <GL/gl.h> // OpenGL functions
-#include <stdlib.h> // Declares malloc() and free() for memory management
-#include "stb_image.h" // Used to read image data (multiple formats support)
+#include <GL/gl.h> // OpenGL functions
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include "stb_image.h" // Used to read image data (multiple formats support)
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -59,208 +59,210 @@ typedef unsigned char byte;
// Load an image into CPU memory (RAM)
Image LoadImage(const char *fileName)
{
- Image image;
-
- int imgWidth;
- int imgHeight;
- int imgBpp;
-
- // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
- byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
-
- // Convert array to pixel array for working convenience
- image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
-
+ Image image;
+
+ int imgWidth;
+ int imgHeight;
+ int imgBpp;
+
+ // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
+ // Force loading to 4 components (RGBA)
+ byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ // Convert array to pixel array for working convenience
+ image.pixels = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
+
int pix = 0;
-
- for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
- {
- image.pixels[pix].r = imgData[i];
- image.pixels[pix].g = imgData[i+1];
- image.pixels[pix].b = imgData[i+2];
- image.pixels[pix].a = imgData[i+3];
- pix++;
- }
-
- stbi_image_free(imgData);
-
- image.width = imgWidth;
- image.height = imgHeight;
-
- // ALTERNATIVE: We can load pixel data directly into Color struct pixels array,
- // to do that struct data alignment should be the right one (4 byte); it is.
- //image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
+ {
+ image.pixels[pix].r = imgData[i];
+ image.pixels[pix].g = imgData[i+1];
+ image.pixels[pix].b = imgData[i+2];
+ image.pixels[pix].a = imgData[i+3];
+ pix++;
+ }
+
+ stbi_image_free(imgData);
+
+ image.width = imgWidth;
+ image.height = imgHeight;
+
+ // ALTERNATIVE: We can load pixel data directly into Color struct pixels array,
+ // to do that struct data alignment should be the right one (4 byte); it is.
+ //image.pixels = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
- return image;
+ return image;
}
// Unload image from CPU memory (RAM)
void UnloadImage(Image image)
{
- free(image.pixels);
+ free(image.pixels);
}
// Load an image as texture into GPU memory
Texture2D LoadTexture(const char *fileName)
{
- Texture2D texture;
+ Texture2D texture;
- int imgWidth;
- int imgHeight;
- int imgBpp;
-
- // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
- byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
-
- // Convert loaded data to OpenGL texture
- //----------------------------------------
- GLuint id;
- glGenTextures(1, &id); // Generate Pointer to the Texture
-
- glBindTexture(GL_TEXTURE_2D, id);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
-
- // NOTE: Not using mipmappings (texture for 2D drawing)
- // At this point we have the image converted to texture and uploaded to GPU
-
- stbi_image_free(imgData); // Now we can free loaded data from RAM memory
-
- texture.glId = id;
- texture.width = imgWidth;
- texture.height = imgHeight;
-
- return texture;
+ int imgWidth;
+ int imgHeight;
+ int imgBpp;
+
+ // NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
+ // Force loading to 4 components (RGBA)
+ byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);
+
+ // Convert loaded data to OpenGL texture
+ //----------------------------------------
+ GLuint id;
+ glGenTextures(1, &id); // Generate Pointer to the Texture
+
+ glBindTexture(GL_TEXTURE_2D, id);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repead on x-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repead on y-axis
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imgWidth, imgHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
+
+ // NOTE: Not using mipmappings (texture for 2D drawing)
+ // At this point we have the image converted to texture and uploaded to GPU
+
+ stbi_image_free(imgData); // Now we can free loaded data from RAM memory
+
+ texture.glId = id;
+ texture.width = imgWidth;
+ texture.height = imgHeight;
+
+ return texture;
}
// Load an image as texture (and convert to POT with mipmaps)
Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps)
{
- Texture2D texture;
-
- // TODO: Load and image and convert to Power-Of-Two
- // NOTE: Conversion could be done just adding extra space to image or by scaling image
- // NOTE: If scaling image, be careful with scaling algorithm (aproximation, bilinear, bicubic...)
-
- // TODO: Generate all required mipmap levels from image and convert to testure (not that easy)
- // NOTE: If using OpenGL 1.1, the only option is doing mipmap generation on CPU side (i.e. gluBuild2DMipmaps)
- // NOTE: raylib tries to minimize external dependencies so, we are not using GLU
- // NOTE: Re-implement some function similar to gluBuild2DMipmaps (not that easy...)
-
- return texture;
+ Texture2D texture;
+
+ // TODO: Load and image and convert to Power-Of-Two
+ // NOTE: Conversion could be done just adding extra space to image or by scaling image
+ // NOTE: If scaling image, be careful with scaling algorithm (aproximation, bilinear, bicubic...)
+
+ // TODO: Generate all required mipmap levels from image and convert to testure (not that easy)
+ // NOTE: If using OpenGL 1.1, the only option is doing mipmap generation on CPU side (i.e. gluBuild2DMipmaps)
+ // NOTE: raylib tries to minimize external dependencies so, we are not using GLU
+ // NOTE: Re-implement some function similar to gluBuild2DMipmaps (not that easy...)
+
+ return texture;
}
// Unload texture from GPU memory
void UnloadTexture(Texture2D texture)
{
- glDeleteTextures(1, &texture.glId);
+ glDeleteTextures(1, &texture.glId);
}
// Draw a Texture2D
void DrawTexture(Texture2D texture, int posX, int posY, Color tint)
{
- DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY}, 0, 1.0f, tint);
+ DrawTextureEx(texture, (Vector2){ (float)posX, (float)posY}, 0, 1.0f, tint);
}
// Draw a Texture2D with extended parameters
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint)
{
- glEnable(GL_TEXTURE_2D); // Enable textures usage
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- glPushMatrix();
- // NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
- // NOTE: Rotation point is upper-left corner
- glTranslatef(position.x, position.y, 0);
- glScalef(scale, scale, 1.0f);
- glRotatef(rotation, 0, 0, 1);
-
- glBegin(GL_QUADS);
- glColor4ub(tint.r, tint.g, tint.b, tint.a);
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
- glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // Bottom-left corner for texture and quad
- glTexCoord2f(1.0f, 0.0f); glVertex2f(texture.width, 0.0f); // Bottom-right corner for texture and quad
- glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
- glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
- glEnd();
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D); // Disable textures usage
+ glEnable(GL_TEXTURE_2D); // Enable textures usage
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ glPushMatrix();
+ // NOTE: Rotation is applied before translation and scaling, even being called in inverse order...
+ // NOTE: Rotation point is upper-left corner
+ glTranslatef(position.x, position.y, 0);
+ glScalef(scale, scale, 1.0f);
+ glRotatef(rotation, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glColor4ub(tint.r, tint.g, tint.b, tint.a);
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+ glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // Bottom-left corner for texture and quad
+ glTexCoord2f(1.0f, 0.0f); glVertex2f(texture.width, 0.0f); // Bottom-right corner for texture and quad
+ glTexCoord2f(1.0f, 1.0f); glVertex2f(texture.width, texture.height); // Top-right corner for texture and quad
+ glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, texture.height); // Top-left corner for texture and quad
+ glEnd();
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D); // Disable textures usage
}
// Draw a part of a texture (defined by a rectangle)
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, float scale, Color tint)
{
- glEnable(GL_TEXTURE_2D); // Enable textures usage
-
- glBindTexture(GL_TEXTURE_2D, texture.glId);
-
- glPushMatrix();
- glTranslatef(position.x, position.y, 0);
- glScalef(scale, scale, 1.0f);
- //glRotatef(rotation, 0, 0, 1);
-
- glBegin(GL_QUADS);
- glColor4ub(tint.r, tint.g, tint.b, tint.a);
- glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
-
- // Bottom-left corner for texture and quad
- glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
- glVertex2f(0.0f, 0.0f);
-
- // Bottom-right corner for texture and quad
- glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
- glVertex2f(sourceRec.width, 0.0f);
-
- // Top-right corner for texture and quad
- glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- glVertex2f(sourceRec.width, sourceRec.height);
-
- // Top-left corner for texture and quad
- glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
- glVertex2f(0.0f, sourceRec.height);
- glEnd();
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D); // Disable textures usage
+ glEnable(GL_TEXTURE_2D); // Enable textures usage
+
+ glBindTexture(GL_TEXTURE_2D, texture.glId);
+
+ glPushMatrix();
+ glTranslatef(position.x, position.y, 0);
+ glScalef(scale, scale, 1.0f);
+ //glRotatef(rotation, 0, 0, 1);
+
+ glBegin(GL_QUADS);
+ glColor4ub(tint.r, tint.g, tint.b, tint.a);
+ glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
+
+ // Bottom-left corner for texture and quad
+ glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
+ glVertex2f(0.0f, 0.0f);
+
+ // Bottom-right corner for texture and quad
+ glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+ glVertex2f(sourceRec.width, 0.0f);
+
+ // Top-right corner for texture and quad
+ glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ glVertex2f(sourceRec.width, sourceRec.height);
+
+ // Top-left corner for texture and quad
+ glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ glVertex2f(0.0f, sourceRec.height);
+ glEnd();
+ glPopMatrix();
+
+ glDisable(GL_TEXTURE_2D); // Disable textures usage
}
// Creates a bitmap (BMP) file from an array of pixel data
// NOTE: This function is only used by module [core], not explicitly available to raylib users
extern void WriteBitmap(const char *fileName, const Color *imgDataPixel, int width, int height)
{
- int filesize = 54 + 3*width*height;
-
- unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
- unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
+ int filesize = 54 + 3*width*height;
+
+ unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
+ unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
- bmpFileHeader[2] = (unsigned char)(filesize);
- bmpFileHeader[3] = (unsigned char)(filesize>>8);
- bmpFileHeader[4] = (unsigned char)(filesize>>16);
- bmpFileHeader[5] = (unsigned char)(filesize>>24);
+ bmpFileHeader[2] = (unsigned char)(filesize);
+ bmpFileHeader[3] = (unsigned char)(filesize>>8);
+ bmpFileHeader[4] = (unsigned char)(filesize>>16);
+ bmpFileHeader[5] = (unsigned char)(filesize>>24);
- bmpInfoHeader[4] = (unsigned char)(width);
- bmpInfoHeader[5] = (unsigned char)(width>>8);
- bmpInfoHeader[6] = (unsigned char)(width>>16);
- bmpInfoHeader[7] = (unsigned char)(width>>24);
- bmpInfoHeader[8] = (unsigned char)(height);
- bmpInfoHeader[9] = (unsigned char)(height>>8);
- bmpInfoHeader[10] = (unsigned char)(height>>16);
- bmpInfoHeader[11] = (unsigned char)(height>>24);
+ bmpInfoHeader[4] = (unsigned char)(width);
+ bmpInfoHeader[5] = (unsigned char)(width>>8);
+ bmpInfoHeader[6] = (unsigned char)(width>>16);
+ bmpInfoHeader[7] = (unsigned char)(width>>24);
+ bmpInfoHeader[8] = (unsigned char)(height);
+ bmpInfoHeader[9] = (unsigned char)(height>>8);
+ bmpInfoHeader[10] = (unsigned char)(height>>16);
+ bmpInfoHeader[11] = (unsigned char)(height>>24);
- FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
-
- // NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
- fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
- fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
-
- // Write pixel data to file
+ FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
+
+ // NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
+ fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
+ fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
+
+ // Write pixel data to file
for (int y = 0; y < height ; y++)
{
for (int x = 0; x < width; x++)
@@ -271,5 +273,5 @@ extern void WriteBitmap(const char *fileName, const Color *imgDataPixel, int wid
}
}
- fclose(bmpFile); // Close bitmap file
+ fclose(bmpFile); // Close bitmap file
} \ No newline at end of file