www.pudn.com > roam.rar > ROAMView.cpp
// ROAMView.cpp : implementation of the CROAMView class
//
#include "stdafx.h"
#include "ROAM.h"
#include "ROAMDoc.h"
#include "ROAMView.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI 3.1415926
GLfloat LightAmbient[]= { 0.0f, 0.0f, 0.9f, 1.0f };//设置光源参数
GLfloat LightDiffuse[]= { 1.0f,0.0f, 0.0f, 1.0f };
GLfloat LightPosition[]= { 1000.0f, 600.0f, 1000.0f, 1.0f };
GLuint texture; // Storage For 6 Textures (MODIFIED)
/////////////////////////////////////////////////////////////////////////////
// CROAMView
IMPLEMENT_DYNCREATE(CROAMView, CView)
BEGIN_MESSAGE_MAP(CROAMView, CView)
//{{AFX_MSG_MAP(CROAMView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CROAMView construction/destruction
CROAMView::CROAMView()
{
roamTerrain = new CRoamTerrain;
m_pDC = NULL;
m_Angle = 180.0;
//眼睛初始位置
eyePos[0] = 500;
eyePos[1] = 512;
eyePos[2] = 800;
//参考点初始位置
double rad = 3.141592653*m_Angle/180.0;
cenPos[0] = float(eyePos[0] + 10*cos(rad));
cenPos[1] = float(eyePos[1] + 10*sin(rad));
//cenPos[0] = 250;
//cenPos[1] = 50;
cenPos[2] = 50;
deltaX = 1;
deltaY = 1;
}
CROAMView::~CROAMView()
{
}
BOOL CROAMView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CROAMView drawing
void CROAMView::OnDraw(CDC* pDC)
{
CROAMDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
DrawScene();
}
/////////////////////////////////////////////////////////////////////////////
// CROAMView diagnostics
#ifdef _DEBUG
void CROAMView::AssertValid() const
{
CView::AssertValid();
}
void CROAMView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CROAMDoc* CROAMView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CROAMDoc)));
return (CROAMDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CROAMView message handlers
int CROAMView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
Init();
return 0;
}
void CROAMView::OnDestroy()
{
CView::OnDestroy();
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL, NULL);
if (hrc)
::wglDeleteContext(hrc);
if (m_pDC)
delete m_pDC;
}
BOOL CROAMView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CROAMView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
GLint w = cx;
GLint h = cy;
if( h == 0 ) h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w > h)
gluPerspective (60, (float)w/(float)h, 10.0, 1000000.0);
else
gluPerspective (60, (float)h/(float)w, 10.0, 1000000.0);
glMatrixMode(GL_MODELVIEW);
}
BOOL CROAMView::bSetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER, // double buffered, // 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;
}
void CROAMView::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);
if (!LoadGLTextures()) //载入纹理
{
return ;
}
glClearDepth(1000000.0f);
glDepthFunc(GL_LEQUAL); // 深度检测类型
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 透视优化
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 环境光
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 散射光
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 光源位置
glEnable(GL_LIGHT1);// 激活光源
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
AUX_RGBImageRec* CROAMView::LoadBMP(char *Filename)
{
FILE *File=NULL; // File Handle
if (!Filename) // 如果不存在
{
return NULL; //
}
File=fopen(Filename,"r"); // 判断文件是否存在
if (File) // Does The File Exist?
{
fclose(File); // 关闭
return auxDIBImageLoad(Filename); // 载入图像文件并返回一个指针
}
return NULL;
}
int CROAMView::LoadGLTextures()
{
int Status=FALSE; // 表示纹理图像载入状态
// memset(TextureImage,0,sizeof(void *)); // 设置空指针
// 载入位图
if (TextureImage=LoadBMP(_T("back1.bmp")) )
{
Status=TRUE; // 设置Status为TRUE
glGenTextures(6, &texture); // 创建三个纹理
// 创建最近的纹理
glBindTexture(GL_TEXTURE_2D, texture); // 生成两个纹理
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage->sizeX, TextureImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data);
}
if (TextureImage) // 如果图像存在
{
if (TextureImage->data) // 如果图像存在
{
free(TextureImage->data); // 释放纹理图像内存
}
free(TextureImage); // 释放纹理结构
}
return Status;
}
void CROAMView::DrawTerrain()
{
roamTerrain->RoamDrawScene(eyePos[0],eyePos[1]);
}
void CROAMView::DrawScene()
{
glClearColor(0.6f, 0.6f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 1, 0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDepthMask(0);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
// 设置贴图
glBindTexture(GL_TEXTURE_2D, texture );
// 绘制背景
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexEnvf ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glEnable ( GL_TEXTURE_2D );
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(1, 0); glVertex2i(1, 0);
glTexCoord2i(1, 1); glVertex2i(1, 1);
glTexCoord2i(0, 1); glVertex2i(0, 1);
glEnd();
glDisable(GL_TEXTURE_2D);
// 恢复3D视角
glDepthMask(1);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyePos[0],eyePos[1],eyePos[2],cenPos[0],cenPos[1],cenPos[2],0,0,1);
// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glEdgeFlag(TRUE);
DrawTerrain();
glFinish();
SwapBuffers(wglGetCurrentDC());
}
void CROAMView::KeyCtrlRoam(UINT lrKey, UINT lrValue, UINT udKey, UINT udValue)
{
float speed = 5.0f;
// float PI=3.14159f;
if(lrKey == VK_LEFT)
{
m_Angle -= 5.0*lrValue;
}
if(lrKey == VK_RIGHT)
{
m_Angle += 5.0*lrValue;
}
float rad = float(PI*m_Angle/180.0f);
if(udKey == VK_UP)
{
eyePos[0] +=(float)cos(rad)*speed*udValue;
eyePos[1] +=(float)sin(rad)*speed*udValue;
}
if(udKey == VK_DOWN)
{
eyePos[0] -=(float)cos(rad)*speed*udValue;
eyePos[1] -=(float)sin(rad)*speed*udValue;
}
// 观察点
cenPos[0] = float(eyePos[0] + 10*cos(rad));
cenPos[1] = float(eyePos[1] + 10*sin(rad));
Invalidate(FALSE);
}
void CROAMView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
KeyCtrlRoam(nChar,1,nChar,1);//调用漫游函数
}