Wise&mystical  1.0
Project about Europe
Loading...
Searching...
No Matches
rlgl.h
Go to the documentation of this file.
1
107#ifndef RLGL_H
108#define RLGL_H
109
110#define RLGL_VERSION "4.0"
111
112// Function specifiers in case library is build/used as a shared library (Windows)
113// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
114#if defined(_WIN32)
115 #if defined(BUILD_LIBTYPE_SHARED)
116 #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
117 #elif defined(USE_LIBTYPE_SHARED)
118 #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
119 #endif
120#endif
121
122// Function specifiers definition
123#ifndef RLAPI
124 #define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
125#endif
126
127// Support TRACELOG macros
128#ifndef TRACELOG
129 #define TRACELOG(level, ...) (void)0
130 #define TRACELOGD(...) (void)0
131#endif
132
133// Allow custom memory allocators
134#ifndef RL_MALLOC
135 #define RL_MALLOC(sz) malloc(sz)
136#endif
137#ifndef RL_CALLOC
138 #define RL_CALLOC(n,sz) calloc(n,sz)
139#endif
140#ifndef RL_REALLOC
141 #define RL_REALLOC(n,sz) realloc(n,sz)
142#endif
143#ifndef RL_FREE
144 #define RL_FREE(p) free(p)
145#endif
146
147// Security check in case no GRAPHICS_API_OPENGL_* defined
148#if !defined(GRAPHICS_API_OPENGL_11) && \
149 !defined(GRAPHICS_API_OPENGL_21) && \
150 !defined(GRAPHICS_API_OPENGL_33) && \
151 !defined(GRAPHICS_API_OPENGL_43) && \
152 !defined(GRAPHICS_API_OPENGL_ES2)
153 #define GRAPHICS_API_OPENGL_33
154#endif
155
156// Security check in case multiple GRAPHICS_API_OPENGL_* defined
157#if defined(GRAPHICS_API_OPENGL_11)
158 #if defined(GRAPHICS_API_OPENGL_21)
159 #undef GRAPHICS_API_OPENGL_21
160 #endif
161 #if defined(GRAPHICS_API_OPENGL_33)
162 #undef GRAPHICS_API_OPENGL_33
163 #endif
164 #if defined(GRAPHICS_API_OPENGL_43)
165 #undef GRAPHICS_API_OPENGL_43
166 #endif
167 #if defined(GRAPHICS_API_OPENGL_ES2)
168 #undef GRAPHICS_API_OPENGL_ES2
169 #endif
170#endif
171
172// OpenGL 2.1 uses most of OpenGL 3.3 Core functionality
173// WARNING: Specific parts are checked with #if defines
174#if defined(GRAPHICS_API_OPENGL_21)
175 #define GRAPHICS_API_OPENGL_33
176#endif
177
178// OpenGL 4.3 uses OpenGL 3.3 Core functionality
179#if defined(GRAPHICS_API_OPENGL_43)
180 #define GRAPHICS_API_OPENGL_33
181#endif
182
183// Support framebuffer objects by default
184// NOTE: Some driver implementation do not support it, despite they should
185#define RLGL_RENDER_TEXTURES_HINT
186
187//----------------------------------------------------------------------------------
188// Defines and Macros
189//----------------------------------------------------------------------------------
190
191// Default internal render batch elements limits
192#ifndef RL_DEFAULT_BATCH_BUFFER_ELEMENTS
193 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
194 // This is the maximum amount of elements (quads) per batch
195 // NOTE: Be careful with text, every letter maps to a quad
196 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192
197 #endif
198 #if defined(GRAPHICS_API_OPENGL_ES2)
199 // We reduce memory sizes for embedded systems (RPI and HTML5)
200 // NOTE: On HTML5 (emscripten) this is allocated on heap,
201 // by default it's only 16MB!...just take care...
202 #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 2048
203 #endif
204#endif
205#ifndef RL_DEFAULT_BATCH_BUFFERS
206 #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
207#endif
208#ifndef RL_DEFAULT_BATCH_DRAWCALLS
209 #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
210#endif
211#ifndef RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS
212 #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture())
213#endif
214
215// Internal Matrix stack
216#ifndef RL_MAX_MATRIX_STACK_SIZE
217 #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of Matrix stack
218#endif
219
220// Shader limits
221#ifndef RL_MAX_SHADER_LOCATIONS
222 #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
223#endif
224
225// Projection matrix culling
226#ifndef RL_CULL_DISTANCE_NEAR
227 #define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance
228#endif
229#ifndef RL_CULL_DISTANCE_FAR
230 #define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance
231#endif
232
233// Texture parameters (equivalent to OpenGL defines)
234#define RL_TEXTURE_WRAP_S 0x2802 // GL_TEXTURE_WRAP_S
235#define RL_TEXTURE_WRAP_T 0x2803 // GL_TEXTURE_WRAP_T
236#define RL_TEXTURE_MAG_FILTER 0x2800 // GL_TEXTURE_MAG_FILTER
237#define RL_TEXTURE_MIN_FILTER 0x2801 // GL_TEXTURE_MIN_FILTER
238
239#define RL_TEXTURE_FILTER_NEAREST 0x2600 // GL_NEAREST
240#define RL_TEXTURE_FILTER_LINEAR 0x2601 // GL_LINEAR
241#define RL_TEXTURE_FILTER_MIP_NEAREST 0x2700 // GL_NEAREST_MIPMAP_NEAREST
242#define RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x2702 // GL_NEAREST_MIPMAP_LINEAR
243#define RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x2701 // GL_LINEAR_MIPMAP_NEAREST
244#define RL_TEXTURE_FILTER_MIP_LINEAR 0x2703 // GL_LINEAR_MIPMAP_LINEAR
245#define RL_TEXTURE_FILTER_ANISOTROPIC 0x3000 // Anisotropic filter (custom identifier)
246
247#define RL_TEXTURE_WRAP_REPEAT 0x2901 // GL_REPEAT
248#define RL_TEXTURE_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE
249#define RL_TEXTURE_WRAP_MIRROR_REPEAT 0x8370 // GL_MIRRORED_REPEAT
250#define RL_TEXTURE_WRAP_MIRROR_CLAMP 0x8742 // GL_MIRROR_CLAMP_EXT
251
252// Matrix modes (equivalent to OpenGL)
253#define RL_MODELVIEW 0x1700 // GL_MODELVIEW
254#define RL_PROJECTION 0x1701 // GL_PROJECTION
255#define RL_TEXTURE 0x1702 // GL_TEXTURE
256
257// Primitive assembly draw modes
258#define RL_LINES 0x0001 // GL_LINES
259#define RL_TRIANGLES 0x0004 // GL_TRIANGLES
260#define RL_QUADS 0x0007 // GL_QUADS
261
262// GL equivalent data types
263#define RL_UNSIGNED_BYTE 0x1401 // GL_UNSIGNED_BYTE
264#define RL_FLOAT 0x1406 // GL_FLOAT
265
266// Buffer usage hint
267#define RL_STREAM_DRAW 0x88E0 // GL_STREAM_DRAW
268#define RL_STREAM_READ 0x88E1 // GL_STREAM_READ
269#define RL_STREAM_COPY 0x88E2 // GL_STREAM_COPY
270#define RL_STATIC_DRAW 0x88E4 // GL_STATIC_DRAW
271#define RL_STATIC_READ 0x88E5 // GL_STATIC_READ
272#define RL_STATIC_COPY 0x88E6 // GL_STATIC_COPY
273#define RL_DYNAMIC_DRAW 0x88E8 // GL_DYNAMIC_DRAW
274#define RL_DYNAMIC_READ 0x88E9 // GL_DYNAMIC_READ
275#define RL_DYNAMIC_COPY 0x88EA // GL_DYNAMIC_COPY
276
277// GL Shader type
278#define RL_FRAGMENT_SHADER 0x8B30 // GL_FRAGMENT_SHADER
279#define RL_VERTEX_SHADER 0x8B31 // GL_VERTEX_SHADER
280#define RL_COMPUTE_SHADER 0x91B9 // GL_COMPUTE_SHADER
281
282//----------------------------------------------------------------------------------
283// Types and Structures Definition
284//----------------------------------------------------------------------------------
285typedef enum {
292
293typedef enum {
305
306typedef enum {
316
317// Dynamic vertex buffers (position + texcoords + colors + indices arrays)
318typedef struct rlVertexBuffer {
319 int elementCount; // Number of elements in the buffer (QUADS)
320
321 float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
322 float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
323 unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
324#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
325 unsigned int *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad)
326#endif
327#if defined(GRAPHICS_API_OPENGL_ES2)
328 unsigned short *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad)
329#endif
330 unsigned int vaoId; // OpenGL Vertex Array Object id
331 unsigned int vboId[4]; // OpenGL Vertex Buffer Objects id (4 types of vertex data)
333
334// Draw call type
335// NOTE: Only texture changes register a new draw, other state-change-related elements are not
336// used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any
337// of those state-change happens (this is done in core module)
338typedef struct rlDrawCall {
339 int mode; // Drawing mode: LINES, TRIANGLES, QUADS
340 int vertexCount; // Number of vertex of the draw
341 int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES)
342 //unsigned int vaoId; // Vertex array id to be used on the draw -> Using RLGL.currentBatch->vertexBuffer.vaoId
343 //unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId
344 unsigned int textureId; // Texture id to be used on the draw -> Use to create new draw call if changes
345
346 //Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default
347 //Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default
349
350// rlRenderBatch type
351typedef struct rlRenderBatch {
352 int bufferCount; // Number of vertex buffers (multi-buffering support)
353 int currentBuffer; // Current buffer tracking in case of multi-buffering
354 rlVertexBuffer *vertexBuffer; // Dynamic buffer(s) for vertex data
355
356 rlDrawCall *draws; // Draw calls array, depends on textureId
357 int drawCounter; // Draw calls counter
358 float currentDepth; // Current depth value for next draw
360
361#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
362 #include <stdbool.h>
363#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
364 // Boolean type
365 typedef enum bool { false, true } bool;
366#endif
367
368#if !defined(RL_MATRIX_TYPE)
369// Matrix, 4x4 components, column major, OpenGL style, right handed
370typedef struct Matrix {
371 float m0, m4, m8, m12; // Matrix first row (4 components)
372 float m1, m5, m9, m13; // Matrix second row (4 components)
373 float m2, m6, m10, m14; // Matrix third row (4 components)
374 float m3, m7, m11, m15; // Matrix fourth row (4 components)
376#define RL_MATRIX_TYPE
377#endif
378
379// Trace log level
380// NOTE: Organized by priority level
381typedef enum {
382 RL_LOG_ALL = 0, // Display all logs
383 RL_LOG_TRACE, // Trace logging, intended for internal use only
384 RL_LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds
385 RL_LOG_INFO, // Info logging, used for program execution info
386 RL_LOG_WARNING, // Warning logging, used on recoverable failures
387 RL_LOG_ERROR, // Error logging, used on unrecoverable failures
388 RL_LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE)
389 RL_LOG_NONE // Disable logging
391
392// Texture formats (support depends on OpenGL version)
393typedef enum {
394 RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
401 RL_PIXELFORMAT_UNCOMPRESSED_R32, // 32 bpp (1 channel - float)
402 RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float)
403 RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float)
416
417// Texture parameters: filter mode
418// NOTE 1: Filtering considers mipmaps if available in the texture
419// NOTE 2: Filter is accordingly set for minification and magnification
420typedef enum {
421 RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation
422 RL_TEXTURE_FILTER_BILINEAR, // Linear filtering
423 RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
424 RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
425 RL_TEXTURE_FILTER_ANISOTROPIC_8X, // Anisotropic filtering 8x
426 RL_TEXTURE_FILTER_ANISOTROPIC_16X, // Anisotropic filtering 16x
428
429// Color blending modes (pre-defined)
430typedef enum {
431 RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default)
432 RL_BLEND_ADDITIVE, // Blend textures adding colors
433 RL_BLEND_MULTIPLIED, // Blend textures multiplying colors
434 RL_BLEND_ADD_COLORS, // Blend textures adding colors (alternative)
435 RL_BLEND_SUBTRACT_COLORS, // Blend textures subtracting colors (alternative)
436 RL_BLEND_ALPHA_PREMUL, // Blend premultiplied textures considering alpha
437 RL_BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendFactors())
439
440// Shader location point type
441typedef enum {
442 RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position
443 RL_SHADER_LOC_VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01
444 RL_SHADER_LOC_VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02
445 RL_SHADER_LOC_VERTEX_NORMAL, // Shader location: vertex attribute: normal
446 RL_SHADER_LOC_VERTEX_TANGENT, // Shader location: vertex attribute: tangent
447 RL_SHADER_LOC_VERTEX_COLOR, // Shader location: vertex attribute: color
448 RL_SHADER_LOC_MATRIX_MVP, // Shader location: matrix uniform: model-view-projection
449 RL_SHADER_LOC_MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform)
450 RL_SHADER_LOC_MATRIX_PROJECTION, // Shader location: matrix uniform: projection
451 RL_SHADER_LOC_MATRIX_MODEL, // Shader location: matrix uniform: model (transform)
452 RL_SHADER_LOC_MATRIX_NORMAL, // Shader location: matrix uniform: normal
453 RL_SHADER_LOC_VECTOR_VIEW, // Shader location: vector uniform: view
454 RL_SHADER_LOC_COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color
455 RL_SHADER_LOC_COLOR_SPECULAR, // Shader location: vector uniform: specular color
456 RL_SHADER_LOC_COLOR_AMBIENT, // Shader location: vector uniform: ambient color
457 RL_SHADER_LOC_MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE)
458 RL_SHADER_LOC_MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR)
459 RL_SHADER_LOC_MAP_NORMAL, // Shader location: sampler2d texture: normal
460 RL_SHADER_LOC_MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness
461 RL_SHADER_LOC_MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion
462 RL_SHADER_LOC_MAP_EMISSION, // Shader location: sampler2d texture: emission
463 RL_SHADER_LOC_MAP_HEIGHT, // Shader location: sampler2d texture: height
464 RL_SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
465 RL_SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
466 RL_SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
467 RL_SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf
469
470#define RL_SHADER_LOC_MAP_DIFFUSE RL_SHADER_LOC_MAP_ALBEDO
471#define RL_SHADER_LOC_MAP_SPECULAR RL_SHADER_LOC_MAP_METALNESS
472
473// Shader uniform data type
474typedef enum {
475 RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float
476 RL_SHADER_UNIFORM_VEC2, // Shader uniform type: vec2 (2 float)
477 RL_SHADER_UNIFORM_VEC3, // Shader uniform type: vec3 (3 float)
478 RL_SHADER_UNIFORM_VEC4, // Shader uniform type: vec4 (4 float)
479 RL_SHADER_UNIFORM_INT, // Shader uniform type: int
480 RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
481 RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
482 RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
483 RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
485
486// Shader attribute data types
487typedef enum {
488 RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float
489 RL_SHADER_ATTRIB_VEC2, // Shader attribute type: vec2 (2 float)
490 RL_SHADER_ATTRIB_VEC3, // Shader attribute type: vec3 (3 float)
491 RL_SHADER_ATTRIB_VEC4 // Shader attribute type: vec4 (4 float)
493
494//------------------------------------------------------------------------------------
495// Functions Declaration - Matrix operations
496//------------------------------------------------------------------------------------
497
498#if defined(__cplusplus)
499extern "C" { // Prevents name mangling of functions
500#endif
501
502RLAPI void rlMatrixMode(int mode); // Choose the current matrix to be transformed
503RLAPI void rlPushMatrix(void); // Push the current matrix to stack
504RLAPI void rlPopMatrix(void); // Pop lattest inserted matrix from stack
505RLAPI void rlLoadIdentity(void); // Reset current matrix to identity matrix
506RLAPI void rlTranslatef(float x, float y, float z); // Multiply the current matrix by a translation matrix
507RLAPI void rlRotatef(float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix
508RLAPI void rlScalef(float x, float y, float z); // Multiply the current matrix by a scaling matrix
509RLAPI void rlMultMatrixf(float *matf); // Multiply the current matrix by another matrix
510RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar);
511RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar);
512RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area
513
514//------------------------------------------------------------------------------------
515// Functions Declaration - Vertex level operations
516//------------------------------------------------------------------------------------
517RLAPI void rlBegin(int mode); // Initialize drawing mode (how to organize vertex)
518RLAPI void rlEnd(void); // Finish vertex providing
519RLAPI void rlVertex2i(int x, int y); // Define one vertex (position) - 2 int
520RLAPI void rlVertex2f(float x, float y); // Define one vertex (position) - 2 float
521RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float
522RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float
523RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float
524RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte
525RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float
526RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float
527
528//------------------------------------------------------------------------------------
529// Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2)
530// NOTE: This functions are used to completely abstract raylib code from OpenGL layer,
531// some of them are direct wrappers over OpenGL calls, some others are custom
532//------------------------------------------------------------------------------------
533
534// Vertex buffers state
535RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array (VAO, if supported)
536RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported)
537RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO)
538RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO)
539RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element)
540RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element)
541RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index
542RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index
543#if defined(GRAPHICS_API_OPENGL_11)
544RLAPI void rlEnableStatePointer(int vertexAttribType, void *buffer); // Enable attribute state pointer
545RLAPI void rlDisableStatePointer(int vertexAttribType); // Disable attribute state pointer
546#endif
547
548// Textures state
549RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot
550RLAPI void rlEnableTexture(unsigned int id); // Enable texture
551RLAPI void rlDisableTexture(void); // Disable texture
552RLAPI void rlEnableTextureCubemap(unsigned int id); // Enable texture cubemap
553RLAPI void rlDisableTextureCubemap(void); // Disable texture cubemap
554RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
555
556// Shader state
557RLAPI void rlEnableShader(unsigned int id); // Enable shader program
558RLAPI void rlDisableShader(void); // Disable shader program
559
560// Framebuffer state
561RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo)
562RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer
563RLAPI void rlActiveDrawBuffers(int count); // Activate multiple draw color buffers
564
565// General render state
566RLAPI void rlEnableColorBlend(void); // Enable color blending
567RLAPI void rlDisableColorBlend(void); // Disable color blending
568RLAPI void rlEnableDepthTest(void); // Enable depth test
569RLAPI void rlDisableDepthTest(void); // Disable depth test
570RLAPI void rlEnableDepthMask(void); // Enable depth write
571RLAPI void rlDisableDepthMask(void); // Disable depth write
572RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
573RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling
574RLAPI void rlEnableScissorTest(void); // Enable scissor test
575RLAPI void rlDisableScissorTest(void); // Disable scissor test
576RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
577RLAPI void rlEnableWireMode(void); // Enable wire mode
578RLAPI void rlDisableWireMode(void); // Disable wire mode
579RLAPI void rlSetLineWidth(float width); // Set the line drawing width
580RLAPI float rlGetLineWidth(void); // Get the line drawing width
581RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
582RLAPI void rlDisableSmoothLines(void); // Disable line aliasing
583RLAPI void rlEnableStereoRender(void); // Enable stereo rendering
584RLAPI void rlDisableStereoRender(void); // Disable stereo rendering
585RLAPI bool rlIsStereoRenderEnabled(void); // Check if stereo render is enabled
586
587RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color
588RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
589RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
590RLAPI void rlSetBlendMode(int mode); // Set blending mode
591RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors)
592
593//------------------------------------------------------------------------------------
594// Functions Declaration - rlgl functionality
595//------------------------------------------------------------------------------------
596// rlgl initialization functions
597RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
598RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
599RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
600RLAPI int rlGetVersion(void); // Get current OpenGL version
601RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
602RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
603RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height
604RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height
605
606RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
607RLAPI unsigned int rlGetShaderIdDefault(void); // Get default shader id
608RLAPI int *rlGetShaderLocsDefault(void); // Get default shader locations
609
610// Render batch management
611// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode
612// but this render batch API is exposed in case of custom batches are required
613RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system
614RLAPI void rlUnloadRenderBatch(rlRenderBatch batch); // Unload render batch system
615RLAPI void rlDrawRenderBatch(rlRenderBatch *batch); // Draw render batch data (Update->Draw->Reset)
616RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal)
617RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch
618RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex
619RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits
620
621//------------------------------------------------------------------------------------------------------------------------
622
623// Vertex buffers management
624RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported
625RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic); // Load a vertex buffer attribute
626RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic); // Load a new attributes element buffer
627RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset); // Update GPU buffer with new data
628RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset); // Update vertex buffer elements with new data
629RLAPI void rlUnloadVertexArray(unsigned int vaoId);
630RLAPI void rlUnloadVertexBuffer(unsigned int vboId);
631RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer);
632RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor);
633RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value
634RLAPI void rlDrawVertexArray(int offset, int count);
635RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer);
636RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances);
637RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances);
638
639// Textures management
640RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
641RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
642RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap
643RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data
644RLAPI void rlGetGlTextureFormats(int format, int *glInternalFormat, int *glFormat, int *glType); // Get OpenGL internal formats
645RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format
646RLAPI void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory
647RLAPI void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps); // Generate mipmap data for selected texture
648RLAPI void *rlReadTexturePixels(unsigned int id, int width, int height, int format); // Read texture pixel data
649RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
650
651// Framebuffer management (fbo)
652RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer
653RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer
654RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete
655RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU
656
657// Shaders management
658RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings
659RLAPI 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)
660RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program
661RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program
662RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform
663RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
664RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
665RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
666RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler
667RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations)
668
669// Compute shader management
670RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId); // Load compute shader program
671RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pilepine)
672
673// Shader buffer storage object management (ssbo)
674RLAPI unsigned int rlLoadShaderBuffer(unsigned long long size, const void *data, int usageHint); // Load shader storage buffer object (SSBO)
675RLAPI void rlUnloadShaderBuffer(unsigned int ssboId); // Unload shader storage buffer object (SSBO)
676RLAPI void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned long long dataSize, unsigned long long offset); // Update SSBO buffer data
677RLAPI unsigned long long rlGetShaderBufferSize(unsigned int id); // Get SSBO buffer size
678RLAPI void rlReadShaderBufferElements(unsigned int id, void *dest, unsigned long long count, unsigned long long offset); // Bind SSBO buffer
679RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index); // Copy SSBO buffer data
680
681// Buffer management
682RLAPI void rlCopyBuffersElements(unsigned int destId, unsigned int srcId, unsigned long long destOffset, unsigned long long srcOffset, unsigned long long count); // Copy SSBO buffer data
683RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly); // Bind image texture
684
685// Matrix state management
686RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix
687RLAPI Matrix rlGetMatrixProjection(void); // Get internal projection matrix
688RLAPI Matrix rlGetMatrixTransform(void); // Get internal accumulated transform matrix
689RLAPI Matrix rlGetMatrixProjectionStereo(int eye); // Get internal projection matrix for stereo render (selected eye)
690RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye); // Get internal view offset matrix for stereo render (selected eye)
691RLAPI void rlSetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
692RLAPI void rlSetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
693RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering
694RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left); // Set eyes view offsets matrices for stereo rendering
695
696// Quick and dirty cube/quad buffers load->draw->unload
697RLAPI void rlLoadDrawCube(void); // Load and draw a cube
698RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
699
700#if defined(__cplusplus)
701}
702#endif
703
704#endif // RLGL_H
705
706
712#if defined(RLGL_IMPLEMENTATION)
713
714#if defined(GRAPHICS_API_OPENGL_11)
715 #if defined(__APPLE__)
716 #include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
717 #include <OpenGL/glext.h> // OpenGL extensions library
718 #else
719 // APIENTRY for OpenGL function pointer declarations is required
720 #ifndef APIENTRY
721 #if defined(_WIN32)
722 #define APIENTRY __stdcall
723 #else
724 #define APIENTRY
725 #endif
726 #endif
727 // WINGDIAPI definition. Some Windows OpenGL headers need it
728 #if !defined(WINGDIAPI) && defined(_WIN32)
729 #define WINGDIAPI __declspec(dllimport)
730 #endif
731
732 #include <GL/gl.h> // OpenGL 1.1 library
733 #endif
734#endif
735
736#if defined(GRAPHICS_API_OPENGL_33)
737 #if defined(__APPLE__)
738 #include <OpenGL/gl3.h> // OpenGL 3 library for OSX
739 #include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
740 #else
741 #define GLAD_MALLOC RL_MALLOC
742 #define GLAD_FREE RL_FREE
743
744 #define GLAD_GL_IMPLEMENTATION
745 #include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
746 #endif
747#endif
748
749#if defined(GRAPHICS_API_OPENGL_ES2)
750 #define GL_GLEXT_PROTOTYPES
751 //#include <EGL/egl.h> // EGL library -> not required, platform layer
752 #include <GLES2/gl2.h> // OpenGL ES 2.0 library
753 #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
754
755 // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi
756 // provided headers (despite being defined in official Khronos GLES2 headers)
757 #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
758 typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
759 typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
760 typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor);
761 #endif
762#endif
763
764#include <stdlib.h> // Required for: malloc(), free()
765#include <string.h> // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading]
766#include <math.h> // Required for: sqrtf(), sinf(), cosf(), floor(), log()
767
768//----------------------------------------------------------------------------------
769// Defines and Macros
770//----------------------------------------------------------------------------------
771#ifndef PI
772 #define PI 3.14159265358979323846f
773#endif
774#ifndef DEG2RAD
775 #define DEG2RAD (PI/180.0f)
776#endif
777#ifndef RAD2DEG
778 #define RAD2DEG (180.0f/PI)
779#endif
780
781#ifndef GL_SHADING_LANGUAGE_VERSION
782 #define GL_SHADING_LANGUAGE_VERSION 0x8B8C
783#endif
784
785#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
786 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
787#endif
788#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
789 #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
790#endif
791#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
792 #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
793#endif
794#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
795 #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
796#endif
797#ifndef GL_ETC1_RGB8_OES
798 #define GL_ETC1_RGB8_OES 0x8D64
799#endif
800#ifndef GL_COMPRESSED_RGB8_ETC2
801 #define GL_COMPRESSED_RGB8_ETC2 0x9274
802#endif
803#ifndef GL_COMPRESSED_RGBA8_ETC2_EAC
804 #define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
805#endif
806#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG
807 #define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
808#endif
809#ifndef GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
810 #define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
811#endif
812#ifndef GL_COMPRESSED_RGBA_ASTC_4x4_KHR
813 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0
814#endif
815#ifndef GL_COMPRESSED_RGBA_ASTC_8x8_KHR
816 #define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
817#endif
818
819#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
820 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
821#endif
822#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT
823 #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
824#endif
825
826#if defined(GRAPHICS_API_OPENGL_11)
827 #define GL_UNSIGNED_SHORT_5_6_5 0x8363
828 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
829 #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
830#endif
831
832#if defined(GRAPHICS_API_OPENGL_21)
833 #define GL_LUMINANCE 0x1909
834 #define GL_LUMINANCE_ALPHA 0x190A
835#endif
836
837#if defined(GRAPHICS_API_OPENGL_ES2)
838 #define glClearDepth glClearDepthf
839 #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER
840 #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER
841#endif
842
843// Default shader vertex attribute names to set location points
844#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION
845 #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Binded by default to shader location: 0
846#endif
847#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD
848 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Binded by default to shader location: 1
849#endif
850#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL
851 #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Binded by default to shader location: 2
852#endif
853#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR
854 #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Binded by default to shader location: 3
855#endif
856#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT
857 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Binded by default to shader location: 4
858#endif
859#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
860 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Binded by default to shader location: 5
861#endif
862
863#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
864 #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
865#endif
866#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW
867 #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
868#endif
869#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION
870 #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
871#endif
872#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL
873 #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
874#endif
875#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL
876 #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
877#endif
878#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
879 #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
880#endif
881#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
882 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
883#endif
884#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1
885 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
886#endif
887#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2
888 #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
889#endif
890
891//----------------------------------------------------------------------------------
892// Types and Structures Definition
893//----------------------------------------------------------------------------------
894#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
895typedef struct rlglData {
896 rlRenderBatch *currentBatch; // Current render batch
897 rlRenderBatch defaultBatch; // Default internal render batch
898
899 struct {
900 int vertexCounter; // Current active render batch vertex counter (generic, used for all batches)
901 float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*())
902 float normalx, normaly, normalz; // Current active normal (added on glVertex*())
903 unsigned char colorr, colorg, colorb, colora; // Current active color (added on glVertex*())
904
905 int currentMatrixMode; // Current matrix mode
906 Matrix *currentMatrix; // Current matrix pointer
907 Matrix modelview; // Default modelview matrix
908 Matrix projection; // Default projection matrix
909 Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale
910 bool transformRequired; // Require transform matrix application to current draw-call vertex (if required)
911 Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop
912 int stackCounter; // Matrix stack counter
913
914 unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader)
915 unsigned int activeTextureId[RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS]; // Active texture ids to be enabled on batch drawing (0 active by default)
916 unsigned int defaultVShaderId; // Default vertex shader id (used by default shader program)
917 unsigned int defaultFShaderId; // Default fragment shader id (used by default shader program)
918 unsigned int defaultShaderId; // Default shader program id, supports vertex color and diffuse texture
919 int *defaultShaderLocs; // Default shader locations pointer to be used on rendering
920 unsigned int currentShaderId; // Current shader id to be used on rendering (by default, defaultShaderId)
921 int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs)
922
923 bool stereoRender; // Stereo rendering flag
924 Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
925 Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices
926
927 int currentBlendMode; // Blending mode active
928 int glBlendSrcFactor; // Blending source factor
929 int glBlendDstFactor; // Blending destination factor
930 int glBlendEquation; // Blending equation
931
932 int framebufferWidth; // Current framebuffer width
933 int framebufferHeight; // Current framebuffer height
934
935 } State; // Renderer state
936 struct {
937 bool vao; // VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object)
938 bool instancing; // Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays)
939 bool texNPOT; // NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot)
940 bool texDepth; // Depth textures supported (GL_ARB_depth_texture, GL_WEBGL_depth_texture, GL_OES_depth_texture)
941 bool texFloat32; // float textures support (32 bit per channel) (GL_OES_texture_float)
942 bool texCompDXT; // DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, GL_WEBKIT_WEBGL_compressed_texture_s3tc)
943 bool texCompETC1; // ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1)
944 bool texCompETC2; // ETC2/EAC texture compression support (GL_ARB_ES3_compatibility)
945 bool texCompPVRT; // PVR texture compression support (GL_IMG_texture_compression_pvrtc)
946 bool texCompASTC; // ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr)
947 bool texMirrorClamp; // Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp)
948 bool texAnisoFilter; // Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic)
949 bool computeShader; // Compute shaders support (GL_ARB_compute_shader)
950 bool ssbo; // Shader storage buffer object support (GL_ARB_shader_storage_buffer_object)
951
952 float maxAnisotropyLevel; // Maximum anisotropy level supported (minimum is 2.0f)
953 int maxDepthBits; // Maximum bits for depth component
954
955 } ExtSupported; // Extensions supported flags
956} rlglData;
957
958typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
959
960#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
961
962//----------------------------------------------------------------------------------
963// Global Variables Definition
964//----------------------------------------------------------------------------------
965#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
966static rlglData RLGL = { 0 };
967#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
968
969#if defined(GRAPHICS_API_OPENGL_ES2)
970// NOTE: VAO functionality is exposed through extensions (OES)
971static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
972static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
973static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
974
975// NOTE: Instancing functionality could also be available through extension
976static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL;
977static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL;
978static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL;
979#endif
980
981//----------------------------------------------------------------------------------
982// Module specific Functions Declaration
983//----------------------------------------------------------------------------------
984#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
985static void rlLoadShaderDefault(void); // Load default shader
986static void rlUnloadShaderDefault(void); // Unload default shader
987#if defined(RLGL_SHOW_GL_DETAILS_INFO)
988static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
989#endif // RLGL_SHOW_GL_DETAILS_INFO
990#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
991#if defined(GRAPHICS_API_OPENGL_11)
992static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
993static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
994#endif
995static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
996// Auxiliar matrix math functions
997static Matrix rlMatrixIdentity(void); // Get identity matrix
998static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices
999
1000//----------------------------------------------------------------------------------
1001// Module Functions Definition - Matrix operations
1002//----------------------------------------------------------------------------------
1003
1004#if defined(GRAPHICS_API_OPENGL_11)
1005// Fallback to OpenGL 1.1 function calls
1006//---------------------------------------
1007void rlMatrixMode(int mode)
1008{
1009 switch (mode)
1010 {
1013 case RL_TEXTURE: glMatrixMode(GL_TEXTURE); break;
1014 default: break;
1015 }
1016}
1017
1018void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
1019{
1020 glFrustum(left, right, bottom, top, znear, zfar);
1021}
1022
1023void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
1024{
1025 glOrtho(left, right, bottom, top, znear, zfar);
1026}
1027
1028void rlPushMatrix(void) { glPushMatrix(); }
1029void rlPopMatrix(void) { glPopMatrix(); }
1030void rlLoadIdentity(void) { glLoadIdentity(); }
1031void rlTranslatef(float x, float y, float z) { glTranslatef(x, y, z); }
1032void rlRotatef(float angle, float x, float y, float z) { glRotatef(angle, x, y, z); }
1033void rlScalef(float x, float y, float z) { glScalef(x, y, z); }
1034void rlMultMatrixf(float *matf) { glMultMatrixf(matf); }
1035#endif
1036#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1037// Choose the current matrix to be transformed
1038void rlMatrixMode(int mode)
1039{
1040 if (mode == RL_PROJECTION) RLGL.State.currentMatrix = &RLGL.State.projection;
1041 else if (mode == RL_MODELVIEW) RLGL.State.currentMatrix = &RLGL.State.modelview;
1042 //else if (mode == RL_TEXTURE) // Not supported
1043
1044 RLGL.State.currentMatrixMode = mode;
1045}
1046
1047// Push the current matrix into RLGL.State.stack
1048void rlPushMatrix(void)
1049{
1050 if (RLGL.State.stackCounter >= RL_MAX_MATRIX_STACK_SIZE) TRACELOG(RL_LOG_ERROR, "RLGL: Matrix stack overflow (RL_MAX_MATRIX_STACK_SIZE)");
1051
1052 if (RLGL.State.currentMatrixMode == RL_MODELVIEW)
1053 {
1054 RLGL.State.transformRequired = true;
1055 RLGL.State.currentMatrix = &RLGL.State.transform;
1056 }
1057
1058 RLGL.State.stack[RLGL.State.stackCounter] = *RLGL.State.currentMatrix;
1059 RLGL.State.stackCounter++;
1060}
1061
1062// Pop lattest inserted matrix from RLGL.State.stack
1063void rlPopMatrix(void)
1064{
1065 if (RLGL.State.stackCounter > 0)
1066 {
1067 Matrix mat = RLGL.State.stack[RLGL.State.stackCounter - 1];
1068 *RLGL.State.currentMatrix = mat;
1069 RLGL.State.stackCounter--;
1070 }
1071
1072 if ((RLGL.State.stackCounter == 0) && (RLGL.State.currentMatrixMode == RL_MODELVIEW))
1073 {
1074 RLGL.State.currentMatrix = &RLGL.State.modelview;
1075 RLGL.State.transformRequired = false;
1076 }
1077}
1078
1079// Reset current matrix to identity matrix
1080void rlLoadIdentity(void)
1081{
1082 *RLGL.State.currentMatrix = rlMatrixIdentity();
1083}
1084
1085// Multiply the current matrix by a translation matrix
1086void rlTranslatef(float x, float y, float z)
1087{
1088 Matrix matTranslation = {
1089 1.0f, 0.0f, 0.0f, x,
1090 0.0f, 1.0f, 0.0f, y,
1091 0.0f, 0.0f, 1.0f, z,
1092 0.0f, 0.0f, 0.0f, 1.0f
1093 };
1094
1095 // NOTE: We transpose matrix with multiplication order
1096 *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix);
1097}
1098
1099// Multiply the current matrix by a rotation matrix
1100// NOTE: The provided angle must be in degrees
1101void rlRotatef(float angle, float x, float y, float z)
1102{
1103 Matrix matRotation = rlMatrixIdentity();
1104
1105 // Axis vector (x, y, z) normalization
1106 float lengthSquared = x*x + y*y + z*z;
1107 if ((lengthSquared != 1.0f) && (lengthSquared != 0.0f))
1108 {
1109 float inverseLength = 1.0f/sqrtf(lengthSquared);
1110 x *= inverseLength;
1111 y *= inverseLength;
1112 z *= inverseLength;
1113 }
1114
1115 // Rotation matrix generation
1116 float sinres = sinf(DEG2RAD*angle);
1117 float cosres = cosf(DEG2RAD*angle);
1118 float t = 1.0f - cosres;
1119
1120 matRotation.m0 = x*x*t + cosres;
1121 matRotation.m1 = y*x*t + z*sinres;
1122 matRotation.m2 = z*x*t - y*sinres;
1123 matRotation.m3 = 0.0f;
1124
1125 matRotation.m4 = x*y*t - z*sinres;
1126 matRotation.m5 = y*y*t + cosres;
1127 matRotation.m6 = z*y*t + x*sinres;
1128 matRotation.m7 = 0.0f;
1129
1130 matRotation.m8 = x*z*t + y*sinres;
1131 matRotation.m9 = y*z*t - x*sinres;
1132 matRotation.m10 = z*z*t + cosres;
1133 matRotation.m11 = 0.0f;
1134
1135 matRotation.m12 = 0.0f;
1136 matRotation.m13 = 0.0f;
1137 matRotation.m14 = 0.0f;
1138 matRotation.m15 = 1.0f;
1139
1140 // NOTE: We transpose matrix with multiplication order
1141 *RLGL.State.currentMatrix = rlMatrixMultiply(matRotation, *RLGL.State.currentMatrix);
1142}
1143
1144// Multiply the current matrix by a scaling matrix
1145void rlScalef(float x, float y, float z)
1146{
1147 Matrix matScale = {
1148 x, 0.0f, 0.0f, 0.0f,
1149 0.0f, y, 0.0f, 0.0f,
1150 0.0f, 0.0f, z, 0.0f,
1151 0.0f, 0.0f, 0.0f, 1.0f
1152 };
1153
1154 // NOTE: We transpose matrix with multiplication order
1155 *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix);
1156}
1157
1158// Multiply the current matrix by another matrix
1159void rlMultMatrixf(float *matf)
1160{
1161 // Matrix creation from array
1162 Matrix mat = { matf[0], matf[4], matf[8], matf[12],
1163 matf[1], matf[5], matf[9], matf[13],
1164 matf[2], matf[6], matf[10], matf[14],
1165 matf[3], matf[7], matf[11], matf[15] };
1166
1167 *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, mat);
1168}
1169
1170// Multiply the current matrix by a perspective matrix generated by parameters
1171void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
1172{
1173 Matrix matFrustum = { 0 };
1174
1175 float rl = (float)(right - left);
1176 float tb = (float)(top - bottom);
1177 float fn = (float)(zfar - znear);
1178
1179 matFrustum.m0 = ((float) znear*2.0f)/rl;
1180 matFrustum.m1 = 0.0f;
1181 matFrustum.m2 = 0.0f;
1182 matFrustum.m3 = 0.0f;
1183
1184 matFrustum.m4 = 0.0f;
1185 matFrustum.m5 = ((float) znear*2.0f)/tb;
1186 matFrustum.m6 = 0.0f;
1187 matFrustum.m7 = 0.0f;
1188
1189 matFrustum.m8 = ((float)right + (float)left)/rl;
1190 matFrustum.m9 = ((float)top + (float)bottom)/tb;
1191 matFrustum.m10 = -((float)zfar + (float)znear)/fn;
1192 matFrustum.m11 = -1.0f;
1193
1194 matFrustum.m12 = 0.0f;
1195 matFrustum.m13 = 0.0f;
1196 matFrustum.m14 = -((float)zfar*(float)znear*2.0f)/fn;
1197 matFrustum.m15 = 0.0f;
1198
1199 *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matFrustum);
1200}
1201
1202// Multiply the current matrix by an orthographic matrix generated by parameters
1203void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
1204{
1205 // NOTE: If left-right and top-botton values are equal it could create a division by zero,
1206 // response to it is platform/compiler dependant
1207 Matrix matOrtho = { 0 };
1208
1209 float rl = (float)(right - left);
1210 float tb = (float)(top - bottom);
1211 float fn = (float)(zfar - znear);
1212
1213 matOrtho.m0 = 2.0f/rl;
1214 matOrtho.m1 = 0.0f;
1215 matOrtho.m2 = 0.0f;
1216 matOrtho.m3 = 0.0f;
1217 matOrtho.m4 = 0.0f;
1218 matOrtho.m5 = 2.0f/tb;
1219 matOrtho.m6 = 0.0f;
1220 matOrtho.m7 = 0.0f;
1221 matOrtho.m8 = 0.0f;
1222 matOrtho.m9 = 0.0f;
1223 matOrtho.m10 = -2.0f/fn;
1224 matOrtho.m11 = 0.0f;
1225 matOrtho.m12 = -((float)left + (float)right)/rl;
1226 matOrtho.m13 = -((float)top + (float)bottom)/tb;
1227 matOrtho.m14 = -((float)zfar + (float)znear)/fn;
1228 matOrtho.m15 = 1.0f;
1229
1230 *RLGL.State.currentMatrix = rlMatrixMultiply(*RLGL.State.currentMatrix, matOrtho);
1231}
1232#endif
1233
1234// Set the viewport area (transformation from normalized device coordinates to window coordinates)
1235// NOTE: We store current viewport dimensions
1236void rlViewport(int x, int y, int width, int height)
1237{
1238 glViewport(x, y, width, height);
1239}
1240
1241//----------------------------------------------------------------------------------
1242// Module Functions Definition - Vertex level operations
1243//----------------------------------------------------------------------------------
1244#if defined(GRAPHICS_API_OPENGL_11)
1245// Fallback to OpenGL 1.1 function calls
1246//---------------------------------------
1247void rlBegin(int mode)
1248{
1249 switch (mode)
1250 {
1251 case RL_LINES: glBegin(GL_LINES); break;
1252 case RL_TRIANGLES: glBegin(GL_TRIANGLES); break;
1253 case RL_QUADS: glBegin(GL_QUADS); break;
1254 default: break;
1255 }
1256}
1257
1258void rlEnd() { glEnd(); }
1259void rlVertex2i(int x, int y) { glVertex2i(x, y); }
1260void rlVertex2f(float x, float y) { glVertex2f(x, y); }
1261void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); }
1262void rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); }
1263void rlNormal3f(float x, float y, float z) { glNormal3f(x, y, z); }
1264void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { glColor4ub(r, g, b, a); }
1265void rlColor3f(float x, float y, float z) { glColor3f(x, y, z); }
1266void rlColor4f(float x, float y, float z, float w) { glColor4f(x, y, z, w); }
1267#endif
1268#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1269// Initialize drawing mode (how to organize vertex)
1270void rlBegin(int mode)
1271{
1272 // Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS
1273 // NOTE: In all three cases, vertex are accumulated over default internal vertex buffer
1274 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode != mode)
1275 {
1276 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0)
1277 {
1278 // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
1279 // that way, following QUADS drawing will keep aligned with index processing
1280 // It implies adding some extra alignment vertex at the end of the draw,
1281 // those vertex are not processed but they are considered as an additional offset
1282 // for the next set of vertex to be drawn
1283 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4);
1284 else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4)));
1285 else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0;
1286
1287 if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
1288 {
1289 RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
1290 RLGL.currentBatch->drawCounter++;
1291 }
1292 }
1293
1294 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
1295
1296 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode;
1297 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0;
1298 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId;
1299 }
1300}
1301
1302// Finish vertex providing
1303void rlEnd(void)
1304{
1305 // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values,
1306 // as well as depth buffer bit-depth (16bit or 24bit or 32bit)
1307 // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits)
1308 RLGL.currentBatch->currentDepth += (1.0f/20000.0f);
1309
1310 // Verify internal buffers limits
1311 // NOTE: This check is combined with usage of rlCheckRenderBatchLimit()
1312 if (RLGL.State.vertexCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
1313 {
1314 // WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlDrawRenderBatch(),
1315 // we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
1316 // If we have multiple matrix pushed, it will require "RLGL.State.stackCounter" pops before launching the draw
1317 for (int i = RLGL.State.stackCounter; i >= 0; i--) rlPopMatrix();
1318 rlDrawRenderBatch(RLGL.currentBatch);
1319 }
1320}
1321
1322// Define one vertex (position)
1323// NOTE: Vertex position data is the basic information required for drawing
1324void rlVertex3f(float x, float y, float z)
1325{
1326 float tx = x;
1327 float ty = y;
1328 float tz = z;
1329
1330 // Transform provided vector if required
1331 if (RLGL.State.transformRequired)
1332 {
1333 tx = RLGL.State.transform.m0*x + RLGL.State.transform.m4*y + RLGL.State.transform.m8*z + RLGL.State.transform.m12;
1334 ty = RLGL.State.transform.m1*x + RLGL.State.transform.m5*y + RLGL.State.transform.m9*z + RLGL.State.transform.m13;
1335 tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14;
1336 }
1337
1338 // Verify that current vertex buffer elements limit has not been reached
1339 if (RLGL.State.vertexCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
1340 {
1341 // Add vertices
1342 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx;
1343 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty;
1344 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz;
1345
1346 // Add current texcoord
1347 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx;
1348 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy;
1349
1350 // TODO: Add current normal
1351 // By default rlVertexBuffer type does not store normals
1352
1353 // Add current color
1354 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr;
1355 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg;
1356 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb;
1357 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora;
1358
1359 RLGL.State.vertexCounter++;
1360
1361 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++;
1362 }
1363 else TRACELOG(RL_LOG_ERROR, "RLGL: Batch elements overflow");
1364}
1365
1366// Define one vertex (position)
1367void rlVertex2f(float x, float y)
1368{
1369 rlVertex3f(x, y, RLGL.currentBatch->currentDepth);
1370}
1371
1372// Define one vertex (position)
1373void rlVertex2i(int x, int y)
1374{
1375 rlVertex3f((float)x, (float)y, RLGL.currentBatch->currentDepth);
1376}
1377
1378// Define one vertex (texture coordinate)
1379// NOTE: Texture coordinates are limited to QUADS only
1380void rlTexCoord2f(float x, float y)
1381{
1382 RLGL.State.texcoordx = x;
1383 RLGL.State.texcoordy = y;
1384}
1385
1386// Define one vertex (normal)
1387// NOTE: Normals limited to TRIANGLES only?
1388void rlNormal3f(float x, float y, float z)
1389{
1390 RLGL.State.normalx = x;
1391 RLGL.State.normaly = y;
1392 RLGL.State.normalz = z;
1393}
1394
1395// Define one vertex (color)
1396void rlColor4ub(unsigned char x, unsigned char y, unsigned char z, unsigned char w)
1397{
1398 RLGL.State.colorr = x;
1399 RLGL.State.colorg = y;
1400 RLGL.State.colorb = z;
1401 RLGL.State.colora = w;
1402}
1403
1404// Define one vertex (color)
1405void rlColor4f(float r, float g, float b, float a)
1406{
1407 rlColor4ub((unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), (unsigned char)(a*255));
1408}
1409
1410// Define one vertex (color)
1411void rlColor3f(float x, float y, float z)
1412{
1413 rlColor4ub((unsigned char)(x*255), (unsigned char)(y*255), (unsigned char)(z*255), 255);
1414}
1415
1416#endif
1417
1418//--------------------------------------------------------------------------------------
1419// Module Functions Definition - OpenGL style functions (common to 1.1, 3.3+, ES2)
1420//--------------------------------------------------------------------------------------
1421
1422// Set current texture to use
1423void rlSetTexture(unsigned int id)
1424{
1425 if (id == 0)
1426 {
1427#if defined(GRAPHICS_API_OPENGL_11)
1429#else
1430 // NOTE: If quads batch limit is reached, we force a draw call and next batch starts
1431 if (RLGL.State.vertexCounter >=
1432 RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)
1433 {
1434 rlDrawRenderBatch(RLGL.currentBatch);
1435 }
1436#endif
1437 }
1438 else
1439 {
1440#if defined(GRAPHICS_API_OPENGL_11)
1441 rlEnableTexture(id);
1442#else
1443 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id)
1444 {
1445 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0)
1446 {
1447 // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
1448 // that way, following QUADS drawing will keep aligned with index processing
1449 // It implies adding some extra alignment vertex at the end of the draw,
1450 // those vertex are not processed but they are considered as an additional offset
1451 // for the next set of vertex to be drawn
1452 if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4);
1453 else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4)));
1454 else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0;
1455
1456 if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
1457 {
1458 RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
1459
1460 RLGL.currentBatch->drawCounter++;
1461 }
1462 }
1463
1464 if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
1465
1466 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = id;
1467 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0;
1468 }
1469#endif
1470 }
1471}
1472
1473// Select and active a texture slot
1474void rlActiveTextureSlot(int slot)
1475{
1476#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1478#endif
1479}
1480
1481// Enable texture
1482void rlEnableTexture(unsigned int id)
1483{
1484#if defined(GRAPHICS_API_OPENGL_11)
1486#endif
1488}
1489
1490// Disable texture
1491void rlDisableTexture(void)
1492{
1493#if defined(GRAPHICS_API_OPENGL_11)
1495#endif
1497}
1498
1499// Enable texture cubemap
1500void rlEnableTextureCubemap(unsigned int id)
1501{
1502#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1504#endif
1505}
1506
1507// Disable texture cubemap
1508void rlDisableTextureCubemap(void)
1509{
1510#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1512#endif
1513}
1514
1515// Set texture parameters (wrap mode/filter mode)
1516void rlTextureParameters(unsigned int id, int param, int value)
1517{
1519
1520 switch (param)
1521 {
1522 case RL_TEXTURE_WRAP_S:
1523 case RL_TEXTURE_WRAP_T:
1524 {
1525 if (value == RL_TEXTURE_WRAP_MIRROR_CLAMP)
1526 {
1527#if !defined(GRAPHICS_API_OPENGL_11)
1528 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value);
1529 else TRACELOG(RL_LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)");
1530#endif
1531 }
1532 else glTexParameteri(GL_TEXTURE_2D, param, value);
1533
1534 } break;
1536 case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break;
1538 {
1539#if !defined(GRAPHICS_API_OPENGL_11)
1540 if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
1541 else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f)
1542 {
1543 TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel);
1544 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
1545 }
1546 else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported");
1547#endif
1548 } break;
1549 default: break;
1550 }
1551
1553}
1554
1555// Enable shader program
1556void rlEnableShader(unsigned int id)
1557{
1558#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
1559 glUseProgram(id);
1560#endif
1561}
1562
1563// Disable shader program
1564void rlDisableShader(void)
1565{
1566#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
1567 glUseProgram(0);
1568#endif
1569}
1570
1571// Enable rendering to texture (fbo)
1572void rlEnableFramebuffer(unsigned int id)
1573{
1574#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
1576#endif
1577}
1578
1579// Disable rendering to texture
1580void rlDisableFramebuffer(void)
1581{
1582#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
1584#endif
1585}
1586
1587// Activate multiple draw color buffers
1588// NOTE: One color buffer is always active by default
1589void rlActiveDrawBuffers(int count)
1590{
1591#if (defined(GRAPHICS_API_OPENGL_33) && defined(RLGL_RENDER_TEXTURES_HINT))
1592 // NOTE: Maximum number of draw buffers supported is implementation dependant,
1593 // it can be queried with glGet*() but it must be at least 8
1594 //GLint maxDrawBuffers = 0;
1595 //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
1596
1597 if (count > 0)
1598 {
1599 if (count > 8) TRACELOG(LOG_WARNING, "GL: Max color buffers limited to 8");
1600 else
1601 {
1602 unsigned int buffers[8] = {
1611 };
1612
1613 glDrawBuffers(count, buffers);
1614 }
1615 }
1616 else TRACELOG(LOG_WARNING, "GL: One color buffer active by default");
1617#endif
1618}
1619
1620//----------------------------------------------------------------------------------
1621// General render state configuration
1622//----------------------------------------------------------------------------------
1623
1624// Enable color blending
1625void rlEnableColorBlend(void) { glEnable(GL_BLEND); }
1626
1627// Disable color blending
1628void rlDisableColorBlend(void) { glDisable(GL_BLEND); }
1629
1630// Enable depth test
1632
1633// Disable depth test
1635
1636// Enable depth write
1637void rlEnableDepthMask(void) { glDepthMask(GL_TRUE); }
1638
1639// Disable depth write
1641
1642// Enable backface culling
1644
1645// Disable backface culling
1647
1648// Enable scissor test
1650
1651// Disable scissor test
1653
1654// Scissor test
1655void rlScissor(int x, int y, int width, int height) { glScissor(x, y, width, height); }
1656
1657// Enable wire mode
1658void rlEnableWireMode(void)
1659{
1660#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
1661 // NOTE: glPolygonMode() not available on OpenGL ES
1663#endif
1664}
1665
1666// Disable wire mode
1667void rlDisableWireMode(void)
1668{
1669#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
1670 // NOTE: glPolygonMode() not available on OpenGL ES
1672#endif
1673}
1674
1675// Set the line drawing width
1676void rlSetLineWidth(float width) { glLineWidth(width); }
1677
1678// Get the line drawing width
1679float rlGetLineWidth(void)
1680{
1681 float width = 0;
1682 glGetFloatv(GL_LINE_WIDTH, &width);
1683 return width;
1684}
1685
1686// Enable line aliasing
1687void rlEnableSmoothLines(void)
1688{
1689#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11)
1691#endif
1692}
1693
1694// Disable line aliasing
1695void rlDisableSmoothLines(void)
1696{
1697#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_11)
1699#endif
1700}
1701
1702// Enable stereo rendering
1703void rlEnableStereoRender(void)
1704{
1705#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
1706 RLGL.State.stereoRender = true;
1707#endif
1708}
1709
1710// Disable stereo rendering
1711void rlDisableStereoRender(void)
1712{
1713#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
1714 RLGL.State.stereoRender = false;
1715#endif
1716}
1717
1718// Check if stereo render is enabled
1719bool rlIsStereoRenderEnabled(void)
1720{
1721#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
1722 return RLGL.State.stereoRender;
1723#else
1724 return false;
1725#endif
1726}
1727
1728// Clear color buffer with color
1729void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
1730{
1731 // Color values clamp to 0.0f(0) and 1.0f(255)
1732 float cr = (float)r/255;
1733 float cg = (float)g/255;
1734 float cb = (float)b/255;
1735 float ca = (float)a/255;
1736
1737 glClearColor(cr, cg, cb, ca);
1738}
1739
1740// Clear used screen buffers (color and depth)
1741void rlClearScreenBuffers(void)
1742{
1743 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers: Color and Depth (Depth is used for 3D)
1744 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used...
1745}
1746
1747// Check and log OpenGL error codes
1748void rlCheckErrors()
1749{
1750#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1751 int check = 1;
1752 while (check)
1753 {
1754 const GLenum err = glGetError();
1755 switch (err)
1756 {
1757 case GL_NO_ERROR: check = 0; break;
1758 case 0x0500: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM"); break;
1759 case 0x0501: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE"); break;
1760 case 0x0502: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION"); break;
1761 case 0x0503: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW"); break;
1762 case 0x0504: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW"); break;
1763 case 0x0505: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY"); break;
1764 case 0x0506: TRACELOG(RL_LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION"); break;
1765 default: TRACELOG(RL_LOG_WARNING, "GL: Error detected: Unknown error code: %x", err); break;
1766 }
1767 }
1768#endif
1769}
1770
1771// Set blend mode
1772void rlSetBlendMode(int mode)
1773{
1774#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1775 if (RLGL.State.currentBlendMode != mode)
1776 {
1777 rlDrawRenderBatch(RLGL.currentBatch);
1778
1779 switch (mode)
1780 {
1787 case RL_BLEND_CUSTOM:
1788 {
1789 // NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors()
1790 glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation);
1791 } break;
1792 default: break;
1793 }
1794
1795 RLGL.State.currentBlendMode = mode;
1796 }
1797#endif
1798}
1799
1800// Set blending mode factor and equation
1801void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
1802{
1803#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1804 RLGL.State.glBlendSrcFactor = glSrcFactor;
1805 RLGL.State.glBlendDstFactor = glDstFactor;
1806 RLGL.State.glBlendEquation = glEquation;
1807#endif
1808}
1809
1810//----------------------------------------------------------------------------------
1811// Module Functions Definition - OpenGL Debug
1812//----------------------------------------------------------------------------------
1813#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43)
1814static void GLAPIENTRY rlDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
1815{
1816 // Ignore non-significant error/warning codes (NVidia drivers)
1817 // NOTE: Here there are the details with a sample output:
1818 // - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low)
1819 // - #131185 - Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_ENUM_88e4)
1820 // will use VIDEO memory as the source for buffer object operations. (severity: low)
1821 // - #131218 - Program/shader state performance warning: Vertex shader in program 7 is being recompiled based on GL state. (severity: medium)
1822 // - #131204 - Texture state usage warning: The texture object (0) bound to texture image unit 0 does not have
1823 // a defined base level and cannot be used for texture mapping. (severity: low)
1824 if ((id == 131169) || (id == 131185) || (id == 131218) || (id == 131204)) return;
1825
1826 const char *msgSource = NULL;
1827 switch (source)
1828 {
1829 case GL_DEBUG_SOURCE_API: msgSource = "API"; break;
1830 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: msgSource = "WINDOW_SYSTEM"; break;
1831 case GL_DEBUG_SOURCE_SHADER_COMPILER: msgSource = "SHADER_COMPILER"; break;
1832 case GL_DEBUG_SOURCE_THIRD_PARTY: msgSource = "THIRD_PARTY"; break;
1833 case GL_DEBUG_SOURCE_APPLICATION: msgSource = "APPLICATION"; break;
1834 case GL_DEBUG_SOURCE_OTHER: msgSource = "OTHER"; break;
1835 default: break;
1836 }
1837
1838 const char *msgType = NULL;
1839 switch (type)
1840 {
1841 case GL_DEBUG_TYPE_ERROR: msgType = "ERROR"; break;
1842 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: msgType = "DEPRECATED_BEHAVIOR"; break;
1843 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: msgType = "UNDEFINED_BEHAVIOR"; break;
1844 case GL_DEBUG_TYPE_PORTABILITY: msgType = "PORTABILITY"; break;
1845 case GL_DEBUG_TYPE_PERFORMANCE: msgType = "PERFORMANCE"; break;
1846 case GL_DEBUG_TYPE_MARKER: msgType = "MARKER"; break;
1847 case GL_DEBUG_TYPE_PUSH_GROUP: msgType = "PUSH_GROUP"; break;
1848 case GL_DEBUG_TYPE_POP_GROUP: msgType = "POP_GROUP"; break;
1849 case GL_DEBUG_TYPE_OTHER: msgType = "OTHER"; break;
1850 default: break;
1851 }
1852
1853 const char *msgSeverity = "DEFAULT";
1854 switch (severity)
1855 {
1856 case GL_DEBUG_SEVERITY_LOW: msgSeverity = "LOW"; break;
1857 case GL_DEBUG_SEVERITY_MEDIUM: msgSeverity = "MEDIUM"; break;
1858 case GL_DEBUG_SEVERITY_HIGH: msgSeverity = "HIGH"; break;
1859 case GL_DEBUG_SEVERITY_NOTIFICATION: msgSeverity = "NOTIFICATION"; break;
1860 default: break;
1861 }
1862
1863 TRACELOG(LOG_WARNING, "GL: OpenGL debug message: %s", message);
1864 TRACELOG(LOG_WARNING, " > Type: %s", msgType);
1865 TRACELOG(LOG_WARNING, " > Source = %s", msgSource);
1866 TRACELOG(LOG_WARNING, " > Severity = %s", msgSeverity);
1867}
1868#endif
1869
1870//----------------------------------------------------------------------------------
1871// Module Functions Definition - rlgl functionality
1872//----------------------------------------------------------------------------------
1873
1874// Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states
1875void rlglInit(int width, int height)
1876{
1877 // Enable OpenGL debug context if required
1878#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT) && defined(GRAPHICS_API_OPENGL_43)
1880 {
1881 glDebugMessageCallback(rlDebugMessageCallback, 0);
1882 // glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); // TODO: Filter message
1883
1884 // Debug context options:
1885 // - GL_DEBUG_OUTPUT - Faster version but not useful for breakpoints
1886 // - GL_DEBUG_OUTPUT_SYNCHRONUS - Callback is in sync with errors, so a breakpoint can be placed on the callback in order to get a stacktrace for the GL error
1889 }
1890#endif
1891
1892#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1893 // Init default white texture
1894 unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes)
1895 RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, 1);
1896
1897 if (RLGL.State.defaultTextureId != 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId);
1898 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load default texture");
1899
1900 // Init default Shader (customized for GL 3.3 and ES2)
1901 // Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs
1902 rlLoadShaderDefault();
1903 RLGL.State.currentShaderId = RLGL.State.defaultShaderId;
1904 RLGL.State.currentShaderLocs = RLGL.State.defaultShaderLocs;
1905
1906 // Init default vertex arrays buffers
1908 RLGL.currentBatch = &RLGL.defaultBatch;
1909
1910 // Init stack matrices (emulating OpenGL 1.1)
1911 for (int i = 0; i < RL_MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = rlMatrixIdentity();
1912
1913 // Init internal matrices
1914 RLGL.State.transform = rlMatrixIdentity();
1915 RLGL.State.projection = rlMatrixIdentity();
1916 RLGL.State.modelview = rlMatrixIdentity();
1917 RLGL.State.currentMatrix = &RLGL.State.modelview;
1918#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
1919
1920 // Initialize OpenGL default states
1921 //----------------------------------------------------------
1922 // Init state: Depth test
1923 glDepthFunc(GL_LEQUAL); // Type of depth testing to apply
1924 glDisable(GL_DEPTH_TEST); // Disable depth testing for 2D (only used for 3D)
1925
1926 // Init state: Blending mode
1927 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Color blending function (how colors are mixed)
1928 glEnable(GL_BLEND); // Enable color blending (required to work with transparencies)
1929
1930 // Init state: Culling
1931 // NOTE: All shapes/models triangles are drawn CCW
1932 glCullFace(GL_BACK); // Cull the back face (default)
1933 glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
1934 glEnable(GL_CULL_FACE); // Enable backface culling
1935
1936 // Init state: Cubemap seamless
1937#if defined(GRAPHICS_API_OPENGL_33)
1938 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0)
1939#endif
1940
1941#if defined(GRAPHICS_API_OPENGL_11)
1942 // Init state: Color hints (deprecated in OpenGL 3.0+)
1943 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Improve quality of color and texture coordinate interpolation
1944 glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
1945#endif
1946
1947#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1948 // Store screen size into global variables
1949 RLGL.State.framebufferWidth = width;
1950 RLGL.State.framebufferHeight = height;
1951
1952 TRACELOG(RL_LOG_INFO, "RLGL: Default OpenGL state initialized successfully");
1953 //----------------------------------------------------------
1954#endif
1955
1956 // Init state: Color/Depth buffers clear
1957 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
1958 glClearDepth(1.0f); // Set clear depth value (default)
1959 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers (depth buffer required for 3D)
1960}
1961
1962// Vertex Buffer Object deinitialization (memory free)
1963void rlglClose(void)
1964{
1965#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
1966 rlUnloadRenderBatch(RLGL.defaultBatch);
1967
1968 rlUnloadShaderDefault(); // Unload default shader
1969
1970 glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
1971 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId);
1972#endif
1973}
1974
1975// Load OpenGL extensions
1976// NOTE: External loader function must be provided
1977void rlLoadExtensions(void *loader)
1978{
1979#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21
1980 // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
1981 #if !defined(__APPLE__)
1982 if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
1983 else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
1984 #endif
1985
1986 // Get number of supported extensions
1987 GLint numExt = 0;
1989 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt);
1990
1991#if defined(RLGL_SHOW_GL_DETAILS_INFO)
1992 // Get supported extensions list
1993 // WARNING: glGetStringi() not available on OpenGL 2.1
1994 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:");
1995 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i));
1996#endif
1997
1998 // Register supported extensions flags
1999 // OpenGL 3.3 extensions supported by default (core)
2000 RLGL.ExtSupported.vao = true;
2001 RLGL.ExtSupported.instancing = true;
2002 RLGL.ExtSupported.texNPOT = true;
2003 RLGL.ExtSupported.texFloat32 = true;
2004 RLGL.ExtSupported.texDepth = true;
2005 RLGL.ExtSupported.maxDepthBits = 32;
2006 RLGL.ExtSupported.texAnisoFilter = true;
2007 RLGL.ExtSupported.texMirrorClamp = true;
2008 #if defined(GRAPHICS_API_OPENGL_43)
2009 if (GLAD_GL_ARB_compute_shader) RLGL.ExtSupported.computeShader = true;
2010 if (GLAD_GL_ARB_shader_storage_buffer_object) RLGL.ExtSupported.ssbo = true;
2011 #endif
2012 #if !defined(__APPLE__)
2013 // NOTE: With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
2014 if (GLAD_GL_EXT_texture_compression_s3tc) RLGL.ExtSupported.texCompDXT = true; // Texture compression: DXT
2015 if (GLAD_GL_ARB_ES3_compatibility) RLGL.ExtSupported.texCompETC2 = true; // Texture compression: ETC2/EAC
2016 #endif
2017#endif // GRAPHICS_API_OPENGL_33
2018
2019#if defined(GRAPHICS_API_OPENGL_ES2)
2020 // Get supported extensions list
2021 GLint numExt = 0;
2022 const char **extList = RL_MALLOC(512*sizeof(const char *)); // Allocate 512 strings pointers (2 KB)
2023 const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string
2024
2025 // NOTE: We have to duplicate string because glGetString() returns a const string
2026 int size = strlen(extensions) + 1; // Get extensions string size in bytes
2027 char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char));
2028 strcpy(extensionsDup, extensions);
2029 extList[numExt] = extensionsDup;
2030
2031 for (int i = 0; i < size; i++)
2032 {
2033 if (extensionsDup[i] == ' ')
2034 {
2035 extensionsDup[i] = '\0';
2036 numExt++;
2037 extList[numExt] = &extensionsDup[i + 1];
2038 }
2039 }
2040
2041 TRACELOG(RL_LOG_INFO, "GL: Supported extensions count: %i", numExt);
2042
2043#if defined(RLGL_SHOW_GL_DETAILS_INFO)
2044 TRACELOG(RL_LOG_INFO, "GL: OpenGL extensions:");
2045 for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", extList[i]);
2046#endif
2047
2048 // Check required extensions
2049 for (int i = 0; i < numExt; i++)
2050 {
2051 // Check VAO support
2052 // NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature
2053 if (strcmp(extList[i], (const char *)"GL_OES_vertex_array_object") == 0)
2054 {
2055 // The extension is supported by our hardware and driver, try to get related functions pointers
2056 // NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance...
2057 glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glGenVertexArraysOES");
2058 glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)((rlglLoadProc)loader)("glBindVertexArrayOES");
2059 glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)((rlglLoadProc)loader)("glDeleteVertexArraysOES");
2060 //glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)loader("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted
2061
2062 if ((glGenVertexArrays != NULL) && (glBindVertexArray != NULL) && (glDeleteVertexArrays != NULL)) RLGL.ExtSupported.vao = true;
2063 }
2064
2065 // Check instanced rendering support
2066 if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // Web ANGLE
2067 {
2068 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");
2069 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");
2070 glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");
2071
2072 if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
2073 }
2074 else
2075 {
2076 if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) && // Standard EXT
2077 (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0))
2078 {
2079 glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
2080 glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
2081 glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");
2082
2083 if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
2084 }
2085 }
2086
2087 // Check NPOT textures support
2088 // NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
2089 if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) RLGL.ExtSupported.texNPOT = true;
2090
2091 // Check texture float support
2092 if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) RLGL.ExtSupported.texFloat32 = true;
2093
2094 // Check depth texture support
2095 if ((strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) ||
2096 (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0)) RLGL.ExtSupported.texDepth = true;
2097
2098 if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) RLGL.ExtSupported.maxDepthBits = 24;
2099 if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) RLGL.ExtSupported.maxDepthBits = 32;
2100
2101 // Check texture compression support: DXT
2102 if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
2103 (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_s3tc") == 0) ||
2104 (strcmp(extList[i], (const char *)"GL_WEBKIT_WEBGL_compressed_texture_s3tc") == 0)) RLGL.ExtSupported.texCompDXT = true;
2105
2106 // Check texture compression support: ETC1
2107 if ((strcmp(extList[i], (const char *)"GL_OES_compressed_ETC1_RGB8_texture") == 0) ||
2108 (strcmp(extList[i], (const char *)"GL_WEBGL_compressed_texture_etc1") == 0)) RLGL.ExtSupported.texCompETC1 = true;
2109
2110 // Check texture compression support: ETC2/EAC
2111 if (strcmp(extList[i], (const char *)"GL_ARB_ES3_compatibility") == 0) RLGL.ExtSupported.texCompETC2 = true;
2112
2113 // Check texture compression support: PVR
2114 if (strcmp(extList[i], (const char *)"GL_IMG_texture_compression_pvrtc") == 0) RLGL.ExtSupported.texCompPVRT = true;
2115
2116 // Check texture compression support: ASTC
2117 if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) RLGL.ExtSupported.texCompASTC = true;
2118
2119 // Check anisotropic texture filter support
2120 if (strcmp(extList[i], (const char *)"GL_EXT_texture_filter_anisotropic") == 0) RLGL.ExtSupported.texAnisoFilter = true;
2121
2122 // Check clamp mirror wrap mode support
2123 if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true;
2124 }
2125
2126 // Free extensions pointers
2127 RL_FREE(extList);
2128 RL_FREE(extensionsDup); // Duplicated string must be deallocated
2129#endif // GRAPHICS_API_OPENGL_ES2
2130
2131 // Check OpenGL information and capabilities
2132 //------------------------------------------------------------------------------
2133 // Show current OpenGL and GLSL version
2134 TRACELOG(RL_LOG_INFO, "GL: OpenGL device information:");
2135 TRACELOG(RL_LOG_INFO, " > Vendor: %s", glGetString(GL_VENDOR));
2136 TRACELOG(RL_LOG_INFO, " > Renderer: %s", glGetString(GL_RENDERER));
2137 TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION));
2139
2140#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2141 // NOTE: Anisotropy levels capability is an extension
2142 #ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
2143 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
2144 #endif
2145 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &RLGL.ExtSupported.maxAnisotropyLevel);
2146
2147#if defined(RLGL_SHOW_GL_DETAILS_INFO)
2148 // Show some OpenGL GPU capabilities
2149 TRACELOG(RL_LOG_INFO, "GL: OpenGL capabilities:");
2150 GLint capability = 0;
2151 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &capability);
2152 TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_SIZE: %i", capability);
2154 TRACELOG(RL_LOG_INFO, " GL_MAX_CUBE_MAP_TEXTURE_SIZE: %i", capability);
2156 TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_IMAGE_UNITS: %i", capability);
2158 TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIBS: %i", capability);
2159 #if !defined(GRAPHICS_API_OPENGL_ES2)
2161 TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_BLOCK_SIZE: %i", capability);
2162 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &capability);
2163 TRACELOG(RL_LOG_INFO, " GL_MAX_DRAW_BUFFERS: %i", capability);
2164 if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(RL_LOG_INFO, " GL_MAX_TEXTURE_MAX_ANISOTROPY: %.0f", RLGL.ExtSupported.maxAnisotropyLevel);
2165 #endif
2167 TRACELOG(RL_LOG_INFO, " GL_NUM_COMPRESSED_TEXTURE_FORMATS: %i", capability);
2168 GLint *compFormats = (GLint *)RL_CALLOC(capability, sizeof(GLint));
2170 for (int i = 0; i < capability; i++) TRACELOG(RL_LOG_INFO, " %s", rlGetCompressedFormatName(compFormats[i]));
2171 RL_FREE(compFormats);
2172
2173#if defined(GRAPHICS_API_OPENGL_43)
2175 TRACELOG(RL_LOG_INFO, " GL_MAX_VERTEX_ATTRIB_BINDINGS: %i", capability);
2177 TRACELOG(RL_LOG_INFO, " GL_MAX_UNIFORM_LOCATIONS: %i", capability);
2178#endif // GRAPHICS_API_OPENGL_43
2179#else // RLGL_SHOW_GL_DETAILS_INFO
2180
2181 // Show some basic info about GL supported features
2182 #if defined(GRAPHICS_API_OPENGL_ES2)
2183 if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully");
2184 else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported");
2185 if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
2186 else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
2187 #endif
2188 if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported");
2189 if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported");
2190 if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported");
2191 if (RLGL.ExtSupported.texCompPVRT) TRACELOG(RL_LOG_INFO, "GL: PVRT compressed textures supported");
2192 if (RLGL.ExtSupported.texCompASTC) TRACELOG(RL_LOG_INFO, "GL: ASTC compressed textures supported");
2193 if (RLGL.ExtSupported.computeShader) TRACELOG(RL_LOG_INFO, "GL: Compute shaders supported");
2194 if (RLGL.ExtSupported.ssbo) TRACELOG(RL_LOG_INFO, "GL: Shader storage buffer objects supported");
2195#endif // RLGL_SHOW_GL_DETAILS_INFO
2196
2197#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
2198}
2199
2200// Get current OpenGL version
2201int rlGetVersion(void)
2202{
2203 int glVersion = 0;
2204#if defined(GRAPHICS_API_OPENGL_11)
2205 glVersion = OPENGL_11;
2206#endif
2207#if defined(GRAPHICS_API_OPENGL_21)
2208 #if defined(__APPLE__)
2209 glVersion = OPENGL_33; // NOTE: Force OpenGL 3.3 on OSX
2210 #else
2211 glVersion = OPENGL_21;
2212 #endif
2213#elif defined(GRAPHICS_API_OPENGL_33)
2214 glVersion = OPENGL_33;
2215#endif
2216#if defined(GRAPHICS_API_OPENGL_43)
2217 glVersion = OPENGL_43;
2218#endif
2219#if defined(GRAPHICS_API_OPENGL_ES2)
2220 glVersion = OPENGL_ES_20;
2221#endif
2222 return glVersion;
2223}
2224
2225// Set current framebuffer width
2226void rlSetFramebufferWidth(int width)
2227{
2228#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2229 RLGL.State.framebufferWidth = width;
2230#endif
2231}
2232
2233// Set current framebuffer height
2234void rlSetFramebufferHeight(int height)
2235{
2236#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2237 RLGL.State.framebufferHeight = height;
2238#endif
2239}
2240
2241// Get default framebuffer width
2242int rlGetFramebufferWidth(void)
2243{
2244 int width = 0;
2245#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2246 width = RLGL.State.framebufferWidth;
2247#endif
2248 return width;
2249}
2250
2251// Get default framebuffer height
2252int rlGetFramebufferHeight(void)
2253{
2254 int height = 0;
2255#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2256 height = RLGL.State.framebufferHeight;
2257#endif
2258 return height;
2259}
2260
2261// Get default internal texture (white texture)
2262// NOTE: Default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
2263unsigned int rlGetTextureIdDefault(void)
2264{
2265 unsigned int id = 0;
2266#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2267 id = RLGL.State.defaultTextureId;
2268#endif
2269 return id;
2270}
2271
2272// Get default shader id
2273unsigned int rlGetShaderIdDefault(void)
2274{
2275 unsigned int id = 0;
2276#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2277 id = RLGL.State.defaultShaderId;
2278#endif
2279 return id;
2280}
2281
2282// Get default shader locs
2283int *rlGetShaderLocsDefault(void)
2284{
2285 int *locs = NULL;
2286#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2287 locs = RLGL.State.defaultShaderLocs;
2288#endif
2289 return locs;
2290}
2291
2292// Render batch management
2293//------------------------------------------------------------------------------------------------
2294// Load render batch
2295rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
2296{
2297 rlRenderBatch batch = { 0 };
2298
2299#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2300 // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes)
2301 //--------------------------------------------------------------------------------------------
2302 batch.vertexBuffer = (rlVertexBuffer *)RL_MALLOC(numBuffers*sizeof(rlVertexBuffer));
2303
2304 for (int i = 0; i < numBuffers; i++)
2305 {
2306 batch.vertexBuffer[i].elementCount = bufferElements;
2307
2308 batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad
2309 batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad
2310 batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad
2311#if defined(GRAPHICS_API_OPENGL_33)
2312 batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(bufferElements*6*sizeof(unsigned int)); // 6 int by quad (indices)
2313#endif
2314#if defined(GRAPHICS_API_OPENGL_ES2)
2315 batch.vertexBuffer[i].indices = (unsigned short *)RL_MALLOC(bufferElements*6*sizeof(unsigned short)); // 6 int by quad (indices)
2316#endif
2317
2318 for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f;
2319 for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f;
2320 for (int j = 0; j < (4*4*bufferElements); j++) batch.vertexBuffer[i].colors[j] = 0;
2321
2322 int k = 0;
2323
2324 // Indices can be initialized right now
2325 for (int j = 0; j < (6*bufferElements); j += 6)
2326 {
2327 batch.vertexBuffer[i].indices[j] = 4*k;
2328 batch.vertexBuffer[i].indices[j + 1] = 4*k + 1;
2329 batch.vertexBuffer[i].indices[j + 2] = 4*k + 2;
2330 batch.vertexBuffer[i].indices[j + 3] = 4*k;
2331 batch.vertexBuffer[i].indices[j + 4] = 4*k + 2;
2332 batch.vertexBuffer[i].indices[j + 5] = 4*k + 3;
2333
2334 k++;
2335 }
2336
2337 RLGL.State.vertexCounter = 0;
2338 }
2339
2340 TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)");
2341 //--------------------------------------------------------------------------------------------
2342
2343 // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs
2344 //--------------------------------------------------------------------------------------------
2345 for (int i = 0; i < numBuffers; i++)
2346 {
2347 if (RLGL.ExtSupported.vao)
2348 {
2349 // Initialize Quads VAO
2350 glGenVertexArrays(1, &batch.vertexBuffer[i].vaoId);
2352 }
2353
2354 // Quads - Vertex buffers binding and attributes enable
2355 // Vertex position buffer (shader-location = 0)
2356 glGenBuffers(1, &batch.vertexBuffer[i].vboId[0]);
2358 glBufferData(GL_ARRAY_BUFFER, bufferElements*3*4*sizeof(float), batch.vertexBuffer[i].vertices, GL_DYNAMIC_DRAW);
2359 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]);
2360 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
2361
2362 // Vertex texcoord buffer (shader-location = 1)
2363 glGenBuffers(1, &batch.vertexBuffer[i].vboId[1]);
2365 glBufferData(GL_ARRAY_BUFFER, bufferElements*2*4*sizeof(float), batch.vertexBuffer[i].texcoords, GL_DYNAMIC_DRAW);
2366 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]);
2367 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
2368
2369 // Vertex color buffer (shader-location = 3)
2370 glGenBuffers(1, &batch.vertexBuffer[i].vboId[2]);
2372 glBufferData(GL_ARRAY_BUFFER, bufferElements*4*4*sizeof(unsigned char), batch.vertexBuffer[i].colors, GL_DYNAMIC_DRAW);
2373 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]);
2374 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
2375
2376 // Fill index buffer
2377 glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]);
2379#if defined(GRAPHICS_API_OPENGL_33)
2380 glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(int), batch.vertexBuffer[i].indices, GL_STATIC_DRAW);
2381#endif
2382#if defined(GRAPHICS_API_OPENGL_ES2)
2383 glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufferElements*6*sizeof(short), batch.vertexBuffer[i].indices, GL_STATIC_DRAW);
2384#endif
2385 }
2386
2387 TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)");
2388
2389 // Unbind the current VAO
2390 if (RLGL.ExtSupported.vao) glBindVertexArray(0);
2391 //--------------------------------------------------------------------------------------------
2392
2393 // Init draw calls tracking system
2394 //--------------------------------------------------------------------------------------------
2396
2397 for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++)
2398 {
2399 batch.draws[i].mode = RL_QUADS;
2400 batch.draws[i].vertexCount = 0;
2401 batch.draws[i].vertexAlignment = 0;
2402 //batch.draws[i].vaoId = 0;
2403 //batch.draws[i].shaderId = 0;
2404 batch.draws[i].textureId = RLGL.State.defaultTextureId;
2405 //batch.draws[i].RLGL.State.projection = rlMatrixIdentity();
2406 //batch.draws[i].RLGL.State.modelview = rlMatrixIdentity();
2407 }
2408
2409 batch.bufferCount = numBuffers; // Record buffer count
2410 batch.drawCounter = 1; // Reset draws counter
2411 batch.currentDepth = -1.0f; // Reset depth value
2412 //--------------------------------------------------------------------------------------------
2413#endif
2414
2415 return batch;
2416}
2417
2418// Unload default internal buffers vertex data from CPU and GPU
2420{
2421#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2422 // Unbind everything
2425
2426 // Unload all vertex buffers data
2427 for (int i = 0; i < batch.bufferCount; i++)
2428 {
2429 // Unbind VAO attribs data
2430 if (RLGL.ExtSupported.vao)
2431 {
2438 }
2439
2440 // Delete VBOs from GPU (VRAM)
2441 glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[0]);
2442 glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[1]);
2443 glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[2]);
2444 glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[3]);
2445
2446 // Delete VAOs from GPU (VRAM)
2447 if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &batch.vertexBuffer[i].vaoId);
2448
2449 // Free vertex arrays memory from CPU (RAM)
2450 RL_FREE(batch.vertexBuffer[i].vertices);
2451 RL_FREE(batch.vertexBuffer[i].texcoords);
2452 RL_FREE(batch.vertexBuffer[i].colors);
2453 RL_FREE(batch.vertexBuffer[i].indices);
2454 }
2455
2456 // Unload arrays
2457 RL_FREE(batch.vertexBuffer);
2458 RL_FREE(batch.draws);
2459#endif
2460}
2461
2462// Draw render batch
2463// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer)
2465{
2466#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2467 // Update batch vertex buffers
2468 //------------------------------------------------------------------------------------------------------------
2469 // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
2470 // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required)
2471 if (RLGL.State.vertexCounter > 0)
2472 {
2473 // Activate elements VAO
2474 if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId);
2475
2476 // Vertex positions buffer
2478 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices);
2479 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
2480
2481 // Texture coordinates buffer
2483 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords);
2484 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
2485
2486 // Colors buffer
2488 glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
2489 //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
2490
2491 // NOTE: glMapBuffer() causes sync issue.
2492 // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job.
2493 // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer().
2494 // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new
2495 // allocated pointer immediately even if GPU is still working with the previous data.
2496
2497 // Another option: map the buffer object into client's memory
2498 // Probably this code could be moved somewhere else...
2499 // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
2500 // if (batch->vertexBuffer[batch->currentBuffer].vertices)
2501 // {
2502 // Update vertex data
2503 // }
2504 // glUnmapBuffer(GL_ARRAY_BUFFER);
2505
2506 // Unbind the current VAO
2507 if (RLGL.ExtSupported.vao) glBindVertexArray(0);
2508 }
2509 //------------------------------------------------------------------------------------------------------------
2510
2511 // Draw batch vertex buffers (considering VR stereo if required)
2512 //------------------------------------------------------------------------------------------------------------
2513 Matrix matProjection = RLGL.State.projection;
2514 Matrix matModelView = RLGL.State.modelview;
2515
2516 int eyeCount = 1;
2517 if (RLGL.State.stereoRender) eyeCount = 2;
2518
2519 for (int eye = 0; eye < eyeCount; eye++)
2520 {
2521 if (eyeCount == 2)
2522 {
2523 // Setup current eye viewport (half screen width)
2524 rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
2525
2526 // Set current eye view offset to modelview matrix
2527 rlSetMatrixModelview(rlMatrixMultiply(matModelView, RLGL.State.viewOffsetStereo[eye]));
2528 // Set current eye projection matrix
2529 rlSetMatrixProjection(RLGL.State.projectionStereo[eye]);
2530 }
2531
2532 // Draw buffers
2533 if (RLGL.State.vertexCounter > 0)
2534 {
2535 // Set current shader and upload current MVP matrix
2536 glUseProgram(RLGL.State.currentShaderId);
2537
2538 // Create modelview-projection matrix and upload to shader
2539 Matrix matMVP = rlMatrixMultiply(RLGL.State.modelview, RLGL.State.projection);
2540 float matMVPfloat[16] = {
2541 matMVP.m0, matMVP.m1, matMVP.m2, matMVP.m3,
2542 matMVP.m4, matMVP.m5, matMVP.m6, matMVP.m7,
2543 matMVP.m8, matMVP.m9, matMVP.m10, matMVP.m11,
2544 matMVP.m12, matMVP.m13, matMVP.m14, matMVP.m15
2545 };
2546 glUniformMatrix4fv(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_MVP], 1, false, matMVPfloat);
2547
2548 if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId);
2549 else
2550 {
2551 // Bind vertex attrib: position (shader-location = 0)
2553 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
2554 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_POSITION]);
2555
2556 // Bind vertex attrib: texcoord (shader-location = 1)
2558 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
2559 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01]);
2560
2561 // Bind vertex attrib: color (shader-location = 3)
2563 glVertexAttribPointer(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
2564 glEnableVertexAttribArray(RLGL.State.currentShaderLocs[RL_SHADER_LOC_VERTEX_COLOR]);
2565
2567 }
2568
2569 // Setup some default shader values
2570 glUniform4f(RLGL.State.currentShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f);
2571 glUniform1i(RLGL.State.currentShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE], 0); // Active default sampler2D: texture0
2572
2573 // Activate additional sampler textures
2574 // Those additional textures will be common for all draw calls of the batch
2575 for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++)
2576 {
2577 if (RLGL.State.activeTextureId[i] > 0)
2578 {
2580 glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]);
2581 }
2582 }
2583
2584 // Activate default sampler2D texture0 (one texture is always active for default batch shader)
2585 // NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls
2587
2588 for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++)
2589 {
2590 // Bind current draw call texture, activated as GL_TEXTURE0 and binded to sampler2D texture0 by default
2592
2593 if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount);
2594 else
2595 {
2596#if defined(GRAPHICS_API_OPENGL_33)
2597 // We need to define the number of indices to be processed: elementCount*6
2598 // NOTE: The final parameter tells the GPU the offset in bytes from the
2599 // start of the index buffer to the location of the first index to process
2600 glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint)));
2601#endif
2602#if defined(GRAPHICS_API_OPENGL_ES2)
2603 glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort)));
2604#endif
2605 }
2606
2607 vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment);
2608 }
2609
2610 if (!RLGL.ExtSupported.vao)
2611 {
2614 }
2615
2616 glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
2617 }
2618
2619 if (RLGL.ExtSupported.vao) glBindVertexArray(0); // Unbind VAO
2620
2621 glUseProgram(0); // Unbind shader program
2622 }
2623
2624 // Restore viewport to default measures
2625 if (eyeCount == 2) rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
2626 //------------------------------------------------------------------------------------------------------------
2627
2628 // Reset batch buffers
2629 //------------------------------------------------------------------------------------------------------------
2630 // Reset vertex counter for next frame
2631 RLGL.State.vertexCounter = 0;
2632
2633 // Reset depth for next draw
2634 batch->currentDepth = -1.0f;
2635
2636 // Restore projection/modelview matrices
2637 RLGL.State.projection = matProjection;
2638 RLGL.State.modelview = matModelView;
2639
2640 // Reset RLGL.currentBatch->draws array
2641 for (int i = 0; i < RL_DEFAULT_BATCH_DRAWCALLS; i++)
2642 {
2643 batch->draws[i].mode = RL_QUADS;
2644 batch->draws[i].vertexCount = 0;
2645 batch->draws[i].textureId = RLGL.State.defaultTextureId;
2646 }
2647
2648 // Reset active texture units for next batch
2649 for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) RLGL.State.activeTextureId[i] = 0;
2650
2651 // Reset draws counter to one draw for the batch
2652 batch->drawCounter = 1;
2653 //------------------------------------------------------------------------------------------------------------
2654
2655 // Change to next buffer in the list (in case of multi-buffering)
2656 batch->currentBuffer++;
2657 if (batch->currentBuffer >= batch->bufferCount) batch->currentBuffer = 0;
2658#endif
2659}
2660
2661// Set the active render batch for rlgl
2663{
2664#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2665 rlDrawRenderBatch(RLGL.currentBatch);
2666
2667 if (batch != NULL) RLGL.currentBatch = batch;
2668 else RLGL.currentBatch = &RLGL.defaultBatch;
2669#endif
2670}
2671
2672// Update and draw internal render batch
2673void rlDrawRenderBatchActive(void)
2674{
2675#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2676 rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
2677#endif
2678}
2679
2680// Check internal buffer overflow for a given number of vertex
2681// and force a rlRenderBatch draw call if required
2682bool rlCheckRenderBatchLimit(int vCount)
2683{
2684 bool overflow = false;
2685
2686#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2687 if ((RLGL.State.vertexCounter + vCount) >=
2688 (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
2689 {
2690 int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode;
2691 int currentTexture = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId;
2692
2693 overflow = true;
2694 rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
2695
2696 // Restore state of last batch so we can continue adding vertices
2697 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = currentMode;
2698 RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = currentTexture;
2699 }
2700#endif
2701
2702 return overflow;
2703}
2704
2705// Textures data management
2706//-----------------------------------------------------------------------------------------
2707// Convert image data to OpenGL texture (returns OpenGL valid Id)
2708unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount)
2709{
2710 glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding
2711
2712 unsigned int id = 0;
2713
2714 // Check texture format support by OpenGL 1.1 (compressed textures not supported)
2715#if defined(GRAPHICS_API_OPENGL_11)
2717 {
2718 TRACELOG(RL_LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats");
2719 return id;
2720 }
2721#else
2722 if ((!RLGL.ExtSupported.texCompDXT) && ((format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA) ||
2724 {
2725 TRACELOG(RL_LOG_WARNING, "GL: DXT compressed texture format not supported");
2726 return id;
2727 }
2728#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2729 if ((!RLGL.ExtSupported.texCompETC1) && (format == RL_PIXELFORMAT_COMPRESSED_ETC1_RGB))
2730 {
2731 TRACELOG(RL_LOG_WARNING, "GL: ETC1 compressed texture format not supported");
2732 return id;
2733 }
2734
2735 if ((!RLGL.ExtSupported.texCompETC2) && ((format == RL_PIXELFORMAT_COMPRESSED_ETC2_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA)))
2736 {
2737 TRACELOG(RL_LOG_WARNING, "GL: ETC2 compressed texture format not supported");
2738 return id;
2739 }
2740
2741 if ((!RLGL.ExtSupported.texCompPVRT) && ((format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGB) || (format == RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA)))
2742 {
2743 TRACELOG(RL_LOG_WARNING, "GL: PVRT compressed texture format not supported");
2744 return id;
2745 }
2746
2747 if ((!RLGL.ExtSupported.texCompASTC) && ((format == RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA) || (format == RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)))
2748 {
2749 TRACELOG(RL_LOG_WARNING, "GL: ASTC compressed texture format not supported");
2750 return id;
2751 }
2752#endif
2753#endif // GRAPHICS_API_OPENGL_11
2754
2756
2757 glGenTextures(1, &id); // Generate texture id
2758
2760
2761 int mipWidth = width;
2762 int mipHeight = height;
2763 int mipOffset = 0; // Mipmap data offset
2764
2765 // Load the different mipmap levels
2766 for (int i = 0; i < mipmapCount; i++)
2767 {
2768 unsigned int mipSize = rlGetPixelDataSize(mipWidth, mipHeight, format);
2769
2770 int glInternalFormat, glFormat, glType;
2771 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
2772
2773 TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset);
2774
2775 if (glInternalFormat != -1)
2776 {
2777 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, glFormat, glType, (unsigned char *)data + mipOffset);
2778#if !defined(GRAPHICS_API_OPENGL_11)
2779 else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, (unsigned char *)data + mipOffset);
2780#endif
2781
2782#if defined(GRAPHICS_API_OPENGL_33)
2784 {
2785 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE };
2787 }
2788 else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA)
2789 {
2790#if defined(GRAPHICS_API_OPENGL_21)
2791 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA };
2792#elif defined(GRAPHICS_API_OPENGL_33)
2793 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
2794#endif
2796 }
2797#endif
2798 }
2799
2800 mipWidth /= 2;
2801 mipHeight /= 2;
2802 mipOffset += mipSize;
2803
2804 // Security check for NPOT textures
2805 if (mipWidth < 1) mipWidth = 1;
2806 if (mipHeight < 1) mipHeight = 1;
2807 }
2808
2809 // Texture parameters configuration
2810 // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used
2811#if defined(GRAPHICS_API_OPENGL_ES2)
2812 // 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
2813 if (RLGL.ExtSupported.texNPOT)
2814 {
2815 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
2816 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
2817 }
2818 else
2819 {
2820 // NOTE: If using negative texture coordinates (LoadOBJ()), it does not work!
2821 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis
2822 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis
2823 }
2824#else
2825 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
2826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
2827#endif
2828
2829 // Magnification and minification filters
2832
2833#if defined(GRAPHICS_API_OPENGL_33)
2834 if (mipmapCount > 1)
2835 {
2836 // Activate Trilinear filtering if mipmaps are available
2839 }
2840#endif
2841
2842 // At this point we have the texture loaded in GPU and texture parameters configured
2843
2844 // NOTE: If mipmaps were not in data, they are not generated automatically
2845
2846 // Unbind current texture
2848
2849 if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Texture loaded successfully (%ix%i | %s | %i mipmaps)", id, width, height, rlGetPixelFormatName(format), mipmapCount);
2850 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load texture");
2851
2852 return id;
2853}
2854
2855// Load depth texture/renderbuffer (to be attached to fbo)
2856// WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture/WEBGL_depth_texture extensions
2857unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
2858{
2859 unsigned int id = 0;
2860
2861#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2862 // In case depth textures not supported, we force renderbuffer usage
2863 if (!RLGL.ExtSupported.texDepth) useRenderBuffer = true;
2864
2865 // NOTE: We let the implementation to choose the best bit-depth
2866 // Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F
2867 unsigned int glInternalFormat = GL_DEPTH_COMPONENT;
2868
2869#if defined(GRAPHICS_API_OPENGL_ES2)
2870 if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
2871 else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES;
2872 else glInternalFormat = GL_DEPTH_COMPONENT16;
2873#endif
2874
2875 if (!useRenderBuffer && RLGL.ExtSupported.texDepth)
2876 {
2877 glGenTextures(1, &id);
2879 glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
2880
2885
2887
2888 TRACELOG(RL_LOG_INFO, "TEXTURE: Depth texture loaded successfully");
2889 }
2890 else
2891 {
2892 // Create the renderbuffer that will serve as the depth attachment for the framebuffer
2893 // NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices
2894 glGenRenderbuffers(1, &id);
2896 glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height);
2897
2899
2900 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16);
2901 }
2902#endif
2903
2904 return id;
2905}
2906
2907// Load texture cubemap
2908// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other),
2909// expected the following convention: +X, -X, +Y, -Y, +Z, -Z
2910unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
2911{
2912 unsigned int id = 0;
2913
2914#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
2915 unsigned int dataSize = rlGetPixelDataSize(size, size, format);
2916
2917 glGenTextures(1, &id);
2919
2920 int glInternalFormat, glFormat, glType;
2921 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
2922
2923 if (glInternalFormat != -1)
2924 {
2925 // Load cubemap faces
2926 for (unsigned int i = 0; i < 6; i++)
2927 {
2928 if (data == NULL)
2929 {
2931 {
2933 {
2934 // Instead of using a sized internal texture format (GL_RGB16F, GL_RGB32F), we let the driver to choose the better format for us (GL_RGB)
2935 if (RLGL.ExtSupported.texFloat32) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, size, size, 0, GL_RGB, GL_FLOAT, NULL);
2936 else TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
2937 }
2938 else if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
2939 else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL);
2940 }
2941 else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format");
2942 }
2943 else
2944 {
2945 if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize);
2946 else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize);
2947 }
2948
2949#if defined(GRAPHICS_API_OPENGL_33)
2951 {
2952 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE };
2954 }
2955 else if (format == RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA)
2956 {
2957#if defined(GRAPHICS_API_OPENGL_21)
2958 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA };
2959#elif defined(GRAPHICS_API_OPENGL_33)
2960 GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
2961#endif
2963 }
2964#endif
2965 }
2966 }
2967
2968 // Set cubemap texture sampling parameters
2973#if defined(GRAPHICS_API_OPENGL_33)
2974 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // Flag not supported on OpenGL ES 2.0
2975#endif
2976
2978#endif
2979
2980 if (id > 0) TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Cubemap texture loaded successfully (%ix%i)", id, size, size);
2981 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to load cubemap texture");
2982
2983 return id;
2984}
2985
2986// Update already loaded texture in GPU with new data
2987// NOTE: We don't know safely if internal texture format is the expected one...
2988void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data)
2989{
2991
2992 int glInternalFormat, glFormat, glType;
2993 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
2994
2995 if ((glInternalFormat != -1) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB))
2996 {
2997 glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, width, height, glFormat, glType, data);
2998 }
2999 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format);
3000}
3001
3002// Get OpenGL internal formats and data type from raylib PixelFormat
3003void rlGetGlTextureFormats(int format, int *glInternalFormat, int *glFormat, int *glType)
3004{
3005 *glInternalFormat = -1;
3006 *glFormat = -1;
3007 *glType = -1;
3008
3009 switch (format)
3010 {
3011 #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2)
3012 // NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
3013 case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_UNSIGNED_BYTE; break;
3014 case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_LUMINANCE_ALPHA; *glFormat = GL_LUMINANCE_ALPHA; *glType = GL_UNSIGNED_BYTE; break;
3015 case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break;
3016 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break;
3017 case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break;
3018 case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break;
3019 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break;
3020 #if !defined(GRAPHICS_API_OPENGL_11)
3021 case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_LUMINANCE; *glFormat = GL_LUMINANCE; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
3022 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB; *glFormat = GL_RGB; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
3023 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA; *glFormat = GL_RGBA; *glType = GL_FLOAT; break; // NOTE: Requires extension OES_texture_float
3024 #endif
3025 #elif defined(GRAPHICS_API_OPENGL_33)
3026 case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: *glInternalFormat = GL_R8; *glFormat = GL_RED; *glType = GL_UNSIGNED_BYTE; break;
3027 case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: *glInternalFormat = GL_RG8; *glFormat = GL_RG; *glType = GL_UNSIGNED_BYTE; break;
3028 case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: *glInternalFormat = GL_RGB565; *glFormat = GL_RGB; *glType = GL_UNSIGNED_SHORT_5_6_5; break;
3029 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: *glInternalFormat = GL_RGB8; *glFormat = GL_RGB; *glType = GL_UNSIGNED_BYTE; break;
3030 case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: *glInternalFormat = GL_RGB5_A1; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_5_5_5_1; break;
3031 case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: *glInternalFormat = GL_RGBA4; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_SHORT_4_4_4_4; break;
3032 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: *glInternalFormat = GL_RGBA8; *glFormat = GL_RGBA; *glType = GL_UNSIGNED_BYTE; break;
3033 case RL_PIXELFORMAT_UNCOMPRESSED_R32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_R32F; *glFormat = GL_RED; *glType = GL_FLOAT; break;
3034 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGB32F; *glFormat = GL_RGB; *glType = GL_FLOAT; break;
3035 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: if (RLGL.ExtSupported.texFloat32) *glInternalFormat = GL_RGBA32F; *glFormat = GL_RGBA; *glType = GL_FLOAT; break;
3036 #endif
3037 #if !defined(GRAPHICS_API_OPENGL_11)
3038 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; break;
3039 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
3040 case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
3041 case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: if (RLGL.ExtSupported.texCompDXT) *glInternalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
3042 case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: if (RLGL.ExtSupported.texCompETC1) *glInternalFormat = GL_ETC1_RGB8_OES; break; // NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3
3043 case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGB8_ETC2; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
3044 case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: if (RLGL.ExtSupported.texCompETC2) *glInternalFormat = GL_COMPRESSED_RGBA8_ETC2_EAC; break; // NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3
3045 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU
3046 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: if (RLGL.ExtSupported.texCompPVRT) *glInternalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; break; // NOTE: Requires PowerVR GPU
3047 case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
3048 case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; break; // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
3049 #endif
3050 default: TRACELOG(RL_LOG_WARNING, "TEXTURE: Current format not supported (%i)", format); break;
3051 }
3052}
3053
3054// Unload texture from GPU memory
3055void rlUnloadTexture(unsigned int id)
3056{
3057 glDeleteTextures(1, &id);
3058}
3059
3060// Generate mipmap data for selected texture
3061void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps)
3062{
3064
3065 // Check if texture is power-of-two (POT)
3066 bool texIsPOT = false;
3067
3068 if (((width > 0) && ((width & (width - 1)) == 0)) &&
3069 ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
3070
3071#if defined(GRAPHICS_API_OPENGL_11)
3072 if (texIsPOT)
3073 {
3074 // WARNING: Manual mipmap generation only works for RGBA 32bit textures!
3076 {
3077 // Retrieve texture data from VRAM
3078 void *texData = rlReadTexturePixels(id, width, height, format);
3079
3080 // NOTE: Texture data size is reallocated to fit mipmaps data
3081 // NOTE: CPU mipmap generation only supports RGBA 32bit data
3082 int mipmapCount = rlGenTextureMipmapsData(texData, width, height);
3083
3084 int size = width*height*4;
3085 int offset = size;
3086
3087 int mipWidth = width/2;
3088 int mipHeight = height/2;
3089
3090 // Load the mipmaps
3091 for (int level = 1; level < mipmapCount; level++)
3092 {
3093 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)texData + offset);
3094
3095 size = mipWidth*mipHeight*4;
3096 offset += size;
3097
3098 mipWidth /= 2;
3099 mipHeight /= 2;
3100 }
3101
3102 *mipmaps = mipmapCount + 1;
3103 RL_FREE(texData); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
3104
3105 TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", id, *mipmaps);
3106 }
3107 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", id);
3108 }
3109#endif
3110#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3111 if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
3112 {
3113 //glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorythm: GL_FASTEST, GL_NICEST, GL_DONT_CARE
3114 glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
3115
3117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps
3118
3119 #define MIN(a,b) (((a)<(b))?(a):(b))
3120 #define MAX(a,b) (((a)>(b))?(a):(b))
3121
3122 *mipmaps = 1 + (int)floor(log(MAX(width, height))/log(2));
3123 TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Mipmaps generated automatically, total: %i", id, *mipmaps);
3124 }
3125#endif
3126 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps", id);
3127
3129}
3130
3131
3132// Read texture pixel data
3133void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
3134{
3135 void *pixels = NULL;
3136
3137#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
3139
3140 // NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0)
3141 // Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE
3142 //int width, height, format;
3143 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
3144 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
3145 //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
3146
3147 // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding.
3148 // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting.
3149 // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.)
3150 // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.)
3152
3153 int glInternalFormat, glFormat, glType;
3154 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
3155 unsigned int size = rlGetPixelDataSize(width, height, format);
3156
3157 if ((glInternalFormat != -1) && (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB))
3158 {
3159 pixels = RL_MALLOC(size);
3160 glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels);
3161 }
3162 else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", id, format);
3163
3165#endif
3166
3167#if defined(GRAPHICS_API_OPENGL_ES2)
3168 // glGetTexImage() is not available on OpenGL ES 2.0
3169 // Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id.
3170 // Two possible Options:
3171 // 1 - Bind texture to color fbo attachment and glReadPixels()
3172 // 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
3173 // We are using Option 1, just need to care for texture format on retrieval
3174 // NOTE: This behaviour could be conditioned by graphic driver...
3175 unsigned int fboId = rlLoadFramebuffer(width, height);
3176
3179
3180 // Attach our texture to FBO
3182
3183 // We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format
3184 pixels = (unsigned char *)RL_MALLOC(rlGetPixelDataSize(width, height, RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8));
3185 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
3186
3188
3189 // Clean up temporal fbo
3190 rlUnloadFramebuffer(fboId);
3191#endif
3192
3193 return pixels;
3194}
3195
3196
3197// Read screen pixel data (color buffer)
3198unsigned char *rlReadScreenPixels(int width, int height)
3199{
3200 unsigned char *screenData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
3201
3202 // NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
3203 // NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly!
3204 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData);
3205
3206 // Flip image vertically!
3207 unsigned char *imgData = (unsigned char *)RL_MALLOC(width*height*4*sizeof(unsigned char));
3208
3209 for (int y = height - 1; y >= 0; y--)
3210 {
3211 for (int x = 0; x < (width*4); x++)
3212 {
3213 imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; // Flip line
3214
3215 // Set alpha component value to 255 (no trasparent image retrieval)
3216 // NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it!
3217 if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255;
3218 }
3219 }
3220
3221 RL_FREE(screenData);
3222
3223 return imgData; // NOTE: image data should be freed
3224}
3225
3226// Framebuffer management (fbo)
3227//-----------------------------------------------------------------------------------------
3228// Load a framebuffer to be used for rendering
3229// NOTE: No textures attached
3230unsigned int rlLoadFramebuffer(int width, int height)
3231{
3232 unsigned int fboId = 0;
3233
3234#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
3235 glGenFramebuffers(1, &fboId); // Create the framebuffer object
3236 glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer
3237#endif
3238
3239 return fboId;
3240}
3241
3242// Attach color buffer texture to an fbo (unloads previous attachment)
3243// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
3244void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel)
3245{
3246#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
3248
3249 switch (attachType)
3250 {
3259 {
3263
3264 } break;
3266 {
3269
3270 } break;
3272 {
3275
3276 } break;
3277 default: break;
3278 }
3279
3281#endif
3282}
3283
3284// Verify render texture is complete
3285bool rlFramebufferComplete(unsigned int id)
3286{
3287 bool result = false;
3288
3289#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
3291
3293
3294 if (status != GL_FRAMEBUFFER_COMPLETE)
3295 {
3296 switch (status)
3297 {
3298 case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", id); break;
3299 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", id); break;
3300#if defined(GRAPHICS_API_OPENGL_ES2)
3301 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", id); break;
3302#endif
3303 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(RL_LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", id); break;
3304 default: break;
3305 }
3306 }
3307
3309
3310 result = (status == GL_FRAMEBUFFER_COMPLETE);
3311#endif
3312
3313 return result;
3314}
3315
3316// Unload framebuffer from GPU memory
3317// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
3318void rlUnloadFramebuffer(unsigned int id)
3319{
3320#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(RLGL_RENDER_TEXTURES_HINT)
3321
3322 // Query depth attachment to automatically delete texture/renderbuffer
3323 int depthType = 0, depthId = 0;
3324 glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type
3327
3328 unsigned int depthIdU = (unsigned int)depthId;
3329 if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU);
3330 else if (depthType == GL_RENDERBUFFER) glDeleteTextures(1, &depthIdU);
3331
3332 // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
3333 // the texture image is automatically detached from the currently bound framebuffer.
3334
3336 glDeleteFramebuffers(1, &id);
3337
3338 TRACELOG(RL_LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id);
3339#endif
3340}
3341
3342// Vertex data management
3343//-----------------------------------------------------------------------------------------
3344// Load a new attributes buffer
3345unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic)
3346{
3347 unsigned int id = 0;
3348
3349#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3350 glGenBuffers(1, &id);
3353#endif
3354
3355 return id;
3356}
3357
3358// Load a new attributes element buffer
3359unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic)
3360{
3361 unsigned int id = 0;
3362
3363#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3364 glGenBuffers(1, &id);
3367#endif
3368
3369 return id;
3370}
3371
3372// Enable vertex buffer (VBO)
3373void rlEnableVertexBuffer(unsigned int id)
3374{
3375#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3377#endif
3378}
3379
3380// Disable vertex buffer (VBO)
3381void rlDisableVertexBuffer(void)
3382{
3383#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3385#endif
3386}
3387
3388// Enable vertex buffer element (VBO element)
3389void rlEnableVertexBufferElement(unsigned int id)
3390{
3391#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3393#endif
3394}
3395
3396// Disable vertex buffer element (VBO element)
3398{
3399#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3401#endif
3402}
3403
3404// Update vertex buffer with new data
3405// NOTE: dataSize and offset must be provided in bytes
3406void rlUpdateVertexBuffer(unsigned int id, const void *data, int dataSize, int offset)
3407{
3408#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3410 glBufferSubData(GL_ARRAY_BUFFER, offset, dataSize, data);
3411#endif
3412}
3413
3414// Update vertex buffer elements with new data
3415// NOTE: dataSize and offset must be provided in bytes
3416void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset)
3417{
3418#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3420 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, dataSize, data);
3421#endif
3422}
3423
3424// Enable vertex array object (VAO)
3425bool rlEnableVertexArray(unsigned int vaoId)
3426{
3427 bool result = false;
3428#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3429 if (RLGL.ExtSupported.vao)
3430 {
3431 glBindVertexArray(vaoId);
3432 result = true;
3433 }
3434#endif
3435 return result;
3436}
3437
3438// Disable vertex array object (VAO)
3439void rlDisableVertexArray(void)
3440{
3441#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3442 if (RLGL.ExtSupported.vao) glBindVertexArray(0);
3443#endif
3444}
3445
3446// Enable vertex attribute index
3447void rlEnableVertexAttribute(unsigned int index)
3448{
3449#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3451#endif
3452}
3453
3454// Disable vertex attribute index
3455void rlDisableVertexAttribute(unsigned int index)
3456{
3457#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3459#endif
3460}
3461
3462// Draw vertex array
3463void rlDrawVertexArray(int offset, int count)
3464{
3465 glDrawArrays(GL_TRIANGLES, offset, count);
3466}
3467
3468// Draw vertex array elements
3469void rlDrawVertexArrayElements(int offset, int count, const void *buffer)
3470{
3471 glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)buffer + offset);
3472}
3473
3474// Draw vertex array instanced
3475void rlDrawVertexArrayInstanced(int offset, int count, int instances)
3476{
3477#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3478 glDrawArraysInstanced(GL_TRIANGLES, 0, count, instances);
3479#endif
3480}
3481
3482// Draw vertex array elements instanced
3483void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances)
3484{
3485#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3486 glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const unsigned short *)buffer + offset, instances);
3487#endif
3488}
3489
3490#if defined(GRAPHICS_API_OPENGL_11)
3491// Enable vertex state pointer
3492void rlEnableStatePointer(int vertexAttribType, void *buffer)
3493{
3494 if (buffer != NULL) glEnableClientState(vertexAttribType);
3495 switch (vertexAttribType)
3496 {
3497 case GL_VERTEX_ARRAY: glVertexPointer(3, GL_FLOAT, 0, buffer); break;
3498 case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(2, GL_FLOAT, 0, buffer); break;
3499 case GL_NORMAL_ARRAY: if (buffer != NULL) glNormalPointer(GL_FLOAT, 0, buffer); break;
3500 case GL_COLOR_ARRAY: if (buffer != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, buffer); break;
3501 //case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors
3502 default: break;
3503 }
3504}
3505
3506// Disable vertex state pointer
3507void rlDisableStatePointer(int vertexAttribType)
3508{
3509 glDisableClientState(vertexAttribType);
3510}
3511#endif
3512
3513// Load vertex array object (VAO)
3514unsigned int rlLoadVertexArray(void)
3515{
3516 unsigned int vaoId = 0;
3517#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3518 if (RLGL.ExtSupported.vao)
3519 {
3520 glGenVertexArrays(1, &vaoId);
3521 }
3522#endif
3523 return vaoId;
3524}
3525
3526// Set vertex attribute
3527void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer)
3528{
3529#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3530 glVertexAttribPointer(index, compSize, type, normalized, stride, pointer);
3531#endif
3532}
3533
3534// Set vertex attribute divisor
3535void rlSetVertexAttributeDivisor(unsigned int index, int divisor)
3536{
3537#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3538 glVertexAttribDivisor(index, divisor);
3539#endif
3540}
3541
3542// Unload vertex array object (VAO)
3543void rlUnloadVertexArray(unsigned int vaoId)
3544{
3545#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3546 if (RLGL.ExtSupported.vao)
3547 {
3549 glDeleteVertexArrays(1, &vaoId);
3550 TRACELOG(RL_LOG_INFO, "VAO: [ID %i] Unloaded vertex array data from VRAM (GPU)", vaoId);
3551 }
3552#endif
3553}
3554
3555// Unload vertex buffer (VBO)
3556void rlUnloadVertexBuffer(unsigned int vboId)
3557{
3558#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3559 glDeleteBuffers(1, &vboId);
3560 //TRACELOG(RL_LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)");
3561#endif
3562}
3563
3564// Shaders management
3565//-----------------------------------------------------------------------------------------------
3566// Load shader from code strings
3567// NOTE: If shader string is NULL, using default vertex/fragment shaders
3568unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
3569{
3570 unsigned int id = 0;
3571
3572#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3573 unsigned int vertexShaderId = 0;
3574 unsigned int fragmentShaderId = 0;
3575
3576 // Compile vertex shader (if provided)
3577 if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER);
3578 // In case no vertex shader was provided or compilation failed, we use default vertex shader
3579 if (vertexShaderId == 0) vertexShaderId = RLGL.State.defaultVShaderId;
3580
3581 // Compile fragment shader (if provided)
3582 if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER);
3583 // In case no fragment shader was provided or compilation failed, we use default fragment shader
3584 if (fragmentShaderId == 0) fragmentShaderId = RLGL.State.defaultFShaderId;
3585
3586 // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id
3587 if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId;
3588 else
3589 {
3590 // One of or both shader are new, we need to compile a new shader program
3591 id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId);
3592
3593 // We can detach and delete vertex/fragment shaders (if not default ones)
3594 // NOTE: We detach shader before deletion to make sure memory is freed
3595 if (vertexShaderId != RLGL.State.defaultVShaderId)
3596 {
3597 glDetachShader(id, vertexShaderId);
3598 glDeleteShader(vertexShaderId);
3599 }
3600 if (fragmentShaderId != RLGL.State.defaultFShaderId)
3601 {
3602 glDetachShader(id, fragmentShaderId);
3603 glDeleteShader(fragmentShaderId);
3604 }
3605
3606 // In case shader program loading failed, we assign default shader
3607 if (id == 0)
3608 {
3609 // In case shader loading fails, we return the default shader
3610 TRACELOG(RL_LOG_WARNING, "SHADER: Failed to load custom shader code, using default shader");
3611 id = RLGL.State.defaultShaderId;
3612 }
3613 /*
3614 else
3615 {
3616 // Get available shader uniforms
3617 // NOTE: This information is useful for debug...
3618 int uniformCount = -1;
3619 glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount);
3620
3621 for (int i = 0; i < uniformCount; i++)
3622 {
3623 int namelen = -1;
3624 int num = -1;
3625 char name[256] = { 0 }; // Assume no variable names longer than 256
3626 GLenum type = GL_ZERO;
3627
3628 // Get the name of the uniforms
3629 glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name);
3630
3631 name[namelen] = 0;
3632 TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name));
3633 }
3634 }
3635 */
3636 }
3637#endif
3638
3639 return id;
3640}
3641
3642// Compile custom shader and return shader id
3643unsigned int rlCompileShader(const char *shaderCode, int type)
3644{
3645 unsigned int shader = 0;
3646
3647#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3648 shader = glCreateShader(type);
3649 glShaderSource(shader, 1, &shaderCode, NULL);
3650
3651 GLint success = 0;
3652 glCompileShader(shader);
3653 glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
3654
3655 if (success == GL_FALSE)
3656 {
3657 switch (type)
3658 {
3659 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile vertex shader code", shader); break;
3660 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile fragment shader code", shader); break;
3661 //case GL_GEOMETRY_SHADER:
3662 #if defined(GRAPHICS_API_OPENGL_43)
3663 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break;
3664 #endif
3665 default: break;
3666 }
3667
3668 int maxLength = 0;
3669 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
3670
3671 if (maxLength > 0)
3672 {
3673 int length = 0;
3674 char *log = RL_CALLOC(maxLength, sizeof(char));
3675 glGetShaderInfoLog(shader, maxLength, &length, log);
3676 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log);
3677 RL_FREE(log);
3678 }
3679 }
3680 else
3681 {
3682 switch (type)
3683 {
3684 case GL_VERTEX_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Vertex shader compiled successfully", shader); break;
3685 case GL_FRAGMENT_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Fragment shader compiled successfully", shader); break;
3686 //case GL_GEOMETRY_SHADER:
3687 #if defined(GRAPHICS_API_OPENGL_43)
3688 case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break;
3689 #endif
3690 default: break;
3691 }
3692 }
3693#endif
3694
3695 return shader;
3696}
3697
3698// Load custom shader strings and return program id
3699unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
3700{
3701 unsigned int program = 0;
3702
3703#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3704 GLint success = 0;
3705 program = glCreateProgram();
3706
3707 glAttachShader(program, vShaderId);
3708 glAttachShader(program, fShaderId);
3709
3710 // NOTE: Default attribute shader locations must be binded before linking
3717
3718 // NOTE: If some attrib name is no found on the shader, it locations becomes -1
3719
3720 glLinkProgram(program);
3721
3722 // NOTE: All uniform variables are intitialised to 0 when a program links
3723
3724 glGetProgramiv(program, GL_LINK_STATUS, &success);
3725
3726 if (success == GL_FALSE)
3727 {
3728 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program);
3729
3730 int maxLength = 0;
3731 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
3732
3733 if (maxLength > 0)
3734 {
3735 int length = 0;
3736 char *log = RL_CALLOC(maxLength, sizeof(char));
3737 glGetProgramInfoLog(program, maxLength, &length, log);
3738 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log);
3739 RL_FREE(log);
3740 }
3741
3742 glDeleteProgram(program);
3743
3744 program = 0;
3745 }
3746 else
3747 {
3748 // Get the size of compiled shader program (not available on OpenGL ES 2.0)
3749 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero.
3750 //GLint binarySize = 0;
3751 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
3752
3753 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Program shader loaded successfully", program);
3754 }
3755#endif
3756 return program;
3757}
3758
3759// Unload shader program
3760void rlUnloadShaderProgram(unsigned int id)
3761{
3762#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3763 glDeleteProgram(id);
3764
3765 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", id);
3766#endif
3767}
3768
3769// Get shader location uniform
3770int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
3771{
3772 int location = -1;
3773#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3774 location = glGetUniformLocation(shaderId, uniformName);
3775
3776 if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName);
3777 else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location);
3778#endif
3779 return location;
3780}
3781
3782// Get shader location attribute
3783int rlGetLocationAttrib(unsigned int shaderId, const char *attribName)
3784{
3785 int location = -1;
3786#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3787 location = glGetAttribLocation(shaderId, attribName);
3788
3789 if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName);
3790 else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location);
3791#endif
3792 return location;
3793}
3794
3795// Set shader value uniform
3796void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
3797{
3798#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3799 switch (uniformType)
3800 {
3801 case RL_SHADER_UNIFORM_FLOAT: glUniform1fv(locIndex, count, (float *)value); break;
3802 case RL_SHADER_UNIFORM_VEC2: glUniform2fv(locIndex, count, (float *)value); break;
3803 case RL_SHADER_UNIFORM_VEC3: glUniform3fv(locIndex, count, (float *)value); break;
3804 case RL_SHADER_UNIFORM_VEC4: glUniform4fv(locIndex, count, (float *)value); break;
3805 case RL_SHADER_UNIFORM_INT: glUniform1iv(locIndex, count, (int *)value); break;
3806 case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break;
3807 case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
3808 case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
3809 case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
3810 default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
3811 }
3812#endif
3813}
3814
3815// Set shader value attribute
3816void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count)
3817{
3818#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3819 switch (attribType)
3820 {
3821 case RL_SHADER_ATTRIB_FLOAT: if (count == 1) glVertexAttrib1fv(locIndex, (float *)value); break;
3822 case RL_SHADER_ATTRIB_VEC2: if (count == 2) glVertexAttrib2fv(locIndex, (float *)value); break;
3823 case RL_SHADER_ATTRIB_VEC3: if (count == 3) glVertexAttrib3fv(locIndex, (float *)value); break;
3824 case RL_SHADER_ATTRIB_VEC4: if (count == 4) glVertexAttrib4fv(locIndex, (float *)value); break;
3825 default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set attrib default value, data type not recognized");
3826 }
3827#endif
3828}
3829
3830// Set shader value uniform matrix
3831void rlSetUniformMatrix(int locIndex, Matrix mat)
3832{
3833#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3834 float matfloat[16] = {
3835 mat.m0, mat.m1, mat.m2, mat.m3,
3836 mat.m4, mat.m5, mat.m6, mat.m7,
3837 mat.m8, mat.m9, mat.m10, mat.m11,
3838 mat.m12, mat.m13, mat.m14, mat.m15
3839 };
3840 glUniformMatrix4fv(locIndex, 1, false, matfloat);
3841#endif
3842}
3843
3844// Set shader value uniform sampler
3845void rlSetUniformSampler(int locIndex, unsigned int textureId)
3846{
3847#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3848 // Check if texture is already active
3849 for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) if (RLGL.State.activeTextureId[i] == textureId) return;
3850
3851 // Register a new active texture for the internal batch system
3852 // NOTE: Default texture is always activated as GL_TEXTURE0
3853 for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++)
3854 {
3855 if (RLGL.State.activeTextureId[i] == 0)
3856 {
3857 glUniform1i(locIndex, 1 + i); // Activate new texture unit
3858 RLGL.State.activeTextureId[i] = textureId; // Save texture id for binding on drawing
3859 break;
3860 }
3861 }
3862#endif
3863}
3864
3865// Set shader currently active (id and locations)
3866void rlSetShader(unsigned int id, int *locs)
3867{
3868#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
3869 if (RLGL.State.currentShaderId != id)
3870 {
3871 rlDrawRenderBatch(RLGL.currentBatch);
3872 RLGL.State.currentShaderId = id;
3873 RLGL.State.currentShaderLocs = locs;
3874 }
3875#endif
3876}
3877
3878// Load compute shader program
3879unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
3880{
3881 unsigned int program = 0;
3882
3883#if defined(GRAPHICS_API_OPENGL_43)
3884 GLint success = 0;
3885 program = glCreateProgram();
3886 glAttachShader(program, shaderId);
3887 glLinkProgram(program);
3888
3889 // NOTE: All uniform variables are intitialised to 0 when a program links
3890
3891 glGetProgramiv(program, GL_LINK_STATUS, &success);
3892
3893 if (success == GL_FALSE)
3894 {
3895 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to link compute shader program", program);
3896
3897 int maxLength = 0;
3898 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
3899
3900 if (maxLength > 0)
3901 {
3902 int length = 0;
3903 char *log = RL_CALLOC(maxLength, sizeof(char));
3904 glGetProgramInfoLog(program, maxLength, &length, log);
3905 TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log);
3906 RL_FREE(log);
3907 }
3908
3909 glDeleteProgram(program);
3910
3911 program = 0;
3912 }
3913 else
3914 {
3915 // Get the size of compiled shader program (not available on OpenGL ES 2.0)
3916 // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero.
3917 //GLint binarySize = 0;
3918 //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
3919
3920 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program);
3921 }
3922#endif
3923
3924 return program;
3925}
3926
3927// Dispatch compute shader (equivalent to *draw* for graphics pilepine)
3928void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ)
3929{
3930#if defined(GRAPHICS_API_OPENGL_43)
3931 glDispatchCompute(groupX, groupY, groupZ);
3932#endif
3933}
3934
3935// Load shader storage buffer object (SSBO)
3936unsigned int rlLoadShaderBuffer(unsigned long long size, const void *data, int usageHint)
3937{
3938 unsigned int ssbo = 0;
3939
3940#if defined(GRAPHICS_API_OPENGL_43)
3941 glGenBuffers(1, &ssbo);
3943 glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, usageHint? usageHint : RL_STREAM_COPY);
3946#endif
3947
3948 return ssbo;
3949}
3950
3951// Unload shader storage buffer object (SSBO)
3952void rlUnloadShaderBuffer(unsigned int ssboId)
3953{
3954#if defined(GRAPHICS_API_OPENGL_43)
3955 glDeleteBuffers(1, &ssboId);
3956#endif
3957}
3958
3959// Update SSBO buffer data
3960void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned long long dataSize, unsigned long long offset)
3961{
3962#if defined(GRAPHICS_API_OPENGL_43)
3964 glBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, dataSize, data);
3965#endif
3966}
3967
3968// Get SSBO buffer size
3969unsigned long long rlGetShaderBufferSize(unsigned int id)
3970{
3971 long long size = 0;
3972
3973#if defined(GRAPHICS_API_OPENGL_43)
3976#endif
3977
3978 return (size > 0)? size : 0;
3979}
3980
3981// Read SSBO buffer data
3982void rlReadShaderBufferElements(unsigned int id, void *dest, unsigned long long count, unsigned long long offset)
3983{
3984#if defined(GRAPHICS_API_OPENGL_43)
3986 glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, offset, count, dest);
3987#endif
3988}
3989
3990// Bind SSBO buffer
3991void rlBindShaderBuffer(unsigned int id, unsigned int index)
3992{
3993#if defined(GRAPHICS_API_OPENGL_43)
3995#endif
3996}
3997
3998// Copy SSBO buffer data
3999void rlCopyBuffersElements(unsigned int destId, unsigned int srcId, unsigned long long destOffset, unsigned long long srcOffset, unsigned long long count)
4000{
4001#if defined(GRAPHICS_API_OPENGL_43)
4004 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, destOffset, count);
4005#endif
4006}
4007
4008// Bind image texture
4009void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly)
4010{
4011#if defined(GRAPHICS_API_OPENGL_43)
4012 int glInternalFormat = 0, glFormat = 0, glType = 0;
4013
4014 rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
4015 glBindImageTexture(index, id, 0, 0, 0, readonly ? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat);
4016#endif
4017}
4018
4019// Matrix state management
4020//-----------------------------------------------------------------------------------------
4021// Get internal modelview matrix
4023{
4024 Matrix matrix = rlMatrixIdentity();
4025#if defined(GRAPHICS_API_OPENGL_11)
4026 float mat[16];
4028 matrix.m0 = mat[0];
4029 matrix.m1 = mat[1];
4030 matrix.m2 = mat[2];
4031 matrix.m3 = mat[3];
4032 matrix.m4 = mat[4];
4033 matrix.m5 = mat[5];
4034 matrix.m6 = mat[6];
4035 matrix.m7 = mat[7];
4036 matrix.m8 = mat[8];
4037 matrix.m9 = mat[9];
4038 matrix.m10 = mat[10];
4039 matrix.m11 = mat[11];
4040 matrix.m12 = mat[12];
4041 matrix.m13 = mat[13];
4042 matrix.m14 = mat[14];
4043 matrix.m15 = mat[15];
4044#else
4045 matrix = RLGL.State.modelview;
4046#endif
4047 return matrix;
4048}
4049
4050// Get internal projection matrix
4052{
4053#if defined(GRAPHICS_API_OPENGL_11)
4054 float mat[16];
4056 Matrix m;
4057 m.m0 = mat[0];
4058 m.m1 = mat[1];
4059 m.m2 = mat[2];
4060 m.m3 = mat[3];
4061 m.m4 = mat[4];
4062 m.m5 = mat[5];
4063 m.m6 = mat[6];
4064 m.m7 = mat[7];
4065 m.m8 = mat[8];
4066 m.m9 = mat[9];
4067 m.m10 = mat[10];
4068 m.m11 = mat[11];
4069 m.m12 = mat[12];
4070 m.m13 = mat[13];
4071 m.m14 = mat[14];
4072 m.m15 = mat[15];
4073 return m;
4074#else
4075 return RLGL.State.projection;
4076#endif
4077}
4078
4079// Get internal accumulated transform matrix
4081{
4082 Matrix mat = rlMatrixIdentity();
4083#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4084 // TODO: Consider possible transform matrices in the RLGL.State.stack
4085 // Is this the right order? or should we start with the first stored matrix instead of the last one?
4086 //Matrix matStackTransform = rlMatrixIdentity();
4087 //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform);
4088 mat = RLGL.State.transform;
4089#endif
4090 return mat;
4091}
4092
4093// Get internal projection matrix for stereo render (selected eye)
4095{
4096 Matrix mat = rlMatrixIdentity();
4097#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4098 mat = RLGL.State.projectionStereo[eye];
4099#endif
4100 return mat;
4101}
4102
4103// Get internal view offset matrix for stereo render (selected eye)
4105{
4106 Matrix mat = rlMatrixIdentity();
4107#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4108 mat = RLGL.State.viewOffsetStereo[eye];
4109#endif
4110 return mat;
4111}
4112
4113// Set a custom modelview matrix (replaces internal modelview matrix)
4115{
4116#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4117 RLGL.State.modelview = view;
4118#endif
4119}
4120
4121// Set a custom projection matrix (replaces internal projection matrix)
4122void rlSetMatrixProjection(Matrix projection)
4123{
4124#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4125 RLGL.State.projection = projection;
4126#endif
4127}
4128
4129// Set eyes projection matrices for stereo rendering
4131{
4132#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4133 RLGL.State.projectionStereo[0] = right;
4134 RLGL.State.projectionStereo[1] = left;
4135#endif
4136}
4137
4138// Set eyes view offsets matrices for stereo rendering
4140{
4141#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4142 RLGL.State.viewOffsetStereo[0] = right;
4143 RLGL.State.viewOffsetStereo[1] = left;
4144#endif
4145}
4146
4147// Load and draw a quad in NDC
4148void rlLoadDrawQuad(void)
4149{
4150#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4151 unsigned int quadVAO = 0;
4152 unsigned int quadVBO = 0;
4153
4154 float vertices[] = {
4155 // Positions Texcoords
4156 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
4157 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
4158 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
4159 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
4160 };
4161
4162 // Gen VAO to contain VBO
4163 glGenVertexArrays(1, &quadVAO);
4164 glBindVertexArray(quadVAO);
4165
4166 // Gen and fill vertex buffer (VBO)
4167 glGenBuffers(1, &quadVBO);
4168 glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
4169 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
4170
4171 // Bind vertex attributes (position, texcoords)
4173 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)0); // Positions
4175 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void *)(3*sizeof(float))); // Texcoords
4176
4177 // Draw quad
4178 glBindVertexArray(quadVAO);
4181
4182 // Delete buffers (VBO and VAO)
4183 glDeleteBuffers(1, &quadVBO);
4184 glDeleteVertexArrays(1, &quadVAO);
4185#endif
4186}
4187
4188// Load and draw a cube in NDC
4189void rlLoadDrawCube(void)
4190{
4191#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4192 unsigned int cubeVAO = 0;
4193 unsigned int cubeVBO = 0;
4194
4195 float vertices[] = {
4196 // Positions Normals Texcoords
4197 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
4198 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
4199 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
4200 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
4201 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
4202 -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
4203 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
4204 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
4205 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
4206 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
4207 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
4208 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
4209 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
4210 -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
4211 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
4212 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
4213 -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
4214 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
4215 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
4216 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
4217 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
4218 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
4219 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
4220 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
4221 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
4222 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
4223 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
4224 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
4225 -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
4226 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
4227 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
4228 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
4229 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
4230 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
4231 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
4232 -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
4233 };
4234
4235 // Gen VAO to contain VBO
4236 glGenVertexArrays(1, &cubeVAO);
4237 glBindVertexArray(cubeVAO);
4238
4239 // Gen and fill vertex buffer (VBO)
4240 glGenBuffers(1, &cubeVBO);
4241 glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
4242 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
4243
4244 // Bind vertex attributes (position, normals, texcoords)
4245 glBindVertexArray(cubeVAO);
4247 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)0); // Positions
4249 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(3*sizeof(float))); // Normals
4251 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *)(6*sizeof(float))); // Texcoords
4254
4255 // Draw cube
4256 glBindVertexArray(cubeVAO);
4257 glDrawArrays(GL_TRIANGLES, 0, 36);
4259
4260 // Delete VBO and VAO
4261 glDeleteBuffers(1, &cubeVBO);
4262 glDeleteVertexArrays(1, &cubeVAO);
4263#endif
4264}
4265
4266// Get name string for pixel format
4267const char *rlGetPixelFormatName(unsigned int format)
4268{
4269 switch (format)
4270 {
4271 case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: return "GRAYSCALE"; break; // 8 bit per pixel (no alpha)
4272 case RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: return "GRAY_ALPHA"; break; // 8*2 bpp (2 channels)
4273 case RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5: return "R5G6B5"; break; // 16 bpp
4274 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: return "R8G8B8"; break; // 24 bpp
4275 case RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: return "R5G5B5A1"; break; // 16 bpp (1 bit alpha)
4276 case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: return "R4G4B4A4"; break; // 16 bpp (4 bit alpha)
4277 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: return "R8G8B8A8"; break; // 32 bpp
4278 case RL_PIXELFORMAT_UNCOMPRESSED_R32: return "R32"; break; // 32 bpp (1 channel - float)
4279 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: return "R32G32B32"; break; // 32*3 bpp (3 channels - float)
4280 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: return "R32G32B32A32"; break; // 32*4 bpp (4 channels - float)
4281 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGB: return "DXT1_RGB"; break; // 4 bpp (no alpha)
4282 case RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA: return "DXT1_RGBA"; break; // 4 bpp (1 bit alpha)
4283 case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA: return "DXT3_RGBA"; break; // 8 bpp
4284 case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA: return "DXT5_RGBA"; break; // 8 bpp
4285 case RL_PIXELFORMAT_COMPRESSED_ETC1_RGB: return "ETC1_RGB"; break; // 4 bpp
4286 case RL_PIXELFORMAT_COMPRESSED_ETC2_RGB: return "ETC2_RGB"; break; // 4 bpp
4287 case RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: return "ETC2_RGBA"; break; // 8 bpp
4288 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGB: return "PVRT_RGB"; break; // 4 bpp
4289 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: return "PVRT_RGBA"; break; // 4 bpp
4290 case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: return "ASTC_4x4_RGBA"; break; // 8 bpp
4291 case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: return "ASTC_8x8_RGBA"; break; // 2 bpp
4292 default: return "UNKNOWN"; break;
4293 }
4294}
4295
4296//----------------------------------------------------------------------------------
4297// Module specific Functions Definition
4298//----------------------------------------------------------------------------------
4299#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
4300// Load default shader (just vertex positioning and texture coloring)
4301// NOTE: This shader program is used for internal buffers
4302// NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs
4303static void rlLoadShaderDefault(void)
4304{
4305 RLGL.State.defaultShaderLocs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int));
4306
4307 // NOTE: All locations must be reseted to -1 (no location)
4308 for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) RLGL.State.defaultShaderLocs[i] = -1;
4309
4310 // Vertex shader directly defined, no external file required
4311 const char *defaultVShaderCode =
4312#if defined(GRAPHICS_API_OPENGL_21)
4313 "#version 120 \n"
4314 "attribute vec3 vertexPosition; \n"
4315 "attribute vec2 vertexTexCoord; \n"
4316 "attribute vec4 vertexColor; \n"
4317 "varying vec2 fragTexCoord; \n"
4318 "varying vec4 fragColor; \n"
4319#elif defined(GRAPHICS_API_OPENGL_33)
4320 "#version 330 \n"
4321 "in vec3 vertexPosition; \n"
4322 "in vec2 vertexTexCoord; \n"
4323 "in vec4 vertexColor; \n"
4324 "out vec2 fragTexCoord; \n"
4325 "out vec4 fragColor; \n"
4326#endif
4327#if defined(GRAPHICS_API_OPENGL_ES2)
4328 "#version 100 \n"
4329 "attribute vec3 vertexPosition; \n"
4330 "attribute vec2 vertexTexCoord; \n"
4331 "attribute vec4 vertexColor; \n"
4332 "varying vec2 fragTexCoord; \n"
4333 "varying vec4 fragColor; \n"
4334#endif
4335 "uniform mat4 mvp; \n"
4336 "void main() \n"
4337 "{ \n"
4338 " fragTexCoord = vertexTexCoord; \n"
4339 " fragColor = vertexColor; \n"
4340 " gl_Position = mvp*vec4(vertexPosition, 1.0); \n"
4341 "} \n";
4342
4343 // Fragment shader directly defined, no external file required
4344 const char *defaultFShaderCode =
4345#if defined(GRAPHICS_API_OPENGL_21)
4346 "#version 120 \n"
4347 "varying vec2 fragTexCoord; \n"
4348 "varying vec4 fragColor; \n"
4349 "uniform sampler2D texture0; \n"
4350 "uniform vec4 colDiffuse; \n"
4351 "void main() \n"
4352 "{ \n"
4353 " vec4 texelColor = texture2D(texture0, fragTexCoord); \n"
4354 " gl_FragColor = texelColor*colDiffuse*fragColor; \n"
4355 "} \n";
4356#elif defined(GRAPHICS_API_OPENGL_33)
4357 "#version 330 \n"
4358 "in vec2 fragTexCoord; \n"
4359 "in vec4 fragColor; \n"
4360 "out vec4 finalColor; \n"
4361 "uniform sampler2D texture0; \n"
4362 "uniform vec4 colDiffuse; \n"
4363 "void main() \n"
4364 "{ \n"
4365 " vec4 texelColor = texture(texture0, fragTexCoord); \n"
4366 " finalColor = texelColor*colDiffuse*fragColor; \n"
4367 "} \n";
4368#endif
4369#if defined(GRAPHICS_API_OPENGL_ES2)
4370 "#version 100 \n"
4371 "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
4372 "varying vec2 fragTexCoord; \n"
4373 "varying vec4 fragColor; \n"
4374 "uniform sampler2D texture0; \n"
4375 "uniform vec4 colDiffuse; \n"
4376 "void main() \n"
4377 "{ \n"
4378 " vec4 texelColor = texture2D(texture0, fragTexCoord); \n"
4379 " gl_FragColor = texelColor*colDiffuse*fragColor; \n"
4380 "} \n";
4381#endif
4382
4383 // NOTE: Compiled vertex/fragment shaders are not deleted,
4384 // they are kept for re-use as default shaders in case some shader loading fails
4385 RLGL.State.defaultVShaderId = rlCompileShader(defaultVShaderCode, GL_VERTEX_SHADER); // Compile default vertex shader
4386 RLGL.State.defaultFShaderId = rlCompileShader(defaultFShaderCode, GL_FRAGMENT_SHADER); // Compile default fragment shader
4387
4388 RLGL.State.defaultShaderId = rlLoadShaderProgram(RLGL.State.defaultVShaderId, RLGL.State.defaultFShaderId);
4389
4390 if (RLGL.State.defaultShaderId > 0)
4391 {
4392 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", RLGL.State.defaultShaderId);
4393
4394 // Set default shader locations: attributes locations
4395 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_POSITION] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexPosition");
4396 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_TEXCOORD01] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexTexCoord");
4397 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_VERTEX_COLOR] = glGetAttribLocation(RLGL.State.defaultShaderId, "vertexColor");
4398
4399 // Set default shader locations: uniform locations
4400 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MATRIX_MVP] = glGetUniformLocation(RLGL.State.defaultShaderId, "mvp");
4401 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_COLOR_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "colDiffuse");
4402 RLGL.State.defaultShaderLocs[RL_SHADER_LOC_MAP_DIFFUSE] = glGetUniformLocation(RLGL.State.defaultShaderId, "texture0");
4403 }
4404 else TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", RLGL.State.defaultShaderId);
4405}
4406
4407// Unload default shader
4408// NOTE: Unloads: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs
4409static void rlUnloadShaderDefault(void)
4410{
4411 glUseProgram(0);
4412
4413 glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultVShaderId);
4414 glDetachShader(RLGL.State.defaultShaderId, RLGL.State.defaultFShaderId);
4415 glDeleteShader(RLGL.State.defaultVShaderId);
4416 glDeleteShader(RLGL.State.defaultFShaderId);
4417
4418 glDeleteProgram(RLGL.State.defaultShaderId);
4419
4420 RL_FREE(RLGL.State.defaultShaderLocs);
4421
4422 TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Default shader unloaded successfully", RLGL.State.defaultShaderId);
4423}
4424
4425#if defined(RLGL_SHOW_GL_DETAILS_INFO)
4426// Get compressed format official GL identifier name
4427static char *rlGetCompressedFormatName(int format)
4428{
4429 switch (format)
4430 {
4431 // GL_EXT_texture_compression_s3tc
4432 case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; break;
4433 case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; break;
4434 case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; break;
4435 case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; break;
4436 // GL_3DFX_texture_compression_FXT1
4437 case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX"; break;
4438 case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX"; break;
4439 // GL_IMG_texture_compression_pvrtc
4440 case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; break;
4441 case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; break;
4442 case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; break;
4443 case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; break;
4444 // GL_OES_compressed_ETC1_RGB8_texture
4445 case 0x8D64: return "GL_ETC1_RGB8_OES"; break;
4446 // GL_ARB_texture_compression_rgtc
4447 case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1"; break;
4448 case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1"; break;
4449 case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2"; break;
4450 case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2"; break;
4451 // GL_ARB_texture_compression_bptc
4452 case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; break;
4453 case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; break;
4454 case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; break;
4455 case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; break;
4456 // GL_ARB_ES3_compatibility
4457 case 0x9274: return "GL_COMPRESSED_RGB8_ETC2"; break;
4458 case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2"; break;
4459 case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break;
4460 case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; break;
4461 case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC"; break;
4462 case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; break;
4463 case 0x9270: return "GL_COMPRESSED_R11_EAC"; break;
4464 case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC"; break;
4465 case 0x9272: return "GL_COMPRESSED_RG11_EAC"; break;
4466 case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC"; break;
4467 // GL_KHR_texture_compression_astc_hdr
4468 case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"; break;
4469 case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"; break;
4470 case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"; break;
4471 case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"; break;
4472 case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"; break;
4473 case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"; break;
4474 case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"; break;
4475 case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"; break;
4476 case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"; break;
4477 case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"; break;
4478 case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"; break;
4479 case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"; break;
4480 case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"; break;
4481 case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"; break;
4482 case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; break;
4483 case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; break;
4484 case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; break;
4485 case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; break;
4486 case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; break;
4487 case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; break;
4488 case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; break;
4489 case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; break;
4490 case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; break;
4491 case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; break;
4492 case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; break;
4493 case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; break;
4494 case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; break;
4495 case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; break;
4496 default: return "GL_COMPRESSED_UNKNOWN"; break;
4497 }
4498}
4499#endif // RLGL_SHOW_GL_DETAILS_INFO
4500
4501#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
4502
4503#if defined(GRAPHICS_API_OPENGL_11)
4504// Mipmaps data is generated after image data
4505// NOTE: Only works with RGBA (4 bytes) data!
4506static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight)
4507{
4508 int mipmapCount = 1; // Required mipmap levels count (including base level)
4509 int width = baseWidth;
4510 int height = baseHeight;
4511 int size = baseWidth*baseHeight*4; // Size in bytes (will include mipmaps...), RGBA only
4512
4513 // Count mipmap levels required
4514 while ((width != 1) && (height != 1))
4515 {
4516 width /= 2;
4517 height /= 2;
4518
4519 TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
4520
4521 mipmapCount++;
4522
4523 size += (width*height*4); // Add mipmap size (in bytes)
4524 }
4525
4526 TRACELOGD("TEXTURE: Total mipmaps required: %i", mipmapCount);
4527 TRACELOGD("TEXTURE: Total size of data required: %i", size);
4528
4529 unsigned char *temp = RL_REALLOC(data, size);
4530
4531 if (temp != NULL) data = temp;
4532 else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to re-allocate required mipmaps memory");
4533
4534 width = baseWidth;
4535 height = baseHeight;
4536 size = (width*height*4); // RGBA: 4 bytes
4537
4538 // Generate mipmaps
4539 // NOTE: Every mipmap data is stored after data (RGBA - 4 bytes)
4540 unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4);
4541 unsigned char *mipmap = NULL;
4542 int offset = 0;
4543
4544 for (int i = 0; i < size; i += 4)
4545 {
4546 image[i] = data[i];
4547 image[i + 1] = data[i + 1];
4548 image[i + 2] = data[i + 2];
4549 image[i + 3] = data[i + 3];
4550 }
4551
4552 TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
4553
4554 for (int mip = 1; mip < mipmapCount; mip++)
4555 {
4556 mipmap = rlGenNextMipmapData(image, width, height);
4557
4558 offset += (width*height*4); // Size of last mipmap
4559
4560 width /= 2;
4561 height /= 2;
4562 size = (width*height*4); // Mipmap size to store after offset
4563
4564 // Add mipmap to data
4565 for (int i = 0; i < size; i += 4)
4566 {
4567 data[offset + i] = mipmap[i];
4568 data[offset + i + 1] = mipmap[i + 1];
4569 data[offset + i + 2] = mipmap[i + 2];
4570 data[offset + i + 3] = mipmap[i + 3];
4571 }
4572
4573 RL_FREE(image);
4574
4575 image = mipmap;
4576 mipmap = NULL;
4577 }
4578
4579 RL_FREE(mipmap); // free mipmap data
4580
4581 return mipmapCount;
4582}
4583
4584// Manual mipmap generation (basic scaling algorithm)
4585static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight)
4586{
4587 int x2 = 0;
4588 int y2 = 0;
4589 unsigned char prow[4] = { 0 };
4590 unsigned char pcol[4] = { 0 };
4591
4592 int width = srcWidth/2;
4593 int height = srcHeight/2;
4594
4595 unsigned char *mipmap = (unsigned char *)RL_MALLOC(width*height*4);
4596
4597 // Scaling algorithm works perfectly (box-filter)
4598 for (int y = 0; y < height; y++)
4599 {
4600 y2 = 2*y;
4601
4602 for (int x = 0; x < width; x++)
4603 {
4604 x2 = 2*x;
4605
4606 prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2;
4607 prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2;
4608 prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/2;
4609 prow[3] = (srcData[(y2*srcWidth + x2)*4 + 3] + srcData[(y2*srcWidth + x2 + 1)*4 + 3])/2;
4610
4611 pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2;
4612 pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2;
4613 pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/2;
4614 pcol[3] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 3] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 3])/2;
4615
4616 mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2;
4617 mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2;
4618 mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2;
4619 mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2;
4620 }
4621 }
4622
4623 TRACELOGD("TEXTURE: Mipmap generated successfully (%ix%i)", width, height);
4624
4625 return mipmap;
4626}
4627#endif // GRAPHICS_API_OPENGL_11
4628
4629// Get pixel data size in bytes (image or texture)
4630// NOTE: Size depends on pixel format
4631static int rlGetPixelDataSize(int width, int height, int format)
4632{
4633 int dataSize = 0; // Size in bytes
4634 int bpp = 0; // Bits per pixel
4635
4636 switch (format)
4637 {
4638 case RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
4642 case RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
4643 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
4644 case RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
4645 case RL_PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
4646 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
4647 case RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
4653 case RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
4657 case RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
4658 case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
4659 default: break;
4660 }
4661
4662 dataSize = width*height*bpp/8; // Total data size in bytes
4663
4664 // Most compressed formats works on 4x4 blocks,
4665 // if texture is smaller, minimum dataSize is 8 or 16
4666 if ((width < 4) && (height < 4))
4667 {
4668 if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA)) dataSize = 8;
4669 else if ((format >= RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
4670 }
4671
4672 return dataSize;
4673}
4674
4675// Auxiliar math functions
4676
4677// Get identity matrix
4678static Matrix rlMatrixIdentity(void)
4679{
4680 Matrix result = {
4681 1.0f, 0.0f, 0.0f, 0.0f,
4682 0.0f, 1.0f, 0.0f, 0.0f,
4683 0.0f, 0.0f, 1.0f, 0.0f,
4684 0.0f, 0.0f, 0.0f, 1.0f
4685 };
4686
4687 return result;
4688}
4689
4690// Get two matrix multiplication
4691// NOTE: When multiplying matrices... the order matters!
4692static Matrix rlMatrixMultiply(Matrix left, Matrix right)
4693{
4694 Matrix result = { 0 };
4695
4696 result.m0 = left.m0*right.m0 + left.m1*right.m4 + left.m2*right.m8 + left.m3*right.m12;
4697 result.m1 = left.m0*right.m1 + left.m1*right.m5 + left.m2*right.m9 + left.m3*right.m13;
4698 result.m2 = left.m0*right.m2 + left.m1*right.m6 + left.m2*right.m10 + left.m3*right.m14;
4699 result.m3 = left.m0*right.m3 + left.m1*right.m7 + left.m2*right.m11 + left.m3*right.m15;
4700 result.m4 = left.m4*right.m0 + left.m5*right.m4 + left.m6*right.m8 + left.m7*right.m12;
4701 result.m5 = left.m4*right.m1 + left.m5*right.m5 + left.m6*right.m9 + left.m7*right.m13;
4702 result.m6 = left.m4*right.m2 + left.m5*right.m6 + left.m6*right.m10 + left.m7*right.m14;
4703 result.m7 = left.m4*right.m3 + left.m5*right.m7 + left.m6*right.m11 + left.m7*right.m15;
4704 result.m8 = left.m8*right.m0 + left.m9*right.m4 + left.m10*right.m8 + left.m11*right.m12;
4705 result.m9 = left.m8*right.m1 + left.m9*right.m5 + left.m10*right.m9 + left.m11*right.m13;
4706 result.m10 = left.m8*right.m2 + left.m9*right.m6 + left.m10*right.m10 + left.m11*right.m14;
4707 result.m11 = left.m8*right.m3 + left.m9*right.m7 + left.m10*right.m11 + left.m11*right.m15;
4708 result.m12 = left.m12*right.m0 + left.m13*right.m4 + left.m14*right.m8 + left.m15*right.m12;
4709 result.m13 = left.m12*right.m1 + left.m13*right.m5 + left.m14*right.m9 + left.m15*right.m13;
4710 result.m14 = left.m12*right.m2 + left.m13*right.m6 + left.m14*right.m10 + left.m15*right.m14;
4711 result.m15 = left.m12*right.m3 + left.m13*right.m7 + left.m14*right.m11 + left.m15*right.m15;
4712
4713 return result;
4714}
4715
4716#endif // RLGL_IMPLEMENTATION
void * id
#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS
Definition: config.h:110
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT
Definition: config.h:125
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD
Definition: config.h:122
#define RL_MAX_MATRIX_STACK_SIZE
Definition: config.h:112
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR
Definition: config.h:124
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL
Definition: config.h:123
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION
Definition: config.h:121
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
Definition: config.h:126
#define GL_TEXTURE_COORD_ARRAY
Definition: gl.h:1279
#define glVertex2f
Definition: gl.h:3600
#define glTexCoordPointer
Definition: gl.h:3466
#define glColor3f
Definition: gl.h:2418
#define glColorPointer
Definition: gl.h:2488
#define glBegin
Definition: gl.h:2328
#define GL_COLOR_ARRAY
Definition: gl.h:284
#define GL_NORMAL_ARRAY
Definition: gl.h:832
#define GL_LUMINANCE_ALPHA
Definition: gl.h:706
#define glColor4f
Definition: gl.h:2450
#define glTranslatef
Definition: gl.h:3520
#define glPopMatrix
Definition: gl.h:3200
#define GL_SMOOTH
Definition: gl.h:1133
#define glMultMatrixf
Definition: gl.h:3034
#define GL_LUMINANCE
Definition: gl.h:695
#define glFrustum
Definition: gl.h:2680
#define glColor4ub
Definition: gl.h:2462
#define glOrtho
Definition: gl.h:3158
#define GL_PROJECTION
Definition: gl.h:938
#define glVertex3f
Definition: gl.h:3616
#define GL_MODELVIEW
Definition: gl.h:811
#define GL_PROJECTION_MATRIX
Definition: gl.h:939
#define glMatrixMode
Definition: gl.h:3030
#define glRotatef
Definition: gl.h:3302
#define GL_MODELVIEW_MATRIX
Definition: gl.h:812
#define glVertex2i
Definition: gl.h:3604
#define glNormalPointer
Definition: gl.h:3152
#define glScalef
Definition: gl.h:3324
#define glDisableClientState
Definition: gl.h:2562
#define glTexCoord2f
Definition: gl.h:3406
#define glPushMatrix
Definition: gl.h:3216
#define glShadeModel
Definition: gl.h:3368
#define glNormal3f
Definition: gl.h:3136
#define glEnd
Definition: gl.h:2604
#define glEnableClientState
Definition: gl.h:2598
#define glVertexPointer
Definition: gl.h:3790
#define GL_PERSPECTIVE_CORRECTION_HINT
Definition: gl.h:875
#define glLoadIdentity
Definition: gl.h:2988
#define GL_DEBUG_TYPE_MARKER
Definition: glad.h:474
#define GL_TRUE
Definition: glad.h:1817
#define glDisableVertexAttribArray
Definition: glad.h:4027
#define glGetError
Definition: glad.h:4277
#define glDebugMessageCallback
Definition: glad.h:3955
#define glAttachShader
Definition: glad.h:3679
#define GL_TEXTURE
Definition: glad.h:1602
#define glGetUniformLocation
Definition: glad.h:4495
#define GL_MAX_TEXTURE_SIZE
Definition: glad.h:1070
#define GL_COMPRESSED_RGB8_ETC2
Definition: glad.h:379
#define glClearColor
Definition: glad.h:3817
#define GL_NICEST
Definition: glad.h:1130
#define GL_COLOR_ATTACHMENT5
Definition: glad.h:347
#define glGetFloatv
Definition: glad.h:4283
#define GL_DEBUG_SEVERITY_LOW
Definition: glad.h:453
#define GL_TEXTURE0
Definition: glad.h:1603
#define GL_TEXTURE_MIN_FILTER
Definition: glad.h:1754
#define GL_VERSION
Definition: glad.h:1915
#define GL_FRAGMENT_SHADER
Definition: glad.h:630
#define glGenBuffers
Definition: glad.h:4173
#define GL_TEXTURE_WRAP_R
Definition: glad.h:1778
#define glUniformMatrix4fv
Definition: glad.h:5369
#define GL_MAX_UNIFORM_BLOCK_SIZE
Definition: glad.h:1076
void GLvoid
Definition: glad.h:2304
khronos_uint16_t GLushort
Definition: glad.h:2312
#define GL_DEBUG_SOURCE_THIRD_PARTY
Definition: glad.h:466
#define glCheckFramebufferStatus
Definition: glad.h:3791
#define glCullFace
Definition: glad.h:3953
#define glGetAttribLocation
Definition: glad.h:4235
#define glDeleteVertexArrays
Definition: glad.h:4003
#define GL_TEXTURE_WRAP_S
Definition: glad.h:1779
#define GL_DEBUG_TYPE_PORTABILITY
Definition: glad.h:480
#define glUniform3fv
Definition: glad.h:5281
#define GL_DEPTH_COMPONENT16
Definition: glad.h:497
#define GL_TEXTURE_CUBE_MAP
Definition: glad.h:1712
#define GL_COPY_WRITE_BUFFER
Definition: glad.h:426
#define glTexParameteriv
Definition: glad.h:5145
#define glUniform4fv
Definition: glad.h:5313
#define glPixelStorei
Definition: glad.h:4815
#define glGetShaderInfoLog
Definition: glad.h:4425
#define GL_R8
Definition: glad.h:1308
#define glDrawArraysInstanced
Definition: glad.h:4043
#define GL_DEBUG_TYPE_OTHER
Definition: glad.h:475
#define GL_RGBA8
Definition: glad.h:1412
#define GL_FRONT_AND_BACK
Definition: glad.h:700
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc
Definition: glad.h:2597
#define glShaderSource
Definition: glad.h:5077
#define GL_QUADS
Definition: glad.h:1280
#define GL_UNSIGNED_SHORT
Definition: glad.h:1905
#define glClearBufferData
Definition: glad.h:3805
#define GL_COMPRESSED_TEXTURE_FORMATS
Definition: glad.h:403
#define glBindBuffer
Definition: glad.h:3695
#define glEnable
Definition: glad.h:4083
#define glFramebufferTexture2D
Definition: glad.h:4153
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
Definition: glad.h:649
#define GL_COLOR_ATTACHMENT7
Definition: glad.h:351
#define GL_RED_INTEGER
Definition: glad.h:1326
#define glGetTexImage
Definition: glad.h:4449
#define GL_RG8
Definition: glad.h:1370
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
Definition: glad.h:470
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
Definition: glad.h:674
#define GL_SHADER_STORAGE_BUFFER_SIZE
Definition: glad.h:1498
#define glVertexAttrib4fv
Definition: glad.h:5545
#define GL_PACK_ALIGNMENT
Definition: glad.h:1176
#define GL_DEBUG_TYPE_PUSH_GROUP
Definition: glad.h:482
#define glBindVertexArray
Definition: glad.h:3739
#define GL_DEPTH_TEST
Definition: glad.h:511
#define glCreateShader
Definition: glad.h:3941
#define glBlendEquation
Definition: glad.h:3751
#define GL_LINEAR
Definition: glad.h:844
#define glDispatchCompute
Definition: glad.h:4033
#define GL_COLOR_ATTACHMENT0
Definition: glad.h:309
#define GL_COMPRESSED_RGBA8_ETC2_EAC
Definition: glad.h:382
#define glGetProgramiv
Definition: glad.h:4383
#define GL_SRC_ALPHA
Definition: glad.h:1520
#define GL_DEBUG_SOURCE_APPLICATION
Definition: glad.h:460
#define GL_R8UI
Definition: glad.h:1310
#define GL_LINES
Definition: glad.h:847
#define glDepthFunc
Definition: glad.h:4005
#define GL_DEBUG_SOURCE_OTHER
Definition: glad.h:462
#define glVertexAttribDivisor
Definition: glad.h:5575
#define glDeleteBuffers
Definition: glad.h:3967
#define GL_TEXTURE_CUBE_MAP_SEAMLESS
Definition: glad.h:1728
#define GL_RGB5_A1
Definition: glad.h:1392
#define glTexParameteri
Definition: glad.h:5143
#define glScissor
Definition: glad.h:5067
int GLint
Definition: glad.h:2314
#define GL_RGB8
Definition: glad.h:1393
#define glClearDepth
Definition: glad.h:3821
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
Definition: glad.h:388
#define GL_TRIANGLES
Definition: glad.h:1810
#define GL_DEBUG_SEVERITY_MEDIUM
Definition: glad.h:455
#define glReadPixels
Definition: glad.h:5027
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE
Definition: glad.h:954
#define GL_SHADER_STORAGE_BUFFER
Definition: glad.h:1495
#define GL_UNSIGNED_SHORT_5_5_5_1
Definition: glad.h:1909
#define glVertexAttrib1fv
Definition: glad.h:5441
#define glGetStringi
Definition: glad.h:4437
#define GL_COLOR_ATTACHMENT2
Definition: glad.h:329
#define GL_MAX_VERTEX_ATTRIBS
Definition: glad.h:1085
#define GL_R32F
Definition: glad.h:1304
#define GL_BACK
Definition: glad.h:230
#define GL_UNSIGNED_INT
Definition: glad.h:1864
#define GL_RGB
Definition: glad.h:1374
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
Definition: glad.h:683
#define GL_FLOAT
Definition: glad.h:598
#define glEnableVertexAttribArray
Definition: glad.h:4087
#define glTexParameterf
Definition: glad.h:5139
#define GL_COLOR_ATTACHMENT1
Definition: glad.h:311
#define glGetIntegerv
Definition: glad.h:4307
#define GL_RGB565
Definition: glad.h:1391
#define GL_ARRAY_BUFFER
Definition: glad.h:207
#define glGenVertexArrays
Definition: glad.h:4199
#define GL_LINEAR_MIPMAP_LINEAR
Definition: glad.h:845
#define glGetString
Definition: glad.h:4435
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT
Definition: glad.h:391
#define GL_COLOR_ATTACHMENT3
Definition: glad.h:341
#define glBindImageTexture
Definition: glad.h:3715
#define GL_VERTEX_ARRAY
Definition: glad.h:1916
#define GL_TEXTURE_SWIZZLE_RGBA
Definition: glad.h:1769
#define GL_DEBUG_SOURCE_SHADER_COMPILER
Definition: glad.h:464
#define GL_COMPUTE_SHADER
Definition: glad.h:405
GLAD_API_CALL int gladLoadGL(GLADloadfunc load)
Definition: glad_gl.c:1785
GLAD_API_CALL int GLAD_GL_ARB_compute_shader
Definition: glad.h:2459
#define GL_FRAMEBUFFER_COMPLETE
Definition: glad.h:665
#define glGetBufferSubData
Definition: glad.h:4253
#define glUniform1fv
Definition: glad.h:5217
#define glUniform1iv
Definition: glad.h:5229
#define glTexImage2D
Definition: glad.h:5127
#define glBindFramebuffer
Definition: glad.h:3711
#define GL_RED
Definition: glad.h:1325
#define GL_NEAREST
Definition: glad.h:1126
unsigned int GLenum
Definition: glad.h:2298
#define GL_RG
Definition: glad.h:1361
#define GL_UNSIGNED_BYTE
Definition: glad.h:1861
#define glDrawElements
Definition: glad.h:4055
#define glGenTextures
Definition: glad.h:4195
#define GL_CCW
Definition: glad.h:281
#define glBindBufferBase
Definition: glad.h:3699
#define GL_NO_ERROR
Definition: glad.h:1137
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS
Definition: glad.h:1140
#define glGetFramebufferAttachmentParameteriv
Definition: glad.h:4289
#define glDrawArrays
Definition: glad.h:4039
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
Definition: glad.h:483
#define GL_RENDERBUFFER
Definition: glad.h:1334
#define glVertexAttribPointer
Definition: glad.h:5661
#define GL_COMPILE_STATUS
Definition: glad.h:368
#define GL_LEQUAL
Definition: glad.h:841
#define glGenRenderbuffers
Definition: glad.h:4189
#define GL_CULL_FACE
Definition: glad.h:428
#define glVertexAttrib3fv
Definition: glad.h:5489
#define GL_UNPACK_ALIGNMENT
Definition: glad.h:1848
#define glUniform2fv
Definition: glad.h:5249
#define glTexSubImage2D
Definition: glad.h:5163
#define glVertexAttrib2fv
Definition: glad.h:5465
#define GL_MAX_DRAW_BUFFERS
Definition: glad.h:963
int GLsizei
Definition: glad.h:2320
#define glDepthMask
Definition: glad.h:4007
#define glBufferData
Definition: glad.h:3781
#define GL_COLOR_BUFFER_BIT
Definition: glad.h:357
#define glDeleteProgram
Definition: glad.h:3979
#define glUniform3iv
Definition: glad.h:5293
#define GL_FILL
Definition: glad.h:591
#define GL_DEBUG_SEVERITY_NOTIFICATION
Definition: glad.h:457
#define GL_DEBUG_TYPE_POP_GROUP
Definition: glad.h:479
#define glBindTexture
Definition: glad.h:3731
#define GL_FRAMEBUFFER_UNSUPPORTED
Definition: glad.h:697
#define GL_COLOR_ATTACHMENT4
Definition: glad.h:345
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM
Definition: glad.h:468
#define GL_FRAMEBUFFER
Definition: glad.h:640
#define GL_RGBA
Definition: glad.h:1398
#define glDrawElementsInstanced
Definition: glad.h:4061
#define glFrontFace
Definition: glad.h:4169
#define GL_MAX_TEXTURE_IMAGE_UNITS
Definition: glad.h:1066
#define glBindRenderbuffer
Definition: glad.h:3723
#define GL_BLEND
Definition: glad.h:237
unsigned int GLuint
Definition: glad.h:2316
#define GL_ONE_MINUS_SRC_ALPHA
Definition: glad.h:1170
#define GL_REPEAT
Definition: glad.h:1359
#define GL_READ_WRITE
Definition: glad.h:1323
#define GL_DEBUG_SOURCE_API
Definition: glad.h:458
#define GL_EXTENSIONS
Definition: glad.h:588
#define glDeleteFramebuffers
Definition: glad.h:3971
#define glFramebufferRenderbuffer
Definition: glad.h:4141
#define GL_ONE
Definition: glad.h:1163
#define GLAPIENTRY
Definition: glad.h:158
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
Definition: glad.h:387
#define GL_DEPTH_COMPONENT
Definition: glad.h:496
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
Definition: glad.h:386
#define glUniform4iv
Definition: glad.h:5325
#define GL_DEBUG_TYPE_ERROR
Definition: glad.h:472
#define glBufferSubData
Definition: glad.h:3787
#define glViewport
Definition: glad.h:5667
#define glBindAttribLocation
Definition: glad.h:3691
#define glGetInteger64v
Definition: glad.h:4303
#define GL_STATIC_DRAW
Definition: glad.h:1534
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X
Definition: glad.h:1722
#define GL_LINE
Definition: glad.h:843
#define GL_DEBUG_SEVERITY_HIGH
Definition: glad.h:451
#define GL_FALSE
Definition: glad.h:589
#define GL_DEBUG_OUTPUT_SYNCHRONOUS
Definition: glad.h:449
#define GL_SCISSOR_TEST
Definition: glad.h:1477
#define glUniform1i
Definition: glad.h:5221
#define GL_MAX_VERTEX_ATTRIB_BINDINGS
Definition: glad.h:1087
#define glDeleteShader
Definition: glad.h:3995
#define GL_DYNAMIC_DRAW
Definition: glad.h:575
#define GL_TEXTURE_WRAP_T
Definition: glad.h:1780
#define GL_DEPTH_ATTACHMENT
Definition: glad.h:491
#define glHint
Definition: glad.h:4549
#define glLineWidth
Definition: glad.h:4619
#define GL_TEXTURE_MAG_FILTER
Definition: glad.h:1750
#define glUniform4f
Definition: glad.h:5309
#define GL_DST_COLOR
Definition: glad.h:572
#define GL_SHADING_LANGUAGE_VERSION
Definition: glad.h:1501
#define GL_RGBA32F
Definition: glad.h:1407
#define GL_VERTEX_SHADER
Definition: glad.h:1948
#define GL_ALPHA
Definition: glad.h:197
#define glCompileShader
Definition: glad.h:3863
#define glCreateProgram
Definition: glad.h:3929
#define GL_FUNC_SUBTRACT
Definition: glad.h:707
#define GL_COLOR_ATTACHMENT6
Definition: glad.h:349
#define glGetProgramInfoLog
Definition: glad.h:4357
#define GL_MAX_UNIFORM_LOCATIONS
Definition: glad.h:1078
#define glPolygonMode
Definition: glad.h:4837
#define glLinkProgram
Definition: glad.h:4623
#define GL_ELEMENT_ARRAY_BUFFER
Definition: glad.h:582
#define glDeleteRenderbuffers
Definition: glad.h:3989
#define GL_TRIANGLE_STRIP
Definition: glad.h:1814
#define GL_TEXTURE_2D
Definition: glad.h:1669
#define glUseProgram
Definition: glad.h:5389
GLADapiproc(* GLADloadfunc)(const char *name)
Definition: glad.h:169
#define GL_RENDERER
Definition: glad.h:1358
#define glRenderbufferStorage
Definition: glad.h:5035
#define GL_UNSIGNED_SHORT_4_4_4_4
Definition: glad.h:1907
#define glDisable
Definition: glad.h:4023
GLAD_API_CALL int GLAD_GL_ARB_ES3_compatibility
Definition: glad.h:2443
#define GL_LINE_WIDTH
Definition: glad.h:856
#define GL_RGB32F
Definition: glad.h:1385
#define glDrawBuffers
Definition: glad.h:4051
GLAD_API_CALL int GLAD_GL_ARB_shader_storage_buffer_object
Definition: glad.h:2575
#define GL_LINK_STATUS
Definition: glad.h:859
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
Definition: glad.h:651
#define glGetShaderiv
Definition: glad.h:4433
#define GL_INFO_LOG_LENGTH
Definition: glad.h:773
#define GL_CLAMP_TO_EDGE
Definition: glad.h:287
#define GL_VENDOR
Definition: glad.h:1914
#define GL_UNSIGNED_SHORT_5_6_5
Definition: glad.h:1910
#define GL_STENCIL_ATTACHMENT
Definition: glad.h:1539
#define GL_DEBUG_TYPE_PERFORMANCE
Definition: glad.h:477
#define glDebugMessageControl
Definition: glad.h:3959
#define glDeleteTextures
Definition: glad.h:3999
#define GL_DEPTH_BUFFER_BIT
Definition: glad.h:493
#define glActiveTexture
Definition: glad.h:3671
#define glGenerateMipmap
Definition: glad.h:4201
#define GL_LINE_SMOOTH
Definition: glad.h:851
#define GL_DEBUG_OUTPUT
Definition: glad.h:448
#define GL_FUNC_ADD
Definition: glad.h:705
#define glCopyBufferSubData
Definition: glad.h:3903
#define GL_NUM_EXTENSIONS
Definition: glad.h:1142
#define GL_GREEN
Definition: glad.h:727
#define glUniform2iv
Definition: glad.h:5261
char GLchar
Definition: glad.h:2334
#define glDetachShader
Definition: glad.h:4021
#define glCompressedTexImage2D
Definition: glad.h:3873
#define glGenFramebuffers
Definition: glad.h:4177
#define GL_RGBA4
Definition: glad.h:1411
#define glBlendFunc
Definition: glad.h:3763
#define glClear
Definition: glad.h:3801
#define GL_COPY_READ_BUFFER
Definition: glad.h:424
#define GL_READ_ONLY
Definition: glad.h:1318
#define NULL
Definition: miniaudio.h:3718
@ LOG_WARNING
Definition: raylib.h:515
#define DEG2RAD
Definition: raylib.h:106
RLAPI int * rlGetShaderLocsDefault(void)
RLAPI void rlNormal3f(float x, float y, float z)
rlFramebufferAttachType
Definition: rlgl.h:293
@ RL_ATTACHMENT_COLOR_CHANNEL2
Definition: rlgl.h:296
@ RL_ATTACHMENT_COLOR_CHANNEL0
Definition: rlgl.h:294
@ RL_ATTACHMENT_COLOR_CHANNEL5
Definition: rlgl.h:299
@ RL_ATTACHMENT_STENCIL
Definition: rlgl.h:303
@ RL_ATTACHMENT_COLOR_CHANNEL6
Definition: rlgl.h:300
@ RL_ATTACHMENT_COLOR_CHANNEL4
Definition: rlgl.h:298
@ RL_ATTACHMENT_COLOR_CHANNEL1
Definition: rlgl.h:295
@ RL_ATTACHMENT_COLOR_CHANNEL7
Definition: rlgl.h:301
@ RL_ATTACHMENT_COLOR_CHANNEL3
Definition: rlgl.h:297
@ RL_ATTACHMENT_DEPTH
Definition: rlgl.h:302
RLAPI Matrix rlGetMatrixProjection(void)
RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount)
RLAPI void rlDisableTextureCubemap(void)
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data)
RLAPI void rlDisableVertexBuffer(void)
RLAPI unsigned int rlCompileShader(const char *shaderCode, int type)
RLAPI void rlClearScreenBuffers(void)
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
#define RL_QUADS
Definition: rlgl.h:260
RLAPI void rlEnd(void)
#define RL_TEXTURE_WRAP_T
Definition: rlgl.h:235
RLAPI int rlGetFramebufferHeight(void)
RLAPI void rlSetRenderBatchActive(rlRenderBatch *batch)
RLAPI void rlUnloadFramebuffer(unsigned int id)
#define TRACELOG(level,...)
Definition: rlgl.h:129
RLAPI void rlActiveDrawBuffers(int count)
#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS
Definition: rlgl.h:212
RLAPI void rlDrawVertexArray(int offset, int count)
RLAPI void rlSetBlendMode(int mode)
RLAPI bool rlIsStereoRenderEnabled(void)
RLAPI void rlLoadIdentity(void)
#define RL_REALLOC(n, sz)
Definition: rlgl.h:141
RLAPI void rlEnableTexture(unsigned int id)
RLAPI void * rlReadTexturePixels(unsigned int id, int width, int height, int format)
#define RL_SHADER_LOC_MAP_DIFFUSE
Definition: rlgl.h:470
RLAPI unsigned int rlLoadVertexArray(void)
RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
RLAPI void rlEnableBackfaceCulling(void)
#define RL_FREE(p)
Definition: rlgl.h:144
RLAPI void rlEnableTextureCubemap(unsigned int id)
RLAPI Matrix rlGetMatrixModelview(void)
rlShaderUniformDataType
Definition: rlgl.h:474
@ RL_SHADER_UNIFORM_IVEC3
Definition: rlgl.h:481
@ RL_SHADER_UNIFORM_IVEC2
Definition: rlgl.h:480
@ RL_SHADER_UNIFORM_FLOAT
Definition: rlgl.h:475
@ RL_SHADER_UNIFORM_INT
Definition: rlgl.h:479
@ RL_SHADER_UNIFORM_VEC4
Definition: rlgl.h:478
@ RL_SHADER_UNIFORM_IVEC4
Definition: rlgl.h:482
@ RL_SHADER_UNIFORM_VEC3
Definition: rlgl.h:477
@ RL_SHADER_UNIFORM_VEC2
Definition: rlgl.h:476
@ RL_SHADER_UNIFORM_SAMPLER2D
Definition: rlgl.h:483
RLAPI unsigned int rlLoadVertexBuffer(const void *buffer, int size, bool dynamic)
RLAPI void rlglClose(void)
RLAPI void rlDisableScissorTest(void)
#define RL_MODELVIEW
Definition: rlgl.h:253
RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void *buffer, int instances)
RLAPI void rlEnableStereoRender(void)
#define RL_TRIANGLES
Definition: rlgl.h:259
RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
rlGlVersion
Definition: rlgl.h:285
@ OPENGL_11
Definition: rlgl.h:286
@ OPENGL_43
Definition: rlgl.h:289
@ OPENGL_21
Definition: rlgl.h:287
@ OPENGL_ES_20
Definition: rlgl.h:290
@ OPENGL_33
Definition: rlgl.h:288
rlBlendMode
Definition: rlgl.h:430
@ RL_BLEND_ALPHA
Definition: rlgl.h:431
@ RL_BLEND_ADDITIVE
Definition: rlgl.h:432
@ RL_BLEND_MULTIPLIED
Definition: rlgl.h:433
@ RL_BLEND_ALPHA_PREMUL
Definition: rlgl.h:436
@ RL_BLEND_ADD_COLORS
Definition: rlgl.h:434
@ RL_BLEND_SUBTRACT_COLORS
Definition: rlgl.h:435
@ RL_BLEND_CUSTOM
Definition: rlgl.h:437
RLAPI void rlLoadDrawCube(void)
RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar)
RLAPI void rlSetVertexAttributeDivisor(unsigned int index, int divisor)
RLAPI void rlDisableBackfaceCulling(void)
RLAPI void rlLoadExtensions(void *loader)
RLAPI void rlDisableTexture(void)
RLAPI void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps)
RLAPI unsigned int rlGetShaderIdDefault(void)
RLAPI void rlDisableSmoothLines(void)
RLAPI void rlVertex3f(float x, float y, float z)
RLAPI void rlDisableVertexArray(void)
RLAPI void rlDisableVertexAttribute(unsigned int index)
RLAPI void rlVertex2i(int x, int y)
RLAPI unsigned char * rlReadScreenPixels(int width, int height)
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat)
#define RL_DEFAULT_BATCH_BUFFERS
Definition: rlgl.h:206
RLAPI void rlSetFramebufferHeight(int height)
RLAPI void rlDisableStereoRender(void)
RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, const void *pointer)
RLAPI void rlPushMatrix(void)
RLAPI void rlUpdateVertexBuffer(unsigned int bufferId, const void *data, int dataSize, int offset)
RLAPI unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
RLAPI unsigned int rlLoadShaderBuffer(unsigned long long size, const void *data, int usageHint)
RLAPI void rlDisableDepthMask(void)
RLAPI unsigned int rlLoadVertexBufferElement(const void *buffer, int size, bool dynamic)
rlShaderAttributeDataType
Definition: rlgl.h:487
@ RL_SHADER_ATTRIB_FLOAT
Definition: rlgl.h:488
@ RL_SHADER_ATTRIB_VEC3
Definition: rlgl.h:490
@ RL_SHADER_ATTRIB_VEC4
Definition: rlgl.h:491
@ RL_SHADER_ATTRIB_VEC2
Definition: rlgl.h:489
#define RL_MAX_MATRIX_STACK_SIZE
Definition: rlgl.h:217
RLAPI unsigned int rlGetTextureIdDefault(void)
RLAPI void rlSetMatrixModelview(Matrix view)
RLAPI void rlViewport(int x, int y, int width, int height)
RLAPI const char * rlGetPixelFormatName(unsigned int format)
RLAPI void rlScissor(int x, int y, int width, int height)
RLAPI int rlGetVersion(void)
RLAPI float rlGetLineWidth(void)
RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
RLAPI bool rlEnableVertexArray(unsigned int vaoId)
RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId)
#define RL_PROJECTION
Definition: rlgl.h:254
RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye)
RLAPI void rlScalef(float x, float y, float z)
RLAPI Matrix rlGetMatrixTransform(void)
rlShaderLocationIndex
Definition: rlgl.h:441
@ RL_SHADER_LOC_VERTEX_TEXCOORD01
Definition: rlgl.h:443
@ RL_SHADER_LOC_MATRIX_NORMAL
Definition: rlgl.h:452
@ RL_SHADER_LOC_MAP_EMISSION
Definition: rlgl.h:462
@ RL_SHADER_LOC_MAP_ROUGHNESS
Definition: rlgl.h:460
@ RL_SHADER_LOC_MATRIX_PROJECTION
Definition: rlgl.h:450
@ RL_SHADER_LOC_MAP_NORMAL
Definition: rlgl.h:459
@ RL_SHADER_LOC_MAP_CUBEMAP
Definition: rlgl.h:464
@ RL_SHADER_LOC_MAP_ALBEDO
Definition: rlgl.h:457
@ RL_SHADER_LOC_VERTEX_POSITION
Definition: rlgl.h:442
@ RL_SHADER_LOC_COLOR_DIFFUSE
Definition: rlgl.h:454
@ RL_SHADER_LOC_MAP_PREFILTER
Definition: rlgl.h:466
@ RL_SHADER_LOC_VERTEX_TANGENT
Definition: rlgl.h:446
@ RL_SHADER_LOC_MATRIX_MODEL
Definition: rlgl.h:451
@ RL_SHADER_LOC_VECTOR_VIEW
Definition: rlgl.h:453
@ RL_SHADER_LOC_COLOR_AMBIENT
Definition: rlgl.h:456
@ RL_SHADER_LOC_MAP_OCCLUSION
Definition: rlgl.h:461
@ RL_SHADER_LOC_MAP_BRDF
Definition: rlgl.h:467
@ RL_SHADER_LOC_MAP_METALNESS
Definition: rlgl.h:458
@ RL_SHADER_LOC_MAP_HEIGHT
Definition: rlgl.h:463
@ RL_SHADER_LOC_COLOR_SPECULAR
Definition: rlgl.h:455
@ RL_SHADER_LOC_MATRIX_MVP
Definition: rlgl.h:448
@ RL_SHADER_LOC_VERTEX_TEXCOORD02
Definition: rlgl.h:444
@ RL_SHADER_LOC_MAP_IRRADIANCE
Definition: rlgl.h:465
@ RL_SHADER_LOC_MATRIX_VIEW
Definition: rlgl.h:449
@ RL_SHADER_LOC_VERTEX_NORMAL
Definition: rlgl.h:445
@ RL_SHADER_LOC_VERTEX_COLOR
Definition: rlgl.h:447
#define RL_MAX_SHADER_LOCATIONS
Definition: rlgl.h:222
RLAPI void rlReadShaderBufferElements(unsigned int id, void *dest, unsigned long long count, unsigned long long offset)
RLAPI void rlDisableWireMode(void)
RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left)
RLAPI void rlEnableSmoothLines(void)
RLAPI void rlVertex2f(float x, float y)
#define RL_TEXTURE_MIN_FILTER
Definition: rlgl.h:237
#define RL_MALLOC(sz)
Definition: rlgl.h:135
RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
RLAPI void rlEnableDepthMask(void)
RLAPI void rlEnableFramebuffer(unsigned int id)
RLAPI void rlSetLineWidth(float width)
RLAPI void rlActiveTextureSlot(int slot)
RLAPI void rlEnableShader(unsigned int id)
RLAPI void rlCopyBuffersElements(unsigned int destId, unsigned int srcId, unsigned long long destOffset, unsigned long long srcOffset, unsigned long long count)
RLAPI void rlCheckErrors(void)
RLAPI int rlGetFramebufferWidth(void)
RLAPI void rlMultMatrixf(float *matf)
RLAPI void rlBegin(int mode)
RLAPI void rlDisableFramebuffer(void)
RLAPI void rlDisableVertexBufferElement(void)
RLAPI void rlEnableScissorTest(void)
RLAPI void rlLoadDrawQuad(void)
#define RLAPI
Definition: rlgl.h:124
RLAPI void rlBindShaderBuffer(unsigned int id, unsigned int index)
RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar)
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel)
RLAPI void rlTexCoord2f(float x, float y)
RLAPI void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left)
RLAPI void rlDrawRenderBatchActive(void)
#define RL_STREAM_COPY
Definition: rlgl.h:269
#define RL_TEXTURE
Definition: rlgl.h:255
RLAPI void rlDrawVertexArrayInstanced(int offset, int count, int instances)
RLAPI void rlEnableVertexAttribute(unsigned int index)
RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count)
RLAPI void rlColor3f(float x, float y, float z)
rlTraceLogLevel
Definition: rlgl.h:381
@ RL_LOG_FATAL
Definition: rlgl.h:388
@ RL_LOG_TRACE
Definition: rlgl.h:383
@ RL_LOG_ERROR
Definition: rlgl.h:387
@ RL_LOG_WARNING
Definition: rlgl.h:386
@ RL_LOG_NONE
Definition: rlgl.h:389
@ RL_LOG_INFO
Definition: rlgl.h:385
@ RL_LOG_DEBUG
Definition: rlgl.h:384
@ RL_LOG_ALL
Definition: rlgl.h:382
RLAPI void rlEnableDepthTest(void)
RLAPI void rlUnloadVertexArray(unsigned int vaoId)
RLAPI void rlEnableWireMode(void)
RLAPI void rlRotatef(float angle, float x, float y, float z)
RLAPI unsigned int rlLoadFramebuffer(int width, int height)
RLAPI void rlEnableVertexBuffer(unsigned int id)
RLAPI void rlSetShader(unsigned int id, int *locs)
RLAPI void rlDisableShader(void)
RLAPI void rlColor4f(float x, float y, float z, float w)
RLAPI void rlUnloadTexture(unsigned int id)
RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName)
#define RL_TEXTURE_WRAP_MIRROR_CLAMP
Definition: rlgl.h:250
#define RL_TEXTURE_MAG_FILTER
Definition: rlgl.h:236
RLAPI void rlEnableColorBlend(void)
RLAPI void rlUpdateVertexBufferElements(unsigned int id, const void *data, int dataSize, int offset)
RLAPI void rlSetMatrixProjection(Matrix proj)
RLAPI void rlglInit(int width, int height)
RLAPI void rlTextureParameters(unsigned int id, int param, int value)
#define RL_TEXTURE_WRAP_S
Definition: rlgl.h:234
#define RL_TEXTURE_FILTER_ANISOTROPIC
Definition: rlgl.h:245
RLAPI void rlPopMatrix(void)
RLAPI void rlSetTexture(unsigned int id)
RLAPI void rlEnableVertexBufferElement(unsigned int id)
#define RL_CALLOC(n, sz)
Definition: rlgl.h:138
RLAPI void rlDrawVertexArrayElements(int offset, int count, const void *buffer)
RLAPI void rlGetGlTextureFormats(int format, int *glInternalFormat, int *glFormat, int *glType)
RLAPI bool rlCheckRenderBatchLimit(int vCount)
RLAPI void rlComputeShaderDispatch(unsigned int groupX, unsigned int groupY, unsigned int groupZ)
#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS
Definition: rlgl.h:196
RLAPI unsigned long long rlGetShaderBufferSize(unsigned int id)
rlPixelFormat
Definition: rlgl.h:393
@ RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA
Definition: rlgl.h:395
@ RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA
Definition: rlgl.h:410
@ RL_PIXELFORMAT_COMPRESSED_PVRT_RGB
Definition: rlgl.h:411
@ RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE
Definition: rlgl.h:394
@ RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA
Definition: rlgl.h:406
@ RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA
Definition: rlgl.h:405
@ RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA
Definition: rlgl.h:407
@ RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8
Definition: rlgl.h:397
@ RL_PIXELFORMAT_COMPRESSED_ETC1_RGB
Definition: rlgl.h:408
@ RL_PIXELFORMAT_UNCOMPRESSED_R32
Definition: rlgl.h:401
@ RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5
Definition: rlgl.h:396
@ RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA
Definition: rlgl.h:412
@ RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32
Definition: rlgl.h:403
@ RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
Definition: rlgl.h:400
@ RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1
Definition: rlgl.h:398
@ RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA
Definition: rlgl.h:413
@ RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA
Definition: rlgl.h:414
@ RL_PIXELFORMAT_COMPRESSED_ETC2_RGB
Definition: rlgl.h:409
@ RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32
Definition: rlgl.h:402
@ RL_PIXELFORMAT_COMPRESSED_DXT1_RGB
Definition: rlgl.h:404
@ RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4
Definition: rlgl.h:399
RLAPI bool rlFramebufferComplete(unsigned int id)
RLAPI void rlUnloadShaderProgram(unsigned int id)
#define RL_LINES
Definition: rlgl.h:258
RLAPI void rlDisableColorBlend(void)
#define RL_DEFAULT_BATCH_DRAWCALLS
Definition: rlgl.h:209
rlTextureFilter
Definition: rlgl.h:420
@ RL_TEXTURE_FILTER_ANISOTROPIC_16X
Definition: rlgl.h:426
@ RL_TEXTURE_FILTER_POINT
Definition: rlgl.h:421
@ RL_TEXTURE_FILTER_ANISOTROPIC_4X
Definition: rlgl.h:424
@ RL_TEXTURE_FILTER_ANISOTROPIC_8X
Definition: rlgl.h:425
@ RL_TEXTURE_FILTER_TRILINEAR
Definition: rlgl.h:423
@ RL_TEXTURE_FILTER_BILINEAR
Definition: rlgl.h:422
rlFramebufferAttachTextureType
Definition: rlgl.h:306
@ RL_ATTACHMENT_CUBEMAP_NEGATIVE_X
Definition: rlgl.h:308
@ RL_ATTACHMENT_TEXTURE2D
Definition: rlgl.h:313
@ RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z
Definition: rlgl.h:312
@ RL_ATTACHMENT_CUBEMAP_POSITIVE_Z
Definition: rlgl.h:311
@ RL_ATTACHMENT_CUBEMAP_POSITIVE_Y
Definition: rlgl.h:309
@ RL_ATTACHMENT_RENDERBUFFER
Definition: rlgl.h:314
@ RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y
Definition: rlgl.h:310
@ RL_ATTACHMENT_CUBEMAP_POSITIVE_X
Definition: rlgl.h:307
RLAPI rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
RLAPI void rlTranslatef(float x, float y, float z)
RLAPI Matrix rlGetMatrixProjectionStereo(int eye)
RLAPI void rlUnloadRenderBatch(rlRenderBatch batch)
RLAPI void rlUnloadShaderBuffer(unsigned int ssboId)
RLAPI void rlMatrixMode(int mode)
RLAPI void rlUpdateShaderBufferElements(unsigned int id, const void *data, unsigned long long dataSize, unsigned long long offset)
RLAPI void rlDisableDepthTest(void)
#define TRACELOGD(...)
Definition: rlgl.h:130
RLAPI void rlSetFramebufferWidth(int width)
RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
RLAPI void rlUnloadVertexBuffer(unsigned int vboId)
RLAPI void rlBindImageTexture(unsigned int id, unsigned int index, unsigned int format, int readonly)
bool
Definition: rlgl.h:365
RLAPI void rlDrawRenderBatch(rlRenderBatch *batch)
Definition: raylib.h:212
float m14
Definition: raylib.h:215
float m11
Definition: raylib.h:216
float m5
Definition: raylib.h:214
float m15
Definition: raylib.h:216
float m3
Definition: raylib.h:216
float m1
Definition: raylib.h:214
float m9
Definition: raylib.h:214
float m0
Definition: raylib.h:213
float m2
Definition: raylib.h:215
float m6
Definition: raylib.h:215
float m4
Definition: raylib.h:213
float m13
Definition: raylib.h:214
float m8
Definition: raylib.h:213
float m12
Definition: raylib.h:213
float m7
Definition: raylib.h:216
float m10
Definition: raylib.h:215
unsigned int textureId
Definition: rlgl.h:344
int vertexCount
Definition: rlgl.h:340
int mode
Definition: rlgl.h:339
int vertexAlignment
Definition: rlgl.h:341
float currentDepth
Definition: rlgl.h:358
int drawCounter
Definition: rlgl.h:357
int bufferCount
Definition: rlgl.h:352
rlDrawCall * draws
Definition: rlgl.h:356
int currentBuffer
Definition: rlgl.h:353
rlVertexBuffer * vertexBuffer
Definition: rlgl.h:354
unsigned int vboId[4]
Definition: rlgl.h:331
unsigned int * indices
Definition: rlgl.h:325
float * vertices
Definition: rlgl.h:321
float * texcoords
Definition: rlgl.h:322
unsigned int vaoId
Definition: rlgl.h:330
int elementCount
Definition: rlgl.h:319
unsigned char * colors
Definition: rlgl.h:323