/// <summary> /// Gets a new instance of Scene. /// </summary> /// <param name="maxWalls">Max walls that the scene can fit</param> /// <param name="maxSprities">Max sprities that the scene can fit</param> public Scene(int maxWalls = 512, int maxSprities = 512) { if (maxWalls <= 0) { throw new ArgumentException("maxWalls cannot be < 1."); } if (maxSprities <= 0) { throw new ArgumentException("maxSprities cannot be < 1."); } Texture background = new Texture((PixelBuffer) new Bitmap(1, 1)); unmanaged = SceneData.Create(maxWalls, maxSprities, background); }
internal static SceneData *Create(int maxWalls, int maxSprities, Texture background) { int total_positions = maxWalls + maxSprities + 1; SceneData *result = (SceneData *)Marshal.AllocHGlobal(sizeof(SceneData)); result->sprities = null; //result->sprities = (Sprite_**)Marshal.AllocHGlobal(maxSprities * sizeof(Sprite_*)); // Not implemented yet result->walls = (WallData **)Marshal.AllocHGlobal(total_positions * sizeof(void *)); *result->walls = null; result->sprite_count = 0; result->sprite_max = maxSprities; result->wall_count = 0; result->wall_max = maxWalls; result->background = background; return(result); }
private WallData *NearestWallTest(SceneData *map, out float nearest_dist, out float nearest_hratio) { nearest_dist = float.PositiveInfinity; nearest_hratio = 2f; WallData * nearest = null; WallData **pptr = map->walls; while (*pptr != null) { //Medium performance impact. GetCollisionData(*pptr, out float cur_dist, out float cur_split); if (cur_dist < nearest_dist) { nearest_hratio = cur_split; nearest_dist = cur_dist; nearest = *pptr; } pptr++; } return(nearest); }
internal WallData *NearestWall(SceneData *map, out float nearest_dist, out float nearest_ratio) { nearest_dist = float.PositiveInfinity; nearest_ratio = 2f; int wallcount = map->wall_count; WallData **cur = map->walls; WallData * nearest = null; for (int i = 0; i < wallcount; i++) { //walls cannot be null. GetCollisionData(*cur, out float cur_dist, out float cur_ratio); if (cur_dist < nearest_dist) { nearest_ratio = cur_ratio; nearest_dist = cur_dist; nearest = *cur; } cur++; } return(nearest); }
private unsafe static void CLRRender(PixelBuffer target, SceneData *scene) // Must be changed { //Caching frequently used values. uint * buffer = target.uint0; int width = target.width; int height = target.height; Texture background = scene->background; if (ParallelRendering) { Parallel.For(0, width, Loop); } else { for (int i = 0; i < width; i++) { Loop(i); } } void Loop(int ray_id) //for (int ray_id = 0; ray_id < rendererData->bitmap_width; ray_id++) { //Caching float ray_cos = cache->cosines[ray_id]; float ray_angle = cache->angles[ray_id] + scene->activeObserver->rotation; Ray ray = new Ray(scene->activeObserver->position, ray_angle); //Cast the ray towards every wall. WallData *nearest = ray.NearestWall(scene, out float nearest_dist, out float nearest_ratio); if (nearest_ratio != 2f) { float columnHeight = (cache->colHeight1 / (ray_cos * nearest_dist)); //Wall column size in pixels float column_start = (height - columnHeight) / 2f; float column_end = (height + columnHeight) / 2f; int draw_column_start = (int)column_start; int draw_column_end = (int)column_end; if (draw_column_start < 0) { draw_column_start = 0; } if (draw_column_end > height) { draw_column_end = height; } for (int line = 0; line < draw_column_start; line++) { //PURPOSELY REPEATED CODE! float background_hratio = ray_angle / 360 + 1; //Temporary bugfix to avoid hratio being < 0 float screenVratio = (float)line / height; float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio; uint color = background.MapPixel(background_hratio, background_vratio); buffer[width * line + ray_id] = color; } for (int line = draw_column_start; line < draw_column_end; line++) { float vratio = (line - column_start) / columnHeight; uint pixel = nearest->texture.MapPixel(nearest_ratio, vratio); buffer[width * line + ray_id] = pixel; } for (int line = draw_column_end; line < height; line++) { //PURPOSELY REPEATED CODE! float background_hratio = ray_angle / 360 + 1; //Temporary bugfix to avoid hratio being < 0 float screenVratio = (float)line / height; float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio; uint color = background.MapPixel(background_hratio, background_vratio); buffer[width * line + ray_id] = color; } } else { for (int line = 0; line < height; line++) { //Critical performance impact. //PURPOSELY REPEATED CODE! float background_hratio = ray_angle / 360 + 1; float screenVratio = (float)line / height; float background_vratio = (1 - ray_cos) / 2 + ray_cos * screenVratio; uint color = background.MapPixel(background_hratio, background_vratio); buffer[width * line + ray_id] = color; } } } }
public static void Delete(SceneData *item) { Marshal.FreeHGlobal((IntPtr)item->sprities); Marshal.FreeHGlobal((IntPtr)item->walls); Marshal.FreeHGlobal((IntPtr)item); }