Fejl i program fra NeHe
Jeg har denne kode:program lesson16;
//
// This code was created by Jeff Molofee '99
//
// If you've found this code useful, please let me know.
//
// Visit me at www.demonews.com/hosted/nehe
//
// Translation to Delphi/Object Pascal by Marc Aarts (marca@stack.nl)
//
uses
Windows,
Messages,
OpenGL,
{ The 'glAux' unit can be found at
http://www.delphi-jedi.org/DelphiGraphics/OpenGL/GLAux.zip
The glaux translation was done by Manuel Parma and is hosted at the
Delphi-Jedi Project web site in the graphics section. You may also
be interested in the OpenGL headers available there, since they are
more complete than the version that shipped with Delphi 4 and 5.
The OpenGL headers there support the full 1.1 spec and supports dynamic
linking to the opengl32.dll so you can detect whether or not it's
available in the first place. If you DO use that version of the OpenGL
header, you can remove the two texture procedures declared below since
they are present in that translation.
Please note: the glAux unit will REQUIRE the glaux.dll library to be
present when you run this program. You can install it from the GLAux.zip
mentioned above into your Windows SYSTEM directory (SYSTEM32 for you
NT users). Or, simply keep a copy of it in the same directory as your
application.
If any of this is confusing or you need help, feel free to e-mail me
at marca@stack.nl. Do NOT e-mail Jeff regarding Delphi translation
issues since he is not responsible for the translation I've done here.}
glAux; // see above comment if you get an error on this line.
const glu32 = 'glu32.dll';
const opengl32 = 'opengl32.dll';
procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
// The gluBuild2DMipmaps declaration in the Delphi 4 version of the OpenGL unit
// was improperly declared. I've redeclared it here:=
function gluBuild2DMipmaps(target: GLenum; components, width, height: GLint; format, atype: GLenum; Data: Pointer): GLint; stdcall; external glu32;
var
h_RC: HGLRC; // Permanent Rendering Context
h_DC: HDC; // Private GDI Device Context
keys: array [0..255] of BOOL; // Array Used For The Keyboard Routine
light: boolean; // Lighting ON/OFF
lp: boolean; // L Pressed?
fp: boolean; // F Pressed?
gp: boolean; // G Pressed? ( NEW )
xrot: GLfloat; // X Rotation
yrot: GLfloat; // Y Rotation
xspeed: GLfloat; // X Rotation Speed
yspeed: GLfloat; // Y Rotation Speed
texture: array [0..2] of GLuint; // Storage for 3 textures
filter: GLuint; // Which Filter To Use
fogfilter: GLuint; // Which Fog mode to use
z: GLfloat;
const
LightAmbient: array [0..3] of GLfloat = ( 0.5, 0.5, 0.5, 1.0 );
LightDiffuse: array [0..3] of GLfloat = ( 1.0, 1.0, 1.0, 1.0 );
LightPosition: array [0..3] of GLfloat = ( 0.0, 0.0, 2.0, 1.0 );
fogMode: array [0..2] of GLuint = (GL_EXP, GL_EXP2, GL_LINEAR); // Storage for three types of Fog
fogColor: array [0..3] of GLfloat = ( 0.5, 0.5, 0.5, 1.0 ); // Fog Color
// Load Bitmaps And Convert To Textures
procedure LoadGLTextures;
var texture1: PTAUX_RGBImageRec;
begin
filter := 0;
fogfilter := 0;
z := -5.0;
// Load Texture
texture1 := auxDIBImageLoadA('Data/crate.bmp');
if not Assigned(texture1) then Halt(1);
// Create Nearest Filtered Texture
glGenTextures(3, texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1^.sizeX, texture1^.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1^.data);
// Create Linear Filtered Texture
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1^.sizeX, texture1^.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1^.data);
// Create MipMapped Texture
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture1^.sizeX, texture1^.sizeY, GL_RGB, GL_UNSIGNED_BYTE, texture1^.data);
end;
procedure InitGL(Width: GLsizei; Height: GLsizei); // This Will Be Called Right After The GL Window Is Created
var fWidth, fHeight: GLfloat;
begin
LoadGLTextures(); // Load The Texture(s)
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glClearColor(0.5, 0.5, 0.5, 1.0); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
fWidth := Width;
fHeight := Height;
gluPerspective(45.0,fWidth/fHeight,0.1,100.0); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
glLightfv(GL_LIGHT1, GL_AMBIENT, @LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,@LightPosition);
glEnable(GL_LIGHT1);
glEnable(GL_FOG); // Enables GL_FOG
glFogi (GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode
glFogfv (GL_FOG_COLOR, @fogColor); // Set Fog Color
glFogf (GL_FOG_DENSITY, 0.35); // How Dense Will The Fog Be
glHint (GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value
glFogf (GL_FOG_START, 1.0); // Fog Start Depth
glFogf (GL_FOG_END, 5.0); // Fog End Depth
end;
procedure ReSizeGLScene(Width: GLsizei; Height: GLsizei);
var
fWidth, fHeight: GLfloat;
begin
if (Height=0) // Prevent A Divide By Zero If The Window Is Too Small
then Height:=1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
fWidth := Width;
fHeight := Height;
gluPerspective(45.0,fWidth/fHeight,0.1,100.0);
glMatrixMode(GL_MODELVIEW);
end;
procedure DrawGLScene;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0,0.0,z);
glRotatef(xrot,1.0,0.0,0.0);
glRotatef(yrot,0.0,1.0,0.0);
glBindTexture(GL_TEXTURE_2D, texture[filter]);
glBegin(GL_QUADS);
// Front Face
glNormal3f( 0.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
// Back Face
glNormal3f( 0.0, 0.0,-1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
// Top Face
glNormal3f( 0.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
// Bottom Face
glNormal3f( 0.0,-1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
// Right face
glNormal3f( 1.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
// Left Face
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glEnd();
xrot := xrot + xspeed;
yrot := yrot + yspeed;
end;
function WndProc(hWnd: HWND; message: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
Screen: TRECT;
PixelFormat: GLuint;
pfd: TPIXELFORMATDESCRIPTOR;
begin
with pfd do begin
nSize:= sizeof( TPIXELFORMATDESCRIPTOR ); // Size Of This Pixel Format Descriptor
nVersion:= 1; // Version Number (?)
dwFlags:= PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType:= PFD_TYPE_RGBA; // Request An RGBA Format
cColorBits:= 16; // Select A 16Bit Color Depth
cRedBits:= 0; // Color Bits Ignored (?)
cRedShift:= 0;
cGreenBits:= 0;
cBlueBits:= 0;
cBlueShift:= 0;
cAlphaBits:= 0; // No Alpha Buffer
cAlphaShift:= 0; // Shift Bit Ignored (?)
cAccumBits:= 0; // No Accumulation Buffer
cAccumRedBits:= 0; // Accumulation Bits Ignored (?)
cAccumGreenBits:= 0;
cAccumBlueBits:= 0;
cAccumAlphaBits:= 0;
cDepthBits:= 16; // 16Bit Z-Buffer (Depth Buffer)
cStencilBits:= 0; // No Stencil Buffer
cAuxBuffers:= 0; // No Auxiliary Buffer (?)
iLayerType:= PFD_MAIN_PLANE; // Main Drawing Layer
bReserved:= 0; // Reserved (?)
dwLayerMask:= 0; // Layer Masks Ignored (?)
dwVisibleMask:= 0;
dwDamageMask:= 0;
end;
Result := 0;
case (message) of // Tells Windows We Want To Check The Message
WM_CREATE:
begin
h_DC := GetDC(hWnd); // Gets a Device Context For The Window
PixelFormat := ChoosePixelFormat(h_DC, @pfd); // Finds The Closest Match To The Pixel Format We Set Above
if (PixelFormat=0) then
begin
MessageBox(0,'Cant''t Find A Suitable PixelFormat.','Error',MB_OK or MB_ICONERROR);
PostQuitMessage(0); // This Sends A 'Message' Telling The Program To Quit
exit;
end;
if (not SetPixelFormat(h_DC,PixelFormat,@pfd)) then
begin
MessageBox(0,'Can''t Set The PixelFormat.','Error',MB_OK or MB_ICONERROR);
PostQuitMessage(0);
exit;
end;
h_RC := wglCreateContext(h_DC);
if (h_RC=0) then
begin
MessageBox(0,'Can''t Create A GL Rendering Context.','Error',MB_OK or MB_ICONERROR);
PostQuitMessage(0);
exit;
end;
if (not wglMakeCurrent(h_DC, h_RC)) then
begin
MessageBox(0,'Can''t activate GLRC.','Error',MB_OK or MB_ICONERROR);
PostQuitMessage(0);
exit;
end;
GetClientRect(hWnd, Screen);
InitGL(Screen.right, Screen.bottom);
end;
WM_DESTROY, WM_CLOSE:
begin
ChangeDisplaySettings(TDEVMODE(nil^), 0);
wglMakeCurrent(h_DC,0);
wglDeleteContext(h_RC);
ReleaseDC(hWnd,h_DC);
PostQuitMessage(0);
end;
WM_KEYDOWN:
begin
keys[wParam] := TRUE;
end;
WM_KEYUP:
begin
keys[wParam] := FALSE;
end;
WM_SIZE:
begin
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
end;
else
begin
Result := DefWindowProc(hWnd, message, wParam, lParam);
exit;
end;
end;
end;
function WinMain(hInstance: HINST; hPrevInstance: HINST; lpCmdLine: PChar; nCmdShow: integer): integer; stdcall;
var
msg: TMsg; // Windows Message Structure
wc: TWndClass; // Windows Class Structure Used To Set Up The Type Of Window
h_Wnd: HWND; // Storage For Window Handle
dmScreenSettings: TDEVMODE;
begin
ZeroMemory( @wc, sizeof( wc ) );
wc.style := CS_HREDRAW or CS_VREDRAW or CS_OWNDC;
wc.lpfnWndProc := @WndProc;
wc.hInstance := hInstance;
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.lpszClassName := 'OpenGL WinClass';
if(RegisterClass(wc)=0) then
begin
MessageBox(0,'Failed To Register The Window Class.','Error',MB_OK or MB_ICONERROR);
Result := 0;
exit;
end;
h_Wnd := CreateWindow(
'OpenGL WinClass',
'Jeff Molofee''s GL Code Tutorial ... NeHe 2000', // Title Appearing At The Top Of The Window
WS_POPUP or
WS_CLIPCHILDREN or
WS_CLIPSIBLINGS,
0, 0, // The Position Of The Window On The Screen
640, 480, // The Width And Height Of The WIndow
0,
0,
hInstance,
nil);
if (h_Wnd = 0) then
begin
MessageBox(0,'Window Creation Error.','Error',MB_OK or MB_ICONERROR);
Result := 0;
exit;
end;
ZeroMemory( @dmScreenSettings, sizeof( TDEVMODE ) );
dmScreenSettings.dmSize := sizeof( TDEVMODE );
dmScreenSettings.dmPelsWidth := 640; // Width
dmScreenSettings.dmPelsHeight := 480; // Height
dmScreenSettings.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT; // Color Depth
ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN); // Switch To Fullscreen Mode
ShowWindow(h_Wnd, SW_SHOW);
UpdateWindow(h_Wnd);
SetFocus(h_Wnd);
while ( true ) do
begin
// Process All Messages
while (PeekMessage(msg, 0, 0, 0, PM_NOREMOVE)) do
begin
if (GetMessage(msg, 0, 0, 0)) then
begin
TranslateMessage(msg);
DispatchMessage(msg);
end
else
begin
Result := 1;
exit;
end;
end;
DrawGLScene();
SwapBuffers(h_DC);
if (keys[VK_ESCAPE]) then SendMessage(h_Wnd,WM_CLOSE,0,0);
if (keys[ord('L')] and not lp) then
begin
lp := True;
light := not light;
if (not light)
then glDisable(GL_LIGHTING)
else glEnable(GL_LIGHTING);
end;
if (not keys[ord('L')]) then lp:=FALSE;
if (keys[ord('F')] and not fp) then
begin
fp := True;
Filter := Filter + 1;
if (Filter > 2) then Filter := 0;
end;
if (not keys[ord('F')]) then
fp:=FALSE;
if (keys[VK_PRIOR]) then z := z - 0.02;
if (keys[VK_NEXT]) then z := z + 0.02;
if (keys[VK_UP]) then xspeed := xspeed - 0.01;
if (keys[VK_DOWN]) then xspeed := xspeed + 0.01;
if (keys[VK_RIGHT]) then yspeed := yspeed + 0.01;
if (keys[VK_LEFT]) then yspeed := yspeed - 0.01;
if (keys[ord('G')] and not gp) then
begin
gp := TRUE;
fogfilter := fogfilter + 1;
if (fogfilter>2) then fogfilter := 0;
glFogi (GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode
end;
if (not keys[ord('G')]) then gp := False;
end;
end;
begin
WinMain( hInstance, hPrevInst, CmdLine, CmdShow );
end.
Når jeg starter programmet, skifter den bare skærmopløsningen til 640*480, og så sker der ikke mere, programmet går bare kold.
Hvad er der ivejen?
Jeg har både de DLL-filer og dcu filer jeg skal bruge!
