Задача: сделать средствами Lazarus'а и Opengl скриншот.
Что странно: в интернете видел кучу таких примеров:
- Код: Выделить всё
w:=1024;
h:=768;
bpp:=32;
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, bits);
После чего в bits должен оказаться скриншот - не работает пробовал на разных машинах - в bits оказывается чёрный экран. Также пробовал:
- Код: Выделить всё
w:=1024;
h:=768;
bpp:=32;
glReadBuffer( GL_BACK );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, bits);
glFlush(); glFinish(); ставил перед выполнением glReadPixels - всё равно чёрный экран получаем.
Как заработало:
- Код: Выделить всё
w:=1024;
h:=768;
bpp:=32;
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(w, h);
glutInitWindowPosition(0, 0);
wingl:=glutCreateWindow('OpenGL Tutorial :: First Program');
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, bits);
glutDestroyWindow(wingl);
Но с косяком (скриншот смотри во вложении) Сверху чёрная полоса снизу и справа муар...
Собственно более полный код:
- Код: Выделить всё
w:=1024;
h:=768;
bpp:=32;
glFlush(); glFinish();
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(w, h);
glutInitWindowPosition(0, 0);
wingl:=glutCreateWindow('OpenGL Tutorial :: First Program');
ZeroMemory(@Binfo, sizeof(BITMAPINFO));
OneCTpokaInBytes:=w*(bpp div 8);
BInfo.bmiHeader.biBitCount := bpp;
//3agaeM LLIupuHy
BInfo.bmiHeader.biWidth := w;
//минус нужен, чтобы перевернуть картинку, потому что см. выше как в дин. памяти всё пишется
BInfo.bmiHeader.biHeight := h;
if ((BInfo.bmiHeader.biBitCount = 0) or (BInfo.bmiHeader.biWidth = 0) or
(BInfo.bmiHeader.biHeight = 0)) then
begin
form1.Caption := '..)=..Получены некорректные данные ширины/высоты/глубины..=(..';
exit;
end;
with BInfo.bmiHeader do
begin
//Длина структуры BInfo
biSize := sizeof(BITMAPINFOHEADER);
//Должно равняться 1(думаю в будущем будет 2ух и 3ез плоскостное =D )
biPlanes := 1;
//noJIy4uJIu y}I{e B oTJIago4HoM npuH9Tuu;
biCompression := BI_RGB;
//abs, потому что biHeight, см. выше величина отрицательная
//pa3Mep должен быть в байтах поэтому глубину(она в битах) делим на 8
biSizeImage := (biWidth*abs(biHeight)*(biBitCount div 8));
end;
//Создаём буферную бмпишку в которую и будут складироваться данные
//С помощью CreateDIBSection мы указываем переменную bits, где на самом деле находится картинка
tmpbmp:=Graphics.TBitmap.Create;
tmpbmp.Handle:=CreateDIBSection(tmpbmp.canvas.handle,BInfo,DIB_RGB_COLORS,bits,0,0);
glReadBuffer( GL_FRONT );
// GL_BGR - 0x80E0
// GL_BGRA - 0x80E1
// I dont know why GL_BGRA and GL_BGR not define in uses gl, glu, glut
glReadPixels( 0, 0, w, h, $80E1, GL_UNSIGNED_BYTE, bits);
tmpbmp.SaveToFile('asd.bmp');
tmpbmp.Free;
glutDestroyWindow(wingl);
Теория почему не работает: glutCreateWindow - создаёт окно у которого есть заголовок и рамка - заголовок на скриншоте отображает чёрным, муар - это рамка.