source: 2014/30/MikkoI/frakt/frakt/frakt/Game1.cs @ 5651

Revision 5651, 10.5 KB checked in by mijoilmo, 6 years ago (diff)
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading;
5using Microsoft.Xna.Framework;
6using Microsoft.Xna.Framework.Audio;
7using Microsoft.Xna.Framework.Content;
8using Microsoft.Xna.Framework.GamerServices;
9using Microsoft.Xna.Framework.Graphics;
10using Microsoft.Xna.Framework.Input;
11using Microsoft.Xna.Framework.Media;
12
13namespace frakt
14{
15    /// <summary>
16    /// This is the main type for your game
17    /// </summary>
18    public class WooooFract : Microsoft.Xna.Framework.Game
19    {
20        GraphicsDeviceManager graphics;
21        SpriteBatch spriteBatch;
22        Vector2 viewportSize;
23        KeyboardState keyboardState;
24        KeyboardState oldKeyboardState;
25        MouseState mouseState;
26        MouseState oldMouseState;
27
28        SpriteFont command;
29
30        Texture2D pixel;
31        Texture2D image;
32
33        string commandStr = "";
34
35        decimal[,][] pointData;
36
37        decimal[] gridOffset = new decimal[2] { 0, 0 };
38        decimal[] gridScale = new decimal[2] { 4, 4 };
39        int[] calcResolution = new int[2] { 10, 10 };
40        int calcIterations = 1;
41
42        int incr = 2;
43
44        Color[] data;
45
46        public WooooFract()
47        {
48            graphics = new GraphicsDeviceManager(this);
49            graphics.PreferredBackBufferWidth = 1920;
50            graphics.PreferredBackBufferHeight = 1080;
51            Content.RootDirectory = "Content";
52        }
53
54        /// <summary>
55        /// Allows the game to perform any initialization it needs to before starting to run.
56        /// This is where it can query for any required services and load any non-graphic
57        /// related content.  Calling base.Initialize will enumerate through any components
58        /// and initialize them as well.
59        /// </summary>
60        protected override void Initialize()
61        {
62            // TODO: Add your initialization logic here
63            pixel = new Texture2D(GraphicsDevice, 1, 1);
64            pixel.SetData(new UInt32[] { UInt32.MaxValue });
65
66            image = new Texture2D(GraphicsDevice, 1, 1);
67
68            base.Initialize();
69
70            piirraKuva();
71        }
72
73        void piirraKuva()
74        {
75            GraphicsDevice.Textures[0] = null;
76
77            image = new Texture2D(GraphicsDevice, (int)calcResolution[0], (int)calcResolution[1]);
78
79            //alusta fraktaalin numeerinen data
80            this.pointData = new decimal[image.Width, image.Height][];
81
82            int threads = 4;
83            Thread[] apurit = new Thread[threads];
84
85            this.data = new Color[image.Width * image.Height];
86            image.GetData(data);
87
88            for (int y = 0; y < threads; y++)
89            {
90                int yy = y;
91                apurit[y] = new Thread(delegate(object o)
92                {
93                    int alku = (image.Height / threads) * yy;
94                    int loppu = (image.Height / threads) * (yy + 1);
95                    if (yy == threads - 1) { loppu = image.Height; }
96                    Test(alku, loppu);
97                });
98
99                apurit[y].Start(null);
100            }
101
102            for (int y = 0; y < threads; y++)
103            {
104                apurit[y].Join();
105            }
106
107            image.SetData(data);
108        }
109
110        void Test(int alku, int loppu)
111        {
112            Random random = new Random();
113            for (int y = alku; y < loppu; y++)
114            {
115                for (int x = 0; x < image.Width; x++)
116                {
117                    decimal VectorX = (gridScale[0] / image.Width) * x - (gridScale[0] / 2M) + gridOffset[0];
118                    decimal VectorY = (gridScale[1] / image.Height) * y - (gridScale[1] / 2M) + gridOffset[1];
119                    pointData[x, y] = new decimal[4] { VectorX, VectorY, VectorX, VectorY };
120                    for (int iterations = 0; iterations < calcIterations; iterations++)
121                    {
122                        if (doesPointEscape(this.pointData[x, y]))
123                        {
124                            this.data[x + y * image.Width] = getColor(iterations, calcIterations + 1);
125                            break;
126                        }
127                        else
128                        {
129                            pointData[x, y] = iteration2d(pointData[x, y]);
130                        }
131                    }
132                }
133            }
134        }
135
136        bool doesPointEscape(decimal[] vec)
137        {
138            if (vec[0] * vec[0] + vec[1] * vec[1] > 4) return true;
139            return false;
140        }
141
142        decimal[] iteration2d(decimal[] vec)
143        {
144            decimal[] nvec = new decimal[4];
145            nvec[0] = 
146                //1M * vec[0] - vec[1] * vec[1] - 1M * vec[1] * vec[0] * vec[0]; // branch
147                vec[0] * vec[0] - vec[1] * vec[1] + vec[2]; // mandelbrot
148            nvec[1] =
149                //1M * vec[1] - vec[0] * vec[0] - 1M * vec[0] * vec[1] * vec[1]; // branch
150                2M * vec[0] * vec[1] + vec[3]; // mandelbrot
151            nvec[2] = vec[2];
152            nvec[3] = vec[3];
153            return nvec;
154        }
155
156        /// <summary>
157        /// LoadContent will be called once per game and is the place to load
158        /// all of your content.
159        /// </summary>
160        protected override void LoadContent()
161        {
162            // Create a new SpriteBatch, which can be used to draw textures.
163            spriteBatch = new SpriteBatch(GraphicsDevice);
164            command = Content.Load<SpriteFont>("fonts/c");
165
166            // TODO: use this.Content to load your game content here
167        }
168
169        /// <summary>
170        /// UnloadContent will be called once per game and is the place to unload
171        /// all content.
172        /// </summary>
173        protected override void UnloadContent()
174        {
175
176        }
177
178        /// <summary>
179        /// Allows the game to run logic such as updating the world,
180        /// checking for collisions, gathering input, and playing audio.
181        /// </summary>
182        /// <param name="gameTime">Provides a snapshot of timing values.</param>
183
184        bool isKeyPressed(Keys key)
185        {
186            return keyboardState.IsKeyDown(key) && oldKeyboardState.IsKeyUp(key);
187        }
188
189        void commandTypeCheck()
190        {
191
192        }
193
194        protected override void Update(GameTime gameTime)
195        {
196            // Allows the game to exit
197
198            this.keyboardState = Keyboard.GetState();
199
200            if (isKeyPressed(Keys.Enter))
201            {
202                incr++;
203                piirraKuva();
204            }
205
206            if (isKeyPressed(Keys.Left))
207            {
208                gridOffset[0] -= gridScale[0] / 10M;//kymmenes imagen koosta
209                piirraKuva();
210            }
211            else if (isKeyPressed(Keys.Right))
212            {
213                gridOffset[0] += gridScale[0] / 10M;
214                piirraKuva();
215            }
216            if (isKeyPressed(Keys.Up))
217            {
218                gridOffset[1] -= gridScale[1] / 10M;
219                piirraKuva();
220            }
221            else if (isKeyPressed(Keys.Down))
222            {
223                gridOffset[1] += gridScale[1] / 10M;
224                piirraKuva();
225            }
226
227            if (isKeyPressed(Keys.Add))
228            {
229                calcResolution[0] *= 2;
230                calcResolution[1] *= 2;
231                piirraKuva();
232            }
233            else if (isKeyPressed(Keys.Subtract))
234            {
235                calcResolution[0] /= 2;
236                calcResolution[1] /= 2;
237                if (calcResolution[0] < 1 || calcResolution[1] < 1) { calcResolution = new int[2] { 1, 1 }; };
238                piirraKuva();
239            }
240
241            if (isKeyPressed(Keys.OemPlus))
242            {
243                calcIterations *= 2;
244                piirraKuva();
245            }
246            else if (isKeyPressed(Keys.OemMinus))
247            {
248                calcIterations /= 2;
249                if (calcIterations < 1) { calcIterations = 1; };
250                piirraKuva();
251            }
252
253            if (keyboardState.IsKeyDown(Keys.Escape))
254                this.Exit();
255
256            commandTypeCheck();
257
258            this.mouseState = Mouse.GetState();
259
260            if (this.mouseState.ScrollWheelValue != this.oldMouseState.ScrollWheelValue)
261            {
262                if (this.mouseState.ScrollWheelValue > this.oldMouseState.ScrollWheelValue)
263                {
264                    gridScale[0] /= 1.1M;
265                    gridScale[1] /= 1.1M;
266                }
267                else if (this.mouseState.ScrollWheelValue < this.oldMouseState.ScrollWheelValue)
268                {
269                    gridScale[0] *= 1.1M;
270                    gridScale[1] *= 1.1M;
271                }
272                piirraKuva();
273            }
274
275            // TODO: Add your update logic here
276
277            this.oldMouseState = mouseState;
278            this.oldKeyboardState = keyboardState;
279
280            base.Update(gameTime);
281        }
282
283        void startRender()
284        {
285            viewportSize.X = Window.ClientBounds.Width;
286            viewportSize.Y = Window.ClientBounds.Height;
287        }
288
289        /// <summary>
290        /// This is called when the game should draw itself.
291        /// </summary>
292        /// <param name="gameTime">Provides a snapshot of timing values.</param>
293        Color getColor(float index, float size)
294        {
295            Color[] palette = { new Color(0, 0, 0), new Color(255, 0, 0), new Color(255, 255, 0), new Color(0, 255, 0), new Color(0, 255, 255), new Color(0, 0, 255), new Color(0, 0, 0) };
296            index = Math.Abs(index);
297            index = index % size;
298            size--;
299            float realIndex = ((float)Math.Floor(index) / size) * (palette.Length - 1);
300            Color col1 = palette[(int)Math.Floor(realIndex)];
301            Color col2 = palette[(int)Math.Ceiling(realIndex)];
302            float rel = realIndex - (float)Math.Floor(realIndex);
303            return Color.Lerp(col1, col2, rel);
304        }
305        protected override void Draw(GameTime gameTime)
306        {
307            GraphicsDevice.Clear(Color.White);
308            // TODO: Add your drawing code here
309
310            spriteBatch.Begin();
311            spriteBatch.Draw(image, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), Color.White);
312            spriteBatch.DrawString(command, commandStr, new Vector2(0, 0), Color.White);
313            spriteBatch.End();
314
315            base.Draw(gameTime);
316        }
317    }
318}
Note: See TracBrowser for help on using the repository browser.