Ver Fonte

*Fixed shader program
*Added operators to vec3
*Commit before changing bloom shader

Panagiotis Christopoulos Charitos há 16 anos atrás
pai
commit
45fec8ff9c

+ 3 - 1
shaders/bs_bp_volfog.glsl

@@ -13,11 +13,13 @@ uniform sampler2D ms_depth_fai;
 
 void main()
 {
-	vec2 tex_coords_ = gl_FragCoord.xy*vec2( 1.0/R_W, 1.0/R_H );
+	vec2 tex_size_ = textureSize(ms_depth_fai, 0);
+	vec2 tex_coords_ = gl_FragCoord.xy/tex_size_;
 	
 	float depth_exp_ = texture2D( ms_depth_fai, tex_coords_ ).r;
 	if( depth_exp_ == 1 ) discard;
 	
 	float depth_ = LinearizeDepth( depth_exp_, 0.1, 10.0 );
 	gl_FragColor = vec4( depth_ );
+	gl_FragColor = vec4( 0.5 );
 }

+ 60 - 2
shaders/final.glsl

@@ -4,6 +4,8 @@
 
 #pragma anki frag_shader_begins
 
+#pragma anki include "shaders/median_filter.glsl"
+
 #pragma anki uniform raster_image 0
 uniform sampler2D raster_image;
 varying vec2 tex_coords;
@@ -12,6 +14,62 @@ void main()
 {
 	//if( gl_FragCoord.x > 0.5 ) discard;
 
-	gl_FragColor.rgb = texture2D( raster_image, tex_coords ).rgb;
-	//gl_FragColor.rgb = gl_FragCoord.xyz;
+	//gl_FragColor.rgb = texture2D( raster_image, tex_coords ).rgb;
+	gl_FragColor.rgb = MedianFilter( raster_image, tex_coords );
+	//gl_FragColor.rgb = vec3( gl_FragCoord.xy/tex_size_, 0.0 );
+	//gl_FragColor.rgb = vec3( gl_FragCoord.xy*vec2( 1.0/R_W, 1.0/R_H ), 0.0 );
 }
+
+/*
+3x3 Median
+Morgan McGuire and Kyle Whitson
+http://graphics.cs.williams.edu
+*
+
+// Input texture
+
+vec2 Tinvsize = vec2( 1/R_W*R_Q, 1/R_H*R_Q );
+
+
+// Change these 2 defines to change precision,
+#define vec vec3
+#define toVec(x) x.rgb
+
+//#define vec vec4
+//#define toVec(x) x.rgba
+
+#define s2(a, b)				temp = a; a = min(a, b); b = max(temp, b);
+#define mn3(a, b, c)			s2(a, b); s2(a, c);
+#define mx3(a, b, c)			s2(b, c); s2(a, c);
+
+#define mnmx3(a, b, c)			mx3(a, b, c); s2(a, b);                                   // 3 exchanges
+#define mnmx4(a, b, c, d)		s2(a, b); s2(c, d); s2(a, c); s2(b, d);                   // 4 exchanges
+#define mnmx5(a, b, c, d, e)	s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e);           // 6 exchanges
+#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges
+
+void main() {
+
+  vec v[9];
+
+  // Add the pixels which make up our window to the pixel array.
+  for(int dX = -1; dX <= 1; ++dX) {
+    for(int dY = -1; dY <= 1; ++dY) {
+      vec2 offset = vec2(float(dX), float(dY));
+
+      // If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the
+      // pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the
+      // bottom right pixel of the window at pixel[N-1].
+      v[(dX + 1) * 3 + (dY + 1)] = texture2D(raster_image, tex_coords + offset * Tinvsize).rgb;
+    }
+  }
+
+  vec temp;
+
+  // Starting with a subset of size 6, remove the min and max each time
+  mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
+  mnmx5(v[1], v[2], v[3], v[4], v[6]);
+  mnmx4(v[2], v[3], v[4], v[7]);
+  mnmx3(v[3], v[4], v[8]);
+  gl_FragColor.rgb = v[4];
+}*/
+

+ 43 - 0
shaders/median_filter.glsl

