Beispiel #1
0
        public void Add(MGLTexture texture)
        {
            if (_values.Count > Maximum)
            {
                // Evict last entry
                MGLTexture dead = _values.Tail;
                _values.Remove(_values.TailEntry);

                Gl.glDeleteTextures(1, ref dead.TextureID);
            }

            _values.InsertAtHead(texture);
        }
Beispiel #2
0
        private void SetTextures()
        {
            MGLTextureInfo info = _ctx.Textures[0];

            if (info.Address == 0)
            {
                if (_currentTextureId != 0)
                {
                    Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
                }
                _currentTextureId = 0;
                return;
            }

            // Check valid
            bool valid = !((info.Address == 0x0) || (info.LineWidth == 0x0) || (info.Width == 0) || (info.Height == 0));

            // TODO: from framebuffer? - make sure this check is still valid!
            valid = valid && !((info.Address == 0x0400000) && (info.LineWidth == 0x4) && (info.Width == 0x2) && (info.Height == 0x2));

            // Check cache
            uint       checksum;
            MGLTexture texture = _ctx.TextureCache.Find(info, out checksum);

            // If found in cache, set and return
            if (texture != null)
            {
                if (_currentTextureId != texture.TextureID)
                {
                    Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.TextureID);
                    _currentTextureId = texture.TextureID;

                    // HACK: required to get textures to work right - does something after the binding so that things show up
                    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, _ctx.TextureMinFilter);
                    //Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST );

                    // TODO: set all
                    _defaultProgram.IsDirty = true;
                }
                return;
            }

            // Not found - create
            texture           = MGLTexture.LoadTexture(this, _ctx, info, checksum);
            _currentTextureId = texture.TextureID;

            _ctx.TextureCache.Add(texture);

            // TODO: set all
            _defaultProgram.IsDirty = true;
        }
Beispiel #3
0
        public MGLTexture Find(MGLTextureInfo info, out uint checksum)
        {
            checksum = 0;
            LinkedListEntry <MGLTexture> e = _values.HeadEntry;

            while (e != null)
            {
                if (e.Value.Address == info.Address)
                {
                    // Check to make sure it's right
                    bool match =
                        (e.Value.Width == info.Width) &&
                        (e.Value.Height == info.Height) &&
                        (e.Value.LineWidth == info.LineWidth) &&
                        (e.Value.PixelStorage == info.PixelStorage) &&
                        (((( int )e.Value.PixelStorage & 0x4) == 0x4) ? (e.Value.ClutChecksum == _ctx.Clut.Checksum) : true);
                    if (match == true)
                    {
                        // Cookie check
                        //uint cookie = *((uint*)

                        if (match == true)
                        {
                            byte *textureAddress = _driver.MemorySystem.Translate(info.Address);
                            checksum = MGLTexture.CalculateChecksum(textureAddress, info.Width, info.Height, info.PixelStorage);
                            match    = (checksum == e.Value.Checksum);
                        }
                    }
                    if (match == true)
                    {
                        // Match - move to head
                        _values.MoveToHead(e);
                        return(e.Value);
                    }
                    else
                    {
                        // Mismatch - free
                        Gl.glDeleteTextures(1, ref e.Value.TextureID);
                        _driver.InvalidateCurrentTexture();
                        _values.Remove(e);
                        return(null);
                    }
                }
                e = e.Next;
            }
            return(null);
        }
Beispiel #4
0
        public static MGLTexture LoadTexture(MGLDriver driver, MGLContext ctx, MGLTextureInfo info, uint checksum)
        {
            uint width     = info.Width;
            uint lineWidth = info.LineWidth;
            uint height    = info.Height;

            MGLTexture texture = new MGLTexture();

            texture.PixelStorage = info.PixelStorage;
            texture.Address      = info.Address;
            texture.LineWidth    = lineWidth;
            texture.Width        = width;
            texture.Height       = height;
            texture.Checksum     = checksum;
            texture.ClutPointer  = ctx.Clut.Pointer;
            texture.ClutChecksum = ctx.Clut.Checksum;

            int textureId;

            Gl.glGenTextures(1, out textureId);
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, textureId);
            texture.TextureID = textureId;

            byte *        address = driver.MemorySystem.Translate(info.Address);
            TextureFormat format  = TextureFormats[( int )info.PixelStorage];
            uint          size    = lineWidth * height * format.Size;

            fixed(byte *unswizzleBuffer = &_unswizzleBuffer[0])
            fixed(byte *decodeBuffer = &_decodeBuffer[0])
            {
                bool  needRowLength = false;
                byte *buffer        = address;

                if (ctx.TexturesSwizzled == true)
                {
                    buffer = Unswizzle(format, buffer, unswizzleBuffer, lineWidth, height);
                }

                switch (texture.PixelStorage)
                {
                case TexturePixelStorage.BGR5650:
                    texture.Checksum = ColorOperations.DecodeBGR5650(buffer, decodeBuffer, lineWidth * height);
                    buffer           = decodeBuffer;
                    break;

                case TexturePixelStorage.ABGR5551:
                    texture.Checksum = ColorOperations.DecodeABGR5551(buffer, decodeBuffer, lineWidth * height);
                    buffer           = decodeBuffer;
                    break;

                case TexturePixelStorage.ABGR4444:
                    texture.Checksum = ColorOperations.DecodeABGR4444(buffer, decodeBuffer, lineWidth * height);
                    buffer           = decodeBuffer;
                    break;

                case TexturePixelStorage.ABGR8888:
                    // Pass through
                    needRowLength = true;
                    break;

                case TexturePixelStorage.Indexed4:
                    ctx.Clut.Decode4(buffer, decodeBuffer, width, height, lineWidth);
                    buffer = decodeBuffer;
                    break;

                case TexturePixelStorage.Indexed8:
                    ctx.Clut.Decode8(buffer, decodeBuffer, width, height, lineWidth);
                    buffer = decodeBuffer;
                    break;

                case TexturePixelStorage.Indexed16:
                    ctx.Clut.Decode16(buffer, decodeBuffer, width, height, lineWidth);
                    buffer = decodeBuffer;
                    break;

                case TexturePixelStorage.Indexed32:
                    ctx.Clut.Decode32(buffer, decodeBuffer, width, height, lineWidth);
                    buffer = decodeBuffer;
                    break;

                case TexturePixelStorage.DXT1:
                case TexturePixelStorage.DXT3:
                case TexturePixelStorage.DXT5:
                    // Not yet implemented
                    Debug.Assert(false);
                    break;
                }

                // TODO: eliminate these
                //Gl.glPixelStorei( Gl.GL_UNPACK_ALIGNMENT, 4 );
                //if( needRowLength == true )
                //    Gl.glPixelStorei( Gl.GL_UNPACK_ROW_LENGTH, ( int )lineWidth );
                //else
                //    Gl.glPixelStorei( Gl.GL_UNPACK_ROW_LENGTH, ( int )width );

                Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8,
                                ( int )width, ( int )height,
                                0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE,
                                ( IntPtr )buffer);

                // Set cookie
                //texture.CookieOriginal = *( ( uint* )address );
                //texture.Cookie = ( uint )textureId;
                //*( ( uint* )address ) = ( uint )textureId;

                // Calculate checksum if needed
                if (texture.Checksum == 0)
                {
                    texture.Checksum = MGLTexture.CalculateChecksum(address, width, height, texture.PixelStorage);
                }
            }

            return(texture);
        }