Images: add mirror extension type

This adds a new mirror image extension type for shaders and
geometry nodes (next to the existing repeat, extend and clip
options).

See D16432 for a more detailed explanation of `wrap_mirror`.

This also adds a new sampler flag `GPU_SAMPLER_MIRROR_REPEAT`.
It acts as a modifier to `GPU_SAMPLER_REPEAT`, so any `REPEAT`
flag must be set for the `MIRROR` flag to have an effect.

Differential Revision: https://developer.blender.org/D16432
This commit is contained in:
Hallam Roberts
2022-12-14 19:19:52 +01:00
committed by Jacques Lucke
parent 8c14992db2
commit a501a2dbff
17 changed files with 174 additions and 53 deletions

View File

@@ -548,12 +548,13 @@ GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0};
void GLTexture::samplers_init()
{
glGenSamplers(GPU_SAMPLER_MAX, samplers_);
for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
for (int i = 0; i < GPU_SAMPLER_ICON; i++) {
eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type;
GLenum repeat_type = (state & GPU_SAMPLER_MIRROR_REPEAT) ? GL_MIRRORED_REPEAT : GL_REPEAT;
GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? repeat_type : clamp_type;
GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? repeat_type : clamp_type;
GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? repeat_type : clamp_type;
GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST;
GLenum min_filter = (state & GPU_SAMPLER_FILTER) ?
((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
@@ -577,7 +578,7 @@ void GLTexture::samplers_init()
char sampler_name[128] = "\0\0";
SNPRINTF(sampler_name,
"%s%s%s%s%s%s%s%s%s%s",
"%s%s%s%s%s%s%s%s%s%s%s",
(state == GPU_SAMPLER_DEFAULT) ? "_default" : "",
(state & GPU_SAMPLER_FILTER) ? "_filter" : "",
(state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "",
@@ -585,6 +586,7 @@ void GLTexture::samplers_init()
(state & GPU_SAMPLER_REPEAT_S) ? "S" : "",
(state & GPU_SAMPLER_REPEAT_T) ? "T" : "",
(state & GPU_SAMPLER_REPEAT_R) ? "R" : "",
(state & GPU_SAMPLER_MIRROR_REPEAT) ? "-mirror" : "",
(state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "",
(state & GPU_SAMPLER_COMPARE) ? "_compare" : "",
(state & GPU_SAMPLER_ANISO) ? "_aniso" : "");
@@ -612,7 +614,7 @@ void GLTexture::samplers_update()
float aniso_filter = min_ff(max_anisotropy, U.anisotropic_filter);
for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) {
for (int i = 0; i < GPU_SAMPLER_ICON; i++) {
eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
if ((state & GPU_SAMPLER_ANISO) && (state & GPU_SAMPLER_MIPMAP)) {
glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter);