示例#1
0
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            DateTime startTime = DateTime.Now;

            cycleRadians += (float)gameTime.ElapsedGameTime.TotalSeconds / 4;

            //TODO: lägg till fler ljuskällor
            Vector3 lightsource = new Vector3(40 * (float)Math.Cos(cycleRadians), 40, 40 * (float)Math.Sin(cycleRadians));
            //ange styrka på ljus
            float lightsourceIntensity = 1450;
            float ambientIntensity     = 0.25f;

            for (int l = 0; l < _vertices.Length; l++)
            {
                //Test hur det skulle kunna se ut, positionen kanske inte ska ändra sig bara rayen...
                //Positionen är svår att ändra när trianglarna är av olika storlek. Då de vertex som ligger på en större
                //triangels långsida måste ta med i beräkningen om den större triangelns vertex har ändrats
                //if (l > 500)
                {
                    _dist = 2;
                    _vertices[l].Position.X = _orgVertices[l].X + _rnd.Next(_dist * 2) - _dist;
                    _vertices[l].Position.Y = _orgVertices[l].Y + _rnd.Next(_dist * 2) - _dist;
                }
                //Ray ray = new Ray(_camera, _vertices[l].Position.X + _rnd.Next(5) - 10, _vertices[l].Position.Y + _rnd.Next(5) - 10);
                Ray   ray   = new Ray(_camera, _vertices[l].Position.X, _vertices[l].Position.Y);
                Color pixel = Color.Black;
                //TODO: Antialiasing (kan vara sista steget. Gå i genom alla _vertices och jämna ut färgerna. Kan vara svårt att få till eftersom närliggande(x och y) vertices kan ligga långt ifrån varandra i _vertices. Kanske varje varvs start-index kan sparas undan för att användas till detta?)
                //TODO: Eftersläpa färgen på de punkter som har lägre detaljnivå
                //TODO: Skicka med en parameter för detaljnivå (kan användas för att strunta i att göra intersection och bara anta att träff gjordes på de spheres som finns i griden och mixa färgen från de som finns)
                //TODO: Ändra positionerna för _vertices x och y random för varje frame (då blir bilden inte så kantig och statisk)
                Intersection closestIntersection = _theEntireWorld.GetClosestIntersection(ray, 200);

                if (closestIntersection.IsHit())
                {
                    //TODO: Lägg till Phong-shading
                    //TODO: Lägg till skugg-kontroll (finns en intersection emellan?)
                    Vector3 direction = lightsource - closestIntersection.GetPosition();
                    float   distance  = (direction).Length();
                    float   factor    = Vector3.Dot(closestIntersection.GetNormal(), Vector3.Normalize(direction));
                    //Använd avstånd för att minska ljuset
                    factor *= (float)(lightsourceIntensity / Math.Pow(distance, 2));
                    factor += ambientIntensity;
                    //sätt gränserna till mellan 0 och 1
                    factor = (factor < 0) ? 0 : ((factor > 1) ? 1 : factor);

                    pixel = Color.Multiply(closestIntersection.GetSphere().GetColor(), factor);
                }
                else
                {
                    pixel = Color.Black;
                }

                //Använd cache av första rayen för att se hur mycket som kameran har flyttats eller roterats från förra gången för att avgöra hur
                //mycket som ska blandas av föregående färg
                float afterBurnFactor = 0.05f + (_vertices[l].Position.Length() * 1.5f) / _graphics.PreferredBackBufferWidth;


                //if(_vertices[l].Color != Color.Black)
                _vertices[l].Color = Color.Lerp(pixel, _vertices[l].Color, afterBurnFactor);
                //else
                //    _vertices[l].Color = Color.Lerp(pixel, _vertices[l].Color, 0.1f);

                ////TODO: Testar att hålla fps uppe - ändra till något bättre senare
                //if ((DateTime.Now - startTime).TotalMilliseconds > 100)
                //    break;
            }
            _vertexBuffer.SetData <VertexPositionColor>(_vertices);
            _indexBuffer.SetData(_indices);

            _basicEffect.VertexColorEnabled = true;

            GraphicsDevice.SetVertexBuffer(_vertexBuffer);
            GraphicsDevice.Indices = _indexBuffer;

            RasterizerState rasterizerState = new RasterizerState();

            rasterizerState.CullMode       = CullMode.None;
            GraphicsDevice.RasterizerState = rasterizerState;

            foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _vertices.Length, 0, _indices.Length);
            }


            //FPS #################
            //_lastShownFPS = _lastShownFPS.Add(gameTime.ElapsedGameTime);

            //if (_lastShownFPS.TotalSeconds > 1.0)
            //{
            //    _lastShownFPS = TimeSpan.Zero;
            //    _fpsString = string.Format("FPS: {0:F0} Cam: {1}", (1.0 / gameTime.ElapsedGameTime.TotalSeconds), _camera.GetPosition().ToString());
            //}
            //_spriteBatch.Begin();
            //_spriteBatch.DrawString(_guiFont, _fpsString, new Vector2(10, 10), Color.LightGray);
            //_spriteBatch.End();
            //FPS #################
        }