📄 lesson5view.cpp
字号:
// Lesson5View.cpp : implementation of the CLesson5View class
//
#include "stdafx.h"
#include "Lesson5.h"
#include "Lesson5Doc.h"
#include "Lesson5View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLesson5View
IMPLEMENT_DYNCREATE(CLesson5View, CView)
BEGIN_MESSAGE_MAP(CLesson5View, CView)
//{{AFX_MSG_MAP(CLesson5View)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
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()
/////////////////////////////////////////////////////////////////////////////
// CLesson5View construction/destruction
CLesson5View::CLesson5View()
{
// TODO: add construction code here
this->m_GLPixelIndex = 0;
this->m_hGLContext = NULL;
}
CLesson5View::~CLesson5View()
{
}
BOOL CLesson5View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
/*OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)
和 WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格*/
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLesson5View drawing
void CLesson5View::OnDraw(CDC* pDC)
{
CLesson5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CLesson5View printing
BOOL CLesson5View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CLesson5View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CLesson5View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CLesson5View diagnostics
#ifdef _DEBUG
void CLesson5View::AssertValid() const
{
CView::AssertValid();
}
void CLesson5View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CLesson5Doc* CLesson5View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLesson5Doc)));
return (CLesson5Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLesson5View message handlers
BOOL CLesson5View::SetWindowPixelFormat(HDC hDC)
{
//定义窗口的像素格式
PIXELFORMATDESCRIPTOR pixelDesc= // /告诉窗口我们所希望的东东,即窗口使用的像素格式
{
sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 格式支持窗口
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL
PFD_DOUBLEBUFFER, // 必须支持双缓冲
PFD_TYPE_RGBA, // 申请 RGBA 格式
24, // 选定色彩深度
0, 0, 0, 0, 0, 0, // 忽略的色彩位
0, // 无Alpha缓存
0, // 忽略Shift Bit
0, // 无累加缓存
0, 0, 0, 0, // 忽略聚集位
16, // 16位 Z-缓存 (深度缓存)
0, // 无蒙板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主绘图层
0, // Reserved
0, 0, 0 // 忽略层遮罩
};
this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
if(this->m_GLPixelIndex==0)
{
this->m_GLPixelIndex = 1;
if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
{
MessageBox("不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
}
if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE)
{
MessageBox("不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;
}
int CLesson5View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
HWND hWnd = this->GetSafeHwnd();
HDC hDC = ::GetDC(hWnd);
if(this->SetWindowPixelFormat(hDC)==FALSE)
{
return 0;
}
if(this->CreateViewGLContext(hDC)==FALSE)
{
MessageBox("不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
return 0;
}
return 0;
}
BOOL CLesson5View::CreateViewGLContext(HDC hDC)
{ //产生绘制环境(RC)并使之成为当前绘制环境
this->m_hGLContext = wglCreateContext(hDC);
if(this->m_hGLContext==NULL)
{//创建失败
return FALSE;
}
if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
{//选为当前RC失败
return FALSE;
}
return TRUE;
}
void CLesson5View::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
if(wglGetCurrentContext()!=NULL)
{
wglMakeCurrent(NULL,NULL);
}
if(this->m_hGLContext!=NULL)
{
wglDeleteContext(this->m_hGLContext);
this->m_hGLContext = NULL;
}
}
int nBufferSizeX,nBufferSizeY;//定义图象窗口长宽
void CLesson5View::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CView::OnPaint() for painting messages
// glLoadIdentity();
// glClear(GL_COLOR_BUFFER_BIT);
/* glBegin(GL_POLYGON);
glColor4f(1.0f,0.0f,0.0f,1.0f);
glVertex2f(100.0f,50.0f);
glColor4f(0.0f,1.0f,0.0f,1.0f);
glVertex2f(450.0f,400.0f);
glColor4f(0.0f,0.0f,1.0f,1.0f);
glVertex2f(450.0f,50.0f);
glEnd();*/
// glDrawPixels(nBufferSizeX, nBufferSizeY, GL_LUMINANCE, GL_UNSIGNED_BYTE, pafScanblock1);
// glFlush();
// SwapBuffers(dc.m_hDC);
}
void CLesson5View::OnFileOpen()
{
// TODO: Add your command handler code here
char szFilter[] = "GeoTiff (*.tif)|*.tif|All Files (*.*)|*.*||";
CString filePath("");
CFileDialog fileOpenDlg(TRUE, "tif", NULL,OFN_HIDEREADONLY,szFilter);
if (fileOpenDlg.DoModal() !=IDOK)
return;
else
{
VERIFY(filePath = fileOpenDlg.GetPathName());
}
CString strFilePath(filePath);
GDALDataset *poDataset; //GDAL数据集
GDALAllRegister();
poDataset = (GDALDataset *) GDALOpen(strFilePath, GA_ReadOnly );
GDALRasterBand *poBand1; //遥感的一个波段
using namespace std;
vector <GDALDataset *> datasets;
if( poDataset == NULL )
{
AfxMessageBox("文件打开失败!!!");
return;
}
GDALDriver * driver=poDataset->GetDriver ();
string papszMetadata=GDALGetDriverShortName((GDALDriverH)poDataset);
int index=papszMetadata.find_first_of("hdf");
if(index<0)
index=papszMetadata.find_first_of("HDF");
if(index)
{
char ** SUBDATASETS = GDALGetMetadata( (GDALDatasetH)poDataset, "SUBDATASETS" );
if( CSLCount(SUBDATASETS) > 0 )
{
for(int i = 0; SUBDATASETS[i] != NULL; i++ )
{
if(i%2==0)
{
string tmpstr=string(SUBDATASETS[i]);
tmpstr=tmpstr.substr(tmpstr.find_first_of("=")+1);
const char *tmpfilename=tmpstr.c_str();
GDALDataset * tmpdt=(GDALDataset *) GDALOpen(tmpfilename, GA_ReadOnly);
if(tmpdt)
{
datasets.push_back(tmpdt);
}
}
}
}
else
{
int bandCount=poDataset->GetRasterCount();
if(bandCount>0)
{
poBand1=poDataset->GetRasterBand(1);
}
}
}
if(!datasets.empty())
{
int count=datasets.size();
int bandCount=0;
for(int i=0;i<count;i++)
{
bandCount+=datasets[i]->GetRasterCount();
if(datasets[i]->GetRasterCount()>0)
{
poBand1=datasets[i]->GetRasterBand(1);
}
}
//for(i=0;i<count;i++)
// {
// delete datasets[i];
// datasets[i]=NULL;
// }
// datasets.reserve(0);
}
//获取图像的尺寸
//获取图像窗口尺寸
// CRect rect;
// GetClientRect(rect);
int nImgSizeX=poDataset->GetRasterXSize(); //图象宽度
int nImgSizeY=poDataset->GetRasterYSize(); //图象高度
/*此处以后建立金子塔*/
nBufferSizeY=800;//nImgSizeY; //图象窗口的高度
float m_fXYRation;
m_fXYRation = (float)nImgSizeX/(float)nImgSizeY; //图象高宽比
//根据图象高宽比和窗口高度计算出需要的窗口宽度,就是说先让纵向铺满
//而横向由图象比例决定
nBufferSizeX = (int)(m_fXYRation*(float)nBufferSizeY);
while( sizeof(BYTE)*(nBufferSizeX) % 4 != 0 ) //重要,如果不修正,可能出现偏差, 修正nBufferSizeX使其为4的倍数
++nBufferSizeX;
BYTE *pafScanblock1;
pafScanblock1 = (BYTE *) CPLMalloc(sizeof(BYTE)*(nBufferSizeX)*(nBufferSizeY)); //分配内存空间
//利用RasterIO分配到内存
//注意1、此处GF_Read 需要看是为读还是写 2、GDT_Byte后面需由图象类型决定
poBand1->RasterIO( GF_Read, 0, 0,nImgSizeX,nImgSizeY,pafScanblock1,nBufferSizeX,nBufferSizeY, GDT_Byte,0, 0 );
GDALClose(poDataset);
//翻转图象
BYTE temp;
for(int i=0; i<int(nBufferSizeY/2); i++)
for(int j=0; j<nBufferSizeX; j++)
{
temp = pafScanblock1[i*nBufferSizeX+j];
pafScanblock1[i*nBufferSizeX+j] = pafScanblock1[(nBufferSizeY-i-1)*nBufferSizeX+j];
pafScanblock1[(nBufferSizeY-i-1)*nBufferSizeX+j] = temp;
}
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(nBufferSizeX, nBufferSizeY, GL_LUMINANCE, GL_UNSIGNED_BYTE, pafScanblock1);
glFlush();
CPaintDC dc(this);
SwapBuffers(dc.m_hDC);
}
void CLesson5View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
GLsizei width,height;
GLdouble aspect;
width = cx;
height = cy;
if(cy==0)
{
aspect = (GLdouble)width;
}
else
{
aspect = (GLdouble)width/(GLdouble)height;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,500.0*aspect,0.0,500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -