예제 #1
0
        public GLESHardwareIndexBuffer(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);
            GLESConfig.GlCheckError(this);
            if (this._bufferId == 0)
            {
                throw new AxiomException("Cannot create GL index buffer");
            }

            OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
            GLESConfig.GlCheckError(this);
            OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
            GLESConfig.GlCheckError(this);
        }
예제 #2
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(), GLESHardwareBufferManager.GetGLUsage(usage));
                GLESConfig.GlCheckError(this);
            }
            else
            {
                if (discardWholeBuffer)
                {
                    GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                GL.BufferSubData(GLenum.ArrayBuffer, new IntPtr(offset), new IntPtr(length), src.Pin());
                GLESConfig.GlCheckError(this);
            }
        }
예제 #3
0
 /// <summary>
 /// </summary>
 /// <param name="p"> </param>
 internal void CopyFromFramebuffer(int p)
 {
     OpenGL.BindBuffer(All.Texture2D, this._textureId);
     GLESConfig.GlCheckError(this);
     OpenGL.CopyTexSubImage2D(All.Texture2D, this._level, 0, 0, 0, 0, Width, Height);
     GLESConfig.GlCheckError(this);
 }
예제 #4
0
        /// <summary>
        ///   Internal method to create a warning texture (bound when a texture unit is blank)
        /// </summary>
        protected void CreateWarningTexture()
        {
            // Generate warning texture
            int width  = 8;
            int height = 8;

            // TODO convert to 5_6_5
            unsafe
            {
                int *data = stackalloc int[width * height];                   // 0xXXRRGGBB

                //yellow / black stripes
                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x)
                    {
                        data[y * width + x] = (((x + y) % 8) < 4) ? 0x000000 : 0xFFFF00;
                    }
                }

                // Create GL resource
                OpenGL.GenTextures(1, ref this._warningTextureID);
                GLESConfig.GlCheckError(this);
                OpenGL.BindTexture(All.Texture2D, this._warningTextureID);
                GLESConfig.GlCheckError(this);
                OpenGL.TexImage2D(All.Texture2D, 0, (int)All.Rgb, width, height, 0, All.Rgb, All.UnsignedByte, (IntPtr)data);
                GLESConfig.GlCheckError(this);
            }
        }
예제 #5
0
        protected override void UpdateFromShadow()
        {
            if (useShadowBuffer && shadowUpdated && !suppressHardwareUpdate)
            {
                var srcData = shadowBuffer.Lock(lockStart, lockSize, BufferLocking.ReadOnly);

                (Root.Instance.RenderSystem as GLESRenderSystem).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(), GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                else
                {
                    //Ogre FIXME: GPU frequently stalls here - DJR
                    GL.BufferSubData(GLenum.ArrayBuffer, new IntPtr(lockStart), new IntPtr(lockSize), srcData.Pin());
                    GLESConfig.GlCheckError(this);
                }

                shadowBuffer.Unlock();
                shadowUpdated = false;
            }
        }
예제 #6
0
        /// <summary>
        ///   Bind FrameBufferObject
        /// </summary>
        public void Bind()
        {
            /// Bind it to FBO
            int fb = this._multiSampleFB != 0 ? this._multiSampleFB : this._fb;

            OpenGLOES.BindFramebuffer(All.FramebufferOes, fb);
            GLESConfig.GlCheckError(this);
        }
예제 #7
0
        /// <summary>
        /// </summary>
        /// <param name="attachment"> </param>
        public override void UnbindSurface(int attachment)
        {
            this._fbo.UnbindSurface(attachment);
            GLESConfig.GlCheckError(attachment);

            Width  = this._fbo.Width;
            Height = this._fbo.Height;
        }
