www.pudn.com > 3dsMFCRender.rar > toolGL.cpp, change:1998-03-31,size:16698b


////////////////////////////////////////////////////////////////////// 
//	Class CtoolGL  toolGL.cpp  
//	Copyright Sivert L. Nielsen 
// 
// 
//		CtoolGL()				Constructor 
//		~CtoolGL()				Destructor 
//		Initialize(...)			Boot and connect OpenGL to a window 
//		RenderScene()			Render all your stuff 
//		Resize()				...hmmmmmmm... 
//		SetError(...)			Sets and errormessage, 'cause one occured 
//		SetupPixelFormat()		PixelformatDescriptor initiates 
//		SetupViewingFrustrum	CameraAngles 
//		SetupViewingTransform	Cameraposition 
//		SetupViewPort			How much of the window is to be rendered? 
//	 
//	CtoolGL needs a pointer to a CDC (in Visual C). 
//	CtoolGL gets it through InitializeOpenGL(...) 
//	You must therefore add this code your onCreate(...) function: 
//	     pDC = new CClientDC(this);  
//	     pGl->InitializeOpenGL(pDC); 
//	Where pDC is a pointer of CDC og pGl is a pointer of CtoolGL. 
//  You may draw and do whatever you like using this lib 
//	through calling memberfunctions of this class. Like 
//	pGl->RenderScene(). pGL->Open3dsFile(...) will do exactly 
//	that, open a .3ds-file. Call RenderScene again and it will appear 
//	in your window. 
// 
//	This Class and the classes used from this is freeware 
//	You may do as you wish with it. Please note that I  
//	strongly encourage you to share of yourself and of  
//	your own knowledge.  
// 
//	One world, one mind. 
//	 
//										Sivert, 1998						 
//							 
 
 
#include "stdafx.h" 
#include "toolgl.h"		 
 
 
 
 
 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CtoolGL::CtoolGL() 
{ 
	 
} 
 
CtoolGL::~CtoolGL() 
{ 
	Destroy(); 
} 
 
////////////////////////////////////////////////////////// 
//							_ErrorStrings 
////////////////////////////////////////////////////////// 
const char* const CtoolGL::_ErrorStrings[]=  
{ 
	{"No Error"},				 //0 
	{"Unable to get a DC"},		 //1 
	{"ChoosePixelFormat failed"},//2 
	{"SelectPixelFormat failed"},//3 
	{"wglCreateContext failed"}, //4 
	{"wglMakeCurrent failed"},	 //5 
	{"wglDeleteContext faild"},  //6 
	{"SwapBuffers failed"},		 //7 
}; 
 
////////////////////////////////////////////////////////// 
//							SetError 
////////////////////////////////////////////////////////// 
void CtoolGL::SetError( int e) 
{ 
	//Sivert Says; Hvis det ikke allerede har dukket opp en feil 
	//Sivert Says; Sett denne som gjeldende 
	if (_ErrorStrings[0] == m_ErrorStrings) 
	{ 
		m_ErrorStrings = _ErrorStrings[e]; 
	} 
	 
} 
 
////////////////////////////////////////////////////////// 
//							InitializeopenGL 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::InitializeOpenGL(CDC* pDC) 
{ 
	m_bitmapIs   = FALSE; 
	m_AscLoaded  = FALSE; 
	m_3dsLoaded  = FALSE; 
	m_Bbox		 = FALSE; 
	m_DispList	 = FALSE; 
	recompile    = 0; 
	list         = 1; 
	camPos[0]	 = 0.0f; 
	camPos[1]	 = 0.0f; 
	camPos[2]	 = -100.0f; 
	camRot[0]	 = 20.0f; 
	camRot[1]	 = -20.0f; 
	camRot[2]	 = 0.0f; 
 
	scenePos[0]	 = 0.0f; 
	scenePos[1]	 = 0.0f; 
	scenePos[2]	 = 0.0f; 
	sceneRot[0]	 = 0.0f; 
	sceneRot[1]	 = 0.0f; 
	sceneRot[2]	 = 0.0f; 
 
 
	m_triList.Init(); 
	m_pDC = pDC; 
 
	if ( m_pDC == NULL) 
	{ 
		//Sivert Says; Fikk ikke DC 
		SetError(1); 
		return FALSE; 
	} 
 
	if (!SetupPixelFormat()) 
	{ 
		return FALSE; 
	} 
 
	if ((m_hRC = ::wglCreateContext(m_pDC->GetSafeHdc())) == 0 ) 
	{ 
		SetError(4); 
		return FALSE; 
	} 
 
	if (::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE) 
	{ 
		SetError(5); 
		return FALSE; 
	} 
	 
 
	//Sivert Says: shadingmodell GL_FLAT eller GL_SMOOTH? 
	::glShadeModel(GL_FLAT); 
	//Sivert Says: svart er "clearcolor" 
	::glClearColor(0.0F, 0.0F, 0.0F, 0.0F); 
	//Sivert Says: bakenden av bufferet er "cleardepth" 
	::glClearDepth(1.0F); 
	//Sivert Says: Skru på dybdetesting 
	::glEnable(GL_DEPTH_TEST); 
	//Sivert Says: Ikke tegn skulte flater 
	::glEnable(GL_CULL_FACE); 
	//Sivert Says: Skru på blending 
	//::glEnable(GL_BLEND); 
	//Sivert Says: Skru på blending med alfa-buffer 
	//::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
 
	//Sivert Says: Lys må vi ha! 
	GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f}; 
	GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f}; 
	GLfloat lightPos[]     = {6000.0f,6000.0f,6000.0f, 1.0f}; 
 
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight); 
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); 
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); 
	 
	glEnable(GL_COLOR_MATERIAL); 
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); 
	glEnable(GL_LIGHTING); 
	glEnable(GL_LIGHT0); 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////// 
