Example #1
0
        public idImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
        {
            _name = name;
            _type = type;

            _filter        = filter;
            _repeat        = repeat;
            _depth         = depth;
            _cubeFiles     = cubeMap;
            _allowDownSize = allowDownSize;
        }
Example #2
0
        // background loading information.

        /*private idImage _partialImage;			// shrunken, space-saving version
         * private bool _isPartialImage;			// true if this is pointed to by another image*/
        #endregion

        #region Constructor
        public idImage(string name, ImageLoadCallback generator)
        {
            _name      = name;
            _generator = generator;
            _type      = TextureType.Disabled;

            _filter    = TextureFilter.Default;
            _repeat    = TextureRepeat.Repeat;
            _depth     = TextureDepth.Default;
            _cubeFiles = CubeFiles.TwoD;
        }
Example #3
0
		/// <summary>
		/// Finds or loads the given image, always returning a valid image pointer.
		/// Loading of the image may be deferred for dynamic loading.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		/// <param name="cubeMap"></param>
		/// <returns></returns>
		public idImage ImageFromFile(string name, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap)
		{
			if((name == null) || (name == string.Empty)
				|| (name.Equals("default", StringComparison.OrdinalIgnoreCase) == true)
				|| (name.Equals("_default", StringComparison.OrdinalIgnoreCase) == true))
			{
				idE.DeclManager.MediaPrint("DEFAULTED");

				return this.DefaultImage;
			}

			idImage image;

			// strip any .tga file extensions from anywhere in the _name, including image program parameters
			name = name.Replace(".tga", "");

			//
			// see if the image is already loaded, unless we
			// are in a reloadImages call
			//
			if(_imageDictionary.TryGetValue(name, out image) == true)
			{
				// the built in's, like _white and _flat always match the other options
				if(name.StartsWith("_") == true)
				{
					return image;
				}

				if(image.CubeFiles != cubeMap)
				{
					idConsole.Error("Image '{0}' has been referenced with conflicting cube map states", name);
				}

				if((image.Filter != filter) || (image.Repeat != repeat))
				{
					// we might want to have the system reset these parameters on every bind and
					// share the image data	

					// FIXME: this might be the wrong behaviour.  original d3 would return a new image but our dictionary
					// requires unique keys.
					return image;
				}
				else
				{
					if((image.AllowDownSize == allowDownSize) && (image.Depth == depth))
					{
						// note that it is used this level load
						image.LevelLoadReferenced = true;

						return image;
					}

					// the same image is being requested, but with a different allowDownSize or depth
					// so pick the highest of the two and reload the old image with those parameters
					if(image.AllowDownSize == false)
					{
						allowDownSize = false;
					}

					if(image.Depth > depth)
					{
						depth = image.Depth;
					}

					if((image.AllowDownSize == allowDownSize) && (image.Depth == depth))
					{
						// the already created one is already the highest quality
						image.LevelLoadReferenced = true;

						return image;
					}

					/*image.AllowDownSize = allowDownSize;
					image.Depth = depth;*/
					image.LevelLoadReferenced = true;


					if((idE.CvarSystem.GetBool("image_preload") == true) && (_insideLevelLoad == false))
					{
						image.ReferencedOutsideLevelLoad = true;
						image.ActuallyLoadImage(true, false); // check for precompressed, load is from front end

						idE.DeclManager.MediaPrint("{0}x{1} {1} (reload for mixed referneces)", image.Width, image.Height, image.Name);
					}

					return image;
				}
			}

			// HACK: to allow keep fonts from being mip'd, as new ones will be introduced with localization
			// this keeps us from having to make a material for each font tga
			if(name.Contains("fontImage_") == true)
			{
				allowDownSize = false;
			}

			//
			// create a new image
			//
			image = CreateImage(name, TextureType.TwoD, filter, repeat, depth, cubeMap, allowDownSize);
			image.LevelLoadReferenced = true;

			// load it if we aren't in a level preload
			if((idE.CvarSystem.GetBool("image_preload") == true) && (_insideLevelLoad == false))
			{
				image.ReferencedOutsideLevelLoad = true;
				image.ActuallyLoadImage(true, false); // check for precompressed, load is from front end

				idE.DeclManager.MediaPrint("{0}x{1} {2}", image.Width, image.Height, image.Name);
			}
			else
			{
				idE.DeclManager.MediaPrint(image.Name);
			}

			return image;
		}
Example #4
0
		/// <summary>
		/// Finds or loads the given image, always returning a valid image pointer.
		/// Loading of the image may be deferred for dynamic loading.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		/// <returns></returns>
		public idImage ImageFromFile(string name, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
		{
			return ImageFromFile(name, filter, allowDownSize, repeat, depth, CubeFiles.TwoD);
		}
Example #5
0
		private idImage CreateImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
		{
			idImage image = new idImage(name, type, filter, repeat, depth, cubeMap, allowDownSize);

			_images.Add(image);
			_imageDictionary.Add(name, image);

			return image;
		}
Example #6
0
		/// <summary>
		/// Adds implicit stages to the material.
		/// </summary>
		/// <remarks>
		/// If a material has diffuse or specular stages without any
		/// bump stage, add an implicit _flat bumpmap stage.
		/// <p/>
		/// It is valid to have either a diffuse or specular without the other.
		/// <p/>
		/// It is valid to have a reflection map and a bump map for bumpy reflection.
		/// </remarks>
		/// <param name="textureRepeatDefault"></param>
		private void AddImplicitStages(TextureRepeat textureRepeatDefault = TextureRepeat.Repeat)
		{
			bool hasDiffuse = false;
			bool hasSpecular = false;
			bool hasBump = false;
			bool hasReflection = false;
			int count = _parsingData.Stages.Count;

			for(int i = 0; i < 
				count; i++)
			{
				switch(_parsingData.Stages[i].Lighting)
				{
					case StageLighting.Bump:
						hasBump = true;
						break;

					case StageLighting.Diffuse:
						hasDiffuse = true;
						break;

					case StageLighting.Specular:
						hasSpecular = true;
						break;
				}

				if(_parsingData.Stages[i].Texture.TextureCoordinates == TextureCoordinateGeneration.ReflectCube)
				{
					hasReflection = true;
				}
			}

			// if it doesn't have an interaction at all, don't add anything
			if((hasBump == false) && (hasDiffuse == false) && (hasSpecular == false))
			{
				return;
			}

			idLexer lexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);

			if(hasBump == false)
			{
				string bump = "blend bumpmap\nmap _flat\n}\n";

				lexer.LoadMemory(bump, "bumpmap");
				ParseStage(lexer, textureRepeatDefault);
			}

			if((hasDiffuse == false) && (hasSpecular == false) && (hasReflection == false))
			{
				string bump = "blend bumpmap\nmap _white\n}\n";

				lexer.LoadMemory(bump, "diffusemap");
				ParseStage(lexer, textureRepeatDefault);
			}
		}
Example #7
0
		private void ParseStage(idLexer lexer, TextureRepeat textureRepeatDefault)
		{
			TextureFilter textureFilter = TextureFilter.Default;
			TextureRepeat textureRepeat = textureRepeatDefault;
			TextureDepth textureDepth = TextureDepth.Default;
			CubeFiles cubeMap = CubeFiles.TwoD;

			bool allowPicmip = true;
			string imageName = string.Empty;

			NewMaterialStage newStage = new NewMaterialStage();
			newStage.VertexParameters = new int[4, 4];

			MaterialStage materialStage = new MaterialStage();
			materialStage.ConditionRegister = GetExpressionConstant(1);
			materialStage.Color.Registers = new int[] {
				GetExpressionConstant(1),
				GetExpressionConstant(1),
				GetExpressionConstant(1),
				GetExpressionConstant(1)
			};

			int[,] matrix = new int[2, 3];

			idToken token;
			int a, b;

			string tokenValue;
			string tokenLower;

			while(true)
			{
				if(TestMaterialFlag(MaterialFlags.Defaulted) == true)
				{
					// we have a parse error
					return;
				}
				else if((token = lexer.ExpectAnyToken()) == null)
				{
					this.MaterialFlag = MaterialFlags.Defaulted;
					return;
				}

				tokenValue = token.ToString();
				tokenLower = tokenValue.ToLower();

				// the close brace for the entire material ends the draw block
				if(tokenLower == "}")
				{
					break;
				}
				// BSM Nerve: Added for stage naming in the material editor
				else if(tokenLower == "name")
				{
					lexer.SkipRestOfLine();
				}
				// image options
				else if(tokenLower == "blend")
				{
					ParseBlend(lexer, ref materialStage);
				}
				else if(tokenLower == "map")
				{
					imageName = ParsePastImageProgram(lexer);
				}
				else if(tokenLower == "remoterendermap")
				{
					materialStage.Texture.Dynamic = DynamicImageType.RemoteRender;
					materialStage.Texture.Width = lexer.ParseInt();
					materialStage.Texture.Height = lexer.ParseInt();
				}
				else if(tokenLower == "mirrorrendermap")
				{
					materialStage.Texture.Dynamic = DynamicImageType.MirrorRender;
					materialStage.Texture.Width = lexer.ParseInt();
					materialStage.Texture.Height = lexer.ParseInt();
					materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.Screen;
				}
				else if(tokenLower == "xrayrendermap")
				{
					materialStage.Texture.Dynamic = DynamicImageType.XRayRender;
					materialStage.Texture.Width = lexer.ParseInt();
					materialStage.Texture.Height = lexer.ParseInt();
					materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.Screen;
				}
				else if(tokenLower == "screen")
				{
					materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.Screen;
				}
				else if(tokenLower == "screen2")
				{
					materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.Screen;
				}
				else if(tokenLower == "glasswarp")
				{
					materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.GlassWarp;
				}
				else if(tokenLower == "videomap")
				{
					// note that videomaps will always be in clamp mode, so texture
					// coordinates had better be in the 0 to 1 range
					if((token = lexer.ReadToken()) == null)
					{
						idConsole.Warning("missing parameter for 'videoMap' keyword in material '{0}'", this.Name);
					}
					else
					{
						bool loop = false;

						if(token.ToString().Equals("loop", StringComparison.OrdinalIgnoreCase) == true)
						{
							loop = true;

							if((token = lexer.ReadToken()) == null)
							{
								idConsole.Warning("missing parameter for 'videoMap' keyword in material '{0}'", this.Name);
								continue;
							}
						}

						idConsole.Warning("TODO: material videoMap keyword");

						// TODO: cinematic
						/*ts->cinematic = idCinematic::Alloc();
						ts->cinematic->InitFromFile( token.c_str(), loop );*/
					}
				}
				else if(tokenLower == "soundmap")
				{
					if((token = lexer.ReadToken()) == null)
					{
						idConsole.Warning("missing parameter for 'soundMap' keyword in material '{0}'", this.Name);
					}
					else
					{
						idConsole.Warning("TODO: material soundMap keyword");

						// TODO
						/*ts->cinematic = new idSndWindow();
						ts->cinematic->InitFromFile( token.c_str(), true );*/
					}
				}
				else if(tokenLower == "cubemap")
				{
					imageName = ParsePastImageProgram(lexer);
					cubeMap = CubeFiles.Native;
				}
				else if(tokenLower == "cameracubemap")
				{
					imageName = ParsePastImageProgram(lexer);
					cubeMap = CubeFiles.Camera;
				}
				else if(tokenLower == "ignorealphatest")
				{
					materialStage.IgnoreAlphaTest = true;
				}
				else if(tokenLower == "nearest")
				{
					textureFilter = TextureFilter.Nearest;
				}
				else if(tokenLower == "linear")
				{
					textureFilter = TextureFilter.Linear;
				}
				else if(tokenLower == "clamp")
				{
					textureRepeat = TextureRepeat.Clamp;
				}
				else if(tokenLower == "noclamp")
				{
					textureRepeat = TextureRepeat.Repeat;
				}
				else if(tokenLower == "zeroclamp")
				{
					textureRepeat = TextureRepeat.ClampToZero;
				}
				else if(tokenLower == "alphazeroclamp")
				{
					textureRepeat = TextureRepeat.ClampToZeroAlpha;
				}
				else if((tokenLower == "uncompressed")
					|| (tokenLower == "highquality"))
				{
					if(idE.CvarSystem.GetInteger("image_ignoreHighQuality") == 0)
					{
						textureDepth = TextureDepth.HighQuality;
					}
				}
				else if(tokenLower == "forcehighquality")
				{
					textureDepth = TextureDepth.HighQuality;
				}
				else if(tokenLower == "nopicmip")
				{
					allowPicmip = false;
				}
				else if(tokenLower == "vertexcolor")
				{
					materialStage.VertexColor = StageVertexColor.Modulate;
				}
				else if(tokenLower == "inversevertexcolor")
				{
					materialStage.VertexColor = StageVertexColor.InverseModulate;
				}
				// privatePolygonOffset
				else if(tokenLower == "privatepolygonoffset")
				{
					if((token = lexer.ReadTokenOnLine()) == null)
					{
						materialStage.PrivatePolygonOffset = 1;
					}
					else
					{
						// explict larger (or negative) offset
						lexer.UnreadToken = token;
						materialStage.PrivatePolygonOffset = lexer.ParseFloat();
					}
				}
				// texture coordinate generation
				else if(tokenLower == "texgen")
				{
					token = lexer.ExpectAnyToken();
					tokenValue = token.ToString();
					tokenLower = tokenValue.ToLower();

					if(tokenLower == "normal")
					{
						materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.DiffuseCube;
					}
					else if(tokenLower == "reflect")
					{
						materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.ReflectCube;
					}
					else if(tokenLower == "skybox")
					{
						materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.SkyboxCube;
					}
					else if(tokenLower == "wobblesky")
					{
						materialStage.Texture.TextureCoordinates = TextureCoordinateGeneration.WobbleSkyCube;

						_texGenRegisters = new int[4];
						_texGenRegisters[0] = ParseExpression(lexer);
						_texGenRegisters[1] = ParseExpression(lexer);
						_texGenRegisters[2] = ParseExpression(lexer);
					}
					else
					{
						idConsole.Warning("bad texGen '{0}' in material {1}", tokenValue, this.Name);
						this.MaterialFlag = MaterialFlags.Defaulted;
					}
				}
				else if((tokenLower == "scroll")
					|| (tokenLower == "translate"))
				{
					a = ParseExpression(lexer);
					MatchToken(lexer, ",");
					b = ParseExpression(lexer);

					matrix[0, 0] = GetExpressionConstant(1);
					matrix[0, 1] = GetExpressionConstant(0);
					matrix[0, 2] = a;

					matrix[1, 0] = GetExpressionConstant(0);
					matrix[1, 1] = GetExpressionConstant(1);
					matrix[1, 2] = b;

					MultiplyTextureMatrix(ref materialStage.Texture, matrix);
				}
				else if(tokenLower == "scale")
				{
					a = ParseExpression(lexer);
					MatchToken(lexer, ",");
					b = ParseExpression(lexer);

					// this just scales without a centering
					matrix[0, 0] = a;
					matrix[0, 1] = GetExpressionConstant(0);
					matrix[0, 2] = GetExpressionConstant(0);

					matrix[1, 0] = GetExpressionConstant(0);
					matrix[1, 1] = b;
					matrix[1, 2] = GetExpressionConstant(0);

					MultiplyTextureMatrix(ref materialStage.Texture, matrix);
				}
				else if(tokenLower == "centerscale")
				{
					a = ParseExpression(lexer);
					MatchToken(lexer, ",");
					b = ParseExpression(lexer);

					// this subtracts 0.5, then scales, then adds 0.5
					matrix[0, 0] = a;
					matrix[0, 1] = GetExpressionConstant(0);
					matrix[0, 2] = EmitOp(GetExpressionConstant(0.5f), EmitOp(GetExpressionConstant(0.5f), a, ExpressionOperationType.Multiply), ExpressionOperationType.Subtract);

					matrix[1, 0] = GetExpressionConstant(0);
					matrix[1, 1] = b;
					matrix[1, 2] = EmitOp(GetExpressionConstant(0.5f), EmitOp(GetExpressionConstant(0.5f), b, ExpressionOperationType.Multiply), ExpressionOperationType.Subtract);

					MultiplyTextureMatrix(ref materialStage.Texture, matrix);
				}
				else if(tokenLower == "shear")
				{
					a = ParseExpression(lexer);
					MatchToken(lexer, ",");
					b = ParseExpression(lexer);

					// this subtracts 0.5, then shears, then adds 0.5
					matrix[0, 0] = GetExpressionConstant(1);
					matrix[0, 1] = a;
					matrix[0, 2] = EmitOp(GetExpressionConstant(-0.5f), a, ExpressionOperationType.Multiply);

					matrix[1, 0] = b;
					matrix[1, 1] = GetExpressionConstant(1);
					matrix[1, 2] = EmitOp(GetExpressionConstant(-0.5f), b, ExpressionOperationType.Multiply);

					MultiplyTextureMatrix(ref materialStage.Texture, matrix);
				}
				else if(tokenLower == "rotate")
				{
					int sinReg, cosReg;

					// in cycles
					a = ParseExpression(lexer);

					idDeclTable table = idE.DeclManager.FindType<idDeclTable>(DeclType.Table, "sinTable", false);

					if(table == null)
					{
						idConsole.Warning("no sinTable for rotate defined");
						this.MaterialFlag = MaterialFlags.Defaulted;

						return;
					}

					sinReg = EmitOp(table.Index, a, ExpressionOperationType.Table);
					table = idE.DeclManager.FindType<idDeclTable>(DeclType.Table, "cosTable", false);

					if(table == null)
					{
						idConsole.Warning("no cosTable for rotate defined");
						this.MaterialFlag = MaterialFlags.Defaulted;

						return;
					}

					cosReg = EmitOp(table.Index, a, ExpressionOperationType.Table);

					// this subtracts 0.5, then rotates, then adds 0.5
					matrix[0, 0] = cosReg;
					matrix[0, 1] = EmitOp(GetExpressionConstant(0), sinReg, ExpressionOperationType.Subtract);
					matrix[0, 2] = EmitOp(EmitOp(EmitOp(GetExpressionConstant(-0.5f), cosReg, ExpressionOperationType.Multiply),
									EmitOp(GetExpressionConstant(0.5f), sinReg, ExpressionOperationType.Multiply), ExpressionOperationType.Add),
										GetExpressionConstant(0.5f), ExpressionOperationType.Add);

					matrix[1, 0] = sinReg;
					matrix[1, 1] = cosReg;
					matrix[1, 2] = EmitOp(EmitOp(EmitOp(GetExpressionConstant(-0.5f), sinReg, ExpressionOperationType.Multiply),
									EmitOp(GetExpressionConstant(-0.5f), cosReg, ExpressionOperationType.Multiply), ExpressionOperationType.Add),
										GetExpressionConstant(0.5f), ExpressionOperationType.Add);

					MultiplyTextureMatrix(ref materialStage.Texture, matrix);
				}
				// color mask options
				else if(tokenLower == "maskred")
				{
					materialStage.DrawStateBits |= MaterialStates.RedMask;
				}
				else if(tokenLower == "maskgreen")
				{
					materialStage.DrawStateBits |= MaterialStates.GreenMask;
				}
				else if(tokenLower == "maskblue")
				{
					materialStage.DrawStateBits |= MaterialStates.BlueMask;
				}
				else if(tokenLower == "maskalpha")
				{
					materialStage.DrawStateBits |= MaterialStates.AlphaMask;
				}
				else if(tokenLower == "maskcolor")
				{
					materialStage.DrawStateBits |= MaterialStates.ColorMask;
				}
				else if(tokenLower == "maskdepth")
				{
					materialStage.DrawStateBits |= MaterialStates.DepthMask;
				}
				else if(tokenLower == "alphatest")
				{
					materialStage.HasAlphaTest = true;
					materialStage.AlphaTestRegister = ParseExpression(lexer);

					_coverage = MaterialCoverage.Perforated;
				}
				// shorthand for 2D modulated
				else if(tokenLower == "colored")
				{
					materialStage.Color.Registers[0] = (int) ExpressionRegister.Parm0;
					materialStage.Color.Registers[1] = (int) ExpressionRegister.Parm1;
					materialStage.Color.Registers[2] = (int) ExpressionRegister.Parm2;
					materialStage.Color.Registers[3] = (int) ExpressionRegister.Parm3;

					_parsingData.RegistersAreConstant = false;
				}
				else if(tokenLower == "color")
				{
					materialStage.Color.Registers[0] = ParseExpression(lexer);
					MatchToken(lexer, ",");

					materialStage.Color.Registers[1] = ParseExpression(lexer);
					MatchToken(lexer, ",");

					materialStage.Color.Registers[2] = ParseExpression(lexer);
					MatchToken(lexer, ",");

					materialStage.Color.Registers[3] = ParseExpression(lexer);
				}
				else if(tokenLower == "red")
				{
					materialStage.Color.Registers[0] = ParseExpression(lexer);
				}
				else if(tokenLower == "green")
				{
					materialStage.Color.Registers[1] = ParseExpression(lexer);
				}
				else if(tokenLower == "blue")
				{
					materialStage.Color.Registers[2] = ParseExpression(lexer);
				}
				else if(tokenLower == "alpha")
				{
					materialStage.Color.Registers[3] = ParseExpression(lexer);
				}
				else if(tokenLower == "rgb")
				{
					materialStage.Color.Registers[0] = materialStage.Color.Registers[1] = materialStage.Color.Registers[2] = ParseExpression(lexer);
				}
				else if(tokenLower == "rgba")
				{
					materialStage.Color.Registers[0] = materialStage.Color.Registers[1] = materialStage.Color.Registers[2] = materialStage.Color.Registers[3] = ParseExpression(lexer);
				}
				else if(tokenLower == "if")
				{
					materialStage.ConditionRegister = ParseExpression(lexer);
				}
				else if(tokenLower == "program")
				{
					if((token = lexer.ReadTokenOnLine()) != null)
					{
						idConsole.Warning("TODO: material program keyword");
						// TODO
						/*newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() );
						newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() );*/
					}
				}
				else if(tokenLower == "fragmentprogram")
				{
					if((token = lexer.ReadTokenOnLine()) != null)
					{
						idConsole.Warning("TODO: material fragmentProgram keyword");
						// TODO
						//newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() );
					}
				}
				else if(tokenLower == "vertexprogram")
				{
					if((token = lexer.ReadTokenOnLine()) != null)
					{
						idConsole.Warning("TODO: material vertexProgram keyword");
						// TODO
						//newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() );
					}
				}
				else if(tokenLower == "megatexture")
				{
					if((token = lexer.ReadTokenOnLine()) != null)
					{
						idConsole.Warning("TODO: material megaTexture keyword");
						// TODO
						/*newStage.megaTexture = new idMegaTexture;
						if ( !newStage.megaTexture->InitFromMegaFile( token.c_str() ) ) {
							delete newStage.megaTexture;
							SetMaterialFlag( MF_DEFAULTED );
							continue;
						}
						newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, "megaTexture.vfp" );
						newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, "megaTexture.vfp" );*/
					}
				}
				else if(tokenLower == "vertexparm")
				{
					ParseVertexParameter(lexer, ref newStage);
				}
				else if(tokenLower == "fragmentmap")
				{
					ParseFragmentMap(lexer, ref newStage);
				}
				else
				{
					idConsole.Warning("unknown token '{0}' in material '{1}'", tokenValue, this.Name);

					this.MaterialFlag = MaterialFlags.Defaulted;

					return;
				}
			}

			// if we are using newStage, allocate a copy of it
			if((newStage.FragmentProgram != 0) || (newStage.VertexProgram != 0))
			{
				materialStage.NewStage = newStage;
			}

			// select a compressed depth based on what the stage is
			if(textureDepth == TextureDepth.Default)
			{
				switch(materialStage.Lighting)
				{
					case StageLighting.Bump:
						textureDepth = TextureDepth.Bump;
						break;

					case StageLighting.Diffuse:
						textureDepth = TextureDepth.Diffuse;
						break;

					case StageLighting.Specular:
						textureDepth = TextureDepth.Specular;
						break;
				}
			}

			// now load the image with all the parms we parsed
			if((imageName != null) && (imageName != string.Empty))
			{
				materialStage.Texture.Image = idE.ImageManager.ImageFromFile(imageName, textureFilter, allowPicmip, textureRepeat, textureDepth, cubeMap);

				if(materialStage.Texture.Image == null)
				{
					materialStage.Texture.Image = idE.ImageManager.DefaultImage;
				}
			}
			else if(/*TODO: !ts->cinematic &&*/ (materialStage.Texture.Dynamic == 0) && (materialStage.NewStage.IsEmpty == true))
			{
				idConsole.Warning("material '{0}' had stage with no image", this.Name);
				materialStage.Texture.Image = idE.ImageManager.DefaultImage;
			}

			// successfully parsed a stage.
			_parsingData.Stages.Add(materialStage);
		}
Example #8
0
		/// <summary>
		/// Used by callback functions to specify the actual data
		/// data goes from the bottom to the top line of the image, as OpenGL expects it
		/// These perform an implicit Bind() on the current texture unit.
		/// </summary>
		/// <remarks>
		/// The alpha channel bytes should be 255 if you don't want the channel.
		/// We need a material characteristic to ask for specific texture modes.
		/// Designed limitations of flexibility:
		/// No support for texture borders.
		/// No support for texture border color.
		/// No support for texture environment colors or GL_BLEND or GL_DECAL
		/// texture environments, because the automatic optimization to single
		/// or dual component textures makes those modes potentially undefined.
		/// No non-power-of-two images.
		/// No palettized textures.
		/// There is no way to specify separate wrap/clamp values for S and T.
		/// There is no way to specify explicit mip map levels.
		/// </remarks>
		/// <param name="data"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		public void Generate(byte[] data, int width, int height, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			// FIXME: should we implement cinematics this way, instead of with explicit calls?
			/*Purge();

			_filter = filter;
			_allowDownSize = allowDownSize;
			_repeat = repeat;
			_depth = depth;*/

			idConsole.Warning("TODO: generate");

			// if we don't have a rendering context, just return after we
			// have filled in the parms.  We must have the values set, or
			// an image match from a shader before OpenGL starts would miss
			// the generated texture
			if(idE.RenderSystem.IsRunning == false)
			{
				return;
			}

			// don't let mip mapping smear the texture into the clamped border
			/*bool preserveBorder = (_repeat == TextureRepeat.ClampToZero);

			// make sure it is a power of 2
			int scaledWidth = idHelper.MakePowerOfTwo(width);
			int scaledHeight = idHelper.MakePowerOfTwo(height);

			if((scaledWidth != width) || (scaledHeight != height))
			{
				idConsole.Error("Image.Generate: not a power of 2 image.");
			}

			// Optionally modify our width/height based on options/hardware			
			GetDownSize(ref scaledWidth, ref scaledHeight);

			byte[] scaledBuffer = null;
			/*idE.RenderSystem.CheckOpenGLErrors();
			uint[] tex = new uint[1];
			//Gl.glGenTextures(1, tex);
			_texNumber = (int) tex[0];
			idE.RenderSystem.CheckOpenGLErrors();*/
			/*_loaded = true;

			// select proper internal format before we resample
			_internalFormat = Gl.GL_RGB8;  // SelectInternalFormat(data, 1, width, height, depth, out _isMonochrome);

			// copy or resample data as appropriate for first MIP level.
			if((scaledWidth == width) && (scaledHeight == height))
			{
				// we must copy even if unchanged, because the border zeroing
				// would otherwise modify const data
				scaledBuffer = data;
			}
			else
			{
				idConsole.Warning("TODO: DONT SUPPORT MIMAP RIGHT NOW");

				// resample down as needed (FIXME: this doesn't seem like it resamples anymore!)
				// scaledBuffer = R_ResampleTexture( pic, width, height, width >>= 1, height >>= 1 );
				/*scaledBuffer = R_MipMap( pic, width, height, preserveBorder );
				width >>= 1;
				height >>= 1;
				if ( width < 1 ) {
					width = 1;
				}
				if ( height < 1 ) {
					height = 1;
				}

				while ( width > scaled_width || height > scaled_height ) {
					shrunk = R_MipMap( scaledBuffer, width, height, preserveBorder );
					R_StaticFree( scaledBuffer );
					scaledBuffer = shrunk;

					width >>= 1;
					height >>= 1;
					if ( width < 1 ) {
						width = 1;
					}
					if ( height < 1 ) {
						height = 1;
					}
				}

				// one might have shrunk down below the target size
				scaled_width = width;
				scaled_height = height;*/
			/*}*/

			/*_uploadWidth = scaledWidth;
			_uploadHeight = scaledHeight;
			_type = TextureType.TwoD;

			// zero the border if desired, allowing clamped projection textures
			// even after picmip resampling or careless artists.
			if(repeat == TextureRepeat.ClampToZero)
			{
				byte[] rgba = new byte[4] { 0, 0, 0, 255 };
				SetBorderTexels(scaledBuffer, width, height, rgba);
			}
			else if(repeat == TextureRepeat.ClampToZeroAlpha)
			{
				byte[] rgba = new byte[4] { 255, 255, 255, 0 };
				SetBorderTexels(scaledBuffer, width, height, rgba);
			}*/

			/*if((_generator == null) && ((_depth == TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeNormalTGA") == true) || (_depth != TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeTGA") == true)))
			{
				idConsole.Warning("TODO: gen = null && bump && write");
				// Optionally write out the texture to a .tga
				/*char filename[MAX_IMAGE_NAME];
				ImageProgramStringToCompressedFileName( imgName, filename );
				char *ext = strrchr(filename, '.');
				if ( ext ) {
					strcpy( ext, ".tga" );
					// swap the red/alpha for the write
					/*
					if ( depth == TD_BUMP ) {
						for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
							scaledBuffer[ i ] = scaledBuffer[ i + 3 ];
							scaledBuffer[ i + 3 ] = 0;
						}
					}
					*/
				// TODO: R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height, false );

				// put it back
				/*
				if ( depth == TD_BUMP ) {
					for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
						scaledBuffer[ i + 3 ] = scaledBuffer[ i ];
						scaledBuffer[ i ] = 0;
					}
				}
				*/
				/*}*/
		/*	}*/

			// swap the red and alpha for rxgb support
			// do this even on tga normal maps so we only have to use
			// one fragment program.
			// if the image is precompressed (either in palletized mode or true rxgb mode)
			// then it is loaded above and the swap never happens here.
			/*if((depth == TextureDepth.Bump) && (idE.CvarSystem.GetInteger("image_useNormalCompression") != 1))
			{
				for(int i = 0; i < scaledWidth * scaledHeight * 4; i += 4)
				{
					scaledBuffer[i + 3] = scaledBuffer[i];
					scaledBuffer[i] = 0;
				}
			}

			// upload the main image level
			Bind();

			if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
			{
				idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, 0 );");
			}
			else
			{
				//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
			}

			// create and upload the mip map levels, which we do in all cases, even if we don't think they are needed
			/*int miplevel = 0;
			// TODO: remove this if not needed
			while((scaledWidth > 1) || (scaledHeight > 1))
			{
				// preserve the border after mip map unless repeating
				scaledBuffer = MipMap(scaledBuffer, scaledWidth, scaledHeight, preserveBorder);
				scaledWidth >>= 1;
				scaledHeight >>= 1;

				if(scaledWidth < 1)
				{
					scaledWidth = 1;
				}

				if(scaledHeight < 1)
				{
					scaledHeight = 1;
				}

				miplevel++;

				// this is a visualization tool that shades each mip map
				// level with a different color so you can see the
				// rasterizer's texture level selection algorithm
				// Changing the color doesn't help with lumminance/alpha/intensity formats...
				// TODO
				/*if ( depth == TD_DIFFUSE && globalImages->image_colorMipLevels.GetBool() ) {
					R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
				}*/

			// upload the mip map
			/*if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
			{
				idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, miplevel );");
			}
			else
			{
				//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, miplevel, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
			}
		}*/

			//SetImageFilterAndRepeat();
		}
Example #9
0
		public idImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
		{
			_name = name;
			_type = type;

			_filter = filter;
			_repeat = repeat;
			_depth = depth;
			_cubeFiles = cubeMap;
			_allowDownSize = allowDownSize;
		}
Example #10
0
		// background loading information.
		/*private idImage _partialImage;			// shrunken, space-saving version
		private bool _isPartialImage;			// true if this is pointed to by another image*/
		#endregion

		#region Constructor
		public idImage(string name, ImageLoadCallback generator)
		{
			_name = name;
			_generator = generator;
			_type = TextureType.Disabled;

			_filter = TextureFilter.Default;
			_repeat = TextureRepeat.Repeat;
			_depth = TextureDepth.Default;
			_cubeFiles = CubeFiles.TwoD;
		}
Example #11
0
        /// <summary>
        /// Used by callback functions to specify the actual data
        /// data goes from the bottom to the top line of the image, as OpenGL expects it
        /// These perform an implicit Bind() on the current texture unit.
        /// </summary>
        /// <remarks>
        /// The alpha channel bytes should be 255 if you don't want the channel.
        /// We need a material characteristic to ask for specific texture modes.
        /// Designed limitations of flexibility:
        /// No support for texture borders.
        /// No support for texture border color.
        /// No support for texture environment colors or GL_BLEND or GL_DECAL
        /// texture environments, because the automatic optimization to single
        /// or dual component textures makes those modes potentially undefined.
        /// No non-power-of-two images.
        /// No palettized textures.
        /// There is no way to specify separate wrap/clamp values for S and T.
        /// There is no way to specify explicit mip map levels.
        /// </remarks>
        /// <param name="data"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="filter"></param>
        /// <param name="allowDownSize"></param>
        /// <param name="repeat"></param>
        /// <param name="depth"></param>
        public void Generate(byte[] data, int width, int height, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            // FIXME: should we implement cinematics this way, instead of with explicit calls?

            /*Purge();
             *
             * _filter = filter;
             * _allowDownSize = allowDownSize;
             * _repeat = repeat;
             * _depth = depth;*/

            idConsole.Warning("TODO: generate");

            // if we don't have a rendering context, just return after we
            // have filled in the parms.  We must have the values set, or
            // an image match from a shader before OpenGL starts would miss
            // the generated texture
            if (idE.RenderSystem.IsRunning == false)
            {
                return;
            }

            // don't let mip mapping smear the texture into the clamped border

            /*bool preserveBorder = (_repeat == TextureRepeat.ClampToZero);
             *
             * // make sure it is a power of 2
             * int scaledWidth = idHelper.MakePowerOfTwo(width);
             * int scaledHeight = idHelper.MakePowerOfTwo(height);
             *
             * if((scaledWidth != width) || (scaledHeight != height))
             * {
             *      idConsole.Error("Image.Generate: not a power of 2 image.");
             * }
             *
             * // Optionally modify our width/height based on options/hardware
             * GetDownSize(ref scaledWidth, ref scaledHeight);
             *
             * byte[] scaledBuffer = null;
             * /*idE.RenderSystem.CheckOpenGLErrors();
             * uint[] tex = new uint[1];
             * //Gl.glGenTextures(1, tex);
             * _texNumber = (int) tex[0];
             * idE.RenderSystem.CheckOpenGLErrors();*/
            /*_loaded = true;
             *
             * // select proper internal format before we resample
             * _internalFormat = Gl.GL_RGB8;  // SelectInternalFormat(data, 1, width, height, depth, out _isMonochrome);
             *
             * // copy or resample data as appropriate for first MIP level.
             * if((scaledWidth == width) && (scaledHeight == height))
             * {
             *      // we must copy even if unchanged, because the border zeroing
             *      // would otherwise modify const data
             *      scaledBuffer = data;
             * }
             * else
             * {
             *      idConsole.Warning("TODO: DONT SUPPORT MIMAP RIGHT NOW");
             *
             *      // resample down as needed (FIXME: this doesn't seem like it resamples anymore!)
             *      // scaledBuffer = R_ResampleTexture( pic, width, height, width >>= 1, height >>= 1 );
             *      /*scaledBuffer = R_MipMap( pic, width, height, preserveBorder );
             *      width >>= 1;
             *      height >>= 1;
             *      if ( width < 1 ) {
             *              width = 1;
             *      }
             *      if ( height < 1 ) {
             *              height = 1;
             *      }
             *
             *      while ( width > scaled_width || height > scaled_height ) {
             *              shrunk = R_MipMap( scaledBuffer, width, height, preserveBorder );
             *              R_StaticFree( scaledBuffer );
             *              scaledBuffer = shrunk;
             *
             *              width >>= 1;
             *              height >>= 1;
             *              if ( width < 1 ) {
             *                      width = 1;
             *              }
             *              if ( height < 1 ) {
             *                      height = 1;
             *              }
             *      }
             *
             *      // one might have shrunk down below the target size
             *      scaled_width = width;
             *      scaled_height = height;*/
            /*}*/

            /*_uploadWidth = scaledWidth;
             * _uploadHeight = scaledHeight;
             * _type = TextureType.TwoD;
             *
             * // zero the border if desired, allowing clamped projection textures
             * // even after picmip resampling or careless artists.
             * if(repeat == TextureRepeat.ClampToZero)
             * {
             *      byte[] rgba = new byte[4] { 0, 0, 0, 255 };
             *      SetBorderTexels(scaledBuffer, width, height, rgba);
             * }
             * else if(repeat == TextureRepeat.ClampToZeroAlpha)
             * {
             *      byte[] rgba = new byte[4] { 255, 255, 255, 0 };
             *      SetBorderTexels(scaledBuffer, width, height, rgba);
             * }*/

            /*if((_generator == null) && ((_depth == TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeNormalTGA") == true) || (_depth != TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeTGA") == true)))
             * {
             *      idConsole.Warning("TODO: gen = null && bump && write");
             *      // Optionally write out the texture to a .tga
             *      /*char filename[MAX_IMAGE_NAME];
             *      ImageProgramStringToCompressedFileName( imgName, filename );
             *      char *ext = strrchr(filename, '.');
             *      if ( ext ) {
             *              strcpy( ext, ".tga" );
             *              // swap the red/alpha for the write
             *              /*
             *              if ( depth == TD_BUMP ) {
             *                      for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
             *                              scaledBuffer[ i ] = scaledBuffer[ i + 3 ];
             *                              scaledBuffer[ i + 3 ] = 0;
             *                      }
             *              }
             */
            // TODO: R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height, false );

            // put it back

            /*
             * if ( depth == TD_BUMP ) {
             *      for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
             *              scaledBuffer[ i + 3 ] = scaledBuffer[ i ];
             *              scaledBuffer[ i ] = 0;
             *      }
             * }
             */
            /*}*/
            /*	}*/

            // swap the red and alpha for rxgb support
            // do this even on tga normal maps so we only have to use
            // one fragment program.
            // if the image is precompressed (either in palletized mode or true rxgb mode)
            // then it is loaded above and the swap never happens here.

            /*if((depth == TextureDepth.Bump) && (idE.CvarSystem.GetInteger("image_useNormalCompression") != 1))
             * {
             *      for(int i = 0; i < scaledWidth * scaledHeight * 4; i += 4)
             *      {
             *              scaledBuffer[i + 3] = scaledBuffer[i];
             *              scaledBuffer[i] = 0;
             *      }
             * }
             *
             * // upload the main image level
             * Bind();
             *
             * if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
             * {
             *      idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, 0 );");
             * }
             * else
             * {
             *      //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
             * }
             *
             * // create and upload the mip map levels, which we do in all cases, even if we don't think they are needed
             * /*int miplevel = 0;
             * // TODO: remove this if not needed
             * while((scaledWidth > 1) || (scaledHeight > 1))
             * {
             *      // preserve the border after mip map unless repeating
             *      scaledBuffer = MipMap(scaledBuffer, scaledWidth, scaledHeight, preserveBorder);
             *      scaledWidth >>= 1;
             *      scaledHeight >>= 1;
             *
             *      if(scaledWidth < 1)
             *      {
             *              scaledWidth = 1;
             *      }
             *
             *      if(scaledHeight < 1)
             *      {
             *              scaledHeight = 1;
             *      }
             *
             *      miplevel++;
             *
             *      // this is a visualization tool that shades each mip map
             *      // level with a different color so you can see the
             *      // rasterizer's texture level selection algorithm
             *      // Changing the color doesn't help with lumminance/alpha/intensity formats...
             *      // TODO
             *      /*if ( depth == TD_DIFFUSE && globalImages->image_colorMipLevels.GetBool() ) {
             *              R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
             *      }*/

            // upload the mip map

            /*if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
             * {
             *      idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, miplevel );");
             * }
             * else
             * {
             *      //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, miplevel, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
             * }
             * }*/

            //SetImageFilterAndRepeat();
        }