ExpectAnyToken() public method

public ExpectAnyToken ( ) : idToken
return idToken
Example #1
0
		/// <summary>
		/// Parses the material, if there are any errors during parsing the defaultShader will be set.
		/// </summary>
		/// <param name="lexer"></param>
		private void ParseMaterial(idLexer lexer)
		{
			_registerCount = PredefinedRegisterCount; // leave space for the parms to be copied in.

			for(int i = 0; i < _registerCount; i++)
			{
				_parsingData.RegisterIsTemporary[i] = true; // they aren't constants that can be folded.
			}

			TextureRepeat textureRepeatDefault = TextureRepeat.Repeat; // allow a global setting for repeat.
			idToken token = null;

			string tokenValue;
			string tokenLower;
			int count;

			while(true)
			{
				if(TestMaterialFlag(Renderer.MaterialFlags.Defaulted) == true)
				{
					// we have a parse error.
					return;
				}

				if((token = lexer.ExpectAnyToken()) == null)
				{
					this.MaterialFlag = MaterialFlags.Defaulted;
					return;
				}

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

				// end of material definition
				if(tokenLower == "}")
				{
					break;
				}
				else if(tokenLower == "qer_editorimage")
				{
					token = lexer.ReadTokenOnLine();
					_editorImageName = (token != null) ? token.ToString() : string.Empty;

					lexer.SkipRestOfLine();
				}
				else if(tokenLower == "description")
				{
					token = lexer.ReadTokenOnLine();
					_description = (token != null) ? token.ToString() : string.Empty;
				}
				// check for the surface / content bit flags.
				else if(CheckSurfaceParameter(token) == true)
				{

				}
				else if(tokenLower == "polygonoffset")
				{
					this.MaterialFlag = Renderer.MaterialFlags.PolygonOffset;

					if((token = lexer.ReadTokenOnLine()) == null)
					{
						_polygonOffset = 1;
					}
					else
					{
						_polygonOffset = token.ToFloat();
					}
				}
				// noshadow.
				else if(tokenLower == "noshadows")
				{
					this.MaterialFlag = MaterialFlags.NoShadows;
				}
				else if(tokenLower == "suppressinsubview")
				{
					_suppressInSubview = true;
				}
				else if(tokenLower == "portalsky")
				{
					_portalSky = true;
				}
				else if(tokenLower == "noselfshadow")
				{
					this.MaterialFlag = Renderer.MaterialFlags.NoSelfShadow;
				}
				else if(tokenLower == "noportalfog")
				{
					this.MaterialFlag = Renderer.MaterialFlags.NoPortalFog;
				}
				// forceShadows allows nodraw surfaces to cast shadows.
				else if(tokenLower == "forceshadows")
				{
					this.MaterialFlag = Renderer.MaterialFlags.ForceShadows;
				}
				// overlay / decal suppression.
				else if(tokenLower == "nooverlays")
				{
					_allowOverlays = false;
				}
				// moster blood overlay forcing for alpha tested or translucent surfaces.
				else if(tokenLower == "forceoverlays")
				{
					_parsingData.ForceOverlays = true;
				}
				else if(tokenLower == "translucent")
				{
					_coverage = MaterialCoverage.Translucent;
				}
				// global zero clamp.
				else if(tokenLower == "zeroclamp")
				{
					textureRepeatDefault = TextureRepeat.ClampToZero;
				}
				// global clamp.
				else if(tokenLower == "clamp")
				{
					textureRepeatDefault = TextureRepeat.Clamp;
				}
				// global clamp.
				else if(tokenLower == "alphazeroclamp")
				{
					textureRepeatDefault = TextureRepeat.ClampToZero;
				}
				// forceOpaque is used for skies-behind-windows.
				else if(tokenLower == "forceopaque")
				{
					_coverage = MaterialCoverage.Opaque;
				}
				else if(tokenLower == "twosided")
				{
					_cullType = CullType.TwoSided;

					// twoSided implies no-shadows, because the shadow
					// volume would be coplanar with the surface, giving depth fighting
					// we could make this no-self-shadows, but it may be more important
					// to receive shadows from no-self-shadow monsters.
					this.MaterialFlag = Renderer.MaterialFlags.NoShadows;
				}
				else if(tokenLower == "backsided")
				{
					_cullType = CullType.Back;

					// the shadow code doesn't handle this, so just disable shadows.
					// We could fix this in the future if there was a need.
					this.MaterialFlag = Renderer.MaterialFlags.NoShadows;
				}
				else if(tokenLower == "foglight")
				{
					_fogLight = true;
				}
				else if(tokenLower == "blendlight")
				{
					_blendLight = true;
				}
				else if(tokenLower == "ambientlight")
				{
					_ambientLight = true;
				}
				else if(tokenLower == "mirror")
				{
					_sort = (float) MaterialSort.Subview;
					_coverage = MaterialCoverage.Opaque;
				}
				else if(tokenLower == "nofog")
				{
					_noFog = true;
				}
				else if(tokenLower == "unsmoothedtangents")
				{
					_unsmoothedTangents = true;
				}
				// lightFallofImage <imageprogram>
				// specifies the image to use for the third axis of projected
				// light volumes.
				else if(tokenLower == "lightfalloffimage")
				{
					_lightFalloffImage = idE.ImageManager.ImageFromFile(ParsePastImageProgram(lexer), TextureFilter.Default, false, TextureRepeat.Clamp, TextureDepth.Default);
				}
				// guisurf <guifile> | guisurf entity
				// an entity guisurf must have an idUserInterface
				// specified in the renderEntity.
				else if(tokenLower == "guisurf")
				{
					token = lexer.ReadTokenOnLine();
					tokenLower = token.ToString().ToLower();

					if(tokenLower == "entity")
					{
						_entityGui = 1;
					}
					else if(tokenLower == "entity2")
					{
						_entityGui = 2;
					}
					else if(tokenLower == "entity3")
					{
						_entityGui = 3;
					}
					else
					{
						_userInterface = idE.UIManager.FindInterface(token.ToString(), true);
					}
				}
				// sort.
				else if(tokenLower == "sort")
				{
					ParseSort(lexer);
				}
				// spectrum <integer>.
				else if(tokenLower == "spectrum")
				{
					int.TryParse(lexer.ReadTokenOnLine().ToString(), out _spectrum);
				}
				// deform < sprite | tube | flare >.
				else if(tokenLower == "deform")
				{
					ParseDeform(lexer);
				}
				// decalInfo <staySeconds> <fadeSeconds> (<start rgb>) (<end rgb>).
				else if(tokenLower == "decalinfo")
				{
					ParseDecalInfo(lexer);
				}
				// renderbump <args...>.
				else if(tokenLower == "renderbump")
				{
					_renderBump = lexer.ParseRestOfLine();
				}
				// diffusemap for stage shortcut.
				else if(tokenLower == "diffusemap")
				{
					idLexer newLexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);
					newLexer.LoadMemory(string.Format("blend diffusemap\nmap {0}\n}}\n", ParsePastImageProgram(lexer)), "diffusemap");

					ParseStage(newLexer, textureRepeatDefault);
				}
				// specularmap for stage shortcut.
				else if(tokenLower == "specularmap")
				{
					idLexer newLexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);
					newLexer.LoadMemory(string.Format("blend specularmap\nmap {0}\n}}\n", ParsePastImageProgram(lexer)), "specularmap");

					ParseStage(newLexer, textureRepeatDefault);
				}
				// normalmap for stage shortcut.
				else if(tokenLower == "bumpmap")
				{
					idLexer newLexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);
					newLexer.LoadMemory(string.Format("blend bumpmap\nmap {0}\n}}\n", ParsePastImageProgram(lexer)), "bumpmap");

					ParseStage(newLexer, textureRepeatDefault);
				}
				// DECAL_MACRO for backwards compatibility with the preprocessor macros.
				else if(tokenLower == "decal_macro")
				{
					// polygonOffset
					this.MaterialFlag = Renderer.MaterialFlags.PolygonOffset;
					_polygonOffset = -1;

					// discrete
					_surfaceFlags |= SurfaceFlags.Discrete;
					_contentFlags &= ~ContentFlags.Solid;

					// sort decal.
					_sort = (float) MaterialSort.Decal;

					// noShadows
					this.MaterialFlag = Renderer.MaterialFlags.NoShadows;
				}
				else if(tokenValue == "{")
				{
					// create the new stage.
					ParseStage(lexer, textureRepeatDefault);
				}
				else
				{
					idConsole.WriteLine("unknown general material parameter '{0}' in '{1}'", tokenValue, this.Name);
					return;
				}
			}

			// add _flat or _white stages if needed.
			AddImplicitStages();

			// order the diffuse / bump / specular stages properly.
			SortInteractionStages();

			// if we need to do anything with normals (lighting or environment mapping)
			// and two sided lighting was asked for, flag
			// shouldCreateBackSides() and change culling back to single sided,
			// so we get proper tangent vectors on both sides.

			// we can't just call ReceivesLighting(), because the stages are still
			// in temporary form.
			if(_cullType == CullType.TwoSided)
			{
				count = _parsingData.Stages.Count;

				for(int i = 0; i < count; i++)
				{
					if((_parsingData.Stages[i].Lighting != StageLighting.Ambient) || (_parsingData.Stages[i].Texture.TextureCoordinates != TextureCoordinateGeneration.Explicit))
					{
						if(_cullType == CullType.TwoSided)
						{
							_cullType = CullType.Front;
							_shouldCreateBackSides = true;
						}

						break;
					}
				}
			}

			// currently a surface can only have one unique texgen for all the stages on old hardware.
			TextureCoordinateGeneration firstGen = TextureCoordinateGeneration.Explicit;

			count = _parsingData.Stages.Count;

			for(int i = 0; i < count; i++)
			{
				if(_parsingData.Stages[i].Texture.TextureCoordinates != TextureCoordinateGeneration.Explicit)
				{
					if(firstGen == TextureCoordinateGeneration.Explicit)
					{
						firstGen = _parsingData.Stages[i].Texture.TextureCoordinates;
					}
					else if(firstGen != _parsingData.Stages[i].Texture.TextureCoordinates)
					{
						idConsole.Warning("material '{0}' has multiple stages with a texgen", this.Name);
						break;
					}
				}
			}
		}
