关闭

VS2010-MFC:用OpenGL在对话框中的PictureControl(图片控件)中绘制三维模型,可旋转、平移、缩放,可用于三维模型的预览

2087人阅读 评论(8) 收藏 举报
分类:

由于有这个需求,就是当在对话框设置一些数值的时候,可以在对话框上预览三维图像。

(1)生成一个基于对话框的程序,或者直接在单文档或者多文档上插入一个对话框,生成一个新的对话框类CGridingDlg,名字可以任取。

(2)配置好工程的OpenGL环境,不知道可以百度。

(3)在CGridingDlg的头文件中添加以下变量:

/*-----OpenGL绘图相关的变量-----------------------*/
	//旋转角度
	float xrof;
	float yrof;
	float zrof; 
	//Z轴移动变量
	BOOL  m_bZoomZ;
	float m_fZoomZ;
	GLfloat fNearPlane, fFarPlane;//透视投影的最近、最远的裁剪面距离
	float cameraPos[3];//相机位置
	float modelView[16];//模型矩阵
	float translateSpeed;//鼠标滑轮平移速度
	float rotateSpeed;//旋转速度
	float walkSpeed;
	float inertia;
	GLfloat m_xCurAngle;//X方向上的旋转角度
	GLfloat m_yCurAngle;//Y方向上的旋转角度
	GLfloat m_zCurAngle;//Z方向上的旋转角度
	CPoint m_MouseDownPoint;//鼠标点击的落点
	BOOL bMouseWheelStop;//鼠标中键滚动
	int buttonState;//鼠标状态
	HGLRC m_hRC;    //Rendering Context着色描述表  
	HDC m_pDC;//Device Context设备描述表
	BOOL SetupPixelFormat(HDC hDC);//设置像素格式
	BOOL InitializeOpenGL(HDC hDC);//初始化OpenGL
	CRect m_oldRect;
	void RenderScene(void);//绘图函数
	/*------------------------------------------------*/

以上为在后面需要使用到变量


(4)重载对话框类CGridingDlg的虚函数OnInitDialog(),添加WM_TIMER消息,

添加函数SetupPixelFormat(HDC hDC)---->用于设置OpenGL的像素格式

