Пример #1
0
 public FireMaterial()
 {
     if (Texture == null)
     {
         var img = Png.Decode("flame.png", File.OpenRead("flame.png"));
         img.FlipY();
         Texture = new Texture(img, true);
     }
 }
Пример #2
0
 static List <Material> FromSkin(OESSkin skin, ZipArchive zip) =>
 skin.Find <OESMaterial>().Select(mat => {
     if (mat.Find <OESEffect>().Any(x => x.Name == "fire"))
     {
         return(null);                        // TODO: Unhack
     }
     return(new Material(
                (mat.Transparent ? MaterialFlag.Translucent : MaterialFlag.Normal) |
                (mat.AlphaMask ? MaterialFlag.Masked : MaterialFlag.Normal),
                mat.Find <OESEffect>().FirstOrDefault(x => x.Name == "animated")?.Get <uint>("speed") ?? 0,
                mat.Find <OESTexture>().Select(x => {
         using (var tzs = zip.GetEntry(x.Filename).Open())
             return Png.Decode(tzs);
     }).ToArray()
                ));
 }).ToList();
Пример #3
0
        static List <Material> FromSkin(OESSkin skin, ZipArchive zip) =>
        skin.Find <OESMaterial>().Select(mat => {
            var effect = mat.Find <OESEffect>().FirstOrDefault();
            effect     = effect ?? new OESEffect("default");

            var textures = mat.Find <OESTexture>().Select(x => {
                using (var tzs = zip.GetEntry(x.Filename)?.Open())
                    return(Png.Decode(Path.GetFileName(x.Filename), tzs));
            }).ToArray();

            switch (effect.Name)
            {
            case "default":
            case "animated":
                var aniSpeed = effect.Name == "animated" ? (uint)effect["speed"] / 1000f : 0;
                if (mat.Transparent)
                {
                    return(mat.AlphaMask
                                                                ? (Material) new ForwardDiffuseMaskedMaterial(textures, aniSpeed)
                                                                : new ForwardDiffuseMaterial(textures, aniSpeed));
                }
                else
                {
                    return(mat.AlphaMask
                                                                ? (Material) new DeferredDiffuseMaskedMaterial(textures, aniSpeed)
                                                                : new DeferredDiffuseMaterial(textures, aniSpeed));
                }

            case "diffuse+normal":
                return(new DeferredDiffuseNormalMaterial(textures));

            case "fire":
                return(new FireMaterial());

            default:
                throw new NotImplementedException($"Unknown OESEffect name: {effect.Name}");
            }
        }).ToList();
