From 9e450df053c9b6f13a89553d65425c350d4399dd Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 21 May 2015 00:18:22 +0200 Subject: [PATCH] Added extensions check on rlglInit() and more Corrected shader version depending on OGL version Corrected bug in gestures module --- src/core.c | 2 +- src/gestures.c | 12 +- src/rlgl.c | 418 +++++++++++++++++++++++++++++-------------------- 3 files changed, 252 insertions(+), 180 deletions(-) diff --git a/src/core.c b/src/core.c index cc8f31fd..ff704ed4 100644 --- a/src/core.c +++ b/src/core.c @@ -211,7 +211,7 @@ extern void InitAndroidGestures(struct android_app *app); #endif #if defined(PLATFORM_WEB) -extern void InitWebGestures(void); +extern void InitWebGestures(void); // [Module: gestures] Initializes emscripten gestures for web #endif //---------------------------------------------------------------------------------- diff --git a/src/gestures.c b/src/gestures.c index 2574aa02..55bae328 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -531,6 +531,7 @@ static float DotProduct(Vector2 v1, Vector2 v2) static double GetCurrentTime() { + double time = 0; #if defined(_WIN32) /* // NOTE: Requires Windows.h @@ -538,7 +539,7 @@ static double GetCurrentTime() GetSystemTimePreciseAsFileTime(&tm); ULONGLONG nowTime = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime; // Time provided in 100-nanosecond intervals - return ((double)nowTime/10000000.0); // Return time in seconds + time = ((double)nowTime/10000000.0); // time in seconds */ #endif @@ -548,8 +549,10 @@ static double GetCurrentTime() clock_gettime(CLOCK_MONOTONIC, &now); uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time provided in nanoseconds - return ((double)nowTime/1000000.0); // Return time in miliseconds + time = ((double)nowTime/1000000.0); // time in miliseconds #endif + + return time; } #if defined(PLATFORM_ANDROID) @@ -618,9 +621,6 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY); } */ - - touchPosition = gestureEvent.position[0]; - GestureEvent gestureEvent; // Action @@ -635,6 +635,8 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].canvasX, touchEvent->touches[0].canvasY }; gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].canvasX, touchEvent->touches[1].canvasY }; + touchPosition = gestureEvent.position[0]; + ProcessMotionEvent(gestureEvent); return 1; diff --git a/src/rlgl.c b/src/rlgl.c index 7349af53..49e51406 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -30,7 +30,7 @@ #include // Standard input / output lib #include // Declares malloc() and free() for memory management, rand() -#include // Declares strcmp(), strlen(), strtok(), strdup() +#include // Declares strcmp(), strlen(), strtok() #if defined(GRAPHICS_API_OPENGL_11) #ifdef __APPLE__ // OpenGL include for OSX @@ -216,8 +216,16 @@ static Vector3 *tempBuffer; static int tempBufferCount = 0; static bool useTempBuffer = false; -// Support for VAOs (OpenGL ES2 could not support VAO extensions) -static bool vaoSupported = false; +// Flags for supported extensions +static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) +static bool npotSupported = false; // NPOT textures full support + +// Compressed textures support flags +static bool texCompDXTSupported = false; // DDS texture compression support +static bool texCompETC1Supported = false; // ETC1 texture compression support +static bool texCompETC2Supported = false; // ETC2/EAC texture compression support +static bool texCompPVRTSupported = false; // PVR texture compression support +static bool texCompASTCSupported = false; // ASTC texture compression support // Framebuffer object and texture static GLuint fbo, fboColorTexture, fboDepthTexture; @@ -226,19 +234,16 @@ static Model postproQuad; #if defined(GRAPHICS_API_OPENGL_ES2) // NOTE: VAO functionality is exposed through extensions (OES) -// emscripten does not support VAOs static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays; static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray; static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays; -static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; +//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted #endif // White texture useful for plain color polys (required by shader) // NOTE: It's required in shapes and models modules! unsigned int whiteTexture; -static bool supportedTextureFormat[32]; - //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- @@ -249,6 +254,8 @@ static void InitializeBuffers(void); static void InitializeBuffersGPU(void); static void UpdateBuffers(void); static char *TextFileRead(char *fn); + +static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat); #endif #if defined(GRAPHICS_API_OPENGL_11) @@ -256,7 +263,7 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight); static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight); #endif -static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat); +static char** StringSplit(char *baseString, const char delimiter, int *numExt); //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations @@ -795,58 +802,9 @@ int rlGetVersion(void) // Init OpenGL 3.3+ required data void rlglInit(void) { -#if defined(GRAPHICS_API_OPENGL_33) - // Loading extensions the hard way (Example) -/* - GLint numExt; - glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); - - for (int i = 0; i < numExt; i++) - { - const GLubyte *extensionName = glGetStringi(GL_EXTENSIONS, i); - if (strcmp(extensionName, (const GLubyte *)"GL_ARB_vertex_array_object") == 0) - { - // The extension is supported by our hardware and driver, try to get related functions pointers - glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)wglGetProcAddress("glGenVertexArrays"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)wglGetProcAddress("glBindVertexArray"); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)wglGetProcAddress("glDeleteVertexArrays"); - glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)wglGetProcAddress("glIsVertexArray"); - } - } -*/ - - // Initialize extensions using GLEW - glewExperimental = 1; // Needed for core profile - - GLenum error = glewInit(); - - if (error != GLEW_OK) TraceLog(ERROR, "Failed to initialize GLEW - Error Code: %s\n", glewGetErrorString(error)); - - if (glewIsSupported("GL_VERSION_3_3")) TraceLog(INFO, "OpenGL 3.3 extensions supported"); - - // NOTE: GLEW is a big library that loads ALL extensions, using glad we can only load required ones... - //if (!gladLoadGL()) TraceLog("ERROR: Failed to initialize glad\n"); - - vaoSupported = true; -#endif - -#if defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... -#if !defined(PLATFORM_WEB) - glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); - glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); - glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); -#endif - - if (glGenVertexArrays == NULL) TraceLog(WARNING, "Could not initialize VAO extensions, VAOs not supported"); - else - { - vaoSupported = true; - TraceLog(INFO, "VAO extensions initialized successfully"); - } -#endif - + // Check OpenGL information and capabilities + //------------------------------------------------------------------------------ + // Print current OpenGL and GLSL version TraceLog(INFO, "GPU: Vendor: %s", glGetString(GL_VENDOR)); TraceLog(INFO, "GPU: Renderer: %s", glGetString(GL_RENDERER)); @@ -857,80 +815,129 @@ void rlglInit(void) //int maxTexSize; //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); //TraceLog(INFO, "GL_MAX_TEXTURE_SIZE: %i", maxTexSize); + + //GL_MAX_TEXTURE_IMAGE_UNITS + //GL_MAX_VIEWPORT_DIMS //int numAuxBuffers; //glGetIntegerv(GL_AUX_BUFFERS, &numAuxBuffers); //TraceLog(INFO, "GL_AUX_BUFFERS: %i", numAuxBuffers); + + //GLint numComp = 0; + //GLint format[32] = { 0 }; + //glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp); + //glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format); + //for (int i = 0; i < numComp; i++) TraceLog(INFO, "Supported compressed format: 0x%x", format[i]); - // Show supported extensions // NOTE: We don't need that much data on screen... right now... - - // Check available extensions for compressed textures support - for (int i = 0; i < 32; i++) supportedTextureFormat[i] = false; -#if defined(GRAPHICS_API_OPENGL_33) +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + // Get supported extensions list GLint numExt; + +#if defined(GRAPHICS_API_OPENGL_33) + // Initialize extensions using GLEW + glewExperimental = 1; // Needed for core profile + + GLenum error = glewInit(); + + if (error != GLEW_OK) TraceLog(ERROR, "Failed to initialize GLEW - Error Code: %s\n", glewGetErrorString(error)); + + if (glewIsSupported("GL_VERSION_3_3")) + { + TraceLog(INFO, "OpenGL 3.3 Core profile"); + + vaoSupported = true; + npotSupported = true; + } + + // NOTE: GLEW is a big library that loads ALL extensions, we can use some alternative to load only required ones + // Alternatives: glLoadGen, glad, libepoxy + //if (!gladLoadGL()) TraceLog("ERROR: Failed to initialize glad\n"); + + // With GLEW we can check if an extension has been loaded in two ways: + //if (GLEW_ARB_vertex_array_object) { } + //if (glewIsSupported("GL_ARB_vertex_array_object")) { } + + + // 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]; + + for (int i = 0; i < numExt; i++) ext[i] = (char *)glGetStringi(GL_EXTENSIONS, i); + +#elif defined(GRAPHICS_API_OPENGL_ES2) + char *extensions = (char *)glGetString(GL_EXTENSIONS); // One big string + + // NOTE: String could be splitted using strtok() function (string.h) + char **ext = StringSplit(extensions, ' ', &numExt); +#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]); + + // Check required extensions for (int i = 0; i < numExt; i++) { - //TraceLog(INFO, "Supported extension: %s", glGetStringi(GL_EXTENSIONS, i)); - - if (strcmp((char *)glGetStringi(GL_EXTENSIONS, i), "GL_EXT_texture_compression_s3tc") == 0) - { - // DDS texture compression support - supportedTextureFormat[COMPRESSED_DXT1_RGB] = true; - supportedTextureFormat[COMPRESSED_DXT1_RGBA] = true; - supportedTextureFormat[COMPRESSED_DXT3_RGBA] = true; - supportedTextureFormat[COMPRESSED_DXT5_RGBA] = true; - } - else if (strcmp((char *)glGetStringi(GL_EXTENSIONS, i), "GL_OES_compressed_ETC1_RGB8_texture") == 0) - { - // ETC1 texture compression support - supportedTextureFormat[COMPRESSED_ETC1_RGB] = true; - } - else if (strcmp((char *)glGetStringi(GL_EXTENSIONS, i),"GL_ARB_ES3_compatibility") == 0) - { - // ETC2/EAC texture compression support - supportedTextureFormat[COMPRESSED_ETC2_RGB] = true; - supportedTextureFormat[COMPRESSED_ETC2_EAC_RGBA] = true; - } - else if (strcmp((char *)glGetStringi(GL_EXTENSIONS, i),"GL_IMG_texture_compression_pvrtc") == 0) - { - // PVR texture compression support - supportedTextureFormat[COMPRESSED_PVRT_RGB] = true; - supportedTextureFormat[COMPRESSED_PVRT_RGBA] = true; - } - else if (strcmp((char *)glGetStringi(GL_EXTENSIONS, i),"GL_KHR_texture_compression_astc_hdr") == 0) +#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) { - // ASTC texture compression support - supportedTextureFormat[COMPRESSED_ASTC_4x4_RGBA] = true; - supportedTextureFormat[COMPRESSED_ASTC_8x8_RGBA] = true; + vaoSupported = true; + + // The extension is supported by our hardware and driver, try to get related functions pointers + // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... + glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); + glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); + //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted } - } -#elif defined(GRAPHICS_API_OPENGL_ES2) - char *extensions = (char *)glGetString(GL_EXTENSIONS); // One big string + + // 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; +#endif + + // DDS texture compression support + if (strcmp(ext[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; - // NOTE: String could be splitted using strtok() function (string.h) - TraceLog(INFO, "Supported extension: %s", extensions); + // ETC2/EAC texture compression support + if (strcmp(ext[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; + + // ASTC texture compression support + if (strcmp(ext[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true; + } - //char** ext = StringSplit(extensions, ' '); - //for (int i = 0; i < numExt; i++) printf("%s", ext[i]); +#if defined(GRAPHICS_API_OPENGL_ES2) + if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully"); + else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported"); -#endif -/* - GLint numComp = 0; - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp); + 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"); - GLint format[32] = { 0 }; - glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format); + // Once supported extensions have been checked, we should free strings memory + free(ext); +#endif - for (int i = 0; i < numComp; i++) - { - TraceLog(INFO, "Supported compressed format: 0x%x", format[i]); - } -*/ -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (texCompDXTSupported) TraceLog(INFO, "[EXTENSION] DXT compressed textures supported"); + if (texCompETC1Supported) TraceLog(INFO, "[EXTENSION] ETC1 compressed textures supported"); + if (texCompETC2Supported) TraceLog(INFO, "[EXTENSION] ETC2/EAC compressed textures supported"); + if (texCompPVRTSupported) TraceLog(INFO, "[EXTENSION] PVRT compressed textures supported"); + if (texCompASTCSupported) TraceLog(INFO, "[EXTENSION] ASTC compressed textures supported"); + + // Initialize buffers, default shaders and default textures + //---------------------------------------------------------- + // Set default draw mode currentDrawMode = RL_TRIANGLES; @@ -1435,6 +1442,7 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) } // Get world coordinates from screen coordinates +// TODO: It doesn't work! It drives me crazy! Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) { //GLint viewport[4]; @@ -1601,19 +1609,13 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma { glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding - GLuint id; + GLuint id = 0; - // Check compressed textures support by OpenGL 1.1 - if (rlGetVersion() == OPENGL_11) + // Check texture format support by OpenGL 1.1 (compressed textures not supported) + if ((rlGetVersion() == OPENGL_11) && (textureFormat >= 8)) { - if ((textureFormat == COMPRESSED_ETC1_RGB) || (textureFormat == COMPRESSED_ETC2_RGB) || (textureFormat == COMPRESSED_ETC2_EAC_RGBA) || - (textureFormat == COMPRESSED_PVRT_RGB) || (textureFormat == COMPRESSED_PVRT_RGBA) || - (textureFormat == COMPRESSED_ASTC_4x4_RGBA) || (textureFormat == COMPRESSED_ASTC_8x8_RGBA)) - { - id = 0; - TraceLog(WARNING, "Required GPU compressed texture format not supported"); - return id; - } + TraceLog(WARNING, "OpenGL 1.1 does not support GPU compressed texture formats"); + return id; } glGenTextures(1, &id); // Generate Pointer to the texture @@ -1657,22 +1659,23 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } break; + case UNCOMPRESSED_R5G6B5: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break; case UNCOMPRESSED_R8G8B8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break; case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break; case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break; case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; - case COMPRESSED_DXT1_RGB: if (supportedTextureFormat[COMPRESSED_DXT1_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break; - case COMPRESSED_DXT1_RGBA: if (supportedTextureFormat[COMPRESSED_DXT1_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break; - case COMPRESSED_DXT3_RGBA: if (supportedTextureFormat[COMPRESSED_DXT3_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; - case COMPRESSED_DXT5_RGBA: if (supportedTextureFormat[COMPRESSED_DXT5_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break; - case COMPRESSED_ETC1_RGB: if (supportedTextureFormat[COMPRESSED_ETC1_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_ETC1_RGB8_OES); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 - case COMPRESSED_ETC2_RGB: if (supportedTextureFormat[COMPRESSED_ETC2_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case COMPRESSED_ETC2_EAC_RGBA: if (supportedTextureFormat[COMPRESSED_ETC2_EAC_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case COMPRESSED_PVRT_RGB: if (supportedTextureFormat[COMPRESSED_PVRT_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU - case COMPRESSED_PVRT_RGBA: if (supportedTextureFormat[COMPRESSED_PVRT_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU - case COMPRESSED_ASTC_4x4_RGBA: if (supportedTextureFormat[COMPRESSED_ASTC_4x4_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 - case COMPRESSED_ASTC_8x8_RGBA: if (supportedTextureFormat[COMPRESSED_ASTC_8x8_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_8x8_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break; + case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break; + case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; + case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break; + case COMPRESSED_ETC1_RGB: if (texCompETC1Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_ETC1_RGB8_OES); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 + case COMPRESSED_ETC2_RGB: if (texCompETC2Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case COMPRESSED_ETC2_EAC_RGBA: if (texCompETC2Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case COMPRESSED_PVRT_RGB: if (texCompPVRTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU + case COMPRESSED_PVRT_RGBA: if (texCompPVRTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU + case COMPRESSED_ASTC_4x4_RGBA: if (texCompASTCSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + case COMPRESSED_ASTC_8x8_RGBA: if (texCompASTCSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_8x8_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 default: TraceLog(WARNING, "Texture format not recognized"); break; } #elif defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_ES2) @@ -1686,17 +1689,19 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break; case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break; case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; - case COMPRESSED_DXT1_RGB: if (supportedTextureFormat[COMPRESSED_DXT1_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break; - case COMPRESSED_DXT1_RGBA: if (supportedTextureFormat[COMPRESSED_DXT1_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break; - case COMPRESSED_DXT3_RGBA: if (supportedTextureFormat[COMPRESSED_DXT3_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; // NOTE: Not supported by WebGL - case COMPRESSED_DXT5_RGBA: if (supportedTextureFormat[COMPRESSED_DXT5_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break; // NOTE: Not supported by WebGL - case COMPRESSED_ETC1_RGB: if (supportedTextureFormat[COMPRESSED_ETC1_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_ETC1_RGB8_OES); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 - case COMPRESSED_ETC2_RGB: if (supportedTextureFormat[COMPRESSED_ETC2_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case COMPRESSED_ETC2_EAC_RGBA: if (supportedTextureFormat[COMPRESSED_ETC2_EAC_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 - case COMPRESSED_PVRT_RGB: if (supportedTextureFormat[COMPRESSED_PVRT_RGB]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU - case COMPRESSED_PVRT_RGBA: if (supportedTextureFormat[COMPRESSED_PVRT_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU - case COMPRESSED_ASTC_4x4_RGBA: if (supportedTextureFormat[COMPRESSED_ASTC_4x4_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 - case COMPRESSED_ASTC_8x8_RGBA: if (supportedTextureFormat[COMPRESSED_ASTC_8x8_RGBA]) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_8x8_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 +#if defined(GRAPHICS_API_OPENGL_ES2) + case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break; + case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break; + case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; // NOTE: Not supported by WebGL + case COMPRESSED_DXT5_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT); break; // NOTE: Not supported by WebGL + case COMPRESSED_ETC1_RGB: if (texCompETC1Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_ETC1_RGB8_OES); break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 + case COMPRESSED_ETC2_RGB: if (texCompETC2Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB8_ETC2); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case COMPRESSED_ETC2_EAC_RGBA: if (texCompETC2Supported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA8_ETC2_EAC); break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 + case COMPRESSED_PVRT_RGB: if (texCompPVRTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU + case COMPRESSED_PVRT_RGBA: if (texCompPVRTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG); break; // NOTE: Requires PowerVR GPU + case COMPRESSED_ASTC_4x4_RGBA: if (texCompASTCSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_4x4_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + case COMPRESSED_ASTC_8x8_RGBA: if (texCompASTCSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_ASTC_8x8_KHR); break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 +#endif default: TraceLog(WARNING, "Texture format not supported"); break; } #endif @@ -1778,7 +1783,8 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma // Unbind current texture glBindTexture(GL_TEXTURE_2D, 0); - TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height); + if (id > 0) TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height); + else TraceLog(WARNING, "Texture could not be created"); return id; } @@ -2154,37 +2160,45 @@ static Shader LoadDefaultShader(void) // Vertex shader directly defined, no external file required #if defined(GRAPHICS_API_OPENGL_33) - char vShaderStr[] = " #version 110 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) + 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" // NOTE: Must be defined this way! 110 doesn't work! -#endif - "uniform mat4 projectionMatrix; \n" - "uniform mat4 modelviewMatrix; \n" + char vShaderStr[] = " #version 100 \n" "attribute vec3 vertexPosition; \n" "attribute vec2 vertexTexCoord; \n" "attribute vec4 vertexColor; \n" "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" + "varying vec4 tintColor; \n" +#endif + "uniform mat4 projectionMatrix; \n" + "uniform mat4 modelviewMatrix; \n" "void main() \n" "{ \n" " fragTexCoord = vertexTexCoord; \n" - " fragColor = vertexColor; \n" - " gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0); \n" + " tintColor = vertexColor; \n" + " gl_Position = projectionMatrix*modelviewMatrix*vec4(vertexPosition, 1.0); \n" "} \n"; // Fragment shader directly defined, no external file required #if defined(GRAPHICS_API_OPENGL_33) - char fShaderStr[] = " #version 110 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) + char fShaderStr[] = " #version 330 \n" + "in vec2 fragTexCoord; \n" + "in vec4 tintColor; \n" #elif defined(GRAPHICS_API_OPENGL_ES2) - char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work! - "precision mediump float; \n" // WebGL, required for emscripten + char fShaderStr[] = " #version 100 \n" + "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) + "varying vec2 fragTexCoord; \n" + "varying vec4 tintColor; \n" #endif "uniform sampler2D texture0; \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" "void main() \n" "{ \n" - " gl_FragColor = texture2D(texture0, fragTexCoord) * fragColor; \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0, use texture() instead + " gl_FragColor = texelColor*tintColor; \n" "} \n"; shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr); @@ -2222,35 +2236,41 @@ static Shader LoadSimpleShader(void) // Vertex shader directly defined, no external file required #if defined(GRAPHICS_API_OPENGL_33) - char vShaderStr[] = " #version 330 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) + 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" // NOTE: Must be defined this way! 110 doesn't work! -#endif - "uniform mat4 projectionMatrix; \n" - "uniform mat4 modelviewMatrix; \n" + char vShaderStr[] = " #version 100 \n" "attribute vec3 vertexPosition; \n" "attribute vec2 vertexTexCoord; \n" "attribute vec3 vertexNormal; \n" "varying vec2 fragTexCoord; \n" +#endif + "uniform mat4 projectionMatrix; \n" + "uniform mat4 modelviewMatrix; \n" "void main() \n" "{ \n" " fragTexCoord = vertexTexCoord; \n" - " gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0); \n" + " gl_Position = projectionMatrix*modelviewMatrix*vec4(vertexPosition, 1.0); \n" "} \n"; // Fragment shader directly defined, no external file required #if defined(GRAPHICS_API_OPENGL_33) - char fShaderStr[] = " #version 330 \n" // NOTE: Actually, #version 110 (quivalent to #version 100 on ES2) + char fShaderStr[] = " #version 330 \n" + "in vec2 fragTexCoord; \n" #elif defined(GRAPHICS_API_OPENGL_ES2) - char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work! + char fShaderStr[] = " #version 100 \n" "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) + "varying vec2 fragTexCoord; \n" #endif "uniform sampler2D texture0; \n" - "varying vec2 fragTexCoord; \n" "uniform vec4 tintColor; \n" "void main() \n" "{ \n" - " gl_FragColor = texture2D(texture0, fragTexCoord) * tintColor; \n" + " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0, use texture() instead + " gl_FragColor = texelColor*tintColor; \n" "} \n"; shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr); @@ -2692,4 +2712,54 @@ void TraceLog(int msgType, const char *text, ...) if (msgType == ERROR) exit(1); } -#endif \ No newline at end of file +#endif + +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; +} \ No newline at end of file