Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - mammon

Pages: [1]
1
True that - I've already had my fair share of optimizing the code to the point of my brain breaking down... And as of IL, well - my nickname isn't chosen by random (my nickname is known a lil' bit in the scene so to speak), I have reversed IL binaries for over a decade now :P

But truth be told, IL is not very efficient when it comes to actual optimization due to the limitations of running ANY code behind some obscured VM :(

That being said, I have now come to a conclusion: only way to make this work at all, is by trying to utilize SDL or something equal... Surely OpenTk/Tao would be a suggestion, but thats even more barebone in comparison to SDL (requires alot of work to make a simple "engine" so to speak) - so I'm gonna attempt to make something with SDL afaik :)

Anyways, I'll keep you guys posted with updates when I make some progress ;)

2
Heya, and thanks for the tip - however, its no use in here... I've made a small modification on the FastBitmap class to actually able one todo such operation  however, to no gain at all :(
Seems GDI+ (your CPU), is not able to work with anything bigger than something tiny in the end... Pherhaps SFML or SDL is the working way to go in the end...

3
So, before you even consider just copy/paste the following code - you should know this:
this code is beyond flawed, and is slow as hell!
And with that in mind, I'm here asking for this board's help in achieving a better way to make this tunnel animated...

I have tried using both jagged arrays, and multidimension arrays (which you can clearly see) - but it still gives this "lag" feature no matter what I change :/
I suspect very much that it is due to the pixel manipulation, which seem to be too slow :(

Oh yes, I have also tried using Parallel.For - but that didn't even work at all (it just crashes due to memory being inaccesible!)...
And yes, I have also considered using every OpenGL and DirectX solution instead (and tried a few, but still slow as shit!)...

So here it is, no more nagging about me failing - hopefully someone in here can aid me in making this possible :D

Oh by the way, the code is derived from "Lode's Computer Graphics Tutorial" - found here: http://lodev.org/cgtutor/tunnel.html
Code: [Select]
//Using FastBitmap.cs by boogop which is found on PSC ;)
//http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=5653&lngWId=10

    public partial class Form1 : Form
    {
BackgroundWorker bw;
        Bitmap bmp;
        int fHeight;
        int fWidth;
        Graphics gForm;
        Graphics gBmp;

/*Multi-dimension array:*/
int[,] distanceTable;
/*Jagged array:*/
        int[][] distanceTable2;
/*Multi-dimension array:*/
        int[,] angleTable;
/*Jagged array:*/
        int[][] angleTable2;

Bitmap myTexture;

int animation = 0;
        int rotation = 0;

        public Form1()
        {
            InitializeComponent();
            InitPictureBox();
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.Opaque | ControlStyles.ResizeRedraw, true);
        }

        void InitPictureBox()
        {
            bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            gForm = pictureBox1.CreateGraphics();
            gBmp = Graphics.FromImage(bmp);

            fWidth = bmp.Width;
            fHeight = bmp.Height;
        }

        void DoXorTunnel()
        {
            while (true)
            {
                animation += 3;
                rotation += 1;

                Application.DoEvents();

                var myBitmap = new Bitmap(bmp.Width, bmp.Height);
                var shiftX = myTexture.Width + animation;
                var shiftY = myTexture.Height + rotation;

                var a = new FastBitmap(myTexture);
                var b = new FastBitmap(myBitmap);
                for (int y = 0; y < bmp.Height; y++)
                {
                    Application.DoEvents();
                    for (int x = 0; x < bmp.Width; x++)
                    {
                        /*Multi-dimension array:*/
                        //b.SetPixel(x, y, (a.GetPixel((distanceTable[x, y] + shiftX) % myTexture.Width, (angleTable[x, y] + shiftY) % myTexture.Height)));

                        /*Jagged array:*/
                        b.SetPixel(x, y, (a.GetPixel((distanceTable2[x][y] + shiftX) % myTexture.Width, (angleTable2[x][y] + shiftY) % myTexture.Height)));
                    }
                }

                a.Release();
                b.Release();
                gForm.DrawImageUnscaled(myBitmap, 0, 0, fWidth, fHeight);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            myTexture = XorTexture(128, 128);

            CreateTables();

            bw = new BackgroundWorker();
            bw.DoWork += Bw_DoWork;
        }

        private void Bw_DoWork(object sender, DoWorkEventArgs e)
        {
            InitPictureBox();
            DoXorTunnel();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            bw.RunWorkerAsync();
        }

        Bitmap XorTexture(int texHeight, int texWidth)
        {
            var myB = new Bitmap(texWidth, texHeight);
            var b = new FastBitmap(myB);

            for (var y = 0; y < texHeight; y++)
            {
                for (var x = 0; x < texWidth; x++)
                {
                    var c = (x ^ y) % 256;
                    b.SetPixel(x, y, Color.FromArgb(c, c, c));
                }
            }
            b.Release();
            return myB;
        }

        void CreateTables()
        {
            distanceTable = new int[bmp.Width, bmp.Height];
            distanceTable2 = new int[bmp.Width][];
            for (var i = 0; i < bmp.Width; i++)
                distanceTable2[i] = new int[bmp.Height];

            angleTable = new int[bmp.Width, bmp.Height];
            angleTable2 = new int[bmp.Width][];
            for (var i = 0; i < bmp.Width; i++)
                angleTable2[i] = new int[bmp.Height];

            for (var y = 0; y < bmp.Height; y++)
            {
                for (var x = 0; x < bmp.Width; x++)
                {
                    int angle, distance;
                    float ratio = 32.0f;
                    distance = (int)(ratio * myTexture.Height / Math.Sqrt((x - bmp.Width / 2.0) * (x - bmp.Width / 2.0) + (y - bmp.Height / 2.0) * (y - bmp.Height / 2.0))) % myTexture.Height;
                    angle = (int)(0.5 * myTexture.Width * Math.Atan2(y - bmp.Height / 2.0, x - bmp.Width / 2.0) / Math.PI);
                    distanceTable[x, y] = distance;
                    angleTable[x, y] = angle;

                    distanceTable2[x][y] = distance;
                    angleTable2[x][y] = angle;
                }
            }
        }
    }

Any suggestions to make this pixel manipulation work faster?

4
This code has been partially converted from various sources, but eventually I ended up with having to code my own custom bitmap-font parser to get it to work properly - I hope everyone finds this useful :)
Code: [Select]
    /// <summary>
    /// String Alignment Options
    /// </summary>
    public enum StringAlignment
    {
        /// <summary>
        /// Sets the alignment all to the left
        /// </summary>
        Left,
        /// <summary>
        /// Sets the alignment all to the middle
        /// </summary>
        Middle,
        /// <summary>
        /// Sets the alignment all to the right
        /// </summary>
        Right,
        /// <summary>
        /// Sets the alignment all to the set number
        /// </summary>
        Custom
    }
    /// <summary>
    /// Structure of the Font
    /// </summary>
    public struct Spritefont
    {
        /// <summary>
        /// The exact string of the alphabet
        /// </summary>
        public string Alphabet;
        /// <summary>
        /// The bitmap of the font to use
        /// </summary>
        public Bitmap FontImage;
        /// <summary>
        /// Height of each individual character
        /// </summary>
        public int CharHeight;
        /// <summary>
        /// Width of each individual character
        /// </summary>
        public int CharWidth;
    }
    /// <summary>
    /// Structure of the mapped alphabet
    /// </summary>
    public struct BitmapAlphabet
    {
        /// <summary>
        /// Mapped image of letter
        /// </summary>
        public Bitmap LetterPic;
        /// <summary>
        /// Mapped character of letter
        /// </summary>
        public char Letter;
    }
    /// <summary>
    /// Classic oldschool sinewave text-scroller
    /// </summary>
    /// <author>
    /// mammon
    /// </author>
    public class clsSineWaveScroller
    {
        int sinemultiplier1 = 70;
        int sinemultiplier2 = 70;

        float[] sinearray1 = new float[360];
        float[] sinearray2 = new float[360];

        float[] nTextScroller;
        float X_POS, Y_POS, x_pos_tracker;

        PictureBox myPicBox;
        Spritefont myFont;
        string textToScroll;
        BitmapAlphabet[] sAlphabet;
        bool isBitmapFontUsed = false;

        /// <summary>
        /// Sets the spritefont...
        /// </summary>
        /// <param name="nyFont">The bitmap font to use</param>
        public void SetMyFont(Spritefont nyFont)
        {
            myFont = nyFont;
            isBitmapFontUsed = true;
            InitiateFont();
        }
        /// <summary>
        /// Initiates the SineWave-TextScroller effect...
        /// </summary>
        /// <param name="cPicBox">PictureBox where the effect will be drawn...</param>
        /// <param name="sSpritFont">The bitmap font to use...</param>
        /// <param name="toScroll">The string to scroll...</param>
        public clsSineWaveScroller(PictureBox cPicBox, Spritefont sSpritFont, string toScroll)
        {
            textToScroll = toScroll;
            myPicBox = cPicBox;

            InitiateSineWave();
            SetMyFont(sSpritFont);
        }
        /// <summary>
        /// Initiates the SineWave TextScroller effect...
        /// </summary>
        /// <param name="cPicBox">PictureBox where the effect will be drawn...</param>
        /// <param name="toScroll">The string to scroll...</param>
        public clsSineWaveScroller(PictureBox cPicBox, string toScroll)
        {
            textToScroll = toScroll;
            myPicBox = cPicBox;
            InitiateSineWave();
        }
        /// <summary>
        /// Draws the sinewave-textscroller upon the provided Graphics field...
        /// </summary>
        /// <param name="gfx">Graphics field to write the sinewave-textscroller to...</param>
        public void DrawScroller(Graphics gfx)
        {
            DrawText(gfx);
        }
        /// <summary>
        /// Draws a simple string to the Graphics field...
        /// </summary>
        /// <param name="toWrite">The string to write...</param>
        /// <param name="strAlign">Alignment of the string...</param>
        /// <param name="gfx">Graphics field to write the string to...</param>
        /// <param name="customAlign">[OPTIONAL] Custom number to align to...</param>
        public void DrawStaticString(string toWrite, StringAlignment strAlign, Graphics gfx, [Optional]int customAlign)
        {
            gfx.FillRectangle(new LinearGradientBrush(myPicBox.ClientRectangle, Color.DarkSlateGray, Color.DarkViolet, LinearGradientMode.Vertical), myPicBox.ClientRectangle);
            var xposx = 0;
            var middle = myPicBox.Width / 2 - (myFont.CharWidth * (toWrite.Length / 2)) - myFont.CharWidth;
            var right = myPicBox.Width - (myFont.CharWidth * toWrite.Length) - myFont.CharWidth;
            for (int x = 0; x < toWrite.Length; x++)
            {
                switch (strAlign)
                {
                    case StringAlignment.Middle:
                        xposx = (x * myFont.CharWidth) + middle;
                        break;
                    case StringAlignment.Left:
                        xposx = (x * myFont.CharWidth);
                        break;
                    case StringAlignment.Right:
                        xposx = (x * myFont.CharWidth) + right;
                        break;
                    case StringAlignment.Custom:
                        xposx = (x * myFont.CharWidth) + customAlign;
                        break;
                }
                gfx.DrawImage(sAlphabet.Single(xx => xx.Letter == toWrite.ToUpper()[x]).LetterPic, xposx, 2);
            }

        }
        void InitiateSineWave()
        {
            nTextScroller = new float[textToScroll.Length];
            for (int i = 0; i < textToScroll.Length; i++)
                nTextScroller[i] = i;

            x_pos_tracker = this.myPicBox.Right;
            for (int i = 0; i < 360; i++)
            {
                sinearray1[i] = sinemultiplier1 + ((float)Math.Sin(DegToRad(i)) * sinemultiplier1);
                sinearray2[i] = sinemultiplier2 + ((float)Math.Sin(DegToRad(i)) * sinemultiplier2);
            }
        }
        void InitiateFont()
        {
            sAlphabet = new BitmapAlphabet[myFont.Alphabet.Length];
            for (var a = 0; a < sAlphabet.Length; a++)
            {
                sAlphabet[a].Letter = myFont.Alphabet[a];
                sAlphabet[a].LetterPic = GetCharacter(myFont.Alphabet[a]);
            }

            sinemultiplier1 = myPicBox.Height / 4 - myFont.CharHeight;
            sinemultiplier2 = myPicBox.Height / 4 - myFont.CharHeight;
        }
        void DrawText(Graphics gfx)
        {
            if (x_pos_tracker + textToScroll.Length * myFont.CharWidth > 0)
                x_pos_tracker--;
            else
                x_pos_tracker = this.myPicBox.Right;

            gfx.FillRectangle(Brushes.Transparent, this.myPicBox.ClientRectangle);
            for (int x = 0; x < textToScroll.Length; x++)
            {
                X_POS = (x * myFont.CharWidth) + x_pos_tracker;
                if (nTextScroller[x] < sinearray1.Length)
                    Y_POS = sinearray1[(int)nTextScroller[x]];
                else
                {
                    nTextScroller[x] = 0;
                    Y_POS = sinearray1[(int)nTextScroller[x]];
                }
                nTextScroller[x]++;
                if (isBitmapFontUsed)
                    gfx.DrawImage(sAlphabet.First(xx => xx.Letter == textToScroll.ToUpper()[x]).LetterPic, new PointF(X_POS, Y_POS));
                else
                    gfx.DrawString(textToScroll[x].ToString(), new Font(SystemFonts.DialogFont, FontStyle.Regular), Brushes.Blue, new PointF(X_POS, Y_POS));
            }
        }
        #region Version 1.1 BMPFontParser
        Bitmap GetCharacter(char c)
        {
            var myAlphabet = myFont.Alphabet;

            var i = 0;
            var myBmp = myFont.FontImage;
            var charBmp = new Bitmap(myFont.CharWidth, myFont.CharHeight);
            myBmp.MakeTransparent();
            var g = Graphics.FromImage(myBmp);

            if (myAlphabet.Contains(c))
            {
                for (i = 0; i < myAlphabet.Length && (myAlphabet[i] != c); i++) ;
                var w = myBmp.Width; var h = myBmp.Height;
                var xpos = 0; var ypos = 0;

                for (var x = 0; x < myAlphabet.Length; x++)
                {
                    if (xpos >= w)
                    {
                        xpos = 0;
                        ypos += myFont.CharHeight;
                    }
                    if (myAlphabet[x] == c)
                    {
                        charBmp = GetCharacter(myBmp, new Rectangle(xpos, ypos, myFont.CharWidth, myFont.CharHeight));
                        return charBmp;
                    }
                    xpos += myFont.CharWidth;
                }
            }
            else
                charBmp = new Bitmap(myFont.CharWidth, myFont.CharHeight);

            return charBmp;
        }
        #endregion
        Bitmap GetCharacter(Bitmap source, Rectangle section)
        {
            var bmp = new Bitmap(section.Width, section.Height);

            var g = Graphics.FromImage(bmp);
            g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);

            return bmp;
        }
        float DegToRad(float degrees)
        {
            return ((degrees * (float)Math.PI) / 90);
        }
    }

Pages: [1]