PMG
http://forum.pmg.org.ru/

3D графика без DirectX
http://forum.pmg.org.ru/viewtopic.php?f=4&t=7975
Страница 1 из 1

Автор:  kurlyak [ 21 май 2010 10:57 ]
Заголовок сообщения:  3D графика без DirectX

Я читаю литературу по началам графики и решил составить небольшой примерчик, демонстрирующий 3Д но без DirectX. Конечно мой пример можна проще всего сделать при помощи DirectX или OpenGL но меня заинтересовал сам механизм трехмерной графики поэтому я взялся за этот пример его делать. Пример заключаеться в слеадующем: я в трехмерном пространстве нарисовал куб в начале центра координатной системы трехмерной. Потом вращаю этот куб (при помощи таймера) по оси Y и по часовой стрелке справа на лево, и у меня получаються искажения, артефакты. Вот рисунок куба при повороте на 0 градусов:
Изображение
, вот при повороте на 90 градусов (идут искажения, как буд то наблюдатель справа от меня, меняеться проекция вроде) 90 градусов -
Изображение
. При повороте на 180 проекция сохраняеться
Изображение
и при повороте на 270 опять проекция вроде наблюдатель слева от меня
Изображение
Вот мой код:
Код:
void CCubeNotDXDlg::OnTimer(UINT nIDEvent)
{
   angle+=(3.1415926/180);
   if(angle>3.1415926*2) angle =0;

   Invalidate();
}

