非常不好意思,上面贴错了,这个才是我的代码// WaveView.cpp : implementation of the CWaveView class
//#include "stdafx.h"
#include "Wave.h"#include "WaveDoc.h"
#include "WaveView.h"
#include "outputwnd.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif#define PERSPECTIVE
//#define FRUSTRUM/////////////////////////////////////////////////////////////////////////////
// CWaveViewIMPLEMENT_DYNCREATE(CWaveView, CView)BEGIN_MESSAGE_MAP(CWaveView, CView)
//{{AFX_MSG_MAP(CWaveView)
ON_WM_SIZE()
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_COMMAND(ID_TIMER, OnTimerSet)
ON_WM_ERASEBKGND()
ON_UPDATE_COMMAND_UI(ID_TIMER, OnUpdateTimer)
ON_COMMAND(ID_MODE_POLYGON, OnModePolygon)
ON_UPDATE_COMMAND_UI(ID_MODE_POLYGON, OnUpdateModePolygon)
ON_COMMAND(ID_MODE_SHADING, OnModeShading)
ON_UPDATE_COMMAND_UI(ID_MODE_SHADING, OnUpdateModeShading)
ON_COMMAND(ID_MODE_POINT, OnModePoint)
ON_UPDATE_COMMAND_UI(ID_MODE_POINT, OnUpdateModePoint)
ON_COMMAND(ID_MODE_TRIANGLE, OnModeTriangle)
ON_UPDATE_COMMAND_UI(ID_MODE_TRIANGLE, OnUpdateModeTriangle)
ON_COMMAND(ID_TIME_O, OnTimeO)
ON_WM_DESTROY()
ON_COMMAND(ID_TEST, OnTest)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CWaveView construction/destructionCWaveView::CWaveView()
{
// TODO: add construction code here
m_lightAmb[0] = .3f; m_lightAmb[1] = .3f;
m_lightAmb[2] = .3f; m_lightAmb[3] = 0.1f; m_lightDif[0] = 0.0f; m_lightDif[1] = 1.0f;
m_lightDif[2] = 0.0f; m_lightDif[3] = .5f; m_lightSpe[0] = 0.0f; m_lightSpe[1] = 0.0f;
m_lightSpe[2] = 0.0f; m_lightSpe[3] = 1.0f; m_lightPos[0] = 1.0f; m_lightPos[1] = 1.0f;
m_lightPos[2] = 1.0f; m_lightPos[3] = 0.f; m_camera.vCenter.x = 0;
m_camera.vCenter.y = 0;
m_camera.vCenter.z = -3.5; m_camera.vEye.x = 0;
m_camera.vEye.y = 0;
m_camera.vEye.z = 5; m_camera.vUp.x = 0;
m_camera.vUp.y = 1;
m_camera.vUp.z = 0; m_dFrustumLeft = -1;
m_dFrustumRight = 1;
m_dFrustumTop = 1;
m_dFrustumBottom = -1;
m_dFrustumNear = 5;
m_dFrustumFar = 50;
m_theta = 0;
m_nDown = BUTTON_NONE;
m_bRotate = true;
m_bTimerOn = false; m_phi = 0;
m_bTimerOn = 0;
m_nMode = MODE_SHADING; h = -0.2;
m_nCycle = 3;
m_dStep = 0.1; m_nWidth = int(RANGE*2/STEP);
m_buffer = new double[m_nWidth*m_nWidth]; m_environment.fVelocity = 0.2; m_zDist = -14.5;
}CWaveView::~CWaveView()
{
FILE *pFile = fopen("wave.cfg", "wb");
WAVE_FHEADER header={"", WAVE_HVER_1};
strncpy(header., "WAVE", 4);
if(pFile)
{
fwrite(&header, 1, sizeof(header), pFile);
fwrite(&m_camera, 1, sizeof(m_camera), pFile);
fclose(pFile);
}
delete m_buffer;
}BOOL CWaveView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
//  the CREATESTRUCT cs return CView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CWaveView drawingvoid CWaveView::OnDraw(CDC* pDC)
{
CWaveDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
DrawScene();
}/////////////////////////////////////////////////////////////////////////////
// CWaveView printingBOOL CWaveView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}void CWaveView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}void CWaveView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}/////////////////////////////////////////////////////////////////////////////
// CWaveView diagnostics#ifdef _DEBUG
void CWaveView::AssertValid() const
{
CView::AssertValid();
}void CWaveView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}CWaveDoc* CWaveView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWaveDoc)));
return (CWaveDoc*)m_pDocument;
}
#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CWaveView message handlersvoid CWaveView::DrawScene()
{
float m_BackDiffuse[] = {1.0f, 0.8f, 0.0f, 1.0f};
float specularProperties[4];
double eqn[] = {0,0,-1, -1.35};
GLfloat mat_emission[] = {0.0f, 0.2f, 1.0f, 0.0f}; specularProperties[0] = 0.2f;
specularProperties[1] = 0.2f;
specularProperties[2] = 0.2f;
specularProperties[3] = 1.0f; glClearColor(.3f, .4f, .6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.2f, 0.5f, 0.8f); glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// glLoadIdentity();// glPushMatrix();
glTranslatef(0.f, 0.f, (float)m_zDist); // init name statck
glInitNames();
glPushName(0); CreateLight();
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_CCW);
glCullFace(GL_BACK);// glRotated(m_theta, 0,1,0); glLoadName(2);
// DrawCoordinate();
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glClearColor(0.8f, 0.8f, 0.8f, 1.0f);
// glColor3f(0.0f, 1.0f, 0.0f);
// glClipPlane(GL_CLIP_PLANE0, eqn);
// glMaterialfv(GL_BACK, GL_DIFFUSE, m_BackDiffuse);
// glMaterialf(GL_FRONT, GL_SHININESS, 1.0);
// glMaterialfv(GL_FRONT, GL_SPECULAR, specularProperties);
// glPushMatrix();
// glFrontFace(GL_CW);
// auxSolidTeapot(0.5);// glLoadName(2);
DrawSurface(); glPopMatrix(); glFinish();
SwapBuffers(wglGetCurrentDC());}void CWaveView::DrawCoordinate()
{
GLUquadricObj* quadObj;
// listCoorAxes=glGenLists(1);
double dLen; dLen = 1.0; glNewList(100,GL_COMPILE);
  glLineWidth(1.0f);
glColor3f(1.0,1.0,0.0); glBegin(GL_LINES);
glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,0.0,dLen); glVertex3d(0.0,0.0,0.0);
glVertex3d(dLen,0.0,0.0);  glVertex3d(0.0,0.0,0.0);
glVertex3d(0.0,dLen,0.0);
glEnd();
    //圆锥
