Exemplo n.º 1
0
    private bool IsFluidFaceVisible(int curLevel, int nX, int nY, int nZ, Block neighbor, int neighborFace)
    {
        if (neighborFace == Direction.Down && curLevel < 5)
        {
            return(true);
        }

        CullType cull = neighbor.GetCullType(neighborFace);

        if (cull == CullType.Solid || cull == CullType.Cutout)
        {
            return(false);
        }

        if (cull == CullType.Transparent)
        {
            if (!neighbor.IsFluid())
            {
                return(false);
            }

            if (neighborFace == Direction.Up || neighborFace == Direction.Down)
            {
                return(false);
            }

            return(neighbor.FluidLevel < curLevel);
        }

        return(true);
    }
        /// <summary>
        /// 设置CullingGroup的距离分区
        /// 例如传入三个值,10,20,30
        /// 如果距离在10以内,代表摄像机范围
        /// 如果距离在20以内,代表超出范围
        /// 如果距离在30以内,代表足够远,超出则代表非常远
        /// </summary>
        /// <param name="_distanceBands"></param>
        public void SetDistanceBands(params float[] _distanceBands)
        {
            if (cullType == CullType.ViewCull)
            {
                cullingGroup.onStateChanged = OnStateDistanceChanged;
                cullType = CullType.DistanceCull;
            }

            cullingGroup.SetBoundingDistances(_distanceBands);
        }
        public ViewCullingGroup(int _maxSize)
        {
            maxSize = _maxSize;
            currentRequestingCount = 0;

            cullingGroup                = new CullingGroup();
            boundingSpheres             = new BoundingSphere[maxSize];
            viewCullingObjects          = new IViewCullingObject[maxSize];
            cullingGroup.onStateChanged = OnStateVisibilityChanged;
            cullType = CullType.ViewCull;

            cullingGroup.SetBoundingSpheres(boundingSpheres);
            cullingGroup.SetBoundingSphereCount(currentRequestingCount);
        }
Exemplo n.º 4
0
    public bool IsFaceVisible(Block neighbor, int face)
    {
        switch (ID)
        {
        case BlockID.TallGrass:
            return(true);

        case BlockID.Cloud:
            CullType cull = neighbor.GetCullType(face);

            if (cull == CullType.Solid || cull == CullType.Cutout)
            {
                return(false);
            }

            if (cull == CullType.Transparent)
            {
                return(neighbor.IsFluid());
            }

            return(true);

        case BlockID.Leaves:
            if (neighbor.ID == BlockID.Leaves)
            {
                if (face == Direction.Left || face == Direction.Back || face == Direction.Down)
                {
                    return(false);
                }

                return(true);
            }

            goto default;

        default:
            return(neighbor.GetCullType(face) != CullType.Solid);
        }
    }
Exemplo n.º 5
0
		/// <summary>
		/// This handles the flipping needed when the view being rendered is a mirrored view.
		/// </summary>
		/// <param name="type"></param>
		private void SetCull(CullType type)
		{
			if(_state.FaceCulling == type)
			{
				return;
			}

			if(type == CullType.TwoSided)
			{
				// TODO: Gl.glDisable(Gl.GL_CULL_FACE);
			}
			else
			{
				if(_state.FaceCulling == CullType.TwoSided)
				{
					// TODO: Gl.glDisable(Gl.GL_CULL_FACE);
				}

				if(type == CullType.TwoSided)
				{
					if(_viewDef.IsMirror == true)
					{
						// TODO: Gl.glCullFace(Gl.GL_FRONT);
					}
					else
					{
						// TODO: Gl.glCullFace(Gl.GL_BACK);
					}
				}
				else
				{
					if(_viewDef.IsMirror == true)
					{
						// TODO: Gl.glCullFace(Gl.GL_BACK);
					}
					else
					{
						// TODO: Gl.glCullFace(Gl.GL_FRONT);
					}
				}
			}

			_state.FaceCulling = type;
		}
Exemplo n.º 6
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;
					}
				}
			}
		}
Exemplo n.º 7
0
		private void Clear()
		{
			_description = "<none>";
			_renderBump = string.Empty;

			_contentFlags = ContentFlags.Solid;
			_surfaceFlags = SurfaceFlags.None;
			_materialFlags = 0;

			_sort = (float) MaterialSort.Bad;
			_coverage = MaterialCoverage.Bad;
			_cullType = CullType.Front;

			_deformType = DeformType.None;
			_deformRegisters = new int[4];

			_ops = null;
			_expressionRegisters = null;
			_constantRegisters = null;
			_stages = new MaterialStage[] { };

			_stageCount = 0;
			_ambientStageCount = 0;
			_registerCount = 0;
			
			_lightFalloffImage = null;
			_entityGui = 0;
			_shouldCreateBackSides = false;
			_editorImageName = null;

			_fogLight = false;
			_blendLight = false;
			_ambientLight = false;
			_noFog = false;
			_hasSubview = false;
			_allowOverlays = true;
			_unsmoothedTangents = false;

			_userInterface = null;
			_referenceCount = 0;
			
			/*editorAlpha = 1.0;*/
			_spectrum = 0;

			_polygonOffset = 0;
			_suppressInSubview = false;
			_portalSky = false;

			_decalInfo.StayTime = 10000;
			_decalInfo.FadeTime = 4000;
			_decalInfo.Start = new float[] { 1, 1, 1, 1 };
			_decalInfo.End = new float[] { 0, 0, 0, 0 };
		}
