WPF三维旋转球体GUI

WPF三维旋转球体GUI,wpf,3d,geometry,Wpf,3d,Geometry,我一直试图在WPF中为我的课堂作业制作一个3D用户界面,但我遇到了一个问题,我现在2-3天都无法解决。我试着用谷歌搜索答案,我查看了一些stackoverflow帖子,但没有一个能帮我解决这个问题 情况就是这样:我有一个3D球体,上面有两个按钮。一个按钮使球体的材质变得透明,另一个按钮旋转整个界面(球体+按钮)。。。问题是,当球体透明时,它的纹理仍然存在,所以当按钮位于球体的另一侧时,我看不到它们。。。我希望看到按钮的背景至少 任何帮助都将不胜感激 这是我的XAML: <Window x:

我一直试图在WPF中为我的课堂作业制作一个3D用户界面,但我遇到了一个问题,我现在2-3天都无法解决。我试着用谷歌搜索答案,我查看了一些stackoverflow帖子,但没有一个能帮我解决这个问题

情况就是这样:我有一个3D球体,上面有两个按钮。一个按钮使球体的材质变得透明,另一个按钮旋转整个界面(球体+按钮)。。。问题是,当球体透明时,它的纹理仍然存在,所以当按钮位于球体的另一侧时,我看不到它们。。。我希望看到按钮的背景至少

任何帮助都将不胜感激

这是我的XAML:

<Window x:Class="RacunalnaGrafika_seminar.SphereWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:RacunalnaGrafika_seminar"
    AllowsTransparency="True"
    WindowStyle="None"
    Title="SphereWindow">

<Window.Resources>
    <src:SphereMeshGenerator x:Key="SphereGenerator" Center="0 0 0" Radius="0.5" />
</Window.Resources>

<Viewport3D x:Name="myViewport3D">

    <Viewport3D.Children>

        <ModelVisual3D>

            <Viewport2DVisual3D Geometry="{Binding Source={StaticResource SphereGenerator}, Path=Geometry}">

                <Viewport2DVisual3D.Material>
                    <MaterialGroup>
                        <DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True"/>
                        <SpecularMaterial Brush="#00FFFFFF" SpecularPower="50"/>
                    </MaterialGroup>
                </Viewport2DVisual3D.Material>

                <Viewport2DVisual3D.Transform>
                    <RotateTransform3D>
                        <RotateTransform3D.Rotation>
                            <AxisAngleRotation3D x:Name="Hax" Axis="0 1 0" />
                        </RotateTransform3D.Rotation>
                    </RotateTransform3D>
                </Viewport2DVisual3D.Transform>

                    <Viewport2DVisual3D.Visual>
                    <Canvas Background="Transparent" Width="500" Height="500">
                        <StackPanel Canvas.Top="150">
                            <Button Content="Rotate" Padding="10" >
                                <Button.Triggers>
                                    <EventTrigger RoutedEvent="Button.Click">
                                        <BeginStoryboard>
                                            <Storyboard TargetName="RotateInterface" TargetProperty="Angle">
                                                <DoubleAnimation From="0" To="360" RepeatBehavior="1x" Duration="0:0:5" />
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </Button.Triggers>
                            </Button>
                            <Button Padding="10" Content="Click me" Click="Button_Click_1">
                                <Button.Triggers>
                                    <EventTrigger RoutedEvent="Button.Click">
                                        <BeginStoryboard>
                                            <Storyboard TargetName="SphereMaterial" TargetProperty="Color">
                                                <ColorAnimation To="Transparent" RepeatBehavior="1x" Duration="0:0:5" />
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </Button.Triggers>
                            </Button>
                        </StackPanel>
                    </Canvas>
                </Viewport2DVisual3D.Visual>
            </Viewport2DVisual3D>

            <ModelVisual3D.Content>

                <Model3DGroup x:Name="SphereModel3DGroup">

                    <GeometryModel3D  x:Name="SphereGeometryModel" Geometry="{Binding Source={StaticResource SphereGenerator}, Path=Geometry}">

                        <GeometryModel3D.BackMaterial>
                            <DiffuseMaterial x:Name="SphereBackMaterial" Brush="Transparent" />
                        </GeometryModel3D.BackMaterial>

                        <GeometryModel3D.Material>
                            <DiffuseMaterial x:Name="SphereMaterial" > 
                                <DiffuseMaterial.Brush>
                                    <RadialGradientBrush>
                                        <GradientStop Color="#FF000000" Offset="1" />
                                        <GradientStop Color="#FF555555" Offset="0" />
                                    </RadialGradientBrush>
                                </DiffuseMaterial.Brush>
                            </DiffuseMaterial>
                        </GeometryModel3D.Material>

                        <GeometryModel3D.Transform>
                            <TranslateTransform3D />
                        </GeometryModel3D.Transform>
                    </GeometryModel3D>

                    <AmbientLight Color="White" />

                </Model3DGroup>
            </ModelVisual3D.Content>

            <ModelVisual3D.Transform>
                <RotateTransform3D>
                    <RotateTransform3D.Rotation>
                        <AxisAngleRotation3D x:Name="RotateInterface" Axis="0 1 0" />
                    </RotateTransform3D.Rotation>
                </RotateTransform3D>
            </ModelVisual3D.Transform>

        </ModelVisual3D>

    </Viewport3D.Children>

    <Viewport3D.Camera>
        <PerspectiveCamera Position="0 0 -3" LookDirection="0 0 1" UpDirection="0 1 0" FieldOfView="45" />
    </Viewport3D.Camera>

