www.pudn.com > OpenGLLoad3DS.zip > Stepinglview.cpp


// StepinGlView.cpp : implementation of the CStepinGlView class 
// 
 
#include "stdafx.h" 
#include "StepinGl.h" 
 
#include "StepinGlDoc.h" 
#include "StepinGlView.h" 
 
#include "main.h"										// This includes our header file 
#include "3ds.h"										// Include the 3DS header file. 
 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define FILE_NAME  "moon.3ds"							// This is the 3D file we will load.	text.3ds 
 
UINT g_Texture[MAX_TEXTURES] = {0};						// This holds the texture info, referenced by an ID 
 
CLoad3DS g_Load3ds;										// This is 3DS class.  This should go in a good model class. 
t3DModel g_3DModel;										// This holds the 3D Model info that we load in 
 
int   g_ViewMode	  = GL_TRIANGLES;					// We want the default drawing mode to be normal 
bool  g_bLighting     = true;							// Turn lighting on initially 
float g_RotateX		  = 0.0f;							// This is the current value at which the model is rotated 
float g_RotationSpeed = 0.8f;							// This is the speed that our model rotates.  (-speed rotates left) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CStepinGlView 
 
IMPLEMENT_DYNCREATE(CStepinGlView, CView) 
 
BEGIN_MESSAGE_MAP(CStepinGlView, CView) 
	//{{AFX_MSG_MAP(CStepinGlView) 
	ON_WM_CREATE() 
	ON_WM_SIZE() 
	ON_WM_DESTROY() 
	ON_WM_TIMER() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CStepinGlView construction/destruction 
 
CStepinGlView::CStepinGlView() 
{ 
	// TODO: add construction code here 
	m_pDC=NULL; 
 
	m_lightAmb[0]=0.1f;		m_lightAmb[1]=0.1f; 
	m_lightAmb[2]=0.1f;		m_lightAmb[3]=1.0f; 
 
	m_lightDif[0]=0.0f;		m_lightDif[1]=1.0f; 
	m_lightDif[2]=0.0f;		m_lightDif[3]=1.0f; 
 
	m_lightSpe[0]=0.0f;		m_lightSpe[1]=1.0f; 
	m_lightSpe[2]=0.0f;		m_lightSpe[3]=1.0f; 
 
	m_lightPos[0]=-10.0f;		m_lightPos[1]=20.0f; 
	m_lightPos[2]=20.0f;		m_lightPos[3]=1.0f; 
 
	m_posx=0.0f; 
	m_posy=0.0f; 
	flagx=1; 
	flagy=1; 
 
	flagfy=1; 
	flagfz=1; 
	m_fAngleY=0.0f; 
    m_fAngleZ=0.0f; 
} 
 
CStepinGlView::~CStepinGlView() 
{ 
} 
 
BOOL CStepinGlView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
	cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS; 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CStepinGlView drawing 
 
void CStepinGlView::OnDraw(CDC* pDC) 
{ 
	CStepinGlDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	// TODO: add draw code for native data here 
	DrawScene(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CStepinGlView diagnostics 
 
#ifdef _DEBUG 
void CStepinGlView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CStepinGlView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CStepinGlDoc* CStepinGlView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CStepinGlDoc))); 
	return (CStepinGlDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CStepinGlView message handlers 
 
void CStepinGlView::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); 
 
    GetClientRect(&m_oldRect); 
 
    glClearDepth(1.0f); 
    glEnable(GL_DEPTH_TEST); 
//	glMatrixMode(GL_MODELVIEW); 
//	glLoadIdentity(); 
 
	g_Load3ds.Import3DS(&g_3DModel, FILE_NAME);			// Load our .3DS file into our model structure 
 
	// Depending on how many textures we found, load each one (Assuming .BMP) 
	// If you want to load other files than bitmaps, you will need to adjust CreateTexture(). 
	// Below, we go through all of the materials and check if they have a texture map to load. 
	// Otherwise, the material just holds the color information and we don't need to load a texture. 
 
	// Go through all the materials 
	for(int i = 0; i < g_3DModel.numOfMaterials; i++) 
	{ 
		// Check to see if there is a file name to load in this material 
		if(strlen(g_3DModel.pMaterials[i].strFile) > 0) 
		{ 
			// Use the name of the texture file to load the bitmap, with a texture ID (i). 
			// We pass in our global texture array, the name of the texture, and an ID to reference it.	 
			CreateTexture(g_Texture, g_3DModel.pMaterials[i].strFile, i);			 
		} 
 
		// Set the texture ID for this material 
		g_3DModel.pMaterials[i].texureId = i; 
	} 
 
	glLightfv(GL_LIGHT0,GL_AMBIENT,m_lightAmb); 
	glLightfv(GL_LIGHT0,GL_DIFFUSE,m_lightDif); 
	glLightfv(GL_LIGHT0,GL_SPECULAR,m_lightSpe); 
	glLightfv(GL_LIGHT0,GL_POSITION,m_lightPos); 
 
	glEnable(GL_LIGHT0);								// Turn on a light with defaults set 
	glEnable(GL_LIGHTING);								// Turn on lighting 
	glEnable(GL_COLOR_MATERIAL);						// Allow color 
 
 
} 
 