@@ -0,0 +1,43 @@
+/*
+3x3 Median
+Morgan McGuire and Kyle Whitson
+http://graphics.cs.williams.edu
+*/
+
+#define s2(a, b)				temp = a; a = min(a, b); b = max(temp, b);
+#define mn3(a, b, c)			s2(a, b); s2(a, c);
+#define mx3(a, b, c)			s2(b, c); s2(a, c);
+
+#define mnmx3(a, b, c)			mx3(a, b, c); s2(a, b);                                   // 3 exchanges
+#define mnmx4(a, b, c, d)		s2(a, b); s2(c, d); s2(a, c); s2(b, d);                   // 4 exchanges
+#define mnmx5(a, b, c, d, e)	s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e);           // 6 exchanges
+#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges
+
+vec3 MedianFilter( in sampler2D tex, in vec2 tex_coords )
+{
+	vec2 tex_inv_size = 1.0/textureSize(tex, 0);
+  vec3 v[9];
+
+  // Add the pixels which make up our window to the pixel array.
+	for(int dX = -1; dX <= 1; ++dX) 
+	{
+		for(int dY = -1; dY <= 1; ++dY) 
+		{
+			vec2 offset = vec2(float(dX), float(dY));
+
+			// If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the
+			// pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the
+			// bottom right pixel of the window at pixel[N-1].
+			v[(dX + 1) * 3 + (dY + 1)] = texture2D(tex, tex_coords + offset * tex_inv_size).rgb;
+		}
+	}
+
+  vec3 temp;
+
+  // Starting with a subset of size 6, remove the min and max each time
+  mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]);
+  mnmx5(v[1], v[2], v[3], v[4], v[6]);
+  mnmx4(v[2], v[3], v[4], v[7]);
+  mnmx3(v[3], v[4], v[8]);
+  return v[4];
+}

+ 21 - 38
shaders/ms_mp_generic.glsl

@@ -1,14 +1,3 @@
-#pragma anki vert_shader_begins
-
-/**
- * This a generic shader to fill the deferred shading buffers. You can always build your own if you dont need to write in all the
- * buffers.
- */
-#pragma anki include "shaders/hw_skinning.glsl"
-
-varying vec3 normal;
-
-
 #if defined( _HAS_DIFFUSE_MAP_ ) || defined( _HAS_NORMAL_MAP_ ) || defined( _HAS_SPECULAR_MAP_ )
 	#define NEEDS_TEX_MAPPING 1
 #else
@@ -23,6 +12,16 @@ varying vec3 normal;
 #endif
 
 
+#pragma anki vert_shader_begins
+
+/**
+ * This a generic shader to fill the deferred shading buffers. You can always build your own if you dont need to write in all the
+ * buffers.
+ */
+#pragma anki include "shaders/hw_skinning.glsl"
+
+varying vec3 normal;
+
 varying vec2 tex_coords_v2f;
 uniform vec2 tex_coords;
 
@@ -121,36 +120,20 @@ calculations in two parts
 VARS                                                                                                                                  =
 =======================================================================================================================================
 */
-varying vec3 normal;
-
-#if defined( _HAS_DIFFUSE_MAP_ )
-	uniform sampler2D diffuse_map;
-#endif
-
-#if defined( _HAS_NORMAL_MAP_ )
-	uniform sampler2D normal_map;
-	varying vec3 tangent_v2f;
-	varying float w_v2f;
-#endif
-
-#if defined( _HAS_SPECULAR_MAP_ )
-	uniform sampler2D specular_map;
-#endif
 
-#if defined( _HAS_DIFFUSE_MAP_ ) || defined( _HAS_NORMAL_MAP_ ) || defined( _HAS_SPECULAR_MAP_ ) || defined( _PARALLAX_MAPPING_ )
-	varying vec2 tex_coords_v2f;
-#endif
-
-#if defined( _PARALLAX_MAPPING_ )
-	uniform sampler2D height_map;
-	varying vec3 eye;
-#endif
+uniform sampler2D diffuse_map;
+uniform sampler2D normal_map;
+uniform sampler2D specular_map;
+uniform sampler2D height_map;
+uniform sampler2D environment_map;
 
+varying vec3 normal;
+varying vec3 tangent_v2f;
+varying float w_v2f;
+varying vec2 tex_coords_v2f;
+varying vec3 eye;
+varying vec3 vert_pos_eye_space_v2f;
 
