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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2016-01-10 09:36:23 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2016-01-10 09:36:23 +0300
commit0372b642705c5304f252f7691b188fc65dd51b59 (patch)
treee7f1d6fb1dff5889a93d7ec0c363a04e0364365a /source/blender/gpu
parentd330162ba6981a6c3691bcc8759215463d47f973 (diff)
OpenGL: port smoke drawing code to GLSL.
Beside the obvious ARB -> GLSL change, the texture slicing algorithm had to be rewritten. Although this new algorithm has the same behaviour as the old one (view aligned slicing), it works with an arbitrary number of slices (which could eventually be set by the user), which means we can preallocate the buffer. The previous algorithm would slice from the begining to the end of the volume's bbox, and draw the slices as it generates them. Also support for ARB program was removed. Patch by myself, with some minor fixes by Brecht. Reviewers: brecht, #opengl_gfx Differential Revision: https://developer.blender.org/D1694
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt9
-rw-r--r--source/blender/gpu/GPU_shader.h21
-rw-r--r--source/blender/gpu/intern/gpu_shader.c122
-rw-r--r--source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl32
-rw-r--r--source/blender/gpu/shaders/gpu_program_smoke_frag.glsl27
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl48
-rw-r--r--source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl12
7 files changed, 86 insertions, 185 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 6d3a5d37d66..3b228c18f5e 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -60,9 +60,6 @@ set(SRC
intern/gpu_shader.c
intern/gpu_texture.c
- shaders/gpu_program_smoke_frag.glsl
- shaders/gpu_program_smoke_color_frag.glsl
-
shaders/gpu_shader_fx_lib.glsl
shaders/gpu_shader_fx_ssao_frag.glsl
shaders/gpu_shader_fx_dof_frag.glsl
@@ -80,6 +77,8 @@ set(SRC
shaders/gpu_shader_vsm_store_frag.glsl
shaders/gpu_shader_vsm_store_vert.glsl
shaders/gpu_shader_fx_depth_resolve.glsl
+ shaders/gpu_shader_smoke_frag.glsl
+ shaders/gpu_shader_smoke_vert.glsl
GPU_basic_shader.h
GPU_buffers.h
@@ -99,8 +98,8 @@ set(SRC
)
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
-data_to_c_simple(shaders/gpu_program_smoke_frag.glsl SRC)
-data_to_c_simple(shaders/gpu_program_smoke_color_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_smoke_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_smoke_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 6464fb7454a..468cc2f0f6e 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -37,21 +37,8 @@ extern "C" {
#endif
typedef struct GPUShader GPUShader;
-typedef struct GPUProgram GPUProgram;
struct GPUTexture;
-/* Builtin/Non-generated shaders */
-typedef enum GPUProgramType {
- GPU_PROGRAM_TYPE_FRAGMENT = 0
-} GPUProgramType;
-
-/* TODO: remove ARB program support (recode smoke shader in GLSL) */
-GPUProgram *GPU_program_shader_create(GPUProgramType type, const char *code);
-void GPU_program_free(GPUProgram *program);
-void GPU_program_parameter_4f(GPUProgram *program, unsigned int location, float x, float y, float z, float w);
-void GPU_program_bind(GPUProgram *);
-void GPU_program_unbind(GPUProgram *);
-
/* GPU Shader
* - only for fragment shaders now
* - must call texture bind before setting a texture as uniform! */
@@ -97,15 +84,11 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name);
typedef enum GPUBuiltinShader {
GPU_SHADER_VSM_STORE = 0,
GPU_SHADER_SEP_GAUSSIAN_BLUR = 1,
+ GPU_SHADER_SMOKE = 2,
+ GPU_SHADER_SMOKE_FIRE = 3,
} GPUBuiltinShader;
-typedef enum GPUBuiltinProgram {
- GPU_PROGRAM_SMOKE = 0,
- GPU_PROGRAM_SMOKE_COLORED = 1,
-} GPUBuiltinProgram;
-
GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader);
-GPUProgram *GPU_shader_get_builtin_program(GPUBuiltinProgram program);
GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp);
void GPU_shader_free_builtin_shaders(void);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index be1cc1c004f..5bef3df928c 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -46,8 +46,8 @@
#define MAX_EXT_DEFINE_LENGTH 1024
/* Non-generated shaders */
-extern char datatoc_gpu_program_smoke_frag_glsl[];
-extern char datatoc_gpu_program_smoke_color_frag_glsl[];
+extern char datatoc_gpu_shader_smoke_vert_glsl[];
+extern char datatoc_gpu_shader_smoke_frag_glsl[];
extern char datatoc_gpu_shader_vsm_store_vert_glsl[];
extern char datatoc_gpu_shader_vsm_store_frag_glsl[];
extern char datatoc_gpu_shader_sep_gaussian_blur_vert_glsl[];
@@ -66,8 +66,8 @@ static struct GPUShadersGlobal {
struct {
GPUShader *vsm_store;
GPUShader *sep_gaussian_blur;
- GPUProgram *smoke;
- GPUProgram *smoke_colored;
+ GPUShader *smoke;
+ GPUShader *smoke_fire;
/* cache for shader fx. Those can exist in combinations so store them here */
GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
} shaders;
@@ -86,11 +86,6 @@ struct GPUShader {
int uniforms; /* required uniforms */
};
-struct GPUProgram {
- GPUProgramType type;
- GLuint prog;
-};
-
static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
{
int i;
@@ -230,70 +225,6 @@ static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH], bool us
return;
}
-void GPU_program_bind(GPUProgram *program)
-{
- glEnable(program->type);
- glBindProgramARB(program->type, program->prog);
-}
-
-void GPU_program_unbind(GPUProgram *program)
-{
- glDisable(program->type);
- glBindProgramARB(program->type, 0);
-}
-
-
-GPUProgram *GPU_program_shader_create(GPUProgramType type, const char *code)
-{
- /* TODO(merwin): remove ARB program support (recode smoke shader in GLSL) */
-
- GPUProgram *program;
- GLint error_pos, is_native;
-
- if (!(GLEW_ARB_fragment_program && type == GPU_PROGRAM_TYPE_FRAGMENT))
- return NULL;
-
- program = MEM_callocN(sizeof(GPUProgram), "GPUProgram");
-
- switch (type) {
- case GPU_PROGRAM_TYPE_FRAGMENT:
- program->type = GL_FRAGMENT_PROGRAM_ARB;
- break;
- }
-
- /* create the object and set its code string */
- glGenProgramsARB(1, &program->prog);
- glBindProgramARB(program->type, program->prog);
-
- glProgramStringARB(program->type, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(code), code);
-
- glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
- glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, &is_native);
- if ((error_pos == -1) && (is_native == 1)) {
- return program;
- }
- else {
- /* glGetError is set before that, clear it */
- while (glGetError() != GL_NO_ERROR)
- ;
- shader_print_errors("compile", (const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB), &code, 1);
- MEM_freeN(program);
- }
-
- return NULL;
-}
-
-void GPU_program_free(GPUProgram *program)
-{
- glDeleteProgramsARB(1, &program->prog);
- MEM_freeN(program);
-}
-
-void GPU_program_parameter_4f(GPUProgram *program, unsigned int location, float x, float y, float z, float w)
-{
- glProgramLocalParameter4fARB(program->type, location, x, y, z, w);
-}
-
GPUShader *GPU_shader_create(const char *vertexcode,
const char *fragcode,
const char *geocode,
@@ -646,37 +577,24 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
NULL, NULL, NULL, 0, 0, 0);
retval = GG.shaders.sep_gaussian_blur;
break;
- }
-
- if (retval == NULL)
- printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
-
- return retval;
-}
-
-GPUProgram *GPU_shader_get_builtin_program(GPUBuiltinProgram program)
-{
- GPUProgram *retval = NULL;
-
- switch (program) {
- case GPU_PROGRAM_SMOKE:
- if (!GG.shaders.smoke) {
- GG.shaders.smoke = GPU_program_shader_create(
- GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_frag_glsl);
- }
+ case GPU_SHADER_SMOKE:
+ if (!GG.shaders.smoke)
+ GG.shaders.smoke = GPU_shader_create(
+ datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
retval = GG.shaders.smoke;
break;
- case GPU_PROGRAM_SMOKE_COLORED:
- if (!GG.shaders.smoke_colored) {
- GG.shaders.smoke_colored = GPU_program_shader_create(
- GPU_PROGRAM_TYPE_FRAGMENT, datatoc_gpu_program_smoke_color_frag_glsl);
- }
- retval = GG.shaders.smoke_colored;
+ case GPU_SHADER_SMOKE_FIRE:
+ if (!GG.shaders.smoke_fire)
+ GG.shaders.smoke_fire = GPU_shader_create(
+ datatoc_gpu_shader_smoke_vert_glsl, datatoc_gpu_shader_smoke_frag_glsl,
+ NULL, NULL, "#define USE_FIRE;\n", 0, 0, 0);
+ retval = GG.shaders.smoke_fire;
break;
}
if (retval == NULL)
- printf("Unable to create a GPUProgram for builtin program: %u\n", program);
+ printf("Unable to create a GPUShader for builtin shader: %u\n", shader);
return retval;
}
@@ -773,13 +691,13 @@ void GPU_shader_free_builtin_shaders(void)
}
if (GG.shaders.smoke) {
- GPU_program_free(GG.shaders.smoke);
+ GPU_shader_free(GG.shaders.smoke);
GG.shaders.smoke = NULL;
}
- if (GG.shaders.smoke_colored) {
- GPU_program_free(GG.shaders.smoke_colored);
- GG.shaders.smoke_colored = NULL;
+ if (GG.shaders.smoke_fire) {
+ GPU_shader_free(GG.shaders.smoke_fire);
+ GG.shaders.smoke_fire = NULL;
}
for (i = 0; i < 2 * MAX_FX_SHADERS; i++) {
diff --git a/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl b/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl
deleted file mode 100644
index a94c823f408..00000000000
--- a/source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-!!ARBfp1.0
-PARAM dx = program.local[0];
-PARAM darkness = program.local[1];
-PARAM render = program.local[2];
-PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};
-TEMP temp, shadow, flame, spec, value;
-TEX temp, fragment.texcoord[0], texture[0], 3D;
-TEX shadow, fragment.texcoord[0], texture[1], 3D;
-TEX flame, fragment.texcoord[0], texture[2], 3D;
-TEX spec, flame.r, texture[3], 1D;
-# unpremultiply volume texture
-RCP value.r, temp.a;
-MUL temp.r, temp.r, value.r;
-MUL temp.g, temp.g, value.r;
-MUL temp.b, temp.b, value.r;
-# calculate shading factor from density
-MUL value.r, temp.a, darkness.a;
-MUL value.r, value.r, dx.r;
-MUL value.r, value.r, f.r;
-EX2 value.r, -value.r;
-# alpha
-SUB temp.a, 1.0, value.r;
-# shade colors
-MUL temp.r, temp.r, shadow.r;
-MUL temp.g, temp.g, shadow.r;
-MUL temp.b, temp.b, shadow.r;
-MUL temp.r, temp.r, value.r;
-MUL temp.g, temp.g, value.r;
-MUL temp.b, temp.b, value.r;
-# for now this just replace smoke shading if rendering fire
-CMP result.color, render.r, temp, spec;
-END
diff --git a/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl
deleted file mode 100644
index 04b171d24bd..00000000000
--- a/source/blender/gpu/shaders/gpu_program_smoke_frag.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-!!ARBfp1.0
-PARAM dx = program.local[0];
-PARAM darkness = program.local[1];
-PARAM render = program.local[2];
-PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};
-TEMP temp, shadow, flame, spec, value;
-TEX temp, fragment.texcoord[0], texture[0], 3D;
-TEX shadow, fragment.texcoord[0], texture[1], 3D;
-TEX flame, fragment.texcoord[0], texture[2], 3D;
-TEX spec, flame.r, texture[3], 1D;
-# calculate shading factor from density
-MUL value.r, temp.a, darkness.a;
-MUL value.r, value.r, dx.r;
-MUL value.r, value.r, f.r;
-EX2 temp, -value.r;
-# alpha
-SUB temp.a, 1.0, temp.r;
-# shade colors
-MUL temp.r, temp.r, shadow.r;
-MUL temp.g, temp.g, shadow.r;
-MUL temp.b, temp.b, shadow.r;
-MUL temp.r, temp.r, darkness.r;
-MUL temp.g, temp.g, darkness.g;
-MUL temp.b, temp.b, darkness.b;
-# for now this just replace smoke shading if rendering fire
-CMP result.color, render.r, temp, spec;
-END
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
new file mode 100644
index 00000000000..c467925725d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_frag.glsl
@@ -0,0 +1,48 @@
+
+varying vec3 coords;
+
+uniform vec4 active_color;
+uniform float cell_spacing;
+
+uniform sampler3D soot_texture;
+uniform sampler3D shadow_texture;
+
+#ifdef USE_FIRE
+uniform sampler3D flame_texture;
+uniform sampler1D spectrum_texture;
+#endif
+
+void main()
+{
+ vec4 soot = texture3D(soot_texture, coords);
+
+ /* unpremultiply volume texture */
+ float value = 1.0f / soot.a;
+ soot.xyz *= vec3(value);
+
+ /* calculate shading factor from soot */
+ value = soot.a * active_color.a;
+ value *= cell_spacing;
+ value *= 1.442695041;
+ soot = vec4(pow(2.0, -value));
+
+ /* alpha */
+ soot.a = 1.0 - soot.r;
+
+ /* shade colors */
+ vec3 shadow = texture3D(shadow_texture, coords).rrr;
+ soot.xyz *= shadow;
+ soot.xyz *= active_color.xyz;
+
+ /* premultiply alpha */
+ vec4 color = vec4(soot.a * soot.rgb, soot.a);
+
+#ifdef USE_FIRE
+ /* blend in fire */
+ float flame = texture3D(flame_texture, coords).r;
+ vec4 spec = texture1D(spectrum_texture, flame);
+ color = vec4(color.rgb + (1 - color.a) * spec.a * spec.rgb, color.a);
+#endif
+
+ gl_FragColor = color;
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
new file mode 100644
index 00000000000..daabf9b97a3
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_smoke_vert.glsl
@@ -0,0 +1,12 @@
+
+varying vec3 coords;
+
+uniform vec3 min;
+uniform vec3 invsize;
+uniform vec3 ob_sizei;
+
+void main()
+{
+ gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz * ob_sizei, 1.0);
+ coords = (gl_Vertex.xyz - min) * invsize;
+}