Ejemplo n.º 1
0
        private void UpdateUniformBuffers()
        {
            UniformInfo ui = new UniformInfo {
                LightPos = new Vector4(0, 0, 0, 1)
            };

            ui.Projection = Matrix4x4.CreatePerspectiveFieldOfView(DegreesToRadians(60.0f), _window.Width / (float)_window.Height, 0.1f, 256.0f);

            Matrix4x4 cameraRot = Matrix4x4.CreateFromYawPitchRoll(
                DegreesToRadians(_rotation.Y),
                DegreesToRadians(_rotation.X),
                DegreesToRadians(_rotation.Z));
            Vector3   cameraLookDir = Vector3.Transform(-Vector3.UnitZ, cameraRot);
            Matrix4x4 viewMatrix    = Matrix4x4.CreateLookAt(_cameraPos, _cameraPos + cameraLookDir, Vector3.UnitY);

            ui.View = viewMatrix;

            ui.Model = Matrix4x4.CreateRotationX(DegreesToRadians(_dragonRotation.X));
            ui.Model = Matrix4x4.CreateRotationY(DegreesToRadians(_dragonRotation.Y)) * ui.Model;
            ui.Model = Matrix4x4.CreateTranslation(_dragonPos) * ui.Model;

            _gd.UpdateBuffer(_uniformBuffers_vsShared, 0, ref ui);

            // Mirror
            ui.Model = Matrix4x4.Identity;
            _gd.UpdateBuffer(_uniformBuffers_vsMirror, 0, ref ui);
        }
Ejemplo n.º 2
0
        public void Link()
        {
            GL.LinkProgram(ProgramID);
            var log = GL.GetProgramInfoLog(ProgramID);

            if (!string.IsNullOrWhiteSpace(log))
            {
                Console.WriteLine(log);
            }
            GL.GetProgram(ProgramID, GetProgramParameterName.ActiveAttributes, out AttributeCount);
            GL.GetProgram(ProgramID, GetProgramParameterName.ActiveUniforms, out UniformCount);

            for (int i = 0; i < AttributeCount; i++)
            {
                AttributeInfo info = new AttributeInfo();
                GL.GetActiveAttrib(ProgramID, i, 256, out var length, out info.size, out info.type, out info.name);
                info.address = GL.GetAttribLocation(ProgramID, info.name);
                Attributes.Add(info.name, info);
            }

            for (int i = 0; i < UniformCount; i++)
            {
                UniformInfo info = new UniformInfo();
                GL.GetActiveUniform(ProgramID, i, 256, out var length, out info.size, out info.type, out info.name);
                Uniforms.Add(info.name, info);
                info.address = GL.GetUniformLocation(ProgramID, info.name);
            }
        }
Ejemplo n.º 3
0
        public void Link()
        {
            GL.LinkProgram(ProgramID);

            GL.GetProgram(ProgramID, GetProgramParameterName.ActiveAttributes, out AttributeCount);
            GL.GetProgram(ProgramID, GetProgramParameterName.ActiveUniforms, out UniformCount);

            for (int i = 0; i < AttributeCount; i++)
            {
                AttributeInfo info = new AttributeInfo();

                GL.GetActiveAttrib(ProgramID, i, 256, out int length, out info.size, out info.type, out string name);

                info.name    = name.ToString();
                info.address = GL.GetAttribLocation(ProgramID, info.name);
                Attributes.Add(name.ToString(), info);
            }

            for (int i = 0; i < UniformCount; i++)
            {
                UniformInfo info = new UniformInfo();

                GL.GetActiveUniform(ProgramID, i, 256, out int length, out info.size, out info.type, out string name);

                info.name = name.ToString();
                Uniforms.Add(name.ToString(), info);
                info.address = GL.GetUniformLocation(ProgramID, info.name);
            }
        }
