www.pudn.com > pccode_2006910124551680.rar > OGL_MFCView.cpp


// OGL_MFCView.cpp : implementation of the COGL_MFCView class 
// 
 
#include "stdafx.h" 
#include "OGL_MFC.h" 
 
#include "OGL_MFCDoc.h" 
#include "OGL_MFCView.h" 
#include "SelectColorDlg.h" 
#include "BMPFile.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// COGL_MFCView 
 
GLfloat COGL_MFCView::glfMatAmbient[4] = {0.000f, 0.450f, 1.000f, 1.0f}; 
GLfloat COGL_MFCView::glfMatDiffuse[4] = {0.000f, 0.000f, 0.580f, 1.0f}; 
GLfloat COGL_MFCView::glfMatSpecular[4]= {1.000f, 1.000f, 1.000f, 1.0f}; 
GLfloat COGL_MFCView::glfMatEmission[4]= {0.000f, 0.000f, 0.000f, 1.0f}; 
GLfloat COGL_MFCView::fShininess = 128.000f; 
 
IMPLEMENT_DYNCREATE(COGL_MFCView, CScrollView) 
 
BEGIN_MESSAGE_MAP(COGL_MFCView, CScrollView) 
	//{{AFX_MSG_MAP(COGL_MFCView) 
	ON_WM_CREATE() 
	ON_WM_SIZE() 
	ON_WM_DESTROY() 
	ON_COMMAND(IDM_METERIAL, OnSelectMeterialColor) 
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen) 
	ON_WM_KEYDOWN() 
	ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) 
	ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// COGL_MFCView construction/destruction 
 
COGL_MFCView::COGL_MFCView() 
{ 
	// TODO: add construction code here 
	m_hRC=NULL; 
	m_fxAngle=0.0;m_fzAngle=0.0; 
	pGrayData=NULL; 
} 
 
COGL_MFCView::~COGL_MFCView() 
{ 
	delete [] pGrayData; 
} 
 
BOOL COGL_MFCView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CScrollView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// COGL_MFCView drawing 
void GLDraw3DBMP(BYTE* pGrayData,int width,int height) 
{ 
	int row,col; 
/* 
	glBegin(GL_POLYGON); 
	glNormal3f(0.0f, 0.0f, -1.0f); 
	glVertex3f(0.0f,0.0f,1.0f); 
	glVertex3f(1.0f,0.0f,1.0f); 
	for(col=width; col>=0; col--){ 
		glVertex3f((GLfloat)col/(GLfloat)width,(GLfloat)pGrayData[col]/255.0f,1.0f); 
	} 
	glEnd(); 
 
	glBegin(GL_POLYGON); 
	glNormal3f(0.0f, 0.0f, 1.0f); 
	glVertex3f(0.0f,0.0f,0.0f); 
	glVertex3f(1.0f,0.0f,0.0f); 
	for(col=width; col>=0; col--){ 
		glVertex3f((GLfloat)col/(GLfloat)width,(GLfloat)pGrayData[height*(width+1)+col]/255.0f,0.0f); 
	} 
	glEnd(); 
 
	glBegin(GL_POLYGON); 
	glNormal3f(-1.0f, 0.0f, 0.0f); 
	glVertex3f(0.0f,0.0f,0.0f); 
	glVertex3f(0,0,1.0f); 
	for(row=height; row>=0; row--){ 
		glVertex3f(0.0f,(GLfloat)pGrayData[row*(width+1)]/255.0f,(GLfloat)row/(GLfloat)height); 
	} 
	glEnd(); 
 
	glBegin(GL_POLYGON); 
	glNormal3f(1.0f, 0.0f, 0.0f); 
	glVertex3f(1.0f,0.0f,0.0f); 
	glVertex3f(1.0f,0.0f,1.0f); 
	for(row=height; row>=0; row--){ 
		glVertex3f(1.0f,(GLfloat)pGrayData[row*(width+1)+width]/255.0f,(GLfloat)row/(GLfloat)height); 
	} 
	glEnd(); 
*/ 
	glBegin(GL_POINTS); 
	glNormal3f(0.0f, 1.0f, 0.0f); 
	for(row=0; row<=height; row++){ 
		for(col=0; col<=width; col++){ 
			int offset=row*(width+1)+col; 
			int tmp=pGrayData[offset]; 
			GLfloat x=2.0f*(GLfloat)col/(GLfloat)width-1.0f; 
			GLfloat y=(GLfloat)tmp/255.0f; 
			GLfloat z=2.0f*(GLfloat)(height-row)/(GLfloat)height-1.0f; 
			glVertex3f(x,y,z); 
		} 
	} 
	glEnd(); 
 
	glBegin(GL_POLYGON); 
	glNormal3f(0.0f, -1.0f, 0.0f); 
	glVertex3f(-1.0f, 0.0f, -1.0f); 
	glVertex3f(1.0f, 0.0f, -1.0f); 
	glVertex3f(1.0f, 0.0f, 1.0f); 
	glVertex3f(-1.0f, 0.0f, 1.0f); 
	glEnd(); 
/* 
	glBegin(GL_LINES); 
	glNormal3f(0.0f, 1.0f, 0.0f); 
	for(row=0; row<=height; row++){ 
		for(col=0; col<=width; col++){ 
			int offset=row*(width+1)+col; 
			int tmp=pGrayData[offset]; 
			GLfloat x=(GLfloat)col/(GLfloat)width; 
			GLfloat y=(GLfloat)tmp/255.0f; 
			GLfloat z=(GLfloat)row/(GLfloat)height; 
			glVertex3f(x,y,z); 
			glVertex3f(x,0,z); 
		} 
	} 
	glEnd(); 
*/ 
} 
 
