Exemplo n.º 1
0
        protected void BindVertexElementToGpu(VertexElement elem, HardwareVertexBuffer vertexBuffer, int vertexStart,
                                              IList <int> attribsBound, IList <int> instanceAttribsBound)
        {
            IntPtr pBufferData;
            var    hwGlBuffer = (GLHardwareVertexBuffer)vertexBuffer;

            if (currentCapabilities.HasCapability(Graphics.Capabilities.VertexBuffer))
            {
                Gl.glBindBufferARB(Gl.GL_ARRAY_BUFFER_ARB, hwGlBuffer.GLBufferID);
                pBufferData = BUFFER_OFFSET(elem.Offset);
            }
            else
            {
                // ReSharper disable PossibleInvalidCastException
                pBufferData = ((GLDefaultHardwareVertexBuffer)(vertexBuffer)).DataPtr(elem.Offset);
                // ReSharper restore PossibleInvalidCastException
            }
            if (vertexStart != 0)
            {
                pBufferData = pBufferData.Offset(vertexStart * vertexBuffer.VertexSize);
            }

            var sem            = elem.Semantic;
            var multitexturing = Capabilities.TextureUnitCount > 1;

            var isCustomAttrib = false;

            if (this.currentVertexProgram != null)
            {
                isCustomAttrib = this.currentVertexProgram.IsAttributeValid(sem, (uint)elem.Index);

                if (hwGlBuffer.IsInstanceData)
                {
                    var attrib = this.currentVertexProgram.AttributeIndex(sem, (uint)elem.Index);
                    glVertexAttribDivisor((int)attrib, hwGlBuffer.InstanceDataStepRate);
                    instanceAttribsBound.Add((int)attrib);
                }
            }


            // Custom attribute support
            // tangents, binormals, blendweights etc always via this route
            // builtins may be done this way too
            if (isCustomAttrib)
            {
                var attrib     = this.currentVertexProgram.AttributeIndex(sem, (uint)elem.Index);
                var typeCount  = VertexElement.GetTypeCount(elem.Type);
                var normalised = Gl.GL_FALSE;
                switch (elem.Type)
                {
                case VertexElementType.Color:
                case VertexElementType.Color_ABGR:
                case VertexElementType.Color_ARGB:
                    // Because GL takes these as a sequence of single unsigned bytes, count needs to be 4
                    // VertexElement::getTypeCount treats them as 1 (RGBA)
                    // Also need to normalise the fixed-point data
                    typeCount  = 4;
                    normalised = Gl.GL_TRUE;
                    break;

                default:
                    break;
                }

                Gl.glVertexAttribPointerARB(attrib, typeCount, GLHardwareBufferManager.GetGLType(elem.Type), normalised,
                                            vertexBuffer.VertexSize, pBufferData);
                Gl.glEnableVertexAttribArrayARB(attrib);

                attribsBound.Add((int)attrib);
            }
            else
            {
                // fixed-function & builtin attribute support
                switch (sem)
                {
                case VertexElementSemantic.Position:
                    Gl.glVertexPointer(VertexElement.GetTypeCount(elem.Type), GLHardwareBufferManager.GetGLType(elem.Type),
                                       vertexBuffer.VertexSize, pBufferData);
                    Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
                    break;

                case VertexElementSemantic.Normal:
                    Gl.glNormalPointer(GLHardwareBufferManager.GetGLType(elem.Type), vertexBuffer.VertexSize, pBufferData);
                    Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);
                    break;

                case VertexElementSemantic.Diffuse:
                    Gl.glColorPointer(4, GLHardwareBufferManager.GetGLType(elem.Type), vertexBuffer.VertexSize, pBufferData);
                    Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);
                    break;

                case VertexElementSemantic.Specular:
                    if (this.GLEW_EXT_secondary_color)
                    {
                        Gl.glSecondaryColorPointerEXT(4, GLHardwareBufferManager.GetGLType(elem.Type), vertexBuffer.VertexSize,
                                                      pBufferData);
                        Gl.glEnableClientState(Gl.GL_SECONDARY_COLOR_ARRAY);
                    }
                    break;

                case VertexElementSemantic.TexCoords:

                    if (this.currentVertexProgram != null)
                    {
                        // Programmable pipeline - direct UV assignment
                        Gl.glClientActiveTextureARB(Gl.GL_TEXTURE0 + elem.Index);
                        Gl.glTexCoordPointer(VertexElement.GetTypeCount(elem.Type), GLHardwareBufferManager.GetGLType(elem.Type),
                                             vertexBuffer.VertexSize, pBufferData);
                        Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
                    }
                    else
                    {
                        // fixed function matching to units based on tex_coord_set
                        for (var i = 0; i < disabledTexUnitsFrom; i++)
                        {
                            // Only set this texture unit's texcoord pointer if it
                            // is supposed to be using this element's index
                            if (this.texCoordIndex[i] != elem.Index || i >= this._fixedFunctionTextureUnits)
                            {
                                continue;
                            }

                            if (multitexturing)
                            {
                                Gl.glClientActiveTextureARB(Gl.GL_TEXTURE0 + i);
                            }
                            Gl.glTexCoordPointer(VertexElement.GetTypeCount(elem.Type), GLHardwareBufferManager.GetGLType(elem.Type),
                                                 vertexBuffer.VertexSize, pBufferData);
                            Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
                        }
                    }
                    break;

                default:
                    break;
                }
            } // isCustomAttrib
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lockedBuffer"></param>
        /// <param name="leftIndex"></param>
        /// <param name="rightIndex"></param>
        /// <param name="destIndex"></param>
        protected void InterpolateVertexData(BufferBase lockedBuffer, int leftIndex, int rightIndex, int destIndex)
        {
#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                var vertexSize  = this.declaration.GetVertexSize(0);
                var elemPos     = this.declaration.FindElementBySemantic(VertexElementSemantic.Position);
                var elemNorm    = this.declaration.FindElementBySemantic(VertexElementSemantic.Normal);
                var elemDiffuse = this.declaration.FindElementBySemantic(VertexElementSemantic.Diffuse);
                var elemTex0    = this.declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 0);
                var elemTex1    = this.declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 1);

                //byte* pDestChar, pLeftChar, pRightChar;

                // Set up pointers & interpolate
                var pDest  = (lockedBuffer + (vertexSize * destIndex));
                var pLeft  = (lockedBuffer + (vertexSize * leftIndex));
                var pRight = (lockedBuffer + (vertexSize * rightIndex));

                // Position
                var pDestReal  = (pDest + elemPos.Offset).ToFloatPointer();
                var pLeftReal  = (pLeft + elemPos.Offset).ToFloatPointer();
                var pRightReal = (pRight + elemPos.Offset).ToFloatPointer();

                pDestReal[0] = (pLeftReal[0] + pRightReal[0]) * 0.5f;
                pDestReal[1] = (pLeftReal[1] + pRightReal[1]) * 0.5f;
                pDestReal[2] = (pLeftReal[2] + pRightReal[2]) * 0.5f;

                if (elemNorm != null)
                {
                    // Normals
                    pDestReal  = (pDest + elemNorm.Offset).ToFloatPointer();
                    pLeftReal  = (pLeft + elemNorm.Offset).ToFloatPointer();
                    pRightReal = (pRight + elemNorm.Offset).ToFloatPointer();

                    var norm = Vector3.Zero;
                    norm.x = (pLeftReal[0] + pRightReal[0]) * 0.5f;
                    norm.y = (pLeftReal[1] + pRightReal[1]) * 0.5f;
                    norm.z = (pLeftReal[2] + pRightReal[2]) * 0.5f;
                    norm.Normalize();

                    pDestReal[0] = norm.x;
                    pDestReal[1] = norm.y;
                    pDestReal[2] = norm.z;
                }
                if (elemDiffuse != null)
                {
                    // Blend each byte individually
                    var pDestChar  = (pDest + elemDiffuse.Offset).ToBytePointer();
                    var pLeftChar  = (pLeft + elemDiffuse.Offset).ToBytePointer();
                    var pRightChar = (pRight + elemDiffuse.Offset).ToBytePointer();

                    // 4 bytes to RGBA
                    pDestChar[0] = (byte)((pLeftChar[0] + pRightReal[0]) * 0.5f);
                    pDestChar[1] = (byte)((pLeftChar[1] + pRightChar[1]) * 0.5f);
                    pDestChar[2] = (byte)((pLeftChar[2] + pRightChar[2]) * 0.5f);
                    pDestChar[3] = (byte)((pLeftChar[3] + pRightChar[3]) * 0.5f);
                }
                if (elemTex0 != null)
                {
                    // Blend each byte individually
                    pDestReal  = (pDest + elemTex0.Offset).ToFloatPointer();
                    pLeftReal  = (pLeft + elemTex0.Offset).ToFloatPointer();
                    pRightReal = (pRight + elemTex0.Offset).ToFloatPointer();

                    for (var dim = 0; dim < VertexElement.GetTypeCount(elemTex0.Type); dim++)
                    {
                        pDestReal[dim] = (pLeftReal[dim] + pRightReal[dim]) * 0.5f;
                    }
                }
                if (elemTex1 != null)
                {
                    // Blend each byte individually
                    pDestReal  = (pDest + elemTex1.Offset).ToFloatPointer();
                    pLeftReal  = (pLeft + elemTex1.Offset).ToFloatPointer();
                    pRightReal = (pRight + elemTex1.Offset).ToFloatPointer();

                    for (var dim = 0; dim < VertexElement.GetTypeCount(elemTex1.Type); dim++)
                    {
                        pDestReal[dim] = (pLeftReal[dim] + pRightReal[dim]) * 0.5f;
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lockedBuffer"></param>
        /// <param name="leftIndex"></param>
        /// <param name="rightIndex"></param>
        /// <param name="destIndex"></param>
        protected unsafe void InterpolateVertexData(IntPtr lockedBuffer, int leftIndex, int rightIndex, int destIndex)
        {
            int           vertexSize  = declaration.GetVertexSize(0);
            VertexElement elemPos     = declaration.FindElementBySemantic(VertexElementSemantic.Position);
            VertexElement elemNorm    = declaration.FindElementBySemantic(VertexElementSemantic.Normal);
            VertexElement elemDiffuse = declaration.FindElementBySemantic(VertexElementSemantic.Diffuse);
            VertexElement elemTex0    = declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 0);
            VertexElement elemTex1    = declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 1);

            float *pDestReal, pLeftReal, pRightReal;
            byte * pDestChar, pLeftChar, pRightChar;
            byte * pDest, pLeft, pRight;

            // Set up pointers & interpolate
            pDest  = ((byte *)(lockedBuffer.ToPointer()) + (vertexSize * destIndex));
            pLeft  = ((byte *)(lockedBuffer.ToPointer()) + (vertexSize * leftIndex));
            pRight = ((byte *)(lockedBuffer.ToPointer()) + (vertexSize * rightIndex));

            // Position
            pDestReal  = (float *)((byte *)pDest + elemPos.Offset);
            pLeftReal  = (float *)((byte *)pLeft + elemPos.Offset);
            pRightReal = (float *)((byte *)pRight + elemPos.Offset);

            *pDestReal++ = (*pLeftReal++ + *pRightReal++) * 0.5f;
            *pDestReal++ = (*pLeftReal++ + *pRightReal++) * 0.5f;
            *pDestReal++ = (*pLeftReal++ + *pRightReal++) * 0.5f;

            if (elemNorm != null)
            {
                // Normals
                pDestReal  = (float *)((byte *)pDest + elemNorm.Offset);
                pLeftReal  = (float *)((byte *)pLeft + elemNorm.Offset);
                pRightReal = (float *)((byte *)pRight + elemNorm.Offset);

                Vector3 norm = Vector3.Zero;
                norm.x = (*pLeftReal++ + *pRightReal++) * 0.5f;
                norm.y = (*pLeftReal++ + *pRightReal++) * 0.5f;
                norm.z = (*pLeftReal++ + *pRightReal++) * 0.5f;
                norm.Normalize();

                *pDestReal++ = norm.x;
                *pDestReal++ = norm.y;
                *pDestReal++ = norm.z;
            }
            if (elemDiffuse != null)
            {
                // Blend each byte individually
                pDestChar  = (byte *)(pDest + elemDiffuse.Offset);
                pLeftChar  = (byte *)(pLeft + elemDiffuse.Offset);
                pRightChar = (byte *)(pRight + elemDiffuse.Offset);

                // 4 bytes to RGBA
                *pDestChar++ = (byte)(((*pLeftChar++) + (*pRightChar++)) * 0.5f);
                *pDestChar++ = (byte)(((*pLeftChar++) + (*pRightChar++)) * 0.5f);
                *pDestChar++ = (byte)(((*pLeftChar++) + (*pRightChar++)) * 0.5f);
                *pDestChar++ = (byte)(((*pLeftChar++) + (*pRightChar++)) * 0.5f);
            }
            if (elemTex0 != null)
            {
                // Blend each byte individually
                pDestReal  = (float *)((byte *)pDest + elemTex0.Offset);
                pLeftReal  = (float *)((byte *)pLeft + elemTex0.Offset);
                pRightReal = (float *)((byte *)pRight + elemTex0.Offset);

                for (int dim = 0; dim < VertexElement.GetTypeCount(elemTex0.Type); dim++)
                {
                    *pDestReal++ = ((*pLeftReal++) + (*pRightReal++)) * 0.5f;
                }
            }
            if (elemTex1 != null)
            {
                // Blend each byte individually
                pDestReal  = (float *)((byte *)pDest + elemTex1.Offset);
                pLeftReal  = (float *)((byte *)pLeft + elemTex1.Offset);
                pRightReal = (float *)((byte *)pRight + elemTex1.Offset);

                for (int dim = 0; dim < VertexElement.GetTypeCount(elemTex1.Type); dim++)
                {
                    *pDestReal++ = ((*pLeftReal++) + (*pRightReal++)) * 0.5f;
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lockedBuffer"></param>
        protected void DistributeControlPoints(BufferBase lockedBuffer)
        {
#if !AXIOM_SAFE_ONLY
            unsafe
#endif
            {
                // Insert original control points into expanded mesh
                var uStep = 1 << this.uLevel;
                var vStep = 1 << this.vLevel;


                var elemPos     = this.declaration.FindElementBySemantic(VertexElementSemantic.Position);
                var elemNorm    = this.declaration.FindElementBySemantic(VertexElementSemantic.Normal);
                var elemTex0    = this.declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 0);
                var elemTex1    = this.declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 1);
                var elemDiffuse = this.declaration.FindElementBySemantic(VertexElementSemantic.Diffuse);

                var pSrc       = this.controlPointBuffer;
                var vertexSize = this.declaration.GetVertexSize(0);

                for (var v = 0; v < this.meshHeight; v += vStep)
                {
                    // set dest by v from base
                    var pDest = lockedBuffer + (vertexSize * this.meshWidth * v);

                    for (var u = 0; u < this.meshWidth; u += uStep)
                    {
                        // Copy Position
                        var pSrcReal  = (pSrc + elemPos.Offset).ToFloatPointer();
                        var pDestReal = (pDest + elemPos.Offset).ToFloatPointer();
                        pDestReal[0] = pSrcReal[0];
                        pDestReal[1] = pSrcReal[1];
                        pDestReal[2] = pSrcReal[2];

                        // Copy Normals
                        if (elemNorm != null)
                        {
                            pSrcReal     = (pSrc + elemNorm.Offset).ToFloatPointer();
                            pDestReal    = (pDest + elemNorm.Offset).ToFloatPointer();
                            pDestReal[0] = pSrcReal[0];
                            pDestReal[1] = pSrcReal[1];
                            pDestReal[2] = pSrcReal[2];
                        }

                        // Copy Diffuse
                        if (elemDiffuse != null)
                        {
                            var pSrcRGBA  = (pSrc + elemDiffuse.Offset).ToIntPointer();
                            var pDestRGBA = (pDest + elemDiffuse.Offset).ToIntPointer();
                            pDestRGBA[0] = pSrcRGBA[0];
                        }

                        // Copy texture coords
                        if (elemTex0 != null)
                        {
                            pSrcReal  = (pSrc + elemTex0.Offset).ToFloatPointer();
                            pDestReal = (pDest + elemTex0.Offset).ToFloatPointer();
                            for (var dim = 0; dim < VertexElement.GetTypeCount(elemTex0.Type); dim++)
                            {
                                pDestReal[dim] = pSrcReal[dim];
                            }
                        }
                        if (elemTex1 != null)
                        {
                            pSrcReal  = (pSrc + elemTex1.Offset).ToFloatPointer();
                            pDestReal = (pDest + elemTex1.Offset).ToFloatPointer();
                            for (var dim = 0; dim < VertexElement.GetTypeCount(elemTex1.Type); dim++)
                            {
                                pDestReal[dim] = pSrcReal[dim];
                            }
                        }

                        // Increment source by one vertex
                        pSrc += vertexSize;
                        // Increment dest by 1 vertex * uStep
                        pDest += vertexSize * uStep;
                    }             // u
                }                 // v
            }
        }
Exemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lockedBuffer"></param>
        protected unsafe void DistributeControlPoints(IntPtr lockedBuffer)
        {
            // Insert original control points into expanded mesh
            int uStep = 1 << uLevel;
            int vStep = 1 << vLevel;

            void * pSrc = Marshal.UnsafeAddrOfPinnedArrayElement(controlPointBuffer, 0).ToPointer();
            void * pDest;
            int    vertexSize = declaration.GetVertexSize(0);
            float *pSrcReal, pDestReal;
            int *  pSrcRGBA, pDestRGBA;

            VertexElement elemPos     = declaration.FindElementBySemantic(VertexElementSemantic.Position);
            VertexElement elemNorm    = declaration.FindElementBySemantic(VertexElementSemantic.Normal);
            VertexElement elemTex0    = declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 0);
            VertexElement elemTex1    = declaration.FindElementBySemantic(VertexElementSemantic.TexCoords, 1);
            VertexElement elemDiffuse = declaration.FindElementBySemantic(VertexElementSemantic.Diffuse);

            for (int v = 0; v < meshHeight; v += vStep)
            {
                // set dest by v from base
                pDest = (void *)((byte *)(lockedBuffer.ToPointer()) + (vertexSize * meshWidth * v));

                for (int u = 0; u < meshWidth; u += uStep)
                {
                    // Copy Position
                    pSrcReal  = (float *)((byte *)pSrc + elemPos.Offset);
                    pDestReal = (float *)((byte *)pDest + elemPos.Offset);
                    *pDestReal++ = *pSrcReal++;
                    *pDestReal++ = *pSrcReal++;
                    *pDestReal++ = *pSrcReal++;

                    // Copy Normals
                    if (elemNorm != null)
                    {
                        pSrcReal  = (float *)((byte *)pSrc + elemNorm.Offset);
                        pDestReal = (float *)((byte *)pDest + elemNorm.Offset);
                        *pDestReal++ = *pSrcReal++;
                        *pDestReal++ = *pSrcReal++;
                        *pDestReal++ = *pSrcReal++;
                    }

                    // Copy Diffuse
                    if (elemDiffuse != null)
                    {
                        pSrcRGBA  = (int *)((byte *)pSrc + elemDiffuse.Offset);
                        pDestRGBA = (int *)((byte *)pDest + elemDiffuse.Offset);
                        *pDestRGBA++ = *pSrcRGBA++;
                    }

                    // Copy texture coords
                    if (elemTex0 != null)
                    {
                        pSrcReal  = (float *)((byte *)pSrc + elemTex0.Offset);
                        pDestReal = (float *)((byte *)pDest + elemTex0.Offset);
                        for (int dim = 0; dim < VertexElement.GetTypeCount(elemTex0.Type); dim++)
                        {
                            *pDestReal++ = *pSrcReal++;
                        }
                    }
                    if (elemTex1 != null)
                    {
                        pSrcReal  = (float *)((byte *)pSrc + elemTex1.Offset);
                        pDestReal = (float *)((byte *)pDest + elemTex1.Offset);
                        for (int dim = 0; dim < VertexElement.GetTypeCount(elemTex1.Type); dim++)
                        {
                            *pDestReal++ = *pSrcReal++;
                        }
                    }

                    // Increment source by one vertex
                    pSrc = (void *)((byte *)(pSrc) + vertexSize);
                    // Increment dest by 1 vertex * uStep
                    pDest = (void *)((byte *)(pDest) + (vertexSize * uStep));
                } // u
            }     // v
        }