Использование OpenTK (z-индексация)

Я делаю что-то среднее между некоторыми учебными пособиями NeHe (перевожу их в OpenTK) и образцом OpenTK, который я нашел в Интернете, чтобы нарисовать треугольник (для простой начальной настройки):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.IO;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Windows.Forms;

namespace GravSimBasic
{
    class GLMain : GameWindow
    {
        int vbo;
        Vector3[,] vertices;

        float time = 0.01f;

        void CreateVertexBuffer()
        {
            vertices = new Vector3[2,3];
            vertices[0,0] = new Vector3(-1f, -1f, (float)Math.Sin(time));
            vertices[0, 1] = new Vector3(0.5f, -1f, (float)Math.Sin(time));
            vertices[0, 2] = new Vector3(-0.25f, 1f, -(float)Math.Sin(time));
            vertices[1, 0] = new Vector3(-0.5f, -1f, (float)Math.Cos(time));
            vertices[1, 1] = new Vector3(1f, -1f, (float)Math.Cos(time));
            vertices[1, 2] = new Vector3(0.25f, 1f, -(float)Math.Cos(time));

            //MessageBox.Show("Length: " + vertices.Length.ToString());

            GL.GenBuffers(1, out vbo);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                                   new IntPtr(vertices.Length * Vector3.SizeInBytes),
                                   vertices, BufferUsageHint.StaticDraw);
        }

        protected override void OnLoad(EventArgs e)
        {
            //set the window area
            GL.Viewport(0, 0, 400, 400);
            //background color
            GL.ClearColor(Color.Black);
            //set the view area
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(-2, 2, -2, 2, 2, -2);
            //now back to 'scene editing' mode
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
            //make things look nice
            GL.ShadeModel(ShadingModel.Smooth);

            //set up our z-rendering logic
            GL.ClearDepth(2.0000f);
            GL.Enable(EnableCap.DepthTest);
            GL.DepthFunc(DepthFunction.Lequal);

            //other improvements to quality
            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
            GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
            //initialize our scene data
            CreateVertexBuffer();

        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            time += 0.01f;
            vertices[0, 0].Z = (float)Math.Sin(time);
            vertices[0, 1].Z = (float)Math.Sin(time);
            vertices[0, 2].Z = -(float)Math.Sin(time);
            vertices[1, 0].Z = (float)Math.Cos(time);
            vertices[1, 1].Z = (float)Math.Cos(time);
            vertices[1, 2].Z = -(float)Math.Cos(time);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                                   new IntPtr(vertices.Length * Vector3.SizeInBytes),
                                   vertices, BufferUsageHint.StaticDraw);
            System.Threading.Thread.Sleep(10);



            GL.Clear(ClearBufferMask.ColorBufferBit);

            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.Color4(0.75f,0.0f,0.0f,0.25f);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);

            GL.DrawArrays(BeginMode.Triangles, 0, 3);

            GL.Color4(0.0f, 0.75f, 0.0f, 0.55f);
            GL.VertexAttribPointer(3, 3, VertexAttribPointerType.Float, false, 0, 0);
            GL.DrawArrays(BeginMode.Triangles, 3, 3);

            GL.DisableVertexAttribArray(0);

            SwapBuffers();
        }
    }
}

Я подозреваю, что проблема в строках 58-60, но я изменил значение в строке 58 между -2,0, 0,00001 и 2,0, результаты не изменились. Однако это может быть настройка перспективы несколькими строками ранее. Я перепробовал почти все функции, доступные в качестве параметра для строки 60. Lequal кажется лучшим вариантом из того, что я ожидал, и он дает наиболее близкий результат к тому, что я хочу, но он не совсем правильно.

Установка: есть зеленый и красный треугольник. Они частично перекрываются по оси x-y. Верхняя ось z одного отображается функцией -sin(time), а нижняя — функцией sin(time). Другой использует cos() вместо sin, но в остальном то же самое. Значение «время» меняется при каждом рендеринге.

Что я хочу/ожидаю: Два перекрывающихся треугольника - один красный, один зеленый. Поскольку они вращаются вперед и назад, неперекрывающаяся часть каждого из них всегда должна быть видна, а перекрывающиеся части должны показывать только передний треугольник.

Что я получаю: (а) ничего (б) отображение обоих треугольников, один поверх другого. (c) Меняющееся изображение битов одного, обоих или ни одного из треугольников - даже если один или оба показаны, это биты любого треугольника, которые должны быть видны, а которые отсутствуют (фон).

Если убрать время, то показывает правильный снимок - красный треугольник спереди в нижней половине, а зеленый впереди сверху.

Кто-нибудь может помочь диагностировать это?


person S James S Stapleton    schedule 06.10.2012    source источник


Ответы (1)


В строке 86 вы очищаете только буфер цвета, а не буфер глубины, поэтому любые изменения в строке 58 не будут иметь никакого эффекта:

 GL.Clear(ClearBufferMask.ColorBufferBit);

Я никогда не использовал OpenTK, но я думаю, что это должно быть что-то вроде этого:

 GL.Clear(ClearBufferMask.ColorBufferBit|ClearBufferMask.DepthBufferBit);
person zacaj    schedule 06.10.2012
comment
У меня нет представителя, чтобы модифицировать вас, но это все исправило. Спасибо. - person S James S Stapleton; 06.10.2012