示例#1
0
        public GLES2HardwareVertexBuffer(HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, bool useShadowBuffer)
            : base(manager, vertexDeclaration, numVertices, usage, false, useShadowBuffer)
        {
            if (!useShadowBuffer)
            {
                throw new AxiomException("Only supported with shadowBuffer");
            }

            var buffers = new int[1];

            GL.GenBuffers(1, buffers);
            GLES2Config.GlCheckError(this);
            this._bufferID = buffers[0];

            if (this._bufferID == 0)
            {
                throw new AxiomException("Cannot create GL ES vertex buffer");
            }

            (Root.Instance.RenderSystem as GLES2RenderSystem).BindGLBuffer(GLenum.ArrayBuffer, this._bufferID);
            GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
            GLES2Config.GlCheckError(this);
        }
示例#2
0
        protected override BufferBase LockImpl(int offset, int length, BufferLocking locking)
        {
            if (IsLocked)
            {
                throw new AxiomException("Invalid attempt to lock an index buffer that has already been locked.");
            }
            BufferBase retPtr;
            var        glBufManager = (HardwareBufferManager.Instance as GLES2HardwareBufferManager);

            //Try to use scratch buffers for smaller buffers
            if (length < glBufManager.MapBufferThreshold)
            {
                retPtr = glBufManager.AllocateScratch(length);

                if (retPtr != null)
                {
                    this._lockedToScratch       = true;
                    this._scratchOffset         = offset;
                    this._scratchSize           = length;
                    this._scratchPtr            = retPtr;
                    this._scratchUploadOnUnlock = (locking != BufferLocking.ReadOnly);

                    if (locking != BufferLocking.Discard)
                    {
                        //have to read back the data before returning the pointer
                        this.ReadData(offset, length, retPtr);
                    }
                }
            }
            else
            {
                throw new AxiomException("Invalid Buffer lockSize");
            }

            if (retPtr == null)
            {
                GLenum access = GLenum.Zero;
                (Root.Instance.RenderSystem as GLES2RenderSystem).BindGLBuffer(GLenum.ArrayBuffer, this._bufferID);

                if (locking == BufferLocking.Discard)
                {
                    //Discard the buffer
                    GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                if ((usage & BufferUsage.WriteOnly) == BufferUsage.WriteOnly)
                {
                    access = GLenum.WriteOnlyOes;
                }

                var pbuffer = GL.Oes.MapBuffer(GLenum.ArrayBuffer, access);
                GLES2Config.GlCheckError(this);

                if (pbuffer == IntPtr.Zero)
                {
                    throw new AxiomException("Vertex Buffer: Out of memory");
                }

                //return offsetted
                retPtr = BufferBase.Wrap(pbuffer, sizeInBytes) + offset;
                this._lockedToScratch = false;
            }
            isLocked = true;
            return(retPtr);
        }
示例#3
0
        protected override void UpdateFromShadow()
        {
            if (useShadowBuffer && shadowUpdated && !suppressHardwareUpdate)
            {
                var srcData = shadowBuffer.Lock(lockStart, lockSize, BufferLocking.ReadOnly);

                (Root.Instance.RenderSystem as GLES2RenderSystem).BindGLBuffer(GLenum.ArrayBuffer, this._bufferID);

                //Update whole buffer if possible, otherwise normal
                if (lockStart == 0 && lockSize == sizeInBytes)
                {
                    GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), srcData.Pin(), GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                else
                {
                    //Ogre FIXME: GPU frequently stalls here - DJR
                    GL.BufferSubData(GLenum.ArrayBuffer, new IntPtr(lockStart), new IntPtr(lockSize), srcData.Pin());
                    GLES2Config.GlCheckError(this);
                }

                shadowBuffer.Unlock();
                shadowUpdated = false;
            }
        }
示例#4
0
        public override void WriteData(int offset, int length, BufferBase src, bool discardWholeBuffer)
        {
            //Update the shadow buffer
            if (useShadowBuffer)
            {
                var destData = shadowBuffer.Lock(offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal);
                src = destData;
                shadowBuffer.Unlock();
            }

            if (offset == 0 && length == sizeInBytes)
            {
                GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), src.Pin(), GLES2HardwareBufferManager.GetGLUsage(usage));
                GLES2Config.GlCheckError(this);
            }
            else
            {
                if (discardWholeBuffer)
                {
                    GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                GL.BufferSubData(GLenum.ArrayBuffer, new IntPtr(offset), new IntPtr(length), src.Pin());
                GLES2Config.GlCheckError(this);
            }
        }
        public GLES2HardwareIndexBuffer(HardwareBufferManagerBase manager, IndexType type, int numIndices, BufferUsage usage, bool useShadowBuffer)
            : base(manager, type, numIndices, usage, false, useShadowBuffer)
        {
            if (type == IndexType.Size32)
            {
                throw new AxiomException("32 bit hardware buffers are not allowed in OpenGL ES.");
            }

            if (!useShadowBuffer)
            {
                throw new AxiomException("Only support with shadowBuffer");
            }

            OpenGL.GenBuffers(1, ref this._bufferId);
            GLES2Config.GlCheckError(this);
            if (this._bufferId == 0)
            {
                throw new AxiomException("Cannot create GL index buffer");
            }

            OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
            GLES2Config.GlCheckError(this);
            OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
            GLES2Config.GlCheckError(this);
        }
        /// <summary>
        /// </summary>
        protected override void UpdateFromShadow()
        {
            if (useShadowBuffer && shadowUpdated && !suppressHardwareUpdate)
            {
                var srcData = shadowBuffer.Lock(lockStart, lockSize, BufferLocking.ReadOnly);
                OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
                GLES2Config.GlCheckError(this);

                var srcPtr = new IntPtr(srcData.Ptr);
                // Update whole buffer if possible, otherwise normal
                if (lockStart == 0 && lockSize == sizeInBytes)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), srcPtr, GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                else
                {
                    OpenGL.BufferSubData(All.ElementArrayBuffer, new IntPtr(lockStart), new IntPtr(lockSize), srcPtr);
                    GLES2Config.GlCheckError(this);
                }
                shadowBuffer.Unlock();
                shadowUpdated = false;
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="offset"> </param>
        /// <param name="length"> </param>
        /// <param name="src"> </param>
        /// <param name="discardWholeBuffer"> </param>
        public override void WriteData(int offset, int length, BufferBase src, bool discardWholeBuffer)
        {
            OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
            GLES2Config.GlCheckError(this);
            // Update the shadow buffer
            if (useShadowBuffer)
            {
                var destData = shadowBuffer.Lock(offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal);
                Memory.Copy(src, destData, length);
                shadowBuffer.Unlock();
            }

            var srcPtr = src.Ptr;

            if (offset == 0 && length == sizeInBytes)
            {
                OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), ref srcPtr, GLES2HardwareBufferManager.GetGLUsage(usage));
                GLES2Config.GlCheckError(this);
            }
            else
            {
                if (discardWholeBuffer)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                // Now update the real buffer
                OpenGL.BufferSubData(All.ElementArrayBuffer, new IntPtr(offset), new IntPtr(length), ref srcPtr);
                GLES2Config.GlCheckError(this);
            }

            if (src.Ptr != srcPtr)
            {
                LogManager.Instance.Write("[GLES2] HardwareIndexBuffer.WriteData - buffer pointer modified by GL.BufferData.");
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="offset"> </param>
        /// <param name="length"> </param>
        /// <param name="locking"> </param>
        /// <returns> </returns>
        protected override BufferBase LockImpl(int offset, int length, BufferLocking locking)
        {
            All access = 0;

            if (isLocked)
            {
                throw new AxiomException("Invalid attempt to lock an index buffer that has already been locked");
            }

            BufferBase retPtr = null;

            if (length < MapBufferThreshold)
            {
                retPtr = ((GLES2HardwareBufferManager)HardwareBufferManager.Instance).AllocateScratch(length);
                if (retPtr != null)
                {
                    this._lockedToScratch       = true;
                    this._scratchOffset         = offset;
                    this._scratchSize           = length;
                    this._scratchPtr            = retPtr;
                    this._scratchUploadOnUnlock = (locking != BufferLocking.ReadOnly);

                    if (locking != BufferLocking.Discard)
                    {
                        this.ReadData(offset, length, retPtr);
                    }
                }
            }
            else
            {
                throw new AxiomException("Invalid Buffer lockSize");
            }

            if (retPtr == null)
            {
                OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
                GLES2Config.GlCheckError(this);
                // Use glMapBuffer
                if (locking == BufferLocking.Discard)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLES2HardwareBufferManager.GetGLUsage(usage));
                    GLES2Config.GlCheckError(this);
                }
                if ((usage & BufferUsage.WriteOnly) != 0)
                {
                    access = All.WriteOnlyOes;
                }

                IntPtr pBuffer = OpenGLOES.MapBuffer(All.ElementArrayBuffer, access);
                GLES2Config.GlCheckError(this);
                if (pBuffer == IntPtr.Zero)
                {
                    throw new AxiomException("Index Buffer: Out of memory");
                }
                unsafe
                {
                    // return offset
                    retPtr = BufferBase.Wrap(pBuffer, sizeInBytes);
                }

                this._lockedToScratch = false;
            }
            isLocked = true;

            return(retPtr);
        }