diff options
| author | Ray <raysan5@gmail.com> | 2014-04-19 14:21:22 +0200 |
|---|---|---|
| committer | Ray <raysan5@gmail.com> | 2014-04-19 14:21:22 +0200 |
| commit | 650a8f7f159d3ce2addb1b0fdb31c3f460005391 (patch) | |
| tree | 01f1a6968b784d07d63f6bf741c1527145cea25c /src/textures.c | |
| parent | 1c8dce429ee5a58d535fcca0e29fe3711aa3fcb5 (diff) | |
| parent | e6b82cb111c3485c5e6131fe29791f938305bce3 (diff) | |
| download | raylib-650a8f7f159d3ce2addb1b0fdb31c3f460005391.tar.gz raylib-650a8f7f159d3ce2addb1b0fdb31c3f460005391.zip | |
Merge pull request #2 from raysan5/testing
Integrate raylib 1.1 changes into master
Diffstat (limited to 'src/textures.c')
| -rw-r--r-- | src/textures.c | 593 |
1 files changed, 369 insertions, 224 deletions
diff --git a/src/textures.c b/src/textures.c index ca0492c4..7d4a0fb4 100644 --- a/src/textures.c +++ b/src/textures.c @@ -28,12 +28,13 @@ #include "raylib.h" -#include <GL/gl.h> // OpenGL functions #include <stdlib.h> // Declares malloc() and free() for memory management +#include <string.h> // Required for strcmp(), strrchr(), strncmp() #include "stb_image.h" // Used to read image data (multiple formats support) - #include "utils.h" // rRES data decompression utility function +#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 + //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -44,15 +45,29 @@ //---------------------------------------------------------------------------------- typedef unsigned char byte; +typedef struct { + unsigned char *data; + int width; + int height; + int mipmaps; + int format; +} ImageDDS; + //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- // It's lonely here... //---------------------------------------------------------------------------------- +// Other Modules Functions Declaration (required by text) +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -// No private (static) functions in this module (.c file) +static const char *GetExtension(const char *fileName); +static ImageDDS LoadDDS(const char *fileName); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -63,32 +78,44 @@ 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, ...) - // 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++; + if ((strcmp(GetExtension(fileName),"png") == 0) || + (strcmp(GetExtension(fileName),"bmp") == 0) || + (strcmp(GetExtension(fileName),"tga") == 0) || + (strcmp(GetExtension(fileName),"jpg") == 0) || + (strcmp(GetExtension(fileName),"gif") == 0) || + (strcmp(GetExtension(fileName),"psd") == 0) || + (strcmp(GetExtension(fileName),"pic") == 0)) + { + 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; + + TraceLog(INFO, "[%s] Image loaded successfully", fileName); } - - stbi_image_free(imgData); - - image.width = imgWidth; - image.height = imgHeight; + else TraceLog(WARNING, "[%s] Image extension not recognized, it can't be loaded", fileName); // 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. @@ -113,103 +140,104 @@ Image LoadImageFromRES(const char *rresName, int resId) FILE *rresFile = fopen(rresName, "rb"); - if (!rresFile) printf("Error opening raylib Resource file\n"); - - // Read rres file (basic file check - id) - fread(&id[0], sizeof(char), 1, rresFile); - fread(&id[1], sizeof(char), 1, rresFile); - fread(&id[2], sizeof(char), 1, rresFile); - fread(&id[3], sizeof(char), 1, rresFile); - fread(&version, sizeof(char), 1, rresFile); - fread(&useless, sizeof(char), 1, rresFile); - - if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S')) - { - printf("This is not a valid raylib Resource file!\n"); - exit(1); - } - - // Read number of resources embedded - fread(&numRes, sizeof(short), 1, rresFile); - - for (int i = 0; i < numRes; i++) + if (!rresFile) TraceLog(WARNING, "[%s] Could not open raylib resource file", rresName); + else { - fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile); + // Read rres file (basic file check - id) + fread(&id[0], sizeof(char), 1, rresFile); + fread(&id[1], sizeof(char), 1, rresFile); + fread(&id[2], sizeof(char), 1, rresFile); + fread(&id[3], sizeof(char), 1, rresFile); + fread(&version, sizeof(char), 1, rresFile); + fread(&useless, sizeof(char), 1, rresFile); - if (infoHeader.id == resId) + if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S')) { - found = true; + TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName); + } + else + { + // Read number of resources embedded + fread(&numRes, sizeof(short), 1, rresFile); - // Check data is of valid IMAGE type - if (infoHeader.type == 0) // IMAGE data type + for (int i = 0; i < numRes; i++) { - // TODO: Check data compression type + fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile); - // NOTE: We suppose compression type 2 (DEFLATE - default) - short imgWidth, imgHeight; - char colorFormat, mipmaps; - - fread(&imgWidth, sizeof(short), 1, rresFile); // Image width - fread(&imgHeight, sizeof(short), 1, rresFile); // Image height - fread(&colorFormat, 1, 1, rresFile); // Image data color format (default: RGBA 32 bit) - fread(&mipmaps, 1, 1, rresFile); // Mipmap images included (default: 0) - - printf("Image width: %i\n", (int)imgWidth); - printf("Image height: %i\n", (int)imgHeight); - - image.width = (int)imgWidth; - image.height = (int)imgHeight; + if (infoHeader.id == resId) + { + found = true; + + // Check data is of valid IMAGE type + if (infoHeader.type == 0) // IMAGE data type + { + // TODO: Check data compression type + + // NOTE: We suppose compression type 2 (DEFLATE - default) + short imgWidth, imgHeight; + char colorFormat, mipmaps; + + fread(&imgWidth, sizeof(short), 1, rresFile); // Image width + fread(&imgHeight, sizeof(short), 1, rresFile); // Image height + fread(&colorFormat, 1, 1, rresFile); // Image data color format (default: RGBA 32 bit) + fread(&mipmaps, 1, 1, rresFile); // Mipmap images included (default: 0) - unsigned char *data = malloc(infoHeader.size); + image.width = (int)imgWidth; + image.height = (int)imgHeight; + + unsigned char *data = malloc(infoHeader.size); - fread(data, infoHeader.size, 1, rresFile); - - unsigned char *imgData = DecompressData(data, infoHeader.size, infoHeader.srcSize); - - image.pixels = (Color *)malloc(sizeof(Color)*imgWidth*imgHeight); - - int pix = 0; - - for (int i = 0; i < (imgWidth*imgHeight*4); i += 4) + fread(data, infoHeader.size, 1, rresFile); + + unsigned char *imgData = DecompressData(data, infoHeader.size, infoHeader.srcSize); + + image.pixels = (Color *)malloc(sizeof(Color)*imgWidth*imgHeight); + + 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++; + } + + free(imgData); + + free(data); + + TraceLog(INFO, "[%s] Image loaded successfully from resource, size: %ix%i", rresName, image.width, image.height); + } + else + { + TraceLog(WARNING, "[%s] Required resource do not seem to be a valid IMAGE resource", rresName); + } + } + else { - 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++; + // Depending on type, skip the right amount of parameters + switch (infoHeader.type) + { + case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters + case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters + case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review) + case 3: break; // TEXT: No parameters + case 4: break; // RAW: No parameters + default: break; + } + + // Jump DATA to read next infoHeader + fseek(rresFile, infoHeader.size, SEEK_CUR); } - - free(imgData); - - free(data); - } - else - { - printf("Required resource do not seem to be a valid IMAGE resource\n"); - exit(2); } } - else - { - // Depending on type, skip the right amount of parameters - switch (infoHeader.type) - { - case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters - case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters - case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review) - case 3: break; // TEXT: No parameters - case 4: break; // RAW: No parameters - default: break; - } - - // Jump DATA to read next infoHeader - fseek(rresFile, infoHeader.size, SEEK_CUR); - } + + fclose(rresFile); } - fclose(rresFile); - - if (!found) printf("Required resource id could not be found in the raylib Resource file!\n"); + if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId); return image; } @@ -218,11 +246,33 @@ Image LoadImageFromRES(const char *rresName, int resId) Texture2D LoadTexture(const char *fileName) { Texture2D texture; - Image image; - - image = LoadImage(fileName); - texture = CreateTexture(image); - UnloadImage(image); + + if (strcmp(GetExtension(fileName),"dds") == 0) + { +#ifdef USE_OPENGL_11 + TraceLog(WARNING, "[%s] DDS file loading requires OpenGL 3.2+ or ES 2.0", fileName); +#else + ImageDDS image = LoadDDS(fileName); + + texture.glId = rlglLoadCompressedTexture(image.data, image.width, image.height, image.mipmaps, image.format); + + texture.width = image.width; + texture.height = image.height; + + if (texture.glId == 0) TraceLog(WARNING, "Compressed texture could not be loaded"); + else TraceLog(INFO, "Compressed texture loaded succesfully"); +#endif + } + else + { + Image image = LoadImage(fileName); + + if (image.pixels != NULL) + { + texture = CreateTexture(image); + UnloadImage(image); + } + } return texture; } @@ -238,43 +288,6 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId) return texture; } -// Create a Texture2D from Image data -// NOTE: Image is not unloaded, it should be done manually... -Texture2D CreateTexture(Image image) -{ - Texture2D texture; - - // Convert image data to OpenGL texture - //---------------------------------------- - GLuint id; - glGenTextures(1, &id); // Generate Pointer to the Texture - - glBindTexture(GL_TEXTURE_2D, id); - - // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used! - 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_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR - - // Trilinear filtering - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate use of mipmaps (must be available) - //glGenerateMipmap(GL_TEXTURE_2D); // OpenGL 3.3! - - // Upload texture to GPU - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels); - - // NOTE: Not using mipmappings (texture for 2D drawing) - // At this point we have the image converted to texture and uploaded to GPU - - texture.glId = id; - texture.width = image.width; - texture.height = image.height; - - return texture; -} - // Unload image from CPU memory (RAM) void UnloadImage(Image image) { @@ -284,13 +297,13 @@ void UnloadImage(Image image) // Unload texture from GPU memory void UnloadTexture(Texture2D texture) { - glDeleteTextures(1, &texture.glId); + rlDeleteTextures(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 position defined as Vector2 @@ -302,101 +315,233 @@ void DrawTextureV(Texture2D texture, Vector2 position, Color 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(); + rlEnableTexture(texture.glId); + + // NOTE: Rotation is applied before translation and scaling, even being called in inverse order... + // NOTE: Rotation point is upper-left corner + rlPushMatrix(); + //rlTranslatef(position.x, position.y, 0.0); + rlRotatef(rotation, 0, 0, 1); + rlScalef(scale, scale, 1.0f); + + rlBegin(RL_QUADS); + rlColor4ub(tint.r, tint.g, tint.b, tint.a); + rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + + rlTexCoord2f(0.0f, 0.0f); + rlVertex2f(position.x, position.y); // Bottom-left corner for texture and quad + + rlTexCoord2f(0.0f, 1.0f); + rlVertex2f(position.x, position.y + texture.height); // Bottom-right corner for texture and quad + + rlTexCoord2f(1.0f, 1.0f); + rlVertex2f(position.x + texture.width, position.y + texture.height); // Top-right corner for texture and quad + + rlTexCoord2f(1.0f, 0.0f); + rlVertex2f(position.x + texture.width, position.y); // Top-left corner for texture and quad + rlEnd(); + rlPopMatrix(); - glDisable(GL_TEXTURE_2D); // Disable textures usage + rlDisableTexture(); } // Draw a part of a texture (defined by a rectangle) void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint) { - glEnable(GL_TEXTURE_2D); // Enable textures usage - - glBindTexture(GL_TEXTURE_2D, texture.glId); + rlEnableTexture(texture.glId); - glPushMatrix(); - glTranslatef(position.x, position.y, 0); - //glScalef(1.0f, 1.0f, 1.0f); - //glRotatef(rotation, 0, 0, 1); + 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 + rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(position.x, position.y); + + // Bottom-right corner for texture and quad + rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(position.x, position.y + sourceRec.height); - glBegin(GL_QUADS); - glColor4ub(tint.r, tint.g, tint.b, tint.a); - glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + // Top-right corner for texture and quad + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(position.x + sourceRec.width, position.y + sourceRec.height); + + // Top-left corner for texture and quad + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(position.x + sourceRec.width, position.y); + rlEnd(); + + rlDisableTexture(); +} + +// Draw a part of a texture (defined by a rectangle) with 'pro' parameters +// TODO: Test this function... +void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint) +{ + rlEnableTexture(texture.glId); + + // NOTE: First we translate texture to origin to apply rotation and translation from there + rlPushMatrix(); + rlTranslatef(-origin.x, -origin.y, 0); + rlRotatef(rotation, 0, 0, 1); + rlTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0); + + 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 - glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); - glVertex2f(0.0f, 0.0f); + rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(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); + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); + rlVertex2f(destRec.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); + rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(destRec.width, destRec.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(); + rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); + rlVertex2f(0.0f, destRec.height); + rlEnd(); + rlPopMatrix(); - glDisable(GL_TEXTURE_2D); // Disable textures usage + rlDisableTexture(); } -// Draw a part of a texture (defined by a rectangle) with 'pro' parameters -// TODO: Test this function... -void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint) +Texture2D CreateTexture(Image image) { - glEnable(GL_TEXTURE_2D); // Enable textures usage + Texture2D texture; + + unsigned char *img = malloc(image.width * image.height * 4); + + int j = 0; + + for (int i = 0; i < image.width * image.height * 4; i += 4) + { + img[i] = image.pixels[j].r; + img[i+1] = image.pixels[j].g; + img[i+2] = image.pixels[j].b; + img[i+3] = image.pixels[j].a; + + j++; + } + + texture.glId = rlglLoadTexture(image.width, image.height, img); + + texture.width = image.width; + texture.height = image.height; + + TraceLog(INFO, "Texture created succesfully"); + + free(img); - glBindTexture(GL_TEXTURE_2D, texture.glId); + return texture; +} + +// Get the extension for a filename +static const char *GetExtension(const char *fileName) +{ + const char *dot = strrchr(fileName, '.'); + if(!dot || dot == fileName) return ""; + return (dot + 1); +} + +// Loading DDS image compressed data +ImageDDS LoadDDS(const char *fileName) +{ + // TODO: Review and expand DDS file loading to support uncompressed formats and new formats + + // DDS Pixel Format + typedef struct { + unsigned int size; + unsigned int flags; + unsigned int fourCC; + unsigned int rgbBitCount; + unsigned int rBitMask; + unsigned int gBitMask; + unsigned int bitMask; + unsigned int aBitMask; + } ddsPixelFormat; + + // DDS Header (124 bytes) + typedef struct { + unsigned int size; + unsigned int flags; + unsigned int height; + unsigned int width; + unsigned int pitchOrLinearSize; + unsigned int depth; + unsigned int mipMapCount; + unsigned int reserved1[11]; + ddsPixelFormat ddspf; + unsigned int caps; + unsigned int caps2; + unsigned int caps3; + unsigned int caps4; + unsigned int reserved2; + } ddsHeader; + + ImageDDS image; + ddsHeader header; + + FILE *ddsFile = fopen(fileName, "rb"); - glPushMatrix(); - glTranslatef(-origin.x, -origin.y, 0); - glRotatef(rotation, 0, 0, 1); - glTranslatef(destRec.x + origin.x, destRec.y + origin.y, 0); + if (ddsFile == NULL) + { + TraceLog(WARNING, "DDS File could not be opened"); + } + else + { + // Verify the type of file + char filecode[4]; + + fread(filecode, 1, 4, ddsFile); - glBegin(GL_QUADS); - glColor4ub(tint.r, tint.g, tint.b, tint.a); - glNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer + if (strncmp(filecode, "DDS ", 4) != 0) + { + TraceLog(WARNING, "DDS File does not seem to be valid"); + fclose(ddsFile); + } + else + { + // Get the surface descriptor + fread(&header, sizeof(ddsHeader), 1, ddsFile); + + int height = header.height; + int width = header.width; + int linearSize = header.pitchOrLinearSize; + int mipMapCount = header.mipMapCount; + int fourCC = header.ddspf.fourCC; - // Bottom-left corner for texture and quad - glTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height); - glVertex2f(0.0f, 0.0f); + TraceLog(DEBUG, "[%s] DDS file header size: %i", fileName, sizeof(ddsHeader)); - // Bottom-right corner for texture and quad - glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height); - glVertex2f(destRec.width, 0.0f); + TraceLog(DEBUG, "[%s] DDS file pixel format size: %i", fileName, header.ddspf.size); + TraceLog(DEBUG, "[%s] DDS file pixel format flags: 0x%x", fileName, header.ddspf.flags); + TraceLog(DEBUG, "[%s] DDS file format: 0x%x", fileName, fourCC); - // Top-right corner for texture and quad - glTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); - glVertex2f(destRec.width, destRec.height); + int bufsize; - // Top-left corner for texture and quad - glTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height); - glVertex2f(0.0f, destRec.height); - glEnd(); - glPopMatrix(); + // Calculate data size, including all mipmaps + bufsize = mipMapCount > 1 ? linearSize * 2 : linearSize; + + image.data = (unsigned char*)malloc(bufsize * sizeof(unsigned char)); + + fread(image.data, 1, bufsize, ddsFile); + + // Close file pointer + fclose(ddsFile); + + //int components = (fourCC == FOURCC_DXT1) ? 3 : 4; // Not required + + image.width = width; + image.height = height; + image.mipmaps = mipMapCount; + image.format = fourCC; + } + } - glDisable(GL_TEXTURE_2D); // Disable textures usage + return image; }
\ No newline at end of file |
