diff --git a/src/rlgl.c b/src/rlgl.c index f83a9f6b4..8912a3940 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -85,18 +85,18 @@ #define WINGDIAPI __declspec(dllimport) #endif - #include // OpenGL 1.1 library + #include // OpenGL 1.1 library #endif #endif #if defined(GRAPHICS_API_OPENGL_21) - #define GRAPHICS_API_OPENGL_33 + #define GRAPHICS_API_OPENGL_33 // OpenGL 2.1 uses mostly OpenGL 3.3 Core functionality #endif #if defined(GRAPHICS_API_OPENGL_33) #if defined(__APPLE__) - #include // OpenGL 3 library for OSX - #include + #include // OpenGL 3 library for OSX + #include // OpenGL 3 extensions library for OSX #else #define GLAD_IMPLEMENTATION #if defined(RLGL_STANDALONE) @@ -108,17 +108,17 @@ #endif #if defined(GRAPHICS_API_OPENGL_ES2) - #include // EGL library - #include // OpenGL ES 2.0 library - #include // OpenGL ES 2.0 extensions library + #include // EGL library + #include // OpenGL ES 2.0 library + #include // OpenGL ES 2.0 extensions library #endif #if defined(RLGL_STANDALONE) - #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] + #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()] #endif #if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER) - #include "shader_distortion.h" // Distortion shader to be embedded + #include "shader_distortion.h" // Distortion shader to be embedded #endif @@ -307,17 +307,17 @@ static bool vrStereoRender = false; // VR stereo rendering enabled/disabled // Extension supported flag: Anisotropic filtering static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support -static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supported (minimum is 2.0f) +static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supported (minimum is 2.0f) // Extension supported flag: Clamp mirror wrap mode -static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported +static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported #if defined(GRAPHICS_API_OPENGL_ES2) // NOTE: VAO functionality is exposed through extensions (OES) static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays; static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray; static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays; -//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted +//static PFNGLISVERTEXARRAYOESPROC glIsVertexArray; // NOTE: Fails in WebGL, omitted #endif static bool debugMarkerSupported = false; @@ -658,13 +658,11 @@ void rlEnd(void) // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) currentDepth += (1.0f/20000.0f); - // TODO: Verify internal buffers limits - // NOTE: Before launching draw, verify no matrix are left in the stack! - // NOTE: Probably a lines/triangles margin should be left, rlEnd could be called - // after an undetermined number of triangles buffered (check shapes::DrawPoly()) + // Verify internal buffers limits + // NOTE: This check is combined with usage of rlCheckBufferLimit() if ((lines.vCounter/2 >= MAX_LINES_BATCH - 2) || - (triangles.vCounter/3 >= MAX_TRIANGLES_BATCH - 16) || - (quads.vCounter/4 >= MAX_QUADS_BATCH - 2)) rlglDraw(); + (triangles.vCounter/3 >= MAX_TRIANGLES_BATCH - 3) || + (quads.vCounter/4 >= MAX_QUADS_BATCH - 4)) rlglDraw(); } // Define one vertex (position) @@ -1313,6 +1311,22 @@ int rlGetVersion(void) #endif } +// Check internal buffer overflow for a given number of vertex +bool rlCheckBufferLimit(int type, int vCount) +{ + bool overflow = false; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + switch (type) + { + case RL_LINES: overflow = ((lines.vCounter + vCount)/2 >= MAX_LINES_BATCH); break; + case RL_TRIANGLES: overflow = ((triangles.vCounter + vCount)/3 >= MAX_TRIANGLES_BATCH); break; + case RL_QUADS: overflow = ((quads.vCounter + vCount)/4 >= MAX_QUADS_BATCH); break; + default: break; + } +#endif + return overflow; +} + // Set debug marker void rlSetDebugMarker(const char *text) { @@ -1325,7 +1339,7 @@ void rlSetDebugMarker(const char *text) // NOTE: External loader function could be passed as a pointer void rlLoadExtensions(void *loader) { -#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) +#if defined(GRAPHICS_API_OPENGL_33) // NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) #if !defined(__APPLE__) if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(LOG_WARNING, "GLAD: Cannot load OpenGL extensions"); @@ -1448,7 +1462,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi else glCompressedTexImage2D(GL_TEXTURE_2D, i, glInternalFormat, mipWidth, mipHeight, 0, mipSize, (unsigned char *)data + mipOffset); #endif - #if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) + #if defined(GRAPHICS_API_OPENGL_33) if (format == UNCOMPRESSED_GRAYSCALE) { GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; diff --git a/src/rlgl.h b/src/rlgl.h index c071acac2..18eff3809 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -424,6 +424,7 @@ void rlglClose(void); // De-inititialize rlgl (buffers void rlglDraw(void); // Update and Draw default buffers (lines, triangles, quads) int rlGetVersion(void); // Returns current OpenGL version +bool rlCheckBufferLimit(int type, int vCount); // Check internal buffer overflow for a given number of vertex void rlSetDebugMarker(const char *text); // Set debug marker for analysis void rlLoadExtensions(void *loader); // Load OpenGL extensions Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates diff --git a/src/shapes.c b/src/shapes.c index 361fb9c7a..dc547e0d2 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -173,6 +173,8 @@ void DrawCircle(int centerX, int centerY, float radius, Color color) // NOTE: Gradient goes from center (color1) to border (color2) void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2) { + if (rlCheckBufferLimit(RL_TRIANGLES, 3*36)) rlglDraw(); + rlBegin(RL_TRIANGLES); for (int i = 0; i < 360; i += 10) { @@ -189,8 +191,10 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co // Draw a color-filled circle (Vector version) // NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues (view rlglDraw) void DrawCircleV(Vector2 center, float radius, Color color) -{ +{ #if defined(SUPPORT_QUADS_DRAW_MODE) + if (rlCheckBufferLimit(RL_QUADS, 4*(36/2))) rlglDraw(); + rlEnableTexture(GetTextureDefault().id); // Default white texture rlBegin(RL_QUADS); @@ -207,6 +211,8 @@ void DrawCircleV(Vector2 center, float radius, Color color) rlDisableTexture(); #else + if (rlCheckBufferLimit(RL_TRIANGLES, 3*(36/2))) rlglDraw(); + rlBegin(RL_TRIANGLES); for (int i = 0; i < 360; i += 10) { @@ -223,6 +229,8 @@ void DrawCircleV(Vector2 center, float radius, Color color) // Draw circle outline void DrawCircleLines(int centerX, int centerY, float radius, Color color) { + if (rlCheckBufferLimit(RL_LINES, 2*36)) rlglDraw(); + rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); @@ -504,6 +512,8 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color) void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color) { if (sides < 3) sides = 3; + + if (rlCheckBufferLimit(RL_QUADS, 4*(360/sides))) rlglDraw(); rlPushMatrix(); rlTranslatef(center.x, center.y, 0.0); @@ -544,6 +554,8 @@ void DrawPolyEx(Vector2 *points, int pointsCount, Color color) { if (pointsCount >= 3) { + if (rlCheckBufferLimit(RL_QUADS, pointsCount)) rlglDraw(); + #if defined(SUPPORT_QUADS_DRAW_MODE) rlEnableTexture(GetTextureDefault().id); // Default white texture @@ -579,6 +591,8 @@ void DrawPolyExLines(Vector2 *points, int pointsCount, Color color) { if (pointsCount >= 2) { + if (rlCheckBufferLimit(RL_LINES, pointsCount)) rlglDraw(); + rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a);