BOOL CStepinGlView::bSetupPixelFormat() 
{ 
static PIXELFORMATDESCRIPTOR pfd =  
	{ 
        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd 
        1,                              // version number 
        PFD_DRAW_TO_WINDOW |            // support window 
          PFD_SUPPORT_OPENGL| 
		  PFD_DOUBLEBUFFER,			// support OpenGL 
        PFD_TYPE_RGBA,                  // RGBA type 
        24,                             // 24-bit color depth 
        0, 0, 0, 0, 0, 0,               // color bits ignored 
        0,                              // no alpha buffer 
        0,                              // shift bit ignored 
        0,                              // no accumulation buffer 
        0, 0, 0, 0,                     // accum bits ignored 
        32,                             // 32-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 ) 
    { 
        MessageBox("ChoosePixelFormat failed"); 
        return FALSE; 
    } 
 
    if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE) 
    { 
        MessageBox("SetPixelFormat failed"); 
        return FALSE; 
    } 
 
    return TRUE; 
 
} 
 
int CStepinGlView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// TODO: Add your specialized creation code here 
	Init(); 
 
		SetTimer(1, 45, NULL); 
	 
	return 0; 
} 
 
void CStepinGlView::DrawScene() 
{ 
	 
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
 
	glMatrixMode(GL_MODELVIEW); 
	glLoadIdentity(); 
 
    glTranslatef(m_posx,m_posy,-5.0f); 
 
        glRotatef(m_fAngleY, 0.0f, 1.0f, 0.0f); 
        glRotatef(m_fAngleZ, 0.0f, 0.0f, 1.0f); 
	 
for(int i = 0; i < g_3DModel.numOfObjects; i++) 
	{ 
		// Make sure we have valid objects just in case. (size() is in the vector class) 
		if(g_3DModel.pObject.size() <= 0) break; 
 
		// Get the current object that we are displaying 
		t3DObject *pObject = &g_3DModel.pObject[i]; 
			 
		// Check to see if this object has a texture map, if so bind the texture to it. 
		if(pObject->bHasTexture) { 
 
			// Turn on texture mapping and turn off color 
			glEnable(GL_TEXTURE_2D); 
 
			// Reset the color to normal again 
			glColor3ub(255, 255, 255); 
 
			// Bind the texture map to the object by it's materialID 
			glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialID]); 
		} else { 
 
			// Turn off texture mapping and turn on color 
			glDisable(GL_TEXTURE_2D); 
 
			// Reset the color to normal again 
			glColor3ub(255, 255, 255); 
		} 
 
		// This determines if we are in wireframe or normal mode 
		glBegin(g_ViewMode);					// Begin drawing with our selected mode (triangles or lines) 
 
			// Go through all of the faces (polygons) of the object and draw them 
			for(int j = 0; j < pObject->numOfFaces; j++) 
			{ 
				// Go through each corner of the triangle and draw it. 
				for(int whichVertex = 0; whichVertex < 3; whichVertex++) 
				{ 
					// Get the index for each point of the face 
					int index = pObject->pFaces[j].vertIndex[whichVertex]; 
			 
					// Give OpenGL the normal for this vertex. 
					glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z); 
				 
					// If the object has a texture associated with it, give it a texture coordinate. 
					if(pObject->bHasTexture) { 
 
						// Make sure there was a UVW map applied to the object or else it won't have tex coords. 
						if(pObject->pTexVerts) { 
							glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y); 
						} 
					} else { 
 
						// Make sure there is a valid material/color assigned to this object. 
						// You should always at least assign a material color to an object,  
						// but just in case we want to check the size of the material list. 
						// if the size is at least one, and the material ID != -1, 
						// then we have a valid material. 
						if(g_3DModel.pMaterials.size() && pObject->materialID >= 0)  
						{ 
							// Get and set the color that the object is, since it must not have a texture 
							BYTE *pColor = g_3DModel.pMaterials[pObject->materialID].color; 
 
							// Assign the current color to this model 
							glColor3ub(pColor[0], pColor[1], pColor[2]); 
						} 
					} 
 
					// Pass in the current vertex of the object (Corner of current face) 
					glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z); 
				} 
			} 
 
		glEnd();								// End the drawing 
	} 
 
	glFinish(); 
	SwapBuffers(wglGetCurrentDC()); 
 
} 
 