예제 #8
0
        protected static void BuildMipmaps(PixelBox data)
        {
            int      width  = 0;
            int      height = 0;
            int      logW   = 0;
            int      logH   = 0;
            int      level  = 0;
            PixelBox scaled = data;

            scaled.Data   = data.Data;
            scaled.Left   = data.Left;
            scaled.Right  = data.Right;
            scaled.Top    = data.Top;
            scaled.Bottom = data.Bottom;
            scaled.Front  = data.Front;
            scaled.Back   = data.Back;

            All format   = GLESPixelUtil.GetGLOriginFormat(data.Format);
            All dataType = GLESPixelUtil.GetGLOriginDataType(data.Format);

            width  = data.Width;
            height = data.Height;

            logW  = ComputeLog(width);
            logH  = ComputeLog(height);
            level = (logW > logH ? logW : logH);

            for (int mip = 0; mip <= level; mip++)
            {
                format   = GLESPixelUtil.GetGLOriginFormat(scaled.Format);
                dataType = GLESPixelUtil.GetGLOriginDataType(scaled.Format);

                OpenGL.TexImage2D(All.Texture2D, mip, (int)format, width, height, 0, format, dataType, scaled.Data);

                GLESConfig.GlCheckError(null);

                if (mip != 0)
                {
                    scaled.Data = IntPtr.Zero;
                }

                if (width > 1)
                {
                    width = width / 2;
                }
                if (height > 1)
                {
                    height = height / 2;
                }

                int sizeInBytes = PixelUtil.GetMemorySize(width, height, 1, data.Format);
                scaled = new PixelBox(width, height, 1, data.Format);
                var dataarr = new byte[sizeInBytes];
                scaled.Data = Memory.PinObject(dataarr);
                Image.Scale(data, scaled, ImageFilter.Linear);
            }
        }
예제 #9
0
        protected override void dispose(bool disposeManagedResources)
        {
            GL.DeleteBuffers(1, ref this._bufferID);
            GLESConfig.GlCheckError(this);

            (Root.Instance.RenderSystem as GLESRenderSystem).DeleteGLBuffer(GLenum.ArrayBuffer, this._bufferID);

            base.dispose(disposeManagedResources);
        }
예제 #10
0
        /// <summary>
        /// </summary>
        /// <param name="disposeManagedResources"> </param>
        protected override void dispose(bool disposeManagedResources)
        {
            // Unregister with group manager
            ResourceGroupManager.Instance.UnregisterResourceManager(base.ResourceType);
            // Delete warning texture
            OpenGL.DeleteTextures(1, ref this._warningTextureID);
            GLESConfig.GlCheckError(this);

            base.dispose(disposeManagedResources);
        }
예제 #11
0
        /// <summary>
        /// </summary>
        /// <param name="support"> </param>
        public GLESTextureManager(GLESSupport support)
        {
            this._glSupport  = support;
            WarningTextureID = 0;
            GLESConfig.GlCheckError(this);
            // Register with group manager
            ResourceGroupManager.Instance.RegisterResourceManager(base.ResourceType, this);

            CreateWarningTexture();
        }
예제 #12
0
 /// <summary>
 /// </summary>
 public GLESFBORTTManager()
     : base()
 {
     LogManager.Instance.Write("FBO CTOR ENTER");
     this._renderBuffer = new Dictionary <RBFormat, RBRef>();
     TemporaryFBO       = 0;
     DetectFBOFormats();
     OpenGLOES.GenFramebuffers(1, ref this._tempFbo);
     GLESConfig.GlCheckError(this);
     LogManager.Instance.Write("FBO CTOR EXIT");
 }
예제 #13
0
        /// <summary>
        /// </summary>
        /// <param name="attachment"> </param>
        /// <param name="target"> </param>
        public override void BindSurface(int attachment, RenderTexture target)
        {
            /// Check if the render target is in the rendertarget->FBO map
            var fbobj = target["FBO"] as GLESFrameBufferObject;

            Utilities.Contract.Requires(fbobj != null);
            this._fbo.BindSurface(attachment, fbobj.GetSurface(0));
            GLESConfig.GlCheckError(this);

            Width  = this._fbo.Width;
            Height = this._fbo.Height;
        }
