Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Graphics in VC++

Status
Not open for further replies.

dega512

Programmer
Sep 2, 2005
4
0
0
US
I am wondering if there is a way for fast graphics in a windows form without having to use GDI, DirectDraw, OpenGL, etc... All I want to be able to do is copy and array of int's containing pixel data to the form. Is this possible?

Thanksb
 
I'm not really sure what you're trying to do, but here's a suggestion. I'm not sure if you're familiar with PGM and PBM files. You could look into these if you'd like. PGM has a range of 256 black and white colors, while PBM black or white. If you import from the PGM or PBM, you can put it into an array. Then you can use the following semi-pseudocode.

Code:
// After importing picture from file

for (int x = 0; x <= width; x++)
  for (int y = 0; y <= height; y++)
    // Use something like RGB(), but this -- as you know --
    // is GDI, but make it a grey color or some other color
    // and save it to crColor
    SetPixel(hdc, x, y, crColor);

I hope this is what you're looking for.
 
SetPixel accomplishes what I want but it seems to be very slow. Is there a way to speed it up or a different function that does the same thing but is faster?

Another option that I might use is to use a bitmap. Is there a way I can dynamically alter the image data within an HBITMAP? This way I could just copy my array into the HBITMAP and draw it. This might also give me the speed I’m aiming for.
 
I forgot to say what it is I'm trying to do in my program. What I want to do is use an image (array of int's) that I render, then somehow place/draw it on my form.
 
as windows will not give you direct access to the hardware then the answer is no. You can use the GDI to do what you want by making a bitmap from your int array and using BitBlt() to blit it. Draw on a memory DC then blit the memory DC to the screen DC to reduce flickering.
 
I found a way to do what I want, but it is in GDI+. I have two versions of my source code to show (note: for some reason the C# version is faster then the C++ one, any ideas on that?). Does anyone know of a way to do the following in plain GDI?

Code:
(C++.NET Version)

// Note: For some reason I got an error when I used BYTE
//       so, I created TByte (TypeByte)
#define TByte unsigned char

void OnPaint(PaintEventArgs* e)
{
	__super::OnPaint(e);

	int width = this->Width;
	int height = this->Height;
	int color = Color::Black.ToArgb();
	int stride;
	int off;
	TByte* bmpData = NULL;

	Graphics* g = CreateGraphics();
	Bitmap* bmp = new Bitmap(width, height, PixelFormat::Format32bppArgb);
	BitmapData* dat = NULL;
	Rectangle rect(0, 0, width, height);

	dat = bmp->LockBits(rect, ImageLockMode::ReadWrite, PixelFormat::Format32bppArgb);

	stride = dat->Stride;
	off = stride - width * 4;
	bmpData = (TByte*)dat->Scan0.ToPointer();

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			bmpData[3] = (TByte)((color >> 24) & 0xFF);
			bmpData[2] = (TByte)((color >> 16) & 0xFF);
			bmpData[1] = (TByte)((color >>  8) & 0xFF);
			bmpData[0] = (TByte)((color) & 0xFF);

			bmpData += 4;
		}

		bmpData += off;
	}

	bmp->UnlockBits(dat);
	g->DrawImage(Image::FromHbitmap(bmp->GetHbitmap().ToPointer()), 0, 0);
	g->Dispose();
}

------------------------
(C# Version [Faster])

protected override void OnPaint(PaintEventArgs e)
{
	base.OnPaint(e);

	Graphics g = this.CreateGraphics();
	int width = this.Width;
	int height = this.Height;
	Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
	BitmapData dat = null;
	Rectangle r = new Rectangle(0, 0, width, height);
	dat = bmp.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

	unsafe
	{
		int stride = dat.Stride;
		int off = stride - width * 4;
		byte* bmpData = (byte*)dat.Scan0.ToPointer();
		int color = System.Drawing.Color.Black.ToArgb();

		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++)
			{
				bmpData[3] = (byte)((color >> 24) & 0xFF);
				bmpData[2] = (byte)((color >> 16) & 0xFF);
				bmpData[1] = (byte)((color >>  8) & 0xFF);
				bmpData[0] = (byte)((color) & 0xFF);

				bmpData += 4;
			}

			bmpData += off;
		}
	}

	bmp.UnlockBits(dat);
	g.DrawImage(Image.FromHbitmap(bmp.GetHbitmap()), 0, 0);
	g.Dispose();
}

P.S. Sorry if there are any bugs in the code.
 
One way of making it faster could be to reuse the bitmap instance between calls and only create a new one when needed (needs to grow).

/Per
[sub]
www.perfnurt.se[/sub]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top