From 6045062a05a0cc5bd654ad2c2e7d88f94579cd73 Mon Sep 17 00:00:00 2001 From: Ray San Date: Fri, 4 May 2018 16:54:05 +0200 Subject: Renamed some functions - Renamed Begin3dMode() --> BeginMode3D() - Renamed Begin2dMode() --> BeginMode2D() - Renamed End3dMode() --> EndMode3D() - Renamed End2dMode() --> EndMode2D() --- src/rlgl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/rlgl.c') diff --git a/src/rlgl.c b/src/rlgl.c index 68bd3670..93a0b0f8 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1947,7 +1947,7 @@ void rlDrawMesh(Mesh mesh, Material material, Matrix transform) if (material.shader.locs[LOC_MATRIX_PROJECTION] != -1) SetShaderValueMatrix(material.shader, material.shader.locs[LOC_MATRIX_PROJECTION], projection); // At this point the modelview matrix just contains the view matrix (camera) - // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() + // That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) Matrix matProjection = projection; // Projection matrix (perspective) -- cgit v1.2.3 From 24adca4ad054196a144eca8629e090ee10e413c5 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 20 May 2018 00:39:56 +0200 Subject: Manual mipmap generation review On OpenGL 1.1 only is supported for 32bit RGBA textures --- src/rlgl.c | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'src/rlgl.c') diff --git a/src/rlgl.c b/src/rlgl.c index 93a0b0f8..e69694e9 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1448,7 +1448,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_33) + #if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33) if (format == UNCOMPRESSED_GRAYSCALE) { GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; @@ -1648,37 +1648,40 @@ void rlGenerateMipmaps(Texture2D *texture) if ((texIsPOT) || (texNPOTSupported)) { #if defined(GRAPHICS_API_OPENGL_11) - // Compute required mipmaps - void *data = rlReadTexturePixels(*texture); + // WARNING: Manual mipmap generation only works for RGBA 32bit textures! + if (texture->format == UNCOMPRESSED_R8G8B8A8) + { + // Retrieve texture data from VRAM + void *data = rlReadTexturePixels(*texture); + + // NOTE: data size is reallocated to fit mipmaps data + // NOTE: CPU mipmap generation only supports RGBA 32bit data + int mipmapCount = GenerateMipmaps(data, texture->width, texture->height); - // NOTE: data size is reallocated to fit mipmaps data - // NOTE: CPU mipmap generation only supports RGBA 32bit data - int mipmapCount = GenerateMipmaps(data, texture->width, texture->height); + int size = texture->width*texture->height*4; + int offset = size; - int size = texture->width*texture->height*4; // RGBA 32bit only - int offset = size; + int mipWidth = texture->width/2; + int mipHeight = texture->height/2; - int mipWidth = texture->width/2; - int mipHeight = texture->height/2; + // Load the mipmaps + for (int level = 1; level < mipmapCount; level++) + { + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data + offset); - // Load the mipmaps - for (int level = 1; level < mipmapCount; level++) - { - glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data + offset); + size = mipWidth*mipHeight*4; + offset += size; - size = mipWidth*mipHeight*4; - offset += size; + mipWidth /= 2; + mipHeight /= 2; + } - mipWidth /= 2; - mipHeight /= 2; + texture->mipmaps = mipmapCount + 1; + free(data); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data + + TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps [%i] generated manually on CPU side", texture->id, texture->mipmaps); } - - TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", texture->id); - - // NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data - free(data); - - texture->mipmaps = mipmapCount + 1; + else TraceLog(LOG_WARNING, "[TEX ID %i] Mipmaps could not be generated for texture format", texture->id); #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -4058,6 +4061,7 @@ static void GetGlFormats(int format, int *glInternalFormat, int *glFormat, int * #if defined(GRAPHICS_API_OPENGL_11) // Mipmaps data is generated after image data +// NOTE: Only works with RGBA (4 bytes) data! static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight) { int mipmapCount = 1; // Required mipmap levels count (including base level) -- cgit v1.2.3 From 3b70b66a089ed48b99305ce058a4bbde4a0bc3b4 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 20 May 2018 00:41:12 +0200 Subject: Love OpenGL gotchas... make my life more enjoyable! --- src/rlgl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/rlgl.c') diff --git a/src/rlgl.c b/src/rlgl.c index e69694e9..f83a9f6b 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1456,7 +1456,11 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi } else if (format == UNCOMPRESSED_GRAY_ALPHA) { + #if defined(GRAPHICS_API_OPENGL_21) + GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ALPHA }; + #elif defined(GRAPHICS_API_OPENGL_33) GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; + #endif glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } #endif -- cgit v1.2.3 From ca690688149e90b8fc92713d31b17330f9ea8b43 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 20 May 2018 01:55:46 +0200 Subject: Added function: rlCheckBufferLimit() --- src/rlgl.c | 54 ++++++++++++++++++++++++++++++++++-------------------- src/rlgl.h | 1 + src/shapes.c | 16 +++++++++++++++- 3 files changed, 50 insertions(+), 21 deletions(-) (limited to 'src/rlgl.c') diff --git a/src/rlgl.c b/src/rlgl.c index f83a9f6b..8912a394 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 c071acac..18eff380 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 361fb9c7..dc547e0d 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); -- cgit v1.2.3