//							SetupPixelFormat 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::SetupPixelFormat() 
{ 
	PIXELFORMATDESCRIPTOR pfd =  
	{ 
		sizeof(PIXELFORMATDESCRIPTOR),//Size of yhis pfd 
		1,							//versjonsnummer 
		PFD_DRAW_TO_WINDOW |		//support window 
			PFD_SUPPORT_OPENGL |	//support openGL 
			PFD_DOUBLEBUFFER,		//double buffered 
		PFD_TYPE_RGBA,				//RGBA typed 
		24,							//24bit color depth 
		0,0,0,0,0,0,				//colorbits ignored 
		0,							//no alpha buffer 
		0,							//shift bit ignored 
		0,							//no accumulation buffer 
		0,0,0,0,					//accum bits ignored 
		16,							//16-bit z-buffer 
		0,							//no stencil buffer 
		0,							//no auxiliary buffer 
		PFD_MAIN_PLANE,				//main layer 
		0,							//reserved 
		0,0,0,						//layer masks ignored 
	}; 
	 
	int pixelformat; 
 
	if ( (pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0) 
	{ 
		SetError(2); 
		return FALSE; 
	} 
	 
	if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) 
	{ 
		SetError(3); 
		return FALSE; 
	} 
 
 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////// 
//							SetupViewPort 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::SetupViewport( int cx, int cy )  
{ 
	//Sivert Says: Velg hele Klientområdet 
	glViewport(0,0,cx,cy); 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////// 
//							SetupViewingFrustrum 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::SetupViewingFrustrum( GLdouble aspect_ratio )  
{ 
	//Sivert Says: Velg default viewing volum 
	gluPerspective(40.0F, aspect_ratio, 1.0F, 10000.0F); 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////// 
//							SetupViewingTransform 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::SetupViewingTransform()  
{ 
	// Sivert Says: Velg default viewing trasformasjon 
	// Sivert Says: 20 grader om X-aksen og -5 bort Z-aksen 
	::glTranslatef( camPos[0], camPos[1], camPos[2] ); 
	::glRotatef( camRot[0], 1.0F, 0.0F, 0.0F ); 
	::glRotatef( camRot[1], 0.0F, 1.0F, 0.0F ); 
	::glRotatef( camRot[2], 0.0F, 0.0F, 1.0F ); 
	return TRUE; 
} 
 
////////////////////////////////////////////////////////// 
//							Resize 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::Resize(int cx, int cy) 
{ 
	GLdouble aspect_ratio; 
 
	if ( 0>=cx || 0>=cy ) return true; 
 
	SetupViewport( cx, cy); 
 
	//Sivert Says: Regn ut aspekt ratio 
	//Sivert Says: Dette holder alle skaleringer like 
	aspect_ratio = (GLdouble)cx/(GLdouble)cy; 
 
	//Sivert Says: velg projeksjons matrisen og tøm alt 
	::glMatrixMode(GL_PROJECTION); 
	::glLoadIdentity(); 
 
	//Sivert Says: Velg view volume 
	SetupViewingFrustrum( aspect_ratio ); 
 
	//Sivert Says: Hopp tilbake til modelviewmatrise og tøm den 
	::glMatrixMode(GL_MODELVIEW); 
	::glLoadIdentity(); 
 
	//Sivert Says: Kjør viewing transformasjoner 
	SetupViewingTransform(); 
 
	//ta vare på vindustørrelse 
	m_pRectSize.left = 0; 
	m_pRectSize.top = 0; 
	m_pRectSize.right = cx; 
	m_pRectSize.bottom = cy; 
 
	return true; 
} 
 
////////////////////////////////////////////////////////// 
//							Destroy() 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::Destroy() 
{ 
	 
	if ( ::wglMakeCurrent(0,0) == FALSE) 
	{ 
		SetError(2); 
		return false; 
	} 
 
	if ( ::wglDeleteContext( m_hRC) == FALSE) 
	{ 
		SetError(6); 
		return false; 
	} 
 
	if ( m_pDC ) 
	{ 
		delete m_pDC; 
	} 
	 
 
	return true; 
} 
 
////////////////////////////////////////////////////////// 
//							RenderScene 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::RenderScene()  
{ 
 
	::glMatrixMode(GL_MODELVIEW); 
	::glLoadIdentity(); 
	SetupViewingTransform(); 
 
	::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
	 
	::glPushMatrix(); 
	::glTranslatef(scenePos[0], scenePos[1], scenePos[2]); 
	::glRotatef( sceneRot[0], 1.0F, 0.0F, 0.0F ); 
	::glRotatef( sceneRot[1], 0.0F, 1.0F, 0.0F ); 
	::glRotatef( sceneRot[2], 0.0F, 0.0F, 1.0F ); 
 
	DrawAxis(); 
	 
	Draw3ds(); 
	 
	::glPopMatrix(); 
 
	// 
	// Sivert: Oppdatér display, alternér frame 
	// 
	if( ::SwapBuffers(m_pDC->GetSafeHdc()) == FALSE) 
	{ 
		SetError(7); 
		return FALSE; 
	} 
	 
	return TRUE; 
} 
 
 
 
////////////////////////////////////////////////////////// 
//							DrawAxis() 
////////////////////////////////////////////////////////// 
void CtoolGL::DrawAxis() 
{ 
	glBegin( GL_LINES); 
			//rød x-akse 
			glColor3f(1.0F, 0.0F, 0.0F); 
			glVertex3f(-3.0f, 0.0f, 0.0f); 
			glVertex3f( 3.0f, 0.0f, 0.0f); 
			glVertex3f( 2.5f, 0.5f, 0.0f); 
			glVertex3f( 3.0f, 0.0f, 0.0f); 
			glVertex3f( 2.5f,-0.5f,-0.0f); 
			glVertex3f( 3.0f, 0.0f, 0.0f); 
			 
			//grønn y-akse 
			glColor3f(0.0F, 1.0F, 0.0F); 
			glVertex3f( 0.0f, -3.0f, 0.0f); 
			glVertex3f( 0.0f,  3.0f, 0.0f); 
			glVertex3f(-0.5f,  2.5f, 0.0f); 
			glVertex3f( 0.0f,  3.0f, 0.0f); 
			glVertex3f( 0.5f,  2.5f, 0.0f); 
			glVertex3f( 0.0f,  3.0f, 0.0f); 
 
			//blå z-akse 
			glColor3f(0.0F, 0.0F, 1.0F); 
			glVertex3f( 0.0f, 0.0f, -3.0f); 
			glVertex3f( 0.0f, 0.0f,  3.0f); 
			glVertex3f(-0.5f, 0.0f,  2.5f); 
			glVertex3f( 0.0f, 0.0f,  3.0f); 
			glVertex3f( 0.5f, 0.0f,  2.5f); 
			glVertex3f( 0.0f, 0.0f,  3.0f); 
	glEnd(); 
} 
 
////////////////////////////////////////////////////////// 
//							DrawGuy() 
////////////////////////////////////////////////////////// 
void CtoolGL::DrawGuy() 
{ 
	 
	//hode 
	glColor3f(1.0F, 0.0F, 0.0F); 
	glBegin( GL_TRIANGLES ); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  1.0f,  1.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  1.0f); 
 
		glVertex3f(  1.0f,  1.0f,  1.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  1.0f,  1.0f); 
		glVertex3f(  0.0f,  1.0f,  1.0f); 
 
		glVertex3f(  0.0f,  1.0f,  1.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  1.0f); 
		glVertex3f(  1.0f,  1.0f,  1.0f); 
 
		glVertex3f(  1.0f,  1.0f,  1.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
	glEnd(); 
 
	glPushMatrix(); 
 
	glRotatef(45.0f, 1.0f, 1.0f, 1.0f); 
	glTranslatef(0.5f, 0.0f, 0.0f); 
 
 
	//torus 
	glColor3f(0.0F, 1.0F, 0.0F); 
	glBegin( GL_TRIANGLES ); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  0.0f,  1.0f,  2.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  0.0f,  0.0f,  0.0f); 
 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  1.0f,  1.0f,  2.0f); 
 
		glVertex3f(  1.0f,  1.0f,  2.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  0.0f,  0.0f); 
 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  1.0f,  2.0f); 
		glVertex3f(  0.0f,  1.0f,  2.0f); 
 
		glVertex3f(  0.0f,  1.0f,  2.0f); 
		glVertex3f(  0.0f,  0.0f,  1.0f); 
		glVertex3f(  1.0f,  0.0f,  1.0f); 
 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  2.0f); 
		glVertex3f(  1.0f,  1.0f,  2.0f); 
 
		glVertex3f(  1.0f,  1.0f,  2.0f); 
		glVertex3f(  1.0f,  1.0f,  0.0f); 
		glVertex3f(  0.0f,  1.0f,  0.0f); 
	glEnd(); 
 
	glPopMatrix(); 
	//ben 
} 
 