void CCubeNotDXDlg::OnPaint()
{
   CPaintDC dc(this); // device context for painting

   float nPoint = 1.0;

   Side[0].x1 = -nPoint;
   Side[0].y1 = nPoint;
   Side[0].z1 = -nPoint;

   Side[0].x2 = nPoint;
   Side[0].y2 = nPoint;
   Side[0].z2 = -nPoint;

   Side[0].x3 = nPoint;
   Side[0].y3 = -nPoint;
   Side[0].z3 = -nPoint;

   Side[0].x4 = -nPoint;
   Side[0].y4 = -nPoint;
   Side[0].z4 = -nPoint;

   Side[1].x1 = nPoint;
   Side[1].y1 = nPoint;
   Side[1].z1 = -nPoint;

   Side[1].x2 = nPoint;
   Side[1].y2 = nPoint;
   Side[1].z2 = nPoint;

   Side[1].x3 = nPoint;
   Side[1].y3 = -nPoint;
   Side[1].z3 = nPoint;

   Side[1].x4 = nPoint;
   Side[1].y4 = -nPoint;
   Side[1].z4 = -nPoint;

   Side[2].x1 = nPoint;
   Side[2].y1 = nPoint;
   Side[2].z1 = nPoint;

   Side[2].x2 = -nPoint;
   Side[2].y2 = nPoint;
   Side[2].z2 = nPoint;

   Side[2].x3 = -nPoint;
   Side[2].y3 = -nPoint;
   Side[2].z3 = nPoint;

   Side[2].x4 = nPoint;
   Side[2].y4 = -nPoint;
   Side[2].z4 = nPoint;

   Side[3].x1 = -nPoint;
   Side[3].y1 = nPoint;
   Side[3].z1 = nPoint;

   Side[3].x2 = -nPoint;
   Side[3].y2 = nPoint;
   Side[3].z2 = -nPoint;

   Side[3].x3 = -nPoint;
   Side[3].y3 = -nPoint;
   Side[3].z3 = -nPoint;

   Side[3].x4 = -nPoint;
   Side[3].y4 = -nPoint;
   Side[3].z4 = nPoint;

   Side[4].x1 = -nPoint;
   Side[4].y1 = nPoint;
   Side[4].z1 = nPoint;

   Side[4].x2 = nPoint;
   Side[4].y2 = nPoint;
   Side[4].z2 = nPoint;

   Side[4].x3 = nPoint;
   Side[4].y3 = nPoint;
   Side[4].z3 = -nPoint;

   Side[4].x4 = -nPoint;
   Side[4].y4 = nPoint;
   Side[4].z4 = -nPoint;

   Side[5].x1 = -nPoint;
   Side[5].y1 = -nPoint;
   Side[5].z1 = nPoint;

   Side[5].x2 = nPoint;
   Side[5].y2 = -nPoint;
   Side[5].z2 = nPoint;

   Side[5].x3 = nPoint;
   Side[5].y3 = -nPoint;
   Side[5].z3 = -nPoint;

   Side[5].x4 = -nPoint;
   Side[5].y4 = -nPoint;
   Side[5].z4 = -nPoint;

   for (int i = 0; i < 6; i++)
   {

      //поворачиваем вокруг Y
      Side[i].x1 = Side[i].x1 * cos(angle) + Side[i].y1 * 0 - Side[i].z1 * sin(angle);
      Side[i].z1 = Side[i].x1 * -sin(angle)+ Side[i].y1 * 0 - Side[i].z1 * cos(angle);

      Side[i].x2 = Side[i].x2 * cos(angle) + Side[i].y2 * 0 - Side[i].z2 * sin(angle);
      Side[i].z2 = Side[i].x2 * -sin(angle)+ Side[i].y2 * 0 - Side[i].z2 * cos(angle);

      Side[i].x3 = Side[i].x3 * cos(angle) + Side[i].y3 * 0 - Side[i].z3 * sin(angle);
      Side[i].z3 = Side[i].x3 * -sin(angle)+ Side[i].y3 * 0 - Side[i].z3 * cos(angle);

      Side[i].x4 = Side[i].x4 * cos(angle) + Side[i].y4 * 0 - Side[i].z4 * sin(angle);
      Side[i].z4 = Side[i].x4 * -sin(angle)+ Side[i].y4 * 0 - Side[i].z4 * cos(angle);


      
      //мировая трансформация

      Side[i].x1+=0;
      Side[i].y1+=0;
      Side[i].z1+=4;

      Side[i].x2+=0;
      Side[i].y2+=0;
      Side[i].z2+=4;

      Side[i].x3+=0;
      Side[i].y3+=0;
      Side[i].z3+=4;

      Side[i].x4+=0;
      Side[i].y4+=0;
      Side[i].z4+=4;

      //перспективная трансформация
   
      Side[i].x1 /= Side[i].z1;
      Side[i].y1 /= Side[i].z1;
      
      Side[i].x2 /= Side[i].z2;
      Side[i].y2 /= Side[i].z2;

      Side[i].x3 /= Side[i].z3;
      Side[i].y3 /= Side[i].z3;

      Side[i].x4 /= Side[i].z4;
      Side[i].y4 /= Side[i].z4;



      //экранная трансформация
      RECT rect;
      GetClientRect(&rect);
         
      Side[i].x1 = Side[i].x1 * rect.right/2 + rect.right/2;
      Side[i].y1 = (-Side[i].y1) * rect.bottom/2 + rect.bottom/2;

      Side[i].x2 = Side[i].x2 * rect.right/2 + rect.right/2;
      Side[i].y2 = (-Side[i].y2) * rect.bottom/2 + rect.bottom/2;

      Side[i].x3 = Side[i].x3 * rect.right/2 + rect.right/2;
      Side[i].y3 = (-Side[i].y3) * rect.bottom/2 + rect.bottom/2;

      Side[i].x4 = Side[i].x4 * rect.right/2 + rect.right/2;
      Side[i].y4 = (-Side[i].y4) * rect.bottom/2 + rect.bottom/2;
      
      CPen penBlue;

      penBlue.CreatePen(PS_SOLID, 3, RGB(0, 0, 255));

      CPen* ppenOld;
      ppenOld=dc.SelectObject(&penBlue);

      dc.MoveTo(Side[i].x1, Side[i].y1);
      
      dc.LineTo(Side[i].x2, Side[i].y2);
      dc.LineTo(Side[i].x3, Side[i].y3);
      dc.LineTo(Side[i].x4, Side[i].y4);
      dc.LineTo(Side[i].x1, Side[i].y1);

      dc.SelectObject(ppenOld);
   }
   if (IsIconic())
   {
      ...................      
   }
   else
   {
      CDialog::OnPaint();
   }
}


