[Bf-blender-cvs] [8665323] master: Fix T31546 fragment program gets created every frame

Antony Riakiotakis noreply at git.blender.org
Thu Apr 9 20:21:02 CEST 2015


Commit: 866532360c75298c88dc51724e878255295b98df
Author: Antony Riakiotakis
Date:   Thu Apr 9 20:20:33 2015 +0200
Branches: master
https://developer.blender.org/rB866532360c75298c88dc51724e878255295b98df

Fix T31546 fragment program gets created every frame

That was really crappy indeed. Now we have a separate API
for low level OpenGL programs, plus a nice interface for GPU, also
removes some GL calls from main code as a plus :)

The source for the programs is also moved to nice external .glsl files
(not sure which extension convention GPU assemply uses)

===================================================================

M	SConstruct
M	source/blender/editors/space_view3d/drawvolume.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_extensions.h
M	source/blender/gpu/SConscript
M	source/blender/gpu/intern/gpu_extensions.c
A	source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl
A	source/blender/gpu/shaders/gpu_program_smoke_frag.glsl

===================================================================

diff --git a/SConstruct b/SConstruct
index 7cdc4b3..6cf3874 100644
--- a/SConstruct
+++ b/SConstruct
@@ -758,6 +758,9 @@ if B.targets != ['cudakernels']:
     data_to_c_simple("release/datafiles/preview_cycles.blend")
 
     # --- glsl ---
+    data_to_c_simple("source/blender/gpu/shaders/gpu_program_smoke_frag.glsl")
+    data_to_c_simple("source/blender/gpu/shaders/gpu_program_smoke_color_frag.glsl")
+
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_simple_frag.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_simple_vert.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 92883f2..c0d8d13 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -135,76 +135,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 	unsigned char *spec_data;
 	float *spec_pixels;
 	GPUTexture *tex_spec;
-
-	/* Fragment program to calculate the view3d of smoke */
-	/* using 4 textures, density, shadow, flame and flame spectrum */
-	const char *shader_basic =
-	        "!!ARBfp1.0\n"
-	        "PARAM dx = program.local[0];\n"
-	        "PARAM darkness = program.local[1];\n"
-	        "PARAM render = program.local[2];\n"
-	        "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n"
-	        "TEMP temp, shadow, flame, spec, value;\n"
-	        "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
-	        "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
-	        "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
-	        "TEX spec, flame.r, texture[3], 1D;\n"
-	        /* calculate shading factor from density */
-	        "MUL value.r, temp.a, darkness.a;\n"
-	        "MUL value.r, value.r, dx.r;\n"
-	        "MUL value.r, value.r, f.r;\n"
-	        "EX2 temp, -value.r;\n"
-	        /* alpha */
-	        "SUB temp.a, 1.0, temp.r;\n"
-	        /* shade colors */
-	        "MUL temp.r, temp.r, shadow.r;\n"
-	        "MUL temp.g, temp.g, shadow.r;\n"
-	        "MUL temp.b, temp.b, shadow.r;\n"
-	        "MUL temp.r, temp.r, darkness.r;\n"
-	        "MUL temp.g, temp.g, darkness.g;\n"
-	        "MUL temp.b, temp.b, darkness.b;\n"
-	        /* for now this just replace smoke shading if rendering fire */
-	        "CMP result.color, render.r, temp, spec;\n"
-	        "END\n";
-
-	/* color shader */
-	const char *shader_color =
-	        "!!ARBfp1.0\n"
-	        "PARAM dx = program.local[0];\n"
-	        "PARAM darkness = program.local[1];\n"
-	        "PARAM render = program.local[2];\n"
-	        "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n"
-	        "TEMP temp, shadow, flame, spec, value;\n"
-	        "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
-	        "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
-	        "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
-	        "TEX spec, flame.r, texture[3], 1D;\n"
-	        /* unpremultiply volume texture */
-	        "RCP value.r, temp.a;\n"
-	        "MUL temp.r, temp.r, value.r;\n"
-	        "MUL temp.g, temp.g, value.r;\n"
-	        "MUL temp.b, temp.b, value.r;\n"
-	        /* calculate shading factor from density */
-	        "MUL value.r, temp.a, darkness.a;\n"
-	        "MUL value.r, value.r, dx.r;\n"
-	        "MUL value.r, value.r, f.r;\n"
-	        "EX2 value.r, -value.r;\n"
-	        /* alpha */
-	        "SUB temp.a, 1.0, value.r;\n"
-	        /* shade colors */
-	        "MUL temp.r, temp.r, shadow.r;\n"
-	        "MUL temp.g, temp.g, shadow.r;\n"
-	        "MUL temp.b, temp.b, shadow.r;\n"
-	        "MUL temp.r, temp.r, value.r;\n"
-	        "MUL temp.g, temp.g, value.r;\n"
-	        "MUL temp.b, temp.b, value.r;\n"
-	        /* for now this just replace smoke shading if rendering fire */
-	        "CMP result.color, render.r, temp, spec;\n"
-	        "END\n";
-
-	GLuint prog;
-
-	
+	GPUProgram *smoke_program;
+	int progtype = (sds->active_fields & SM_ACTIVE_COLORS) ? GPU_PROGRAM_SMOKE_COLORED : GPU_PROGRAM_SMOKE;
 	float size[3];
 
 	if (!tex) {
@@ -349,24 +281,17 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 	// printf("i: %d\n", i);
 	// printf("point %f, %f, %f\n", cv[i][0], cv[i][1], cv[i][2]);
 
-	if (GL_TRUE == glewIsSupported("GL_ARB_fragment_program")) {
-		glEnable(GL_FRAGMENT_PROGRAM_ARB);
-		glGenProgramsARB(1, &prog);
-
-		glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog);
-		/* set shader */
-		if (sds->active_fields & SM_ACTIVE_COLORS)
-			glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color);
-		else
-			glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic);
+	smoke_program = GPU_shader_get_builtin_program(progtype);
+	if (smoke_program) {
+		GPU_program_bind(smoke_program);
 
 		/* cell spacing */
-		glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0);
+		GPU_program_parameter_4f(smoke_program, 0, dx, dx, dx, 1.0);
 		/* custom parameter for smoke style (higher = thicker) */
 		if (sds->active_fields & SM_ACTIVE_COLORS)