예제 #14
0
        /// <summary>
        /// </summary>
        /// <param name="name"> </param>
        /// <param name="target"> </param>
        /// <param name="id"> </param>
        /// <param name="width"> </param>
        /// <param name="height"> </param>
        /// <param name="format"> </param>
        /// <param name="face"> </param>
        /// <param name="level"> </param>
        /// <param name="usage"> </param>
        /// <param name="crappyCard"> </param>
        /// <param name="writeGamma"> </param>
        /// <param name="fsaa"> </param>
        public GLESTextureBuffer(string basename, All targetfmt, int id, int width, int height, int format, int face, int level, BufferUsage usage, bool crappyCard, bool writeGamma, int fsaa)
            : base(0, 0, 0, Media.PixelFormat.Unknown, usage)
        {
            this._target         = targetfmt;
            this._textureId      = id;
            this._face           = face;
            this._level          = level;
            this._softwareMipmap = crappyCard;

            GLESConfig.GlCheckError(this);
            OpenGL.BindTexture(All.Texture2D, this._textureId);
            GLESConfig.GlCheckError(this);

            // Get face identifier
            this._faceTarget = this._target;

            // TODO verify who get this
            Width  = width;
            Height = height;
            Depth  = 1;

            _glInternalFormat = (All)format;
            Format            = GLESPixelUtil.GetClosestAxiomFormat(_glInternalFormat);

            RowPitch    = Width;
            SlicePitch  = Height * Width;
            sizeInBytes = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

            // Set up a pixel box
            _buffer = new PixelBox(Width, Height, Depth, Format);
            if (Width == 0 || Height == 0 || Depth == 0)
            {
                /// We are invalid, do not allocate a buffer
                return;
            }

            // Is this a render target?
            if (((int)Usage & (int)TextureUsage.RenderTarget) != 0)
            {
                // Create render target for each slice
                for (int zoffset = 0; zoffset < Depth; zoffset++)
                {
                    string name = string.Empty;
                    name = "rtt/" + GetHashCode() + "/" + basename;
                    var target = new GLESSurfaceDescription();
                    target.Buffer  = this;
                    target.ZOffset = zoffset;
                    RenderTexture trt = GLESRTTManager.Instance.CreateRenderTexture(name, target, writeGamma, fsaa);
                    this._sliceTRT.Add(trt);
                    Root.Instance.RenderSystem.AttachRenderTarget(this._sliceTRT[zoffset]);
                }
            }
        }
예제 #15
0
 /// <summary>
 /// </summary>
 /// <param name="manager"> </param>
 /// <param name="fsaa"> </param>
 public GLESFrameBufferObject(GLESFBORTTManager manager, int fsaa)
 {
     /// Generate framebuffer object
     OpenGLOES.GenFramebuffers(1, ref this._fb);
     GLESConfig.GlCheckError(this);
     this._depth   = new GLESSurfaceDescription();
     this._stencil = new GLESSurfaceDescription();
     for (int x = 0; x < Configuration.Config.MaxMultipleRenderTargets; x++)
     {
         this._color[x] = new GLESSurfaceDescription();
     }
 }
예제 #16
0
        /// <summary>
        /// </summary>
        /// <param name="disposeManagedResources"> </param>
        protected override void dispose(bool disposeManagedResources)
        {
            if (!IsDisposed)
            {
                if (disposeManagedResources)
                {
                    OpenGL.DeleteBuffers(1, ref this._bufferId);
                    GLESConfig.GlCheckError(this);
                }
            }

            // If it is available, make the call to the
            // base class's Dispose(Boolean) method
            base.dispose(disposeManagedResources);
        }
예제 #17
0
        /// <summary>
        /// </summary>
        public void Dispose()
        {
            Manager.ReleaseRenderbuffer(this._depth);
            Manager.ReleaseRenderbuffer(this._stencil);
            Manager.ReleaseRenderbuffer(this._multisampleColorBuffer);

            /// Delete framebuffer object
            OpenGLOES.DeleteFramebuffers(1, ref this._fb);
            GLESConfig.GlCheckError(this);

            if (this._multiSampleFB != 0)
            {
                OpenGLOES.DeleteFramebuffers(1, ref this._multiSampleFB);
            }

            GLESConfig.GlCheckError(this);
        }
예제 #18
0
        /// <summary>
        /// </summary>
        /// <param name="format"> </param>
        /// <param name="width"> </param>
        /// <param name="height"> </param>
        /// <param name="numSamples"> </param>
        public GLESRenderBuffer(All format, int width, int height, int numSamples)
            : base(width, height, 1, GLESPixelUtil.GetClosestAxiomFormat(format), BufferUsage.WriteOnly)
        {
            _glInternalFormat = format;
            /// Generate renderbuffer
            OpenGLOES.GenRenderbuffers(1, ref this._renderbufferID);
            GLESConfig.GlCheckError(this);
            /// Bind it to FBO
            OpenGLOES.BindRenderbuffer(All.RenderbufferOes, this._renderbufferID);
            GLESConfig.GlCheckError(this);

            /// Allocate storage for depth buffer
            if (numSamples <= 0)
            {
                OpenGLOES.RenderbufferStorage(All.RenderbufferOes, format, width, height);
                GLESConfig.GlCheckError(this);
            }
        }
