Reputation: 31
I use delphi 7 and delphix so I can have ddraw and be able to create a surface to play with pixels.
so in a button trigger i use this:
for i:=1 to 100 do
for j:=1 to 100 do
dxdraw1.Surface.Pixels[i,j]:=250;
where dxdraw1 is a ddraw surface.
The problem is that it works, but the result shows after I hoover another window above my program, like it is not updating the rectangle area with the pixels.
(I press the button, the cpu usage is getting up for a short and the rectangle remains black until I hoover another window.)
Also its slow. I read somewhere this:
"...
DXDraw.Surface.Canvas.Pixels[X,Y]:=clBlue;
DXDraw.Surface.Canvas.Release;
..."
and after this:
"... Just remember that this function is extremely slow . It's locking and unlocking the surface on every pixel set.. not very usable. PixelDX and turboPixel don't, you manually lock the surface, do all of your pixel operations and then unlock it.. 1000 times faster. ..."
How to use these functions? I cant find them (and I have no idea since I am beginner on this)? How to lock first and then unlock?
U P D A T E :
Ok, I used undelphix, but in the rectangle I cant see the result, it still remains black:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
i,j :integer;
begin
dxdraw1.Surface.Lock;
for i:=1 to 150 do
for j:=1 to 150 do
dxdraw1.Surface.Pixel[i,j]:=100;
dxdraw1.Surface.Unlock;
end;
U P D A T E 2 :
It works but this bizarre happens: to see the result I have to "hide" the app window under another window or program, and the minimize that window to see the result. If I move the app then the result is gone, and it stays blank. Any ideas?
Upvotes: 3
Views: 676
Reputation: 76567
I'm not up to date on Delphi-X, but I have used the raw DirectX libs a lot in my Life32 program.
Here's how it works behind the scenes:
The memory pointer in step 2 can be regarded as a pointer directly to videomemory.
It is up to you to know:
- bits per pixel;
- number of pixels in the x and y direction;
- padding bytes at the end of each scan-line;
- if the bits per pixel are less than 24, you will not be working with RGB values, but with a palette;
- if you write past the end of the screen unpredicatable stuff will happen(!)
DelphiX is obsolete
I recommend you use unDelphiX
: http://www.micrel.cz/Dx/
It is much more advanced and has many more features.
You can simply use:
DXDraw1.Surface.Lock; //special version Lock without any parameters
try
for xy:= 0 to Min(DXDraw1.Height, DXDraw1.Width) - 1 do begin
//silly example, unDirectX has line drawing routines
DXDraw1.Surface.Pixel[xy, xy]:= TheColor;
end; {for xy}
finally
DXDraw1.Surface.Unlock;
end;
Because you've called lock
prior to accessing the pixel array, it will not bracket the call in a lock - unlock
pair.
Warning
Always spend the absolute minimum amount of time possible in between lock
and unlock
calls, because your entire system will be frozen while the display is locked.
Also make sure that Delphi does not break on exceptions when debugging the code inside the lock
box, because you system will be frozen with no way to revive it.
Note
There is still some overhead in the call to pixel
, because the color
value gets translated into a format dictated by the BytesPerPixel
for your display.
Also the [x,y]
coordinates get translated into a memory address.
In Life32 I resolved to write 8 different drawing routines, for every possible pixel depth.
And doing my own drawing of 16x16 blocks, thereby avoiding address translation per individual pixel.
Don't draw until you have to
Because DirectX is so fast, it's easy to draw much faster than the eye can see, use a high resolution timer (included in unDirectX
) to limit drawing to x frames per second.
Do not use Windows messages like WM_PAINT to do your main drawing, but do redraw when you're receiving an incoming WM_PAINT message.
Upvotes: 1