Преглед на файлове

Reviewed to work on Raspberry Pi

[rlgl] Extensions strings loading was redone to avoid a Segmentation
Fault on Raspberry Pi
raysan5 преди 10 години
родител
ревизия
4879106096
променени са 6 файла, в които са добавени 94 реда и са изтрити 118 реда
  1. 2 2
      src/core.c
  2. 1 1
      src/makefile
  3. 17 13
      src/models.c
  4. 64 95
      src/rlgl.c
  5. 1 3
      src/text.c
  6. 9 4
      src/textures.c

+ 2 - 2
src/core.c

@@ -1627,7 +1627,7 @@ static void PollInputEvents(void)
             else if (key == 0x7f) currentKeyState[259] = 1;
             else
             {
-                TraceLog(INFO, "Pressed key (ASCII): 0x%02x", key);
+                TraceLog(DEBUG, "Pressed key (ASCII): 0x%02x", key);
 
                 currentKeyState[key] = 1;
             }
@@ -1637,7 +1637,7 @@ static void PollInputEvents(void)
         }
         else if (keyboardMode == 1)
         {
-            TraceLog(INFO, "Pressed key (keycode): 0x%02x", key);
+            TraceLog(DEBUG, "Pressed key (keycode): 0x%02x", key);
 
             int asciiKey = -1;
 

+ 1 - 1
src/makefile

@@ -80,7 +80,7 @@ endif
 
 # define any directories containing required header files
 ifeq ($(PLATFORM),PLATFORM_RPI)
-    INCLUDES = -I. -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
+    INCLUDES = -I. -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads
 else
     INCLUDES = -I. -I../src
 # external libraries headers

+ 17 - 13
src/models.c

@@ -584,6 +584,7 @@ Model LoadModel(const char *fileName)
             free(vData.vertices);
             free(vData.texcoords);
             free(vData.normals);
+            free(vData.colors);
         }
     }
 
@@ -619,10 +620,10 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
 
     vData.vertexCount = numTriangles*3;
 
-    vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
-    vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char)); // Not used...
+    vData.vertices = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.normals = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.texcoords = (float *)malloc(vData.vertexCount*2*sizeof(float));
+    vData.colors = (unsigned char *)malloc(vData.vertexCount*4*sizeof(unsigned char)); // Not used...
 
     int vCounter = 0;       // Used to count vertices float by float
     int tcCounter = 0;      // Used to count texcoords float by float
@@ -722,6 +723,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
         free(vData.vertices);
         free(vData.texcoords);
         free(vData.normals);
+        free(vData.colors);
     }
 
     return model;
@@ -1038,10 +1040,10 @@ Model LoadCubicmap(Image cubicmap)
     // Move data from mapVertices temp arays to vertices float array
     vData.vertexCount = vCounter;
 
-    vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
-    vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char));  // Not used...
+    vData.vertices = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.normals = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.texcoords = (float *)malloc(vData.vertexCount*2*sizeof(float));
+    vData.colors = (unsigned char *)malloc(vData.vertexCount*4*sizeof(unsigned char));  // Not used...
 
     // Fill color data
     // NOTE: Not used any more... just one plain color defined at DrawModel()
@@ -1096,6 +1098,7 @@ Model LoadCubicmap(Image cubicmap)
         free(vData.vertices);
         free(vData.texcoords);
         free(vData.normals);
+        free(vData.colors);
     }
 
     return model;
@@ -1117,7 +1120,8 @@ void UnloadModel(Model model)
 
     rlDeleteVertexArrays(model.mesh.vaoId);
     
-    TraceLog(INFO, "Unloaded model data");
+    if (model.mesh.vaoId > 0) TraceLog(INFO, "[VAO ID %i] Unloaded model data from VRAM (GPU)", model.mesh.vaoId);
+    else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i] Unloaded model data from VRAM (GPU)", model.mesh.vboId[0], model.mesh.vboId[1], model.mesh.vboId[2]);
 }
 
 // Link a texture to a model
@@ -1718,10 +1722,10 @@ static VertexData LoadOBJ(const char *fileName)
     vData.vertexCount = numTriangles*3;
 
     // Additional arrays to store vertex data as floats
-    vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
-    vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
-    vData.colors = (unsigned char *)malloc(vData.vertexCount * 4 * sizeof(unsigned char));
+    vData.vertices = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.texcoords = (float *)malloc(vData.vertexCount*2*sizeof(float));
+    vData.normals = (float *)malloc(vData.vertexCount*3*sizeof(float));
+    vData.colors = (unsigned char *)malloc(vData.vertexCount*4*sizeof(unsigned char));
 
     int vCounter = 0;       // Used to count vertices float by float
     int tcCounter = 0;      // Used to count texcoords float by float

+ 64 - 95
src/rlgl.c

@@ -283,10 +283,6 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight);
 static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight);
 #endif
 
-#if defined(GRAPHICS_API_OPENGL_ES2)
-static char** StringSplit(char *baseString, const char delimiter, int *numExt);
-#endif
-
 #if defined(RLGL_STANDALONE)
 static void TraceLog(int msgType, const char *text, ...);
 #endif
@@ -863,7 +859,7 @@ void rlglInit(void)
 
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     // Get supported extensions list
-    GLint numExt;
+    GLint numExt = 0;
     
 #if defined(GRAPHICS_API_OPENGL_33)
 
@@ -923,21 +919,39 @@ void rlglInit(void)
     // NOTE: We don't need to check again supported extensions but we do (in case GLEW is replaced sometime)
     // We get a list of available extensions and we check for some of them (compressed textures)
     glGetIntegerv(GL_NUM_EXTENSIONS, &numExt);
-    const char *ext[numExt];
+    const char *extList[numExt];
     
-    for (int i = 0; i < numExt; i++) ext[i] = (char *)glGetStringi(GL_EXTENSIONS, i);
+    for (int i = 0; i < numExt; i++) extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i);
     
 #elif defined(GRAPHICS_API_OPENGL_ES2)
-    char *extensions = (char *)glGetString(GL_EXTENSIONS);  // One big string
+    char *extensions = (char *)glGetString(GL_EXTENSIONS);  // One big const string
+    
+    // NOTE: We have to duplicate string because glGetString() returns a const value
+    // If not duplicated, it fails in some systems (Raspberry Pi)
+    char *extensionsDup = strdup(extensions);
     
     // NOTE: String could be splitted using strtok() function (string.h)
-    char **ext = StringSplit(extensions, ' ', &numExt);
+    // NOTE: strtok() modifies the received string, it can not be const
+    
+    char *extList[512];     // Allocate 512 strings pointers (2 KB)
+
+    extList[numExt] = strtok(extensionsDup, " ");
+
+    while (extList[numExt] != NULL)
+    {
+        numExt++;
+        extList[numExt] = strtok(NULL, " ");
+    }
+    
+    free(extensionsDup);    // Duplicated string must be deallocated
+    
+    numExt -= 1;
 #endif
 
     TraceLog(INFO, "Number of supported extensions: %i", numExt);
 
     // Show supported extensions
-    //for (int i = 0; i < numExt; i++)  TraceLog(INFO, "Supported extension: %s", ext[i]);
+    //for (int i = 0; i < numExt; i++)  TraceLog(INFO, "Supported extension: %s", extList[i]);
 
     // Check required extensions
     for (int i = 0; i < numExt; i++)
@@ -945,7 +959,7 @@ void rlglInit(void)
 #if defined(GRAPHICS_API_OPENGL_ES2)
         // Check VAO support
         // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature
-        if (strcmp(ext[i], (const char *)"GL_OES_vertex_array_object") == 0)
+        if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0)
         {
             vaoSupported = true;
             
@@ -959,23 +973,23 @@ void rlglInit(void)
         
         // Check NPOT textures support
         // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
-        if (strcmp(ext[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
+        if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
 #endif   
         
         // DDS texture compression support
-        if (strcmp(ext[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) texCompDXTSupported = true; 
+        if (strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) texCompDXTSupported = true; 
         
         // ETC1 texture compression support
-        if (strcmp(ext[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) texCompETC1Supported = true;
+        if (strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) texCompETC1Supported = true;
 
         // ETC2/EAC texture compression support
-        if (strcmp(ext[i], (const char *)"GL_ARB_ES3_compatibility") == 0) texCompETC2Supported = true;
+        if (strcmp(extList[i], (const char *)"GL_ARB_ES3_compatibility") == 0) texCompETC2Supported = true;
 
         // PVR texture compression support
-        if (strcmp(ext[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) texCompPVRTSupported = true;
+        if (strcmp(extList[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) texCompPVRTSupported = true;
 
         // ASTC texture compression support
-        if (strcmp(ext[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true;
+        if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true;
     }
     
 #if defined(GRAPHICS_API_OPENGL_ES2)
@@ -984,9 +998,6 @@ void rlglInit(void)
     
     if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
     else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, NPOT textures not supported");
-    
-    // Once supported extensions have been checked, we should free strings memory
-    free(ext);
 #endif
 
     if (texCompDXTSupported) TraceLog(INFO, "[EXTENSION] DXT compressed textures supported");
@@ -1008,8 +1019,16 @@ void rlglInit(void)
 
     // Initialize matrix stack
     for (int i = 0; i < MATRIX_STACK_SIZE; i++) stack[i] = MatrixIdentity();
+    
+    // Create default white texture for plain colors (required by shader)
+    unsigned char pixels[4] = { 255, 255, 255, 255 };   // 1 pixel RGBA (4 bytes)
 
-    // Init default Shader (GLSL 110) -> Common for GL 3.3+ and ES2
+    whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1);
+
+    if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
+    else TraceLog(WARNING, "Base white texture could not be loaded");
+
+    // Init default Shader (Custom for GL 3.3 and ES2)
     defaultShader = LoadDefaultShader();
     simpleShader = LoadSimpleShader();
     //customShader = LoadShader("custom.vs", "custom.fs");     // Works ok
@@ -1024,14 +1043,6 @@ void rlglInit(void)
 
     for (int i = 0; i < TEMP_VERTEX_BUFFER_SIZE; i++) tempBuffer[i] = VectorZero();
 
-    // Create default white texture for plain colors (required by shader)
-    unsigned char pixels[4] = { 255, 255, 255, 255 };   // 1 pixel RGBA (4 bytes)
-
-    whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1);
-
-    if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
-    else TraceLog(WARNING, "Base white texture could not be loaded");
-
     // Init draw calls tracking system
     draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
 
@@ -1189,6 +1200,7 @@ void rlglClose(void)
 
     // Free GPU texture
     glDeleteTextures(1, &whiteTexture);
+    TraceLog(INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", whiteTexture);
 
     if (fbo != 0)
     {
@@ -1207,7 +1219,7 @@ void rlglClose(void)
 
         rlDeleteVertexArrays(postproQuad.mesh.vaoId);
         
-        TraceLog(INFO, "Unloaded postpro quad data");
+        TraceLog(INFO, "[FBO %i] Unloaded postpro quad data", fbo);
     }
 
     free(draws);
@@ -1869,12 +1881,12 @@ Model rlglLoadModel(VertexData mesh)
 
     model.mesh = mesh;
     model.transform = MatrixIdentity();
-
-#if defined(GRAPHICS_API_OPENGL_11)
     model.mesh.vaoId = 0;       // Vertex Array Object
     model.mesh.vboId[0] = 0;    // Vertex position VBO
     model.mesh.vboId[1] = 0;    // Texcoords VBO
     model.mesh.vboId[2] = 0;    // Normals VBO
+
+#if defined(GRAPHICS_API_OPENGL_11)
     model.texture.id = 0;       // No texture required
     model.shader.id = 0;        // No shader used
 
@@ -1882,8 +1894,9 @@ Model rlglLoadModel(VertexData mesh)
     model.texture.id = whiteTexture;    // Default whiteTexture
     model.texture.width = 1;            // Default whiteTexture width
     model.texture.height = 1;           // Default whiteTexture height
+    model.texture.format = UNCOMPRESSED_R8G8B8A8; // Default whiteTexture format
     model.shader = simpleShader;        // Default model shader
-
+    
     GLuint vaoModel = 0;         // Vertex Array Objects (VAO)
     GLuint vertexBuffer[3];      // Vertex Buffer Objects (VBO)
 
@@ -2533,14 +2546,14 @@ static Shader LoadDefaultShader(void)
 
     // Vertex shader directly defined, no external file required
 #if defined(GRAPHICS_API_OPENGL_33)
-    char vShaderStr[] = " #version 330      \n"
+    char vShaderStr[] = "#version 330       \n"
         "in vec3 vertexPosition;            \n"
         "in vec2 vertexTexCoord;            \n"
         "in vec4 vertexColor;               \n"
         "out vec2 fragTexCoord;             \n"
         "out vec4 tintColor;                \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
-    char vShaderStr[] = " #version 100      \n"
+    char vShaderStr[] = "#version 100       \n"
         "attribute vec3 vertexPosition;     \n"
         "attribute vec2 vertexTexCoord;     \n"
         "attribute vec4 vertexColor;        \n"
@@ -2558,11 +2571,11 @@ static Shader LoadDefaultShader(void)
 
     // Fragment shader directly defined, no external file required
 #if defined(GRAPHICS_API_OPENGL_33)
-    char fShaderStr[] = " #version 330      \n"
+    char fShaderStr[] = "#version 330       \n"
         "in vec2 fragTexCoord;              \n"
         "in vec4 tintColor;                 \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
-    char fShaderStr[] = " #version 100      \n"
+    char fShaderStr[] = "#version 100       \n"
         "precision mediump float;           \n"     // precision required for OpenGL ES2 (WebGL)
         "varying vec2 fragTexCoord;         \n"
         "varying vec4 tintColor;            \n"
@@ -2596,6 +2609,10 @@ static Shader LoadDefaultShader(void)
     shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
     shader.mapNormalLoc = -1;       // It can be set later
     shader.mapSpecularLoc = -1;     // It can be set later
+    
+    shader.texDiffuseId = whiteTexture; // Default white texture
+    shader.texNormalId = 0;
+    shader.texSpecularId = 0;
     //--------------------------------------------------------------------
 
     return shader;
@@ -2613,13 +2630,13 @@ static Shader LoadSimpleShader(void)
 
     // Vertex shader directly defined, no external file required
 #if defined(GRAPHICS_API_OPENGL_33)
-    char vShaderStr[] = " #version 330      \n"
+    char vShaderStr[] = "#version 330       \n"
         "in vec3 vertexPosition;            \n"
         "in vec2 vertexTexCoord;            \n"
         "in vec3 vertexNormal;              \n"
         "out vec2 fragTexCoord;             \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
-    char vShaderStr[] = " #version 100      \n"
+    char vShaderStr[] = "#version 100       \n"
         "attribute vec3 vertexPosition;     \n"
         "attribute vec2 vertexTexCoord;     \n"
         "attribute vec3 vertexNormal;       \n"
@@ -2635,10 +2652,10 @@ static Shader LoadSimpleShader(void)
 
     // Fragment shader directly defined, no external file required
 #if defined(GRAPHICS_API_OPENGL_33)
-    char fShaderStr[] = " #version 330      \n"
-        "in vec2 fragTexCoord;         \n"
+    char fShaderStr[] = "#version 330       \n"
+        "in vec2 fragTexCoord;              \n"
 #elif defined(GRAPHICS_API_OPENGL_ES2)
-    char fShaderStr[] = " #version 100      \n"
+    char fShaderStr[] = "#version 100       \n"
         "precision mediump float;           \n"     // precision required for OpenGL ES2 (WebGL)
         "varying vec2 fragTexCoord;         \n"
 #endif
@@ -2672,6 +2689,10 @@ static Shader LoadSimpleShader(void)
     shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0");
     shader.mapNormalLoc = -1;       // It can be set later
     shader.mapSpecularLoc = -1;     // It can be set later
+    
+    shader.texDiffuseId = whiteTexture; // Default white texture
+    shader.texNormalId = 0;
+    shader.texSpecularId = 0;
     //--------------------------------------------------------------------
 
     return shader;
@@ -2698,7 +2719,7 @@ static char *TextFileRead(char *fileName)
 
             if (count > 0)
             {
-                text = (char *)malloc(sizeof(char) * (count + 1));
+                text = (char *)malloc(sizeof(char)*(count + 1));
                 count = fread(text, sizeof(char), count, textFile);
                 text[count] = '\0';
             }
@@ -3091,55 +3112,3 @@ static void TraceLog(int msgType, const char *text, ...)
     if (msgType == ERROR) exit(1);
 }
 #endif
-
-#if defined(GRAPHICS_API_OPENGL_ES2)
-static char **StringSplit(char *baseString, const char delimiter, int *numExt)
-{
-    char **result = 0;
-    int count = 0;
-    char *tmp = baseString;
-    char *lastComma = 0;
-    char delim[2];
-    
-    delim[0] = delimiter;
-    delim[1] = 0;
-
-    // Count how many elements will be extracted
-    while (*tmp)
-    {
-        if (delimiter == *tmp)
-        {
-            count++;
-            lastComma = tmp;
-        }
-        
-        tmp++;
-    }
-
-    // Add space for trailing token
-    count += lastComma < (baseString + strlen(baseString) - 1);
-
-    // Add space for terminating null string
-    count++;
-
-    result = malloc(sizeof(char *)*count);
-
-    if (result)
-    {
-        int idx = 0;
-        char *token = strtok(baseString, delim);
-
-        while (token)
-        {
-            *(result + idx++) = token;
-            token = strtok(0, delim);
-        }
-
-        *(result + idx) = 0;
-    }
-    
-    *numExt = (count - 1);
-
-    return result;
-}
-#endif

+ 1 - 3
src/text.c

@@ -221,8 +221,6 @@ extern void UnloadDefaultFont(void)
     UnloadTexture(defaultFont.texture);
     free(defaultFont.charValues);
     free(defaultFont.charRecs);
-    
-    TraceLog(INFO, "Unloaded default font data");
 }
 
 // Get the default font, useful to be used with extended parameters
@@ -243,7 +241,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
     {
         Image image = LoadImage(fileName);
 
-#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+#if defined(PLATFORM_WEB)
         ImageConvertToPOT(&image, MAGENTA);
 #endif
         // Process bitmap font pixel data to get characters measures

+ 9 - 4
src/textures.c

@@ -321,7 +321,7 @@ Texture2D LoadTexture(const char *fileName)
 
     Image image = LoadImage(fileName);
     
-#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+#if defined(PLATFORM_WEB)
     ImageConvertToPOT(&image, BLANK);
 #endif
 
@@ -404,7 +404,7 @@ void UnloadTexture(Texture2D texture)
     {
         rlDeleteTextures(texture.id);
         
-        TraceLog(INFO, "[TEX ID %i] Unloaded texture data", texture.id);
+        TraceLog(INFO, "[TEX ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
     }
 }
 
@@ -501,7 +501,10 @@ Image GetTextureData(Texture2D texture)
 {
     Image image;
     image.data = NULL;
-    
+
+#if defined(GRAPHICS_API_OPENGL_ES2)
+    TraceLog(WARNING, "Texture data retrieval not supported on OpenGL ES 2.0");
+#else
     if (texture.format < 8)
     {
         image.data = rlglReadTexturePixels(texture.id, texture.format);
@@ -518,7 +521,7 @@ Image GetTextureData(Texture2D texture)
         else TraceLog(WARNING, "Texture pixel data could not be obtained");
     }
     else TraceLog(WARNING, "Compressed texture data could not be obtained");
-    
+#endif
     return image;
 }
 
@@ -695,6 +698,8 @@ void ImageConvertToPOT(Image *image, Color fillColor)
         
         int format = image->format;         // Store image data format to reconvert later
         
+        // TODO: Image width and height changes... do we want to store new values or keep the old ones?
+        // NOTE: Issues when using image.width and image.height for sprite animations...
         *image = LoadImageEx(pixelsPOT, potWidth, potHeight);
         
         free(pixelsPOT);                    // Free POT pixels data