-			glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0);
+			GPU_program_parameter_4f(smoke_program, 1, 1.0, 1.0, 1.0, 10.0);
 		else
-			glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0);
+			GPU_program_parameter_4f(smoke_program, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0);
 	}
 	else
 		printf("Your gfx card does not support 3D View smoke drawing.\n");
@@ -446,7 +371,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 				else
 					glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
-				glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0);
+				GPU_program_parameter_4f(smoke_program, 2, 1.0, 0.0, 0.0, 0.0);
 				glBegin(GL_POLYGON);
 				glColor3f(1.0, 1.0, 1.0);
 				for (i = 0; i < numpoints; i++) {
@@ -466,7 +391,7 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 			else
 				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-			glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0);
+			GPU_program_parameter_4f(smoke_program, 2, -1.0, 0.0, 0.0, 0.0);
 			glBegin(GL_POLYGON);
 			glColor3f(1.0, 1.0, 1.0);
 			for (i = 0; i < numpoints; i++) {
@@ -499,10 +424,8 @@ void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
 	free(spec_data);
 	free(spec_pixels);
 
-	if (GLEW_ARB_fragment_program) {
-		glDisable(GL_FRAGMENT_PROGRAM_ARB);
-		glDeleteProgramsARB(1, &prog);
-	}
+	if (smoke_program)
+		GPU_program_unbind(smoke_program);
 
 
 	MEM_freeN(points);
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 97b0e7e..23a2b77 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -57,6 +57,9 @@ set(SRC
 	intern/gpu_compositing.c
 	intern/gpu_debug.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
@@ -89,6 +92,8 @@ set(SRC
 	intern/gpu_private.h
 )
 
+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_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_extensions.h b/source/blender/gpu/GPU_extensions.h
index de0af81..27a4396 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -52,6 +52,9 @@ typedef struct GPUOffScreen GPUOffScreen;
 struct GPUShader;
 typedef struct GPUShader GPUShader;
 
+struct GPUProgram;
+typedef struct GPUProgram GPUProgram;
+
 /* GPU extensions support */
 
 void GPU_extensions_disable(void);
@@ -181,6 +184,18 @@ void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
 int GPU_offscreen_width(const GPUOffScreen *ofs);
 int GPU_offscreen_height(const GPUOffScreen *ofs);
 
+/* Builtin/Non-generated shaders */
+typedef enum GPUProgramType {
+	GPU_PROGRAM_TYPE_FRAGMENT = 0
+} GPUProgramType;
+
+
+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! */
@@ -205,11 +220,17 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name);
 
 /* Builtin/Non-generated shaders */
 typedef enum GPUBuiltinShader {
-	GPU_SHADER_VSM_STORE =         (1<<0),
-	GPU_SHADER_SEP_GAUSSIAN_BLUR = (1<<1),
+	GPU_SHADER_VSM_STORE         = 0,
+	GPU_SHADER_SEP_GAUSSIAN_BLUR = 1,
 } 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/SConscript b/source/blender/gpu/SConscript
index 8d0ef39..ff5fb42 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -63,6 +63,8 @@ if env['WITH_BF_DDS']:
 # generated data files
 import os
 sources.extend((
+    os.path.join(env['DATA_SOURCES'], "gpu_program_smoke_frag.glsl.c"),
+    os.path.join(env['DATA_SOURCES'], "gpu_program_smoke_color_frag.glsl.c"),
     os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_frag.glsl.c"),
     os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_vert.glsl.c"),
     os.path.join(env['DATA_SOURCES'], "gpu_shader_fx_ssao_frag.glsl.c"),
d

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list