![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
вектора нормалей [Delphi, Windows]
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 нормали сам.
Проблема расчитать чтоли?