[rlsw] RenderTexture support (#5655)

* review texture formats
Added support for `R3G3B2`, `R5G6B5`, `R4G4B4A4` and `R5G5B5A1`
Added depth formats

* use of textures for the framebuffer
- Framebuffers can now use all texture types that are already available.
- The 24-bit depth format has been removed as it is no longer needed.
- Framebuffer formats are still defined at compile time.
- The allocated texture size is now preserved, which avoids frequent reallocations when resizing framebuffers and will allow the use of `glTexSubImage2D`.

* review framebuffer blit/copy
This greatly simplifies the framebuffer blit/copy logic while now supporting all pixel formats. It is slightly slower in debug builds, but this path is mainly kept for compatibility anyway. The `copy_fast` version is still used for the "normal" cases when presenting to the screen.

* review pixel get/set
less ops for certain formats + fixes

* fix depth write

* texture read/write cleanup + tweaks
I made the  pointers parameters `restrict` for reading/writing textures, which resulted in a slight improvement.
And I reviewed the `static inline` statements, which could potentially bias the compiler; no difference, but it's cleaner.

* style tweaks

* review uint8_t <-> float conversion

* added a reusable object pool system
will allow management of both textures and framebuffers
added support for `glTexSubImage2D`
added handling of 'GL_OUT_OF_MEMORY' errors
removed the default internal texture (unused)

* added FBO API + refactored rasterizer dispatch logic

* fix ndc projection + review presentation
and rename rlsw's resize/copy/blit

* add `glRenderbufferStorage` binding
+ tweaks and fixes

* fix quad sorting + simplify quad rasterization part

* fix line shaking issue

* support of `GL_DRAW_FRAMEBUFFER_BINDING`

* update rlgl - support of rlsw's framebuffers

* fix pixel origin in line rasterization
my bad, an oversight in my previous fix.
This offset should have been moved here rather than per pixel during truncation.

* style tweaks

* fix vla issue with msvc - fill depth / fill color
This commit is contained in:
Le Juez Victor
2026-03-17 17:50:32 +01:00
committed by GitHub
parent 93be463322
commit e7d999e3c7
2 changed files with 3881 additions and 2694 deletions

6547
src/external/rlsw.h vendored

File diff suppressed because it is too large Load Diff

View File

@@ -838,6 +838,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
#define RLSW_IMPLEMENTATION
#define SW_MALLOC(sz) RL_MALLOC(sz)
#define SW_CALLOC(n,sz) RL_CALLOC(n, sz)
#define SW_REALLOC(ptr, newSz) RL_REALLOC(ptr, newSz)
#define SW_FREE(ptr) RL_FREE(ptr)
#include "external/rlsw.h" // OpenGL 1.1 software implementation
@@ -1857,7 +1858,7 @@ void rlDisableShader(void)
// Enable rendering to texture (fbo)
void rlEnableFramebuffer(unsigned int id)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glBindFramebuffer(GL_FRAMEBUFFER, id);
#endif
}
@@ -1866,7 +1867,7 @@ void rlEnableFramebuffer(unsigned int id)
unsigned int rlGetActiveFramebuffer(void)
{
GLint fboId = 0;
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboId);
#endif
return fboId;
@@ -1875,7 +1876,7 @@ unsigned int rlGetActiveFramebuffer(void)
// Disable rendering to texture
void rlDisableFramebuffer(void)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
}
@@ -1891,7 +1892,7 @@ void rlBlitFramebuffer(int srcX, int srcY, int srcWidth, int srcHeight, int dstX
// Bind framebuffer object (fbo)
void rlBindFramebuffer(unsigned int target, unsigned int framebuffer)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glBindFramebuffer(target, framebuffer);
#endif
}
@@ -3471,6 +3472,13 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16);
}
#elif defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// NOTE: Renderbuffers are the same type of object as textures in rlsw
// WARNING: Ensure that the depth format is the one specified at rlsw compilation
glGenRenderbuffers(1, &id);
glBindRenderbuffer(GL_RENDERBUFFER, id);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
#endif
return id;
@@ -3771,7 +3779,7 @@ void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pi
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
unsigned int glInternalFormat, glFormat, glType;
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType); // Get OpenGL texture format
swCopyFramebuffer(x, y, width, height, glFormat, glType, pixels);
swReadPixels(x, y, width, height, glFormat, glType, pixels);
#endif
}
@@ -3779,7 +3787,7 @@ void rlCopyFramebuffer(int x, int y, int width, int height, int format, void *pi
void rlResizeFramebuffer(int width, int height)
{
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
swResizeFramebuffer(width, height);
swResize(width, height);
#endif
}
@@ -3829,7 +3837,7 @@ unsigned int rlLoadFramebuffer(void)
unsigned int fboId = 0;
if (!isGpuReady) { TRACELOG(RL_LOG_WARNING, "GL: GPU is not ready to load data, trying to load before InitWindow()?"); return fboId; }
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glGenFramebuffers(1, &fboId); // Create the framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer
#endif
@@ -3841,7 +3849,7 @@ unsigned int rlLoadFramebuffer(void)
// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
void rlFramebufferAttach(unsigned int id, unsigned int texId, int attachType, int texType, int mipLevel)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glBindFramebuffer(GL_FRAMEBUFFER, id);
switch (attachType)
@@ -3881,7 +3889,7 @@ bool rlFramebufferComplete(unsigned int id)
{
bool result = false;
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
glBindFramebuffer(GL_FRAMEBUFFER, id);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -3912,7 +3920,7 @@ bool rlFramebufferComplete(unsigned int id)
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
void rlUnloadFramebuffer(unsigned int id)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE))
// Query depth attachment to automatically delete texture/renderbuffer
int depthType = 0;
glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type