Exemplo n.º 8
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;
			}
		}
Exemplo n.º 9
0
 private static extern void Pass_SetCullType(IntPtr Pass, CullType Mode);
Exemplo n.º 10
0
        void CompileShader(string vertexSrc, string fragmentSrc)
        {
            void GetUniform(string line)
            {
                var    elements = line.Split(' ');
                string type     = elements[1];
                string name     = elements[2].Trim(';');

                Debug.Log($"Found uniform: {name} of type {type}");

                //TODO Add to dictionary/list/whatever
                uniforms.Add(name, new Uniform(name, GetUniformLocation(name), this, null));
            }

            void CheckForUniforms(string src)
            {
                var lines = src.Split('\n');

                foreach (var line in lines)
                {
                    if (line.Contains("uniform") && !line.StartsWith("//") && !line.Contains("layout(std140)"))
                    {
                        GetUniform(line);
                    }
                }
            }

            void CheckForIncludes()
            {
                Check(ref vertexSrc);
                Check(ref fragmentSrc);

                void Check(ref string source)
                {
                    var lines = source.Split('\n');

                    foreach (var line in lines)
                    {
                        if (line.StartsWith("#include "))
                        {
                            string inc      = line.Split(' ')[1].Trim('"');
                            string location = "Resources/Shaders/" + inc;

                            var          entry        = AssetDatabase.GetPackageFile()[location];
                            MemoryStream outputStream = new MemoryStream();
                            entry.Extract(outputStream);
                            string text = Encoding.ASCII.GetString(outputStream.ToArray());

                            text = text.Replace("?", "").Replace("\r", "").Replace("\t", "");

                            string file = text;
                            source = source.Replace(line, file);
                        }
                    }
                }
            }

            void CheckForQueue()
            {
                var lines = fragmentSrc.Split('\n');

                foreach (var line in lines)
                {
                    if (line.StartsWith("#queue"))
                    {
                        var types = line.Split(' ');
                        var type  = types[1];
                        if (type == "transparent")
                        {
                            IsTransparent = true;
                        }
                        else
                        {
                            IsTransparent = false;
                        }

                        fragmentSrc = fragmentSrc.Replace(line, "");
                    }
                }
            }

            void CheckForBlending()
            {
                var lines = fragmentSrc.Split('\n');

                foreach (var line in lines)
                {
                    if (line.StartsWith("#blend"))
                    {
                        var types = line.Split(' ');
                        var type  = types[1];
                        if (type == "none")
                        {
                            Blending = BlendType.None;
                        }
                        else if (type == "oneminus")
                        {
                            Blending = BlendType.OneMinus;
                        }

                        fragmentSrc = fragmentSrc.Replace(line, "");
                    }
                }
            }

            void CheckForCulling()
            {
                var lines = fragmentSrc.Split('\n');

                foreach (var line in lines)
                {
                    if (line.StartsWith("#culling"))
                    {
                        var types = line.Split(' ');
                        var type  = types[1];
                        if (type == "front")
                        {
                            CullingType = CullType.Front;
                        }
                        else if (type == "none")
                        {
                            CullingType = CullType.None;
                        }
                        else if (type == "back")
                        {
                            CullingType = CullType.Back;
                        }

                        fragmentSrc = fragmentSrc.Replace(line, "");
                    }
                }
            }

            int vertShader = 0, fragShader = 0;

            CheckForIncludes();

            CheckForQueue();
            CheckForBlending();
            CheckForCulling();

            vertShader = GL.CreateShader(ShaderType.VertexShader);
            GL.ShaderSource(vertShader, vertexSrc);

            fragShader = GL.CreateShader(ShaderType.FragmentShader);
            GL.ShaderSource(fragShader, fragmentSrc);

            GL.CompileShader(vertShader);

            string infoLogVert = GL.GetShaderInfoLog(vertShader);

            if (infoLogVert != System.String.Empty)
            {
                //Debug.Assert(infoLogVert);
                throw new Exception("Vertex Shader " + vertShader + " failed to compile!\n" + infoLogVert);
            }
            else
            {
                Debug.Log($"VertexContainer shader {vertShader} compiled successfully!");
            }

            GL.CompileShader(fragShader);

            string infoLogFrag = GL.GetShaderInfoLog(fragShader);

            if (infoLogFrag != System.String.Empty)
            {
                throw new Exception("FragShader " + fragShader + " failed to compile!\n" + infoLogFrag);
            }
            else
            {
                Debug.Log($"Fragment shader {fragShader} compiled successfully!");
            }

            Handle = GL.CreateProgram();

            GL.AttachShader(Handle, vertShader);
            GL.AttachShader(Handle, fragShader);

            GL.LinkProgram(Handle);

            GL.DetachShader(Handle, vertShader);
            GL.DetachShader(Handle, fragShader);

            GL.DeleteShader(vertShader);
            GL.DeleteShader(fragShader);

            CheckForUniforms(vertexSrc);
            CheckForUniforms(fragmentSrc);
        }
Exemplo n.º 11
0
 public Cull(CullType side)
 {
     this.Side = side;
 }
Exemplo n.º 12
0
 public Cull()
 {
     this.Side = CullType.Back;
 }