www.pudn.com > OBJReadandRender.rar > OGLView.cpp, change:2009-06-16,size:31243b


 
#include "stdafx.h" 
#include <mmsystem.h> 
#include <math.h> 
#include "ToonTex.h" 
#include "OGLView.h" 
#include "LoadOBJ.h" 
#include "LoadTex.h" 
#include "ToonSet.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#pragma warning (disable:4244)      // I NEED TO CONVERT FROM DOUBLE TO FLOAT 
 
/// Application Definitions /////////////////////////////////////////////////// 
#define OGL_AXIS_DLIST		1		// OPENGL DISPLAY LIST ID 
#define OGL_SELECTED_DLIST	2		// SELECTED BONE OPENGL DISPLAY LIST 
#define ROTATE_SPEED		1.0		// SPEED OF ROTATION 
/////////////////////////////////////////////////////////////////////////////// 
 
/// Global Variables ////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
// COGLView 
 
COGLView::COGLView() 
{ 
	// INITIALIZE THE MODE KEYS 
	m_StatusBar = NULL;	// CLEAR THIS.  IT IS SET BY MAINFRAME BUT UNTIL THEN MARK IT 
	m_AntiAlias	= FALSE; 
	m_Dragging = FALSE; 
	m_Silhouette = TRUE; 
    m_ARBMultiTexture = FALSE;		// Is ARBMultiTexture supported 
	m_UseMultiTexture = TRUE;		// Do I want to use it? 
 
	// INITIALIZE SOME OF THE CAMERA VARIABLES 
	ResetBone(&m_Camera, NULL); 
	m_Camera.id = -1; 
	strcpy(m_Camera.name,"Camera"); 
	m_Camera.rot.x = 0.0f; 
	m_Camera.rot.y = 0.0f; 
	m_Camera.rot.z = 0.0f; 
	m_Camera.b_trans.y = 0.0f; 
	m_Camera.b_trans.z = -50.0f; 
	m_Camera.trans.y = 0.0f; 
	m_Camera.trans.z = -50.0f; 
 
	m_Model.vertex = NULL; 
 
	// Set the Default Light Direction 
	m_ShadeLight.x = 0.3f; 
	m_ShadeLight.y = 0.1f; 
	m_ShadeLight.z = 0.8f;	 
	NormalizeVector(&m_ShadeLight);	// Normalize it since I know I didn't 
 
	m_SilhouetteColor.r = 0.0f; 
	m_SilhouetteColor.g = 0.0f; 
	m_SilhouetteColor.b = 0.0f; 
	m_SilhouetteWidth = 3;			// Width of Silhouette line 
 
} 
 
COGLView::~COGLView() 
{ 
} 
 
BOOL COGLView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)  
{ 
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); 
} 
 
BEGIN_MESSAGE_MAP(COGLView, CWnd) 
	//{{AFX_MSG_MAP(COGLView) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_PAINT() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_RBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_MOVE() 
	ON_WM_LBUTTONUP() 
	ON_WM_RBUTTONUP() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// COGLView message handlers 
 
BOOL COGLView::SetupPixelFormat(HDC hdc) 
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
    PIXELFORMATDESCRIPTOR pfd, *ppfd; 
    int pixelformat; 
/////////////////////////////////////////////////////////////////////////////// 
    ppfd = &pfd; 
 
    ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); 
    ppfd->nVersion = 1; 
    ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 
    ppfd->dwLayerMask = PFD_MAIN_PLANE; 
    ppfd->iPixelType = PFD_TYPE_RGBA; 
    ppfd->cColorBits = 24; 
    ppfd->cDepthBits = 32; 
    ppfd->cAccumBits = 0; 
    ppfd->cStencilBits = 0; 
 
    pixelformat = ChoosePixelFormat(hdc, ppfd); 
 
    if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0) { 
        MessageBox("ChoosePixelFormat failed", "Error", MB_OK); 
        return FALSE; 
    } 
 
    if (pfd.dwFlags & PFD_NEED_PALETTE) { 
        MessageBox("Needs palette", "Error", MB_OK); 
        return FALSE; 
    } 
 
    if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { 
        MessageBox("SetPixelFormat failed", "Error", MB_OK); 
        return FALSE; 
    } 
 
    return TRUE; 
} 
 
 
int COGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
	RECT rect; 