BOOL CGriding::SetupPixelFormat(HDC hDC)
{
	//PIXELFORMATDESCRIPTOR pixelDesc;
	//pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	//pixelDesc.nVersion = 1;
	//pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | 
	//	PFD_SUPPORT_OPENGL |
	//	PFD_DOUBLEBUFFER |
	//	PFD_TYPE_RGBA;
	//pixelDesc.iPixelType = PFD_TYPE_RGBA;
	//pixelDesc.cColorBits = 32;
	//pixelDesc.cRedBits = 0;
	//pixelDesc.cRedShift = 0;
	//pixelDesc.cGreenBits = 0;
	//pixelDesc.cGreenShift = 0;
	//pixelDesc.cBlueBits = 0;
	//pixelDesc.cBlueShift = 0;
	//pixelDesc.cAlphaBits = 0;
	//pixelDesc.cAlphaShift = 0;
	//pixelDesc.cAccumBits = 0;
	//pixelDesc.cAccumRedBits = 0;
	//pixelDesc.cAccumGreenBits = 0;
	//pixelDesc.cAccumBlueBits = 0;
	//pixelDesc.cAccumAlphaBits = 0;
	//pixelDesc.cDepthBits = 0;
	//pixelDesc.cStencilBits = 1;
	//pixelDesc.cAuxBuffers = 0;
	//pixelDesc.iLayerType = PFD_MAIN_PLANE;
	//pixelDesc.bReserved = 0;
	//pixelDesc.dwLayerMask = 0;
	//pixelDesc.dwVisibleMask = 0;
	//pixelDesc.dwDamageMask = 0;
	//int PixelFormat = ChoosePixelFormat(hDC,&pixelDesc);
	//if(PixelFormat==0) // Choose default
	//{
	//	PixelFormat = 1;
	//	if(DescribePixelFormat(hDC,PixelFormat,
	//		sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
	//	{
	//		return FALSE;
	//	}
	//}
	//if(SetPixelFormat(hDC,PixelFormat,&pixelDesc)==FALSE)
	//{ 
	//	return FALSE;
	//}
	//return TRUE;
	//初始化象素格式以及选取合适的格式来创建RC
	PIXELFORMATDESCRIPTOR pfd = { 
		sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小 
		1, // 版本号 
		PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图 
		PFD_SUPPORT_OPENGL | // 支持 OpenGL 
		PFD_DOUBLEBUFFER, // 双缓存模式 
		PFD_TYPE_RGBA, // RGBA 颜色模式 
		24, // 24 位颜色深度 ,color depth
		0, 0, 0, 0, 0, 0, // 忽略颜色位 
		0, // 没有非透明度缓存 
		0, // 忽略移位位 
		0, // 无累加缓存 
		0, 0, 0, 0, // 忽略累加位 
		32, // 32 位深度缓存 
		0, // 无模板缓存 
		0, // 无辅助缓存 
		PFD_MAIN_PLANE, // 主层 
		0, // 保留 
		0, 0, 0 // 忽略层,可见性和损毁掩模 
	}; 
	//在DC中选择合适的象素格式并返回索引号
	int pixelformat;
	pixelformat=::ChoosePixelFormat(m_pDC,&pfd);
	if (pixelformat==0)
	{
		AfxMessageBox("选择像素格式失败!");
		return FALSE;
	}
	//设置指定象素格式
	if (::SetPixelFormat(m_pDC,pixelformat,&pfd)==FALSE)
	{
		AfxMessageBox("设置像素格式失败!");
		return FALSE;
	}
	return TRUE;
}

上面是两种设置OpenGL像素格式的方法,其中注释的代码也可以用于设置像素格式,任用一种。

在对话框上面添加一个Picture控件,用于显示图形,设置其ID为IDC_STATIC_PictureRender


添加InitializeOpenGL()函数用于在对话框中初始化OpenGL。

BOOL CGriding::InitializeOpenGL(HDC hDC)
{
	//首先把DC的象素格式调整为指定的格式,以便后面对DC的使用
	SetupPixelFormat(hDC); 
	//根据DC来创建RC
	m_hRC=::wglCreateContext(hDC);  
	if (m_hRC==NULL)
	{
		return FALSE;
	}
	//设置当前的RC,以后的画图操作都画在m_pDC指向的DC上
	if ((::wglMakeCurrent(hDC,m_hRC))==FALSE)
	{
		return FALSE;
	}
	return TRUE;

	//下面可以进行画图操作了	
	//初始化整个场景和OpenGL的状态变量
	// OpenGL场景初始化(光照、雾化等〕
//	GetClientRect(&m_oldRect);
	GetDlgItem(IDC_STATIC_PictureRender)->GetClientRect(&m_oldRect);//获取图片控件的大小
	//*--设置OpenGL初始状态模式---*/
	///设置清屏颜色为白色
	glClearColor(1.0f,1.0f,1.0f, 1.0f);	
	//清除颜色缓冲区
	glClear(GL_COLOR_BUFFER_BIT);
	glEnable( GL_COLOR_MATERIAL );//启动颜色材料模式,使得在光照下模型颜色有用-不加这一句,模型颜色全为黑白色
	//设置深度缓存的清除值 ,Depth Buffer Setup
	glClearDepth(1.0f);	
	glClear(GL_DEPTH_BUFFER_BIT);
	//做深度测试,实现三维场景的消隐
	glEnable(GL_DEPTH_TEST);
	//深度测试函数,GL_LEQUAL:深度小或相等当前深度的时候也渲染 
	glDepthFunc(GL_LEQUAL);
	//可以调用函数glHint()对图像质量和绘制速度之间的权衡作一些控制
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	

	/*表示把渲染的图像融合到目标区域。也就是说源的每一个像素的alpha
	都等于自己的alpha,目标的每一个像素的alpha等于1减去该位置源像素
	的alpha。 因此不论叠加多少次,亮度是不变的。*/

	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	//glEnable(GL_TEXTURE_RECTANGLE_ARB);

	glEnable(GL_NORMALIZE);//打开法线矢量自动归一化功能

	GLfloat      fAspect;
	
	if (m_oldRect.bottom)
		fAspect = (GLfloat)m_oldRect.right/m_oldRect.bottom;
	else    
		fAspect = 1.0f;
	fNearPlane = 0.1f;//透视投影近平面
	fFarPlane = 1000.0f;//透视投影远平面		
	cameraPos[2] =-(fNearPlane + fFarPlane)/ 40.0f;
	cameraPos[0]=-0;
	cameraPos[1]=-0;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//设置透视投影矩阵
	gluPerspective(45, fAspect, fNearPlane, fFarPlane);
//	glOrtho(0,10000000,0,10000000,-2000,10000000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	SwapBuffers(m_pDC); 
	return TRUE;
}

在对话框类中的初始化对话框函数OnInitDialog(),初始化OpenGL;

BOOL CGriding::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	
	// TODO:  在此添加额外的初始化
	
	/*-------OpenGL绘图初始化相关---------------------*/
	CWnd *wnd=GetDlgItem(IDC_STATIC_PictureRender);//获取图片控件的窗口指针
	m_pDC=::GetDC(wnd->m_hWnd);//将绘图DC与图片窗口关联起来,如果这里是Wnd则绘图区域就设置为整个对//话框
	InitializeOpenGL(m_pDC);//初始化OpenGL函数
	     /////////////////////////////////////////// 
	SetTimer(1,1,0); //设置定时器



	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


然后为该对话框类添加一个函数RenderScene(),用于三维模型的绘制

void CGriding::RenderScene(void)
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//基本准备
	glClearColor(1,1,1,1.0);//设置背景颜色为白色
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除颜色缓冲和深度缓冲
	glEnable( GL_COLOR_MATERIAL );//启动颜色材料模式,使得在光照下模型颜色有用-不加这一句,模型颜色全为黑白色
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//开始显示图形
	//设置模型视景矩阵,包括了视点变换和模型变换矩阵
	//重置模型矩阵
	glMatrixMode(GL_MODELVIEW);//对模型视景矩阵堆栈应用随后的矩阵操作
	glLoadIdentity();//将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作
	//keyboard();//响应键盘按键

	//ShowLegend();//绘制图例,在固定地方,没有改变模型视景矩阵

	/*GL_MODELVIEW矩阵在一个矩阵中包含view矩阵和model 矩阵
	 视点变换:gluLookAt()
	 模型变换:包括平移、旋转和缩放。
	 在程序中, 视点变换必须在模型变换之前完成, 但是投影变换和视口变换可以在绘图之前的任何时候指定。
	 函数glRotate( ) 旋转的是坐标系而不是物体,旋转操作遵循右手规则
	 如果矩阵模式是GL_MODELVIEW 或GL_PROJECTION 时,函数glRotate ( ) 调用后所有绘制的对象将被旋转。
	 glTranslate( ) 函数平移的是坐标系而不是物体。glTranslate( ) 函数可以作用于几何矩阵、投影矩阵和纹理坐标变换矩阵。
	 如果当前矩阵为几何矩阵, 函数的功能则是将物体坐标系的原点移到( x, y, z) 所指的位置,形成新的物体坐标系*/


	glTranslatef(cameraPos[0], cameraPos[1], cameraPos[2]);//平移,用到后面的modelView
	/*modelView的X(m0、m4、m8)、Y(m1、m5、m9)、Z(m2、m6、m10)存的是模型矩阵的X、Y、Z的方向
	,默认为(1,0,0)、(0,1,0)、(0,0,1)。本实例中modelView的X、Y、Z的方向保持不变,值也
	没有变化*/
	glGetFloatv(GL_MODELVIEW_MATRIX, modelView); 
	glRotatef(m_xCurAngle, 1.0, 0.0, 0.0);
	glRotatef(m_yCurAngle, 0.0, 1.0, 0.0);
	glRotatef(m_zCurAngle, 0.0, 0.0, 1.0);

	
	glPushMatrix();
	
	
	/*---------绘图函数代码区,只需添加绘图代码即可----------------*/
	//这里绘制了三个坐标轴线和一个立方体
	glBegin( GL_LINES );
	glColor3d(1.0, 0.0, 0.0);	// X轴 红色
	glVertex3d(0.0, 0.0, 0.0); 
	glVertex3d(1.0, 0.0, 0.0);
	glColor3d(0.0, 1.0, 0.0);	// Y轴 绿色
	glVertex3d(0.0, 0.0, 0.0);
	glVertex3d(0.0, 1.0, 0.0);
	glColor3d(0.0, 0.0, 1.0);	// Z轴 蓝色
	glVertex3d(0.0, 0.0, 0.0); 
	glVertex3d(0.0, 0.0, 1.0);
	glEnd();
	glColor3f(1.0, 0.0, 0.0);
	glutWireCube(1);

	/*--------------------------------------------------------------*/
	
	glPopMatrix();
	

	glDisable(GL_LIGHTING);
	glColor3f(1,0.5,0.5);
	glRasterPos2f(2.0,2.0);
	
	glEnable(GL_LIGHTING);
	glFinish();
	SwapBuffers(m_pDC);//交换缓冲区
}

