![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
OpenGL - как сделать "скриншот"? [D7, WinXP]
Franzy © (2008-03-19 11:22:00)Пишу программу для вывода трехмерных изображений (сеток, если быть точным) с помощью OpenGL. Хочу предусмотреть возможность сохранения картинки в файл в формате BMP. Для чего хочу задействовать стандартную процедуру SavetoFile класса TPicture.
OpenGL у меня рисует на канвасе формы. Пишу такой обработчик события (пункт меню) для формы:
var temp: TPicture;
i,j : longint;
begin
temp:=TPicture.create;
temp.canvas.width:=ClientWidth;
temp.canvas.height:=ClientHeight;
for i:=1 to ClientWidth do
for j:=1 to ClientHeight do
temp.canvas.pixels[i,j]:=canvas.pixels[i,j];
temp.SaveToFile(....)
end;
Все комплилится, работает, даже рисунок сохраняется... НО!!!! Когда открываешь рисунок в том же пэйнте вместо ожидаемого изображения видны картинке в духе черного квадрата Малевича: все залито цветом фона и где-нибудь сбоку широкая полоса цвета, которым рисуется объект...
Подскажите, что я делаю не так, или предложите свой вариант реализации описанной в начале поста возможности.
GladiatorX (2008-08-04 14:00:00) [1]TPanel - наследник от TControl, а у него в секции privateесть
Canvas: TCanvas;. Поэтому для изменения видимости Canvas, сделай согласно предложенному medved_68.
medved_68 (2008-07-31 17:47:00) [2]
> а на TPanel - у нее канваса нет.
Ты ошибаешься. Сделай наследника и переведи канву в раздел public.
Franzy (2008-07-31 14:09:00) [3]P.S. DC - хэндл panel1.
Franzy (2008-07-31 13:54:00) [4]Прога уже другая, но задача осталась прежней. Важное отличие - теперь рисую не на канвасе формы, а на TPanel - у нее канваса нет. Решил сделать по уму, через BitBlt, но не получается. Что я делаю не так?
Вот код:
procedure TForm1.Button3Click(Sender: TObject);
var p : TPicture;
i,j: longint;
shotfile:TFileName;
begin
p:=TPicture.Create;
p.Bitmap.Width:=panel1.ClientWidth;
p.BitMap.Height:=panel1.clientHeight;
BitBlt(p.Bitmap.Handle,0,0,p.Bitmap.Width,p.Bitmap.Height,DC,0,0,SRCCOPY);
if SavePictureDialog1.Execute then
begin
ShotFile:=SavePictureDialog1.FileName;
p.SaveToFile(ShotFile);
p.Destroy;
end;
end;
В файл сохраняется только белый прямоугольник без рисунка.
Sergio666 (2008-03-20 12:00:00) [5]1) Вставляй в конец отрисовки glFinish
2) Используй не canvas.pixels, а BitBlt (из DC OpenGL'я во временный bitmap)
Franzy (2008-03-19 12:17:00) [6]Осталась только одна проблема - как отловить окончание прорисовки?!
Эксперименты показали, что опенджиэль отдает управление еще до того, как закончит рисовать на канвасе. (Запись в файл я поместил в конец обработчика OnPaint формы). Соответственно, в файл картинка сохраняется не полностью... Я в расстройстве. Подскажите, как решить проблему.
Подчеркиваю, мне нужно, чтобы вызывался диалог SavePictureDialog. Как сделать без него (например, по нажатию на клавишу), я знаю.
Franzy (2008-03-19 12:04:00) [7]Пардон, только врубился. Чего-то я не сообразил, что при вызове диалога с именем файла будет вызвано и событие onpaint, в котором идет отрисовка...
Если это учесть, все работает, как надо :)
Спс :)
Franzy (2008-03-19 11:59:00) [8]Повторяю, это обработчик события. Вызывается по нажатию кнопки или пункта меню. Нажатие, разумеется, производится юзером уже после того, как картинка нарисована.
grisme (2008-03-19 11:39:00) [9]
> for i:=1 to ClientWidth do for j:=1 to ClientHeight do
> temp.canvas.pixels[i,j]:=canvas.pixels[i,j];
Маньяк %) а может надо делать скриншот после отрисовки? дождаться ПОЛНОЙ отрисовки кадра, а только затем делать вышеуказанный перегон и сохранять в файл? это просто как вариант.