public string Print(IFixedFunctionMaterial material) { var sb = new StringBuilder(); using var os = new StringWriter(sb); this.Print(os, material); return(sb.ToString()); }
public static ITexture?GetFor(IFixedFunctionMaterial material) { var equations = material.Equations; var textures = material.Textures; // TODO: Use some kind of priority class var compiledTexture = material.CompiledTexture; if (compiledTexture != null) { return(compiledTexture); } var prioritizedTextures = textures // Sort by UV type, "normal" first .OrderByDescending( texture => texture.ColorType == ColorType.COLOR) .ThenByDescending( texture => BitmapUtil.GetTransparencyType( texture.ImageData) == BitmapTransparencyType.OPAQUE) .ToArray(); if (prioritizedTextures.Length > 0) { // TODO: First or last? return(prioritizedTextures[0]); } return(material.Textures.LastOrDefault((ITexture?)null)); // TODO: Prioritize textures w/ color rather than intensity // TODO: Prioritize textures w/ standard texture sets }
public GlFixedFunctionMaterialShader( IFixedFunctionMaterial fixedFunctionMaterial) { this.Material = fixedFunctionMaterial; // TODO: Sometimes vertex colors are passed in from model, and sometimes they // represent lighting. How to tell the difference?? var vertexShaderSrc = @" # version 120 in vec2 in_uv0; varying vec3 vertexNormal; varying vec2 normalUv; varying vec4 vertexColor0_; varying vec4 vertexColor1_; varying vec2 uv0; varying vec2 uv1; varying vec2 uv2; varying vec2 uv3; void main() { gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; vertexNormal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0)).xyz; normalUv = normalize(gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(gl_Normal, 0)).xy; vertexColor0_ = vec4(0.5, 0.5, 0.5, 1); vertexColor1_ = vec4(0, 0, 0, 1); uv0 = gl_MultiTexCoord0.st; uv1 = gl_MultiTexCoord1.st; uv2 = gl_MultiTexCoord2.st; uv3 = gl_MultiTexCoord3.st; }"; var pretty = new FixedFunctionEquationsPrettyPrinter <FixedFunctionSource>() .Print(fixedFunctionMaterial.Equations); var fragmentShaderSrc = new FixedFunctionEquationsGlslPrinter( fixedFunctionMaterial.TextureSources) .Print(fixedFunctionMaterial); this.impl_ = GlShaderProgram.FromShaders(vertexShaderSrc, fragmentShaderSrc); var finTextures = fixedFunctionMaterial.TextureSources; var nSupportedTextures = 8; this.textures_ = new List <GlTexture>(); for (var i = 0; i < nSupportedTextures; ++i) { var finTexture = i < (finTextures?.Count ?? 0) ? finTextures[i] : null; this.textures_.Add(finTexture != null ? new GlTexture(finTexture) : GlMaterialConstants.NULL_WHITE_TEXTURE); } }
public void Print( StringWriter os, IFixedFunctionMaterial material) { var equations = material.Equations; os.WriteLine("# version 130"); os.WriteLine(); for (var t = 0; t < 8; ++t) { if (equations.ColorInputs.ContainsKey( FixedFunctionSource.TEXTURE_COLOR_0 + t) || equations.ColorInputs.ContainsKey( FixedFunctionSource.TEXTURE_ALPHA_0 + t) || equations.ScalarInputs.ContainsKey( FixedFunctionSource.TEXTURE_ALPHA_0 + t)) { os.WriteLine($"uniform sampler2D texture{t};"); } } os.WriteLine(); os.WriteLine("in vec2 normalUv;"); os.WriteLine("in vec3 vertexNormal;"); os.WriteLine("in vec4 vertexColor0_;"); os.WriteLine("in vec4 vertexColor1_;"); for (var i = 0; i < 4; ++i) { os.WriteLine($"in vec2 uv{i};"); } os.WriteLine(); os.WriteLine("out vec4 fragColor;"); os.WriteLine(); os.WriteLine("void main() {"); // TODO: Define inputs once as needed up here. os.WriteLine(@" vec3 diffuseLightNormal = normalize(vec3(.5, .5, -1)); float diffuseLightAmount = max(-dot(vertexNormal, diffuseLightNormal), 0); float ambientLightAmount = .3; float lightAmount = min(ambientLightAmount + diffuseLightAmount, 1); vec3 lightColor = vec3(.5, .5, .5); vec4 vertexColor0 = vec4(lightAmount * lightColor, 1);"); os.WriteLine(); os.WriteLine(" vec3 ambientLightColor = vec3(0, 0, 0);"); os.WriteLine(" vec4 vertexColor1 = vec4(ambientLightColor, 1);"); os.WriteLine(); // TODO: Get tree of all values that this depends on, in case there needs to be other variables defined before. var outputColor = equations.ColorOutputs[FixedFunctionSource.OUTPUT_COLOR]; os.Write(" vec3 colorComponent = "); this.PrintColorValue_(os, outputColor.ColorValue); os.WriteLine(";"); os.WriteLine(); var outputAlpha = equations.ScalarOutputs[FixedFunctionSource.OUTPUT_ALPHA]; os.Write(" float alphaComponent = "); this.PrintScalarValue_(os, outputAlpha.ScalarValue); os.WriteLine(";"); os.WriteLine(); os.WriteLine(" fragColor = vec4(colorComponent, alphaComponent);"); var alphaOpValue = DetermineAlphaOpValue( material.AlphaOp, DetermineAlphaCompareType( material.AlphaCompareType0, material.AlphaReference0), DetermineAlphaCompareType( material.AlphaCompareType1, material.AlphaReference1)); if (alphaOpValue != AlphaOpValue.ALWAYS_TRUE) { os.WriteLine(); var alphaCompareText0 = GetAlphaCompareText_(material.AlphaCompareType0, material.AlphaReference0); var alphaCompareText1 = GetAlphaCompareText_(material.AlphaCompareType1, material.AlphaReference1); switch (alphaOpValue) { case AlphaOpValue.ONLY_0_REQUIRED: { os.WriteLine($@" if (!({alphaCompareText0})) {{ discard; }}"); break; } case AlphaOpValue.ONLY_1_REQUIRED: { os.WriteLine($@" if (!({alphaCompareText1})) {{ discard; }}"); break; } case AlphaOpValue.BOTH_REQUIRED: { switch (material.AlphaOp) { case AlphaOp.And: { os.Write( $" if (!({alphaCompareText0} && {alphaCompareText1})"); break; } case AlphaOp.Or: { os.Write( $" if (!({alphaCompareText0} || {alphaCompareText1})"); break; } case AlphaOp.XOR: { os.WriteLine($" bool a = {alphaCompareText0};"); os.WriteLine($" bool b = {alphaCompareText1};"); os.Write( $" if (!(any(bvec2(all(bvec2(!a, b)), all(bvec2(a, !b)))))"); break; } case AlphaOp.XNOR: { os.WriteLine($" bool a = {alphaCompareText0};"); os.WriteLine($" bool b = {alphaCompareText1};"); os.Write( " if (!(any(bvec2(all(bvec2(!a, !b)), all(bvec2(a, b)))))"); break; } default: throw new ArgumentOutOfRangeException(); } os.WriteLine(@") { discard; }"); break; } case AlphaOpValue.ALWAYS_FALSE: { os.WriteLine(" discard;"); break; } default: throw new ArgumentOutOfRangeException(); } } os.WriteLine("}"); }