public static ClipPlaneType SelectClippingPlane(Vertex[] clipVertices, int[] clipIndices, ViewportType viewportType, Point pos, Point size, Vector2 orthoSize, Vector3 orthoPos, Vector3 orthoLookAt, ViewportOrientation viewport) { if (viewportType == ViewportType.Perspective) return ClipPlaneType.NONE; Vector3 outCamPos = new Vector3(), outSurfPos = new Vector3(); CalcOrthoCoords(pos, size, orthoSize, orthoPos, orthoLookAt, out outCamPos, out outSurfPos); // Indeksy trójkątów które trzeba odrzucić, aby można było wybrać // właściwą płaszczyznę obcinającą. int minRejectIdx, maxRejectIdx; switch (viewport) { case ViewportOrientation.Front: minRejectIdx = 144/3; maxRejectIdx = 216/3-1; break; case ViewportOrientation.Side: minRejectIdx = 72/3; maxRejectIdx = 144/3-1; break; case ViewportOrientation.Top: minRejectIdx = 0/3; maxRejectIdx = 72/3-1; break; default: minRejectIdx = 0; maxRejectIdx = 0; break; } Vector3[] shiftDist = new Vector3[6]; for(int i = 0; i < 6; ++i) { shiftDist[i] = (clipVertices[8 * i].Position - clipVertices[8 * i + 4].Position) * 2; } for(int i = 0; i < 6; ++i) { for(int j = 0; j < 8; ++j) { if(j < 4) { clipVertices[i * 8 + j].Position += shiftDist[i]; } else { clipVertices[i * 8 + j].Position -= shiftDist[i]; } } } List<Triang> clipPlaneTriangs = new List<Triang>(); for (int i = 0; i < clipIndices.Length; i += 3) { clipPlaneTriangs.Add(new Triang(clipVertices[clipIndices[i]].Position, clipVertices[clipIndices[i + 1]].Position, clipVertices[clipIndices[i + 2]].Position)); } for(int i = 0; i < 6; ++i) { for(int j = 0; j < 8; ++j) { if(j < 4) { clipVertices[i * 8 + j].Position -= shiftDist[i]; } else { clipVertices[i * 8 + j].Position += shiftDist[i]; } } } Vector3 rayDir = Vector3.Normalize(outSurfPos - outCamPos); Ray ray = new Ray(outCamPos + 0.01f*rayDir, rayDir); float dist = float.PositiveInfinity; float tmpDist; int minIdx = -1; for (int i = 0; i < clipPlaneTriangs.Count; ++i) { if (i < minRejectIdx || i > maxRejectIdx) { if (Ray.Intersects(ray, clipPlaneTriangs[i].p1, clipPlaneTriangs[i].p2, clipPlaneTriangs[i].p3, out tmpDist)) { if (tmpDist < dist) { dist = tmpDist; minIdx = i; } } } } return (ClipPlaneType) (minIdx == -1 ? -1 : minIdx/12); }
public void RenderBezier(ViewportInfo viewportInfo, BezierSurface bezier) { if (bezierPp.BackBufferWidth != viewportInfo.resX || bezierPp.BackBufferHeight != viewportInfo.resY || bezierImageCreated) { bezierPp = new PresentParameters(); bezierPp.SwapEffect = SwapEffect.Discard; bezierPp.Windowed = true; bezierPp.BackBufferWidth = viewportInfo.resX; bezierPp.BackBufferHeight = viewportInfo.resY; bezierPp.BackBufferFormat = Format.A8R8G8B8; if (d3dBezier != null) { d3dBezier.Dispose(); } if (deviceBezier != null) { deviceBezier.Dispose(); } bezierImageCreated = false; d3dBezier = new Direct3D(); deviceBezier = new Device(d3dBezier, 0, DeviceType.Hardware, handleBezier, CreateFlags.HardwareVertexProcessing, bezierPp); if(font2 != null) { font2.Dispose(); } font2 = new SlimDX.Direct3D9.Font(deviceBezier, new System.Drawing.Font(FontFamily.GenericSansSerif, 7)); } if (top.X != viewportInfo.posX[2] || top.Y != viewportInfo.posY[2] || top.Width != viewportInfo.sizeX[2] || top.Height != viewportInfo.sizeY[2]) { top = new Viewport(); top.X = viewportInfo.posX[2]; top.Y = viewportInfo.posY[2]; top.Width = viewportInfo.sizeX[2]; top.Height = viewportInfo.sizeY[2]; top.MinZ = 0; top.MaxZ = 1; } if (front.X != viewportInfo.posX[0] || front.Y != viewportInfo.posY[0] || front.Width != viewportInfo.sizeX[0] || front.Height != viewportInfo.sizeY[0]) { front = new Viewport(); front.X = viewportInfo.posX[0]; front.Y = viewportInfo.posY[0]; front.Width = viewportInfo.sizeX[0]; front.Height = viewportInfo.sizeY[0]; front.MinZ = 0; front.MaxZ = 1; } if (side.X != viewportInfo.posX[1] || side.Y != viewportInfo.posY[1] || side.Width != viewportInfo.sizeX[1] || side.Height != viewportInfo.sizeY[1]) { side = new Viewport(); side.X = viewportInfo.posX[1]; side.Y = viewportInfo.posY[1]; side.Width = viewportInfo.sizeX[1]; side.Height = viewportInfo.sizeY[1]; side.MinZ = 0; side.MaxZ = 1; } if(perspective.X != viewportInfo.posX[3] || perspective.Y != viewportInfo.posY[3] || perspective.Width != viewportInfo.sizeX[3] || perspective.Height != viewportInfo.sizeY[3]) { perspective = new Viewport(); perspective.X = viewportInfo.posX[3]; perspective.Y = viewportInfo.posY[3]; perspective.Width = viewportInfo.sizeX[3]; perspective.Height = viewportInfo.sizeY[3]; perspective.MinZ = 0; perspective.MaxZ = 1; } deviceBezier.SetRenderState(RenderState.Lighting, true); deviceBezier.SetLight(0, defLight); deviceBezier.EnableLight(0, true); deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); deviceBezier.SetRenderState(RenderState.CullMode, Cull.None); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); Vertex[] gridVertices = new Vertex[bezier.OutputPoints.Length]; Vertex[] controlVertices = new Vertex[bezier.ControlPoints.Length]; List<int>[] vertexTriangle = new List<int>[bezier.OutputPoints.Length]; Parallel.For(0, vertexTriangle.Length, index => vertexTriangle[index] = new List<int>()); /*for(int i = 0; i < vertexTriangle.Length; ++i) { vertexTriangle[i] = new List<int>(); }*/ int[] indices = new int[3 * bezier.triangles.Count]; //int[] selIndices = new int[3 * scene.triangles.Count]; uint numIndices = 0; //uint numSelIndices = 0; //bool[] selPoints = new bool[scene.points.Count]; //Parallel.For(0, selPoints.Length, index => selPoints[index] = false); for (int i = 0; i < bezier.triangles.Count; i++) { indices[numIndices++] = (int)bezier.triangles[i].p1; indices[numIndices++] = (int)bezier.triangles[i].p2; indices[numIndices++] = (int)bezier.triangles[i].p3; vertexTriangle[bezier.triangles[i].p1].Add(i); vertexTriangle[bezier.triangles[i].p2].Add(i); vertexTriangle[bezier.triangles[i].p3].Add(i); } // Liczenie normalnych siatki trojkątów for (int i = 0; i < bezier.OutputPoints.Length; i++) { Vector3 normal = new Vector3(); foreach (int face in vertexTriangle[i]) { normal += Utilities.CalculateNormal(bezier.OutputPoints[(int)bezier.triangles[face].p3], bezier.OutputPoints[(int)bezier.triangles[face].p2], bezier.OutputPoints[(int)bezier.triangles[face].p1]); } normal.Normalize(); gridVertices[i].Position = new Vector3(bezier.OutputPoints[i].x, bezier.OutputPoints[i].y, bezier.OutputPoints[i].z); gridVertices[i].Normal = normal; gridVertices[i].Color = Color.Beige.ToArgb(); } Mesh gridMesh = numIndices > 2 ? new Mesh(deviceBezier, (int)numIndices / 3, bezier.OutputPoints.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems): null; VertexBuffer vb = gridMesh != null ? gridMesh.VertexBuffer : null; IndexBuffer ib = gridMesh != null ? gridMesh.IndexBuffer : null; if (gridMesh != null) { vb.Lock(0, 0, LockFlags.None).WriteRange(gridVertices); vb.Unlock(); ib.Lock(0, 0, LockFlags.None).WriteRange(indices, 0, (int)numIndices); ib.Unlock(); } Mesh controlPointsMesh = Mesh.CreateSphere(deviceBezier, 0.05f, 12, 12); if (perspective.Width > 0 && perspective.Height > 0) { deviceBezier.Viewport = perspective; float aspect = (float)perspective.Width / perspective.Height; deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH( bezierCam.position, bezierCam.lookAt, Utilities.RotatePointAroundVector(new Vector3(0, 1, 0), Vector3.Normalize(bezierCam.lookAt - bezierCam.position), bezierCam.rotateAngle))); deviceBezier.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH( bezierCam.fovAngle, aspect, 0.01f, 110000)); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); deviceBezier.BeginScene(); if (gridMesh != null) { gridMesh.DrawSubset(0); deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid); for (int i = 0; i < bezier.ControlPoints.Length; i++) { deviceBezier.SetTransform(TransformState.World, Matrix.Translation( bezier.ControlPoints[i].x, bezier.ControlPoints[i].y, bezier.ControlPoints[i].z)); if (i == bezier.selectedPointIdx) { deviceBezier.Material = selectedControlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, false); controlPointsMesh.DrawSubset(0); deviceBezier.Material = controlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, true); } else { controlPointsMesh.DrawSubset(0); } } deviceBezier.SetTransform(TransformState.World, Matrix.Identity); deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } deviceBezier.EndScene(); } if (top.Width > 0 && top.Height > 0) { deviceBezier.Viewport = top; deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH( bezierOrthoPos[2], bezierOrthoLookAt[2], new Vector3(0, 1, 0))); deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH( bezierOrthoWidth[2], (float)(top.Height) / top.Width * bezierOrthoWidth[2], 0.01f, 110000)); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); deviceBezier.BeginScene(); string text1 = " -z\n/|\\\n |\n"; font2.DrawString(null, text1, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Blue); string text2 = "\n\n\n -----> x"; font2.DrawString(null, text2, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Red); if (gridMesh != null) { gridMesh.DrawSubset(0); deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid); for (int i = 0; i < bezier.ControlPoints.Length; i++) { deviceBezier.SetTransform(TransformState.World, Matrix.Translation( bezier.ControlPoints[i].x, bezier.ControlPoints[i].y, bezier.ControlPoints[i].z)); if (i == bezier.selectedPointIdx) { deviceBezier.Material = selectedControlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, false); controlPointsMesh.DrawSubset(0); deviceBezier.Material = controlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, true); } else { controlPointsMesh.DrawSubset(0); } } deviceBezier.SetTransform(TransformState.World, Matrix.Identity); deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } deviceBezier.EndScene(); } if (front.Width > 0 && front.Height > 0) { deviceBezier.Viewport = front; deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH( bezierOrthoPos[0], bezierOrthoLookAt[0], new Vector3(0, 1, 0))); deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH( bezierOrthoWidth[0], (float)(front.Height) / front.Width * bezierOrthoWidth[0], 0.01f, 110000)); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); deviceBezier.BeginScene(); string text1 = " y\n/|\\\n |\n"; font2.DrawString(null, text1, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Green); string text2 = "\n\n\n -----> x"; font2.DrawString(null, text2, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Red); if (gridMesh != null) { gridMesh.DrawSubset(0); deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid); for (int i = 0; i < bezier.ControlPoints.Length; i++) { deviceBezier.SetTransform(TransformState.World, Matrix.Translation( bezier.ControlPoints[i].x, bezier.ControlPoints[i].y, bezier.ControlPoints[i].z)); if (i == bezier.selectedPointIdx) { deviceBezier.Material = selectedControlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, false); controlPointsMesh.DrawSubset(0); deviceBezier.Material = controlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, true); } else { controlPointsMesh.DrawSubset(0); } } deviceBezier.SetTransform(TransformState.World, Matrix.Identity); deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } deviceBezier.EndScene(); } if (side.Width > 0 && side.Height > 0) { deviceBezier.Viewport = side; deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH( bezierOrthoPos[1], bezierOrthoLookAt[1], new Vector3(0, 1, 0))); deviceBezier.SetTransform(TransformState.Projection, Matrix.OrthoRH( bezierOrthoWidth[1], (float)(side.Height) / side.Width * bezierOrthoWidth[1], 0.01f, 110000)); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); deviceBezier.BeginScene(); string text1 = " y\n/|\\\n |\n"; font2.DrawString(null, text1, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Green); string text2 = "\n\n\n -----> -z"; font2.DrawString(null, text2, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Blue); if (gridMesh != null) { gridMesh.DrawSubset(0); deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid); for (int i = 0; i < bezier.ControlPoints.Length; i++) { deviceBezier.SetTransform(TransformState.World, Matrix.Translation( bezier.ControlPoints[i].x, bezier.ControlPoints[i].y, bezier.ControlPoints[i].z)); if (i == bezier.selectedPointIdx) { deviceBezier.Material = selectedControlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, false); controlPointsMesh.DrawSubset(0); deviceBezier.Material = controlPointMaterial; deviceBezier.SetRenderState(RenderState.Lighting, true); } else { controlPointsMesh.DrawSubset(0); } } deviceBezier.SetTransform(TransformState.World, Matrix.Identity); deviceBezier.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } deviceBezier.EndScene(); } deviceBezier.Present(); gridMesh.Dispose(); controlPointsMesh.Dispose(); //d3dBezier.Dispose(); //deviceBezier.Dispose(); }
public Renderer(IntPtr handle, IntPtr handleBezier) { this.handle = handle; this.handleBezier = handleBezier; currScene = null; font = null; font2 = null; cameras = new List<RenderCamera>(); lights = new List<RenderLight>(); orthoWidth = new float[] { 10, 10, 10 }; orthoPos = new Vector3[] { new Vector3(0, 0, 50001), new Vector3(50001, 0, 0), new Vector3(0, 50001, 0) }; orthoLookAt = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, -0.01f) }; ortoWidhtChange = false; bezierOrthoWidth = new float[] { 5, 5, 5 }; bezierOrthoPos = new Vector3[] { new Vector3(0, 0, 50000), new Vector3(50000, 0, 0), new Vector3(0, 50000, 0) }; bezierOrthoLookAt = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, -0.01f) }; bezierCam = new Camera(null, 0, 0, new Vector3(-10, 10, -10), new Vector3(0, 0, 0), Utilities.DegToRad(15), 0); selectedControlPointMaterial = new Material() { Diffuse = new Color4(Color.Red) }; controlPointMaterial = new Material() { Diffuse = new Color4(Color.Black) }; camsLookAtPoints = new List<Vector3>(); clipping = false; clipVertices = new Vertex[48]; for(int i = 0; i < clipVertices.Length; ++i) { clipVertices[i] = new Vertex(); clipVertices[i].Color = Color.DarkViolet.ToArgb(); } for(int i = 0; i < 8; ++i) { clipVertices[i + 0].Position = new Vector3(i == 0 || i == 3 || i == 4 || i == 7 ? -50000 : 50000, i == 0 || i == 1 || i == 2 || i == 3 ? 2 : 2 + clipPlaneWidth * orthoWidth[0], i == 0 || i == 1 || i == 4 || i == 5 ? 50000 : -50000); } for(int i = 0; i < 8; ++i) { clipVertices[i + 8].Position = new Vector3(i == 0 || i == 3 || i == 4 || i == 7 ? 50000 : -50000, i == 0 || i == 1 || i == 2 || i == 3 ? -2 : -2 - clipPlaneWidth * orthoWidth[0], i == 0 || i == 1 || i == 4 || i == 5 ? 50000 : -50000); } for(int i = 0; i < 8; ++i) { clipVertices[i + 16].Position = new Vector3(i == 0 || i == 1 || i == 2 || i == 3 ? 2 : 2 + clipPlaneWidth * orthoWidth[0], i == 0 || i == 3 || i == 4 || i == 7 ? 50000 : -50000, i == 0 || i == 1 || i == 4 || i == 5 ? 50000 : -50000); } for(int i = 0; i < 8; ++i) { clipVertices[i + 24].Position = new Vector3(i == 0 || i == 1 || i == 2 || i == 3 ? -2 : -2 - clipPlaneWidth * orthoWidth[0], i == 0 || i == 3 || i == 4 || i == 7 ? -50000 : 50000, i == 0 || i == 1 || i == 4 || i == 5 ? 50000 : -50000); } for(int i = 0; i < 8; ++i) { clipVertices[i + 32].Position = new Vector3(i == 0 || i == 3 || i == 4 || i == 7 ? -50000 : 50000, i == 0 || i == 1 || i == 4 || i == 5 ? -50000 : 50000, i == 0 || i == 1 || i == 2 || i == 3 ? -2 : -2 - clipPlaneWidth * orthoWidth[0]); } for(int i = 0; i < 8; ++i) { clipVertices[i + 40].Position = new Vector3(i == 0 || i == 3 || i == 4 || i == 7 ? 50000 : -50000, i == 0 || i == 1 || i == 4 || i == 5 ? -50000 : 50000, i == 0 || i == 1 || i == 2 || i == 3 ? 2 : 2 + clipPlaneWidth * orthoWidth[0]); } clipIndices = new int[216]; for(int i = 0; i < 6; ++i) { clipIndices[36 * i + 0] = 8 * i + 0; clipIndices[36 * i + 1] = 8 * i + 1; clipIndices[36 * i + 2] = 8 * i + 5; clipIndices[36 * i + 3] = 8 * i + 0; clipIndices[36 * i + 4] = 8 * i + 5; clipIndices[36 * i + 5] = 8 * i + 4; clipIndices[36 * i + 6] = 8 * i + 1; clipIndices[36 * i + 7] = 8 * i + 2; clipIndices[36 * i + 8] = 8 * i + 6; clipIndices[36 * i + 9] = 8 * i + 1; clipIndices[36 * i + 10] = 8 * i + 6; clipIndices[36 * i + 11] = 8 * i + 5; clipIndices[36 * i + 12] = 8 * i + 2; clipIndices[36 * i + 13] = 8 * i + 3; clipIndices[36 * i + 14] = 8 * i + 7; clipIndices[36 * i + 15] = 8 * i + 2; clipIndices[36 * i + 16] = 8 * i + 7; clipIndices[36 * i + 17] = 8 * i + 6; clipIndices[36 * i + 18] = 8 * i + 3; clipIndices[36 * i + 19] = 8 * i + 0; clipIndices[36 * i + 20] = 8 * i + 5; clipIndices[36 * i + 21] = 8 * i + 3; clipIndices[36 * i + 22] = 8 * i + 5; clipIndices[36 * i + 23] = 8 * i + 7; clipIndices[36 * i + 24] = 8 * i + 0; clipIndices[36 * i + 25] = 8 * i + 1; clipIndices[36 * i + 26] = 8 * i + 2; clipIndices[36 * i + 27] = 8 * i + 0; clipIndices[36 * i + 28] = 8 * i + 2; clipIndices[36 * i + 29] = 8 * i + 3; clipIndices[36 * i + 30] = 8 * i + 4; clipIndices[36 * i + 31] = 8 * i + 5; clipIndices[36 * i + 32] = 8 * i + 6; clipIndices[36 * i + 33] = 8 * i + 4; clipIndices[36 * i + 34] = 8 * i + 6; clipIndices[36 * i + 35] = 8 * i + 7; } perspective = new Viewport(); perspective.X = 0; perspective.Y = 0; perspective.Width = 1; perspective.Height = 1; perspective.MinZ = -1000; perspective.MaxZ = 1000; top = new Viewport(); top.X = 0; top.Y = 0; top.Width = 1; top.Height = 1; top.MinZ = -1000; top.MaxZ = 1000; front = new Viewport(); front.X = 0; front.Y = 0; front.Width = 1; front.Height = 1; front.MinZ = -1000; front.MaxZ = 1000; side = new Viewport(); side.X = 0; side.Y = 0; side.Width = 1; side.Height = 1; side.MinZ = -1000; side.MaxZ = 1000; defLight = new Light(); defLight.Type = LightType.Directional; defLight.Diffuse = Color.White; defLight.Direction = new Vector3(1, -1, -2); maxLights = 0; vertexElems = new[] { new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0), new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0), new VertexElement(0, 24, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0), new VertexElement(0, 28, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0), VertexElement.VertexDeclarationEnd }; wireframe = true; pp = new PresentParameters(); pp.SwapEffect = SwapEffect.Discard; pp.Windowed = true; pp.BackBufferFormat = Format.A8R8G8B8; bezierPp = new PresentParameters(); bezierPp.SwapEffect = SwapEffect.Discard; bezierPp.Windowed = true; bezierPp.BackBufferFormat = Format.A8R8G8B8; }
public Image GetBezierImage(BezierSurface bezier) { pp = new PresentParameters(); pp.SwapEffect = SwapEffect.Discard; pp.Windowed = true; pp.BackBufferWidth = 512; pp.BackBufferHeight = 512; pp.BackBufferFormat = Format.A8R8G8B8; if (d3dBezier != null) { d3dBezier.Dispose(); } if (deviceBezier != null) { deviceBezier.Dispose(); } d3dBezier = new Direct3D(); deviceBezier = new Device(d3d, 0, DeviceType.Hardware, handle, CreateFlags.HardwareVertexProcessing, pp); deviceBezier.SetRenderState(RenderState.Lighting, true); deviceBezier.SetLight(0, defLight); deviceBezier.EnableLight(0, true); deviceBezier.SetRenderState(RenderState.FillMode, FillMode.Solid); deviceBezier.SetRenderState(RenderState.CullMode, Cull.None); deviceBezier.SetRenderState(RenderState.ShadeMode, ShadeMode.Gouraud); Vertex[] gridVertices = new Vertex[bezier.OutputPoints.Length]; Vertex[] controlVertices = new Vertex[bezier.ControlPoints.Length]; List<int>[] vertexTriangle = new List<int>[bezier.OutputPoints.Length]; Parallel.For(0, vertexTriangle.Length, index => vertexTriangle[index] = new List<int>()); /*for(int i = 0; i < vertexTriangle.Length; ++i) { vertexTriangle[i] = new List<int>(); }*/ int[] indices = new int[3 * bezier.triangles.Count]; //int[] selIndices = new int[3 * scene.triangles.Count]; uint numIndices = 0; //uint numSelIndices = 0; //bool[] selPoints = new bool[scene.points.Count]; //Parallel.For(0, selPoints.Length, index => selPoints[index] = false); for (int i = 0; i < bezier.triangles.Count; i++) { indices[numIndices++] = (int)bezier.triangles[i].p1; indices[numIndices++] = (int)bezier.triangles[i].p2; indices[numIndices++] = (int)bezier.triangles[i].p3; vertexTriangle[bezier.triangles[i].p1].Add(i); vertexTriangle[bezier.triangles[i].p2].Add(i); vertexTriangle[bezier.triangles[i].p3].Add(i); } // Liczenie normalnych siatki trojkątów for (int i = 0; i < bezier.OutputPoints.Length; i++) { Vector3 normal = new Vector3(); foreach (int face in vertexTriangle[i]) { normal += Utilities.CalculateNormal(bezier.OutputPoints[(int)bezier.triangles[face].p3], bezier.OutputPoints[(int)bezier.triangles[face].p2], bezier.OutputPoints[(int)bezier.triangles[face].p1]); } normal.Normalize(); gridVertices[i].Position = new Vector3(bezier.OutputPoints[i].x, bezier.OutputPoints[i].y, bezier.OutputPoints[i].z); gridVertices[i].Normal = normal; gridVertices[i].Color = Color.Beige.ToArgb(); } Mesh gridMesh = numIndices > 2 ? new Mesh(deviceBezier, (int)numIndices / 3, bezier.OutputPoints.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems) : null; VertexBuffer vb = gridMesh != null ? gridMesh.VertexBuffer : null; IndexBuffer ib = gridMesh != null ? gridMesh.IndexBuffer : null; if (gridMesh != null) { vb.Lock(0, 0, LockFlags.None).WriteRange(gridVertices); vb.Unlock(); ib.Lock(0, 0, LockFlags.None).WriteRange(indices, 0, (int)numIndices); ib.Unlock(); } Viewport viewport = new Viewport(0, 0, 512, 512, 0, 1); Texture texture = new Texture(deviceBezier, 64, 64, 0, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default); deviceBezier.SetRenderTarget(0, texture.GetSurfaceLevel(0)); float aspect = (float)perspective.Width / perspective.Height; deviceBezier.SetTransform(TransformState.View, Matrix.LookAtRH( bezierCam.position, bezierCam.lookAt, Utilities.RotatePointAroundVector(new Vector3(0, 1, 0), Vector3.Normalize(bezierCam.lookAt - bezierCam.position), bezierCam.rotateAngle))); deviceBezier.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH( bezierCam.fovAngle, aspect, 0.01f, 110000)); deviceBezier.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.White, 1.0f, 0); deviceBezier.BeginScene(); if (gridMesh != null) { gridMesh.DrawSubset(0); } deviceBezier.EndScene(); Image image = Bitmap.FromStream(Texture.ToStream(texture, ImageFileFormat.Png)); texture.Dispose(); bezierImageCreated = true; return image; }
public void RenderViews(ViewportInfo viewportInfo, Scene scene) { currScene = scene; #if MEASURE_TIMES DateTime ts = DateTime.Now; DateTime t1 = DateTime.Now; #endif if (pp.BackBufferWidth != viewportInfo.resX || pp.BackBufferHeight != viewportInfo.resY) { pp = new PresentParameters(); pp.SwapEffect = SwapEffect.Discard; pp.Windowed = true; pp.BackBufferWidth = viewportInfo.resX; pp.BackBufferHeight = viewportInfo.resY; pp.BackBufferFormat = Format.A8R8G8B8; if (d3d != null) { d3d.Dispose(); } if (device != null) { device.Dispose(); } d3d = new Direct3D(); device = new Device(d3d, 0, DeviceType.Hardware, handle, CreateFlags.HardwareVertexProcessing, pp); if(font != null) { font.Dispose(); } font = new SlimDX.Direct3D9.Font(device, new System.Drawing.Font(FontFamily.GenericSansSerif, 7)); } bool viewportChange = false; if(top.X != viewportInfo.posX[2] || top.Y != viewportInfo.posY[2] || top.Width != viewportInfo.sizeX[2] || top.Height != viewportInfo.sizeY[2]) { top = new Viewport(); top.X = viewportInfo.posX[2]; top.Y = viewportInfo.posY[2]; top.Width = viewportInfo.sizeX[2]; top.Height = viewportInfo.sizeY[2]; top.MinZ = 0; top.MaxZ = 1; viewportChange = true; } if(front.X != viewportInfo.posX[0] || front.Y != viewportInfo.posY[0] || front.Width != viewportInfo.sizeX[0] || front.Height != viewportInfo.sizeY[0]) { front = new Viewport(); front.X = viewportInfo.posX[0]; front.Y = viewportInfo.posY[0]; front.Width = viewportInfo.sizeX[0]; front.Height = viewportInfo.sizeY[0]; front.MinZ = 0; front.MaxZ = 1; viewportChange = true; } if(side.X != viewportInfo.posX[1] || side.Y != viewportInfo.posY[1] || side.Width != viewportInfo.sizeX[1] || side.Height != viewportInfo.sizeY[1]) { side = new Viewport(); side.X = viewportInfo.posX[1]; side.Y = viewportInfo.posY[1]; side.Width = viewportInfo.sizeX[1]; side.Height = viewportInfo.sizeY[1]; side.MinZ = 0; side.MaxZ = 1; viewportChange = true; } if(perspective.X != viewportInfo.posX[3] || perspective.Y != viewportInfo.posY[3] || perspective.Width != viewportInfo.sizeX[3] || perspective.Height != viewportInfo.sizeY[3]) { perspective = new Viewport(); perspective.X = viewportInfo.posX[3]; perspective.Y = viewportInfo.posY[3]; perspective.Width = viewportInfo.sizeX[3]; perspective.Height = viewportInfo.sizeY[3]; perspective.MinZ = 0; perspective.MaxZ = 1; viewportChange = true; } if(perspective.Width > 0 && perspective.Height > 0) { persPos = new System.Drawing.Point(perspective.Width, perspective.Height); } #if MEASURE_TIMES DateTime t2 = DateTime.Now; TimeSpan t = t2 - t1; w.WriteLine("Tworzenie device'a " + t.Milliseconds); #endif //selectionTex = Texture.FromFile(device, "..\\..\\selectionTex.png"); #if MEASURE_TIMES t1 = DateTime.Now; #endif device.SetRenderState(RenderState.Lighting, true); for(int i = scene.lights.Count; i < maxLights; ++i) { device.EnableLight(i, false); } maxLights = scene.lights.Count; int l = 0; foreach (Light_ light_ in scene.lights) { Light light = new Light(); light.Diffuse = new Color4(light_.colorR, light_.colorG, light_.colorB); light.Position = light_.position; light.Range = 100000; light.Attenuation1 = 2.0f / light_.power; if(light_.type == Light_Type.Point || light_.type == Light_Type.Goniometric) { light.Type = LightType.Point; } else { light.Type = LightType.Spot; } if(light_.type == Light_Type.Spot) { light.Direction = light_.direction; light.Theta = Utilities.DegToRad(light_.innerAngle); light.Phi = Utilities.DegToRad(light_.outerAngle); light.Falloff = 1; } device.SetLight(l, light); device.EnableLight(l, true); ++l; } #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Tworzenie świateł " + t.Milliseconds); t1 = DateTime.Now; #endif device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); device.SetRenderState(RenderState.CullMode, Cull.None); device.SetRenderState(RenderState.ShadeMode, ShadeMode.Gouraud); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("SetRenderState " + t.Milliseconds); t1 = DateTime.Now; #endif for(int i = 0; i < scene.points.Count; ++i) { if(selPoints[i] == true || scene.normals.Count <= i) { Vector3D normal = new Vector3D(); foreach(int face in vertexTriangle[i]) { normal += Utilities.CalculateNormal(scene.points[(int)scene.triangles[face].p3], scene.points[(int)scene.triangles[face].p2], scene.points[(int)scene.triangles[face].p1]); } normal.Normalize(); if(scene.normals.Count <= i) { scene.normals.Add(normal); } else { scene.normals[i] = normal; } Vector3D point = scene.points[i]; vertices[i].Position = new Vector3(point.x, point.y, point.z); vertices[i].Normal = new Vector3(scene.normals[i].x, scene.normals[i].y, scene.normals[i].z); } } #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Liczenie normalnych " + t.Milliseconds); t1 = DateTime.Now; #endif Mesh mesh = numIndices >= 3 ? new Mesh(device, (int)numIndices / 3, scene.points.Count, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems) : null; VertexBuffer vb = mesh != null ? mesh.VertexBuffer : null; IndexBuffer ib = mesh != null ? mesh.IndexBuffer : null; #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Tworzenie mesh1 " + t.Milliseconds); t1 = DateTime.Now; #endif if (mesh != null) { vb.Lock(0, 0, LockFlags.None).WriteRange(vertices); vb.Unlock(); ib.Lock(0, 0, LockFlags.None).WriteRange(indices, 0, (int)numIndices); ib.Unlock(); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Kopiowanie buforów mesh1 " + t.Milliseconds); #endif } #if MEASURE_TIMES t1 = DateTime.Now; #endif Mesh selMesh = numSelIndices >= 3 ? new Mesh(device, (int)numSelIndices / 3, scene.points.Count, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems) : null; VertexBuffer selvb = selMesh != null ? selMesh.VertexBuffer : null; IndexBuffer selib = selMesh != null ? selMesh.IndexBuffer : null; #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Tworzenie mesh2 " + t.Milliseconds); t1 = DateTime.Now; #endif if (selMesh != null) { selvb.Lock(0, 0, LockFlags.None).WriteRange(vertices); selvb.Unlock(); selib.Lock(0, 0, LockFlags.None).WriteRange(selIndices, 0, (int)numSelIndices); selib.Unlock(); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Kopiowanie buforów mesh2 " + t.Milliseconds); #endif } while(cameras.Count < scene.cams.Count) { cameras.Add(new RenderCamera()); } while(cameras.Count > scene.cams.Count) { cameras.RemoveAt(cameras.Count - 1); } while(camsLookAtPoints.Count < scene.cams.Count) { camsLookAtPoints.Add(new Vector3()); } while(camsLookAtPoints.Count > scene.cams.Count) { camsLookAtPoints.RemoveAt(camsLookAtPoints.Count - 1); } for(int i = 0; i < cameras.Count; ++i) { if(cameras[i].set == false || viewportChange || cameras[i].position != scene.cams[i].position || cameras[i].lookAt != scene.cams[i].lookAt || cameras[i].fovAngle != scene.cams[i].fovAngle || cameras[i].rotateAngle != scene.cams[i].rotateAngle) { if(cameras[i].set == false) { cameras[i].set = true; } cameras[i].position = scene.cams[i].position; cameras[i].lookAt = scene.cams[i].lookAt; cameras[i].fovAngle = scene.cams[i].fovAngle; cameras[i].rotateAngle = scene.cams[i].rotateAngle; Vector3 upLeft, upRight, loLeft, loRight; SelectingElems.GetViewCorners(cameras[i].position, cameras[i].lookAt, cameras[i].fovAngle, cameras[i].rotateAngle, persPos, out upLeft, out upRight, out loLeft, out loRight); const float camViewLength = 2.0f; Vector3 ld = loLeft - cameras[i].position; ld.Normalize(); Vector3 lu = upLeft - cameras[i].position; lu.Normalize(); Vector3 rd = loRight - cameras[i].position; rd.Normalize(); Vector3 ru = upRight - cameras[i].position; ru.Normalize(); cameras[i].points[0] = cameras[i].position; /*cameras[i].points[1] = cameras[i].position + ((0.5f + (cameras[i].fovAngle / 180)) * camViewLength) * ld; cameras[i].points[2] = cameras[i].position + ((0.5f + (cameras[i].fovAngle / 180)) * camViewLength) * lu; cameras[i].points[3] = cameras[i].position + ((0.5f + (cameras[i].fovAngle / 180)) * camViewLength) * ru; cameras[i].points[4] = cameras[i].position + ((0.5f + (cameras[i].fovAngle / 180)) * camViewLength) * rd;*/ cameras[i].points[1] = loLeft; cameras[i].points[2] = upLeft; cameras[i].points[3] = upRight; cameras[i].points[4] = loRight; Vector3 up = cameras[i].points[2] - cameras[i].points[1]; up.Normalize(); Vector3 left = cameras[i].points[2] - cameras[i].points[3]; left.Normalize(); Vector3 right = -left; float dist = (float)Math.Sqrt((cameras[i].points[2].X - cameras[i].points[3].X) * (cameras[i].points[2].X - cameras[i].points[3].X) + (cameras[i].points[2].Y - cameras[i].points[3].Y) * (cameras[i].points[2].Y - cameras[i].points[3].Y) + (cameras[i].points[2].Z - cameras[i].points[3].Z) * (cameras[i].points[2].Z - cameras[i].points[3].Z)); dist *= 0.8f; float upTriangleFactor = cameras[i].fovAngle / 60; cameras[i].points[5] = (cameras[i].points[2] + cameras[i].points[3]) / 2 + left * upTriangleFactor * 0.3f * dist; cameras[i].points[6] = (cameras[i].points[2] + cameras[i].points[3]) / 2 + up * upTriangleFactor * 0.25f * dist; cameras[i].points[7] = (cameras[i].points[2] + cameras[i].points[3]) / 2 + right * upTriangleFactor * 0.3f * dist; camsLookAtPoints[i] = (cameras[i].points[1] + cameras[i].points[2] + cameras[i].points[3] + cameras[i].points[4]) / 4; } } Vertex[] camVertices = new Vertex[cameras.Count * 8]; int[] camIndices = new int[3 * cameras.Count * RenderCamera.triangles.Length]; for(int i = 0; i < cameras.Count; ++i) { for(int j = 0; j < RenderCamera.triangles.Length; ++j) { camIndices[i * 3 * RenderCamera.triangles.Length + 3 * j + 0] = i * cameras[i].points.Length + (int)RenderCamera.triangles[j].p1; camIndices[i * 3 * RenderCamera.triangles.Length + 3 * j + 1] = i * cameras[i].points.Length + (int)RenderCamera.triangles[j].p2; camIndices[i * 3 * RenderCamera.triangles.Length + 3 * j + 2] = i * cameras[i].points.Length + (int)RenderCamera.triangles[j].p3; } } bool[] selCameras = new bool[cameras.Count]; for(int i = 0; i < selCameras.Length; ++i) { selCameras[i] = false; } for(int i = 0; i < scene.selCams.Count; ++i) { selCameras[scene.selCams[i]] = true; } for(int i = 0; i < cameras.Count; ++i) { for(int j = 0; j < cameras[i].points.Length; ++j) { camVertices[i * 8 + j].Position = cameras[i].points[j]; camVertices[i * 8 + j].Normal = new Vector3(); if(selCameras[i] == false) { if(scene.activeCamera == i) { camVertices[i * 8 + j].Color = Color.FromArgb(249, 203, 44).ToArgb(); } else { camVertices[i * 8 + j].Color = Color.FromArgb(193, 227, 195).ToArgb(); } } else { if(scene.activeCamera == i) { camVertices[i * 8 + j].Color = Color.FromArgb(243, 106, 24).ToArgb(); } else { camVertices[i * 8 + j].Color = Color.FromArgb(255, 255, 150).ToArgb(); } } camVertices[i * 8 + j].tex0 = 0; camVertices[i * 8 + j].tex1 = 0; } } Mesh camMesh = cameras.Count > 0 ? new Mesh(device, (int)camIndices.Length / 3, camVertices.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems) : null; VertexBuffer camVB = camMesh != null ? camMesh.VertexBuffer : null; IndexBuffer camIB = camMesh != null ? camMesh.IndexBuffer : null; if(camMesh != null) { camVB.Lock(0, 0, LockFlags.None).WriteRange(camVertices); camVB.Unlock(); camIB.Lock(0, 0, LockFlags.None).WriteRange(camIndices); camIB.Unlock(); } while(lights.Count < scene.lights.Count) { lights.Add(new RenderLight()); } while(lights.Count > scene.lights.Count) { lights.RemoveAt(lights.Count - 1); } for(int i = 0; i < lights.Count; ++i) { if(ortoWidhtChange == true || lights[i].set == false || lights[i].position != scene.lights[i].position || lights[i].direction != scene.lights[i].direction || lights[i].type != scene.lights[i].type || lights[i].innerAngle != scene.lights[i].innerAngle || lights[i].outerAngle != scene.lights[i].outerAngle) { if(lights[i].set == false) { lights[i].set = true; } lights[i].position = scene.lights[i].position; lights[i].direction = scene.lights[i].direction; lights[i].type = scene.lights[i].type; lights[i].innerAngle = scene.lights[i].innerAngle; lights[i].outerAngle = scene.lights[i].outerAngle; for(int j = 0; j < RenderLight.pointsDef.Length; ++j) { lights[i].points[j] = RenderLight.pointsDef[j]; } for(int j = RenderLight.pointsDef.Length; j < RenderLight.pointsSpotNum; ++j) { lights[i].points[j] = new Vector3(); } if(lights[i].type == Light_Type.Spot || lights[i].type == Light_Type.Goniometric) { Vector3 dir = lights[i].direction; dir.Normalize(); if(dir.Z == 0) { dir.Z = 0.0001f; } Vector3 Vs = new Vector3(1, 1, -(dir.X + dir.Y) / dir.Z); Vector3 V1 = Vector3.Normalize(Vs); Vector3 V2 = Vector3.Cross(dir, V1); Vector2[,] circle = new Vector2[2, 20]; float r1 = spotLightDist * (float)Math.Tan(Utilities.DegToRad(lights[i].innerAngle / 2)); float r2 = spotLightDist * (float)Math.Tan(Utilities.DegToRad(lights[i].outerAngle / 2)); for(int j = 0; j < 2; ++j) { for(int k = 0; k < 20; ++k) { circle[j, k] = new Vector2((j == 0 ? r1 : r2) * (float)Math.Sin(Utilities.DegToRad(18 * k)), (j == 0 ? r1 : r2) * (float)Math.Cos(Utilities.DegToRad(18 * k))); } } Vector3[,] circle3D = new Vector3[2, 20]; for(int j = 0; j < 2; ++j) { for(int k = 0; k < 20; ++k) { float X = V1.X * circle[j, k].X + V2.X * circle[j, k].Y; float Y = V1.Y * circle[j, k].X + V2.Y * circle[j, k].Y; float Z = V1.Z * circle[j, k].X + V2.Z * circle[j, k].Y; Vector3 radius = spotLightDist * dir; circle3D[j, k] = new Vector3(X, Y, Z) + radius; } } for(int j = 0; j < 20; ++j) { lights[i].points[RenderLight.pointsPointNum + 2 * j] = new Vector3(circle3D[0, j].X, circle3D[0, j].Y, circle3D[0, j].Z); lights[i].points[RenderLight.pointsPointNum + 2 * j + 1] = new Vector3(circle3D[0, j].X + 0.000001f, circle3D[0, j].Y, circle3D[0, j].Z); lights[i].points[RenderLight.pointsPointNum + 40 + 2 * j] = new Vector3(circle3D[1, j].X, circle3D[1, j].Y, circle3D[1, j].Z); lights[i].points[RenderLight.pointsPointNum + 40 + 2 * j + 1] = new Vector3(circle3D[1, j].X + 0.000001f, circle3D[1, j].Y, circle3D[1, j].Z); } lights[i].points[120] = new Vector3(0, 0, 0); lights[i].points[121] = new Vector3(0.000001f, 0, 0); } for(int j = 0; j < lights[i].points.Length; ++j) { lights[i].points[j] *= OrthoWidth[0] / 10; lights[i].points[j] += lights[i].position; } } } ortoWidhtChange = false; Vertex[] lightsVertices = new Vertex[lights.Count * RenderLight.pointsSpotNum]; int[] lightsIndices = new int[3 * lights.Count * RenderLight.triangles.Length]; int trIndex = 0; for(int i = 0; i < lights.Count; ++i) { int trNum = lights[i].type == Light_Type.Point ? RenderLight.trianglesPointNum : RenderLight.trianglesSpotNum; for(int j = 0; j < trNum; ++j) { lightsIndices[trIndex++] = i * lights[i].points.Length + (int)RenderLight.triangles[j].p1; lightsIndices[trIndex++] = i * lights[i].points.Length + (int)RenderLight.triangles[j].p2; lightsIndices[trIndex++] = i * lights[i].points.Length + (int)RenderLight.triangles[j].p3; } } bool[] selLights = new bool[lights.Count]; for(int i = 0; i < selLights.Length; ++i) { selLights[i] = false; } for(int i = 0; i < scene.selLights.Count; ++i) { selLights[scene.selLights[i]] = true; } for(int i = 0; i < lights.Count; ++i) { for(int j = 0; j < lights[i].points.Length; ++j) { lightsVertices[i * RenderLight.pointsSpotNum + j].Position = lights[i].points[j]; lightsVertices[i * RenderLight.pointsSpotNum + j].Normal = new Vector3(); if(selLights[i] == false) { if(scene.lights[i].enabled == true) { if(scene.lights[i].type != Light_Type.Goniometric) { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(234, 203, 28).ToArgb(); } else { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(123, 120, 46).ToArgb(); } } else { if(scene.lights[i].type != Light_Type.Goniometric) { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(48, 46, 54).ToArgb(); } else { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(67, 78, 63).ToArgb(); } } } else { if(scene.lights[i].enabled == true) { if(scene.lights[i].type != Light_Type.Goniometric) { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(243, 106, 24).ToArgb(); } else { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(159, 210, 4).ToArgb(); } } else { if(scene.lights[i].type != Light_Type.Goniometric) { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(19, 24, 224).ToArgb(); } else { lightsVertices[i * RenderLight.pointsSpotNum + j].Color = Color.FromArgb(19, 224, 96).ToArgb(); } } } lightsVertices[i * RenderLight.pointsSpotNum + j].tex0 = 0; lightsVertices[i * RenderLight.pointsSpotNum + j].tex1 = 0; } } Mesh lightsMesh = lights.Count > 0 ? new Mesh(device, trIndex / 3, lightsVertices.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems) : null; VertexBuffer lightsVB = lightsMesh != null ? lightsMesh.VertexBuffer : null; IndexBuffer lightsIB = lightsMesh != null ? lightsMesh.IndexBuffer : null; if(lightsMesh != null) { lightsVB.Lock(0, 0, LockFlags.None).WriteRange(lightsVertices); lightsVB.Unlock(); lightsIB.Lock(0, 0, LockFlags.None).WriteRange(lightsIndices, 0, trIndex); lightsIB.Unlock(); } int coneLights = 0; foreach(Light_ light in scene.lights) { if(light.type == Light_Type.Spot || light.type == Light_Type.Goniometric) { ++coneLights; } } Mesh pointsMesh = Mesh.CreateBox(device, pointSize, pointSize, pointSize); Mesh clipMeshX = null; Mesh clipMeshY = null; Mesh clipMeshZ = null; VertexBuffer clipVBX = null; IndexBuffer clipIBX = null; VertexBuffer clipVBY = null; IndexBuffer clipIBY = null; VertexBuffer clipVBZ = null; IndexBuffer clipIBZ = null; if(clipping == true) { clipMeshX = new Mesh(device, clipIndices.Length / 9, clipVertices.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems); clipMeshY = new Mesh(device, clipIndices.Length / 9, clipVertices.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems); clipMeshZ = new Mesh(device, clipIndices.Length / 9, clipVertices.Length, MeshFlags.Managed | MeshFlags.Use32Bit, vertexElems); clipVBX = clipMeshX.VertexBuffer; clipIBX = clipMeshX.IndexBuffer; clipVBX.Lock(0, 0, LockFlags.None).WriteRange(clipVertices); clipVBX.Unlock(); clipIBX.Lock(0, 0, LockFlags.None).WriteRange(clipIndices, (clipIndices.Length / 6) * 2, (clipIndices.Length / 6) * 2); clipIBX.Unlock(); clipVBY = clipMeshY.VertexBuffer; clipIBY = clipMeshY.IndexBuffer; clipVBY.Lock(0, 0, LockFlags.None).WriteRange(clipVertices); clipVBY.Unlock(); clipIBY.Lock(0, 0, LockFlags.None).WriteRange(clipIndices, 0, (clipIndices.Length / 6) * 2); clipIBY.Unlock(); clipVBZ = clipMeshZ.VertexBuffer; clipIBZ = clipMeshZ.IndexBuffer; clipVBZ.Lock(0, 0, LockFlags.None).WriteRange(clipVertices); clipVBZ.Unlock(); clipIBZ.Lock(0, 0, LockFlags.None).WriteRange(clipIndices, (clipIndices.Length / 6) * 4, (clipIndices.Length / 6) * 2); clipIBZ.Unlock(); } #if MEASURE_TIMES t1 = DateTime.Now; #endif device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Modyfikacja viewport'ów " + t.Milliseconds); t1 = DateTime.Now; #endif if (perspective.Width > 0 && perspective.Height > 0) { device.Viewport = perspective; float camRotAngle = scene.cams.ElementAt(scene.activeCamera).rotateAngle; float aspect = (float)perspective.Width / perspective.Height; float angle = 2.0f * (float)Math.Atan(Math.Tan(Utilities.DegToRad(scene.cams.ElementAt(scene.activeCamera).fovAngle) / 2.0f) / aspect); device.SetTransform(TransformState.View, Matrix.LookAtRH( scene.cams[scene.activeCamera].position, scene.cams[scene.activeCamera].lookAt, Utilities.RotatePointAroundVector(new Vector3(0, 1, 0), Vector3.Normalize(scene.cams[scene.activeCamera].lookAt - scene.cams[scene.activeCamera].position), camRotAngle))); device.SetTransform(TransformState.Projection, Matrix.PerspectiveFovRH( angle, aspect, 0.01f, 110000)); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); device.BeginScene(); if (mesh != null) { mesh.DrawSubset(0); } //device.SetTexture(0, selectionTex); device.SetRenderState(RenderState.Lighting, false); if (selMesh != null) { selMesh.DrawSubset(0); } device.SetRenderState(RenderState.Lighting, true); //device.SetTexture(0, null); device.EndScene(); } SlimDX.Plane clipPlaneX = new SlimDX.Plane(); SlimDX.Plane clipPlaneX2 = new SlimDX.Plane(); SlimDX.Plane clipPlaneY = new SlimDX.Plane(); SlimDX.Plane clipPlaneY2 = new SlimDX.Plane(); SlimDX.Plane clipPlaneZ = new SlimDX.Plane(); SlimDX.Plane clipPlaneZ2 = new SlimDX.Plane(); SlimDX.Plane clipPlaneXPlus = new SlimDX.Plane(); SlimDX.Plane clipPlaneX2Minus = new SlimDX.Plane(); SlimDX.Plane clipPlaneYPlus = new SlimDX.Plane(); SlimDX.Plane clipPlaneY2Minus = new SlimDX.Plane(); SlimDX.Plane clipPlaneZPlus = new SlimDX.Plane(); SlimDX.Plane clipPlaneZ2Minus = new SlimDX.Plane(); clipPlaneYPlus = new SlimDX.Plane(new Vector3(0, 50000, 0), new Vector3(0, -1, 0)); clipPlaneY2Minus = new SlimDX.Plane(new Vector3(0, -50000, 0), new Vector3(0, 1, 0)); clipPlaneXPlus = new SlimDX.Plane(new Vector3(50000, 0, 0), new Vector3(-1, 0, 0)); clipPlaneX2Minus = new SlimDX.Plane(new Vector3(-50000, 0, 0), new Vector3(1, 0, 0)); clipPlaneZPlus = new SlimDX.Plane(new Vector3(0, 0, -50000), new Vector3(0, 0, 1)); clipPlaneZ2Minus = new SlimDX.Plane(new Vector3(0, 0, 50000), new Vector3(0, 0, -1)); if(clipping == true) { clipPlaneY = new SlimDX.Plane(new Vector3(0, clipVertices[0].Position.Y, 0), new Vector3(0, -1, 0)); clipPlaneY2 = new SlimDX.Plane(new Vector3(0, clipVertices[8].Position.Y, 0), new Vector3(0, 1, 0)); clipPlaneX = new SlimDX.Plane(new Vector3(clipVertices[16].Position.X, 0, 0), new Vector3(-1, 0, 0)); clipPlaneX2 = new SlimDX.Plane(new Vector3(clipVertices[24].Position.X, 0, 0), new Vector3(1, 0, 0)); clipPlaneZ = new SlimDX.Plane(new Vector3(0, 0, clipVertices[32].Position.Z), new Vector3(0, 0, 1)); clipPlaneZ2 = new SlimDX.Plane(new Vector3(0, 0, clipVertices[40].Position.Z), new Vector3(0, 0, -1)); device.SetRenderState(RenderState.ClipPlaneEnable, ClipFlags.Bottom | ClipFlags.Front | ClipFlags.Left | ClipFlags.Right | ClipFlags.Back | ClipFlags.Top); } if (top.Width > 0 && top.Height > 0) { device.Viewport = top; device.SetTransform(TransformState.View, Matrix.LookAtRH( orthoPos[2], orthoLookAt[2], new Vector3(0, 1, 0))); device.SetTransform(TransformState.Projection, Matrix.OrthoRH( orthoWidth[2], (float)(top.Height) / top.Width * orthoWidth[2], 0.01f, 110000)); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); device.BeginScene(); string text1 = " -z\n/|\\\n |\n"; font.DrawString(null, text1, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Blue); string text2 = "\n\n\n -----> x"; font.DrawString(null, text2, viewportInfo.posX[2] + 15, viewportInfo.posY[2], Color.Red); if(clipping == true) { device.SetRenderState(RenderState.Lighting, false); device.SetRenderState(RenderState.FillMode, FillMode.Solid); clipMeshX.DrawSubset(0); clipMeshZ.DrawSubset(0); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); device.SetRenderState(RenderState.Lighting, true); device.SetClipPlane(0, clipPlaneX); device.SetClipPlane(1, clipPlaneX2); device.SetClipPlane(2, clipPlaneY); device.SetClipPlane(3, clipPlaneY2); device.SetClipPlane(4, clipPlaneZ); device.SetClipPlane(5, clipPlaneZ2); } if (mesh != null) { mesh.DrawSubset(0); } //device.SetTexture(0, selectionTex); device.SetRenderState(RenderState.Lighting, false); if (selMesh != null) { selMesh.DrawSubset(0); } device.SetRenderState(RenderState.Lighting, true); //device.SetTexture(0, null); device.SetClipPlane(0, clipPlaneXPlus); device.SetClipPlane(1, clipPlaneX2Minus); device.SetClipPlane(2, clipPlaneYPlus); device.SetClipPlane(3, clipPlaneY2Minus); device.SetClipPlane(4, clipPlaneZPlus); device.SetClipPlane(5, clipPlaneZ2Minus); device.SetRenderState(RenderState.FillMode, FillMode.Solid); for(int i = 0; i < scene.lights.Count; ++i) { if(scene.lights[i].type == Light_Type.Spot || scene.lights[i].type == Light_Type.Goniometric) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[2] / 10, orthoWidth[0] / 10, orthoWidth[2] / 10) * Matrix.Translation(scene.lights[i].position + scene.lights[i].direction * spotLightDist * orthoWidth[1] / 10)); pointsMesh.DrawSubset(0); } } for(int i = 0; i < scene.cams.Count; ++i) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[2] / 10, orthoWidth[2] / 10, orthoWidth[2] / 10) * Matrix.Translation(scene.cams[i].position)); pointsMesh.DrawSubset(0); device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[2] / 10, orthoWidth[2] / 10, orthoWidth[2] / 10) * Matrix.Translation(camsLookAtPoints[i])); pointsMesh.DrawSubset(0); } device.SetTransform(TransformState.World, Matrix.Identity); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); if(camMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); camMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } if(lightsMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); lightsMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } device.EndScene(); } if (front.Width > 0 && front.Height > 0) { device.Viewport = front; device.SetTransform(TransformState.View, Matrix.LookAtRH( orthoPos[0], orthoLookAt[0], new Vector3(0, 1, 0))); device.SetTransform(TransformState.Projection, Matrix.OrthoRH( orthoWidth[0], (float)(front.Height) / front.Width * orthoWidth[0], 0.01f, 110000)); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); device.BeginScene(); string text1 = " y\n/|\\\n |\n"; font.DrawString(null, text1, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Green); string text2 = "\n\n\n -----> x"; font.DrawString(null, text2, viewportInfo.posX[0] + 15, viewportInfo.posY[0], Color.Red); if(clipping == true) { device.SetRenderState(RenderState.Lighting, false); device.SetRenderState(RenderState.FillMode, FillMode.Solid); clipMeshX.DrawSubset(0); clipMeshY.DrawSubset(0); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); device.SetRenderState(RenderState.Lighting, true); device.SetClipPlane(0, clipPlaneX); device.SetClipPlane(1, clipPlaneX2); device.SetClipPlane(2, clipPlaneY); device.SetClipPlane(3, clipPlaneY2); device.SetClipPlane(4, clipPlaneZ); device.SetClipPlane(5, clipPlaneZ2); } if (mesh != null) { mesh.DrawSubset(0); } //device.SetTexture(0, selectionTex); device.SetRenderState(RenderState.Lighting, false); if (selMesh != null) { selMesh.DrawSubset(0); } device.SetRenderState(RenderState.Lighting, true); //device.SetTexture(0, null); device.SetClipPlane(0, clipPlaneXPlus); device.SetClipPlane(1, clipPlaneX2Minus); device.SetClipPlane(2, clipPlaneYPlus); device.SetClipPlane(3, clipPlaneY2Minus); device.SetClipPlane(4, clipPlaneZPlus); device.SetClipPlane(5, clipPlaneZ2Minus); device.SetRenderState(RenderState.FillMode, FillMode.Solid); for(int i = 0; i < scene.lights.Count; ++i) { if(scene.lights[i].type == Light_Type.Spot || scene.lights[i].type == Light_Type.Goniometric) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[0] / 10, orthoWidth[0] / 10, orthoWidth[0] / 10) * Matrix.Translation(scene.lights[i].position + scene.lights[i].direction * spotLightDist * orthoWidth[0] / 10)); pointsMesh.DrawSubset(0); } } for(int i = 0; i < scene.cams.Count; ++i) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[0] / 10, orthoWidth[0] / 10, orthoWidth[0] / 10) * Matrix.Translation(scene.cams[i].position)); pointsMesh.DrawSubset(0); device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[0] / 10, orthoWidth[0] / 10, orthoWidth[0] / 10) * Matrix.Translation(camsLookAtPoints[i])); pointsMesh.DrawSubset(0); } device.SetTransform(TransformState.World, Matrix.Identity); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); if(camMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); camMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } if(lightsMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); lightsMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } device.EndScene(); } if (side.Width > 0 && side.Height > 0) { device.Viewport = side; device.SetTransform(TransformState.View, Matrix.LookAtRH( orthoPos[1], orthoLookAt[1], new Vector3(0, 1, 0))); device.SetTransform(TransformState.Projection, Matrix.OrthoRH( orthoWidth[1], (float)(side.Height) / side.Width * orthoWidth[1], 0.01f, 110000)); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(230, 230, 230), 1.0f, 0); device.BeginScene(); string text1 = " y\n/|\\\n |\n"; font.DrawString(null, text1, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Green); string text2 = "\n\n\n -----> -z"; font.DrawString(null, text2, viewportInfo.posX[1] + 15, viewportInfo.posY[1], Color.Blue); if(clipping == true) { device.SetRenderState(RenderState.Lighting, false); device.SetRenderState(RenderState.FillMode, FillMode.Solid); clipMeshY.DrawSubset(0); clipMeshZ.DrawSubset(0); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); device.SetRenderState(RenderState.Lighting, true); device.SetClipPlane(0, clipPlaneX); device.SetClipPlane(1, clipPlaneX2); device.SetClipPlane(2, clipPlaneY); device.SetClipPlane(3, clipPlaneY2); device.SetClipPlane(4, clipPlaneZ); device.SetClipPlane(5, clipPlaneZ2); } if (mesh != null) { mesh.DrawSubset(0); } //device.SetTexture(0, selectionTex); device.SetRenderState(RenderState.Lighting, false); if (selMesh != null) { selMesh.DrawSubset(0); } device.SetRenderState(RenderState.Lighting, true); //device.SetTexture(0, null); device.SetClipPlane(0, clipPlaneXPlus); device.SetClipPlane(1, clipPlaneX2Minus); device.SetClipPlane(2, clipPlaneYPlus); device.SetClipPlane(3, clipPlaneY2Minus); device.SetClipPlane(4, clipPlaneZPlus); device.SetClipPlane(5, clipPlaneZ2Minus); device.SetRenderState(RenderState.FillMode, FillMode.Solid); for(int i = 0; i < scene.lights.Count; ++i) { if(scene.lights[i].type == Light_Type.Spot || scene.lights[i].type == Light_Type.Goniometric) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[1] / 10, orthoWidth[0] / 10, orthoWidth[1] / 10) * Matrix.Translation(scene.lights[i].position + scene.lights[i].direction * spotLightDist * orthoWidth[1] / 10)); pointsMesh.DrawSubset(0); } } for(int i = 0; i < scene.cams.Count; ++i) { device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[1] / 10, orthoWidth[1] / 10, orthoWidth[1] / 10) * Matrix.Translation(scene.cams[i].position)); pointsMesh.DrawSubset(0); device.SetTransform(TransformState.World, Matrix.Scaling(orthoWidth[1] / 10, orthoWidth[1] / 10, orthoWidth[1] / 10) * Matrix.Translation(camsLookAtPoints[i])); pointsMesh.DrawSubset(0); } device.SetTransform(TransformState.World, Matrix.Identity); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); if(camMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); camMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } if(lightsMesh != null) { device.SetRenderState(RenderState.FillMode, FillMode.Wireframe); device.SetRenderState(RenderState.Lighting, false); lightsMesh.DrawSubset(0); device.SetRenderState(RenderState.Lighting, true); device.SetRenderState(RenderState.FillMode, wireframe ? FillMode.Wireframe : FillMode.Solid); } device.EndScene(); } #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Renderowanie " + t.Milliseconds); t1 = DateTime.Now; #endif device.Present(); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Present " + t.Milliseconds); t1 = DateTime.Now; #endif //selectionTex.Dispose(); if (selMesh != null) { selvb.Dispose(); selib.Dispose(); selMesh.Dispose(); } if (mesh != null) { vb.Dispose(); ib.Dispose(); mesh.Dispose(); } if(camMesh != null) { camVB.Dispose(); camIB.Dispose(); camMesh.Dispose(); } if(lightsMesh != null) { lightsVB.Dispose(); lightsIB.Dispose(); lightsMesh.Dispose(); } if(clipping == true) { clipVBX.Dispose(); clipIBX.Dispose(); clipVBY.Dispose(); clipIBY.Dispose(); clipVBZ.Dispose(); clipIBZ.Dispose(); clipMeshX.Dispose(); clipMeshY.Dispose(); clipMeshZ.Dispose(); } pointsMesh.Dispose(); #if MEASURE_TIMES t2 = DateTime.Now; t = t2 - t1; w.WriteLine("Czyszczenie " + t.Milliseconds); DateTime te = DateTime.Now; t = te - ts; w.WriteLine("Całość " + t.Milliseconds); w.WriteLine("-----------------------------------------------------------------"); w.WriteLine(); w.WriteLine(); w.WriteLine(); #endif }