|
|
@ -1029,7 +1029,7 @@ void rlglInit(void) |
|
|
else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported"); |
|
|
else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported"); |
|
|
|
|
|
|
|
|
if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported"); |
|
|
if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported"); |
|
|
else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, NPOT textures support is limited (no-mipmaps, no-repeat"); |
|
|
|
|
|
|
|
|
else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, NPOT textures support is limited (no-mipmaps, no-repeat)"); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
if (texCompDXTSupported) TraceLog(INFO, "[EXTENSION] DXT compressed textures supported"); |
|
|
if (texCompDXTSupported) TraceLog(INFO, "[EXTENSION] DXT compressed textures supported"); |
|
|
@ -1610,7 +1610,7 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height) |
|
|
// NOTE: Don't confuse glViewport with the transformation matrix |
|
|
// NOTE: Don't confuse glViewport with the transformation matrix |
|
|
// NOTE: glViewport just defines the area of the context that you will actually draw to. |
|
|
// NOTE: glViewport just defines the area of the context that you will actually draw to. |
|
|
|
|
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color (black) |
|
|
|
|
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) |
|
|
//glClearDepth(1.0f); // Clear depth buffer (default) |
|
|
//glClearDepth(1.0f); // Clear depth buffer (default) |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear used buffers, depth buffer is used for 3D |
|
|
|
|
|
|
|
|
@ -1880,6 +1880,38 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma |
|
|
return id; |
|
|
return id; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data) |
|
|
|
|
|
{ |
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, id); |
|
|
|
|
|
|
|
|
|
|
|
#if defined(GRAPHICS_API_OPENGL_33) |
|
|
|
|
|
switch (format) |
|
|
|
|
|
{ |
|
|
|
|
|
case UNCOMPRESSED_GRAYSCALE: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_GRAY_ALPHA: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RG, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R5G6B5: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R8G8B8: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R5G5B5A1: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R4G4B4A4: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R8G8B8A8: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
default: TraceLog(WARNING, "Texture format updating not supported"); break; |
|
|
|
|
|
} |
|
|
|
|
|
#elif defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_ES2) |
|
|
|
|
|
// NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA |
|
|
|
|
|
switch (format) |
|
|
|
|
|
{ |
|
|
|
|
|
case UNCOMPRESSED_GRAYSCALE: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_GRAY_ALPHA: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R5G6B5: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R8G8B8: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R5G5B5A1: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R4G4B4A4: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break; |
|
|
|
|
|
case UNCOMPRESSED_R8G8B8A8: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break; |
|
|
|
|
|
default: TraceLog(WARNING, "Texture format updating not supported"); break; |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Generate mipmap data for selected texture |
|
|
// Generate mipmap data for selected texture |
|
|
void rlglGenerateMipmaps(unsigned int textureId) |
|
|
void rlglGenerateMipmaps(unsigned int textureId) |
|
|
{ |
|
|
{ |
|
|
@ -2019,8 +2051,6 @@ Model rlglLoadModel(VertexData mesh) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Read screen pixel data (color buffer) |
|
|
// Read screen pixel data (color buffer) |
|
|
// ISSUE: Non pre-multiplied alpha when reading from backbuffer! |
|
|
|
|
|
// TODO: Multiply alpha |
|
|
|
|
|
unsigned char *rlglReadScreenPixels(int width, int height) |
|
|
unsigned char *rlglReadScreenPixels(int width, int height) |
|
|
{ |
|
|
{ |
|
|
unsigned char *screenData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); |
|
|
unsigned char *screenData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); |
|
|
@ -2031,11 +2061,16 @@ unsigned char *rlglReadScreenPixels(int width, int height) |
|
|
// Flip image vertically! |
|
|
// Flip image vertically! |
|
|
unsigned char *imgData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); |
|
|
unsigned char *imgData = (unsigned char *)malloc(width*height*sizeof(unsigned char)*4); |
|
|
|
|
|
|
|
|
for (int y = height-1; y >= 0; y--) |
|
|
|
|
|
|
|
|
for (int y = height - 1; y >= 0; y--) |
|
|
{ |
|
|
{ |
|
|
for (int x = 0; x < (width*4); x++) |
|
|
for (int x = 0; x < (width*4); x++) |
|
|
{ |
|
|
{ |
|
|
imgData[x + (height - y - 1)*width*4] = screenData[x + (y*width*4)]; |
|
|
|
|
|
|
|
|
// Flip line |
|
|
|
|
|
imgData[((height - 1) - y)*width*4 + x] = screenData[(y*width*4) + x]; |
|
|
|
|
|
|
|
|
|
|
|
// Set alpha component value to 255 (no trasparent image retrieval) |
|
|
|
|
|
// NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! |
|
|
|
|
|
if (((x + 1)%4) == 0) imgData[((height - 1) - y)*width*4 + x] = 255; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -2045,27 +2080,30 @@ unsigned char *rlglReadScreenPixels(int width, int height) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Read texture pixel data |
|
|
// Read texture pixel data |
|
|
// NOTE: Retrieving pixel data from GPU (glGetTexImage()) not supported on OpenGL ES 2.0 |
|
|
|
|
|
void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) |
|
|
|
|
|
|
|
|
// NOTE: glGetTexImage() is not available on OpenGL ES 2.0 |
|
|
|
|
|
// Texture2D width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. |
|
|
|
|
|
void *rlglReadTexturePixels(Texture2D texture) |
|
|
{ |
|
|
{ |
|
|
void *pixels = NULL; |
|
|
void *pixels = NULL; |
|
|
|
|
|
|
|
|
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) |
|
|
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) |
|
|
int width, height; |
|
|
|
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, textureId); |
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture.id); |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: Using texture.id, we can retrieve some texture info (but not on OpenGL ES 2.0) |
|
|
|
|
|
/* |
|
|
|
|
|
int width, height, format; |
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); |
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); |
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); |
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); |
|
|
//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); |
|
|
|
|
|
//GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE |
|
|
|
|
|
|
|
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); |
|
|
|
|
|
// Other texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
int glFormat = 0, glType = 0; |
|
|
int glFormat = 0, glType = 0; |
|
|
|
|
|
|
|
|
unsigned int size = width*height; |
|
|
|
|
|
|
|
|
unsigned int size = texture.width*texture.height; |
|
|
|
|
|
|
|
|
// NOTE: GL_LUMINANCE and GL_LUMINANCE_ALPHA are removed since OpenGL 3.1 |
|
|
// NOTE: GL_LUMINANCE and GL_LUMINANCE_ALPHA are removed since OpenGL 3.1 |
|
|
// Must be replaced by GL_RED and GL_RG on Core OpenGL 3.3 and data must be swizzled |
|
|
|
|
|
|
|
|
// Must be replaced by GL_RED and GL_RG on Core OpenGL 3.3 |
|
|
|
|
|
|
|
|
switch (format) |
|
|
switch (format) |
|
|
{ |
|
|
{ |
|
|
@ -2073,27 +2111,15 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) |
|
|
case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; break; // 8 bit per pixel (no alpha) |
|
|
case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; break; // 8 bit per pixel (no alpha) |
|
|
case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; break; // 16 bpp (2 channels) |
|
|
case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; break; // 16 bpp (2 channels) |
|
|
#elif defined(GRAPHICS_API_OPENGL_33) |
|
|
#elif defined(GRAPHICS_API_OPENGL_33) |
|
|
case UNCOMPRESSED_GRAYSCALE: // 8 bit per pixel (no alpha) |
|
|
|
|
|
{ |
|
|
|
|
|
pixels = (unsigned char *)malloc(size); glFormat = GL_RED; glType = GL_UNSIGNED_BYTE; |
|
|
|
|
|
|
|
|
|
|
|
GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; |
|
|
|
|
|
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); |
|
|
|
|
|
} break; |
|
|
|
|
|
case UNCOMPRESSED_GRAY_ALPHA: // 16 bpp (2 channels) |
|
|
|
|
|
{ |
|
|
|
|
|
pixels = (unsigned char *)malloc(size*2); glFormat = GL_RG; glType = GL_UNSIGNED_BYTE; |
|
|
|
|
|
|
|
|
|
|
|
GLint swizzleMask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; |
|
|
|
|
|
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); |
|
|
|
|
|
} break; |
|
|
|
|
|
|
|
|
case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_RED; glType = GL_UNSIGNED_BYTE; break; |
|
|
|
|
|
case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_RG; glType = GL_UNSIGNED_BYTE; break; |
|
|
#endif |
|
|
#endif |
|
|
case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; break; // 16 bpp |
|
|
case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; break; // 16 bpp |
|
|
case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; break; // 24 bpp |
|
|
case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; break; // 24 bpp |
|
|
case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; break; // 16 bpp (1 bit alpha) |
|
|
case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; break; // 16 bpp (1 bit alpha) |
|
|
case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; break; // 16 bpp (4 bit alpha) |
|
|
case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; break; // 16 bpp (4 bit alpha) |
|
|
case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; break; // 32 bpp |
|
|
case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; break; // 32 bpp |
|
|
default: TraceLog(WARNING, "Texture format not suported"); break; |
|
|
|
|
|
|
|
|
default: TraceLog(WARNING, "Texture data retrieval, format not suported"); break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. |
|
|
// NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. |
|
|
@ -2108,16 +2134,36 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if defined(GRAPHICS_API_OPENGL_ES2) |
|
|
#if defined(GRAPHICS_API_OPENGL_ES2) |
|
|
// TODO: Look for some way to retrieve texture width and height from id |
|
|
|
|
|
int width = 1024; |
|
|
|
|
|
int height = 1024; |
|
|
|
|
|
|
|
|
FBO fbo = rlglLoadFBO(texture.width, texture.height); |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: Two possible Options: |
|
|
|
|
|
// 1 - Bind texture to color fbo attachment and glReadPixels() |
|
|
|
|
|
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels() |
|
|
|
|
|
|
|
|
|
|
|
#define GET_TEXTURE_FBO_OPTION_1 // It works |
|
|
|
|
|
|
|
|
|
|
|
#if defined(GET_TEXTURE_FBO_OPTION_1) |
|
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); |
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0); |
|
|
|
|
|
|
|
|
FBO fbo = rlglLoadFBO(width, height); |
|
|
|
|
|
|
|
|
// Attach our texture to FBO -> Texture must be RGB |
|
|
|
|
|
// NOTE: Previoust attached texture is automatically detached |
|
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.id, 0); |
|
|
|
|
|
|
|
|
|
|
|
pixels = (unsigned char *)malloc(texture.width*texture.height*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
|
|
|
|
// NOTE: Despite FBO color texture is RGB, we read data as RGBA... reading as RGB doesn't work... o__O |
|
|
|
|
|
glReadPixels(0, 0, texture.width, texture.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
|
|
|
|
|
|
|
|
|
|
|
// Re-attach internal FBO color texture before deleting it |
|
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo.colorTextureId, 0); |
|
|
|
|
|
|
|
|
// NOTE: Altenatively we can bind texture to color fbo and glReadPixels() |
|
|
|
|
|
|
|
|
n">glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
|
|
|
|
|
|
|
|
|
|
#elif defined(GET_TEXTURE_FBO_OPTION_2) |
|
|
// Render texture to fbo |
|
|
// Render texture to fbo |
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); |
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id); |
|
|
|
|
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0); |
|
|
glClearColor(0.0, 0.0, 0.0, 0.0); |
|
|
glClearDepthf(1.0f); |
|
|
glClearDepthf(1.0f); |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
@ -2131,16 +2177,23 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) |
|
|
//glDisable(GL_BLEND); |
|
|
//glDisable(GL_BLEND); |
|
|
glEnable(GL_DEPTH_TEST); |
|
|
glEnable(GL_DEPTH_TEST); |
|
|
|
|
|
|
|
|
//Model quad = GenModelQuad(width, height); |
|
|
|
|
|
//DrawModel(quad, (Vector3){ 0, 0, 0 }, 1.0f, WHITE); |
|
|
|
|
|
|
|
|
Model quad; |
|
|
|
|
|
//quad.mesh = GenMeshQuad(width, height); |
|
|
|
|
|
quad.transform = MatrixIdentity(); |
|
|
|
|
|
quad.shader = simpleShader; |
|
|
|
|
|
|
|
|
pixels = (unsigned char *)malloc(width*height*4*sizeof(unsigned char)); |
|
|
|
|
|
|
|
|
DrawModel(quad, (Vector3){ 0, 0, 0 }, 1.0f, WHITE); |
|
|
|
|
|
|
|
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
|
|
|
|
|
|
|
|
pixels = (unsigned char *)malloc(texture.width*texture.height*3*sizeof(unsigned char)); |
|
|
|
|
|
|
|
|
|
|
|
glReadPixels(0, 0, texture.width, texture.height, GL_RGB, GL_UNSIGNED_BYTE, pixels); |
|
|
|
|
|
|
|
|
// Bind framebuffer 0, which means render to back buffer |
|
|
// Bind framebuffer 0, which means render to back buffer |
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); |
|
|
|
|
|
|
|
|
|
|
|
UnloadModel(quad); |
|
|
|
|
|
#endif // GET_TEXTURE_FBO_OPTION |
|
|
|
|
|
|
|
|
// Clean up temporal fbo |
|
|
// Clean up temporal fbo |
|
|
rlglUnloadFBO(fbo); |
|
|
rlglUnloadFBO(fbo); |
|
|
#endif |
|
|
#endif |
|
|
|