Помогите новичку с Tao Framework и list объектов

Добрый день, хочу реализовать с помощью OpenGL (Tao Framework) программу которая б создавала атомы в пространстве по указанным координатам (как бы кристаллическую решетку) и можно было манипулировать этими объектами (вращать, передвигать), также надо это сделать компонентом, чтоб можно было просто в другие проекты вставлять, и все это нужно для моего универа. Суть проблемы в том, что вроде все правильно, а работает с глюками. Создает атомы, по координатам, вращает, но через несколько поворотов/созданий, исчезают все атомы кроме первого созданного атома, я пока не понимаю почему так происходит. Работаю без таймера, графика рисуется и обновляется по событию (к примеру кнопки вращения или добавления нового атома).

Вот код, не могу понять своей ошибки =(
/*http://esate.ru, OniKy*/


using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
// для работы с библиотекой OpenGL 
using Tao.OpenGl;
// для работы с библиотекой FreeGLUT 
using Tao.FreeGlut;
// для работы с элементом управления SimpleOpenGLControl 
using Tao.Platform.Windows;
 
namespace WindowsFormsControlLibrary1
{
   public partial class UserControl1 : UserControl
   {
 
      Atom[] SomeAtom = new Atom[9999];
      public int AtomNum = 0;
 
      public double rotX = 0; //повороты
      public double rotY = 0;
      public double rotZ = 0;
      public double rot = 0;
 
      class Atom
      {
        private int AtomID; // идентификатор/номер Атома
        private double X = 0;
        private double Y = 0;
        private double Z = 0;
        private string Color = "red";
 
        public int ID // метод присовения ИД
        {
           get { return AtomID; }
           set { AtomID = value; }
        }
 
        public double x
        {
           get { return X; }
           set { X = value; }
        }
 
        public double y
        {
           get { return Y; }
           set { Y = value; }
        }
 
        public double z
        {
           get { return Z; }
           set { Z = value; }
        }
 
        public string color
        {
           get { return Color; }
           set { Color = value; }
        }
 
 
      }
 
      public UserControl1()
      {
        InitializeComponent();
        GraphicsWindow.InitializeContexts(); //Инициализация OpenGL
      }
 
      private void DrawMatrix(int x)
      {
        float quad_size = 1;
 
        // две последовательно линий после пересечения создадут "матрицу" чтобы мы могли понимать где находится центр
        Gl.glBegin(Gl.GL_LINES);
 
        Gl.glColor3f(0.0f, 0.0f, 0.0f);
 
        Gl.glVertex3d(0, 0, 0 - (x / 2));
        Gl.glVertex3d(0, 0, quad_size * (x / 2));
 
        Gl.glVertex3d(0 - (x / 2), 0, 0);
        Gl.glVertex3d(quad_size * (x / 2), 0, 0);
 
        Gl.glColor3f(0.7f, 0.7f, 0.7f);
 
        for (int ax = -(x / 2); ax < (x / 2)+1; ax++)
        {
           Gl.glVertex3d(quad_size * ax, 0, 0 - (x / 2));
           Gl.glVertex3d(quad_size * ax, 0, quad_size * (x / 2));
        }
 
        for (int bx = -(x / 2); bx < (x / 2)+1; bx++)
        {
           Gl.glVertex3d(0 - (x / 2), 0, quad_size * bx);
           Gl.glVertex3d(quad_size * (x / 2), 0, quad_size * bx);
        }
 
        Gl.glEnd();
      }
 
      private void Visualization()
      {
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
 
        Gl.glLoadIdentity();
 
        Gl.glPushMatrix();
 
        Gl.glTranslated(0, 0, -12);
        Gl.glRotated(45+rotX, 1, 0, 0);
        Gl.glRotated(rotY, 0, 1, 0);
        Gl.glRotated(rotZ, 0, 0, 1);
        
        DrawMatrix(10);
 
        Gl.glColor3f(1.0f, 0, 0);
 
        for (int i = 0; i <= AtomNum; i++)
        {
           try
           {
              Gl.glPushMatrix();
              Gl.glTranslated(SomeAtom[i].x, SomeAtom[i].y, SomeAtom[i].z);
              Gl.glRotated(rot, 1, 1, 0);
 
              // рисуем сферу с помощью библиотеки FreeGLUT 
              Glut.glutWireSphere(0.5, 8, 8);
 
              Gl.glPopMatrix();
              
           }
           catch
           {
              //MessageBox.Show("Ошибка!");
           }
        }
 
        Gl.glPopMatrix();
        Gl.glFlush();
 
        GraphicsWindow.Invalidate();
      }
 
      private void UserControl1_Load(object sender, EventArgs e)
      {
        // инициализация Glut 
        Glut.glutInit();
        Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
 
        // очитка окна 
        Gl.glClearColor(255, 255, 255, 1);
 
        // установка порта вывода в соотвествии с размерами элемента anT 
        Gl.glViewport(0, 0, GraphicsWindow.Width, GraphicsWindow.Height);
 
 
        // настройка проекции 
        Gl.glMatrixMode(Gl.GL_PROJECTION);
        Gl.glLoadIdentity();
        Glu.gluPerspective(45, (float)GraphicsWindow.Width / (float)GraphicsWindow.Height, 0.1, 200);
        Gl.glMatrixMode(Gl.GL_MODELVIEW);
        Gl.glLoadIdentity();
 
        Gl.glEnable(Gl.GL_DEPTH_TEST);
        Gl.glEnable(Gl.GL_LIGHTING);
        Gl.glEnable(Gl.GL_LIGHT0);
 
        // настройка параметров OpenGL для визуализации 
        Gl.glEnable(Gl.GL_DEPTH_TEST);
 
        SomeAtom[0] = new Atom(); //чтоб самим не рисовать уже в программе, изначально создадим квадрат из атомов
        SomeAtom[0].x = -2.0f;
        SomeAtom[0].y = 0.0f;
        SomeAtom[0].z = -2.0f;
        AtomNum++;
 
        SomeAtom[1] = new Atom();
        SomeAtom[1].x = 2.0f;
        SomeAtom[1].y = 0.0f;
        SomeAtom[1].z = -2.0f;
        AtomNum++;
 
        SomeAtom[2] = new Atom();
        SomeAtom[2].x = -2.0f;
        SomeAtom[2].y = 0.0f;
        SomeAtom[2].z = 2.0f;
        AtomNum++;
 
        SomeAtom[3] = new Atom();
        SomeAtom[3].x = 2.0f;
        SomeAtom[3].y = 0.0f;
        SomeAtom[3].z = 2.0f;
        AtomNum++;
 
        Visualization();
      }
 
      private void button2_Click(object sender, EventArgs e)
      {
        SomeAtom[AtomNum] = new Atom();
        SomeAtom[AtomNum].x = Convert.ToDouble(numericUpDown1.Value);
        SomeAtom[AtomNum].y = Convert.ToDouble(numericUpDown2.Value);
        SomeAtom[AtomNum].z = Convert.ToDouble(numericUpDown3.Value);
        AtomNum++;
 
        Visualization();
      }
 
      private void button3_Click(object sender, EventArgs e)
      {
        rotX += 5;
        Visualization();
        label4.Text = Convert.ToString(rotX);
      }
 
      private void button4_Click(object sender, EventArgs e)
      {
        rotX -= 5;
        Visualization();
      }
   }
}
0       713        22.12.2010        8

0  
22.12.2010 00:00:00
Забавная ошибка.
Собрал проект как у вас — действительно исчезают сспустя пару секунд визуализации.

Виноват во всем таинственный 5-й атом :) Который не существует, но его визуализация вызывает ошибку, но не сразу

