WARNING: BREAKING: rlgl module redesign -WIP-

- Some rlgl functions have been moved to core
 - Some functions have been made internal to rlgl
 - rlgl functions prefixed with rl*()
This commit is contained in:
Ray 2021-03-21 01:29:31 +01:00
parent f4f6f665f7
commit ed4ca6a7f3
6 changed files with 462 additions and 537 deletions

View file

@ -13,6 +13,7 @@
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "rlgl.h"
#include <time.h> // Required for: localtime(), asctime() #include <time.h> // Required for: localtime(), asctime()
@ -76,7 +77,7 @@ int main(void)
// Try reloading updated shader // Try reloading updated shader
Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION)); Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION));
if (updatedShader.id != GetShaderDefault().id) // It was correctly loaded if (updatedShader.id != rlGetShaderDefault().id) // It was correctly loaded
{ {
UnloadShader(shader); UnloadShader(shader);
shader = updatedShader; shader = updatedShader;

View file

@ -760,7 +760,7 @@ void InitWindow(int width, int height, const char *title)
LoadFontDefault(); LoadFontDefault();
Rectangle rec = GetFontDefault().recs[95]; Rectangle rec = GetFontDefault().recs[95];
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); rlSetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
#endif #endif
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
@ -1837,7 +1837,7 @@ void EndDrawing(void)
} }
#endif #endif
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
#if defined(SUPPORT_GIF_RECORDING) #if defined(SUPPORT_GIF_RECORDING)
#define GIF_RECORD_FRAMERATE 10 #define GIF_RECORD_FRAMERATE 10
@ -1854,7 +1854,7 @@ void EndDrawing(void)
unsigned char *screenData = rlReadScreenPixels(CORE.Window.screen.width, CORE.Window.screen.height); unsigned char *screenData = rlReadScreenPixels(CORE.Window.screen.width, CORE.Window.screen.height);
msf_gif_frame(&gifState, screenData, 10, 16, CORE.Window.screen.width*4); msf_gif_frame(&gifState, screenData, 10, 16, CORE.Window.screen.width*4);
RL_FREE(screenData); // Free image data RL_FREE(screenData); // Free image data
} }
if (((gifFramesCounter/15)%2) == 1) if (((gifFramesCounter/15)%2) == 1)
@ -1863,7 +1863,7 @@ void EndDrawing(void)
DrawText("RECORDING", 50, CORE.Window.screen.height - 25, 10, MAROON); DrawText("RECORDING", 50, CORE.Window.screen.height - 25, 10, MAROON);
} }
rlglDraw(); // Draw RECORDING message rlDrawRenderBatchActive(); // Update and draw internal render batch
} }
#endif #endif
@ -1894,9 +1894,9 @@ void EndDrawing(void)
// Initialize 2D mode with custom camera (2D) // Initialize 2D mode with custom camera (2D)
void BeginMode2D(Camera2D camera) void BeginMode2D(Camera2D camera)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
// Apply 2d camera transformation to modelview // Apply 2d camera transformation to modelview
rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera))); rlMultMatrixf(MatrixToFloat(GetCameraMatrix2D(camera)));
@ -1908,20 +1908,20 @@ void BeginMode2D(Camera2D camera)
// Ends 2D mode with custom camera // Ends 2D mode with custom camera
void EndMode2D(void) void EndMode2D(void)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required
} }
// Initializes 3D mode with custom camera (3D) // Initializes 3D mode with custom camera (3D)
void BeginMode3D(Camera3D camera) void BeginMode3D(Camera3D camera)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection rlPushMatrix(); // Save previous matrix, which contains the settings for the 2d ortho projection
rlLoadIdentity(); // Reset current matrix (projection) rlLoadIdentity(); // Reset current matrix (projection)
float aspect = (float)CORE.Window.currentFbo.width/(float)CORE.Window.currentFbo.height; float aspect = (float)CORE.Window.currentFbo.width/(float)CORE.Window.currentFbo.height;
@ -1943,53 +1943,53 @@ void BeginMode3D(Camera3D camera)
rlOrtho(-right, right, -top,top, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); rlOrtho(-right, right, -top,top, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
} }
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
// Setup Camera view // Setup Camera view
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
rlMultMatrixf(MatrixToFloat(matView)); // Multiply modelview matrix by view matrix (camera) rlMultMatrixf(MatrixToFloat(matView)); // Multiply modelview matrix by view matrix (camera)
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
} }
// Ends 3D mode and returns to default 2D orthographic mode // Ends 3D mode and returns to default 2D orthographic mode
void EndMode3D(void) void EndMode3D(void)
{ {
rlglDraw(); // Process internal buffers (update + draw) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlPopMatrix(); // Restore previous matrix (projection) from matrix stack rlPopMatrix(); // Restore previous matrix (projection) from matrix stack
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required rlMultMatrixf(MatrixToFloat(CORE.Window.screenScale)); // Apply screen scaling if required
rlDisableDepthTest(); // Disable DEPTH_TEST for 2D rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
} }
// Initializes render texture for drawing // Initializes render texture for drawing
void BeginTextureMode(RenderTexture2D target) void BeginTextureMode(RenderTexture2D target)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlEnableFramebuffer(target.id); // Enable render target rlEnableFramebuffer(target.id); // Enable render target
// Set viewport to framebuffer size // Set viewport to framebuffer size
rlViewport(0, 0, target.texture.width, target.texture.height); rlViewport(0, 0, target.texture.width, target.texture.height);
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlLoadIdentity(); // Reset current matrix (projection) rlLoadIdentity(); // Reset current matrix (projection)
// Set orthographic projection to current framebuffer size // Set orthographic projection to current framebuffer size
// NOTE: Configured top-left corner as (0, 0) // NOTE: Configured top-left corner as (0, 0)
rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f); rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f);
rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix rlMatrixMode(RL_MODELVIEW); // Switch back to modelview matrix
rlLoadIdentity(); // Reset current matrix (modelview) rlLoadIdentity(); // Reset current matrix (modelview)
//rlScalef(0.0f, -1.0f, 0.0f); // Flip Y-drawing (?) //rlScalef(0.0f, -1.0f, 0.0f); // Flip Y-drawing (?)
// Setup current width/height for proper aspect ratio // Setup current width/height for proper aspect ratio
// calculation when using BeginMode3D() // calculation when using BeginMode3D()
@ -2000,9 +2000,9 @@ void BeginTextureMode(RenderTexture2D target)
// Ends drawing to render texture // Ends drawing to render texture
void EndTextureMode(void) void EndTextureMode(void)
{ {
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) rlDrawRenderBatchActive(); // Update and draw internal render batch
rlDisableFramebuffer(); // Disable render target (fbo) rlDisableFramebuffer(); // Disable render target (fbo)
// Set viewport to default framebuffer size // Set viewport to default framebuffer size
SetupViewport(CORE.Window.render.width, CORE.Window.render.height); SetupViewport(CORE.Window.render.width, CORE.Window.render.height);
@ -2012,6 +2012,121 @@ void EndTextureMode(void)
CORE.Window.currentFbo.height = CORE.Window.screen.height; CORE.Window.currentFbo.height = CORE.Window.screen.height;
} }
// Load shader from files and bind default locations
// NOTE: If shader string is NULL, using default vertex/fragment shaders
Shader LoadShader(const char *vsFileName, const char *fsFileName)
{
Shader shader = { 0 };
shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS, sizeof(int));
// NOTE: All locations must be reseted to -1 (no location)
for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
char *vShaderStr = NULL;
char *fShaderStr = NULL;
if (vsFileName != NULL) vShaderStr = LoadFileText(vsFileName);
if (fsFileName != NULL) fShaderStr = LoadFileText(fsFileName);
shader.id = rlLoadShaderCode(vShaderStr, fShaderStr);
if (vShaderStr != NULL) RL_FREE(vShaderStr);
if (fShaderStr != NULL) RL_FREE(fShaderStr);
// After shader loading, we TRY to set default location names
if (shader.id > 0) SetShaderDefaultLocations(&shader);
return shader;
}
// Unload shader from GPU memory (VRAM)
void UnloadShader(Shader shader)
{
if (shader.id != rlGetShaderDefault().id)
{
rlUnloadShaderProgram(shader.id);
RL_FREE(shader.locs);
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
}
}
// Begin custom shader mode
void BeginShaderMode(Shader shader)
{
rlSetShaderCurrent(shader);
}
// End custom shader mode (returns to default shader)
void EndShaderMode(void)
{
BeginShaderMode(rlGetShaderDefault());
}
// Get shader uniform location
int GetShaderLocation(Shader shader, const char *uniformName)
{
int location = rlGetLocationUniform(shader.id, uniformName);
if (location == -1) TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shader.id, uniformName);
else TRACELOG(LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shader.id, uniformName, location);
return location;
}
// Get shader attribute location
int GetShaderLocationAttrib(Shader shader, const char *attribName)
{
int location = rlGetLocationAttrib(shader.id, attribName);
if (location == -1) TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shader.id, attribName);
else TRACELOG(LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shader.id, attribName, location);
return location;
}
// Set shader uniform value
void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType)
{
SetShaderValueV(shader, locIndex, value, uniformType, 1);
}
// Set shader uniform value vector
void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count)
{
rlEnableShader(shader.id);
rlSetUniform(locIndex, value, uniformType, count);
//rlDisableShader(); // Avoid reseting current shader program, in case other uniforms are set
}
// Set shader uniform value (matrix 4x4)
void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat)
{
rlEnableShader(shader.id);
rlSetUniformMatrix(locIndex, mat);
//rlDisableShader();
}
// Set shader uniform value for texture
void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
{
rlEnableShader(shader.id);
rlSetUniformSampler(locIndex, texture);
//rlDisableShader();
}
// Begin blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes supported, default blend mode is alpha
void BeginBlendMode(int mode)
{
rlSetBlendMode(mode);
}
// End blending mode (reset to default: alpha blending)
void EndBlendMode(void)
{
rlSetBlendMode(BLEND_ALPHA);
}
#if defined(SUPPORT_VR_SIMULATOR) #if defined(SUPPORT_VR_SIMULATOR)
// Init VR simulator for selected device parameters // Init VR simulator for selected device parameters
@ -2143,9 +2258,9 @@ void EndVrDrawing(void)
rlDisableFramebuffer(); // Unbind current framebuffer rlDisableFramebuffer(); // Unbind current framebuffer
// Reset viewport and default projection-modelview matrices // Reset viewport and default projection-modelview matrices
rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight); rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
SetMatrixProjection(MatrixOrtho(0.0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, 0.0, 0.0, 1.0)); rlSetMatrixProjection(MatrixOrtho(0.0, GetScreenWidth(), GetScreenHeight(), 0.0, 0.0, 1.0));
SetMatrixModelview(MatrixIdentity()); rlSetMatrixModelview(MatrixIdentity());
rlDisableDepthTest(); rlDisableDepthTest();
} }
@ -2157,7 +2272,7 @@ void EndVrDrawing(void)
// NOTE: Scissor rec refers to bottom-left corner, we change it to upper-left // NOTE: Scissor rec refers to bottom-left corner, we change it to upper-left
void BeginScissorMode(int x, int y, int width, int height) void BeginScissorMode(int x, int y, int width, int height)
{ {
rlglDraw(); // Force drawing elements rlDrawRenderBatchActive(); // Update and draw internal render batch
rlEnableScissorTest(); rlEnableScissorTest();
rlScissor(x, CORE.Window.currentFbo.height - (y + height), width, height); rlScissor(x, CORE.Window.currentFbo.height - (y + height), width, height);
@ -2166,7 +2281,7 @@ void BeginScissorMode(int x, int y, int width, int height)
// End scissor mode // End scissor mode
void EndScissorMode(void) void EndScissorMode(void)
{ {
rlglDraw(); // Force drawing elements rlDrawRenderBatchActive(); // Update and draw internal render batch
rlDisableScissorTest(); rlDisableScissorTest();
} }
@ -5057,7 +5172,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
LoadFontDefault(); LoadFontDefault();
Rectangle rec = GetFontDefault().recs[95]; Rectangle rec = GetFontDefault().recs[95];
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); rlSetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
#endif #endif
// TODO: GPU assets reload in case of lost focus (lost context) // TODO: GPU assets reload in case of lost focus (lost context)

View file

@ -131,7 +131,7 @@ static void InitGLTFBones(Model* model, const cgltf_data* data);
// Draw a line in 3D world space // Draw a line in 3D world space
void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color) void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
{ {
if (rlCheckBufferLimit(2)) rlglDraw(); rlCheckRenderBatchLimit(2);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -143,7 +143,7 @@ void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
// Draw a point in 3D space, actually a small line // Draw a point in 3D space, actually a small line
void DrawPoint3D(Vector3 position, Color color) void DrawPoint3D(Vector3 position, Color color)
{ {
if (rlCheckBufferLimit(2)) rlglDraw(); rlCheckRenderBatchLimit(2);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -158,7 +158,7 @@ void DrawPoint3D(Vector3 position, Color color)
// Draw a circle in 3D world space // Draw a circle in 3D world space
void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color) void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color)
{ {
if (rlCheckBufferLimit(2*36)) rlglDraw(); rlCheckRenderBatchLimit(2*36);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(center.x, center.y, center.z); rlTranslatef(center.x, center.y, center.z);
@ -179,7 +179,7 @@ void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rota
// Draw a color-filled triangle (vertex in counter-clockwise order!) // Draw a color-filled triangle (vertex in counter-clockwise order!)
void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color) void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
{ {
if (rlCheckBufferLimit(3)) rlglDraw(); rlCheckRenderBatchLimit(3);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -194,7 +194,7 @@ void DrawTriangleStrip3D(Vector3 *points, int pointsCount, Color color)
{ {
if (pointsCount >= 3) if (pointsCount >= 3)
{ {
if (rlCheckBufferLimit(3*(pointsCount - 2))) rlglDraw(); rlCheckRenderBatchLimit(3*(pointsCount - 2));
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -226,7 +226,7 @@ void DrawCube(Vector3 position, float width, float height, float length, Color c
float y = 0.0f; float y = 0.0f;
float z = 0.0f; float z = 0.0f;
if (rlCheckBufferLimit(36)) rlglDraw(); rlCheckRenderBatchLimit(36);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate) // NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
@ -307,7 +307,7 @@ void DrawCubeWires(Vector3 position, float width, float height, float length, Co
float y = 0.0f; float y = 0.0f;
float z = 0.0f; float z = 0.0f;
if (rlCheckBufferLimit(36)) rlglDraw(); rlCheckRenderBatchLimit(36);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -384,7 +384,7 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
float y = position.y; float y = position.y;
float z = position.z; float z = position.z;
if (rlCheckBufferLimit(36)) rlglDraw(); rlCheckRenderBatchLimit(36);
rlEnableTexture(texture.id); rlEnableTexture(texture.id);
@ -448,7 +448,7 @@ void DrawSphere(Vector3 centerPos, float radius, Color color)
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color) void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color)
{ {
int numVertex = (rings + 2)*slices*6; int numVertex = (rings + 2)*slices*6;
if (rlCheckBufferLimit(numVertex)) rlglDraw(); rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate) // NOTE: Transformation is applied in inverse order (scale -> translate)
@ -491,7 +491,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color) void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color)
{ {
int numVertex = (rings + 2)*slices*6; int numVertex = (rings + 2)*slices*6;
if (rlCheckBufferLimit(numVertex)) rlglDraw(); rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> translate) // NOTE: Transformation is applied in inverse order (scale -> translate)
@ -538,7 +538,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*6; int numVertex = sides*6;
if (rlCheckBufferLimit(numVertex)) rlglDraw(); rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -597,7 +597,7 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
int numVertex = sides*8; int numVertex = sides*8;
if (rlCheckBufferLimit(numVertex)) rlglDraw(); rlCheckRenderBatchLimit(numVertex);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(position.x, position.y, position.z); rlTranslatef(position.x, position.y, position.z);
@ -626,7 +626,7 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
// Draw a plane // Draw a plane
void DrawPlane(Vector3 centerPos, Vector2 size, Color color) void DrawPlane(Vector3 centerPos, Vector2 size, Color color)
{ {
if (rlCheckBufferLimit(4)) rlglDraw(); rlCheckRenderBatchLimit(4);
// NOTE: Plane is always created on XZ ground // NOTE: Plane is always created on XZ ground
rlPushMatrix(); rlPushMatrix();
@ -664,7 +664,7 @@ void DrawGrid(int slices, float spacing)
{ {
int halfSlices = slices/2; int halfSlices = slices/2;
if (rlCheckBufferLimit((slices + 2)*4)) rlglDraw(); rlCheckRenderBatchLimit((slices + 2)*4);
rlBegin(RL_LINES); rlBegin(RL_LINES);
for (int i = -halfSlices; i <= halfSlices; i++) for (int i = -halfSlices; i <= halfSlices; i++)
@ -968,7 +968,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
// Set materials shader to default (DIFFUSE, SPECULAR, NORMAL) // Set materials shader to default (DIFFUSE, SPECULAR, NORMAL)
if (materials != NULL) if (materials != NULL)
{ {
for (unsigned int i = 0; i < count; i++) materials[i].shader = GetShaderDefault(); for (unsigned int i = 0; i < count; i++) materials[i].shader = rlGetShaderDefault();
} }
*materialCount = count; *materialCount = count;
@ -981,8 +981,8 @@ Material LoadMaterialDefault(void)
Material material = { 0 }; Material material = { 0 };
material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS, sizeof(MaterialMap)); material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS, sizeof(MaterialMap));
material.shader = GetShaderDefault(); material.shader = rlGetShaderDefault();
material.maps[MATERIAL_MAP_DIFFUSE].texture = GetTextureDefault(); // White texture (1x1 pixel) material.maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault(); // White texture (1x1 pixel)
//material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set //material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set
//material.maps[MATERIAL_MAP_SPECULAR].texture; // NOTE: By default, not set //material.maps[MATERIAL_MAP_SPECULAR].texture; // NOTE: By default, not set
@ -996,12 +996,12 @@ Material LoadMaterialDefault(void)
void UnloadMaterial(Material material) void UnloadMaterial(Material material)
{ {
// Unload material shader (avoid unloading default shader, managed by raylib) // Unload material shader (avoid unloading default shader, managed by raylib)
if (material.shader.id != GetShaderDefault().id) UnloadShader(material.shader); if (material.shader.id != rlGetShaderDefault().id) UnloadShader(material.shader);
// Unload loaded texture maps (avoid unloading default texture, managed by raylib) // Unload loaded texture maps (avoid unloading default texture, managed by raylib)
for (int i = 0; i < MAX_MATERIAL_MAPS; i++) for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{ {
if (material.maps[i].texture.id != GetTextureDefault().id) rlUnloadTexture(material.maps[i].texture.id); if (material.maps[i].texture.id != rlGetTextureDefault().id) rlUnloadTexture(material.maps[i].texture.id);
} }
RL_FREE(material.maps); RL_FREE(material.maps);
@ -2454,7 +2454,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
Vector3 c = Vector3Add(center, p2); Vector3 c = Vector3Add(center, p2);
Vector3 d = Vector3Subtract(center, p1); Vector3 d = Vector3Subtract(center, p1);
if (rlCheckBufferLimit(4)) rlglDraw(); rlCheckRenderBatchLimit(4);
rlEnableTexture(texture.id); rlEnableTexture(texture.id);
@ -2894,10 +2894,10 @@ static Model LoadOBJ(const char *fileName)
// NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE // NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE
model.materials[m] = LoadMaterialDefault(); model.materials[m] = LoadMaterialDefault();
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = GetTextureDefault(); // Get default texture, in case no texture is defined model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault(); // Get default texture, in case no texture is defined
if (materials[m].diffuse_texname != NULL) model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname); //char *diffuse_texname; // map_Kd if (materials[m].diffuse_texname != NULL) model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname); //char *diffuse_texname; // map_Kd
else model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = GetTextureDefault(); else model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault();
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3]; model.materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3];
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f; model.materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f;

View file

@ -1095,6 +1095,18 @@ RLAPI void SetCameraAltControl(int keyAlt); // Set camera
RLAPI void SetCameraSmoothZoomControl(int keySmoothZoom); // Set camera smooth zoom key to combine with mouse (free camera) RLAPI void SetCameraSmoothZoomControl(int keySmoothZoom); // Set camera smooth zoom key to combine with mouse (free camera)
RLAPI void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int keyLeft, int keyUp, int keyDown); // Set camera move controls (1st person and 3rd person cameras) RLAPI void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int keyLeft, int keyUp, int keyDown); // Set camera move controls (1st person and 3rd person cameras)
//------------------------------------------------------------------------------------
// VR Simulator Functions (Module: core)
//------------------------------------------------------------------------------------
RLAPI void InitVrSimulator(VrDeviceInfo device); // Init VR simulator for selected device parameters
RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
RLAPI void BeginVrDrawing(RenderTexture2D target); // Begin VR simulator stereo rendering (using provided fbo)
RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
RLAPI VrStereoConfig GetVrConfig(VrDeviceInfo device); // Get stereo rendering configuration parameters
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes) // Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -1414,51 +1426,21 @@ RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);
// NOTE: This functions are useless when using OpenGL 1.1 // NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Shader loading/unloading functions
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI Shader LoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI Shader GetShaderDefault(void); // Get default shader
RLAPI Texture2D GetTextureDefault(void); // Get default texture
RLAPI Texture2D GetShapesTexture(void); // Get texture to draw shapes
RLAPI Rectangle GetShapesTextureRec(void); // Get texture rectangle to draw shapes
RLAPI void SetShapesTexture(Texture2D texture, Rectangle source); // Define default texture used to draw shapes
// Shader configuration functions
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI Matrix GetMatrixModelview(void); // Get internal modelview matrix
RLAPI Matrix GetMatrixProjection(void); // Get internal projection matrix
// Texture maps generation (PBR)
// NOTE: Required shaders should be provided
RLAPI TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); // Generate cubemap texture from 2D panorama texture
RLAPI TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size); // Generate irradiance texture using cubemap data
RLAPI TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size); // Generate prefilter texture using cubemap data
RLAPI Texture2D GenTextureBRDF(Shader shader, int size); // Generate BRDF texture
// Shading begin/end functions // Shading begin/end functions
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader) RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied) RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending) RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
// VR control functions // Shader management functions
RLAPI void InitVrSimulator(VrDeviceInfo device); // Init VR simulator for selected device parameters RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI void CloseVrSimulator(void); // Close VR simulator for current device RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
RLAPI void BeginVrDrawing(RenderTexture2D target); // Begin VR simulator stereo rendering (using provided fbo) RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
RLAPI VrStereoConfig GetVrConfig(VrDeviceInfo device); // Get stereo rendering configuration parameters RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4)
RLAPI Texture2D GetVrTexture(void); // Get VR framebuffer texture RLAPI void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio) // Audio Loading and Playing Functions (Module: audio)

View file

@ -8,7 +8,6 @@
* When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal * When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal
* VBO buffers (and VAOs if available). It requires calling 3 functions: * VBO buffers (and VAOs if available). It requires calling 3 functions:
* rlglInit() - Initialize internal buffers and auxiliary resources * rlglInit() - Initialize internal buffers and auxiliary resources
* rlglDraw() - Process internal buffers and send required draw calls
* rlglClose() - De-initialize internal buffers data and other auxiliar resources * rlglClose() - De-initialize internal buffers data and other auxiliar resources
* *
* CONFIGURATION: * CONFIGURATION:
@ -520,14 +519,13 @@ RLAPI unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *b
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states) RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures) RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
RLAPI void rlglDraw(void); // Update and draw default internal buffers
RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
RLAPI int rlGetVersion(void); // Returns current OpenGL version RLAPI int rlGetVersion(void); // Returns current OpenGL version
RLAPI bool rlCheckBufferLimit(int vCount); // Check internal buffer overflow for a given number of vertex RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
RLAPI void rlSetDebugMarker(const char *text); // Set debug marker for analysis RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function pointer required)
RLAPI void rlSetBlendMode(int glSrcFactor, int glDstFactor, int glEquation); // // Set blending mode factor and equation (using OpenGL factors)
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions RLAPI void rlSetBlendMode(int mode);
RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors)
// Textures data management // Textures data management
RLAPI unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU RLAPI unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
@ -561,48 +559,27 @@ RLAPI void rlUnloadMesh(Mesh *mesh); // Unl
// NOTE: There is a set of shader related functions that are available to end user, // NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h // to avoid creating function wrappers through core module, they have been directly declared in raylib.h
#if defined(RLGL_STANDALONE) RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
//------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
// Shader loading/unloading functions
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
RLAPI Shader LoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
RLAPI Shader GetShaderDefault(void); // Get default shader RLAPI Shader rlGetShaderDefault(void); // Get default shader
RLAPI Texture2D GetTextureDefault(void); // Get default texture RLAPI Texture2D rlGetTextureDefault(void); // Get default texture
RLAPI Texture2D GetShapesTexture(void); // Get texture to draw shapes RLAPI Texture2D rlGetShapesTexture(void); // Get texture to draw shapes
RLAPI Rectangle GetShapesTextureRec(void); // Get texture rectangle to draw shapes RLAPI Rectangle rlGetShapesTextureRec(void); // Get texture rectangle to draw shapes
RLAPI void rlSetShapesTexture(Texture2D texture, Rectangle source); // Define default texture used to draw shapes
// Shader configuration functions RLAPI void rlSetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location RLAPI void rlSetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value RLAPI Matrix rlGetMatrixProjection(void); // Get internal projection matrix
RLAPI void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); // Set shader uniform value vector
RLAPI void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI Matrix GetMatrixModelview(void); // Get internal modelview matrix
RLAPI Matrix GetMatrixProjection(void); // Get internal projection matrix
// Texture maps generation (PBR) // Texture maps generation (PBR)
// NOTE: Required shaders should be provided // NOTE: Required shaders should be provided
RLAPI TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); // Generate cubemap (6 faces) from equirectangular (panorama) texture RLAPI TextureCubemap rlGenTextureCubemap(Shader shader, Texture2D panorama, int size, int format); // Generate cubemap (6 faces) from equirectangular (panorama) texture
RLAPI TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size); // Generate irradiance cubemap using cubemap texture RLAPI TextureCubemap rlGenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size); // Generate irradiance cubemap using cubemap texture
RLAPI TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size); // Generate prefilter cubemap using cubemap texture RLAPI TextureCubemap rlGenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size); // Generate prefilter cubemap using cubemap texture
RLAPI Texture2D GenTextureBRDF(Shader shader, int size); // Generate a generic BRDF texture RLAPI Texture2D rlGenTextureBRDF(Shader shader, int size); // Generate a generic BRDF texture
// Shading begin/end functions
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
RLAPI char *LoadFileText(const char *fileName); // Load chars array from text file
RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data size in bytes (image or texture)
#endif
#if defined(__cplusplus) #if defined(__cplusplus)
} }
@ -618,9 +595,7 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data
#if defined(RLGL_IMPLEMENTATION) #if defined(RLGL_IMPLEMENTATION)
#if defined(RLGL_STANDALONE) #if !defined(RLGL_STANDALONE)
#include <stdio.h> // Required for: fopen(), fseek(), fread(), fclose() [LoadFileText]
#else
// Check if config flags have been externally provided on compilation line // Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS) #if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
@ -868,7 +843,6 @@ typedef struct rlglData {
bool texCompASTC; // ASTC texture compression support bool texCompASTC; // ASTC texture compression support
bool texMirrorClamp; // Clamp mirror wrap mode supported bool texMirrorClamp; // Clamp mirror wrap mode supported
bool texAnisoFilter; // Anisotropic texture filtering support bool texAnisoFilter; // Anisotropic texture filtering support
bool debugMarker; // Debug marker support
float maxAnisotropicLevel; // Maximum anisotropy level supported (minimum is 2.0f) float maxAnisotropicLevel; // Maximum anisotropy level supported (minimum is 2.0f)
int maxDepthBits; // Maximum bits for depth component int maxDepthBits; // Maximum bits for depth component
@ -907,17 +881,18 @@ static Shader LoadShaderDefault(void); // Load default shader (
static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms) static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
static void UnloadShaderDefault(void); // Unload default shader static void UnloadShaderDefault(void); // Unload default shader
static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system
static void UnloadRenderBatch(RenderBatch batch); // Unload render batch system
static void DrawRenderBatch(RenderBatch *batch); // Draw render batch data (Update->Draw->Reset)
static void SetRenderBatchActive(RenderBatch *batch); // Set the active render batch for rlgl
static void SetRenderBatchDefault(void); // Set default render batch for rlgl
//static bool CheckRenderBatchLimit(RenderBatch batch, int vCount); // Check render batch vertex buffer limits
static void GenDrawCube(void); // Generate and draw cube static void GenDrawCube(void); // Generate and draw cube
static void GenDrawQuad(void); // Generate and draw quad static void GenDrawQuad(void); // Generate and draw quad
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 #endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
//static int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
static RenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system
static void rlUnloadRenderBatch(RenderBatch batch); // Unload render batch system
static void rlDrawRenderBatch(RenderBatch *batch); // Draw render batch data (Update->Draw->Reset)
static void rlSetRenderBatchActive(RenderBatch *batch); // Set the active render batch for rlgl
static void rlSetRenderBatchDefault(void); // Set default render batch for rlgl
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight); static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight);
static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight); static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight);
@ -1120,11 +1095,9 @@ void rlBegin(int mode)
// for the next set of vertex to be drawn // for the next set of vertex to be drawn
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4); if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4))); else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0; else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
if (rlCheckBufferLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment)) DrawRenderBatch(RLGL.currentBatch); if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
else
{ {
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment; RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment; RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
@ -1134,7 +1107,7 @@ void rlBegin(int mode)
} }
} }
if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) DrawRenderBatch(RLGL.currentBatch); if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode = mode; RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode = mode;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0; RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
@ -1184,14 +1157,15 @@ void rlEnd(void)
RLGL.currentBatch->currentDepth += (1.0f/20000.0f); RLGL.currentBatch->currentDepth += (1.0f/20000.0f);
// Verify internal buffers limits // Verify internal buffers limits
// NOTE: This check is combined with usage of rlCheckBufferLimit() // NOTE: This check is combined with usage of rlCheckRenderBatchLimit()
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter) >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4 - 4)) if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4 - 4))
{ {
// WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a DrawRenderBatch(), // WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlDrawRenderBatch(),
// we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call! // we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
// If we have multiple matrix pushed, it will require "RLGL.State.stackCounter" pops before launching the draw // If we have multiple matrix pushed, it will require "RLGL.State.stackCounter" pops before launching the draw
for (int i = RLGL.State.stackCounter; i >= 0; i--) rlPopMatrix(); for (int i = RLGL.State.stackCounter; i >= 0; i--) rlPopMatrix();
DrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
} }
} }
@ -1293,11 +1267,9 @@ void rlEnableTexture(unsigned int id)
// for the next set of vertex to be drawn // for the next set of vertex to be drawn
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4); if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4))); else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0; else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
if (rlCheckBufferLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment)) DrawRenderBatch(RLGL.currentBatch); if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
else
{ {
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment; RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment; RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
@ -1307,7 +1279,7 @@ void rlEnableTexture(unsigned int id)
} }
} }
if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) DrawRenderBatch(RLGL.currentBatch); if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id; RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0; RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
@ -1324,7 +1296,7 @@ void rlDisableTexture(void)
#else #else
// NOTE: If quads batch limit is reached, // NOTE: If quads batch limit is reached,
// we force a draw call and next batch starts // we force a draw call and next batch starts
if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) DrawRenderBatch(RLGL.currentBatch); if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) rlDrawRenderBatch(RLGL.currentBatch);
#endif #endif
} }
@ -1704,9 +1676,6 @@ void rlglInit(int width, int height)
// Clamp mirror wrap mode supported // Clamp mirror wrap mode supported
if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true; if (strcmp(extList[i], (const char *)"GL_EXT_texture_mirror_clamp") == 0) RLGL.ExtSupported.texMirrorClamp = true;
// Debug marker support
if (strcmp(extList[i], (const char *)"GL_EXT_debug_marker") == 0) RLGL.ExtSupported.debugMarker = true;
} }
// Free extensions pointers // Free extensions pointers
@ -1733,8 +1702,6 @@ void rlglInit(int width, int height)
if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "GL: Anisotropic textures filtering supported (max: %.0fX)", RLGL.ExtSupported.maxAnisotropicLevel); if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "GL: Anisotropic textures filtering supported (max: %.0fX)", RLGL.ExtSupported.maxAnisotropicLevel);
if (RLGL.ExtSupported.texMirrorClamp) TRACELOG(LOG_INFO, "GL: Mirror clamp wrap texture mode supported"); if (RLGL.ExtSupported.texMirrorClamp) TRACELOG(LOG_INFO, "GL: Mirror clamp wrap texture mode supported");
if (RLGL.ExtSupported.debugMarker) TRACELOG(LOG_INFO, "GL: Debug Marker supported");
// Initialize buffers, default shaders and default textures // Initialize buffers, default shaders and default textures
//---------------------------------------------------------- //----------------------------------------------------------
// Init default white texture // Init default white texture
@ -1749,7 +1716,7 @@ void rlglInit(int width, int height)
RLGL.State.currentShader = RLGL.State.defaultShader; RLGL.State.currentShader = RLGL.State.defaultShader;
// Init default vertex arrays buffers // Init default vertex arrays buffers
RLGL.defaultBatch = LoadRenderBatch(DEFAULT_BATCH_BUFFERS, DEFAULT_BATCH_BUFFER_ELEMENTS); RLGL.defaultBatch = rlLoadRenderBatch(DEFAULT_BATCH_BUFFERS, DEFAULT_BATCH_BUFFER_ELEMENTS);
RLGL.currentBatch = &RLGL.defaultBatch; RLGL.currentBatch = &RLGL.defaultBatch;
// Init stack matrices (emulating OpenGL 1.1) // Init stack matrices (emulating OpenGL 1.1)
@ -1796,7 +1763,7 @@ void rlglInit(int width, int height)
RLGL.State.framebufferHeight = height; RLGL.State.framebufferHeight = height;
// Init texture and rectangle used on basic shapes drawing // Init texture and rectangle used on basic shapes drawing
RLGL.State.shapesTexture = GetTextureDefault(); RLGL.State.shapesTexture = rlGetTextureDefault();
RLGL.State.shapesTextureRec = (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }; RLGL.State.shapesTextureRec = (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f };
TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully"); TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully");
@ -1812,7 +1779,7 @@ void rlglInit(int width, int height)
void rlglClose(void) void rlglClose(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
UnloadRenderBatch(RLGL.defaultBatch); rlUnloadRenderBatch(RLGL.defaultBatch);
UnloadShaderDefault(); // Unload default shader UnloadShaderDefault(); // Unload default shader
glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
@ -1821,48 +1788,33 @@ void rlglClose(void)
#endif #endif
} }
// Update and draw internal buffers // Update and draw internal render batch
void rlglDraw(void) void rlDrawRenderBatchActive(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
DrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
#endif #endif
} }
// Check and log OpenGL error codes // Check and log OpenGL error codes
void rlCheckErrors() { void rlCheckErrors()
{
#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
int check = 1; int check = 1;
while (check) { while (check)
{
const GLenum err = glGetError(); const GLenum err = glGetError();
switch (err) { switch (err)
case GL_NO_ERROR: {
check = 0; case GL_NO_ERROR: check = 0; break;
break; case 0x0500: TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM"); break;
case 0x0500: // GL_INVALID_ENUM: case 0x0501: TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE"); break;
TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_ENUM"); case 0x0502: TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION"); break;
break; case 0x0503: TRACELOG(LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW"); break;
case 0x0501: //GL_INVALID_VALUE: case 0x0504: TRACELOG(LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW"); break;
TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_VALUE"); case 0x0505: TRACELOG(LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY"); break;
break; case 0x0506: TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION"); break;
case 0x0502: //GL_INVALID_OPERATION: default: TRACELOG(LOG_WARNING, "GL: Error detected: Unknown error code: %x", err); break;
TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_OPERATION");
break;
case 0x0503: // GL_STACK_OVERFLOW:
TRACELOG(LOG_WARNING, "GL: Error detected: GL_STACK_OVERFLOW");
break;
case 0x0504: // GL_STACK_UNDERFLOW:
TRACELOG(LOG_WARNING, "GL: Error detected: GL_STACK_UNDERFLOW");
break;
case 0x0505: // GL_OUT_OF_MEMORY:
TRACELOG(LOG_WARNING, "GL: Error detected: GL_OUT_OF_MEMORY");
break;
case 0x0506: // GL_INVALID_FRAMEBUFFER_OPERATION:
TRACELOG(LOG_WARNING, "GL: Error detected: GL_INVALID_FRAMEBUFFER_OPERATION");
break;
default:
TRACELOG(LOG_WARNING, "GL: Error detected: unknown error code %x", err);
break;
} }
} }
#endif #endif
@ -1890,25 +1842,23 @@ int rlGetVersion(void)
} }
// Check internal buffer overflow for a given number of vertex // Check internal buffer overflow for a given number of vertex
bool rlCheckBufferLimit(int vCount) // and force a RenderBatch draw call if required
bool rlCheckRenderBatchLimit(int vCount)
{ {
bool overflow = false; bool overflow = false;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + vCount) >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) overflow = true; if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + vCount) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4))
{
overflow = true;
rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
}
#endif #endif
return overflow; return overflow;
} }
// Set debug marker
void rlSetDebugMarker(const char *text)
{
#if defined(GRAPHICS_API_OPENGL_33)
if (RLGL.ExtSupported.debugMarker) glInsertEventMarkerEXT(0, text);
#endif
}
// Set blending mode factor and equation // Set blending mode factor and equation
void rlSetBlendMode(int glSrcFactor, int glDstFactor, int glEquation) void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.glBlendSrcFactor = glSrcFactor; RLGL.State.glBlendSrcFactor = glSrcFactor;
@ -2862,9 +2812,9 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight); rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
// Set current eye view offset to modelview matrix // Set current eye view offset to modelview matrix
SetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye])); rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
// Set current eye projection matrix // Set current eye projection matrix
SetMatrixProjection(RLGL.State.eyesProjection[eye]); rlSetMatrixProjection(RLGL.State.eyesProjection[eye]);
} }
// Calculate model-view-projection matrix (MVP) // Calculate model-view-projection matrix (MVP)
@ -3132,7 +3082,7 @@ void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Get default internal texture (white texture) // Get default internal texture (white texture)
Texture2D GetTextureDefault(void) Texture2D rlGetTextureDefault(void)
{ {
Texture2D texture = { 0 }; Texture2D texture = { 0 };
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -3146,7 +3096,7 @@ Texture2D GetTextureDefault(void)
} }
// Get texture to draw shapes (RAII) // Get texture to draw shapes (RAII)
Texture2D GetShapesTexture(void) Texture2D rlGetShapesTexture(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
Texture2D texture = { 0 }; Texture2D texture = { 0 };
@ -3157,7 +3107,7 @@ Texture2D GetShapesTexture(void)
} }
// Get texture rectangle to draw shapes // Get texture rectangle to draw shapes
Rectangle GetShapesTextureRec(void) Rectangle rlGetShapesTextureRec(void)
{ {
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
Rectangle rec = { 0 }; Rectangle rec = { 0 };
@ -3168,7 +3118,7 @@ Rectangle GetShapesTextureRec(void)
} }
// Define default texture used to draw shapes // Define default texture used to draw shapes
void SetShapesTexture(Texture2D texture, Rectangle source) void rlSetShapesTexture(Texture2D texture, Rectangle source)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.shapesTexture = texture; RLGL.State.shapesTexture = texture;
@ -3177,7 +3127,7 @@ void SetShapesTexture(Texture2D texture, Rectangle source)
} }
// Get default shader // Get default shader
Shader GetShaderDefault(void) Shader rlGetShaderDefault(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
return RLGL.State.defaultShader; return RLGL.State.defaultShader;
@ -3187,37 +3137,11 @@ Shader GetShaderDefault(void)
#endif #endif
} }
// Load shader from files and bind default locations
// NOTE: If shader string is NULL, using default vertex/fragment shaders
Shader LoadShader(const char *vsFileName, const char *fsFileName)
{
Shader shader = { 0 };
// NOTE: Shader.locs is allocated by LoadShaderCode()
char *vShaderStr = NULL;
char *fShaderStr = NULL;
if (vsFileName != NULL) vShaderStr = LoadFileText(vsFileName);
if (fsFileName != NULL) fShaderStr = LoadFileText(fsFileName);
shader = LoadShaderCode(vShaderStr, fShaderStr);
if (vShaderStr != NULL) RL_FREE(vShaderStr);
if (fShaderStr != NULL) RL_FREE(fShaderStr);
return shader;
}
// Load shader from code strings // Load shader from code strings
// NOTE: If shader string is NULL, using default vertex/fragment shaders // NOTE: If shader string is NULL, using default vertex/fragment shaders
Shader LoadShaderCode(const char *vsCode, const char *fsCode) unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
{ {
Shader shader = { 0 }; unsigned int id = 0;
shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS, sizeof(int));
// NOTE: All locations must be reseted to -1 (no location)
for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
unsigned int vertexShaderId = RLGL.State.defaultVShaderId; unsigned int vertexShaderId = RLGL.State.defaultVShaderId;
@ -3226,39 +3150,36 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
if (vsCode != NULL) vertexShaderId = CompileShader(vsCode, GL_VERTEX_SHADER); if (vsCode != NULL) vertexShaderId = CompileShader(vsCode, GL_VERTEX_SHADER);
if (fsCode != NULL) fragmentShaderId = CompileShader(fsCode, GL_FRAGMENT_SHADER); if (fsCode != NULL) fragmentShaderId = CompileShader(fsCode, GL_FRAGMENT_SHADER);
if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) shader = RLGL.State.defaultShader; if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShader.id;
else else
{ {
shader.id = LoadShaderProgram(vertexShaderId, fragmentShaderId); id = LoadShaderProgram(vertexShaderId, fragmentShaderId);
if (vertexShaderId != RLGL.State.defaultVShaderId) if (vertexShaderId != RLGL.State.defaultVShaderId)
{ {
// Detach shader before deletion to make sure memory is freed // Detach shader before deletion to make sure memory is freed
glDetachShader(shader.id, vertexShaderId); glDetachShader(id, vertexShaderId);
glDeleteShader(vertexShaderId); glDeleteShader(vertexShaderId);
} }
if (fragmentShaderId != RLGL.State.defaultFShaderId) if (fragmentShaderId != RLGL.State.defaultFShaderId)
{ {
// Detach shader before deletion to make sure memory is freed // Detach shader before deletion to make sure memory is freed
glDetachShader(shader.id, fragmentShaderId); glDetachShader(id, fragmentShaderId);
glDeleteShader(fragmentShaderId); glDeleteShader(fragmentShaderId);
} }
if (shader.id == 0) if (id == 0)
{ {
TRACELOG(LOG_WARNING, "SHADER: Failed to load custom shader code"); TRACELOG(LOG_WARNING, "SHADER: Failed to load custom shader code");
shader = RLGL.State.defaultShader; id = RLGL.State.defaultShader.id;
} }
// After shader loading, we TRY to set default location names
if (shader.id > 0) SetShaderDefaultLocations(&shader);
} }
// Get available shader uniforms // Get available shader uniforms
// NOTE: This information is useful for debug... // NOTE: This information is useful for debug...
int uniformCount = -1; int uniformCount = -1;
glGetProgramiv(shader.id, GL_ACTIVE_UNIFORMS, &uniformCount); glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount);
for (int i = 0; i < uniformCount; i++) for (int i = 0; i < uniformCount; i++)
{ {
@ -3268,89 +3189,79 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
GLenum type = GL_ZERO; GLenum type = GL_ZERO;
// Get the name of the uniforms // Get the name of the uniforms
glGetActiveUniform(shader.id, i, sizeof(name) - 1, &namelen, &num, &type, name); glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name);
name[namelen] = 0; name[namelen] = 0;
TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", shader.id, name, glGetUniformLocation(shader.id, name)); TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name));
} }
#endif #endif
return shader; return id;
} }
// Unload shader from GPU memory (VRAM) void rlUnloadShaderProgram(unsigned int id)
void UnloadShader(Shader shader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (shader.id != RLGL.State.defaultShader.id) glDeleteProgram(id);
{
glDeleteProgram(shader.id);
RL_FREE(shader.locs);
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
}
#endif #endif
} }
// Begin custom shader mode void rlSetShaderCurrent(Shader shader)
void BeginShaderMode(Shader shader)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.State.currentShader.id != shader.id) if (RLGL.State.currentShader.id != shader.id)
{ {
DrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
RLGL.State.currentShader = shader; RLGL.State.currentShader = shader;
} }
#endif #endif
} }
// End custom shader mode (returns to default shader) void rlSetBlendMode(int mode)
void EndShaderMode(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
BeginShaderMode(RLGL.State.defaultShader); if (RLGL.State.currentBlendMode != mode)
{
rlDrawRenderBatch(RLGL.currentBatch);
switch (mode)
{
case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break;
case BLEND_CUSTOM: glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); break;
default: break;
}
RLGL.State.currentBlendMode = mode;
}
#endif #endif
} }
// Get shader uniform location int rlGetLocationUniform(unsigned int shaderId, const char *uniformName)
int GetShaderLocation(Shader shader, const char *uniformName)
{ {
int location = -1; int location = -1;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
location = glGetUniformLocation(shader.id, uniformName); location = glGetUniformLocation(shaderId, uniformName);
if (location == -1) TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shader.id, uniformName);
else TRACELOG(LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shader.id, uniformName, location);
#endif #endif
return location; return location;
} }
// Get shader attribute location int rlGetLocationAttrib(unsigned int shaderId, const char *attribName)
int GetShaderLocationAttrib(Shader shader, const char *attribName)
{ {
int location = -1; int location = -1;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
location = glGetAttribLocation(shader.id, attribName); location = glGetAttribLocation(shaderId, attribName);
if (location == -1) TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shader.id, attribName);
else TRACELOG(LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shader.id, attribName, location);
#endif #endif
return location; return location;
} }
// Set shader uniform value void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType)
{
SetShaderValueV(shader, locIndex, value, uniformType, 1);
}
// Set shader uniform value vector
void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
switch (uniformType) switch (uniformType)
{ {
case SHADER_UNIFORM_FLOAT: glUniform1fv(locIndex, count, (float *)value); break; case SHADER_UNIFORM_FLOAT: glUniform1fv(locIndex, count, (float *)value); break;
@ -3362,32 +3273,21 @@ void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniform
case SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break; case SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
case SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break; case SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
case SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break; case SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
default: TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to set uniform, data type not recognized", shader.id); default: TRACELOG(LOG_WARNING, "SHADER: Failed to set uniform, data type not recognized");
} }
//glUseProgram(0); // Avoid reseting current shader program, in case other uniforms are set
#endif #endif
} }
void rlSetUniformMatrix(int locIndex, Matrix mat)
// Set shader uniform value (matrix 4x4)
void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
glUniformMatrix4fv(locIndex, 1, false, MatrixToFloat(mat)); glUniformMatrix4fv(locIndex, 1, false, MatrixToFloat(mat));
//glUseProgram(0);
#endif #endif
} }
// Set shader uniform value for texture void rlSetUniformSampler(int locIndex, Texture2D texture)
void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
// Check if texture is already active // Check if texture is already active
for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == texture.id) return; for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == texture.id) return;
@ -3402,13 +3302,12 @@ void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
break; break;
} }
} }
//glUseProgram(0);
#endif #endif
} }
// Set a custom projection matrix (replaces internal projection matrix) // Set a custom projection matrix (replaces internal projection matrix)
void SetMatrixProjection(Matrix projection) void rlSetMatrixProjection(Matrix projection)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.projection = projection; RLGL.State.projection = projection;
@ -3416,7 +3315,8 @@ void SetMatrixProjection(Matrix projection)
} }
// Return internal projection matrix // Return internal projection matrix
Matrix GetMatrixProjection(void) { Matrix rlGetMatrixProjection(void)
{
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
float mat[16]; float mat[16];
glGetFloatv(GL_PROJECTION_MATRIX,mat); glGetFloatv(GL_PROJECTION_MATRIX,mat);
@ -3433,7 +3333,7 @@ Matrix GetMatrixProjection(void) {
} }
// Set a custom modelview matrix (replaces internal modelview matrix) // Set a custom modelview matrix (replaces internal modelview matrix)
void SetMatrixModelview(Matrix view) void rlSetMatrixModelview(Matrix view)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
RLGL.State.modelview = view; RLGL.State.modelview = view;
@ -3441,7 +3341,7 @@ void SetMatrixModelview(Matrix view)
} }
// Return internal modelview matrix // Return internal modelview matrix
Matrix GetMatrixModelview(void) Matrix rlGetMatrixModelview(void)
{ {
Matrix matrix = MatrixIdentity(); Matrix matrix = MatrixIdentity();
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
@ -3457,8 +3357,9 @@ Matrix GetMatrixModelview(void)
return matrix; return matrix;
} }
// Generate cubemap texture from HDR texture // Generate cubemap texture from HDR texture
TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, int format) TextureCubemap rlGenTextureCubemap(Shader shader, Texture2D panorama, int size, int format)
{ {
TextureCubemap cubemap = { 0 }; TextureCubemap cubemap = { 0 };
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -3480,10 +3381,11 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
// STEP 2: Draw to framebuffer // STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
// NOTE: Shader is used to convert HDR equirectangular environment map to cubemap equivalent (6 faces) // NOTE: Shader is used to convert HDR equirectangular environment map to cubemap equivalent (6 faces)
rlEnableShader(shader.id);
// Define projection matrix and send it to shader // Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[SHADER_LOC_MATRIX_PROJECTION], fboProjection); rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
// Define view matrix for every side of the cubemap // Define view matrix for every side of the cubemap
Matrix fboViews[6] = { Matrix fboViews[6] = {
@ -3495,7 +3397,6 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }) MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
}; };
rlEnableShader(shader.id);
#if !defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM) #if !defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, panorama.id); glBindTexture(GL_TEXTURE_2D, panorama.id);
@ -3505,7 +3406,7 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
SetShaderValueMatrix(shader, shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]); rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i); rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i);
rlEnableFramebuffer(fbo); rlEnableFramebuffer(fbo);
@ -3517,9 +3418,9 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
#if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM) #if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
// Using internal batch system instead of raw OpenGL cube creating+drawing // Using internal batch system instead of raw OpenGL cube creating+drawing
// NOTE: DrawCubeV() is actually provided by models.c! -> GenTextureCubemap() should be moved to user code! // NOTE: DrawCubeV() is actually provided by models.c! -> rlGenTextureCubemap() should be moved to user code!
DrawCubeV(Vector3Zero(), Vector3One(), WHITE); DrawCubeV(Vector3Zero(), Vector3One(), WHITE);
DrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
#endif #endif
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -3545,7 +3446,7 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
} }
// Generate irradiance texture using cubemap data // Generate irradiance texture using cubemap data
TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size) TextureCubemap rlGenTextureIrradiance(Shader shader, TextureCubemap cubemap, int size)
{ {
TextureCubemap irradiance = { 0 }; TextureCubemap irradiance = { 0 };
@ -3565,10 +3466,11 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
// STEP 2: Draw to framebuffer // STEP 2: Draw to framebuffer
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
// NOTE: Shader is used to solve diffuse integral by convolution to create an irradiance cubemap // NOTE: Shader is used to solve diffuse integral by convolution to create an irradiance cubemap
rlEnableShader(shader.id);
// Define projection matrix and send it to shader // Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); Matrix matFboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[SHADER_LOC_MATRIX_PROJECTION], fboProjection); rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_PROJECTION], matFboProjection);
// Define view matrix for every side of the cubemap // Define view matrix for every side of the cubemap
Matrix fboViews[6] = { Matrix fboViews[6] = {
@ -3580,7 +3482,6 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }) MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
}; };
rlEnableShader(shader.id);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
@ -3588,7 +3489,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
SetShaderValueMatrix(shader, shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]); rlSetUniformMatrix(shader.locs[SHADER_LOC_MATRIX_VIEW], fboViews[i]);
rlFramebufferAttach(fbo, irradiance.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i); rlFramebufferAttach(fbo, irradiance.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X + i);
rlEnableFramebuffer(fbo); rlEnableFramebuffer(fbo);
@ -3618,7 +3519,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
} }
// Generate prefilter texture using cubemap data // Generate prefilter texture using cubemap data
TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size) TextureCubemap rlGenTexturePrefilter(Shader shader, TextureCubemap cubemap, int size)
{ {
TextureCubemap prefilter = { 0 }; TextureCubemap prefilter = { 0 };
@ -3717,7 +3618,7 @@ TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int si
// Generate BRDF texture using cubemap data // Generate BRDF texture using cubemap data
// TODO: Review implementation: https://github.com/HectorMF/BRDFGenerator // TODO: Review implementation: https://github.com/HectorMF/BRDFGenerator
Texture2D GenTextureBRDF(Shader shader, int size) Texture2D rlGenTextureBRDF(Shader shader, int size)
{ {
Texture2D brdf = { 0 }; Texture2D brdf = { 0 };
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
@ -3763,37 +3664,6 @@ Texture2D GenTextureBRDF(Shader shader, int size)
return brdf; return brdf;
} }
// Begin blending mode (alpha, additive, multiplied)
// NOTE: Only 3 blending modes supported, default blend mode is alpha
void BeginBlendMode(int mode)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.State.currentBlendMode != mode)
{
DrawRenderBatch(RLGL.currentBatch);
switch (mode)
{
case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break;
case BLEND_CUSTOM: glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); break;
default: break;
}
RLGL.State.currentBlendMode = mode;
}
#endif
}
// End blending mode (reset to default: alpha blending)
void EndBlendMode(void)
{
BeginBlendMode(BLEND_ALPHA);
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Definition // Module specific Functions Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -4035,7 +3905,7 @@ static void UnloadShaderDefault(void)
} }
// Load render batch // Load render batch
static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements) static RenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
{ {
RenderBatch batch = { 0 }; RenderBatch batch = { 0 };
@ -4160,7 +4030,7 @@ static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
// Draw render batch // Draw render batch
// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) // NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer)
static void DrawRenderBatch(RenderBatch *batch) static void rlDrawRenderBatch(RenderBatch *batch)
{ {
// Update batch vertex buffers // Update batch vertex buffers
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
@ -4222,9 +4092,9 @@ static void DrawRenderBatch(RenderBatch *batch)
rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight); rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
// Set current eye view offset to modelview matrix // Set current eye view offset to modelview matrix
SetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye])); rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
// Set current eye projection matrix // Set current eye projection matrix
SetMatrixProjection(RLGL.State.eyesProjection[eye]); rlSetMatrixProjection(RLGL.State.eyesProjection[eye]);
} }
// Draw buffers // Draw buffers
@ -4349,7 +4219,7 @@ static void DrawRenderBatch(RenderBatch *batch)
} }
// Unload default internal buffers vertex data from CPU and GPU // Unload default internal buffers vertex data from CPU and GPU
static void UnloadRenderBatch(RenderBatch batch) static void rlUnloadRenderBatch(RenderBatch batch)
{ {
// Unbind everything // Unbind everything
if (RLGL.ExtSupported.vao) glBindVertexArray(0); if (RLGL.ExtSupported.vao) glBindVertexArray(0);
@ -4385,19 +4255,20 @@ static void UnloadRenderBatch(RenderBatch batch)
} }
// Set the active render batch for rlgl // Set the active render batch for rlgl
static void SetRenderBatchActive(RenderBatch *batch) static void rlSetRenderBatchActive(RenderBatch *batch)
{ {
DrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch = batch; RLGL.currentBatch = batch;
} }
// Set default render batch for rlgl // Set default render batch for rlgl
static void SetRenderBatchDefault(void) static void rlSetRenderBatchDefault(void)
{ {
DrawRenderBatch(RLGL.currentBatch); rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch = &RLGL.defaultBatch; RLGL.currentBatch = &RLGL.defaultBatch;
} }
// Renders a 1x1 XY quad in NDC // Renders a 1x1 XY quad in NDC
static void GenDrawQuad(void) static void GenDrawQuad(void)
{ {
@ -4643,50 +4514,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
#endif #endif
#if defined(RLGL_STANDALONE) #if defined(RLGL_STANDALONE)
// Load text data from file, returns a '\0' terminated string
// NOTE: text chars array should be freed manually
char *LoadFileText(const char *fileName)
{
char *text = NULL;
if (fileName != NULL)
{
FILE *file = fopen(fileName, "rt");
if (file != NULL)
{
// WARNING: When reading a file as 'text' file,
// text mode causes carriage return-linefeed translation...
// ...but using fseek() should return correct byte-offset
fseek(file, 0, SEEK_END);
int size = ftell(file);
fseek(file, 0, SEEK_SET);
if (size > 0)
{
text = (char *)RL_MALLOC((size + 1)*sizeof(char));
int count = (int)fread(text, sizeof(char), size, file);
// WARNING: \r\n is converted to \n on reading, so,
// read bytes count gets reduced by the number of lines
if (count < size) text = RL_REALLOC(text, count + 1);
// Zero-terminate the string
text[count] = '\0';
TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName);
fclose(file);
}
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
}
else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
return text;
}
// Get pixel data size in bytes (image or texture) // Get pixel data size in bytes (image or texture)
// NOTE: Size depends on pixel format // NOTE: Size depends on pixel format
int GetPixelDataSize(int width, int height, int format) int GetPixelDataSize(int width, int height, int format)

View file

@ -184,7 +184,7 @@ void DrawLineStrip(Vector2 *points, int pointsCount, Color color)
{ {
if (pointsCount >= 2) if (pointsCount >= 2)
{ {
if (rlCheckBufferLimit(pointsCount)) rlglDraw(); rlCheckRenderBatchLimit(pointsCount);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -231,9 +231,9 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
float angle = startAngle; float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*segments/2)) rlglDraw(); rlCheckRenderBatchLimit(4*segments/2);
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
// NOTE: Every QUAD actually represents two segments // NOTE: Every QUAD actually represents two segments
@ -241,16 +241,16 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
angle += (stepLength*2); angle += (stepLength*2);
@ -261,23 +261,23 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
} }
rlEnd(); rlEnd();
rlDisableTexture(); rlDisableTexture();
#else #else
if (rlCheckBufferLimit(3*segments)) rlglDraw(); rlCheckRenderBatchLimit(3*segments);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
@ -324,7 +324,7 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
int limit = 2*(segments + 2); int limit = 2*(segments + 2);
if ((int)(endAngle - startAngle)%360 == 0) { limit = 2*segments; showCapLines = false; } if ((int)(endAngle - startAngle)%360 == 0) { limit = 2*segments; showCapLines = false; }
if (rlCheckBufferLimit(limit)) rlglDraw(); rlCheckRenderBatchLimit(limit);
rlBegin(RL_LINES); rlBegin(RL_LINES);
if (showCapLines) if (showCapLines)
@ -357,7 +357,7 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
// NOTE: Gradient goes from center (color1) to border (color2) // NOTE: Gradient goes from center (color1) to border (color2)
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2) void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
{ {
if (rlCheckBufferLimit(3*36)) rlglDraw(); rlCheckRenderBatchLimit(3*36);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
@ -373,7 +373,7 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
} }
// Draw a color-filled circle (Vector version) // Draw a color-filled circle (Vector version)
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw) // NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawCircleV(Vector2 center, float radius, Color color) void DrawCircleV(Vector2 center, float radius, Color color)
{ {
DrawCircleSector(center, radius, 0, 360, 36, color); DrawCircleSector(center, radius, 0, 360, 36, color);
@ -382,7 +382,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
// Draw circle outline // Draw circle outline
void DrawCircleLines(int centerX, int centerY, float radius, Color color) void DrawCircleLines(int centerX, int centerY, float radius, Color color)
{ {
if (rlCheckBufferLimit(2*36)) rlglDraw(); rlCheckRenderBatchLimit(2*36);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -399,7 +399,7 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
// Draw ellipse // Draw ellipse
void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color) void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color)
{ {
if (rlCheckBufferLimit(3*36)) rlglDraw(); rlCheckRenderBatchLimit(3*36);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
@ -415,7 +415,7 @@ void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color c
// Draw ellipse outline // Draw ellipse outline
void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color) void DrawEllipseLines(int centerX, int centerY, float radiusH, float radiusV, Color color)
{ {
if (rlCheckBufferLimit(2*36)) rlglDraw(); rlCheckRenderBatchLimit(2*36);
rlBegin(RL_LINES); rlBegin(RL_LINES);
for (int i = 0; i < 360; i += 10) for (int i = 0; i < 360; i += 10)
@ -470,25 +470,25 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
float angle = startAngle; float angle = startAngle;
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*segments)) rlglDraw(); rlCheckRenderBatchLimit(4*segments);
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
angle += stepLength; angle += stepLength;
@ -497,7 +497,7 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
rlDisableTexture(); rlDisableTexture();
#else #else
if (rlCheckBufferLimit(6*segments)) rlglDraw(); rlCheckRenderBatchLimit(6*segments);
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
@ -563,7 +563,7 @@ void DrawRingLines(Vector2 center, float innerRadius, float outerRadius, float s
int limit = 4*(segments + 1); int limit = 4*(segments + 1);
if ((int)(endAngle - startAngle)%360 == 0) { limit = 4*segments; showCapLines = false; } if ((int)(endAngle - startAngle)%360 == 0) { limit = 4*segments; showCapLines = false; }
if (rlCheckBufferLimit(limit)) rlglDraw(); rlCheckRenderBatchLimit(limit);
rlBegin(RL_LINES); rlBegin(RL_LINES);
if (showCapLines) if (showCapLines)
@ -602,7 +602,7 @@ void DrawRectangle(int posX, int posY, int width, int height, Color color)
} }
// Draw a color-filled rectangle (Vector version) // Draw a color-filled rectangle (Vector version)
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw) // NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawRectangleV(Vector2 position, Vector2 size, Color color) void DrawRectangleV(Vector2 position, Vector2 size, Color color)
{ {
DrawRectanglePro((Rectangle){ position.x, position.y, size.x, size.y }, (Vector2){ 0.0f, 0.0f }, 0.0f, color); DrawRectanglePro((Rectangle){ position.x, position.y, size.x, size.y }, (Vector2){ 0.0f, 0.0f }, 0.0f, color);
@ -617,7 +617,7 @@ void DrawRectangleRec(Rectangle rec, Color color)
// Draw a color-filled rectangle with pro parameters // Draw a color-filled rectangle with pro parameters
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color) void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
{ {
if (rlCheckBufferLimit(4)) rlglDraw(); rlCheckRenderBatchLimit(4);
Vector2 bottomLeft = { 0 }; Vector2 bottomLeft = { 0 };
Vector2 bottomRight = { 0 }; Vector2 bottomRight = { 0 };
@ -656,22 +656,22 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
topLeft.y = y + dx*sinRotation + dy*cosRotation; topLeft.y = y + dx*sinRotation + dy*cosRotation;
} }
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f); rlNormal3f(0.0f, 0.0f, 1.0f);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(bottomLeft.x, bottomLeft.y); rlVertex2f(bottomLeft.x, bottomLeft.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(bottomRight.x, bottomRight.y); rlVertex2f(bottomRight.x, bottomRight.y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(topRight.x, topRight.y); rlVertex2f(topRight.x, topRight.y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(topLeft.x, topLeft.y); rlVertex2f(topLeft.x, topLeft.y);
rlEnd(); rlEnd();
@ -696,7 +696,7 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col
// NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise // NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4) void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4)
{ {
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlPushMatrix(); rlPushMatrix();
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
@ -704,19 +704,19 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3,
// NOTE: Default raylib font character 95 is a white square // NOTE: Default raylib font character 95 is a white square
rlColor4ub(col1.r, col1.g, col1.b, col1.a); rlColor4ub(col1.r, col1.g, col1.b, col1.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(rec.x, rec.y); rlVertex2f(rec.x, rec.y);
rlColor4ub(col2.r, col2.g, col2.b, col2.a); rlColor4ub(col2.r, col2.g, col2.b, col2.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(rec.x, rec.y + rec.height); rlVertex2f(rec.x, rec.y + rec.height);
rlColor4ub(col3.r, col3.g, col3.b, col3.a); rlColor4ub(col3.r, col3.g, col3.b, col3.a);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(rec.x + rec.width, rec.y + rec.height); rlVertex2f(rec.x + rec.width, rec.y + rec.height);
rlColor4ub(col4.r, col4.g, col4.b, col4.a); rlColor4ub(col4.r, col4.g, col4.b, col4.a);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(rec.x + rec.width, rec.y); rlVertex2f(rec.x + rec.width, rec.y);
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();
@ -725,7 +725,7 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3,
} }
// Draw rectangle outline // Draw rectangle outline
// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw) // NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues
void DrawRectangleLines(int posX, int posY, int width, int height, Color color) void DrawRectangleLines(int posX, int posY, int width, int height, Color color)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
@ -821,9 +821,9 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f }; const float angles[4] = { 180.0f, 90.0f, 0.0f, 270.0f };
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(16*segments/2 + 5*4)) rlglDraw(); rlCheckRenderBatchLimit(16*segments/2 + 5*4);
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner // Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
@ -835,13 +835,13 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
for (int i = 0; i < segments/2; i++) for (int i = 0; i < segments/2; i++)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength*2))*radius, center.y + cosf(DEG2RAD*(angle + stepLength*2))*radius);
angle += (stepLength*2); angle += (stepLength*2);
} }
@ -849,76 +849,76 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
if (segments%2) if (segments%2)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*radius, center.y + cosf(DEG2RAD*angle)*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*radius, center.y + cosf(DEG2RAD*(angle + stepLength))*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x, center.y); rlVertex2f(center.x, center.y);
} }
} }
// [2] Upper Rectangle // [2] Upper Rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[0].x, point[0].y); rlVertex2f(point[0].x, point[0].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[8].x, point[8].y); rlVertex2f(point[8].x, point[8].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[9].x, point[9].y); rlVertex2f(point[9].x, point[9].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[1].x, point[1].y); rlVertex2f(point[1].x, point[1].y);
// [4] Right Rectangle // [4] Right Rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[2].x, point[2].y); rlVertex2f(point[2].x, point[2].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[9].x, point[9].y); rlVertex2f(point[9].x, point[9].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[10].x, point[10].y); rlVertex2f(point[10].x, point[10].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[3].x, point[3].y); rlVertex2f(point[3].x, point[3].y);
// [6] Bottom Rectangle // [6] Bottom Rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[11].x, point[11].y); rlVertex2f(point[11].x, point[11].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[5].x, point[5].y); rlVertex2f(point[5].x, point[5].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[4].x, point[4].y); rlVertex2f(point[4].x, point[4].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[10].x, point[10].y); rlVertex2f(point[10].x, point[10].y);
// [8] Left Rectangle // [8] Left Rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[7].x, point[7].y); rlVertex2f(point[7].x, point[7].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[6].x, point[6].y); rlVertex2f(point[6].x, point[6].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[11].x, point[11].y); rlVertex2f(point[11].x, point[11].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[8].x, point[8].y); rlVertex2f(point[8].x, point[8].y);
// [9] Middle Rectangle // [9] Middle Rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[8].x, point[8].y); rlVertex2f(point[8].x, point[8].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[11].x, point[11].y); rlVertex2f(point[11].x, point[11].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[10].x, point[10].y); rlVertex2f(point[10].x, point[10].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[9].x, point[9].y); rlVertex2f(point[9].x, point[9].y);
rlEnd(); rlEnd();
rlDisableTexture(); rlDisableTexture();
#else #else
if (rlCheckBufferLimit(12*segments + 5*6)) rlglDraw(); // 4 corners with 3 vertices per segment + 5 rectangles with 6 vertices each rlCheckRenderBatchLimit(12*segments + 5*6); // 4 corners with 3 vertices per segment + 5 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner // Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
@ -1050,9 +1050,9 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
if (lineThick > 1) if (lineThick > 1)
{ {
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
if (rlCheckBufferLimit(4*4*segments + 4*4)) rlglDraw(); // 4 corners with 4 vertices for each segment + 4 rectangles with 4 vertices each rlCheckRenderBatchLimit(4*4*segments + 4*4); // 4 corners with 4 vertices for each segment + 4 rectangles with 4 vertices each
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
// Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner // Draw all of the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
@ -1063,13 +1063,13 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
for (int i = 0; i < segments; i++) for (int i = 0; i < segments; i++)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*innerRadius, center.y + cosf(DEG2RAD*angle)*innerRadius);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius); rlVertex2f(center.x + sinf(DEG2RAD*angle)*outerRadius, center.y + cosf(DEG2RAD*angle)*outerRadius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*outerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*outerRadius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius); rlVertex2f(center.x + sinf(DEG2RAD*(angle + stepLength))*innerRadius, center.y + cosf(DEG2RAD*(angle + stepLength))*innerRadius);
angle += stepLength; angle += stepLength;
@ -1078,52 +1078,52 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
// Upper rectangle // Upper rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[0].x, point[0].y); rlVertex2f(point[0].x, point[0].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[8].x, point[8].y); rlVertex2f(point[8].x, point[8].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[9].x, point[9].y); rlVertex2f(point[9].x, point[9].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[1].x, point[1].y); rlVertex2f(point[1].x, point[1].y);
// Right rectangle // Right rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[2].x, point[2].y); rlVertex2f(point[2].x, point[2].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[10].x, point[10].y); rlVertex2f(point[10].x, point[10].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[11].x, point[11].y); rlVertex2f(point[11].x, point[11].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[3].x, point[3].y); rlVertex2f(point[3].x, point[3].y);
// Lower rectangle // Lower rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[13].x, point[13].y); rlVertex2f(point[13].x, point[13].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[5].x, point[5].y); rlVertex2f(point[5].x, point[5].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[4].x, point[4].y); rlVertex2f(point[4].x, point[4].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[12].x, point[12].y); rlVertex2f(point[12].x, point[12].y);
// Left rectangle // Left rectangle
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[15].x, point[15].y); rlVertex2f(point[15].x, point[15].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[7].x, point[7].y); rlVertex2f(point[7].x, point[7].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(point[6].x, point[6].y); rlVertex2f(point[6].x, point[6].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(point[14].x, point[14].y); rlVertex2f(point[14].x, point[14].y);
rlEnd(); rlEnd();
rlDisableTexture(); rlDisableTexture();
#else #else
if (rlCheckBufferLimit(4*6*segments + 4*6)) rlglDraw(); // 4 corners with 6(2*3) vertices for each segment + 4 rectangles with 6 vertices each rlCheckRenderBatchLimit(4*6*segments + 4*6); // 4 corners with 6(2*3) vertices for each segment + 4 rectangles with 6 vertices each
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
@ -1190,7 +1190,7 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
else else
{ {
// Use LINES to draw the outline // Use LINES to draw the outline
if (rlCheckBufferLimit(8*segments + 4*2)) rlglDraw(); // 4 corners with 2 vertices for each segment + 4 rectangles with 2 vertices each rlCheckRenderBatchLimit(8*segments + 4*2); // 4 corners with 2 vertices for each segment + 4 rectangles with 2 vertices each
rlBegin(RL_LINES); rlBegin(RL_LINES);
@ -1225,24 +1225,24 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
// NOTE: Vertex must be provided in counter-clockwise order // NOTE: Vertex must be provided in counter-clockwise order
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{ {
if (rlCheckBufferLimit(4)) rlglDraw(); rlCheckRenderBatchLimit(4);
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(v1.x, v1.y); rlVertex2f(v1.x, v1.y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(v2.x, v2.y); rlVertex2f(v2.x, v2.y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(v2.x, v2.y); rlVertex2f(v2.x, v2.y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(v3.x, v3.y); rlVertex2f(v3.x, v3.y);
rlEnd(); rlEnd();
@ -1261,7 +1261,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
// NOTE: Vertex must be provided in counter-clockwise order // NOTE: Vertex must be provided in counter-clockwise order
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
{ {
if (rlCheckBufferLimit(6)) rlglDraw(); rlCheckRenderBatchLimit(6);
rlBegin(RL_LINES); rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -1283,24 +1283,24 @@ void DrawTriangleFan(Vector2 *points, int pointsCount, Color color)
{ {
if (pointsCount >= 3) if (pointsCount >= 3)
{ {
if (rlCheckBufferLimit((pointsCount - 2)*4)) rlglDraw(); rlCheckRenderBatchLimit((pointsCount - 2)*4);
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 1; i < pointsCount - 1; i++) for (int i = 1; i < pointsCount - 1; i++)
{ {
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(points[0].x, points[0].y); rlVertex2f(points[0].x, points[0].y);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(points[i].x, points[i].y); rlVertex2f(points[i].x, points[i].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(points[i + 1].x, points[i + 1].y); rlVertex2f(points[i + 1].x, points[i + 1].y);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(points[i + 1].x, points[i + 1].y); rlVertex2f(points[i + 1].x, points[i + 1].y);
} }
rlEnd(); rlEnd();
@ -1314,7 +1314,7 @@ void DrawTriangleStrip(Vector2 *points, int pointsCount, Color color)
{ {
if (pointsCount >= 3) if (pointsCount >= 3)
{ {
if (rlCheckBufferLimit(3*(pointsCount - 2))) rlglDraw(); rlCheckRenderBatchLimit(3*(pointsCount - 2));
rlBegin(RL_TRIANGLES); rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
@ -1344,31 +1344,31 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = 0.0f; float centralAngle = 0.0f;
if (rlCheckBufferLimit(4*(360/sides))) rlglDraw(); rlCheckRenderBatchLimit(4*(360/sides));
rlPushMatrix(); rlPushMatrix();
rlTranslatef(center.x, center.y, 0.0f); rlTranslatef(center.x, center.y, 0.0f);
rlRotatef(rotation, 0.0f, 0.0f, 1.0f); rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
#if defined(SUPPORT_QUADS_DRAW_MODE) #if defined(SUPPORT_QUADS_DRAW_MODE)
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS); rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++) for (int i = 0; i < sides; i++)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(0, 0); rlVertex2f(0, 0);
rlTexCoord2f(GetShapesTextureRec().x/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f(rlGetShapesTextureRec().x/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, (GetShapesTextureRec().y + GetShapesTextureRec().height)/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, (rlGetShapesTextureRec().y + rlGetShapesTextureRec().height)/rlGetShapesTexture().height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
centralAngle += 360.0f/(float)sides; centralAngle += 360.0f/(float)sides;
rlTexCoord2f((GetShapesTextureRec().x + GetShapesTextureRec().width)/GetShapesTexture().width, GetShapesTextureRec().y/GetShapesTexture().height); rlTexCoord2f((rlGetShapesTextureRec().x + rlGetShapesTextureRec().width)/rlGetShapesTexture().width, rlGetShapesTextureRec().y/rlGetShapesTexture().height);
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
} }
rlEnd(); rlEnd();
@ -1396,7 +1396,7 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo
if (sides < 3) sides = 3; if (sides < 3) sides = 3;
float centralAngle = 0.0f; float centralAngle = 0.0f;
if (rlCheckBufferLimit(3*(360/sides))) rlglDraw(); rlCheckRenderBatchLimit(3*(360/sides));
rlPushMatrix(); rlPushMatrix();
rlTranslatef(center.x, center.y, 0.0f); rlTranslatef(center.x, center.y, 0.0f);