void COGL_MFCView::OnDraw(CDC* pDC) 
{ 
	if(m_hRC==NULL) return; 
	if(pGrayData==NULL) return; 
 
	wglMakeCurrent(pDC->GetSafeHdc(), m_hRC); 
	DrawScene(); 
	SwapBuffers(pDC->GetSafeHdc()); 
	wglMakeCurrent(0, 0); 
} 
 
void COGL_MFCView::OnInitialUpdate() 
{ 
	CScrollView::OnInitialUpdate(); 
 
	CSize sizeTotal; 
	sizeTotal.cx = sizeTotal.cy = 100; 
	SetScrollSizes(MM_TEXT, sizeTotal); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// COGL_MFCView diagnostics 
 
#ifdef _DEBUG 
void COGL_MFCView::AssertValid() const 
{ 
	CScrollView::AssertValid(); 
} 
 
void COGL_MFCView::Dump(CDumpContext& dc) const 
{ 
	CScrollView::Dump(dc); 
} 
 
COGL_MFCDoc* COGL_MFCView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COGL_MFCDoc))); 
	return (COGL_MFCDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// COGL_MFCView message handlers 
int COGL_MFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CScrollView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	// Define pixel format 
	PIXELFORMATDESCRIPTOR pfd; 
	int nPixelFormat;	 
	memset(&pfd, NULL, sizeof(pfd));     
	pfd.nSize      = sizeof(pfd); 
	pfd.nVersion   = 1; 
	pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 
	pfd.iPixelType = PFD_TYPE_RGBA; 
	pfd.cColorBits = 24; 
	pfd.cDepthBits = 16; 
	pfd.iLayerType = PFD_MAIN_PLANE; 
	 
	// Set pixel format 
	CClientDC dc(this); 
	HDC hDC = dc.GetSafeHdc(); 
	nPixelFormat = ChoosePixelFormat(hDC, &pfd); 
	SetPixelFormat(hDC, nPixelFormat, &pfd); 
	 
	// Create RC--Rendering Context 
	m_hRC = wglCreateContext(hDC); 
	wglMakeCurrent(hDC, m_hRC); 
	   
	InitScene(); 
	wglMakeCurrent(0, 0); 
 
	return 0; 
} 
 
void COGL_MFCView::OnSize(UINT nType, int cx, int cy)  
{ 
	CScrollView::OnSize(nType, cx, cy); 
	 
	CClientDC dc(this); 
	if(cx==0 || cy ==0 ) 
		return; 
 
	GLfloat fFovy  = 30.0f; // Field-of-view 
	GLfloat fZNear = 1.0f;  // Near clipping plane 
	GLfloat fZFar = 10.0f;  // Far clipping plane 
 
	HDC hDC = dc.GetSafeHdc(); 
	wglMakeCurrent(hDC, m_hRC); 
	 
	// Calculate viewport aspect 
	RECT rv; 
	GetClientRect(&rv); 
	GLfloat fAspect = (GLfloat)(rv.right-rv.left) / (GLfloat)(rv.bottom-rv.top); 
 
	// Define viewport 
	glMatrixMode(GL_PROJECTION); 
	glLoadIdentity(); 
	gluPerspective(fFovy, fAspect, fZNear, fZFar); 
	glViewport(rv.left, rv.top, rv.right-rv.left, rv.bottom-rv.top); 
	glMatrixMode(GL_MODELVIEW); 
 
	wglMakeCurrent(0, 0); 
} 
 
