首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >渲染WPF应用程序以获取.jpg / .png格式的输出

渲染WPF应用程序以获取.jpg / .png格式的输出
EN

Stack Overflow用户
提问于 2014-03-06 20:06:55
回答 1查看 629关注 0票数 1

我需要渲染一个从AutoDesk 3DS max导入的.obj,以获得jpg或png文件格式的输出。我该怎么做呢?我使用的是Expression blend 4和WPF Visual Studio。

EN

回答 1

Stack Overflow用户

发布于 2014-03-06 23:02:44

使用SharpGL,这是一个C#库,它使在C#应用程序中使用OpenGL变得非常容易。它包括对直接加载.obj文件的支持。

双重编辑:我已经将我的代码示例替换为使用它们的实现。我已经运行了下面的代码,它确实可以工作,它加载了一个.obj并在屏幕上呈现它,没有任何问题

XAML ..Make确保您添加了

代码语言:javascript
运行
复制
xmlns:sharpGL="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF"

添加到窗口属性

代码语言:javascript
运行
复制
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Orientation="Horizontal">
        <Button Content="Add Item" Click="Add_Click" />
        <Button Content="Take Screen Shot" Click="ScreenShot_Click" />
    </StackPanel>

    <sharpGL:OpenGLControl Grid.Row="1" Name="myOpenGLControl"
        OpenGLDraw="OpenGLControl_OpenGLDraw" OpenGLInitialized="OpenGLControl_OpenGLInitialized"
        RenderContextType="FBO" />
</Grid>

代码隐藏

注释:我实际上还没有实现图形的保存,但在这一点上,您可以在屏幕上呈现模型的预览。

代码语言:javascript
运行
复制
public partial class MainWindow : Window
{
    float rotation_angle = 0f;
    float rotation_x = 0f;
    float rotation_y = 0f;
    float rotation_z = 0f;

    private List<Polygon> _polygons = new List<Polygon>();

    public MainWindow()
    {
        InitializeComponent();

        myOpenGLControl.OpenGL.Enable(OpenGL.GL_TEXTURE_2D);
    }

    private void OpenGLControl_OpenGLDraw(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
    {
        OpenGL gl = args.OpenGL;

        // Clear The Screen And The Depth Buffer
        gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

        // Move Left And Into The Screen
        gl.LoadIdentity();
        gl.Translate(0.0f, -1.0f, -10.0f);

        gl.Rotate(rotation_angle, rotation_x, rotation_y, rotation_z);

        foreach (Polygon polygon in _polygons)
        {
            polygon.PushObjectSpace(gl);
            polygon.Render(gl, SharpGL.SceneGraph.Core.RenderMode.Render);
            polygon.PopObjectSpace(gl);
        }

        rotation_angle += 3;
        rotation_x = 0;
        rotation_y = 20;
        rotation_z = -5;
    }

    private void OpenGLControl_OpenGLInitialized(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
    {
        OpenGL gl = args.OpenGL;

        gl.Enable(OpenGL.GL_DEPTH_TEST);

        float[] global_ambient = new float[] { 0.5f, 0.5f, 0.5f, 1.0f };
        float[] light0pos = new float[] { 0.0f, 5.0f, 10.0f, 1.0f };
        float[] light0ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
        float[] light0diffuse = new float[] { 0.3f, 0.3f, 0.3f, 1.0f };
        float[] light0specular = new float[] { 0.8f, 0.8f, 0.8f, 1.0f };

        float[] lmodel_ambient = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
        gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);

        gl.LightModel(OpenGL.GL_LIGHT_MODEL_AMBIENT, global_ambient);
        gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, light0pos);
        gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, light0ambient);
        gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, light0diffuse);
        gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_SPECULAR, light0specular);
        gl.Enable(OpenGL.GL_LIGHTING);
        gl.Enable(OpenGL.GL_LIGHT0);

        gl.ShadeModel(OpenGL.GL_SMOOTH);
    }

    private void Add_Click(object sender, RoutedEventArgs e)
    {
        List<Polygon> polygons = LoadScene("ducky.obj");
        polygons.ScaleMaxExtentTo(10);
        _polygons.AddRange(polygons);
    }

    private void ScreenShot_Click(object sender, RoutedEventArgs e)
    {
        //Here you can use either of the below methods to get the raw pixel data
        //which needs to be manually formatted for the file type of your choice.
        //myOpenGLControl.OpenGL.ReadBuffer();
        //myOpenGLControl.OpenGL.ReadPixels();
    }

    private List<Polygon> LoadScene(string filePath)
    {
        List<Polygon> polygons = new List<Polygon>();
        Scene scene = SerializationEngine.Instance.LoadScene(filePath);
        if (scene != null)
        {
            polygons.AddRange(scene.SceneContainer.Traverse<Polygon>());
        }

        return polygons;
    }
}

public static class ExtensionMethods
{
    /// <summary>Scales the polygons to not excede the maximum size in OpenGL Units.</summary>
    public static void ScaleMaxExtentTo(this List<Polygon> polygons, float maxSize)
    {
        foreach (var polygon in polygons) { polygon.ScaleMaxExtentTo(maxSize); }
    }

    /// <summary>Scales the polygon to not excede the maximum size in OpenGL Units.</summary>
    public static void ScaleMaxExtentTo(this Polygon polygon, float maxSize)
    {
        float[] extent = new float[3];
        polygon.BoundingVolume.GetBoundDimensions(out extent[0], out extent[1], out extent[2]);
        float maxExtent = extent.Max();
        float scaleFactor = maxExtent > maxSize ? maxSize / maxExtent : 1;
        polygon.Transformation.ScaleX = scaleFactor;
        polygon.Transformation.ScaleY = scaleFactor;
        polygon.Transformation.ScaleZ = scaleFactor;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22224022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档