GPUTexture: Add support for depth_stencil textures.
This commit is contained in:
parent
b7355425cd
commit
c4644b484d
|
@ -101,8 +101,8 @@ typedef enum GPUTextureFormat {
|
|||
GPU_RGB10_A2,
|
||||
GPU_RGB10_A2UI,
|
||||
GPU_DEPTH32F_STENCIL8,
|
||||
GPU_DEPTH24_STENCIL8,
|
||||
#endif
|
||||
GPU_DEPTH24_STENCIL8,
|
||||
|
||||
/* Texture only format */
|
||||
#if 0
|
||||
|
@ -155,6 +155,7 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int d, const float *pixels, char
|
|||
GPUTexture *GPU_texture_create_3D_custom(
|
||||
int w, int h, int d, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]);
|
||||
GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
|
||||
GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256]);
|
||||
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256]);
|
||||
|
||||
GPUTexture *GPU_texture_from_blender(
|
||||
|
@ -183,7 +184,8 @@ void GPU_texture_framebuffer_set(GPUTexture *tex, struct GPUFrameBuffer *fb, int
|
|||
int GPU_texture_target(const GPUTexture *tex);
|
||||
int GPU_texture_width(const GPUTexture *tex);
|
||||
int GPU_texture_height(const GPUTexture *tex);
|
||||
int GPU_texture_depth(const GPUTexture *tex);
|
||||
bool GPU_texture_depth(const GPUTexture *tex);
|
||||
bool GPU_texture_stencil(const GPUTexture *tex);
|
||||
int GPU_texture_opengl_bindcode(const GPUTexture *tex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -133,14 +133,16 @@ bool GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slo
|
|||
}
|
||||
}
|
||||
|
||||
if (GPU_texture_depth(tex))
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
|
||||
GG.currentfb = fb->object;
|
||||
|
||||
if (GPU_texture_stencil(tex) && GPU_texture_depth(tex))
|
||||
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
else if (GPU_texture_depth(tex))
|
||||
attachment = GL_DEPTH_ATTACHMENT;
|
||||
else
|
||||
attachment = GL_COLOR_ATTACHMENT0 + slot;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
|
||||
GG.currentfb = fb->object;
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
|
||||
GPU_texture_target(tex), GPU_texture_opengl_bindcode(tex), 0);
|
||||
|
||||
|
@ -168,7 +170,11 @@ void GPU_framebuffer_texture_detach(GPUTexture *tex)
|
|||
GG.currentfb = fb->object;
|
||||
}
|
||||
|
||||
if (GPU_texture_depth(tex)) {
|
||||
if (GPU_texture_stencil(tex) && GPU_texture_depth(tex)) {
|
||||
fb->depthtex = NULL;
|
||||
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
}
|
||||
else if (GPU_texture_depth(tex)) {
|
||||
fb->depthtex = NULL;
|
||||
attachment = GL_DEPTH_ATTACHMENT;
|
||||
}
|
||||
|
|
|
@ -62,19 +62,30 @@ struct GPUTexture {
|
|||
GPUFrameBuffer *fb; /* GPUFramebuffer this texture is attached to */
|
||||
int fb_attachment; /* slot the texture is attached to */
|
||||
bool depth; /* is a depth texture? */
|
||||
bool stencil; /* is a stencil texture? */
|
||||
};
|
||||
|
||||
static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, bool *is_depth)
|
||||
static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil)
|
||||
{
|
||||
if (data_type == GPU_DEPTH_COMPONENT24 ||
|
||||
data_type == GPU_DEPTH_COMPONENT16 ||
|
||||
data_type == GPU_DEPTH_COMPONENT32F)
|
||||
{
|
||||
*is_depth = true;
|
||||
*is_stencil = false;
|
||||
*data_format = GL_FLOAT;
|
||||
*format = GL_DEPTH_COMPONENT;
|
||||
}
|
||||
else if (data_type == GPU_DEPTH24_STENCIL8) {
|
||||
*is_depth = true;
|
||||
*is_stencil = true;
|
||||
*data_format = GL_UNSIGNED_INT_24_8;
|
||||
*format = GL_DEPTH_STENCIL;
|
||||
}
|
||||
else {
|
||||
*is_depth = false;
|
||||
*is_stencil = false;
|
||||
*data_format = GL_FLOAT;
|
||||
|
||||
switch (components) {
|
||||
case 1: *format = GL_RED; break;
|
||||
|
@ -95,7 +106,7 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type,
|
|||
case GPU_RGBA8: return GL_RGBA8;
|
||||
case GPU_R8: return GL_R8;
|
||||
/* Special formats texture & renderbuffer */
|
||||
/* ** Add Format here **/
|
||||
case GPU_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
|
||||
/* Texture only format */
|
||||
/* ** Add Format here **/
|
||||
/* Special formats texture only */
|
||||
|
@ -148,20 +159,20 @@ static float *GPU_texture_3D_rescale(GPUTexture *tex, int w, int h, int d, int c
|
|||
/* This tries to allocate video memory for a given texture
|
||||
* If alloc fails, lower the resolution until it fits. */
|
||||
static bool GPU_texture_try_alloc(
|
||||
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, int channels,
|
||||
bool try_rescale, const float *fpixels, float **rescaled_fpixels)
|
||||
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum format, GLenum data_format,
|
||||
int channels, bool try_rescale, const float *fpixels, float **rescaled_fpixels)
|
||||
{
|
||||
int r_width;
|
||||
|
||||
switch (proxy) {
|
||||
case GL_PROXY_TEXTURE_1D:
|
||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
|
||||
break;
|
||||
case GL_PROXY_TEXTURE_2D:
|
||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
|
||||
break;
|
||||
case GL_PROXY_TEXTURE_3D:
|
||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -182,11 +193,11 @@ static bool GPU_texture_try_alloc(
|
|||
if (tex->d == 0 && proxy == GL_PROXY_TEXTURE_3D) break;
|
||||
|
||||
if (proxy == GL_PROXY_TEXTURE_1D)
|
||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage1D(proxy, 0, internalformat, tex->w, 0, format, data_format, NULL);
|
||||
else if (proxy == GL_PROXY_TEXTURE_2D)
|
||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, format, data_format, NULL);
|
||||
else if (proxy == GL_PROXY_TEXTURE_3D)
|
||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, NULL);
|
||||
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, NULL);
|
||||
|
||||
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &r_width);
|
||||
}
|
||||
|
@ -213,7 +224,7 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
GPUTextureFormat data_type, int components, int samples,
|
||||
const bool can_rescale, char err_out[256])
|
||||
{
|
||||
GLenum format, internalformat, proxy;
|
||||
GLenum format, internalformat, proxy, data_format;
|
||||
float *rescaled_fpixels = NULL;
|
||||
const float *pix;
|
||||
bool valid;
|
||||
|
@ -228,6 +239,7 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
tex->d = d;
|
||||
tex->number = -1;
|
||||
tex->refcount = 1;
|
||||
tex->fb_attachment = -1;
|
||||
|
||||
if (n == 1) {
|
||||
if (h == 0)
|
||||
|
@ -245,12 +257,10 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
tex->target_base = tex->target = GL_TEXTURE_3D;
|
||||
}
|
||||
|
||||
tex->fb_attachment = -1;
|
||||
|
||||
if (samples && n == 2 && d == 0)
|
||||
tex->target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
|
||||
internalformat = GPU_texture_get_format(components, data_type, &format, &tex->depth);
|
||||
internalformat = GPU_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil);
|
||||
|
||||
/* Generate Texture object */
|
||||
glGenTextures(1, &tex->bindcode);
|
||||
|
@ -278,7 +288,7 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
proxy = GL_PROXY_TEXTURE_1D;
|
||||
}
|
||||
|
||||
valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, components, can_rescale, fpixels,
|
||||
valid = GPU_texture_try_alloc(tex, proxy, internalformat, format, data_format, components, can_rescale, fpixels,
|
||||
&rescaled_fpixels);
|
||||
|
||||
if (!valid) {
|
||||
|
@ -294,7 +304,7 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
pix = (rescaled_fpixels) ? rescaled_fpixels : fpixels;
|
||||
|
||||
if (tex->target == GL_TEXTURE_1D) {
|
||||
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, GL_FLOAT, pix);
|
||||
glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, data_format, pix);
|
||||
}
|
||||
else if (tex->target == GL_TEXTURE_1D_ARRAY ||
|
||||
tex->target == GL_TEXTURE_2D ||
|
||||
|
@ -303,14 +313,14 @@ static GPUTexture *GPU_texture_create_nD(
|
|||
if (samples) {
|
||||
glTexImage2DMultisample(tex->target, samples, internalformat, tex->w, tex->h, true);
|
||||
if (pix)
|
||||
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, GL_FLOAT, pix);
|
||||
glTexSubImage2D(tex->target, 0, 0, 0, tex->w, tex->h, format, data_format, pix);
|
||||
}
|
||||
else {
|
||||
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, GL_FLOAT, pix);
|
||||
glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, data_format, pix);
|
||||
}
|
||||
}
|
||||
else {
|
||||
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, GL_FLOAT, pix);
|
||||
glTexImage3D(tex->target, 0, internalformat, tex->w, tex->h, tex->d, 0, format, data_format, pix);
|
||||
}
|
||||
|
||||
if (rescaled_fpixels)
|
||||
|
@ -494,6 +504,11 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
|
|||
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, 0, false, err_out);
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_depth_with_stencil(int w, int h, char err_out[256])
|
||||
{
|
||||
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH24_STENCIL8, 1, 0, false, err_out);
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char err_out[256])
|
||||
{
|
||||
return GPU_texture_create_nD(w, h, 0, 2, NULL, GPU_DEPTH_COMPONENT24, 1, samples, false, err_out);
|
||||
|
@ -708,11 +723,16 @@ int GPU_texture_height(const GPUTexture *tex)
|
|||
return tex->h;
|
||||
}
|
||||
|
||||
int GPU_texture_depth(const GPUTexture *tex)
|
||||
bool GPU_texture_depth(const GPUTexture *tex)
|
||||
{
|
||||
return tex->depth;
|
||||
}
|
||||
|
||||
bool GPU_texture_stencil(const GPUTexture *tex)
|
||||
{
|
||||
return tex->stencil;
|
||||
}
|
||||
|
||||
int GPU_texture_opengl_bindcode(const GPUTexture *tex)
|
||||
{
|
||||
return tex->bindcode;
|
||||
|
|
|
@ -214,7 +214,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
|
|||
}
|
||||
|
||||
/* Depth */
|
||||
dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
|
||||
dtxl->depth = GPU_texture_create_depth_with_stencil(rect_w, rect_h, NULL);
|
||||
if (!dtxl->depth) {
|
||||
ok = false;
|
||||
goto cleanup;
|
||||
|
|
Loading…
Reference in New Issue