www.pudn.com > lesson6.rar > lesson1View.cpp


// lesson1View.cpp : implementation of the CLesson1View class 
// 
 
#include "stdafx.h" 
#include "lesson1.h" 
 
#include "lesson1Doc.h" 
#include "lesson1View.h" 
#include "gl\gl.h" 
#include "gl\glu.h" 
#include "gl\glaux.h" 
#include "gl\glut.h" 
#include "POINTchoice.h" 
#include"TEAPOT2.h" 
#include "math.h" 
GLuint	texture[1];// 存储一个纹理  
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
extern int size1; 
extern double m_r,m_g,m_b; 
extern int new_width,new_height; 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View 
 
IMPLEMENT_DYNCREATE(CLesson1View, CView) 
 
BEGIN_MESSAGE_MAP(CLesson1View, CView) 
	//{{AFX_MSG_MAP(CLesson1View) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_SIZE() 
	ON_COMMAND(ID_POINT_DISPLAY, OnPointDisplay) 
	ON_WM_LBUTTONDOWN() 
	ON_COMMAND(ID_LIGHT_DIPLAY, OnLightDiplay) 
	ON_COMMAND(ID_IMAGE_DISPLAY, OnImageDisplay) 
	ON_COMMAND(ID_GLOBE, OnGlobe) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View construction/destruction 
 
CLesson1View::CLesson1View() 
{ 
	// TODO: add construction code here 
 
} 
 
CLesson1View::~CLesson1View() 
{ 
} 
 
BOOL CLesson1View::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View drawing 
 
void CLesson1View::OnDraw(CDC* pDC) 
{ 
	CLesson1Doc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	COLORREF color; 
	DrawSceneinit(); 
/*	color=RGB(0,0,255);//显示字体为蓝色 
	m_pDC->SetTextColor(color); 
	m_pDC->TextOut(100,100,"这是第一次作业!"); */ 
//	drawpoint(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View printing 
 
BOOL CLesson1View::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CLesson1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CLesson1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View diagnostics 
 
#ifdef _DEBUG 
void CLesson1View::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CLesson1View::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CLesson1Doc* CLesson1View::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLesson1Doc))); 
	return (CLesson1Doc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CLesson1View message handlers 
 
void CLesson1View::init() 
{ 
PIXELFORMATDESCRIPTOR pfd; 
	int         n; 
	HGLRC       hrc;// 
 
	m_pDC = new CClientDC(this); 
 
	ASSERT(m_pDC != NULL); 
 
	if (!bSetupPixelFormat()) 
		return; 
 
	n = ::GetPixelFormat(m_pDC->GetSafeHdc()); 
	::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd); 
 
	hrc = wglCreateContext(m_pDC->GetSafeHdc()); 
	wglMakeCurrent(m_pDC->GetSafeHdc(), hrc); 
 
	glClearDepth(1.0f); 
	glEnable(GL_DEPTH_TEST); 
} 
 
int CLesson1View::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	init(); // 初始化OpenGL 
	return 0; 
} 
 
void CLesson1View::OnDestroy()  
{ 
 
	 
	// TODO: Add your message handler code here 
	HGLRC   hrc; 
 
	hrc = ::wglGetCurrentContext(); 
 
	::wglMakeCurrent(NULL,  NULL); 
 
	if (hrc) 
		::wglDeleteContext(hrc); 
 
	if (m_pDC) 
		delete m_pDC; 
	//add up 
 
	CView::OnDestroy(); 
	 
} 
 
void CLesson1View::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	//add down 
	int w=cx; 
	new_width=w; 
	int h=cy; 
	new_height=h; 
	GLfloat nRange=1.0f; 
	//避免除数为0 
	if(h==0) h=1; 
 
	//设置视口与窗口匹配 
	glViewport(0,0,w,h); 
 
	//重新设置坐标系统 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	 
	//建立正交变换下的剪切体 
	if(wGetSafeHdc(), &pfd)) == 0 ) 
	{ 
		MessageBox("ChoosePixelFormat failed"); 
		return FALSE; 
	} 
