public Wireframe(IEnumerable <Triangle> mesh) { var vdata = new List <Vector3>(); foreach (var tri in mesh) { vdata.Add(tri.A); vdata.Add(Vector3.UnitX); vdata.Add(tri.B); vdata.Add(Vector3.UnitY); vdata.Add(tri.C); vdata.Add(Vector3.UnitZ); } Vao = new Vao(); Vao.Attach(new Buffer <Vector3>(vdata.ToArray()), (0, typeof(Vector3)), (1, typeof(Vector3))); VertexCount = vdata.Count / 6; Program = new Program(@" #version 410 precision highp float; layout (location = 0) in vec4 aPosition; layout (location = 1) in vec3 aBarycentric; uniform mat4 uProjectionViewMat; out vec3 vBarycentric; void main() { vBarycentric = aBarycentric; gl_Position = uProjectionViewMat * aPosition; } " , @" #version 410 precision highp float; in vec3 vBarycentric; layout (location = 0) out vec4 color; uniform sampler2D uTex; vec3 fwidth(vec3 p) { return abs(dFdx(p)) + abs(dFdy(p)); } void main() { vec3 d = fwidth(vBarycentric); vec3 a3 = smoothstep(vec3(0), d * 1.5, vBarycentric); color = vec4(1 - min(min(a3.x, a3.y), a3.z)); } " ); }
public Mesh(Material material, float[] vdata, uint[] indices, bool isCollidable) { Material = material; Vao = new Vao(); Vao.Attach(IndexBuffer = new Buffer <uint>(indices, BufferTarget.ElementArrayBuffer)); Vao.Attach(VertexBuffer = new Buffer <float>(vdata), (0, typeof(Vector3)), (1, typeof(Vector3)), (2, typeof(Vector2))); IsCollidable = isCollidable; if (IsCollidable) { PhysicsMesh = (indices.Length / 3).Times(i => { i *= 3; Vector3 GetPoint(int off) { var voff = indices[i + off] * 8; return(vec3(vdata[voff + 0], vdata[voff + 1], vdata[voff + 2])); } return(new Triangle(GetPoint(0), GetPoint(1), GetPoint(2))); }).ToList(); } }
void SetupDeferredPathway() { if (DeferredSetup || !DeferredEnabled) { return; } DeferredSetup = true; FBO = new FrameBuffer(Width, Height, FrameBufferAttachment.Rgb, FrameBufferAttachment.Xyz, FrameBufferAttachment.Depth); Resize += (_, __) => FBO.Resize(Width, Height); QuadVAO = new Vao(); QuadVAO.Attach(new Buffer <uint>(new[] { 0U, 1U, 2U, 3U, 4U, 5U }, BufferTarget.ElementArrayBuffer)); QuadVAO.Attach(new Buffer <float>(new[] { -1f, -1f, 1f, -1f, 1f, 1f, -1f, -1f, 1f, 1f, -1f, 1f }), (0, typeof(Vector2))); Program = new Program(@" #version 410 precision highp float; in vec2 aPosition; out vec2 vTexCoord; void main() { gl_Position = vec4(aPosition, 0.0, 1.0); vTexCoord = aPosition.xy * 0.5 + 0.5; } " , @" #version 410 precision highp float; in vec2 vTexCoord; struct Light { vec3 pos, color; float radius; }; uniform mat4 uInvProjectionViewMat; uniform sampler2D uColor, uNormal, uDepth; uniform vec3 uAmbientColor; uniform Light uLights[" + maxLights + @"]; uniform int uLightCount; out vec4 color; void main() { gl_FragDepth = texture(uDepth, vTexCoord).x; // Copy depth from FBO to screen depth buffer vec3 csv = texture(uColor, vTexCoord).rgb; vec3 normal = normalize(texture(uNormal, vTexCoord).xyz); vec4 sspos = uInvProjectionViewMat * (vec4(vTexCoord.xy, gl_FragDepth, 1) * 2 - 1); vec3 pos = sspos.xyz / sspos.w; vec3 accum = uAmbientColor; for(int i = 0; i < uLightCount; ++i) { Light light = uLights[i]; vec3 toLight = light.pos - pos; float dist = length(toLight); float intensity = min(max(dot(normal, toLight / dist), 0.0), 1); accum += light.color * pow(1 - min(dist / light.radius, 1), 3) * intensity; } color = vec4(csv * accum, 1); } " ); Program.Use(); UniformLocs = Enumerable.Range(0, maxLights).Select(i => new[] { Program.GetUniform($"uLights[{i}].pos"), Program.GetUniform($"uLights[{i}].color"), Program.GetUniform($"uLights[{i}].radius") }).SelectMany(x => x).ToArray(); UniformLC = Program.GetUniform("uLightCount"); }