WARNING: REDESIGN of rlgl framebuffers API #721
This redesign allows more flexibility when creating RenderTexture and a simplification (and hopefully removal) of `GenTexture*()` functions, that should not belong to this model but the user code, due to the use of custom shaders. Also, this new API opens the door for a possible GBuffers type and advance rendering possibilities... Some functions of the API have been also simplified or even removed. rlgl module can be used as an standalone library, so, a version for the library has been added: v3.1.0, matching current raylib version.
This commit is contained in:
parent
fa2c114636
commit
cdc8850e68
4 changed files with 197 additions and 227 deletions
|
@ -1543,7 +1543,7 @@ void BeginTextureMode(RenderTexture2D target)
|
||||||
{
|
{
|
||||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||||
|
|
||||||
rlEnableRenderTexture(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);
|
||||||
|
@ -1571,7 +1571,7 @@ void EndTextureMode(void)
|
||||||
{
|
{
|
||||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||||
|
|
||||||
rlDisableRenderTexture(); // Disable render target
|
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);
|
||||||
|
|
|
@ -944,7 +944,7 @@ void UnloadMaterial(Material material)
|
||||||
// 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) rlDeleteTextures(material.maps[i].texture.id);
|
if (material.maps[i].texture.id != GetTextureDefault().id) rlUnloadTexture(material.maps[i].texture.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
RL_FREE(material.maps);
|
RL_FREE(material.maps);
|
||||||
|
|
355
src/rlgl.h
355
src/rlgl.h
|
@ -1,6 +1,6 @@
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
* rlgl - raylib OpenGL abstraction layer
|
* rlgl v3.1.0 - raylib OpenGL abstraction layer
|
||||||
*
|
*
|
||||||
* rlgl is a wrapper for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0) to
|
* rlgl is a wrapper for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0) to
|
||||||
* pseudo-OpenGL 1.1 style functions (rlVertex, rlTranslate, rlRotate...).
|
* pseudo-OpenGL 1.1 style functions (rlVertex, rlTranslate, rlRotate...).
|
||||||
|
@ -205,7 +205,15 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef enum {
|
||||||
|
RL_ATTACHMENT_COLOR_TEXTURE = 0,
|
||||||
|
RL_ATTACHMENT_COLOR_CUBEMAP = 20,
|
||||||
|
RL_ATTACHMENT_COLOR_RENDERBUFFER = 40,
|
||||||
|
RL_ATTACHMENT_DEPTH_TEXTURE = 100,
|
||||||
|
RL_ATTACHMENT_DEPTH_RENDERBUFFER = 101,
|
||||||
|
RL_ATTACHMENT_STENCIL_TEXTURE = 200,
|
||||||
|
RL_ATTACHMENT_STENCIL_RENDERBUFFER = 201,
|
||||||
|
} FramebufferAttachType;
|
||||||
|
|
||||||
#if defined(RLGL_STANDALONE)
|
#if defined(RLGL_STANDALONE)
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
@ -245,16 +253,6 @@ typedef unsigned char byte;
|
||||||
// TextureCubemap type, actually, same as Texture2D
|
// TextureCubemap type, actually, same as Texture2D
|
||||||
typedef Texture2D TextureCubemap;
|
typedef Texture2D TextureCubemap;
|
||||||
|
|
||||||
// RenderTexture2D type, for texture rendering
|
|
||||||
typedef struct RenderTexture2D {
|
|
||||||
unsigned int id; // OpenGL framebuffer (fbo) id
|
|
||||||
Texture2D texture; // Color buffer attachment texture
|
|
||||||
Texture2D depth; // Depth buffer attachment texture
|
|
||||||
} RenderTexture2D;
|
|
||||||
|
|
||||||
// RenderTexture type, same as RenderTexture2D
|
|
||||||
typedef RenderTexture2D RenderTexture;
|
|
||||||
|
|
||||||
// Vertex data definning a mesh
|
// Vertex data definning a mesh
|
||||||
typedef struct Mesh {
|
typedef struct Mesh {
|
||||||
int vertexCount; // number of vertices stored in arrays
|
int vertexCount; // number of vertices stored in arrays
|
||||||
|
@ -329,7 +327,6 @@ typedef unsigned char byte;
|
||||||
int eyeViewportLeft[4]; // VR stereo rendering left eye viewport [x, y, w, h]
|
int eyeViewportLeft[4]; // VR stereo rendering left eye viewport [x, y, w, h]
|
||||||
} VrStereoConfig;
|
} VrStereoConfig;
|
||||||
|
|
||||||
|
|
||||||
// TraceLog message types
|
// TraceLog message types
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LOG_ALL,
|
LOG_ALL,
|
||||||
|
@ -482,7 +479,7 @@ RLAPI void rlVertex2f(float x, float y); // Define one vertex (posi
|
||||||
RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float
|
RLAPI void rlVertex3f(float x, float y, float z); // Define one vertex (position) - 3 float
|
||||||
RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float
|
RLAPI void rlTexCoord2f(float x, float y); // Define one vertex (texture coordinate) - 2 float
|
||||||
RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float
|
RLAPI void rlNormal3f(float x, float y, float z); // Define one vertex (normal) - 3 float
|
||||||
RLAPI void rlColor4ub(byte r, byte g, byte b, byte a); // Define one vertex (color) - 4 byte
|
RLAPI void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Define one vertex (color) - 4 byte
|
||||||
RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float
|
RLAPI void rlColor3f(float x, float y, float z); // Define one vertex (color) - 3 float
|
||||||
RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float
|
RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (color) - 4 float
|
||||||
|
|
||||||
|
@ -493,8 +490,8 @@ RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (
|
||||||
RLAPI void rlEnableTexture(unsigned int id); // Enable texture usage
|
RLAPI void rlEnableTexture(unsigned int id); // Enable texture usage
|
||||||
RLAPI void rlDisableTexture(void); // Disable texture usage
|
RLAPI void rlDisableTexture(void); // Disable texture usage
|
||||||
RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
|
RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
|
||||||
RLAPI void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
|
RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo)
|
||||||
RLAPI void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer
|
||||||
RLAPI void rlEnableDepthTest(void); // Enable depth test
|
RLAPI void rlEnableDepthTest(void); // Enable depth test
|
||||||
RLAPI void rlDisableDepthTest(void); // Disable depth test
|
RLAPI void rlDisableDepthTest(void); // Disable depth test
|
||||||
RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
|
RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
|
||||||
|
@ -504,12 +501,8 @@ RLAPI void rlDisableScissorTest(void); // Disable scissor
|
||||||
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
|
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
|
||||||
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
RLAPI void rlEnableWireMode(void); // Enable wire mode
|
||||||
RLAPI void rlDisableWireMode(void); // Disable wire mode
|
RLAPI void rlDisableWireMode(void); // Disable wire mode
|
||||||
RLAPI void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
|
|
||||||
RLAPI void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
|
RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color
|
||||||
RLAPI void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
|
|
||||||
RLAPI void rlDeleteVertexArrays(unsigned int id); // Unload vertex data (VAO) from GPU memory
|
|
||||||
RLAPI void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from GPU memory
|
|
||||||
RLAPI void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
|
||||||
RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
||||||
RLAPI void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
|
RLAPI void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
|
||||||
RLAPI unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic); // Load a new attributes buffer
|
RLAPI unsigned int rlLoadAttribBuffer(unsigned int vaoId, int shaderLoc, void *buffer, int size, bool dynamic); // Load a new attributes buffer
|
||||||
|
@ -530,7 +523,7 @@ RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions
|
||||||
|
|
||||||
// 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
|
||||||
RLAPI unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
|
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
|
||||||
RLAPI unsigned int rlLoadTextureCubemap(void *data, int size, int format); // Load texture cubemap
|
RLAPI unsigned int rlLoadTextureCubemap(void *data, int size, int format); // Load texture cubemap
|
||||||
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data
|
RLAPI void rlUpdateTexture(unsigned int id, int offsetX, int offsetY, int width, int height, int format, const void *data); // Update GPU texture with new data
|
||||||
RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
|
RLAPI void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
|
||||||
|
@ -540,10 +533,11 @@ RLAPI void rlGenerateMipmaps(Texture2D *texture); // Gen
|
||||||
RLAPI void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
|
RLAPI void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
|
||||||
RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||||
|
|
||||||
// Render texture management (fbo)
|
// Framebuffer management (fbo)
|
||||||
RLAPI RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depthBits, bool useDepthTexture); // Load a render texture (with color and depth attachments)
|
RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer
|
||||||
RLAPI void rlRenderTextureAttach(RenderTexture target, unsigned int id, int attachType); // Attach texture/renderbuffer to an fbo
|
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType); // Attach texture/renderbuffer to a framebuffer
|
||||||
RLAPI bool rlRenderTextureComplete(RenderTexture target); // Verify render texture is complete
|
RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete
|
||||||
|
RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU
|
||||||
|
|
||||||
// Vertex data management
|
// Vertex data management
|
||||||
RLAPI void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
|
RLAPI void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
|
||||||
|
@ -883,7 +877,8 @@ typedef struct rlglData {
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
#if defined(SUPPORT_VR_SIMULATOR)
|
||||||
struct {
|
struct {
|
||||||
VrStereoConfig config; // VR stereo configuration for simulator
|
VrStereoConfig config; // VR stereo configuration for simulator
|
||||||
RenderTexture2D stereoFbo; // VR stereo rendering framebuffer
|
unsigned int stereoFboId; // VR stereo rendering framebuffer id
|
||||||
|
unsigned int stereoTexId; // VR stereo color texture (attached to framebuffer)
|
||||||
bool simulatorReady; // VR simulator ready flag
|
bool simulatorReady; // VR simulator ready flag
|
||||||
bool stereoRender; // VR stereo rendering enabled/disabled flag
|
bool stereoRender; // VR stereo rendering enabled/disabled flag
|
||||||
} Vr;
|
} Vr;
|
||||||
|
@ -1114,7 +1109,7 @@ void rlVertex2f(float x, float y) { glVertex2f(x, y); }
|
||||||
void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); }
|
void rlVertex3f(float x, float y, float z) { glVertex3f(x, y, z); }
|
||||||
void rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); }
|
void rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); }
|
||||||
void rlNormal3f(float x, float y, float z) { glNormal3f(x, y, z); }
|
void rlNormal3f(float x, float y, float z) { glNormal3f(x, y, z); }
|
||||||
void rlColor4ub(byte r, byte g, byte b, byte a) { glColor4ub(r, g, b, a); }
|
void rlColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { glColor4ub(r, g, b, a); }
|
||||||
void rlColor3f(float x, float y, float z) { glColor3f(x, y, z); }
|
void rlColor3f(float x, float y, float z) { glColor3f(x, y, z); }
|
||||||
void rlColor4f(float x, float y, float z, float w) { glColor4f(x, y, z, w); }
|
void rlColor4f(float x, float y, float z, float w) { glColor4f(x, y, z, w); }
|
||||||
|
|
||||||
|
@ -1262,7 +1257,7 @@ void rlNormal3f(float x, float y, float z)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define one vertex (color)
|
// Define one vertex (color)
|
||||||
void rlColor4ub(byte x, byte y, byte z, byte w)
|
void rlColor4ub(unsigned char x, unsigned char y, unsigned char z, unsigned char w)
|
||||||
{
|
{
|
||||||
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter] = x;
|
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter] = x;
|
||||||
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 1] = y;
|
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 1] = y;
|
||||||
|
@ -1274,13 +1269,13 @@ void rlColor4ub(byte x, byte y, byte z, byte w)
|
||||||
// Define one vertex (color)
|
// Define one vertex (color)
|
||||||
void rlColor4f(float r, float g, float b, float a)
|
void rlColor4f(float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
rlColor4ub((byte)(r*255), (byte)(g*255), (byte)(b*255), (byte)(a*255));
|
rlColor4ub((unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), (unsigned char)(a*255));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define one vertex (color)
|
// Define one vertex (color)
|
||||||
void rlColor3f(float x, float y, float z)
|
void rlColor3f(float x, float y, float z)
|
||||||
{
|
{
|
||||||
rlColor4ub((byte)(x*255), (byte)(y*255), (byte)(z*255), 255);
|
rlColor4ub((unsigned char)(x*255), (unsigned char)(y*255), (unsigned char)(z*255), 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1385,7 +1380,7 @@ void rlTextureParameters(unsigned int id, int param, int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable rendering to texture (fbo)
|
// Enable rendering to texture (fbo)
|
||||||
void rlEnableRenderTexture(unsigned int id)
|
void rlEnableFramebuffer(unsigned int id)
|
||||||
{
|
{
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
||||||
|
@ -1396,7 +1391,7 @@ void rlEnableRenderTexture(unsigned int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable rendering to texture
|
// Disable rendering to texture
|
||||||
void rlDisableRenderTexture(void)
|
void rlDisableFramebuffer(void)
|
||||||
{
|
{
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
@ -1445,88 +1440,34 @@ void rlDisableWireMode(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload texture from GPU memory
|
// Unload framebuffer from GPU memory
|
||||||
void rlDeleteTextures(unsigned int id)
|
|
||||||
{
|
|
||||||
if (id > 0) glDeleteTextures(1, &id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload render texture from GPU memory
|
|
||||||
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
|
// NOTE: All attached textures/cubemaps/renderbuffers are also deleted
|
||||||
void rlDeleteRenderTextures(RenderTexture2D target)
|
void rlUnloadFramebuffer(unsigned int id)
|
||||||
{
|
{
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
int depthType = 0;
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target.id); // Bind framebuffer to query depth texture type
|
// Query depth attachment to automatically delete texture/renderbuffer
|
||||||
|
int depthType = 0, depthId = 0;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType);
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind framebuffer to delete textures
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &depthId);
|
||||||
|
|
||||||
|
unsigned int depthIdU = (unsigned int)depthId;
|
||||||
|
if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU);
|
||||||
|
else if (depthType == GL_RENDERBUFFER) glDeleteTextures(1, &depthIdU);
|
||||||
|
|
||||||
// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
|
// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
|
||||||
// the texture image is automatically detached from the currently bound framebuffer.
|
// the texture image is automatically detached from the currently bound framebuffer.
|
||||||
|
|
||||||
if (target.texture.id > 0)
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
{
|
glDeleteFramebuffers(1, &id);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); // Detach texture from FBO
|
|
||||||
glDeleteTextures(1, &target.texture.id);
|
|
||||||
}
|
|
||||||
if (target.depth.id > 0)
|
|
||||||
{
|
|
||||||
if (depthType == GL_TEXTURE)
|
|
||||||
{
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
|
||||||
glDeleteTextures(1, &target.depth.id);
|
|
||||||
}
|
|
||||||
else if (depthType == GL_RENDERBUFFER)
|
|
||||||
{
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
|
||||||
glDeleteRenderbuffers(1, &target.depth.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.id > 0) glDeleteFramebuffers(1, &target.id);
|
TRACELOG(LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id);
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "FBO: [ID %i] Unloaded render texture data from VRAM (GPU)", target.id);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload shader from GPU memory
|
|
||||||
void rlDeleteShader(unsigned int id)
|
|
||||||
{
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
||||||
if (id != 0) glDeleteProgram(id);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload vertex data (VAO) from GPU memory
|
|
||||||
void rlDeleteVertexArrays(unsigned int id)
|
|
||||||
{
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
||||||
if (RLGL.ExtSupported.vao)
|
|
||||||
{
|
|
||||||
if (id != 0)
|
|
||||||
{
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glDeleteVertexArrays(1, &id);
|
|
||||||
TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex data from VRAM (GPU)", id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload vertex data (VBO) from GPU memory
|
|
||||||
void rlDeleteBuffers(unsigned int id)
|
|
||||||
{
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
||||||
if (id != 0)
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &id);
|
|
||||||
if (!RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "VBO: [ID %i] Unloaded vertex data from VRAM (GPU)", id);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear color buffer with color
|
// Clear color buffer with color
|
||||||
void rlClearColor(byte r, byte g, byte b, byte a)
|
void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
|
||||||
{
|
{
|
||||||
// Color values clamp to 0.0f(0) and 1.0f(255)
|
// Color values clamp to 0.0f(0) and 1.0f(255)
|
||||||
float cr = (float)r/255;
|
float cr = (float)r/255;
|
||||||
|
@ -2090,33 +2031,23 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
|
||||||
|
|
||||||
// Load depth texture/renderbuffer (to be attached to fbo)
|
// Load depth texture/renderbuffer (to be attached to fbo)
|
||||||
// WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture/WEBGL_depth_texture extensions
|
// WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture/WEBGL_depth_texture extensions
|
||||||
unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderBuffer)
|
unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
|
||||||
{
|
{
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
unsigned int glInternalFormat = GL_DEPTH_COMPONENT16;
|
if (!RLGL.ExtSupported.texDepth) useRenderBuffer = false;
|
||||||
|
|
||||||
if ((bits != 16) && (bits != 24) && (bits != 32)) bits = 16;
|
// NOTE: We let the implementation to choose the best bit-depth
|
||||||
|
unsigned int glInternalFormat = GL_DEPTH_COMPONENT;
|
||||||
if (bits == 24)
|
/*
|
||||||
{
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33)
|
#if defined(GRAPHICS_API_OPENGL_33)
|
||||||
glInternalFormat = GL_DEPTH_COMPONENT24;
|
glInternalFormat = GL_DEPTH_COMPONENT24; // GL_DEPTH_COMPONENT32
|
||||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
|
||||||
if (RLGL.ExtSupported.maxDepthBits >= 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bits == 32)
|
|
||||||
{
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33)
|
|
||||||
glInternalFormat = GL_DEPTH_COMPONENT32;
|
|
||||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
|
if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
|
||||||
|
else if (RLGL.ExtSupported.maxDepthBits == 24) glInternalFormat = GL_DEPTH_COMPONENT24_OES;
|
||||||
#endif
|
#endif
|
||||||
}
|
*/
|
||||||
|
|
||||||
if (!useRenderBuffer && RLGL.ExtSupported.texDepth)
|
if (!useRenderBuffer && RLGL.ExtSupported.texDepth)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
|
@ -2146,7 +2077,7 @@ unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load texture cubemap
|
// Load texture cubemap
|
||||||
// NOTE: Cubemap data is expected to be 6 images in a single column,
|
// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other),
|
||||||
// expected the following convention: +X, -X, +Y, -Y, +Z, -Z
|
// expected the following convention: +X, -X, +Y, -Y, +Z, -Z
|
||||||
unsigned int rlLoadTextureCubemap(void *data, int size, int format)
|
unsigned int rlLoadTextureCubemap(void *data, int size, int format)
|
||||||
{
|
{
|
||||||
|
@ -2165,9 +2096,31 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
|
||||||
{
|
{
|
||||||
// Load cubemap faces
|
// Load cubemap faces
|
||||||
for (unsigned int i = 0; i < 6; i++)
|
for (unsigned int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (data == NULL)
|
||||||
|
{
|
||||||
|
if (format < COMPRESSED_DXT1_RGB)
|
||||||
|
{
|
||||||
|
if (format == UNCOMPRESSED_R32G32B32)
|
||||||
|
{
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
// Instead of using a sized internal texture format (GL_RGB16F, GL_RGB32F),
|
||||||
|
// we let the driver to choose the better format for us (GL_RGB)
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, size, size, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
|
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
if (RLGL.ExtSupported.texFloat32) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, size, size, 0, GL_RGB, GL_FLOAT, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if ((format == UNCOMPRESSED_R32) || (format == UNCOMPRESSED_R32G32B32A32)) TRACELOG(LOG_WARNING, "TEXTURES: Cubemap requested format not supported");
|
||||||
|
else glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, NULL);
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "TEXTURES: Empty cubemap creation does not support compressed format");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (format < COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize);
|
if (format < COMPRESSED_DXT1_RGB) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, glFormat, glType, (unsigned char *)data + i*dataSize);
|
||||||
else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize);
|
else glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, size, size, 0, dataSize, (unsigned char *)data + i*dataSize);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33)
|
#if defined(GRAPHICS_API_OPENGL_33)
|
||||||
if (format == UNCOMPRESSED_GRAYSCALE)
|
if (format == UNCOMPRESSED_GRAYSCALE)
|
||||||
|
@ -2274,79 +2227,40 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
|
||||||
// Unload texture from GPU memory
|
// Unload texture from GPU memory
|
||||||
void rlUnloadTexture(unsigned int id)
|
void rlUnloadTexture(unsigned int id)
|
||||||
{
|
{
|
||||||
if (id > 0) glDeleteTextures(1, &id);
|
glDeleteTextures(1, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a texture to be used for rendering (fbo with default color and depth attachments)
|
// Load a framebuffer to be used for rendering
|
||||||
// NOTE: If colorFormat or depthBits are no supported, no attachment is done
|
// NOTE: No textures attached
|
||||||
RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depthBits, bool useDepthTexture)
|
unsigned int rlLoadFramebuffer(int width, int height)
|
||||||
{
|
{
|
||||||
RenderTexture2D target = { 0 };
|
unsigned int fboId = 0;
|
||||||
|
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
if (useDepthTexture && !RLGL.ExtSupported.texDepth) useDepthTexture = false;
|
glGenFramebuffers(1, &fboId); // Create the framebuffer object
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer
|
||||||
// Create the framebuffer object
|
|
||||||
glGenFramebuffers(1, &target.id);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
|
|
||||||
|
|
||||||
// Create fbo color texture attachment
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
if ((format != -1) && (format < COMPRESSED_DXT1_RGB))
|
|
||||||
{
|
|
||||||
// WARNING: Some texture formats are not supported for fbo color attachment
|
|
||||||
target.texture.id = rlLoadTexture(NULL, width, height, format, 1);
|
|
||||||
target.texture.width = width;
|
|
||||||
target.texture.height = height;
|
|
||||||
target.texture.format = format;
|
|
||||||
target.texture.mipmaps = 1;
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Create fbo depth renderbuffer/texture
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
if (depthBits > 0)
|
|
||||||
{
|
|
||||||
target.depth.id = rlLoadTextureDepth(width, height, depthBits, !useDepthTexture);
|
|
||||||
target.depth.width = width;
|
|
||||||
target.depth.height = height;
|
|
||||||
target.depth.format = 19; //DEPTH_COMPONENT_24BIT?
|
|
||||||
target.depth.mipmaps = 1;
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Attach color texture and depth renderbuffer to FBO
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
rlRenderTextureAttach(target, target.texture.id, 0); // COLOR attachment
|
|
||||||
rlRenderTextureAttach(target, target.depth.id, 1); // DEPTH attachment
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Check if fbo is complete with attachments (valid)
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
if (rlRenderTextureComplete(target)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", target.id);
|
|
||||||
//-----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return target;
|
return fboId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach color buffer texture to an fbo (unloads previous attachment)
|
// Attach color buffer texture to an fbo (unloads previous attachment)
|
||||||
// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
|
// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
|
||||||
void rlRenderTextureAttach(RenderTexture2D target, unsigned int id, int attachType)
|
void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType)
|
||||||
{
|
{
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
|
||||||
|
|
||||||
if (attachType == 0) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
|
switch (attachType)
|
||||||
else if (attachType == 1)
|
|
||||||
{
|
{
|
||||||
int depthType = 0;
|
case RL_ATTACHMENT_COLOR_TEXTURE: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); break; // TODO: Support multiple color attachments
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType);
|
case RL_ATTACHMENT_COLOR_CUBEMAP: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texId, 0); break; // TODO: Support multiple faces attachments
|
||||||
|
case RL_ATTACHMENT_COLOR_RENDERBUFFER: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, texId, 0); break;
|
||||||
if (depthType == GL_TEXTURE) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, id, 0);
|
case RL_ATTACHMENT_DEPTH_TEXTURE: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0); break;
|
||||||
else if (depthType == GL_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, id);
|
case RL_ATTACHMENT_DEPTH_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); break;
|
||||||
|
case RL_ATTACHMENT_STENCIL_TEXTURE: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId); break;
|
||||||
|
case RL_ATTACHMENT_STENCIL_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
@ -2354,12 +2268,12 @@ void rlRenderTextureAttach(RenderTexture2D target, unsigned int id, int attachTy
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify render texture is complete
|
// Verify render texture is complete
|
||||||
bool rlRenderTextureComplete(RenderTexture target)
|
bool rlFramebufferComplete(unsigned int id)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
|
||||||
|
@ -2367,12 +2281,12 @@ bool rlRenderTextureComplete(RenderTexture target)
|
||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", target.id); break;
|
case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", id); break;
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", target.id); break;
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", id); break;
|
||||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", target.id); break;
|
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", id); break;
|
||||||
#endif
|
#endif
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", target.id); break;
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", id); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2908,15 +2822,16 @@ void rlUnloadMesh(Mesh mesh)
|
||||||
RL_FREE(mesh.boneWeights);
|
RL_FREE(mesh.boneWeights);
|
||||||
RL_FREE(mesh.boneIds);
|
RL_FREE(mesh.boneIds);
|
||||||
|
|
||||||
rlDeleteBuffers(mesh.vboId[0]); // vertex
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
rlDeleteBuffers(mesh.vboId[1]); // texcoords
|
for (int i = 0; i < 7; i++) glDeleteBuffers(1, &mesh.vboId[i]); // DEFAULT_MESH_VERTEX_BUFFERS (model.c)
|
||||||
rlDeleteBuffers(mesh.vboId[2]); // normals
|
if (RLGL.ExtSupported.vao)
|
||||||
rlDeleteBuffers(mesh.vboId[3]); // colors
|
{
|
||||||
rlDeleteBuffers(mesh.vboId[4]); // tangents
|
glBindVertexArray(0);
|
||||||
rlDeleteBuffers(mesh.vboId[5]); // texcoords2
|
glDeleteVertexArrays(1, &mesh.vaoId);
|
||||||
rlDeleteBuffers(mesh.vboId[6]); // indices
|
TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex data from VRAM (GPU)", mesh.vaoId);
|
||||||
|
}
|
||||||
rlDeleteVertexArrays(mesh.vaoId);
|
else TRACELOG(LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read screen pixel data (color buffer)
|
// Read screen pixel data (color buffer)
|
||||||
|
@ -2991,13 +2906,15 @@ void *rlReadTexturePixels(Texture2D texture)
|
||||||
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
|
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
|
||||||
// We are using Option 1, just need to care for texture format on retrieval
|
// We are using Option 1, just need to care for texture format on retrieval
|
||||||
// NOTE: This behaviour could be conditioned by graphic driver...
|
// NOTE: This behaviour could be conditioned by graphic driver...
|
||||||
RenderTexture2D fbo = rlLoadRenderTexture(texture.width, texture.height, UNCOMPRESSED_R8G8B8A8, 16, false);
|
unsigned int fboId = rlLoadFramebuffer(texture.width, texture.height);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
|
// TODO: Create depth texture/renderbuffer for fbo?
|
||||||
|
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
// Attach our texture to FBO
|
// Attach our texture to FBO
|
||||||
// NOTE: Previoust attached texture is automatically detached
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0);
|
||||||
|
|
||||||
// We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format
|
// We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format
|
||||||
|
@ -3010,7 +2927,7 @@ void *rlReadTexturePixels(Texture2D texture)
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
// Clean up temporal fbo
|
// Clean up temporal fbo
|
||||||
rlDeleteRenderTextures(fbo);
|
rlUnloadFramebuffer(fbo);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return pixels;
|
return pixels;
|
||||||
|
@ -3172,13 +3089,15 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
|
||||||
// Unload shader from GPU memory (VRAM)
|
// Unload shader from GPU memory (VRAM)
|
||||||
void UnloadShader(Shader shader)
|
void UnloadShader(Shader shader)
|
||||||
{
|
{
|
||||||
if ((shader.id != RLGL.State.defaultShader.id) && (shader.id > 0))
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
if (shader.id != RLGL.State.defaultShader.id)
|
||||||
{
|
{
|
||||||
rlDeleteShader(shader.id);
|
glDeleteProgram(shader.id);
|
||||||
RL_FREE(shader.locs);
|
RL_FREE(shader.locs);
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
|
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin custom shader mode
|
// Begin custom shader mode
|
||||||
|
@ -3674,13 +3593,21 @@ void EndBlendMode(void)
|
||||||
|
|
||||||
#if defined(SUPPORT_VR_SIMULATOR)
|
#if defined(SUPPORT_VR_SIMULATOR)
|
||||||
// Init VR simulator for selected device parameters
|
// Init VR simulator for selected device parameters
|
||||||
// NOTE: It modifies the global variable: RLGL.Vr.stereoFbo
|
// NOTE: It modifies the global variable: RLGL.Vr.stereoFboId
|
||||||
void InitVrSimulator(void)
|
void InitVrSimulator(void)
|
||||||
{
|
{
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
// Initialize framebuffer and textures for stereo rendering
|
// Initialize framebuffer and textures for stereo rendering
|
||||||
// NOTE: Screen size should match HMD aspect ratio
|
// NOTE: Screen size should match HMD aspect ratio
|
||||||
RLGL.Vr.stereoFbo = rlLoadRenderTexture(RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
|
RLGL.Vr.stereoFboId = rlLoadFramebuffer(RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
|
||||||
|
|
||||||
|
// Load color/depth textures to attach to framebuffer
|
||||||
|
RLGL.Vr.stereoTexId = rlLoadTexture(NULL, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, UNCOMPRESSED_R8G8B8A8, 1);
|
||||||
|
unsigned int depthId = rlLoadTextureDepth(RLGL.State.framebufferWidth, RLGL.State.framebufferHeight, true);
|
||||||
|
|
||||||
|
// Attach color texture and depth renderbuffer/texture to FBO
|
||||||
|
rlFramebufferAttach(RLGL.Vr.stereoFboId, RLGL.Vr.stereoTexId, RL_ATTACHMENT_COLOR_TEXTURE);
|
||||||
|
rlFramebufferAttach(RLGL.Vr.stereoFboId, depthId, RL_ATTACHMENT_DEPTH_RENDERBUFFER);
|
||||||
|
|
||||||
RLGL.Vr.simulatorReady = true;
|
RLGL.Vr.simulatorReady = true;
|
||||||
#else
|
#else
|
||||||
|
@ -3699,7 +3626,11 @@ void UpdateVrTracking(Camera *camera)
|
||||||
void CloseVrSimulator(void)
|
void CloseVrSimulator(void)
|
||||||
{
|
{
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
if (RLGL.Vr.simulatorReady) rlDeleteRenderTextures(RLGL.Vr.stereoFbo); // Unload stereo framebuffer and texture
|
if (RLGL.Vr.simulatorReady)
|
||||||
|
{
|
||||||
|
rlUnloadTexture(RLGL.Vr.stereoTexId); // Unload color texture
|
||||||
|
rlUnloadFramebuffer(RLGL.Vr.stereoFboId); // Unload stereo framebuffer and depth texture/renderbuffer
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3823,10 +3754,10 @@ void BeginVrDrawing(void)
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
if (RLGL.Vr.simulatorReady)
|
if (RLGL.Vr.simulatorReady)
|
||||||
{
|
{
|
||||||
rlEnableRenderTexture(RLGL.Vr.stereoFbo.id); // Setup framebuffer for stereo rendering
|
rlEnableFramebuffer(RLGL.Vr.stereoFboId); // Setup framebuffer for stereo rendering
|
||||||
//glEnable(GL_FRAMEBUFFER_SRGB); // Enable SRGB framebuffer (only if required)
|
//glEnable(GL_FRAMEBUFFER_SRGB); // Enable SRGB framebuffer (only if required)
|
||||||
|
|
||||||
//glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
|
//rlViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
|
||||||
rlClearScreenBuffers(); // Clear current framebuffer
|
rlClearScreenBuffers(); // Clear current framebuffer
|
||||||
|
|
||||||
RLGL.Vr.stereoRender = true;
|
RLGL.Vr.stereoRender = true;
|
||||||
|
@ -3842,7 +3773,7 @@ void EndVrDrawing(void)
|
||||||
{
|
{
|
||||||
RLGL.Vr.stereoRender = false; // Disable stereo render
|
RLGL.Vr.stereoRender = false; // Disable stereo render
|
||||||
|
|
||||||
rlDisableRenderTexture(); // Unbind current framebuffer
|
rlDisableFramebuffer(); // Unbind current framebuffer
|
||||||
|
|
||||||
rlClearScreenBuffers(); // Clear current framebuffer
|
rlClearScreenBuffers(); // Clear current framebuffer
|
||||||
|
|
||||||
|
@ -3856,11 +3787,11 @@ void EndVrDrawing(void)
|
||||||
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
|
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
|
||||||
rlLoadIdentity(); // Reset internal modelview matrix
|
rlLoadIdentity(); // Reset internal modelview matrix
|
||||||
|
|
||||||
// Draw RenderTexture (RLGL.Vr.stereoFbo) using distortion shader if available
|
// Draw stereo framebuffer texture using distortion shader if available
|
||||||
if (RLGL.Vr.config.distortionShader.id > 0) RLGL.State.currentShader = RLGL.Vr.config.distortionShader;
|
if (RLGL.Vr.config.distortionShader.id > 0) RLGL.State.currentShader = RLGL.Vr.config.distortionShader;
|
||||||
else RLGL.State.currentShader = GetShaderDefault();
|
else RLGL.State.currentShader = GetShaderDefault();
|
||||||
|
|
||||||
rlEnableTexture(RLGL.Vr.stereoFbo.texture.id);
|
rlEnableTexture(RLGL.Vr.stereoTexId);
|
||||||
|
|
||||||
rlPushMatrix();
|
rlPushMatrix();
|
||||||
rlBegin(RL_QUADS);
|
rlBegin(RL_QUADS);
|
||||||
|
@ -3873,15 +3804,15 @@ void EndVrDrawing(void)
|
||||||
|
|
||||||
// Bottom-right corner for texture and quad
|
// Bottom-right corner for texture and quad
|
||||||
rlTexCoord2f(0.0f, 0.0f);
|
rlTexCoord2f(0.0f, 0.0f);
|
||||||
rlVertex2f(0.0f, (float)RLGL.Vr.stereoFbo.texture.height);
|
rlVertex2f(0.0f, (float)RLGL.State.framebufferHeight);
|
||||||
|
|
||||||
// Top-right corner for texture and quad
|
// Top-right corner for texture and quad
|
||||||
rlTexCoord2f(1.0f, 0.0f);
|
rlTexCoord2f(1.0f, 0.0f);
|
||||||
rlVertex2f((float)RLGL.Vr.stereoFbo.texture.width, (float)RLGL.Vr.stereoFbo.texture.height);
|
rlVertex2f((float)RLGL.State.framebufferWidth, (float)RLGL.State.framebufferHeight);
|
||||||
|
|
||||||
// Top-left corner for texture and quad
|
// Top-left corner for texture and quad
|
||||||
rlTexCoord2f(1.0f, 1.0f);
|
rlTexCoord2f(1.0f, 1.0f);
|
||||||
rlVertex2f((float)RLGL.Vr.stereoFbo.texture.width, 0.0f);
|
rlVertex2f((float)RLGL.State.framebufferWidth, 0.0f);
|
||||||
rlEnd();
|
rlEnd();
|
||||||
rlPopMatrix();
|
rlPopMatrix();
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
#include "utils.h" // Required for: fopen() Android mapping
|
#include "utils.h" // Required for: fopen() Android mapping
|
||||||
|
|
||||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
|
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
|
||||||
// Required for: rlLoadTexture() rlDeleteTextures(),
|
// Required for: rlLoadTexture() rlUnloadTexture(),
|
||||||
// rlGenerateMipmaps(), some funcs for DrawTexturePro()
|
// rlGenerateMipmaps(), some funcs for DrawTexturePro()
|
||||||
|
|
||||||
// Support only desired texture formats on stb_image
|
// Support only desired texture formats on stb_image
|
||||||
|
@ -2796,7 +2796,38 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
|
||||||
// NOTE: Render texture is loaded by default with RGBA color attachment and depth RenderBuffer
|
// NOTE: Render texture is loaded by default with RGBA color attachment and depth RenderBuffer
|
||||||
RenderTexture2D LoadRenderTexture(int width, int height)
|
RenderTexture2D LoadRenderTexture(int width, int height)
|
||||||
{
|
{
|
||||||
RenderTexture2D target = rlLoadRenderTexture(width, height, UNCOMPRESSED_R8G8B8A8, 24, false);
|
RenderTexture2D target = { 0 };
|
||||||
|
|
||||||
|
target.id = rlLoadFramebuffer(width, height); // Load an empty framebuffer
|
||||||
|
|
||||||
|
if (target.id > 0)
|
||||||
|
{
|
||||||
|
rlEnableFramebuffer(target.id);
|
||||||
|
|
||||||
|
// Create color texture (default to RGBA)
|
||||||
|
target.texture.id = rlLoadTexture(NULL, width, height, UNCOMPRESSED_R8G8B8A8, 1);
|
||||||
|
target.texture.width = width;
|
||||||
|
target.texture.height = height;
|
||||||
|
target.texture.format = UNCOMPRESSED_R8G8B8A8;
|
||||||
|
target.texture.mipmaps = 1;
|
||||||
|
|
||||||
|
// Create depth renderbuffer/texture
|
||||||
|
target.depth.id = rlLoadTextureDepth(width, height, true);
|
||||||
|
target.depth.width = width;
|
||||||
|
target.depth.height = height;
|
||||||
|
target.depth.format = 19; //DEPTH_COMPONENT_24BIT?
|
||||||
|
target.depth.mipmaps = 1;
|
||||||
|
|
||||||
|
// Attach color texture and depth renderbuffer/texture to FBO
|
||||||
|
rlFramebufferAttach(target.id, target.texture.id, RL_ATTACHMENT_COLOR_TEXTURE); // COLOR attachment
|
||||||
|
rlFramebufferAttach(target.id, target.depth.id, RL_ATTACHMENT_DEPTH_RENDERBUFFER); // DEPTH attachment
|
||||||
|
|
||||||
|
// Check if fbo is complete with attachments (valid)
|
||||||
|
if (rlFramebufferComplete(target.id)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", target.id);
|
||||||
|
|
||||||
|
rlDisableFramebuffer();
|
||||||
|
}
|
||||||
|
else TRACELOG(LOG_WARNING, "FBO: Framebuffer object can not be created");
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
@ -2806,7 +2837,7 @@ void UnloadTexture(Texture2D texture)
|
||||||
{
|
{
|
||||||
if (texture.id > 0)
|
if (texture.id > 0)
|
||||||
{
|
{
|
||||||
rlDeleteTextures(texture.id);
|
rlUnloadTexture(texture.id);
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
|
TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
|
||||||
}
|
}
|
||||||
|
@ -2815,7 +2846,15 @@ void UnloadTexture(Texture2D texture)
|
||||||
// Unload render texture from GPU memory (VRAM)
|
// Unload render texture from GPU memory (VRAM)
|
||||||
void UnloadRenderTexture(RenderTexture2D target)
|
void UnloadRenderTexture(RenderTexture2D target)
|
||||||
{
|
{
|
||||||
if (target.id > 0) rlDeleteRenderTextures(target);
|
if (target.id > 0)
|
||||||
|
{
|
||||||
|
// Color texture attached to FBO is deleted
|
||||||
|
rlUnloadTexture(target.texture.id);
|
||||||
|
|
||||||
|
// NOTE: Depth texture/renderbuffer is automatically
|
||||||
|
// queried and deleted before deleting framebuffer
|
||||||
|
rlUnloadFramebuffer(target.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update GPU texture with new data
|
// Update GPU texture with new data
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue