Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La funcionalidad 3D de Windows Presentation Foundation (WPF) permite a los desarrolladores dibujar, transformar y animar gráficos 3D en código de marcado y procedimiento. Los desarrolladores pueden combinar gráficos 2D y 3D para crear controles enriquecidos, proporcionar ilustraciones complejas de datos o mejorar la experiencia del usuario de la interfaz de una aplicación. La compatibilidad con 3D en WPF no está diseñada para proporcionar una plataforma de desarrollo de juegos completa. En este tema se proporciona información general sobre la funcionalidad 3D en el sistema gráfico de WPF.
3D en un contenedor 2D
El contenido de gráficos 3D en WPF se encapsula en un elemento , Viewport3Dque puede participar en la estructura de elementos bidimensionales. El sistema de gráficos trata a Viewport3D como un elemento visual bidimensional, similar a muchos otros en WPF. Viewport3D funciona como una ventana—un visor—en una escena tridimensional. Con mayor precisión, es una superficie en la que se proyecta una escena 3D.
En una aplicación 2D convencional, use Viewport3D como lo haría con otro elemento de contenedor, como Grid o Canvas. Aunque puede usar Viewport3D con otros objetos de dibujo 2D en el mismo gráfico de escenas, no puede interpenetrar objetos 2D y 3D dentro de Viewport3D. Este tema se centrará en cómo dibujar gráficos 3D dentro de Viewport3D.
Espacio de coordenadas 3D
El sistema de coordenadas WPF para gráficos 2D localiza el origen en la parte superior izquierda del área de representación (normalmente la pantalla). En el sistema 2D, los valores positivos del eje X continúan hacia la derecha y los valores positivos del eje Y continúan hacia abajo. Sin embargo, en el sistema de coordenadas 3D, el origen se encuentra en el centro del área de representación, con valores positivos del eje X que continúan hacia la derecha, pero los valores positivos del eje Y continúan hacia arriba, y los valores positivos del eje Z que continúan hacia fuera desde el origen, hacia el visor.
Representaciones convencionales del sistema de coordenadas 2D y 3D
El espacio definido por estos ejes es el marco fijo de referencia para objetos 3D en WPF. A medida que crea modelos en este espacio y crea luces y cámaras para verlas, resulta útil distinguir este marco de referencia estacionario, o "espacio mundial", del marco de referencia local que se crea para cada modelo al aplicar transformaciones. Recuerde también que los objetos del espacio mundial pueden parecer completamente diferentes o no estar visibles en absoluto, dependiendo de la luz y la configuración de la cámara, pero la posición de la cámara no cambia la ubicación de los objetos en el espacio mundial.
Cámaras y proyecciones
Los desarrolladores que trabajan en 2D están acostumbrados a colocar primitivos de dibujo en una pantalla bidimensional. Al crear una escena 3D, es importante recordar que realmente está creando una representación 2D de objetos 3D. Dado que una escena 3D tiene un aspecto diferente en función del punto de vista del onlooker, debe especificar ese punto de vista. La Camera clase permite especificar este punto de vista para una escena 3D.
Otra manera de entender cómo se representa una escena 3D en una superficie 2D es describir la escena como una proyección en la superficie de visualización. ProjectionCamera permite especificar diferentes proyecciones y sus propiedades para cambiar cómo el onlooker ve los modelos 3D. Un PerspectiveCamera especifica una proyección que acorta la escena. En otras palabras, PerspectiveCamera proporciona una perspectiva de punto de fuga. Puede especificar la posición de la cámara en el espacio de coordenadas de la escena, la dirección y el campo de vista de la cámara, y un vector que define la dirección de "arriba" en la escena. En el diagrama siguiente se muestra la proyección de PerspectiveCamera.
Las propiedades NearPlaneDistance y FarPlaneDistance de ProjectionCamera limitan el rango de proyección de la cámara. Dado que las cámaras se pueden ubicar en cualquier parte de la escena, es posible que la cámara se coloque realmente dentro de un modelo o muy cerca de un modelo, lo que dificulta la distinción de objetos correctamente. NearPlaneDistance permite especificar una distancia mínima desde la cámara más allá de qué objetos no se dibujarán. Por el contrario, FarPlaneDistance permite especificar una distancia desde la cámara más allá de qué objetos no se dibujarán, lo que garantiza que los objetos demasiado lejos de ser reconocibles no se incluirán en la escena.
Posición de la cámara
OrthographicCamera especifica una proyección ortogonal de un modelo 3D en una superficie visual 2D. Al igual que otras cámaras, especifica una posición, dirección de visualización y dirección "hacia arriba". A diferencia de PerspectiveCamera, OrthographicCamera describe una proyección que no incluye el acortamiento. En otras palabras, OrthographicCamera describe un cuadro de visualización cuyos lados son paralelos, en lugar de uno cuyos lados se encuentran en un punto de la cámara. En la imagen siguiente se muestra el mismo modelo que se ve mediante PerspectiveCamera y OrthographicCamera.
Perspectivas y proyecciones ortográficas
En el código siguiente se muestran algunas configuraciones de cámara típicas.
// Defines the camera used to view the 3D object. In order to view the 3D object,
// the camera must be positioned and pointed such that the object is within view
// of the camera.
PerspectiveCamera myPCamera = new PerspectiveCamera();
// Specify where in the 3D scene the camera is.
myPCamera.Position = new Point3D(0, 0, 2);
// Specify the direction that the camera is pointing.
myPCamera.LookDirection = new Vector3D(0, 0, -1);
// Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60;
// Asign the camera to the viewport
myViewport3D.Camera = myPCamera;
' Defines the camera used to view the 3D object. In order to view the 3D object,
' the camera must be positioned and pointed such that the object is within view
' of the camera.
Dim myPCamera As New PerspectiveCamera()
' Specify where in the 3D scene the camera is.
myPCamera.Position = New Point3D(0, 0, 2)
' Specify the direction that the camera is pointing.
myPCamera.LookDirection = New Vector3D(0, 0, -1)
' Define camera's horizontal field of view in degrees.
myPCamera.FieldOfView = 60
' Asign the camera to the viewport
myViewport3D.Camera = myPCamera
Modelo y malla primitivas
Model3D es la clase base abstracta que representa un objeto 3D genérico. Para crear una escena 3D, necesita algunos objetos para ver y los objetos que componen el grafo de escena derivan de Model3D. Actualmente, WPF admite geometrías de modelado con GeometryModel3D. La Geometry propiedad de este modelo toma un primitivo de malla.
Para compilar un modelo, empiece por crear un primitivo o una malla. Un primitivo 3D es una colección de vértices que forman una sola entidad 3D. La mayoría de los sistemas 3D proporcionan primitivos modelados en la figura cerrada más sencilla: un triángulo definido por tres vértices. Dado que los tres puntos de un triángulo son coplanares, puede seguir agregando triángulos para modelar formas más complejas, denominadas mallas.
El sistema WPF 3D proporciona actualmente la MeshGeometry3D clase , que permite especificar cualquier geometría; actualmente no admite primitivos 3D predefinidos como esferas y formas cúbicas. Comience a crear un MeshGeometry3D mediante la especificación de una lista de vértices de triángulo como su Positions propiedad. Cada vértice se especifica como .Point3D (En XAML, especifique esta propiedad como una lista de números agrupados en tres que representan las coordenadas de cada vértice). Dependiendo de su geometría, la malla puede estar compuesta de muchos triángulos, algunos de los cuales comparten las mismas esquinas (vértices). Para dibujar correctamente la malla, WPF necesita información sobre los vértices que comparten los triángulos. Para proporcionar esta información, especifique una lista de índices de triángulo con la propiedad TriangleIndices. Esta lista especifica el orden en el que los puntos especificados en la Positions lista determinarán un triángulo.
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="-1 -1 0 1 -1 0 -1 1 0 1 1 0"
Normals="0 0 1 0 0 1 0 0 1 0 0 1"
TextureCoordinates="0 1 1 1 0 0 1 0 "
TriangleIndices="0 1 2 1 3 2" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<!-- Translate the plane. -->
<GeometryModel3D.Transform>
<TranslateTransform3D
OffsetX="2" OffsetY="0" OffsetZ="-1" >
</TranslateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
En el ejemplo anterior, la Positions lista especifica cuatro vértices para definir una malla de rectángulo. La TriangleIndices propiedad especifica una lista de dos grupos de tres índices. Cada número de la lista hace referencia a un desplazamiento en la Positions lista. Por ejemplo, los tres primeros vértices especificados por la Positions lista son (-1,-1,0), (1,-1,0)y (-1,1,0). Los tres primeros índices especificados por la TriangleIndices lista son 0, 1 y 2, que corresponden al primer, segundo y tercer punto de la Positions lista. Como resultado, el primer triángulo que compone el modelo de rectángulo se compondrá de (-1,-1,0) a (1,-1,0) a (-1,1,0), y el segundo triángulo se determinará de forma similar.
Puede seguir definiendo el modelo especificando valores para las Normals propiedades y TextureCoordinates . Para representar la superficie del modelo, el sistema gráfico necesita información sobre la dirección a la que se enfrenta la superficie en cualquier triángulo determinado. Usa esta información para realizar cálculos de iluminación para el modelo: las superficies que se enfrentan directamente hacia una fuente de luz aparecen más brillantes que las inclinadas lejos de la luz. Aunque WPF puede determinar los vectores normales predeterminados mediante las coordenadas de posición, también puede especificar distintos vectores normales para aproximar la apariencia de las superficies curvadas.
La TextureCoordinates propiedad especifica una colección de Points que indica al sistema gráfico cómo asignar las coordenadas que determinan cómo se dibuja una textura a los vértices de la malla. TextureCoordinates se especifican como un valor entre cero y 1, ambos incluidos. Al igual que con la Normals propiedad , el sistema de gráficos puede calcular coordenadas de textura predeterminadas, pero puede optar por establecer coordenadas de textura diferentes para controlar la asignación de una textura que incluye parte de un patrón de repetición, por ejemplo. Puede encontrar más información sobre las coordenadas de textura en temas posteriores o en el SDK de Direct3D administrado.
En el ejemplo siguiente se muestra cómo crear una cara del modelo de cubo en código de procedimientos. Puede dibujar todo el cubo como un solo GeometryModel3D
; en este ejemplo se dibuja la cara del cubo como un modelo distinto para aplicar texturas independientes a cada cara más adelante.
MeshGeometry3D side1Plane = new MeshGeometry3D();
Private side1Plane As New MeshGeometry3D()
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, 0.5, -0.5));
side1Plane.Positions.Add(new Point3D(0.5, -0.5, -0.5));
side1Plane.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
side1Plane.TriangleIndices.Add(0);
side1Plane.TriangleIndices.Add(1);
side1Plane.TriangleIndices.Add(2);
side1Plane.TriangleIndices.Add(3);
side1Plane.TriangleIndices.Add(4);
side1Plane.TriangleIndices.Add(5);
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.Normals.Add(new Vector3D(0, 0, -1));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 1));
side1Plane.TextureCoordinates.Add(new Point(0, 0));
side1Plane.TextureCoordinates.Add(new Point(1, 0));
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, 0.5, -0.5))
side1Plane.Positions.Add(New Point3D(0.5, -0.5, -0.5))
side1Plane.Positions.Add(New Point3D(-0.5, -0.5, -0.5))
side1Plane.TriangleIndices.Add(0)
side1Plane.TriangleIndices.Add(1)
side1Plane.TriangleIndices.Add(2)
side1Plane.TriangleIndices.Add(3)
side1Plane.TriangleIndices.Add(4)
side1Plane.TriangleIndices.Add(5)
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.Normals.Add(New Vector3D(0, 0, -1))
side1Plane.TextureCoordinates.Add(New Point(1, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 1))
side1Plane.TextureCoordinates.Add(New Point(0, 0))
side1Plane.TextureCoordinates.Add(New Point(1, 0))
Aplicación de materiales al modelo
Para que una malla tenga un aspecto similar a un objeto tridimensional, debe tener una textura aplicada para cubrir la superficie definida por sus vértices y triángulos para que la cámara pueda iluminarla y proyectarla. En 2D, se usa la Brush clase para aplicar colores, patrones, degradados u otro contenido visual a áreas de la pantalla. Sin embargo, la apariencia de los objetos 3D es una función del modelo de iluminación, no solo del color o patrón aplicado a ellos. Los objetos reales reflejan la luz de forma diferente en función de la calidad de sus superficies: las superficies brillantes y brillantes no tienen el mismo aspecto que las superficies rugosas o mates, y algunos objetos parecen absorber la luz mientras que otros brillan. Puede aplicar todos los mismos pinceles a objetos 3D que se pueden aplicar a objetos 2D, pero no se pueden aplicar directamente.
Para definir las características de la superficie de un modelo, WPF usa la Material clase abstracta. Las subclases concretas de Material determinan algunas de las características de apariencia de la superficie del modelo, y cada una de ellas también ofrece una propiedad Brush a la cual puede asignarse un SolidColorBrush, TileBrush o VisualBrush.
DiffuseMaterial especifica que el pincel se aplicará al modelo como si ese modelo se iluminara difusamente. El uso de DiffuseMaterial más se parece al uso de pinceles directamente en modelos 2D; Las superficies del modelo no reflejan la luz como si estuviera brillante.
SpecularMaterial especifica que el pincel se aplicará al modelo como si la superficie del modelo fuera dura o brillante, capaz de reflejar los resaltados. Puede establecer el grado en el que la textura sugerirá esta calidad reflectante o "brillar", especificando un valor para la SpecularPower propiedad .
EmissiveMaterial permite especificar que la textura se aplicará como si el modelo emita luz igual al color del pincel. Esto no hace que el modelo sea claro; sin embargo, participará de forma diferente en sombras que si se texturara con DiffuseMaterial o SpecularMaterial.
Para mejorar el rendimiento, las caras posteriores de un GeometryModel3D (aquellas caras que están fuera de la vista porque están en el lado opuesto al de la cámara del modelo) se eliminan de la escena. Para especificar un Material para aplicar a la cara trasera de un modelo como un plano, establezca la propiedad BackMaterial del modelo.
Para lograr algunas cualidades de superficie, como los efectos iluminados o reflectantes, es posible que desee aplicar varios pinceles diferentes a un modelo en sucesión. Puede aplicar y reutilizar varios materiales mediante la MaterialGroup clase . Los elementos secundarios de MaterialGroup se aplican de principio a fin a través de múltiples pasos de renderizado.
En los ejemplos de código siguientes se muestra cómo aplicar un color sólido y un dibujo como pinceles a modelos 3D.
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<DrawingBrush x:Key="patternBrush" Viewport="0,0,0.1,0.1" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M0,0.1 L0.1,0 1,0.9, 0.9,1z"
Brush="Gray" />
<GeometryDrawing Geometry="M0.9,0 L1,0.1 0.1,1 0,0.9z"
Brush="Gray" />
<GeometryDrawing Geometry="M0.25,0.25 L0.5,0.125 0.75,0.25 0.5,0.5z"
Brush="#FFFF00" />
<GeometryDrawing Geometry="M0.25,0.75 L0.5,0.875 0.75,0.75 0.5,0.5z"
Brush="Black" />
<GeometryDrawing Geometry="M0.25,0.75 L0.125,0.5 0.25,0.25 0.5,0.5z"
Brush="#FF0000" />
<GeometryDrawing Geometry="M0.75,0.25 L0.875,0.5 0.75,0.75 0.5,0.5z"
Brush="MediumBlue" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
DiffuseMaterial side5Material = new DiffuseMaterial((Brush)Application.Current.Resources["patternBrush"]);
Dim side5Material As New DiffuseMaterial(CType(Application.Current.Resources("patternBrush"), Brush))
Iluminar la escena
Las luces en gráficos 3D hacen lo que hacen las luces en el mundo real: hacen que las superficies sean visibles. Más hasta el punto, las luces determinan qué parte de una escena se incluirá en la proyección. Los objetos de luz en WPF crean una variedad de efectos de luz y sombra y se modelan después del comportamiento de varias luces del mundo real. Incluya al menos una luz en la escena o ningún modelo estará visible.
Las siguientes luces derivan de la clase base Light:
AmbientLight: proporciona iluminación ambiental que ilumina todos los objetos uniformemente independientemente de su ubicación o orientación.
DirectionalLight: Ilumina como una fuente de luz distante. Las luces direccionales tienen un Direction especificado como Vector3D, pero no tienen ubicación especificada.
PointLight: ilumina como una fuente de luz cercana. PointLights tienen una posición y emiten luz desde esa posición. Los objetos de la escena se iluminan en función de su posición y distancia con respecto a la luz. PointLightBase expone una Range propiedad , que determina una distancia más allá de la cual los modelos no se iluminarán mediante la luz. PointLight también expone propiedades de atenuación, que determinan cómo disminuye la intensidad de la luz a lo largo de la distancia. Puede especificar interpolaciones constantes, lineales o cuadráticas para la atenuación de la luz.
SpotLight: hereda de PointLight. Los focos iluminan como las luces puntuales y tienen tanto posición como dirección. Proyectan luz en un área con forma de cono establecida por InnerConeAngle y OuterConeAngle propiedades, especificadas en grados.
Las luces son Model3D objetos, por lo que puede transformar y animar propiedades de luz, como la posición, el color, la dirección y el intervalo.
<ModelVisual3D.Content>
<AmbientLight Color="#333333" />
</ModelVisual3D.Content>
DirectionalLight myDirLight = new DirectionalLight();
Private myDirLight As New DirectionalLight()
myDirLight.Color = Colors.White;
myDirLight.Direction = new Vector3D(-3, -4, -5);
myDirLight.Color = Colors.White
myDirLight.Direction = New Vector3D(-3, -4, -5)
modelGroup.Children.Add(myDirLight);
modelGroup.Children.Add(myDirLight)
Transformación de modelos
Al crear modelos, tienen una ubicación determinada en la escena. Para mover esos modelos alrededor de la escena, para girarlos o cambiar su tamaño, no es práctico cambiar los vértices que definen los propios modelos. En su lugar, al igual que en 2D, se aplican transformaciones a los modelos.
Cada objeto de modelo tiene una Transform propiedad con la que puede mover, reorientar o cambiar el tamaño del modelo. Al aplicar una transformación, se desplazan eficazmente todos los puntos del modelo por cualquier vector o valor especificado por la transformación. En otras palabras, ha transformado el espacio de coordenadas en el que se define el modelo ("espacio del modelo"), pero no ha cambiado los valores que componen la geometría del modelo en el sistema de coordenadas de toda la escena ("espacio mundial").
Para obtener más información sobre la transformación de modelos, consulte Información general sobre transformaciones 3D.
Animar modelos
La implementación de WPF 3D participa en el mismo sistema de tiempo y animación que los gráficos 2D. En otras palabras, para animar una escena 3D, anima las propiedades de sus modelos. Es posible animar las propiedades de los primitivos directamente, pero normalmente es más fácil animar las transformaciones que cambian la posición o la apariencia de los modelos. Dado que las transformaciones se pueden aplicar tanto a Model3DGroup objetos como a modelos individuales, es posible aplicar un conjunto de animaciones a un elemento secundario de un Model3DGroup y otro conjunto de animaciones a un grupo de objetos secundarios. También puede lograr una variedad de efectos visuales animando las propiedades de la iluminación de la escena. Por último, puede optar por animar la propia proyección animando la posición de la cámara o el campo de vista. Para obtener información general sobre el sistema de tiempo y animación de WPF, vea los temas Información general sobre animaciones, Información general sobre guiones gráficos y Información general sobre objetos Freezable .
Para animar un objeto en WPF, se crea una escala de tiempo, se define una animación (que es realmente un cambio en algún valor de propiedad con el tiempo) y se especifica la propiedad a la que se va a aplicar la animación. Dado que todos los objetos de una escena 3D son hijos de Viewport3D, las propiedades a las que se dirige cualquier animación que quiera aplicar a la escena son propiedades de Viewport3D.
Supongamos que quiere hacer que un modelo parezca tambalearse en su sitio. Puede optar por aplicar un RotateTransform3D elemento al modelo y animar el eje de su rotación de un vector a otro. En el ejemplo de código siguiente se muestra cómo aplicar vector3DAnimation a la propiedad Axis de la transformación Rotation3D, suponiendo que RotateTransform3D sea una de las varias transformaciones aplicadas al modelo con un TransformGroup.
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation);
myRotateTransform.Rotation.BeginAnimation(AxisAngleRotation3D.AxisProperty, myVectorAnimation)
//Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform);
'Add transformation to the model
cube1TransformGroup.Children.Add(myRotateTransform)
Agregar contenido 3D a la ventana
Para representar la escena, agregue modelos y luces a Model3DGroup, luego establezca Model3DGroup como Content de un ModelVisual3D. Agregue ModelVisual3D a la colección Children del Viewport3D. Agregue cámaras al Viewport3D estableciendo su propiedad Camera.
Por último, agregue Viewport3D a la ventana. Cuando Viewport3D se incluye como el contenido de un elemento de diseño como Canvas, especifique el tamaño de Viewport3D estableciendo sus propiedades Height y Width (heredadas de FrameworkElement).
<UserControl x:Class="HostingWpfUserControlInWf.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<!-- Place a Label control at the top of the view. -->
<Label
HorizontalAlignment="Center"
TextBlock.TextAlignment="Center"
FontSize="20"
Foreground="Red"
Content="Model: Cone"/>
<!-- Viewport3D is the rendering surface. -->
<Viewport3D Name="myViewport" >
<!-- Add a camera. -->
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="20"
LookDirection="0,0,1"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="0,0,-3"
FieldOfView="45" />
</Viewport3D.Camera>
<!-- Add models. -->
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup >
<Model3DGroup.Children>
<!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
<DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
<!-- Define a red cone. -->
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="0.293893 -0.5 0.404509 0.475528 -0.5 0.154509 0 0.5 0 0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 0.154509 0.475528 -0.5 -0.154509 0 0.5 0 0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 -0.154509 0.293893 -0.5 -0.404509 0 0.5 0 0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 0.293893 -0.5 -0.404509 0 -0.5 -0.5 0 0.5 0 0 -0.5 -0.5 0 0.5 0 0 0.5 0 0 -0.5 -0.5 -0.293893 -0.5 -0.404509 0 0.5 0 -0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 -0.293893 -0.5 -0.404509 -0.475528 -0.5 -0.154509 0 0.5 0 -0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 -0.154509 -0.475528 -0.5 0.154509 0 0.5 0 -0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 0.154509 -0.293892 -0.5 0.404509 0 0.5 0 -0.293892 -0.5 0.404509 0 0.5 0 0 0.5 0 -0.293892 -0.5 0.404509 0 -0.5 0.5 0 0.5 0 0 -0.5 0.5 0 0.5 0 0 0.5 0 0 -0.5 0.5 0.293893 -0.5 0.404509 0 0.5 0 0.293893 -0.5 0.404509 0 0.5 0 0 0.5 0 "
Normals="0.7236065,0.4472139,0.5257313 0.2763934,0.4472138,0.8506507 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 -0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.5308242,0.4294462,0.7306172 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.7236065,0.4472139,0.5257313 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.858892,0.429446,0.279071 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.8944269,0.4472139,0 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.858892,0.429446,-0.279071 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.7236065,0.4472139,-0.5257313 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.5308242,0.4294462,-0.7306172 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.2763934,0.4472138,-0.8506507 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.5308249,0.4294459,-0.7306169 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.7236068,0.4472141,-0.5257306 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8588922,0.4294461,-0.27907 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8944269,0.4472139,0 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.858892,0.429446,0.279071 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.7236065,0.4472139,0.5257313 0.858892,0.429446,0.279071 0.7236065,0.4472139,0.5257313 0.5308242,0.4294462,0.7306172 0.858892,0.429446,0.279071 " TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush
Color="Red"
Opacity="1.0"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</Model3DGroup.Children>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
</Grid>
</UserControl>
Consulte también
.NET Desktop feedback