private void GenerateMesh(List <MeshFilter> filters) { List <MeshMaterial> meshMaterials = new List <MeshMaterial>(); if (_Data.SeprateByMaterial) { foreach (MeshFilter mf in filters) { MeshRenderer renderer = mf.GetComponent <MeshRenderer>(); if (renderer != null && renderer.sharedMaterials != null) { for (int i = 0; i < mf.sharedMesh.subMeshCount; i++) { if (renderer.sharedMaterials.Length > i) { MeshMaterial mm = FindMeshMaterial(meshMaterials, renderer.sharedMaterials[i]); if (mm == null) { mm = new MeshMaterial(renderer.sharedMaterials[i]); meshMaterials.Add(mm); } mm.Add(mf, i); } } } } } else { // just find a material Material mat = null; foreach (MeshFilter mf in filters) { MeshRenderer renderer = mf.GetComponent <MeshRenderer>(); if (renderer != null) { if (renderer.sharedMaterials.Length > 0) { mat = renderer.sharedMaterials[0]; break; } } } MeshMaterial mm = new MeshMaterial(mat); foreach (MeshFilter mf in filters) // combine all submesh { for (int i = 0; i < mf.sharedMesh.subMeshCount; i++) { mm.Add(mf, i); } } meshMaterials.Add(mm); } for (int i = 0; i < meshMaterials.Count; i++) { CreateMesh(meshMaterials[i]); } }
public MeshMaterial CreateMaterial() { var ret = new MeshMaterial(); parts[ret] = new MeshData(); return(ret); }
public void AddGeometryData(MeshPartGeometryData data, MeshMaterial material, Matrix transform) { if (!parts.ContainsKey(material)) { throw new InvalidOperationException("Material not created by the meshbuilder"); } var p = parts[material]; var xTransform = transform.xna(); var sPositions = data.GetSourceVector3(MeshPartGeometryData.Semantic.Position); var sNormals = data.GetSourceVector3(MeshPartGeometryData.Semantic.Normal); var sTexcoords = data.GetSourceVector2(MeshPartGeometryData.Semantic.Texcoord); var nPositions = new XnaVector3[sPositions.Length]; var nNormals = new XnaVector3[sNormals.Length]; var nTexcoords = sTexcoords; XnaVector3.Transform(sPositions, ref xTransform, nPositions); XnaVector3.TransformNormal(sNormals, ref xTransform, nNormals); p.Positions.AddRange(nPositions); p.Normals.AddRange(nNormals); p.Texcoords.AddRange(nTexcoords); }
public void AddBox(Vector3 min, Vector3 max, MeshMaterial material) { if (!parts.ContainsKey(material)) { throw new InvalidOperationException("Material not created by the meshbuilder"); } TangentVertex[] vertices; short[] indices; BoxMesh.CreateUnitBoxVerticesAndIndices(out vertices, out indices); var data = parts[material]; for (int i = 0; i < indices.Length; i++) { var pos = vertices[indices[i]].pos; pos.X = pos.X * (max.X - min.X); pos.Y = pos.Y * (max.Y - min.Y); pos.Z = pos.Z * (max.Z - min.Z); data.Positions.Add(pos + min.xna()); data.Normals.Add(vertices[indices[i]].normal); data.Texcoords.Add(vertices[indices[i]].uv); } }
/// <summary> /// Update per model object data /// </summary> /// <param name="animationOffset">Animation index</param> /// <param name="material">Material</param> /// <param name="textureIndex">Texture index</param> /// <param name="useAnisotropic">Use anisotropic filtering</param> public void UpdatePerObject( uint animationOffset, MeshMaterial material, uint textureIndex, bool useAnisotropic) { if (material != null) { this.DiffuseMap = material.DiffuseTexture; this.NormalMap = material.NormalMap; this.SpecularMap = material.SpecularTexture; this.MaterialIndex = material.ResourceIndex; } else { this.DiffuseMap = null; this.NormalMap = null; this.SpecularMap = null; this.MaterialIndex = 0; } this.TextureIndex = textureIndex; this.Anisotropic = useAnisotropic; this.AnimationOffset = animationOffset; }
public static Model Plane(float width, float height, MeshMaterial material, OpenToolkit.Mathematics.Matrix4 state = default, RenderFlags renderFlags = RenderFlags.Solid) { var vertices = new MeshVertex[] { new MeshVertex { Position = new Vector3(-width, 0.0f, -height), Normal = Vector3.UnitY }, new MeshVertex { Position = new Vector3(width, 0.0f, -height), Normal = Vector3.UnitY }, new MeshVertex { Position = new Vector3(-width, 0.0f, height), Normal = Vector3.UnitY }, new MeshVertex { Position = new Vector3(width, 0.0f, height), Normal = Vector3.UnitY } }; var indices = new uint[] { 0, 1, 2, 1, 2, 3 }; return(new Model(vertices, indices, material, state, renderFlags: renderFlags)); }
/// <summary> /// Update per model object data /// </summary> /// <param name="animationOffset">Animation index</param> /// <param name="material">Material</param> /// <param name="textureIndex">Texture index</param> public override void UpdatePerObject( uint animationOffset, MeshMaterial material, uint textureIndex) { this.AnimationOffset = animationOffset; this.DiffuseMap = material?.DiffuseTexture; this.TextureIndex = textureIndex; }
protected override void CreateInternal(ReadOnlyMemory <byte> data) { Materials = new List <MeshMaterial>(); // Read the file. // todo: Use spans instead of splits. // https://en.wikipedia.org/wiki/Wavefront_.obj_file var stream = new ReadOnlyMemoryStream(data); var reader = new StreamReader(stream); MeshMaterial currentMaterial = null; while (!reader.EndOfStream) { string currentLine = reader.ReadLine(); if (string.IsNullOrEmpty(currentLine)) { continue; } currentLine = currentLine.Trim(); if (currentLine == "" || currentLine[0] == '#') { continue; // Comment } string[] args = Regex.Replace(currentLine, @"\s+", " ").Split(' '); string identifier = args[0]; switch (identifier) { case "newmtl": { var newMat = new MeshMaterial { Name = args[1] }; currentMaterial = newMat; Materials.Add(newMat); break; } case "map_Kd" when currentMaterial != null: { string directory = AssetLoader.GetDirectoryName(Name); string texturePath = AssetLoader.GetNonRelativePath(directory, AssetLoader.NameToEngineName(args[1])); var texture = Engine.AssetLoader.Get <TextureAsset>(texturePath); if (texture != null) { texture.Texture.Tile = true; texture.Texture.Smooth = true; currentMaterial.DiffuseTextureName = texturePath; currentMaterial.DiffuseTexture = texture.Texture; } break; } } } }
internal ModelMeshPart( uint startIndex, uint indexCount, MeshMaterial material) { StartIndex = startIndex; IndexCount = indexCount; Material = material; }
public SpriteStackFrame(int w, int h) { Pixels = new Color[w * h]; for (var i = 0; i < Pixels.Length; i++) { Pixels[i].A = 0; } Material = new MeshMaterial(); }
/// <summary> /// Constructor /// </summary> /// <param name="game">Game</param> /// <param name="bufferManager">Buffer manager</param> /// <param name="description">Description</param> public GroundGardener(Scene scene, GroundGardenerDescription description) : base(scene, description) { if (description == null) { throw new EngineException("A gardener description should be specified."); } this.textureRandom = this.Game.ResourceManager.CreateResource(Guid.NewGuid(), 1024, -1, 1, 24); this.foliageSphere = new BoundingSphere(Vector3.Zero, description.VisibleRadius); //Material this.material = new MeshMaterial() { Material = description.Material != null?description.Material.GetMaterial() : Material.Default }; //Read foliage textures string contentPath = description.ContentPath; if (!string.IsNullOrEmpty(description.VegetationMap)) { var foliageMapImage = new ImageContent() { Streams = ContentManager.FindContent(contentPath, description.VegetationMap), }; this.foliageMap = FoliageMap.FromStream(foliageMapImage.Stream); } for (int i = 0; i < description.Channels.Length; i++) { var channelDesc = description.Channels[i]; if (channelDesc?.Enabled == true) { var newChannel = CreateChannel(channelDesc, i, contentPath); this.foliageMapChannels.Add(newChannel); } } for (int i = 0; i < MaxFoliageBuffers; i++) { this.foliageBuffers.Add(new FoliageBuffer(this.Game, this.BufferManager, description.Name)); } }
protected override async Task _draw() { RecordSet layer = GetMetadata(); Dictionary <string, Unit> symbology = GetMetadata().Properties.Units; meshes = new List <Transform>(); foreach (DMesh3 dMesh in features) { if (dMesh.HasVertexColors) { MeshMaterial.SetInt("_hasColor", 1); } await dMesh.CalculateUVsAsync(); meshes.Add(Instantiate(Mesh, transform).GetComponent <EditableMesh>().Draw(dMesh, MeshMaterial, WireframeMaterial, true)); } transform.position = AppState.instance.map.transform.TransformVector((Vector3)layer.Transform.Position); transform.rotation = layer.Transform.Rotate; transform.localScale = layer.Transform.Scale; }
private void CreateMesh(MeshMaterial mm) { if (mm.Count < 1) { return; } if (_Data.Sort != BatchMesh.SortAxis.None) { mm.Sort(_Data.Sort); } List <CombineInstance> instances = new List <CombineInstance>(); int polyCount = 0; int vertexCount = 0; for (int i = 0; i < mm.Count; i++) { if (instances.Count > 0 && (((polyCount + mm[i].PolyCount) > _Data.MaxPolyCount) || ((vertexCount + mm[i].VertexCount) >= ushort.MaxValue))) { CreateMesh(instances.ToArray(), mm.Material); instances.Clear(); polyCount = 0; vertexCount = 0; } instances.Add(mm[i].CI); polyCount += mm[i].PolyCount; vertexCount += mm[i].VertexCount; } if (instances.Count > 0) { CreateMesh(instances.ToArray(), mm.Material); instances.Clear(); polyCount = 0; } }
public static Model Grid(int lines, float stride, MeshMaterial material, OpenToolkit.Mathematics.Matrix4 state = default, RenderFlags renderFlags = RenderFlags.Solid) { float lineLengthHalf = (lines - 1) * stride / 2; var vertices = new List <MeshVertex>(); for (int i = 0; i < lines; i++) { var current = -lineLengthHalf + i * stride; // Z parallel lines vertices.Add(new MeshVertex { Position = new Vector3(current, 0, -lineLengthHalf), Normal = Vector3.UnitY }); vertices.Add(new MeshVertex { Position = new Vector3(current, 0, lineLengthHalf), Normal = Vector3.UnitY }); // X parallel lines vertices.Add(new MeshVertex { Position = new Vector3(-lineLengthHalf, 0, current), Normal = Vector3.UnitY }); vertices.Add(new MeshVertex { Position = new Vector3(lineLengthHalf, 0, current), Normal = Vector3.UnitY }); } var indices = new uint[vertices.Count]; for (uint i = 0; i < indices.Length; i++) { indices[i] = i; } return(new Model(vertices.ToArray(), indices, material, state, renderFlags: renderFlags)); }
private static void traverseMeshHierarchy(GameObject obj, ONSPPropagationMaterial[] currentMaterials, bool includeChildren, List <MeshMaterial> meshMaterials, List <TerrainMaterial> terrainMaterials, bool ignoreStatic) { if (!obj.activeInHierarchy) { return; } MeshFilter[] meshes = obj.GetComponents <MeshFilter>(); Terrain[] terrains = obj.GetComponents <Terrain>(); ONSPPropagationMaterial[] materials = obj.GetComponents <ONSPPropagationMaterial>(); // Initialize the current material array to a new array if there are any new materials. if (materials != null && materials.Length > 0) { // Determine the length of the material array. int maxLength = materials.Length; if (currentMaterials != null) { maxLength = Math.Max(maxLength, currentMaterials.Length); } ONSPPropagationMaterial[] newMaterials = new ONSPPropagationMaterial[maxLength]; // Copy the previous materials into the new array. if (currentMaterials != null) { for (int i = materials.Length; i < maxLength; i++) { newMaterials[i] = currentMaterials[i]; } } currentMaterials = newMaterials; // Copy the current materials. for (int i = 0; i < materials.Length; i++) { currentMaterials[i] = materials[i]; } } // Gather the meshes. foreach (MeshFilter meshFilter in meshes) { Mesh mesh = meshFilter.sharedMesh; if (mesh == null) { continue; } if (ignoreStatic && !mesh.isReadable) { Debug.Log("Mesh: " + meshFilter.gameObject.name + " not readable, cannot be static."); continue; } MeshMaterial m = new MeshMaterial(); m.meshFilter = meshFilter; m.materials = currentMaterials; meshMaterials.Add(m); } // Gather the terrains. foreach (Terrain terrain in terrains) { TerrainMaterial m = new TerrainMaterial(); m.terrain = terrain; m.materials = currentMaterials; terrainMaterials.Add(m); } // Traverse to the child objects. if (includeChildren) { foreach (Transform child in obj.transform) { if (child.GetComponent <ONSPPropagationGeometry>() == null) // skip children which have their own component { traverseMeshHierarchy(child.gameObject, currentMaterials, includeChildren, meshMaterials, terrainMaterials, ignoreStatic); } } } }
public void RenderFaceImmediateMode(ObjectState State, MeshFace Face, bool IsDebugTouchMode = false) { if (State.Prototype.Mesh.Vertices.Length < 1) { return; } VertexTemplate[] vertices = State.Prototype.Mesh.Vertices; MeshMaterial material = State.Prototype.Mesh.Materials[Face.Material]; if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); } else if (OptionBackFaceCulling) { if ((Face.Flags & MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); } } Matrix4D modelMatrix = State.ModelMatrix * Camera.TranslationMatrix; // matrix unsafe { GL.MatrixMode(MatrixMode.Projection); GL.PushMatrix(); fixed(double *matrixPointer = &CurrentProjectionMatrix.Row0.X) { GL.LoadMatrix(matrixPointer); } GL.MatrixMode(MatrixMode.Modelview); GL.PushMatrix(); fixed(double *matrixPointer = &CurrentViewMatrix.Row0.X) { GL.LoadMatrix(matrixPointer); } double *matrixPointer2 = &modelMatrix.Row0.X; { GL.MultMatrix(matrixPointer2); } GL.MatrixMode(MatrixMode.Texture); GL.PushMatrix(); fixed(double *matrixPointer = &State.TextureTranslation.Row0.X) { GL.LoadMatrix(matrixPointer); } } if (OptionWireFrame) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } // lighting if (material.NighttimeTexture == null) { if (OptionLighting) { GL.Enable(EnableCap.Lighting); } } if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new Color4(material.EmissiveColor.R, material.EmissiveColor.G, material.EmissiveColor.B, 255)); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new Color4(0.0f, 0.0f, 0.0f, 1.0f)); } // fog if (OptionFog) { GL.Enable(EnableCap.Fog); } PrimitiveType DrawMode; switch (Face.Flags & MeshFace.FaceTypeMask) { case MeshFace.FaceTypeTriangles: DrawMode = PrimitiveType.Triangles; break; case MeshFace.FaceTypeTriangleStrip: DrawMode = PrimitiveType.TriangleStrip; break; case MeshFace.FaceTypeQuads: DrawMode = PrimitiveType.Quads; break; case MeshFace.FaceTypeQuadStrip: DrawMode = PrimitiveType.QuadStrip; break; default: DrawMode = PrimitiveType.Polygon; break; } // daytime polygon { // texture if (material.DaytimeTexture != null) { if (currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { GL.Enable(EnableCap.Texture2D); if (LastBoundTexture != material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]; } } } // blend mode float factor; if (material.BlendMode == MeshMaterialBlendMode.Additive) { factor = 1.0f; GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); GL.Disable(EnableCap.Fog); } else if (material.NighttimeTexture == null) { float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } factor = 1.0f - 0.7f * blend; } else { factor = 1.0f; } float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData); } else { alphaFactor = 1.0f; } GL.Begin(DrawMode); if (OptionWireFrame) { GL.Color4(inv255 * material.Color.R * factor, inv255 * material.Color.G * factor, inv255 * material.Color.B * factor, 1.0f); } else { GL.Color4(inv255 * material.Color.R * factor, inv255 * material.Color.G * factor, inv255 * material.Color.B * factor, inv255 * material.Color.A * alphaFactor); } for (int i = 0; i < Face.Vertices.Length; i++) { GL.Normal3(Face.Vertices[i].Normal.X, Face.Vertices[i].Normal.Y, -Face.Vertices[i].Normal.Z); GL.TexCoord2(vertices[Face.Vertices[i].Index].TextureCoordinates.X, vertices[Face.Vertices[i].Index].TextureCoordinates.Y); if (vertices[Face.Vertices[i].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)vertices[Face.Vertices[i].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); } GL.End(); } // nighttime polygon if (material.NighttimeTexture != null && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { // texture GL.Enable(EnableCap.Texture2D); if (LastBoundTexture != material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]; } GL.Enable(EnableCap.Blend); // alpha test GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData); float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } alphaFactor *= blend; } else { alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (alphaFactor > 1.0f) { alphaFactor = 1.0f; } } GL.Begin(DrawMode); if (OptionWireFrame) { GL.Color4(inv255 * material.Color.R, inv255 * material.Color.G, inv255 * material.Color.B, 1.0f); } else { GL.Color4(inv255 * material.Color.R, inv255 * material.Color.G, inv255 * material.Color.B, inv255 * material.Color.A * alphaFactor); } for (int i = 0; i < Face.Vertices.Length; i++) { GL.Normal3(Face.Vertices[i].Normal.X, Face.Vertices[i].Normal.Y, -Face.Vertices[i].Normal.Z); GL.TexCoord2(vertices[Face.Vertices[i].Index].TextureCoordinates.X, vertices[Face.Vertices[i].Index].TextureCoordinates.Y); if (vertices[Face.Vertices[i].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)vertices[Face.Vertices[i].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); } GL.End(); RestoreBlendFunc(); RestoreAlphaFunc(); } GL.Disable(EnableCap.Texture2D); // normals if (OptionNormals) { for (int i = 0; i < Face.Vertices.Length; i++) { GL.Begin(PrimitiveType.Lines); GL.Color4(new Color4(material.Color.R, material.Color.G, material.Color.B, 255)); GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X, vertices[Face.Vertices[i].Index].Coordinates.Y, -vertices[Face.Vertices[i].Index].Coordinates.Z); GL.Vertex3(vertices[Face.Vertices[i].Index].Coordinates.X + Face.Vertices[i].Normal.X, vertices[Face.Vertices[i].Index].Coordinates.Y + +Face.Vertices[i].Normal.Z, -(vertices[Face.Vertices[i].Index].Coordinates.Z + Face.Vertices[i].Normal.Z)); GL.End(); } } // finalize if (OptionWireFrame) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } if (material.BlendMode == MeshMaterialBlendMode.Additive) { RestoreBlendFunc(); } GL.PopMatrix(); GL.MatrixMode(MatrixMode.Modelview); GL.PopMatrix(); GL.MatrixMode(MatrixMode.Projection); GL.PopMatrix(); }
public void AddCustom(Vector3[] nPositions, Vector3[] nNormals, Vector2[] nTexcoords, MeshMaterial material) { if (!parts.ContainsKey(material)) { throw new InvalidOperationException("Material not created by the meshbuilder"); } if (nPositions.Length != nNormals.Length) { throw new ArgumentException(); } if (nPositions.Length != nTexcoords.Length) { throw new ArgumentException(); } var data = parts[material]; data.Positions.AddRange(nPositions.Select(v => v.xna())); data.Normals.AddRange(nNormals.Select(v => v.xna())); data.Texcoords.AddRange(nTexcoords.Select(t => new Microsoft.Xna.Framework.Vector2(t.X, t.Y))); }
public MeshBuilder() { parts = new Dictionary <MeshMaterial, MeshData>(); defaultMaterial = CreateMaterial(); defaultMaterial.DiffuseColor = Color.White; }
public void RenderFace(Shader Shader, ObjectState State, MeshFace Face, Matrix4D modelMatrix, Matrix4D modelViewMatrix, bool IsDebugTouchMode = false) { if (State.Prototype.Mesh.Vertices.Length < 1) { return; } MeshMaterial material = State.Prototype.Mesh.Materials[Face.Material]; VertexArrayObject VAO = (VertexArrayObject)State.Prototype.Mesh.VAO; if (lastVAO != VAO.handle) { VAO.Bind(); lastVAO = VAO.handle; } if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); } else if (OptionBackFaceCulling) { if ((Face.Flags & MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); } } // matrix Shader.SetCurrentModelViewMatrix(modelViewMatrix); Shader.SetCurrentTextureMatrix(State.TextureTranslation); if (OptionWireFrame || IsDebugTouchMode) { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); lastColor = material.Color; } Shader.SetOpacity(1.0f); Shader.SetBrightness(1.0f); VAO.Draw(PrimitiveType.LineLoop, Face.IboStartIndex, Face.Vertices.Length); return; } // lighting if (OptionLighting) { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); Shader.SetMaterialDiffuse(material.Color); Shader.SetMaterialSpecular(material.Color); //TODO: Ambient and specular colors are not set by any current parsers } if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0) { Shader.SetMaterialEmission(material.EmissiveColor); Shader.SetMaterialEmissive(true); } else { Shader.SetMaterialEmissive(false); } Shader.SetMaterialShininess(1.0f); } else { if (material.Color != lastColor) { Shader.SetMaterialAmbient(material.Color); } //As lighting is disabled, the face cannot be emitting light.... Shader.SetMaterialEmissive(false); } lastColor = material.Color; PrimitiveType DrawMode; switch (Face.Flags & MeshFace.FaceTypeMask) { case MeshFace.FaceTypeTriangles: DrawMode = PrimitiveType.Triangles; break; case MeshFace.FaceTypeTriangleStrip: DrawMode = PrimitiveType.TriangleStrip; break; case MeshFace.FaceTypeQuads: DrawMode = PrimitiveType.Quads; break; case MeshFace.FaceTypeQuadStrip: DrawMode = PrimitiveType.QuadStrip; break; default: DrawMode = PrimitiveType.Polygon; break; } // daytime polygon { // texture if (material.DaytimeTexture != null && currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { Shader.SetIsTexture(true); if (LastBoundTexture != material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode]; } } else { Shader.SetIsTexture(false); } // Calculate the brightness of the poly to render float factor; if (material.BlendMode == MeshMaterialBlendMode.Additive) { //Additive blending- Full brightness factor = 1.0f; GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); Shader.SetIsFog(false); } else if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0) { //As material is emitting light, it must be at full brightness factor = 1.0f; } else if (material.NighttimeTexture == null || material.NighttimeTexture == material.DaytimeTexture) { //No nighttime texture or both are identical- Darken the polygon to match the light conditions float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } factor = 1.0f - 0.7f * blend; } else { //Valid nighttime texture- Blend the two textures by DNB at max brightness factor = 1.0f; } Shader.SetBrightness(factor); float alphaFactor; GlowAttenuationMode mode = GlowAttenuationMode.None; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData, out mode); } else { alphaFactor = 1.0f; } if (material.BlendMode == MeshMaterialBlendMode.Additive) { Shader.SetMaterialAdditive(1 + (int)mode); } else { Shader.SetMaterialAdditive(0); } Shader.SetOpacity(inv255 * material.Color.A * alphaFactor); // render polygon VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length); } // nighttime polygon if (material.NighttimeTexture != null && material.NighttimeTexture != material.DaytimeTexture && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode)) { // texture Shader.SetIsTexture(true); if (LastBoundTexture != material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]) { GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name); LastBoundTexture = material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode]; } GL.Enable(EnableCap.Blend); // alpha test GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode float alphaFactor; if (material.GlowAttenuationData != 0) { alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData); float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } alphaFactor *= blend; } else { alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount; if (alphaFactor > 1.0f) { alphaFactor = 1.0f; } } Shader.SetOpacity(inv255 * material.Color.A * alphaFactor); // render polygon VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length); RestoreBlendFunc(); RestoreAlphaFunc(); } // normals if (OptionNormals) { Shader.SetIsTexture(false); Shader.SetBrightness(1.0f); Shader.SetOpacity(1.0f); VertexArrayObject NormalsVAO = (VertexArrayObject)State.Prototype.Mesh.NormalsVAO; NormalsVAO.Bind(); lastVAO = NormalsVAO.handle; NormalsVAO.Draw(PrimitiveType.Lines, Face.NormalsIboStartIndex, Face.Vertices.Length * 2); } // finalize if (material.BlendMode == MeshMaterialBlendMode.Additive) { RestoreBlendFunc(); Shader.SetIsFog(OptionFog); } }
public void AddSphere(int segments, float radius, MeshMaterial material) { if (!parts.ContainsKey(material)) { throw new InvalidOperationException("Material not created by the meshbuilder"); } TangentVertex[] vertices; short[] indices; // Source: http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/sphere_cylinder/ // Maak ringen van vertices van onder naar boven int i = 0; float phi, theta; float phiStep, thetaStep; float phiStart, phiEnd, thetaStart, thetaEnd; phiStep = MathHelper.TwoPi / segments; thetaStep = MathHelper.Pi / segments; phiStart = 0; phiEnd = MathHelper.TwoPi; thetaStart = -MathHelper.PiOver2 + thetaStep; thetaEnd = MathHelper.PiOver2; int numRings = (int)Math.Round((thetaEnd - thetaStart) / thetaStep); int numVertsOnRing = (int)Math.Round((phiEnd - phiStart) / phiStep); int numVertices = 1 + numRings * numVertsOnRing + 1; vertices = new TangentVertex[numVertices]; // Bottom vertex: (0,-1,0) vertices[i].pos = new Microsoft.Xna.Framework.Vector3(0, -1, 0); i++; theta = thetaStart; for (int iRing = 0; iRing < numRings; iRing++, theta += thetaStep) { phi = 0; for (int iVert = 0; iVert < numVertsOnRing; iVert++, phi += phiStep) { vertices[i].pos = new Microsoft.Xna.Framework.Vector3( (float)Math.Cos(theta) * (float)Math.Cos(phi), (float)Math.Sin(theta), -(float)Math.Cos(theta) * (float)Math.Sin(phi)); i++; } } // Top vertex: (0,1,0) vertices[i].pos = new Microsoft.Xna.Framework.Vector3(0, 1, 0); i++; // Generate normals for (int j = 0; j < vertices.Length; j++) { vertices[j].normal = Microsoft.Xna.Framework.Vector3.Normalize(vertices[j].pos); } int numIndices = (numVertsOnRing * 2 * 3) * numRings; indices = new short[numIndices]; i = 0; // Triangle fan at bottom and top, elsewhere strips between the rings // Top and bottom fan for (int iVert = 0; iVert < numVertsOnRing - 1; iVert++) { // Bottom fan indices[i] = (short)(0); i++; indices[i] = (short)(1 + iVert); i++; indices[i] = (short)(1 + (iVert + 1)); i++; // Top fan indices[i] = (short)(numVertices - 1); i++; indices[i] = (short)(1 + (numRings - 1) * numVertsOnRing + (iVert + 1)); i++; indices[i] = (short)(1 + (numRings - 1) * numVertsOnRing + iVert); i++; } // Top and bottom final fan indices[i] = (short)(0); i++; indices[i] = (short)(1 + numVertsOnRing - 1); i++; indices[i] = (short)(1 + 0); i++; indices[i] = (short)(numVertices - 1); i++; indices[i] = (short)(1 + (numRings - 1) * numVertsOnRing + 0); i++; indices[i] = (short)(1 + (numRings - 1) * numVertsOnRing + numVertsOnRing - 1); i++; // Strips for (int iRing = 0; iRing < numRings - 1; iRing++) { for (int iVert = 0; iVert < numVertsOnRing - 1; iVert++) { indices[i] = (short)(1 + numVertsOnRing * iRing + iVert); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + iVert); i++; indices[i] = (short)(1 + numVertsOnRing * iRing + (iVert + 1)); i++; indices[i] = (short)(1 + numVertsOnRing * iRing + (iVert + 1)); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + iVert); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + (iVert + 1)); i++; } // Final gap: indices[i] = (short)(1 + numVertsOnRing * iRing + (numVertsOnRing - 1)); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + (numVertsOnRing - 1)); i++; indices[i] = (short)(1 + numVertsOnRing * iRing + (0)); i++; indices[i] = (short)(1 + numVertsOnRing * iRing + (0)); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + (numVertsOnRing - 1)); i++; indices[i] = (short)(1 + numVertsOnRing * (iRing + 1) + (0)); i++; } var mapping = new SphericalMapping(); var data = parts[material]; foreach (var index in indices) { data.Positions.Add(vertices[index].pos * radius); data.Normals.Add(vertices[index].normal); data.Texcoords.Add(mapping.Map(data.Positions[data.Positions.Count - 1].ToSlimDX()).xna() * 3); } }
public EngineContent ToSceneNode() { string name = Path.GetFileNameWithoutExtension(this.name); VertexDescriptor vd = EngineResources.CreateVertexDescriptor <ModelVertex>(); List <Tuple <string, Mesh> > meshes = new List <Tuple <string, Mesh> >(groups.Count); List <SceneNode> nodes = new List <SceneNode>(groups.Count); MeshMaterial[] sceneMaterials = new MeshMaterial[materials.Count]; Dictionary <string, MeshMaterial> materialLookup = new Dictionary <string, MeshMaterial>(); for (int i = 0; i < materials.Values.Count; i++) { var sourceMat = materials.Values[i]; sceneMaterials[i] = new MeshMaterial { Name = name + "_" + sourceMat.Name, Surface = sourceMat.ToSurfaceInfo(), NormalMap = sourceMat.NormalMap, DiffuseMap = sourceMat.Textures != null && sourceMat.Textures.Length > 0 ? sourceMat.Textures[0] : null }; materialLookup.Add(sceneMaterials[i].Name, sceneMaterials[i]); } List <MeshLayer> layers = new List <MeshLayer>(); //register for each positionIndex in the source container the List of the destination vertices that contain that position Dictionary <int, List <VertexInfo> > lookup = new Dictionary <int, List <VertexInfo> >(); VertexInfo vi; ModelVertex v; List <ModelVertex> vertexes = new List <ModelVertex>(); uint[] indexes; #region Groups foreach (var g in groups) { List <MeshMaterial> meshMaterials = new List <MeshMaterial>(); Mesh mesh = new Mesh(vd: vd); mesh.Name = g.Name; indexes = new uint[g.FaceCount * 3]; int k = 0; #region Layers layers.Clear(); foreach (var layer in g.Layers) { int startVertex = int.MaxValue; int vertexCount = 0; MeshLayer meshLayer = new MeshLayer(); meshLayer.startIndex = k; meshLayer.primitiveCount = layer.Faces.Count; var mat = materialLookup[name + "_" + layer.MaterialName]; meshLayer.materialIndex = meshMaterials.IndexOf(mat); if (meshLayer.materialIndex < 0) { meshLayer.materialIndex = meshMaterials.Count; meshMaterials.Add(mat); } #region Faces foreach (var face in layer.Faces) { //for each vertex of the face create a new mesh vertex if the vertex if not yet in the mesh add it to the VertexBuffer //and create a new face in the IndexBuffer for (int i = 0; i < 3; i++) { //vi describe a new vertex vi = new VertexInfo() { PositionIndex = face.Vertexes[i].Position, NormalIndex = -1, TcIndex = -1 }; //if the vertex position is not in the VertexBuffer add it if (!lookup.ContainsKey(vi.PositionIndex)) { v = new ModelVertex(position: positions[vi.PositionIndex]); if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal && face.Vertexes[i].Normal >= 0) { vi.NormalIndex = face.Vertexes[i].Normal; v.Normal = normals[vi.NormalIndex]; } if ((vertexFormat & VertexFormat.TexCoord) == VertexFormat.TexCoord && face.Vertexes[i].TexCoord >= 0) { vi.TcIndex = face.Vertexes[i].TexCoord; v.TexCoord = texCoords[vi.TcIndex]; } vi.VertexIndex = vertexes.Count; lookup.Add(vi.PositionIndex, new List <VertexInfo>() { vi }); vertexes.Add(v); vertexCount++; indexes[k] = (uint)vi.VertexIndex; } else { //else get the list of vertices that contains that position and // if new vertex is not in the list create the new destination vertex and add it to the VertexBuffer var vlist = lookup[vi.PositionIndex]; if ((vertexFormat & VertexFormat.Normal) == VertexFormat.Normal) { vi.NormalIndex = face.Vertexes[i].Normal; } if ((vertexFormat & VertexFormat.TexCoord) == VertexFormat.TexCoord) { vi.TcIndex = face.Vertexes[i].TexCoord; } int index = vlist.FindIndex(x => x.Equals(vi)); if (index < 0) { v = new ModelVertex(positions[vi.PositionIndex]); if (vi.NormalIndex >= 0) { v.Normal = normals[vi.NormalIndex]; } if (vi.TcIndex >= 0) { v.TexCoord = texCoords[vi.TcIndex]; } vi.VertexIndex = vertexes.Count; indexes[k] = (uint)vi.VertexIndex; vertexCount++; vertexes.Add(v); vlist.Add(vi); } else { //else the vertex is already in the VertexBuffer so create add the vertex index //to the indexbuffer vi = vlist[index]; indexes[k] = (uint)vi.VertexIndex; } } k++; startVertex = Math.Min(startVertex, vi.VertexIndex); } } #endregion Faces meshLayer.startVertex = startVertex; meshLayer.vertexCount = vertexCount; layers.Add(meshLayer); } #endregion Layers mesh.SetLayers(layers.ToArray()); var data = vertexes.ToArray(); mesh.CreateVertexBuffer(data); if (mesh.VertexCount < ushort.MaxValue) { mesh.CreateIndexBuffer(indexes.Select(x => (ushort)x).ToArray()); } else { mesh.CreateIndexBuffer(indexes); } mesh.DefragmentLayers(); mesh.BlendLayers(); if ((vertexFormat & VertexFormat.Normal) != VertexFormat.Normal) { mesh.ComputeNormals(); } if ((vertexFormat & VertexFormat.TexCoord) != VertexFormat.TexCoord) { mesh.ComputeTextureCoords(CoordMappingType.Spherical); } mesh.ComputeTangents(); nodes.Add(new SceneNode <MeshInstance>(g.Name, new MeshInstance(meshMaterials.ToArray(), mesh))); vertexes.Clear(); //test lookup.Clear(); } #endregion QuadTreeSceneNode node = new QuadTreeSceneNode(name, 10); node.Context = new TechniqueRenderContext(node); foreach (var item in nodes) { node.Add(item); } node.UpdateLayout(); var package = new EngineContent(name); package.Providers.AddRange(sceneMaterials); package.Providers.Add(node); return(package); }
public static Model Sphere(float radius, uint stackCount, uint sectorCount, MeshMaterial material, OpenToolkit.Mathematics.Matrix4 state = default, RenderFlags renderFlags = RenderFlags.Solid) { float radiusInv = 1.0f / radius; float pi2 = (float)Math.PI / 2; var vertices = new List <MeshVertex>(); float x, y, z, xy; // positions float nx, ny, nz; // normals //float s, t; //textures float stackStep = (float)Math.PI / stackCount; float sectorStep = 2 * (float)Math.PI / sectorCount; float stackAngle, sectorAngle; for (int i = 0; i <= stackCount; i++) { stackAngle = pi2 - i * stackStep; xy = radius * (float)Math.Cos(stackAngle); z = radius * (float)Math.Sin(stackAngle); for (int j = 0; j <= sectorCount; j++) { sectorAngle = j * sectorStep; // positions x = xy * (float)Math.Cos(sectorAngle); y = xy * (float)Math.Sin(sectorAngle); // normals nx = x * radiusInv; ny = y * radiusInv; nz = z * radiusInv; // textures //s = (float)j / sectorCount; //t = (float)i / stackCount; vertices.Add(new MeshVertex { Position = new Vector3(x, y, z), Normal = new Vector3(nx, ny, nz) }); } } var indices = new List <uint>(); uint k1, k2; for (uint i = 0; i < stackCount; i++) { k1 = i * (sectorCount + 1); k2 = k1 + sectorCount + 1; for (int j = 0; j < sectorCount; j++, k1++, k2++) { if (i != 0) { indices.Add(k1); indices.Add(k2); indices.Add(k1 + 1); } if (i != stackCount - 1) { indices.Add(k1 + 1); indices.Add(k2); indices.Add(k2 + 1); } } } // return a model return(new Model(vertices.ToArray(), indices.ToArray(), material, state, renderFlags: renderFlags)); }
public static Mesh Cylinder(float radius, float extentDown, float extentUp, int circleCount, MeshMaterial material, OpenToolkit.Mathematics.Matrix4 state = default, RenderFlags renderFlags = RenderFlags.Solid) { float radiusInv = 1.0f / radius; float angleStep = 2 * (float)Math.PI / circleCount; // the order of the vertices: // [L, U, LC1, UC1, LS1, US1, LC2, UC2, LS2, US2, ...], // where // L - central point of the lower circle, // U - central point of the upper circle, // LCi - i-th point of the lower circle with central normal, // UCi - i-th point of the upper circle with central normal, // LSi - i-th point of the lower circle with side normal, // USi - i-th point of the upper circle with side normal var vertices = new List <MeshVertex> { // add L and U new MeshVertex { Position = new Vector3(0, -extentDown, 0), Normal = -Vector3.UnitY }, new MeshVertex { Position = new Vector3(0, extentUp, 0), Normal = Vector3.UnitY } }; float angle, cos, sin; for (int i = 0; i <= circleCount; i++) { angle = i * angleStep; cos = radius * (float)Math.Cos(angle); sin = radius * (float)Math.Sin(angle); // add LCi and UCi vertices.Add(new MeshVertex { Position = new Vector3(cos, -extentDown, sin), Normal = -Vector3.UnitY }); vertices.Add(new MeshVertex { Position = new Vector3(cos, extentUp, sin), Normal = Vector3.UnitY }); // add LSi and USi vertices.Add(new MeshVertex { Position = new Vector3(cos, -extentDown, sin), Normal = new Vector3(cos * radiusInv, 0, sin * radiusInv) }); vertices.Add(new MeshVertex { Position = new Vector3(cos, extentUp, sin), Normal = new Vector3(cos * radiusInv, 0, sin * radiusInv) }); } var indices = new List <uint>(); // lower circle faces for (uint i = 0; i < circleCount; i++) { indices.Add(0); indices.Add(4 * i + 2); indices.Add(4 * i + 6); } // upper circle faces for (uint i = 0; i < circleCount; i++) { indices.Add(1); indices.Add(4 * i + 3); indices.Add(4 * i + 7); } // side faces for (uint i = 0; i < circleCount; i++) { // lower triangle indices.Add(4 * i + 4); indices.Add(4 * i + 5); indices.Add(4 * i + 8); // upper triangle indices.Add(4 * i + 5); indices.Add(4 * i + 8); indices.Add(4 * i + 9); } //return new Model(vertices.ToArray(), indices.ToArray(), material, state, renderFlags: renderFlags); return(new Mesh("Cylinder", vertices.ToArray(), indices.ToArray(), new MeshTexture[0], material)); }
/// <summary> /// Update per model object data /// </summary> /// <param name="animationOffset">Animation index</param> /// <param name="material">Material</param> /// <param name="textureIndex">Texture index</param> public abstract void UpdatePerObject( uint animationOffset, MeshMaterial material, uint textureIndex);
private static void RenderFace(ref MeshMaterial Material, VertexTemplate[] Vertices, OpenGlTextureWrapMode wrap, ref MeshFace Face, double CameraX, double CameraY, double CameraZ) { // texture if (Material.DaytimeTexture != null) { if (Textures.LoadTexture(Material.DaytimeTexture, wrap)) { if (!TexturingEnabled) { GL.Enable(EnableCap.Texture2D); TexturingEnabled = true; } if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture) { GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name); LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap]; } } else { if (TexturingEnabled) { GL.Disable(EnableCap.Texture2D); TexturingEnabled = false; LastBoundTexture = null; } } } else { if (TexturingEnabled) { GL.Disable(EnableCap.Texture2D); TexturingEnabled = false; LastBoundTexture = null; } } // blend mode float factor; if (Material.BlendMode == MeshMaterialBlendMode.Additive) { factor = 1.0f; if (!BlendEnabled) { GL.Enable(EnableCap.Blend); } GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One); if (FogEnabled) { GL.Disable(EnableCap.Fog); } } else if (Material.NighttimeTexture == null) { float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } factor = 1.0f - 0.7f * blend; } else { factor = 1.0f; } if (Material.NighttimeTexture != null) { if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } } else { if (OptionLighting & !LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } } // render daytime polygon int FaceType = Face.Flags & MeshFace.FaceTypeMask; switch (FaceType) { case MeshFace.FaceTypeTriangles: GL.Begin(PrimitiveType.Triangles); break; case MeshFace.FaceTypeTriangleStrip: GL.Begin(PrimitiveType.TriangleStrip); break; case MeshFace.FaceTypeQuads: GL.Begin(PrimitiveType.Quads); break; case MeshFace.FaceTypeQuadStrip: GL.Begin(PrimitiveType.QuadStrip); break; default: GL.Begin(PrimitiveType.Polygon); break; } if (Material.GlowAttenuationData != 0) { float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ); if (OptionWireframe) { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f); } else { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor); } } else { if (OptionWireframe) { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f); } else { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A); } } if ((Material.Flags & MeshMaterial.EmissiveColorMask) != 0) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f }); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); } if (Material.DaytimeTexture != null) { if (LightingEnabled) { for (int j = 0; j < Face.Vertices.Length; j++) { GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z); GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y); if (Vertices[Face.Vertices[j].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); } } else { for (int j = 0; j < Face.Vertices.Length; j++) { GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y); if (Vertices[Face.Vertices[j].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); } } } else { if (LightingEnabled) { for (int j = 0; j < Face.Vertices.Length; j++) { GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z); if (Vertices[Face.Vertices[j].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); } } else { for (int j = 0; j < Face.Vertices.Length; j++) { if (Vertices[Face.Vertices[j].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); } } } GL.End(); // render nighttime polygon if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap)) { if (!TexturingEnabled) { GL.Enable(EnableCap.Texture2D); TexturingEnabled = true; } if (!BlendEnabled) { GL.Enable(EnableCap.Blend); } GL.BindTexture(TextureTarget.Texture2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name); LastBoundTexture = null; GL.AlphaFunc(AlphaFunction.Greater, 0.0f); GL.Enable(EnableCap.AlphaTest); switch (FaceType) { case MeshFace.FaceTypeTriangles: GL.Begin(PrimitiveType.Triangles); break; case MeshFace.FaceTypeTriangleStrip: GL.Begin(PrimitiveType.TriangleStrip); break; case MeshFace.FaceTypeQuads: GL.Begin(PrimitiveType.Quads); break; case MeshFace.FaceTypeQuadStrip: GL.Begin(PrimitiveType.QuadStrip); break; default: GL.Begin(PrimitiveType.Polygon); break; } float alphafactor; if (Material.GlowAttenuationData != 0) { alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ); float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount; if (blend > 1.0f) { blend = 1.0f; } alphafactor *= blend; } else { alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount; if (alphafactor > 1.0f) { alphafactor = 1.0f; } } if (OptionWireframe) { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f); } else { GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor); } if ((Material.Flags & MeshMaterial.EmissiveColorMask) != 0) { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f }); } else { GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); } for (int j = 0; j < Face.Vertices.Length; j++) { GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y); if (Vertices[Face.Vertices[j].Index] is ColoredVertex) { ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index]; GL.Color3(v.Color.R, v.Color.G, v.Color.B); } GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); } GL.End(); RestoreAlphaFunc(); if (!BlendEnabled) { GL.Disable(EnableCap.Blend); } } // normals if (OptionNormals) { if (TexturingEnabled) { GL.Disable(EnableCap.Texture2D); TexturingEnabled = false; } for (int j = 0; j < Face.Vertices.Length; j++) { GL.Begin(PrimitiveType.Lines); GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f); GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ)); GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ)); GL.End(); } } // finalize if (Material.BlendMode == MeshMaterialBlendMode.Additive) { GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); if (!BlendEnabled) { GL.Disable(EnableCap.Blend); } if (FogEnabled) { GL.Enable(EnableCap.Fog); } } }
public static Mesh Cone(float radius, float height, int circleCount, MeshMaterial material, Vector3 origin = default /*, OpenTK.Matrix4 state = default*/, RenderFlags renderFlags = RenderFlags.Solid) { // cone center should be in the middle origin -= 0.5f * height * Vector3.UnitY; float radiusInv = 1.0f / radius; float angleStep = 2 * (float)Math.PI / circleCount; // the order of the vertices: // [L, U, LC1, LS1, LC2, LS2, ...], // where // L - central point of the lower circle, // U - apex of the cone, // LCi - i-th point of the lower circle with central normal, // LSi - i-th point of the lower circle with side normal, var vertices = new List <MeshVertex> { // add L and U new MeshVertex { Position = origin, Normal = -Vector3.UnitY }, new MeshVertex { Position = origin + height * Vector3.UnitY, Normal = Vector3.UnitY } }; float angle, cos, sin; for (int i = 0; i <= circleCount; i++) { angle = i * angleStep; cos = radius * (float)Math.Cos(angle); sin = radius * (float)Math.Sin(angle); // add LCi vertices.Add(new MeshVertex { Position = origin + new Vector3(cos, 0, sin), Normal = -Vector3.UnitY }); // add LSi vertices.Add(new MeshVertex { Position = origin + new Vector3(cos, 0, sin), Normal = new Vector3(cos * radiusInv, 0, sin * radiusInv) }); } var indices = new List <uint>(); // lower circle faces for (uint i = 0; i < circleCount; i++) { indices.Add(0); indices.Add(2 * i + 2); indices.Add(2 * i + 4); } // side faces for (uint i = 0; i < circleCount; i++) { indices.Add(1); indices.Add(2 * i + 3); indices.Add(2 * i + 5); } //return new Model(vertices.ToArray(), indices.ToArray(), material, state, renderFlags: renderFlags); return(new Mesh("Cone", vertices.ToArray(), indices.ToArray(), new MeshTexture[0], material)); }
public override Material Convert(MeshMaterial material) { return(new Material()); }
private void RebuildMeshObjectBuffers() { if (!_MeshObjectsNeedRebuilding) { return; } GeometryUtility.CalculateFrustumPlanes(_Camera, _FrustumPlanes); _MeshObjectsNeedRebuilding = false; _CurrentSample = 0; // Clear all lists _MeshObjects.Clear(); _MeshMaterials.Clear(); _Vertices.Clear(); _Indices.Clear(); _Textures.Clear(); _Triangles.Clear(); int texId = -1; // Loop over all objects and gather their data foreach (RayTracingMeshObject obj in _RayTracingObjects) { MeshFilter meshFilter = obj.GetComponent <MeshFilter>(); Mesh mesh = meshFilter.sharedMesh; int firstVertex = _Vertices.Count; for (int vertexId = 0; vertexId < mesh.vertexCount; ++vertexId) { VertexInfo vertexInfo = new VertexInfo() { // position = mesh.vertices[vertexId], position = meshFilter.transform.TransformPoint(mesh.vertices[vertexId]), normal = mesh.normals[vertexId], uv = mesh.uv[vertexId] }; _Vertices.Add(vertexInfo); } // Add index data - if the vertex buffer wasn't empty before, the // indices need to be offset int firstIndex = _Indices.Count; var indices = mesh.GetIndices(0); _Indices.AddRange(indices.Select(index => index + firstVertex)); // Add the object itself _MeshObjects.Add(new MeshObject() { localToWorldMatrix = obj.transform.localToWorldMatrix, indices_offset = firstIndex / 3, indices_count = indices.Length / 3 }); Material material = obj.GetComponent <MeshRenderer>().sharedMaterial; Texture2D baseTexture = material.GetTexture("_BaseMap") as Texture2D; if (baseTexture) { _Textures.Add(baseTexture); } MeshMaterial meshMaterial = new MeshMaterial() { smoothness = material.GetFloat("_Smoothness"), specular = material.GetVector("_SpecColor"), albedo = material.GetVector("_BaseColor"), emission = material.GetVector("_EmissionColor"), textureID = baseTexture ? ++texId : -1 }; _MeshMaterials.Add(meshMaterial); } if (_TextureBuffer != null) { Destroy(_TextureBuffer); } _TextureBuffer = CreateTextureArray(_Textures.ToArray()); CreateComputeBuffer(ref _MeshObjectBuffer, _MeshObjects, 72); CreateComputeBuffer(ref _MeshMaterialBuffer, _MeshMaterials, 44); CreateComputeBuffer(ref _VertexBuffer, _Vertices, 32); CreateComputeBuffer(ref _IndexBuffer, _Indices, 12); for (int id = 0; id < _Indices.Count; id += 3) { Triangle tri = new Triangle() { id0 = _Indices[id], id1 = _Indices[id + 1], id2 = _Indices[id + 2] }; _Triangles.Add(tri); } CreateComputeBuffer(ref _FrustumBuffer, _FrustumPlanes.ToList(), 16); CreateComputeBuffer(ref _TriangleBuffer, _Triangles, 12); SetComputeBuffer(_KiFrustumCulling, "_FrustumPlanes", _FrustumBuffer); SetComputeBuffer(_KiFrustumCulling, "_Vertices", _VertexBuffer); SetComputeBuffer(_KiFrustumCulling, "_Indices", _IndexBuffer); m_RayTracingShader.Dispatch(_KiFrustumCulling, Mathf.CeilToInt(_Triangles.Count / 32.0f), 1, 1); }
/// <summary> /// Renders the mesh to the screen /// </summary> /// <param name="renderer">Renderer object to render with</param> /// <param name="camera">Camera object that is currently viewed from</param> /// <param name="lights">Dictionary of all the lights in the scene</param> public override void Render(Renderer renderer, Camera camera, ReadOnlyDictionary <string, Light> lights) { Shader shader = MeshMaterial.MatShader; shader.Bind(); shader.SetUniformMat4("u_Model", TransformationMatrix); shader.SetUniformMat3("u_ModelNormalMatrix", NormalTransformMatrix); if (camera != null) { shader.SetUniformMat4("u_View", camera.ViewMatrix); shader.SetUniformMat3("u_ViewNormalMatrix", camera.NormalMatrix); shader.SetUniformMat4("u_Projection", camera.ProjectionMatrix); } int index = 0; int numOfVisibleLights = 0; foreach (var light in lights.Values) { if (light.IsVisible) { string pre = "u_Lights[" + index.ToString() + "]."; shader.SetUniform1i(pre + "Type", (int)light.Type); shader.SetUniform3f(pre + "Position", light.Position.x, light.Position.y, light.Position.z); shader.SetUniform3f(pre + "Direction", light.Direction.x, light.Direction.y, light.Direction.z); shader.SetUniform4f(pre + "Color", light.Parameters.Color.x, light.Parameters.Color.y, light.Parameters.Color.z, light.Parameters.Color.w); shader.SetUniform1f(pre + "InnerCutoffAngle", light.Parameters.InnerCutoffAngle); shader.SetUniform1f(pre + "OuterCutoffAngle", light.Parameters.OuterCutoffAngle); shader.SetUniform1f(pre + "Intensity", light.Parameters.Intensity); shader.SetUniform1f(pre + "Exposure", light.Parameters.Exposure); shader.SetUniform1i(pre + "AttenuationType", (int)light.Parameters.AttenuationType); index++; numOfVisibleLights++; } } shader.SetUniform1i("u_NumLights", numOfVisibleLights); MeshMaterial.UpdateShader(); if (Settings.CurrentShading == ShadingOption.BoundingBox) { DrawBoundingBox(renderer, camera); } else if (Settings.CurrentShading == ShadingOption.Wireframe) { DrawWireframe(renderer, camera, Settings.WireframeThickness, Settings.WireframeColor); } else if (Settings.CurrentShading == ShadingOption.Shaded || Settings.CurrentShading == ShadingOption.WireframeOnShaded) { shader.Bind(); shader.SetUniform1b("u_Wireframe.On", Settings.CurrentShading == ShadingOption.WireframeOnShaded); shader.SetUniform4f("u_Wireframe.Color", Settings.WireframeColor.x, Settings.WireframeColor.y, Settings.WireframeColor.z, Settings.WireframeColor.w); shader.SetUniform1f("u_Wireframe.Thickness", Settings.WireframeThickness); shader.SetUniformMat4("u_ViewportMatrix", renderer.ViewportMatrix); if (Settings.Smoothing == SmoothingOption.Smooth) { renderer.Draw(m_Vao, m_Ibo, shader); } else if (Settings.Smoothing == SmoothingOption.Flat) { renderer.Draw(m_VaoFlat, m_VerticesFlat.Count, shader); } } DrawNormals(renderer, camera); if (IsSelected) { DrawSilhouette(renderer, camera); } }
public static Model Cube(float halfX, float halfY, float halfZ, MeshMaterial material, OpenToolkit.Mathematics.Matrix4 state = default, RenderFlags renderFlags = RenderFlags.Solid) { var vertices = new List <MeshVertex>(); float x, y, z; foreach (var sign in new int[] { -1, 1 }) { // X ortho faces x = sign * halfX; vertices.Add(new MeshVertex { Position = new Vector3(x, halfY, halfZ), Normal = new Vector3(sign, 0.0f, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(x, halfY, -halfZ), Normal = new Vector3(sign, 0.0f, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(x, -halfY, halfZ), Normal = new Vector3(sign, 0.0f, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(x, -halfY, -halfZ), Normal = new Vector3(sign, 0.0f, 0.0f) }); // Y ortho faces y = sign * halfY; vertices.Add(new MeshVertex { Position = new Vector3(halfX, y, halfZ), Normal = new Vector3(0.0f, sign, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(halfX, y, -halfZ), Normal = new Vector3(0.0f, sign, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(-halfX, y, halfZ), Normal = new Vector3(0.0f, sign, 0.0f) }); vertices.Add(new MeshVertex { Position = new Vector3(-halfX, y, -halfZ), Normal = new Vector3(0.0f, sign, 0.0f) }); // Z ortho faces z = sign * halfZ; vertices.Add(new MeshVertex { Position = new Vector3(halfX, halfY, z), Normal = new Vector3(0.0f, 0.0f, sign) }); vertices.Add(new MeshVertex { Position = new Vector3(halfX, -halfY, z), Normal = new Vector3(0.0f, 0.0f, sign) }); vertices.Add(new MeshVertex { Position = new Vector3(-halfX, halfY, z), Normal = new Vector3(0.0f, 0.0f, sign) }); vertices.Add(new MeshVertex { Position = new Vector3(-halfX, -halfY, z), Normal = new Vector3(0.0f, 0.0f, sign) }); } var indices = new List <uint>(); uint k; for (uint i = 0; i < 6; i++) { k = 4 * i; // lower triangle indices.Add(k); indices.Add(k + 1); indices.Add(k + 2); // upper triangle indices.Add(k + 1); indices.Add(k + 2); indices.Add(k + 3); } return(new Model(vertices.ToArray(), indices.ToArray(), material, state, renderFlags: renderFlags)); }