/////////////////////////////////////////////////////////////////////////////// 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
    m_hDC = ::GetDC(m_hWnd); 
    if (!SetupPixelFormat(m_hDC)) 
		PostQuitMessage (0); 
	 
    m_hRC = wglCreateContext(m_hDC); 
    wglMakeCurrent(m_hDC, m_hRC); 
    GetClientRect(&rect); 
    initializeGL(rect.right, rect.bottom); 
 
	// GENERATE THE OPENGL TEXTURE ID 
	glGenTextures(1,&m_ShadeTexture); 
 
	LoadShadeTexture("default.shd"); 
 
	// CREATE THE DISPLAY LIST FOR AN AXIS WITH ARROWS POINTING IN 
	// THE POSITIVE DIRECTION Red = X, Green = Y, Blue = Z 
	glNewList(OGL_AXIS_DLIST,GL_COMPILE); 
		glBegin(GL_LINES); 
			glColor3f(1.0f, 0.0f, 0.0f);	// X AXIS STARTS - COLOR RED 
			glVertex3f(-0.2f,  0.0f, 0.0f); 
			glVertex3f( 0.2f,  0.0f, 0.0f); 
			glVertex3f( 0.2f,  0.0f, 0.0f);	// TOP PIECE OF ARROWHEAD 
			glVertex3f( 0.15f,  0.04f, 0.0f); 
			glVertex3f( 0.2f,  0.0f, 0.0f);	// BOTTOM PIECE OF ARROWHEAD 
			glVertex3f( 0.15f, -0.04f, 0.0f); 
			glColor3f(0.0f, 1.0f, 0.0f);	// Y AXIS STARTS - COLOR GREEN 
			glVertex3f( 0.0f,  0.2f, 0.0f); 
			glVertex3f( 0.0f, -0.2f, 0.0f);			 
			glVertex3f( 0.0f,  0.2f, 0.0f);	// TOP PIECE OF ARROWHEAD 
			glVertex3f( 0.04f,  0.15f, 0.0f); 
			glVertex3f( 0.0f,  0.2f, 0.0f);	// BOTTOM PIECE OF ARROWHEAD 
			glVertex3f( -0.04f,  0.15f, 0.0f); 
			glColor3f(0.0f, 0.0f, 1.0f);	// Z AXIS STARTS - COLOR BLUE 
			glVertex3f( 0.0f,  0.0f,  0.2f); 
			glVertex3f( 0.0f,  0.0f, -0.2f); 
			glVertex3f( 0.0f,  0.0f, 0.2f);	// TOP PIECE OF ARROWHEAD 
			glVertex3f( 0.0f,  0.04f, 0.15f); 
			glVertex3f( 0.0f, 0.0f, 0.2f);	// BOTTOM PIECE OF ARROWHEAD 
			glVertex3f( 0.0f, -0.04f, 0.15f); 
		glEnd(); 
	glEndList(); 
 
	drawScene(); 
	return 0; 
} 
 
/* OpenGL code */ 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	resize 
// Purpose:		This code handles the windows resize for OpenGL 
// Arguments:	Width and heights of the view window 
/////////////////////////////////////////////////////////////////////////////// 
GLvoid COGLView::resize( GLsizei width, GLsizei height ) 
{ 
// Local Variables /////////////////////////////////////////////////////////// 
    GLfloat aspect; 
/////////////////////////////////////////////////////////////////////////////// 
 
    glViewport(0, 0, width, height); 
 
    aspect = (GLfloat)width/(GLfloat)height; 
 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
	gluPerspective(20.0, aspect,1, 2000); 
    glMatrixMode(GL_MODELVIEW); 
	m_ScreenWidth = width; 
	m_ScreenHeight = height; 
 
}     
//// resize ///////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	CheckForMultiTexture 
// Purpose:		Check if there is support for ARBMultitexture and save pointers 
/////////////////////////////////////////////////////////////////////////////// 
void COGLView::CheckForMultiTexture() 
{ 
    char *strExtensions; 
 
    strExtensions = (char*)glGetString(GL_EXTENSIONS); 
	// Check if MultiTexture is supported 
    if (strstr(strExtensions, "GL_ARB_multitexture") == 0) { 
		MessageBox("GL_ARB_multitexture was not found.\nSingle Pass will be used","GL Error",MB_OK); 
        m_ARBMultiTexture = FALSE; 
        return; 
    } 
    m_ARBMultiTexture = TRUE; 
 
	// Grab pointers to the functions I need 
    glActiveTextureARB         = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB"); 
    glMultiTexCoord2fARB       = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB"); 
    glMultiTexCoord1fARB       = (PFNGLMULTITEXCOORD1FARBPROC)wglGetProcAddress("glMultiTexCoord1fARB"); 
} 
 
GLvoid COGLView::initializeGL(GLsizei width, GLsizei height) 
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
    GLfloat aspect; 
