I simply want to texture a 3D object with an image (texture file here). For this purpose I use the System.Windows.Media3D
stuff. My Problem is that a cube is not textured with an image. When I draw the cube with a SolidColorBrush
, the cube is visible. After replacing the SolidColorBrush
with an ImageBrush
the Cube gets invisible. Where is my fault? The code below uses the programmatic approach because I want to generate the texture and meshes dynamically in the later program.
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Label
HorizontalAlignment="Center"
TextBlock.TextAlignment="Center"
FontSize="20"
Foreground="Red"
Content="Model: Cube"/>
<Viewport3D x:Name="MainViewport">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="20"
LookDirection="0,0,1"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="0,0,-3"
FieldOfView="45" />
</Viewport3D.Camera>
</Viewport3D>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
namespace WpfApp1
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//setup the 3D Object
ModelVisual3D model = new ModelVisual3D();
Model3DGroup mdlGroup = new Model3DGroup();
//Jpg Texture as main purpose
BitmapImage imgSource = new BitmapImage();
string texturePath = @"./Texture.PNG";
imgSource.BeginInit();
imgSource.UriSource = new Uri(texturePath, UriKind.Relative);
imgSource.EndInit();
ImageBrush imgBrush = new ImageBrush(imgSource);
//Solid Black as alternative for testing
SolidColorBrush colorBrush = new SolidColorBrush(Color.FromRgb(0,0,0));
//Create Material
DiffuseMaterial material = new DiffuseMaterial(imgBrush);
//Generating the model
GeometryModel3D internalModel = new GeometryModel3D(new MeshGeometry3D(), material)
{
BackMaterial = material
};
//Generating the mesh of the model
MeshGeometry3D mesh = (MeshGeometry3D)internalModel.Geometry;
mesh.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
mesh.Positions.Add(new Point3D(-0.5, 0.5, -0.5));
mesh.Positions.Add(new Point3D(0.5, 0.5, -0.5));
mesh.Positions.Add(new Point3D(0.5, 0.5, -0.5));
mesh.Positions.Add(new Point3D(0.5, -0.5, -0.5));
mesh.Positions.Add(new Point3D(-0.5, -0.5, -0.5));
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(2);
mesh.TriangleIndices.Add(3);
mesh.TriangleIndices.Add(4);
mesh.TriangleIndices.Add(5);
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Normals.Add(new Vector3D(0, 0, -1));
mesh.Freeze();
//including everything
mdlGroup.Children.Add(internalModel);
DirectionalLight myDirLight = new DirectionalLight
{
Color = Colors.White,
Direction = new Vector3D(-3, -4, -5)
};
mdlGroup.Children.Add(myDirLight);
model.Content = mdlGroup;
this.MainViewport.Children.Add(model);
}
}
}
After contacting the MS Q & A, it turned out that I forgot to set the texture coordinates. Thanks to Peter Fleischer.