0

各ポイントに 3 次元を使用してポイントを作成し、直交投影を使用してポイントを表示する場合、-near サーフェス上のポイントのみが表示される理由はありますか? たとえば、(SharpGL メソッド) を使用する場合、gl.Ortho(0, width, height, 0, -10, 10)実際には z=10 の点のみが表示されます (近い面は -10 であるため)。

私は現在 SharpGL を使用していますが、私が抱えている問題がその特定の実装/ライブラリにないことを願っています。

編集:問題を示す以下のコードを追加しています。この例には SharpGL が必要であり、実際には現在の SharpGL ソース コードに付属する WPF サンプル プロジェクトを変更したものであることに注意してください (元のサンプル プロジェクトは TwoDSample と呼ばれます)。

プロジェクトには MainWindow.xaml と MainWindow.xaml.cs が必要です。xaml は次のとおりです。

<Window x:Class="TwoDSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:my="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF">
    <Grid>
        <my:OpenGLControl Name="openGLControl1" OpenGLDraw="openGLControl1_OpenGLDraw" OpenGLInitialized="openGLControl1_OpenGLInitialized"
                          Resized="openGLControl1_Resized"/>
    </Grid>
</Window>

コードビハインドは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SharpGL.Enumerations;

namespace TwoDSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        // NOTE: I use this to restrict the openGLControl1_OpenGLDraw method to 
        // drawing only once after m_drawCount is set to zero;
        int m_drawCount = 0;
        private void openGLControl1_OpenGLDraw(object sender,     SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            // NOTE: Only draw once after m_drawCount is set to zero
            if (m_drawCount < 1)
            {
                //  Get the OpenGL instance.
                var gl = args.OpenGL;

                gl.Color(1f, 0f, 0f);
                gl.PointSize(2.0f);

                //  Draw 10000 random points.
                gl.Begin(BeginMode.Points);
                Random random = new Random();
                for (int i = 0; i < 10000; i++)
                {
                    double x = 10 + 400 * random.NextDouble();
                    double y = 10 + 400 * random.NextDouble();
                    double z = (double)random.Next(-10, 0);

                    // Color the point according to z value
                    gl.Color(0f, 0f, 1f);  // default to blue
                    if (z == -10)
                        gl.Color(1f, 0f, 0f);   // Red for z = -10
                    else if (z == -1)
                        gl.Color(0f, 1f, 0f);   // Green for z = -1

                    gl.Vertex(x, y, z);
                }

                    gl.End();
                    m_drawCount++;
                }
            }

            private void openGLControl1_OpenGLInitialized(object sender,     SharpGL.SceneGraph.OpenGLEventArgs args)
        {

        }

        private void openGLControl1_Resized(object sender,     SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            // NOTE: force the draw routine to happen again when resize occurs
            m_drawCount = 0;
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            //  Create an orthographic projection.
            gl.MatrixMode(MatrixMode.Projection);
            gl.LoadIdentity();

            // NOTE: Basically no matter what I do, the only points I see are those at
            // the "near" surface (with z = -zNear)--in this case, I only see green points
            gl.Ortho(0, openGLControl1.ActualWidth, openGLControl1.ActualHeight, 0, 1, 10);

            //  Back to the modelview.
            gl.MatrixMode(MatrixMode.Modelview);
        }
    }
}
4

1 に答える 1

1

深度バッファと少しのグーグルについての MadcoreTom のコメントのおかげで、解決策 (または少なくとも「a」) を見つけたと思います。描画ルーチンの開始時に深度バッファーをクリアすると (そして z == -10 ではなく z == -9 の場合、色は赤を指します。これは random.Next(-10,0) が -10 の値を与えないためです) )、THEN は期待どおりに動作しているようです。

すべての z 値 (Ortho 制限内) でポイントを表示するために、openGlControl1_OpenGLDraw メソッドを次のように置き換えました。

    private void openGLControl1_OpenGLDraw(object sender,     SharpGL.SceneGraph.OpenGLEventArgs args)
    {
        // NOTE: Only draw once after m_drawCount is set to zero
        if (m_drawCount < 1)
        {
            //  Get the OpenGL instance.
            var gl = args.OpenGL;

            // ADDED THIS LINE
            gl.Clear(SharpGL.OpenGL.GL_DEPTH_BUFFER_BIT);

            gl.Color(1f, 0f, 0f);
            gl.PointSize(2.0f);

            //  Draw 10000 random points.
            gl.Begin(BeginMode.Points);
            Random random = new Random();
            for (int i = 0; i < 10000; i++)
            {
                double x = 10 + 400 * random.NextDouble();
                double y = 10 + 400 * random.NextDouble();
                double z = (double)random.Next(-10, 0);

                // Color the point according to z value
                gl.Color(0f, 0f, 1f);  // default to blue
                if (z == -9)
                    gl.Color(1f, 0f, 0f);   // Red for z = -10
                else if (z == -1)
                    gl.Color(0f, 1f, 0f);   // Green for z = -1

                gl.Vertex(x, y, z);
            }

                gl.End();
                m_drawCount++;
            }
        }
于 2012-06-06T04:37:57.627 に答える