然后在该类的定时器响应函数OnTime()将RenderScene()函数添加进去,每隔多少毫秒就调用RenderScene(),时间间隔设置的越少就可以形成连续绘制的效果

void CGriding::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	RenderScene();


	CDialogEx::OnTimer(nIDEvent);
	
}
最后别忘了在该类的析构函数中释放绘图句柄,防止出现内存泄露

CGriding::~CGriding()
{
	wglMakeCurrent(NULL, NULL) ;               
	wglDeleteContext(m_hRC);                                  //删除绘图描述表
	::ReleaseDC (m_hWnd, m_pDC) ;               //释放设备描述表
}

这样,我们就可以在对话框中看见我们所画的图形了,如果想自己随便画什么模型,那么就需要自己再在RenderScene()函数中封装一个函数,将该函数放置于RenderScene()函数的绘图代码区就好了。

绘制的效果如下



但是上面中的模型并不能进行交互操作,所以须在CGridingDlg该类中添加鼠标左键,鼠标中键以及鼠标滑轮的消息响应函数,但先需要在该类的构造函数中初始化控制变量。

//旋转角度
	xrof=-90.0f;
	yrof=0.0f;
	zrof=40.0f;
	//Z轴移动
	m_fZoomZ=0;
	m_bZoomZ=FALSE;
	translateSpeed = 0.0001f;//平移速度
	//	translateSpeed = 1.08f;//鼠标放大缩小时的缩放大小因子
//	translateSpeed = 0.9f;//鼠标放大缩小时的缩放大小因子
	rotateSpeed = 0.04f;//旋转速度
	walkSpeed = 0.08f;
	inertia = 0.1f;
	m_xCurAngle = -90.0f;
	m_yCurAngle = 0.0f;
	m_zCurAngle = 0.0f;
	bMouseWheelStop = TRUE;
	buttonState = -1; //鼠标按键的状态


然后在其各种鼠标响应消息中添加以下代码,鼠标左键用于选择,中键用于移动,滑轮用于缩放