Пример #4
0
        public FireMaterial()
        {
            if (Program == null)
            {
                Program = new Program(@"
#version 410
precision highp float;
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in mat4 aModelMat;
uniform mat4 uProjectionViewMat;
out vec3 vPosition;
out vec2 vTexCoord;
void main() {
	vec4 pos = aModelMat * aPosition;
	gl_Position = uProjectionViewMat * pos;
	vPosition = pos.xyz;
	vTexCoord = aTexCoord;
}
					"                    , @"
#version 410
precision highp float;
in vec3 vPosition;
in vec2 vTexCoord;
out vec4 color;
uniform float uTime;
uniform sampler2D uTex;

vec4 fire(float time, vec2 tc) {
	// Generate noisy x value
	vec2 n0Uv = vec2(tc.x*1.4 + 0.01, tc.y - time*0.69);
	vec2 n1Uv = vec2(tc.x*0.5 - 0.033, tc.y*2.0 - time*0.12);
	vec2 n2Uv = vec2(tc.x*0.94 + 0.02, tc.y*3.0 - time*0.61);
	float n0 = (texture(uTex, n0Uv).w-0.5)*2.0;
	float n1 = (texture(uTex, n1Uv).w-0.5)*2.0;
	float n2 = (texture(uTex, n2Uv).w-0.5)*2.0;
	float noiseA = clamp(n0 + n1 + n2, -1.0, 1.0);
	
	// Generate noisy y value
	vec2 n0UvB = vec2(tc.x*0.7 - 0.01, tc.y - time*0.27);
	vec2 n1UvB = vec2(tc.x*0.45 + 0.033, tc.y*1.9 - time*0.71);
	vec2 n2UvB = vec2(tc.x*0.8 - 0.02, tc.y*2.5 - time*0.63);
	float n0B = (texture(uTex, n0UvB).w-0.5)*2.0;
	float n1B = (texture(uTex, n1UvB).w-0.5)*2.0;
	float n2B = (texture(uTex, n2UvB).w-0.5)*2.0;
	float noiseB = clamp(n0B + n1B + n2B, -1.0, 1.0);
	
	vec2 finalNoise = vec2(noiseA, noiseB);
	float perturb = (1.0 - tc.y) * 0.35 + 0.02;
	finalNoise = (finalNoise * perturb) + tc - 0.02;
	vec4 ret = texture(uTex, finalNoise);
	ret = vec4(ret.x*2.0, ret.y*0.9, (ret.y/ret.x)*0.2, 1.0);
	finalNoise = clamp(finalNoise, 0.05, 1.0);
	ret.w = texture(uTex, finalNoise).z*2.0;
	ret.w = ret.w*texture(uTex, tc / vec2(1.3, 1.5)).z;
	ret *= vec4(1.0, 1.3, 0.5, 0.6);
	return ret;
}

void main() {
	float time = uTime * 1.3 + length(vPosition);
	vec2 tc = abs(mod(vTexCoord, 1));
	if(tc.y > .95) discard;
	color = (fire(mod(time, 10), tc) + fire(mod(time + .05, 10), tc)) / 2;
}
				"                );
                Program.SetUniform("uTex", 0);
                var img = Png.Decode(File.OpenRead("flame.png"));
                img.FlipY();
                Texture = new Texture(img, true);
            }
        }
Пример #5
0
        public Mesh(Material material, float[] vdata, uint[] indices, Matrix4x4[] modelMatrices)
        {
            if (DeferredProgram == null)
            {
                DeferredProgram = new Program(@"
#version 410
precision highp float;
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in mat4 aModelMat;
uniform mat4 uProjectionViewMat;
out vec2 vTexCoord;
void main() {
	gl_Position = uProjectionViewMat * aModelMat * aPosition;
	vTexCoord = aTexCoord;
}
			"            , @"
#version 410
precision highp float;
in vec3 vPosition;
in vec2 vTexCoord;
layout (location = 0) out vec4 color;
uniform sampler2D uTex;
uniform bool uMasked;
void main() {
	color = texture(uTex, vTexCoord);
	if(uMasked && color.a < 0.5)
		discard;
	color.a = 0;
}
				"                );
                ForwardProgram  = new Program(@"
#version 410
precision highp float;
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in mat4 aModelMat;
uniform mat4 uProjectionViewMat;
out vec2 vTexCoord;
void main() {
	gl_Position = uProjectionViewMat * aModelMat * aPosition;
	vTexCoord = aTexCoord;
}
			"            , @"
#version 410
precision highp float;
in vec3 vPosition;
in vec2 vTexCoord;
out vec4 color;
uniform sampler2D uTex;
uniform bool uMasked;
void main() {
	color = texture(uTex, vTexCoord);
	if(uMasked)
		color.a *= (color.r + color.g + color.b) / 3;
}
				"                );

                // Credit: http://clockworkchilli.com/blog/8_a_fire_shader_in_glsl_for_your_webgl_games
                FireProgram = new Program(@"
#version 410
precision highp float;
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoord;
layout (location = 3) in mat4 aModelMat;
uniform mat4 uProjectionViewMat;
out vec3 vPosition;
out vec2 vTexCoord;
void main() {
	vec4 pos = aModelMat * aPosition;
	gl_Position = uProjectionViewMat * pos;
	vPosition = pos.xyz;
	vTexCoord = aTexCoord;
}
			"            , @"
#version 410
precision highp float;
in vec3 vPosition;
in vec2 vTexCoord;
out vec4 color;
uniform float uTime;
uniform sampler2D uTex;

vec4 fire(float time, vec2 tc) {
	// Generate noisy x value
	vec2 n0Uv = vec2(tc.x*1.4 + 0.01, tc.y - time*0.69);
	vec2 n1Uv = vec2(tc.x*0.5 - 0.033, tc.y*2.0 - time*0.12);
	vec2 n2Uv = vec2(tc.x*0.94 + 0.02, tc.y*3.0 - time*0.61);
	float n0 = (texture(uTex, n0Uv).w-0.5)*2.0;
	float n1 = (texture(uTex, n1Uv).w-0.5)*2.0;
	float n2 = (texture(uTex, n2Uv).w-0.5)*2.0;
	float noiseA = clamp(n0 + n1 + n2, -1.0, 1.0);
	
	// Generate noisy y value
	vec2 n0UvB = vec2(tc.x*0.7 - 0.01, tc.y - time*0.27);
	vec2 n1UvB = vec2(tc.x*0.45 + 0.033, tc.y*1.9 - time*0.71);
	vec2 n2UvB = vec2(tc.x*0.8 - 0.02, tc.y*2.5 - time*0.63);
	float n0B = (texture(uTex, n0UvB).w-0.5)*2.0;
	float n1B = (texture(uTex, n1UvB).w-0.5)*2.0;
	float n2B = (texture(uTex, n2UvB).w-0.5)*2.0;
	float noiseB = clamp(n0B + n1B + n2B, -1.0, 1.0);
	
	vec2 finalNoise = vec2(noiseA, noiseB);
	float perturb = (1.0 - tc.y) * 0.35 + 0.02;
	finalNoise = (finalNoise * perturb) + tc - 0.02;
	vec4 ret = texture(uTex, finalNoise);
	ret = vec4(ret.x*2.0, ret.y*0.9, (ret.y/ret.x)*0.2, 1.0);
	finalNoise = clamp(finalNoise, 0.05, 1.0);
	ret.w = texture(uTex, finalNoise).z*2.0;
	ret.w = ret.w*texture(uTex, tc / vec2(1.3, 1.5)).z;
	ret *= vec4(1.0, 1.3, 0.5, 0.6);
	return ret;
}

void main() {
	float time = uTime * 1.3 + length(vPosition);
	vec2 tc = mod(vTexCoord, 1);
	if(tc.y > .95) discard;
	color = (fire(mod(time, 10), tc) + fire(mod(time + .05, 10), tc)) / 2;
}
				"                );
                var img = Png.Decode(File.OpenRead("flame.png"));
                img.FlipY();
                FlameTexture = new Texture(img, true);
            }

            Material = material;

            GL.BindVertexArray(Vao = GL.GenVertexArray());
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, Ibo = GL.GenBuffer());
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * 4, indices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, Pbo = GL.GenBuffer());
            GL.BufferData(BufferTarget.ArrayBuffer, vdata.Length * 4, vdata, BufferUsageHint.StaticDraw);
            var pp = 0;             // aPosition

            GL.EnableVertexAttribArray(pp);
            GL.VertexAttribPointer(pp, 3, VertexAttribPointerType.Float, false, (3 + 3 + 2) * 4, 0);
            pp = 1;             // aNormal
            GL.EnableVertexAttribArray(pp);
            GL.VertexAttribPointer(pp, 3, VertexAttribPointerType.Float, false, (3 + 3 + 2) * 4, 3 * 4);
            pp = 2;             // aTexCoord
            GL.EnableVertexAttribArray(pp);
            GL.VertexAttribPointer(pp, 2, VertexAttribPointerType.Float, false, (3 + 3 + 2) * 4, (3 + 3) * 4);

            GL.BindBuffer(BufferTarget.ArrayBuffer, Mbo = GL.GenBuffer());
            GL.BufferData(BufferTarget.ArrayBuffer, modelMatrices.Length * 16 * 4,
                          modelMatrices.Select(x => x.AsArray()).SelectMany(x => x).ToArray(), BufferUsageHint.StaticDraw);
            pp = 3;             // aModelMat
            GL.EnableVertexAttribArray(pp);
            GL.VertexAttribPointer(pp, 4, VertexAttribPointerType.Float, false, 4 * 16, 0);
            GL.VertexAttribDivisor(pp, 1);
            GL.EnableVertexAttribArray(pp + 1);
            GL.VertexAttribPointer(pp + 1, 4, VertexAttribPointerType.Float, false, 4 * 16, 4 * 4);
            GL.VertexAttribDivisor(pp + 1, 1);
            GL.EnableVertexAttribArray(pp + 2);
            GL.VertexAttribPointer(pp + 2, 4, VertexAttribPointerType.Float, false, 4 * 16, 8 * 4);
            GL.VertexAttribDivisor(pp + 2, 1);
            GL.EnableVertexAttribArray(pp + 3);
            GL.VertexAttribPointer(pp + 3, 4, VertexAttribPointerType.Float, false, 4 * 16, 12 * 4);
            GL.VertexAttribDivisor(pp + 3, 1);

            ElementCount  = indices.Length;
            InstanceCount = modelMatrices.Length;
        }