diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_texture.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index 3513250993e..88dbe0c2ed9 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -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; @@ -93,9 +104,10 @@ static GLenum GPU_texture_get_format(int components, GPUTextureFormat data_type, case GPU_RG32F: return GL_RG32F; case GPU_RG16F: return GL_RG16F; case GPU_RGBA8: return GL_RGBA8; + case GPU_R16F: return GL_R16F; 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 +160,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 +194,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 +225,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 +240,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 +258,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 +289,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 +305,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 +314,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 +505,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 +724,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; |