Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

вектора нормалей [Delphi, Windows]


Страницы:   1 2

basf ©   (2007-01-17 12:34:00) 

В одной книжонке по 3D-графике прочитал что по умолчанию за вектор нормали в OpenGL принимается вектор перпендикулярный к какой-либо плоскости (что, вроде бы, очевидно). Я рисую не самую сложную фигуру ("срезка" эллипсоида), при включении освещения объект пропадает, когда я нормали ставлю сам, то фигура видна, но так как я их ставлю с некоторой "погрешностью" получается не совсем то что надо. В общем, ставит OpenGL нормали сам или нет, может эту "опцию"  нужно как-то включить, подскажите, plz, как их правильно расставить.


MBo   (2007-01-18 10:11:00) [21]

>да и на самом деле количество тактов то не уменьшилось %)

Три деления обычно медленнее одного деления и трех умножений


Rial   (2007-01-18 09:32:00) [22]

>[7] ors_archangel ©   (17.01.07 19:36)
>оптимизация деления:
> WrkI:=Sqrt(X * X + Y * Y + Z * Z);
> If WrkI <> 0.0 then begin //Для предотвращения деления на ноль
>  WrkI := 1/WrkI;


Это, наверное, опечатка, да ? :)
Ибо во - первых нет
else WrkI:=1.0;
да и на самом деле количество тактов то не уменьшилось %)

Уж если придираешься к тиким глупостям, то уж
придирайся обоснованно.


Думкин   (2007-01-18 05:37:00) [23]


> XProger ©   (17.01.07 21:03) [9]

Ну если под нормалью понимать именно нормаль в математическом смысле в еквлидовом пространстве - то это так. А если конечно, в применении к ЖЛ - то таки нет.


XProger   (2007-01-17 21:03:00) [24]

Нормаль в OpenGL это перпендикуляр к плоскости плоскости полигона?
СОЖГИТЕ ЭТУ КНИГУ!


Rial   (2007-01-17 20:22:00) [25]

> [6] Думкин ©   (17.01.07 18:49)
> Кстати в glut была ошибка на подобную тему и в одном примере
> у Краснова, додекаэдр(кажется) при вращении терял одну сторону.
> :)

А glut вообще зло, имхо :)
Если glu можно еще использовать, чтобы не мучаться со своими
текстурными координатами и нормалями, то все, что делается
в glut лучше переписать заново.
Возможно, сейчас есть более новые версии, но в той, что испугала
меня, нашлись таки тоже какие то глюки, да и лишнего много там.

P.S.
Как я не изголялся с оптимизацией, а обогнать, например,
gluSphere по производительности хоть на сколько - нибудь
значимое число операций так и не смог,
даже переписав всю процедуру на ассемблере.


ors_archangel   (2007-01-17 19:36:00) [26]


//Вычисляем длину
WrkI:=Sqrt(X * X + Y * Y + Z * Z);
If (WrkI = 0.0) then WrkI := 1.0; //Для предотвращения деления на ноль
//Номализуем
Result[0]:=X / WrkI;
Result[1]:=Y / WrkI;
Result[2]:=Z / WrkI;

оптимизация деления:

//Вычисляем длину
WrkI:=Sqrt(X * X + Y * Y + Z * Z);
If WrkI <> 0.0 then begin //Для предотвращения деления на ноль
  WrkI := 1/WrkI;
  //Номализуем
  Result[0]:=X * WrkI;
  Result[1]:=Y * WrkI;
  Result[2]:=Z * WrkI;
end else begin
  Result[0]:=X;
  Result[1]:=Y;
  Result[2]:=Z;
end;


Думкин   (2007-01-17 18:49:00) [27]

Кстати в glut была ошибка на подобную тему и в одном примере у Краснова, додекаэдр(кажется) при вращении терял одну сторону. :)


Думкин   (2007-01-17 18:42:00) [28]

> Оказывается норамаль - это тупо векторное произведение двух
> векторов.

Так то оно так, но оно не коммутативно, и при смене порядка - меняет направление. То есть определяет ориентацию. Это самая засада для многих.


@!!ex   (2007-01-17 16:32:00) [29]


> basf   (17.01.07 12:34)  

На будущее. (Я пока не чтал учиьтся даже и не знал).
Оказывается норамаль - это тупо векторное произведение двух векторов.
Возьми учебник ао Аналитической геометрии и посмотри тему: "векторное произведение". ИМХО это лучше чем тупо скопировать текст.


Rial   (2007-01-17 16:25:00) [30]

Рассчет нормали (кое что наспех удалил, но работать должно):

function CalcNormal(Const V1X, V1Y, V1Z,
                                     V2X, V2Y, V2Z,
                                     V3X, V3Y, V3Z : GLFloat;
                               Const bNormalize : Boolean) : Array[0..2] of GLFloat;
Var VX1, VY1, VZ1,
    VX2, VY2, VZ2 : GLFloat;
   X, Y, Z : GLFloat;
   WrkI : GLFloat;
begin
VX1:=V1X - V2X;
VY1:=V1Y - V2Y;
VZ1:=V1Z - V2Z;
VX2:=V2X - V3X;
VY2:=V2Y - V3Y;
VZ2:=V2Z - V3Z;
//Вектор перпендикулярен центру треугольника
X:=VY1 * VZ2 - VZ1 * VY2;
Y:=VZ1 * VX2 - VX1 * VZ2;
Z:=VX1 * VY2 - VY1 * VX2;
If (bNormalize)then begin
 //Вычисляем длину
 WrkI:=Sqrt(X * X + Y * Y + Z * Z);
 If (WrkI = 0.0) then WrkI := 1.0; //Для предотвращения деления на ноль
 //Номализуем
 Result[0]:=X / WrkI;
 Result[1]:=Y / WrkI;
 Result[2]:=Z / WrkI;
end else begin
 Result[0]:=X;
 Result[1]:=Y;
 Result[2]:=Z;
end;
end;

procedure SetNormal(Const V1X, V1Y, V1Z,
                                     V2X, V2Y, V2Z,
                                     V3X, V3Y, V3Z : GLFloat);
Var GLNormal : Array[0..2] of GLFloat;
begin
GLNormal:=CalcNormal(V1X, V1Y, V1Z,
                     V2X, V2Y, V2Z,
                     V3X, V3Y, V3Z,
                     True);
glNormal3fv(@GLNormal);
end;


А вот как все делается без лишних библиотек.
Опять же, кое чего не хватает, но это прими как домашнее задание :)

procedure rglCalc_Disk(Const InnerRadius, OuterRadius, Height1, Height2 :  GLFloat);
Var Sn, Cs  :  Extended;
   iX, iY, oX, oY  :  GLFloat;
   biX, biY, boX, boY  :  GLFloat;
   I : Integer;
   iTexPosX, iTexPosY, oTexPosX, oTexPosY  :  GLFloat;
   biTexPosX, biTexPosY, boTexPosX, boTexPosY  :  GLFloat;
begin
 SinCos(TwoPi / DetailedX, Sn, Cs);
 biX :=InnerRadius;
 biY :=0.0;
 boX :=OuterRadius;
 boY :=0.0;

 boTexPosX :=1.0;
 boTexPosY :=0.5;
 biTexPosX :=0.5 + (InnerRadius / OuterRadius) / 2.0;
 biTexPosY :=0.5;

 SetDefaultNormal;

 glBegin(GL_Triangles);
  For I :=0 to DetailedX do begin
   iX :=biX;
   iY :=biY;
   oX :=boX;
   oY :=boY;

   iTexPosX :=biTexPosX;
   iTexPosY :=biTexPosY;
   oTexPosX :=boTexPosX;
   oTexPosY :=boTexPosY;

   PerformCoords(oX, oY, Cs, Sn, boX, boY);
   PerformCoords(iX, iY, Cs, Sn, biX, biY);

   boTexPosX :=oTexPosX + (boX - oX) / 2.0;
   boTexPosY :=oTexPosY + (boY - oY) / 2.0;

   biTexPosX :=iTexPosX + (biX - iX) / 2.0;
   biTexPosY :=iTexPosY + (biY - iY) / 2.0;

   //Первый треугольник
   glTexCoord2f(iTexPosX, iTexPosY);
   glVertex3f(iX, iY, Height1);

   glTexCoord2f(oTexPosX, oTexPosY);
   glVertex3f(oX, oY, Height2);

   glTexCoord2f(boTexPosX, boTexPosY);
   glVertex3f(boX, boY, Height2);

   //Второй треугольник
   glTexCoord2f(iTexPosX, iTexPosY);
   glVertex3f(iX, iY, Height1);

   glTexCoord2f(boTexPosX, boTexPosY);
   glVertex3f(boX, boY, Height2);

   glTexCoord2f(biTexPosX, biTexPosY);
   glVertex3f(biX, biY, Height1);

  end;
 glEnd;
end; //With rglEngine

procedure PerformCoords(Const X, Y, Cs, Sn  :  GLFloat; Var OutX, OutY  :  GLFloat);
begin
OutX :=X * Cs - Y * Sn;
OutY :=Y * Cs + X * Sn;
end;


@!!ex   (2007-01-17 13:44:00) [31]

glut?
GLUT сам считает нормали, если ему указать, никогда им не пользовался...
Рисуй элипс сам? :)


@!!ex   (2007-01-17 13:28:00) [32]

Не ставит OpenGL нормали сам.
Проблема расчитать чтоли?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо