Mercurial
comparison third_party/raylib/include/rlgl.h @ 276:b55c22cff335
Add interactive infinite canvas prototype
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 16:57:56 -0700 |
| parents | f33d9ff8b6e8 |
| children |
comparison
equal
deleted
inserted
replaced
| 274:c9be578316a6 | 276:b55c22cff335 |
|---|---|
| 1 /********************************************************************************************** | 1 /********************************************************************************************** |
| 2 * | 2 * |
| 3 * rlgl v5.0 - A multi-OpenGL abstraction layer with an immediate-mode style API | 3 * rlgl v6.0 - A multi-OpenGL abstraction layer with an immediate-mode style API |
| 4 * | 4 * |
| 5 * DESCRIPTION: | 5 * DESCRIPTION: |
| 6 * An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) | 6 * An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0, ES 3.0) |
| 7 * that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) | 7 * that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) |
| 8 * | 8 * |
| 9 * ADDITIONAL NOTES: | 9 * ADDITIONAL NOTES: |
| 10 * When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are | 10 * When choosing an OpenGL backend different than OpenGL 1.1, some internal buffers are |
| 11 * initialized on rlglInit() to accumulate vertex data | 11 * initialized on rlglInit() to accumulate vertex data |
| 12 * | 12 * |
| 13 * When an internal state change is required all the stored vertex data is renderer in batch, | 13 * When an internal state change is required all the stored vertex data is rendered in a batch, |
| 14 * additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch | 14 * additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch |
| 15 * | 15 * |
| 16 * Some resources are also loaded for convenience, here the complete list: | 16 * Some resources are also loaded for convenience, here the complete list: |
| 17 * - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data | 17 * - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data |
| 18 * - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 | 18 * - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 |
| 19 * - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) | 19 * - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) |
| 20 * | 20 * |
| 21 * Internal buffer (and resources) must be manually unloaded calling rlglClose() | 21 * Internal buffer (and resources) must be manually unloaded calling rlglClose() |
| 22 * | 22 * |
| 23 * CONFIGURATION: | 23 * CONFIGURATION: |
| 24 * #define GRAPHICS_API_OPENGL_SOFTWARE | |
| 24 * #define GRAPHICS_API_OPENGL_11 | 25 * #define GRAPHICS_API_OPENGL_11 |
| 25 * #define GRAPHICS_API_OPENGL_21 | 26 * #define GRAPHICS_API_OPENGL_21 |
| 26 * #define GRAPHICS_API_OPENGL_33 | 27 * #define GRAPHICS_API_OPENGL_33 |
| 27 * #define GRAPHICS_API_OPENGL_43 | 28 * #define GRAPHICS_API_OPENGL_43 |
| 28 * #define GRAPHICS_API_OPENGL_ES2 | 29 * #define GRAPHICS_API_OPENGL_ES2 |
| 29 * #define GRAPHICS_API_OPENGL_ES3 | 30 * #define GRAPHICS_API_OPENGL_ES3 |
| 30 * Use selected OpenGL graphics backend, should be supported by platform | 31 * Use selected OpenGL graphics backend, should be supported by platform |
| 31 * Those preprocessor defines are only used on rlgl module, if OpenGL version is | 32 * Those preprocessor defines are only used on the rlgl module, if OpenGL version is |
| 32 * required by any other module, use rlGetVersion() to check it | 33 * required by any other module, use rlGetVersion() to check it |
| 33 * | 34 * |
| 34 * #define RLGL_IMPLEMENTATION | 35 * #define RLGL_IMPLEMENTATION |
| 35 * Generates the implementation of the library into the included file | 36 * Generates the implementation of the library into the included file |
| 36 * If not defined, the library is in header only mode and can be included in other headers | 37 * If not defined, the library is in header only mode and can be included in other headers |
| 37 * or source files without problems. But only ONE file should hold the implementation | 38 * or source files without problems. But only ONE file should hold the implementation |
| 38 * | 39 * |
| 39 * #define RLGL_RENDER_TEXTURES_HINT | 40 * #if RLGL_SHOW_GL_DETAILS_INFO |
| 40 * Enable framebuffer objects (fbo) support (enabled by default) | |
| 41 * Some GPUs could not support them despite the OpenGL version | |
| 42 * | |
| 43 * #define RLGL_SHOW_GL_DETAILS_INFO | |
| 44 * Show OpenGL extensions and capabilities detailed logs on init | 41 * Show OpenGL extensions and capabilities detailed logs on init |
| 45 * | 42 * |
| 46 * #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT | 43 * #if RLGL_ENABLE_OPENGL_DEBUG_CONTEXT |
| 47 * Enable debug context (only available on OpenGL 4.3) | 44 * Enable debug context (only available on OpenGL 4.3) |
| 48 * | 45 * |
| 49 * rlgl capabilities could be customized just defining some internal | 46 * rlgl capabilities could be customized defining some internal |
| 50 * values before library inclusion (default values listed): | 47 * values before library inclusion (default values listed): |
| 51 * | 48 * |
| 52 * #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits | 49 * #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits |
| 53 * #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) | 50 * #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) |
| 54 * #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) | 51 * #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) |
| 55 * #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) | 52 * #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of texture units that can be activated on batch drawing (SetShaderValueTexture()) |
| 56 * | 53 * |
| 57 * #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack | 54 * #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack |
| 58 * #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported | 55 * #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported |
| 59 * #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance | 56 * #define RL_CULL_DISTANCE_NEAR 0.05 // Default projection matrix near cull distance |
| 60 * #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance | 57 * #define RL_CULL_DISTANCE_FAR 4000.0 // Default projection matrix far cull distance |
| 61 * | 58 * |
| 62 * When loading a shader, the following vertex attributes and uniform | 59 * When loading a shader, the following vertex attributes and uniform |
| 63 * location names are tried to be set automatically: | 60 * location names are tried to be set automatically: |
| 64 * | 61 * |
| 65 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION | 62 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION |
| 66 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD | 63 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD |
| 67 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL | 64 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL |
| 68 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR | 65 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR |
| 69 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT | 66 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT |
| 70 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 | 67 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 |
| 71 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS | 68 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES |
| 72 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS | 69 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS |
| 73 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix | 70 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix |
| 74 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix | 71 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix |
| 75 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix | 72 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix |
| 76 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix | 73 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix |
| 77 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))) | 74 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))) |
| 78 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) | 75 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) |
| 79 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices | 76 * #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices |
| 80 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) | 77 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) |
| 81 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) | 78 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) |
| 82 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) | 79 * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) |
| 83 * | 80 * |
| 84 * DEPENDENCIES: | 81 * DEPENDENCIES: |
| 86 * - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) | 83 * - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) |
| 87 * | 84 * |
| 88 * | 85 * |
| 89 * LICENSE: zlib/libpng | 86 * LICENSE: zlib/libpng |
| 90 * | 87 * |
| 91 * Copyright (c) 2014-2024 Ramon Santamaria (@raysan5) | 88 * Copyright (c) 2014-2026 Ramon Santamaria (@raysan5) |
| 92 * | 89 * |
| 93 * This software is provided "as-is", without any express or implied warranty. In no event | 90 * This software is provided "as-is", without any express or implied warranty. In no event |
| 94 * will the authors be held liable for any damages arising from the use of this software. | 91 * will the authors be held liable for any damages arising from the use of this software. |
| 95 * | 92 * |
| 96 * Permission is granted to anyone to use this software for any purpose, including commercial | 93 * Permission is granted to anyone to use this software for any purpose, including commercial |
| 108 **********************************************************************************************/ | 105 **********************************************************************************************/ |
| 109 | 106 |
| 110 #ifndef RLGL_H | 107 #ifndef RLGL_H |
| 111 #define RLGL_H | 108 #define RLGL_H |
| 112 | 109 |
| 113 #define RLGL_VERSION "5.0" | 110 #define RLGL_VERSION "6.0" |
| 114 | 111 |
| 115 // Function specifiers in case library is build/used as a shared library | 112 // Function specifiers in case library is build/used as a shared library |
| 116 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll | 113 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll |
| 117 // NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden | 114 // NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden |
| 118 #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) | 115 #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) |
| 119 #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) | 116 #define RLAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) |
| 120 #elif defined(BUILD_LIBTYPE_SHARED) | 117 #elif defined(BUILD_LIBTYPE_SHARED) |
| 121 #define RLAPI __attribute__((visibility("default"))) // We are building the library as a Unix shared library (.so/.dylib) | 118 #define RLAPI __attribute__((visibility("default"))) // Building the library as a Unix shared library (.so/.dylib) |
| 122 #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) | 119 #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) |
| 123 #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) | 120 #define RLAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) |
| 124 #endif | 121 #endif |
| 125 | 122 |
| 126 // Function specifiers definition | 123 // Function specifiers definition |
| 127 #ifndef RLAPI | 124 #ifndef RLAPI |
| 128 #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) | 125 #define RLAPI // Functions defined as 'extern' by default (implicit specifiers) |
| 129 #endif | 126 #endif |
| 130 | 127 |
| 131 // Support TRACELOG macros | 128 // Support TRACELOG macros |
| 132 #ifndef TRACELOG | 129 #ifndef TRACELOG |
| 133 #define TRACELOG(level, ...) (void)0 | 130 #define TRACELOG(level, ...) (void)0 |
| 134 #define TRACELOGD(...) (void)0 | |
| 135 #endif | 131 #endif |
| 136 | 132 |
| 137 // Allow custom memory allocators | 133 // Allow custom memory allocators |
| 138 #ifndef RL_MALLOC | 134 #ifndef RL_MALLOC |
| 139 #define RL_MALLOC(sz) malloc(sz) | 135 #define RL_MALLOC(sz) malloc(sz) |
| 147 #ifndef RL_FREE | 143 #ifndef RL_FREE |
| 148 #define RL_FREE(p) free(p) | 144 #define RL_FREE(p) free(p) |
| 149 #endif | 145 #endif |
| 150 | 146 |
| 151 // Security check in case no GRAPHICS_API_OPENGL_* defined | 147 // Security check in case no GRAPHICS_API_OPENGL_* defined |
| 152 #if !defined(GRAPHICS_API_OPENGL_11) && \ | 148 #if !defined(GRAPHICS_API_OPENGL_SOFTWARE) && \ |
| 149 !defined(GRAPHICS_API_OPENGL_11) && \ | |
| 153 !defined(GRAPHICS_API_OPENGL_21) && \ | 150 !defined(GRAPHICS_API_OPENGL_21) && \ |
| 154 !defined(GRAPHICS_API_OPENGL_33) && \ | 151 !defined(GRAPHICS_API_OPENGL_33) && \ |
| 155 !defined(GRAPHICS_API_OPENGL_43) && \ | 152 !defined(GRAPHICS_API_OPENGL_43) && \ |
| 156 !defined(GRAPHICS_API_OPENGL_ES2) && \ | 153 !defined(GRAPHICS_API_OPENGL_ES2) && \ |
| 157 !defined(GRAPHICS_API_OPENGL_ES3) | 154 !defined(GRAPHICS_API_OPENGL_ES3) |
| 158 #define GRAPHICS_API_OPENGL_33 | 155 #define GRAPHICS_API_OPENGL_33 |
| 159 #endif | 156 #endif |
| 160 | 157 |
| 161 // Security check in case multiple GRAPHICS_API_OPENGL_* defined | 158 // Security check in case multiple GRAPHICS_API_OPENGL_* defined |
| 162 #if defined(GRAPHICS_API_OPENGL_11) | 159 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_SOFTWARE) |
| 163 #if defined(GRAPHICS_API_OPENGL_21) | 160 #if defined(GRAPHICS_API_OPENGL_21) |
| 164 #undef GRAPHICS_API_OPENGL_21 | 161 #undef GRAPHICS_API_OPENGL_21 |
| 165 #endif | 162 #endif |
| 166 #if defined(GRAPHICS_API_OPENGL_33) | 163 #if defined(GRAPHICS_API_OPENGL_33) |
| 167 #undef GRAPHICS_API_OPENGL_33 | 164 #undef GRAPHICS_API_OPENGL_33 |
| 172 #if defined(GRAPHICS_API_OPENGL_ES2) | 169 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 173 #undef GRAPHICS_API_OPENGL_ES2 | 170 #undef GRAPHICS_API_OPENGL_ES2 |
| 174 #endif | 171 #endif |
| 175 #endif | 172 #endif |
| 176 | 173 |
| 174 // Software implementation uses OpenGL 1.1 functionality | |
| 175 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 176 #define GRAPHICS_API_OPENGL_11 | |
| 177 #endif | |
| 178 | |
| 177 // OpenGL 2.1 uses most of OpenGL 3.3 Core functionality | 179 // OpenGL 2.1 uses most of OpenGL 3.3 Core functionality |
| 178 // WARNING: Specific parts are checked with #if defines | 180 // WARNING: Specific parts are checked with #if defines |
| 179 #if defined(GRAPHICS_API_OPENGL_21) | 181 #if defined(GRAPHICS_API_OPENGL_21) |
| 180 #define GRAPHICS_API_OPENGL_33 | 182 #define GRAPHICS_API_OPENGL_33 |
| 181 #endif | 183 #endif |
| 187 | 189 |
| 188 // OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more) | 190 // OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more) |
| 189 #if defined(GRAPHICS_API_OPENGL_ES3) | 191 #if defined(GRAPHICS_API_OPENGL_ES3) |
| 190 #define GRAPHICS_API_OPENGL_ES2 | 192 #define GRAPHICS_API_OPENGL_ES2 |
| 191 #endif | 193 #endif |
| 192 | |
| 193 // Support framebuffer objects by default | |
| 194 // NOTE: Some driver implementation do not support it, despite they should | |
| 195 #define RLGL_RENDER_TEXTURES_HINT | |
| 196 | 194 |
| 197 //---------------------------------------------------------------------------------- | 195 //---------------------------------------------------------------------------------- |
| 198 // Defines and Macros | 196 // Defines and Macros |
| 199 //---------------------------------------------------------------------------------- | 197 //---------------------------------------------------------------------------------- |
| 200 | 198 |
| 204 // This is the maximum amount of elements (quads) per batch | 202 // This is the maximum amount of elements (quads) per batch |
| 205 // NOTE: Be careful with text, every letter maps to a quad | 203 // NOTE: Be careful with text, every letter maps to a quad |
| 206 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 | 204 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 |
| 207 #endif | 205 #endif |
| 208 #if defined(GRAPHICS_API_OPENGL_ES2) | 206 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 209 // We reduce memory sizes for embedded systems (RPI and HTML5) | 207 // Reducing memory sizes for embedded systems (RPI and HTML5) |
| 210 // NOTE: On HTML5 (emscripten) this is allocated on heap, | 208 // NOTE: On HTML5 (emscripten) this is allocated on heap, |
| 211 // by default it's only 16MB!...just take care... | 209 // by default heap is only 16MB!...just take care... |
| 212 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 | 210 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048 |
| 213 #endif | 211 #endif |
| 214 #endif | 212 #endif |
| 215 #ifndef RL_DEFAULT_BATCH_BUFFERS | 213 #ifndef RL_DEFAULT_BATCH_BUFFERS |
| 216 #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) | 214 #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) |
| 232 #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported | 230 #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported |
| 233 #endif | 231 #endif |
| 234 | 232 |
| 235 // Projection matrix culling | 233 // Projection matrix culling |
| 236 #ifndef RL_CULL_DISTANCE_NEAR | 234 #ifndef RL_CULL_DISTANCE_NEAR |
| 237 #define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance | 235 #define RL_CULL_DISTANCE_NEAR 0.05 // Default near cull distance |
| 238 #endif | 236 #endif |
| 239 #ifndef RL_CULL_DISTANCE_FAR | 237 #ifndef RL_CULL_DISTANCE_FAR |
| 240 #define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance | 238 #define RL_CULL_DISTANCE_FAR 4000.0 // Default far cull distance |
| 241 #endif | 239 #endif |
| 242 | 240 |
| 243 // Texture parameters (equivalent to OpenGL defines) | 241 // Texture parameters (equivalent to OpenGL defines) |
| 244 #define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S | 242 #define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S |
| 245 #define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T | 243 #define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T |
| 345 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 | 343 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 |
| 346 #endif | 344 #endif |
| 347 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES | 345 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES |
| 348 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6 | 346 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6 |
| 349 #endif | 347 #endif |
| 350 #ifdef RL_SUPPORT_MESH_GPU_SKINNING | 348 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES |
| 351 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS | 349 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES 7 |
| 352 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7 | |
| 353 #endif | 350 #endif |
| 354 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS | 351 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS |
| 355 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8 | 352 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8 |
| 356 #endif | 353 #endif |
| 354 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM | |
| 355 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM 9 | |
| 357 #endif | 356 #endif |
| 358 | 357 |
| 359 //---------------------------------------------------------------------------------- | 358 //---------------------------------------------------------------------------------- |
| 360 // Types and Structures Definition | 359 // Types and Structures Definition |
| 361 //---------------------------------------------------------------------------------- | 360 //---------------------------------------------------------------------------------- |
| 395 unsigned int vboId[5]; // OpenGL Vertex Buffer Objects id (5 types of vertex data) | 394 unsigned int vboId[5]; // OpenGL Vertex Buffer Objects id (5 types of vertex data) |
| 396 } rlVertexBuffer; | 395 } rlVertexBuffer; |
| 397 | 396 |
| 398 // Draw call type | 397 // Draw call type |
| 399 // NOTE: Only texture changes register a new draw, other state-change-related elements are not | 398 // NOTE: Only texture changes register a new draw, other state-change-related elements are not |
| 400 // used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any | 399 // used at this moment (vaoId, shaderId, matrices), raylib forces a batch draw call if any |
| 401 // of those state-change happens (this is done in core module) | 400 // of those state-change happens (this is done in core module) |
| 402 typedef struct rlDrawCall { | 401 typedef struct rlDrawCall { |
| 403 int mode; // Drawing mode: LINES, TRIANGLES, QUADS | 402 int mode; // Drawing mode: LINES, TRIANGLES, QUADS |
| 404 int vertexCount; // Number of vertex of the draw | 403 int vertexCount; // Number of vertex of the draw |
| 405 int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) | 404 int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) |
| 422 float currentDepth; // Current depth value for next draw | 421 float currentDepth; // Current depth value for next draw |
| 423 } rlRenderBatch; | 422 } rlRenderBatch; |
| 424 | 423 |
| 425 // OpenGL version | 424 // OpenGL version |
| 426 typedef enum { | 425 typedef enum { |
| 427 RL_OPENGL_11 = 1, // OpenGL 1.1 | 426 RL_OPENGL_SOFTWARE = 0, // Software rendering |
| 427 RL_OPENGL_11, // OpenGL 1.1 | |
| 428 RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) | 428 RL_OPENGL_21, // OpenGL 2.1 (GLSL 120) |
| 429 RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) | 429 RL_OPENGL_33, // OpenGL 3.3 (GLSL 330) |
| 430 RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) | 430 RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330) |
| 431 RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) | 431 RL_OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) |
| 432 RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es) | 432 RL_OPENGL_ES_30 // OpenGL ES 3.0 (GLSL 300 es) |
| 476 | 476 |
| 477 // Texture parameters: filter mode | 477 // Texture parameters: filter mode |
| 478 // NOTE 1: Filtering considers mipmaps if available in the texture | 478 // NOTE 1: Filtering considers mipmaps if available in the texture |
| 479 // NOTE 2: Filter is accordingly set for minification and magnification | 479 // NOTE 2: Filter is accordingly set for minification and magnification |
| 480 typedef enum { | 480 typedef enum { |
| 481 RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation | 481 RL_TEXTURE_FILTER_POINT = 0, // No filter, pixel approximation |
| 482 RL_TEXTURE_FILTER_BILINEAR, // Linear filtering | 482 RL_TEXTURE_FILTER_BILINEAR, // Linear filtering |
| 483 RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) | 483 RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) |
| 484 RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x | 484 RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x |
| 485 RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x | 485 RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x |
| 486 RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x | 486 RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x |
| 639 RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO) | 639 RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO) |
| 640 RLAPI void rlEnableVertexBufferElement(unsigned int id); // Enable vertex buffer element (VBO element) | 640 RLAPI void rlEnableVertexBufferElement(unsigned int id); // Enable vertex buffer element (VBO element) |
| 641 RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element) | 641 RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element) |
| 642 RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index | 642 RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index |
| 643 RLAPI void rlDisableVertexAttribute(unsigned int index); // Disable vertex attribute index | 643 RLAPI void rlDisableVertexAttribute(unsigned int index); // Disable vertex attribute index |
| 644 #if defined(GRAPHICS_API_OPENGL_11) | |
| 645 RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer | 644 RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer |
| 646 RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer | 645 RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer |
| 647 #endif | |
| 648 | 646 |
| 649 // Textures state | 647 // Textures state |
| 650 RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot | 648 RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot |
| 651 RLAPI void rlEnableTexture(unsigned int id); // Enable texture | 649 RLAPI void rlEnableTexture(unsigned int id); // Enable texture |
| 652 RLAPI void rlDisableTexture(void); // Disable texture | 650 RLAPI void rlDisableTexture(void); // Disable texture |
| 679 RLAPI void rlColorMask(bool r, bool g, bool b, bool a); // Color mask control | 677 RLAPI void rlColorMask(bool r, bool g, bool b, bool a); // Color mask control |
| 680 RLAPI void rlSetCullFace(int mode); // Set face culling mode | 678 RLAPI void rlSetCullFace(int mode); // Set face culling mode |
| 681 RLAPI void rlEnableScissorTest(void); // Enable scissor test | 679 RLAPI void rlEnableScissorTest(void); // Enable scissor test |
| 682 RLAPI void rlDisableScissorTest(void); // Disable scissor test | 680 RLAPI void rlDisableScissorTest(void); // Disable scissor test |
| 683 RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test | 681 RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test |
| 682 RLAPI void rlEnablePointMode(void); // Enable point mode | |
| 683 RLAPI void rlDisablePointMode(void); // Disable point mode | |
| 684 RLAPI void rlSetPointSize(float size); // Set the point drawing size | |
| 685 RLAPI float rlGetPointSize(void); // Get the point drawing size | |
| 684 RLAPI void rlEnableWireMode(void); // Enable wire mode | 686 RLAPI void rlEnableWireMode(void); // Enable wire mode |
| 685 RLAPI void rlEnablePointMode(void); // Enable point mode | 687 RLAPI void rlDisableWireMode(void); // Disable wire mode |
| 686 RLAPI void rlDisableWireMode(void); // Disable wire (and point) mode | |
| 687 RLAPI void rlSetLineWidth(float width); // Set the line drawing width | 688 RLAPI void rlSetLineWidth(float width); // Set the line drawing width |
| 688 RLAPI float rlGetLineWidth(void); // Get the line drawing width | 689 RLAPI float rlGetLineWidth(void); // Get the line drawing width |
| 689 RLAPI void rlEnableSmoothLines(void); // Enable line aliasing | 690 RLAPI void rlEnableSmoothLines(void); // Enable line aliasing |
| 690 RLAPI void rlDisableSmoothLines(void); // Disable line aliasing | 691 RLAPI void rlDisableSmoothLines(void); // Disable line aliasing |
| 691 RLAPI void rlEnableStereoRender(void); // Enable stereo rendering | 692 RLAPI void rlEnableStereoRender(void); // Enable stereo rendering |
| 704 //------------------------------------------------------------------------------------ | 705 //------------------------------------------------------------------------------------ |
| 705 // rlgl initialization functions | 706 // rlgl initialization functions |
| 706 RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) | 707 RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) |
| 707 RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures) | 708 RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures) |
| 708 RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) | 709 RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required) |
| 710 RLAPI void *rlGetProcAddress(const char *procName); // Get OpenGL procedure address | |
| 709 RLAPI int rlGetVersion(void); // Get current OpenGL version | 711 RLAPI int rlGetVersion(void); // Get current OpenGL version |
| 710 RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width | 712 RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width |
| 711 RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width | 713 RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width |
| 712 RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height | 714 RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height |
| 713 RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height | 715 RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height |
| 758 RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data | 760 RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data |
| 759 RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) | 761 RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) |
| 760 | 762 |
| 761 // Framebuffer management (fbo) | 763 // Framebuffer management (fbo) |
| 762 RLAPI unsigned int rlLoadFramebuffer(void); // Load an empty framebuffer | 764 RLAPI unsigned int rlLoadFramebuffer(void); // Load an empty framebuffer |
| 763 RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer | 765 RLAPI void rlFramebufferAttach(unsigned int id, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer |
| 764 RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete | 766 RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete |
| 765 RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU | 767 RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU |
| 768 // WARNING: Copy and resize framebuffer functionality only defined for software backend | |
| 769 RLAPI void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pixels); // Copy framebuffer pixel data to internal buffer | |
| 770 RLAPI void rlResizeFramebuffer(int width, int height); // Resize internal framebuffer | |
| 766 | 771 |
| 767 // Shaders management | 772 // Shaders management |
| 768 RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings | 773 RLAPI unsigned int rlLoadShader(const char *code, int type); // Load (compile) shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) |
| 769 RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) | 774 RLAPI unsigned int rlLoadShaderProgram(const char *vsCode, const char *fsCode); // Load shader from code strings |
| 770 RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program | 775 RLAPI unsigned int rlLoadShaderProgramEx(unsigned int vsId, unsigned int fsId); // Load shader program, using already loaded shader ids |
| 776 RLAPI unsigned int rlLoadShaderProgramCompute(unsigned int csId); // Load compute shader program | |
| 777 RLAPI void rlUnloadShader(unsigned int id); // Unload shader, loaded with rlLoadShader() | |
| 771 RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program | 778 RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program |
| 772 RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform | 779 RLAPI int rlGetLocationUniform(unsigned int id, const char *uniformName); // Get shader location uniform, requires shader program id |
| 773 RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute | 780 RLAPI int rlGetLocationAttrib(unsigned int id, const char *attribName); // Get shader location attribute, requires shader program id |
| 774 RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform | 781 RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform |
| 775 RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix | 782 RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix |
| 776 RLAPI void rlSetUniformMatrices(int locIndex, const Matrix *mat, int count); // Set shader value matrices | 783 RLAPI void rlSetUniformMatrices(int locIndex, const Matrix *mat, int count); // Set shader value matrices |
| 777 RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler | 784 RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler |
| 778 RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) | 785 RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) |
| 779 | 786 |
| 780 // Compute shader management | 787 // Compute shader management |
| 781 RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId); // Load compute shader program | |
| 782 RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) | 788 RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) |
| 783 | 789 |
| 784 // Shader buffer storage object management (ssbo) | 790 // Shader buffer storage object management (ssbo) |
| 785 RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) | 791 RLAPI unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHint); // Load shader storage buffer object (SSBO) |
| 786 RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO) | 792 RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO) |
| 827 #define GLAD_API_CALL_EXPORT | 833 #define GLAD_API_CALL_EXPORT |
| 828 #define GLAD_API_CALL_EXPORT_BUILD | 834 #define GLAD_API_CALL_EXPORT_BUILD |
| 829 #endif | 835 #endif |
| 830 | 836 |
| 831 #if defined(GRAPHICS_API_OPENGL_11) | 837 #if defined(GRAPHICS_API_OPENGL_11) |
| 832 #if defined(__APPLE__) | 838 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) |
| 833 #include <OpenGL/gl.h> // OpenGL 1.1 library for OSX | 839 #define RLSW_IMPLEMENTATION |
| 834 #include <OpenGL/glext.h> // OpenGL extensions library | 840 #define SW_MALLOC(sz) RL_MALLOC(sz) |
| 841 #define SW_CALLOC(n,sz) RL_CALLOC(n, sz) | |
| 842 #define SW_REALLOC(ptr, newSz) RL_REALLOC(ptr, newSz) | |
| 843 #define SW_FREE(ptr) RL_FREE(ptr) | |
| 844 #include "external/rlsw.h" // OpenGL 1.1 software implementation | |
| 835 #else | 845 #else |
| 836 // APIENTRY for OpenGL function pointer declarations is required | 846 #if defined(__APPLE__) |
| 837 #if !defined(APIENTRY) | 847 #include <OpenGL/gl.h> // OpenGL 1.1 library for OSX |
| 838 #if defined(_WIN32) | 848 #include <OpenGL/glext.h> // OpenGL extensions library |
| 839 #define APIENTRY __stdcall | 849 #else |
| 840 #else | 850 // APIENTRY for OpenGL function pointer declarations is required |
| 841 #define APIENTRY | 851 #if !defined(APIENTRY) |
| 852 #if defined(_WIN32) | |
| 853 #define APIENTRY __stdcall | |
| 854 #else | |
| 855 #define APIENTRY | |
| 856 #endif | |
| 842 #endif | 857 #endif |
| 858 // WINGDIAPI definition. Some Windows OpenGL headers need it | |
| 859 #if !defined(WINGDIAPI) && defined(_WIN32) | |
| 860 #define WINGDIAPI __declspec(dllimport) | |
| 861 #endif | |
| 862 | |
| 863 #include <GL/gl.h> // OpenGL 1.1 library | |
| 843 #endif | 864 #endif |
| 844 // WINGDIAPI definition. Some Windows OpenGL headers need it | |
| 845 #if !defined(WINGDIAPI) && defined(_WIN32) | |
| 846 #define WINGDIAPI __declspec(dllimport) | |
| 847 #endif | |
| 848 | |
| 849 #include <GL/gl.h> // OpenGL 1.1 library | |
| 850 #endif | 865 #endif |
| 851 #endif | 866 #endif |
| 852 | 867 |
| 853 #if defined(GRAPHICS_API_OPENGL_33) | 868 #if defined(GRAPHICS_API_OPENGL_33) |
| 854 #define GLAD_MALLOC RL_MALLOC | 869 #define GLAD_MALLOC RL_MALLOC |
| 863 #define GL_GLEXT_PROTOTYPES | 878 #define GL_GLEXT_PROTOTYPES |
| 864 #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library | 879 #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library |
| 865 #elif defined(GRAPHICS_API_OPENGL_ES2) | 880 #elif defined(GRAPHICS_API_OPENGL_ES2) |
| 866 // NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms, | 881 // NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms, |
| 867 // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 | 882 // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 |
| 883 // TODO: OpenGL ES 2.0 support shouldn't be platform-dependent, neither require GLAD | |
| 868 #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL) | 884 #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL) |
| 869 #define GLAD_GLES2_IMPLEMENTATION | 885 #define GLAD_GLES2_IMPLEMENTATION |
| 870 #include "external/glad_gles2.h" | 886 #include "external/glad_gles2.h" |
| 871 #else | 887 #else |
| 872 #define GL_GLEXT_PROTOTYPES | 888 #define GL_GLEXT_PROTOTYPES |
| 875 #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library | 891 #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library |
| 876 #endif | 892 #endif |
| 877 | 893 |
| 878 // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi | 894 // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi |
| 879 // provided headers (despite being defined in official Khronos GLES2 headers) | 895 // provided headers (despite being defined in official Khronos GLES2 headers) |
| 896 // TODO: Avoid raylib platform-dependent code on rlgl, it should be a completely portable library | |
| 880 #if defined(PLATFORM_DRM) | 897 #if defined(PLATFORM_DRM) |
| 881 typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); | 898 typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); |
| 882 typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); | 899 typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); |
| 883 typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); | 900 typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); |
| 884 #endif | 901 #endif |
| 885 #endif | 902 #endif |
| 886 | 903 |
| 887 #include <stdlib.h> // Required for: malloc(), free() | 904 #include <stdlib.h> // Required for: calloc(), free() |
| 888 #include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] | 905 #include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] |
| 889 #include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log() | 906 #include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log() |
| 890 | 907 |
| 891 //---------------------------------------------------------------------------------- | 908 //---------------------------------------------------------------------------------- |
| 892 // Defines and Macros | 909 // Defines and Macros |
| 973 #endif | 990 #endif |
| 974 #endif | 991 #endif |
| 975 | 992 |
| 976 // Default shader vertex attribute names to set location points | 993 // Default shader vertex attribute names to set location points |
| 977 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION | 994 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION |
| 978 #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION | 995 #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION |
| 979 #endif | 996 #endif |
| 980 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD | 997 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD |
| 981 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD | 998 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD |
| 982 #endif | 999 #endif |
| 983 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL | 1000 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL |
| 984 #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL | 1001 #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL |
| 985 #endif | 1002 #endif |
| 986 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR | 1003 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR |
| 987 #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR | 1004 #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR |
| 988 #endif | 1005 #endif |
| 989 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT | 1006 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT |
| 990 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT | 1007 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT |
| 991 #endif | 1008 #endif |
| 992 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 | 1009 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 |
| 993 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 | 1010 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 |
| 994 #endif | 1011 #endif |
| 995 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS | 1012 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES |
| 996 #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS | 1013 #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES "vertexBoneIndices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES |
| 997 #endif | 1014 #endif |
| 998 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS | 1015 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS |
| 999 #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS | 1016 #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS |
| 1017 #endif | |
| 1018 | |
| 1019 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM | |
| 1020 #define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM | |
| 1000 #endif | 1021 #endif |
| 1001 | 1022 |
| 1002 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP | 1023 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP |
| 1003 #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix | 1024 #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix |
| 1004 #endif | 1025 #endif |
| 1015 #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) | 1036 #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) |
| 1016 #endif | 1037 #endif |
| 1017 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR | 1038 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR |
| 1018 #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) | 1039 #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) |
| 1019 #endif | 1040 #endif |
| 1020 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES | |
| 1021 #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices | |
| 1022 #endif | |
| 1023 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 | 1041 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 |
| 1024 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) | 1042 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) |
| 1025 #endif | 1043 #endif |
| 1026 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 | 1044 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 |
| 1027 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) | 1045 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) |
| 1028 #endif | 1046 #endif |
| 1029 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 | 1047 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 |
| 1030 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) | 1048 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) |
| 1031 #endif | 1049 #endif |
| 1050 #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES | |
| 1051 #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // bone matrices (required for GPU skinning) | |
| 1052 #endif | |
| 1032 | 1053 |
| 1033 //---------------------------------------------------------------------------------- | 1054 //---------------------------------------------------------------------------------- |
| 1034 // Types and Structures Definition | 1055 // Module Types and Structures Definition |
| 1035 //---------------------------------------------------------------------------------- | 1056 //---------------------------------------------------------------------------------- |
| 1036 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 1057 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 1058 | |
| 1059 typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) | |
| 1060 | |
| 1037 typedef struct rlglData { | 1061 typedef struct rlglData { |
| 1038 rlRenderBatch *currentBatch; // Current render batch | 1062 rlRenderBatch *currentBatch; // Current render batch |
| 1039 rlRenderBatch defaultBatch; // Default internal render batch | 1063 rlRenderBatch defaultBatch; // Default internal render batch |
| 1064 | |
| 1065 rlglLoadProc loader; // OpenGL function loader | |
| 1040 | 1066 |
| 1041 struct { | 1067 struct { |
| 1042 int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) | 1068 int vertexCounter; // Current active render batch vertex counter (generic, used for all batches) |
| 1043 float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) | 1069 float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*()) |
| 1044 float normalx, normaly, normalz; // Current active normal (added on glVertex*()) | 1070 float normalx, normaly, normalz; // Current active normal (added on glVertex*()) |
| 1051 Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale | 1077 Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale |
| 1052 bool transformRequired; // Require transform matrix application to current draw-call vertex (if required) | 1078 bool transformRequired; // Require transform matrix application to current draw-call vertex (if required) |
| 1053 Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop | 1079 Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop |
| 1054 int stackCounter; // Matrix stack counter | 1080 int stackCounter; // Matrix stack counter |
| 1055 | 1081 |
| 1082 unsigned int currentTextureId; // Current texture id to be used on glBegin | |
| 1056 unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader) | 1083 unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader) |
| 1057 unsigned int activeTextureId[RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]; // Active texture ids to be enabled on batch drawing (0 active by default) | 1084 unsigned int activeTextureId[RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]; // Active texture ids to be enabled on batch drawing (0 active by default) |
| 1058 unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program) | 1085 unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program) |
| 1059 unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program) | 1086 unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program) |
| 1060 unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture | 1087 unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture |
| 1105 int maxDepthBits; // Maximum bits for depth component | 1132 int maxDepthBits; // Maximum bits for depth component |
| 1106 | 1133 |
| 1107 } ExtSupported; // Extensions supported flags | 1134 } ExtSupported; // Extensions supported flags |
| 1108 } rlglData; | 1135 } rlglData; |
| 1109 | 1136 |
| 1110 typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc) | 1137 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 |
| 1111 | |
| 1112 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | |
| 1113 | 1138 |
| 1114 //---------------------------------------------------------------------------------- | 1139 //---------------------------------------------------------------------------------- |
| 1115 // Global Variables Definition | 1140 // Global Variables Definition |
| 1116 //---------------------------------------------------------------------------------- | 1141 //---------------------------------------------------------------------------------- |
| 1142 static bool isGpuReady = false; | |
| 1117 static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR; | 1143 static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR; |
| 1118 static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR; | 1144 static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR; |
| 1119 | 1145 |
| 1120 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 1146 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 1121 static rlglData RLGL = { 0 }; | 1147 static rlglData RLGL = { 0 }; |
| 1122 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | 1148 #endif |
| 1123 | 1149 |
| 1124 #if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3) | 1150 #if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3) |
| 1151 // VAO functions entry points | |
| 1125 // NOTE: VAO functionality is exposed through extensions (OES) | 1152 // NOTE: VAO functionality is exposed through extensions (OES) |
| 1126 static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; | 1153 static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; |
| 1127 static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; | 1154 static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; |
| 1128 static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL; | 1155 static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL; |
| 1129 | 1156 |
| 1130 // NOTE: Instancing functionality could also be available through extension | 1157 // Instancing functionality entry points |
| 1158 // NOTE: Instancing functionality could be available through extensions | |
| 1131 static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; | 1159 static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; |
| 1132 static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL; | 1160 static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL; |
| 1133 static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; | 1161 static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; |
| 1134 #endif | 1162 #endif |
| 1135 | 1163 |
| 1136 //---------------------------------------------------------------------------------- | 1164 //---------------------------------------------------------------------------------- |
| 1137 // Module specific Functions Declaration | 1165 // Module Functions Declaration |
| 1138 //---------------------------------------------------------------------------------- | 1166 //---------------------------------------------------------------------------------- |
| 1139 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 1167 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 1140 static void rlLoadShaderDefault(void); // Load default shader | 1168 static void rlLoadShaderDefault(void); // Load default shader |
| 1141 static void rlUnloadShaderDefault(void); // Unload default shader | 1169 static void rlUnloadShaderDefault(void); // Unload default shader |
| 1142 #if defined(RLGL_SHOW_GL_DETAILS_INFO) | 1170 #if RLGL_SHOW_GL_DETAILS_INFO |
| 1143 static const char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name | 1171 static const char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name |
| 1144 #endif // RLGL_SHOW_GL_DETAILS_INFO | 1172 #endif |
| 1145 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | 1173 #endif |
| 1146 | 1174 |
| 1147 static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) | 1175 static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture) |
| 1148 | 1176 |
| 1177 static Matrix rlMatrixIdentity(void); // Get identity matrix | |
| 1178 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 1149 // Auxiliar matrix math functions | 1179 // Auxiliar matrix math functions |
| 1150 typedef struct rl_float16 { | 1180 typedef struct rl_float16 { float v[16]; } rl_float16; |
| 1151 float v[16]; | |
| 1152 } rl_float16; | |
| 1153 static rl_float16 rlMatrixToFloatV(Matrix mat); // Get float array of matrix data | 1181 static rl_float16 rlMatrixToFloatV(Matrix mat); // Get float array of matrix data |
| 1154 #define rlMatrixToFloat(mat) (rlMatrixToFloatV(mat).v) // Get float vector for Matrix | 1182 #define rlMatrixToFloat(mat) (rlMatrixToFloatV(mat).v) // Get float vector for Matrix |
| 1155 static Matrix rlMatrixIdentity(void); // Get identity matrix | |
| 1156 static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices | 1183 static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices |
| 1157 static Matrix rlMatrixTranspose(Matrix mat); // Transposes provided matrix | 1184 static Matrix rlMatrixTranspose(Matrix mat); // Transposes provided matrix |
| 1158 static Matrix rlMatrixInvert(Matrix mat); // Invert provided matrix | 1185 static Matrix rlMatrixInvert(Matrix mat); // Invert provided matrix |
| 1186 #endif | |
| 1159 | 1187 |
| 1160 //---------------------------------------------------------------------------------- | 1188 //---------------------------------------------------------------------------------- |
| 1161 // Module Functions Definition - Matrix operations | 1189 // Module Functions Definition - Matrix operations |
| 1162 //---------------------------------------------------------------------------------- | 1190 //---------------------------------------------------------------------------------- |
| 1163 | 1191 |
| 1217 | 1245 |
| 1218 RLGL.State.stack[RLGL.State.stackCounter] = *RLGL.State.currentMatrix; | 1246 RLGL.State.stack[RLGL.State.stackCounter] = *RLGL.State.currentMatrix; |
| 1219 RLGL.State.stackCounter++; | 1247 RLGL.State.stackCounter++; |
| 1220 } | 1248 } |
| 1221 | 1249 |
| 1222 // Pop lattest inserted matrix from RLGL.State.stack | 1250 // Pop latest inserted matrix from RLGL.State.stack |
| 1223 void rlPopMatrix(void) | 1251 void rlPopMatrix(void) |
| 1224 { | 1252 { |
| 1225 if (RLGL.State.stackCounter > 0) | 1253 if (RLGL.State.stackCounter > 0) |
| 1226 { | 1254 { |
| 1227 Matrix mat = RLGL.State.stack[RLGL.State.stackCounter - 1]; | 1255 Matrix mat = RLGL.State.stack[RLGL.State.stackCounter - 1]; |
| 1243 } | 1271 } |
| 1244 | 1272 |
| 1245 // Multiply the current matrix by a translation matrix | 1273 // Multiply the current matrix by a translation matrix |
| 1246 void rlTranslatef(float x, float y, float z) | 1274 void rlTranslatef(float x, float y, float z) |
| 1247 { | 1275 { |
| 1248 Matrix matTranslation = { | 1276 Matrix matTranslation = rlMatrixIdentity(); |
| 1249 1.0f, 0.0f, 0.0f, x, | 1277 |
| 1250 0.0f, 1.0f, 0.0f, y, | 1278 // Set translation component of matrix |
| 1251 0.0f, 0.0f, 1.0f, z, | 1279 matTranslation.m12 = x; |
| 1252 0.0f, 0.0f, 0.0f, 1.0f | 1280 matTranslation.m13 = y; |
| 1253 }; | 1281 matTranslation.m14 = z; |
| 1254 | 1282 |
| 1255 // NOTE: We transpose matrix with multiplication order | 1283 // NOTE: Transposing matrix by multiplication order |
| 1256 *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); | 1284 *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); |
| 1257 } | 1285 } |
| 1258 | 1286 |
| 1259 // Multiply the current matrix by a rotation matrix | 1287 // Multiply the current matrix by a rotation matrix |
| 1260 // NOTE: The provided angle must be in degrees | 1288 // NOTE: The provided angle must be in degrees |
| 1295 matRotation.m12 = 0.0f; | 1323 matRotation.m12 = 0.0f; |
| 1296 matRotation.m13 = 0.0f; | 1324 matRotation.m13 = 0.0f; |
| 1297 matRotation.m14 = 0.0f; | 1325 matRotation.m14 = 0.0f; |
| 1298 matRotation.m15 = 1.0f; | 1326 matRotation.m15 = 1.0f; |
| 1299 | 1327 |
| 1300 // NOTE: We transpose matrix with multiplication order | 1328 // NOTE: Transposing matrix by multiplication order |
| 1301 *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix); | 1329 *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix); |
| 1302 } | 1330 } |
| 1303 | 1331 |
| 1304 // Multiply the current matrix by a scaling matrix | 1332 // Multiply the current matrix by a scaling matrix |
| 1305 void rlScalef(float x, float y, float z) | 1333 void rlScalef(float x, float y, float z) |
| 1306 { | 1334 { |
| 1307 Matrix matScale = { | 1335 Matrix matScale = rlMatrixIdentity(); |
| 1308 x, 0.0f, 0.0f, 0.0f, | 1336 |
| 1309 0.0f, y, 0.0f, 0.0f, | 1337 // Set scale component of matrix |
| 1310 0.0f, 0.0f, z, 0.0f, | 1338 matScale.m0 = x; |
| 1311 0.0f, 0.0f, 0.0f, 1.0f | 1339 matScale.m5 = y; |
| 1312 }; | 1340 matScale.m10 = z; |
| 1313 | 1341 |
| 1314 // NOTE: We transpose matrix with multiplication order | 1342 // NOTE: Transposing matrix by multiplication order |
| 1315 *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); | 1343 *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); |
| 1316 } | 1344 } |
| 1317 | 1345 |
| 1318 // Multiply the current matrix by another matrix | 1346 // Multiply the current matrix by another matrix |
| 1319 void rlMultMatrixf(const float *matf) | 1347 void rlMultMatrixf(const float *matf) |
| 1320 { | 1348 { |
| 1321 // Matrix creation from array | 1349 // Matrix creation from array |
| 1350 // Conversion from column-major to row-major memory order | |
| 1322 Matrix mat = { matf[0], matf[4], matf[8], matf[12], | 1351 Matrix mat = { matf[0], matf[4], matf[8], matf[12], |
| 1323 matf[1], matf[5], matf[9], matf[13], | 1352 matf[1], matf[5], matf[9], matf[13], |
| 1324 matf[2], matf[6], matf[10], matf[14], | 1353 matf[2], matf[6], matf[10], matf[14], |
| 1325 matf[3], matf[7], matf[11], matf[15] }; | 1354 matf[3], matf[7], matf[11], matf[15] }; |
| 1326 | 1355 |
| 1361 | 1390 |
| 1362 // Multiply the current matrix by an orthographic matrix generated by parameters | 1391 // Multiply the current matrix by an orthographic matrix generated by parameters |
| 1363 void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) | 1392 void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) |
| 1364 { | 1393 { |
| 1365 // NOTE: If left-right and top-botton values are equal it could create a division by zero, | 1394 // NOTE: If left-right and top-botton values are equal it could create a division by zero, |
| 1366 // response to it is platform/compiler dependant | 1395 // response to it is platform/compiler dependent |
| 1367 Matrix matOrtho = { 0 }; | 1396 Matrix matOrtho = { 0 }; |
| 1368 | 1397 |
| 1369 float rl = (float)(right - left); | 1398 float rl = (float)(right - left); |
| 1370 float tb = (float)(top - bottom); | 1399 float tb = (float)(top - bottom); |
| 1371 float fn = (float)(zfar - znear); | 1400 float fn = (float)(zfar - znear); |
| 1390 *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho); | 1419 *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho); |
| 1391 } | 1420 } |
| 1392 #endif | 1421 #endif |
| 1393 | 1422 |
| 1394 // Set the viewport area (transformation from normalized device coordinates to window coordinates) | 1423 // Set the viewport area (transformation from normalized device coordinates to window coordinates) |
| 1395 // NOTE: We store current viewport dimensions | |
| 1396 void rlViewport(int x, int y, int width, int height) | 1424 void rlViewport(int x, int y, int width, int height) |
| 1397 { | 1425 { |
| 1398 glViewport(x, y, width, height); | 1426 glViewport(x, y, width, height); |
| 1399 } | 1427 } |
| 1400 | 1428 |
| 1471 } | 1499 } |
| 1472 | 1500 |
| 1473 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); | 1501 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); |
| 1474 | 1502 |
| 1475 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode; | 1503 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode; |
| 1476 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0; | 1504 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.currentTextureId; |
| 1477 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId; | 1505 RLGL.State.currentTextureId = RLGL.State.defaultTextureId; |
| 1478 } | 1506 } |
| 1479 } | 1507 } |
| 1480 | 1508 |
| 1481 // Finish vertex providing | 1509 // Finish vertex providing |
| 1482 void rlEnd(void) | 1510 void rlEnd(void) |
| 1483 { | 1511 { |
| 1484 // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, | 1512 // NOTE: Depth increment is dependent on rlOrtho(): z-near and z-far values, |
| 1485 // as well as depth buffer bit-depth (16bit or 24bit or 32bit) | 1513 // as well as depth buffer bit-depth (16bit or 24bit or 32bit) |
| 1486 // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) | 1514 // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) |
| 1487 RLGL.currentBatch->currentDepth += (1.0f/20000.0f); | 1515 RLGL.currentBatch->currentDepth += (1.0f/20000.0f); |
| 1488 } | 1516 } |
| 1489 | 1517 |
| 1501 tx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z + RLGL.State.transform.m12; | 1529 tx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z + RLGL.State.transform.m12; |
| 1502 ty = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z + RLGL.State.transform.m13; | 1530 ty = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z + RLGL.State.transform.m13; |
| 1503 tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; | 1531 tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; |
| 1504 } | 1532 } |
| 1505 | 1533 |
| 1506 // WARNING: We can't break primitives when launching a new batch | 1534 // WARNING: Be careful with primitives breaking when launching a new batch! |
| 1507 // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices | 1535 // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices |
| 1508 // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 | 1536 // Checking current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 |
| 1509 if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) | 1537 if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) |
| 1510 { | 1538 { |
| 1511 if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) && | 1539 if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) && |
| 1512 (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%2 == 0)) | 1540 (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%2 == 0)) |
| 1513 { | 1541 { |
| 1514 // Reached the maximum number of vertices for RL_LINES drawing | 1542 // Reached the maximum number of vertices for RL_LINES drawing |
| 1515 // Launch a draw call but keep current state for next vertices comming | 1543 // Launch a draw call but keep current state for next vertices comming |
| 1516 // NOTE: We add +1 vertex to the check for security | 1544 // NOTE: Adding +1 vertex to the check for some safety |
| 1517 rlCheckRenderBatchLimit(2 + 1); | 1545 rlCheckRenderBatchLimit(2 + 1); |
| 1518 } | 1546 } |
| 1519 else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && | 1547 else if ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) && |
| 1520 (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%3 == 0)) | 1548 (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%3 == 0)) |
| 1521 { | 1549 { |
| 1583 { | 1611 { |
| 1584 normalx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z; | 1612 normalx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z; |
| 1585 normaly = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z; | 1613 normaly = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z; |
| 1586 normalz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z; | 1614 normalz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z; |
| 1587 } | 1615 } |
| 1616 | |
| 1617 // NOTE: Default behavior assumes the normal vector is in the correct space for what the shader expects, | |
| 1618 // it could be not normalized to 0.0f..1.0f, magnitud can be useed for some effects | |
| 1619 /* | |
| 1620 // WARNING: Vector normalization if required | |
| 1588 float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz); | 1621 float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz); |
| 1589 if (length != 0.0f) | 1622 if (length != 0.0f) |
| 1590 { | 1623 { |
| 1591 float ilength = 1.0f/length; | 1624 float ilength = 1.0f/length; |
| 1592 normalx *= ilength; | 1625 normalx *= ilength; |
| 1593 normaly *= ilength; | 1626 normaly *= ilength; |
| 1594 normalz *= ilength; | 1627 normalz *= ilength; |
| 1595 } | 1628 } |
| 1629 */ | |
| 1596 RLGL.State.normalx = normalx; | 1630 RLGL.State.normalx = normalx; |
| 1597 RLGL.State.normaly = normaly; | 1631 RLGL.State.normaly = normaly; |
| 1598 RLGL.State.normalz = normalz; | 1632 RLGL.State.normalz = normalz; |
| 1599 } | 1633 } |
| 1600 | 1634 |
| 1631 if (id == 0) | 1665 if (id == 0) |
| 1632 { | 1666 { |
| 1633 #if defined(GRAPHICS_API_OPENGL_11) | 1667 #if defined(GRAPHICS_API_OPENGL_11) |
| 1634 rlDisableTexture(); | 1668 rlDisableTexture(); |
| 1635 #else | 1669 #else |
| 1636 // NOTE: If quads batch limit is reached, we force a draw call and next batch starts | 1670 // NOTE: If quads batch limit is reached, force a draw call and next batch starts |
| 1637 if (RLGL.State.vertexCounter >= | 1671 if (RLGL.State.vertexCounter >= |
| 1638 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4) | 1672 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4) |
| 1639 { | 1673 { |
| 1640 rlDrawRenderBatch(RLGL.currentBatch); | 1674 rlDrawRenderBatch(RLGL.currentBatch); |
| 1641 } | 1675 } |
| 1676 RLGL.State.currentTextureId = RLGL.State.defaultTextureId; | |
| 1642 #endif | 1677 #endif |
| 1643 } | 1678 } |
| 1644 else | 1679 else |
| 1645 { | 1680 { |
| 1646 #if defined(GRAPHICS_API_OPENGL_11) | 1681 #if defined(GRAPHICS_API_OPENGL_11) |
| 1647 rlEnableTexture(id); | 1682 rlEnableTexture(id); |
| 1648 #else | 1683 #else |
| 1684 RLGL.State.currentTextureId = id; | |
| 1649 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id) | 1685 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id) |
| 1650 { | 1686 { |
| 1651 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) | 1687 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0) |
| 1652 { | 1688 { |
| 1653 // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, | 1689 // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, |
| 1662 if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) | 1698 if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment)) |
| 1663 { | 1699 { |
| 1664 RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; | 1700 RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment; |
| 1665 | 1701 |
| 1666 RLGL.currentBatch->drawCounter++; | 1702 RLGL.currentBatch->drawCounter++; |
| 1703 | |
| 1704 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 2].mode; | |
| 1705 | |
| 1667 } | 1706 } |
| 1668 } | 1707 } |
| 1669 | 1708 |
| 1670 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); | 1709 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch); |
| 1671 | 1710 |
| 1720 | 1759 |
| 1721 // Set texture parameters (wrap mode/filter mode) | 1760 // Set texture parameters (wrap mode/filter mode) |
| 1722 void rlTextureParameters(unsigned int id, int param, int value) | 1761 void rlTextureParameters(unsigned int id, int param, int value) |
| 1723 { | 1762 { |
| 1724 glBindTexture(GL_TEXTURE_2D, id); | 1763 glBindTexture(GL_TEXTURE_2D, id); |
| 1725 | |
| 1726 #if !defined(GRAPHICS_API_OPENGL_11) | |
| 1727 // Reset anisotropy filter, in case it was set | |
| 1728 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); | |
| 1729 #endif | |
| 1730 | 1764 |
| 1731 switch (param) | 1765 switch (param) |
| 1732 { | 1766 { |
| 1733 case RL_TEXTURE_WRAP_S: | 1767 case RL_TEXTURE_WRAP_S: |
| 1734 case RL_TEXTURE_WRAP_T: | 1768 case RL_TEXTURE_WRAP_T: |
| 1739 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value); | 1773 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value); |
| 1740 else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); | 1774 else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); |
| 1741 #endif | 1775 #endif |
| 1742 } | 1776 } |
| 1743 else glTexParameteri(GL_TEXTURE_2D, param, value); | 1777 else glTexParameteri(GL_TEXTURE_2D, param, value); |
| 1744 | |
| 1745 } break; | 1778 } break; |
| 1746 case RL_TEXTURE_MAG_FILTER: | 1779 case RL_TEXTURE_MAG_FILTER: |
| 1747 case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; | 1780 case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; |
| 1748 case RL_TEXTURE_FILTER_ANISOTROPIC: | 1781 case RL_TEXTURE_FILTER_ANISOTROPIC: |
| 1749 { | 1782 { |
| 1750 #if !defined(GRAPHICS_API_OPENGL_11) | 1783 #if !defined(GRAPHICS_API_OPENGL_11) |
| 1784 // Reset anisotropy filter, in case it was set | |
| 1785 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); | |
| 1786 | |
| 1751 if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); | 1787 if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); |
| 1752 else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) | 1788 else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f) |
| 1753 { | 1789 { |
| 1754 TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); | 1790 TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel); |
| 1755 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); | 1791 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); |
| 1784 { | 1820 { |
| 1785 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); | 1821 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); |
| 1786 else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); | 1822 else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)"); |
| 1787 } | 1823 } |
| 1788 else glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); | 1824 else glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); |
| 1789 | |
| 1790 } break; | 1825 } break; |
| 1791 case RL_TEXTURE_MAG_FILTER: | 1826 case RL_TEXTURE_MAG_FILTER: |
| 1792 case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); break; | 1827 case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_CUBE_MAP, param, value); break; |
| 1793 case RL_TEXTURE_FILTER_ANISOTROPIC: | 1828 case RL_TEXTURE_FILTER_ANISOTROPIC: |
| 1794 { | 1829 { |
| 1827 } | 1862 } |
| 1828 | 1863 |
| 1829 // Enable rendering to texture (fbo) | 1864 // Enable rendering to texture (fbo) |
| 1830 void rlEnableFramebuffer(unsigned int id) | 1865 void rlEnableFramebuffer(unsigned int id) |
| 1831 { | 1866 { |
| 1832 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 1867 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 1833 glBindFramebuffer(GL_FRAMEBUFFER, id); | 1868 glBindFramebuffer(GL_FRAMEBUFFER, id); |
| 1834 #endif | 1869 #endif |
| 1835 } | 1870 } |
| 1836 | 1871 |
| 1837 // return the active render texture (fbo) | 1872 // return the active render texture (fbo) |
| 1838 unsigned int rlGetActiveFramebuffer(void) | 1873 unsigned int rlGetActiveFramebuffer(void) |
| 1839 { | 1874 { |
| 1840 GLint fboId = 0; | 1875 GLint fboId = 0; |
| 1841 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) | 1876 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 1842 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId); | 1877 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId); |
| 1843 #endif | 1878 #endif |
| 1844 return fboId; | 1879 return fboId; |
| 1845 } | 1880 } |
| 1846 | 1881 |
| 1847 // Disable rendering to texture | 1882 // Disable rendering to texture |
| 1848 void rlDisableFramebuffer(void) | 1883 void rlDisableFramebuffer(void) |
| 1849 { | 1884 { |
| 1850 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 1885 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 1851 glBindFramebuffer(GL_FRAMEBUFFER, 0); | 1886 glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 1852 #endif | 1887 #endif |
| 1853 } | 1888 } |
| 1854 | 1889 |
| 1855 // Blit active framebuffer to main framebuffer | 1890 // Blit active framebuffer to main framebuffer |
| 1856 void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask) | 1891 void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask) |
| 1857 { | 1892 { |
| 1858 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT) | 1893 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) |
| 1859 glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST); | 1894 glBlitFramebuffer(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask, GL_NEAREST); |
| 1860 #endif | 1895 #endif |
| 1861 } | 1896 } |
| 1862 | 1897 |
| 1863 // Bind framebuffer object (fbo) | 1898 // Bind framebuffer object (fbo) |
| 1864 void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) | 1899 void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) |
| 1865 { | 1900 { |
| 1866 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 1901 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 1867 glBindFramebuffer(target, framebuffer); | 1902 glBindFramebuffer(target, framebuffer); |
| 1868 #endif | 1903 #endif |
| 1869 } | 1904 } |
| 1870 | 1905 |
| 1871 // Activate multiple draw color buffers | 1906 // Activate multiple draw color buffers |
| 1872 // NOTE: One color buffer is always active by default | 1907 // NOTE: One color buffer is always active by default |
| 1873 void rlActiveDrawBuffers(int count) | 1908 void rlActiveDrawBuffers(int count) |
| 1874 { | 1909 { |
| 1875 #if ((defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) && defined(RLGL_RENDER_TEXTURES_HINT)) | 1910 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) |
| 1876 // NOTE: Maximum number of draw buffers supported is implementation dependant, | 1911 // NOTE: Maximum number of draw buffers supported is implementation dependent, |
| 1877 // it can be queried with glGet*() but it must be at least 8 | 1912 // it can be queried with glGet*() but it must be at least 8 |
| 1878 //GLint maxDrawBuffers = 0; | 1913 //GLint maxDrawBuffers = 0; |
| 1879 //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); | 1914 //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); |
| 1880 | 1915 |
| 1881 if (count > 0) | 1916 if (count > 0) |
| 1882 { | 1917 { |
| 1883 if (count > 8) TRACELOG(LOG_WARNING, "GL: Max color buffers limited to 8"); | 1918 if (count > 8) TRACELOG(RL_LOG_WARNING, "GL: Max color buffers limited to 8"); |
| 1884 else | 1919 else |
| 1885 { | 1920 { |
| 1886 unsigned int buffers[8] = { | 1921 unsigned int buffers[8] = { |
| 1887 #if defined(GRAPHICS_API_OPENGL_ES3) | |
| 1888 GL_COLOR_ATTACHMENT0_EXT, | |
| 1889 GL_COLOR_ATTACHMENT1_EXT, | |
| 1890 GL_COLOR_ATTACHMENT2_EXT, | |
| 1891 GL_COLOR_ATTACHMENT3_EXT, | |
| 1892 GL_COLOR_ATTACHMENT4_EXT, | |
| 1893 GL_COLOR_ATTACHMENT5_EXT, | |
| 1894 GL_COLOR_ATTACHMENT6_EXT, | |
| 1895 GL_COLOR_ATTACHMENT7_EXT, | |
| 1896 #else | |
| 1897 GL_COLOR_ATTACHMENT0, | 1922 GL_COLOR_ATTACHMENT0, |
| 1898 GL_COLOR_ATTACHMENT1, | 1923 GL_COLOR_ATTACHMENT1, |
| 1899 GL_COLOR_ATTACHMENT2, | 1924 GL_COLOR_ATTACHMENT2, |
| 1900 GL_COLOR_ATTACHMENT3, | 1925 GL_COLOR_ATTACHMENT3, |
| 1901 GL_COLOR_ATTACHMENT4, | 1926 GL_COLOR_ATTACHMENT4, |
| 1902 GL_COLOR_ATTACHMENT5, | 1927 GL_COLOR_ATTACHMENT5, |
| 1903 GL_COLOR_ATTACHMENT6, | 1928 GL_COLOR_ATTACHMENT6, |
| 1904 GL_COLOR_ATTACHMENT7, | 1929 GL_COLOR_ATTACHMENT7, |
| 1905 #endif | |
| 1906 }; | 1930 }; |
| 1907 | 1931 |
| 1908 #if defined(GRAPHICS_API_OPENGL_ES3) | |
| 1909 glDrawBuffersEXT(count, buffers); | |
| 1910 #else | |
| 1911 glDrawBuffers(count, buffers); | 1932 glDrawBuffers(count, buffers); |
| 1912 #endif | |
| 1913 } | 1933 } |
| 1914 } | 1934 } |
| 1915 else TRACELOG(LOG_WARNING, "GL: One color buffer active by default"); | 1935 else TRACELOG(RL_LOG_WARNING, "GL: One color buffer active by default"); |
| 1916 #endif | 1936 #endif |
| 1917 } | 1937 } |
| 1918 | 1938 |
| 1919 //---------------------------------------------------------------------------------- | 1939 //---------------------------------------------------------------------------------- |
| 1920 // General render state configuration | 1940 // General render state configuration |
| 1971 void rlEnableWireMode(void) | 1991 void rlEnableWireMode(void) |
| 1972 { | 1992 { |
| 1973 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) | 1993 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) |
| 1974 // NOTE: glPolygonMode() not available on OpenGL ES | 1994 // NOTE: glPolygonMode() not available on OpenGL ES |
| 1975 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | 1995 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
| 1996 #endif | |
| 1997 } | |
| 1998 | |
| 1999 // Disable wire mode | |
| 2000 void rlDisableWireMode(void) | |
| 2001 { | |
| 2002 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) | |
| 2003 // NOTE: glPolygonMode() not available on OpenGL ES | |
| 2004 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
| 1976 #endif | 2005 #endif |
| 1977 } | 2006 } |
| 1978 | 2007 |
| 1979 // Enable point mode | 2008 // Enable point mode |
| 1980 void rlEnablePointMode(void) | 2009 void rlEnablePointMode(void) |
| 1984 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); | 2013 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); |
| 1985 glEnable(GL_PROGRAM_POINT_SIZE); | 2014 glEnable(GL_PROGRAM_POINT_SIZE); |
| 1986 #endif | 2015 #endif |
| 1987 } | 2016 } |
| 1988 | 2017 |
| 1989 // Disable wire mode | 2018 // Disable point mode |
| 1990 void rlDisableWireMode(void) | 2019 void rlDisablePointMode(void) |
| 1991 { | 2020 { |
| 1992 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) | 2021 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) |
| 1993 // NOTE: glPolygonMode() not available on OpenGL ES | 2022 // NOTE: glPolygonMode() not available on OpenGL ES |
| 1994 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 2023 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
| 1995 #endif | 2024 #endif |
| 2002 float rlGetLineWidth(void) | 2031 float rlGetLineWidth(void) |
| 2003 { | 2032 { |
| 2004 float width = 0; | 2033 float width = 0; |
| 2005 glGetFloatv(GL_LINE_WIDTH, &width); | 2034 glGetFloatv(GL_LINE_WIDTH, &width); |
| 2006 return width; | 2035 return width; |
| 2036 } | |
| 2037 | |
| 2038 // Set the point drawing size | |
| 2039 void rlSetPointSize(float size) | |
| 2040 { | |
| 2041 #if defined(GRAPHICS_API_OPENGL_11) | |
| 2042 glPointSize(size); | |
| 2043 #endif | |
| 2044 } | |
| 2045 | |
| 2046 // Get the point drawing size | |
| 2047 float rlGetPointSize(void) | |
| 2048 { | |
| 2049 float size = 1; | |
| 2050 #if defined(GRAPHICS_API_OPENGL_11) | |
| 2051 glGetFloatv(GL_POINT_SIZE, &size); | |
| 2052 #endif | |
| 2053 return size; | |
| 2054 | |
| 2007 } | 2055 } |
| 2008 | 2056 |
| 2009 // Enable line aliasing | 2057 // Enable line aliasing |
| 2010 void rlEnableSmoothLines(void) | 2058 void rlEnableSmoothLines(void) |
| 2011 { | 2059 { |
| 2109 case RL_BLEND_ALPHA_PREMULTIPLY: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; | 2157 case RL_BLEND_ALPHA_PREMULTIPLY: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; |
| 2110 case RL_BLEND_CUSTOM: | 2158 case RL_BLEND_CUSTOM: |
| 2111 { | 2159 { |
| 2112 // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() | 2160 // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() |
| 2113 glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); | 2161 glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); |
| 2114 | |
| 2115 } break; | 2162 } break; |
| 2116 case RL_BLEND_CUSTOM_SEPARATE: | 2163 case RL_BLEND_CUSTOM_SEPARATE: |
| 2117 { | 2164 { |
| 2118 // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() | 2165 // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() |
| 2119 glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha); | 2166 glBlendFuncSeparate(RLGL.State.glBlendSrcFactorRGB, RLGL.State.glBlendDestFactorRGB, RLGL.State.glBlendSrcFactorAlpha, RLGL.State.glBlendDestFactorAlpha); |
| 2120 glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha); | 2167 glBlendEquationSeparate(RLGL.State.glBlendEquationRGB, RLGL.State.glBlendEquationAlpha); |
| 2121 | |
| 2122 } break; | 2168 } break; |
| 2123 default: break; | 2169 default: break; |
| 2124 } | 2170 } |
| 2125 | 2171 |
| 2126 RLGL.State.currentBlendMode = mode; | 2172 RLGL.State.currentBlendMode = mode; |
| 2170 } | 2216 } |
| 2171 | 2217 |
| 2172 //---------------------------------------------------------------------------------- | 2218 //---------------------------------------------------------------------------------- |
| 2173 // Module Functions Definition - OpenGL Debug | 2219 // Module Functions Definition - OpenGL Debug |
| 2174 //---------------------------------------------------------------------------------- | 2220 //---------------------------------------------------------------------------------- |
| 2175 #if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) | 2221 #if defined(GRAPHICS_API_OPENGL_43) && RLGL_ENABLE_OPENGL_DEBUG_CONTEXT |
| 2176 static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) | 2222 static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) |
| 2177 { | 2223 { |
| 2178 // Ignore non-significant error/warning codes (NVidia drivers) | 2224 // Ignore non-significant error/warning codes (NVidia drivers) |
| 2179 // NOTE: Here there are the details with a sample output: | 2225 // NOTE: Here there are the details with a sample output: |
| 2180 // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) | 2226 // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) |
| 2220 case GL_DEBUG_SEVERITY_HIGH: msgSeverity = "HIGH"; break; | 2266 case GL_DEBUG_SEVERITY_HIGH: msgSeverity = "HIGH"; break; |
| 2221 case GL_DEBUG_SEVERITY_NOTIFICATION: msgSeverity = "NOTIFICATION"; break; | 2267 case GL_DEBUG_SEVERITY_NOTIFICATION: msgSeverity = "NOTIFICATION"; break; |
| 2222 default: break; | 2268 default: break; |
| 2223 } | 2269 } |
| 2224 | 2270 |
| 2225 TRACELOG(LOG_WARNING, "GL: OpenGL debug message: %s", message); | 2271 TRACELOG(RL_LOG_WARNING, "GL: OpenGL debug message: %s", message); |
| 2226 TRACELOG(LOG_WARNING, " > Type: %s", msgType); | 2272 TRACELOG(RL_LOG_WARNING, " > Type: %s", msgType); |
| 2227 TRACELOG(LOG_WARNING, " > Source = %s", msgSource); | 2273 TRACELOG(RL_LOG_WARNING, " > Source = %s", msgSource); |
| 2228 TRACELOG(LOG_WARNING, " > Severity = %s", msgSeverity); | 2274 TRACELOG(RL_LOG_WARNING, " > Severity = %s", msgSeverity); |
| 2229 } | 2275 } |
| 2230 #endif | 2276 #endif |
| 2231 | 2277 |
| 2232 //---------------------------------------------------------------------------------- | 2278 //---------------------------------------------------------------------------------- |
| 2233 // Module Functions Definition - rlgl functionality | 2279 // Module Functions Definition - rlgl functionality |
| 2234 //---------------------------------------------------------------------------------- | 2280 //---------------------------------------------------------------------------------- |
| 2235 | 2281 |
| 2236 // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states | 2282 // Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states |
| 2237 void rlglInit(int width, int height) | 2283 void rlglInit(int width, int height) |
| 2238 { | 2284 { |
| 2239 // Enable OpenGL debug context if required | 2285 isGpuReady = true; |
| 2240 #if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43) | 2286 |
| 2287 // Enable OpenGL debug context if requested (and supported) | |
| 2288 #if defined(GRAPHICS_API_OPENGL_43) && RLGL_ENABLE_OPENGL_DEBUG_CONTEXT | |
| 2241 if ((glDebugMessageCallback != NULL) && (glDebugMessageControl != NULL)) | 2289 if ((glDebugMessageCallback != NULL) && (glDebugMessageControl != NULL)) |
| 2242 { | 2290 { |
| 2243 glDebugMessageCallback(rlDebugMessageCallback, 0); | 2291 glDebugMessageCallback(rlDebugMessageCallback, 0); |
| 2244 // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); | 2292 // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); |
| 2245 | 2293 |
| 2253 | 2301 |
| 2254 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2302 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2255 // Init default white texture | 2303 // Init default white texture |
| 2256 unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) | 2304 unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes) |
| 2257 RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); | 2305 RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1); |
| 2306 RLGL.State.currentTextureId = RLGL.State.defaultTextureId; | |
| 2258 | 2307 |
| 2259 if (RLGL.State.defaultTextureId != 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId); | 2308 if (RLGL.State.defaultTextureId != 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId); |
| 2260 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load default texture"); | 2309 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load default texture"); |
| 2261 | 2310 |
| 2262 // Init default Shader (customized for GL 3.3 and ES2) | 2311 // Init default Shader (customized for GL 3.3 and ES2) |
| 2278 // Init internal matrices | 2327 // Init internal matrices |
| 2279 RLGL.State.transform = rlMatrixIdentity(); | 2328 RLGL.State.transform = rlMatrixIdentity(); |
| 2280 RLGL.State.projection = rlMatrixIdentity(); | 2329 RLGL.State.projection = rlMatrixIdentity(); |
| 2281 RLGL.State.modelview = rlMatrixIdentity(); | 2330 RLGL.State.modelview = rlMatrixIdentity(); |
| 2282 RLGL.State.currentMatrix = &RLGL.State.modelview; | 2331 RLGL.State.currentMatrix = &RLGL.State.modelview; |
| 2283 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | 2332 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 |
| 2333 | |
| 2334 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 2335 // Initialize software renderer backend | |
| 2336 int result = swInit(width, height); | |
| 2337 if (result == 0) | |
| 2338 { | |
| 2339 TRACELOG(RL_LOG_ERROR, "RLSW: Software renderer initialization failed!"); | |
| 2340 exit(-1); | |
| 2341 } | |
| 2342 #endif | |
| 2284 | 2343 |
| 2285 // Initialize OpenGL default states | 2344 // Initialize OpenGL default states |
| 2286 //---------------------------------------------------------- | 2345 //---------------------------------------------------------- |
| 2287 // Init state: Depth test | 2346 // Init state: Depth test |
| 2288 glDepthFunc(GL_LEQUAL); // Type of depth testing to apply | 2347 glDepthFunc(GL_LEQUAL); // Type of depth testing to apply |
| 2296 // NOTE: All shapes/models triangles are drawn CCW | 2355 // NOTE: All shapes/models triangles are drawn CCW |
| 2297 glCullFace(GL_BACK); // Cull the back face (default) | 2356 glCullFace(GL_BACK); // Cull the back face (default) |
| 2298 glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) | 2357 glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) |
| 2299 glEnable(GL_CULL_FACE); // Enable backface culling | 2358 glEnable(GL_CULL_FACE); // Enable backface culling |
| 2300 | 2359 |
| 2301 // Init state: Cubemap seamless | |
| 2302 #if defined(GRAPHICS_API_OPENGL_33) | |
| 2303 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0) | |
| 2304 #endif | |
| 2305 | |
| 2306 #if defined(GRAPHICS_API_OPENGL_11) | 2360 #if defined(GRAPHICS_API_OPENGL_11) |
| 2307 // Init state: Color hints (deprecated in OpenGL 3.0+) | 2361 // Init state: Color hints (deprecated in OpenGL 3.0+) |
| 2308 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation | 2362 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation |
| 2309 glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) | 2363 glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) |
| 2310 #endif | 2364 #endif |
| 2311 | 2365 #if defined(GRAPHICS_API_OPENGL_33) |
| 2366 // Init state: Cubemap seamless | |
| 2367 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0) | |
| 2368 #endif | |
| 2312 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2369 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2313 // Store screen size into global variables | 2370 // Store screen size into global variables |
| 2314 RLGL.State.framebufferWidth = width; | 2371 RLGL.State.framebufferWidth = width; |
| 2315 RLGL.State.framebufferHeight = height; | 2372 RLGL.State.framebufferHeight = height; |
| 2316 | |
| 2317 TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully"); | |
| 2318 //---------------------------------------------------------- | |
| 2319 #endif | 2373 #endif |
| 2320 | 2374 |
| 2321 // Init state: Color/Depth buffers clear | 2375 // Init state: Color/Depth buffers clear |
| 2322 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) | 2376 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) |
| 2323 glClearDepth(1.0f); // Set clear depth value (default) | 2377 glClearDepth(1.0f); // Set clear depth value (default) |
| 2324 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) | 2378 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D) |
| 2379 | |
| 2380 TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully"); | |
| 2381 //---------------------------------------------------------- | |
| 2325 } | 2382 } |
| 2326 | 2383 |
| 2327 // Vertex Buffer Object deinitialization (memory free) | 2384 // Vertex Buffer Object deinitialization (memory free) |
| 2328 void rlglClose(void) | 2385 void rlglClose(void) |
| 2329 { | 2386 { |
| 2330 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2387 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2331 rlUnloadRenderBatch(RLGL.defaultBatch); | 2388 rlUnloadRenderBatch(RLGL.defaultBatch); |
| 2332 | 2389 |
| 2333 rlUnloadShaderDefault(); // Unload default shader | 2390 rlUnloadShaderDefault(); // Unload default shader |
| 2334 | 2391 |
| 2335 glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture | 2392 glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture |
| 2336 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId); | 2393 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId); |
| 2337 #endif | 2394 #endif |
| 2395 | |
| 2396 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 2397 swClose(); // Unload sofware renderer resources | |
| 2398 #endif | |
| 2399 isGpuReady = false; | |
| 2338 } | 2400 } |
| 2339 | 2401 |
| 2340 // Load OpenGL extensions | 2402 // Load OpenGL extensions |
| 2341 // NOTE: External loader function must be provided | 2403 // NOTE: External loader function must be provided |
| 2342 void rlLoadExtensions(void *loader) | 2404 void rlLoadExtensions(void *loader) |
| 2349 // Get number of supported extensions | 2411 // Get number of supported extensions |
| 2350 GLint numExt = 0; | 2412 GLint numExt = 0; |
| 2351 glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); | 2413 glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); |
| 2352 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); | 2414 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); |
| 2353 | 2415 |
| 2354 #if defined(RLGL_SHOW_GL_DETAILS_INFO) | 2416 #if RLGL_SHOW_GL_DETAILS_INFO |
| 2355 // Get supported extensions list | 2417 // Get supported extensions list |
| 2356 // WARNING: glGetStringi() not available on OpenGL 2.1 | 2418 // WARNING: glGetStringi() not available on OpenGL 2.1 |
| 2357 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); | 2419 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); |
| 2358 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i)); | 2420 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i)); |
| 2359 #endif | 2421 #endif |
| 2391 #if defined(GRAPHICS_API_OPENGL_43) | 2453 #if defined(GRAPHICS_API_OPENGL_43) |
| 2392 RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader; | 2454 RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader; |
| 2393 RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object; | 2455 RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object; |
| 2394 #endif | 2456 #endif |
| 2395 | 2457 |
| 2396 #endif // GRAPHICS_API_OPENGL_33 | 2458 #endif // GRAPHICS_API_OPENGL_33 |
| 2397 | 2459 |
| 2398 #if defined(GRAPHICS_API_OPENGL_ES3) | 2460 #if defined(GRAPHICS_API_OPENGL_ES3) |
| 2399 // Register supported extensions flags | 2461 // Register supported extensions flags |
| 2400 // OpenGL ES 3.0 extensions supported by default (or it should be) | 2462 // OpenGL ES 3.0 extensions supported by default (or it should be) |
| 2401 RLGL.ExtSupported.vao = true; | 2463 RLGL.ExtSupported.vao = true; |
| 2426 else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); | 2488 else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); |
| 2427 #endif | 2489 #endif |
| 2428 | 2490 |
| 2429 // Get supported extensions list | 2491 // Get supported extensions list |
| 2430 GLint numExt = 0; | 2492 GLint numExt = 0; |
| 2431 const char **extList = RL_MALLOC(512*sizeof(const char *)); // Allocate 512 strings pointers (2 KB) | 2493 const char **extList = (const char **)RL_CALLOC(512, sizeof(const char *)); // Allocate 512 strings pointers (2 KB) |
| 2432 const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string | 2494 const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string |
| 2433 | 2495 |
| 2434 // NOTE: We have to duplicate string because glGetString() returns a const string | 2496 // NOTE: String duplication rquired because glGetString() returns a const string |
| 2435 int size = strlen(extensions) + 1; // Get extensions string size in bytes | 2497 int extensionsLength = (int)strlen(extensions); // Get extensions string size in bytes |
| 2436 char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char)); | 2498 char *extensionsDup = (char *)RL_CALLOC(extensionsLength + 1, sizeof(char)); // Allocate space for copy with additional EOL byte |
| 2437 strcpy(extensionsDup, extensions); | 2499 strncpy(extensionsDup, extensions, extensionsLength); |
| 2438 extList[numExt] = extensionsDup; | 2500 extList[numExt] = extensionsDup; |
| 2439 | 2501 |
| 2440 for (int i = 0; i < size; i++) | 2502 for (int i = 0; i < extensionsLength; i++) |
| 2441 { | 2503 { |
| 2442 if (extensionsDup[i] == ' ') | 2504 if (extensionsDup[i] == ' ') |
| 2443 { | 2505 { |
| 2444 extensionsDup[i] = '\0'; | 2506 extensionsDup[i] = '\0'; |
| 2445 numExt++; | 2507 numExt++; |
| 2447 } | 2509 } |
| 2448 } | 2510 } |
| 2449 | 2511 |
| 2450 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); | 2512 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt); |
| 2451 | 2513 |
| 2452 #if defined(RLGL_SHOW_GL_DETAILS_INFO) | 2514 #if RLGL_SHOW_GL_DETAILS_INFO |
| 2453 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); | 2515 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:"); |
| 2454 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", extList[i]); | 2516 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", extList[i]); |
| 2455 #endif | 2517 #endif |
| 2456 | 2518 |
| 2457 // Check required extensions | 2519 // Check required extensions |
| 2470 | 2532 |
| 2471 if ((glGenVertexArrays != NULL) && (glBindVertexArray != NULL) && (glDeleteVertexArrays != NULL)) RLGL.ExtSupported.vao = true; | 2533 if ((glGenVertexArrays != NULL) && (glBindVertexArray != NULL) && (glDeleteVertexArrays != NULL)) RLGL.ExtSupported.vao = true; |
| 2472 } | 2534 } |
| 2473 | 2535 |
| 2474 // Check instanced rendering support | 2536 // Check instanced rendering support |
| 2475 if (strstr(extList[i], (const char*)"instanced_arrays") != NULL) // Broad check for instanced_arrays | 2537 if (strstr(extList[i], (const char *)"instanced_arrays") != NULL) // Broad check for instanced_arrays |
| 2476 { | 2538 { |
| 2477 // Specific check | 2539 // Specific check |
| 2478 if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // ANGLE | 2540 if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // ANGLE |
| 2479 { | 2541 { |
| 2480 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE"); | 2542 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE"); |
| 2503 if (strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) | 2565 if (strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) |
| 2504 { | 2566 { |
| 2505 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT"); | 2567 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT"); |
| 2506 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT"); | 2568 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT"); |
| 2507 } | 2569 } |
| 2508 else if (strcmp(extList[i], (const char*)"GL_NV_draw_instanced") == 0) | 2570 else if (strcmp(extList[i], (const char *)"GL_NV_draw_instanced") == 0) |
| 2509 { | 2571 { |
| 2510 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV"); | 2572 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV"); |
| 2511 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV"); | 2573 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV"); |
| 2512 } | 2574 } |
| 2513 | 2575 |
| 2523 if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) RLGL.ExtSupported.texFloat32 = true; | 2585 if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) RLGL.ExtSupported.texFloat32 = true; |
| 2524 if (strcmp(extList[i], (const char *)"GL_OES_texture_half_float") == 0) RLGL.ExtSupported.texFloat16 = true; | 2586 if (strcmp(extList[i], (const char *)"GL_OES_texture_half_float") == 0) RLGL.ExtSupported.texFloat16 = true; |
| 2525 | 2587 |
| 2526 // Check depth texture support | 2588 // Check depth texture support |
| 2527 if (strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) RLGL.ExtSupported.texDepth = true; | 2589 if (strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) RLGL.ExtSupported.texDepth = true; |
| 2528 if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format | 2590 if (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0) RLGL.ExtSupported.texDepthWebGL = true; // WebGL requires unsized internal format |
| 2529 if (RLGL.ExtSupported.texDepthWebGL) RLGL.ExtSupported.texDepth = true; | 2591 if (RLGL.ExtSupported.texDepthWebGL) RLGL.ExtSupported.texDepth = true; |
| 2530 | 2592 |
| 2531 if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL | 2593 if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24; // Not available on WebGL |
| 2532 if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL | 2594 if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32; // Not available on WebGL |
| 2533 | 2595 |
| 2534 // Check texture compression support: DXT | 2596 // Check texture compression support: DXT |
| 2535 if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) || | 2597 if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) || |
| 2536 (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) || | 2598 (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) || |
| 2537 (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true; | 2599 (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true; |
| 2557 } | 2619 } |
| 2558 | 2620 |
| 2559 // Free extensions pointers | 2621 // Free extensions pointers |
| 2560 RL_FREE(extList); | 2622 RL_FREE(extList); |
| 2561 RL_FREE(extensionsDup); // Duplicated string must be deallocated | 2623 RL_FREE(extensionsDup); // Duplicated string must be deallocated |
| 2562 #endif // GRAPHICS_API_OPENGL_ES2 | 2624 #endif // GRAPHICS_API_OPENGL_ES2 |
| 2563 | 2625 |
| 2564 // Check OpenGL information and capabilities | 2626 // Check OpenGL information and capabilities |
| 2565 //------------------------------------------------------------------------------ | 2627 //------------------------------------------------------------------------------ |
| 2566 // Show current OpenGL and GLSL version | 2628 // Show current OpenGL and GLSL version |
| 2567 TRACELOG(RL_LOG_INFO, "GL: OpenGL device information:"); | 2629 TRACELOG(RL_LOG_INFO, "GL: OpenGL device information:"); |
| 2569 TRACELOG(RL_LOG_INFO, " > Renderer: %s", glGetString(GL_RENDERER)); | 2631 TRACELOG(RL_LOG_INFO, " > Renderer: %s", glGetString(GL_RENDERER)); |
| 2570 TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION)); | 2632 TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION)); |
| 2571 TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); | 2633 TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION)); |
| 2572 | 2634 |
| 2573 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2635 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2636 RLGL.loader = (rlglLoadProc)loader; | |
| 2637 | |
| 2574 // NOTE: Anisotropy levels capability is an extension | 2638 // NOTE: Anisotropy levels capability is an extension |
| 2575 #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT | 2639 #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT |
| 2576 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF | 2640 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF |
| 2577 #endif | 2641 #endif |
| 2578 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel); | 2642 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel); |
| 2579 | 2643 |
| 2580 #if defined(RLGL_SHOW_GL_DETAILS_INFO) | 2644 #if RLGL_SHOW_GL_DETAILS_INFO |
| 2581 // Show some OpenGL GPU capabilities | 2645 // Show some OpenGL GPU capabilities |
| 2582 TRACELOG(RL_LOG_INFO, "GL: OpenGL capabilities:"); | 2646 TRACELOG(RL_LOG_INFO, "GL: OpenGL capabilities:"); |
| 2583 GLint capability = 0; | 2647 GLint capability = 0; |
| 2584 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability); | 2648 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability); |
| 2585 TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability); | 2649 TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability); |
| 2606 #if defined(GRAPHICS_API_OPENGL_43) | 2670 #if defined(GRAPHICS_API_OPENGL_43) |
| 2607 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability); | 2671 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &capability); |
| 2608 TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability); | 2672 TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability); |
| 2609 glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &capability); | 2673 glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &capability); |
| 2610 TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability); | 2674 TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability); |
| 2611 #endif // GRAPHICS_API_OPENGL_43 | 2675 #endif |
| 2612 #else // RLGL_SHOW_GL_DETAILS_INFO | 2676 |
| 2677 #else // !RLGL_SHOW_GL_DETAILS_INFO | |
| 2613 | 2678 |
| 2614 // Show some basic info about GL supported features | 2679 // Show some basic info about GL supported features |
| 2615 if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully"); | 2680 if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully"); |
| 2616 else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported"); | 2681 else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported"); |
| 2617 if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported"); | 2682 if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported"); |
| 2621 if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported"); | 2686 if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported"); |
| 2622 if (RLGL.ExtSupported.texCompPVRT) TRACELOG(RL_LOG_INFO, "GL: PVRT compressed textures supported"); | 2687 if (RLGL.ExtSupported.texCompPVRT) TRACELOG(RL_LOG_INFO, "GL: PVRT compressed textures supported"); |
| 2623 if (RLGL.ExtSupported.texCompASTC) TRACELOG(RL_LOG_INFO, "GL: ASTC compressed textures supported"); | 2688 if (RLGL.ExtSupported.texCompASTC) TRACELOG(RL_LOG_INFO, "GL: ASTC compressed textures supported"); |
| 2624 if (RLGL.ExtSupported.computeShader) TRACELOG(RL_LOG_INFO, "GL: Compute shaders supported"); | 2689 if (RLGL.ExtSupported.computeShader) TRACELOG(RL_LOG_INFO, "GL: Compute shaders supported"); |
| 2625 if (RLGL.ExtSupported.ssbo) TRACELOG(RL_LOG_INFO, "GL: Shader storage buffer objects supported"); | 2690 if (RLGL.ExtSupported.ssbo) TRACELOG(RL_LOG_INFO, "GL: Shader storage buffer objects supported"); |
| 2626 #endif // RLGL_SHOW_GL_DETAILS_INFO | 2691 #endif |
| 2627 | 2692 |
| 2628 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | 2693 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 |
| 2694 } | |
| 2695 | |
| 2696 // Get OpenGL procedure address | |
| 2697 void *rlGetProcAddress(const char *procName) | |
| 2698 { | |
| 2699 void *func = NULL; | |
| 2700 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 2701 func = RLGL.loader(procName); | |
| 2702 #endif | |
| 2703 return func; | |
| 2629 } | 2704 } |
| 2630 | 2705 |
| 2631 // Get current OpenGL version | 2706 // Get current OpenGL version |
| 2632 int rlGetVersion(void) | 2707 int rlGetVersion(void) |
| 2633 { | 2708 { |
| 2634 int glVersion = 0; | 2709 int glVersion = 0; |
| 2635 #if defined(GRAPHICS_API_OPENGL_11) | 2710 |
| 2711 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 2712 glVersion = RL_OPENGL_SOFTWARE; | |
| 2713 #elif defined(GRAPHICS_API_OPENGL_11) | |
| 2636 glVersion = RL_OPENGL_11; | 2714 glVersion = RL_OPENGL_11; |
| 2637 #endif | 2715 #endif |
| 2638 #if defined(GRAPHICS_API_OPENGL_21) | 2716 #if defined(GRAPHICS_API_OPENGL_21) |
| 2639 glVersion = RL_OPENGL_21; | 2717 glVersion = RL_OPENGL_21; |
| 2640 #elif defined(GRAPHICS_API_OPENGL_43) | 2718 #elif defined(GRAPHICS_API_OPENGL_43) |
| 2722 //------------------------------------------------------------------------------------------------ | 2800 //------------------------------------------------------------------------------------------------ |
| 2723 // Load render batch | 2801 // Load render batch |
| 2724 rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) | 2802 rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements) |
| 2725 { | 2803 { |
| 2726 rlRenderBatch batch = { 0 }; | 2804 rlRenderBatch batch = { 0 }; |
| 2805 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return batch; } | |
| 2727 | 2806 |
| 2728 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2807 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2729 // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) | 2808 // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) |
| 2730 //-------------------------------------------------------------------------------------------- | 2809 //-------------------------------------------------------------------------------------------- |
| 2731 batch.vertexBuffer = (rlVertexBuffer *)RL_MALLOC(numBuffers*sizeof(rlVertexBuffer)); | 2810 batch.vertexBuffer = (rlVertexBuffer *)RL_CALLOC(numBuffers, sizeof(rlVertexBuffer)); |
| 2732 | 2811 |
| 2733 for (int i = 0; i < numBuffers; i++) | 2812 for (int i = 0; i < numBuffers; i++) |
| 2734 { | 2813 { |
| 2735 batch.vertexBuffer[i].elementCount = bufferElements; | 2814 batch.vertexBuffer[i].elementCount = bufferElements; |
| 2736 | 2815 |
| 2737 batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad | 2816 batch.vertexBuffer[i].vertices = (float *)RL_CALLOC(bufferElements*3*4, sizeof(float)); // 3 float by vertex, 4 vertex by quad |
| 2738 batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad | 2817 batch.vertexBuffer[i].texcoords = (float *)RL_CALLOC(bufferElements*2*4, sizeof(float)); // 2 float by texcoord, 4 texcoord by quad |
| 2739 batch.vertexBuffer[i].normals = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad | 2818 batch.vertexBuffer[i].normals = (float *)RL_CALLOC(bufferElements*3*4, sizeof(float)); // 3 float by vertex, 4 vertex by quad |
| 2740 batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad | 2819 batch.vertexBuffer[i].colors = (unsigned char *)RL_CALLOC(bufferElements*4*4, sizeof(unsigned char)); // 4 float by color, 4 colors by quad |
| 2741 #if defined(GRAPHICS_API_OPENGL_33) | 2820 #if defined(GRAPHICS_API_OPENGL_33) |
| 2742 batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(bufferElements*6*sizeof(unsigned int)); // 6 int by quad (indices) | 2821 batch.vertexBuffer[i].indices = (unsigned int *)RL_CALLOC(bufferElements*6, sizeof(unsigned int)); // 6 int by quad (indices) |
| 2743 #endif | 2822 #endif |
| 2744 #if defined(GRAPHICS_API_OPENGL_ES2) | 2823 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 2745 batch.vertexBuffer[i].indices = (unsigned short *)RL_MALLOC(bufferElements*6*sizeof(unsigned short)); // 6 int by quad (indices) | 2824 batch.vertexBuffer[i].indices = (unsigned short *)RL_CALLOC(bufferElements*6, sizeof(unsigned short)); // 6 int by quad (indices) |
| 2746 #endif | 2825 #endif |
| 2747 | 2826 |
| 2748 for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f; | 2827 for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f; |
| 2749 for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f; | 2828 for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f; |
| 2750 for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].normals[j] = 0.0f; | 2829 for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].normals[j] = 0.0f; |
| 2828 if (RLGL.ExtSupported.vao) glBindVertexArray(0); | 2907 if (RLGL.ExtSupported.vao) glBindVertexArray(0); |
| 2829 //-------------------------------------------------------------------------------------------- | 2908 //-------------------------------------------------------------------------------------------- |
| 2830 | 2909 |
| 2831 // Init draw calls tracking system | 2910 // Init draw calls tracking system |
| 2832 //-------------------------------------------------------------------------------------------- | 2911 //-------------------------------------------------------------------------------------------- |
| 2833 batch.draws = (rlDrawCall *)RL_MALLOC(RL_DEFAULT_BATCH_DRAWCALLS*sizeof(rlDrawCall)); | 2912 batch.draws = (rlDrawCall *)RL_CALLOC(RL_DEFAULT_BATCH_DRAWCALLS, sizeof(rlDrawCall)); |
| 2834 | 2913 |
| 2835 for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) | 2914 for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++) |
| 2836 { | 2915 { |
| 2837 batch.draws[i].mode = RL_QUADS; | 2916 batch.draws[i].mode = RL_QUADS; |
| 2838 batch.draws[i].vertexCount = 0; | 2917 batch.draws[i].vertexCount = 0; |
| 2844 //batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); | 2923 //batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); |
| 2845 } | 2924 } |
| 2846 | 2925 |
| 2847 batch.bufferCount = numBuffers; // Record buffer count | 2926 batch.bufferCount = numBuffers; // Record buffer count |
| 2848 batch.drawCounter = 1; // Reset draws counter | 2927 batch.drawCounter = 1; // Reset draws counter |
| 2849 batch.currentDepth = -1.0f; // Reset depth value | 2928 batch.currentDepth = -1.0f; // Reset depth value |
| 2850 //-------------------------------------------------------------------------------------------- | 2929 //-------------------------------------------------------------------------------------------- |
| 2851 #endif | 2930 #endif |
| 2852 | 2931 |
| 2853 return batch; | 2932 return batch; |
| 2854 } | 2933 } |
| 2898 RL_FREE(batch.draws); | 2977 RL_FREE(batch.draws); |
| 2899 #endif | 2978 #endif |
| 2900 } | 2979 } |
| 2901 | 2980 |
| 2902 // Draw render batch | 2981 // Draw render batch |
| 2903 // NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) | 2982 // NOTE: Batch is reseted and current buffer is updated (for multi-buffer config) |
| 2904 void rlDrawRenderBatch(rlRenderBatch *batch) | 2983 void rlDrawRenderBatch(rlRenderBatch *batch) |
| 2905 { | 2984 { |
| 2906 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 2985 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 2907 // Update batch vertex buffers | 2986 // Update batch vertex buffers |
| 2908 //------------------------------------------------------------------------------------------------------------ | 2987 //------------------------------------------------------------------------------------------------------------ |
| 2909 // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) | 2988 // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) |
| 2910 // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?) | |
| 2911 if (RLGL.State.vertexCounter > 0) | 2989 if (RLGL.State.vertexCounter > 0) |
| 2912 { | 2990 { |
| 2913 // Activate elements VAO | 2991 // Activate elements VAO |
| 2914 if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); | 2992 if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId); |
| 2993 | |
| 2994 // TODO: If no data changed on the CPU arrays there is no need to re-upload data to GPU, | |
| 2995 // a flag can be used to detect changes but it would imply keeping a copy buffer and memcmp() both, does it worth it? | |
| 2915 | 2996 |
| 2916 // Vertex positions buffer | 2997 // Vertex positions buffer |
| 2917 glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); | 2998 glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]); |
| 2918 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices); | 2999 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices); |
| 2919 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer | 3000 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer |
| 2933 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); | 3014 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); |
| 2934 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer | 3015 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer |
| 2935 | 3016 |
| 2936 // NOTE: glMapBuffer() causes sync issue | 3017 // NOTE: glMapBuffer() causes sync issue |
| 2937 // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job | 3018 // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job |
| 2938 // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer() | 3019 // To avoid waiting (idle), glBufferData() can bee called first with NULL pointer before glMapBuffer() |
| 2939 // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new | 3020 // Doing that, the previous data in PBO will be discarded and glMapBuffer() returns a new |
| 2940 // allocated pointer immediately even if GPU is still working with the previous data | 3021 // allocated pointer immediately even if GPU is still working with the previous data |
| 2941 | 3022 |
| 2942 // Another option: map the buffer object into client's memory | 3023 // Another option: map the buffer object into client's memory |
| 2943 // Probably this code could be moved somewhere else... | 3024 //batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); |
| 2944 // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); | 3025 //if (batch->vertexBuffer[batch->currentBuffer].vertices) |
| 2945 // if (batch->vertexBuffer[batch->currentBuffer].vertices) | 3026 //{ |
| 2946 // { | 3027 // Update vertex data |
| 2947 // Update vertex data | 3028 //} |
| 2948 // } | 3029 //glUnmapBuffer(GL_ARRAY_BUFFER); |
| 2949 // glUnmapBuffer(GL_ARRAY_BUFFER); | |
| 2950 | 3030 |
| 2951 // Unbind the current VAO | 3031 // Unbind the current VAO |
| 2952 if (RLGL.ExtSupported.vao) glBindVertexArray(0); | 3032 if (RLGL.ExtSupported.vao) glBindVertexArray(0); |
| 2953 } | 3033 } |
| 2954 //------------------------------------------------------------------------------------------------------------ | 3034 //------------------------------------------------------------------------------------------------------------ |
| 3052 // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls | 3132 // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls |
| 3053 glActiveTexture(GL_TEXTURE0); | 3133 glActiveTexture(GL_TEXTURE0); |
| 3054 | 3134 |
| 3055 for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++) | 3135 for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++) |
| 3056 { | 3136 { |
| 3057 // Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default | 3137 // Bind current draw call texture, activated as GL_TEXTURE0 and bound to sampler2D texture0 by default |
| 3058 glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId); | 3138 glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId); |
| 3059 | 3139 |
| 3060 if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount); | 3140 if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount); |
| 3061 else | 3141 else |
| 3062 { | 3142 { |
| 3063 #if defined(GRAPHICS_API_OPENGL_33) | 3143 #if defined(GRAPHICS_API_OPENGL_33) |
| 3064 // We need to define the number of indices to be processed: elementCount*6 | 3144 // The number of indices to be processed needs to be defined: elementCount*6 |
| 3065 // NOTE: The final parameter tells the GPU the offset in bytes from the | 3145 // NOTE: The final parameter tells the GPU the offset in bytes from the |
| 3066 // start of the index buffer to the location of the first index to process | 3146 // start of the index buffer to the location of the first index to process |
| 3067 glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); | 3147 glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); |
| 3068 #endif | 3148 #endif |
| 3069 #if defined(GRAPHICS_API_OPENGL_ES2) | 3149 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 3160 int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode; | 3240 int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode; |
| 3161 int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId; | 3241 int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId; |
| 3162 | 3242 |
| 3163 rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside | 3243 rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside |
| 3164 | 3244 |
| 3165 // Restore state of last batch so we can continue adding vertices | 3245 // Restore state of last batch so new vertices can be added |
| 3166 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode; | 3246 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode; |
| 3167 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; | 3247 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture; |
| 3168 } | 3248 } |
| 3169 #endif | 3249 #endif |
| 3170 | 3250 |
| 3175 //----------------------------------------------------------------------------------------- | 3255 //----------------------------------------------------------------------------------------- |
| 3176 // Convert image data to OpenGL texture (returns OpenGL valid Id) | 3256 // Convert image data to OpenGL texture (returns OpenGL valid Id) |
| 3177 unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) | 3257 unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount) |
| 3178 { | 3258 { |
| 3179 unsigned int id = 0; | 3259 unsigned int id = 0; |
| 3260 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } | |
| 3180 | 3261 |
| 3181 glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding | 3262 glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding |
| 3182 | 3263 |
| 3183 // Check texture format support by OpenGL 1.1 (compressed textures not supported) | 3264 // Check texture format support by OpenGL 1.1 (compressed textures not supported) |
| 3184 #if defined(GRAPHICS_API_OPENGL_11) | 3265 #if defined(GRAPHICS_API_OPENGL_11) |
| 3185 if (format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) | 3266 if (format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) |
| 3186 { | 3267 { |
| 3268 // TODO: Support texture data decompression | |
| 3187 TRACELOG(RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats"); | 3269 TRACELOG(RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats"); |
| 3188 return id; | 3270 return id; |
| 3189 } | 3271 } |
| 3190 #else | 3272 #else |
| 3191 if ((!RLGL.ExtSupported.texCompDXT) && ((format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA) || | 3273 if ((!RLGL.ExtSupported.texCompDXT) && ((format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA) || |
| 3217 { | 3299 { |
| 3218 TRACELOG(RL_LOG_WARNING, "GL: ASTC compressed texture format not supported"); | 3300 TRACELOG(RL_LOG_WARNING, "GL: ASTC compressed texture format not supported"); |
| 3219 return id; | 3301 return id; |
| 3220 } | 3302 } |
| 3221 #endif | 3303 #endif |
| 3222 #endif // GRAPHICS_API_OPENGL_11 | 3304 #endif // GRAPHICS_API_OPENGL_11 |
| 3223 | 3305 |
| 3224 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | 3306 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| 3225 | 3307 |
| 3226 glGenTextures(1, &id); // Generate texture id | 3308 glGenTextures(1, &id); // Generate texture id |
| 3227 | 3309 |
| 3228 glBindTexture(GL_TEXTURE_2D, id); | 3310 glBindTexture(GL_TEXTURE_2D, id); |
| 3229 | 3311 |
| 3230 int mipWidth = width; | 3312 int mipWidth = width; |
| 3231 int mipHeight = height; | 3313 int mipHeight = height; |
| 3232 int mipOffset = 0; // Mipmap data offset, only used for tracelog | 3314 int mipOffset = 0; // Mipmap data offset, only used for tracelog |
| 3315 (void)mipOffset; // Used to avoid gcc warnings about unused variable | |
| 3233 | 3316 |
| 3234 // NOTE: Added pointer math separately from function to avoid UBSAN complaining | 3317 // NOTE: Added pointer math separately from function to avoid UBSAN complaining |
| 3235 unsigned char *dataPtr = NULL; | 3318 unsigned char *dataPtr = NULL; |
| 3236 if (data != NULL) dataPtr = (unsigned char *)data; | 3319 if (data != NULL) dataPtr = (unsigned char *)data; |
| 3237 | 3320 |
| 3241 unsigned int mipSize = rlGetPixelDataSize(mipWidth, mipHeight, format); | 3324 unsigned int mipSize = rlGetPixelDataSize(mipWidth, mipHeight, format); |
| 3242 | 3325 |
| 3243 unsigned int glInternalFormat, glFormat, glType; | 3326 unsigned int glInternalFormat, glFormat, glType; |
| 3244 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); | 3327 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); |
| 3245 | 3328 |
| 3246 TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); | 3329 TRACELOG(RL_LOG_DEBUG, "TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset); |
| 3247 | 3330 |
| 3248 if (glInternalFormat != 0) | 3331 if (glInternalFormat != 0) |
| 3249 { | 3332 { |
| 3250 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr); | 3333 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, dataPtr); |
| 3251 #if !defined(GRAPHICS_API_OPENGL_11) | 3334 #if !defined(GRAPHICS_API_OPENGL_11) |
| 3270 #endif | 3353 #endif |
| 3271 } | 3354 } |
| 3272 | 3355 |
| 3273 mipWidth /= 2; | 3356 mipWidth /= 2; |
| 3274 mipHeight /= 2; | 3357 mipHeight /= 2; |
| 3275 mipOffset += mipSize; // Increment offset position to next mipmap | 3358 mipOffset += mipSize; // Increment offset position to next mipmap |
| 3276 if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap | 3359 if (data != NULL) dataPtr += mipSize; // Increment data pointer to next mipmap |
| 3277 | 3360 |
| 3278 // Security check for NPOT textures | 3361 // Security check for NPOT textures |
| 3279 if (mipWidth < 1) mipWidth = 1; | 3362 if (mipWidth < 1) mipWidth = 1; |
| 3280 if (mipHeight < 1) mipHeight = 1; | 3363 if (mipHeight < 1) mipHeight = 1; |
| 3281 } | 3364 } |
| 3282 | 3365 |
| 3283 // Texture parameters configuration | 3366 // Texture parameters configuration |
| 3284 // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used | 3367 // NOTE: glTexParameteri does NOT affect texture uploading |
| 3285 #if defined(GRAPHICS_API_OPENGL_ES2) | 3368 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 3286 // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used | 3369 // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used |
| 3287 if (RLGL.ExtSupported.texNPOT) | 3370 if (RLGL.ExtSupported.texNPOT) |
| 3288 { | 3371 { |
| 3289 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis | 3372 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis |
| 3305 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR | 3388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Alternative: GL_LINEAR |
| 3306 | 3389 |
| 3307 #if defined(GRAPHICS_API_OPENGL_33) | 3390 #if defined(GRAPHICS_API_OPENGL_33) |
| 3308 if (mipmapCount > 1) | 3391 if (mipmapCount > 1) |
| 3309 { | 3392 { |
| 3310 // Activate Trilinear filtering if mipmaps are available | 3393 // Activate trilinear filtering if mipmaps are available |
| 3311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 3394 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 3312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); | 3395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
| 3313 } | 3396 |
| 3314 #endif | 3397 // Define the maximum number of mipmap levels to be used, 0 is base texture size |
| 3315 | 3398 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); |
| 3316 // At this point we have the texture loaded in GPU and texture parameters configured | 3399 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapCount - 1); |
| 3400 | |
| 3401 // Check if the loaded texture with mipmaps is complete, | |
| 3402 // uncomplete textures will draw in black if mipmap filtering is required | |
| 3403 //GLint complete = 0; | |
| 3404 //glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT, &complete); | |
| 3405 } | |
| 3406 #endif | |
| 3407 | |
| 3408 // At this point texture is loaded in GPU and texture parameters configured | |
| 3317 | 3409 |
| 3318 // NOTE: If mipmaps were not in data, they are not generated automatically | 3410 // NOTE: If mipmaps were not in data, they are not generated automatically |
| 3319 | 3411 |
| 3320 // Unbind current texture | 3412 // Unbind current texture |
| 3321 glBindTexture(GL_TEXTURE_2D, 0); | 3413 glBindTexture(GL_TEXTURE_2D, 0); |
| 3329 // Load depth texture/renderbuffer (to be attached to fbo) | 3421 // Load depth texture/renderbuffer (to be attached to fbo) |
| 3330 // WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture and WebGL requires WEBGL_depth_texture extensions | 3422 // WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture and WebGL requires WEBGL_depth_texture extensions |
| 3331 unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) | 3423 unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer) |
| 3332 { | 3424 { |
| 3333 unsigned int id = 0; | 3425 unsigned int id = 0; |
| 3334 | 3426 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } |
| 3335 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 3427 |
| 3336 // In case depth textures not supported, we force renderbuffer usage | 3428 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3429 // In case depth textures were not supported, force renderbuffer usage | |
| 3337 if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true; | 3430 if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true; |
| 3338 | 3431 |
| 3339 // NOTE: We let the implementation to choose the best bit-depth | 3432 // NOTE: Letting the implementation to choose the best bit-depth |
| 3340 // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F | 3433 // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F |
| 3341 unsigned int glInternalFormat = GL_DEPTH_COMPONENT; | 3434 unsigned int glInternalFormat = GL_DEPTH_COMPONENT; |
| 3342 | 3435 |
| 3343 #if (defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_ES3)) | 3436 #if defined(GRAPHICS_API_OPENGL_ES2) |
| 3344 // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) | 3437 // WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) |
| 3345 // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities | 3438 // while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities |
| 3346 if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) | 3439 if (!RLGL.ExtSupported.texDepthWebGL || useRenderBuffer) |
| 3347 { | 3440 { |
| 3348 if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES; | 3441 if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES; |
| 3349 else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES; | 3442 else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES; |
| 3350 else glInternalFormat = GL_DEPTH_COMPONENT16; | 3443 else glInternalFormat = GL_DEPTH_COMPONENT16; |
| 3351 } | 3444 } |
| 3445 #endif | |
| 3446 #if defined(GRAPHICS_API_OPENGL_ES3) | |
| 3447 // NOTE: This sized internal format should also work for WebGL 2.0 | |
| 3448 // WARNING: Specification only allows GL_DEPTH_COMPONENT32F for GL_FLOAT type | |
| 3449 // REF: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml | |
| 3450 if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24; | |
| 3451 else glInternalFormat = GL_DEPTH_COMPONENT16; | |
| 3352 #endif | 3452 #endif |
| 3353 | 3453 |
| 3354 if (!useRenderBuffer && RLGL.ExtSupported.texDepth) | 3454 if (!useRenderBuffer && RLGL.ExtSupported.texDepth) |
| 3355 { | 3455 { |
| 3356 glGenTextures(1, &id); | 3456 glGenTextures(1, &id); |
| 3376 | 3476 |
| 3377 glBindRenderbuffer(GL_RENDERBUFFER, 0); | 3477 glBindRenderbuffer(GL_RENDERBUFFER, 0); |
| 3378 | 3478 |
| 3379 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16); | 3479 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16); |
| 3380 } | 3480 } |
| 3481 #elif defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 3482 // NOTE: Renderbuffers are the same type of object as textures in rlsw | |
| 3483 // WARNING: Ensure that the depth format is the one specified at rlsw compilation | |
| 3484 glGenRenderbuffers(1, &id); | |
| 3485 glBindRenderbuffer(GL_RENDERBUFFER, id); | |
| 3486 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height); | |
| 3487 glBindRenderbuffer(GL_RENDERBUFFER, 0); | |
| 3381 #endif | 3488 #endif |
| 3382 | 3489 |
| 3383 return id; | 3490 return id; |
| 3384 } | 3491 } |
| 3385 | 3492 |
| 3387 // NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), | 3494 // NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), |
| 3388 // expected the following convention: +X, -X, +Y, -Y, +Z, -Z | 3495 // expected the following convention: +X, -X, +Y, -Y, +Z, -Z |
| 3389 unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount) | 3496 unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount) |
| 3390 { | 3497 { |
| 3391 unsigned int id = 0; | 3498 unsigned int id = 0; |
| 3499 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } | |
| 3392 | 3500 |
| 3393 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 3501 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3394 int mipSize = size; | 3502 int mipSize = size; |
| 3395 | 3503 |
| 3396 // NOTE: Added pointer math separately from function to avoid UBSAN complaining | 3504 // NOTE: Added pointer math separately from function to avoid UBSAN complaining |
| 3415 | 3523 |
| 3416 if (data == NULL) | 3524 if (data == NULL) |
| 3417 { | 3525 { |
| 3418 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) | 3526 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) |
| 3419 { | 3527 { |
| 3420 if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || | 3528 if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || |
| 3421 (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) || | 3529 (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) || |
| 3422 (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || | 3530 (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || |
| 3423 (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported"); | 3531 (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported"); |
| 3424 else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, NULL); | 3532 else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, NULL); |
| 3425 } | 3533 } |
| 3426 else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format"); | 3534 else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format"); |
| 3427 } | 3535 } |
| 3479 | 3587 |
| 3480 return id; | 3588 return id; |
| 3481 } | 3589 } |
| 3482 | 3590 |
| 3483 // Update already loaded texture in GPU with new data | 3591 // Update already loaded texture in GPU with new data |
| 3484 // NOTE: We don't know safely if internal texture format is the expected one... | 3592 // WARNING: Not possible to know safely if internal texture format is the expected one... |
| 3485 void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data) | 3593 void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data) |
| 3486 { | 3594 { |
| 3487 glBindTexture(GL_TEXTURE_2D, id); | 3595 glBindTexture(GL_TEXTURE_2D, id); |
| 3488 | 3596 |
| 3489 unsigned int glInternalFormat, glFormat, glType; | 3597 unsigned int glInternalFormat, glFormat, glType; |
| 3577 | 3685 |
| 3578 // Generate mipmap data for selected texture | 3686 // Generate mipmap data for selected texture |
| 3579 // NOTE: Only supports GPU mipmap generation | 3687 // NOTE: Only supports GPU mipmap generation |
| 3580 void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps) | 3688 void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps) |
| 3581 { | 3689 { |
| 3690 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return; } | |
| 3691 | |
| 3582 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 3692 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3583 glBindTexture(GL_TEXTURE_2D, id); | 3693 glBindTexture(GL_TEXTURE_2D, id); |
| 3584 | 3694 |
| 3585 // Check if texture is power-of-two (POT) | 3695 // Check if texture is power-of-two (POT) |
| 3586 bool texIsPOT = false; | 3696 bool texIsPOT = false; |
| 3613 void *pixels = NULL; | 3723 void *pixels = NULL; |
| 3614 | 3724 |
| 3615 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) | 3725 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) |
| 3616 glBindTexture(GL_TEXTURE_2D, id); | 3726 glBindTexture(GL_TEXTURE_2D, id); |
| 3617 | 3727 |
| 3618 // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) | 3728 // NOTE: Using texture id, some texture info can be retrieved (but not on OpenGL ES 2.0) |
| 3619 // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE | 3729 // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE |
| 3620 //int width, height, format; | 3730 //int width, height, format; |
| 3621 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); | 3731 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); |
| 3622 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); | 3732 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); |
| 3623 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); | 3733 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); |
| 3632 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); | 3742 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); |
| 3633 unsigned int size = rlGetPixelDataSize(width, height, format); | 3743 unsigned int size = rlGetPixelDataSize(width, height, format); |
| 3634 | 3744 |
| 3635 if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) | 3745 if ((glInternalFormat != 0) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)) |
| 3636 { | 3746 { |
| 3637 pixels = RL_MALLOC(size); | 3747 pixels = RL_CALLOC(size, 1); |
| 3638 glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); | 3748 glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); |
| 3639 } | 3749 } |
| 3640 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format); | 3750 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format); |
| 3641 | 3751 |
| 3642 glBindTexture(GL_TEXTURE_2D, 0); | 3752 glBindTexture(GL_TEXTURE_2D, 0); |
| 3646 // glGetTexImage() is not available on OpenGL ES 2.0 | 3756 // glGetTexImage() is not available on OpenGL ES 2.0 |
| 3647 // Texture width and height are required on OpenGL ES 2.0, there is no way to get it from texture id | 3757 // Texture width and height are required on OpenGL ES 2.0, there is no way to get it from texture id |
| 3648 // Two possible Options: | 3758 // Two possible Options: |
| 3649 // 1 - Bind texture to color fbo attachment and glReadPixels() | 3759 // 1 - Bind texture to color fbo attachment and glReadPixels() |
| 3650 // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() | 3760 // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() |
| 3651 // We are using Option 1, just need to care for texture format on retrieval | 3761 // Using Option 1, care for texture format on retrieval |
| 3652 // NOTE: This behaviour could be conditioned by graphic driver... | 3762 // NOTE: This behaviour could be conditioned by graphic driver... |
| 3653 unsigned int fboId = rlLoadFramebuffer(); | 3763 unsigned int fboId = rlLoadFramebuffer(); |
| 3654 | 3764 |
| 3655 glBindFramebuffer(GL_FRAMEBUFFER, fboId); | 3765 glBindFramebuffer(GL_FRAMEBUFFER, fboId); |
| 3656 glBindTexture(GL_TEXTURE_2D, 0); | 3766 glBindTexture(GL_TEXTURE_2D, 0); |
| 3657 | 3767 |
| 3658 // Attach our texture to FBO | 3768 // Attach our texture to FBO |
| 3659 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); | 3769 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0); |
| 3660 | 3770 |
| 3661 // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format | 3771 // Reading data as RGBA because FBO texture is configured as RGBA, despite binding another texture format |
| 3662 pixels = (unsigned char *)RL_MALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)); | 3772 pixels = RL_CALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8), 1); |
| 3663 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 3773 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
| 3664 | 3774 |
| 3665 glBindFramebuffer(GL_FRAMEBUFFER, 0); | 3775 glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 3666 | 3776 |
| 3667 // Clean up temporal fbo | 3777 // Clean up temporal fbo |
| 3669 #endif | 3779 #endif |
| 3670 | 3780 |
| 3671 return pixels; | 3781 return pixels; |
| 3672 } | 3782 } |
| 3673 | 3783 |
| 3784 // Copy framebuffer pixel data to internal buffer | |
| 3785 void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pixels) | |
| 3786 { | |
| 3787 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 3788 unsigned int glInternalFormat, glFormat, glType; | |
| 3789 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); // Get OpenGL texture format | |
| 3790 swReadPixels(x, y, width, height, glFormat, glType, pixels); | |
| 3791 #endif | |
| 3792 } | |
| 3793 | |
| 3794 // Resize internal framebuffer | |
| 3795 void rlResizeFramebuffer(int width, int height) | |
| 3796 { | |
| 3797 #if defined(GRAPHICS_API_OPENGL_SOFTWARE) | |
| 3798 swResize(width, height); | |
| 3799 #endif | |
| 3800 } | |
| 3801 | |
| 3674 // Read screen pixel data (color buffer) | 3802 // Read screen pixel data (color buffer) |
| 3675 unsigned char *rlReadScreenPixels(int width, int height) | 3803 unsigned char *rlReadScreenPixels(int width, int height) |
| 3676 { | 3804 { |
| 3677 unsigned char *screenData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); | 3805 unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); |
| 3678 | 3806 |
| 3679 // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer | 3807 // NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer |
| 3680 // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! | 3808 // WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly! |
| 3681 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); | 3809 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData); |
| 3682 | 3810 |
| 3683 // Flip image vertically! | 3811 // Flip image vertically |
| 3684 unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char)); | 3812 // NOTE: Alpha value has already been applied to RGB in framebuffer, not needed anymore |
| 3685 | 3813 for (int y = height - 1; y >= height/2; y--) |
| 3686 for (int y = height - 1; y >= 0; y--) | 3814 { |
| 3687 { | 3815 for (int x = 0; x < (width*4); x += 4) |
| 3688 for (int x = 0; x < (width*4); x++) | |
| 3689 { | 3816 { |
| 3690 imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; // Flip line | 3817 unsigned int s = ((height - 1) - y)*width*4 + x; |
| 3691 | 3818 unsigned int e = y*width*4 + x; |
| 3692 // Set alpha component value to 255 (no trasparent image retrieval) | 3819 |
| 3693 // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! | 3820 unsigned char r = imgData[s]; |
| 3694 if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255; | 3821 unsigned char g = imgData[s+1]; |
| 3822 unsigned char b = imgData[s+2]; | |
| 3823 | |
| 3824 imgData[s] = imgData[e]; | |
| 3825 imgData[s+1] = imgData[e+1]; | |
| 3826 imgData[s+2] = imgData[e+2]; | |
| 3827 imgData[s+3] = 255; // Set alpha component value to 255 (no trasparent image retrieval) | |
| 3828 | |
| 3829 imgData[e] = r; | |
| 3830 imgData[e+1] = g; | |
| 3831 imgData[e+2] = b; | |
| 3832 imgData[e+3] = 255; // Ditto | |
| 3695 } | 3833 } |
| 3696 } | 3834 } |
| 3697 | |
| 3698 RL_FREE(screenData); | |
| 3699 | 3835 |
| 3700 return imgData; // NOTE: image data should be freed | 3836 return imgData; // NOTE: image data should be freed |
| 3701 } | 3837 } |
| 3702 | 3838 |
| 3703 // Framebuffer management (fbo) | 3839 // Framebuffer management (fbo) |
| 3705 // Load a framebuffer to be used for rendering | 3841 // Load a framebuffer to be used for rendering |
| 3706 // NOTE: No textures attached | 3842 // NOTE: No textures attached |
| 3707 unsigned int rlLoadFramebuffer(void) | 3843 unsigned int rlLoadFramebuffer(void) |
| 3708 { | 3844 { |
| 3709 unsigned int fboId = 0; | 3845 unsigned int fboId = 0; |
| 3710 | 3846 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return fboId; } |
| 3711 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 3847 |
| 3712 glGenFramebuffers(1, &fboId); // Create the framebuffer object | 3848 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 3713 glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer | 3849 glGenFramebuffers(1, &fboId); // Create the framebuffer object |
| 3850 glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer | |
| 3714 #endif | 3851 #endif |
| 3715 | 3852 |
| 3716 return fboId; | 3853 return fboId; |
| 3717 } | 3854 } |
| 3718 | 3855 |
| 3719 // Attach color buffer texture to an fbo (unloads previous attachment) | 3856 // Attach color buffer texture to a framebuffer object (unloads previous attachment) |
| 3720 // NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture | 3857 // NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture |
| 3721 void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel) | 3858 void rlFramebufferAttach(unsigned int id, unsigned int texId, int attachType, int texType, int mipLevel) |
| 3722 { | 3859 { |
| 3723 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 3860 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 3724 glBindFramebuffer(GL_FRAMEBUFFER, fboId); | 3861 glBindFramebuffer(GL_FRAMEBUFFER, id); |
| 3725 | 3862 |
| 3726 switch (attachType) | 3863 switch (attachType) |
| 3727 { | 3864 { |
| 3728 case RL_ATTACHMENT_COLOR_CHANNEL0: | 3865 case RL_ATTACHMENT_COLOR_CHANNEL0: |
| 3729 case RL_ATTACHMENT_COLOR_CHANNEL1: | 3866 case RL_ATTACHMENT_COLOR_CHANNEL1: |
| 3735 case RL_ATTACHMENT_COLOR_CHANNEL7: | 3872 case RL_ATTACHMENT_COLOR_CHANNEL7: |
| 3736 { | 3873 { |
| 3737 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, mipLevel); | 3874 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, mipLevel); |
| 3738 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId); | 3875 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId); |
| 3739 else if (texType >= RL_ATTACHMENT_CUBEMAP_POSITIVE_X) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_CUBE_MAP_POSITIVE_X + texType, texId, mipLevel); | 3876 else if (texType >= RL_ATTACHMENT_CUBEMAP_POSITIVE_X) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_CUBE_MAP_POSITIVE_X + texType, texId, mipLevel); |
| 3740 | |
| 3741 } break; | 3877 } break; |
| 3742 case RL_ATTACHMENT_DEPTH: | 3878 case RL_ATTACHMENT_DEPTH: |
| 3743 { | 3879 { |
| 3744 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); | 3880 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); |
| 3745 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); | 3881 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); |
| 3746 | |
| 3747 } break; | 3882 } break; |
| 3748 case RL_ATTACHMENT_STENCIL: | 3883 case RL_ATTACHMENT_STENCIL: |
| 3749 { | 3884 { |
| 3750 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); | 3885 if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, mipLevel); |
| 3751 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); | 3886 else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); |
| 3752 | |
| 3753 } break; | 3887 } break; |
| 3754 default: break; | 3888 default: break; |
| 3755 } | 3889 } |
| 3756 | 3890 |
| 3757 glBindFramebuffer(GL_FRAMEBUFFER, 0); | 3891 glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 3761 // Verify render texture is complete | 3895 // Verify render texture is complete |
| 3762 bool rlFramebufferComplete(unsigned int id) | 3896 bool rlFramebufferComplete(unsigned int id) |
| 3763 { | 3897 { |
| 3764 bool result = false; | 3898 bool result = false; |
| 3765 | 3899 |
| 3766 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 3900 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 3767 glBindFramebuffer(GL_FRAMEBUFFER, id); | 3901 glBindFramebuffer(GL_FRAMEBUFFER, id); |
| 3768 | 3902 |
| 3769 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); | 3903 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| 3770 | 3904 |
| 3771 if (status != GL_FRAMEBUFFER_COMPLETE) | 3905 if (status != GL_FRAMEBUFFER_COMPLETE) |
| 3792 | 3926 |
| 3793 // Unload framebuffer from GPU memory | 3927 // Unload framebuffer from GPU memory |
| 3794 // NOTE: All attached textures/cubemaps/renderbuffers are also deleted | 3928 // NOTE: All attached textures/cubemaps/renderbuffers are also deleted |
| 3795 void rlUnloadFramebuffer(unsigned int id) | 3929 void rlUnloadFramebuffer(unsigned int id) |
| 3796 { | 3930 { |
| 3797 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT) | 3931 #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_SOFTWARE)) |
| 3798 // Query depth attachment to automatically delete texture/renderbuffer | 3932 // Query depth attachment to automatically delete texture/renderbuffer |
| 3799 int depthType = 0, depthId = 0; | 3933 int depthType = 0; |
| 3800 glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type | 3934 glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type |
| 3801 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType); | 3935 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType); |
| 3802 | 3936 |
| 3803 // TODO: Review warning retrieving object name in WebGL | |
| 3804 // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name | 3937 // WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name |
| 3805 // https://registry.khronos.org/webgl/specs/latest/1.0/ | 3938 // REF: https://registry.khronos.org/webgl/specs/latest/1.0/ |
| 3939 int depthId = 0; | |
| 3806 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); | 3940 glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId); |
| 3807 | 3941 |
| 3808 unsigned int depthIdU = (unsigned int)depthId; | 3942 unsigned int depthIdU = (unsigned int)depthId; |
| 3809 if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU); | 3943 if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU); |
| 3810 else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU); | 3944 else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU); |
| 3823 //----------------------------------------------------------------------------------------- | 3957 //----------------------------------------------------------------------------------------- |
| 3824 // Load a new attributes buffer | 3958 // Load a new attributes buffer |
| 3825 unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) | 3959 unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic) |
| 3826 { | 3960 { |
| 3827 unsigned int id = 0; | 3961 unsigned int id = 0; |
| 3962 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } | |
| 3828 | 3963 |
| 3829 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 3964 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3830 glGenBuffers(1, &id); | 3965 glGenBuffers(1, &id); |
| 3831 glBindBuffer(GL_ARRAY_BUFFER, id); | 3966 glBindBuffer(GL_ARRAY_BUFFER, id); |
| 3832 glBufferData(GL_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); | 3967 glBufferData(GL_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); |
| 3837 | 3972 |
| 3838 // Load a new attributes element buffer | 3973 // Load a new attributes element buffer |
| 3839 unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic) | 3974 unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic) |
| 3840 { | 3975 { |
| 3841 unsigned int id = 0; | 3976 unsigned int id = 0; |
| 3977 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } | |
| 3842 | 3978 |
| 3843 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 3979 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3844 glGenBuffers(1, &id); | 3980 glGenBuffers(1, &id); |
| 3845 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); | 3981 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); |
| 3846 glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); | 3982 glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); |
| 3957 | 4093 |
| 3958 // Draw vertex array instanced | 4094 // Draw vertex array instanced |
| 3959 void rlDrawVertexArrayInstanced(int offset, int count, int instances) | 4095 void rlDrawVertexArrayInstanced(int offset, int count, int instances) |
| 3960 { | 4096 { |
| 3961 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4097 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 3962 glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances); | 4098 glDrawArraysInstanced(GL_TRIANGLES, offset, count, instances); |
| 3963 #endif | 4099 #endif |
| 3964 } | 4100 } |
| 3965 | 4101 |
| 3966 // Draw vertex array elements instanced | 4102 // Draw vertex array elements instanced |
| 3967 void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances) | 4103 void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances) |
| 3973 | 4109 |
| 3974 glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr, instances); | 4110 glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)bufferPtr, instances); |
| 3975 #endif | 4111 #endif |
| 3976 } | 4112 } |
| 3977 | 4113 |
| 3978 #if defined(GRAPHICS_API_OPENGL_11) | |
| 3979 // Enable vertex state pointer | 4114 // Enable vertex state pointer |
| 3980 void rlEnableStatePointer(int vertexAttribType, void *buffer) | 4115 void rlEnableStatePointer(int vertexAttribType, void *buffer) |
| 3981 { | 4116 { |
| 4117 #if defined(GRAPHICS_API_OPENGL_11) | |
| 3982 if (buffer != NULL) glEnableClientState(vertexAttribType); | 4118 if (buffer != NULL) glEnableClientState(vertexAttribType); |
| 3983 switch (vertexAttribType) | 4119 switch (vertexAttribType) |
| 3984 { | 4120 { |
| 3985 case GL_VERTEX_ARRAY: glVertexPointer(3, GL_FLOAT, 0, buffer); break; | 4121 case GL_VERTEX_ARRAY: glVertexPointer(3, GL_FLOAT, 0, buffer); break; |
| 3986 case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(2, GL_FLOAT, 0, buffer); break; | 4122 case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(2, GL_FLOAT, 0, buffer); break; |
| 3987 case GL_NORMAL_ARRAY: if (buffer != NULL) glNormalPointer(GL_FLOAT, 0, buffer); break; | 4123 case GL_NORMAL_ARRAY: if (buffer != NULL) glNormalPointer(GL_FLOAT, 0, buffer); break; |
| 3988 case GL_COLOR_ARRAY: if (buffer != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer); break; | 4124 case GL_COLOR_ARRAY: if (buffer != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer); break; |
| 3989 //case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors | 4125 //case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors |
| 3990 default: break; | 4126 default: break; |
| 3991 } | 4127 } |
| 4128 #endif | |
| 3992 } | 4129 } |
| 3993 | 4130 |
| 3994 // Disable vertex state pointer | 4131 // Disable vertex state pointer |
| 3995 void rlDisableStatePointer(int vertexAttribType) | 4132 void rlDisableStatePointer(int vertexAttribType) |
| 3996 { | 4133 { |
| 4134 #if defined(GRAPHICS_API_OPENGL_11) | |
| 3997 glDisableClientState(vertexAttribType); | 4135 glDisableClientState(vertexAttribType); |
| 3998 } | 4136 #endif |
| 3999 #endif | 4137 } |
| 4000 | 4138 |
| 4001 // Load vertex array object (VAO) | 4139 // Load vertex array object (VAO) |
| 4002 unsigned int rlLoadVertexArray(void) | 4140 unsigned int rlLoadVertexArray(void) |
| 4003 { | 4141 { |
| 4004 unsigned int vaoId = 0; | 4142 unsigned int vaoId = 0; |
| 4005 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4143 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return vaoId; } |
| 4006 if (RLGL.ExtSupported.vao) | 4144 |
| 4007 { | 4145 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4008 glGenVertexArrays(1, &vaoId); | 4146 if (RLGL.ExtSupported.vao) glGenVertexArrays(1, &vaoId); |
| 4009 } | 4147 #endif |
| 4010 #endif | 4148 |
| 4011 return vaoId; | 4149 return vaoId; |
| 4012 } | 4150 } |
| 4013 | 4151 |
| 4014 // Set vertex attribute | 4152 // Set vertex attribute |
| 4015 void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset) | 4153 void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, int offset) |
| 4055 #endif | 4193 #endif |
| 4056 } | 4194 } |
| 4057 | 4195 |
| 4058 // Shaders management | 4196 // Shaders management |
| 4059 //----------------------------------------------------------------------------------------------- | 4197 //----------------------------------------------------------------------------------------------- |
| 4060 // Load shader from code strings | 4198 // Load (compile) shader and return shader id |
| 4199 unsigned int rlLoadShader(const char *code, int type) | |
| 4200 { | |
| 4201 unsigned int shaderId = 0; | |
| 4202 | |
| 4203 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 4204 shaderId = glCreateShader(type); | |
| 4205 glShaderSource(shaderId, 1, &code, NULL); | |
| 4206 | |
| 4207 GLint success = 0; | |
| 4208 glCompileShader(shaderId); | |
| 4209 glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success); | |
| 4210 | |
| 4211 if (success == GL_FALSE) | |
| 4212 { | |
| 4213 switch (type) | |
| 4214 { | |
| 4215 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shaderId); break; | |
| 4216 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shaderId); break; | |
| 4217 //case GL_GEOMETRY_SHADER: | |
| 4218 #if defined(GRAPHICS_API_OPENGL_43) | |
| 4219 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shaderId); break; | |
| 4220 #elif defined(GRAPHICS_API_OPENGL_33) | |
| 4221 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shaderId); break; | |
| 4222 #endif | |
| 4223 default: break; | |
| 4224 } | |
| 4225 | |
| 4226 int maxLength = 0; | |
| 4227 glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength); | |
| 4228 | |
| 4229 if (maxLength > 0) | |
| 4230 { | |
| 4231 int length = 0; | |
| 4232 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); | |
| 4233 glGetShaderInfoLog(shaderId, maxLength, &length, log); | |
| 4234 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shaderId, log); | |
| 4235 RL_FREE(log); | |
| 4236 } | |
| 4237 | |
| 4238 // Unload object allocated by glCreateShader(), | |
| 4239 // despite failing in the compilation process | |
| 4240 glDeleteShader(shaderId); | |
| 4241 shaderId = 0; | |
| 4242 } | |
| 4243 else | |
| 4244 { | |
| 4245 switch (type) | |
| 4246 { | |
| 4247 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shaderId); break; | |
| 4248 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shaderId); break; | |
| 4249 //case GL_GEOMETRY_SHADER: | |
| 4250 #if defined(GRAPHICS_API_OPENGL_43) | |
| 4251 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shaderId); break; | |
| 4252 #elif defined(GRAPHICS_API_OPENGL_33) | |
| 4253 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shaderId); break; | |
| 4254 #endif | |
| 4255 default: break; | |
| 4256 } | |
| 4257 } | |
| 4258 #endif | |
| 4259 | |
| 4260 return shaderId; | |
| 4261 } | |
| 4262 | |
| 4263 // Load shader program from code strings | |
| 4061 // NOTE: If shader string is NULL, using default vertex/fragment shaders | 4264 // NOTE: If shader string is NULL, using default vertex/fragment shaders |
| 4062 unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode) | 4265 unsigned int rlLoadShaderProgram(const char *vsCode, const char *fsCode) |
| 4063 { | 4266 { |
| 4064 unsigned int id = 0; | 4267 unsigned int id = 0; // Shader program id |
| 4268 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return id; } | |
| 4065 | 4269 |
| 4066 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4270 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4067 unsigned int vertexShaderId = 0; | 4271 unsigned int vertexShaderId = 0; |
| 4068 unsigned int fragmentShaderId = 0; | 4272 unsigned int fragmentShaderId = 0; |
| 4069 | 4273 |
| 4070 // Compile vertex shader (if provided) | 4274 // Compile vertex shader (if provided) |
| 4071 // NOTE: If not vertex shader is provided, use default one | 4275 // NOTE: If not vertex shader is provided, use default one |
| 4072 if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER); | 4276 if (vsCode != NULL) vertexShaderId = rlLoadShader(vsCode, GL_VERTEX_SHADER); |
| 4073 else vertexShaderId = RLGL.State.defaultVShaderId; | 4277 else vertexShaderId = RLGL.State.defaultVShaderId; |
| 4074 | 4278 |
| 4075 // Compile fragment shader (if provided) | 4279 // Compile fragment shader (if provided) |
| 4076 // NOTE: If not vertex shader is provided, use default one | 4280 // NOTE: If not vertex shader is provided, use default one |
| 4077 if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER); | 4281 if (fsCode != NULL) fragmentShaderId = rlLoadShader(fsCode, GL_FRAGMENT_SHADER); |
| 4078 else fragmentShaderId = RLGL.State.defaultFShaderId; | 4282 else fragmentShaderId = RLGL.State.defaultFShaderId; |
| 4079 | 4283 |
| 4080 // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id | 4284 // In case vertex and fragment shader are the default ones, no need to recompile, assign the default shader program id |
| 4081 if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; | 4285 if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; |
| 4082 else if ((vertexShaderId > 0) && (fragmentShaderId > 0)) | 4286 else if ((vertexShaderId > 0) && (fragmentShaderId > 0)) |
| 4083 { | 4287 { |
| 4084 // One of or both shader are new, we need to compile a new shader program | 4288 // One of or both shader are new, a new shader program needs to be compiled |
| 4085 id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId); | 4289 id = rlLoadShaderProgramEx(vertexShaderId, fragmentShaderId); |
| 4086 | 4290 |
| 4087 // We can detach and delete vertex/fragment shaders (if not default ones) | 4291 // Detaching and deleting vertex/fragment shaders (if not default ones) |
| 4088 // NOTE: We detach shader before deletion to make sure memory is freed | 4292 // WARNING: Detach shader before deletion to make sure memory is freed |
| 4089 if (vertexShaderId != RLGL.State.defaultVShaderId) | 4293 if (vertexShaderId != RLGL.State.defaultVShaderId) |
| 4090 { | 4294 { |
| 4091 // WARNING: Shader program linkage could fail and returned id is 0 | 4295 // WARNING: Shader program linkage could fail and returned id is 0 |
| 4092 if (id > 0) glDetachShader(id, vertexShaderId); | 4296 if (id > 0) glDetachShader(id, vertexShaderId); |
| 4093 glDeleteShader(vertexShaderId); | 4297 glDeleteShader(vertexShaderId); |
| 4097 // WARNING: Shader program linkage could fail and returned id is 0 | 4301 // WARNING: Shader program linkage could fail and returned id is 0 |
| 4098 if (id > 0) glDetachShader(id, fragmentShaderId); | 4302 if (id > 0) glDetachShader(id, fragmentShaderId); |
| 4099 glDeleteShader(fragmentShaderId); | 4303 glDeleteShader(fragmentShaderId); |
| 4100 } | 4304 } |
| 4101 | 4305 |
| 4102 // In case shader program loading failed, we assign default shader | 4306 // In case shader program loading failed, assign default shader |
| 4103 if (id == 0) | 4307 if (id == 0) |
| 4104 { | 4308 { |
| 4105 // In case shader loading fails, we return the default shader | 4309 // In case shader loading fails, reassigning default shader |
| 4106 TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader"); | 4310 TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader"); |
| 4107 id = RLGL.State.defaultShaderId; | 4311 id = RLGL.State.defaultShaderId; |
| 4108 } | 4312 } |
| 4109 /* | 4313 /* |
| 4110 else | 4314 else |
| 4123 | 4327 |
| 4124 // Get the name of the uniforms | 4328 // Get the name of the uniforms |
| 4125 glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); | 4329 glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); |
| 4126 | 4330 |
| 4127 name[namelen] = 0; | 4331 name[namelen] = 0; |
| 4128 TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); | 4332 TRACELOG(RL_LOG_DEBUG, "SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); |
| 4129 } | 4333 } |
| 4130 } | 4334 } |
| 4131 */ | 4335 */ |
| 4132 } | 4336 } |
| 4133 #endif | 4337 #endif |
| 4134 | 4338 |
| 4135 return id; | 4339 return id; |
| 4136 } | 4340 } |
| 4137 | 4341 |
| 4138 // Compile custom shader and return shader id | 4342 // Load shader program from already loaded shader ids |
| 4139 unsigned int rlCompileShader(const char *shaderCode, int type) | 4343 unsigned int rlLoadShaderProgramEx(unsigned int vsId, unsigned int fsId) |
| 4140 { | 4344 { |
| 4141 unsigned int shader = 0; | 4345 unsigned int programId = 0; |
| 4142 | 4346 if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return programId; } |
| 4143 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4347 |
| 4144 shader = glCreateShader(type); | 4348 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4145 glShaderSource(shader, 1, &shaderCode, NULL); | |
| 4146 | |
| 4147 GLint success = 0; | 4349 GLint success = 0; |
| 4148 glCompileShader(shader); | 4350 programId = glCreateProgram(); |
| 4149 glGetShaderiv(shader, GL_COMPILE_STATUS, &success); | 4351 |
| 4352 glAttachShader(programId, vsId); | |
| 4353 glAttachShader(programId, fsId); | |
| 4354 | |
| 4355 // Default attribute shader locations must be bound before linking | |
| 4356 // NOTE: There is no problem with binding a generic attribute index to an attribute variable name | |
| 4357 // that is never used; if some attrib name is no found on the shader, it locations becomes -1 | |
| 4358 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); | |
| 4359 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); | |
| 4360 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); | |
| 4361 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); | |
| 4362 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); | |
| 4363 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); | |
| 4364 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM, RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM); | |
| 4365 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEINDICES, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEINDICES); | |
| 4366 glBindAttribLocation(programId, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS); | |
| 4367 | |
| 4368 glLinkProgram(programId); | |
| 4369 | |
| 4370 // NOTE: All uniform variables are intitialised to 0 when a program links | |
| 4371 | |
| 4372 glGetProgramiv(programId, GL_LINK_STATUS, &success); | |
| 4150 | 4373 |
| 4151 if (success == GL_FALSE) | 4374 if (success == GL_FALSE) |
| 4152 { | 4375 { |
| 4153 switch (type) | 4376 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", programId); |
| 4154 { | |
| 4155 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break; | |
| 4156 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break; | |
| 4157 //case GL_GEOMETRY_SHADER: | |
| 4158 #if defined(GRAPHICS_API_OPENGL_43) | |
| 4159 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break; | |
| 4160 #elif defined(GRAPHICS_API_OPENGL_33) | |
| 4161 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break; | |
| 4162 #endif | |
| 4163 default: break; | |
| 4164 } | |
| 4165 | 4377 |
| 4166 int maxLength = 0; | 4378 int maxLength = 0; |
| 4167 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); | 4379 glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength); |
| 4168 | 4380 |
| 4169 if (maxLength > 0) | 4381 if (maxLength > 0) |
| 4170 { | 4382 { |
| 4171 int length = 0; | 4383 int length = 0; |
| 4172 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); | 4384 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); |
| 4173 glGetShaderInfoLog(shader, maxLength, &length, log); | 4385 glGetProgramInfoLog(programId, maxLength, &length, log); |
| 4174 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log); | 4386 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", programId, log); |
| 4175 RL_FREE(log); | 4387 RL_FREE(log); |
| 4176 } | 4388 } |
| 4177 | 4389 |
| 4178 shader = 0; | 4390 glDeleteProgram(programId); |
| 4391 | |
| 4392 programId = 0; | |
| 4179 } | 4393 } |
| 4180 else | 4394 else |
| 4181 { | 4395 { |
| 4182 switch (type) | 4396 // Get the size of compiled shader program (not available on OpenGL ES 2.0) |
| 4183 { | 4397 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero |
| 4184 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break; | 4398 //GLint binarySize = 0; |
| 4185 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break; | 4399 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); |
| 4186 //case GL_GEOMETRY_SHADER: | 4400 |
| 4187 #if defined(GRAPHICS_API_OPENGL_43) | 4401 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", programId); |
| 4188 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break; | 4402 } |
| 4189 #elif defined(GRAPHICS_API_OPENGL_33) | 4403 #endif |
| 4190 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break; | 4404 return programId; |
| 4191 #endif | 4405 } |
| 4192 default: break; | 4406 |
| 4193 } | 4407 // Load compute shader program |
| 4194 } | 4408 unsigned int rlLoadShaderProgramCompute(unsigned int csId) |
| 4195 #endif | 4409 { |
| 4196 | 4410 unsigned int programId = 0; |
| 4197 return shader; | 4411 |
| 4198 } | 4412 #if defined(GRAPHICS_API_OPENGL_43) |
| 4199 | |
| 4200 // Load custom shader strings and return program id | |
| 4201 unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId) | |
| 4202 { | |
| 4203 unsigned int program = 0; | |
| 4204 | |
| 4205 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 4206 GLint success = 0; | 4413 GLint success = 0; |
| 4207 program = glCreateProgram(); | 4414 programId = glCreateProgram(); |
| 4208 | 4415 |
| 4209 glAttachShader(program, vShaderId); | 4416 glAttachShader(programId, csId); |
| 4210 glAttachShader(program, fShaderId); | 4417 |
| 4211 | 4418 glLinkProgram(programId); |
| 4212 // NOTE: Default attribute shader locations must be Bound before linking | |
| 4213 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION); | |
| 4214 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); | |
| 4215 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL); | |
| 4216 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR); | |
| 4217 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); | |
| 4218 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); | |
| 4219 | |
| 4220 #ifdef RL_SUPPORT_MESH_GPU_SKINNING | |
| 4221 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS); | |
| 4222 glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS); | |
| 4223 #endif | |
| 4224 | |
| 4225 // NOTE: If some attrib name is no found on the shader, it locations becomes -1 | |
| 4226 | |
| 4227 glLinkProgram(program); | |
| 4228 | 4419 |
| 4229 // NOTE: All uniform variables are intitialised to 0 when a program links | 4420 // NOTE: All uniform variables are intitialised to 0 when a program links |
| 4230 | 4421 |
| 4231 glGetProgramiv(program, GL_LINK_STATUS, &success); | 4422 glGetProgramiv(programId, GL_LINK_STATUS, &success); |
| 4232 | 4423 |
| 4233 if (success == GL_FALSE) | 4424 if (success == GL_FALSE) |
| 4234 { | 4425 { |
| 4235 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program); | 4426 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", programId); |
| 4236 | 4427 |
| 4237 int maxLength = 0; | 4428 int maxLength = 0; |
| 4238 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); | 4429 glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &maxLength); |
| 4239 | 4430 |
| 4240 if (maxLength > 0) | 4431 if (maxLength > 0) |
| 4241 { | 4432 { |
| 4242 int length = 0; | 4433 int length = 0; |
| 4243 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); | 4434 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); |
| 4244 glGetProgramInfoLog(program, maxLength, &length, log); | 4435 glGetProgramInfoLog(programId, maxLength, &length, log); |
| 4245 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); | 4436 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", programId, log); |
| 4246 RL_FREE(log); | 4437 RL_FREE(log); |
| 4247 } | 4438 } |
| 4248 | 4439 |
| 4249 glDeleteProgram(program); | 4440 glDeleteProgram(programId); |
| 4250 | 4441 |
| 4251 program = 0; | 4442 programId = 0; |
| 4252 } | 4443 } |
| 4253 else | 4444 else |
| 4254 { | 4445 { |
| 4255 // Get the size of compiled shader program (not available on OpenGL ES 2.0) | 4446 // Get the size of compiled shader program (not available on OpenGL ES 2.0) |
| 4256 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero | 4447 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero |
| 4257 //GLint binarySize = 0; | 4448 //GLint binarySize = 0; |
| 4258 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); | 4449 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); |
| 4259 | 4450 |
| 4260 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program); | 4451 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", programId); |
| 4261 } | 4452 } |
| 4262 #endif | 4453 #else |
| 4263 return program; | 4454 TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not supported, enable GRAPHICS_API_OPENGL_43"); |
| 4455 #endif | |
| 4456 | |
| 4457 return programId; | |
| 4458 } | |
| 4459 | |
| 4460 // Delete shader | |
| 4461 void rlUnloadShader(unsigned int id) | |
| 4462 { | |
| 4463 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 4464 glDeleteShader(id); | |
| 4465 | |
| 4466 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader data from VRAM (GPU)", id); | |
| 4467 #endif | |
| 4264 } | 4468 } |
| 4265 | 4469 |
| 4266 // Unload shader program | 4470 // Unload shader program |
| 4267 void rlUnloadShaderProgram(unsigned int id) | 4471 void rlUnloadShaderProgram(unsigned int id) |
| 4268 { | 4472 { |
| 4272 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id); | 4476 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id); |
| 4273 #endif | 4477 #endif |
| 4274 } | 4478 } |
| 4275 | 4479 |
| 4276 // Get shader location uniform | 4480 // Get shader location uniform |
| 4277 int rlGetLocationUniform(unsigned int shaderId, const char *uniformName) | 4481 // NOTE: First parameter refers to shader program id |
| 4482 int rlGetLocationUniform(unsigned int id, const char *uniformName) | |
| 4278 { | 4483 { |
| 4279 int location = -1; | 4484 int location = -1; |
| 4280 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4485 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4281 location = glGetUniformLocation(shaderId, uniformName); | 4486 location = glGetUniformLocation(id, uniformName); |
| 4282 | 4487 |
| 4283 //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); | 4488 //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); |
| 4284 //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); | 4489 //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); |
| 4285 #endif | 4490 #endif |
| 4286 return location; | 4491 return location; |
| 4287 } | 4492 } |
| 4288 | 4493 |
| 4289 // Get shader location attribute | 4494 // Get shader location attribute |
| 4290 int rlGetLocationAttrib(unsigned int shaderId, const char *attribName) | 4495 // NOTE: First parameter refers to shader program id |
| 4496 int rlGetLocationAttrib(unsigned int id, const char *attribName) | |
| 4291 { | 4497 { |
| 4292 int location = -1; | 4498 int location = -1; |
| 4293 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4499 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4294 location = glGetAttribLocation(shaderId, attribName); | 4500 location = glGetAttribLocation(id, attribName); |
| 4295 | 4501 |
| 4296 //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); | 4502 //if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); |
| 4297 //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); | 4503 //else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); |
| 4298 #endif | 4504 #endif |
| 4299 return location; | 4505 return location; |
| 4319 case RL_SHADER_UNIFORM_UIVEC3: glUniform3uiv(locIndex, count, (unsigned int *)value); break; | 4525 case RL_SHADER_UNIFORM_UIVEC3: glUniform3uiv(locIndex, count, (unsigned int *)value); break; |
| 4320 case RL_SHADER_UNIFORM_UIVEC4: glUniform4uiv(locIndex, count, (unsigned int *)value); break; | 4526 case RL_SHADER_UNIFORM_UIVEC4: glUniform4uiv(locIndex, count, (unsigned int *)value); break; |
| 4321 #endif | 4527 #endif |
| 4322 case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; | 4528 case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; |
| 4323 default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); | 4529 default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); |
| 4324 | |
| 4325 // TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv() | |
| 4326 } | 4530 } |
| 4327 #endif | 4531 #endif |
| 4328 } | 4532 } |
| 4329 | 4533 |
| 4330 // Set shader value attribute | 4534 // Set shader value attribute |
| 4344 | 4548 |
| 4345 // Set shader value uniform matrix | 4549 // Set shader value uniform matrix |
| 4346 void rlSetUniformMatrix(int locIndex, Matrix mat) | 4550 void rlSetUniformMatrix(int locIndex, Matrix mat) |
| 4347 { | 4551 { |
| 4348 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4552 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4349 float matfloat[16] = { | 4553 glUniformMatrix4fv(locIndex, 1, false, rlMatrixToFloat(mat)); |
| 4350 mat.m0, mat.m1, mat.m2, mat.m3, | |
| 4351 mat.m4, mat.m5, mat.m6, mat.m7, | |
| 4352 mat.m8, mat.m9, mat.m10, mat.m11, | |
| 4353 mat.m12, mat.m13, mat.m14, mat.m15 | |
| 4354 }; | |
| 4355 glUniformMatrix4fv(locIndex, 1, false, matfloat); | |
| 4356 #endif | 4554 #endif |
| 4357 } | 4555 } |
| 4358 | 4556 |
| 4359 // Set shader value uniform matrix | 4557 // Set shader value uniform matrix |
| 4360 void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count) | 4558 void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count) |
| 4405 rlDrawRenderBatch(RLGL.currentBatch); | 4603 rlDrawRenderBatch(RLGL.currentBatch); |
| 4406 RLGL.State.currentShaderId = id; | 4604 RLGL.State.currentShaderId = id; |
| 4407 RLGL.State.currentShaderLocs = locs; | 4605 RLGL.State.currentShaderLocs = locs; |
| 4408 } | 4606 } |
| 4409 #endif | 4607 #endif |
| 4410 } | |
| 4411 | |
| 4412 // Load compute shader program | |
| 4413 unsigned int rlLoadComputeShaderProgram(unsigned int shaderId) | |
| 4414 { | |
| 4415 unsigned int program = 0; | |
| 4416 | |
| 4417 #if defined(GRAPHICS_API_OPENGL_43) | |
| 4418 GLint success = 0; | |
| 4419 program = glCreateProgram(); | |
| 4420 glAttachShader(program, shaderId); | |
| 4421 glLinkProgram(program); | |
| 4422 | |
| 4423 // NOTE: All uniform variables are intitialised to 0 when a program links | |
| 4424 | |
| 4425 glGetProgramiv(program, GL_LINK_STATUS, &success); | |
| 4426 | |
| 4427 if (success == GL_FALSE) | |
| 4428 { | |
| 4429 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program); | |
| 4430 | |
| 4431 int maxLength = 0; | |
| 4432 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); | |
| 4433 | |
| 4434 if (maxLength > 0) | |
| 4435 { | |
| 4436 int length = 0; | |
| 4437 char *log = (char *)RL_CALLOC(maxLength, sizeof(char)); | |
| 4438 glGetProgramInfoLog(program, maxLength, &length, log); | |
| 4439 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log); | |
| 4440 RL_FREE(log); | |
| 4441 } | |
| 4442 | |
| 4443 glDeleteProgram(program); | |
| 4444 | |
| 4445 program = 0; | |
| 4446 } | |
| 4447 else | |
| 4448 { | |
| 4449 // Get the size of compiled shader program (not available on OpenGL ES 2.0) | |
| 4450 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero | |
| 4451 //GLint binarySize = 0; | |
| 4452 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); | |
| 4453 | |
| 4454 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program); | |
| 4455 } | |
| 4456 #else | |
| 4457 TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43"); | |
| 4458 #endif | |
| 4459 | |
| 4460 return program; | |
| 4461 } | 4608 } |
| 4462 | 4609 |
| 4463 // Dispatch compute shader (equivalent to *draw* for graphics pilepine) | 4610 // Dispatch compute shader (equivalent to *draw* for graphics pilepine) |
| 4464 void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ) | 4611 void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ) |
| 4465 { | 4612 { |
| 4492 #if defined(GRAPHICS_API_OPENGL_43) | 4639 #if defined(GRAPHICS_API_OPENGL_43) |
| 4493 glDeleteBuffers(1, &ssboId); | 4640 glDeleteBuffers(1, &ssboId); |
| 4494 #else | 4641 #else |
| 4495 TRACELOG(RL_LOG_WARNING, "SSBO: SSBO not enabled. Define GRAPHICS_API_OPENGL_43"); | 4642 TRACELOG(RL_LOG_WARNING, "SSBO: SSBO not enabled. Define GRAPHICS_API_OPENGL_43"); |
| 4496 #endif | 4643 #endif |
| 4497 | |
| 4498 } | 4644 } |
| 4499 | 4645 |
| 4500 // Update SSBO buffer data | 4646 // Update SSBO buffer data |
| 4501 void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset) | 4647 void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSize, unsigned int offset) |
| 4502 { | 4648 { |
| 4507 } | 4653 } |
| 4508 | 4654 |
| 4509 // Get SSBO buffer size | 4655 // Get SSBO buffer size |
| 4510 unsigned int rlGetShaderBufferSize(unsigned int id) | 4656 unsigned int rlGetShaderBufferSize(unsigned int id) |
| 4511 { | 4657 { |
| 4658 unsigned int result = 0; | |
| 4512 #if defined(GRAPHICS_API_OPENGL_43) | 4659 #if defined(GRAPHICS_API_OPENGL_43) |
| 4513 GLint64 size = 0; | 4660 GLint64 size = 0; |
| 4514 glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); | 4661 glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); |
| 4515 glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size); | 4662 glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size); |
| 4516 return (size > 0)? (unsigned int)size : 0; | 4663 if (size > 0) result = (unsigned int)size; |
| 4517 #else | 4664 #endif |
| 4518 return 0; | 4665 return result; |
| 4519 #endif | |
| 4520 } | 4666 } |
| 4521 | 4667 |
| 4522 // Read SSBO buffer data (GPU->CPU) | 4668 // Read SSBO buffer data (GPU->CPU) |
| 4523 void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset) | 4669 void rlReadShaderBuffer(unsigned int id, void *dest, unsigned int count, unsigned int offset) |
| 4524 { | 4670 { |
| 4623 Matrix rlGetMatrixTransform(void) | 4769 Matrix rlGetMatrixTransform(void) |
| 4624 { | 4770 { |
| 4625 Matrix mat = rlMatrixIdentity(); | 4771 Matrix mat = rlMatrixIdentity(); |
| 4626 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4772 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4627 // TODO: Consider possible transform matrices in the RLGL.State.stack | 4773 // TODO: Consider possible transform matrices in the RLGL.State.stack |
| 4628 // Is this the right order? or should we start with the first stored matrix instead of the last one? | |
| 4629 //Matrix matStackTransform = rlMatrixIdentity(); | 4774 //Matrix matStackTransform = rlMatrixIdentity(); |
| 4630 //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); | 4775 //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); |
| 4776 | |
| 4631 mat = RLGL.State.transform; | 4777 mat = RLGL.State.transform; |
| 4632 #endif | 4778 #endif |
| 4633 return mat; | 4779 return mat; |
| 4634 } | 4780 } |
| 4635 | 4781 |
| 4838 default: return "UNKNOWN"; break; | 4984 default: return "UNKNOWN"; break; |
| 4839 } | 4985 } |
| 4840 } | 4986 } |
| 4841 | 4987 |
| 4842 //---------------------------------------------------------------------------------- | 4988 //---------------------------------------------------------------------------------- |
| 4843 // Module specific Functions Definition | 4989 // Module Functions Definition |
| 4844 //---------------------------------------------------------------------------------- | 4990 //---------------------------------------------------------------------------------- |
| 4845 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | 4991 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) |
| 4846 // Load default shader (just vertex positioning and texture coloring) | 4992 // Load default shader (just vertex positioning and texture coloring) |
| 4847 // NOTE: This shader program is used for internal buffers | 4993 // NOTE: This shader program is used for internal buffers |
| 4848 // NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs | 4994 // NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs |
| 4951 "} \n"; | 5097 "} \n"; |
| 4952 #endif | 5098 #endif |
| 4953 | 5099 |
| 4954 // NOTE: Compiled vertex/fragment shaders are not deleted, | 5100 // NOTE: Compiled vertex/fragment shaders are not deleted, |
| 4955 // they are kept for re-use as default shaders in case some shader loading fails | 5101 // they are kept for re-use as default shaders in case some shader loading fails |
| 4956 RLGL.State.defaultVShaderId = rlCompileShader(defaultVShaderCode, GL_VERTEX_SHADER); // Compile default vertex shader | 5102 RLGL.State.defaultVShaderId = rlLoadShader(defaultVShaderCode, GL_VERTEX_SHADER); // Compile default vertex shader |
| 4957 RLGL.State.defaultFShaderId = rlCompileShader(defaultFShaderCode, GL_FRAGMENT_SHADER); // Compile default fragment shader | 5103 RLGL.State.defaultFShaderId = rlLoadShader(defaultFShaderCode, GL_FRAGMENT_SHADER); // Compile default fragment shader |
| 4958 | 5104 |
| 4959 RLGL.State.defaultShaderId = rlLoadShaderProgram(RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId); | 5105 RLGL.State.defaultShaderId = rlLoadShaderProgramEx(RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId); |
| 4960 | 5106 |
| 4961 if (RLGL.State.defaultShaderId > 0) | 5107 if (RLGL.State.defaultShaderId > 0) |
| 4962 { | 5108 { |
| 4963 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId); | 5109 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId); |
| 4964 | 5110 |
| 4991 RL_FREE(RLGL.State.defaultShaderLocs); | 5137 RL_FREE(RLGL.State.defaultShaderLocs); |
| 4992 | 5138 |
| 4993 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId); | 5139 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId); |
| 4994 } | 5140 } |
| 4995 | 5141 |
| 4996 #if defined(RLGL_SHOW_GL_DETAILS_INFO) | 5142 #if RLGL_SHOW_GL_DETAILS_INFO |
| 4997 // Get compressed format official GL identifier name | 5143 // Get compressed format official GL identifier name |
| 4998 static const char *rlGetCompressedFormatName(int format) | 5144 static const char *rlGetCompressedFormatName(int format) |
| 4999 { | 5145 { |
| 5000 switch (format) | 5146 switch (format) |
| 5001 { | 5147 { |
| 5065 case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; break; | 5211 case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; break; |
| 5066 case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; break; | 5212 case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; break; |
| 5067 default: return "GL_COMPRESSED_UNKNOWN"; break; | 5213 default: return "GL_COMPRESSED_UNKNOWN"; break; |
| 5068 } | 5214 } |
| 5069 } | 5215 } |
| 5070 #endif // RLGL_SHOW_GL_DETAILS_INFO | 5216 #endif |
| 5071 | 5217 |
| 5072 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 | 5218 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 |
| 5073 | 5219 |
| 5074 // Get pixel data size in bytes (image or texture) | 5220 // Get pixel data size in bytes (image or texture) |
| 5075 // NOTE: Size depends on pixel format | 5221 // NOTE: Size depends on pixel format |
| 5076 static int rlGetPixelDataSize(int width, int height, int format) | 5222 static int rlGetPixelDataSize(int width, int height, int format) |
| 5077 { | 5223 { |
| 5096 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: | 5242 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: |
| 5097 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: | 5243 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: |
| 5098 case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: | 5244 case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: |
| 5099 case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: | 5245 case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: |
| 5100 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: | 5246 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: |
| 5101 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break; | 5247 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 8 bytes per each 4x4 block |
| 5248 { | |
| 5249 int blockWidth = (width + 3)/4; | |
| 5250 int blockHeight = (height + 3)/4; | |
| 5251 dataSize = blockWidth*blockHeight*8; | |
| 5252 } break; | |
| 5102 case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: | 5253 case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: |
| 5103 case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: | 5254 case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: |
| 5104 case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: | 5255 case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: |
| 5105 case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break; | 5256 case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 16 bytes per each 4x4 block |
| 5106 case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break; | 5257 { |
| 5258 int blockWidth = (width + 3)/4; | |
| 5259 int blockHeight = (height + 3)/4; | |
| 5260 dataSize = blockWidth*blockHeight*16; | |
| 5261 } break; | |
| 5262 case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block | |
| 5263 { | |
| 5264 int blockWidth = (width + 3)/4; | |
| 5265 int blockHeight = (height + 3)/4; | |
| 5266 dataSize = blockWidth*blockHeight*4; | |
| 5267 } break; | |
| 5107 default: break; | 5268 default: break; |
| 5108 } | 5269 } |
| 5109 | 5270 |
| 5110 double bytesPerPixel = (double)bpp/8.0; | 5271 // Compute dataSize for uncompressed texture data (no blocks) |
| 5111 dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes | 5272 if ((format >= RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) && |
| 5112 | 5273 (format <= RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) |
| 5113 // Most compressed formats works on 4x4 blocks, | 5274 { |
| 5114 // if texture is smaller, minimum dataSize is 8 or 16 | 5275 double bytesPerPixel = (double)bpp/8.0; |
| 5115 if ((width < 4) && (height < 4)) | 5276 dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes |
| 5116 { | |
| 5117 if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8; | |
| 5118 else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16; | |
| 5119 } | 5277 } |
| 5120 | 5278 |
| 5121 return dataSize; | 5279 return dataSize; |
| 5122 } | 5280 } |
| 5123 | 5281 |
| 5124 // Auxiliar math functions | 5282 // Auxiliar math functions |
| 5125 | 5283 //------------------------------------------------------------------------------- |
| 5284 // Get identity matrix | |
| 5285 static Matrix rlMatrixIdentity(void) | |
| 5286 { | |
| 5287 Matrix matIdentity = { 0 }; | |
| 5288 matIdentity.m0 = 1.0f; | |
| 5289 matIdentity.m5 = 1.0f; | |
| 5290 matIdentity.m10 = 1.0f; | |
| 5291 matIdentity.m15 = 1.0f; | |
| 5292 | |
| 5293 return matIdentity; | |
| 5294 } | |
| 5295 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) | |
| 5126 // Get float array of matrix data | 5296 // Get float array of matrix data |
| 5297 // Explicit conversion to column-major memory layout | |
| 5127 static rl_float16 rlMatrixToFloatV(Matrix mat) | 5298 static rl_float16 rlMatrixToFloatV(Matrix mat) |
| 5128 { | 5299 { |
| 5129 rl_float16 result = { 0 }; | 5300 rl_float16 result = { 0 }; |
| 5130 | 5301 |
| 5131 result.v[0] = mat.m0; | 5302 result.v[0] = mat.m0; |
| 5146 result.v[15] = mat.m15; | 5317 result.v[15] = mat.m15; |
| 5147 | 5318 |
| 5148 return result; | 5319 return result; |
| 5149 } | 5320 } |
| 5150 | 5321 |
| 5151 // Get identity matrix | |
| 5152 static Matrix rlMatrixIdentity(void) | |
| 5153 { | |
| 5154 Matrix result = { | |
| 5155 1.0f, 0.0f, 0.0f, 0.0f, | |
| 5156 0.0f, 1.0f, 0.0f, 0.0f, | |
| 5157 0.0f, 0.0f, 1.0f, 0.0f, | |
| 5158 0.0f, 0.0f, 0.0f, 1.0f | |
| 5159 }; | |
| 5160 | |
| 5161 return result; | |
| 5162 } | |
| 5163 | |
| 5164 // Get two matrix multiplication | 5322 // Get two matrix multiplication |
| 5165 // NOTE: When multiplying matrices... the order matters! | 5323 // NOTE: When multiplying matrices... the order matters! |
| 5166 static Matrix rlMatrixMultiply(Matrix left, Matrix right) | 5324 static Matrix rlMatrixMultiply(Matrix left, Matrix right) |
| 5167 { | 5325 { |
| 5168 Matrix result = { 0 }; | 5326 Matrix result = { 0 }; |
| 5256 result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; | 5414 result.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet; |
| 5257 result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; | 5415 result.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet; |
| 5258 | 5416 |
| 5259 return result; | 5417 return result; |
| 5260 } | 5418 } |
| 5261 | 5419 #endif |
| 5262 #endif // RLGL_IMPLEMENTATION | 5420 |
| 5421 #endif // RLGL_IMPLEMENTATION |