public static void ClipLine(ref QLine line) { QPoint vec = line.a - line.b; const float y0 = 1e-4f; if (line.a.y < 0) { line.a.y = y0; line.a.x = line.b.x + vec.x * (y0 - line.b.y) / vec.y; return; } if (line.b.y < 0) { line.b.y = y0; line.b.x = line.a.x + vec.x * (y0 - line.a.y) / vec.y; } }
private static void DrawSectors() { GL.LineWidth(2.0f); GL.Begin(PrimitiveType.Lines); foreach (Sector sector in World.sectors) { for (int i = 0; i < sector.vertices.Count - 1; i++) { //Console.WriteLine("V: " + sector.vertices.Count); //Console.WriteLine("N: " + sector.neighbors.Count); int vertexIndex = sector.vertices[i]; int vertexIndexNext = sector.vertices[i + 1]; QPoint a = World.vertices[vertexIndex]; QPoint b = World.vertices[vertexIndexNext]; if (sector.neighbors[(i) % sector.vertices.Count] != -1) { GL.Color3(Color.Red); } else { GL.Color3(Color.Lime); //GL.End(); //continue; } GL.Vertex2(mapScale * a.x + Game.window.Width / 4, mapScale * a.y + Game.window.Height / 4); GL.Vertex2(mapScale * b.x + Game.window.Width / 4, mapScale * b.y + Game.window.Height / 4); } } GL.End(); }
private static void DrawSectors() { var renderedSectors = new RedBlackTree <int, object>() { }; var sectorQueue = new Queue(); int currentSector = player.sector; var secRender = new SectorRendering(currentSector, 0, window.Width - 1); int[] yTop = new int[window.Width]; int[] yBottom = Enumerable.Repeat(window.Height - 1, window.Width).ToArray(); GL.Begin(PrimitiveType.Lines); do { var sector = World.sectors[currentSector]; for (int i = 0; i < sector.numPoints; i++) { int vertexIndex = sector.vertices[i]; int vertexIndexNext = sector.vertices[i + 1]; QLine temp = new QLine(World.vertices[vertexIndex], World.vertices[vertexIndexNext]); temp.a -= player.pos; temp.b -= player.pos; QLine trans = RotateLine(temp, player.viewAngle); // x for x, y for z if (trans.a.y < 0 && trans.b.y < 0) { return; } ClipLine(ref trans); QPoint[] scales = new QPoint[2] { new QPoint(x_scale / trans.a.y, y_scale / trans.a.y), new QPoint(x_scale / trans.b.y, y_scale / trans.b.y) }; int x1 = window.Width / 2 - (int)(trans.a.x * scales[0].x); int x2 = window.Width / 2 - (int)(trans.b.x * scales[1].x); if (x1 >= x2 || x2 < secRender.sx1 || x1 > secRender.sx2) { continue; } float yCeil = World.sectors[currentSector].ceilHeight - player.height; float yFloor = World.sectors[currentSector].floorHeight - player.height; int neighbor = World.sectors[currentSector].neighbors[i]; float nyCeil = 0.0f, nyFloor = 0.0f; if (neighbor >= 0) { nyCeil = World.sectors[currentSector].ceilHeight - player.height; nyFloor = World.sectors[currentSector].floorHeight - player.height; } // TODO: ADD YAW int y1a = window.Height / 2 - (int)(yCeil * scales[0].y); int y2a = window.Height / 2 - (int)(yCeil * scales[1].y); int y1b = window.Height / 2 - (int)(yFloor * scales[0].y); int y2b = window.Height / 2 - (int)(yFloor * scales[1].y); int ny1a = window.Height / 2 - (int)(nyCeil * scales[0].y); int ny2a = window.Height / 2 - (int)(nyCeil * scales[1].y); int ny1b = window.Height / 2 - (int)(nyFloor * scales[0].y); int ny2b = window.Height / 2 - (int)(nyFloor * scales[1].y); int beginX = Math.Max(x1, secRender.sx1); int endX = Math.Min(x2, secRender.sx2); for (int x = beginX; x <= endX; x++) { int cya = (x - x1) * (y2a - y1a) / (x2 - x1) + y1a; Clamp(ref cya, yTop[x], yBottom[x]); int cyb = (x - x1) * (y2b - y1b) / (x2 - x1) + y1b; Clamp(ref cyb, yTop[x], yBottom[x]); GL.Color3(Color.Gray); GL.Vertex2(x, yTop[x]); GL.Vertex2(x, cya - 1); GL.Color3(Color.CadetBlue); GL.Vertex2(x, yBottom[x]); GL.Vertex2(x, cyb + 1); if (neighbor >= 0) { int cnya = (x - x1) * (ny2a - ny1a) / (x2 - x1) + ny1a; Clamp(ref cnya, yTop[x], yBottom[x]); int cnyb = (x - x1) * (ny2b - ny1b) / (x2 - x1) + ny1b; Clamp(ref cnyb, yTop[x], yBottom[x]); if (x == x1 || x == x2) { GL.Color3(Color.Black); } else { GL.Color3(Color.White); } GL.Vertex2(x, cya); GL.Vertex2(x, cnya); int max = Math.Max(cya, cnya); Clamp(ref max, yTop[x], window.Height - 1); yTop[x] = max; // Shrink the remaining window below these ceilings /* If our floor is lower than their floor, render bottom wall */ if (x == x1 || x == x2) { GL.Color3(Color.Black); } else { GL.Color3(Color.White); } GL.Vertex2(x, cnyb); GL.Vertex2(x, cyb); int min = Math.Max(cyb, cnyb); Clamp(ref min, 0, yBottom[x]); yBottom[x] = min; } else { } } } } while (sectorQueue.Count > 0); GL.End(); }
public QLine(QPoint x, QPoint y) { a = x; b = y; }
public static float Det(QPoint p1, QPoint p2) { return(p1.x * p2.y + p2.x * p1.y); }