Конференция "Игры" » Реализация свободной камеры на openGL
 
  • Franzy (28.05.09 15:06) [0]
    Нужен пример реализации свободной камеры, как в 3D-играх. Т.е. направление камеры задается мышью (mouselook), плюс можно двигаться в направлении камеры и назад (не приближение/удаление, а именно перемещение точки, вокруг которой вращается камера).
  • @!!ex © (28.05.09 16:11) [1]
    //Ниже закоментированный код можно использовать чтобы полетать по сцене
    //UPDATE MOUSE
    POINT Mouse;
    GetCursorPos(&Mouse);
    /*if ((GetAsyncKeyState(VK_LBUTTON)&0x8000)!=0){
     m_CameraRotation.x=m_CameraRotation.x+(Mouse.x-m_OldX);
     m_CameraRotation.y=m_CameraRotation.y+(Mouse.y-m_OldY);
    }
    ;*/
    m_OldX = Mouse.x;
    m_OldY = Mouse.y;
    //UPDATE MOUSE

    //UPDATE KEYBOARD
    /*if ((GetAsyncKeyState('W') & 0x8000)!=0){
     m_CameraPosition.x = m_CameraPosition.x - sin(m_CameraRotation.x*pi/180)*MoveSpeed*(-1);
     m_CameraPosition.y = m_CameraPosition.y - cos(m_CameraRotation.x*pi/180)*MoveSpeed*(-1);
     m_CameraPosition.z = m_CameraPosition.z - sin((m_CameraRotation.y-90)*pi/180)*MoveSpeed*(-1);
    }
    ;

    if ((GetAsyncKeyState('S') & 0x8000)!=0){
     m_CameraPosition.x = m_CameraPosition.x - sin(m_CameraRotation.x*pi/180)*MoveSpeed*(1);
     m_CameraPosition.y = m_CameraPosition.y - cos(m_CameraRotation.x*pi/180)*MoveSpeed*(1);
     m_CameraPosition.z = m_CameraPosition.z - sin((m_CameraRotation.y-90)*pi/180)*MoveSpeed*(1);
    }
    ;

    if ((GetAsyncKeyState('A') & 0x8000)!=0){
     m_CameraPosition.x = m_CameraPosition.x - sin((m_CameraRotation.x-90)*pi/180)*MoveSpeed*(-1);
     m_CameraPosition.y = m_CameraPosition.y - cos((m_CameraRotation.x-90)*pi/180)*MoveSpeed*(-1);
    }
    ;

    if ((GetAsyncKeyState('D') & 0x8000)!=0){
     m_CameraPosition.x = m_CameraPosition.x - sin((m_CameraRotation.x-90)*pi/180)*MoveSpeed*(1);
     m_CameraPosition.y = m_CameraPosition.y - cos((m_CameraRotation.x-90)*pi/180)*MoveSpeed*(1);
    }
    ;*/
    //UPDATE KEYBOARD
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, m_Width / m_Height, 1.0, 2000.0);
    glViewport(0, 0, m_Width, m_Height);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);

    glRotatef(m_CameraRotation.y, 1, 0, 0);
    glRotatef(m_CameraRotation.x, 0, 0, 1);

    glTranslatef(-m_CameraPosition.x,-m_CameraPosition.y,-m_CameraPosition.z);

  • Franzy (31.05.09 19:19) [2]
    Перевел на дельфи, не фига не работает. Камера ведет себя хаотично, ни о каком мауслуке даже речи нет. Вот мой код (может, где ошибся?). Всего-то требуется, чтобы при нажатии W камера летела по направлению "взгляда", т.е. к центру картинки.

    -------------------------
     TMyCamera = record
      x,y,z : single;
      a1,a2,a3 : single;
      speed : single;
      farclip, nearclip, viewangle : single;
     End;

    var
    cam : TMyCamera;
    ---------------------------------------------
    procedure UpdateScene;
    begin
     glViewport(Sc_x, Sc_y, Sc_x+Sc_w, Sc_y+Sc_h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity;
     gluPerspective(cam.viewangle, Sc_w / Sc_h, cam.nearclip, cam.farclip);
    end;
    ----------------------------------------------
    procedure UpdateCamera;
    begin

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity;
    glRotatef(cam.a2, 1, 0, 0,);
    glRotatef(cam.a1, 0, 0, 1);
    glTranslatef(-cam.x,-cam.y,-cam.z);
    InvalidateRect(form1.Handle, nil, False);

    end;
    --------------------------------------
    procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
    begin

    Case UpCase(Key) of
      '+' : cam.speed:=cam.speed*1.1;
      '-' : cam.speed:=cam.speed*0.9;
      'W' : begin
               cam.x := cam.x - sin(cam.a1*pi/180)*cam.Speed*(-1);
               cam.y := cam.y - cos(cam.a1*pi/180)*cam.Speed*(-1);
               cam.z := cam.z - sin((cam.a2-90)*pi/180)*cam.Speed*(-1);
            end;
      'S' : begin
               cam.x := cam.x - sin(cam.a1*pi/180)*cam.Speed;
               cam.y := cam.y - cos(cam.a1*pi/180)*cam.Speed;
               cam.z := cam.z - sin((cam.a2-90)*pi/180)*cam.Speed;
            end;
      'Q' : cam.a2:=cam.a2-5;
      'E' : cam.a2:=cam.a2+5;

    End;

    //UpdateScene;
    UpdateCamera;

    end;
    ------------------------------
    procedure TForm1.FormCreate(Sender: TObject);
    begin

    Sc_x:=0;
    Sc_y:=0;
    Sc_h:=ClientHeight;
    Sc_w:=ClientWidth;

    DC := GetDC (Handle);
    SetDCPixelFormat(DC);
    hrc := wglCreateContext(DC);
    wglMakeCurrent(DC, hrc);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_AUTO_NORMAL);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    cam.x:=0;
    cam.y:=0;
    cam.z:=5;
    cam.a1:=0;
    cam.a2:=0;
    cam.a3:=0;
    cam.speed:=1;
    cam.nearclip:=1;
    cam.farclip:=1000;
    cam.viewangle:=30;

    UpdateScene;
    UpdateCamera;

    end;
  • @!!ex © (31.05.09 19:31) [3]
    > Камера ведет себя хаотично, ни о каком мауслуке даже речи
    > нет.

    Что значит "хаотично"?
    В OnPaint вставьте мой код без изменений, для теста.
  • Franzy (01.06.09 09:20) [4]
    Вы мы не предлагаете код на си вставить в дельфи? 8-0
  • @!!ex © (01.06.09 09:53) [5]
    > [4] Franzy   (01.06.09 09:20)
    > код на си

    Там от С++ - только синтаксис ifов.
  • Franzy (01.06.09 14:58) [6]
    Сделал все с помощью GluLookAt - с ней оказалось все намного проще, и никаких проблем в полном 3D.
  • @!!ex © (01.06.09 15:11) [7]
    > [6] Franzy   (01.06.09 14:58)

    gluLookAt - не проще, делает тоже самое только прозрачно для прогера.
  • Franzy (01.06.09 16:08) [8]
    Я знаю, матрица одна и та же :)
 
Конференция "Игры" » Реализация свободной камеры на openGL
Есть новые Нет новых   [134430   +2][b:0][p:0.001]