-#if defined( _ENVIRONMENT_MAPPING_ )
-	uniform sampler2D environment_map;
-	varying vec3 vert_pos_eye_space_v2f;
-#endif
 
 
 /*

+ 3 - 4
src/main.cpp

@@ -25,7 +25,6 @@
 #include "skybox.h"
 #include "map.h"
 #include "model.h"
-#include "shader_parser.h"
 
 camera_t main_cam;
 
@@ -172,7 +171,7 @@ void Init()
 	scene::lights.Register( &point_lights[1] );
 	scene::lights.Register( &projlights[0] );
 	scene::lights.Register( &projlights[1] );
-	scene::meshes.Register( &sphere );
+	//scene::meshes.Register( &sphere );
 
 	//map.Load( "maps/temple/temple.map" );
 	//map.CreateOctree();
@@ -276,8 +275,8 @@ int main( int /*argc*/, char* /*argv*/[] )
 		SDL_GL_SwapBuffers();
 		r::PrintLastError();
 		//if( r::frames_num == 10 ) r::TakeScreenshot("gfx/screenshot.tga");
-		hndl::WaitForNextFrame();
-		//if( r::frames_num == 5000 ) break;
+		//hndl::WaitForNextFrame();
+		if( r::frames_num == 5000 ) break;
 	}while( true );
 	PRINT( "Exiting main loop (" << hndl::GetTicks()-ticks << ")" );
 

+ 8 - 1
src/math/vec3.h

@@ -57,7 +57,7 @@ class vec3_t
 		void   Normalize();
 		vec3_t Normalized() const;
 		vec3_t Project( const vec3_t& to_this ) const;
-		vec3_t Rotated( const quat_t& q ) const; // returns q * this * q.Conjucated() aka returns a rotated this. 21 muls, 12 adds
+		vec3_t Rotated( const quat_t& q ) const; // returns q * this * q.Conjucated() aka returns a rotated this. 18 muls, 12 adds
 		void   Rotate( const quat_t& q );
 		vec3_t Lerp( const vec3_t& v1, float t ) const; // return Lerp( this, v1, t )
 		void   Print() const;
@@ -75,6 +75,13 @@ class vec3_t
 };
 
 
+// other operators
+extern vec3_t operator +( float f, const vec3_t& v );
+extern vec3_t operator -( float f, const vec3_t& v );
+extern vec3_t operator *( float f, const vec3_t& v );
+extern vec3_t operator /( float f, const vec3_t& v );
+
+
 } // end namespace
 
 

+ 28 - 2
src/math/vec3.inl.h

@@ -137,6 +137,12 @@ M_INLINE vec3_t vec3_t::operator +( float f ) const
 	return ME + vec3_t(f);
 }
 
+// float + vec3
+M_INLINE vec3_t operator +( float f, const vec3_t& v )
+{
+	return v+f;
+}
+
 // vec3 += float
 M_INLINE vec3_t& vec3_t::operator +=( float f )
 {
@@ -150,6 +156,12 @@ M_INLINE vec3_t vec3_t::operator -( float f ) const
 	return ME - vec3_t(f);
 }
 
+// float - vec3
+M_INLINE vec3_t operator -( float f, const vec3_t& v )
+{
+	return vec3_t(f-v.x, f-v.y, f-v.z);
+}
+
 // vec3 -= float
 M_INLINE vec3_t& vec3_t::operator -=( float f )
 {
@@ -163,6 +175,12 @@ M_INLINE vec3_t vec3_t::operator *( float f ) const
 	return ME * vec3_t(f);
 }
 
+// float * vec3
+M_INLINE vec3_t operator *( float f, const vec3_t& v )
+{
+	return v*f;
+}
+
 // vec3 *= float
 M_INLINE vec3_t& vec3_t::operator *=( float f )
 {
@@ -176,6 +194,12 @@ M_INLINE vec3_t vec3_t::operator /( float f ) const
 	return ME / vec3_t(f);
 }
 
