www.pudn.com > opengl_pick_sample.rar > glview.cpp


// glview.cpp 
// 
 
#include "stdafx.h" 
#include "glview.h" 
#include  
 
 
GLView3D::GLView3D(void) 
{ 
	InitImage(); 
} 
 
GLView3D::~GLView3D(void) 
{ 
} 
 
void GLView3D::CreateImage(UINT32 width, UINT32 height) 
{ 
	if ((width > 0) && (height > 0)) 
	{ 
		m_dib.Create(width,height,24); 
 
		if (!IsInitialized()) 
		{ 
			InitializeOpenGL(); 
			if (CreateView()) 
			{ 
				m_IsInitialized = 1; 
			} 
		} 
	} 
} 
 
void GLView3D::SizeImage(UINT32 width, UINT32 height) 
{ 
	if ((width > 0) && (height > 0)) 
	{ 
		if (!IsInitialized()) 
		{ 
			CreateImage(width,height); 
		} 
		else 
		{ 
			if (!m_dib.IsCreated()) 
			{ 
				m_dib.Create(width,height,24); 
 
				if (SetImagePixelFormat(*m_dib.GetDC())) 
				{ 
					CreateImageGLContext(*m_dib.GetDC()); 
				} 
			} 
			else if ((width != m_dib.Width()) || (height != m_dib.Height())) 
			{ 
				m_dib.Create(width,height,24); 
				CreateView(); 
			} 
		} 
 
		glViewport(0,0,width,height); 
		double aspect; 
		aspect = (height == 0) ? (double)width : (double)width/(double)height; 
		glMatrixMode(GL_PROJECTION); 
		glLoadIdentity(); 
		gluPerspective(45,aspect,0.01,25.0); 
		glMatrixMode(GL_MODELVIEW); 
		glLoadIdentity(); 
	} 
} 
 
void GLView3D::InitializeOpenGL(void) 
{ 
	m_hGLContext = NULL; 
	m_GLPixelIndex = 0; 
	InitGeometry(); 
} 
 
void GLView3D::InitGeometry(void) 
{ 
	m_model_matrix.SetRotation(45.0,0.0,0.0); 
	m_model_matrix.SetScale(1.0,1.0,1.0); 
	m_model_matrix.SetPosition(0.0,0.0,-5.0); 
} 
 
  // Lights, camera, action... 
int GLView3D::CreateView(void) 
{ 
	int result = 0; 
 
	  // do the standard OpenGL initialization 
	if(SetImagePixelFormat(*m_dib.GetDC()) && CreateImageGLContext(*m_dib.GetDC())) 
		result = 1; 
	else 
		return result; 
 
	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
	glShadeModel(GL_SMOOTH); 
	glEnable(GL_NORMALIZE); 
	glEnable(GL_COLOR_MATERIAL); 
 
 
	// Lights, material properties 
	GLfloat	ambientProperties[]  = {0.3f, 0.3f, 0.3f, 0.7f}; 
	GLfloat	diffuseProperties[]  = {0.9f, 0.9f, 0.9f, 1.0f}; 
	GLfloat	specularProperties[] = {0.7f, 0.7f, 0.7f, 1.0f}; 
	GLfloat mat_amb_diff[] = { 0.7f, 0.7f, 0.7f, 1.0f}; 
	GLfloat shine[] = { 128.0f}; 
	GLfloat emissionProperties[] = {0.2f, 0.2f, 0.2f, 1.0f}; 
		 
	glLightfv( GL_LIGHT0, GL_AMBIENT, ambientProperties); 
	glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseProperties); 
	glLightfv( GL_LIGHT0, GL_SPECULAR, specularProperties); 
 
	glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0); 
 
	//glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff); 
	//glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine); 
	//glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissionProperties); 
 
	// lighting 
	glEnable(GL_LIGHT0); 
	glEnable(GL_LIGHTING); 
	glEnable(GL_DEPTH_TEST); 
 
	return result; 
} 
 
BOOL GLView3D::SetImagePixelFormat(HDC hDC) 
{ 
	PIXELFORMATDESCRIPTOR pixelDesc; 
	 
	pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
	pixelDesc.nVersion = 1; 
	 
	pixelDesc.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | 
		PFD_SUPPORT_GDI; 
	 
	pixelDesc.iPixelType = PFD_TYPE_RGBA; 
	pixelDesc.cColorBits = 24; 
	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 = 24; 
	pixelDesc.cStencilBits = 0; 
	pixelDesc.cAuxBuffers = 0; 
	pixelDesc.iLayerType = PFD_MAIN_PLANE; 
	pixelDesc.bReserved = 0; 
	pixelDesc.dwLayerMask = 0; 
	pixelDesc.dwVisibleMask = 0; 
	pixelDesc.dwDamageMask = 0; 
	 
	int pix_index = ChoosePixelFormat(hDC,&pixelDesc); 
	 
	if(!SetPixelFormat(hDC,pix_index,&pixelDesc)) 
	{ 
		DWORD code = GetLastError(); 
		return FALSE; 
	} 
	 
	return TRUE; 
} 
 
