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;
}