+// float / vec3
+M_INLINE vec3_t operator /( float f, const vec3_t& v )
+{
+	return vec3_t(f/v.x, f/v.y, f/v.z);
+}
+
 // vec3 /= float
 M_INLINE vec3_t& vec3_t::operator /=( float f )
 {
@@ -236,13 +260,15 @@ M_INLINE vec3_t vec3_t::Rotated( const quat_t& q ) const
 {
 	DEBUG_ERR( !IsZero(1.0f-q.Length()) ); // Not normalized quat
 
-	float vmult = 2.0f*(q.x*x + q.y*y + q.z*z);
+	/*float vmult = 2.0f*(q.x*x + q.y*y + q.z*z);
 	float crossmult = 2.0*q.w;
 	float pmult = crossmult*q.w - 1.0;
 
 	return vec3_t( pmult*x + vmult*q.x + crossmult*(q.y*z - q.z*y),
 							   pmult*y + vmult*q.y + crossmult*(q.z*x - q.x*z),
-	               pmult*z + vmult*q.z + crossmult*(q.x*y - q.y*x) );
+	               pmult*z + vmult*q.z + crossmult*(q.x*y - q.y*x) );*/
+	vec3_t q_xyz( q );
+	return ME + q_xyz.Cross( q_xyz.Cross(ME) + ME*q.w ) * 2.0;
 }
 
 // Rotate

+ 3 - 6
src/renderer/renderer.cpp

@@ -35,7 +35,7 @@ float quad_vert_cords [][2] = { {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0} };
  * Standard shader preprocessor defines. Used to pass some global params to the shaders. The standard shader preprocessor defines
  * go on top of the shader code and its defines
  */
-char* std_shader_preproc_defines = NULL;
+string std_shader_preproc_defines;
 
 // texture
 bool mipmaping = true;
@@ -52,9 +52,9 @@ I pass all the static vars (vars that do not change at all) with defines so I do
 */
 static void BuildStdShaderPreProcStr()
 {
-	string tmp = "";
+	string& tmp = std_shader_preproc_defines;
 
-	tmp += "#version 120\n";
+	tmp  = "#version 120\n";
 	tmp += "#pragma optimize(on)\n";
 	tmp += "#pragma debug(off)\n";
 	tmp += "#define R_W " + FloatToStr(r::w) + "\n";
@@ -80,9 +80,6 @@ static void BuildStdShaderPreProcStr()
 		tmp += "#define _LSCATT_\n";
 		tmp += "#define LSCATT_RENDERING_QUALITY " + FloatToStr(r::pps::lscatt::rendering_quality) + "\n";
 	}
-
-	std_shader_preproc_defines = new char [tmp.length()+1];
-	strcpy( std_shader_preproc_defines, tmp.c_str() );
 }
 
 

+ 1 - 1
src/renderer/renderer.h

@@ -36,7 +36,7 @@ extern void TakeScreenshot( const char* filename ); ///< Save the colorbuffer as
 extern void Init(); ///< Inits the renderer subsystem. Setting OpenGL and executes "r::*::Init" functions among other things
 extern void PrepareNextFrame(); ///< Runs before rendering
 extern void PrintLastError(); ///< Prints last OpenGL error
-inline const char* GetStdShaderPreprocDefines() { extern char* std_shader_preproc_defines; return std_shader_preproc_defines; }
+inline const string& GetStdShaderPreprocDefines() { extern string std_shader_preproc_defines; return std_shader_preproc_defines; }
 extern void Render( const camera_t& cam ); ///< The spine funciton of the renderer
 
 extern void SetGLState_Wireframe();

+ 184 - 42
src/uncategorized/gstring.h

@@ -4,18 +4,16 @@
 #include <iostream>
 #include <cstdlib>
 #include <string.h>
+#include <climits>
+#include <cmath>
+#include "common.h"
 
 using namespace std;
 
