Модератор: Модераторы
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;
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;
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15