void COGL_MFCView::InitScene() 
{ 
	glClearColor(0.000f, 0.000f, 0.000f, 1.0f); //Background color 
 
	// Activate lighting and a light source 
	glEnable(GL_LIGHT0); 
	glEnable(GL_LIGHTING); 
	glEnable(GL_DEPTH_TEST); 
/* 
	// Define material parameters 
	static GLfloat glfMatAmbient[] = {0.000f, 0.450f, 1.000f, 1.0f}; 
	static GLfloat glfMatDiffuse[] = {0.000f, 0.000f, 0.580f, 1.0f}; 
	static GLfloat glfMatSpecular[]= {1.000f, 1.000f, 1.000f, 1.0f}; 
	static GLfloat glfMatEmission[]= {0.000f, 0.000f, 0.000f, 1.0f}; 
	static GLfloat fShininess = 128.000f; 
 
	// Set material parameters 
	glMaterialfv(GL_FRONT, GL_AMBIENT,  glfMatAmbient); 
	glMaterialfv(GL_FRONT, GL_DIFFUSE,  glfMatDiffuse); 
	glMaterialfv(GL_FRONT, GL_SPECULAR, glfMatSpecular); 
	glMaterialfv(GL_FRONT, GL_EMISSION, glfMatEmission); 
	glMaterialf(GL_FRONT, GL_SHININESS, fShininess); 
*/ 
} 
 
void COGL_MFCView::DrawScene() 
{ 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear buffers 
	glLoadIdentity(); // Load identity matrix 
 
	// Add a light source 
	GLfloat glfLight[] = {-4.0f, 4.0f, 4.0f, 0.0f}; 
	glLightfv(GL_LIGHT0, GL_POSITION, glfLight); 
  
	// Set material parameters 
	glMaterialfv(GL_FRONT, GL_AMBIENT,  glfMatAmbient); 
	glMaterialfv(GL_FRONT, GL_DIFFUSE,  glfMatDiffuse); 
	glMaterialfv(GL_FRONT, GL_SPECULAR, glfMatSpecular); 
	glMaterialfv(GL_FRONT, GL_EMISSION, glfMatEmission); 
	glMaterialf(GL_FRONT, GL_SHININESS, fShininess); 
 
	// Position and rotate the camera 
	glTranslatef(0.0f, 0.0f, -5.0f);	 
	glRotatef(30.0f, 1.0f, 0.0f, 0.0f); 
	glRotatef(m_fxAngle, 1.0f, 0.0f, 0.0f); 
	glRotatef(m_fzAngle, 0.0f, 0.0f, 1.0f); 
 
	GLDraw3DBMP(pGrayData,nWidth-1,nHeight-1); 
 
	glFlush(); 
} 
 
void COGL_MFCView::KillScene() 
{ 
	 
} 
 
void COGL_MFCView::OnDestroy()  
{ 
	CScrollView::OnDestroy(); 
	if(m_hRC==NULL) return; 
	if(pGrayData==NULL) return; 
 
	CClientDC dc(this); 
	HDC hDC = dc.GetSafeHdc(); 
	wglMakeCurrent(hDC, m_hRC); 
	KillScene(); 
	wglMakeCurrent(0, 0); 
	wglDeleteContext(m_hRC); 
} 
 
void COGL_MFCView::OnSelectMeterialColor()  
{ 
	CSelectColorDlg dlg; 
	if(dlg.DoModal()!=IDOK) return; 
		 
	if(dlg.m_bDiffuseColor){ 
		GLfloat r,g,b; 
		RGBToGLfloatv(dlg.m_crDiffuseColor,r,g,b); 
		glfMatDiffuse[0]=r; 
		glfMatDiffuse[1]=g; 
		glfMatDiffuse[2]=b; 
		glfMatDiffuse[3]=1.0; 
	} 
	if(dlg.m_bEmbientColor){ 
		GLfloat r,g,b; 
		RGBToGLfloatv(dlg.m_crEmbientColor,r,g,b); 
		glfMatAmbient[0]=r; 
		glfMatAmbient[1]=g; 
		glfMatAmbient[2]=b; 
		glfMatAmbient[3]=1.0; 
	} 
	if(dlg.m_bEmissionColor){ 
		GLfloat r,g,b; 
		RGBToGLfloatv(dlg.m_crEmissionColor,r,g,b); 
		glfMatEmission[0]=r; 
		glfMatEmission[1]=g; 
		glfMatEmission[2]=b; 
		glfMatEmission[3]=1.0; 
	} 
	if(dlg.m_bSpecularColor){ 
		GLfloat r,g,b; 
		RGBToGLfloatv(dlg.m_crSpecularColor,r,g,b); 
		glfMatSpecular[0]=r; 
		glfMatSpecular[1]=g; 
		glfMatSpecular[2]=b; 
		glfMatSpecular[3]=1.0; 
	} 
	fShininess=(GLfloat)dlg.m_nShininess; 
 
	Invalidate(); 
} 
 