for (int i = 0; i <= AtomNum; i++)

Здесь должно быть

for (int i = 0; i < AtomNum; i++)

Иначе при визуализации мы передаем в функцию glTranslate судя по всему какой-то мусор, который и сбивает нам визуализацию, спустя десяток кадров.

0  
24.12.2010 00:00:00
хм, спасибо) разобрался, еще по дописывал пару функций, сделал как компонент, и снова появилась проблема. Если на форме более 1-го компонента, и в компоненте сразу инициализируется графика, то выкидывает из студии даже не написав ошибку, решил сделать так, чтоб графика инициализировалась по событию (по нажатию кнопки к прим.), тогда компонент уже в студии создается, и можно вытаскивать на форму сколько угодно. Вот, только как реализовать, чтоб визуализировалась графика в каждом компоненте не зависимо друг от друга. Плиз хелп, снова застопорился. Ссылка на мой проект.
0  
24.12.2010 00:00:00
Несколько компонентов не пробовал, но мне кажется, что это неверный подход и так работать не будет.
0  
24.12.2010 00:00:00
А как же тогда реализовать чтоб в одном проекте было несколько OpenGl окошек? получается никак? или есть варианты и я просто делаю не так )
0  
24.12.2010 00:00:00
А множественные области просмотра не подойдут?
0  
24.12.2010 00:00:00
0  
24.12.2010 00:00:00
Для меня б подошло, прям как в 3д максе можно было б сделать. Но преподаватель настойчиво хочет, можно было сделать мульти сди проект (как в фотошопе при открытии более 1го рисунка), где много форм, на каждую форму закинуть по компоненту. Чтоб открыв одну модель атома, можно было открыть другую в другом окне и сравнить, или открыть две модели одного и того же атома, и экспериментировать с одним компонентом, и наблюдать изменения.
0  
24.12.2010 00:00:00
Была у меня книжка давно

там было много по работе с MFC и (вроде как раз MDI/SDI приложения) и под конец были примеры интеграции OpenGL.

Точно не уверен, но возможно как раз будет в тему
^