Archived

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

qadir

Stars

Recommended Posts

Hi, I''m an absolute newbie, so I decided to start with something as simple as a starfield written in C. It is just a basic plotting of pixels randomly on the screen and then changing their positions. My code is somewhat as follows /* Get the current device context */ hdc = GetDC(hwnd); /* Set up a buffer device context */ bufdc = CreateCompatibleDC(hdc); I''m using SetPixel to plot the changed pixels onto the new DC i.e bufdc and then trying to load it into memory using BitBlt(hdc,0,0,rect.right,rect.bottom,bufdc,0,0,SRCCOPY) However, I just can''t get it to work. Could someone please help as to where I''m going wrong. Also ant advice as to what a rank newcomer such as me might read, would be greatly appreciated Thx Qadir All Sprites are created equal

Share this post


Link to post
Share on other sites
Is this DirectX you are using? If so, you do not need to blit anything to the screen. when you plot a pixel, that''s exactly what it does..

If you don''t have a backbuffer then it should just show up on the screen with no additional work required.

Share this post


Link to post
Share on other sites
Well, I'm not using directX, I've directly used GetDC to get the handle to device context.

If I use

SetPixel(hdc,400,400,RGB(red,green,blue));

I can see the pixel on screen. So I thought I would write the pixels to a buffer DC which I got using GetCompatibleDC and once the pixels have been plotted I would use BitBlt to transfer the pixels from bufdc to hdc.

When I say it doesn't work, I mean that the pixels written on dc remain, while the pixels on bufdc fail to appear. Its as if BitBlt has no effect. However if I pass the parameter as WHITENESS instead of SRCCOPY, the screen turns white so I know BitBlt is working.

I think there might be some other problem, since even the pixels on hdc disappear if I minimise the window and then remaximise it

[edited by - qadir on July 5, 2003 5:47:00 AM]

Share this post


Link to post
Share on other sites
If I understood right, your method involves loading a bitmap onto the buffer dc and then blitting it to hdc. I''m sure that would work since I have already tried blitting bitmaps using this technique and it has worked.

However what I need is someway to plot the stars at changing locations everytime so as to simulate the effect of a starfield. If I blit with the bitmap, the bitmap must contain the pixels at their new position so as to succeed. So I need to plot the pixels onto the bitmap before using your method and this is the part I do not understand.

All Sprites are created equal

Share this post


Link to post
Share on other sites
quote:
Are you ever calling InvalidateRect() to make sure that the window is redrawn


I didn''t know about that, I''ll try it and let u know. I was able to get the effect using DirectX, however since I''m using only the primary surface, there is no hardware acceleration and it seems kinda slow.

I have put up the directX source here but don''t expect anything too advanced, since it is my first directX program.
As soon as I fully understand the part about how to use page flipping with the back buffer, I''ll update the code so that the effect is not so jerky.

Here it is

www.geocities.com/abdul_stud/dx.txt

All Sprites are created equal

Share this post


Link to post
Share on other sites
HDC = GetDC(hWnd);
HDC hOffscreenDC = CreateCompatibleDC(hDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDC,640,480);
HGDIOBJ OldBmp = SelectObject(hOffscreenDC,hBmp);

// draw your stars
SetPixelV(hOffscreenDC,0,0,RGB(255,255,255));
BitBlt(hDC,0,0,640,480,hOffscreenDC,0,0,SRCCOPY)

// clean up
SelectObject(hOffscreenDC,OldBmp);
DeleteObject(hBmp);
DeleteDC(hOffscreenDC);
ReleaseDC(hDC);

this is just out of my head, but i think it should work.

My Site

Share this post


Link to post
Share on other sites
I tried your code, it didn''t work exactly how I planned it, but it has given me an idea as to be able to get the effect without the use of blitting. Thx

Also I have updated the code in DirectX, it uses double buffering instead of the crude blank screen and replot pixels that I had used earlier. So the effect is a lot smoother
I''m still working on using page flipping which should be able to make the movement very smooth.

The link to the old code should now have the improved code

All Sprites are created equal

Share this post


Link to post
Share on other sites
Well , as suggested by Invader X, I used InvalidateRect and managed to come up with working code written in GDI. However the screen seems to be flickering since the code is similar to my old direct X code. i.e Blank the screen using InvalidateRect() and replot the pixels.

The code is in GDI and is much shorter than the one in DirectX.

If someone could please go over the code and suggest optimizations
I have uploaded the code at

www.geocities.com/abdul_stud/starfield.txt

All Sprites are created equal

Share this post


Link to post
Share on other sites
If you don''t want flickering, you have to draw to a backbuffer (ie offscreen dc), and blit that backbuffer to the screen.

This time I have checked the code, and it works fine, with no flickering.

HDC hDC = GetDC(hWnd);
HDC hOffscreenDC = CreateCompatibleDC(hDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDC,640,480);
HGDIOBJ OldBmp = SelectObject(hOffscreenDC,hBmp);

// draw your stars
RECT rect;
SetRect(&rect,0,0,640,480);
FillRect(hOffscreenDC,&rect,(HBRUSH)GetStockObject(BLACK_BRUSH));

SetPixelV(hOffscreenDC,50,80,RGB(255,255,255));

BitBlt(hDC,0,0,640,480,hOffscreenDC,0,0,SRCCOPY);

// clean up
SelectObject(hOffscreenDC,OldBmp);
DeleteObject(hBmp);
DeleteDC(hOffscreenDC);
ReleaseDC(hWnd,hDC);

I won''t use invalidate rect, since it clears the screen. If you blit the offscreen dc over the existing image, you don''t need to clear the screen, because every pixel will be redrawn anyway.

My Site

Share this post


Link to post
Share on other sites
I meant InvalidateRect() to be used in conjunction with WM_PAINT (which, by the example code posted here, is not being used). InvalidateRect() does not clean the screen at all (unless the second parameter is TRUE) but instead only updates the area that needs to be redrawn. It sends a WM_PAINT message so that you can erase and draw.



Qui fut tout, et qui ne fut rien
Invader''s Realm

Share this post


Link to post
Share on other sites
Thanks a lot quasar3d, the code works perfectly.

InvaderX, I guess I misunderstood what you meant to say, thanks anyway.

I have put up the corrected code, in case anyone is interested.

Thanks to everyone who helped

All Sprites are created equal

Share this post


Link to post
Share on other sites