예제 #19
0
        /// <summary>
        ///   Bind a certain render target if it is a FBO. If it is not a FBO, bind the main frame buffer.
        /// </summary>
        /// <param name="target"> </param>
        public override void Bind(Graphics.RenderTarget target)
        {
            /// Check if the render target is in the rendertarget->FBO map
            GLESFrameBufferObject fbo = null;

            fbo = target["FBO"] as GLESFrameBufferObject;
            if (fbo != null)
            {
                fbo.Bind();
            }
            else
            {
                // Old style context (window/pbuffer) or copying render texture
#if AXIOM_PLATFORM_IPHONE
                // The screen buffer is 1 on iPhone
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 1);
#else
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 0);
#endif
                GLESConfig.GlCheckError(this);
            }
        }
예제 #20
0
        public GLESHardwareVertexBuffer(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);
            GLESConfig.GlCheckError(this);
            this._bufferID = buffers[0];

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

            (Root.Instance.RenderSystem as GLESRenderSystem).BindGLBuffer(GLenum.ArrayBuffer, this._bufferID);
            GL.BufferData(GLenum.ArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
            GLESConfig.GlCheckError(this);
        }
예제 #21
0
        /// <summary>
        /// </summary>
        protected override void UpdateFromShadow()
        {
            if (useShadowBuffer && shadowUpdated && !suppressHardwareUpdate)
            {
                var srcData = shadowBuffer.Lock(lockStart, lockSize, BufferLocking.ReadOnly);
                OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
                GLESConfig.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, GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                else
                {
                    OpenGL.BufferSubData(All.ElementArrayBuffer, new IntPtr(lockStart), new IntPtr(lockSize), srcPtr);
                    GLESConfig.GlCheckError(this);
                }
                shadowBuffer.Unlock();
                shadowUpdated = false;
            }
        }
예제 #22
0
 /// <summary>
 /// </summary>
 protected override void UnlockImpl()
 {
     if (this._lockedToScratch)
     {
         if (this._scratchUploadOnUnlock)
         {
             // have to write the data back to vertex buffer
             this.WriteData(this._scratchOffset, this._scratchSize, this._scratchPtr, this._scratchOffset == 0 && this._scratchSize == sizeInBytes);
         }
         // deallocate from scratch buffer
         ((GLESHardwareBufferManager)HardwareBufferManager.Instance).DeallocateScratch(this._scratchPtr);
         this._lockedToScratch = false;
     }
     else
     {
         OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId);
         GLESConfig.GlCheckError(this);
         if (!OpenGLOES.UnmapBuffer(All.ElementArrayBuffer))
         {
             throw new AxiomException("Buffer data corrupted, please reload");
         }
     }
     isLocked = false;
 }
예제 #23
0
        /// <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);
            GLESConfig.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, GLESHardwareBufferManager.GetGLUsage(usage));
                GLESConfig.GlCheckError(this);
            }
            else
            {
                if (discardWholeBuffer)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                // Now update the real buffer
                OpenGL.BufferSubData(All.ElementArrayBuffer, new IntPtr(offset), new IntPtr(length), ref srcPtr);
                GLESConfig.GlCheckError(this);
            }

            if (src.Ptr != srcPtr)
            {
                LogManager.Instance.Write("[GLES2] HardwareIndexBuffer.WriteData - buffer pointer modified by GL.BufferData.");
            }
        }
예제 #24
0
        /// <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 = ((GLESHardwareBufferManager)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);
                GLESConfig.GlCheckError(this);
                // Use glMapBuffer
                if (locking == BufferLocking.Discard)
                {
                    OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage));
                    GLESConfig.GlCheckError(this);
                }
                if ((usage & BufferUsage.WriteOnly) != 0)
                {
                    access = All.WriteOnlyOes;
                }

                IntPtr pBuffer = OpenGLOES.MapBuffer(All.ElementArrayBuffer, access);
                GLESConfig.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);
        }