Ejemplo n.º 4
0
        public static UniformInfo[] Hlsl2Glsl_GetUniformInfo(IntPtr handle)
        {
            var numUniforms     = Hlsl2Glsl_GetUniformCount(handle);
            var uniformInfosPtr = Hlsl2Glsl_GetUniformInfo_Impl(handle);
            var structSize      = Marshal.SizeOf(typeof(UniformInfo));

            var result = new UniformInfo[numUniforms];

            for (int i = 0; i < numUniforms; ++i)
            {
                var data = IntPtr.Add(uniformInfosPtr, structSize * i);
                result[i] = (UniformInfo)Marshal.PtrToStructure(data, typeof(UniformInfo));
            }

            return(result);
        }
Ejemplo n.º 5
0
        private void UpdateUniformBufferOffscreen()
        {
            UniformInfo ui = new UniformInfo {
                LightPos = new Vector4(0, 0, 0, 1)
            };

            ui.Projection = Matrix4x4.CreatePerspectiveFieldOfView(DegreesToRadians(60.0f), Window.Width / (float)Window.Height, 0.1f, 256.0f);

            ui.View = Matrix4x4.CreateLookAt(_camera.Position, _camera.Position + _camera.Forward, Vector3.UnitY);

            ui.Model = Matrix4x4.CreateRotationX(DegreesToRadians(_dragonRotation.X));
            ui.Model = Matrix4x4.CreateRotationY(DegreesToRadians(_dragonRotation.Y)) * ui.Model;
            ui.Model = Matrix4x4.CreateScale(new Vector3(1, -1, 1)) * ui.Model;
            ui.Model = Matrix4x4.CreateTranslation(_dragonPos) * ui.Model;

            GraphicsDevice.UpdateBuffer(_uniformBuffers_vsOffScreen, 0, ref ui);
        }
Ejemplo n.º 6
0
        private Dictionary <string, UniformInfo> GetUniformsInformation(int shaderProgramId)
        {
            GL.GetProgram(shaderProgramId, GetProgramParameterName.ActiveUniforms, out int UniformCount);
            Dictionary <string, UniformInfo> uniforms = new Dictionary <string, UniformInfo>();

            for (int i = 0; i < UniformCount; i++)
            {
                UniformInfo info = new UniformInfo();
                GL.GetActiveUniform(shaderProgramId, i, 256, out int length, out info.Size, out ActiveUniformType type, out string name);

                info.Name    = name.ToString();
                info.Address = GL.GetAttribLocation(shaderProgramId, info.Name);
                info.Type    = (int)type;
                uniforms.Add(name.ToString(), info);
            }

            return(uniforms);
        }
Ejemplo n.º 7
0
        private void Reflect(ShaderProgram.Sampler[] samplers)
        {
            GL.GetProgram(GLProgram, ProgramParameter.ActiveUniforms, out int uniformCount);
            GLHelper.CheckGLErrors();
            GL.GetProgram(GLProgram, ProgramParameter.ActiveUniformMaxLength, out int maxUniformNameLength);
            GLHelper.CheckGLErrors();
            uniformInfos           = new UniformInfo[uniformCount];
            uniformStagingDataSize = 0;
            var sb = new StringBuilder(maxUniformNameLength);

            for (var i = 0; i < uniformCount; i++)
            {
                sb.Clear();
                GL.GetActiveUniform(GLProgram, i, maxUniformNameLength, out _, out var arraySize, out ActiveUniformType type, sb);
                GLHelper.CheckGLErrors();
                var name     = sb.ToString();
                var location = GL.GetUniformLocation(GLProgram, name);
                GLHelper.CheckGLErrors();
                var info = new UniformInfo {
                    Name              = AdjustUniformName(name),
                    Type              = ConvertUniformType(type),
                    ArraySize         = arraySize,
                    Location          = location,
                    StagingDataOffset = -1,
                    TextureSlot       = -1
                };
                if (info.Type.IsSampler())
                {
                    if (info.ArraySize > 1)
                    {
                        throw new NotSupportedException();
                    }
                    info.TextureSlot = samplers.First(sampler => sampler.Name == info.Name).Stage;
                }
                else
                {
                    info.StagingDataOffset  = uniformStagingDataSize;
                    info.ElementSize        = 4 * info.Type.GetRowCount() * info.Type.GetColumnCount();
                    uniformStagingDataSize += info.ElementSize * info.ArraySize;
                }
                uniformInfos[i] = info;
            }
        }
