diff options
Diffstat (limited to 'source/blender/gpu')
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 7 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_draw.h | 14 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_codegen.c | 22 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 388 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_draw_smoke.c | 416 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_matrix.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl | 2 |
8 files changed, 446 insertions, 410 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index bcdc1550fd2..8daeda67c80 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -44,7 +44,7 @@ set(INC ../../../intern/glew-mx ../../../intern/guardedalloc - ../../../intern/smoke/extern + ../../../intern/mantaflow/extern ) set(INC_SYS @@ -61,6 +61,7 @@ set(SRC intern/gpu_context.cpp intern/gpu_debug.c intern/gpu_draw.c + intern/gpu_draw_smoke.c intern/gpu_element.c intern/gpu_extensions.c intern/gpu_framebuffer.c @@ -319,8 +320,8 @@ data_to_c_simple(shaders/gpu_shader_cfg_world_clip_lib.glsl SRC) data_to_c_simple(shaders/gpu_shader_common_obinfos_lib.glsl SRC) -if(WITH_MOD_SMOKE) - add_definitions(-DWITH_SMOKE) +if(WITH_MOD_FLUID) + add_definitions(-DWITH_FLUID) endif() add_definitions(${GL_DEFINITIONS}) diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 6d2b0ad3be3..2ed4ee44287 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -31,12 +31,12 @@ struct CCGElem; struct CCGKey; struct DMFlagMat; struct GSet; -struct Mesh; struct MLoop; struct MLoopCol; struct MLoopTri; struct MPoly; struct MVert; +struct Mesh; struct PBVH; /* Buffers for drawing from PBVH grids. */ diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index 7814c723fec..f89a76cf49c 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -28,11 +28,11 @@ extern "C" { #endif +struct FluidModifierData; struct ImBuf; struct Image; struct ImageUser; struct Main; -struct SmokeModifierData; #include "DNA_object_enums.h" @@ -83,12 +83,12 @@ void GPU_free_images(struct Main *bmain); void GPU_free_images_anim(struct Main *bmain); void GPU_free_images_old(struct Main *bmain); -/* smoke drawing functions */ -void GPU_free_smoke(struct SmokeModifierData *smd); -void GPU_free_smoke_velocity(struct SmokeModifierData *smd); -void GPU_create_smoke(struct SmokeModifierData *smd, int highres); -void GPU_create_smoke_coba_field(struct SmokeModifierData *smd); -void GPU_create_smoke_velocity(struct SmokeModifierData *smd); +/* gpu_draw_smoke.c */ +void GPU_free_smoke(struct FluidModifierData *mmd); +void GPU_free_smoke_velocity(struct FluidModifierData *mmd); +void GPU_create_smoke(struct FluidModifierData *mmd, int highres); +void GPU_create_smoke_coba_field(struct FluidModifierData *mmd); +void GPU_create_smoke_velocity(struct FluidModifierData *mmd); /* Delayed free of OpenGL buffers by main thread */ void GPU_free_unused_buffers(struct Main *bmain); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 23ea9a62ef8..ca804a26acd 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -2131,8 +2131,10 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, static int count_active_texture_sampler(GPUShader *shader, char *source) { char *code = source; - int samplers_id[64]; /* Remember this is per stage. */ - int sampler_len = 0; + + /* Remember this is per stage. */ + GSet *sampler_ids = BLI_gset_int_new(__func__); + int num_samplers = 0; while ((code = strstr(code, "uniform "))) { /* Move past "uniform". */ @@ -2167,22 +2169,16 @@ static int count_active_texture_sampler(GPUShader *shader, char *source) continue; } /* Catch duplicates. */ - bool is_duplicate = false; - for (int i = 0; i < sampler_len; i++) { - if (samplers_id[i] == id) { - is_duplicate = true; - } - } - - if (!is_duplicate) { - samplers_id[sampler_len] = id; - sampler_len++; + if (BLI_gset_add(sampler_ids, POINTER_FROM_INT(id))) { + num_samplers++; } } } } - return sampler_len; + BLI_gset_free(sampler_ids, NULL); + + return num_samplers; } static bool gpu_pass_shader_validate(GPUPass *pass, GPUShader *shader) diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index d698db45b7a..95738bb1a95 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -36,17 +36,9 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "DNA_light_types.h" -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_node_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_smoke_types.h" -#include "DNA_view3d_types.h" -#include "DNA_particle_types.h" +#include "DNA_image_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_userdef_types.h" #include "MEM_guardedalloc.h" @@ -54,14 +46,10 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "BKE_colorband.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" -#include "BKE_material.h" #include "BKE_movieclip.h" -#include "BKE_node.h" -#include "BKE_scene.h" #include "GPU_draw.h" #include "GPU_extensions.h" @@ -71,10 +59,6 @@ #include "PIL_time.h" -#ifdef WITH_SMOKE -# include "smoke_API.h" -#endif - static void gpu_free_image_immediate(Image *ima); //* Checking powers of two for images since OpenGL ES requires it */ @@ -940,372 +924,6 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i BKE_image_release_ibuf(ima, ibuf, NULL); } -/* *************************** Transfer functions *************************** */ - -enum { - TFUNC_FLAME_SPECTRUM = 0, - TFUNC_COLOR_RAMP = 1, -}; - -#define TFUNC_WIDTH 256 - -#ifdef WITH_SMOKE -static void create_flame_spectrum_texture(float *data) -{ -# define FIRE_THRESH 7 -# define MAX_FIRE_ALPHA 0.06f -# define FULL_ON_FIRE 100 - - float *spec_pixels = MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels"); - - blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000); - - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - for (int k = 0; k < TFUNC_WIDTH; k++) { - int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4; - if (k >= FIRE_THRESH) { - spec_pixels[index] = (data[k * 4]); - spec_pixels[index + 1] = (data[k * 4 + 1]); - spec_pixels[index + 2] = (data[k * 4 + 2]); - spec_pixels[index + 3] = MAX_FIRE_ALPHA * - ((k > FULL_ON_FIRE) ? - 1.0f : - (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); - } - else { - zero_v4(&spec_pixels[index]); - } - } - } - } - - memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH); - - MEM_freeN(spec_pixels); - -# undef FIRE_THRESH -# undef MAX_FIRE_ALPHA -# undef FULL_ON_FIRE -} - -static void create_color_ramp(const ColorBand *coba, float *data) -{ - for (int i = 0; i < TFUNC_WIDTH; i++) { - BKE_colorband_evaluate(coba, (float)i / TFUNC_WIDTH, &data[i * 4]); - } -} - -static GPUTexture *create_transfer_function(int type, const ColorBand *coba) -{ - float *data = MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__); - - switch (type) { - case TFUNC_FLAME_SPECTRUM: - create_flame_spectrum_texture(data); - break; - case TFUNC_COLOR_RAMP: - create_color_ramp(coba, data); - break; - } - - GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_RGBA8, data, NULL); - - MEM_freeN(data); - - return tex; -} - -static void swizzle_texture_channel_rrrr(GPUTexture *tex) -{ - GPU_texture_bind(tex, 0); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_RED); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_RED); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED); - GPU_texture_unbind(tex); -} - -static GPUTexture *create_field_texture(SmokeDomainSettings *sds) -{ - float *field = NULL; - - switch (sds->coba_field) { - case FLUID_FIELD_DENSITY: - field = smoke_get_density(sds->fluid); - break; - case FLUID_FIELD_HEAT: - field = smoke_get_heat(sds->fluid); - break; - case FLUID_FIELD_FUEL: - field = smoke_get_fuel(sds->fluid); - break; - case FLUID_FIELD_REACT: - field = smoke_get_react(sds->fluid); - break; - case FLUID_FIELD_FLAME: - field = smoke_get_flame(sds->fluid); - break; - case FLUID_FIELD_VELOCITY_X: - field = smoke_get_velocity_x(sds->fluid); - break; - case FLUID_FIELD_VELOCITY_Y: - field = smoke_get_velocity_y(sds->fluid); - break; - case FLUID_FIELD_VELOCITY_Z: - field = smoke_get_velocity_z(sds->fluid); - break; - case FLUID_FIELD_COLOR_R: - field = smoke_get_color_r(sds->fluid); - break; - case FLUID_FIELD_COLOR_G: - field = smoke_get_color_g(sds->fluid); - break; - case FLUID_FIELD_COLOR_B: - field = smoke_get_color_b(sds->fluid); - break; - case FLUID_FIELD_FORCE_X: - field = smoke_get_force_x(sds->fluid); - break; - case FLUID_FIELD_FORCE_Y: - field = smoke_get_force_y(sds->fluid); - break; - case FLUID_FIELD_FORCE_Z: - field = smoke_get_force_z(sds->fluid); - break; - default: - return NULL; - } - - GPUTexture *tex = GPU_texture_create_nD( - sds->res[0], sds->res[1], sds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); - - swizzle_texture_channel_rrrr(tex); - return tex; -} - -static GPUTexture *create_density_texture(SmokeDomainSettings *sds, int highres) -{ - float *data = NULL, *source; - int cell_count = (highres) ? smoke_turbulence_get_cells(sds->wt) : sds->total_cells; - const bool has_color = (highres) ? smoke_turbulence_has_colors(sds->wt) : - smoke_has_colors(sds->fluid); - int *dim = (highres) ? sds->res_wt : sds->res; - eGPUTextureFormat format = (has_color) ? GPU_RGBA8 : GPU_R8; - - if (has_color) { - data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); - } - - if (highres) { - if (has_color) { - smoke_turbulence_get_rgba(sds->wt, data, 0); - } - else { - source = smoke_turbulence_get_density(sds->wt); - } - } - else { - if (has_color) { - smoke_get_rgba(sds->fluid, data, 0); - } - else { - source = smoke_get_density(sds->fluid); - } - } - - GPUTexture *tex = GPU_texture_create_nD(dim[0], - dim[1], - dim[2], - 3, - (has_color) ? data : source, - format, - GPU_DATA_FLOAT, - 0, - true, - NULL); - if (data) { - MEM_freeN(data); - } - - if (format == GPU_R8) { - /* Swizzle the RGBA components to read the Red channel so - * that the shader stay the same for colored and non color - * density textures. */ - swizzle_texture_channel_rrrr(tex); - } - return tex; -} - -static GPUTexture *create_flame_texture(SmokeDomainSettings *sds, int highres) -{ - float *source = NULL; - const bool has_fuel = (highres) ? smoke_turbulence_has_fuel(sds->wt) : - smoke_has_fuel(sds->fluid); - int *dim = (highres) ? sds->res_wt : sds->res; - - if (!has_fuel) { - return NULL; - } - - if (highres) { - source = smoke_turbulence_get_flame(sds->wt); - } - else { - source = smoke_get_flame(sds->fluid); - } - - GPUTexture *tex = GPU_texture_create_nD( - dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); - - swizzle_texture_channel_rrrr(tex); - - return tex; -} -#endif /* WITH_SMOKE */ - -void GPU_free_smoke(SmokeModifierData *smd) -{ - if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) { - if (smd->domain->tex) { - GPU_texture_free(smd->domain->tex); - } - smd->domain->tex = NULL; - - if (smd->domain->tex_shadow) { - GPU_texture_free(smd->domain->tex_shadow); - } - smd->domain->tex_shadow = NULL; - - if (smd->domain->tex_flame) { - GPU_texture_free(smd->domain->tex_flame); - } - smd->domain->tex_flame = NULL; - - if (smd->domain->tex_flame_coba) { - GPU_texture_free(smd->domain->tex_flame_coba); - } - smd->domain->tex_flame_coba = NULL; - - if (smd->domain->tex_coba) { - GPU_texture_free(smd->domain->tex_coba); - } - smd->domain->tex_coba = NULL; - - if (smd->domain->tex_field) { - GPU_texture_free(smd->domain->tex_field); - } - smd->domain->tex_field = NULL; - } -} - -void GPU_create_smoke_coba_field(SmokeModifierData *smd) -{ -#ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - SmokeDomainSettings *sds = smd->domain; - - if (!sds->tex_field) { - sds->tex_field = create_field_texture(sds); - } - if (!sds->tex_coba) { - sds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, sds->coba); - } - } -#else // WITH_SMOKE - smd->domain->tex_field = NULL; -#endif // WITH_SMOKE -} - -void GPU_create_smoke(SmokeModifierData *smd, int highres) -{ -#ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - SmokeDomainSettings *sds = smd->domain; - - if (!sds->tex) { - sds->tex = create_density_texture(sds, highres); - } - if (!sds->tex_flame) { - sds->tex_flame = create_flame_texture(sds, highres); - } - if (!sds->tex_flame_coba && sds->tex_flame) { - sds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); - } - if (!sds->tex_shadow) { - sds->tex_shadow = GPU_texture_create_nD(sds->res[0], - sds->res[1], - sds->res[2], - 3, - sds->shadow, - GPU_R8, - GPU_DATA_FLOAT, - 0, - true, - NULL); - } - } -#else // WITH_SMOKE - (void)highres; - smd->domain->tex = NULL; - smd->domain->tex_flame = NULL; - smd->domain->tex_flame_coba = NULL; - smd->domain->tex_shadow = NULL; -#endif // WITH_SMOKE -} - -void GPU_create_smoke_velocity(SmokeModifierData *smd) -{ -#ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - SmokeDomainSettings *sds = smd->domain; - - const float *vel_x = smoke_get_velocity_x(sds->fluid); - const float *vel_y = smoke_get_velocity_y(sds->fluid); - const float *vel_z = smoke_get_velocity_z(sds->fluid); - - if (ELEM(NULL, vel_x, vel_y, vel_z)) { - return; - } - - if (!sds->tex_velocity_x) { - sds->tex_velocity_x = GPU_texture_create_3d( - sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_x, NULL); - sds->tex_velocity_y = GPU_texture_create_3d( - sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_y, NULL); - sds->tex_velocity_z = GPU_texture_create_3d( - sds->res[0], sds->res[1], sds->res[2], GPU_R16F, vel_z, NULL); - } - } -#else // WITH_SMOKE - smd->domain->tex_velocity_x = NULL; - smd->domain->tex_velocity_y = NULL; - smd->domain->tex_velocity_z = NULL; -#endif // WITH_SMOKE -} - -/* TODO Unify with the other GPU_free_smoke. */ -void GPU_free_smoke_velocity(SmokeModifierData *smd) -{ - if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain) { - if (smd->domain->tex_velocity_x) { - GPU_texture_free(smd->domain->tex_velocity_x); - } - - if (smd->domain->tex_velocity_y) { - GPU_texture_free(smd->domain->tex_velocity_y); - } - - if (smd->domain->tex_velocity_z) { - GPU_texture_free(smd->domain->tex_velocity_z); - } - - smd->domain->tex_velocity_x = NULL; - smd->domain->tex_velocity_y = NULL; - smd->domain->tex_velocity_z = NULL; - } -} - static LinkNode *image_free_queue = NULL; static ThreadMutex img_queue_mutex = BLI_MUTEX_INITIALIZER; diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/gpu/intern/gpu_draw_smoke.c new file mode 100644 index 00000000000..5cca472148a --- /dev/null +++ b/source/blender/gpu/intern/gpu_draw_smoke.c @@ -0,0 +1,416 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + * + * GPU fluid drawing functions. + */ + +#include <string.h> + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_modifier_types.h" +#include "DNA_fluid_types.h" + +#include "MEM_guardedalloc.h" + +#include "BKE_colorband.h" + +#include "GPU_draw.h" +#include "GPU_glew.h" +#include "GPU_texture.h" + +#ifdef WITH_FLUID +# include "manta_fluid_API.h" +#endif + +/* -------------------------------------------------------------------- */ +/** \name Private API + * \{ */ + +#ifdef WITH_FLUID + +enum { + TFUNC_FLAME_SPECTRUM = 0, + TFUNC_COLOR_RAMP = 1, +}; + +# define TFUNC_WIDTH 256 + +static void create_flame_spectrum_texture(float *data) +{ +# define FIRE_THRESH 7 +# define MAX_FIRE_ALPHA 0.06f +# define FULL_ON_FIRE 100 + + float *spec_pixels = MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels"); + + blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000); + + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { + for (int k = 0; k < TFUNC_WIDTH; k++) { + int index = (j * TFUNC_WIDTH * 16 + i * TFUNC_WIDTH + k) * 4; + if (k >= FIRE_THRESH) { + spec_pixels[index] = (data[k * 4]); + spec_pixels[index + 1] = (data[k * 4 + 1]); + spec_pixels[index + 2] = (data[k * 4 + 2]); + spec_pixels[index + 3] = MAX_FIRE_ALPHA * + ((k > FULL_ON_FIRE) ? + 1.0f : + (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); + } + else { + zero_v4(&spec_pixels[index]); + } + } + } + } + + memcpy(data, spec_pixels, sizeof(float) * 4 * TFUNC_WIDTH); + + MEM_freeN(spec_pixels); + +# undef FIRE_THRESH +# undef MAX_FIRE_ALPHA +# undef FULL_ON_FIRE +} + +static void create_color_ramp(const struct ColorBand *coba, float *data) +{ + for (int i = 0; i < TFUNC_WIDTH; i++) { + BKE_colorband_evaluate(coba, (float)i / TFUNC_WIDTH, &data[i * 4]); + } +} + +static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba) +{ + float *data = MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__); + + switch (type) { + case TFUNC_FLAME_SPECTRUM: + create_flame_spectrum_texture(data); + break; + case TFUNC_COLOR_RAMP: + create_color_ramp(coba, data); + break; + } + + GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_RGBA8, data, NULL); + + MEM_freeN(data); + + return tex; +} + +static void swizzle_texture_channel_rrrr(GPUTexture *tex) +{ + GPU_texture_bind(tex, 0); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_RED); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_RED); + GPU_texture_unbind(tex); +} + +static GPUTexture *create_field_texture(FluidDomainSettings *mds) +{ + float *field = NULL; + + switch (mds->coba_field) { + case FLUID_DOMAIN_FIELD_DENSITY: + field = manta_smoke_get_density(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_HEAT: + field = manta_smoke_get_heat(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_FUEL: + field = manta_smoke_get_fuel(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_REACT: + field = manta_smoke_get_react(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_FLAME: + field = manta_smoke_get_flame(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_X: + field = manta_get_velocity_x(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_Y: + field = manta_get_velocity_y(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_VELOCITY_Z: + field = manta_get_velocity_z(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_R: + field = manta_smoke_get_color_r(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_G: + field = manta_smoke_get_color_g(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_COLOR_B: + field = manta_smoke_get_color_b(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_X: + field = manta_get_force_x(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_Y: + field = manta_get_force_y(mds->fluid); + break; + case FLUID_DOMAIN_FIELD_FORCE_Z: + field = manta_get_force_z(mds->fluid); + break; + default: + return NULL; + } + + GPUTexture *tex = GPU_texture_create_nD( + mds->res[0], mds->res[1], mds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + + swizzle_texture_channel_rrrr(tex); + return tex; +} + +static GPUTexture *create_density_texture(FluidDomainSettings *mds, int highres) +{ + float *data = NULL, *source; + int cell_count = (highres) ? manta_smoke_turbulence_get_cells(mds->fluid) : mds->total_cells; + const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(mds->fluid) : + manta_smoke_has_colors(mds->fluid); + int *dim = (highres) ? mds->res_noise : mds->res; + eGPUTextureFormat format = (has_color) ? GPU_RGBA8 : GPU_R8; + + if (has_color) { + data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); + } + + if (highres) { + if (has_color) { + manta_smoke_turbulence_get_rgba(mds->fluid, data, 0); + } + else { + source = manta_smoke_turbulence_get_density(mds->fluid); + } + } + else { + if (has_color) { + manta_smoke_get_rgba(mds->fluid, data, 0); + } + else { + source = manta_smoke_get_density(mds->fluid); + } + } + + GPUTexture *tex = GPU_texture_create_nD(dim[0], + dim[1], + dim[2], + 3, + (has_color) ? data : source, + format, + GPU_DATA_FLOAT, + 0, + true, + NULL); + if (data) { + MEM_freeN(data); + } + + if (format == GPU_R8) { + /* Swizzle the RGBA components to read the Red channel so + * that the shader stay the same for colored and non color + * density textures. */ + swizzle_texture_channel_rrrr(tex); + } + return tex; +} + +static GPUTexture *create_flame_texture(FluidDomainSettings *mds, int highres) +{ + float *source = NULL; + const bool has_fuel = (highres) ? manta_smoke_turbulence_has_fuel(mds->fluid) : + manta_smoke_has_fuel(mds->fluid); + int *dim = (highres) ? mds->res_noise : mds->res; + + if (!has_fuel) { + return NULL; + } + + if (highres) { + source = manta_smoke_turbulence_get_flame(mds->fluid); + } + else { + source = manta_smoke_get_flame(mds->fluid); + } + + GPUTexture *tex = GPU_texture_create_nD( + dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); + + swizzle_texture_channel_rrrr(tex); + + return tex; +} + +#endif /* WITH_FLUID */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Public API + * \{ */ + +void GPU_free_smoke(FluidModifierData *mmd) +{ + if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) { + if (mmd->domain->tex) { + GPU_texture_free(mmd->domain->tex); + } + mmd->domain->tex = NULL; + + if (mmd->domain->tex_shadow) { + GPU_texture_free(mmd->domain->tex_shadow); + } + mmd->domain->tex_shadow = NULL; + + if (mmd->domain->tex_flame) { + GPU_texture_free(mmd->domain->tex_flame); + } + mmd->domain->tex_flame = NULL; + + if (mmd->domain->tex_flame_coba) { + GPU_texture_free(mmd->domain->tex_flame_coba); + } + mmd->domain->tex_flame_coba = NULL; + + if (mmd->domain->tex_coba) { + GPU_texture_free(mmd->domain->tex_coba); + } + mmd->domain->tex_coba = NULL; + + if (mmd->domain->tex_field) { + GPU_texture_free(mmd->domain->tex_field); + } + mmd->domain->tex_field = NULL; + } +} + +void GPU_create_smoke_coba_field(FluidModifierData *mmd) +{ +#ifndef WITH_FLUID + UNUSED_VARS(mmd); +#else + if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *mds = mmd->domain; + + if (!mds->tex_field) { + mds->tex_field = create_field_texture(mds); + } + if (!mds->tex_coba) { + mds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, mds->coba); + } + } +#endif +} + +void GPU_create_smoke(FluidModifierData *mmd, int highres) +{ +#ifndef WITH_FLUID + UNUSED_VARS(mmd, highres); +#else + if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *mds = mmd->domain; + + if (!mds->tex) { + mds->tex = create_density_texture(mds, highres); + } + if (!mds->tex_flame) { + mds->tex_flame = create_flame_texture(mds, highres); + } + if (!mds->tex_flame_coba && mds->tex_flame) { + mds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); + } + if (!mds->tex_shadow) { + mds->tex_shadow = GPU_texture_create_nD(mds->res[0], + mds->res[1], + mds->res[2], + 3, + manta_smoke_get_shadow(mds->fluid), + GPU_R8, + GPU_DATA_FLOAT, + 0, + true, + NULL); + } + } +#endif /* WITH_FLUID */ +} + +void GPU_create_smoke_velocity(FluidModifierData *mmd) +{ +#ifndef WITH_FLUID + UNUSED_VARS(mmd); +#else + if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { + FluidDomainSettings *mds = mmd->domain; + + const float *vel_x = manta_get_velocity_x(mds->fluid); + const float *vel_y = manta_get_velocity_y(mds->fluid); + const float *vel_z = manta_get_velocity_z(mds->fluid); + + if (ELEM(NULL, vel_x, vel_y, vel_z)) { + return; + } + + if (!mds->tex_velocity_x) { + mds->tex_velocity_x = GPU_texture_create_3d( + mds->res[0], mds->res[1], mds->res[2], GPU_R16F, vel_x, NULL); + mds->tex_velocity_y = GPU_texture_create_3d( + mds->res[0], mds->res[1], mds->res[2], GPU_R16F, vel_y, NULL); + mds->tex_velocity_z = GPU_texture_create_3d( + mds->res[0], mds->res[1], mds->res[2], GPU_R16F, vel_z, NULL); + } + } +#endif /* WITH_FLUID */ +} + +/* TODO Unify with the other GPU_free_smoke. */ +void GPU_free_smoke_velocity(FluidModifierData *mmd) +{ + if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) { + if (mmd->domain->tex_velocity_x) { + GPU_texture_free(mmd->domain->tex_velocity_x); + } + + if (mmd->domain->tex_velocity_y) { + GPU_texture_free(mmd->domain->tex_velocity_y); + } + + if (mmd->domain->tex_velocity_z) { + GPU_texture_free(mmd->domain->tex_velocity_z); + } + + mmd->domain->tex_velocity_x = NULL; + mmd->domain->tex_velocity_y = NULL; + mmd->domain->tex_velocity_z = NULL; + } +} + +/** \} */ diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c index fb0dffb58d1..5e44a950ba7 100644 --- a/source/blender/gpu/intern/gpu_matrix.c +++ b/source/blender/gpu/intern/gpu_matrix.c @@ -535,6 +535,11 @@ bool GPU_matrix_unproject_precalc(struct GPUMatrixUnproject_Precalc *precalc, &precalc->dims.ymax, &precalc->dims.zmin, &precalc->dims.zmax); + if (isinf(precalc->dims.zmax)) { + /* We cannot retrieve the actual value of the clip_end. + * Use `FLT_MAX` to avoid nans. */ + precalc->dims.zmax = FLT_MAX; + } for (int i = 0; i < 4; i++) { precalc->view[i] = (float)view[i]; } diff --git a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl index b0fa9eaed21..3254a7e1508 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl @@ -90,7 +90,7 @@ void main() stretch = stretch; stretch = 1.0 - stretch * stretch; #else - float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, -totalAreaRatioInv); + float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, totalAreaRatioInv); #endif |