예제 #25
0
        /// <summary>
        ///   Detect which internal formats are allowed as RTT Also detect what combinations of stencil and depth are allowed with this internal format.
        /// </summary>
        private void DetectFBOFormats()
        {
            // Try all formats, and report which ones work as target
            int fb = 0, tid = 0;
            All target = All.Texture2D;

            for (int x = 0; x < (int)Media.PixelFormat.Count; x++)
            {
                LogManager.Instance.Write("[GLES] [DEBUG] testing PixelFormat : {0}", (Media.PixelFormat)x);

                this._props[x]         = new FormatProperties();
                this._props[x].Modes   = new List <FormatProperties.Mode>();
                this._props[x].IsValid = false;

                // Fetch GL format token
                All fmt = GLESPixelUtil.GetClosestGLInternalFormat((Media.PixelFormat)x);
                LogManager.Instance.Write("[GLES] [DEBUG] fmt={0}", fmt);
                if (fmt == All.Zero && x != 0)
                {
                    continue;
                }

                // No test for compressed formats
                if (PixelUtil.IsCompressed((Media.PixelFormat)x))
                {
                    continue;
                }

                // Create and attach framebuffer
                OpenGLOES.GenRenderbuffers(1, ref fb);
                GLESConfig.GlCheckError(this);
                OpenGLOES.BindFramebuffer(All.FramebufferOes, fb);
                GLESConfig.GlCheckError(this);

                if (fmt != All.Zero)
                {
                    // Create and attach texture
                    OpenGL.GenTextures(1, ref tid);
                    GLESConfig.GlCheckError(this);
                    OpenGL.BindTexture(target, tid);
                    GLESConfig.GlCheckError(this);

                    // Set some default parameters
                    OpenGL.TexParameterx(target, All.TextureMinFilter, (int)All.LinearMipmapNearest);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureMagFilter, (int)All.Nearest);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureWrapS, (int)All.ClampToEdge);
                    GLESConfig.GlCheckError(this);
                    OpenGL.TexParameterx(target, All.TextureWrapT, (int)All.ClampToEdge);
                    GLESConfig.GlCheckError(this);

                    OpenGL.TexImage2D(target, 0, (int)fmt, ProbeSize, ProbeSize, 0, fmt, All.UnsignedByte, IntPtr.Zero);
                    GLESConfig.GlCheckError(this);
                    OpenGLOES.FramebufferTexture2D(All.FramebufferOes, All.ColorAttachment0Oes, target, tid, 0);
                    GLESConfig.GlCheckError(this);
                }

                // Check status
                All status = OpenGLOES.CheckFramebufferStatus(All.FramebufferOes);
                GLESConfig.GlCheckError(this);
                LogManager.Instance.Write("[GLES] [DEBUG] status={0}", status);

                // Ignore status in case of fmt==GL_NONE, because no implementation will accept
                // a buffer without *any* attachment. Buffers with only stencil and depth attachment
                // might still be supported, so we must continue probing.
                if (fmt == 0 || status == All.FramebufferCompleteOes)
                {
                    this._props[x].IsValid = true;
                    var str = new StringBuilder();
                    str.Append("FBO " + PixelUtil.GetFormatName((Media.PixelFormat)x) + " depth/stencil support: ");

                    // For each depth/stencil formats
                    for (int depth = 0; depth < DepthFormats.Length; ++depth)
                    {
                        if (DepthFormats[depth] != All.Depth24Stencil8Oes)
                        {
                            // General depth/stencil combination
                            for (int stencil = 0; stencil < StencilFormats.Length; ++stencil)
                            {
                                if (TryFormat(DepthFormats[depth], StencilFormats[stencil]))
                                {
                                    /// Add mode to allowed modes
                                    str.Append("D" + DepthBits[depth] + "S" + StencilBits[stencil] + " ");
                                    var mode = new FormatProperties.Mode();
                                    mode.Depth   = depth;
                                    mode.Stencil = stencil;
                                    this._props[x].Modes.Add(mode);
                                }
                            }                     //end for stencil
                        }                         //end if
                        else
                        {
                            // Packed depth/stencil format
                            if (TryPacketFormat(DepthFormats[depth]))
                            {
                                /// Add mode to allowed modes
                                str.Append("Packed-D" + DepthBits[depth] + "S8" + " ");
                                var mode = new FormatProperties.Mode();
                                mode.Depth   = depth;
                                mode.Stencil = 0;                                 //unused
                                this._props[x].Modes.Add(mode);
                            }
                        }
                    }             //end for depth
                    LogManager.Instance.Write(str.ToString());
                }                 //end if
                                  // Delete texture and framebuffer
