Dvelopment : Custom Model File Format (Rendering) (original) (raw)

A template for model rendering.

using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Toolbox.Library; using Toolbox.Library.IO; using Toolbox.Library.Rendering; using Toolbox.Library.Forms; using OpenTK; using GL_EditorFramework.GL_Core; using OpenTK.Graphics.OpenGL;

namespace FirstPlugin { public class MDL : TreeNodeFile, IFileFormat { public FileType FileType { get; set; } = FileType.Model;

    public bool CanSave { get; set; }
    public string[] Description { get; set; } = new string[] { "MDL" };
    public string[] Extension { get; set; } = new string[] { "*.mdl" };
    public string FileName { get; set; }
    public string FilePath { get; set; }
    public IFileInfo IFileInfo { get; set; }

    public bool Identify(System.IO.Stream stream)
    {
        using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
        {
            return reader.CheckSignature(4, "MDL3");
        }
    }

    public Type[] Types
    {
        get
        {
            List<Type> types = new List<Type>();
            return types.ToArray();
        }
    }

    //Check for the viewport in the object editor
    //This is attached to it to load multiple file formats within the object editor to the viewer
    Viewport viewport
    {
        get
        {
            var editor = LibraryGUI.GetObjectEditor();
            return editor.GetViewport();
        }
        set
        {
            var editor = LibraryGUI.GetObjectEditor();
            editor.LoadViewport(value);
        }
    }

    bool DrawablesLoaded = false;
    public override void OnClick(TreeView treeView)
    {
        //Make sure opengl is enabled
        if (Runtime.UseOpenGL)
        {
            //Open the viewport
            if (viewport == null)
            {
                viewport = new Viewport(ObjectEditor.GetDrawableContainers());
                viewport.Dock = DockStyle.Fill;
            }

            //Make sure to load the drawables only once so set it to true!
            if (!DrawablesLoaded)
            {
                ObjectEditor.AddContainer(DrawableContainer);
                DrawablesLoaded = true;
            }

            //Reload which drawable to display
            viewport.ReloadDrawables(DrawableContainer);
            LibraryGUI.LoadEditor(viewport);

            viewport.Text = Text;
        }
    }

    public MDL_Renderer Renderer;

    public DrawableContainer DrawableContainer = new DrawableContainer();

    public void Load(System.IO.Stream stream)
    {
        CanSave = true;

        //Set renderer
        //Load it to a drawables list
        Renderer = new MDL_Renderer();
        DrawableContainer.Name = FileName;
        DrawableContainer.Drawables.Add(Renderer);

        //Lets make a new skeleton too
        STSkeleton skeleton = new STSkeleton();

        //Note the bone class will be rewritten soon to be a bit better
        STBone bone = new STBone(skeleton); //Add the skeleton as a paramater
        bone.RotationType = STBone.BoneRotationType.Euler;
        bone.Position = new Vector3(5,0,0);
        bone.Scale = new Vector3(1, 1, 1);
        bone.Rotation =new Vector4(0, 0.5f, 0, 1);
        bone.parentIndex = -1;
        skeleton.bones.Add(bone);

        //Update the skeleton bone matrices
        skeleton.reset();
        skeleton.update();

        //Create a renderable object for our mesh
        var renderedMesh = new GenericRenderedObject();
        renderedMesh.ImageKey = "mesh";
        renderedMesh.SelectedImageKey = "mesh";
        renderedMesh.Checked = true;

        //Load vertices
        for (int v = 0; v < 100; v++)
        {
            Vertex vert = new Vertex();
            vert.pos = new Vector3(1,5,1);
            vert.nrm = new Vector3(1, 0, 1);
            vert.uv0 = new Vector2(1, 0);
            renderedMesh.vertices.Add(vert);
        }

        ushort[] Indices = new ushort[] { 0, 1, 2, 3, 4, 5, 6 };

        //Faces are stored in polygon groups allowing to specifically map materials to certain groups
        renderedMesh.PolygonGroups = new List<STGenericPolygonGroup>();
        var polygonGroup = new STGenericPolygonGroup();

        for (int f = 0; f < Indices.Length; f++)
        {
            polygonGroup.faces.AddRange(new int[3]
            {
                       Indices[f++],
                       Indices[f++],
                       Indices[f]
            });
        }

        renderedMesh.PolygonGroups.Add(polygonGroup);
        renderedMesh.Text = $"Mesh 0";
        Nodes.Add(renderedMesh);
        Renderer.Meshes.Add(renderedMesh);
    }
    public void Unload()
    {

    }
    public byte[] Save()
    {
        return null;
    }

    public class MaterialTextureMap : STGenericMatTexture
    {
        //The index of a texture
        //Some formats will map them by index, some by name, some by a hash, it's up to how the user handles it
        public int TextureIndex { get; set; }
    }

    public class MDL_Renderer : GenericModelRenderer
    {
        //A list of textures to display on the model
        public List<STGenericTexture> TextureList = new List<STGenericTexture>();

        public override void OnRender(GLControl control)
        {
            //Here we can add things on each frame rendered
        }

        //Render data to display by per material and per mesh
        public override void SetRenderData(STGenericMaterial mat, ShaderProgram shader, STGenericObject m)
        {
        }

        //Custom bind texture method
        public override int BindTexture(STGenericMatTexture tex, ShaderProgram shader)
        {
            //By default we bind to the default texture to use
            //This will be used if no texture is found
            GL.ActiveTexture(TextureUnit.Texture0 + tex.textureUnit + 1);
            GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.RenderableTex.TexID);

            string activeTex = tex.Name;

            //We want to cast our custom texture map class to get any custom properties we may need
            //If you don't need any custom way of mapping, you can just stick with the generic one
            var matTexture = (MaterialTextureMap)tex;

            //Go through our texture maps in the material and see if the index matches
            foreach (var texture in TextureList)
            {
                if (TextureList.IndexOf(texture) == matTexture.TextureIndex)
                {
                    BindGLTexture(tex, shader, TextureList[matTexture.TextureIndex]);
                    return tex.textureUnit + 1;
                }

                //You can also check if the names match
                if (texture.Text == tex.Name)
                {
                    BindGLTexture(tex, shader, TextureList[matTexture.TextureIndex]);
                    return tex.textureUnit + 1;
                }
            }

            //Return our texture uint id. 
            return tex.textureUnit + 1;
        }
    }
}

}

`