首页 > 代码库 > GDI+学习笔记(五)绘制一个正方体

GDI+学习笔记(五)绘制一个正方体


本文将介绍如何利用GDI+绘制一个正方体。

(一)准备阶段

想象一下,高中的时候,我们在学立体几何的时候是怎样画一个正方体的,我们在一张纸上利用投影的思路将其绘制在一张纸上,对吧,这计算投影的部分,我们暂且忽略。下图是我用windows的画图绘制的一个正方体:

我们计算出这些点在平面上的坐标如下:

	Point A(100,200);
	Point B(200,200);
	Point C(100,300);
	Point D(200,300);
	Point E(100+50*1.414, 200-50*1.414/2);
	Point F(200+50*1.414, 200-50*1.414/2);

只算了六个点?没错,只需要六个,因为我们绘制一个平行四边形的时候只需要三个点。

(二)初始化

画这个的时候,我们需要三个面,每个面应该对应一个Bitmap,定义如下:

Bitmap *m_pSliders[3];

然后,为这些面的值赋上一个自己的颜色,为了省事,我们将颜色简单地进行如下定义:

	for (int i=0; i<3; i++)
	{
			m_pSliders[i] = new Bitmap(100, 100);
			if (m_pSliders[i]->GetLastStatus() != Ok)
			{
				return false;
			}
			Graphics bmpGraphics(m_pSliders[i]);
			bmpGraphics.Clear(Color::Blue+100*i);
	}

上面这段代码,实际上就是把三个bitmap填充上颜色,第一个面的颜色为blue,后面会根据i的值稍微调整一下。

(三)绘制

现在,我们需要将这三个矩形的bitmap分别绘制到它们应该去的平行四边形里,这也是本文的核心代码了,但说白了,只是利用了DrawImage的另一个重载函数,看了下面代码,如果还不明白,请留言。

	// 正面
	Point destPoints1[3] ={E,A,F};
	cacheGraphics.DrawImage(m_pSliders[0], destPoints1,3);
	// 上面
	Point destPoints2[3] ={A,C,B};
	cacheGraphics.DrawImage(m_pSliders[1], destPoints2,3);
	// 侧面
	Point destPoints3[3] ={B,D,F};
	cacheGraphics.DrawImage(m_pSliders[2], destPoints3,3);

我们将三个面都绘制到了一个缓存的Graphics类中,它同样被初始化了一张bitmap,如果不明白,请再稍微看一下上一节的GDI+的双缓冲。

这之后,我们可以将缓冲图片绘制到最终的设备上,代码如下:

	if (m_pGraphics != NULL)
	{
		m_pGraphics->DrawImage(&cacheBitmap, 0, 0);
	}

至此,我们完成了一个矩形三个面的绘制,当然这里重点讲述的是GDI+的实现代码,而没有过多的提及这些点是怎么算的。事实上,DirectX提供了很多算法,以后开始DirectX学习笔记,有机会的话会详细说明。

好了,啰嗦了半天,看看结果吧。


(四)贴图正方体

贴图只是对之前的操作再进行一些利用罢了,每个面实际上已经对应了一个Graphics类,初始化的时候,在上面画一个我们的图片就可以完成这样的操作。

代码如下:

	for (int i=0; i<3; i++)
	{
			m_pSliders[i] = new Bitmap(100, 100);
			if (m_pSliders[i]->GetLastStatus() != Ok)
			{
				return false;
			}

			Graphics bmpGraphics(m_pSliders[i]);

			TCHAR szName[50];
			wsprintf(szName, _T("0%d.jpg"), i+1);
			Image img(szName);

			bmpGraphics.Clear(Color::Blue+100*i);

			bmpGraphics.DrawImage(&img, 0, 0, 100, 100);
	}
我的图片名叫01.jpg,02.jpg,03.jpg,所以才这么懒省事儿地写,要用别的名字,要用名字数组喔。

我用了几张女朋友去江南玩拍的照片,因为只有100宽,所以似乎不是很清楚,下面是结果:



(五)填充背景

上述贴图之后,好像不大好看清楚,我们在缓冲图片中,放一个灰色的背景(好吧,敲代码,敲久了,已经没有审美了。。)代码如下:

	RECT rect;
	GetClientRect(m_hwnd, &rect);
	Bitmap cacheBitmap(rect.right-rect.left, rect.bottom-rect.top);
	Graphics cacheGraphics(&cacheBitmap);

	cacheGraphics.Clear(Color::Gray);

看一下效果:



本想尽可能简单说来着,还是啰啰嗦嗦说了很多。。代码下载地址,稍后会传上去。如下:

http://download.csdn.net/detail/fukainankai/7429983