Example #2
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 #3
0
		private void ParseDeform(idLexer lexer)
		{
			idToken token = lexer.ExpectAnyToken();

			if(token == null)
			{
				return;
			}

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

			if(tokenLower == "sprite")
			{
				_deformType = DeformType.Sprite;
				_cullType = CullType.TwoSided;

				this.MaterialFlag = MaterialFlags.NoShadows;
			}
			else if(tokenLower == "tube")
			{
				_deformType = DeformType.Tube;
				_cullType = CullType.TwoSided;

				this.MaterialFlag = MaterialFlags.NoShadows;
			}
			else if(tokenLower == "flare")
			{
				_deformType = DeformType.Flare;
				_cullType = CullType.TwoSided;
				_deformRegisters[0] = ParseExpression(lexer);

				this.MaterialFlag = MaterialFlags.NoShadows;
			}
			else if(tokenLower == "expand")
			{
				_deformType = DeformType.Expand;
				_deformRegisters[0] = ParseExpression(lexer);
			}
			else if(tokenLower == "move")
			{
				_deformType = DeformType.Move;
				_deformRegisters[0] = ParseExpression(lexer);
			}
			else if(tokenLower == "turbulent")
			{
				_deformType = DeformType.Turbulent;

				if((token = lexer.ExpectAnyToken()) == null)
				{
					lexer.Warning("deform particle missing particle name");
					this.MaterialFlag = MaterialFlags.Defaulted;
				}
				else
				{
					_deformDecl = idE.DeclManager.FindType(DeclType.Table, token.ToString(), true);

					_deformRegisters[0] = ParseExpression(lexer);
					_deformRegisters[1] = ParseExpression(lexer);
					_deformRegisters[2] = ParseExpression(lexer);
				}
			}
			else if(tokenLower == "eyeball")
			{
				_deformType = DeformType.Eyeball;
			}
			else if(tokenLower == "particle")
			{
				_deformType = DeformType.Particle;

				if((token = lexer.ExpectAnyToken()) == null)
				{
					lexer.Warning("deform particle missing particle name");
					this.MaterialFlag = MaterialFlags.Defaulted;
				}
				else
				{
					_deformDecl = idE.DeclManager.FindType(DeclType.Particle, token.ToString(), true);
				}
			}
			else if(tokenLower == "particle2")
			{
				_deformType = DeformType.Particle2;

				if((token = lexer.ExpectAnyToken()) == null)
				{
					lexer.Warning("deform particle missing particle name");
					this.MaterialFlag = MaterialFlags.Defaulted;
				}
				else
				{
					_deformDecl = idE.DeclManager.FindType(DeclType.Table, token.ToString(), true);

					_deformRegisters[0] = ParseExpression(lexer);
					_deformRegisters[1] = ParseExpression(lexer);
					_deformRegisters[2] = ParseExpression(lexer);
				}
			}
			else
			{
				lexer.Warning("Bad deform type '{0}'", tokenValue);
				this.MaterialFlag = MaterialFlags.Defaulted;
			}
		}
