Конференция "Media" » OpenGL - как сделать "скриншот"? [D7, WinXP]
 
  • Franzy (19.03.08 11:22) [0]
    Пишу программу для вывода трехмерных изображений (сеток, если быть точным) с помощью 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;

    Все комплилится, работает, даже рисунок сохраняется... НО!!!! Когда открываешь рисунок в том же пэйнте вместо ожидаемого изображения видны картинке в духе черного квадрата Малевича: все залито цветом фона и где-нибудь сбоку широкая полоса цвета, которым рисуется объект...

    Подскажите, что я делаю не так, или предложите свой вариант реализации описанной в начале поста возможности.
  • grisme (19.03.08 11:39) [1]

    > for i:=1 to ClientWidth do  for j:=1 to ClientHeight do
    >    temp.canvas.pixels[i,j]:=canvas.pixels[i,j];


    Маньяк %) а может надо делать скриншот после отрисовки? дождаться ПОЛНОЙ отрисовки кадра, а только затем делать вышеуказанный перегон и сохранять в файл? это просто как вариант.
  • Franzy (19.03.08 11:59) [2]
    Повторяю, это обработчик события. Вызывается по нажатию кнопки или пункта меню. Нажатие, разумеется, производится юзером уже после того, как картинка нарисована.
  • Franzy (19.03.08 12:04) [3]
    Пардон, только врубился. Чего-то я не сообразил, что при вызове диалога с именем файла будет вызвано и событие onpaint, в котором идет отрисовка...
    Если это учесть, все работает, как надо :)
    Спс :)
  • Franzy (19.03.08 12:17) [4]
    Осталась только одна проблема - как отловить окончание прорисовки?!

    Эксперименты показали, что опенджиэль отдает управление еще до того, как закончит рисовать на канвасе. (Запись в файл я поместил в конец обработчика OnPaint формы). Соответственно, в файл картинка сохраняется не полностью... Я в расстройстве. Подскажите, как решить проблему.

    Подчеркиваю, мне нужно, чтобы вызывался диалог SavePictureDialog. Как сделать без него (например, по нажатию на клавишу), я знаю.
  • Sergio666 © (20.03.08 12:00) [5]
    1) Вставляй в конец отрисовки glFinish
    2) Используй не canvas.pixels, а BitBlt (из DC OpenGL'я во временный bitmap)
  • Franzy (31.07.08 13:54) [6]
    Прога уже другая, но задача осталась прежней. Важное отличие - теперь рисую не на канвасе формы, а на 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;



    В файл сохраняется только белый прямоугольник без рисунка.
  • Franzy (31.07.08 14:09) [7]
    P.S. DC - хэндл panel1.
  • medved_68 © (31.07.08 17:47) [8]

    > а на TPanel - у нее канваса нет.

    Ты ошибаешься. Сделай наследника и переведи канву в раздел public.
  • GladiatorX © (04.08.08 14:00) [9]
    TPanel - наследник от TControl, а у него в секции private есть
    Canvas: TCanvas;

    . Поэтому для изменения видимости Canvas, сделай согласно предложенному medved_68.
 
Конференция "Media" » OpenGL - как сделать "скриншот"? [D7, WinXP]
Есть новые Нет новых   [133926   +461][b:0][p:0.001]