📄 terraintestview.cpp
字号:
// terraintestView.cpp : implementation of the CTerraintestView class
//
#include "stdafx.h"
#include "terraintest.h"
#include "terraintestDoc.h"
#include "terraintestView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView
IMPLEMENT_DYNCREATE(CTerraintestView, CView)
BEGIN_MESSAGE_MAP(CTerraintestView, CView)
//{{AFX_MSG_MAP(CTerraintestView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView construction/destruction
CTerraintestView::CTerraintestView()
{
// TODO: add construction code here
}
CTerraintestView::~CTerraintestView()
{
}
BOOL CTerraintestView::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);
}
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView drawing
void CTerraintestView::OnDraw(CDC* pDC)
{
CTerraintestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//渲染场景
RenderScene();
}
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView printing
BOOL CTerraintestView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTerraintestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CTerraintestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView diagnostics
#ifdef _DEBUG
void CTerraintestView::AssertValid() const
{
CView::AssertValid();
}
void CTerraintestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CTerraintestDoc* CTerraintestView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTerraintestDoc)));
return (CTerraintestDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CTerraintestView message handlers
BOOL CTerraintestView::InitializeOpenGL(CDC *pDC)
{
//进行opengl的初始化工作
m_pDC=pDC;
//首先把DC的象素格式调整为指定的格式,以便后面对DC的使用
SetupPixelFormat();
//根据DC来创建RC
m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());
//设置当前的RC,以后的画图操作都画在m_pDC指向的DC上
::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
//下面可以进行画图操作了
return TRUE;
}
int CTerraintestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
//做的工作是进行opengl的初始化,地形的初始化,
//opengl的一些显示参数的设置以及启动定时器
//获取客户区的设备描述表
m_pDC=new CClientDC(this);
//初始化OpenGL
InitializeOpenGL(m_pDC);
//启动定时器,准备进行画图操作
//SetTimer(1,20,NULL);
//初始化OpenGL的一些状态参数并对地形数据进行初始化(注意地形只需要一次初始化即可)
InitGL();
return 0;
}
BOOL CTerraintestView::SetupPixelFormat()
{
//初始化象素格式以及选取合适的格式来创建RC
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度 ,color depth
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累加缓存
0, 0, 0, 0, // 忽略累加位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
//在DC中选择合适的象素格式并返回索引号
int pixelformat;
pixelformat=::ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if (pixelformat==0)
{
AfxMessageBox("no matched pixelformat!");
return FALSE;
}
//设置指定象素格式
if (::SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)==FALSE)
{
AfxMessageBox("can't set specified pixelformat!");
return FALSE;
}
//设定逻辑调色板
if (pfd.dwFlags & PFD_NEED_PALETTE)
SetupLogicalPalette();
return TRUE;
}
void CTerraintestView::SetupLogicalPalette()
{
//设置逻辑调色板
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[256];
} logicalPalette = { 0x300, 256 };
BYTE reds[] = {0, 36, 72, 109, 145, 182, 218, 255};
BYTE greens[] = {0, 36, 72, 109, 145, 182, 218, 255};
BYTE blues[] = {0, 85, 170, 255};
for (int colorNum=0; colorNum<256; ++colorNum)
{
logicalPalette.aEntries[colorNum].peRed =
reds[colorNum & 0x07];
logicalPalette.aEntries[colorNum].peGreen =
greens[(colorNum >> 0x03) & 0x07];
logicalPalette.aEntries[colorNum].peBlue =
blues[(colorNum >> 0x06) & 0x03];
logicalPalette.aEntries[colorNum].peFlags = 0;
}
m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
}
BOOL CTerraintestView::InitGL()
{
//初始化整个场景和OpenGL的状态变量
GLfloat fgcolor[]={ 0.0f, 0.0f, 0.0f,1.0f };
//初始化地形数据以便于绘制
InitTerrainData();
// OpenGL场景初始化(光照、雾化等〕
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glFogfv(GL_FOG_COLOR,fgcolor);
glFogf(GL_FOG_START,25.0f);
glFogf(GL_FOG_END,33.0f);
glFogf(GL_FOG_MODE,GL_LINEAR);
glFogf(GL_FOG_DENSITY, 0.5f); // How Dense Will The Fog Be
glEnable(GL_FOG);
return TRUE; // Initialization Went OK
}
void CTerraintestView::InitTerrainData()
{
//初始化地形数据
CString str;
int i,j;
m_Max=100;
m_Min=0;
//首先将地形数据初始化为0
for (i=0;i<Max;i++)
{
for(j=0;j<Max;j++)
m_land[i][j]=0;
}
//随机计算地形高程,高度应该在0-10之间
for (i=1;i<Max-1;i++)
{
for(j=1;j<Max-1;j++)
{
m_land[i][j]=(float)(rand()%5);
// str.Format("%f",m_land[i][j]);
// AfxMessageBox("sdf"+str);
}
}
//地形平滑
for (i=1;i<Max-1;i++)
for(j=1;j<Max-1;j++)
m_land[i][j]=(m_land[i+1][j]+m_land[i][j+1]+m_land[i-1][j]+m_land[i][j-1])/4;
//计算并保存地形高程的最大值和最小值,目的是
for (i=1;i<Max-1;i++)
for(j=1;j<Max-1;j++)
{
if (m_Max<m_land[i][j])
m_Max=m_land[i][j];
if (m_Min>m_land[i][j])
m_Min=m_land[i][j];
}
}
BOOL CTerraintestView::RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0,7,0,4,4,4,0,1,0);
DrawTerrain();
::SwapBuffers(m_pDC->GetSafeHdc()); //交互缓冲区
return TRUE;
}
BOOL CTerraintestView::DrawTerrain()
{
//根据地形数据绘制出地形
CString str;
float h1,h2,h3,h4;
float color1,color2,color3,color4;
int x,y,z;
for(x=1;x<29;x++)
{
for(z=1;z<29;z++)
{
//获取相邻的四个顶点的高程数据
h1=m_land[x][z];
h2=m_land[x][z+1];
h3=m_land[x+1][z];
h4=m_land[x+1][z+1];
str.Format("%f",h1);
// AfxMessageBox(str);
//计算各个顶点的颜色数据
color1=h1*256/(m_Max-m_Min);
color2=h2*256/(m_Max-m_Min);
color3=h3*256/(m_Max-m_Min);
color4=h4*256/(m_Max-m_Min);
//地形由四边形构成
glBegin(GL_QUADS);
glColor3f(color1,0,color1);
glVertex3d((float)x,h1,(float)z);
glColor3f(color2,color2,color2);
glVertex3d((float)x,h2,(float)(z+1));
glColor3f(color3,color3,color3);
glVertex3d((float)(x+1),h3,(float)z);
glColor3f(color4,color4,color4);
glVertex3d((float)(x+1),h4,(float)(z+1));
glEnd();
}
}
return TRUE;
}
void CTerraintestView::OnDestroy()
{
CView::OnDestroy();
::wglMakeCurrent(NULL,NULL);
//删除RC
::wglDeleteContext(m_hRC);
if (m_hPalette)
DeleteObject(m_hPalette);
if (m_pDC)
delete m_pDC;
}
void CTerraintestView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
//添加窗口缩放时的图形变换函数
glViewport(0,0,cx,cy);
/////////////////////////////////////////////////////////////////
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -