public void CopyTo( Surface target, int x = 0, int y = 0 ) { int src = 0; int dst = 0; int srcwidth = width; int srcheight = height; int dstwidth = target.width; int dstheight = target.height; if ((srcwidth + x) > dstwidth) srcwidth = dstwidth - x; if ((srcheight + y) > dstheight) srcheight = dstheight - y; if (x < 0) { src -= x; srcwidth += x; x = 0; } if (y < 0) { src -= y * width; srcheight += y; y = 0; } if ((srcwidth > 0) && (srcheight > 0)) { dst += x + dstwidth * y; for ( int v = 0; v < srcheight; v++ ) { for( int u = 0; u < srcwidth; u++ ) target.pixels[dst + u] = pixels[src + u]; dst += dstwidth; src += width; } } }
//Draw the ray on the debug. public void DrawRay(Surface screen) { int x1 = Debug.TX(O.X, screen.width); int y1 = Debug.TZ(O.Z, screen.height); int x2 = Debug.TX((O + D * l).X, screen.width); int y2 = Debug.TZ((O + D * l).Z, screen.height); screen.Line(x1, y1, x2, y2, 16776960); }
// initialize public void Init(Rectangle bounds) { screen = new Surface(bounds.Width, bounds.Height); camera = new Camera(bounds.Width, bounds.Height); scene = new Scene(); Application.CreateApplication(camera, screen, scene, bounds); Debug.CreateDebug(scene, screen); }
public virtual void DrawDebug(Surface screen) { int x1 = Debug.TX(p.X, screen.width); int z1 = Debug.TZ(p.Z, screen.height); int x2 = Debug.TX((e1 + p).X, screen.width); int z2 = Debug.TZ((e1 + p).Z, screen.height); int x3 = Debug.TX((e2 + p).X, screen.width); int z3 = Debug.TZ((e2 + p).Z, screen.height); screen.Line(x1, z1, x2, z2, Raytracer.VectorToColor(Vector3.One)); screen.Line(x1, z1, x3, z3, Raytracer.VectorToColor(Vector3.One)); screen.Line(x2, z2, x3, z3, Raytracer.VectorToColor(Vector3.One)); }
public void Render(Camera cam, Surface screen, Scene scene) { Parallel.For(0, screen.height, y => { float hi = y / (float)screen.height; for (int x = 0; x < (screen.width / 2); x++) { float wi = x / ((float)screen.width / 2); RenderPixel(cam, screen, scene, hi, wi, x, y); } }); }
//Constructor of the application. static public void CreateApplication(Camera cam, Surface scr, Scene sce, Rectangle bound) { raytracer = new Raytracer(); camera = cam; screen = scr; scene = sce; bounds = bound; //Move the cursor to the middle of the screen and instantiate the variables to measure mouse movement. Cursor.Position = new Point(bounds.Left + bounds.Width / 2, bounds.Top + bounds.Height / 2); currentCursor = Cursor.Position; previousCursor = Cursor.Position; mouseDelta = Vector2.Zero; }
public void RenderPixel(Camera cam, Surface screen, Scene scene, float hi, float wi, int x, int y) { Vector3[] points = cam.GetPoints; Vector3 direction = new Vector3(); Vector3 result; Ray ray; if (AntiAlias) { float offX = 1 / 2f * 1 / screen.width; float offY = 1 / 2f * 1 / screen.height; Vector3 directionLB = points[0] + wi * (points[1] - points[0]) + hi * (points[2] - points[0]); Vector3 directionRB = points[0] + (wi + offX) * (points[1] - points[0]) + hi * (points[2] - points[0]); Vector3 directionLO = points[0] + wi * (points[1] - points[0]) + (hi + offY) * (points[2] - points[0]); Vector3 directionRO = points[0] + (wi + offX) * (points[1] - points[0]) + (hi + offY) * (points[2] - points[0]); ray = new Ray(cam.Position, directionLB, float.MaxValue); Ray ray2 = new Ray(cam.Position, directionRB, float.MaxValue); Ray ray3 = new Ray(cam.Position, directionLO, float.MaxValue); Ray ray4 = new Ray(cam.Position, directionRO, float.MaxValue); Vector3 res1 = CastPrimaryRay(ray, scene); Vector3 res2 = CastPrimaryRay(ray2, scene); Vector3 res3 = CastPrimaryRay(ray3, scene); Vector3 res4 = CastPrimaryRay(ray4, scene); result = (res1 + res2 + res3 + res4) / 4; } else { direction = points[0] + wi * (points[1] - points[0]) + hi * (points[2] - points[0]); ray = new Ray(cam.Position, direction, float.MaxValue); result = CastPrimaryRay(ray, scene); } if (ray.D.Y < .01f && ray.D.Y > -.01f && x % 10 == 0) { Debug.Rays.Add(ray); } //screen.pixels[x + y * screen.width] = VectorToColor(CastPrimaryRay(ray, screen, scene, 0)); screen.pixels[x + y * screen.width] = VectorToColor(result); }
public override void DrawDebug(Surface screen) { screen.Circle((radius / 10) * screen.width, Debug.TX(position.X, screen.width), Debug.TZ(position.Z, screen.height), Raytracer.VectorToColor(color), (float)100); }
public void Print( string t, int x, int y, int c ) { if (!fontReady) { font = new Surface( "../../assets/font.png" ); string ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_-+={}[];:<>,.?/\\ "; fontRedir = new int[256]; for( int i = 0; i < 256; i++ ) fontRedir[i] = 0; for( int i = 0; i < ch.Length; i++ ) { int l = (int)ch[i]; fontRedir[l & 255] = i; } fontReady = true; } for( int i = 0; i < t.Length; i++ ) { int f = fontRedir[(int)t[i] & 255]; int dest = x + i * 12 + y * width; int src = f * 12; for( int v = 0; v < font.height; v++, src += font.width, dest += width ) for( int u = 0; u < 12; u++ ) { if ((font.pixels[src + u] & 0xffffff) != 0) pixels[dest + u] = c; } } }
public Sprite( string fileName ) { bitmap = new Surface( fileName ); textureID = bitmap.GenTexture(); }
public virtual void DrawDebug(Surface screen) //For drawing on the debug screen. { }
static public void Report( int ms, int spp, Surface screen ) { // get system information int RealCores = 0, VirtualCores = System.Environment.ProcessorCount; try { foreach (var item in new System.Management.ManagementObjectSearcher( "Select NumberOfCores from Win32_Processor" ).Get()) RealCores += int.Parse(item["NumberOfCores"].ToString()); } catch { RealCores = System.Environment.ProcessorCount; } // calculate RMSE Surface reference = new Surface( "../../assets/reference.png" ); float SE = 0; for( int y = 0; y < screen.height; y++ ) for( int x = 0; x < screen.width; x++ ) { int p1 = reference.pixels[x + y * reference.width], p2 = screen.pixels[x + y * screen.width]; int dr = ((p1 >> 16) & 255) - ((p2 >> 16) & 255); int dg = ((p1 >> 8) & 255) - ((p2 >> 8) & 255); int db = (p1 & 255) - (p2 & 255); SE += (float)(dr * dr + dg * dg + db * db); } float RMSE = (float)Math.Sqrt( SE / (float)(screen.width * screen.height) ); // report Console.Write( spp.ToString() + " " + ms.ToString() + " " + RMSE.ToString() + " " + RealCores.ToString() + " " + VirtualCores.ToString() ); terminated = true; }
public void Render(Camera cam, Scene scene, Surface displaySurf) { if (aa == 2) { for (int x = -sQuarterWidth; x < sQuarterWidth; x++) { for (int y = -sHalfHeight; y < sHalfHeight; y++) { Vector3 color = AugustRay(x, y, (x * divX * cam.right) + (y * divY * cam.up) + cam.position + cam.direction, 4); int finalColor = (((int)color.X * 65536) + ((int)color.Y * 256) + (int)color.Z); pixelBuffer[(y + sHalfHeight) * sWidth + (x + sQuarterWidth)] = finalColor;//screenpoint inserted here }//for loop y }//(for loop x) } else if (aa == 1) { for (int x = -sQuarterWidth; x < sQuarterWidth; x += 2) { for (int y = -sHalfHeight; y < sHalfHeight; y += 2) { Vector3 color = AugustRay(x, y, (x * divX * cam.right) + (y * divY * cam.up) + cam.position + cam.direction, 4); int finalColor = (((int)color.X * 65536) + ((int)color.Y * 256) + (int)color.Z); int bufferBuffer = finalColor; pixelBuffer[(y + sHalfHeight) * sWidth + (x + sQuarterWidth)] = bufferBuffer; // pixelBuffer[(y + sHalfHeight) * sWidth + (x + 1 + sQuarterWidth)] = bufferBuffer; // pixelBuffer[(y + 1 + sHalfHeight) * sWidth + (x + sQuarterWidth)] = bufferBuffer; // pixelBuffer[(y + 1 + sHalfHeight) * sWidth + (x + 1 + sQuarterWidth)] = bufferBuffer; // }//for loop y }//(for loop x) } else if (aa == 3) { for (int x = -sQuarterWidth * 2; x < sQuarterWidth * 2; x += 2) { for (int y = -sHalfHeight * 2; y < sHalfHeight * 2; y += 2) { float red = (AugustRay(x, y, (x * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).X + AugustRay(x + 1, y, ((x + 1) * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).X + AugustRay(x, y + 1, (x * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).X + AugustRay(x + 1, y + 1, ((x + 1) * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).X) * 0.25f; float green = (AugustRay(x, y, (x * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Y + AugustRay(x + 1, y, ((x + 1) * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Y + AugustRay(x, y + 1, (x * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Y + AugustRay(x + 1, y + 1, ((x + 1) * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Y) * 0.25f; float blue = (AugustRay(x, y, (x * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Z + AugustRay(x + 1, y, ((x + 1) * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Z + AugustRay(x, y + 1, (x * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Z + AugustRay(x + 1, y + 1, ((x + 1) * 0.5f * divX * cam.right) + ((y + 1) * 0.5f * divY * cam.up) + cam.position + cam.direction, 4).Z) * 0.25f; int finalColor = (((int)red * 65536) + ((int)green * 256) + (int)blue); pixelBuffer[(y / 2 + sHalfHeight) * sWidth + (x / 2 + sQuarterWidth)] = finalColor; //if (x % 2 == 0 && y % 2 == 0) //{ // pixelBuffer[(y / 2 + sHalfHeight) * sWidth + (x / 2 + sQuarterWidth)] = 0; //} //int bufferBuffer = (AugustRay(x, y, (x * 0.5f * divX * cam.right) + (y * 0.5f * divY * cam.up) + cam.position + cam.direction, 4) >> 2); //bufferBuffer &= 4144959; //pixelBuffer[(y / 2 + sHalfHeight) * sWidth + (x / 2 + sQuarterWidth)] += bufferBuffer; } //for loop y } //(for loop x) } //Debugging view: foreach (Primitive s in scene.primitives) { if (s is Sphere) { Vector2 sphereScreenPosition = returnScreenCoordinates(s.position); double red = 255 * s.color.X , green = 255 * s.color.Y , blue = 255 * s.color.Z; int pixelColor = ((int)red * 65536) + ((int)green * 256) + ((int)blue); drawCircle(sphereScreenPosition, (s as Sphere).radius * zMultiplier, pixelColor); } } for (int u = 0; u < sWidth * sHeight; u++) { if (u % sWidth < sHeight) { screen.pixels[u] = pixelBuffer[u]; } } screen.Print("WASD and Arrow keys to move, R to reset, F and G to change FOV", 5, 5, 0xffffff); screen.Print("Current FOV: " + cam.fov, sQuarterWidth * 2 + 5, 25, 0xffffff); screen.Print("1-2-3 to pick antialiasing.", sQuarterWidth * 2 + 5, 45, 0xffffff); screen.Print("x0.25, x1 and x4 respectively.", sQuarterWidth * 2 + 5, 65, 0xffffff); for (int i = 0; i < sHeight; i++) { screen.pixels[sWidth / 2 + i * sWidth] = 0xffffff; } Vector2 screenFirst = returnScreenCoordinates(cam.position + cam.left + cam.direction); Vector2 screenSecond = returnScreenCoordinates(cam.position + cam.right + cam.direction); screen.Line((int)screenFirst.X, (int)screenFirst.Y, (int)screenSecond.X, (int)screenSecond.Y, 0xffffff);//deze moet iets anders tekenen op het moment dat je omhoog kijkt .... }
//Constructor. public static void CreateDebug(Scene sce, Surface scr) { Rays = new List<Ray>(); scene = sce; screen = scr; }
public Sprite(string fileName) { bitmap = new Surface(fileName); textureID = bitmap.GenTexture(); }