summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRay <[email protected]>2019-02-04 16:28:17 +0100
committerRay <[email protected]>2019-02-04 16:28:17 +0100
commitdb56d432e4812f9b21f3548108fb4f1963a81ff5 (patch)
tree98ed83c66491e75ab9948c613fbb3a2103583527 /src
parentfce48e85f441215192d188011b48a0f35828e4b3 (diff)
downloadraylib-db56d432e4812f9b21f3548108fb4f1963a81ff5.tar.gz
raylib-db56d432e4812f9b21f3548108fb4f1963a81ff5.zip
ADDED: rlLoadTextureDepth()
REDESIGNED: rlLoadRenderTexture() ADDED: rlRenderTextureAttach() ADDED: rlRenderTextureComplete()
Diffstat (limited to 'src')
-rw-r--r--src/libraylib.abin0 -> 1293464 bytes
-rw-r--r--src/rlgl.h231
-rw-r--r--src/textures.c2
3 files changed, 140 insertions, 93 deletions
diff --git a/src/libraylib.a b/src/libraylib.a
new file mode 100644
index 00000000..fc9a7820
--- /dev/null
+++ b/src/libraylib.a
Binary files differ
diff --git a/src/rlgl.h b/src/rlgl.h
index 69af55e6..91d337d2 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -175,13 +175,22 @@ typedef unsigned char byte;
int format; // Data format (PixelFormat)
} Texture2D;
+ // Texture type, same as Texture2D
+ typedef Texture2D Texture;
+
+ // TextureCubemap type, actually, same as Texture2D
+ typedef Texture2D TextureCubemap;
+
// RenderTexture2D type, for texture rendering
typedef struct RenderTexture2D {
- unsigned int id; // Render texture (fbo) id
+ unsigned int id; // OpenGL Framebuffer Object (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
@@ -450,18 +459,20 @@ Vector3 rlUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coo
// Textures data management
unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
+unsigned int rlLoadTextureDepth(int width, int height, int bits, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
unsigned int rlLoadTextureCubemap(void *data, int size, int format); // Load texture cubemap
void rlUpdateTexture(unsigned int id, int width, int height, int format, const void *data); // Update GPU texture with new data
void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned int *glFormat, unsigned int *glType); // Get OpenGL internal formats
-void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory
+void rlUnloadTexture(unsigned int id); // Unload texture from GPU memory
void rlGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture
void *rlReadTexturePixels(Texture2D texture); // Read texture pixel data
unsigned char *rlReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
-RenderTexture2D rlLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with default color and depth attachments)
-RenderTexture2D rlLoadRenderTextureEx(int width, int height, int colorFormat, int depthBits, bool useDepthTexture);
-void rlAttachRenderTexture(RenderTexture target, unsigned int textureId); // Attach/detach color buffer texture to an FBO (returns previous attachment)
-bool rlCompleteRenderTexture(RenderTexture target); // Verify rendertexture is complete
+
+// Render texture management (fbo)
+RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depthBits, bool useDepthTexture); // Load a render texture (with color and depth attachments)
+void rlRenderTextureAttach(RenderTexture target, unsigned int id, int attachType); // Attach texture/renderbuffer to an fbo
+bool rlRenderTextureComplete(RenderTexture target); // Verify render texture is complete
// Vertex data management
void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
@@ -850,6 +861,8 @@ static bool texCompASTCSupported = false; // ASTC texture compression support
// Extension supported flag: Textures format
static bool texNPOTSupported = false; // NPOT textures full support
static bool texFloatSupported = false; // float textures support (32 bit per channel)
+static bool texDepthSupported = false; // Depth textures supported
+static int maxDepthBits = 16; // Maximum bits for depth component
// Extension supported flag: Clamp mirror wrap mode
static bool texMirrorClampSupported = false; // Clamp mirror wrap mode supported
@@ -1503,8 +1516,11 @@ void rlglInit(int width, int height)
// NOTE: On OpenGL 3.3 VAO and NPOT are supported by default
vaoSupported = true;
+
+ // Multiple texture extensions supported by default
texNPOTSupported = true;
texFloatSupported = true;
+ texDepthSupported = true;
// We get a list of available extensions and we check for some of them (compressed textures)
// NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that)
@@ -1573,6 +1589,13 @@ void rlglInit(int width, int height)
// Check texture float support
if (strcmp(extList[i], (const char *)"GL_OES_texture_float") == 0) texFloatSupported = true;
+
+ // Check depth texture support
+ if ((strcmp(extList[i], (const char *)"GL_OES_depth_texture") == 0) ||
+ (strcmp(extList[i], (const char *)"GL_WEBGL_depth_texture") == 0)) texDepthSupported = true;
+
+ if (strcmp(extList[i], (const char *)"GL_OES_depth24") == 0) maxDepthBits = 24;
+ if (strcmp(extList[i], (const char *)"GL_OES_depth32") == 0) maxDepthBits = 32;
#endif
// DDS texture compression support
if ((strcmp(extList[i], (const char *)"GL_EXT_texture_compression_s3tc") == 0) ||
@@ -1970,6 +1993,60 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
return id;
}
+// 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 id = 0;
+ unsigned int glInternalFormat = GL_DEPTH_COMPONENT16;
+
+ if ((bits != 16) && (bits != 24) && (bits != 32)) bits = 16;
+
+ if (bits == 24)
+ {
+#if defined(GRAPHICS_API_OPENGL_33)
+ glInternalFormat = GL_DEPTH_COMPONENT24;
+#elif defined(GRAPHICS_API_OPENGL_ES2)
+ if (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 (maxDepthBits == 32) glInternalFormat = GL_DEPTH_COMPONENT32_OES;
+#endif
+ }
+
+ if (!useRenderBuffer && texDepthSupported)
+ {
+ glGenTextures(1, &id);
+ glBindTexture(GL_TEXTURE_2D, id);
+ glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ else
+ {
+ // Create the renderbuffer that will serve as the depth attachment for the framebuffer
+ // NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices
+ glGenRenderbuffers(1, &id);
+ glBindRenderbuffer(GL_RENDERBUFFER, id);
+ glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ }
+
+ return id;
+}
+
// Update already loaded texture in GPU with new data
// TODO: We don't know safely if internal texture format is the expected one...
void rlUpdateTexture(unsigned int id, int width, int height, int format, const void *data)
@@ -2102,7 +2179,7 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
// 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 colorFormat, int depthBits, bool useDepthTexture);
+RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depthBits, bool useDepthTexture)
{
RenderTexture2D target = { 0 };
@@ -2113,116 +2190,86 @@ RenderTexture2D rlLoadRenderTexture(int width, int height) //, int colorFormat,
// Create fbo color texture attachment
//-----------------------------------------------------------------------------------------------------
- target.texture.id = 0;
- target.texture.width = width;
- target.texture.height = height;
- target.texture.format = UNCOMPRESSED_R8G8B8A8;
- target.texture.mipmaps = 1;
-
- // Create the texture that will serve as the color attachment for the framebuffer
- glGenTextures(1, &target.texture.id);
- glBindTexture(GL_TEXTURE_2D, target.texture.id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
+ 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
//-----------------------------------------------------------------------------------------------------
- target.depth.id = 0;
- target.depth.width = width;
- target.depth.height = height;
- target.depth.format = 19; //DEPTH_COMPONENT_24BIT
- target.depth.mipmaps = 1;
-
-#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_ES2)
- #define USE_DEPTH_RENDERBUFFER
-#else
- #define USE_DEPTH_TEXTURE
-#endif
-
-#if defined(USE_DEPTH_RENDERBUFFER)
- // Create the renderbuffer that will serve as the depth attachment for the framebuffer.
- glGenRenderbuffers(1, &target.depth.id);
- glBindRenderbuffer(GL_RENDERBUFFER, target.depth.id);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); // GL_DEPTH_COMPONENT24 not supported on Android
-#elif defined(USE_DEPTH_TEXTURE)
- // NOTE: We can also use a texture for depth buffer (GL_ARB_depth_texture/GL_OES_depth_texture extension required)
- // A renderbuffer is simpler than a texture and could offer better performance on embedded devices
- glGenTextures(1, &target.depth.id);
- glBindTexture(GL_TEXTURE_2D, target.depth.id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
- glBindTexture(GL_TEXTURE_2D, 0);
-#endif
+ 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
//-----------------------------------------------------------------------------------------------------
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target.texture.id, 0);
-#if defined(USE_DEPTH_RENDERBUFFER)
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, target.depth.id);
-#elif defined(USE_DEPTH_TEXTURE)
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, target.depth.id, 0);
-#endif
+ rlRenderTextureAttach(target, target.texture.id, 0);
+ if (useDepthTexture && texDepthSupported) rlRenderTextureAttach(target, target.depth.id, 2);
+ else rlRenderTextureAttach(target, target.depth.id, 1);
//-----------------------------------------------------------------------------------------------------
// 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
+
+ return target;
+}
+
+// Attach color buffer texture to an fbo (unloads previous attachment)
+// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture
+void rlRenderTextureAttach(RenderTexture target, unsigned int id, int attachType)
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, target.id);
+
+ if (attachType == 0) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, id, 0);
+ else if (attachType == 1) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, id);
+ else if (attachType == 2) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, id, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+// Verify render texture is complete
+bool rlRenderTextureComplete(RenderTexture target)
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, target.id);
+
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
- TraceLog(LOG_WARNING, "Framebuffer object could not be created...");
-
switch (status)
{
case GL_FRAMEBUFFER_UNSUPPORTED: TraceLog(LOG_WARNING, "Framebuffer is unsupported"); break;
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TraceLog(LOG_WARNING, "Framebuffer incomplete attachment"); break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TraceLog(LOG_WARNING, "Framebuffer has incomplete attachment"); break;
#if defined(GRAPHICS_API_OPENGL_ES2)
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TraceLog(LOG_WARNING, "Framebuffer incomplete dimensions"); break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TraceLog(LOG_WARNING, "Framebuffer has incomplete dimensions"); break;
#endif
- case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TraceLog(LOG_WARNING, "Framebuffer incomplete missing attachment"); break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TraceLog(LOG_WARNING, "Framebuffer has a missing attachment"); break;
default: break;
}
-
- if (target.texture.id > 0) glDeleteTextures(1, &target.texture.id);
- if (target.depth.id > 0)
- {
-#if defined(USE_DEPTH_RENDERBUFFER)
- glDeleteRenderbuffers(1, &target.depth.id);
-#elif defined(USE_DEPTH_TEXTURE)
- glDeleteTextures(1, &target.depth.id);
-#endif
- }
-
- glDeleteFramebuffers(1, &target.id);
}
- else TraceLog(LOG_INFO, "[FBO ID %i] Framebuffer object created successfully", target.id);
- //-----------------------------------------------------------------------------------------------------
-
+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
-#endif
-
- return target;
+
+ return (status == GL_FRAMEBUFFER_COMPLETE);
}
-// Improved FBO generation function to allow selecting the attached color buffer pixel format
-// and the depth buffer type (Renderbuffer or Texture) and size
-// NOTE: Be careful on supported pixel formats...
-//RenderTexture rlLoadRenderTexture(int width, int height, int colorFormat, int depthBits, bool useDepthTexture);
-// Attach/detach color buffer texture to an FBO (returns previous attachment)
-//Texture2D rlAttachRenderTexture(RenderTexture target, Texture2D texture);
-
-//void rlRenderTextureColorAttach(RenderTexture target, Texture2D texture);
-//bool rlRenderTextureComplete(RenderTexture target); // Verify valid rendertexture
-
// Generate mipmap data for selected texture
void rlGenerateMipmaps(Texture2D *texture)
{
@@ -2770,7 +2817,7 @@ 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);
+ RenderTexture2D fbo = rlLoadRenderTexture(texture.width, texture.height, UNCOMPRESSED_R8G8B8A8, 16, false);
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -3509,7 +3556,7 @@ void InitVrSimulator(VrDeviceInfo info)
#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
- vrConfig.stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight);
+ vrConfig.stereoFbo = rlLoadRenderTexture(screenWidth, screenHeight, UNCOMPRESSED_R8G8B8A8, 24, false);
#if defined(SUPPORT_DISTORTION_SHADER)
// Load distortion shader
diff --git a/src/textures.c b/src/textures.c
index 988b94a3..5ab22970 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -486,7 +486,7 @@ 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);
+ RenderTexture2D target = rlLoadRenderTexture(width, height, UNCOMPRESSED_R8G8B8A8, 24, false);
return target;
}