X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=src%2Fgraph3dview.cpp;h=c9b28f70e0bf6e4fd4ac571d682a94fce2c38f30;hb=f692b2d39f56ffbafc04283f32233c098aa2978b;hp=fdcb82369e391b49254c8f030a2fcd8bb56f203d;hpb=ba8635d790ee847d9746c6da24b60bd4cb6d9116;p=ctsim.git diff --git a/src/graph3dview.cpp b/src/graph3dview.cpp index fdcb823..c9b28f7 100644 --- a/src/graph3dview.cpp +++ b/src/graph3dview.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (c) 1983-2001 Kevin Rosenberg ** -** $Id: graph3dview.cpp,v 1.1 2001/01/30 07:32:13 kevin Exp $ +** $Id: graph3dview.cpp,v 1.5 2001/02/02 00:46:38 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -25,7 +25,6 @@ ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ - #ifdef __GNUG__ #pragma implementation #pragma interface @@ -42,6 +41,8 @@ #include "wx/wx.h" #endif +#if wxUSE_GLCANVAS + #if !wxUSE_GLCANVAS #error Please set wxUSE_GLCANVAS to 1 in setup.h. #endif @@ -69,6 +70,35 @@ #include #endif +// Rainbow: Purple->Blue->Cyan->Green->Yellow->Red = (1,0,1)-(0,0,1)-(0,1,1)-(0,1,0)-(1,1,0)-(1,0,0) +static void +intensityToColor (double dIntensity, float vecColor[3]) +{ + double dRange = dIntensity * 5; + int iRange = static_cast(floor (dRange)); + double dFrac = dRange - iRange; + + switch (iRange) { + case 0: + vecColor[0] = 1 - dFrac; vecColor[1] = 0; vecColor[2] = 1; + break; + case 1: + vecColor[0] = 0; vecColor[1] = dFrac; vecColor[2] = 1; + break; + case 2: + vecColor[0] = 0; vecColor[1] = 1; vecColor[2] = 1 - dFrac; + break; + case 3: + vecColor[0] = dFrac; vecColor[1] = 1; vecColor[2] = 0; + break; + case 4: + vecColor[0] = 0; vecColor[1] = 1 - dFrac; vecColor[2] = 0; + break; + case 5: + vecColor[0] = 1; vecColor[1] = 0; vecColor[2] = 0; + break; + } +} //*********************************************************************** // Function: CalculateVectorNormal @@ -109,16 +139,25 @@ IMPLEMENT_DYNAMIC_CLASS(Graph3dFileView, wxView) BEGIN_EVENT_TABLE(Graph3dFileView, wxView) EVT_MENU(IFMENU_FILE_PROPERTIES, Graph3dFileView::OnProperties) +EVT_MENU(GRAPH3D_VIEW_LIGHTING, Graph3dFileView::OnLighting) +EVT_MENU(GRAPH3D_VIEW_COLOR, Graph3dFileView::OnColor) +EVT_MENU(GRAPH3D_VIEW_SMOOTH, Graph3dFileView::OnSmooth) +EVT_MENU(GRAPH3D_VIEW_SURFACE, Graph3dFileView::OnSurface) END_EVENT_TABLE() Graph3dFileView::Graph3dFileView () -: m_pFileMenu(NULL) +: m_pFileMenu(NULL), m_pViewMenu(NULL) { - m_bUseVertexArrays = GL_FALSE; - m_bDoubleBuffer = GL_TRUE; - m_bSmooth = GL_TRUE; - m_bLighting = GL_TRUE; - + m_bUseVertexArrays = false; + m_bDoubleBuffer = true; + m_bSmooth = true; + m_bLighting = true; + m_bSurface = true; + m_bLighting = true; + m_bColor = true; + m_dXRotate = 0; + m_dYRotate = 0; + m_dZRotate = 0; } Graph3dFileView::~Graph3dFileView() @@ -150,6 +189,10 @@ Graph3dFileView::OnCreate (wxDocument *doc, long WXUNUSED(flags) ) m_pFrame->Show(true); Activate(true); + m_pViewMenu->Check (GRAPH3D_VIEW_COLOR, m_bColor); + m_pViewMenu->Check (GRAPH3D_VIEW_LIGHTING, m_bLighting); + m_pViewMenu->Check (GRAPH3D_VIEW_SMOOTH, m_bSmooth); + m_pViewMenu->Check (GRAPH3D_VIEW_SURFACE, m_bSurface); return true; } @@ -158,7 +201,7 @@ Graph3dFileView::CreateCanvas (wxFrame* parent) { Graph3dFileCanvas* pCanvas; int width, height; - parent->GetClientSize(&width, &height); + parent->GetClientSize (&width, &height); #ifdef __WXMSW__ int *gl_attrib = NULL; @@ -175,7 +218,6 @@ Graph3dFileView::CreateCanvas (wxFrame* parent) pCanvas = new Graph3dFileCanvas (this, parent, wxPoint(0, 0), wxSize(200, 200), 0, gl_attrib); - pCanvas->SetScrollbars(20, 20, 50, 50); pCanvas->SetBackgroundColour(*wxWHITE); pCanvas->Clear(); @@ -189,16 +231,110 @@ Graph3dFileView::DrawSurface() { #ifdef GL_EXT_vertex_array if (m_bUseVertexArrays) { - glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, m_nVerts ); + // glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, nVertices ); } else { #endif - glBegin( GL_TRIANGLE_STRIP ); - for (GLint i = 0;i < m_nVerts; i++) { - // glNormal3fv( &m_vecNorms[i] ); - // glVertex3fv( &m_vecVerts[i] ); + double edge = 1.; + unsigned int nx = GetDocument()->nx(); + unsigned int ny = GetDocument()->ny(); + const ImageFileArrayConst v = GetDocument()->getArray(); + if (nx == 0 || ny == 0 || ! v) + return; + + glRotatef( m_dXRotate, 1.0, 0.0, 0.0 ); + glRotatef( m_dZRotate, 0.0, 1.0, 0.0 ); + glRotatef( m_dYRotate, 0.0, 0.0, 1.0 ); + glTranslatef (-static_cast(nx) / 2., 0, -static_cast(ny) / 2.); + + InitMaterials(); + + if (m_bSmooth) { + glShadeModel (GL_SMOOTH); + } else { + glShadeModel (GL_FLAT); + } + + if (m_bLighting) { + glEnable (GL_LIGHTING); + } else { + glDisable (GL_LIGHTING); } - glEnd(); + + double dMin = v[0][0]; + double dMax = dMin; + unsigned int ix; + for (ix = 0; ix < nx; ix++) + for (unsigned int iy = 0; iy < ny; iy++) + if (v[ix][iy] < dMin) + dMin = v[ix][iy]; + else if (v[ix][iy] > dMax) + dMax = v[ix][iy]; + + double dIntensityScale = dMax - dMin; + double actOffset = dMin; + double actScale = 0.3 * sqrt(nx*nx+ny*ny) / (dMax - dMin); + + // glNewList(opnListNum++,GL_COMPILE); + if (! m_bColor) + glColor3f (1.0, 1.0, 1.0); + + glDisable (GL_CULL_FACE); + for (ix = 0; ix < nx-1; ix++) { + for (unsigned int iy = 0; iy < ny-1; iy++) { + + float p1[3], p2[3], p3[3], p4[3]; + float n1[3], n2[3], n3[3], n4[3]; + if (m_bSurface) + glBegin(GL_QUADS); + else + glBegin(GL_LINE_LOOP); + + p1[0] = ix; p1[1] = actScale * (v[ix][iy] + actOffset); p1[2] = iy; + p2[0] = ix+1; p2[1] = actScale * (v[ix+1][iy] + actOffset); p2[2] = iy; + p3[0] = ix+1; p3[1] = actScale * (v[ix+1][iy+1] + actOffset); p3[2] = iy+1; + p4[0] = ix; p4[1] = actScale * (v[ix][iy+1] + actOffset); p4[2] = iy+1; + + // n1[0] = -(p2[1] - p1[1])*(p3[2] - p1[2]) + (p2[2] - p1[2])*(p3[1] - p2[1]); + // n1[1] = -(p2[2] - p1[2])*(p3[0] - p2[0]) + (p2[0] - p1[0])*(p3[2] - p2[2]); + // n1[2] = -(p2[0] - p1[0])*(p3[1] - p2[1]) + (p2[1] - p1[1])*(p3[0] - p2[0]); + CalculateVectorNormal (p1, p2, p4, &n1[0], &n1[1], &n1[2]); + //CalculateVectorNormal (p2, p1, p3, &n2[0], &n2[1], &n2[2]) + //CalculateVectorNormal (p3, p2, p4, &n1[0], &n1[1], &n1[2]) + double dIntensity1, dIntensity2, dIntensity3, dIntensity4; + if (m_bColor) { + dIntensity1 = (v[ix][iy] - dMin) / dIntensityScale; + dIntensity2 = (v[ix+1][iy] - dMin) / dIntensityScale; + dIntensity3 = (v[ix+1][iy+1] - dMin) / dIntensityScale; + dIntensity4 = (v[ix][iy+1] - dMin) / dIntensityScale; + } + float vecColor[3]; + if (m_bColor) { + intensityToColor (dIntensity1, vecColor); + glColor3fv (vecColor); + } + glVertex3fv (p1); glNormal3fv (n1); + if (m_bColor) { + intensityToColor (dIntensity2, vecColor); + glColor3fv (vecColor); + } + glVertex3fv (p2); glNormal3fv (n1); + if (m_bColor) { + intensityToColor (dIntensity3, vecColor); + glColor3fv (vecColor); + } + glVertex3fv (p3); glNormal3fv (n1); + if (m_bColor) { + intensityToColor (dIntensity4, vecColor); + glColor3fv (vecColor); + } + glVertex3fv (p4); glNormal3fv (n1); + glEnd(); + } + + } + glEndList(); + #ifdef GL_EXT_vertex_array } #endif @@ -208,33 +344,43 @@ Graph3dFileView::DrawSurface() void Graph3dFileView::OnProperties (wxCommandEvent& event) { - const ImageFile& rIF = GetDocument()->getImageFile(); - if (rIF.nx() == 0 || rIF.ny() == 0) - *theApp->getLog() << "Properties: empty imagefile\n"; - else { - const std::string& rFilename = rIF.getFilename(); - std::ostringstream os; - double min, max, mean, mode, median, stddev; - rIF.statistics (rIF.getArray(), min, max, mean, mode, median, stddev); - os << "Filename: " << rFilename << "\n"; - os << "Size: (" << rIF.nx() << "," << rIF.ny() << ")\n"; - os << "Data type: "; - if (rIF.isComplex()) - os << "Complex\n"; - else - os << "Real\n"; - os << "Minimum: "< 0) { - rIF.printLabelsBrief (os); - } - *theApp->getLog() << ">>>>\n" << os.str().c_str() << "<<<<\n"; - wxMessageDialog dialogMsg (getFrameForChild(), os.str().c_str(), "Imagefile Properties", wxOK | wxICON_INFORMATION); - dialogMsg.ShowModal(); - } + std::ostringstream os; + *theApp->getLog() << ">>>>\n" << os.str().c_str() << "<<<<\n"; + wxMessageDialog dialogMsg (getFrameForChild(), os.str().c_str(), "Imagefile Properties", wxOK | wxICON_INFORMATION); + dialogMsg.ShowModal(); +} + +void +Graph3dFileView::OnLighting (wxCommandEvent& event) +{ + m_bLighting = ! m_bLighting; + m_pViewMenu->Check (GRAPH3D_VIEW_LIGHTING, m_bLighting); + + m_pCanvas->Refresh(); +} + +void +Graph3dFileView::OnSurface (wxCommandEvent& event) +{ + m_bSurface = ! m_bSurface; + m_pViewMenu->Check (GRAPH3D_VIEW_SURFACE, m_bSurface); + m_pCanvas->Refresh(); +} + +void +Graph3dFileView::OnColor (wxCommandEvent& event) +{ + m_bColor = ! m_bColor; + m_pViewMenu->Check (GRAPH3D_VIEW_COLOR, m_bColor); + m_pCanvas->Refresh(); +} + +void +Graph3dFileView::OnSmooth (wxCommandEvent& event) +{ + m_bSmooth = ! m_bSmooth; + m_pViewMenu->Check (GRAPH3D_VIEW_SMOOTH, m_bSmooth); + m_pCanvas->Refresh(); } @@ -247,6 +393,9 @@ Graph3dFileView::OnDraw (wxDC* dc) #endif Draw(); + std::ostringstream os; + os << "Xangle=" << m_dXRotate << ", Yangle=" << m_dYRotate << ", Zangle=" << m_dZRotate; + m_statusBar.SetStatusText (os.str().c_str()); m_pCanvas->SwapBuffers(); } @@ -256,9 +405,6 @@ Graph3dFileView::Draw () { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix(); - glRotatef( m_dYRotate, 0.0, 1.0, 0.0 ); - glRotatef( m_dXRotate, 1.0, 0.0, 0.0 ); - DrawSurface(); glPopMatrix(); @@ -269,38 +415,134 @@ Graph3dFileView::Draw () void Graph3dFileView::InitMaterials() { + if (! GetDocument()) + return; + int nx = GetDocument()->nx(); + int ny = GetDocument()->ny(); + +#if 1 static float ambient[] = {0.1, 0.1, 0.1, 1.0}; - static float diffuse[] = {0.5, 1.0, 1.0, 1.0}; - static float position0[] = {0.0, 0.0, 20.0, 0.0}; - static float position1[] = {0.0, 0.0, -20.0, 0.0}; - static float front_mat_shininess[] = {60.0}; - static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0}; - static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0}; + static float diffuse[] = {1.0, 1.0, 1.0, 1.0}; + static float position0[] = {0, 0, -nx/4, 0, 0.0}; + static float position1[] = {nx/2, ny/2, nx/4, 0.0}; + // static float position0[] = {0.0, 0.0, 20.0, 0.0}; + // static float position1[] = {0.0, 0.0, -20.0, 0.0}; + static float front_mat_shininess[] = {5.0}; + static float front_mat_specular[] = {0.1, 0.1, 0.1, 1.0}; + static float front_mat_diffuse[] = {0.3, 0.3, 0.3, 1.0}; /* static float back_mat_shininess[] = {60.0}; - static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0}; - static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0}; + static float back_mat_specular[] = {0.2, 0.2, 0.2, 1.0}; + static float back_mat_diffuse[] = {1.0, 1.0, 1.0, 1.0}; */ static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0}; static float lmodel_twoside[] = {GL_FALSE}; - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, position0); - glEnable(GL_LIGHT0); + glLightfv (GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv (GL_LIGHT0, GL_POSITION, position0); + glEnable (GL_LIGHT0); - glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT1, GL_POSITION, position1); - glEnable(GL_LIGHT1); + glLightfv (GL_LIGHT1, GL_AMBIENT, ambient); + glLightfv (GL_LIGHT1, GL_DIFFUSE, diffuse); + glLightfv (GL_LIGHT1, GL_POSITION, position1); + glEnable (GL_LIGHT1); + + glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); + glLightModelfv (GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); + + glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess); + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular); + glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse); + + glColorMaterial (GL_FRONT_AND_BACK, GL_DIFFUSE); + // glColorMaterial (GL_FRONT_AND_BACK, GL_SPECULAR); + glEnable(GL_COLOR_MATERIAL); +#else + GLfloat impLPos[] = {1.0, 1.0, 1.0, 0.0}; + + GLfloat defaultLightAmb [] = {.2, .2, .2, 1.0}; + GLfloat defaultLightDiff [] = {.2, .2, .2, 1.0}; + GLfloat defaultLightSpec [] = { .3, .3, .3, 1.0}; + + GLfloat defaultGlobalAmb [] = {.3, .3, .3, 1.0}; + GLfloat defaultGlobalDiff[] = {.3, .3, .3, 1.0}; + + GLfloat defaultMatShine[] = { 30.0 }; + GLfloat defaultMatSpec[] = { .4, .4, .4, 1.0}; + GLfloat defaultMatAmb[] = { .3, .3, .3, 1.0}; + GLfloat defaultMatDiff[] = { .5, .5, .5, 1.0}; + + GLfloat brassMatAmb[] = { .33, .22, .03, 1.0}; + GLfloat brassMatDiff[] = { .78, .57, .11, 1.0}; + GLfloat brassMatSpec[] = { .99, .91, .81, 1.0}; + GLfloat brassMatShine[] = { 27.8 }; + + GLfloat emeraldMatAmb[] = { .021, .1745 , .021, 1.0}; + GLfloat emeraldMatDiff[] = { .075, .6142 , .075, 1.0 }; + GLfloat emeraldMatSpec[] = { .633, .7278 , .633, 1.0 }; + GLfloat emeraldMatShine[] = { 76.8 }; + + GLfloat slateMatAmb[] = { .02, .02 , .02, 1.0 }; + GLfloat slateMatDiff[] = { .02, .01 , .01, 1.0 }; + GLfloat slateMatSpec[] = { .4, .4 , .4 , 1.0 }; + GLfloat slateMatShine[] = { .768 }; + + // double opnX = nx, opnY = ny, opnZ = z; + // eyeX = 1; eyeY = 1, eyeZ = 1; + + impLPos[0] = nx/2.; impLPos[1]= ny/2.; impLPos[2] = 0.; + //opnListNum = 1; + //impGraphicsFlag = IMP__3D; + + // glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGB | GLUT_DEPTH | GLUT_ACCUM); + // glutInitWindowSize (IMP_WIN_X, IMP_WIN_Y); + // glutInitWindowPosition (100, 100); + // glutCreateWindow ("- imp3D graphics -" ); + + glClearColor(0.0, 0.0, 0.0, 0.0); + + glShadeModel (GL_SMOOTH); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glHint(GL_LINE_SMOOTH, GL_DONT_CARE); + glEnable(GL_NORMALIZE); + + + glEnable(GL_DEPTH_TEST); + + glLightfv(GL_LIGHT0, GL_AMBIENT, defaultLightAmb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, defaultLightDiff); + glLightfv(GL_LIGHT0, GL_SPECULAR,defaultLightSpec); + + glLightfv(GL_LIGHT1, GL_AMBIENT, defaultLightAmb); + glLightfv(GL_LIGHT1, GL_DIFFUSE, defaultLightDiff); + glLightfv(GL_LIGHT1, GL_SPECULAR,defaultLightSpec); + + glLightfv(GL_LIGHT2, GL_AMBIENT , defaultLightAmb); + glLightfv(GL_LIGHT2, GL_DIFFUSE , defaultLightDiff); + glLightfv(GL_LIGHT2, GL_SPECULAR, defaultLightSpec); + + glLightfv(GL_LIGHT0, GL_POSITION,impLPos); + glLightfv(GL_LIGHT1, GL_POSITION,impLPos); + glLightfv(GL_LIGHT2, GL_POSITION,impLPos); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT , defaultMatAmb); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE , defaultMatDiff); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR , defaultMatSpec); + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, defaultMatShine); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, defaultGlobalAmb); + + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + + glEnable(GL_COLOR_MATERIAL); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); - glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); glEnable(GL_LIGHTING); + glEnable(GL_LIGHT1); + glEnable(GL_LIGHT2); + glEnable(GL_LIGHT0); +#endif - glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse); } @@ -309,59 +551,38 @@ Graph3dFileView::InitGL () { glClearColor(0.0, 0.0, 0.0, 0.0); - glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); - InitMaterials(); +} + +void +Graph3dFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) +{ + int nVertices = GetDocument()->m_nVertices; + glTripleFloat* pVertices = GetDocument()->m_pVertices; + glTripleFloat* pNormals = GetDocument()->m_pNormals; glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 ); + if (! GetDocument()) + return; + int nx = GetDocument()->nx(); + int ny = GetDocument()->ny(); + int maxDim = maxValue (nx, ny); + glOrtho (-maxDim * 0.71, maxDim * 0.71, -maxDim * 0.71, maxDim * 0.71, maxDim * 0.71, -maxDim * 0.71); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslatef( 0.0, 0.0, -6.0 ); + #ifdef GL_EXT_vertex_array if (m_bUseVertexArrays) { - // glVertexPointerEXT( 3, GL_FLOAT, 0, m_nVerts, verts ); - // glNormalPointerEXT( GL_FLOAT, 0, m_nVerts, norms ); + // glVertexPointerEXT( 3, GL_FLOAT, 0, nVertices, pVertices ); + // glNormalPointerEXT( GL_FLOAT, 0, nVertices, pNormals ); glEnable( GL_VERTEX_ARRAY_EXT ); glEnable( GL_NORMAL_ARRAY_EXT ); } #endif -} - -void -Graph3dFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) ) -{ - const ImageFile& rIF = GetDocument()->getImageFile(); - ImageFileArrayConst v = rIF.getArray(); - int nx = rIF.nx(); - int ny = rIF.ny(); - if (v != NULL && nx != 0 && ny != 0) { -#if 0 - unsigned char* imageData = new unsigned char [nx * ny * 3]; - for (int ix = 0; ix < nx; ix++) { - for (int iy = 0; iy < ny; iy++) { - double scaleValue = ((v[ix][iy] - m_dMinPixel) / scaleWidth) * 255; - int intensity = static_cast(scaleValue + 0.5); - intensity = clamp (intensity, 0, 255); - int baseAddr = ((ny - 1 - iy) * nx + ix) * 3; - imageData[baseAddr] = imageData[baseAddr+1] = imageData[baseAddr+2] = intensity; - } - } - wxImage image (nx, ny, imageData, true); - m_bitmap = image.ConvertToBitmap(); - delete imageData; - int xSize = nx; - int ySize = ny; - ySize = clamp (ySize, 0, 800); - m_pFrame->SetClientSize (xSize, ySize); - m_pCanvas->SetScrollbars(20, 20, nx/20, ny/20); - m_pCanvas->SetBackgroundColour(*wxWHITE); -#endif - } if (m_pCanvas) m_pCanvas->Refresh(); @@ -408,19 +629,18 @@ Graph3dFileView::CreateChildFrame (wxDocument *doc, wxView *view) #endif theApp->setIconForFrame (subframe); + m_statusBar.Create (subframe, -1); + subframe->SetStatusBar (&m_statusBar); + m_pFileMenu = new wxMenu; m_pFileMenu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...\tCtrl-P"); m_pFileMenu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...\tCtrl-F"); m_pFileMenu->Append(wxID_OPEN, "&Open...\tCtrl-O"); - m_pFileMenu->Append(wxID_SAVE, "&Save\tCtrl-S"); - m_pFileMenu->Append(wxID_SAVEAS, "Save &As..."); m_pFileMenu->Append(wxID_CLOSE, "&Close\tCtrl-W"); - m_pFileMenu->Append(wxID_REVERT, "Re&vert"); m_pFileMenu->AppendSeparator(); m_pFileMenu->Append(IFMENU_FILE_PROPERTIES, "P&roperties"); - m_pFileMenu->Append(IFMENU_FILE_EXPORT, "&Export..."); m_pFileMenu->AppendSeparator(); m_pFileMenu->Append(wxID_PRINT, "&Print..."); @@ -433,35 +653,11 @@ Graph3dFileView::CreateChildFrame (wxDocument *doc, wxView *view) GetDocumentManager()->FileHistoryAddFilesToMenu(m_pFileMenu); GetDocumentManager()->FileHistoryUseMenu(m_pFileMenu); - wxMenu *view_menu = new wxMenu; - view_menu->Append(IFMENU_VIEW_SCALE_MINMAX, "Display Scale S&et...\tCtrl-E"); - view_menu->Append(IFMENU_VIEW_SCALE_AUTO, "Display Scale &Auto...\tCtrl-A"); - view_menu->Append(IFMENU_VIEW_SCALE_FULL, "Display F&ull Scale\tCtrl-U"); - - wxMenu* filter_menu = new wxMenu; - filter_menu->Append (IFMENU_FILTER_INVERTVALUES, "&Invert Values"); - filter_menu->Append (IFMENU_FILTER_SQUARE, "&Square"); - filter_menu->Append (IFMENU_FILTER_SQRT, "Square &Root"); - filter_menu->Append (IFMENU_FILTER_LOG, "&Log"); - filter_menu->Append (IFMENU_FILTER_EXP, "&Exp"); - filter_menu->AppendSeparator(); -#ifdef HAVE_FFT - filter_menu->Append (IFMENU_FILTER_FFT, "2D &FFT"); - filter_menu->Append (IFMENU_FILTER_IFFT, "2D &IFFT"); - filter_menu->Append (IFMENU_FILTER_FFT_ROWS, "FFT Rows"); - filter_menu->Append (IFMENU_FILTER_IFFT_ROWS, "IFFT Rows"); - filter_menu->Append (IFMENU_FILTER_FFT_COLS, "FFT Columns"); - filter_menu->Append (IFMENU_FILTER_IFFT_COLS, "IFFT Columns"); - filter_menu->Append (IFMENU_FILTER_FOURIER, "F&ourier"); - filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "Inverse Fo&urier"); -#else - filter_menu->Append (IFMENU_FILTER_FOURIER, "&Fourier"); - filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "&Inverse Fourier"); -#endif - filter_menu->Append (IFMENU_FILTER_SHUFFLEFOURIERTONATURALORDER, "S&huffle Fourier to Natural Order"); - filter_menu->Append (IFMENU_FILTER_SHUFFLENATURALTOFOURIERORDER, "Shu&ffle Natural to Fourier Order"); - filter_menu->Append (IFMENU_FILTER_MAGNITUDE, "&Magnitude"); - filter_menu->Append (IFMENU_FILTER_PHASE, "&Phase"); + m_pViewMenu = new wxMenu; + m_pViewMenu->Append(GRAPH3D_VIEW_SURFACE, "&Surface\tCtrl-U", "", true); + m_pViewMenu->Append(GRAPH3D_VIEW_SMOOTH, "&Smooth\tCtrl-M", "", true); + m_pViewMenu->Append(GRAPH3D_VIEW_COLOR, "&Color\tCtrl-R", "", true); + m_pViewMenu->Append(GRAPH3D_VIEW_LIGHTING, "&Lighting\tCtrl-L", "", true); wxMenu *help_menu = new wxMenu; help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents\tF1"); @@ -471,8 +667,7 @@ Graph3dFileView::CreateChildFrame (wxDocument *doc, wxView *view) wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(m_pFileMenu, "&File"); - menu_bar->Append(view_menu, "&View"); - menu_bar->Append(filter_menu, "Fi<er"); + menu_bar->Append(m_pViewMenu, "&View"); menu_bar->Append(help_menu, "&Help"); subframe->SetMenuBar(menu_bar); @@ -481,16 +676,15 @@ Graph3dFileView::CreateChildFrame (wxDocument *doc, wxView *view) wxAcceleratorEntry accelEntries[10]; accelEntries[0].Set (wxACCEL_CTRL, static_cast('O'), wxID_OPEN); - accelEntries[1].Set (wxACCEL_CTRL, static_cast('S'), wxID_SAVE); - accelEntries[2].Set (wxACCEL_CTRL, static_cast('W'), wxID_CLOSE); - accelEntries[3].Set (wxACCEL_CTRL, static_cast('H'), MAINMENU_HELP_TOPICS); - accelEntries[4].Set (wxACCEL_CTRL, static_cast('P'), MAINMENU_FILE_CREATE_PHANTOM); - accelEntries[5].Set (wxACCEL_CTRL, static_cast('F'), MAINMENU_FILE_CREATE_FILTER); - accelEntries[6].Set (wxACCEL_NORMAL, WXK_F1, MAINMENU_HELP_CONTENTS); - accelEntries[7].Set (wxACCEL_CTRL, static_cast('A'), IFMENU_VIEW_SCALE_AUTO); - accelEntries[8].Set (wxACCEL_CTRL, static_cast('U'), IFMENU_VIEW_SCALE_FULL); - accelEntries[9].Set (wxACCEL_CTRL, static_cast('E'), IFMENU_VIEW_SCALE_MINMAX); - wxAcceleratorTable accelTable (10, accelEntries); + accelEntries[1].Set (wxACCEL_CTRL, static_cast('H'), MAINMENU_HELP_TOPICS); + accelEntries[2].Set (wxACCEL_CTRL, static_cast('P'), MAINMENU_FILE_CREATE_PHANTOM); + accelEntries[3].Set (wxACCEL_CTRL, static_cast('F'), MAINMENU_FILE_CREATE_FILTER); + accelEntries[4].Set (wxACCEL_NORMAL, WXK_F1, MAINMENU_HELP_CONTENTS); + accelEntries[5].Set (wxACCEL_CTRL, static_cast('U'), GRAPH3D_VIEW_SURFACE); + accelEntries[6].Set (wxACCEL_CTRL, static_cast('R'), GRAPH3D_VIEW_COLOR); + accelEntries[7].Set (wxACCEL_CTRL, static_cast('L'), GRAPH3D_VIEW_LIGHTING); + accelEntries[8].Set (wxACCEL_CTRL, static_cast('M'), GRAPH3D_VIEW_SMOOTH); + wxAcceleratorTable accelTable (9, accelEntries); subframe->SetAcceleratorTable (accelTable); return subframe; @@ -554,9 +748,8 @@ Graph3dFileCanvas::OnChar(wxKeyEvent& event) if (! m_pView) return; - switch(event.KeyCode()) { - case WXK_ESCAPE: - exit(0); + wxCommandEvent dummyEvent; + switch (event.KeyCode()) { case WXK_LEFT: m_pView->m_dYRotate -= 15.0; break; @@ -569,21 +762,20 @@ Graph3dFileCanvas::OnChar(wxKeyEvent& event) case WXK_DOWN: m_pView->m_dXRotate -= 15.0; break; + case 'z': case 'Z': + m_pView->m_dZRotate += 15.0; + break; + case 'x': case 'X': + m_pView->m_dZRotate -= 15.0; + break; case 's': case 'S': - m_pView->m_bSmooth = !m_pView->m_bSmooth; - if (m_pView->m_bSmooth) { - glShadeModel(GL_SMOOTH); - } else { - glShadeModel(GL_FLAT); - } + m_pView->OnSmooth (dummyEvent); break; case 'l': case 'L': - m_pView->m_bLighting = !m_pView->m_bLighting; - if (m_pView->m_bLighting) { - glEnable(GL_LIGHTING); - } else { - glDisable(GL_LIGHTING); - } + m_pView->OnLighting (dummyEvent); + break; + case 'c': case 'C': + m_pView->OnColor (dummyEvent); break; default: { @@ -592,13 +784,13 @@ Graph3dFileCanvas::OnChar(wxKeyEvent& event) } } - Refresh(FALSE); + Refresh (false); } void Graph3dFileCanvas::Reshape (int width, int height) { - glViewport(0, 0, (GLint)width, (GLint)height); + glViewport (0, 0, (GLint)width, (GLint)height); } @@ -608,8 +800,11 @@ Graph3dFileCanvas::OnMouseEvent(wxMouseEvent& event) static int dragging = 0; static float last_x, last_y; + if (! m_pView) + return; + if(event.LeftIsDown()) { - if(!dragging) { + if(! dragging) { dragging = 1; } else { m_pView->m_dXRotate += (event.GetX() - last_x)*1.0; @@ -631,3 +826,4 @@ Graph3dFileCanvas::OnEraseBackground(wxEraseEvent& event) +#endif // wxUSE_GLCANVAS