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);
}