-
Всем привет. Натолкнулся на проблему по сабжу. Может кто сталкивался с таким? Захотелось мне нарисовать кружок на форме средствами OpenGL и сделать все пространство формы вне этого кружечка прозрачным. Проблема собственно в скорости вывода на экран, никак не пойму почему фпс у меня выходит около 100, а картинка перемещается рывками, когда выключаю TransparentColor, все плавно и фпс 500, пробовал при выключеном TransparentColor затормозить прорисовку командой Sleep(10), получается фпс 90, а картинка все равно движется плавно. Если OpenGL и TForm.TransparentColor не совместимы, то можно ли как-нибудь по другому вывести анимированный трехмерный объект на рабочий стол без фона? Раскадровку не предлагать :)
-
рендер в BitMap. BitMap на форму.
-
сомневаюсь что он получит 90фпс даже если сделать окно layered
-
Мне не нужно 90 фпс, они у меня и так есть, мне нужна плавная анимация не важно на каком фпс. А пока не получается даже заставить рисовать OpenGL в битмап. Вычитал что OpenGL может рисовать только в DIB, сейчас пытаюсь инициализировать, пока безуспешно. А функция glBitMap, с ее помощью можно решить проблему?
-
Что-то совсем не выходит, сейчас не выводит битмап на форму, раньше рисовался но сам OpenGL не рисовал в битмап. Посмотрите может где оступился:
procedure TForm1.Initialize;
var
pfd : TPixelFormatDescriptor;
nPixelFormat : Integer;
BIH: tagBITMAPINFO;
begin
Bit:=TBitMap.Create;
W:=Form1.Width;
H:=Form1.Height;
Bit.Width:=W;
Bit.Height:=H;
DC:=GetDC(Bit.Handle);
BIH.bmiHeader.biSize := sizeof(tagBITMAPINFOHEADER);
BIH.bmiHeader.biWidth := W;
BIH.bmiHeader.biHeight := H;
BIH.bmiHeader.biPlanes := 1;
BIH.bmiHeader.biBitCount := 32;
BIH.bmiHeader.biCompression := BI_RGB;
Bit.Handle := CreateDIBSection(DC, BIH, DIB_RGB_COLORS, Scr, 0, 0);
ZeroMemory(Scr, W * H * 4);
FillChar(pfd, SizeOf(pfd), 0);
with pfd do begin
nsize:=sizeof(tpixelformatdescriptor);
nversion:=1;
dwflags:=PFD_DRAW_TO_BITMAP or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
ipixeltype:=PFD_TYPE_RGBA;
ilayertype:=PFD_MAIN_PLANE;
ccolorbits:=32;
cdepthbits:=16;
end;
nPixelFormat := ChoosePixelFormat (DC, @pfd);
SetPixelFormat (DC, nPixelFormat, @pfd);
hrc := wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
end;
Рисую здесь
procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Ball.Render;
SwapBuffers(DC);
BitBlt(Canvas.Handle, 0, 0, W, H, Bit.Canvas.Handle, 0, 0, SRCCOPY);
end;
-
Тут я ошибся, на самом деле битмап рисует в канвас, просто сделал форму черного цвета, а после создания DIB в битмапе фон становится черным а не белым как до создания, сейчас поменял цвет формы и видно что все же рисует но сам OpenGL не заполняет битмап. Значит проблема в инициализации, подскажите сам не справлюсь.
-
Получилось рисовать в DIB, и выводить его на форму. Оказалось что TBitMap здесь абсолютно лишний. Как хэндл для контекста и для вывода в канвас нужен был только HBITMAP. Не разобрался сразу т.к. в гугле не нашел на эту тему решений на Делфи, на C++ навалом, а вот на Делфи да еще и с OpenGL так совсем ничего не попалось. Правда пока разбирался что-то у меня сломалось в Idle, теперь отрисовка идет только срабатывает событие OnMouseMove. Сейчас отремонтирую и будет видно как такой вывод повлияет на плавность анимации.
-
Я ничего про TBitMap не говорил. В инете есть кучка примеров, там никаких языкозависимых вещей нету, поэтому они легко переносятся с С++ на Дельфи.
-
@!!ex, спасибо. Анимация стала заметно лучше правда скорость сильно зависит от размеров окна, хотелось сделать его на весь экран, а все лишнее сделать прозрачным, придется совмещать движение объекта и положение формы. В общем инициализация у меня приняла вид:
procedure TForm1.Initialize;
var
pfd : TPixelFormatDescriptor;
nPixelFormat : Integer;
BitInfo : BITMAPINFO;
hBit : HBITMAP;
Scr : Pointer;
begin
W:=ClientWidth;
H:=ClientHeight;
ZeroMemory(@BitInfo, sizeof(BITMAPINFOHEADER));
With BitInfo.bmiHeader do begin
biSize:=sizeof(BITMAPINFOHEADER);
biWidth:=W;
biHeight:=H;
biPlanes:=1;
biBitCount:=16;
biCompression:=BI_RGB;
end;
DC:=CreateCompatibleDC(0);
hBit:=CreateDIBSection(DC, BitInfo, DIB_RGB_COLORS, Scr, 0, 0);
SelectObject(DC, hBit);
FillChar(pfd, SizeOf(pfd), 0);
with pfd do begin
nsize:=sizeof(tpixelformatdescriptor);
nversion:=1;
dwflags:=PFD_DRAW_TO_BITMAP or PFD_SUPPORT_OPENGL or PFD_SUPPORT_GDI;
ipixeltype:=PFD_TYPE_RGBA;
ilayertype:=PFD_MAIN_PLANE;
ccolorbits:=16;
cdepthbits:=16;
end;
nPixelFormat:=ChoosePixelFormat (DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
hrc:=wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
end;
А отрисовка:
procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Ball.Render;
glFlush;
BitBlt(Canvas.Handle, 0, 0, W, H, DC, 0, 0, SRCCOPY);
InvalidateRect(Handle, nil, false);
end;
При запуске если окно с бордюром (не bsNone), то заметно, что перед первой прорисовкой оно окрашено в черный цвет хотя Color окна имеет другое значение и сразу должно быть прозрачным. Хотелось бы избавиться от этого "мерцания".
-
Такой вариант не поддерживает двойную буферизацию и анимация выглядит как... как без двойной буферизации :( Как быть?
|