请问cs中的第一人称视角是怎样实现的?
解决方案 »
- 求一个SQL语句
- HOOK及窗口问题
- 怎么获得数据集的第n个记录?
- 关于Web页面上使用ClientSocket和ServerSocket的问题。
- 放分大调查:各位兄弟平时看的专业技术书籍是买还是借的?如果是买的平均一个月买几本?
- 谁有ExpressQuantumGrid的中文详细说明?
- 一个很简单的问题:如何定义一个全局变量,即能被整个程序,任何窗体调用。
- 关于exit
- 用MediaPlayer在win2000播放mp3时,有严重的暴音,音质很差(win98没事),请问有没有别的比较好的的控件?谢谢
- 求控件:TBitBtn、TSpeedButton的图像能放在dll里面
- ToolButton1问题,帮忙.
- 有没有办法把程序用到的第三方控件生成为DLL文件,程序运行时才调用呢?
但是在delphi里,如果用openGL的话
只要改变时点就行了
只要改变视点就行了
印像当中好像是用的Opengllookat()
但这个函数并不是核心函数,
而是通过调用诸如平移,旋转之类的函数所构成的。transform,rotate.
Windows,
Messages, Dialogs,
OpenGL,
SysUtils,
Textures;Const
WND_TITLE = 'OPenGl 演示程序';
FPS_TIMER = 1;
FPS_INTERVAL = 500;Type
TCoord = Record
X, Y, Z: glFLoat;
End;
TFace = Record
V1, V2, V3, V4: Integer;
U, V: glFloat;
TextureIndex: Integer;
End;Var
h_Wnd : HWND;
h_DC : HDC;
h_RC : HGLRC;
keys : Array[0..255] Of Boolean;
FPSCount : Integer = 0;
ElapsedTime : Integer;
FrameTime : Integer; Texture : Array Of glUint; TextureCount : Integer;
VertexCount : Integer;
FaceCount : Integer;
Vertex : Array Of TCoord;
Face : Array Of TFace; X, Z, Y : glFloat;
HeadMovement, HeadMovAngle: glFloat;
mpos : TPoint;
Heading : glFloat;
Tilt : glFloat; MouseSpeed : Integer = 7;
MoveSpeed : glFloat = 0.03; {$R *.RES}Procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external
opengl32;
Procedure LoadMap;
Var
F : Textfile;
Tex : Array Of String;
S : String;
I, J : Integer;
Begin
AssignFile(F, 'map.txt');
Reset(F); Readln(F, TextureCount);
SetLength(Tex, TextureCount);
SetLength(Texture, TextureCount);
For I := 0 To TextureCount - 1 Do
Begin
Readln(F, S);
Tex[i] := Copy(S, 1, Pos(' ', S) - 1);
S := Copy(S, Pos(' ', S) + 1, length(S));
LoadTexture(S, Texture[i], FALSE);
End; Readln(F, VertexCount);
SetLength(Vertex, VertexCount);
For I := 0 To VertexCount - 1 Do
Readln(F, Vertex[i].X, Vertex[i].Y, Vertex[i].Z); Readln(F, FaceCount);
SetLength(Face, FaceCount);
For I := 0 To FaceCount - 1 Do
Begin
Readln(F, Face[i].V1, Face[i].V2, Face[i].V3, Face[i].V4, Face[i].U,
Face[i].V, S);
S := Trim(Copy(S, 1, 12)); For J := 0 To TextureCount - 1 Do
If Tex[J] = S Then
Face[i].TextureIndex := J;
End;
CloseFile(F);
End;
Var
I : Integer;
Begin
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); glRotate(Tilt, 1, 0, 0);
glRotate(Heading, 0, 1, 0); glTranslatef(X, -0.5 + HeadMovement, Z); For I := 0 To FaceCount - 1 Do
With face[i] Do
Begin
glBindTexture(GL_TEXTURE_2D, Texture[TextureIndex]); glBegin(GL_QUADS);
glTexCoord(0, 0);
glVertex3fv(@Vertex[V1 - 1]);
glTexCoord(U, 0);
glVertex3fv(@Vertex[V2 - 1]);
glTexCoord(U, V);
glVertex3fv(@Vertex[V3 - 1]);
glTexCoord(0, V);
glVertex3fv(@Vertex[V4 - 1]);
glEnd();
End;
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); glEnable(GL_TEXTURE_2D);
LoadMap; Heading := 180;
X := 2.25;
Z := 2;
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, 0.1, 100.0); glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
End;
Procedure ProcessKeys;
Begin
If Keys[VK_UP] Then
Begin
X := X - sin(Heading * pi / 180) * FrameTime / 900;
Z := Z + cos(Heading * pi / 180) * FrameTime / 900;
HeadMovAngle := HeadMovAngle + 5;
HeadMovement := 0.025 * sin(HeadMovAngle * pi / 180);
End;
If Keys[VK_DOWN] Then
Begin
X := X + sin(Heading * pi / 180) * FrameTime / 900;
Z := Z - cos(Heading * pi / 180) * FrameTime / 900;
HeadMovAngle := HeadMovAngle - 5;
HeadMovement := 0.025 * sin(HeadMovAngle * pi / 180);
End;
If Keys[VK_LEFT] Then
Begin
X := X + sin((Heading + 90) * pi / 180) * FrameTime / 900;
Z := Z - cos((Heading + 90) * pi / 180) * FrameTime / 900;
End;
If Keys[VK_RIGHT] Then
Begin
X := X - sin((Heading + 90) * pi / 180) * FrameTime / 900;
Z := Z + cos((Heading + 90) * pi / 180) * FrameTime / 900;
End;
If Keys[VK_Return] Then
Begin
HeadMovAngle := HeadMovAngle - 5;
HeadMovement := 0.025 * sin(HeadMovAngle * pi / 180);
End;End;Function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM):
LRESULT; stdcall;
Begin
Result := 0;
Case (Msg) Of
WM_CREATE:
Begin End;
WM_CLOSE:
Begin
PostQuitMessage(0);
Result := 0
End;
WM_KEYDOWN:
Begin
keys[wParam] := True;
Result := 0;
End;
WM_KEYUP:
Begin
keys[wParam] := False;
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) + ' 帧/秒]'));
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 h_RC > 0 Then
If (Not wglMakeCurrent(h_DC, 0)) Then
MessageBox(0, '释放设备场景句柄失败!', '错误', MB_OK Or
MB_ICONERROR); If (Not wglDeleteContext(h_RC)) Then
Begin
MessageBox(0, '释放渲染句柄失败!', '错误', 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!', '错误', MB_OK Or
MB_ICONERROR);
h_DC := 0;
End; If ((h_Wnd <> 0) And (Not DestroyWindow(h_Wnd))) Then
Begin
MessageBox(0, '无法销毁窗体!', '错误', MB_OK Or
MB_ICONERROR);
h_Wnd := 0;
End; If (Not UnRegisterClass('OpenGL', hInstance)) Then
Begin
MessageBox(0, '无法注册窗体类!', '错误', MB_OK Or
MB_ICONERROR);
hInstance := 0;
End;
End;
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, '注册窗体类失败!', '错误', 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, '不能转换为全屏模式!', '错误', 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;
ShowCursor(false);
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, '不能创建窗体!', '错误', 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; h_DC := GetDC(h_Wnd);
If (h_DC = 0) Then
Begin
glKillWnd(Fullscreen);
MessageBox(0, '不能得到设备场景!', '错误', MB_OK Or
MB_ICONERROR);
Result := False;
Exit;
End; PixelFormat := ChoosePixelFormat(h_DC, @pfd);
If (PixelFormat = 0) Then
Begin
glKillWnd(Fullscreen);
MessageBox(0, '找不到合适的格式', '错误', MB_OK
Or MB_ICONERROR);
Result := False;
Exit;
End; If (Not SetPixelFormat(h_DC, PixelFormat, @pfd)) Then
Begin
glKillWnd(Fullscreen);
MessageBox(0, '无法创建渲染格式', '错误', MB_OK Or
MB_ICONERROR);
Result := False;
Exit;
End; h_RC := wglCreateContext(h_DC);
If (h_RC = 0) Then
Begin
glKillWnd(Fullscreen);
MessageBox(0, '无法创建OpenGL 绘制描述表', '错误',
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();
SetCursorPos(400, 300); 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); FrameTime := GetTickCount() - ElapsedTime - DemoStart;
LastTime := ElapsedTime;
ElapsedTime := GetTickCount() - DemoStart;
ElapsedTime := (LastTime + ElapsedTime) Div 2; If GetForegroundWindow = h_Wnd Then
Begin
GetCursorPos(mpos);
SetCursorPos(400, 300);
Heading := Heading + (mpos.x - 400) / 100 * MouseSpeed;
Tilt := Tilt - (300 - mpos.y) / 100 * MouseSpeed;
If Tilt > 60 Then
Tilt := 60;
If Tilt < -60 Then
Tilt := -60;
End; glDraw();
SwapBuffers(h_DC); If (keys[VK_ESCAPE]) Then
finished := True
Else
ProcessKeys;
End;
End;
glKillWnd(FALSE);
Result := msg.wParam;
End;Begin
WinMain(hInstance, hPrevInst, CmdLine, CmdShow);
End.
阿德的例子没有错的啦,就是一个主视角的demo
所以……up啦