////////////////////////////////////////////////////////// 
//							DrawAsc() 
////////////////////////////////////////////////////////// 
void CtoolGL::DrawAsc() 
{ 
	/*if(!m_AscLoaded)  
	{ 
		recompile = 0; //recompilere lista for å være sikker 
		return; //må være lastet inn 
	} 
	 
	if (recompile==0) { 
		glNewList(list, GL_COMPILE_AND_EXECUTE); 
		glBegin( GL_TRIANGLES ); 
			for( int i = 0; i  m_pAsc->NumFaces; i++) 
			{ 
				glColor4fv( m_pAsc->MaterialData[i]); 
				glNormal3fv( m_pAsc->NormalData[i]); 
				glVertex3fv( m_pAsc->VertexData[ m_pAsc->FaceData[i][0] ]); 
				glVertex3fv( m_pAsc->VertexData[ m_pAsc->FaceData[i][1] ]); 
				glVertex3fv( m_pAsc->VertexData[ m_pAsc->FaceData[i][2] ]); 
			} 
		glEnd(); 
		glEndList(); 
		recompile = 1; 
	} 
	else glCallList(list); 
	*/ 
} 
 
////////////////////////////////////////////////////////// 
//							SetAsc() 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::setAsc(CtoolAscReader * theAsc, BOOL loaded) 
{ 
/*	m_pAsc = theAsc; 
	m_AscLoaded =  loaded; 
	if (!loaded) recompile = 0; 
*/	return TRUE; 
 
} 
////////////////////////////////////////////////////////// 
//							Draw3ds() 
////////////////////////////////////////////////////////// 
void CtoolGL::Draw3ds() 
{ 
	if (m_3dsLoaded) { 
		if(m_Bbox)  
			m_triList.drawGLBbox(); 
		else if(m_DispList) 
			m_triList.drawGLDispList(); 
		else  
			m_triList.drawGL(); 
	} 
} 
////////////////////////////////////////////////////////// 
//							Open3dsFile() 
////////////////////////////////////////////////////////// 
BOOL CtoolGL::Open3dsFile(char * filename) 
{ 
	C3dsReader Loader; 
	BOOL result; 
	if( m_triList.getNumObjects() > 0 ) m_triList.removeAllObjects(); 
	 
	//tygg på 3dstudio fila 
	result = Loader.Reader(filename, &m_triList); 
	if( result)  
	{ 
		m_3dsLoaded = TRUE; 
		m_triList.doAfterMath(); 
		m_triList.getAnimRange(animstart, animend); 
	} 
	 
	return result; 
} 
 
