Пример #1
0
        private unsafe void ClipSpace2NormalDeviceSpace(PassBuffer passBuffer)
        {
            if (passBuffer.elementType != PassType.Vec4)
            {
                throw new Exception(String.Format("This pass-buffer must be of vec4 type!"));
            }

            var array  = (vec4 *)passBuffer.Mapbuffer();
            int length = passBuffer.Length();

            for (int i = 0; i < length; i++)
            {
                vec4  gl_Position = array[i];
                float w           = gl_Position.w;
                if (w != 0)
                {
                    gl_Position.x = gl_Position.x / w;
                    gl_Position.y = gl_Position.y / w;
                    gl_Position.z = gl_Position.z / w;
                    gl_Position.w = 1;
                }
                array[i] = gl_Position;
            }
            passBuffer.Unmapbuffer();
        }
Пример #2
0
        /// <summary>
        /// Find fragments in the specified triangle.
        /// </summary>
        /// <param name="fragCoord0"></param>
        /// <param name="fragCoord1"></param>
        /// <param name="fragCoord2"></param>
        /// <param name="pointers"></param>
        /// <param name="group"></param>
        /// <param name="passBuffers"></param>
        /// <param name="result"></param>
        unsafe private static void FindFragmentsInTriangle(vec3 fragCoord0, vec3 fragCoord1, vec3 fragCoord2, void *[] pointers, LinearInterpolationInfoGroup group, PassBuffer[] passBuffers, List <Fragment> result)
        {
            int attributeCount = passBuffers.Length - 1;
            var pixelList      = new List <vec3>();

            FindPixelsAtTriangle(fragCoord0, fragCoord1, fragCoord2, pixelList);
            //OnSamePlane(fragCoord0, fragCoord1, fragCoord2, pixelList);
            for (int i = 0; i < pixelList.Count; i++) // for each pixel at this line..
            {
                vec3  pixel = pixelList[i];
                var   fragment = new Fragment(pixel, attributeCount);
                float p0, p1, p2;
                LinearInterpolationTriangle(pixel, fragCoord0, fragCoord1, fragCoord2, out p0, out p1, out p2);
                for (int t = 0; t < attributeCount; t++) // new pass-buffer objects.
                {
                    PassType passType = passBuffers[t + 1].elementType;
                    fragment.attributes[t] = new PassBuffer(passType, 1);        // only one element.
                }
                for (int attrIndex = 0; attrIndex < attributeCount; attrIndex++) // fill data in pass-buffer.
                {
                    PassBuffer attribute         = fragment.attributes[attrIndex];
                    void *     fragmentAttribute = attribute.Mapbuffer().ToPointer();
                    switch (attribute.elementType)
                    {
                    case PassType.Float:
                    {
                        var fAttr = (float *)fragmentAttribute; var array = (float *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Vec2:
                    {
                        var fAttr = (vec2 *)fragmentAttribute; var array = (vec2 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Vec3:
                    {
                        var fAttr = (vec3 *)fragmentAttribute; var array = (vec3 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Vec4:
                    {
                        var fAttr = (vec4 *)fragmentAttribute; var array = (vec4 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Mat2:
                    {
                        var fAttr = (mat2 *)fragmentAttribute; var array = (mat2 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Mat3:
                    {
                        var fAttr = (mat3 *)fragmentAttribute; var array = (mat3 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    case PassType.Mat4:
                    {
                        var fAttr = (mat4 *)fragmentAttribute; var array = (mat4 *)pointers[attrIndex];
                        fAttr[0] = array[group.array[0].gl_VertexID] * p0 + array[group.array[1].gl_VertexID] * p1 + array[group.array[2].gl_VertexID] * p2;
                    } break;

                    default:
                        throw new NotDealWithNewEnumItemException(typeof(PassType));
                    }
                    attribute.Unmapbuffer();
                }
                result.Add(fragment);
            }
        }
Пример #3
0
        private unsafe void FragmentShaderStage(ShaderProgram program, List <Fragment> fragmentList)
        {
            FragmentShader fs = program.FragmentShader; if (fs == null)

            {
                return;
            }

            foreach (var fragment in fragmentList)
            {
                var instance = fs.CreateCodeInstance() as FragmentCodeBase; // an executable fragment shader.
                instance.gl_FragCoord = fragment.gl_FragCoord;              // setup fragmen coordinatein window/screen space.
                // setup "in SomeType varName;" vertex attributes.
                InVariable[] inVariables = fs.inVariableDict.Values.ToArray();
                if (inVariables.Length != fragment.attributes.Length)
                {
                    throw new Exception("This should not happen!");
                }
                for (int index = 0; index < inVariables.Length; index++)
                {
                    InVariable inVar     = inVariables[index];
                    PassBuffer attribute = fragment.attributes[index];
                    var        pointer   = attribute.Mapbuffer().ToPointer();
                    switch (attribute.elementType)
                    {
                    case PassType.Float: inVar.fieldInfo.SetValue(instance, ((float *)pointer)[0]); break;

                    case PassType.Vec2: inVar.fieldInfo.SetValue(instance, ((vec2 *)pointer)[0]); break;

                    case PassType.Vec3: inVar.fieldInfo.SetValue(instance, ((vec3 *)pointer)[0]); break;

                    case PassType.Vec4: inVar.fieldInfo.SetValue(instance, ((vec4 *)pointer)[0]); break;

                    case PassType.Mat2: inVar.fieldInfo.SetValue(instance, ((mat2 *)pointer)[0]); break;

                    case PassType.Mat3: inVar.fieldInfo.SetValue(instance, ((mat3 *)pointer)[0]); break;

                    case PassType.Mat4: inVar.fieldInfo.SetValue(instance, ((mat4 *)pointer)[0]); break;

                    default: throw new NotDealWithNewEnumItemException(typeof(PassType));
                    }
                    attribute.Unmapbuffer();
                }
                // setup "uniform SomeType varName;" in fragment shader.
                Dictionary <string, UniformValue> nameUniformDict = program.nameUniformDict;
                foreach (UniformVariable uniformVar in fs.UniformVariableDict.Values)
                {
                    string       name = uniformVar.fieldInfo.Name;
                    UniformValue obj  = null;
                    if (nameUniformDict.TryGetValue(name, out obj))
                    {
                        if (obj.value != null)
                        {
                            uniformVar.fieldInfo.SetValue(instance, obj.value);
                        }
                    }
                }

                instance.main();       // execute fragment shader code.
                fragment.discard = instance.discard;
                if (!instance.discard) // if this fragment is not discarded.
                {
                    OutVariable[] outVariables = fs.outVariableDict.Values.ToArray();
                    var           outBuffers   = new PassBuffer[outVariables.Length];
                    for (int index = 0; index < outVariables.Length; index++)
                    {
                        OutVariable outVar    = outVariables[index];
                        var         outBuffer = new PassBuffer(outVar.fieldInfo.FieldType.GetPassType(), 1);
                        var         pointer   = outBuffer.Mapbuffer().ToPointer();
                        switch (outBuffer.elementType)
                        {
                        case PassType.Float: ((float *)pointer)[0] = (float)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Vec2: ((vec2 *)pointer)[0] = (vec2)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Vec3: ((vec3 *)pointer)[0] = (vec3)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Vec4: ((vec4 *)pointer)[0] = (vec4)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Mat2: ((mat2 *)pointer)[0] = (mat2)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Mat3: ((mat3 *)pointer)[0] = (mat3)outVar.fieldInfo.GetValue(instance); break;

                        case PassType.Mat4: ((mat4 *)pointer)[0] = (mat4)outVar.fieldInfo.GetValue(instance); break;

                        default: throw new NotDealWithNewEnumItemException(typeof(PassType));
                        }
                        outBuffer.Unmapbuffer();
                        outBuffers[index] = outBuffer;
                    }
                    fragment.outVariables = outBuffers;
                }
            }
        }
Пример #4
0
        private unsafe List <Fragment> LinearInterpolationPoints(int count, DrawElementsType type, IntPtr indices, VertexArrayObject vao, ShaderProgram program, GLBuffer indexBuffer, PassBuffer[] passBuffers)
        {
            var result           = new List <Fragment>();
            int attributeCount   = passBuffers.Length - 1;
            var gl_PositionArray = (vec4 *)passBuffers[0].Mapbuffer().ToPointer();
            var pointers         = new void *[passBuffers.Length - 1];

            for (int i = 0; i < pointers.Length; i++)
            {
                pointers[i] = passBuffers[i + 1].Mapbuffer().ToPointer();
            }
            byte[]   indexData       = indexBuffer.Data;
            int      indexLength     = indexData.Length / ByteLength(type);
            GCHandle pin             = GCHandle.Alloc(indexData, GCHandleType.Pinned);
            IntPtr   pointer         = pin.AddrOfPinnedObject();
            var      gl_VertexIDList = new List <uint>();
            ivec4    viewport        = this.viewport;

            for (int indexID = indices.ToInt32() / ByteLength(type), c = 0; c < count && indexID < indexLength; indexID++, c++)
            {
                uint gl_VertexID = GetVertexID(pointer, type, indexID);
                if (gl_VertexIDList.Contains(gl_VertexID))
                {
                    continue;
                }
                else
                {
                    gl_VertexIDList.Add(gl_VertexID);
                }

                vec3 fragCoord = new vec3((gl_PositionArray[gl_VertexID].x + 1) / 2.0f * viewport.z + viewport.x,
                                          (gl_PositionArray[gl_VertexID].y + 1) / 2.0f * viewport.w + viewport.y,
                                          (gl_PositionArray[gl_VertexID].z + 1) / 2.0f * (float)(this.depthRangeFar - this.depthRangeNear) + (float)this.depthRangeNear);
                var fragment = new Fragment(fragCoord, attributeCount);
                for (int i = 0; i < attributeCount; i++) // new pass-buffer objects.
                {
                    PassType passType = passBuffers[i].elementType;
                    fragment.attributes[i] = new PassBuffer(passType, 1);        // only one element.
                }
                for (int attrIndex = 0; attrIndex < attributeCount; attrIndex++) // fill data in pass-buffer.
                {
                    PassBuffer attribute         = fragment.attributes[attrIndex];
                    void *     fragmentAttribute = attribute.Mapbuffer().ToPointer();
                    switch (attribute.elementType)
                    {
                    case PassType.Float:
                    {
                        var fAttr = (float *)fragmentAttribute; var array = (float *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Vec2:
                    {
                        var fAttr = (vec2 *)fragmentAttribute; var array = (vec2 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Vec3:
                    {
                        var fAttr = (vec3 *)fragmentAttribute; var array = (vec3 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Vec4:
                    {
                        var fAttr = (vec4 *)fragmentAttribute; var array = (vec4 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Mat2:
                    {
                        var fAttr = (mat2 *)fragmentAttribute; var array = (mat2 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Mat3:
                    {
                        var fAttr = (mat3 *)fragmentAttribute; var array = (mat3 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    case PassType.Mat4:
                    {
                        var fAttr = (mat4 *)fragmentAttribute; var array = (mat4 *)pointers[attrIndex];
                        fAttr[0] = array[gl_VertexID];
                    } break;

                    default:
                        throw new NotDealWithNewEnumItemException(typeof(PassType));
                    }
                    attribute.Unmapbuffer();
                }
                result.Add(fragment);
            }

            for (int i = 0; i < passBuffers.Length; i++)
            {
                passBuffers[i].Unmapbuffer();
            }

            return(result);
        }