/////////////////////////////////////////////////////////////////////////////// 
 
    glClearColor(0.7f, 0.7f, 0.7f, 0.0f); 
    glClearDepth(1.0); 
    glDepthFunc(GL_LESS); 
    glShadeModel(GL_SMOOTH); 
 
    glEnable(GL_DEPTH_TEST); 
 
    glMatrixMode(GL_PROJECTION); 
    aspect = (GLfloat)width/(GLfloat)height; 
	// Establish viewing volume 
	gluPerspective(60.0, aspect,1, 2000); 
    glMatrixMode(GL_MODELVIEW); 
 
	// SET SOME OGL INITIAL STATES SO THEY ARE NOT DONE IN THE DRAW LOOP 
	glPolygonMode(GL_FRONT,GL_FILL); 
	glDepthFunc(GL_LESS); 
    glEnable(GL_CULL_FACE); 
	glPointSize(8.0);		// NICE BEEFY POINTS FOR THE VERTEX SELECTION 
	glDisable(GL_TEXTURE_2D); 
 
	glDisable(GL_LIGHTING); 
 
	glEnable(GL_BLEND); 
//	glBlendFunc( 
 
	CheckForMultiTexture();		// Get ARB_MultiTexture settings 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	CalculateShadow 
// Purpose:		Calculate the shadow coordinate value for a normal 
// Arguments:	The vertex normal, Light vector, and Object rotation matrix 
// Returns:		An index coordinate into the shade table 
/////////////////////////////////////////////////////////////////////////////// 
float COGLView::CalculateShadow(tVector *normal,tVector *light, tMatrix *mat) 
{ 
//// Local Variables //////////////////////////////////////////////////////////////// 
	tVector post; 
	float dot; 
///////////////////////////////////////////////////////////////////////////////////// 
	// Rotate the normal by the current object matrix 
	MultVectorByRotMatrix(mat, normal, &post); 
	dot = DotProduct(&post,light);				// Calculate the Dot Product 
 
	if (dot  0) dot = 0;						// Make sure the Back half dark 
	return dot;									// Return the shadow value 
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	drawModel 
// Purpose:		Actually Draws the Model using the Cartoon Settings 
// Arguments:	Pointer to the model 
/////////////////////////////////////////////////////////////////////////////// 
GLvoid COGLView::drawModel(t_Visual *visual) 
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
	tMatrix mat;		// Needed for Lighting Calc 
	int loop; 
	t_faceIndex *face; 
	float   u; 
/////////////////////////////////////////////////////////////////////////////// 
 
	if (visual->vertex != NULL) 
	{ 
		// Turn on anti-aliased silhouette lines if selected 
		if (m_AntiAlias) 
		{ 
			glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); 
			glEnable(GL_LINE_SMOOTH); 
		} 
		else 
			glDisable(GL_LINE_SMOOTH); 
 
		// Set the Base color of the Model from the material 
		glDisable(GL_LIGHTING); 
 
		// Grab the matrix for lighting calc 
		glGetFloatv(GL_MODELVIEW_MATRIX,mat.m); 
 
		// If Multitexture is supported render two passes with the shadow modulated with the base texture in each pass 
		if (m_ARBMultiTexture && m_UseMultiTexture) 
		{ 
			// Pass one is the "dark" texture modulated with the shadow texture 
			glAlphaFunc(GL_EQUAL,0.0f);	// Draw this when shade "alpha" = 0 
			glEnable(GL_ALPHA_TEST); 
 
			(*glActiveTextureARB)(GL_TEXTURE0_ARB); 
		    glEnable(GL_TEXTURE_2D); 
			glBindTexture( GL_TEXTURE_2D,visual->glTex); 
			glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 
			glEnable(GL_BLEND); 
 
		    (*glActiveTextureARB)(GL_TEXTURE1_ARB); 
			// Bind my 1D shade texture 
			glEnable(GL_TEXTURE_1D); 
			glBindTexture( GL_TEXTURE_1D,m_ShadeTexture); 
			glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 
			glEnable(GL_BLEND); 
 
			face = visual->index; 
			if(visual->uvCnt>0) 
			{ 
				for (loop = 0; loop  visual->faceCnt; loop++,face++) 
			    { 
				glBegin(GL_TRIANGLES); 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[0]].u, visual->texture[face->t[0]].v); 
					u = CalculateShadow(&visual->normal[face->n[0]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[0]].x); 
					 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[1]].u, visual->texture[face->t[1]].v); 
					u = CalculateShadow(&visual->normal[face->n[1]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[1]].x); 
 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[2]].u, visual->texture[face->t[2]].v); 
					u = CalculateShadow(&visual->normal[face->n[2]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[2]].x); 
 
					glColor3f(visual->Ka[visual->index[loop].mat].r,visual->Ka[visual->index[loop].mat].g,visual->Ka[visual->index[loop].mat].b); 
                    glColor3f(visual->Kd[visual->index[loop].mat].r,visual->Kd[visual->index[loop].mat].g,visual->Kd[visual->index[loop].mat].b); 
                    glColor3f(visual->Ks[visual->index[loop].mat].r,visual->Ks[visual->index[loop].mat].g,visual->Ks[visual->index[loop].mat].b); 
                    glColor3f(visual->matColor[visual->index[loop].mat].r,visual->matColor[visual->index[loop].mat].g,visual->matColor[visual->index[loop].mat].b); 
				 
				glEnd(); 
			    } 
 
			} 
			// Pass two is the "light" texture modulated with the shadow texture 
			glAlphaFunc(GL_GREATER,0.0f);		// Only draw this when shade "alpha" is > 0 
			glEnable(GL_ALPHA_TEST); 
			 
			(*glActiveTextureARB)(GL_TEXTURE0_ARB); 
		    glEnable(GL_TEXTURE_2D); 
			glBindTexture( GL_TEXTURE_2D,visual->glTex2); 
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
			glEnable(GL_BLEND); 
 
		    (*glActiveTextureARB)(GL_TEXTURE1_ARB); 
			// Bind my 1D shade texture 
			glEnable(GL_TEXTURE_1D); 
			glBindTexture( GL_TEXTURE_1D,m_ShadeTexture); 
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
			glEnable(GL_BLEND); 
 
			face = visual->index; 
			if(visual->uvCnt>0) 
			{ 
				for (loop = 0; loop  visual->faceCnt; loop++,face++) 
			    { 
				glBegin(GL_TRIANGLES); 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[0]].u, visual->texture[face->t[0]].v); 
					u = CalculateShadow(&visual->normal[face->n[0]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[0]].x); 
 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[1]].u, visual->texture[face->t[1]].v); 
					u = CalculateShadow(&visual->normal[face->n[1]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[1]].x); 
 
					(*glMultiTexCoord2fARB)(GL_TEXTURE0_ARB, visual->texture[face->t[2]].u, visual->texture[face->t[2]].v); 
					u = CalculateShadow(&visual->normal[face->n[2]],&m_ShadeLight, &mat); 
					(*glMultiTexCoord1fARB)(GL_TEXTURE1_ARB, u); 
					glVertex3fv(&visual->vertex[face->v[2]].x); 
 
					glColor3f(visual->Ka[visual->index[loop].mat].r,visual->Ka[visual->index[loop].mat].g,visual->Ka[visual->index[loop].mat].b); 
                    glColor3f(visual->Kd[visual->index[loop].mat].r,visual->Kd[visual->index[loop].mat].g,visual->Kd[visual->index[loop].mat].b); 
                    glColor3f(visual->Ks[visual->index[loop].mat].r,visual->Ks[visual->index[loop].mat].g,visual->Ks[visual->index[loop].mat].b); 
                    glColor3f(visual->matColor[visual->index[loop].mat].r,visual->matColor[visual->index[loop].mat].g,visual->matColor[visual->index[loop].mat].b); 
 
				glEnd(); 
			    } 
			} 
		} 
		// If MultiTexture is not supported just draw pass 1 
		else	 
		{ 
			glEnable(GL_TEXTURE_2D); 
			glBindTexture( GL_TEXTURE_2D,visual->glTex2); 
			face = visual->index; 
			if(visual->uvCnt>0) 
			{ 
				for (loop = 0; loop  visual->faceCnt; loop++,face++) 
			    { 
				// Pass 1, Base Texture with no Shading 
				glColor3f(1.0f,1.0f,1.0f);	 
				glBegin(GL_TRIANGLES); 
					glTexCoord2f(visual->texture[face->t[0]].u,visual->texture[face->t[0]].v);	 
					glVertex3fv(&visual->vertex[face->v[0]].x); 
 
					glTexCoord2f(visual->texture[face->t[1]].u,visual->texture[face->t[1]].v);	 
					glVertex3fv(&visual->vertex[face->v[1]].x); 
 
					glTexCoord2f(visual->texture[face->t[2]].u,visual->texture[face->t[2]].v);	 
					glVertex3fv(&visual->vertex[face->v[2]].x); 
 
					glColor3f(visual->Ka[visual->index[loop].mat].r,visual->Ka[visual->index[loop].mat].g,visual->Ka[visual->index[loop].mat].b); 
                    glColor3f(visual->Kd[visual->index[loop].mat].r,visual->Kd[visual->index[loop].mat].g,visual->Kd[visual->index[loop].mat].b); 
                    glColor3f(visual->Ks[visual->index[loop].mat].r,visual->Ks[visual->index[loop].mat].g,visual->Ks[visual->index[loop].mat].b); 
                    glColor3f(visual->matColor[visual->index[loop].mat].r,visual->matColor[visual->index[loop].mat].g,visual->matColor[visual->index[loop].mat].b); 
 
				glEnd(); 
				glDisable(GL_TEXTURE_2D); 
			    } 
			} 
		} 
 
		if (m_Silhouette) 
		{ 
		    glDisable(GL_TEXTURE_2D); 
		    glDisable(GL_TEXTURE_1D); 
			glEnable(GL_BLEND); 
			glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 
 
			glColor3fv(&m_SilhouetteColor.r);	// Set Line Color 
			glLineWidth(m_SilhouetteWidth);		// Give it some beef 
			glDepthFunc(GL_LEQUAL);			// Draw shared edges 
			glPolygonMode(GL_BACK,GL_LINE);	// Draw Lines 
			glCullFace(GL_FRONT);			// Draw backfacing edges only 
 
			face = visual->index; 
			glBegin(GL_TRIANGLES); 
			for (loop = 0; loop  visual->faceCnt; loop++,face++) 
			{ 
					glVertex3fv(&visual->vertex[face->v[0]].x); 
					glVertex3fv(&visual->vertex[face->v[1]].x); 
					glVertex3fv(&visual->vertex[face->v[2]].x); 
 
			} 
			glEnd(); 
 
			// Set Everything Back to original settings 
			glDepthFunc(GL_LESS); 
			glColor3f(1.0f, 1.0f, 1.0f); 
			glCullFace(GL_BACK); 
		} 
 
	} 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	drawScene 
