[Quake2world-dev] r104 - quake2world/trunk/src

jdolan at jdolan.dyndns.org jdolan at jdolan.dyndns.org
Tue Jan 13 05:12:47 UTC 2009


Author: jdolan
Date: 2009-01-13 05:12:47 +0000 (Tue, 13 Jan 2009)
New Revision: 104

Modified:
   quake2world/trunk/src/r_main.c
   quake2world/trunk/src/r_program.c
   quake2world/trunk/src/shared.h
Log:
Add cvar_t aware conditional preprocessor to GLSL programs.  This allows #if r_lights ... #endif to preclude the expensive for-loop in the lighting shader.  Use r_restart to refresh the shaders.

Modified: quake2world/trunk/src/r_main.c
===================================================================
--- quake2world/trunk/src/r_main.c	2009-01-11 20:20:10 UTC (rev 103)
+++ quake2world/trunk/src/r_main.c	2009-01-13 05:12:47 UTC (rev 104)
@@ -527,13 +527,20 @@
 	else {
 		R_SetMode();
 
+		// re-upload the shaders if certain cvars have changed
+		if(Cvar_PendingVars(CVAR_PROGRAMS)){
+			R_ShutdownPrograms();
+
+			R_InitPrograms();
+		}
+
 		// we also let people call r_restart when they mean r_reload
 		if(Cvar_PendingVars(CVAR_IMAGES))
 			R_Reload_f();
 	}
 #endif
 
-	Cvar_ClearVars(CVAR_IMAGES | CVAR_CONTEXT);
+	Cvar_ClearVars(CVAR_IMAGES | CVAR_CONTEXT | CVAR_PROGRAMS);
 
 	r_rendermode->modified = true;
 
@@ -573,7 +580,7 @@
 	r_invert = Cvar_Get("r_invert", "0", CVAR_ARCHIVE | CVAR_IMAGES, NULL);
 	r_lightmapsize = Cvar_Get("r_lightmapsize", "1024", CVAR_ARCHIVE | CVAR_IMAGES, NULL);
 	r_lighting = Cvar_Get("r_lighting", "1", CVAR_ARCHIVE, "Activate or deactivate lighting effects");
-	r_lights = Cvar_Get("r_lights", "1", CVAR_ARCHIVE, NULL);
+	r_lights = Cvar_Get("r_lights", "1", CVAR_ARCHIVE | CVAR_PROGRAMS, NULL);
 	r_lines = Cvar_Get("r_lines", "0.5", CVAR_ARCHIVE, NULL);
 	r_linewidth = Cvar_Get("r_linewidth", "1.0", CVAR_ARCHIVE, NULL);
 	r_materials = Cvar_Get("r_materials", "1", CVAR_ARCHIVE, NULL);
@@ -596,7 +603,7 @@
 	r_width = Cvar_Get("r_width", "1024", CVAR_ARCHIVE, NULL);
 
 	// prevent unecessary reloading for initial values
-	Cvar_ClearVars(CVAR_IMAGES | CVAR_CONTEXT);
+	Cvar_ClearVars(CVAR_IMAGES | CVAR_CONTEXT | CVAR_PROGRAMS);
 
 	Cmd_AddCommand("r_listmodels", R_ListModels_f, "Print information about all the loaded models to the game console");
 	Cmd_AddCommand("r_hunkstats", R_HunkStats_f, "Renderer memory usage information");

Modified: quake2world/trunk/src/r_program.c
===================================================================
--- quake2world/trunk/src/r_program.c	2009-01-11 20:20:10 UTC (rev 103)
+++ quake2world/trunk/src/r_program.c	2009-01-13 05:12:47 UTC (rev 104)
@@ -225,37 +225,76 @@
 
 
 /*
- * R_ShaderIncludes
+ * R_PreprocessShader
  */
-static size_t R_ShaderIncludes(const char *name, const char *in, char *out, size_t len){
+static size_t R_PreprocessShader(const char *name, const char *in, char *out, size_t len){
+	size_t plen;
 	char path[MAX_QPATH];
 	void *buf;
+	float f;
 	int i;
 
 	i = 0;
 	while(*in){
 
-		if(!strncmp(in, "#include", 8)){
-			size_t inc_len;
+		if(!strncmp(in, "#include", 8)){  // includes
 			in += 8;
+
 			snprintf(path, sizeof(path), "shaders/%s", Com_Parse(&in));
 
 			if(Fs_LoadFile(path, &buf) == -1){
-				Com_Warn("Failed to resolve #include: %s.\n", path);
-				continue;
+				Com_Error(ERR_DROP, "R_PreprocessShader: "
+						"Failed to resolve #include: %s.\n", path);
 			}
 
-			inc_len = R_ShaderIncludes(name, (const char *)buf, out, len);
-			len -= inc_len;
-			out += inc_len;
+			plen = R_PreprocessShader(name, (const char *)buf, out, len);
+			len -= plen;
+			out += plen;
+
 			Fs_FreeFile(buf);
 		}
+
+		if(!strncmp(in, "#if", 3)){  // conditionals
+			in += 3;
+
+			f = Cvar_VariableValue(Com_Parse(&in));
+
+			while(*in){
+
+				if(!strncmp(in, "#endif", 6)){
+					in += 6;
+					break;
+				}
+
+				len--;
+				if(len < 0){
+					Com_Error(ERR_DROP, "R_PreprocessShader: "
+							"Overflow: %s", name);
+				}
+
+				if(f){
+					*out++ = *in++;
+					i++;
+				}
+				else
+					in++;
+			}
+
+			if(!*in){
+				Com_Error(ERR_DROP, "R_PreprocessShader: "
+						"Unterminated conditional: %s", name);
+			}
+		}
+
+		// general case is to copy so long as the buffer has room
 		len--;
 		if(len < 0)
-			Sys_Error("overflow in shader loading '%s'", name);
+			Com_Error(ERR_DROP, "R_PreprocessShader: Overflow: %s", name);
+
 		*out++ = *in++;
 		i++;
 	}
+
 	return i;
 }
 
@@ -281,7 +320,7 @@
 
 	source = Z_Malloc(SHADER_BUF_SIZE);
 
-	R_ShaderIncludes(name, (const char *)buf, source, SHADER_BUF_SIZE);
+	R_PreprocessShader(name, (const char *)buf, source, SHADER_BUF_SIZE);
 	Fs_FreeFile(buf);
 
 	src[0] = source;

Modified: quake2world/trunk/src/shared.h
===================================================================
--- quake2world/trunk/src/shared.h	2009-01-11 20:20:10 UTC (rev 103)
+++ quake2world/trunk/src/shared.h	2009-01-13 05:12:47 UTC (rev 104)
@@ -248,6 +248,7 @@
 #define CVAR_LATCH		16  // save changes until server restart
 #define CVAR_IMAGES		32  // effects image filtering
 #define CVAR_CONTEXT	64  // effects gl context
+#define CVAR_PROGRAMS	128  // effects glsl programs
 
 // nothing outside the Cvar_*() functions should modify these fields!
 typedef struct cvar_s {



More information about the Quake2World-dev mailing list