Exemple #1
0
 protected override void Draw()
 {
     if (_activeProfile > -1)
     {
         _profiles[_activeProfile].Draw();
     }
     else
     {
         SoftwareRasterizer.ClearBitmap(CurrentSwapchainBuffer, System.Drawing.Color.CornflowerBlue);
     }
     base.Draw();
 }
Exemple #2
0
        void initializeResources()
        {
            _swapchainBuffers = new Bitmap[SWAPCHAIN_BUFFER_COUNT];
            _depthBuffers     = new float[SWAPCHAIN_BUFFER_COUNT][, ];

            for (int i = 0; i < SWAPCHAIN_BUFFER_COUNT; i++)
            {
                _swapchainBuffers[i] = new Bitmap(800, 600);
                _depthBuffers[i]     = new float[800, 600];

                SoftwareRasterizer.ClearBitmap(_swapchainBuffers[i], Color.CornflowerBlue);
                SoftwareRasterizer.ClearDepth(_depthBuffers[i]);
            }
        }
        public void Run(VertexIn[] vertexBuffer, int[] indexBuffer, CBuffer constantBuffer, Bitmap outputBuffer, float[,] depthBuffer)
        {
            TextureSampler sampler = new TextureSampler()
            {
                _pipeline = this
            };

            //initialize variables
            if (verts == null || verts.Length == vertexBuffer.Length)
            {
                verts = new VertexData[vertexBuffer.Length];
            }

            if (depthBuffer != null)
            {
                if (depthLock == null || depthLock.GetLength(0) != outputBuffer.Width || depthLock.GetLength(1) != outputBuffer.Height)
                {
                    depthLock = new object[depthBuffer.GetLength(0), depthBuffer.GetLength(0)];
                }

                for (int x = 0; x < outputBuffer.Width; x++)
                {
                    for (int y = 0; y < outputBuffer.Height; y++)
                    {
                        depthLock[x, y] = new object();
                    }
                }
            }

            //Create tasks and process vertices;
            Parallel.For(0, vertexBuffer.Length, (i) =>
            {
                verts[i]            = VertexShader.VertexMain(vertexBuffer[i], in constantBuffer);
                verts[i].Position.Y = -verts[i].Position.Y;
            });

            int        size = outputBuffer.Width * outputBuffer.Height;
            BitmapData dat  = outputBuffer.LockBits(new Rectangle(0, 0, 800, 600), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            byte[] colDat = new byte[size * 4];
            Marshal.Copy(dat.Scan0, colDat, 0, colDat.Length);
            int width  = outputBuffer.Width;
            int height = outputBuffer.Height;

            //Create tasks and process data to output pixels
            Parallel.For(0, indexBuffer.Length / 3, (i) =>
            {
                int i1 = i * 3;
                //Assemble geometry and rasterize triangles
                List <FragmentData> frags = SoftwareRasterizer.Rasterize(verts[indexBuffer[i1]], verts[indexBuffer[i1 + 1]],
                                                                         verts[indexBuffer[i1 + 2]], height, width);


                Parallel.For(0, frags.Count, (j) =>
                {
                    //get fragment
                    FragmentData frag = frags[j];
                    //get pixel color
                    Vector4 pixel = FragmentShader.FragmentMain(frag, in sampler, in constantBuffer);

                    //store coord into ints for speed
                    int x = (int)frag.Position.X, y = (int)frag.Position.Y;

                    //don't do depth test if no buffer is given
                    if (depthBuffer == null)
                    {
                        lock (depthLock[x, y])
                        {
                            int index         = (y * width) + x;
                            index            *= 4;
                            colDat[index]     = (byte)(pixel.Z * 255);
                            colDat[index + 1] = (byte)(pixel.Y * 255);
                            colDat[index + 2] = (byte)(pixel.X * 255);
                            colDat[index + 3] = (byte)(pixel.W * 255);
                        }
                    }
                    else
                    {
                        //check depth buffer and set output if necessary
                        //lock for thread safety
                        lock (depthLock[x, y])
                        {
                            //check if our pixel is nearer than nearest pixel previously drawn
                            float depth = depthBuffer[x, y];
                            if (frag.Position.Z <= depth)
                            {
                                //if our pixel is closest, set depthbuffer to our depth
                                depthBuffer[x, y] = frag.Position.Z;
                                //set outputBuffer color
                                int index         = (y * width) + x;
                                index            *= 4;
                                colDat[index]     = (byte)(pixel.Z * 255);
                                colDat[index + 1] = (byte)(pixel.Y * 255);
                                colDat[index + 2] = (byte)(pixel.X * 255);
                                colDat[index + 3] = (byte)(pixel.W * 255);
                            }
                        }
                    }
                });
            });

            Marshal.Copy(colDat, 0, dat.Scan0, colDat.Length);
            outputBuffer.UnlockBits(dat);
        }