Пожалуйста, помогите!
Уважаемые господа, расскажите, пожалуйста, как в Direct3D изображать сферы, конусы и цилиндры. Я знаю, что прямого способа для этого нет. Если не трудно, дайте ссылки по теме. Заранее благодарен.
Есть алгоритм для OpenGL.
Есть алгоритм для OpenGL.
Но мне нужно хотя бы словесное описание того, как это делается.
Но мне нужно хотя бы словесное описание того, как это делается.
Ниже приводится алгоритм построения цилиндра с криволинейными образующими. Имеется массив радиусов, задающий радиусы вдоль оси цилиндра. (Надеюсь, из этого понятно, что из себя этот цилиндр представляет.) Ось симметрии цилиндра перпендикулярна его основанию.
Вот алгоритм [не самый оптимальный, конечно :), но работает]. Берешь два значения угла: ang и ang + d_ang. (Так как у тебя в градусах, то сначала берешь 0 и 0 + 2 = 2.) Далее строишь кусок поверхности цилиндра между двумя образующими цилиндра, соответствующими этим углам, следующим образом: пробегаешь весь массив радиусов и для каждого из них добавляешь точки вызовами glVertex (функция добавления точки в последовательность ломаной), как показано на рисунке (надо выставить режим соединения точек отрезками). Надеюсь, я понятно нарисовал (строится "снизу вверх"):
12,15_******_10,13_(r = 3)
______*___**
______*__*_*
______*_*__*
______**___*
_8,11_******_6,9___(r = 2)
______*___**
______*__*_*
______*_*__*
______**___*
__4,7_******_2,5___(r = 1)
______*___**
______*__*_*
______*_*__*
______**___*
__0,3_******_1_____(r = 0, если массив радиусов нумеруется с нуля)
(Последовательность вызовов glVertex происходит в порядке возрастания индексов точек: 0, 1, 2, ... Там, где у точки два индекса, она добавляется два раза. То есть, начиная с точки 0, добавляем затем точку 1, затем 2, затем 3, но точка 3 совпадает с 0. Это надо для того, чтобы нарисовать диагональ прямоугольника.) И так далее до последнего радиуса. Получишь кусок поверхности цилиндра между двумя его образующими, аппроксимированный четырехугольниками. [Можно и без диагоналей, но так, имхо, красивше %) ] Далее берешь углы 2 и 4 и для них повторяешь ту же последовательность действий. И так далее, пока не сделаешь полный круг.
На Пасквиле выглядит примерно так (я этот код пишу на шару; не запускал, не отлаживал):
glBegin();
for ang := 0 to 180 do
{RCount - количество радиусов; Radius - массив радиусов}
for r := 0 to RCount - 2 do
begin{ось симметрии цилиндра - ось Z}
glVertex3f(Radius[r] * cos((ang + 1) * 2.0), Radius[r] * sin((ang + 1) * 2.0), r);{точка 0}
glVertex3f(Radius[r] * cos(ang), Radius[r] * sin(ang), r);{точка 1}
glVertex3f(Radius[r + 1] * cos(ang), Radius[r + 1] * sin(ang), r + 1);{точка 2}
glVertex3f(Radius[r] * cos((ang + 1) * 2.0), Radius[r] * sin((ang + 1) * 2.0), r);{точка 3}
end;
glEnd;
Если очень надо, могу кинуть исходник на билдере.
Спасибо, но мне бы хотелось увидеьб, как рисовать подобные фигуры из треугольников, как это делается в Direct3D
Так в чем проблема? Немножко изменив алгоритм, можно получить нужный вывод. Просто делай обход фигуры треугольниками. Вообще, если тебе нужно оптимальное покрытие поверхности, почитай какую-нибудь книгу по вычислительной геометрии, есть стандартные алгоритмы триангуляции. Я этим не занимался никогда, поскольку мне и приведенного выше хватало. Вообще-то подумай, а надо ли тебе это?
FLOAT d,FLOAT phi1,FLOAT phi2)
{
FLOAT z=0.0f, n=1.0f;
FLOAT dphi=(phi2-phi1)/24;
FLOAT rsm=r-w;
FLOAT sinphi,cosphi,phi=phi2;
for (int i=0;i<25;i++,phi+=dphi) {
sinphi=-sinf(phi);
cosphi=cosf(phi);
pV[2*i].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z);
pV[2*i].normal=D3DXVECTOR3(z,z,-n);
pV[2*i+1].position=D3DXVECTOR3(base.x+r*sinphi,base.y+r*cosphi,base.z);
pV[2*i+1].normal=D3DXVECTOR3(z,z,-n);
}
pV[50].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z+d);
pV[50].normal=D3DXVECTOR3(z,z,z);
pV[51].position=D3DXVECTOR3(base.x+r*sinphi,base.y+r*cosphi,base.z+d);
pV[51].normal=D3DXVECTOR3(z,z,z);
// Вот тут непонятно
phi-=dphi;
for (i=0;i<25;i++,phi-=dphi) {
sinphi=-sinf(phi);
cosphi=cosf(phi);
pV[52+2*i].position=D3DXVECTOR3(base.x+r*sinphi,base.y+r*cosphi,base.z);
pV[52+2*i].normal=D3DXVECTOR3(sinphi,cosphi,z);
pV[52+2*i+1].position=D3DXVECTOR3(base.x+r*sinphi,base.y+r*cosphi,base.z+d);
pV[52+2*i+1].normal=D3DXVECTOR3(sinphi,cosphi,z);
}
pV[102].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z);
pV[102].normal=D3DXVECTOR3(z,z,z);
pV[103].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z+d);
pV[103].normal=D3DXVECTOR3(z,z,z);
// Почему знак приращения угла меняется?
phi+=dphi;
for (i=0;i<25;i++,phi+=dphi) {
sinphi=-sinf(phi);
cosphi=cosf(phi);
pV[104+2*i].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z);
pV[104+2*i].normal=D3DXVECTOR3(-sinphi,-cosphi,z);
pV[104+2*i+1].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z+d);
pV[104+2*i+1].normal=D3DXVECTOR3(-sinphi,-cosphi,z);
}
// М здесь то же
phi-=dphi;
for (i=0;i<25;i++,phi-=dphi) {
sinphi=-sinf(phi);
cosphi=cosf(phi);
pV[154+2*i].position=D3DXVECTOR3(base.x+rsm*sinphi,base.y+rsm*cosphi,base.z+d);
pV[154+2*i].normal=D3DXVECTOR3(z,z,n);
pV[154+2*i+1].position=D3DXVECTOR3(base.x+r*sinphi,base.y+r*cosphi,base.z+d);
pV[154+2*i+1].normal=D3DXVECTOR3(z,z,n);
}
}
И почему здесь после циклов следуют одиночные вставки вершин?