-
+/// class string_t
 class string_t
 {
 	private:
-		char* data;
-		bool const_data;
-		uint length;
-		
-	public:
 		// friends
 		friend ostream& operator <<( ostream& output, const string_t& str );
 		friend string_t operator +( const string_t& a, const string_t& b );
@@ -23,7 +21,29 @@ class string_t
 		friend string_t operator +( char a, const string_t& b );
 		friend string_t operator +( const string_t& a, const char* b );
 		friend string_t operator +( const string_t& a, char b );
-
+		friend bool operator ==( const string_t& a, const string_t& b );
+		friend bool operator ==( const string_t& a, const char* b );
+		friend bool operator ==( const char* a, const string_t& b );
+		
+		// data
+		char* data;
+		bool const_data; ///< false means that we have allocated memory
+		uint length;
+		
+		// private stuff
+		void Init( float d )
+		{
+			char pc [256];
+			sprintf( pc, "%f", d );
+			length = strlen( pc );
+			const_data = false;
+			data = (char*) malloc( (length+1)*sizeof(char) );
+			memcpy( data, pc, length+1 );
+		}
+		
+	public:
+		static const uint npos = UINT_MAX;  // ToDo: change it when C++0x becomes standard
+		
 		// constructor []
 		string_t(): data(NULL), const_data(true), length(0) {}
 				
@@ -33,7 +53,6 @@ class string_t
 			data = const_cast<char*>(pchar);
 			const_data = true;
 			length = strlen(pchar);
-			DEBUG_ERR( Length()<1 );
 		}		
 		
 		// constructor [char*]
@@ -41,33 +60,34 @@ class string_t
 		{
 			length = strlen( pchar );
 			const_data = false;
-			DEBUG_ERR( Length()<1 );
-			data = (char*) malloc( (Length()+1)*sizeof(char) );
-			memcpy( data, pchar, Length()+1 );
+			data = (char*) malloc( (length+1)*sizeof(char) );
+			memcpy( data, pchar, length+1 );
 		}		
 		
 		// constructor [string_t]
 		string_t( const string_t& b )
 		{
 			const_data = b.const_data;
-			length = b.Length();
+			length = b.length;
 			if( b.const_data )
 				data = b.data;
 			else
 			{
-				data = (char*) malloc( (Length()+1)*sizeof(char) );
-				memcpy( data, b.data, Length()+1 );
+				data = (char*) malloc( (length+1)*sizeof(char) );
+				memcpy( data, b.data, length+1 );
 			}
 		}	
 		
 		// constructor [char]
-		string_t( char char_ )
+		string_t( char c )
 		{
-			DEBUG_ERR( char_ == '\0' );
+			DEBUG_ERR( c == '\0' );
+			length = 1;
 			data = (char*) malloc( 2*sizeof(char) );
-			data[0] = char_;
+			const_data = false;
+			data[0] = c;
 			data[1] = '\0';
-		}	
+		}
 		
 		// destructor
 		virtual ~string_t()
@@ -80,13 +100,17 @@ class string_t
 		const char& operator []( uint i ) const { DEBUG_ERR(i>=length); return data[i]; }
 		char& operator []( uint i ) { DEBUG_ERR(i>=length); return data[i]; }
 		
+		
+		//================================================================================================================================
+		// operator =                                                                                                                    =
+		//================================================================================================================================
+		
 		// = [string_t]
 		string_t& operator =( const string_t& b )
 		{
-			if( data!=NULL && !const_data )
-				free( data );
+			if( !const_data ) free( data );
 			const_data = b.const_data;
-			length = b.Length();
+			length = b.length;
 			if( b.const_data )
 				data = b.data;
 			else
@@ -100,40 +124,40 @@ class string_t
 		// = [char*]
 		string_t& operator =( char* pchar )
 		{
-			if( data!=NULL && !const_data )
-				free( data );
+			if( !const_data ) free( data );
 			length = strlen( pchar );
 			const_data = false;
-			DEBUG_ERR( Length()<1 );
-			data = (char*) malloc( (Length()+1)*sizeof(char) );
-			memcpy( data, pchar, Length()+1 );
+			data = (char*) malloc( (length+1)*sizeof(char) );
+			memcpy( data, pchar, length+1 );
 			return (*this);
 		}
 		
 		// = [const char*]
 		string_t& operator =( const char* pchar )
 		{
-			if( data!=NULL && !const_data )
-				free( data );
+			if( !const_data ) free( data );
 			data = const_cast<char*>(pchar);
 			const_data = true;
 			length = strlen(pchar);
-			DEBUG_ERR( Length()<1 );
 			return (*this);
 		}
 		
 		// = [char]
-		string_t& operator =( char char_ )
+		string_t& operator =( char c )
 		{
-			if( data!=NULL && !const_data )
-				free( data );
-			DEBUG_ERR( char_ == '\0' );
+			if( !const_data ) free( data );
+			DEBUG_ERR( c == '\0' );
 			data = (char*) malloc( 2*sizeof(char) );
-			data[0] = char_;
+			data[0] = c;
 			data[1] = '\0';
 			return (*this);
 		}
 		
+		
+		//================================================================================================================================
+		// operator +=                                                                                                                   =
+		//================================================================================================================================
+		
 		// += [string_t]
 		string_t& operator +=( const string_t& str )
 		{
@@ -193,10 +217,72 @@ class string_t
 			return (*this);
 		}
 		
+		
+		//================================================================================================================================
+		// misc                                                                                                                          =
+		//================================================================================================================================
+		
+		// Convert
+		static string_t Convert( int i )
+		{
+			string_t out;
+			if( i == 0 )
+			{
+				out.data = "0";
+				out.const_data = true;
+				out.length = 1;
+			}
+			else
+			{
+				char cv [256];
+				const size_t cv_size = sizeof(cv)/sizeof(char); 
+				char* pc = &cv[ cv_size ];
+				int ii = (i<0) ? -i : i;
+				while( ii != 0 )
+				{
+					int mod = ii%10;
+					ii /= 10;
+					--pc;
+					*pc = ('0' + mod);
+				}
+				if( i < 0 )
+				{
+					--pc;
+					*pc = '-';
+				}
+				out.length = cv + cv_size - pc;
+				DEBUG_ERR( out.length >= sizeof(cv)/sizeof(char) );
+				out.const_data = false;
+				out.data = (char*) malloc( (out.length+1)*sizeof(char) );
+				memcpy( out.data, pc, out.length );
+				out.data[out.length] = '\0';
+			}
+			return out;
+		}
+		
+		// Convert [float]
+		static string_t Convert( float f )
+		{
+			string_t out;
+			char pc [256];
+			sprintf( pc, "%f", f );
+			out.length = strlen( pc );
+			out.const_data = false;
+			out.data = (char*) malloc( (out.length+1)*sizeof(char) );
+			memcpy( out.data, pc, out.length+1 );
+			return out;
+		}
+		
+		// Convert [double]
+		static string_t Convert( double d )
+		{
+			return Convert( (float)d );
+		}
+		
 		// Clear
 		void Clear()
 		{
-			DEBUG_ERR( (data==NULL && length!=0) || (data!=NULL && length==0) );
+			DEBUG_ERR( (data==NULL && length!=0) || (data!=NULL && length==0) ); // not my bug
 			if( data != NULL )
 			{
 				if( !const_data )
@@ -210,7 +296,7 @@ class string_t
 		// CStr
 		const char* CStr() const
 		{
-			DEBUG_ERR( data == NULL );
+			DEBUG_ERR( data == NULL ); // not my bug
 			return data;
 		}
 		
@@ -221,7 +307,7 @@ class string_t
 			return length;
 		}
 		
-		// Find
+		// Find [char]
 		uint Find( char c, uint pos = 0 ) const
 		{
 			DEBUG_ERR( pos >= length ); // not my bug
@@ -230,11 +316,45 @@ class string_t
 			{
 				++pc;
 			}
-			return pc - data;
+			uint diff = pc - data; 
+			return (diff == length) ? npos : diff;
+		}
+		
+		// RFind [char]
+		uint RFind( char c, uint pos = npos ) const
+		{
+			DEBUG_ERR( pos >= length && pos!=npos ); // not my bug
+			if( pos==npos ) pos = length-1;
+			char* pc = data + pos;
+			while( pc!=data-1 && *pc!=c )
+			{
+				--pc;
+			}
+			return (pc == data-1) ? npos : pc - data;
+		}
+		
+		// Find [string_t]
+		uint Find( const string_t& str, uint pos = 0 ) const
+		{
+			DEBUG_ERR( pos >= length ); // not my bug
+			char* pc = strstr( data+pos, str.data );
+			return (pc == NULL) ? npos : pc-data;
+		}
+		
+		// Find [char*]
+		uint Find( const char* pc, uint pos = 0 ) const
+		{
+			DEBUG_ERR( pos >= length ); // not my bug
+			char* pc_ = strstr( data+pos, pc );
+			return (pc_ == NULL) ? npos : pc_-data;
 		}
 };
 
 
+//================================================================================================================================
+// operator +                                                                                                                    =
+//================================================================================================================================
+
 /// string_t + string_t
 inline string_t operator +( const string_t& a, const string_t& b )
 {
@@ -247,7 +367,6 @@ inline string_t operator +( const string_t& a, const string_t& b )
 	return out;
 }
 
-
 /// char* + string_t
 inline string_t operator +( const char* a, const string_t& b )
 {
@@ -265,7 +384,6 @@ inline string_t operator +( const char* a, const string_t& b )
 	return out;
 }
 
-
 /// char + string_t
 inline string_t operator +( char a, const string_t& b )
 {
@@ -278,7 +396,6 @@ inline string_t operator +( char a, const string_t& b )
 	return out;
 }
 
-
 /// string_t + char*
 inline string_t operator +( const string_t& a, const char* b )
 {
@@ -293,7 +410,6 @@ inline string_t operator +( const string_t& a, const char* b )
 	return out;
 }
 
-
 /// string_t + char
 inline string_t operator +( const string_t& a, char b )
 {
@@ -309,6 +425,32 @@ inline string_t operator +( const string_t& a, char b )
 }
 
 
+//================================================================================================================================
+// operator ==                                                                                                                   =
+//================================================================================================================================
+
+/// string_t == string_t
+inline bool operator ==( const string_t& a, const string_t& b )
+{
+	return strcmp( a.data, b.data ) == 0;
+}
+
+/// string_t == char*
+inline bool operator ==( const string_t& a, const char* b )
+{
+	return strcmp( a.data, b ) == 0;
+}
+
+/// char* == string_t
+inline bool operator ==( const char* a, const string_t& b )
+{
+	return strcmp( a, b.data ) == 0;
+}
+
+
+//================================================================================================================================
+// misc                                                                                                                          =
+//================================================================================================================================
 /// For cout support
 inline ostream& operator <<( ostream& output, const string_t& str ) 
 {

+ 8 - 5
src/uncategorized/shader_prog.cpp

@@ -8,6 +8,7 @@
 #define SHADER_WARNING( x ) WARNING( "Shader prog \"" << GetName() << "\": " << x )
 
 
+
 //=====================================================================================================================================
 // CreateAndCompileShader                                                                                                             =
 //=====================================================================================================================================
@@ -21,7 +22,7 @@ uint shader_prog_t::CreateAndCompileShader( const char* source_code, int type )
 
 	// attach the source
 	source_strs[1] = source_code;
-	source_strs[0] = r::GetStdShaderPreprocDefines();
+	source_strs[0] = r::GetStdShaderPreprocDefines().c_str();
 
 	// compile
 	glShaderSource( gl_id, 2, source_strs, NULL );
@@ -114,13 +115,14 @@ void shader_prog_t::GetUniAndAttribLocs()
 		name_[ length ] = '\0';
 
 		// check if its FFP location
-		if( glGetAttribLocation(gl_id, name_) == -1 )
+		int loc = glGetAttribLocation(gl_id, name_);
+		if( loc == -1 )
 		{
 			//SHADER_WARNING( "You are using FFP vertex attributes (\"" << name_ << "\")" );
 			continue;
 		}
 
-		attrib_name_to_loc[ name_ ] = i;
+		attrib_name_to_loc[ name_ ] = loc;
 	}
 
 
@@ -132,13 +134,14 @@ void shader_prog_t::GetUniAndAttribLocs()
 		name_[ length ] = '\0';
 
 		// check if its FFP location
-		if( glGetUniformLocation(gl_id, name_) == -1 )
+		int loc = glGetUniformLocation(gl_id, name_);
+		if( loc == -1 )
 		{
 			//SHADER_WARNING( "You are using FFP vertex attributes (\"" << name_ << "\")" );
 			continue;
 		}
 
-		uni_name_to_loc[ name_ ] = i;
+		uni_name_to_loc[ name_ ] = loc;
 	}
 }
 

+ 1 - 0
src/uncategorized/shader_prog.h

@@ -36,6 +36,7 @@ class shader_prog_t: public resource_t
 		static uint GetCurrentProgram() { int i; glGetIntegerv( GL_CURRENT_PROGRAM, &i ); return i; }
 
 		bool Load( const char* filename );
+		bool CustomLoad( const char*  );
 		void Unload() { /* ToDo: add code */ }
 
 		int GetUniformLocation( const char* name ) const; ///< Returns -1 if fail and throws error