Utskrifter ifrån OpenGL

Allting som har med programmering att göra.

Utskrifter ifrån OpenGL

Inläggav VilleK » 08 sep 2009, 10:58

Jag behöver kunna printa ut OpenGL-grafik. Utskrifterna ska använda skrivarens upplösning så det går inte att bara göra en skärmdump. Det är i Win32-miljö.

När jag googlar hittar jag olika exempel på att gå via bitmappar och metafiler, men när jag provat så har det inte fungerat. Det verkar vara i hög grad beroende av Windows-version och skrivardrivrutin ifall det ska lyckas.

Är det någon som gjort detta? Tacksam för ett kod-exempel i så fall.
Användarvisningsbild
VilleK
 
Inlägg: 30
Blev medlem: 12 maj 2009, 09:26

Re: Utskrifter ifrån OpenGL

Inläggav Hildenborg » 08 sep 2009, 13:19

Jag har inte gjort något system som arbetar direkt mot en skrivare.
På Autodesk så skrev jag rutiner för att ta snapshots med högre upplösning än vad skärmen klarade av, och syftet med dom var att kunna skriva ut med mycket hög upplösning.
Snapshot rutinerna var rätt komplicrade, och byggde på att man delade upp bilden i flera tiles, och beräknade kamera och viewport för varje tile för att till slut mergea ihop allting till en fetingbild.
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg

Re: Utskrifter ifrån OpenGL

Inläggav Mattias Gustavsson » 08 sep 2009, 13:24

Nån av Game Programming Gems böckerna beskriver den tekniken (flera tiles) har jag för mig...
:P http://www.mattiasgustavsson.com - Min blogg
8-) http://www.tophatarcade.com - Utvecklarsajt och Sim/Strategi/RPG butik
:roll: http://www.retrogamedev.org - Forum för retrospel-utvecklare
:shock: http://www.pixieuniversity.com - Min gratis 2D spelmotor
Användarvisningsbild
Mattias Gustavsson
 
Inlägg: 135
Blev medlem: 11 maj 2009, 22:24
Ort: Royal Leamington Spa, UK

Re: Utskrifter ifrån OpenGL

Inläggav VilleK » 08 sep 2009, 14:42

Jag gjorde en lösning som skriver ut till en bitmap i minnet. Kör man i skrivarens fulla upplösning så tar det 100mb i anspråk så jag använder 1/4 av upplösningen i exemplet nedan. Om jag förstått rätt så används inte hårdvauracceleration när man gör på det här sättet men resultatet duger för mitt behov just nu.

Bra tips om att rita ut i tiles, det kan jag testa senare om det behövs. Ifall kortet stöder FBO så ska man kunna använda det också har jag läst mig till.

