public static Mesh BezierPatch(float width, float height, int pointSet) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var vertexCount = 16; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; var segmentsX = 3; var segmentsZ = 3; float deltaW = width / 3; float deltaH = height / 3; var cpSet = SelectCPSet(pointSet); for (int z = 0; z <= segmentsX; z++) { for (int x = 0; x <= segmentsZ; x++) { var pos = cpSet[x + z * (segmentsX + 1)]; var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / segmentsX, (float)z / segmentsZ); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } uint[] indices = new uint[16]; for (int i = 0; i < 16; i++) { indices[i] = (uint)i; } mesh.SetBufferData(vertices, indices, BufferUsageHint.StaticDraw); return(mesh); }
public void SetDrawablePmx(ICommonContents common, BackgroundWorker worker) { if (VertexLayout != null) { VertexLayout.Dispose(); } if (VertexBuffer != null) { VertexBuffer.Dispose(); } if (IndexBuffer != null) { IndexBuffer.Dispose(); } if (EffectManager != null) { EffectManager.Dispose(); } Device = common.Effect.Device; SetEffectManager(new EffectManager11(common.Effect), false); initVertexLayout(Device, common.Effect); initVertexBuffer(Device, worker); initIndexBuffer(Device, worker); m_Materials.Clear(); int indexOffset = 0; foreach (var ipxMaterial in Pmx.Material) { var tmpMaterial = new DrawableMaterial(ipxMaterial, indexOffset); tmpMaterial.SetTextures(common); m_Materials.Add(tmpMaterial); indexOffset += ipxMaterial.Faces.Count * 3; } }
public static Mesh PlaneMesh(PrimitiveType type, float width, float height, int segmentsX = 1, int segmentsZ = 1) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var vertexCount = 4 + 2 * (segmentsX - 1) + (1 + segmentsX) * (segmentsZ - 1); float deltaW = width / segmentsX; float deltaH = height / segmentsZ; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; for (int z = 0; z <= segmentsZ; z++) { for (int x = 0; x <= segmentsX; x++) { var pos = new Vector3(-width * 0.5f + deltaW * x, 0.0f, -height * 0.5f + deltaH * z); var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / segmentsX, (float)z / segmentsZ); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } if (type == PrimitiveType.Triangles) { mesh.SetBufferData(vertices, PlaneIndicesTriangles(segmentsX, segmentsZ), BufferUsageHint.StaticDraw); } else if (type == PrimitiveType.Patches) { mesh.SetBufferData(vertices, PlaneIndicesPatches(segmentsX, segmentsZ), BufferUsageHint.StaticDraw); } else { throw new InvalidOperationException("Only Triangles and Patches allowed"); } return(mesh); }
private void PurgeStateCache() { sStateCurrentVertexLayout = null; sStatePendingVertexLayout = null; _sVertexAttribEnables.Clear(); sActiveTexture = -1; }
static VertexLayout ReadVertexLayout(MemoryReader reader) { var layout = new VertexLayout(); layout.Begin(); var attributeCount = reader.Read <byte>(); var stride = reader.Read <ushort>(); for (int i = 0; i < attributeCount; i++) { var e = reader.Read <VertexElement>(); var usage = attributeUsageMap[e.Attrib]; layout.Add(usage, e.Count, attributeTypeMap[e.AttribType], e.Normalized != 0, e.AsInt != 0); if (layout.GetOffset(usage) != e.Offset) { throw new InvalidOperationException("Invalid mesh data; vertex attribute offset mismatch."); } } layout.End(); if (layout.Stride != stride) { throw new InvalidOperationException("Invalid mesh data; vertex layout stride mismatch."); } return(layout); }
public virtual void Dispose() { m_Materials.Clear(); if (!VertexLayout.Disposed) { VertexLayout.Dispose(); } if (!VertexBuffer.Disposed) { VertexBuffer.Dispose(); } if (!IndexBuffer.Disposed) { IndexBuffer.Dispose(); } if (m_IsCommonEffectManager) { EffectManager = null; } else { EffectManager.Dispose(); } Device = null; }
public JellyMesh(JellyData data, Vector3[] positions, Vector3[] normals) { _data = data; _UVWs = positions.Select((x) => GetVertexUVW(x)).ToArray(); _normals = normals; _vertices = new float[_UVWs.Length * VertexLayout.Stride(VertexLayout.Type.PositionNormal)]; }
/// <summary> /// Reads vertices from a vertex buffer. /// </summary> /// <param name="reader">The stream to read from.</param> /// <param name="layout">The layout of each vertex to read.</param> /// <param name="count">The number of vertices to read.</param> /// <param name="boundingBox">The bounding box to transform vertices with. Can be null.</param> /// <param name="processor">The IVertexProcessor to send read vertices to. Can be null.</param> public static void ReadVertices(IReader reader, VertexLayout layout, int count, BoundingBox boundingBox, IVertexProcessor processor) { for (int i = 0; i < count; i++) { long vertexStartPos = reader.Position; if (processor != null) { processor.BeginVertex(); } foreach (VertexElementLayout element in layout.Elements) { if (element.Stream == 0) // Not sure how multistream vertices work yet { reader.SeekTo(vertexStartPos + element.Offset); ReadElement(reader, element, boundingBox, processor); } } if (processor != null) { processor.EndVertex(); } } }
public static VertexLayout ReadVertexLayout(this UnmanagedMemoryAccessor reader, ref int index) { var layout = new VertexLayout(); layout.Begin(); var attributeCount = reader.ReadByte(ref index); var stride = reader.ReadUInt16(ref index); for (int i = 0; i < attributeCount; i++) { var offset = reader.ReadUInt16(ref index); var attrib = reader.ReadUInt16(ref index); var count = reader.ReadByte(ref index); var attribType = reader.ReadUInt16(ref index); var normalized = reader.ReadBool(ref index); var asInt = reader.ReadBool(ref index); var usage = attributeUsageMap[attrib]; layout.Add(usage, count, attributeTypeMap[attribType], normalized, asInt); if (layout.GetOffset(usage) != offset) { throw new InvalidOperationException("Invalid mesh data; vertex attribute offset mismatch."); } } layout.End(); if (layout.Stride != stride) { throw new InvalidOperationException("Invalid mesh data; vertex layout stride mismatch."); } return(layout); }
public static (Mesh mesh, Vector3[] positions, Vector3[] normals) LoadObj(string path) { ObjLoaderFactory factory = new ObjLoaderFactory(); var objLoader = factory.Create(); using (var fStream = new FileStream(path, FileMode.Open)) { var result = objLoader.Load(fStream); Dictionary <FaceVertex, VertexObjData> vertexData = new Dictionary <FaceVertex, VertexObjData>(); var verts = result.Vertices; var norms = result.Normals; var tex = result.Textures; var faces = result.Groups[0].Faces; uint[] indices = new uint[faces.Count * 3]; for (int i = 0; i < faces.Count; i++) { for (int j = 0; j < 3; j++) { var vert = faces[i][j]; if (vertexData.ContainsKey(vert) == false) { var v = ConvertVert(verts[vert.VertexIndex - 1]); var n = ConvertNorm(norms[vert.NormalIndex - 1]); var t = ConvertTexCoord(tex[vert.TextureIndex - 1]); vertexData.Add(vert, new VertexObjData(v, n, t, vertexData.Count)); } } } List <VertexObjData> sortedVertexData = vertexData.Values.ToList(); //sortedVertexData.Sort((a, b) => a.index.CompareTo(b.index)); for (int i = 0; i < faces.Count; i++) { for (int j = 0; j < 3; j++) { indices[i * 3 + j] = (uint)vertexData[faces[i][j]].index; } } var positions = new Vector3[sortedVertexData.Count]; var normals = new Vector3[sortedVertexData.Count]; float[] vertices = new float[sortedVertexData.Count * VertexLayout.Stride(VertexLayout.Type.PositionNormal)]; for (int i = 0; i < sortedVertexData.Count; i++) { var vert = sortedVertexData[i]; positions[vert.index] = vert.position; normals[vert.index] = vert.normal; VBOUtility.SetVertex(vertices, vert.position, vert.normal, vert.index); } var mesh = new Mesh(VertexLayout.Type.PositionNormal); mesh.SetBufferData(vertices, indices, OpenTK.Graphics.OpenGL.BufferUsageHint.StaticDraw); return(mesh, positions, normals); } }
private void SetupLayout(GraphicsDevice device) { var layout = device.CreateVertexLayout(); var attribute = new VertexAttribute(); attribute.Index = 0; attribute.Offset = 0; attribute.Stride = Marshal.SizeOf <Vertex2>(); attribute.Format = VertexAttributeFormat.Vector2f; attribute.Usage = VertexAttributeUsage.Position; layout.SetAttribute(attribute); attribute.Index = 1; attribute.Offset = Marshal.SizeOf <Vector2>(); attribute.Stride = Marshal.SizeOf <Vertex2>(); attribute.Format = VertexAttributeFormat.Vector2f; attribute.Usage = VertexAttributeUsage.TextureCoordinate; layout.SetAttribute(attribute); attribute.Index = 2; attribute.Offset = Marshal.SizeOf <Vector2>() * 2; attribute.Stride = Marshal.SizeOf <Vertex2>(); attribute.Format = VertexAttributeFormat.Vector4f; attribute.Usage = VertexAttributeUsage.Colour; layout.SetAttribute(attribute); this.layout = layout; }
public GuiRenderer(IGL owner) { Owner = owner; VertexLayout = owner.CreateVertexLayout(); VertexLayout.DefineVertexAttribute("aPosition", 0, 2, VertexAttribPointerType.Float, AttribUsage.Position, false, 32, 0); VertexLayout.DefineVertexAttribute("aTexcoord", 1, 2, VertexAttribPointerType.Float, AttribUsage.Texcoord0, false, 32, 8); VertexLayout.DefineVertexAttribute("aColor", 2, 4, VertexAttribPointerType.Float, AttribUsage.Texcoord1, false, 32, 16); VertexLayout.Close(); _Projection = new MatrixStack(); _Modelview = new MatrixStack(); string psProgram, vsProgram; if (owner.API == "D3D9") { vsProgram = DefaultShader_d3d9; psProgram = DefaultShader_d3d9; } else { vsProgram = DefaultVertexShader_gl; psProgram = DefaultPixelShader_gl; } var vs = Owner.CreateVertexShader(vsProgram, "vsmain", true); var ps = Owner.CreateFragmentShader(psProgram, "psmain", true); CurrPipeline = DefaultPipeline = Owner.CreatePipeline(VertexLayout, vs, ps, true, "xgui"); }
private void SetupGrahpicsResources(GraphicsDevice device) { this.vertexBuffer.Generate(); this.layout = device.CreateVertexLayout(); var attribute = new VertexAttribute(); attribute.Index = 0; attribute.Offset = 0; attribute.Stride = Marshal.SizeOf <Vertex>(); attribute.Format = VertexAttributeFormat.Vector2f; attribute.Usage = VertexAttributeUsage.Position; this.layout.SetAttribute(attribute); attribute.Index = 1; attribute.Offset = Marshal.SizeOf <Vector2>(); attribute.Stride = Marshal.SizeOf <Vertex>(); attribute.Format = VertexAttributeFormat.Vector4f; attribute.Usage = VertexAttributeUsage.Colour; this.layout.SetAttribute(attribute); var asm = typeof(GLShapeRenderer).Assembly; var vertpath = $"{nameof(GLShapeRenderer)}.vert.glsl"; var fragpath = $"{nameof(GLShapeRenderer)}.frag.glsl"; this.program = (GLShader)device.CreateShader(ShaderFormat.GLSL, asm.GetManifestResourceStream(vertpath), asm.GetManifestResourceStream(fragpath)); this.program.SetVertexData(this.vertexBuffer, this.layout); }
public bool Equals(ShaderProgramDescription <VertexT> other) { return(VertexLayout.Equals(other.VertexLayout) && VertexShader.Equals(other.VertexShader) && FragmentShader.Equals(other.FragmentShader) && PipelineOptions.Equals(other.PipelineOptions) && UseSpirV == other.UseSpirV); }
public static Mesh BezierJoined(float width, float height, int segmentsX, int segmentsZ) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var verticesX = 1 + 3 * segmentsX; var verticesZ = 1 + 3 * segmentsZ; var vertexCount = verticesX * verticesZ; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; float deltaW = width / (verticesX - 1); float deltaH = height / (verticesZ - 1); bool up = false; for (int z = 0; z < verticesX; z++) { up = false; for (int x = 0; x < verticesZ; x++) { if (x % 3 == 0) { up = !up; } var y = x % 3 == 1 || x % 3 == 2 ? width * 0.06f : 0.0f; if (up == false) { y = -y; } var pos = new Vector3(-width * 0.5f + deltaW * x, y, -height * 0.5f + deltaH * z); var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / (verticesX - 1), (float)z / (verticesZ - 1)); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } uint[] indices = new uint[segmentsX * segmentsZ * 16]; int indicesIdx = 0; for (int vPatch = 0; vPatch < segmentsZ; vPatch++) { for (int uPatch = 0; uPatch < segmentsX; uPatch++) { var uIdx = uPatch * 3; var vIdx = vPatch * 3; for (int j = vIdx; j < vIdx + 4; j++) { for (int i = uIdx; i < uIdx + 4; i++) { indices[indicesIdx] = (uint)(i + j * verticesX); indicesIdx++; } } } } mesh.SetBufferData(vertices, indices, BufferUsageHint.StaticDraw); return(mesh); }
protected virtual void CreateVertexLayout() { VertexLayout?.Dispose(); VertexLayout = new InputLayout( Device, UsingEffectPass.Description.Signature, new TVertex().VertexElements ); }
protected override void CreateVertexLayout() { VertexLayout?.Dispose(); VertexLayout = new InputLayout( Device, UsingEffectPass.Description.Signature, new TVertex().VertexElements.Concat(new TInstanceData().VertexElements).ToArray() ); }
public unsafe static Mesh LoadMesh(string fileName) { var path = Path.Combine(RootPath, "meshes/", fileName); var groups = new List <MeshGroup>(); var group = new MeshGroup(); VertexLayout layout = null; using (var reader = new MemoryReader(File.ReadAllBytes(path))) { while (!reader.Done) { var tag = reader.Read <uint>(); if (tag == ChunkTagVB) { // skip bounding volume info reader.Skip(BoundingVolumeSize); layout = ReadVertexLayout(reader); var vertexCount = reader.Read <ushort>(); var vertexData = reader.ReadArray <byte>(vertexCount * layout.Stride); group.VertexBuffer = new VertexBuffer(MemoryBlock.FromArray(vertexData), layout); } else if (tag == ChunkTagIB) { var indexCount = reader.Read <uint>(); var indexData = reader.ReadArray <ushort>((int)indexCount); group.IndexBuffer = new IndexBuffer(MemoryBlock.FromArray(indexData)); } else if (tag == ChunkTagPri) { // skip material name var len = reader.Read <ushort>(); reader.Skip(len); // read primitive data var count = reader.Read <ushort>(); for (int i = 0; i < count; i++) { // skip name len = reader.Read <ushort>(); reader.Skip(len); var prim = reader.Read <Primitive>(); group.Primitives.Add(prim); // skip bounding volumes reader.Skip(BoundingVolumeSize); } groups.Add(group); group = new MeshGroup(); } } } return(new Mesh(layout, groups)); }
/// <summary> /// Constructor /// </summary> /// <param name="Renderer">A reference to the base renderer</param> /// <param name="VertexShaderName">file path and name to vertex shader source</param> /// <param name="FragmentShaderName">file path and name to fragment shader source</param> /// <param name="IsFromStream"></param> public Shader(BaseRenderer Renderer, string VertexShaderName, string FragmentShaderName, bool IsFromStream = false) { renderer = Renderer; int status; handle = GL.CreateProgram(); if (IsFromStream) { Assembly thisAssembly = Assembly.GetExecutingAssembly(); using (Stream stream = thisAssembly.GetManifestResourceStream($"LibRender2.{VertexShaderName}.vert")) { if (stream != null) { using (StreamReader reader = new StreamReader(stream)) { LoadShader(reader.ReadToEnd(), ShaderType.VertexShader); } } } using (Stream stream = thisAssembly.GetManifestResourceStream($"LibRender2.{FragmentShaderName}.frag")) { if (stream != null) { using (StreamReader reader = new StreamReader(stream)) { LoadShader(reader.ReadToEnd(), ShaderType.FragmentShader); } } } } else { LoadShader(File.ReadAllText(VertexShaderName, Encoding.UTF8), ShaderType.VertexShader); LoadShader(File.ReadAllText(FragmentShaderName, Encoding.UTF8), ShaderType.FragmentShader); } GL.AttachShader(handle, vertexShader); GL.AttachShader(handle, fragmentShader); GL.DeleteShader(vertexShader); GL.DeleteShader(fragmentShader); GL.LinkProgram(handle); GL.GetProgram(handle, GetProgramParameterName.LinkStatus, out status); if (status == 0) { throw new ApplicationException(GL.GetProgramInfoLog(handle)); } VertexLayout = GetVertexLayout(); UniformLayout = GetUniformLayout(); Disposable.Add(this); }
/// <summary> /// Imports the mesh's vertex data. /// </summary> private void GetMeshVerts(Vector3[] verts, int arrayPos, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool vertsExist = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Position, 0, out info); Assert.IsTrue(vertsExist); ReadVertexStream(verts, arrayPos, meshData, info); }
private void GetMeshNormals(Vector3[] normals, int arrayPos, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool normalExists = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Normal, 0, out info); if (normalExists) { ReadVertexStream(normals, arrayPos, meshData, info); } }
private void ProcessMesh(int arrayPos, Dme modelData, Mesh meshData, Vector3[] verts, Vector2[] uvs) { uint materialHash = modelData.Materials[(int)meshData.MaterialIndex].MaterialDefinitionHash; MaterialDefinition materialDefinition = materialDefinitionManager.GetMaterial(materialHash); uint vertexLayoutHash = materialDefinition.DrawStyles[DRAWSTYLE_INDEX].VertexLayoutNameHash; VertexLayout vertexLayout = materialDefinitionManager.GetVertexLayout(vertexLayoutHash); GetMeshVerts(verts, arrayPos, meshData, vertexLayout); GetMeshUVs(uvs, arrayPos, meshData, vertexLayout); }
/// <summary> /// Loads a VertexLayout based off of information in a vertex XML element. /// </summary> /// <param name="vertexElement">The vertex element to create the layout from.</param> /// <returns>The VertexLayout that was created.</returns> private static VertexLayout LoadLayout(XElement vertexElement) { // Vertex tags have the format: // <vertex type="(type index)" name="(vertex name)">(elements)</vertex> int type = XMLUtil.GetNumericAttribute(vertexElement, "type"); string name = XMLUtil.GetStringAttribute(vertexElement, "name"); var result = new VertexLayout(type, name); result.AddElements(LoadLayoutElements(vertexElement)); return(result); }
public override int GetHashCode() { var hashCode = 2038128800; hashCode = hashCode * -1521134295 + VertexLayout.GetHashCode(); hashCode = hashCode * -1521134295 + VertexShader.GetHashCode(); hashCode = hashCode * -1521134295 + FragmentShader.GetHashCode(); hashCode = hashCode * -1521134295 + PipelineOptions.GetHashCode(); hashCode = hashCode * -1521134295 + UseSpirV.GetHashCode(); return(hashCode); }
/// <summary> /// Imports the mesh's texture coordinates. /// </summary> private void GetMeshUVs(Vector2[] uvs, int offset, Mesh meshData, VertexLayout vertexLayout) { VertexLayout.EntryInfo info; bool uvsExist = vertexLayout.GetEntryInfo(VertexLayout.Entry.DataUsages.Texcoord, 0, out info); if (uvsExist) { ReadVertexStream(uvs, offset, meshData, info); } }
/// <summary> /// Loads a VertexLayout based off of information in a vertex XML element. /// </summary> /// <param name="vertexElement">The vertex element to create the layout from.</param> /// <returns>The VertexLayout that was created.</returns> private static VertexLayout LoadLayout(XElement vertexElement) { // Vertex tags have the format: // <vertex type="(type index)" name="(vertex name)">(elements)</vertex> int type = XMLUtil.GetNumericAttribute(vertexElement, "type"); string name = XMLUtil.GetStringAttribute(vertexElement, "name"); var result = new VertexLayout(type, name); result.AddElements(LoadLayoutElements(vertexElement)); return result; }
public Mesh(GraphicsDevice graphicsDevice, MeshData meshData, VertexBufferFactory vertBuffFactory) { device = graphicsDevice; vertLayout = VertexLayouts.DetermineLayout(meshData); vertexBuffer = vertBuffFactory.CreateVertexBuffer(graphicsDevice, meshData, vertLayout); indexBuffer = Buffer.Index.New(graphicsDevice, meshData.GetIndices()); isLoaded = true; }
public Mesh(MemoryBlock vertices, VertexLayout decl, ushort[] indices) { var group = new MeshGroup(); group.VertexBuffer = new VertexBuffer(vertices, decl); group.IndexBuffer = new IndexBuffer(MemoryBlock.FromArray(indices)); vertexDecl = decl; groups = new List <MeshGroup> { group }; }
private static Geometry ConvertGeometry(Assimp.Mesh mesh, float scale, VertexLayout vertexLayout, VertexComponent[] vertexComponents, bool combineVB, bool combineIB, out BoundingBox meshBoundingBox) { VkPrimitiveTopology[] primitiveTopology = { VkPrimitiveTopology.PointList, VkPrimitiveTopology.PointList, VkPrimitiveTopology.LineList, VkPrimitiveTopology.LineList, VkPrimitiveTopology.TriangleList, }; if (!combineVB) { vertexBuffer.Clear(); } if (!combineIB) { indexBuffer.Clear(); } ConvertGeom(scale, (uint)vertexOffset, mesh, out meshBoundingBox, vertexComponents); var geometry = new Geometry { Name = mesh.Name, VertexLayout = vertexLayout }; if (!combineVB) { geometry.VertexBuffer = Buffer.Create(VkBufferUsageFlags.VertexBuffer, false, sizeof(float), vertexBuffer.Count, vertexBuffer.Data); } if (!combineIB) { geometry.IndexBuffer = Buffer.Create(VkBufferUsageFlags.IndexBuffer, false, sizeof(uint), indexBuffer.Count, indexBuffer.Data); } geometry.SetDrawRange(primitiveTopology[(int)mesh.PrimitiveType], indexOffset, (uint)mesh.FaceCount * 3, 0 /*vertexOffset*/); if (combineVB) { vertexOffset += mesh.VertexCount; } if (combineIB) { indexOffset += (uint)mesh.FaceCount * 3; } return(geometry); }
public unsafe static VertexLayout begin(this VertexLayout layout, RendererType renderer) { layout.hash = (uint)renderer; layout.stride = 0; Span <ushort> attributes = new Span <ushort>(layout.attributes, (int)Attrib.Count); attributes.Fill(65535); Span <ushort> offsets = new Span <ushort>(layout.offset, (int)Attrib.Count); offsets.Fill(0); return(layout); }
public RetroShader(IGL owner, string source, bool debug = false) { Owner = owner as IGL_TK; VertexLayout = owner.CreateVertexLayout(); VertexLayout.DefineVertexAttribute("VertexCoord", 0, 4, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 0); //VertexCoord VertexLayout.DefineVertexAttribute("ColorShit", 1, 4, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 16); //COLOR VertexLayout.DefineVertexAttribute("TexCoord", 2, 2, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 32); //TexCoord (is this vec2 or vec4? the glsl converted from cg had vec4 but the cg had vec2...) VertexLayout.Close(); string vsSource = "#define VERTEX\r\n" + source; string psSource = "#define FRAGMENT\r\n" + source; var vs = Owner.CreateVertexShader(vsSource, debug); var ps = Owner.CreateFragmentShader(psSource, debug); Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, debug); }
public unsafe static VertexLayout end(this VertexLayout layout) { var hash = new bgfx_hash.HashMurmur2(); var size = (uint)Attrib.Count; hash.exp_ushort(size * 2); hash.exp_ushort(size * 2); hash.exp_ushort(sizeof(ushort)); hash.exp_end(); hash.add(layout.attributes, size); hash.add(layout.offset, size); hash.add(&layout.stride); layout.hash = hash.end(); return(layout); }
public void Dispose() { VertexLayout.Dispose(); VertexLayout = null; }
unsafe void MyBindArrayData(VertexLayout layout, void* pData) { UnbindVertexAttributes(); //HAMNUTS (continued) var currBindings = sVertexAttribEnables; sStateCurrentVertexLayout = sStatePendingVertexLayout; if (layout == null) return; foreach (var kvp in layout.Items) { GL.VertexAttribPointer(kvp.Key, kvp.Value.Components, (VertexAttribPointerType)kvp.Value.AttribType, kvp.Value.Normalized, kvp.Value.Stride, new IntPtr(pData) + kvp.Value.Offset); GL.EnableVertexAttribArray(kvp.Key); currBindings.Add(kvp.Key); } }
public void BindPipeline(Pipeline pipeline) { if (pipeline == null) { sStatePendingVertexLayout = null; GL.UseProgram(0); return; } if (!pipeline.Available) throw new InvalidOperationException("Attempt to bind unavailable pipeline"); sStatePendingVertexLayout = pipeline.VertexLayout; GL.UseProgram(pipeline.Id.ToInt32()); }
void PurgeStateCache() { sStateCurrentVertexLayout = null; sStatePendingVertexLayout = null; sVertexAttribEnables.Clear(); sActiveTexture = -1; }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo) { if (!vertexShader.Available || !fragmentShader.Available) { string errors = string.Format("Vertex Shader:\r\n {0} \r\n-------\r\nFragment Shader:\r\n{1}", vertexShader.Errors, fragmentShader.Errors); if (required) throw new InvalidOperationException("Couldn't build required GL pipeline:\r\n" + errors); var pipeline = new Pipeline(this, null, false, null, null, null); pipeline.Errors = errors; return pipeline; } VertexElement[] ves = new VertexElement[vertexLayout.Items.Count]; int stride = 0; foreach (var kvp in vertexLayout.Items) { var item = kvp.Value; d3d9.DeclarationType decltype = DeclarationType.Float1; switch (item.AttribType) { case gl.VertexAttribPointerType.Float: if (item.Components == 1) decltype = DeclarationType.Float1; else if (item.Components == 2) decltype = DeclarationType.Float2; else if (item.Components == 3) decltype = DeclarationType.Float3; else if (item.Components == 4) decltype = DeclarationType.Float4; else throw new NotSupportedException(); stride += 4 * item.Components; break; default: throw new NotSupportedException(); } d3d9.DeclarationUsage usage = DeclarationUsage.Position; byte usageIndex = 0; switch(item.Usage) { case AttributeUsage.Position: usage = DeclarationUsage.Position; break; case AttributeUsage.Texcoord0: usage = DeclarationUsage.TextureCoordinate; break; case AttributeUsage.Texcoord1: usage = DeclarationUsage.TextureCoordinate; usageIndex = 1; break; case AttributeUsage.Color0: usage = DeclarationUsage.Color; break; default: throw new NotSupportedException(); } ves[kvp.Key] = new VertexElement(0, (short)item.Offset, decltype, DeclarationMethod.Default, usage, usageIndex); } var pw = new PipelineWrapper() { VertexDeclaration = new VertexDeclaration(dev, ves), VertexShader = vertexShader.Opaque as ShaderWrapper, FragmentShader = fragmentShader.Opaque as ShaderWrapper, VertexStride = stride, }; //scan uniforms from constant tables //handles must be disposed later (with the pipeline probably) var uniforms = new List<UniformInfo>(); var fs = pw.FragmentShader; var vs = pw.VertexShader; var fsct = fs.bytecode.ConstantTable; var vsct = vs.bytecode.ConstantTable; foreach(var ct in new[]{fsct,vsct}) { Queue<Tuple<string,EffectHandle>> todo = new Queue<Tuple<string,EffectHandle>>(); int n = ct.Description.Constants; for (int i = 0; i < n; i++) { var handle = ct.GetConstant(null, i); todo.Enqueue(Tuple.Create("", handle)); } while(todo.Count != 0) { var tuple = todo.Dequeue(); var prefix = tuple.Item1; var handle = tuple.Item2; var descr = ct.GetConstantDescription(handle); //Console.WriteLine("D3D UNIFORM: " + descr.Name); if (descr.StructMembers != 0) { string newprefix = prefix + descr.Name + "."; for (int j = 0; j < descr.StructMembers; j++) { var subhandle = ct.GetConstant(handle, j); todo.Enqueue(Tuple.Create(newprefix, subhandle)); } continue; } UniformInfo ui = new UniformInfo(); UniformWrapper uw = new UniformWrapper(); ui.Opaque = uw; string name = prefix + descr.Name; //mehhh not happy about this stuff if (fs.MapCodeToNative != null || vs.MapCodeToNative != null) { string key = name.TrimStart('$'); if (descr.Rows != 1) key = key + "[0]"; if (fs.MapCodeToNative != null && ct == fsct) if (fs.MapCodeToNative.ContainsKey(key)) name = fs.MapCodeToNative[key]; if (vs.MapCodeToNative != null && ct == vsct) if (vs.MapCodeToNative.ContainsKey(key)) name = vs.MapCodeToNative[key]; } ui.Name = name; uw.Description = descr; uw.EffectHandle = handle; uw.FS = (ct == fsct); uw.CT = ct; if (descr.Type == ParameterType.Sampler2D) { ui.IsSampler = true; ui.SamplerIndex = descr.RegisterIndex; uw.SamplerIndex = descr.RegisterIndex; } uniforms.Add(ui); } } pw.fsct = fsct; pw.vsct = vsct; return new Pipeline(this, pw, true, vertexLayout, uniforms,memo); }
public void BindPipeline(Pipeline pipeline) { _CurrPipeline = pipeline; if (pipeline == null) { sStatePendingVertexLayout = null; GL.UseProgram(0); return; } if (!pipeline.Available) throw new InvalidOperationException("Attempt to bind unavailable pipeline"); sStatePendingVertexLayout = pipeline.VertexLayout; var pw = pipeline.Opaque as PipelineWrapper; GL.UseProgram(pw.pid); //this is dumb and confusing, but we have to bind physical sampler numbers to sampler variables. for (int i = 0; i < pw.SamplerLocs.Count; i++) { GL.Uniform1(pw.SamplerLocs[i], i); } }
public override uint GetVertexCount(VertexLayout layout) { return 0; }
public void Dispose() { VertexLayout.Dispose(); VertexLayout = null; DefaultPipeline.Dispose(); DefaultPipeline = null; }
public GuiRenderer(IGL owner) { Owner = owner; VertexLayout = owner.CreateVertexLayout(); VertexLayout.DefineVertexAttribute("aPosition", 0, 2, VertexAttribPointerType.Float, AttributeUsage.Position, false, 32, 0); VertexLayout.DefineVertexAttribute("aTexcoord", 1, 2, VertexAttribPointerType.Float, AttributeUsage.Texcoord0, false, 32, 8); VertexLayout.DefineVertexAttribute("aColor", 2, 4, VertexAttribPointerType.Float, AttributeUsage.Texcoord1, false, 32, 16); VertexLayout.Close(); _Projection = new MatrixStack(); _Modelview = new MatrixStack(); string psProgram, vsProgram; if (owner.API == "D3D9") { vsProgram = DefaultShader_d3d9; psProgram = DefaultShader_d3d9; } else { vsProgram = DefaultVertexShader_gl; psProgram = DefaultPixelShader_gl; } var vs = Owner.CreateVertexShader(vsProgram, true); var ps = Owner.CreateFragmentShader(psProgram, true); CurrPipeline = DefaultPipeline = Owner.CreatePipeline(VertexLayout, vs, ps, true); }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required) { bool success = true; ErrorCode errcode; int pid = GL.CreateProgram(); GL.AttachShader(pid, vertexShader.Id.ToInt32()); errcode = GL.GetError(); GL.AttachShader(pid, fragmentShader.Id.ToInt32()); errcode = GL.GetError(); //bind the attribute locations from the vertex layout foreach (var kvp in vertexLayout.Items) GL.BindAttribLocation(pid, kvp.Key, kvp.Value.Name); GL.LinkProgram(pid); errcode = GL.GetError(); string resultLog = GL.GetProgramInfoLog(pid); if (errcode != ErrorCode.NoError) if (required) throw new InvalidOperationException("Error creating pipeline (error returned from glLinkProgram): " + errcode + "\r\n\r\n" + resultLog); else success = false; int linkStatus; GL.GetProgram(pid, GetProgramParameterName.LinkStatus, out linkStatus); if (linkStatus == 0) if (required) throw new InvalidOperationException("Error creating pipeline (link status false returned from glLinkProgram): " + "\r\n\r\n" + resultLog); else success = false; //need to work on validation. apparently there are some weird caveats to glValidate which make it complicated and possibly excuses (barely) the intel drivers' dysfunctional operation //"A sampler points to a texture unit used by fixed function with an incompatible target" // //info: //http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml //This function mimics the validation operation that OpenGL implementations must perform when rendering commands are issued while programmable shaders are part of current state. //glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state //This function is typically useful only during application development. // //So, this is no big deal. we shouldnt be calling validate right now anyway. //conclusion: glValidate is very complicated and is of virtually no use unless your draw calls are returning errors and you want to know why //GL.ValidateProgram(pid); //errcode = GL.GetError(); //resultLog = GL.GetProgramInfoLog(pid); //if (errcode != ErrorCode.NoError) // throw new InvalidOperationException("Error creating pipeline (error returned from glValidateProgram): " + errcode + "\r\n\r\n" + resultLog); //int validateStatus; //GL.GetProgram(pid, GetProgramParameterName.ValidateStatus, out validateStatus); //if (validateStatus == 0) // throw new InvalidOperationException("Error creating pipeline (validateStatus status false returned from glValidateProgram): " + "\r\n\r\n" + resultLog); //set the program to active, in case we need to set sampler uniforms on it GL.UseProgram(pid); ////get all the attributes (not needed) //List<AttributeInfo> attributes = new List<AttributeInfo>(); //int nAttributes; //GL.GetProgram(pid, GetProgramParameterName.ActiveAttributes, out nAttributes); //for (int i = 0; i < nAttributes; i++) //{ // int size, length; // var sbName = new System.Text.StringBuilder(); // ActiveAttribType type; // GL.GetActiveAttrib(pid, i, 1024, out length, out size, out type, sbName); // attributes.Add(new AttributeInfo() { Handle = new IntPtr(i), Name = sbName.ToString() }); //} //get all the uniforms List<UniformInfo> uniforms = new List<UniformInfo>(); int nUniforms; int nSamplers = 0; GL.GetProgram(pid,GetProgramParameterName.ActiveUniforms,out nUniforms); for (int i = 0; i < nUniforms; i++) { int size, length; ActiveUniformType type; var sbName = new System.Text.StringBuilder(); GL.GetActiveUniform(pid, i, 1024, out length, out size, out type, sbName); errcode = GL.GetError(); string name = sbName.ToString(); int loc = GL.GetUniformLocation(pid, name); var ui = new UniformInfo(); ui.Name = name; ui.Handle = new IntPtr(loc); //automatically assign sampler uniforms to texture units (and bind them) bool isSampler = (type == ActiveUniformType.Sampler2D); if (isSampler) { ui.SamplerIndex = nSamplers; GL.Uniform1(loc, nSamplers); nSamplers++; } uniforms.Add(ui); } //deactivate the program, so we dont accidentally use it GL.UseProgram(0); if (!vertexShader.Available) success = false; if (!fragmentShader.Available) success = false; return new Pipeline(this, new IntPtr(pid), success, vertexLayout, uniforms); }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo) { //if the shaders arent available, the pipeline isn't either if (!vertexShader.Available || !fragmentShader.Available) { string errors = string.Format("Vertex Shader:\r\n {0} \r\n-------\r\nFragment Shader:\r\n{1}", vertexShader.Errors, fragmentShader.Errors); if (required) throw new InvalidOperationException("Couldn't build required GL pipeline:\r\n" + errors); var pipeline = new Pipeline(this, null, false, null, null, null); pipeline.Errors = errors; return pipeline; } bool success = true; var vsw = vertexShader.Opaque as ShaderWrapper; var fsw = fragmentShader.Opaque as ShaderWrapper; var sws = new[] { vsw,fsw }; bool mapVariables = vsw.MapCodeToNative != null || fsw.MapCodeToNative != null; ErrorCode errcode; int pid = GL.CreateProgram(); GL.AttachShader(pid, vsw.sid); errcode = GL.GetError(); GL.AttachShader(pid, fsw.sid); errcode = GL.GetError(); //NOT BEING USED NOW: USING SEMANTICS INSTEAD ////bind the attribute locations from the vertex layout ////as we go, look for attribute mappings (CGC will happily reorder and rename our attribute mappings) ////what's more it will _RESIZE_ them but this seems benign..somehow.. ////WELLLLLLL we wish we could do that by names ////but the shaders dont seem to be adequate quality (oddly named attributes.. texCoord vs texCoord1). need to use semantics instead. //foreach (var kvp in vertexLayout.Items) //{ // string name = kvp.Value.Name; // //if (mapVariables) // //{ // // foreach (var sw in sws) // // { // // if (sw.MapNativeToCode.ContainsKey(name)) // // { // // name = sw.MapNativeToCode[name]; // // break; // // } // // } // //} // if(mapVariables) { // ////proxy for came-from-cgc // //switch (kvp.Value.Usage) // //{ // // case AttributeUsage.Position: // //} // } // //GL.BindAttribLocation(pid, kvp.Key, name); //} GL.LinkProgram(pid); errcode = GL.GetError(); string resultLog = GL.GetProgramInfoLog(pid); if (errcode != ErrorCode.NoError) if (required) throw new InvalidOperationException("Error creating pipeline (error returned from glLinkProgram): " + errcode + "\r\n\r\n" + resultLog); else success = false; int linkStatus; GL.GetProgram(pid, GetProgramParameterName.LinkStatus, out linkStatus); if (linkStatus == 0) if (required) throw new InvalidOperationException("Error creating pipeline (link status false returned from glLinkProgram): " + "\r\n\r\n" + resultLog); else success = false; //need to work on validation. apparently there are some weird caveats to glValidate which make it complicated and possibly excuses (barely) the intel drivers' dysfunctional operation //"A sampler points to a texture unit used by fixed function with an incompatible target" // //info: //http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml //This function mimics the validation operation that OpenGL implementations must perform when rendering commands are issued while programmable shaders are part of current state. //glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state //This function is typically useful only during application development. // //So, this is no big deal. we shouldnt be calling validate right now anyway. //conclusion: glValidate is very complicated and is of virtually no use unless your draw calls are returning errors and you want to know why //GL.ValidateProgram(pid); //errcode = GL.GetError(); //resultLog = GL.GetProgramInfoLog(pid); //if (errcode != ErrorCode.NoError) // throw new InvalidOperationException("Error creating pipeline (error returned from glValidateProgram): " + errcode + "\r\n\r\n" + resultLog); //int validateStatus; //GL.GetProgram(pid, GetProgramParameterName.ValidateStatus, out validateStatus); //if (validateStatus == 0) // throw new InvalidOperationException("Error creating pipeline (validateStatus status false returned from glValidateProgram): " + "\r\n\r\n" + resultLog); //set the program to active, in case we need to set sampler uniforms on it GL.UseProgram(pid); //get all the attributes (not needed) List<AttributeInfo> attributes = new List<AttributeInfo>(); int nAttributes; GL.GetProgram(pid, GetProgramParameterName.ActiveAttributes, out nAttributes); for (int i = 0; i < nAttributes; i++) { int size, length; var sbName = new System.Text.StringBuilder(1024); ActiveAttribType type; GL.GetActiveAttrib(pid, i, 1024, out length, out size, out type, sbName); attributes.Add(new AttributeInfo() { Handle = new IntPtr(i), Name = sbName.ToString() }); } //get all the uniforms List<UniformInfo> uniforms = new List<UniformInfo>(); int nUniforms; GL.GetProgram(pid,GetProgramParameterName.ActiveUniforms,out nUniforms); List<int> samplers = new List<int>(); for (int i = 0; i < nUniforms; i++) { int size, length; ActiveUniformType type; var sbName = new System.Text.StringBuilder(1024); GL.GetActiveUniform(pid, i, 1024, out length, out size, out type, sbName); errcode = GL.GetError(); string name = sbName.ToString(); int loc = GL.GetUniformLocation(pid, name); //translate name if appropriate //not sure how effective this approach will be, due to confusion of vertex and fragment uniforms if (mapVariables) { if (vsw.MapCodeToNative.ContainsKey(name)) name = vsw.MapCodeToNative[name]; if (fsw.MapCodeToNative.ContainsKey(name)) name = fsw.MapCodeToNative[name]; } var ui = new UniformInfo(); ui.Name = name; ui.Opaque = loc; if (type == ActiveUniformType.Sampler2D) { ui.IsSampler = true; ui.SamplerIndex = samplers.Count; ui.Opaque = loc | (samplers.Count << 24); samplers.Add(loc); } uniforms.Add(ui); } //deactivate the program, so we dont accidentally use it GL.UseProgram(0); if (!vertexShader.Available) success = false; if (!fragmentShader.Available) success = false; var pw = new PipelineWrapper() { pid = pid, VertexShader = vertexShader, FragmentShader = fragmentShader, SamplerLocs = samplers }; return new Pipeline(this, pw, success, vertexLayout, uniforms, memo); }
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required) { return null; }
unsafe void MyBindArrayData(VertexLayout layout, void* pData) { UnbindVertexAttributes(); //HAMNUTS (continued) var currBindings = sVertexAttribEnables; sStateCurrentVertexLayout = sStatePendingVertexLayout; if (layout == null) return; //disable all the client states.. a lot of overhead right now, to be sure GL.DisableClientState(ArrayCap.VertexArray); GL.DisableClientState(ArrayCap.ColorArray); for(int i=0;i<8;i++) GL.DisableVertexAttribArray(i); for (int i = 0; i < 8; i++) { GL.ClientActiveTexture(TextureUnit.Texture0 + i); GL.DisableClientState(ArrayCap.TextureCoordArray); } GL.ClientActiveTexture(TextureUnit.Texture0); foreach (var kvp in layout.Items) { if(_CurrPipeline.Memo == "gui") { GL.VertexAttribPointer(kvp.Key, kvp.Value.Components, (VertexAttribPointerType)kvp.Value.AttribType, kvp.Value.Normalized, kvp.Value.Stride, new IntPtr(pData) + kvp.Value.Offset); GL.EnableVertexAttribArray(kvp.Key); currBindings.Add(kvp.Key); } else { var pw = _CurrPipeline.Opaque as PipelineWrapper; //comment SNACKPANTS switch (kvp.Value.Usage) { case AttributeUsage.Position: GL.EnableClientState(ArrayCap.VertexArray); GL.VertexPointer(kvp.Value.Components,VertexPointerType.Float,kvp.Value.Stride,new IntPtr(pData) + kvp.Value.Offset); break; case AttributeUsage.Texcoord0: GL.ClientActiveTexture(TextureUnit.Texture0); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer(kvp.Value.Components, TexCoordPointerType.Float, kvp.Value.Stride, new IntPtr(pData) + kvp.Value.Offset); break; case AttributeUsage.Texcoord1: GL.ClientActiveTexture(TextureUnit.Texture1); GL.EnableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer(kvp.Value.Components, TexCoordPointerType.Float, kvp.Value.Stride, new IntPtr(pData) + kvp.Value.Offset); GL.ClientActiveTexture(TextureUnit.Texture0); break; case AttributeUsage.Color0: break; } } } }
public abstract uint GetVertexCount(VertexLayout layout);
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required) { VertexElement[] ves = new VertexElement[vertexLayout.Items.Count]; foreach (var kvp in vertexLayout.Items) { var item = kvp.Value; d3d9.DeclarationType decltype = DeclarationType.Float1; switch (item.AttribType) { case gl.VertexAttribPointerType.Float: if (item.Components == 1) decltype = DeclarationType.Float1; else if (item.Components == 2) decltype = DeclarationType.Float2; else if (item.Components == 3) decltype = DeclarationType.Float3; else if (item.Components == 4) decltype = DeclarationType.Float4; else throw new NotSupportedException(); break; default: throw new NotSupportedException(); } d3d9.DeclarationUsage usage = DeclarationUsage.Position; byte usageIndex = 0; switch(item.Usage) { case AttributeUsage.Position: usage = DeclarationUsage.Position; break; case AttributeUsage.Texcoord0: usage = DeclarationUsage.TextureCoordinate; break; case AttributeUsage.Texcoord1: usage = DeclarationUsage.TextureCoordinate; usageIndex = 1; break; case AttributeUsage.Color0: usage = DeclarationUsage.Color; break; default: throw new NotSupportedException(); } ves[kvp.Key] = new VertexElement(0, (short)item.Offset, decltype, DeclarationMethod.Default, usage, usageIndex); } var pw = new PipelineWrapper(); pw.VertexDeclaration = new VertexDeclaration(dev, ves); Pipeline pipeline = new Pipeline(this,IntPtr.Zero,true, vertexLayout, new List<UniformInfo>()); pipeline.Opaque = pw; return pipeline; }