// Purpose:		Actually draw the OpenGL Scene 
// Arguments:	None 
/////////////////////////////////////////////////////////////////////////////// 
GLvoid COGLView::drawScene() 
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////// 
 
	if (m_Camera.rot.y  > 360.0f) m_Camera.rot.y  -= 360.0f; 
	if (m_Camera.rot.x   > 360.0f) m_Camera.rot.x   -= 360.0f; 
	if (m_Camera.rot.z > 360.0f) m_Camera.rot.z -= 360.0f; 
	 
	glDisable(GL_DEPTH_TEST);	// TURN OFF DEPTH TEST FOR CLEAR 
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
 
	glEnable(GL_DEPTH_TEST);	// ENABLE DEPTH TESTING 
 
	glPushMatrix(); 
 
	// Set camera's orientation and position 
	glTranslatef(m_Camera.trans.x, m_Camera.trans.y, m_Camera.trans.z); 
 
	glRotatef(m_Camera.rot.y, 0.0f, 1.0f, 0.0f); 
	glRotatef(m_Camera.rot.x, 1.0f, 0.0f, 0.0f); 
	glRotatef(m_Camera.rot.z, 0.0f, 0.0f, 1.0f);  
 
	// Draw any loaded model 
	drawModel(&m_Model); 
 
	glPopMatrix(); 
 
	//    glFinish(); 
 
	SwapBuffers(m_hDC); 
 
} 
//// drawScene ////////////////////////////////////////////////////// 
 