Delphi-kod:
  1.  
  2. uses OpenGL12, SysUtils, Windows, Commdlg, Forms, Graphics,
  3.   Printers, Classes;
  4.  
  5. //...
  6.  
  7. procedure PrintGL(SetupProc,RenderProc : TPrintGLProcedure);
  8. var
  9.   PFDescriptor: TPixelFormatDescriptor;
  10.   cxPage,cyPage,nPixelFormat : integer;
  11.   hPRC : HGLRC;
  12.   MyBitmap : TBitmap;
  13. begin
  14.   Printer.Orientation := poLandscape;
  15.   Printer.BeginDoc;
  16.  
  17.   MyBitmap := nil;
  18.   try
  19.     // Get the dimensions of the page
  20.     cxPage := GetDeviceCaps(Printer.Handle, HORZRES);
  21.     cyPage := GetDeviceCaps(Printer.Handle, VERTRES);
  22.  
  23.     MyBitmap := TBitmap.Create;
  24.     MyBitmap.Width := cxPage div 4;
  25.     MyBitmap.Height := cyPage div 4;
  26.     MyBitmap.PixelFormat := pf24bit;
  27.  
  28.     FillChar(PFDescriptor, SizeOf(PFDescriptor), 0);
  29.     with PFDescriptor do
  30.     begin
  31.       nSize := SizeOf(PFDescriptor);
  32.       nVersion := 1;
  33.       dwFlags := PFD_SUPPORT_OPENGL or PFD_SUPPORT_GDI or
  34.         PFD_TYPE_RGBA or PFD_DRAW_TO_BITMAP;
  35.       cColorBits := 24;
  36.       cDepthBits := 16;
  37.     end;
  38.  
  39.     // Choose a pixel format that best matches that described in pfd
  40.     nPixelFormat := ChoosePixelFormat(MyBitmap.Canvas.Handle, @PFDescriptor);
  41.     // Watch for no pixel format available for this printer
  42.     if nPixelFormat = 0 then
  43.       raise Exception.Create('Print error: no pixel format');
  44.  
  45.     // Set the pixel format for the device context, but watch for failure
  46.     if not SetPixelFormat(MyBitmap.Canvas.Handle, nPixelFormat, @PFDescriptor) then
  47.     begin
  48.       DescribePixelFormat(MyBitmap.Canvas.Handle,nPixelFormat,PFDescriptor.nSize,PFDescriptor);
  49.       if not SetPixelFormat(MyBitmap.Canvas.Handle, nPixelFormat, @PFDescriptor) then
  50.         raise Exception.Create('Print error: no pixel format');
  51.     end;
  52.  
  53.     // Create the Rendering context and make it current
  54.     hPRC := wglCreateContext(MyBitmap.Canvas.Handle);
  55.     if HasActiveContext then
  56.       DeActivateRenderingContext;
  57.     ActivateRenderingContext(MyBitmap.Canvas.Handle, hPRC);
  58.  
  59.     // Setup rendering context state
  60.     SetupProc;
  61.     // Perform the OpenGL Commands
  62.     RenderProc;
  63.     glFinish();
  64.  
  65.     // Cleanup the rendering context for the printer
  66.     CheckGLError;
  67.     DeactivateRenderingContext;
  68.     DestroyRenderingContext(hPRC);
  69.  
  70. //    Printer.Canvas.Draw(0,0,MyBitmap);
  71.     Printer.Canvas.StretchDraw( Rect(0,0,cxPage,cyPage), MyBitmap);
  72.  
  73.     //MyBitmap.SaveToFile('c:\test.bmp');
  74.     Printer.EndDoc;
  75.  
  76.   finally
  77.     if Printer.Printing then
  78.       Printer.Abort;
  79.     MyBitmap.Free;
  80.   end;
  81.  
  82. end;
  83.  
Användarvisningsbild
VilleK
 
Inlägg: 30
Blev medlem: 12 maj 2009, 09:26

Re: Utskrifter ifrån OpenGL

Inläggav sirGustav » 09 sep 2009, 07:03

Mattias Gustavsson skrev:Nån av Game Programming Gems böckerna beskriver den tekniken (flera tiles) har jag för mig...

2:an, sida 406 enligt denna artikeln
sirGustav
 
Inlägg: 45
Blev medlem: 06 jun 2009, 14:46
Ort: Malmö

Re: Utskrifter ifrån OpenGL

Inläggav Hildenborg » 09 sep 2009, 18:58

VilleK skrev:Om jag förstått rätt så används inte hårdvauracceleration när man gör på det här sättet men resultatet duger för mitt behov just nu.

Stämmer, Windows kan bara använda grafikhårdvara mot skärmen (eller en off screen buffer på grafikkortet).
Men, om du behöver göra stora renderingar i opengl, så rekomenderar jag att du renderar tiles som du sedan sätter ihop.
Min lösning för Autodesk arbetade dessutom mot hårddisken om man tog extra stora bilder. Vilket innebar att även på en 32bit maskin, så kunde man göra snapshots på 2 miljarder pixels bredd.
Om man hade en hårddisk på ett större antal terabyte...

Att skapa en kamera etc. för tiles är inte så svårt.
Tänk dig en normal kamera i opengl, som är riktad rakt mot centrum av skärmen. Sen sätter du viewporten till att bara vara en liten kvadrat uppe i hörnet. Det är ju då en tile, fast en liten sådan.
Så, tänk dig en jättestor skärm, och så sätter du viewporten till en ganska stor tile, och loopar över den virtuella skärmen. Så är det fixat sen.
Sun Tzu: "In peace prepare for war, in war prepare for peace."
Användarvisningsbild
Hildenborg
Site Admin
 
Inlägg: 191
Blev medlem: 22 apr 2009, 20:25
Ort: Göteborg


Återgå till Programmering

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 0 gäster

cron