Здравствуйте.
Использовал код примеров NeHe для Delphi, переписав его под Lazarus. Но, почему-то при компиляции помимо выводимых текстур появляется черная полоса, причем, при каждом запуске ее расположение меняется.
Скажите, в чем может быть проблема?
Архив с программой | Скриншот
Код программы:
- Код: Выделить всё
program Beta;
{$MODE ObjFPC}
{$APPTYPE gui}
uses
//
GL, FreeImage, Windows;
const
//
TexturesCount = 2;
// Textures.
//
BackgroundTex = 0;
//
LogoTex = 1;
//
TexturesNames: array [0..1] of String = (
//
'bg', 'title');
type
//
PByteArray = ^TByteArray;
//
TByteArray = array [Word] of Byte;
var
//
h_Rc: HGLRC;
//
h_Dc: HDC;
//
h_Wnd: HWND;
//
Keys: array [0..255] of Boolean;
//
Active: Boolean = True;
//
FullScreen: Boolean;
//
MenuStage: Byte;
//
Textures: array of GLuint;
//
procedure LoadTexture(
FileName: AnsiString; var Texture: GLuint);
const
//
AlphaGreenMask = $FF00FF00;
//
ThirdByteMask = $FF0000;
//
FirstByteMask = $FF;
var
//
dib: PFIBITMAP; w, h: Cardinal;
//
Data: PByteArray; Dest, Src: Pointer;
begin
//
FileName:='Data\' + FileName + '.png';
//
dib:=FreeImage_Load(FIF_PNG, PChar(FileName));
//
if dib = nil then Exit;
//
FreeImage_FlipVertical(dib);
//
dib:=FreeImage_ConvertTo32Bits(dib);
//
w:=FreeImage_GetWidth(dib);
//
h:=FreeImage_GetHeight(dib);
//
GetMem(Data, 4 * w * h);
//
Dest:=Data;
//
Src:=FreeImage_GetBits(dib);
//
{$ASMMODE Intel}
asm
//
push esi
//
push edi
//
push eax
//
push ebx
//
push ecx
//
push edx
//
mov esi, [Src]
//
mov edi, [Dest]
//
xor eax, eax
//
mov eax, w
//
mul h
@Move4Bits:
//
mov ebx, [esi]
//
mov ecx, ebx
//
and ecx, ThirdByteMask
//
shr ecx, 16
//
mov edx, ebx
//
and edx, FirstByteMask
//
shl edx, 16
//
mov dl, cl
//
and ebx, AlphaGreenMask
//
add ebx, edx
//
mov [edi], ebx
//
add esi, 4
//
add edi, 4
//
dec eax
//
jnz @Move4Bits
//
pop edx
//
pop ecx
//
pop ebx
//
pop eax
//
pop edi
//
pop esi
//
emms
end;
//
FreeImage_Unload(dib);
//
glBindTexture(GL_TEXTURE_2D, Texture);
//
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
//
w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data);
//
glTexParameteri(GL_TEXTURE_2D,
//
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//
glTexParameteri(GL_TEXTURE_2D,
//
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//
glEnable(GL_TEXTURE_2D);
//
FreeMem(Data, w * h * 4);
//
Data:=nil;
end;
procedure LoadTextures;
var
i, k: Byte;
begin
//
SetLength(Textures, TexturesCount);
//
k:=TexturesCount - 1;
//
for i:=0 to k do
begin
//
glGenTextures(1, @Textures[i]);
//
LoadTexture(TexturesNames[i], Textures[i]);
end;
end;
//
procedure ReSizeGLScene(Width: GLsizei; Height: GLsizei);
begin
//
if Height = 0 then Height:=1;
//
glViewport(0, 0, Width, Height);
//
glMatrixMode(GL_PROJECTION);
//
glLoadIdentity;
//
glMatrixMode(GL_MODELVIEW);
//
glLoadIdentity;
end;
//
procedure LoadData;
begin
//
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//
LoadTextures;
end;
procedure FreeTextures;
var
i, k: Byte;
begin
//
k:=TexturesCount - 1;
//
for i:=0 to k do
//
glDeleteTextures(1, @Textures[i]);
end;
procedure FreeData;
begin
//
FreeTextures;
end;
function InitGL: Boolean;
begin
//
LoadData;
//
Result:=True;
end;
procedure PreRender;
begin
//
glMatrixMode(GL_PROJECTION);
//
glLoadIdentity;
//
glOrtho(0, 800, 600, 0, 0, 1);
//
glMatrixMode(GL_MODELVIEW);
//
glLoadIdentity;
//
glBindTexture(GL_TEXTURE_2D, Textures[BackgroundTex]);
//
glBegin(GL_QUADS);
//
glTexCoord2f(0, 0);
//
glVertex2f(0, 0);
//
glTexCoord2f(1, 0);
//
glVertex2f(800, 0);
//
glTexCoord2f(1, 1);
//
glVertex2f(800, 600);
//
glTexCoord2f(0, 1);
//
glVertex2f(0, 600);
//
glEnd;
//
glBindTexture(GL_TEXTURE_2D, Textures[LogoTex]);
//
glBegin(GL_QUADS);
//
glTexCoord2f(0, 0);
//
glVertex2f(304, 68);
//
glTexCoord2f(1, 0);
//
glVertex2f(495, 68);
//
glTexCoord2f(1, 1);
//
glVertex2f(495, 150);
//
glTexCoord2f(0, 1);
//
glVertex2f(304, 150);
//
glEnd;
end;
function glDraw: Boolean;
begin
//
glViewport(0, 0, 800, 600);
//
glColor3f(1, 1, 1);
//
glClearColor(0, 0, 0, 0);
//
glClearDepth(1);
//
glClear(GL_COLOR_BUFFER_BIT or
GL_DEPTH_BUFFER_BIT);
//
PreRender;
//
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
//
FreeData;
//
PostQuitMessage(0);
//
Result:=0;
end;
//
WM_KEYDOWN:
begin
//
Keys[wParam]:=True;
//
Result:=0;
end;
//
WM_KEYUP:
begin
//
Keys[wParam]:=False;
//
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 Window', hInstance)) then
//
MessageBox(0, 'Could Not Unregister Class.', 'SHUTDOWN ERROR', MB_OK or MB_ICONINFORMATION);
end;
function CreateGlWindow(FullScreenflag: Boolean):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:=800;
//
WindowRect.Bottom:=600;
//
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_APPLICATION);
//
hCursor:=LoadCursor(0, IDC_ARROW);
//
hbrBackground:=0;
//
lpszMenuName:=nil;
//
lpszClassName:='OpenGL Window';
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:=800;
//
dmPelsHeight:=600;
//
dmBitsPerPel:=32;
//
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?', 'NeHe 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 Window',
'OpenGL',
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;
//
FillChar(pfd,
//
SizeOf(PIXELFORMATDESCRIPTOR), 0);
//
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:=32;
//
cDepthBits:=32;
//
iLayerType:=PFD_MAIN_PLANE;
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(800, 600);
//
if not InitGl then
begin
//
KillGLWindow;
//
MessageBox(0, 'initialization failed.', 'Error', MB_OK or MB_ICONEXCLAMATION);
//
Result:=False;
//
Exit;
end;
//
Result:=True; // Vљe probмhlo v poшбdku
end;
function WinMain: Integer; stdcall;
var
//
WndMsg: TMsg;
//
Done: Boolean;
begin
//
Done:=False;
//
if MessageBox(0, 'Would You Like To Run In FullScreen Mode?', 'Start FullScreen',
MB_YESNO or MB_ICONQUESTION) = IDNO then
//
FullScreen:=False else FullScreen:=True;
//
if not CreateGLWindow(FullScreen) then
begin
//
Result:=0;
//
Exit;
end;
//
while not Done do
begin
//
if PeekMessage(WndMsg, 0, 0, 0, PM_REMOVE) then
begin
//
if WndMsg.message = WM_QUIT then Done:=True // Konec programu
else
begin
//
TranslateMessage(WndMsg);
//
DispatchMessage(WndMsg);
end;
end
else
begin
//
if ((Active) and (not glDraw)) 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(FullScreen) then
//
Result:=0;
end;
end;
end;
//
killGLwindow;
//
Result:=WndMsg.wParam;
end;
{$R *.res}
begin
//
WinMain;
end.