Пример #1
0
        /// <summary>
        /// Create OpenGL object. Standard object constructor for ProtoFX.
        /// </summary>
        /// <param name="block"></param>
        /// <param name="scene"></param>
        /// <param name="debugging"></param>
        public GLBuffer(Compiler.Block block, Dict scene, bool debugging)
            : base(block.Name, block.Anno)
        {
            var err = new CompileException($"buffer '{block.Name}'");

            // PARSE COMMANDS AND CONVERT THEM TO CLASS FIELDS
            Cmds2Fields(block, err);

            // PARSE COMMANDS
            var datalist = new List <byte[]>();

            foreach (var cmd in block["txt"])
            {
                datalist.Add(LoadText(cmd, scene, err | $"command {cmd.Name} 'txt'"));
            }

            foreach (var cmd in block["xml"])
            {
                datalist.Add(LoadXml(cmd, scene, err | $"command {cmd.Name} 'xml'"));
            }

            // merge data into a single array
            var iter = datalist.Cat();
            var data = iter.Take(Size == 0 ? iter.Count() : Size).ToArray();

            if (Size == 0)
            {
                Size = data.Length;
            }

            // CONVERT DATA
            var clazz = block["class"].FirstOrDefault();

            if (clazz != null && Size > 0)
            {
                var converter = GLCsharp.GetMethod(clazz, scene, err);
                data = (byte[])converter?.Invoke(null, new[] { data });
            }

            // CREATE OPENGL OBJECT
            CreateBuffer(data);
            if (HasErrorOrGlError(err, block))
            {
                throw err;
            }
        }
Пример #2
0
        /// <summary>
        /// Create class instance of a C# class compiled through GLCSharp.
        /// </summary>
        /// <param name="params">Input parameters for GLObject creation.</param>
        public GLInstance(Compiler.Block block, Dict scene, bool debugging)
            : base(block.Name, block.Anno)
        {
            var err = new CompileException($"instance '{Name}'");

            // INSTANTIATE CSHARP CLASS FROM CODE BLOCK
            Instance = GLCsharp.CreateInstance(block, scene, err);
            if (err.HasErrors)
            {
                throw err;
            }

            // get Bind method from main class instance
            update = Instance.GetType().GetMethod("Update", new[] {
                typeof(int), typeof(int), typeof(int), typeof(int), typeof(int)
            });

            // get Unbind method from main class instance
            endpass = Instance.GetType().GetMethod("EndPass", new[] { typeof(int) });

            // get Delete method from main class instance
            delete = Instance.GetType().GetMethod("Delete");

            // get all public methods and check whether
            // they can be used as event handlers for glControl
            var reference = scene.GetValueOrDefault <GLReference>(GraphicControl.nullname);
            var glControl = (GraphicControl)reference.Reference;
            var methods   = Instance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);

            foreach (var method in methods)
            {
                var info = glControl.GetType().GetEvent(method.Name);
                if (info != null)
                {
                    var csmethod = Delegate.CreateDelegate(info.EventHandlerType, Instance, method.Name);
                    info.AddEventHandler(glControl, csmethod);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Create OpenGL object. Standard object constructor for ProtoFX.
        /// </summary>
        /// <param name="block"></param>
        /// <param name="scene"></param>
        /// <param name="debugging"></param>
        public GLShader(Compiler.Block block, Dict scene, bool debugging)
            : base(block.Name, block.Anno)
        {
            var err = new CompileException($"shader '{Name}'");

            // COMPILE AND LINK SHADER INTO A SHADER PROGRAM

            switch (Anno)
            {
            case "vert": ShaderType = ShaderType.VertexShader; break;

            case "tess": ShaderType = ShaderType.TessControlShader; break;

            case "eval": ShaderType = ShaderType.TessEvaluationShader; break;

            case "geom": ShaderType = ShaderType.GeometryShader; break;

            case "frag": ShaderType = ShaderType.FragmentShader; break;

            case "comp": ShaderType = ShaderType.ComputeShader; break;

            default: throw err.Add($"Shader type '{Anno}' is not supported.", block);
            }

            glname = GL.CreateShaderProgram(ShaderType, 1, new[] { block.Body });

            // check for errors

            GL.GetProgram(glname, GetProgramParameterName.LinkStatus, out int status);
            if (status != 1)
            {
                err.Add($"\n{GL.GetProgramInfoLog(glname)}", block);
            }
            if (HasErrorOrGlError(err, block))
            {
                throw err;
            }

            // CREATE CSHARP DEBUG CODE

            string          code;
            CompilerResults rs;

            if (debugging)
            {
                code = Converter.Shader2Class(ShaderType, Name, block.Body, block.BodyIndex);
                rs   = GLCsharp.CompileFilesOrSource(new[] { code }, null, block, err, new[] { Name });
                if (rs.Errors.Count == 0)
                {
                    DebugShader = (Shader)rs.CompiledAssembly.CreateInstance(
                        $"App.Glsl.{Name}", false, BindingFlags.Default, null,
                        new object[] { block.LineInFile }, CultureInfo.CurrentCulture, null);
                }
            }

            // check for errors
            if (err.HasErrors)
            {
                throw err;
            }
        }