</Viewport3D>

以下是取自Charles Petzold的球体生成器:

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace RacunalnaGrafika_seminar
{
  public class SphereMeshGenerator
  {
    private int _slices = 32;
    private int _stacks = 16;
    private Point3D _center = new Point3D();
    private double _radius = 1;

    public int Slices
    {
        get { return _slices; }
        set { _slices = value; }
    }

    public int Stacks
    {
        get { return _stacks; }
        set { _stacks = value; }
    }

    public Point3D Center
    {
        get { return _center; }
        set { _center = value; }
    }

    public double Radius
    {
        get { return _radius; }
        set { _radius = value; }
    }

    public MeshGeometry3D Geometry
    {
        get
        {
            return CalculateMesh();
        }
    }


    private MeshGeometry3D CalculateMesh()
    {
        MeshGeometry3D mesh = new MeshGeometry3D();

        for (int stack = 0; stack <= Stacks; stack++)
        {
            double phi = Math.PI / 2 - stack * Math.PI / Stacks; // kut koji zamisljeni pravac povucen iz sredista koordinatnog sustava zatvara sa XZ ravninom. 
            double y = _radius * Math.Sin(phi); // Odredi poziciju Y koordinate. 
            double scale = -_radius * Math.Cos(phi);

            for (int slice = 0; slice <= Slices; slice++)
            {
                double theta = slice * 2 * Math.PI / Slices; // Kada gledamo 2D koordinatni sustav osi X i Z... ovo je kut koji zatvara zamisljeni pravac povucen iz sredista koordinatnog sustava sa Z osi ( Z = Y ). 
                double x = scale * Math.Sin(theta); // Odredi poziciju X koordinate. Uoči da je scale = -_radius * Math.Cos(phi)
                double z = scale * Math.Cos(theta); // Odredi poziciju Z koordinate. Uoči da je scale = -_radius * Math.Cos(phi)

                Vector3D normal = new Vector3D(x, y, z); // Normala je vektor koji je okomit na površinu. U ovom slučaju normala je vektor okomit na trokut plohu trokuta. 
                mesh.Normals.Add(normal);                
                mesh.Positions.Add(normal + Center);     // Positions dobiva vrhove trokuta. 
                mesh.TextureCoordinates.Add(new Point((double)slice / Slices, (double)stack / Stacks));
                // TextureCoordinates kaže gdje će se neka točka iz 2D-a preslikati u 3D svijet. 
            }
        }

        for (int stack = 0; stack <= Stacks; stack++)
        {
            int top = (stack + 0) * (Slices + 1);
            int bot = (stack + 1) * (Slices + 1);

            for (int slice = 0; slice < Slices; slice++)
            {
                if (stack != 0)
                {
                    mesh.TriangleIndices.Add(top + slice);
                    mesh.TriangleIndices.Add(bot + slice);
                    mesh.TriangleIndices.Add(top + slice + 1);
                }

                if (stack != Stacks - 1)
                {
                    mesh.TriangleIndices.Add(top + slice + 1);
                    mesh.TriangleIndices.Add(bot + slice);
                    mesh.TriangleIndices.Add(bot + slice + 1);
                }
            }
        }

        return mesh;
      }
  }
}
使用系统;
使用System.Windows;
使用System.Windows.Media;
使用System.Windows.Media.Media3D;
名称空间RacunalnaGrafika_研讨会
{
公共类SphereMeshGenerator
{
私有int_片=32;
私有整数=16;
私有点3D_中心=新点3D();
专用双半径=1;
公共整数切片
{
获取{return\u slices;}
设置{u slices=value;}
}
公共整数堆栈
{
获取{return\u stacks;}
设置{u stacks=value;}
}
公共点3D中心
{
获取{return\u center;}
设置{u center=value;}
}
公共双半径
{
获取{return\u radius;}
设置{u radius=value;}
}
公共网格几何三维几何
{
得到
{
返回CalculateMesh();
}
}
专用网格Geometry3D CalculateMesh()
{
MeshGeometry3D mesh=新MeshGeometry3D();

对于(int stack=0;stack好的,我刚刚意识到我不能这样做,因为按钮没有背面定义…在删除定义球体的GeometryModel3D并单击“旋转”按钮后,我注意到同样的事情发生了,这意味着没有按钮背面…我不敢相信我没有更早地想到这一点


感谢所有花时间阅读我的问题的人。

我想你看到的是背面剔除,请查看这篇文章,看看这是否有帮助。老实说,这是我第一次听到背面剔除,然而,正如我在你发布的链接上看到的,这个人只是用代码设置了背面材料来解决问题……然而,我一直在想请记住,在3D三角形中,有一个正面和一个背面,通常由顶点的顺序表示。因为它们通常用于形成“填充”形状对象,如立方体或球体,在面向摄影机的三角形上渲染纹理是没有意义的,这称为背面消隐。你需要在球体上设置一种材质,使其背面看起来像你想要的样子。你的材质只是透明的,试着使用纯色,然后检查这是否是问题所在。这没有帮助…我很抱歉我将背景材质设置为带有红色的solidcolorbrush,当我使材质透明时,我得到的只是一个红色球体。。。