Ejemplo n.º 8
0
        private void SetUniforms()
        {
            int number;

            GL.GetProgram(ProgramID, GetProgramParameterName.ActiveUniforms, out number);

            for (int i = 0; i < number; i++)
            {
                UniformInfo info   = new UniformInfo();
                int         length = 0;

                StringBuilder name = new StringBuilder();

                GL.GetActiveUniform(ProgramID, i, 256, out length, out info.Size, out info.type, name);

                info.Name = name.ToString();
                uniforms.Add(name.ToString(), info);
                info.Address = GL.GetUniformLocation(ProgramID, info.Name);
            }
        }
Ejemplo n.º 9
0
        public void Link()
        {
            GL.LinkProgram(ProgramID);

            Console.WriteLine(GL.GetProgramInfoLog(ProgramID));

#pragma warning disable CS0618 // Type or member is obsolete
            GL.GetProgram(ProgramID, ProgramParameter.ActiveAttributes, out AttributeCount);
            GL.GetProgram(ProgramID, ProgramParameter.ActiveUniforms, out UniformCount);
#pragma warning restore CS0618 // Type or member is obsolete

            for (int i = 0; i < AttributeCount; i++)
            {
                AttributeInfo info   = new AttributeInfo();
                int           length = 0;

                StringBuilder name = new StringBuilder();

                GL.GetActiveAttrib(ProgramID, i, 256, out length, out info.size, out info.type, name);

                info.name    = name.ToString();
                info.address = GL.GetAttribLocation(ProgramID, info.name);
                Attributes.Add(name.ToString(), info);
            }

            for (int i = 0; i < UniformCount; i++)
            {
                UniformInfo info   = new UniformInfo();
                int         length = 0;

                StringBuilder name = new StringBuilder();

                GL.GetActiveUniform(ProgramID, i, 256, out length, out info.size, out info.type, name);

                info.name = name.ToString();
                Uniforms.Add(name.ToString(), info);
                info.address = GL.GetUniformLocation(ProgramID, info.name);
            }
        }
