PDA

View Full Version : DirextX/OpenGL TImage.



marcov
20-11-2006, 07:22 PM
For an imaging application I have to display an image (bmp) in a part of a normal Delphi screen. Updating a picture takes about 5-7ms, more if it is fullscreen, and I'd like to decrease that. (at 25 frames per second, that being quite a lot of the per frame budget)

So using accelerated api's would be great, however can it be done without chucking out the entire VCL/LCL? IOW can one effectively use dx/gl for parts of a form?

Of course pointers to bmp drawing using accelerated techniques would be great.

savage
20-11-2006, 09:18 PM
Hi MarcoV,
Using TImage is always really slow. Are you able to draw directly onto the Form surface instead? I suppose the questions that need answering are how big is the image you are blitting and is it static or animated?

Just for interests sake, what machine specs are you aiming your application at?

marcov
20-11-2006, 09:43 PM
Hi MarcoV,
Using TImage is always really slow. Are you able to draw directly onto the Form surface instead?


(we use an own developed variant that draws to the canvas using .draw
there also is a SetStretchBltMode and canvas.copyrect using variant, but it is not in use at the moment. It is already quite a bit faster than TImage, sorry for the inexactness of the question)



I suppose the questions that need answering are how big is the image you are blitting and is it static or animated?


Not just blitting, zooming too. Usually full screen and bigger. The largest are over 4k x2kx8bpp. (but the really large ones have lower framerates, typically 2fps). Typical is 1280x960x8bpp or 1024x1800x8bpp with a framerate of 8-15fps. The images come from digital camera's and are 8bit.

The user can scroll and zoom the image. Currently only by powers of 2, but continuous zoom in the future is planned.



Just for interests sake, what machine specs are you aiming your application at?

Multiple configurations. E.g. heavy machines (think E6700) but then they have multiple image sources (so effective framerates of 2 x 10fps or even 3x), or C7 1200Mhz for lowpowered ones. (usually for hot environments).

All but the C7's have GF6200TD as lowest GPU. New ones typically have budget 7300's. (the reason for the GPU is actually not the GPU, but just the cheapest external GPU. Chipset GPU usually use too much memory bandwidth). The C7 hasn't arrived yet, but probably will have some S3 unichrome.

grudzio
20-11-2006, 10:03 PM
It is possible to use OpenGL and VCL/ LCL in the same time. All you need is a VCL control which has a handle. The very simple OpenGL form would look something like this



TGLForm = class(TForm)
private
FGLRC : HGLRC;
fGLDC : HDC;
fPFD : TPixelFormatDescriptor;
...
public
constructor Create(AOwner : TComponent);
destructor Destroy; override;
procedure InitGL;
...
end;

implementation

constructor TGLForm.Create(AOwner : TComponent);
var
formatIndex : integer;
begin
inherited;
//setup pixel format
with fPFD do begin
nSize := SizeOf(fPFD);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 24; //bits per pixel
cDepthBits := 24; //size of depth buffer
cStencilBits := 8; //size of stencilbuffer
iLayerType := PFD_MAIN_PLANE;
end;
fGLDC := getDC(self.Handle);
FormatIndex := ChoosePixelFormat(fGLDC,@FPFD);
//if FormatIndex = 0 then error
SetPixelFormat(fGLDC,FormatInsex,@fPFD);
//create rendering context;
fGLRC := wglCreateContext(fGLDC);
wglMakeCurrent(fGLDC,fGLRC);
end;

destructor TGLForm.Destroy;
begin
//destroy rendering context;
wglMakeCurrent(fGLDC,0);
wglDeleteContext(fGLRC);
ReleaseDC(self.Handle,fGLDC);
inherited;
end;

procedure TGLForm.InitGL;
begin
glMatrixMode(GL_PROJECTION);
glOrtho(0,ClientWidth,0,ClientHeight,0,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glViewport(0,0,ClientWidth,ClientHeight);
end;


Drawing can be done in TGLForm.OnPaint event.
For more sophisticated example look there:
http://www.delphi3d.net/dot/