Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_draw_smoke.c
| Show First 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba) | ||||
| GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_RGBA8, data, NULL); | GPUTexture *tex = GPU_texture_create_1d(TFUNC_WIDTH, GPU_RGBA8, data, NULL); | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| return tex; | return tex; | ||||
| } | } | ||||
| static void swizzle_texture_channel_rrrr(GPUTexture *tex) | static void swizzle_texture_channel_single(GPUTexture *tex) | ||||
| { | { | ||||
| GPU_texture_bind(tex, 0); | GPU_texture_bind(tex, 0); | ||||
| glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED); | GPU_texture_swizzle_channel_auto(tex, 1); | ||||
| 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); | GPU_texture_unbind(tex); | ||||
| } | } | ||||
| static GPUTexture *create_field_texture(FluidDomainSettings *mds) | static GPUTexture *create_field_texture(FluidDomainSettings *mds) | ||||
| { | { | ||||
| float *field = NULL; | float *field = NULL; | ||||
| switch (mds->coba_field) { | switch (mds->coba_field) { | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | case FLUID_DOMAIN_FIELD_FORCE_Z: | ||||
| break; | break; | ||||
| default: | default: | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| GPUTexture *tex = GPU_texture_create_nD( | 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); | mds->res[0], mds->res[1], mds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); | ||||
| swizzle_texture_channel_rrrr(tex); | swizzle_texture_channel_single(tex); | ||||
| return tex; | return tex; | ||||
| } | } | ||||
| static GPUTexture *create_density_texture(FluidDomainSettings *mds, int highres) | static GPUTexture *create_density_texture(FluidDomainSettings *mds, int highres) | ||||
| { | { | ||||
| float *data = NULL, *source; | int *dim = (highres) ? mds->res_noise : mds->res; | ||||
| int cell_count = (highres) ? manta_smoke_turbulence_get_cells(mds->fluid) : mds->total_cells; | |||||
| float *data; | |||||
| if (highres) { | |||||
| data = manta_smoke_turbulence_get_density(mds->fluid); | |||||
| } | |||||
| else { | |||||
| data = manta_smoke_get_density(mds->fluid); | |||||
| } | |||||
| GPUTexture *tex = GPU_texture_create_nD( | |||||
| dim[0], dim[1], dim[2], 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); | |||||
| swizzle_texture_channel_single(tex); | |||||
sebbas: I found the comment above `swizzle_texture_channel_rrrr()` quite helpful to understand what's… | |||||
| return tex; | |||||
| } | |||||
| static GPUTexture *create_color_texture(FluidDomainSettings *mds, int highres) | |||||
| { | |||||
| const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(mds->fluid) : | const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(mds->fluid) : | ||||
| manta_smoke_has_colors(mds->fluid); | manta_smoke_has_colors(mds->fluid); | ||||
| if (!has_color) { | |||||
| return NULL; | |||||
| } | |||||
| int cell_count = (highres) ? manta_smoke_turbulence_get_cells(mds->fluid) : mds->total_cells; | |||||
| int *dim = (highres) ? mds->res_noise : mds->res; | int *dim = (highres) ? mds->res_noise : mds->res; | ||||
| eGPUTextureFormat format = (has_color) ? GPU_RGBA8 : GPU_R8; | float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); | ||||
| if (has_color) { | if (data == NULL) { | ||||
| data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture"); | return NULL; | ||||
| } | } | ||||
| if (highres) { | if (highres) { | ||||
| if (has_color) { | |||||
| manta_smoke_turbulence_get_rgba(mds->fluid, data, 0); | manta_smoke_turbulence_get_rgba(mds->fluid, data, 0); | ||||
| } | } | ||||
| else { | else { | ||||
| source = manta_smoke_turbulence_get_density(mds->fluid); | |||||
| } | |||||
| } | |||||
| else { | |||||
| if (has_color) { | |||||
| manta_smoke_get_rgba(mds->fluid, data, 0); | manta_smoke_get_rgba(mds->fluid, data, 0); | ||||
| } | } | ||||
| else { | |||||
| source = manta_smoke_get_density(mds->fluid); | |||||
| } | |||||
| } | |||||
| GPUTexture *tex = GPU_texture_create_nD(dim[0], | GPUTexture *tex = GPU_texture_create_nD( | ||||
| dim[1], | dim[0], dim[1], dim[2], 3, data, GPU_RGBA8, GPU_DATA_FLOAT, 0, true, NULL); | ||||
| dim[2], | |||||
| 3, | |||||
| (has_color) ? data : source, | |||||
| format, | |||||
| GPU_DATA_FLOAT, | |||||
| 0, | |||||
| true, | |||||
| NULL); | |||||
| if (data) { | |||||
| MEM_freeN(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; | return tex; | ||||
| } | } | ||||
| static GPUTexture *create_flame_texture(FluidDomainSettings *mds, int highres) | static GPUTexture *create_flame_texture(FluidDomainSettings *mds, int highres) | ||||
| { | { | ||||
| float *source = NULL; | float *source = NULL; | ||||
| const bool has_fuel = (highres) ? manta_smoke_turbulence_has_fuel(mds->fluid) : | const bool has_fuel = (highres) ? manta_smoke_turbulence_has_fuel(mds->fluid) : | ||||
| manta_smoke_has_fuel(mds->fluid); | manta_smoke_has_fuel(mds->fluid); | ||||
| int *dim = (highres) ? mds->res_noise : mds->res; | int *dim = (highres) ? mds->res_noise : mds->res; | ||||
| if (!has_fuel) { | if (!has_fuel) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (highres) { | if (highres) { | ||||
| source = manta_smoke_turbulence_get_flame(mds->fluid); | source = manta_smoke_turbulence_get_flame(mds->fluid); | ||||
| } | } | ||||
| else { | else { | ||||
| source = manta_smoke_get_flame(mds->fluid); | source = manta_smoke_get_flame(mds->fluid); | ||||
| } | } | ||||
| GPUTexture *tex = GPU_texture_create_nD( | GPUTexture *tex = GPU_texture_create_nD( | ||||
| dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); | dim[0], dim[1], dim[2], 3, source, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL); | ||||
| swizzle_texture_channel_rrrr(tex); | swizzle_texture_channel_single(tex); | ||||
| return tex; | return tex; | ||||
| } | } | ||||
| #endif /* WITH_FLUID */ | #endif /* WITH_FLUID */ | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Public API | /** \name Public API | ||||
| * \{ */ | * \{ */ | ||||
| void GPU_free_smoke(FluidModifierData *mmd) | void GPU_free_smoke(FluidModifierData *mmd) | ||||
| { | { | ||||
| if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) { | if (mmd->type & MOD_FLUID_TYPE_DOMAIN && mmd->domain) { | ||||
| if (mmd->domain->tex) { | if (mmd->domain->tex_density) { | ||||
| GPU_texture_free(mmd->domain->tex); | GPU_texture_free(mmd->domain->tex_density); | ||||
| mmd->domain->tex_density = NULL; | |||||
| } | |||||
| if (mmd->domain->tex_color) { | |||||
| GPU_texture_free(mmd->domain->tex_color); | |||||
| mmd->domain->tex_color = NULL; | |||||
| } | } | ||||
| mmd->domain->tex = NULL; | |||||
| if (mmd->domain->tex_shadow) { | if (mmd->domain->tex_shadow) { | ||||
| GPU_texture_free(mmd->domain->tex_shadow); | GPU_texture_free(mmd->domain->tex_shadow); | ||||
| } | |||||
| mmd->domain->tex_shadow = NULL; | mmd->domain->tex_shadow = NULL; | ||||
| } | |||||
| if (mmd->domain->tex_flame) { | if (mmd->domain->tex_flame) { | ||||
| GPU_texture_free(mmd->domain->tex_flame); | GPU_texture_free(mmd->domain->tex_flame); | ||||
| } | |||||
| mmd->domain->tex_flame = NULL; | mmd->domain->tex_flame = NULL; | ||||
| } | |||||
| if (mmd->domain->tex_flame_coba) { | if (mmd->domain->tex_flame_coba) { | ||||
| GPU_texture_free(mmd->domain->tex_flame_coba); | GPU_texture_free(mmd->domain->tex_flame_coba); | ||||
| } | |||||
| mmd->domain->tex_flame_coba = NULL; | mmd->domain->tex_flame_coba = NULL; | ||||
| } | |||||
| if (mmd->domain->tex_coba) { | if (mmd->domain->tex_coba) { | ||||
| GPU_texture_free(mmd->domain->tex_coba); | GPU_texture_free(mmd->domain->tex_coba); | ||||
| } | |||||
| mmd->domain->tex_coba = NULL; | mmd->domain->tex_coba = NULL; | ||||
| } | |||||
| if (mmd->domain->tex_field) { | if (mmd->domain->tex_field) { | ||||
| GPU_texture_free(mmd->domain->tex_field); | GPU_texture_free(mmd->domain->tex_field); | ||||
| } | |||||
| mmd->domain->tex_field = NULL; | mmd->domain->tex_field = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| void GPU_create_smoke_coba_field(FluidModifierData *mmd) | void GPU_create_smoke_coba_field(FluidModifierData *mmd) | ||||
| { | { | ||||
| #ifndef WITH_FLUID | #ifndef WITH_FLUID | ||||
| UNUSED_VARS(mmd); | UNUSED_VARS(mmd); | ||||
| #else | #else | ||||
| if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { | if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { | ||||
| FluidDomainSettings *mds = mmd->domain; | FluidDomainSettings *mds = mmd->domain; | ||||
| Show All 11 Lines | |||||
| void GPU_create_smoke(FluidModifierData *mmd, int highres) | void GPU_create_smoke(FluidModifierData *mmd, int highres) | ||||
| { | { | ||||
| #ifndef WITH_FLUID | #ifndef WITH_FLUID | ||||
| UNUSED_VARS(mmd, highres); | UNUSED_VARS(mmd, highres); | ||||
| #else | #else | ||||
| if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { | if (mmd->type & MOD_FLUID_TYPE_DOMAIN) { | ||||
| FluidDomainSettings *mds = mmd->domain; | FluidDomainSettings *mds = mmd->domain; | ||||
| if (!mds->tex) { | if (!mds->tex_density) { | ||||
| mds->tex = create_density_texture(mds, highres); | mds->tex_density = create_density_texture(mds, highres); | ||||
| } | |||||
| if (!mds->tex_color) { | |||||
| mds->tex_color = create_color_texture(mds, highres); | |||||
| } | } | ||||
| if (!mds->tex_flame) { | if (!mds->tex_flame) { | ||||
| mds->tex_flame = create_flame_texture(mds, highres); | mds->tex_flame = create_flame_texture(mds, highres); | ||||
| } | } | ||||
| if (!mds->tex_flame_coba && mds->tex_flame) { | if (!mds->tex_flame_coba && mds->tex_flame) { | ||||
| mds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); | mds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); | ||||
| } | } | ||||
| if (!mds->tex_shadow) { | if (!mds->tex_shadow) { | ||||
| ▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines | |||||
I found the comment above swizzle_texture_channel_rrrr() quite helpful to understand what's going on. Maybe keep it somewhere over here?