void CStepinGlView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	 
	// TODO: Add your message handler code here 
	  if(cy > 0) 
    {  
		if((m_oldRect.right > cx) || (m_oldRect.bottom > cy)) 
            RedrawWindow(); 
 
        m_oldRect.right = cx; 
        m_oldRect.bottom = cy; 
 
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); 
		glFrustum(-2.0,2.0,-4.0,4.0,1.0,8.0);	//-1.0,1.0,-1.0,1.0,3.0,7.0 
		glViewport(0, 0, cx, cy); 
    
    } 
 
	 
} 
 
void CStepinGlView::OnDestroy()  
{ 
		 
	// TODO: Add your message handler code here 
 
		KillTimer(1); 
 
	HGLRC	hrc; 
 
	hrc = ::wglGetCurrentContext(); 
 
    ::wglMakeCurrent(NULL,  NULL); 
	 
    if (hrc) 
        ::wglDeleteContext(hrc); 
 
    if (m_pDC) 
        delete m_pDC; 
 
 
	CView::OnDestroy(); 
 
} 
 
void CStepinGlView::CreateTexture(UINT textureArray[], LPSTR strFileName, int textureID) 
{ 
	AUX_RGBImageRec *pBitmap = NULL; 
	 
	if(!strFileName)									// Return from the function if no file name was passed in 
		return; 
 
	pBitmap = auxDIBImageLoad(strFileName);				// Load the bitmap and store the data 
	 
	if(pBitmap == NULL)									// If we can't load the file, quit! 
		exit(0); 
 
	// Generate a texture with the associative texture ID stored in the array 
	glGenTextures(1, &textureArray[textureID]); 
 
	// This sets the alignment requirements for the start of each pixel row in memory. 
	glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 
 
	// Bind the texture to the texture arrays index and init the texture 
	glBindTexture(GL_TEXTURE_2D, textureArray[textureID]); 
 
	// Build Mipmaps (builds different versions of the picture for distances - looks better) 
	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap->sizeX, pBitmap->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pBitmap->data); 
 
	// Lastly, we need to tell OpenGL the quality of our texture map.  GL_LINEAR is the smoothest. 
	// GL_NEAREST is faster than GL_LINEAR, but looks blochy and pixelated.  Good for slower computers though. 
	// Read more about the MIN and MAG filters at the bottom of main.cpp 
		 
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	 
 
	// Now we need to free the bitmap data that we loaded since openGL stored it as a texture 
 
	if (pBitmap)										// If we loaded the bitmap 
	{ 
		if (pBitmap->data)								// If there is texture data 
		{ 
			free(pBitmap->data);						// Free the texture data, we don't need it anymore 
		} 
 
		free(pBitmap);									// Free the bitmap structure 
	} 
} 
 
void CStepinGlView::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
 
	switch(flagx) 
	{ 
	case 1: 
	    if(m_posx<0.9f) 
		    m_posx+=0.05f; 
	    if(m_posx>=0.9f) 
		    flagx=0; 
	    break; 
    case 0: 
		if(m_posx>-0.9f) 
			m_posx-=0.05f; 
		if(m_posx<=-0.9f) 
			flagx=1; 
		break; 
	 
	} 
 
    switch(flagy) 
	{ 
	case 1: 
	    if(m_posy<1.2f) 
		    m_posy+=0.025f; 
	    if(m_posy>=1.2f) 
		    flagy=0; 
	    break; 
    case 0: 
		if(m_posy>-1.2f) 
			m_posy-=0.025f; 
		if(m_posy<=-1.2f) 
			flagy=1; 
		break; 
	 
	} 
	 
	switch(flagfy) 
	{ 
	case 1: 
	    if(m_fAngleY<30.0f) 
		    m_fAngleY+=2.0f; 
	    if(m_fAngleY>=30.0f) 
		    flagfy=0; 
	    break; 
    case 0: 
		if(m_fAngleY>-30.0f) 
			m_fAngleY-=2.0f; 
		if(m_fAngleY<=-30.0f) 
			flagfy=1; 
		break; 
	 
	} 
 
    switch(flagfz) 
	{ 
	case 1: 
	    if(m_fAngleZ<30.0f) 
		    m_fAngleZ+=2.0f; 
	    if(m_fAngleZ>=30.0f) 
		    flagfz=0; 
	    break; 
    case 0: 
		if(m_fAngleZ>-30.0f) 
			m_fAngleZ-=2.0f; 
		if(m_fAngleZ<=-30.0f) 
			flagfz=1; 
		break; 
	 
	} 
 
	Invalidate(FALSE); 
 
	 
	CView::OnTimer(nIDEvent); 
}