Ejemplo n.º 10
0
        /// <exception cref="InvalidOperationException">
        /// <paramref name="required"/> is <see langword="true"/> and either <paramref name="vertexShader"/> or <paramref name="fragmentShader"/> is unavailable (their <see cref="Shader.Available"/> property is <see langword="false"/>), or
        /// <c>glLinkProgram</c> call did not produce expected result
        /// </exception>
        public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo)
        {
            // if the shaders aren't available, the pipeline isn't either
            if (!vertexShader.Available || !fragmentShader.Available)
            {
                string errors = $"Vertex Shader:\r\n {vertexShader.Errors} \r\n-------\r\nFragment Shader:\r\n{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)
                {
                    Errors = errors
                };
                return(pipeline);
            }

            bool success = true;

            var vsw = vertexShader.Opaque as ShaderWrapper;
            var fsw = fragmentShader.Opaque as ShaderWrapper;
            var sws = new[] { vsw, fsw };

            ErrorCode errcode;
            int       pid = GL.CreateProgram();

            GL.AttachShader(pid, vsw.sid);
            errcode = GL.GetError();
            GL.AttachShader(pid, fsw.sid);
            errcode = GL.GetError();

            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;
                }
            }

            GL.GetProgram(pid, GetProgramParameterName.LinkStatus, out var 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;
                }
                resultLog = GL.GetProgramInfoLog(pid);
                Util.DebugWriteLine(resultLog);
            }

            //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 shouldn't 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>();

            GL.GetProgram(pid, GetProgramParameterName.ActiveAttributes, out var nAttributes);
            for (int i = 0; i < nAttributes; i++)
            {
                int              size, length;
                string           name = new System.Text.StringBuilder(1024).ToString();
                ActiveAttribType type;
                GL.GetActiveAttrib(pid, i, 1024, out length, out size, out type, out name);
                attributes.Add(new AttributeInfo()
                {
                    Handle = new IntPtr(i), Name = name
                });
            }

            //get all the uniforms
            List <UniformInfo> uniforms = new List <UniformInfo>();

            GL.GetProgram(pid, GetProgramParameterName.ActiveUniforms, out var nUniforms);
            List <int> samplers = new List <int>();

            for (int i = 0; i < nUniforms; i++)
            {
                int    size, length;
                string name = new System.Text.StringBuilder(1024).ToString();
                GL.GetActiveUniform(pid, i, 1024, out length, out size, out var type, out name);
                errcode = GL.GetError();
                int loc = GL.GetUniformLocation(pid, name);

                var ui = new UniformInfo {
                    Name = name, 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 don't 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));
        }
Ejemplo n.º 11
0
        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;
                string           name = new System.Text.StringBuilder(1024).ToString();
                ActiveAttribType type;
                GL.GetActiveAttrib(pid, i, 1024, out length, out size, out type, out name);
                attributes.Add(new AttributeInfo()
                {
                    Handle = new IntPtr(i), Name = name
                });
            }

            //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;
                string            name = new System.Text.StringBuilder(1024).ToString().ToString();
                GL.GetActiveUniform(pid, i, 1024, out length, out size, out type, out name);
                errcode = GL.GetError();
                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));
        }
Ejemplo n.º 12
0
        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));
        }
Ejemplo n.º 13
0
        public void Link()
        {
            GL.LinkProgram(ProgramID);

            Console.WriteLine(GL.GetProgramInfoLog(ProgramID));

            GL.GetProgram(ProgramID, ProgramParameter.ActiveAttributes, out AttributeCount);
            GL.GetProgram(ProgramID, ProgramParameter.ActiveUniforms, out UniformCount);

            for (int i = 0; i < AttributeCount; i++)
            {
                AttributeInfo info = new AttributeInfo();
                int length = 0;

                StringBuilder name = new StringBuilder();

                GL.GetActiveAttrib(ProgramID, i, 256, out length, out info.size, out info.type, name);

                info.name = name.ToString();
                info.address = GL.GetAttribLocation(ProgramID, info.name);
                Attributes.Add(name.ToString(), info);
            }

            for (int i = 0; i < UniformCount; i++)
            {
                UniformInfo info = new UniformInfo();
                int length = 0;

                StringBuilder name = new StringBuilder();

                GL.GetActiveUniform(ProgramID, i, 256, out length, out info.size, out info.type, name);

                info.name = name.ToString();
                Uniforms.Add(name.ToString(), info);
                info.address = GL.GetUniformLocation(ProgramID, info.name);
            }
        }
Ejemplo n.º 14
0
 internal ConversionResult(string glslCode, UniformInfo[] uniforms)
 {
     GlslCode = glslCode;
     Uniforms = uniforms;
 }
Ejemplo n.º 15
0
        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));
        }
Ejemplo n.º 16
0
        public static UniformInfo[] Hlsl2Glsl_GetUniformInfo(IntPtr handle)
        {
            var numUniforms = Hlsl2Glsl_GetUniformCount(handle);
            var uniformInfosPtr = Hlsl2Glsl_GetUniformInfo_Impl(handle);
            var structSize = Marshal.SizeOf(typeof(UniformInfo));

            var result = new UniformInfo[numUniforms];
            for (int i = 0; i < numUniforms; ++i)
            {
                var data = IntPtr.Add(uniformInfosPtr, structSize * i);
                result[i] = (UniformInfo) Marshal.PtrToStructure(data, typeof (UniformInfo));
            }

            return result;
        }