Глобальное позиционирование освещения в Opengl

Тема в разделе "Delphi - Multimedia, Графика, Игры", создана пользователем MoDErahN, 2 июн 2009.

  1. MoDErahN

    MoDErahN Гость

    Народ, в общем трабл такой. Пишу прожку для моделирования 3D систем, все пашет нормально, кроме освещения.
    Оно ведет себя жутко странно, вроде бы я его включаю до всех преобразований матриц, а в итоге оно отображаеться для всех объектов с разными векторами направления. Причем даже не с соответствующим вектором в системе координат самого объекта, а с каким-то неясно-непонятным вектором.
    Вот ссыль на бинарник и модель: http://slil.ru/27717863
    Запускаем прогу, тусим в "Визуализацию моделей", там правый клик на окошке с надписью "Новая модель" и выбираем "Открыть модель", выбираем файлик, тот что в архиве с прогой, и смело жмем "Начать визуализацию". Чтобы было проще увидеть в чем трабл, можно поставить скорость где-то на 0,1. Ориентация в пространстве просто мышкой.


    Вот листинг отрисовки, подскажите что тут не так. Вроде ж свет в глобальной системе координат врубаеться, почему он так криво отрабатывает?

    Код (Text):
    //###################################################
    //### внизу процедуры вывода объектов ###############
    //###################################################

    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 оборот относительно глобальной системы отсчета) источник света делает два оборота относительно глобальной системы отсчета.

    Вот вращение сферы, вид сверху.
    [​IMG]

    Есть идеи?

    Не стесняемся в предположениях, буду рад любой идее, уже часов 5 убил на попытки это отладить.
     
  2. mastiff

    mastiff Гость

    таже проблема.
    тллко я смотрю отвечать тут не торопятся)
     
Загрузка...
Похожие Темы - Глобальное позиционирование освещения
  1. Num2
    Ответов:
    3
    Просмотров:
    2.278
  2. ioni
    Ответов:
    14
    Просмотров:
    5.604

Поделиться этой страницей