void COGLView::OnDestroy()  
{ 
	CWnd::OnDestroy(); 
	if (m_hRC) 
		wglDeleteContext(m_hRC); 
    if (m_hDC) 
		::ReleaseDC(m_hWnd,m_hDC); 
    m_hRC = 0; 
    m_hDC = 0; 
	 
	 
} 
 
void COGLView::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
 
	drawScene(); 
	// Do not call CWnd::OnPaint() for painting messages 
} 
 
void COGLView::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	// STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER 
	m_mousepos = point; 
	m_Dragging = TRUE; 
	m_Grab_Rot_X = 	m_Camera.rot.x; 
	m_Grab_Rot_Y = 	m_Camera.rot.y; 
	m_Grab_Rot_Z = 	m_Camera.rot.z; 
	m_Grab_Trans_X = 	m_Camera.trans.x; 
	m_Grab_Trans_Y = 	m_Camera.trans.y; 
	m_Grab_Trans_Z = 	m_Camera.trans.z; 
	CWnd::OnLButtonDown(nFlags, point); 
} 
 
void COGLView::OnRButtonDown(UINT nFlags, CPoint point)  
{ 
	// STORE OFF THE HIT POINT AND SETTINGS FOR THE MOVEMENT LATER 
	m_mousepos = point; 
	m_Dragging = TRUE; 
	m_Grab_Rot_X = 	m_Camera.rot.x; 
	m_Grab_Rot_Y = 	m_Camera.rot.y; 
	m_Grab_Rot_Z = 	m_Camera.rot.z; 
	m_Grab_Trans_X = 	m_Camera.trans.x; 
	m_Grab_Trans_Y = 	m_Camera.trans.y; 
	m_Grab_Trans_Z = 	m_Camera.trans.z; 
	CWnd::OnRButtonDown(nFlags, point); 
} 
 
 
void COGLView::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	m_Dragging = FALSE; 
	CWnd::OnLButtonUp(nFlags, point); 
} 
 
void COGLView::OnRButtonUp(UINT nFlags, CPoint point)  
{ 
	m_Dragging = FALSE; 
	CWnd::OnRButtonUp(nFlags, point); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	OnMouseMove 
// Purpose:		Handler for the mouse.  Handles movement when pressed 
// Arguments:	Flags for key masks and point 
/////////////////////////////////////////////////////////////////////////////// 
void COGLView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	if (!m_Dragging) return; 
 
//	UpdateStatusBar(0); 
	if ((nFlags & MK_LBUTTON) > 0) 
	{ 
		if ((nFlags & MK_CONTROL) > 0) 
		{ 
		}	 
		// ELSE "SHIFT" MOVE THE BONE IN XY 
		else if ((nFlags & MK_SHIFT) > 0) 
		{ 
			UpdateStatusBar(1); 
			if ((point.x - m_mousepos.x) != 0)	// Rotate Camera in Z 
			{ 
				m_Camera.rot.z = m_Grab_Rot_Z + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); 
				drawScene(); 
			} 
		} 
		else 
		{ 
			UpdateStatusBar(1); 
			if ((point.x - m_mousepos.x) != 0)	// Rotate Camera in Y 
			{ 
				m_Camera.rot.y = m_Grab_Rot_Y + ((float)ROTATE_SPEED * (point.x - m_mousepos.x)); 
				drawScene(); 
			} 
			if ((point.y - m_mousepos.y) != 0)	// Rotate Camera in X 
			{ 
				m_Camera.rot.x = m_Grab_Rot_X + ((float)ROTATE_SPEED * (point.y - m_mousepos.y)); 
				drawScene(); 
			} 
		} 
	} 
	else if ((nFlags & MK_RBUTTON) == MK_RBUTTON) 
	{ 
		if ((nFlags & MK_CONTROL) > 0) 
		{ 
		} 
		else if ((nFlags & MK_SHIFT) > 0) 
		{ 
			UpdateStatusBar(2); 
			if ((point.x - m_mousepos.x) != 0)	// Move Camera in X 
			{ 
				m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); 
				drawScene(); 
			} 
			if ((point.y - m_mousepos.y) != 0)	// Move Camera in Y 
			{ 
				m_Camera.trans.y = m_Grab_Trans_Y - (.1f * (point.y - m_mousepos.y)); 
				drawScene(); 
			} 
		} 
		// IF I AM HOLDING THE RM BUTTON Translate IN Z 
		else 
		{ 
			UpdateStatusBar(2); 
			if ((point.x - m_mousepos.x) != 0)	// Move Camera in X 
			{ 
				m_Camera.trans.x = m_Grab_Trans_X + (.1f * (point.x - m_mousepos.x)); 
				drawScene(); 
			} 
			if ((point.y - m_mousepos.y) != 0) 
			{ 
				m_Camera.trans.z = m_Grab_Trans_Z + (.1f * (point.y - m_mousepos.y)); 
				drawScene(); 
			} 
		} 
	} 
	 
	CWnd::OnMouseMove(nFlags, point); 
} 
//// OnMouseMove ////////////////////////////////////////////////////// 
 
void COGLView::OnMove(int x, int y)  
{ 
	CWnd::OnMove(x, y); 
	 
	resize( x,y ); 
	 
} 
 
// 0 = READY 
// 1 = ROTATE 
// 2 = TRANSLATE 
void COGLView::UpdateStatusBar(int mode)  
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
	char message[80]; 
/////////////////////////////////////////////////////////////////////////////// 
	if (mode == 1) 
	{ 
		sprintf(message,"Rotate (%.2f,%.2f,%.2f)",m_Camera.rot.x,m_Camera.rot.y,m_Camera.rot.z); 
	} 
	else if (mode == 2) 
	{ 
		sprintf(message,"Translate (%.2f,%.2f,%.2f)",m_Camera.trans.x,m_Camera.trans.y,m_Camera.trans.z); 
	} 
	else 
	{ 
		strcpy(message,"Ready"); 
	} 
	m_StatusBar->SetPaneText(0,message); 
} 
 
void COGLView::HandleKeyDown(UINT nChar)  
{ 
} 
 
void COGLView::HandleKeyUp(UINT nChar)  
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////// 
	switch (nChar) 
	{ 
	case VK_SPACE: 
		break; 
	case 'I': 
		break; 
	case 'W': 
	glPolygonMode(GL_FRONT,GL_LINE); 
		break; 
	case 'F': 
	glPolygonMode(GL_FRONT,GL_FILL); 
		break; 
	} 
 
	Invalidate(TRUE); 
 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	GetGLInfo 
// Purpose:		Get the OpenGL Vendor and Renderer 
/////////////////////////////////////////////////////////////////////////////// 
void COGLView::GetGLInfo()  
{ 
//// Local Variables //////////////////////////////////////////////////////////////// 
	char *who, *which, *ver, *ext, *message; 
	int len; 
///////////////////////////////////////////////////////////////////////////////////// 
	who = (char *)::glGetString( GL_VENDOR ); 
	which = (char *)::glGetString( GL_RENDERER ); 
	ver = (char *)::glGetString( GL_VERSION ); 
	ext = (char *)::glGetString( GL_EXTENSIONS ); 
 
	len = 200 + strlen(who) + strlen(which) + strlen(ver) + strlen(ext); 
 
	message = (char *)malloc(len); 
	sprintf(message,"Who:\t%s\nWhich:\t%s\nVersion:\t%s\nExtensions:\t%s", 
		who, which, ver, ext); 
 
	::MessageBox(NULL,message,"GL Info",MB_OK); 
 
	free(message); 
} 
//// GetGLInfo ///////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	LoadOBJModel 
// Purpose:		Load an OBJ Model into the system 
// Arguments:	Name of the file to open 
/////////////////////////////////////////////////////////////////////////////// 
BOOL COGLView::LoadOBJModel(CString name) 
{ 
/// Local Variables /////////////////////////////////////////////////////////// 
	char texname[255],*pos; 
	tTGAHeader_s header; 
	unsigned char *texture; 
 
/////////////////////////////////////////////////////////////////////////////// 
	if (m_Model.vertex != NULL)	// Free model data if exists 
	{ 
		free(m_Model.vertex); 
		m_Model.vertex = NULL; 
	} 
	LoadOBJ((LPCSTR)name,&m_Model); 
	m_Camera.rot.x = 0.0f; 
	m_Camera.rot.y = 0.0f; 
	m_Camera.rot.z = 0.0f; 
	m_Camera.b_trans.y = 0.0f; 
	m_Camera.b_trans.z = -50.0f; 
	m_Camera.trans.y = 0.0f; 
	m_Camera.trans.z = -50.0f; 
 
	if (strlen(m_Model.map) > 0) 
	{ 
		pos = m_Model.map + strlen(m_Model.map); 
		while (*pos != '/' && pos != m_Model.map) 
			pos--; 
 
		if (*pos == '/') pos++; 
 
		sprintf(texname,"%s",pos); 
 
		texture = LoadTGAFile( texname,	&header);  // 
 
		// GENERATE THE OPENGL TEXTURE ID 
		glGenTextures(1,&m_Model.glTex); 
 
		glBindTexture(GL_TEXTURE_2D, m_Model.glTex); 
 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
 
		/* 
		* Define the 2D texture image. 
		*/ 
 
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);	/* Force 4-byte alignment */ 
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 
		glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 
		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 
 
		if (header.d_pixel_size == 32) 
		{ 
			glTexImage2D(GL_TEXTURE_2D, 0, 4, header.d_width, header.d_height, 0, 
					 GL_RGBA , GL_UNSIGNED_BYTE, texture); 
 
		} 
		else 
		{ 
			glTexImage2D(GL_TEXTURE_2D, 0, 3, header.d_width, header.d_height, 0, 
					 GL_RGB , GL_UNSIGNED_BYTE, texture); 
 
		} 
		free(texture); 
	} 
	else 
		m_Model.glTex = 0; 
 
	// Load 2nd Texture if it is there 
	if (strlen(m_Model.map2) > 0) 
	{ 
		pos = m_Model.map2 + strlen(m_Model.map2); 
		while (*pos != '/' && pos != m_Model.map2) 
			pos--; 
 
		if (*pos == '/') pos++; 
 
		sprintf(texname,"%s",pos); 
 
		texture = LoadTGAFile( texname,	&header);  // 
 
		// GENERATE THE OPENGL TEXTURE ID 
		glGenTextures(1,&m_Model.glTex2); 
 
		glBindTexture(GL_TEXTURE_2D, m_Model.glTex2); 
 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
 
		/* 
		* Define the 2D texture image. 
		*/ 
 
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);	/* Force 4-byte alignment */ 
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 
		glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 
		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 
 
		if (header.d_pixel_size == 32) 
		{ 
			glTexImage2D(GL_TEXTURE_2D, 0, 4, header.d_width, header.d_height, 0, 
					 GL_RGBA , GL_UNSIGNED_BYTE, texture); 
 
		} 
		else 
		{ 
			glTexImage2D(GL_TEXTURE_2D, 0, 3, header.d_width, header.d_height, 0, 
					 GL_RGB , GL_UNSIGNED_BYTE, texture); 
 
		} 
 
		free(texture); 
	} 
	else 
		m_Model.glTex = 0; 
	return TRUE; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	LoadShadeTexture 
// Purpose:		Load a shaded environment texture 
// Arguments:	Name of the file to open 
/////////////////////////////////////////////////////////////////////////////// 
void COGLView::LoadShadeTexture(const char *texfile) 
{ 
//// Local Variables //////////////////////////////////////////////////////////////// 
	int loop; 
	FILE *fp; 
	char line[255]; 
	float value1, value2; 
///////////////////////////////////////////////////////////////////////////////////// 
 
	// Make a Default one One shade with highlight 
	for (loop = 0; loop  32; loop++) 
	{ 
 
		if (loop  8) 
		{ 
			MAKEVECTOR4(m_ShadeSrc[loop], 0.4f, 0.4f, 0.4f, 0.0f) 
		} 
		else if (loop  28) 
		{ 
			MAKEVECTOR4(m_ShadeSrc[loop], 0.9f, 0.9f, 0.9f, 1.0f) 
		} 
		else 
		{ 
			MAKEVECTOR4(m_ShadeSrc[loop], 1.0f, 1.0f, 1.0f, 1.0f) 
		} 
	} 
 
	// Totally simple file format to load a 1D shade table 
	// just a list of floats in a text file 
	fp = fopen(texfile,"r"); 
	if (fp) 
	{ 
		for (loop = 0; loop  32; loop++) 
		{ 
			if (feof(fp)) 
				break; 
			// Get a line from the file 
			fgets(line,255,fp); 
			// Convert it to a shade value 
			sscanf(line,"%f %f",&value1,&value2); 
			m_ShadeSrc[loop].x = m_ShadeSrc[loop].y = m_ShadeSrc[loop].z = value1; 
			m_ShadeSrc[loop].w = value2; 
		} 
		fclose(fp); 
	} 
	glBindTexture(GL_TEXTURE_1D, m_ShadeTexture); 
 
	// Do not allow bilinear filtering - not for cartoon rendering 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	 
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
 
	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 32, 0, 
			 GL_RGBA , GL_FLOAT, (float *)m_ShadeSrc); //visual->texData); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Function:	CartoonSettings 
// Purpose:		Adjust Line Settings for Cartoon Render 
// Arguments:	Name of the file to open 
/////////////////////////////////////////////////////////////////////////////// 
void COGLView::CartoonSettings() 
{ 
//// Local Variables //////////////////////////////////////////////////////////////// 
	CToonSet	dialog; 
///////////////////////////////////////////////////////////////////////////////////// 
	dialog.m_Sil_Red = m_SilhouetteColor.r; 
	dialog.m_Sil_Green = m_SilhouetteColor.g; 
	dialog.m_Sil_Blue = m_SilhouetteColor.b; 
	dialog.m_LineWidth = m_SilhouetteWidth; 
	dialog.m_Light_X = m_ShadeLight.x; 
	dialog.m_Light_Y = m_ShadeLight.y; 
	dialog.m_Light_Z = m_ShadeLight.z; 
	if (dialog.DoModal()) 
	{ 
		m_SilhouetteColor.r = dialog.m_Sil_Red; 
		m_SilhouetteColor.g = dialog.m_Sil_Green; 
		m_SilhouetteColor.b = dialog.m_Sil_Blue; 
		m_SilhouetteWidth = dialog.m_LineWidth; 
		m_ShadeLight.x = dialog.m_Light_X; 
		m_ShadeLight.y = dialog.m_Light_Y; 
		m_ShadeLight.z = dialog.m_Light_Z; 
		NormalizeVector(&m_ShadeLight);	// Normalize it since I know I didn't 
	} 
	Invalidate(TRUE); 
}