//设置最匹配的像素格式为当前的像素格式 
	if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) 
	{ 
		MessageBox("SetPixelFormat failed"); 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
void CLesson1View::DrawSceneinit() 
{ 
	//设置清屏颜色为白色 
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	 
	//必须要加的矩阵堆栈函数,和glPopMatrix()相对应,具体内容请见下一章 
	glPushMatrix(); 
		glPopMatrix(); 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
} 
 
void CLesson1View::drawpoint() 
{//设置清屏颜色为黑色 
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
	//清除颜色缓冲区和深度缓冲区 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	 
	//必须要加的矩阵堆栈函数,和glPopMatrix()相对应,具体内容请见下一章 
	glPushMatrix(); 
	 
	//设置点的大小 
	glPointSize(12.0); 
	//说明几何图元为“点” ,和glEnd()相对应。 
	glBegin(GL_POINTS); 
		//绘制红色的点 
		glColor3f(1.0,0.0,0.0); 
		glVertex3f(-0.7,-0.7,0.0); 
		//绘制绿色的点 
		glColor3f(0.0,1.0,0.0); 
		glVertex3f(0.7,-0.7,0.0); 
		//绘制白色的点 
		glColor3f(1.0,1.0,1.0); 
		glVertex3f(0.0,0.0,0.0); 
		 
	 
	glEnd(); 
 
		glPointSize(32.0); 
	glBegin(GL_POINTS); 
	 
		//绘制蓝色的点 
		glColor3f(0.0,0.0,1.0); 
		glVertex3f(0.7,0.7,0.0); 
		//绘制绿色的点 
		glColor3f(0.0,1.0,0.0); 
		glVertex3f(-0.7,0.7,0.0); 
	glEnd(); 
 
	glPopMatrix(); 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
 
} 
 
void CLesson1View::OnPointDisplay()  
{ 
	// TODO: Add your command handler code here 
	drawpoint(); 
} 
 
void CLesson1View::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
	double pointx; 
 
	 
	double pointy; 
	if (new_width>=new_height)  
	  { 
          pointx=(2*(float)point.x-(float)new_width)/(float)new_height; 
          pointy=(-1.0)*(2*(float)point.y-(float)new_height)/(float)new_height; 
	  } 
	  else 
	  { 
          pointx=(2*(float)point.x-(float)new_width)/(float)new_width; 
		  pointy=(-1.0)*(2*(float)point.y-(float)new_height)/(float)new_width; 
      } 
 
		//必须要加的矩阵堆栈函数,和glPopMatrix()相对应,具体内容请见下一章 
	glPushMatrix(); 
	//设置点的大小 
	 
//	size1=2; 
	glPointSize(size1); 
	//glColor3f(0,0,0); 
	glColor3f(m_r/255.0,m_g/255.0,m_b/255.0); 
	glBegin(GL_POINTS); 
		glVertex3f(pointx,pointy,0.0); 
	glEnd(); 
	glPopMatrix(); 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CLesson1View::OnLightDiplay()  
{ 
	TEAPOT2 tea; 
	tea.m_Teasize =0.5; 
	if(tea.DoModal()==IDOK) 
	{ 
		viewteasize=tea.m_Teasize; 
		teapotshow(tea.m_Teasize); 
	} 
	 
 
} 
 
void CLesson1View::teapotshow(float teasize) 
{ 
//设置清屏颜色为白色 
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 
	//清除颜色缓冲区和深度缓冲区 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	glLoadIdentity(); 
	//必须要加的矩阵堆栈函数,和glPopMatrix()相对应 
	glPushMatrix(); 
	//首先定义一个材质,定义方法非常类似前面讲到的光源定义。 
	GLfloat mat_ambient[]={0.8,0.8,0.8,1.0}; 
//定义 紫色 的漫反射特性 
	GLfloat mat_diffuse[]={0.8,0.0,0.8,1.0}; 
//定义 亮紫色 的镜面反射特性 
	GLfloat mat_specular[]={1.0,0.0,1.0,1.0}; 
//定义镜面反射的光亮度 
	GLfloat mat_shininess[]={50.0}; 
//将以上材质定义应用 
	glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); 
	glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); 
	glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); 
	glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); 
 
 
//这里我们简化光源,以显示材质的效果。 
//这里我们只指定光源位置,其他默认:白色光源。 
//你也可以加入光源的定义,看看光源和材质的合成的效果 
//正是因为它们能够合成,才能产生比真实生活中多的多的效果,这也正是 
//3D技术吸引人的魅力所在。 
	GLfloat light_position[]={1.0,1.0,1.0,0.0}; 
	glLightfv(GL_LIGHT0,GL_POSITION,light_position); 
// GLfloat light_diffuse[]={0.0,0.0,1.0,1.0}; 
// glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); 
 
 
//将光源设置应用 
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0); 
//	glEnable(GL_CULL_FACE); 
 
	glEnable(GL_AUTO_NORMAL); 
	glEnable(GL_NORMALIZE); 
	glFrontFace(GL_CW); 
	glCullFace(GL_BACK); 
//glMaterialf(GL_FRONT,GL_SHININESS,64.0); 
 glShadeModel(GL_FLAT); 
 
 
 
 