Example #4
0
		private idRenderModel ParseShadowModel(idLexer lexer)
		{
			lexer.ExpectTokenString("{");

			// parse the name
			idToken token = lexer.ExpectAnyToken();

			idRenderModel model = idE.RenderModelManager.AllocateModel();
			model.InitEmpty(token.ToString());

			RenderModelSurface modelSurface = new RenderModelSurface();
			modelSurface.Material = idE.RenderSystem.DefaultMaterial;

			modelSurface.Geometry = new Surface();
			modelSurface.Geometry.ShadowVertices = new ShadowVertex[lexer.ParseInt()];
			modelSurface.Geometry.ShadowIndexesNoCapsCount = lexer.ParseInt();
			modelSurface.Geometry.ShadowIndexesNoFrontCapsCount = lexer.ParseInt();
			modelSurface.Geometry.Indexes = new int[lexer.ParseInt()];
			modelSurface.Geometry.ShadowCapPlaneBits = lexer.ParseInt();
			modelSurface.Geometry.Bounds.Clear();

			int count = modelSurface.Geometry.ShadowVertices.Length;

			for(int j = 0; j < count; j++)
			{
				float[] vec = lexer.Parse1DMatrix(3);

				modelSurface.Geometry.ShadowVertices[j].Position = new Vector4(vec[0], vec[1], vec[2], 1);
				modelSurface.Geometry.Bounds.AddPoint(modelSurface.Geometry.ShadowVertices[j].Position);
			}

			count = modelSurface.Geometry.Indexes.Length;

			for(int j = 0; j < count; j++)
			{
				modelSurface.Geometry.Indexes[j] = lexer.ParseInt();
			}

			// add the completed surface to the model
			model.AddSurface(modelSurface);

			lexer.ExpectTokenString("}");

			// we do NOT do a model->FinishSurfaces, because we don't need sil edges, planes, tangents, etc.
			//	model.FinishSurfaces();

			return model;
		}
Example #5
0
		private idRenderModel ParseModel(idLexer lexer)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			RenderModelSurface modelSurface;

			lexer.ExpectTokenString("{");

			// parse the name
			idToken token = lexer.ExpectAnyToken();

			idRenderModel model = idE.RenderModelManager.AllocateModel();
			model.InitEmpty(token.ToString());

			int surfaceCount = lexer.ParseInt();
			int loopCount = 0;

			if(surfaceCount < 0)
			{
				lexer.Error("ParseModel: bad surfaceCount");
			}

			for(int i = 0; i < surfaceCount; i++)
			{
				lexer.ExpectTokenString("{");
				token = lexer.ExpectAnyToken();

				modelSurface = new RenderModelSurface();
				modelSurface.Material = idE.DeclManager.FindMaterial(token.ToString());
				modelSurface.Material.AddReference();

				modelSurface.Geometry = new Surface();
				modelSurface.Geometry.Vertices = new Vertex[lexer.ParseInt()];
				modelSurface.Geometry.Indexes = new int[lexer.ParseInt()];

				loopCount = modelSurface.Geometry.Vertices.Length;

				for(int j = 0; j < loopCount; j++)
				{
					float[] vec = lexer.Parse1DMatrix(8);

					modelSurface.Geometry.Vertices[j].Position = new Vector3(vec[0], vec[1], vec[2]);
					modelSurface.Geometry.Vertices[j].TextureCoordinates = new Vector2(vec[3], vec[4]);
					modelSurface.Geometry.Vertices[j].Normal = new Vector3(vec[5], vec[6], vec[7]);
				}

				loopCount = modelSurface.Geometry.Indexes.Length;

				for(int j = 0; j < loopCount; j++)
				{
					modelSurface.Geometry.Indexes[j] = lexer.ParseInt();
				}

				lexer.ExpectTokenString("}");

				// add the completed surface to the model
				model.AddSurface(modelSurface);
			}

			lexer.ExpectTokenString("}");
			model.FinishSurfaces();

			return model;
		}
Example #6
0
		private bool ParseMaterial(idLexer lexer)
		{
			_parameters.MinDistance = 1;
			_parameters.MaxDistance = 10;
			_parameters.Volume = 1;

			_speakerMask = 0;
			_altSound = null;

			idToken token;
			string tokenValue;
			int sampleCount = 0;

			while(true)
			{
				if((token = lexer.ExpectAnyToken()) == null)
				{
					return false;
				}
				
				tokenValue = token.ToString().ToLower();
				
				if(tokenValue == "}")
				{
					break;
				}
				// minimum number of sounds
				else if(tokenValue == "minsamples")
				{
					sampleCount = lexer.ParseInt();
				}
				else if(tokenValue == "description")
				{
					_description = lexer.ReadTokenOnLine().ToString();
				}
				else if(tokenValue == "mindistance")
				{
					_parameters.MinDistance = lexer.ParseFloat();
				}
				else if(tokenValue == "maxdistance")
				{
					_parameters.MaxDistance = lexer.ParseFloat();
				}
				else if(tokenValue == "shakes")
				{
					token = lexer.ExpectAnyToken();

					if(token.Type == TokenType.Number)
					{
						_parameters.Shakes = token.ToFloat();
					}
					else
					{
						lexer.UnreadToken = token;
						_parameters.Shakes = 1.0f;
					}
				}
				else if(tokenValue == "reverb")
				{
					float reg0 = lexer.ParseFloat();

					if(lexer.ExpectTokenString(",") == false)
					{
						return false;
					}

					float reg1 = lexer.ParseFloat();
					// no longer supported
				}
				else if(tokenValue == "volume")
				{
					_parameters.Volume = lexer.ParseFloat();
				}
				// leadinVolume is used to allow light breaking leadin sounds to be much louder than the broken loop
				else if(tokenValue == "leadinvolume")
				{
					_leadInVolume = lexer.ParseFloat();
				}
				else if(tokenValue == "mask_center")
				{
					_speakerMask |= 1 << (int) Speakers.Center;
				}
				else if(tokenValue == "mask_left")
				{
					_speakerMask |= 1 << (int) Speakers.Left;
				}
				else if(tokenValue == "mask_right")
				{
					_speakerMask |= 1 << (int) Speakers.Right;
				}
				else if(tokenValue == "mask_backright")
				{
					_speakerMask |= 1 << (int) Speakers.BackRight;
				}
				else if(tokenValue == "mask_backleft")
				{
					_speakerMask |= 1 << (int) Speakers.BackLeft;
				}
				else if(tokenValue == "mask_lfe")
				{
					_speakerMask |= 1 << (int) Speakers.Lfe;
				}
				else if(tokenValue == "soundclass")
				{
					_parameters.SoundClass = lexer.ParseInt();

					if(_parameters.SoundClass < 0)
					{
						lexer.Warning("SoundClass out of range");
						return false;
					}
				}
				else if(tokenValue == "altsound")
				{
					if((token = lexer.ExpectAnyToken()) == null)
					{
						return false;
					}

					_altSound = idE.DeclManager.FindSound(token.ToString());
				}
				else if(tokenValue == "ordered")
				{
					// no longer supported
				}
				else if(tokenValue == "no_dups")
				{
					_parameters.Flags |= SoundMaterialFlags.NoDuplicates;
				}
				else if(tokenValue == "no_flicker")
				{
					_parameters.Flags |= SoundMaterialFlags.NoFlicker;
				}
				else if(tokenValue == "plain")
				{
					// no longer supported
				}
				else if(tokenValue == "looping")
				{
					_parameters.Flags |= SoundMaterialFlags.Looping;
				}
				else if(tokenValue == "no_occlusion")
				{
					_parameters.Flags |= SoundMaterialFlags.NoOcclusion;
				}
				else if(tokenValue == "private")
				{
					_parameters.Flags |= SoundMaterialFlags.PrivateSound;
				}
				else if(tokenValue == "antiprivate")
				{
					_parameters.Flags |= SoundMaterialFlags.AntiPrivateSound;
				}
				else if(tokenValue == "playonce")
				{
					_parameters.Flags |= SoundMaterialFlags.PlayOnce;
				}
				else if(tokenValue == "global")
				{
					_parameters.Flags |= SoundMaterialFlags.Global;
				}
				else if(tokenValue == "unclamped")
				{
					_parameters.Flags |= SoundMaterialFlags.Unclamped;
				}
				else if(tokenValue == "omnidirectional")
				{
					_parameters.Flags |= SoundMaterialFlags.OmniDirectional;
				}
				// onDemand can't be a parms, because we must track all references and overrides would confuse it
				else if(tokenValue == "ondemand")
				{
					// no longer loading sounds on demand
					// _onDemand = true;
				}
				// the wave files
				else if(tokenValue == "leadin")
				{
					// add to the leadin list
					if((token = lexer.ReadToken()) == null)
					{
						lexer.Warning("Expected sound after leadin");
						return false;
					}

					idConsole.Warning("TODO: leadin");

					/*if(soundSystemLocal.soundCache && numLeadins < maxSamples)
					{
						leadins[numLeadins] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
						numLeadins++;
					}*/
				}
				else if((tokenValue.EndsWith(".wav") == true) || (tokenValue.EndsWith(".ogg") == true))
				{
					idConsole.Warning("TODO: .wav|.ogg");

					/*// add to the wav list
					if(soundSystemLocal.soundCache && numEntries < maxSamples)
					{
						token.BackSlashesToSlashes();
						idStr lang = cvarSystem->GetCVarString("sys_lang");
						if(lang.Icmp("english") != 0 && token.Find("sound/vo/", false) >= 0)
						{
							idStr work = token;
							work.ToLower();
							work.StripLeading("sound/vo/");
							work = va("sound/vo/%s/%s", lang.c_str(), work.c_str());
							if(fileSystem->ReadFile(work, NULL, NULL) > 0)
							{
								token = work;
							}
							else
							{
								// also try to find it with the .ogg extension
								work.SetFileExtension(".ogg");
								if(fileSystem->ReadFile(work, NULL, NULL) > 0)
								{
									token = work;
								}
							}
						}
						entries[numEntries] = soundSystemLocal.soundCache->FindSound(token.c_str(), onDemand);
						numEntries++;
					}*/
				}
				else
				{
					lexer.Warning("unknown token '{0}'", token.ToString());
					return false;
				}
			}

			if(_parameters.Shakes > 0.0f)
			{
				idConsole.Warning("TODO: CheckShakesAndOgg()");
			}

			return true;
		}