Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt7
-rw-r--r--source/blender/gpu/GPU_buffers.h2
-rw-r--r--source/blender/gpu/GPU_draw.h14
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c22
-rw-r--r--source/blender/gpu/intern/gpu_draw.c388
-rw-r--r--source/blender/gpu/intern/gpu_draw_smoke.c416
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c5
-rw-r--r--source/blender/gpu/shaders/gpu_shader_2D_edituvs_stretch_vert.glsl2
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