浏览代码

Added some functions and renamed some others

Added:
- LoadImageRaw()
- ImageCopy()
Renamed:
- GetPixelData() -> GetImageData()
raysan5 10 年之前
父节点
当前提交
66556b8b47
共有 3 个文件被更改,包括 161 次插入161 次删除
  1. 19 57
      src/models.c
  2. 1 1
      src/text.c
  3. 141 103
      src/textures.c

+ 19 - 57
src/models.c

@@ -600,7 +600,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
     int mapX = heightmap.width;
     int mapZ = heightmap.height;
     
-    Color *heightmapPixels = GetPixelData(heightmap);
+    Color *heightmapPixels = GetImageData(heightmap);
 
     // NOTE: One vertex per pixel
     // TODO: Consider resolution when generating model data?
@@ -721,7 +721,7 @@ Model LoadCubicmap(Image cubicmap)
 {
     VertexData vData;
 
-    Color *cubicmapPixels = GetPixelData(cubicmap);
+    Color *cubicmapPixels = GetImageData(cubicmap);
     
     // Map cube size will be 1.0
     float mapCubeSide = 1.0f;
@@ -1105,8 +1105,6 @@ void UnloadModel(Model model)
     rlDeleteBuffers(model.mesh.vboId[2]);
 
     rlDeleteVertexArrays(model.mesh.vaoId);
-    //rlDeleteTextures(model.texture.id);
-    //rlDeleteShader(model.shader.id);
 }
 
 // Link a texture to a model
@@ -1114,8 +1112,9 @@ void SetModelTexture(Model *model, Texture2D texture)
 {
     if (texture.id <= 0)
     {
-        model->texture.id = whiteTexture;  // Default white texture (use mesh color)
-        model->shader.texDiffuseId = whiteTexture;
+        // Use default white texture (use mesh color)
+        model->texture.id = whiteTexture;               // OpenGL 1.1
+        model->shader.texDiffuseId = whiteTexture;      // OpenGL 3.3 / ES 2.0
     }
     else
     {
@@ -1124,26 +1123,6 @@ void SetModelTexture(Model *model, Texture2D texture)
     }
 }
 
-// Load a custom shader (vertex shader + fragment shader)
-Shader LoadShader(char *vsFileName, char *fsFileName)
-{
-    Shader shader = rlglLoadShader(vsFileName, fsFileName); 
-    
-    return shader;
-}
-
-// Unload a custom shader from memory
-void UnloadShader(Shader shader)
-{
-    rlDeleteShader(shader.id);
-}
-
-// Set shader for a model
-void SetModelShader(Model *model, Shader shader)
-{
-    rlglSetModelShader(model, shader);
-}
-
 // Draw a model (with texture if set)
 void DrawModel(Model model, Vector3 position, float scale, Color tint)
 {
@@ -1269,7 +1248,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
     rlDisableTexture();
 }
 
-
+// Detect collision between two spheres
 bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB)
 {
     bool collision = false;
@@ -1285,22 +1264,10 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa
     return collision;
 }
 
+// Detect collision between two boxes
+// NOTE: Boxes are defined by two points minimum and maximum
 bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2)
 {
-    /*
-    // Get min and max vertex to construct bounds (AABB)
-    Vector3 minVertex = tempVertices[0];
-    Vector3 maxVertex = tempVertices[0];
-
-    for (int i = 1; i < tempVertices.Count; i++)
-    {
-        minVertex = Vector3.Min(minVertex, tempVertices[i]);
-        maxVertex = Vector3.Max(maxVertex, tempVertices[i]);
-    }
-
-    bounds = new BoundingBox(minVertex, maxVertex);
-    */
-
     bool collision = true;
 
     if ((maxBBox1.x >= minBBox2.x) && (minBBox1.x <= maxBBox2.x))
@@ -1313,6 +1280,7 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V
     return collision;
 }
 
+// Detect collision between box and sphere
 bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere)
 {
     bool collision = false;
@@ -1326,35 +1294,29 @@ bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSph
     {
         float dmin = 0;
 
-        if (centerSphere.x - minBBox.x <= radiusSphere)
-            dmin += (centerSphere.x - minBBox.x) * (centerSphere.x - minBBox.x);
-        else if (maxBBox.x - centerSphere.x <= radiusSphere)
-            dmin += (centerSphere.x - maxBBox.x) * (centerSphere.x - maxBBox.x);
+        if (centerSphere.x - minBBox.x <= radiusSphere) dmin += (centerSphere.x - minBBox.x)*(centerSphere.x - minBBox.x);
+        else if (maxBBox.x - centerSphere.x <= radiusSphere) dmin += (centerSphere.x - maxBBox.x)*(centerSphere.x - maxBBox.x);
 
-        if (centerSphere.y - minBBox.y <= radiusSphere)
-            dmin += (centerSphere.y - minBBox.y) * (centerSphere.y - minBBox.y);
-        else if (maxBBox.y - centerSphere.y <= radiusSphere)
-            dmin += (centerSphere.y - maxBBox.y) * (centerSphere.y - maxBBox.y);
+        if (centerSphere.y - minBBox.y <= radiusSphere) dmin += (centerSphere.y - minBBox.y)*(centerSphere.y - minBBox.y);
+        else if (maxBBox.y - centerSphere.y <= radiusSphere) dmin += (centerSphere.y - maxBBox.y)*(centerSphere.y - maxBBox.y);
 
-        if (centerSphere.z - minBBox.z <= radiusSphere)
-            dmin += (centerSphere.z - minBBox.z) * (centerSphere.z - minBBox.z);
-        else if (maxBBox.z - centerSphere.z <= radiusSphere)
-            dmin += (centerSphere.z - maxBBox.z) * (centerSphere.z - maxBBox.z);
+        if (centerSphere.z - minBBox.z <= radiusSphere) dmin += (centerSphere.z - minBBox.z)*(centerSphere.z - minBBox.z);
+        else if (maxBBox.z - centerSphere.z <= radiusSphere) dmin += (centerSphere.z - maxBBox.z)*(centerSphere.z - maxBBox.z);
 
-        if (dmin <= radiusSphere * radiusSphere) collision = true;
+        if (dmin <= radiusSphere*radiusSphere) collision = true;
     }
 
     return collision;
 }
 
-// TODO
+// TODO: Useful function to check collision area?
 //BoundingBox GetCollisionArea(BoundingBox box1, BoundingBox box2)
 
 // Detect and resolve cubicmap collisions
 // NOTE: player position (or camera) is modified inside this function
 Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius)
 {
-    Color *cubicmapPixels = GetPixelData(cubicmap);
+    Color *cubicmapPixels = GetImageData(cubicmap);
     
     // Detect the cell where the player is located
     Vector3 impactDirection = { 0, 0, 0 };
@@ -1697,7 +1659,7 @@ static VertexData LoadOBJ(const char *fileName)
 
     // Second reading pass: Get vertex data to fill intermediate arrays
     // NOTE: This second pass is required in case of multiple meshes defined in same OBJ
-    // TODO: Consider that diferent meshes can have different vertex data available (position, texcoords, normals)
+    // TODO: Consider that different meshes can have different vertex data available (position, texcoords, normals)
     while(!feof(objFile))
     {
         fscanf(objFile, "%c", &dataType);

+ 1 - 1
src/text.c

@@ -238,7 +238,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
 
         // At this point we have a data array...
         
-        Color *imagePixels = GetPixelData(image);
+        Color *imagePixels = GetImageData(image);
 
 #if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
         ImageConvertToPOT(&image, MAGENTA);

+ 141 - 103
src/textures.c

@@ -149,6 +149,56 @@ Image LoadImageEx(Color *pixels, int width, int height)
     return image;
 }
 
+// Load an image from RAW file
+Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize)
+{
+    Image image;
+
+    image.data = NULL;
+    image.width = 0;
+    image.height = 0;
+    image.mipmaps = 0;
+    image.format = 0;
+
+    FILE *rawFile = fopen(fileName, "rb");
+
+    if (rawFile == NULL)
+    {
+        TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName);
+    }
+    else
+    {
+        if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET);
+
+        unsigned int size = width*height;
+        
+        switch (format)
+        {
+            case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break;               // 8 bit per pixel (no alpha)
+            case UNCOMPRESSED_GRAY_ALPHA: image.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels)
+            case UNCOMPRESSED_R5G6B5: image.data = (unsigned short *)malloc(size); break;                 // 16 bpp
+            case UNCOMPRESSED_R8G8B8: image.data = (unsigned char *)malloc(size*3); size *= 3; break;     // 24 bpp
+            case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break;               // 16 bpp (1 bit alpha)
+            case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break;               // 16 bpp (4 bit alpha)
+            case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break;   // 32 bpp
+            default: TraceLog(WARNING, "Image format not suported"); break;
+        }
+        
+        fread(image.data, size, 1, rawFile);
+        
+        // TODO: Check if data have been read
+        
+        image.width = width;
+        image.height = height;
+        image.mipmaps = 0;
+        image.format = format;
+        
+        fclose(rawFile);
+    }
+
+    return image;
+}
+
 // Load an image from rRES file (raylib Resource)
 // TODO: Review function to support multiple color modes
 Image LoadImageFromRES(const char *rresName, int resId)
@@ -301,6 +351,18 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, in
     return texture;
 }
 
+// Load an image as texture from rRES file (raylib Resource)
+Texture2D LoadTextureFromRES(const char *rresName, int resId)
+{
+    Texture2D texture;
+
+    Image image = LoadImageFromRES(rresName, resId);
+    texture = LoadTextureFromImage(image);
+    UnloadImage(image);
+
+    return texture;
+}
+
 // Load a texture from image data
 // NOTE: image is not unloaded, it must be done manually
 Texture2D LoadTextureFromImage(Image image)
@@ -324,18 +386,6 @@ Texture2D LoadTextureFromImage(Image image)
     return texture;
 }
 
-// Load an image as texture from rRES file (raylib Resource)
-Texture2D LoadTextureFromRES(const char *rresName, int resId)
-{
-    Texture2D texture;
-
-    Image image = LoadImageFromRES(rresName, resId);
-    texture = LoadTextureFromImage(image);
-    UnloadImage(image);
-
-    return texture;
-}
-
 // Unload image from CPU memory (RAM)
 void UnloadImage(Image image)
 {
@@ -348,46 +398,8 @@ void UnloadTexture(Texture2D texture)
     rlDeleteTextures(texture.id);
 }
 
-// Convert image to POT (power-of-two)
-// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
-void ImageConvertToPOT(Image *image, Color fillColor)
-{
-    // TODO: Review for new image struct
-    /*
-    // Just add the required amount of pixels at the right and bottom sides of image...
-    int potWidth = GetNextPOT(image->width);
-    int potHeight = GetNextPOT(image->height);
-
-    // Check if POT texture generation is required (if texture is not already POT)
-    if ((potWidth != image->width) || (potHeight != image->height))
-    {
-        Color *imgDataPixelPOT = NULL;
-
-        // Generate POT array from NPOT data
-        imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
-
-        for (int j = 0; j < potHeight; j++)
-        {
-            for (int i = 0; i < potWidth; i++)
-            {
-                if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i];
-                else imgDataPixelPOT[j*potWidth + i] = fillColor;
-            }
-        }
-
-        TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
-
-        free(image->pixels);
-
-        image->pixels = imgDataPixelPOT;
-        image->width = potWidth;
-        image->height = potHeight;
-    }
-    */
-}
-
 // Get pixel data from image in the form of Color struct array
-Color *GetPixelData(Image image)
+Color *GetImageData(Image image)
 {
     Color *pixels = (Color *)malloc(image.width*image.height*sizeof(Color));
     
@@ -497,7 +509,7 @@ void ImageConvertFormat(Image *image, int newFormat)
 {
     if ((image->format != newFormat) && (image->format < 8) && (newFormat < 8))
     {
-        Color *pixels = GetPixelData(*image);
+        Color *pixels = GetImageData(*image);
         
         free(image->data);
         
@@ -627,13 +639,83 @@ void ImageConvertFormat(Image *image, int newFormat)
     else TraceLog(WARNING, "Image data format is compressed, can not be converted");
 }
 
-/*
-Image ImageCopy(Image image);
-void ImageCrop(Image *image, Rectangle crop);
-void ImageResize(Image *image, int newWidth, int newHeight);
-void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec);
-void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color);
-*/
+
+// Convert image to POT (power-of-two)
+// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
+void ImageConvertToPOT(Image *image, Color fillColor)
+{
+    // TODO: Review for new image struct
+    /*
+    // Just add the required amount of pixels at the right and bottom sides of image...
+    int potWidth = GetNextPOT(image->width);
+    int potHeight = GetNextPOT(image->height);
+
+    // Check if POT texture generation is required (if texture is not already POT)
+    if ((potWidth != image->width) || (potHeight != image->height))
+    {
+        Color *imgDataPixelPOT = NULL;
+
+        // Generate POT array from NPOT data
+        imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
+
+        for (int j = 0; j < potHeight; j++)
+        {
+            for (int i = 0; i < potWidth; i++)
+            {
+                if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i];
+                else imgDataPixelPOT[j*potWidth + i] = fillColor;
+            }
+        }
+
+        TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
+
+        free(image->pixels);
+
+        image->pixels = imgDataPixelPOT;
+        image->width = potWidth;
+        image->height = potHeight;
+    }
+    */
+}
+
+// Copy an image to a new image
+Image ImageCopy(Image image)
+{
+    Image newImage;
+    
+    int size = image.width*image.height;
+    
+    switch (image.format)
+    {
+        case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break;               // 8 bit per pixel (no alpha)
+        case UNCOMPRESSED_GRAY_ALPHA: newImage.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels)
+        case UNCOMPRESSED_R5G6B5: newImage.data = (unsigned short *)malloc(size); size *= 2; break;      // 16 bpp
+        case UNCOMPRESSED_R8G8B8: newImage.data = (unsigned char *)malloc(size*3); size *= 3; break;     // 24 bpp
+        case UNCOMPRESSED_R5G5B5A1: newImage.data = (unsigned short *)malloc(size); size *= 2; break;    // 16 bpp (1 bit alpha)
+        case UNCOMPRESSED_R4G4B4A4: newImage.data = (unsigned short *)malloc(size); size *= 2; break;    // 16 bpp (4 bit alpha)
+        case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break;   // 32 bpp
+        default: TraceLog(WARNING, "Image format not suported for copy"); break;
+    }
+    
+    if (newImage.data != NULL)
+    {
+        // NOTE: Size must be provided in bytes
+        memcpy(newImage.data, image.data, size);
+        
+        newImage.width = image.width;
+        newImage.height = image.height;
+        newImage.mipmaps = image.mipmaps;
+        newImage.format = image.format;
+    }
+    
+    return newImage;
+}
+
+// TODO: Some useful functions to deal with images
+//void ImageCrop(Image *image, Rectangle crop) {}
+//void ImageResize(Image *image, int newWidth, int newHeight) {}
+//void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) {}
+//void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color) {}
 
 // Generate GPU mipmaps for a texture
 void GenTextureMipmaps(Texture2D texture)
@@ -1310,47 +1392,3 @@ static Image LoadASTC(const char *fileName)
 
     return image;
 }
-
-// Load RAW image file
-static Image LoadRAW(const char *fileName, int width, int height, int format, int headerSize)
-{
-    Image image;
-
-    image.data = NULL;
-    image.width = 0;
-    image.height = 0;
-    image.mipmaps = 0;
-    image.format = 0;
-
-    FILE *rawFile = fopen(fileName, "rb");
-
-    if (rawFile == NULL)
-    {
-        TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName);
-    }
-    else
-    {
-        if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET);
-
-        int dataSize = 0;
-        
-        // TODO: Calculate data size and allocate memory
-        switch (format)
-        {
-            
-        }
-        
-        fread(image.data, dataSize, 1, rawFile);
-        
-        // TODO: Check if data have been read
-        
-        image.width = width;
-        image.height = height;
-        image.mipmaps = 0;
-        image.format = format;
-        
-        fclose(rawFile);
-    }
-
-    return image;
-}