Новичок
Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.6.2009
Репутация: нет Всего: нет
|
Народ, в общем трабл такой. Пишу прожку для моделирования 3D систем, все пашет нормально, кроме освещения. Оно ведет себя жутко странно, вроде бы я его включаю до всех преобразований матриц, а в итоге оно отображаеться для всех объектов с разными векторами направления. Причем даже не с соответствующим вектором в системе координат самого объекта, а с каким-то неясно-непонятным вектором. Вот ссыль на бинарник и модель: http://slil.ru/27717863Запускаем прогу, тусим в "Визуализацию моделей", там правый клик на окошке с надписью "Новая модель" и выбираем "Открыть модель", выбираем файлик, тот что в архиве с прогой, и смело жмем "Начать визуализацию". Чтобы было проще увидеть в чем трабл, можно поставить скорость где-то на 0,1. Ориентация в пространстве просто мышкой. Вот листинг отрисовки, подскажите что тут не так. Вроде ж свет в глобальной системе координат врубаеться, почему он так криво отрабатывает? Код | //################################################### //### внизу процедуры вывода объектов ############### //###################################################
Procedure PaintSSphere(Sph: TSSphere); Var i: byte; Begin glBegin(GL_TRIANGLES); For i := 1 to 8 do Begin glColor4fv(@Sph.Color[Sph.Triangle[i].F]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].F]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].F]); glColor4fv(@Sph.Color[Sph.Triangle[i].S]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].S]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].S]); glColor4fv(@Sph.Color[Sph.Triangle[i].T]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].T]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].T]); End; glEnd; End;
Procedure PaintMSphere(Sph: TMSphere); Var i: byte; Begin glBegin(GL_TRIANGLES); For i := 1 to 48 do Begin glColor4fv(@Sph.Color[Sph.Triangle[i].F]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].F]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].F]); glColor4fv(@Sph.Color[Sph.Triangle[i].S]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].S]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].S]); glColor4fv(@Sph.Color[Sph.Triangle[i].T]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].T]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].T]); End; glEnd; End;
Procedure PaintHSphere(Sph: THSphere); Var i: byte; Begin glBegin(GL_TRIANGLES); For i := 1 to 120 do Begin glColor4fv(@Sph.Color[Sph.Triangle[i].F]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].F]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].F]); glColor4fv(@Sph.Color[Sph.Triangle[i].S]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].S]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].S]); glColor4fv(@Sph.Color[Sph.Triangle[i].T]); glNormal3fv(@Sph.Normal[Sph.Triangle[i].T]); glVertex3fv(@Sph.Vartex[Sph.Triangle[i].T]); End; glEnd; End;
Procedure PaintCirc(Circ: TCirc); Var i: byte; Begin glBegin(GL_TRIANGLES); glNormal3f(0, -1, 0); For i := 1 to 216 do Begin glColor4fv(@Circ.Color[Circ.Triangle[i].F]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].F]); glColor4fv(@Circ.Color[Circ.Triangle[i].T]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].T]); glColor4fv(@Circ.Color[Circ.Triangle[i].S]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].S]); End; glNormal3f(0, 1, 0); For i := 1 to 216 do Begin glColor4fv(@Circ.Color[Circ.Triangle[i].F]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].F]); glColor4fv(@Circ.Color[Circ.Triangle[i].S]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].S]); glColor4fv(@Circ.Color[Circ.Triangle[i].T]); glVertex3fv(@Circ.Vartex[Circ.Triangle[i].T]); End; glEnd; End;
Procedure LightOn(Light: TLight); Begin glEnable(GLLight[VM.lights]); glLightfv(GLLight[VM.lights], GL_AMBIENT, @Light.FonColor); glLightfv(GLLight[VM.lights], GL_DIFFUSE, @Light.GlColor); glLightf(GLLight[VM.lights], GL_LINEAR_ATTENUATION, Light.con); glLightfv(GLLight[VM.lights], GL_POSITION, @Light.Pos); End;
Function GetPointOrb(a, b, stang, speed: real): TGLPoint; Var ang: real; Begin ang := stang / 57.2956 + speed * 6.2832 * VM.RealTime; ang := ang - round(ang / 6.2832 - 0.5) * 6.2832; GetPointOrb[1] := 0; GetPointOrb[0] := cos(ang) * a; GetPointOrb[2] := sin(ang) * b; End;
Procedure DisableLights; Var i: integer; Begin For i := 0 to 7 do glDisable(GLLight[i]); End;
Procedure TVM.SetLights(Root: TOT); Var i: byte; Begin DisableLights; lights := 0; i := 0; While (i <= length(Root.Child) - 1) and (lights < 7) do Begin if Root.Child[i].Obj.ObjType = 5 then Begin LightOn(Root.Child[i].Obj.LT); inc(lights); End; inc(i); End; End;
//################################################### //### внизу логическая структура отрисовки ########## //###################################################
Procedure TVM.GlobalPaint(Root: TOT); Var Pnt: TGLPoint; ang: real; i: integer; Begin glPushMatrix; // <-- (Матрицу в стек)
if Root <> TreeRoot then Begin //вращаем ось орбиты и смещаемся в точку на орбите glRotatef(Root.Obj.Rotorb[1][0], Root.Obj.Rotorb[1][1], Root.Obj.Rotorb[1][2], Root.Obj.Rotorb[1][3]); glRotatef(Root.Obj.Rotorb[2][0], Root.Obj.Rotorb[2][1], Root.Obj.Rotorb[2][2], Root.Obj.Rotorb[2][3]); glRotatef(Root.Obj.Rotorb[3][0], Root.Obj.Rotorb[3][1], Root.Obj.Rotorb[3][2], Root.Obj.Rotorb[3][3]); Pnt := GetPointOrb(Root.Obj.a, Root.Obj.b, Root.Obj.stang, Root.Obj.rotspeed); glTranslatef(Pnt[0], Pnt[1], Pnt[2]); End;
if Root.Obj.ObjType in [1..4] then Begin //вращаем ось объекта и масштабируем glPushMatrix; // <-- (Матрицу в стек) glRotatef(Root.Obj.Rotspin[1][0], Root.Obj.Rotspin[1][1], Root.Obj.Rotspin[1][2], Root.Obj.Rotspin[1][3]); glRotatef(Root.Obj.Rotspin[2][0], Root.Obj.Rotspin[2][1], Root.Obj.Rotspin[2][2], Root.Obj.Rotspin[2][3]); glRotatef(Root.Obj.Rotspin[3][0], Root.Obj.Rotspin[3][1], Root.Obj.Rotspin[3][2], Root.Obj.Rotspin[3][3]); ang := Root.Obj.stspin + 360 * Root.Obj.spinspeed * RealTime; ang := ang - round(ang / 360 - 0.5) * 360; glRotatef(ang, 0, 1, 0);
glScalef (Root.Obj.radius * 2, Root.Obj.radius * 2, Root.Obj.radius * 2); // * 2 потому что модели имеют границы в 0.5 End;
if Root.Obj.shadowed = false then glDisable(GL_LIGHTING); //если у объекта отключено затенение, то вырубаем освещение
case Root.Obj.ObjType of 1: PaintSSphere(Root.Obj.SS); 2: PaintMSphere(Root.Obj.MS); 3: PaintHSphere(Root.Obj.HS); 4: PaintCirc(Root.Obj.CR); end;
if Root.Obj.shadowed = false then glEnable(GL_LIGHTING);
if Root.Obj.ObjType in [1..4] then Begin glPopMatrix; // --> (Матрицу из стека) End;
If Length(Root.Child) > 0 then Begin For i := 0 to Length(Root.Child) - 1 do GlobalPaint(Root.Child[i]); End;
glPopMatrix; // --> (Матрицу из стека) End;
//################################################### //### внизу перехватчик сообщения отрисовки окна #### //###################################################
procedure TimeProc(uTimerID, uMessage: UINT;dwUser, dw1, dw2: DWORD) stdcall; //процедура обработки мультимедийного таймера begin InvalidateRect(VM.Handle, nil, False); //обновляем окно end;
procedure TVM.WMPaint(var Msg: TWMPaint); //перехватчик сообщения отрисовки окна var ps: TPaintStruct; begin //расчет реального времени TimerTime := GetTickCount - StartTime; RealTime := LRTime + TimerTime * TimeSpeed / 1000;
//расчет координат камеры Cam.Eye.X := sin(camgorang) * camrad * cos(camvertang); Cam.Eye.Z := cos(camgorang) * camrad * cos(camvertang); Cam.Eye.Y := sin(camvertang) * camrad;
BeginPaint(Handle, ps); //начало отрисовки
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //очистка буферов цвета и глубины
glLoadIdentity;
//установка камеры gluLookAt (Cam.Eye.X, Cam.Eye.Y, Cam.Eye.Z, Cam.Target.X, Cam.Target.Y, Cam.Target.Z, Cam.RVect.X, Cam.RVect.Y, Cam.RVect.Z);
//установка освещения SetLights(TreeRoot);
//отрисовка объектов GlobalPaint(TreeRoot);
SwapBuffers(DC); //"выбрасываем" на экран
EndPaint(Handle, ps); //завершаем отрисовку end; |
Оно поворачивает источник света вместе с объектом, даже не вместе, а с удвоенным углом, т.е. если объект делает оборот вокруг своей оси (т.е. система координат в которой он рисуется делает 1 оборот относительно глобальной системы отсчета) источник света делает два оборота относительно глобальной системы отсчета. Вот вращение сферы, вид сверху.  Есть идеи? Не стесняемся в предположениях, буду рад любой идее, уже часов 5 убил на попытки это отладить. Это сообщение отредактировал(а) MoDErahN - 2.6.2009, 19:14
|