glPushMatrix();
glColor3f(0.0,0.0,1.0);
glTranslatef(0.0f,0.0f,(float)dLen);
quadObj=gluNewQuadric();
gluQuadricDrawStyle(quadObj,GLU_FILL);
gluQuadricNormals(quadObj,GLU_FLAT);//SMOOTH);
gluCylinder(quadObj,0.02,0.0,0.05,16,16);
gluDeleteQuadric(quadObj);
glPopMatrix();
glPushMatrix();
glColor3f(0.0f,1.0f,0.0f);
glTranslatef(0.0f,(float)dLen,0.0f);
glRotatef(-90.0,1.0,0.0,0.0);
quadObj=gluNewQuadric();
gluQuadricDrawStyle(quadObj,GLU_FILL);
gluQuadricNormals(quadObj,GLU_FLAT);//SMOOTH);
gluCylinder(quadObj,0.02,0.0,0.05,16,16);
gluDeleteQuadric(quadObj);
glPopMatrix();
glPushMatrix();
glColor3f(1.0,0.0,0.0);
glTranslatef((float)dLen,0.0f,0.0f);
glRotatef(90.0,0.0,1.0,0.0);
quadObj=gluNewQuadric();
gluQuadricDrawStyle(quadObj,GLU_FILL);
gluQuadricNormals(quadObj,GLU_FLAT);//SMOOTH);
gluCylinder(quadObj,0.02,0.0,0.05,16,16);
gluDeleteQuadric(quadObj);
glPopMatrix();

glEndList(); glCallList(100);
}void CWaveView::OnSize(UINT nType, int cx, int cy) 
{
CView::OnSize(nType, cx, cy); if(cy>0)
{
if((m_oldRect.right>cx) || (m_oldRect.bottom>cy))
RedrawWindow();
m_oldRect.right = cx;
m_oldRect.bottom = cy;#ifdef FRUSTRUM
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(m_dFrustumLeft, m_dFrustumRight, m_dFrustumBottom,m_dFrustumTop, 
m_dFrustumNear, m_dFrustumFar);
gluLookAt(m_camera.vEye.x, m_camera.vEye.y, m_camera.vEye.z,
m_camera.vCenter.x, m_camera.vCenter.y, m_camera.vCenter.z,
m_camera.vUp.x, m_camera.vUp.y, m_camera.vUp.z);
cx = max(cx, cy);
m_cx = cx;
glViewport(0,0, cx, cx);
#endif#ifdef PERSPECTIVE
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, 1, 1.0, 425.0);
// gluLookAt(m_camera.vEye.x, m_camera.vEye.y, m_camera.vEye.z,
// m_camera.vCenter.x, m_camera.vCenter.y, m_camera.vCenter.z,
// m_camera.vUp.x, m_camera.vUp.y, m_camera.vUp.z);
cx = max(cx, cy);
m_cx = cx;
glViewport(0,0, cx, cx);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();#endif
}}void CWaveView::Init()
{
PIXELFORMATDESCRIPTOR pfd; int n;
HGLRC hrc; m_pDC = new CClientDC(this); ASSERT(m_pDC!=NULL); if(!SetupPixelFormat())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();
}bool CWaveView::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | 
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
}; 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 CWaveView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1; FILE *pFile = fopen("wave.cfg", "rb");
WAVE_FHEADER header;
if(pFile)
{
if(fread(&header, 1, sizeof(header), pFile)==sizeof(header)
&& !strncmp(header., "WAVE", 4)
&& header.nVer==WAVE_HVER_1)
{
CAMERA camera;
if(fread(&camera, 1, sizeof(camera), pFile)==sizeof(camera))
m_camera = camera;
}
fclose(pFile);
}
Init(); return 0;
}void CWaveView::CreateLight()
{
GLfloat fGloablAmbient[] = {0.9f, 1.f, 1.f, 1.0f}; 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); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fGloablAmbient); glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);}void CWaveView::OnLButtonDown(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
m_nDown = BUTTON_LEFT;
m_pointDown = point;
m_pointLast = point;
m_thetaOld = m_theta;
m_cameraOld = m_camera;
m_zDistOld = m_zDist;
SetCapture();

CView::OnLButtonDown(nFlags, point);
}void CWaveView::OnMButtonDown(UINT nFlags, CPoint point) 
{
m_nDown = BUTTON_MIDDLE;
m_pointLast = point;
SetCapture();
CView::OnMButtonDown(nFlags, point);
}void CWaveView::OnMButtonUp(UINT nFlags, CPoint point) 
{
m_nDown = BUTTON_NONE;
ReleaseCapture();
CView::OnMButtonUp(nFlags, point);
}void CWaveView::OnLButtonUp(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
m_nDown = BUTTON_NONE;
ReleaseCapture();

CView::OnLButtonUp(nFlags, point);
}void CWaveView::OnMouseMove(UINT nFlags, CPoint point) 
{
// TODO: Add your message handler code here and/or call default
switch(m_nDown)
{
case BUTTON_LEFT:
if(nFlags & MK_CONTROL)
{
// m_zDist = m_zDistOld + 0.02*(point.y - m_pointDown.y);
// RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
ScaleView(nFlags, point);
}
else
RotateView(nFlags, point);
break; case BUTTON_MIDDLE:
PanView(nFlags, point);
break;
} if(nFlags & MK_SHIFT)
{
ProcessSel(point);
} CView::OnMouseMove(nFlags, point);
}void CWaveView::DrawSurface()
{
int i, j;
double x, y, z, d, T, v;
PNT2D pnt[5], pntPos; pnt[0].x = 0;
pnt[0].y = 0; pnt[1].x = 0;
pnt[1].y = 4; pnt[2].x = 0;
pnt[2].y = -4; pnt[3].x = 4;
pnt[3].y = 0; pnt[4].x = -4;
pnt[4].y = 0; v = m_environment.fVelocity;
T = 10;
for(i=0; i<m_nWidth; i++)
{
x = -RANGE + STEP*i;
for(j=0; j<m_nWidth; j++)
{
y = -RANGE + STEP*j;
d = sqrt(x*x + y*y);
pntPos.x = x;
pntPos.y = y;
z = CNAlg::Wave(&pnt[0], &pntPos, m_phi, v, T) +
CNAlg::Wave(&pnt[1], &pntPos, m_phi, v, T) +
CNAlg::Wave(&pnt[2], &pntPos, m_phi, v, T) +
CNAlg::Wave(&pnt[3], &pntPos, m_phi, v, T) +
CNAlg::Wave(&pnt[4], &pntPos, m_phi, v, T); m_buffer[i*m_nWidth + j] = z; }
} if(m_nMode==MODE_POLYGON)
{
for(i=0; i<m_nWidth; i++)
{
x = -RANGE + STEP*i;
glBegin(GL_LINE_STRIP);
for(j=0; j<m_nWidth; j++)
{
y = -RANGE + STEP*j;
glVertex3d(x, y, m_buffer[i*m_nWidth + j]);
}
glEnd();
}
}
else if(m_nMode==MODE_POINT)
{
for(i=0; i<m_nWidth; i++)
{
x = -RANGE + STEP*i;
glBegin(GL_POINTS);
for(j=0; j<m_nWidth; j++)
{
y = -RANGE + STEP*j;
glVertex3d(x, y, m_buffer[i*m_nWidth + j]);
}
glEnd();
}
}
else if(m_nMode==MODE_SHADING)
{
PNT3D v1, v2, v3, vNormal;

for(i=1; i<m_nWidth; i++)
{
x = -RANGE + STEP*i;
v1.x = x-STEP;
v1.y = -RANGE;
v1.z = m_buffer[(i-1)*m_nWidth];
v2.x = x;
v2.y = -RANGE;
v2.z = m_buffer[i*m_nWidth];
vNormal.x = 0;
vNormal.y = 0;
vNormal.z = 1;
glBegin(GL_TRIANGLE_STRIP);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v1.x, v1.y, v1.z);
glVertex3d(v2.x, v2.y, v2.z);
for(j=1; j<m_nWidth; j++)
{
y = -RANGE + STEP*j;
v3.x = x - STEP;
v3.y = y;
{
v3.z = m_buffer[(i-1)*m_nWidth + j];
}
vNormal = (v1-v2)%(v2-v3);
Normalize(&vNormal);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v3.x, v3.y, v3.z);

v1 = v2;
v2 = v3;
v3.z = m_buffer[i*m_nWidth + j];
v3.x = x;

vNormal = (v3-v2)%(v2-v1);
Normalize(&vNormal);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v3.x, v3.y, v3.z);

v1 = v2;
v2 = v3;
}
glEnd();
}
}
else if(m_nMode==MODE_TRIANGLE)
{
PNT3D v1, v2, v3, vNormal;

for(i=1; i<m_nWidth; i++)
{
x = -RANGE + STEP*i;
v1.x = x-STEP;
v1.y = -RANGE;
v1.z = m_buffer[(i-1)*m_nWidth];
v2.x = x;
v2.y = -RANGE;
v2.z = m_buffer[i*m_nWidth];
vNormal.x = 0;
vNormal.y = 0;
vNormal.z = 1;
glBegin(GL_LINE_STRIP);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v1.x, v1.y, v1.z);
glVertex3d(v2.x, v2.y, v2.z);
for(j=1; j<m_nWidth; j++)
{
y = -RANGE + STEP*j;
v3.x = x - STEP;
v3.y = y;
{
v3.z = m_buffer[(i-1)*m_nWidth + j];
}
vNormal = (v1-v2)%(v2-v3);
Normalize(&vNormal);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v3.x, v3.y, v3.z);

v1 = v2;
v2 = v3;
v3.z = m_buffer[i*m_nWidth + j];
v3.x = x;

vNormal = (v3-v2)%(v2-v1);
Normalize(&vNormal);
glNormal3d(vNormal.x, vNormal.y, vNormal.z);
glVertex3d(v3.x, v3.y, v3.z);

v1 = v2;
v2 = v3;
}
glEnd();
}
}
}void CWaveView::OnTimer(UINT nIDEvent) 
{
m_phi += 0.5;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
CView::OnTimer(nIDEvent);
}void CWaveView::OnTimerSet() 
{
if(m_bTimerOn)
{
KillTimer(10);
m_bTimerOn = 0;
}
else
{
SetTimer(10, 100, 0);
m_bTimerOn = 1;
}
}BOOL CWaveView::OnEraseBkgnd(CDC* pDC) 
{
return 1;
return CView::OnEraseBkgnd(pDC);
}void CWaveView::OnUpdateTimer(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_bTimerOn);
}void CWaveView::OnInitialUpdate() 
{
CView::OnInitialUpdate();
CWaveDoc* pDoc = GetDocument();
pDoc->InitViews(this);
}void CWaveView::OnModePolygon() 
{
m_nMode = MODE_POLYGON;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::OnUpdateModePolygon(CCmdUI* pCmdUI) 
{
pCmdUI->SetCheck(m_nMode==MODE_POLYGON);
}void CWaveView::OnModeShading() 
{
m_nMode = MODE_SHADING;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::OnUpdateModeShading(CCmdUI* pCmdUI) 
{
pCmdUI->SetCheck(m_nMode==MODE_SHADING);
}void CWaveView::OnModePoint() 
{
m_nMode = MODE_POINT;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::OnUpdateModePoint(CCmdUI* pCmdUI) 
{
pCmdUI->SetCheck(m_nMode==MODE_POINT);
}void CWaveView::OnModeTriangle() 
{
m_nMode = MODE_TRIANGLE;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::OnUpdateModeTriangle(CCmdUI* pCmdUI) 
{
pCmdUI->SetCheck(m_nMode==MODE_TRIANGLE);
}void CWaveView::OnTimeO() 
{
m_phi = 0;
RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::UpdateEnvironment(ENVIRONMENT *pEn)
{
m_environment = *pEn;
}void CWaveView::RotateView(UINT nFlags, CPoint point)
{
double theta;
PNT3D PxOld, axis, x1, y1, p; m_camera = m_cameraOld;
PxOld = (m_cameraOld.vCenter-m_cameraOld.vEye)%m_cameraOld.vUp;
PxOld = PxOld/Module(PxOld);
y1 = (point.y-m_pointDown.y)*m_cameraOld.vUp;
x1 = -(point.x-m_pointDown.x)*PxOld;
p = x1+y1;
theta = sqrt(p.y*p.y + p.x*p.x)/100;
if(theta<0.001)return ;
axis = (x1+y1)%(m_cameraOld.vCenter-m_cameraOld.vEye);
axis = axis/Module(axis);
Rotate(axis, m_camera.vCenter, theta, &m_camera.vEye);
Rotate(axis, theta, &m_camera.vUp);#ifdef FRUSTRUM
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(m_dFrustumLeft, m_dFrustumRight, m_dFrustumBottom,m_dFrustumTop, 
m_dFrustumNear, m_dFrustumFar);
gluLookAt(m_camera.vEye.x, m_camera.vEye.y, m_camera.vEye.z,
m_camera.vCenter.x, m_camera.vCenter.y, m_camera.vCenter.z,
m_camera.vUp.x, m_camera.vUp.y, m_camera.vUp.z);
#endif RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}void CWaveView::OnDestroy() 
{
CView::OnDestroy();

delete m_pDC;
}void CWaveView::PanView(UINT nFlags, CPoint point)
{
PNT3D right, sight;
double k; k = 4.5*(m_dFrustumRight-m_dFrustumLeft)/m_cx;
sight = m_camera.vCenter - m_camera.vEye;
Normalize(&sight);
right = sight % m_camera.vUp; m_camera.vCenter = m_camera.vCenter 
-k *(point.x-m_pointLast.x) * right
+k *(point.y-m_pointLast.y) * m_camera.vUp;#ifdef FRUSTRUM
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(m_dFrustumLeft, m_dFrustumRight, m_dFrustumBottom,m_dFrustumTop, 
m_dFrustumNear, m_dFrustumFar);
gluLookAt(m_camera.vEye.x, m_camera.vEye.y, m_camera.vEye.z,
m_camera.vCenter.x, m_camera.vCenter.y, m_camera.vCenter.z,
m_camera.vUp.x, m_camera.vUp.y, m_camera.vUp.z);
#endif RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW); m_pointLast = point;
TRACE("PanView %lf, %lf\n", m_camera.vCenter.x, m_camera.vCenter.y);
}void CWaveView::ScaleView(UINT nFlags, CPoint point)
{
double scale = 1 + 0.01*(point.y-m_pointLast.y); if(scale>0.1)
{
m_dFrustumLeft *= scale;
m_dFrustumRight *= scale;
m_dFrustumBottom *= scale;
m_dFrustumTop *= scale;#ifdef FRUSTRUM
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(m_dFrustumLeft, m_dFrustumRight, m_dFrustumBottom,m_dFrustumTop, 
m_dFrustumNear, m_dFrustumFar);
gluLookAt(m_camera.vEye.x, m_camera.vEye.y, m_camera.vEye.z,
m_camera.vCenter.x, m_camera.vCenter.y, m_camera.vCenter.z,
m_camera.vUp.x, m_camera.vUp.y, m_camera.vUp.z);
#endif

RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
}
m_pointLast = point;
}void CWaveView::OnTest() 
{
COutputWnd::OutString((char*)"dddddddddddd333333dddddddddd\r\n");
}#define BUFFER_LENGTH 16
void CWaveView::ProcessSel(CPoint point)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH]; // Hit counter and viewport storeage
GLint hits, viewport[4]; // Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);

// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport); // Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix(); // Change render mode
glRenderMode(GL_SELECT); // Establish new clipping volume to be unit cube around
// mouse cursor point (point.x, point.y) and extending two pixels
// in the vertical and horzontal direction. Remember OpenGL specifies the
// y coordinate from the bottom, Windows from the top. So windows position
// (as measured from the top) subtract the height and you get it in terms 
// OpenGL Likes.
glLoadIdentity();
gluPickMatrix(point.x, viewport[3] - point.y, 8,8, viewport); // Apply perspective matrix 
gluPerspective(45.0f, 1, 1.0, 425.0);
// glFrustum(m_dFrustumLeft, m_dFrustumRight, m_dFrustumBottom,m_dFrustumTop, 
// m_dFrustumNear, m_dFrustumFar); // Draw the scene
DrawScene(); // Collect the hits
hits = glRenderMode(GL_RENDER); // If a single hit occured, display the info.
static int hitcount=0;
if(hits==1)
{
CString str;
str.Format("hit[%d %d] %d\r\n", selectBuff[0], selectBuff[1], hitcount++);
COutputWnd::OutString((LPCTSTR)str);
SetCursor(AfxGetApp()->LoadCursor(IDC_SELECT));
} // Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix(); // Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}