//着色消隐 
//*******其实说白乐,这就是大名鼎鼎的 Z-BUFFER 呀************// 
	glDepthFunc(GL_LESS);//启动消影模式 
	glEnable(GL_DEPTH_TEST); 
	glRotatef(30.0,1.0,0.0,0.0); 
//功能强大的辅助库函数:呵呵画出一个大茶壶。 
glutSolidTeapot(teasize); 
 
//auxSolidSphere(0.2);//球 
	glDisable(GL_CULL_FACE); 
 
	glDisable(GL_AUTO_NORMAL); 
	glDisable(GL_NORMALIZE);	 
	 
	glDisable(GL_LIGHT0); 
	glDisable(GL_DEPTH_TEST);	 
 
	glPopMatrix(); 
 
	glFinish(); 
	 
	SwapBuffers(wglGetCurrentDC()); 
glDisable(GL_LIGHTING); 
 
} 
 
 
 
void CLesson1View::OnImageDisplay()  
{ 
	// TODO: Add your command handler code here 
	//清屏,设置背景色为黑色 
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
	//清除缓冲区 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	 
	glPushMatrix(); 
 
//	InitGL();// 
//	LoadGLTextures(); 
AUX_RGBImageRec *TextureImage[1]; 
  memset(TextureImage,0,sizeof(void *)*1); 
  if (TextureImage[0]=auxDIBImageLoad("Nehe.bmp")) 
  {//取得一个目前没有被其它纹理使用的纹理id来标识这个纹理 
   //这里取得的textures[0] 就是一个可用的纹理id。  
	  glGenTextures(1, &texture[0]); 
	 // 绑定新的纹理进行设置(以后要使用这个纹理也是这样操作 
 	  glBindTexture(GL_TEXTURE_2D, texture[0]); 
	  glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 
	  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//设置重复纹理,即 不仅显示一个位图而是显示几个拷贝 
	  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
	  //glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 
	  glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); 
  } 
 /* if (TextureImage[0])								 
  { 
	if (TextureImage[0]->data)					 
	{ 
		free(TextureImage[0]->data);			 
	} 
	free(TextureImage[0]);						 
  }*/ 
  glEnable(GL_TEXTURE_2D);						 
  glShadeModel(GL_SMOOTH);	// 启用阴影平滑					 
  glClearColor(0.0f, 0.0f, 0.0f, 0.5f);			 
   
  //接下来的三行必须做的是关于深度缓存(depth buffer)的。 
  //将深度缓存设想为屏幕后面的层。深度缓存不断的对物体进入 
  //屏幕内部有多深进行跟踪。我们本节的程序其实没有真正使用深度缓存, 
  //但几乎所有在屏幕上显示3D场景OpenGL程序都使用深度缓存。它的排序决 
  //定那个物体先画。这样您就不会将一个圆形后面的正方形画到圆形上来。 
  //深度缓存是OpenGL十分重要的部分。  
  glClearDepth(1.0f);	// 设置深度缓存   							 
  glEnable(GL_DEPTH_TEST);	// 启用深度测试      					 
  glDepthFunc(GL_LEQUAL);	// 所作深度测试的类型 
//接着告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点 
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 真正精细的透视修正 
//	glBindTexture(GL_TEXTURE_2D, texture[0]); 
 
    glLoadIdentity(); 
	glRotatef(25,0.0,1.0,0.0); 
	glRotatef(25,1.0,0.0,0.0); 
 
    glColor3f(0.0,1.0,0.0); 
	glutSolidTeapot(0.5); 
     
	glPopMatrix(); 
 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
 
	glDisable(GL_TEXTURE_2D); 
} 
 
void CLesson1View::OnGlobe()  
{ 
	// TODO: Add your command handler code here 
	for(int i=0;i<272;i++) 
	{ 
		glClearColor(0.0,0.0,0.0,0.0);////背景色清屏色 
	glClear(GL_COLOR_BUFFER_BIT);	 
 
		///////////// 
		//不断变换视口来模仿各种运动曲线效果 
		///////////// 
	glPushMatrix(); 
 
	glViewport(50+10*i,100+100*cos(double(i))-sin(i*1.0),50,50); 
 
	//	glViewport(2*i,i*i*0.01,50,50); //模拟各种曲线 
		glColor3f(1.0,1.0,0.0);///实体球颜色 
	glTranslated(0.0,0.0,0.0);//	 
	    auxSolidSphere(0.4);///实体球 
	    
	    glPopMatrix(); 
	    glFlush(); 
 
   Sleep(100); 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
 
	 
	} 
	 
 
	//设置视口与窗口匹配 
	glViewport(0,0,new_width,new_height); 
}