void CGriding::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_MouseDownPoint=CPoint(0,0);
	/*ReleaseCapture():该函数从当前线程中的窗口释放鼠标捕获,并恢复通
	常的鼠标输入处理。捕获鼠标的窗口接收所有的鼠标输入(无论光标的位置
	在哪里),除非点击鼠标键时,光标热点在另一个线程的窗口中。*/
	ReleaseCapture();
	buttonState = -1;
	///////////////////
	CDialogEx::OnLButtonUp(nFlags, point);
}


void CGriding::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_MouseDownPoint=point;
	/*SetCapture():该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,
	所有鼠标输入都针对该窗口,无论光标是否在窗口的边界内*/
	SetCapture();
	buttonState = GLUT_LEFT_BUTTON;

	CDialogEx::OnLButtonDown(nFlags, point);
}


void CGriding::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	/*GetCapture():该函数取得捕获了鼠标的窗口(如果存在)的句柄。
	在同一时刻,只有一个窗口能捕获鼠标;此时,该窗口接收鼠标的输入
	,无论光标是否在其范围内。*/
	if (GetCapture()==this)
 	{
		float dx, dy;
		dx = point.x - m_MouseDownPoint.x;
		dy = point.y - m_MouseDownPoint.y;
		if (buttonState == GLUT_LEFT_BUTTON)//如果是左键按下,就旋转物体
		{
			m_xCurAngle += dy/10;
			m_yCurAngle += dx/10;
		}
		if (buttonState == GLUT_MIDDLE_BUTTON ||buttonState == GLUT_RIGHT_BUTTON)//如果是鼠标中键或者是右键按下,就平移物体
		{
			float v[3];
			v[0] = dx*translateSpeed;
			v[1] = -dy*translateSpeed;
			v[2] = 0.0f;

			float r[3];
			r[0] = v[0]*modelView[0] + v[1]*modelView[1] + v[2]*modelView[2];
			r[1] = v[0]*modelView[4] + v[1]*modelView[5] + v[2]*modelView[6];
			r[2] = v[0]*modelView[8] + v[1]*modelView[9] + v[2]*modelView[10];
			
			cameraPos[0] += r[0];
			cameraPos[1] += r[1];
			cameraPos[2] += r[2];
		}
		/*if (buttonState== GLUT_WHEEL_UP) 
		//if(nFlags & MK_MBUTTON)
		{
			// left+middle = zoom
			float v[3];
			v[0] = 0.0;
			v[1] = 0.0;
			v[2] = dy*translateSpeed;
			
			float r[3];
			r[0] = v[0]*modelView[0] + v[1]*modelView[1] + v[2]*modelView[2];
			r[1] = v[0]*modelView[4] + v[1]*modelView[5] + v[2]*modelView[6];
			r[2] = v[0]*modelView[8] + v[1]*modelView[9] + v[2]*modelView[10];
			
			cameraPos[0] += r[0];
			cameraPos[1] += r[1];
			cameraPos[2] += r[2];
		} */
		
		m_MouseDownPoint=point;
		InvalidateRect(NULL,FALSE);
	}
	CDialogEx::OnMouseMove(nFlags, point);
}


BOOL CGriding::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//鼠标中键滑轮滚动进行放大缩小操作

	float v[3];
	v[0] = 0.0;
	v[1] = 0.0;
	v[2] = zDelta*translateSpeed;

	float r[3];
	r[0] = v[0]*modelView[0] + v[1]*modelView[1] + v[2]*modelView[2];
	r[1] = v[0]*modelView[4] + v[1]*modelView[5] + v[2]*modelView[6];
	r[2] = v[0]*modelView[8] + v[1]*modelView[9] + v[2]*modelView[10];

	cameraPos[0] += r[0];
	cameraPos[1] += r[1];
	cameraPos[2] += r[2];

	InvalidateRect(NULL,FALSE);
	return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}


void CGriding::OnMButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_MouseDownPoint=point;
	SetCapture();
	buttonState = GLUT_MIDDLE_BUTTON;
	CDialogEx::OnMButtonDown(nFlags, point);
}


void CGriding::OnMButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_MouseDownPoint=CPoint(0,0);
	ReleaseCapture();
	buttonState = -1;
	CDialogEx::OnMButtonUp(nFlags, point);
}

这样我们就可以旋转、放大、缩放物体了











2
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

在VS2010里MFC对话框中使用OpenGL绘图,添加的控件不显示的一种解决方法

当我想在MFC对话框里一部分显示OpenGL图形,一部分显示滚动条和一些按钮等控件的时候,图形可以显示,但是控件不显示,网上很多人说是修改对话框的ClipChildren属性,我没搞明白,试了一下没有成功。         控件不可见的原因,可能是OpenGL...
  • Main_3K10
  • Main_3K10
  • 2014-03-07 21:41
  • 1439

iOS控件的缩放,平移,旋转和回到原点

#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIButton *moving; - (IBAction)move; - (IBAc...
  • young____
  • young____
  • 2015-10-04 20:20
  • 895

基于对话框的Opengl框架

这里,我主要是利用opengl在一个picture控件中绘图,绘制的是一个静态图片,如果想实现动画,可以利用ontimer函数实现。编译器为vs2010。 1、首先创建一个基于对话框的MFC程序,我这里命名为MFC_Dlg。 2、配置opengl环境 首先添加链接库,在菜单栏 项目->属...
  • longxiaoshi
  • longxiaoshi
  • 2012-11-29 14:55
  • 2133

(2)在vs2010上配置opengl

参考自http://www.yakergong.net/nehe/ 在Visual Studio 2003 中创建基于Nehe SDK的应用程序分为以下几个步骤: 创建一个空白的工程文件包含Nehe SDK的头文件包含Nehe SDK的库文件添加基本框架代码编译把资源文件复制到你的运行程序所...
  • lhq186
  • lhq186
  • 2014-03-05 21:43
  • 1184

基于OpengL与MFC对话框Picture控件绘制的旋转正方体

  • 2015-09-05 15:18
  • 14.19MB
  • 下载

MFC调用Opengl实现三维图形的旋转平移缩放

  • 2016-04-10 16:06
  • 2.10MB
  • 下载

OpenGL + vs2010开发环境配置

vs2010-OpenGL环境配置 1、下载GLUT。Windows环境下的GLUT下载地址:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip 2、将下载的压缩包解开,将得到5个文件:glut.h glut.lib g...
  • hellokandy
  • hellokandy
  • 2017-04-11 12:05
  • 665

OpenGL在MFC对话框中的配置与开发

OpenGL在MFC对话框中的使用方法: 环境配置: 首先在菜单中选择“工程”——》选择“设置”——》选择选项卡“LINK”——》“对象和库模块”的编辑款中添加如下命令:opengl32.lib glu32.lib glut.lib glaux.lib ,中间都有空格哟。然后确定就好了。 首先...
  • sky_person
  • sky_person
  • 2014-02-08 00:10
  • 1572

MFC调用Opengl实现三维图形的旋转平移缩放

  • 2013-03-14 10:13
  • 2.10MB
  • 下载

OpenGL实现鼠标绕任意轴旋转/平移/缩放

刚刚学opengl的童鞋肯定有个苦恼的麻烦,只会绘制一个三角形,但是想像那些三维软件那样用鼠标控制视角还是有点困难的,所以我就封装了一个场景漫游类:RoamingScenceManager,这个类使用非常方便,跟界面没有半毛钱关系,可以在Qt,原生OpenGL,MFC用,下面的内容是简单介绍怎么用,...
  • trustguan
  • trustguan
  • 2016-03-06 10:57
  • 8491
    个人资料
    • 访问:183827次
    • 积分:3049
    • 等级:
    • 排名:第13328名
    • 原创:112篇
    • 转载:18篇
    • 译文:0篇
    • 评论:208条
    联系我
    博客专栏
    最新评论