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