#if AXIOM_PLATFORM_IPHONE
                // The screen buffer is 1 on iPhone
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 1);
#else
                OpenGLOES.BindFramebuffer(All.FramebufferOes, 0);
#endif
                GLESConfig.GlCheckError(this);
                OpenGLOES.DeleteFramebuffers(1, ref fb);
                GLESConfig.GlCheckError(this);
                if (fmt != 0)
                {
                    OpenGL.DeleteTextures(1, ref tid);
                }
            }             //end for pixelformat count

            string fmtstring = string.Empty;
            for (int x = 0; x < (int)Media.PixelFormat.Count; x++)
            {
                if (this._props[x].IsValid)
                {
                    fmtstring += PixelUtil.GetFormatName((Media.PixelFormat)x);
                }
            }
            LogManager.Instance.Write("[GLES] : Valid FBO targets " + fmtstring);
        }
예제 #26
0
 /// <summary>
 /// </summary>
 /// <param name="attachment"> </param>
 /// <param name="zOffset"> </param>
 public override void BindToFramebuffer(All attachment, int zOffset)
 {
     Utilities.Contract.Requires(zOffset < Depth);
     OpenGLOES.FramebufferRenderbuffer(All.FramebufferOes, attachment, All.RenderbufferOes, this._renderbufferID);
     GLESConfig.GlCheckError(this);
 }
예제 #27
0
        /// <summary>
        /// </summary>
        /// <param name="data"> </param>
        /// <param name="dest"> </param>
        protected override void Upload(PixelBox data, BasicBox dest)
        {
            OpenGL.BindTexture(this._target, this._textureId);
            GLESConfig.GlCheckError(this);

            if (PixelUtil.IsCompressed(data.Format))
            {
                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new AxiomException("Compressed images must be consecutive, in the source format");
                }

                if (data.Format != Format || !data.IsConsecutive)
                {
                    throw new AxiomException("Compressed images must be consecutive, in the source format.");
                }

                All format = GLESPixelUtil.GetClosestGLInternalFormat(Format);
                // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
                // for compressed formats
                if (dest.Left == 0 && dest.Top == 0)
                {
                    OpenGL.CompressedTexImage2D(All.Texture2D, this._level, format, dest.Width, dest.Height, 0, data.ConsecutiveSize, data.Data);
                }
                else
                {
                    OpenGL.CompressedTexSubImage2D(All.Texture2D, this._level, dest.Left, dest.Top, dest.Width, dest.Height, format, data.ConsecutiveSize, data.Data);
                }
                GLESConfig.GlCheckError(this);
            }
            else if (this._softwareMipmap)
            {
                if (data.Width != data.RowPitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }

                OpenGL.PixelStore(All.UnpackAlignment, 1);
                GLESConfig.GlCheckError(this);
                BuildMipmaps(data);
            }
            else
            {
                if (data.Width != data.RowPitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }
                if (data.Height * data.Width != data.SlicePitch)
                {
                    //TODO
                    throw new AxiomException("Unsupported Texture format!");
                }

                if (((data.Width * PixelUtil.GetNumElemBytes(data.Format)) & 3) != 0)
                {
                    // Standard alignment of 4 is not right
                    OpenGL.PixelStore(All.UnpackAlignment, 1);
                    GLESConfig.GlCheckError(this);
                }
                All form = GLESPixelUtil.GetGLOriginFormat(data.Format);
                All pix  = GLESPixelUtil.GetGLOriginDataType(data.Format);
                GLESConfig.GlCheckError(this);
                GL.TexSubImage2D(this._faceTarget, this._level, dest.Left, dest.Top, dest.Width, dest.Height, GLESPixelUtil.GetGLOriginFormat(data.Format), GLESPixelUtil.GetGLOriginDataType(data.Format), data.Data);
                GLESConfig.GlCheckError(this);
            }

            OpenGL.PixelStore(All.UnpackAlignment, 4);
            GLESConfig.GlCheckError(this);
        }