long CtoolGL::AdvanceAnim(int step, int direction, long frame) 
{ 
	return m_triList.advanceFrame(step,direction,frame); 
} 
 
////////////////////////////////////////////////////////// 
//							SetCamPos(...) 
//		     axis : 0=X  1=Y  2=Z 
//		    value : amount to move or set 
//		increment : apply increment. if false set exact value 
//		    apply : if false don't store value 
////////////////////////////////////////////////////////// 
void CtoolGL::SetCamPos(int axis, int value, BOOL increment, BOOL apply) 
{ 
	if(increment) 
	{ 
		camPos[axis] += (float)value*camPos[axis]/100; 
	} 
	else 
	{ 
		camPos[axis] = (float)value/2; 
	} 
 
	//Sivert Says: Hopp tilbake til modelviewmatrise og tøm den 
	::glMatrixMode(GL_MODELVIEW); 
	::glLoadIdentity(); 
 
	//Sivert Says: Kjør viewing transformasjoner 
	SetupViewingTransform(); 
	RenderScene(); 
 
} 
 
void CtoolGL::SetSceneRot(int axis, int value, BOOL increment, BOOL apply) 
{ 
	if(increment) 
		sceneRot[axis] += (sceneRot[axis] >=360) ? (-360 + value/2): value/2; 
	else 
		sceneRot[axis] = (sceneRot[axis] >=360) ? (-360 + value/2): value/2; 
	 
	RenderScene(); 
} 
 
void CtoolGL::SetBoundingBoxMode() 
{ 
	m_Bbox = !m_Bbox;	 
	if(m_Bbox) m_DispList = FALSE; 
} 
 
void CtoolGL::setDisplayListMode() 
{ 
	m_DispList = !m_DispList; 
	if(m_DispList) m_Bbox = FALSE; 
}