Juz mam sterowanie...
Teraz problem jest tego typu, że jeśli mam "podloge", a na niej "osobe", to gdy ruszę kamerą "osoba" znika.
Dwie funkcje:
function DrawCharacter(x,y,z : integer) : bool; // rysowanie bohateraz
begin
glLoadIdentity();
glColor3f(1.0,1.0,0.0);
glTranslatef(x,y,-z);
glBegin(GL_QUADS);
glBlendFunc(GL_ONE,GL_SRC_ALPHA);
glVertex2f(-1.0, 1.0);
glVertex2f( 1.0, 1.0);
glVertex2f( 1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
glFlush();
//pomijam result
end;
function GenerateMap(x,y,z : integer) : bool; //generowanie mapy
begin
result := false;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
for i := x to y do
begin
for n := x-2 to y+2 do
begin
glLoadIdentity();
glColor3f(1.0,0.0,0.0);
if n < S then
glTranslatef(-n*2,i*2,-z)
else
glTranslatef(n*2,i*2,-z);
glBegin(GL_QUADS);
glVertex2f(-1.0, 1.0);
glVertex2f( 1.0, 1.0);
glVertex2f( 1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
end;
end;
glFlush();
result := true;
end;
//dodatkowo
procedure ReSizeGLScene();
begin
glViewport(L, U, S, H);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,S/H,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
function InitGL:bool;
begin
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 0.5);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
Result:=true;
end;
function DrawGLScene():bool;
begin
GenerateMap(-world,world, 56);
DrawCharacter(L,U, 54);
Result := true;
end;
...
WM_KEYDOWN:
begin
if wparam = VK_UP then
U := U - step;
if wparam = VK_DOWN then
U := U + step;
if wparam = VK_LEFT then
L := L + step;
if wparam = VK_RIGHT then
L := L - step;
ReSizeGLScene();
...
Cały kod:
program rpg;
uses
Windows,
Messages,
Dialogs,
SysUtils,
Forms,
OpenGL;
var
i,n : integer;
h_Rc: HGLRC;
h_Dc: HDC;
h_Wnd: HWND;
keys: array [0..255] of bool;
Active: bool = true;
FullScreen:bool = true;
speed : extended = 0.5;
S,H : integer;
U : integer = 0;
L : integer = 0;
mapsize, world : integer;
step : integer = 43;
function DrawCharacter(x,y,z : integer) : bool;
begin
glLoadIdentity();
glColor3f(1.0,1.0,0.0);
glTranslatef(x,y,-z);
glBegin(GL_QUADS);
glBlendFunc(GL_ONE,GL_SRC_ALPHA);
glVertex2f(-1.0, 1.0);
glVertex2f( 1.0, 1.0);
glVertex2f( 1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
glFlush();
end;
function GenerateMap(x,y,z : integer) : bool;
begin
result := false;
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
for i := x to y do
begin
for n := x-2 to y+2 do
begin
glLoadIdentity();
glColor3f(1.0,0.0,0.0);
if n < S then
glTranslatef(-n*2,i*2,-56)
else
glTranslatef(n*2,i*2,-56);
glBegin(GL_QUADS);
glVertex2f(-1.0, 1.0);
glVertex2f( 1.0, 1.0);
glVertex2f( 1.0,-1.0);
glVertex2f(-1.0,-1.0);
glEnd();
end;
end;
glFlush();
result := true;
end;
procedure ReSizeGLScene();
begin
glViewport(L, U, S, H);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,S/H,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
function InitGL:bool;
begin
glShadeModel(GL_SMOOTH);
glClearColor(0.0, 0.0, 0.0, 0.5);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
Result:=true;
end;
function DrawGLScene():bool;
begin
GenerateMap(-world,world, 56);
DrawCharacter(L,U, 54);
Result := true;
end;
function WndProc(hWnd: HWND;
message: UINT;
wParam: WPARAM;
lParam: LPARAM):
LRESULT; stdcall;
begin
if message=WM_SYSCOMMAND then
begin
case wParam of
SC_SCREENSAVE,SC_MONITORPOWER:
begin
result:=0;
exit;
end;
end;
end;
case message of
WM_ACTIVATE:
begin
if (Hiword(wParam)=0) then
active:=true
else
active:=false;
Result:=0;
end;
WM_CLOSE:
Begin
PostQuitMessage(0);
result:=0
end;
WM_KEYDOWN:
begin
keys[wParam] := TRUE;
if wparam = VK_UP then
U := U - step;
if wparam = VK_DOWN then
U := U + step;
if wparam = VK_LEFT then
L := L + step;
if wparam = VK_RIGHT then
L := L - step;
ReSizeGLScene();
result:=0;
end;
WM_KEYUP:
begin
keys[wParam] := FALSE;
result:=0;
end;
WM_SIZE:
begin
//ReSizeGLScene(mapsize,mapsize);
H := HIWORD(lparam);
S := LOWORD(lparam);
ReSizeGLScene();
result:=0;
end
else
begin
Result := DefWindowProc(hWnd, message, wParam, lParam);
end;
end;
end;
procedure KillGLWindow;
begin
if FullScreen then
begin
ChangeDisplaySettings(devmode(nil^),0);
showcursor(true);
end;
if h_rc<> 0 then
begin
if (not wglMakeCurrent(h_Dc,0)) then
MessageBox(0,'Release of DC and RC failed.',' Shutdown Error',MB_OK or MB_ICONERROR);
if (not wglDeleteContext(h_Rc)) then
begin
MessageBox(0,'Release of Rendering Context failed.',' Shutdown Error',MB_OK or MB_ICONERROR);
h_Rc:=0;
end;
end;
if (h_Dc=1) and (releaseDC(h_Wnd,h_Dc)<>0) then
begin
MessageBox(0,'Release of Device Context failed.',' Shutdown Error',MB_OK or MB_ICONERROR);
h_Dc:=0;
end;
if (h_Wnd<>0) and (not destroywindow(h_Wnd))then
begin
MessageBox(0,'Could not release hWnd.',' Shutdown Error',MB_OK or MB_ICONERROR);
h_Wnd:=0;
end;
if (not UnregisterClass('OpenGL',hInstance)) then
begin
MessageBox(0,'Could not unregister class.','SHUTDOWN ERROR',MB_OK or MB_ICONINFORMATION);
end;
end;
function CreateGlWindow(title:Pchar; width,height,bits:integer;FullScreenflag:bool):boolean stdcall;
var
Pixelformat: GLuint;
wc:TWndclass;
dwExStyle:dword;
dwStyle:dword;
pfd: pixelformatdescriptor;
dmScreenSettings: Devmode;
h_Instance:hinst;
WindowRect: TRect;
begin
WindowRect.Left := 0;
WindowRect.Top := 0;
WindowRect.Right := width;
WindowRect.Bottom := height;
h_instance:=GetModuleHandle(nil);
FullScreen:=FullScreenflag;
with wc do
begin
style:=CS_HREDRAW or CS_VREDRAW or CS_OWNDC;
lpfnWndProc:=@WndProc;
cbClsExtra:=0;
cbWndExtra:=0;
hInstance:=h_Instance;
hIcon:=LoadIcon(0,IDI_WINLOGO);
hCursor:=LoadCursor(0,IDC_ARROW);
hbrBackground:=0;
lpszMenuName:=nil;
lpszClassName:='OpenGl';
end;
if RegisterClass(wc)=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 := bits;
dmFields := DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT;
end;
if (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN))<>DISP_CHANGE_SUCCESSFUL THEN
Begin
if MessageBox(0,'This FullScreen Mode Is Not Supported. Use Windowed Mode Instead?'
,'GL',MB_YESNO or MB_ICONEXCLAMATION)= IDYES then
FullScreen:=false
else
begin
MessageBox(0,'Program will now close.','Error',MB_OK or MB_ICONERROR);
Result:=false;
exit;
end;
end;
end;
if FullScreen then
begin
dwExStyle:=WS_EX_APPWINDOW;
dwStyle:=WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
Showcursor(false);
end
else
begin
dwExStyle:=WS_EX_APPWINDOW or WS_EX_WINDOWEDGE;
dwStyle:=WS_OVERLAPPEDWINDOW or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
end;
AdjustWindowRectEx(WindowRect,dwStyle,false,dwExStyle);
H_wnd:=CreateWindowEx(dwExStyle,
'OpenGl',
Title,
dwStyle,
0,0,
WindowRect.Right-WindowRect.Left,
WindowRect.Bottom-WindowRect.Top,
0,
0,
hinstance,
nil);
if h_Wnd=0 then
begin
KillGlWindow();
MessageBox(0,'Window creation error.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
with pfd do
begin
nSize:= SizeOf( PIXELFORMATDESCRIPTOR );
nVersion:= 1;
dwFlags:= PFD_DRAW_TO_WINDOW
or PFD_SUPPORT_OPENGL
or PFD_DOUBLEBUFFER;
iPixelType:= PFD_TYPE_RGBA;
cColorBits:= bits;
cRedBits:= 0;
cRedShift:= 0;
cGreenBits:= 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;
h_Dc := GetDC(h_Wnd);
if h_Dc=0 then
begin
KillGLWindow();
MessageBox(0,'Cant''t create a GL device context.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
PixelFormat := ChoosePixelFormat(h_Dc, @pfd);
if (PixelFormat=0) then
begin
KillGLWindow();
MessageBox(0,'Cant''t Find A Suitable PixelFormat.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
if (not SetPixelFormat(h_Dc,PixelFormat,@pfd)) then
begin
KillGLWindow();
MessageBox(0,'Cant''t set PixelFormat.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
h_Rc := wglCreateContext(h_Dc);
if (h_Rc=0) then
begin
KillGLWindow();
MessageBox(0,'Cant''t create a GL rendering context.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
if (not wglMakeCurrent(h_Dc, h_Rc)) then
begin
KillGLWindow();
MessageBox(0,'Cant''t activate the GL rendering context.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
ShowWindow(h_Wnd,SW_SHOW);
SetForegroundWindow(h_Wnd);
SetFOcus(h_Wnd);
ReSizeGLScene();
if (not InitGl()) then
begin
KillGLWindow();
MessageBox(0,'initialization failed.','Error',MB_OK or MB_ICONEXCLAMATION);
Result:=false;
exit;
end;
Result:=true;
end;
function WinMain(hInstance: HINST;
hPrevInstance: HINST;
lpCmdLine: PChar;
nCmdShow: integer):
integer; stdcall;
var
msg: TMsg;
done: Bool;
begin
done:=false;
FullScreen:=false;
if not CreateGLWindow('Vecco''s OpenGL Framework',Screen.WorkAreaWidth-40,Screen.WorkAreaHeight-40,16,FullScreen) then
begin
Result := 0;
exit;
end;
while not done do
begin
if (PeekMessage(msg, 0, 0, 0, PM_REMOVE)) then
begin
if msg.message=WM_QUIT then
done:=true
else
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
end
else
begin
if (active and not(DrawGLScene()) or keys[VK_ESCAPE]) then
done:=true
else
SwapBuffers(h_Dc);
if keys[VK_F1] then
begin
Keys[VK_F1] := false;
KillGLWindow();
FullScreen := not FullScreen;
if not CreateGLWindow('Vecco''s OpenGL Framework',Screen.WorkAreaWidth-40,Screen.WorkAreaHeight-40,16,fullscreen) then
Result := 0;
end;
end;
end;
killGLwindow();
result:=msg.wParam;
end;
begin
world := 10;
mapsize :=10;
WinMain(hInstance, hPrevInst, CmdLine, CmdShow );
end.
Głównie z NeHe