Печать OpenGL картинки

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Печать OpenGL картинки

Сообщение Vlad04 » 01.12.2011 20:19:43

Здравствуйте. Кто-нибудь может привести работающий пример вывода картинки созданной командами OpenGL на принтер. Создание контекста OpenGL на канве принтера печатает чистый лист.
Аватара пользователя
Vlad04
новенький
 
Сообщения: 79
Зарегистрирован: 11.12.2007 21:11:19
Откуда: Караганда. Казахстан

Re: Печать OpenGL картинки

Сообщение FedeX » 02.12.2011 11:39:55

Под вендой на контекст принтера OpenGL рендерить не сможет. По-идее OpenGL может рендерить в софтовом режиме в dib (device intepended bitmap). Иначе - только в окно, этого требуют драйвера (правда как вариант попробовать создать маленькое а возможно и невидимое окно с контекстом, затем приаттачить к нему OpenGL pbuffer или framebuffer, непомню точно, рендерить в них и потом при помощи glreadPixels читать пикселы в битмап, который уже рисовать на принтере - но могут быть траблы с драйверами).
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: Печать OpenGL картинки

Сообщение Vlad04 » 04.12.2011 12:31:07

Ок, буду разбираться сам.

Добавлено спустя 4 часа 20 минут 2 секунды:
Вот нашел такой пример: OpenGL выводит картинку на TBitmap, который потом копируется на канву принтера. В Delphi все пашет, а в Lazarus`е черная страница...
Код: Выделить всё
procedure SetDCPixelFormat(DC:THandle;var Palette:HPalette;ToBitmap:Boolean);
var hHeap:THandle;
     nColors,I:Integer;
     lpPalette:PLogPalette;
     byRedMask,byGreenMask,byBlueMask:Byte;
     nPixelFormat:Integer;
     pfd:TPixelFormatDescriptor;
  begin
   FillChar(pfd,SizeOf(pfd),0);
   with pfd do
    begin
     nSize:=sizeof(pfd);
     nVersion:=1;
     if ToBitmap then
      dwFlags:=PFD_DRAW_TO_BITMAP or PFD_GENERIC_ACCELERATED or PFD_SUPPORT_OPENGL
     else
      dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
     iPixelType:=PFD_TYPE_RGBA;
     cColorBits:=24;
     cDepthBits:=32;
     iLayerType:=PFD_MAIN_PLANE
    end;
   nPixelFormat:=ChoosePixelFormat(DC,@pfd);
   SetPixelFormat(DC,nPixelFormat,@pfd);
   DescribePixelFormat(DC,nPixelFormat,SizeOf(TPixelFormatDescriptor),pfd);
   if (pfd.dwFlags and PFD_NEED_PALETTE) <> 0 then
    begin
     nColors:= 1 shl pfd.cColorBits;
     hHeap:=GetProcessHeap;
     lpPalette:=HeapAlloc(hHeap,0,SizeOf(TLogPalette)+(nColors*SizeOf(TPaletteEntry)));
     lpPalette^.palVersion:=$300;
     lpPalette^.palNumEntries:=nColors;
     byRedMask:=1 shl pfd.cRedBits-1;
     byGreenMask:=1 shl pfd.cGreenBits-1;
     byBlueMask:=1 shl pfd.cBlueBits-1;
     for I:=0 to nColors-1 do
      begin
       lpPalette^.palPalEntry[I].peRed:=(((I shr pfd.cRedShift) and byRedMask)*255) div byRedMask;
       lpPalette^.palPalEntry[I].peGreen:=(((I shr pfd.cGreenShift) and byGreenMask)*255) div byGreenMask;
       lpPalette^.palPalEntry[I].peBlue:=(((I shr pfd.cBlueShift) and byBlueMask)*255) div byBlueMask;
       lpPalette^.palPalEntry[I].peFlags:= 0
      end;
     Palette:=CreatePalette(lpPalette^);
     HeapFree(hHeap,0,lpPalette);
     if Palette<>0 then
      begin
       SelectPalette(DC,Palette,False);
       RealizePalette(DC)
      end
    end
  end;

procedure TForm1.Button1Click(Sender: TObject);
var Pict:TBitmap;
         hrc:HGLRC;
         Palette:HPalette;
         Obj:GLUQuadricObj;
  begin
   Pict:=TBitmap.Create;
   Palette:=0;
   try
    Pict.Width:=200;
    Pict.Height:=200;
    Pict.PixelFormat:=pf24bit;
    SetDCPixelFormat(Pict.Canvas.Handle,Palette,True);
    hrc:=wglCreateContext(Pict.Canvas.Handle);
    wglMakeCurrent(Pict.Canvas.Handle,hrc);
    glViewport(0,0,Pict.Width,Pict.Height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    gluPerspective(30,1,0.5,100);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity;
    gluLookAt(0,-4.5,3.5,0,0,0,0,0,1);
    glClearColor(1,1,1,1);
    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glLightModelI(GL_Light_Model_Two_Side,1);
    glEnable(GL_COLOR_MATERIAL);
    glColor4F(0.7,0.3,0.5,0.9);
    Obj:=gluNewQuadric;
    gluCylinder(Obj,1.4,0.8,1.2,20,20);
    gluDeleteQuadric(Obj);
    glFinish;
    glFlush;
    wglMakeCurrent(0,0);
    wglDeleteContext(hrc);
    Printer.BeginDoc ;
    Printer.Canvas.Draw(10,10,Pict) ;
    Printer.EndDoc ;
   finally
    DeleteObject(Palette);
    Pict.Free
   end
  end;
Аватара пользователя
Vlad04
новенький
 
Сообщения: 79
Зарегистрирован: 11.12.2007 21:11:19
Откуда: Караганда. Казахстан

Re: Печать OpenGL картинки

Сообщение Vlad04 » 08.12.2011 18:47:05

Вот такой вариант работает:
Код: Выделить всё
procedure TForm1.PrintButtonClick(Sender: TObject);
var
  Pict:TBitmap;     
  Phrc : HGLRC;
  Palette : HPalette;
  Pixels,P : PGLUByte ; // указатель на область памяти для хранения картинки и счетчик
  X,Y : word ;
  R,G,B,A : byte ;   // цвета
begin
  Printer.Copies := 1 ;
  Printer.Orientation := poPortrait ;  {}
  Pict := TBitmap.Create;   // создаем битмап
  Pict.PixelFormat := pf24bit;
  Pict.Width := Printer.PageWidth ;     // задаём размеры страницы принтера
  Pict.Height := Printer.PageHeight ;
  Palette := 0;
  try
    SetDCPixelFormat(Pict.Canvas.Handle,Palette,True) ;    // включаем OpenGL процедура из предыдущего примера
    Phrc := wglCreateContext(Pict.Canvas.Handle);             // назначаем вывод в битмап
    wglMakeCurrent(Pict.Canvas.Handle,Phrc);
    GLInit ;                                                                       // задаем начальные настройки - всё стандартно
    glViewport (0,0,Printer.PageWidth,Printer.PageHeight); { define the viewport }
    GLCtrlPaint(Pict.Canvas.Handle,Phrc) ;                        // процедура формирования рисунка - любая
    getmem(Pixels,(Printer.PageWidth+1)*(Printer.PageHeight+1)*4) ;  // выделяем память под буфер вывода
    glReadPixels(0,0,Printer.PageWidth,Printer.PageHeight,GL_RGBA,GL_UNSIGNED_BYTE,Pixels) ; // копируем буфер вывода
    P := Pixels ;  // устанавливаем счетчик  на начало копии буфера
    for Y := 0 to Printer.PageHeight do          // формируем картинку из буфера в битмап
      for X := 0 to Printer.PageWidth-1 do
      begin
        R := P^ ; inc(P) ;  // читаем инфу по цветам ...
        G := P^ ; inc(P) ;
        B := P^ ; inc(P) ;
        A := P^ ; inc(P) ;
        Pict.Canvas.Pixels[X,Y] := R+G*$100+B*$10000 ;  // и задаем цвет пикселя в битмапе
      end;
    wglMakeCurrent(fDC,fhrc);   // переключаем контекст вывода
    wglDeleteContext(Phrc);      //

    Printer.BeginDoc ;                     // выводим картинку на принтер
    Printer.Canvas.Draw(0,0,Pict) ;
    Printer.EndDoc ;
  finally
    DeleteObject(Palette);
    Pict.Free
  end ;
end;

работает медленно, но работает!!!
В принципе в название темы можно добавить "РЕШЕНО"
Аватара пользователя
Vlad04
новенький
 
Сообщения: 79
Зарегистрирован: 11.12.2007 21:11:19
Откуда: Караганда. Казахстан


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15

Рейтинг@Mail.ru