作者: qiaoke_song
查看: 95|回复: 2

[源码] 【2D纹理映射】WPF 2D纹理的准确映射

[复制链接]
qiaoke_song 发表于 2019-10-5 10:44:46 | 显示全部楼层 |阅读模式
查看: 95|回复: 2
说明:
TextureCoordinates定义了如何将一副2D纹理映射到所建立的3D网格上,TextureCoordinates为Positions集合中的每一个3D顶点提供了一个2D顶点。
映射时方向确定比较麻烦,需要3D每个面映射都为正确的方向,在baidu上找了很多,映射基本是乱的。
通过归纳测试,有了准确的参数,需要的可参考使用,不必再费劲计算。
里面注销掉的部分,可以恢复并注销调自动转动部分,为手动点击对象转动。
通过VisualBrush写入的 image可以换为UserControl等组件。
代码不长,就100多行,仅供参考,如有错误,自行修正。

MainWindow.xaml
[C#] 纯文本查看 复制代码
<Window x:Class="Test3.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="768" Width="1024">
    <Grid x:Name="main">
        <Button Content="纵向" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button Content="横向" HorizontalAlignment="Left" Margin="10,48,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
        <Button Content="纵横" HorizontalAlignment="Left" Margin="10,85.74,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
        <Button Content="横纵" HorizontalAlignment="Left" Margin="10,124.5,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3"/>

    </Grid>
</Window>


MainWindow.xaml.cs
[C#] 纯文本查看 复制代码
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;

namespace Test3
{
    public partial class MainWindow : Window
    {
        private AxisAngleRotation3D axisAngleRotation3D;

        public MainWindow()
        {
            InitializeComponent();
            main.MouseDown += Main_MouseDown;

            init_draw();
        }

        public void init_draw()
        {
            Point3DCollection[] positions = new Point3DCollection[6]
            {
                new Point3DCollection(new Point3D[] {
                    new Point3D(0.5, 0.5, -0.5), new Point3D(- 0.5, 0.5, -0.5), new Point3D(- 0.5, 0.5, 0.5),
                    new Point3D(- 0.5, 0.5, 0.5),new Point3D(0.5, 0.5, 0.5), new Point3D(0.5, 0.5, -0.5)
                }),
                new Point3DCollection(new Point3D[] {
                    new Point3D(-0.5,0.5,-0.5),new Point3D(-0.5,-0.5,-0.5), new Point3D(-0.5,-0.5,0.5),
                    new Point3D(-0.5,-0.5,0.5),new Point3D(-0.5,0.5,0.5),new Point3D(-0.5,0.5,-0.5)
                }),
                new Point3DCollection(new Point3D[] {
                    new Point3D(-0.5,-0.5,0.5),new Point3D(0.5,-0.5,0.5),new Point3D(0.5,0.5,0.5),
                    new Point3D(0.5,0.5,0.5),new Point3D(-0.5,0.5,0.5), new Point3D(-0.5,-0.5,0.5)
                }),
                new Point3DCollection( new Point3D[] {
                    new Point3D(-0.5,-0.5,-0.5),new Point3D(-0.5,0.5,-0.5),new Point3D(0.5,0.5,-0.5),
                    new Point3D(0.5,0.5,-0.5), new Point3D(0.5,-0.5,-0.5),new Point3D(-0.5,-0.5,-0.5)
                }),
                new Point3DCollection( new Point3D[] {
                    new Point3D(-0.5,-0.5,-0.5), new Point3D(0.5,-0.5,-0.5), new Point3D(0.5,-0.5,0.5),
                    new Point3D(0.5,-0.5,0.5),new Point3D(-0.5,-0.5,0.5), new Point3D(-0.5,-0.5,-0.5)
                }),
                new Point3DCollection( new Point3D[] {
                    new Point3D(0.5,-0.5,-0.5),new Point3D(0.5,0.5,-0.5),new Point3D(0.5,0.5,0.5),
                    new Point3D(0.5,0.5,0.5), new Point3D(0.5,-0.5,0.5), new Point3D(0.5,-0.5,-0.5)
                })
            };
            
            PointCollection[] texturepoints = new PointCollection[6]
            {
                new PointCollection {new Point(1,0), new Point(0,0), new Point(0,1), new Point(0,1), new Point(1,1),new Point(1,0) },
                new PointCollection { new Point(0,0),new Point(0,1),new Point(1,1),  new Point(1,1),new Point(1,0),new Point(0,0) },
                new PointCollection { new Point(0,1), new Point(1,1),new Point(1,0), new Point(1,0),new Point(0,0),new Point(0,1) },
                new PointCollection { new Point(1,1), new Point(1,0),new Point(0,0), new Point(0,0), new Point(0,1), new Point(1,1) },
                new PointCollection { new Point(0,1), new Point(1,1), new Point(1,0),new Point(1,0), new Point(0,0), new Point(0,1)},
                new PointCollection{ new Point(1,1), new Point(1,0),new Point(0,0),new Point(0,0), new Point(0,1),new Point(1,1)}
            };

            string[] filename = new string[6] //430251
            {
                "pack://application:,,,/Images/4.jpg",
                "pack://application:,,,/Images/3.jpg",
                "pack://application:,,,/Images/0.jpg",
                "pack://application:,,,/Images/2.jpg",
                "pack://application:,,,/Images/5.jpg",
                "pack://application:,,,/Images/1.jpg"
            };

            Viewport3D viewport3D = new Viewport3D();
            
            PerspectiveCamera perspectiveCamera = new PerspectiveCamera()
            {
                Position = new Point3D(0, 0, 3),
                LookDirection = new Vector3D(0, 0, -3),
                FieldOfView = 50,
                UpDirection = new Vector3D(0, 1, 0),
                FarPlaneDistance = 20,
                NearPlaneDistance = 0,
            };
            viewport3D.Camera = perspectiveCamera;

            ModelVisual3D modelVisual3D = new ModelVisual3D();
            Model3DGroup model3DGroup = new Model3DGroup();

            for (int i = 0; i < 6; i++)
            {
                GeometryModel3D geometryModel3D = new GeometryModel3D();

                DiffuseMaterial diffuse = new DiffuseMaterial();
                VisualBrush visualBrush = new VisualBrush();
                Image image = new Image();
                image.Source = new BitmapImage(new Uri(filename[i]));
                visualBrush.Visual = image;
                diffuse.Brush = visualBrush;
                geometryModel3D.Material = diffuse;

                MeshGeometry3D meshGeometry3D = new MeshGeometry3D()
                {
                    Positions = positions[i],
                    TextureCoordinates = texturepoints[i],
                };
                geometryModel3D.Geometry = meshGeometry3D;
                model3DGroup.Children.Add(geometryModel3D);
            }
            AmbientLight ambientLight = new AmbientLight();
            model3DGroup.Children.Add(ambientLight);

            modelVisual3D.Content = model3DGroup;
            viewport3D.Children.Add(modelVisual3D);

            main.Children.Add(viewport3D);

            /*
            axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(1, 1, 0), 0);
            RotateTransform3D rotateTransform3D = new RotateTransform3D(axisAngleRotation3D);
            rotateTransform3D.Rotation = axisAngleRotation3D;
            modelVisual3D.Transform = rotateTransform3D;
            */
            // 如恢复上面,以下可以注销
            axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0);
            RotateTransform3D rotate = new RotateTransform3D(axisAngleRotation3D);
            modelVisual3D.Transform = rotate;
            DoubleAnimation animation = new DoubleAnimation();
            animation.From = 0;
            animation.To = 360;
            animation.Duration = new Duration(TimeSpan.FromSeconds(10.0));
            animation.RepeatBehavior = RepeatBehavior.Forever;
            NameScope.SetNameScope(main, new NameScope());
            main.RegisterName("cubeaxis", axisAngleRotation3D);
            Storyboard.SetTargetName(animation, "cubeaxis");
            Storyboard.SetTargetProperty(animation, new PropertyPath(AxisAngleRotation3D.AngleProperty));
            Storyboard RotCube = new Storyboard();
            RotCube.Children.Add(animation);
            RotCube.Begin(main);
        }

        double tmp = 0;

        private void Main_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // 点击对象手动转动
            /*
            tmp = axisAngleRotation3D.Angle;
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                tmp -= 5;
            }
            if (e.RightButton == MouseButtonState.Pressed)
            {
                tmp += 5;
            }
            axisAngleRotation3D.Angle = tmp;
            */
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            axisAngleRotation3D.Axis = new Vector3D(1,0,0);
            axisAngleRotation3D.Angle = 0;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            axisAngleRotation3D.Axis = new Vector3D(0,1,0);
            axisAngleRotation3D.Angle = 0;
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            axisAngleRotation3D.Axis = new Vector3D(1, 1, 0);
            axisAngleRotation3D.Angle = 0;
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            axisAngleRotation3D.Axis = new Vector3D(0, 1, 1);
            axisAngleRotation3D.Angle = 0;
        }
    }
}


效果图:

WPF 2D纹理的准确映射

WPF 2D纹理的准确映射

回复 论坛版权

使用道具 举报

 楼主| qiaoke_song 发表于 2019-10-6 08:27:00 | 显示全部楼层
不想复制粘贴的,这里:https://pan.baidu.com/s/1yJGS1_jJPL68nPX28NTl4g
klbb625 发表于 2019-10-9 16:43:19 | 显示全部楼层
qiaoke_song 发表于 2019-10-6 08:27
不想复制粘贴的,这里:https://pan.baidu.com/s/1yJGS1_jJPL68nPX28NTl4g

大佬,您这个https://www.cnblogs.com/qiaoke/p/6358050.html里面第一个练习的完整代码有嘛?想学习学习,谢谢啦
您需要登录后才可以回帖 登录 | 加入CSkin论坛

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2019-10-19 22:52, Processed in 0.521088 second(s), 33 queries , Gzip On.

快速回复 返回顶部 返回列表