예제 #28
0
 /// <summary>
 /// </summary>
 /// <param name="attachment"> </param>
 /// <param name="zOffset"> </param>
 public override void BindToFramebuffer(All attachment, int zOffset)
 {
     Axiom.Utilities.Contract.Requires(zOffset < Depth, "GLESTextureBuffer.BindToFramebuffer, z offset must be smaller then depth");
     OpenGL.Oes.FramebufferTexture2D(All.FramebufferOes, attachment, this._faceTarget, this._textureId, this._level);
     GLESConfig.GlCheckError(this);
 }
예제 #29
0
        /// <summary>
        /// </summary>
        protected override void createInternalResources()
        {
            // Convert to nearest power-of-two size if required
            Width  = GLESPixelUtil.OptionalPO2(Width);
            Height = GLESPixelUtil.OptionalPO2(Height);
            Depth  = GLESPixelUtil.OptionalPO2(Depth);

            //adjust format if required
            Format = TextureManager.Instance.GetNativeFormat(Graphics.TextureType.TwoD, Format, Usage);
            // Check requested number of mipmaps
            int maxMips = GLESPixelUtil.GetMaxMipmaps(Width, Height, Depth, Format);

            if (PixelUtil.IsCompressed(Format) && _mipmapCount == 0)
            {
                RequestedMipmapCount = 0;
            }

            _mipmapCount = RequestedMipmapCount;
            if (_mipmapCount > maxMips)
            {
                _mipmapCount = maxMips;
            }

            // Generate texture name
            OpenGL.GenTextures(1, ref this._textureID);
            GLESConfig.GlCheckError(this);
            // Set texture type
            OpenGL.BindTexture(All.Texture2D, this._textureID);
            GLESConfig.GlCheckError(this);
            // Set some misc default parameters, these can of course be changed later
            OpenGL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.LinearMipmapNearest);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Nearest);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge);
            GLESConfig.GlCheckError(this);
            OpenGL.TexParameter(All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge);
            GLESConfig.GlCheckError(this);
            // If we can do automip generation and the user desires this, do so
            MipmapsHardwareGenerated = Root.Instance.RenderSystem.HardwareCapabilities.HasCapability(Capabilities.HardwareMipMaps) && !PixelUtil.IsCompressed(Format);

            if ((Usage & TextureUsage.AutoMipMap) == TextureUsage.AutoMipMap && RequestedMipmapCount > 0 && MipmapsHardwareGenerated)
            {
                OpenGL.TexParameter(All.Texture2D, All.GenerateMipmap, (int)All.True);
                GLESConfig.GlCheckError(this);
            }

            // Allocate internal buffer so that TexSubImageXD can be used
            // Internal format
            All format = GLESPixelUtil.GetClosestGLInternalFormat(Format, HardwareGammaEnabled);
            int width  = Width;
            int height = Height;
            int depth  = Depth;

            if (PixelUtil.IsCompressed(Format))
            {
                // Compressed formats
                int size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);

                // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
                // accept a 0 pointer like normal glTexImageXD
                // Run through this process for every mipmap to pregenerate mipmap pyramid

                var    tmpData    = new byte[size];
                IntPtr tmpDataptr = Memory.PinObject(tmpData);
                for (int mip = 0; mip <= MipmapCount; mip++)
                {
                    size = PixelUtil.GetMemorySize(Width, Height, Depth, Format);
                    OpenGL.CompressedTexImage2D(All.Texture2D, mip, format, width, height, 0, size, tmpDataptr);

                    GLESConfig.GlCheckError(this);

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1)
                    {
                        depth = depth / 2;
                    }
                }
                Memory.UnpinObject(tmpData);
            }
            else
            {
                // Run through this process to pregenerate mipmap pyramid
                for (int mip = 0; mip <= MipmapCount; mip++)
                {
                    OpenGL.TexImage2D(All.Texture2D, mip, (int)format, width, height, 0, format, All.UnsignedByte, IntPtr.Zero);
                    GLESConfig.GlCheckError(this);

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                }
            }

            CreateSurfaceList();

            // Get final internal format
            Format = GetBuffer(0, 0).Format;
        }
예제 #30
0
 /// <summary>
 /// </summary>
 protected override void freeInternalResources()
 {
     this._surfaceList.Clear();
     OpenGL.DeleteTextures(1, ref this._textureID);
     GLESConfig.GlCheckError(this);
 }