Автор:  MagicWolf [ 21 май 2010 11:40 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Какую литературу?

Автор:  kurlyak [ 28 май 2010 12:12 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Значит я читаю Ла Мот главу "Третье измерение" и еще скачал с интернета, автора не знаю какой то курс лекций на 2 тыс страниц ПДФ на английском языке называеться "Graphics programming with DirectX". Там подробно описываеться как сделать то что я спрашиваю на форуме здесь, но в виде псевдокода. Исходников к Ла Моту у меня тоже нету. То есть не знаю. Когда кубик согласно этому коду поворачиваеться, то вроде меняеться положение осей получаеться, в частности оси Z потому что выходит глядя на картинки что при 90 градусов ось Z меняет направление, потому что проекция справа на лево, вроде наблюдатель справа от кубика, а не как прямо смотрит в экран при 0 градусов или 360. Что делать?

Автор:  MagicWolf [ 29 май 2010 17:11 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Какая у тебя проекция?

Автор:  MagicWolf [ 31 май 2010 08:57 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Мне кажется, что тебе надо почитать для начала Эйнджела или Хилла, а потом уже переходить к реализации собственного конвейра рендеринга.

Автор:  kurlyak [ 07 июн 2010 07:46 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Просмотрел я эти книги - к сожалению у меня сложности с математикой, да к тому же я изучаю DirectX а не OpenGL - я в этих книгах вобщим не нашел для себя ответов. Может быть вы могли бы уточнить именно какая страница в этих книгах или глава, что бы я почитал. А то я не нашел эту информацию что мне нужно. Кроме того проекцию я создаю когда делю на z координаты x,y каждой вершины. Так написано в той литературе что я читал. Как еще дополнительно что нужно сделать, что бы проекция была правильная? Может если Вам не сложно подскажете?

Автор:  MagicWolf [ 07 июн 2010 08:35 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Я думая тебе надо прочитать главу 5 от Эйнджела.

Автор:  kurlyak [ 07 июн 2010 14:59 ]
Заголовок сообщения:  Re: 3D графика без DirectX

Дело было оказываеться не в проекции. Дело в том, что координаты которые участруют в повороте должны были быть сохранены перед поворотом, что бы участвовали не преобразованные координаты. Я думаю понятно будет если выложить код:
Код:
Temp[0].y1 = Side[i].y1;
Temp[0].z1 = Side[i].z1;

Temp[0].y2 = Side[i].y2;
Temp[0].z2 = Side[i].z2;

Temp[0].y3 = Side[i].y3;
Temp[0].z3 = Side[i].z3;

Temp[0].y4 = Side[i].y4;
Temp[0].z4 = Side[i].z4;
      

//вращение по X при помощи матриц
Side[i].y1 = Temp[0].y1 * cos(angle)  + Temp[0].z1 * -sin(angle);
Side[i].z1 = Temp[0].y1 * sin(angle)+ Temp[0].z1 * cos(angle);

Side[i].y2 = Temp[0].y2 * cos(angle) + Temp[0].z2 * -sin(angle);
Side[i].z2 = Temp[0].y2 * sin(angle)+ Temp[0].z2 * cos(angle);

Side[i].y3 = Temp[0].y3 * cos(angle) + Temp[0].z3 * -sin(angle);
Side[i].z3 = Temp[0].y3 * sin(angle)+ Temp[0].z3 * cos(angle);

Side[i].y4 = Temp[0].y4 * cos(angle) + Temp[0].z4 * -sin(angle);
Side[i].z4 = Temp[0].y4 * sin(angle)+ Temp[0].z4 * cos(angle);

MagicWolf спасибо за поддержку!

Автор:  jec [ 16 июл 2010 18:17 ]
Заголовок сообщения:  Re: 3D графика без DirectX

да ну нафиг так стараться писать без библиотек как раз для этого сделанных
я бы за то времяя пока ты написал бы как сделать куб сделал уже загрузку модели в ДХ

Страница 1 из 1 Часовой пояс: UTC + 3 часа [ Летнее время ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/