Поворот всей сцены в текущей позиции на Delphi

  • Автор темы RAIN
  • Дата начала
Статус
Закрыто для дальнейших ответов.
R

RAIN

Гость
#1
Я начинаю осваивать OPENGL. Написал небольшую прогу, которая почти ничего не далает, но... :
Код:
program DOOM5;

uses
Forms,
Windows,
Messages,
OpenGL;

{$R *.res}
const
WND_TITLE = 'OpenGL';
FPS_TIMER = 1;
FPS_INTERVAL = 1;
FPS_INTERVAL_HOD = 1;

var
h_Wnd : HWND;
h_DC  : HDC;
h_RC  : HGLRC;
keys : Array[0..255] of Boolean;
FPSCount : Integer = 0;
ElapsedTime : Integer;
povor: GLfloat;
dviz: GLfloat;
shag_d: GLfloat;
shag_p: GLfloat;

procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;

function IntToStr(Num : Integer) : String;
begin
Str(Num, result);
end;

Procedure Dvizhenie;
Begin
dviz:=dviz+shag_d;
End;

Procedure Povorot;
Begin
povor:=povor+shag_p;
End;

procedure glDraw();
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// пол
glTranslatef(0,0.0,dviz);
glRotatef(povor,0.0,1.0,0.0);
glBegin(GL_QUADS);
 glColor3f(0.85,0.4,1.0);
 glVertex3f(-5.0, -2.0,0.0); // Слева вверху
 glColor3f(0.85,0.4,1.0);
 glVertex3f(1.0, -2.0, 0.0); // Справа вверху
 glColor3f(0.85,0.4,1.0);
 glVertex3f(1.0, -2.0, -25.0); // Справа внизу
 glColor3f(0.85,0.4,1.0);
 glVertex3f(-5.0, -2.0, -25.0); // Слева внизу
glEnd();
// стенки
glBegin(GL_QUADS);
 glColor3f(0.85,0.4,0.0);
 glVertex3f(1.0, -2.0, 0.0); // Слева вверху
 glColor3f(0.85,0.4,0.0);
 glVertex3f(1.0, -2.0, -25.0); // Справа вверху
 glColor3f(0.85,0.4,0.0);
 glVertex3f(1.0, 2.0, -25.0); // Справа внизу
 glColor3f(0.85,0.4,0.0);
 glVertex3f(1.0, 2.0, 0.0); // Слева внизу
glEnd();
glBegin(GL_QUADS);
 glColor3f(0.85,0.4,0.0);
 glVertex3f(-5.0, -2.0, 0.0); // Слева вверху
 glColor3f(0.85,0.4,0.0);
 glVertex3f(-5.0, -2.0, -25.0); // Справа вверху
 glColor3f(0.85,0.4,0.0);
 glVertex3f(-5.0, 2.0, -25.0); // Справа внизу
 glColor3f(0.85,0.4,0.0);
 glVertex3f(-5.0, 2.0, 0.0); // Слева внизу
glEnd();

// потолок
glBegin(GL_QUADS);
 glColor3f(0.85,0.0,0.0);
 glVertex3f(1.0, 2.0, -25.0); // Справа внизу
 glColor3f(0.85,0.0,0.0);
 glVertex3f(1.0, 2.0, 0.0); // Слева внизу
 glColor3f(0.85,0.0,0.0);
 glVertex3f(-5.0, 2.0, 0.0); // Слева внизу
 glColor3f(0.85,0.0,0.0);
 glVertex3f(-5.0, 2.0, -25.0); // Справа внизу
glEnd();
end;


procedure glInit();
begin
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
end;


procedure glResizeWnd(Width, Height : Integer);
begin
if (Height = 0) then
 Height := 1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, Width/Height, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
end;


function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM):
   LRESULT; stdcall;
begin
case (Msg) of
 WM_CREATE:
  begin
   shag_d:=0;
   shag_p:=0;
  end;
 WM_CLOSE:
  begin
   PostQuitMessage(0);
   Result := 0
  end;
 WM_KEYDOWN:
  begin
   keys[wParam] := True;
   if wParam = VK_ESCAPE then PostQuitMessage(0);
   if wParam = 40 then shag_d:=-0.3;
   if wParam = 38 then shag_d:=0.3;
   if wParam = 37 then shag_p:=-0.5;
   if wParam = 39 then shag_p:=0.5;
   {if wParam = 40 then dviz:=dviz-0.3;
   if wParam = 38 then dviz:=dviz+0.3;
   if wParam = 37 then povor:=povor-0.5;
   if wParam = 39 then povor:=povor+0.5;}
   Result := 0;
  end;
 WM_KEYUP:
  begin
   keys[wParam] := False;
   if wParam = 40 then shag_d:=0;
   if wParam = 38 then shag_d:=0;
   if wParam = 37 then shag_p:=0;
   if wParam = 39 then shag_p:=0;
   Result := 0;
  end;
 WM_SIZE:
  begin
   glResizeWnd(LOWORD(lParam),HIWORD(lParam));
   Result := 0;
  end;
 WM_TIMER :
  begin
   if wParam = FPS_TIMER then
   begin
    //FPSCount :=Round(FPSCount * 1000/FPS_INTERVAL);
    //SetWindowText(h_Wnd, PChar(WND_TITLE + '  [' + intToStr(FPSCount) + ' FPS]'));
    dvizhenie;
    povorot;
    //FPSCount := 0;
    Result := 0;
   end;
  end;
 else
  Result := DefWindowProc(hWnd, Msg, wParam, lParam);
end;
end;


procedure glKillWnd(Fullscreen : Boolean);
begin
if Fullscreen then
begin
 ChangeDisplaySettings(devmode(nil^), 0);
 ShowCursor(True);
end;
if (not wglMakeCurrent(h_DC, 0)) then
 MessageBox(0, 'Release of DC and RC failed!', 'Error',
                        MB_OK or MB_ICONERROR);
if (not wglDeleteContext(h_RC)) then
begin
 MessageBox(0, 'Release of rendering context failed!', 'Error',
                        MB_OK or MB_ICONERROR);
 h_RC := 0;
end;
if ((h_DC > 0) and (ReleaseDC(h_Wnd, h_DC) = 0)) then
begin
 MessageBox(0, 'Release of device context failed!', 'Error',
                        MB_OK or MB_ICONERROR);
 h_DC := 0;
end;
if ((h_Wnd <> 0) and (not DestroyWindow(h_Wnd))) then
begin
 MessageBox(0, 'Unable to destroy window!', 'Error',
                        MB_OK or MB_ICONERROR);
 h_Wnd := 0;
end;
if (not UnRegisterClass('OpenGL', hInstance)) then
begin
 MessageBox(0, 'Unable to unregister window class!', 'Error',
                        MB_OK or MB_ICONERROR);
 hInstance := 0;
end;
end;


function glCreateWnd(Width, Height : Integer; Fullscreen : Boolean;
                     PixelDepth : Integer) : Boolean;
var
wndClass : TWndClass;
dwStyle : DWORD;
dwExStyle : DWORD;
dmScreenSettings : DEVMODE;
PixelFormat : GLuint;
h_Instance : HINST;
pfd : TPIXELFORMATDESCRIPTOR;
begin
h_Instance := GetModuleHandle(nil);
ZeroMemory(@wndClass, SizeOf(wndClass));
with wndClass do
begin
 style     := CS_HREDRAW or
          CS_VREDRAW or
          CS_OWNDC;
 lpfnWndProc  := @WndProc;
 hInstance   := h_Instance;
 hCursor    := LoadCursor(0, IDC_ARROW);
 lpszClassName := 'OpenGL';
end;
if (RegisterClass(wndClass) = 0) then
begin
 MessageBox(0, 'Failed to register the window class!', 'Error',
                       MB_OK or MB_ICONERROR);
 Result := False;
 Exit
end;
if Fullscreen then
begin
 ZeroMemory(@dmScreenSettings, SizeOf(dmScreenSettings));
 with dmScreenSettings do begin
  dmSize    := SizeOf(dmScreenSettings);
  dmPelsWidth := Width;
  dmPelsHeight := Height;
  dmBitsPerPel := PixelDepth;
  dmFields   := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL;
 end;
 if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN)
                     = DISP_CHANGE_FAILED) then
 begin
  MessageBox(0, 'Unable to switch to fullscreen!', 'Error',
                       MB_OK or MB_ICONERROR);
  Fullscreen := False;
 end;
end;
if (Fullscreen) then
begin
 dwStyle := WS_POPUP or
       WS_CLIPCHILDREN
       or WS_CLIPSIBLINGS;
 dwExStyle := WS_EX_APPWINDOW;
 ShowCursor(False);
end
else
begin
 dwStyle := WS_OVERLAPPEDWINDOW or
       WS_CLIPCHILDREN or
       WS_CLIPSIBLINGS;
 dwExStyle := WS_EX_APPWINDOW or
        WS_EX_WINDOWEDGE;
