Archived

This topic is now archived and is closed to further replies.

SetPixel()

This topic is 4947 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ive been playing with the SetPixel() function in an attempt to understand better some things about graphical programming. I use DirectX usually, but since all DXgraphics *really* does is draw a point at (x,y) of a certian color, I thought I could learn things from SetPixel(), since thats what it does. its (at its core) Well, I have learnt some things, and now I have questions. Heres the most pressing one : Q : Is there anything faster than SetPixel() to put a pixel to the screen? Even using inline functions and Win32Releaase on a dual processor P4 3.2GHZ, its slow doing it 25,000,000 times. -Jason BTW, some of the neato things Ive been able to figure out : 1) How to stuff the screen into a custom "buffer" I made using ScreenData[500][500] and GetPixel(dc, x, y,), and be able to redisplay it. 2) A nifty spirograph function using LineTo() 3) Manipulating the ScreenData[][] to make random points appear to move 4) Drawing a grid 5) Repositioning the origin from the default top left of the window to dead center. 6)Im now trying to make a rotating 3D MTV logo like John Carmack did as described in the book "masters of doom". Stuck on going from model space to perspectivelike screen space.

Share this post


Link to post
Share on other sites
If you really must use GDI to plot pixels, you should probably use CreateDIBSection to create a bitmap whose pixels you can modify directly using pointers. This at least will save you the overhead of calling a function like SetPixel.

xyzzy

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Create a memory device context, select a bitmap into it, then blit it to the screen. CreateDibSection() returns a pointer that you can work with for setting pixels yourself. I can''t remember if you can mess with the pointer while it''s selected or not. You will have to look this one up to be sure.

Share this post


Link to post
Share on other sites
Arg! The same thread in two different places! And with two different names!

I''ll move my other post over here.

quote:
Technically, Direct3D does not put pixels on the screen. Direct3D tells the graphics card about vertices and textures, and the graphics card figures out a bunch of stuff, and the graphics card puts the pixel on the screen.

But yes, if my memory serves me right, SetPixel is pretty slow. The solution is typically to have your own piece of memory which you read from and write to manually. You then tell Windows or DirectX or whatever else to display the whole chunk of memory (or at least part of it) to the screen. SetPixel probably does a bunch of checks and conversions before actually writing the pixel to the screen.

Share this post


Link to post
Share on other sites
As the others have said, create a bitmap surface and use pointers from its base address, its much faster. When you''re done drawing just make windows blit the whole bitmap. I have a small graphics library that works this way which also serves as the basis for my computer graphics class work. One thing to remember is that windows bitmaps are stored up-side-down. If you want to make a general system (that could be used on a standard linear framebuffer as well as Windows'' up-side-down bitmaps) you can use a tad of preprocessor logic and a #define at no loss to speed.

My system defines a macro, YSTEP, that is either 1 or -1 and is used to increment the vertical step. I also have a function which returns the base pointer of a horizontal scan line, which is integral to the system because the calculation is intirely different for what I call linear (standard, top-to-bottom) and inverted (windows bitmap, bottom-to-top) framebuffers. The function looks like this:

void * GetLine(int y)
{
#if YSTEP == 1
-- Linear buffer code.
#else
-- Inverted buffer code.
#endif
}


Its a really good excersize to find out what goes on behind the scenes. You won''t compete with hardware acceleration, but you can get good enough performance for many uses. For example I can fill my 640x480 buffer with 300 32x32 images at around 900 fps on my P4 3ghz :-D

Ravyne, NYN Interactive Entertainment
[My Site][My School][My Group]

Share this post


Link to post
Share on other sites
If you really must do Pixel-based work in DirectX, I suggest you create a Lockable Backbuffer.

This allows you to lock the backbuffer and get direct access to the surface data, with a suitable assembler get/set-pixel procedure you can increase your graphical throughput tremendously.

I''ve got an example of pixel-based effects here, though i didn''t include the source. (424kb)

http://www.cs.sun.ac.za/~henri/PixelBumpDemo.zip

Share this post


Link to post
Share on other sites