void COGL_MFCView::RGBToGLfloatv(COLORREF color,GLfloat& rf,GLfloat& gf,GLfloat& bf) 
{ 
	BYTE r=(BYTE)(color & 0x000000FF); 
	BYTE g=(BYTE)((color & 0x0000FF00)>>8); 
	BYTE b=(BYTE)((color & 0x00FF0000)>>16); 
	rf=r/(GLfloat)255.0; 
	gf=g/(GLfloat)255.0; 
	bf=b/(GLfloat)255.0; 
} 
 
void COGL_MFCView::OnFileOpen()  
{ 
	COGL_MFCDoc* pDoc=GetDocument(); 
 
	if(pGrayData!=NULL) { 
		delete [] pGrayData; 
		pGrayData=NULL; 
	} 
 
	CString fileName; 
	CString filter="BMP File (*.BMP)|*.BMP||"; 
     
	CFileDialog fileDlg(TRUE,NULL,NULL,NULL,filter,this); 
	fileDlg.m_ofn.Flags|=OFN_FILEMUSTEXIST; 
	fileDlg.m_ofn.lpstrTitle="Loading image file..."; 
	if (fileDlg.DoModal()==IDOK) { 
		AfxGetApp()->BeginWaitCursor(); 
		fileName=fileDlg.GetFileName(); 
		pDoc->SetTitle(fileName); 
		CString ext=fileName.Right(4); 
		if (!ext.CompareNoCase(".BMP")){ 
 
			BMPFile theBMP; 
			BYTE* pData=theBMP.LoadImage(fileName,nWidth,nHeight,nBitCount,nWidthBytes); 
			if(pData==NULL) return; 
			pGrayData=new BYTE[nWidth*nHeight]; 
			if(pGrayData==NULL) return; 
			theBMP.RGB2Gray(nWidth,nHeight,pData,pGrayData); 
			delete [] pData; 
 
			m_fxAngle=m_fzAngle=0.0; 
 
			Invalidate(); 
		} 
	} 
} 
 
//Rotate around x,z axis 
void COGL_MFCView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	switch(nChar){ 
	case VK_UP: 
		m_fxAngle++; 
		Invalidate(0); 
		break; 
	case VK_DOWN: 
		m_fxAngle--; 
		Invalidate(0); 
		break; 
	case VK_LEFT: 
		m_fzAngle++; 
		Invalidate(0); 
		break; 
	case VK_RIGHT: 
		m_fzAngle--; 
		Invalidate(0); 
		break; 
	default: 
		break; 
	} 
 
	CScrollView::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
// Load Image data from clipboard 
void COGL_MFCView::OnEditPaste()  
{ 
    COleDataObject dataObject; 
    VERIFY(dataObject.AttachClipboard()); 
    DoPasteDib(&dataObject);	 
} 
 
void COGL_MFCView::OnUpdateEditPaste(CCmdUI* pCmdUI)  
{ 
    COleDataObject dataObject; 
    BOOL bAvail = dataObject.AttachClipboard() && dataObject.IsDataAvailable(CF_DIB); 
    pCmdUI->Enable(bAvail);		 
} 
 
BOOL COGL_MFCView::DoPasteDib(COleDataObject* pOleDataObject) 
{ 
    // update command user interface should keep us out of  
	//  here if not CF_DIB 
    if (!pOleDataObject->IsDataAvailable(CF_DIB)) { 
        TRACE("CF_DIB format is unavailable\n"); 
        return FALSE; 
    } 
    // Seems to be MOVEABLE memory, so we must use GlobalLock! 
    // GetGlobalData copies the memory 
	// After copying the memory, we unlock and free it. 
    HGLOBAL hDib = pOleDataObject->GetGlobalData(CF_DIB); 
    ASSERT(hDib != NULL); 
    LPVOID lpDib = ::GlobalLock(hDib); 
    ASSERT(lpDib != NULL); 
 
	if(pGrayData){ 
		delete [] pGrayData; 
		pGrayData=NULL; 
	} 
	BMPFile theBMP; 
	BYTE* pData=theBMP.AttachMemory(lpDib,nWidth,nHeight,nBitCount,nWidthBytes); 
	if(pData==NULL) return 0; 
	pGrayData=new BYTE[nWidth*nHeight]; 
	if(pGrayData==NULL) return 0; 
	theBMP.RGB2Gray(nWidth,nHeight,pData,pGrayData); 
	delete [] pData; 
 
	m_fxAngle=m_fzAngle=0.0; 
 
	Invalidate(); 
 
	::GlobalUnlock(hDib); 
	::GlobalFree(hDib); 
 
    return TRUE; 
}