end;
h_Wnd := CreateWindowEx(dwExStyle,
            'OpenGL',
            WND_TITLE,
            dwStyle,
            0, 0,
            Width, Height,
            0,
            0,
            h_Instance,
            nil);
if h_Wnd = 0 then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to create window!', 'Error',
                        MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
h_DC := GetDC(h_Wnd);
if (h_DC = 0) then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to get a device context!', 'Error',
                        MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
with pfd do
begin
 nSize      := SizeOf(TPIXELFORMATDESCRIPTOR);
 nVersion    := 1;
 dwFlags     := PFD_DRAW_TO_WINDOW
           or PFD_SUPPORT_OPENGL
           or PFD_DOUBLEBUFFER;
 iPixelType   := PFD_TYPE_RGBA;
 cColorBits   := PixelDepth;
 cRedBits    := 0;
 cRedShift    := 0;
 cGreenBits   := 0;
 cGreenShift   := 0;
 cBlueBits    := 0;
 cBlueShift   := 0;
 cAlphaBits   := 0;
 cAlphaShift   := 0;
 cAccumBits   := 0;
 cAccumRedBits  := 0;
 cAccumGreenBits := 0;
 cAccumBlueBits := 0;
 cAccumAlphaBits := 0;
 cDepthBits   := 16;
 cStencilBits  := 0;
 cAuxBuffers   := 0;
 iLayerType   := PFD_MAIN_PLANE;
 bReserved    := 0;
 dwLayerMask   := 0;
 dwVisibleMask  := 0;
 dwDamageMask  := 0;
end;
PixelFormat := ChoosePixelFormat(h_DC, @pfd);
if (PixelFormat = 0) then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to find a suitable pixel format', 'Error',
                          MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
if (not SetPixelFormat(h_DC, PixelFormat, @pfd)) then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to set the pixel format', 'Error',
                          MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
h_RC := wglCreateContext(h_DC);
if (h_RC = 0) then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to create an OpenGL rendering context', 'Error',
                          MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
if (not wglMakeCurrent(h_DC, h_RC)) then
begin
 glKillWnd(Fullscreen);
 MessageBox(0, 'Unable to activate OpenGL rendering context', 'Error',
                          MB_OK or MB_ICONERROR);
 Result := False;
 Exit;
end;
SetTimer(h_Wnd, FPS_TIMER, FPS_INTERVAL, nil);
ShowWindow(h_Wnd, SW_SHOW);
SetForegroundWindow(h_Wnd);
SetFocus(h_Wnd);
glResizeWnd(Width, Height);
glInit();
Result := True;
end;


function WinMain(hInstance : HINST; hPrevInstance : HINST;
      lpCmdLine : PChar; nCmdShow : Integer) : Integer; stdcall;
var
msg : TMsg;
finished : Boolean;
DemoStart, LastTime : DWord;
begin
finished := False;
if not glCreateWnd(800, 600, FALSE, 32) then
begin
 Result := 0;
 Exit;
end;
DemoStart := GetTickCount();
while not finished do
begin
 if (PeekMessage(msg, 0, 0, 0, PM_REMOVE)) then
 begin
  if (msg.message = WM_QUIT) then
   finished := True
  else
  begin
TranslateMessage(msg);
   DispatchMessage(msg);
  end;
 end
 else
 begin
  Inc(FPSCount);
  LastTime :=ElapsedTime;
  ElapsedTime :=GetTickCount() - DemoStart;
  ElapsedTime :=(LastTime + ElapsedTime) DIV 2;
  glDraw();
  SwapBuffers(h_DC);
  if (keys[VK_ESCAPE]) then
   finished := True
  else
 end;
end;
glKillWnd(FALSE);
Result := msg.wParam;
end;

begin
WinMain( hInstance, hPrevInst, CmdLine, CmdShow );
end.
Но при повороте в центре да и в других частях пространства, поворачивается сцена в центре начала запуска программы, но я бы хотел бы чтобы центр поворота была текущяя координата. Так же дело состоит и с шагом, когда в центре коридора повернутся на некоторое кол-во градусов, далее попробовать пройтись вперед, все двигается не прямо, а как бы передвигаясь немного в бок.
Подскажите, что сделать, пожалуйста.
 
R

RAIN

Гость
#2
А еще дополнение к этомой теме: Как сделать так, чтобы при движении мышки можно было поворачиваьтся и смотреть вверх и вниз.
 
Статус
Закрыто для дальнейших ответов.