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
@ -1543,7 +1543,7 @@ void BeginTextureMode(RenderTexture2D target)
|
||||
{
|
||||
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
|
||||
rlViewport(0, 0, target.texture.width, target.texture.height);
|
||||
@ -1569,9 +1569,9 @@ void BeginTextureMode(RenderTexture2D target)
|
||||
// Ends drawing to render texture
|
||||
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
|
||||
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)
|
||||
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);
|
||||
|
369
src/rlgl.h
369
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
|
||||
* 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 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)
|
||||
#ifndef __cplusplus
|
||||
@ -245,16 +253,6 @@ typedef unsigned char byte;
|
||||
// TextureCubemap type, actually, same as Texture2D
|
||||
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
|
||||
typedef struct Mesh {
|
||||
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]
|
||||
} VrStereoConfig;
|
||||
|
||||
|
||||
// TraceLog message types
|
||||
typedef enum {
|
||||
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 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 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 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 rlDisableTexture(void); // Disable texture usage
|
||||
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 rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
||||
RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo)
|
||||
RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer
|
||||
RLAPI void rlEnableDepthTest(void); // Enable depth test
|
||||
RLAPI void rlDisableDepthTest(void); // Disable depth test
|
||||
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 rlEnableWireMode(void); // Enable 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 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 rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color
|
||||
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 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
|
||||
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 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
|
||||
@ -540,10 +533,11 @@ RLAPI void rlGenerateMipmaps(Texture2D *texture); // Gen
|
||||
RLAPI void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
|
||||
RLAPI unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||
|
||||
// Render texture 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 void rlRenderTextureAttach(RenderTexture target, unsigned int id, int attachType); // Attach texture/renderbuffer to an fbo
|
||||
RLAPI bool rlRenderTextureComplete(RenderTexture target); // Verify render texture is complete
|
||||
// Framebuffer management (fbo)
|
||||
RLAPI unsigned int rlLoadFramebuffer(int width, int height); // Load an empty framebuffer
|
||||
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType); // Attach texture/renderbuffer to a framebuffer
|
||||
RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete
|
||||
RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU
|
||||
|
||||
// Vertex data management
|
||||
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)
|
||||
struct {
|
||||
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 stereoRender; // VR stereo rendering enabled/disabled flag
|
||||
} 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 rlTexCoord2f(float x, float y) { glTexCoord2f(x, y); }
|
||||
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 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)
|
||||
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 + 1] = y;
|
||||
@ -1274,13 +1269,13 @@ void rlColor4ub(byte x, byte y, byte z, byte w)
|
||||
// Define one vertex (color)
|
||||
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)
|
||||
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
|
||||
@ -1385,7 +1380,7 @@ void rlTextureParameters(unsigned int id, int param, int value)
|
||||
}
|
||||
|
||||
// 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)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, id);
|
||||
@ -1396,7 +1391,7 @@ void rlEnableRenderTexture(unsigned int id)
|
||||
}
|
||||
|
||||
// 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)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
@ -1445,88 +1440,34 @@ void rlDisableWireMode(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Unload texture from GPU memory
|
||||
void rlDeleteTextures(unsigned int id)
|
||||
{
|
||||
if (id > 0) glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
// Unload render texture from GPU memory
|
||||
// Unload framebuffer from GPU memory
|
||||
// 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)
|
||||
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);
|
||||
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,
|
||||
// the texture image is automatically detached from the currently bound framebuffer.
|
||||
|
||||
if (target.texture.id > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &id);
|
||||
|
||||
if (target.id > 0) glDeleteFramebuffers(1, &target.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);
|
||||
}
|
||||
TRACELOG(LOG_INFO, "FBO: [ID %i] Unloaded framebuffer from VRAM (GPU)", id);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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)
|
||||
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)
|
||||
// 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;
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
if (bits == 24)
|
||||
{
|
||||
// NOTE: We let the implementation to choose the best bit-depth
|
||||
unsigned int glInternalFormat = GL_DEPTH_COMPONENT;
|
||||
/*
|
||||
#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;
|
||||
if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
|
||||
else 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)
|
||||
if (RLGL.ExtSupported.maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
|
||||
#endif
|
||||
}
|
||||
|
||||
*/
|
||||
if (!useRenderBuffer && RLGL.ExtSupported.texDepth)
|
||||
{
|
||||
glGenTextures(1, &id);
|
||||
@ -2146,7 +2077,7 @@ unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderB
|
||||
}
|
||||
|
||||
// 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
|
||||
unsigned int rlLoadTextureCubemap(void *data, int size, int format)
|
||||
{
|
||||
@ -2166,8 +2097,30 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
|
||||
// Load cubemap faces
|
||||
for (unsigned int i = 0; i < 6; i++)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
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 (format == UNCOMPRESSED_GRAYSCALE)
|
||||
@ -2274,79 +2227,40 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
|
||||
// Unload texture from GPU memory
|
||||
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)
|
||||
// NOTE: If colorFormat or depthBits are no supported, no attachment is done
|
||||
RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depthBits, bool useDepthTexture)
|
||||
// Load a framebuffer to be used for rendering
|
||||
// NOTE: No textures attached
|
||||
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 (useDepthTexture && !RLGL.ExtSupported.texDepth) useDepthTexture = false;
|
||||
|
||||
// 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);
|
||||
glGenFramebuffers(1, &fboId); // Create the framebuffer object
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind any framebuffer
|
||||
#endif
|
||||
|
||||
return target;
|
||||
return fboId;
|
||||
}
|
||||
|
||||
// Attach color buffer texture to an fbo (unloads previous attachment)
|
||||
// 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)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, target.id);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
|
||||
|
||||
if (attachType == 0) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
|
||||
else if (attachType == 1)
|
||||
switch (attachType)
|
||||
{
|
||||
int depthType = 0;
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &depthType);
|
||||
|
||||
if (depthType == GL_TEXTURE) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, id, 0);
|
||||
else if (depthType == GL_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, id);
|
||||
case RL_ATTACHMENT_COLOR_TEXTURE: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0); break; // TODO: Support multiple color attachments
|
||||
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;
|
||||
case RL_ATTACHMENT_DEPTH_TEXTURE: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0); break;
|
||||
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);
|
||||
@ -2354,12 +2268,12 @@ void rlRenderTextureAttach(RenderTexture2D target, unsigned int id, int attachTy
|
||||
}
|
||||
|
||||
// Verify render texture is complete
|
||||
bool rlRenderTextureComplete(RenderTexture target)
|
||||
bool rlFramebufferComplete(unsigned int id)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
#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);
|
||||
|
||||
@ -2367,12 +2281,12 @@ bool rlRenderTextureComplete(RenderTexture target)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", target.id); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", 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", id); break;
|
||||
#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
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -2908,15 +2822,16 @@ void rlUnloadMesh(Mesh mesh)
|
||||
RL_FREE(mesh.boneWeights);
|
||||
RL_FREE(mesh.boneIds);
|
||||
|
||||
rlDeleteBuffers(mesh.vboId[0]); // vertex
|
||||
rlDeleteBuffers(mesh.vboId[1]); // texcoords
|
||||
rlDeleteBuffers(mesh.vboId[2]); // normals
|
||||
rlDeleteBuffers(mesh.vboId[3]); // colors
|
||||
rlDeleteBuffers(mesh.vboId[4]); // tangents
|
||||
rlDeleteBuffers(mesh.vboId[5]); // texcoords2
|
||||
rlDeleteBuffers(mesh.vboId[6]); // indices
|
||||
|
||||
rlDeleteVertexArrays(mesh.vaoId);
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
for (int i = 0; i < 7; i++) glDeleteBuffers(1, &mesh.vboId[i]); // DEFAULT_MESH_VERTEX_BUFFERS (model.c)
|
||||
if (RLGL.ExtSupported.vao)
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &mesh.vaoId);
|
||||
TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex data from VRAM (GPU)", mesh.vaoId);
|
||||
}
|
||||
else TRACELOG(LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)");
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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()
|
||||
// We are using Option 1, just need to care for texture format on retrieval
|
||||
// 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);
|
||||
|
||||
// Attach our texture to FBO
|
||||
// NOTE: Previoust attached texture is automatically detached
|
||||
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
|
||||
@ -3010,7 +2927,7 @@ void *rlReadTexturePixels(Texture2D texture)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Clean up temporal fbo
|
||||
rlDeleteRenderTextures(fbo);
|
||||
rlUnloadFramebuffer(fbo);
|
||||
#endif
|
||||
|
||||
return pixels;
|
||||
@ -3172,13 +3089,15 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
|
||||
// Unload shader from GPU memory (VRAM)
|
||||
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);
|
||||
|
||||
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Begin custom shader mode
|
||||
@ -3674,13 +3593,21 @@ void EndBlendMode(void)
|
||||
|
||||
#if defined(SUPPORT_VR_SIMULATOR)
|
||||
// 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)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Initialize framebuffer and textures for stereo rendering
|
||||
// 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;
|
||||
#else
|
||||
@ -3699,7 +3626,11 @@ void UpdateVrTracking(Camera *camera)
|
||||
void CloseVrSimulator(void)
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
@ -3823,11 +3754,11 @@ void BeginVrDrawing(void)
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (RLGL.Vr.simulatorReady)
|
||||
{
|
||||
rlEnableRenderTexture(RLGL.Vr.stereoFbo.id); // Setup framebuffer for stereo rendering
|
||||
//glEnable(GL_FRAMEBUFFER_SRGB); // Enable SRGB framebuffer (only if required)
|
||||
rlEnableFramebuffer(RLGL.Vr.stereoFboId); // Setup framebuffer for stereo rendering
|
||||
//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)
|
||||
rlClearScreenBuffers(); // Clear current framebuffer
|
||||
//rlViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
|
||||
rlClearScreenBuffers(); // Clear current framebuffer
|
||||
|
||||
RLGL.Vr.stereoRender = true;
|
||||
}
|
||||
@ -3840,9 +3771,9 @@ void EndVrDrawing(void)
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (RLGL.Vr.simulatorReady)
|
||||
{
|
||||
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
|
||||
|
||||
@ -3856,11 +3787,11 @@ void EndVrDrawing(void)
|
||||
rlMatrixMode(RL_MODELVIEW); // Enable 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;
|
||||
else RLGL.State.currentShader = GetShaderDefault();
|
||||
|
||||
rlEnableTexture(RLGL.Vr.stereoFbo.texture.id);
|
||||
rlEnableTexture(RLGL.Vr.stereoTexId);
|
||||
|
||||
rlPushMatrix();
|
||||
rlBegin(RL_QUADS);
|
||||
@ -3873,15 +3804,15 @@ void EndVrDrawing(void)
|
||||
|
||||
// Bottom-right corner for texture and quad
|
||||
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
|
||||
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
|
||||
rlTexCoord2f(1.0f, 1.0f);
|
||||
rlVertex2f((float)RLGL.Vr.stereoFbo.texture.width, 0.0f);
|
||||
rlVertex2f((float)RLGL.State.framebufferWidth, 0.0f);
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
|
||||
|
@ -72,7 +72,7 @@
|
||||
#include "utils.h" // Required for: fopen() Android mapping
|
||||
|
||||
#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()
|
||||
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
@ -2806,7 +2837,7 @@ void UnloadTexture(Texture2D texture)
|
||||
{
|
||||
if (texture.id > 0)
|
||||
{
|
||||
rlDeleteTextures(texture.id);
|
||||
rlUnloadTexture(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)
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user