BOOL GLView3D::CreateImageGLContext(HDC hDC) 
{ 
	m_hGLContext = wglCreateContext(hDC); 
	 
	if(m_hGLContext==NULL) 
		return FALSE; 
	 
	if(wglMakeCurrent(hDC,m_hGLContext)==FALSE) 
		return FALSE; 
	 
	return TRUE; 
} 
 
void GLView3D::SetBackgroundColor(double r, double g, double b) 
{ 
	m_red_bg = r; 
	m_green_bg = g; 
	m_blue_bg = b; 
} 
 
void GLView3D::RenderImage(void) 
{ 
	if (m_IsInitialized && m_dib.IsCreated()) 
	{ 
		glClearColor((float)m_red_bg,(float)m_blue_bg, 
			(float)m_green_bg,1.0f); 
 
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
		 
		  // put a working copy on the matrix stack 
		glPushMatrix(); 
		 
			// Position / translation / scale 
		glTranslated(m_model_matrix.X(),m_model_matrix.Y(),m_model_matrix.Z()); 
		glRotated(m_model_matrix.XRot(), 1.0, 0.0, 0.0); 
		glRotated(m_model_matrix.YRot(), 0.0, 1.0, 0.0); 
		glRotated(m_model_matrix.ZRot(), 0.0, 0.0, 1.0); 
		glScaled(m_model_matrix.XScale(),m_model_matrix.YScale(),m_model_matrix.ZScale()); 
 
		  // build the scene...if necessary 
		RenderPrimaryImage(); 
 
		glFlush(); 
	 
		  // pop the working copy of the matrix stack 
		glPopMatrix(); 
	} 
} 
 
void GLView3D::RenderPrimaryImage(void) 
{ 
	//glColor3ub(128,128,128); 
	//GLUquadricObj * q = gluNewQuadric(); 
	//gluQuadricDrawStyle(q, GLU_LINE); 
	//gluQuadricNormals(q, GLU_SMOOTH); 
	//gluSphere(q,1.0,16,16); 
	//gluDeleteQuadric(q); 
 
	GLdouble v1[3], v2[3]; 
 
	glBegin(GL_LINES); 
	v1[0] = v1[1] = v1[2] = 0.0; 
	v2[0] = 1.5; v2[1] = v2[2] = 0.0; 
	glColor3ub(224,0,0); 
	glVertex3dv(v1); 
	glVertex3dv(v2); 
	v2[0] = 0.0; v2[1] = 1.5; v2[2] = 0.0; 
	glColor3ub(0,224,0); 
	glVertex3dv(v1); 
	glVertex3dv(v2); 
	v2[0] = 0.0; v2[1] = 0.0; v2[2] = 1.5; 
	glColor3ub(0,0,224); 
	glVertex3dv(v1); 
	glVertex3dv(v2); 
	glEnd(); 
} 
 
void GLView3D::DrawImage(CWnd * wnd) 
{ 
	CClientDC dc(wnd); 
	m_dib.Draw(&dc,0,0); 
} 
 
void GLView3D::PushMatrixValues(void) 
{ 
	m_saved_matrix = m_model_matrix; 
} 
 
void GLView3D::PopMatrixValues(void) 
{ 
	m_model_matrix = m_saved_matrix; 
} 
 
void NormalVector(GLdouble p1[3], GLdouble p2[3], 
				  GLdouble p3[3], GLdouble n[3]) 
{ 
	GLdouble v1[3], v2[3], d; 
	// calculate two vectors, using the middle point 
	// as the common origin 
	v1[0] = p3[0] - p1[0]; 
	v1[1] = p3[1] - p1[1]; 
	v1[2] = p3[2] - p1[2]; 
	v2[0] = p3[0] - p2[0]; 
	v2[1] = p3[1] - p2[1]; 
	v2[2] = p3[2] - p2[2]; 
 
	// calculate the cross product of the two vectors 
	n[0] = v1[1] * v2[2] - v2[1] * v1[2]; 
	n[1] = v1[2] * v2[0] - v2[2] * v1[0]; 
	n[2] = v1[0] * v2[1] - v2[0] * v1[1]; 
 
	// normalize the vector 
	d = ( n[0] * n[0] + n[1] * n[1] + n[2] * n[2] ); 
	// try to catch very small vectors 
	if (d < (GLdouble)0.00000001) 
	{ 
		d = (GLdouble)100000000.0; 
	} 
	else 
	{ 
		d = (GLdouble)1.0 / sqrt(d); 
	} 
 
	n[0] *= d; 
	n[1] *= d; 
	n[2] *= d; 
}