rlgl.h updated

This commit is contained in:
JupiterRider 2024-11-23 16:53:25 +01:00
parent 3af3eea92a
commit 466f3e0804

View file

@ -8,17 +8,17 @@
* *
* ADDITIONAL NOTES: * ADDITIONAL NOTES:
* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are * When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are
* initialized on rlglInit() to accumulate vertex data. * initialized on rlglInit() to accumulate vertex data
* *
* When an internal state change is required all the stored vertex data is renderer in batch, * When an internal state change is required all the stored vertex data is renderer in batch,
* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch. * additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch
* *
* Some resources are also loaded for convenience, here the complete list: * Some resources are also loaded for convenience, here the complete list:
* - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data * - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data
* - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 * - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8
* - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) * - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs)
* *
* Internal buffer (and resources) must be manually unloaded calling rlglClose(). * Internal buffer (and resources) must be manually unloaded calling rlglClose()
* *
* CONFIGURATION: * CONFIGURATION:
* #define GRAPHICS_API_OPENGL_11 * #define GRAPHICS_API_OPENGL_11
@ -32,9 +32,9 @@
* required by any other module, use rlGetVersion() to check it * required by any other module, use rlGetVersion() to check it
* *
* #define RLGL_IMPLEMENTATION * #define RLGL_IMPLEMENTATION
* Generates the implementation of the library into the included file. * Generates the implementation of the library into the included file
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation. * or source files without problems. But only ONE file should hold the implementation
* *
* #define RLGL_RENDER_TEXTURES_HINT * #define RLGL_RENDER_TEXTURES_HINT
* Enable framebuffer objects (fbo) support (enabled by default) * Enable framebuffer objects (fbo) support (enabled by default)
@ -68,12 +68,15 @@
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR * #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 * #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
* #define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix * #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))) * #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)))
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) * #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
* #define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) * #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
@ -341,6 +344,17 @@
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 #ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5 #define RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2 5
#endif #endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES 6
#endif
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS 7
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS 8
#endif
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -527,6 +541,10 @@ typedef enum {
RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int) RL_SHADER_UNIFORM_IVEC2, // Shader uniform type: ivec2 (2 int)
RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int) RL_SHADER_UNIFORM_IVEC3, // Shader uniform type: ivec3 (3 int)
RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int) RL_SHADER_UNIFORM_IVEC4, // Shader uniform type: ivec4 (4 int)
RL_SHADER_UNIFORM_UINT, // Shader uniform type: unsigned int
RL_SHADER_UNIFORM_UIVEC2, // Shader uniform type: uivec2 (2 unsigned int)
RL_SHADER_UNIFORM_UIVEC3, // Shader uniform type: uivec3 (3 unsigned int)
RL_SHADER_UNIFORM_UIVEC4, // Shader uniform type: uivec4 (4 unsigned int)
RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d RL_SHADER_UNIFORM_SAMPLER2D // Shader uniform type: sampler2d
} rlShaderUniformDataType; } rlShaderUniformDataType;
@ -590,9 +608,9 @@ RLAPI void rlMultMatrixf(const float *matf); // Multiply the current
RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlFrustum(double left, double right, double bottom, double top, double znear, double zfar);
RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar); RLAPI void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar);
RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area RLAPI void rlViewport(int x, int y, int width, int height); // Set the viewport area
RLAPI void rlSetClipPlanes(double near, double far); // Set clip planes distances RLAPI void rlSetClipPlanes(double nearPlane, double farPlane); // Set clip planes distances
RLAPI double rlGetCullDistanceNear(); // Get cull plane distance near RLAPI double rlGetCullDistanceNear(void); // Get cull plane distance near
RLAPI double rlGetCullDistanceFar(); // Get cull plane distance far RLAPI double rlGetCullDistanceFar(void); // Get cull plane distance far
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Functions Declaration - Vertex level operations // Functions Declaration - Vertex level operations
@ -665,7 +683,7 @@ RLAPI void rlDisableScissorTest(void); // Disable scissor test
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
RLAPI void rlEnableWireMode(void); // Enable wire mode RLAPI void rlEnableWireMode(void); // Enable wire mode
RLAPI void rlEnablePointMode(void); // Enable point mode RLAPI void rlEnablePointMode(void); // Enable point mode
RLAPI void rlDisableWireMode(void); // Disable wire mode ( and point ) maybe rename RLAPI void rlDisableWireMode(void); // Disable wire (and point) mode
RLAPI void rlSetLineWidth(float width); // Set the line drawing width RLAPI void rlSetLineWidth(float width); // Set the line drawing width
RLAPI float rlGetLineWidth(void); // Get the line drawing width RLAPI float rlGetLineWidth(void); // Get the line drawing width
RLAPI void rlEnableSmoothLines(void); // Enable line aliasing RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
@ -731,7 +749,7 @@ RLAPI void rlDrawVertexArrayElementsInstanced(int offset, int count, const void
// Textures management // Textures management
RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data RLAPI unsigned int rlLoadTexture(const void *data, int width, int height, int format, int mipmapCount); // Load texture data
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format); // Load texture cubemap data RLAPI unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount); // Load texture cubemap data
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update texture with new data on GPU RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update texture with new data on GPU
RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format RLAPI const char *rlGetPixelFormatName(unsigned int format); // Get name string for pixel format
@ -755,6 +773,7 @@ RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName);
RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
RLAPI void rlSetUniformMatrices(int locIndex, const Matrix *mat, int count); // Set shader value matrices
RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler
RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations) RLAPI void rlSetShader(unsigned int id, int *locs); // Set shader currently active (id and locations)
@ -844,9 +863,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library #include <GLES2/gl2ext.h> // OpenGL ES 2.0 extensions library
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, // NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms,
// in that case, functions are loaded from a custom glad for OpenGL ES 2.0 // in that case, functions are loaded from a custom glad for OpenGL ES 2.0
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
#define GLAD_GLES2_IMPLEMENTATION #define GLAD_GLES2_IMPLEMENTATION
#include "external/glad_gles2.h" #include "external/glad_gles2.h"
#else #else
@ -973,6 +992,12 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 #ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2
#endif #endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS "vertexBoneIds" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS
#endif
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
#endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_MVP
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
@ -992,6 +1017,9 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR #ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
#endif #endif
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES "boneMatrices" // bone matrices
#endif
#ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 #ifndef RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
#endif #endif
@ -1371,10 +1399,10 @@ void rlViewport(int x, int y, int width, int height)
} }
// Set clip planes distances // Set clip planes distances
void rlSetClipPlanes(double near, double far) void rlSetClipPlanes(double nearPlane, double farPlane)
{ {
rlCullDistanceNear = near; rlCullDistanceNear = nearPlane;
rlCullDistanceFar = far; rlCullDistanceFar = farPlane;
} }
// Get cull plane distance near // Get cull plane distance near
@ -1406,7 +1434,7 @@ void rlBegin(int mode)
} }
} }
void rlEnd() { glEnd(); } void rlEnd(void) { glEnd(); }
void rlVertex2i(int x, int y) { glVertex2i(x, y); } void rlVertex2i(int x, int y) { glVertex2i(x, y); }
void rlVertex2f(float x, float y) { glVertex2f(x, y); } void rlVertex2f(float x, float y) { glVertex2f(x, y); }
void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); } void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); }
@ -1475,8 +1503,8 @@ void rlVertex3f(float x, float y, float z)
tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14; tz = RLGL.State.transform.m2*x + RLGL.State.transform.m6*y + RLGL.State.transform.m10*z + RLGL.State.transform.m14;
} }
// WARNING: We can't break primitives when launching a new batch. // WARNING: We can't break primitives when launching a new batch
// RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices. // RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices
// We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 // We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4
if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4)) if (RLGL.State.vertexCounter > (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{ {
@ -1560,7 +1588,7 @@ void rlNormal3f(float x, float y, float z)
float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz); float length = sqrtf(normalx*normalx + normaly*normaly + normalz*normalz);
if (length != 0.0f) if (length != 0.0f)
{ {
float ilength = 1.0f / length; float ilength = 1.0f/length;
normalx *= ilength; normalx *= ilength;
normaly *= ilength; normaly *= ilength;
normalz *= ilength; normalz *= ilength;
@ -1948,6 +1976,7 @@ void rlEnableWireMode(void)
#endif #endif
} }
// Enable point mode
void rlEnablePointMode(void) void rlEnablePointMode(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
@ -1956,6 +1985,7 @@ void rlEnablePointMode(void)
glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_PROGRAM_POINT_SIZE);
#endif #endif
} }
// Disable wire mode // Disable wire mode
void rlDisableWireMode(void) void rlDisableWireMode(void)
{ {
@ -2038,7 +2068,7 @@ void rlClearScreenBuffers(void)
} }
// Check and log OpenGL error codes // Check and log OpenGL error codes
void rlCheckErrors() void rlCheckErrors(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int check = 1; int check = 1;
@ -2390,7 +2420,7 @@ void rlLoadExtensions(void *loader)
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL)
// TODO: Support GLAD loader for OpenGL ES 3.0 // TODO: Support GLAD loader for OpenGL ES 3.0
if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions"); if (gladLoadGLES2((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL ES2.0 functions");
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully"); else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL ES 2.0 loaded successfully");
@ -2442,25 +2472,47 @@ void rlLoadExtensions(void *loader)
} }
// Check instanced rendering support // Check instanced rendering support
if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // Web ANGLE if (strstr(extList[i], (const char*)"instanced_arrays") != NULL) // Broad check for instanced_arrays
{
// Specific check
if (strcmp(extList[i], (const char *)"GL_ANGLE_instanced_arrays") == 0) // ANGLE
{ {
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE"); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedANGLE");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE"); glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedANGLE");
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE"); glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorANGLE");
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
} }
else else if (strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0) // EXT
{
if ((strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0) && // Standard EXT
(strcmp(extList[i], (const char *)"GL_EXT_instanced_arrays") == 0))
{ {
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT"); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT"); glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT"); glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorEXT");
}
else if (strcmp(extList[i], (const char *)"GL_NV_instanced_arrays") == 0) // NVIDIA GLES
{
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");
glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISOREXTPROC)((rlglLoadProc)loader)("glVertexAttribDivisorNV");
}
// The feature will only be marked as supported if the elements from GL_XXX_instanced_arrays are present
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true; if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
} }
else if (strstr(extList[i], (const char *)"draw_instanced") != NULL)
{
// GL_ANGLE_draw_instanced doesn't exist
if (strcmp(extList[i], (const char *)"GL_EXT_draw_instanced") == 0)
{
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedEXT");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedEXT");
}
else if (strcmp(extList[i], (const char*)"GL_NV_draw_instanced") == 0)
{
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawArraysInstancedNV");
glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC)((rlglLoadProc)loader)("glDrawElementsInstancedNV");
}
// But the functions will at least be loaded if only GL_XX_EXT_draw_instanced exist
if ((glDrawArraysInstanced != NULL) && (glDrawElementsInstanced != NULL) && (glVertexAttribDivisor != NULL)) RLGL.ExtSupported.instancing = true;
} }
// Check NPOT textures support // Check NPOT textures support
@ -2881,11 +2933,11 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors); glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
// NOTE: glMapBuffer() causes sync issue. // NOTE: glMapBuffer() causes sync issue
// If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job. // If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job
// To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer(). // To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer()
// If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new // If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new
// allocated pointer immediately even if GPU is still working with the previous data. // allocated pointer immediately even if GPU is still working with the previous data
// Another option: map the buffer object into client's memory // Another option: map the buffer object into client's memory
// Probably this code could be moved somewhere else... // Probably this code could be moved somewhere else...
@ -2938,7 +2990,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
} }
// WARNING: For the following setup of the view, model, and normal matrices, it is expected that // WARNING: For the following setup of the view, model, and normal matrices, it is expected that
// transformations and rendering occur between rlPushMatrix and rlPopMatrix. // transformations and rendering occur between rlPushMatrix() and rlPopMatrix()
if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_VIEW] != -1) if (RLGL.State.currentShaderLocs[RL_SHADER_LOC_MATRIX_VIEW] != -1)
{ {
@ -3008,15 +3060,15 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount); if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount);
else else
{ {
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
// We need to define the number of indices to be processed: elementCount*6 // We need to define the number of indices to be processed: elementCount*6
// NOTE: The final parameter tells the GPU the offset in bytes from the // NOTE: The final parameter tells the GPU the offset in bytes from the
// start of the index buffer to the location of the first index to process // start of the index buffer to the location of the first index to process
glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint))); glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint)));
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort))); glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(vertexOffset/4*6*sizeof(GLushort)));
#endif #endif
} }
vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment); vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment);
@ -3334,11 +3386,17 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
// Load texture cubemap // Load texture cubemap
// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), // NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other),
// expected the following convention: +X, -X, +Y, -Y, +Z, -Z // expected the following convention: +X, -X, +Y, -Y, +Z, -Z
unsigned int rlLoadTextureCubemap(const void *data, int size, int format) unsigned int rlLoadTextureCubemap(const void *data, int size, int format, int mipmapCount)
{ {
unsigned int id = 0; unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int mipSize = size;
// NOTE: Added pointer math separately from function to avoid UBSAN complaining
unsigned char *dataPtr = NULL;
if (data != NULL) dataPtr = (unsigned char *)data;
unsigned int dataSize = rlGetPixelDataSize(size, size, format); unsigned int dataSize = rlGetPixelDataSize(size, size, format);
glGenTextures(1, &id); glGenTextures(1, &id);
@ -3349,24 +3407,28 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
if (glInternalFormat != 0) if (glInternalFormat != 0)
{ {
// Load cubemap faces // Load cubemap faces/mipmaps
for (unsigned int i = 0; i < 6; i++) for (int i = 0; i < 6*mipmapCount; i++)
{ {
int mipmapLevel = i/6;
int face = i%6;
if (data == NULL) if (data == NULL)
{ {
if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB)
{ {
if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) if ((format == RL_PIXELFORMAT_UNCOMPRESSED_R32) ||
|| (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) || (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) (format == RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32) ||
TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported"); (format == RL_PIXELFORMAT_UNCOMPRESSED_R16) ||
else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL); (format == RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16)) TRACELOG(RL_LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, NULL);
} }
else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format"); else TRACELOG(RL_LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format");
} }
else else
{ {
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); if (format < RL_PIXELFORMAT_COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, glFormat, glType, (unsigned char *)dataPtr + face*dataSize);
else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize); else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mipmapLevel, glInternalFormat, mipSize, mipSize, 0, dataSize, (unsigned char *)dataPtr + face*dataSize);
} }
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
@ -3385,11 +3447,23 @@ unsigned int rlLoadTextureCubemap(const void *data, int size, int format)
glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); glTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
} }
#endif #endif
if (face == 5)
{
mipSize /= 2;
if (data != NULL) dataPtr += dataSize*6; // Increment data pointer to next mipmap
// Security check for NPOT textures
if (mipSize < 1) mipSize = 1;
dataSize = rlGetPixelDataSize(mipSize, mipSize, format);
}
} }
} }
// Set cubemap texture sampling parameters // Set cubemap texture sampling parameters
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (mipmapCount > 1) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -3548,8 +3622,8 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format);
// 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. // 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
// Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting
// GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.)
// GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.)
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
@ -3570,7 +3644,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
#if defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_ES2)
// glGetTexImage() is not available on OpenGL ES 2.0 // glGetTexImage() is not available on OpenGL ES 2.0
// Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. // Texture width and height are required on OpenGL ES 2.0, there is no way to get it from texture id
// Two possible Options: // Two possible Options:
// 1 - Bind texture to color fbo attachment and glReadPixels() // 1 - Bind texture to color fbo attachment and glReadPixels()
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels() // 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
@ -3736,7 +3810,7 @@ void rlUnloadFramebuffer(unsigned int id)
else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU); else if (depthType == GL_TEXTURE) glDeleteTextures(1, &depthIdU);
// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
// the texture image is automatically detached from the currently bound framebuffer. // the texture image is automatically detached from the currently bound framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &id); glDeleteFramebuffers(1, &id);
@ -3945,7 +4019,9 @@ void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool norma
// Additional types (depends on OpenGL version or extensions): // Additional types (depends on OpenGL version or extensions):
// - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, // - GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED,
// - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV // - GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT_10F_11F_11F_REV
glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offset);
size_t offsetNative = offset;
glVertexAttribPointer(index, compSize, type, normalized, stride, (void *)offsetNative);
#endif #endif
} }
@ -3992,18 +4068,18 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
unsigned int fragmentShaderId = 0; unsigned int fragmentShaderId = 0;
// Compile vertex shader (if provided) // Compile vertex shader (if provided)
// NOTE: If not vertex shader is provided, use default one
if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER); if (vsCode != NULL) vertexShaderId = rlCompileShader(vsCode, GL_VERTEX_SHADER);
// In case no vertex shader was provided or compilation failed, we use default vertex shader else vertexShaderId = RLGL.State.defaultVShaderId;
if (vertexShaderId == 0) vertexShaderId = RLGL.State.defaultVShaderId;
// Compile fragment shader (if provided) // Compile fragment shader (if provided)
// NOTE: If not vertex shader is provided, use default one
if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER); if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER);
// In case no fragment shader was provided or compilation failed, we use default fragment shader else fragmentShaderId = RLGL.State.defaultFShaderId;
if (fragmentShaderId == 0) fragmentShaderId = RLGL.State.defaultFShaderId;
// In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id // In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id
if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId; if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId;
else else if ((vertexShaderId > 0) && (fragmentShaderId > 0))
{ {
// One of or both shader are new, we need to compile a new shader program // One of or both shader are new, we need to compile a new shader program
id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId); id = rlLoadShaderProgram(vertexShaderId, fragmentShaderId);
@ -4081,6 +4157,8 @@ unsigned int rlCompileShader(const char *shaderCode, int type)
//case GL_GEOMETRY_SHADER: //case GL_GEOMETRY_SHADER:
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break; case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to compile compute shader code", shader); break;
#elif defined(GRAPHICS_API_OPENGL_33)
case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break;
#endif #endif
default: break; default: break;
} }
@ -4096,6 +4174,8 @@ unsigned int rlCompileShader(const char *shaderCode, int type)
TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log); TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log);
RL_FREE(log); RL_FREE(log);
} }
shader = 0;
} }
else else
{ {
@ -4106,6 +4186,8 @@ unsigned int rlCompileShader(const char *shaderCode, int type)
//case GL_GEOMETRY_SHADER: //case GL_GEOMETRY_SHADER:
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break; case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader compiled successfully", shader); break;
#elif defined(GRAPHICS_API_OPENGL_33)
case GL_COMPUTE_SHADER: TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43", shader); break;
#endif #endif
default: break; default: break;
} }
@ -4135,6 +4217,11 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
#ifdef RL_SUPPORT_MESH_GPU_SKINNING
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS);
glBindAttribLocation(program, RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS, RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS);
#endif
// NOTE: If some attrib name is no found on the shader, it locations becomes -1 // NOTE: If some attrib name is no found on the shader, it locations becomes -1
glLinkProgram(program); glLinkProgram(program);
@ -4166,7 +4253,7 @@ unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId)
else else
{ {
// Get the size of compiled shader program (not available on OpenGL ES 2.0) // Get the size of compiled shader program (not available on OpenGL ES 2.0)
// NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero
//GLint binarySize = 0; //GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
@ -4226,8 +4313,16 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break; case RL_SHADER_UNIFORM_IVEC2: glUniform2iv(locIndex, count, (int *)value); break;
case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break; case RL_SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break; case RL_SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
#if !defined(GRAPHICS_API_OPENGL_ES2)
case RL_SHADER_UNIFORM_UINT: glUniform1uiv(locIndex, count, (unsigned int *)value); break;
case RL_SHADER_UNIFORM_UIVEC2: glUniform2uiv(locIndex, count, (unsigned int *)value); break;
case RL_SHADER_UNIFORM_UIVEC3: glUniform3uiv(locIndex, count, (unsigned int *)value); break;
case RL_SHADER_UNIFORM_UIVEC4: glUniform4uiv(locIndex, count, (unsigned int *)value); break;
#endif
case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; case RL_SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized"); default: TRACELOG(RL_LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
// TODO: Support glUniform1uiv(), glUniform2uiv(), glUniform3uiv(), glUniform4uiv()
} }
#endif #endif
} }
@ -4261,6 +4356,18 @@ void rlSetUniformMatrix(int locIndex, Matrix mat)
#endif #endif
} }
// Set shader value uniform matrix
void rlSetUniformMatrices(int locIndex, const Matrix *matrices, int count)
{
#if defined(GRAPHICS_API_OPENGL_33)
glUniformMatrix4fv(locIndex, count, true, (const float *)matrices);
#elif defined(GRAPHICS_API_OPENGL_ES2)
// WARNING: WebGL does not support Matrix transpose ("true" parameter)
// REF: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/uniformMatrix
glUniformMatrix4fv(locIndex, count, false, (const float *)matrices);
#endif
}
// Set shader value uniform sampler // Set shader value uniform sampler
void rlSetUniformSampler(int locIndex, unsigned int textureId) void rlSetUniformSampler(int locIndex, unsigned int textureId)
{ {
@ -4340,12 +4447,14 @@ unsigned int rlLoadComputeShaderProgram(unsigned int shaderId)
else else
{ {
// Get the size of compiled shader program (not available on OpenGL ES 2.0) // Get the size of compiled shader program (not available on OpenGL ES 2.0)
// NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. // NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero
//GLint binarySize = 0; //GLint binarySize = 0;
//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); //glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize);
TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program); TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Compute shader program loaded successfully", program);
} }
#else
TRACELOG(RL_LOG_WARNING, "SHADER: Compute shaders not enabled. Define GRAPHICS_API_OPENGL_43");
#endif #endif
return program; return program;
@ -4370,6 +4479,8 @@ unsigned int rlLoadShaderBuffer(unsigned int size, const void *data, int usageHi
glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, usageHint? usageHint : RL_STREAM_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, usageHint? usageHint : RL_STREAM_COPY);
if (data == NULL) glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL); // Clear buffer data to 0 if (data == NULL) glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NULL); // Clear buffer data to 0
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
#else
TRACELOG(RL_LOG_WARNING, "SSBO: SSBO not enabled. Define GRAPHICS_API_OPENGL_43");
#endif #endif
return ssbo; return ssbo;
@ -4380,7 +4491,10 @@ void rlUnloadShaderBuffer(unsigned int ssboId)
{ {
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
glDeleteBuffers(1, &ssboId); glDeleteBuffers(1, &ssboId);
#else
TRACELOG(RL_LOG_WARNING, "SSBO: SSBO not enabled. Define GRAPHICS_API_OPENGL_43");
#endif #endif
} }
// Update SSBO buffer data // Update SSBO buffer data
@ -4395,14 +4509,14 @@ void rlUpdateShaderBuffer(unsigned int id, const void *data, unsigned int dataSi
// Get SSBO buffer size // Get SSBO buffer size
unsigned int rlGetShaderBufferSize(unsigned int id) unsigned int rlGetShaderBufferSize(unsigned int id)
{ {
long long size = 0;
#if defined(GRAPHICS_API_OPENGL_43) #if defined(GRAPHICS_API_OPENGL_43)
GLint64 size = 0;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, id); glBindBuffer(GL_SHADER_STORAGE_BUFFER, id);
glGetInteger64v(GL_SHADER_STORAGE_BUFFER_SIZE, &size); glGetBufferParameteri64v(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &size);
#endif
return (size > 0)? (unsigned int)size : 0; return (size > 0)? (unsigned int)size : 0;
#else
return 0;
#endif
} }
// Read SSBO buffer data (GPU->CPU) // Read SSBO buffer data (GPU->CPU)
@ -4440,6 +4554,8 @@ void rlBindImageTexture(unsigned int id, unsigned int index, int format, bool re
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
glBindImageTexture(index, id, 0, 0, 0, readonly? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat); glBindImageTexture(index, id, 0, 0, 0, readonly? GL_READ_ONLY : GL_READ_WRITE, glInternalFormat);
#else
TRACELOG(RL_LOG_WARNING, "TEXTURE: Image texture binding not enabled. Define GRAPHICS_API_OPENGL_43");
#endif #endif
} }
@ -4518,7 +4634,7 @@ Matrix rlGetMatrixTransform(void)
} }
// Get internal projection matrix for stereo render (selected eye) // Get internal projection matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixProjectionStereo(int eye) Matrix rlGetMatrixProjectionStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -4528,7 +4644,7 @@ RLAPI Matrix rlGetMatrixProjectionStereo(int eye)
} }
// Get internal view offset matrix for stereo render (selected eye) // Get internal view offset matrix for stereo render (selected eye)
RLAPI Matrix rlGetMatrixViewOffsetStereo(int eye) Matrix rlGetMatrixViewOffsetStereo(int eye)
{ {
Matrix mat = rlMatrixIdentity(); Matrix mat = rlMatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -4754,7 +4870,16 @@ static void rlLoadShaderDefault(void)
"out vec2 fragTexCoord; \n" "out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n" "out vec4 fragColor; \n"
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_ES3)
"#version 300 es \n"
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2) (on some browsers)
"in vec3 vertexPosition; \n"
"in vec2 vertexTexCoord; \n"
"in vec4 vertexColor; \n"
"out vec2 fragTexCoord; \n"
"out vec4 fragColor; \n"
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n" "#version 100 \n"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers) "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) (on some browsers)
"attribute vec3 vertexPosition; \n" "attribute vec3 vertexPosition; \n"
@ -4763,6 +4888,7 @@ static void rlLoadShaderDefault(void)
"varying vec2 fragTexCoord; \n" "varying vec2 fragTexCoord; \n"
"varying vec4 fragColor; \n" "varying vec4 fragColor; \n"
#endif #endif
"uniform mat4 mvp; \n" "uniform mat4 mvp; \n"
"void main() \n" "void main() \n"
"{ \n" "{ \n"
@ -4797,7 +4923,21 @@ static void rlLoadShaderDefault(void)
" finalColor = texelColor*colDiffuse*fragColor; \n" " finalColor = texelColor*colDiffuse*fragColor; \n"
"} \n"; "} \n";
#endif #endif
#if defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_ES3)
"#version 300 es \n"
"precision mediump float; \n" // Precision required for OpenGL ES3 (WebGL 2)
"in vec2 fragTexCoord; \n"
"in vec4 fragColor; \n"
"out vec4 finalColor; \n"
"uniform sampler2D texture0; \n"
"uniform vec4 colDiffuse; \n"
"void main() \n"
"{ \n"
" vec4 texelColor = texture(texture0, fragTexCoord); \n"
" finalColor = texelColor*colDiffuse*fragColor; \n"
"} \n";
#elif defined(GRAPHICS_API_OPENGL_ES2)
"#version 100 \n" "#version 100 \n"
"precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL) "precision mediump float; \n" // Precision required for OpenGL ES2 (WebGL)
"varying vec2 fragTexCoord; \n" "varying vec2 fragTexCoord; \n"
@ -4967,7 +5107,8 @@ static int rlGetPixelDataSize(int width, int height, int format)
default: break; default: break;
} }
dataSize = width*height*bpp/8; // Total data size in bytes double bytesPerPixel = (double)bpp/8.0;
dataSize = (int)(bytesPerPixel*width*height); // Total data size in bytes
// Most compressed formats works on 4x4 blocks, // Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16 // if texture is smaller, minimum dataSize is 8 or 16