// Geo3View.cpp : реализация класса CGeo3View // #include "stdafx.h" #include "Geo3.h" #include "Geo3Doc.h" #include "Geo3View.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CGeo3View IMPLEMENT_DYNCREATE(CGeo3View, CView) BEGIN_MESSAGE_MAP(CGeo3View, CView) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() END_MESSAGE_MAP() // создание/уничтожение CGeo3View CGeo3View::CGeo3View() { // TODO: добавьте код создания } CGeo3View::~CGeo3View() { } BOOL CGeo3View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: изменить класс Window или стили посредством изменения // CREATESTRUCT cs cs.style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS; return CView::PreCreateWindow(cs); } // рисование CGeo3View void CGeo3View::OnDraw(CDC* pDC) { CGeo3Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; wglMakeCurrent(pDC->m_hDC, m_hRC); glClearColor(1.0f,1.0f, 1.0f , 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); CRect rect; GetClientRect(&rect); glMatrixMode(GL_PROJECTION); glViewport(0,0,rect.Width(),rect.Height()); glLoadIdentity(); gluOrtho2D(0,rect.Width(),0,rect.Height()); // Отступ слева const int OffsetLeft = 30; // Отступ справа const int OffsetRight = 30; // Отступ сверху const int OffsetTop = 30; // Отступ снизу const int OffsetBottom = 30; // Тестовые данные для вывода интерполяции /* const int size = 10; double Data[] = {50,400,150,180,200,350,200,500,150,78}; //double Data[] = {50,50,50,50,400,400,400,400,50,250}; double valX[] = {0,1,2,3,4,5,6,7,8,9}; */ spline1dinterpolant c; real_1d_array a; real_1d_array x; real_1d_array y; ae_int_t n = testsize; x.setcontent(testsize,testX); y.setcontent(testsize,testData); // Вычисляем сплайн Акимы spline1dbuildakima(x,y,n,c); // Задаём масштаб по оси OY double scaleOY = 100.0; // Задаём масштаб по оси OX double scaleOX; // Указываем скакой позиции i выводить данные int startData = 200; // Указываем на какой позиции i закончить вывод данных int endData = testsize; // endData > startData // Шаг между по OX между отчётами (не интерполироваными) double dk = (rect.Width() - (OffsetRight + OffsetLeft)) / (double)(endData - startData) ; // Смещение по оси OY (добавление постоянной состовляющей, чтобы график начинался из середины OY) double whalf = (rect.Height() - (OffsetRight + OffsetLeft)) / 2.0; // Шаг по интерполяциооной функции double dt; dt = 1.0 / dk; int k = 0; double currentVal; double tt = 0; double ti = 0; // Выводим интерполированные данные glLineWidth(1.3f); glColor3d(1,0,0); glBegin(GL_LINE_STRIP); for(int i = 0; i < (endData - startData); ++i) { for(double t = 0.0; t < 1; t = t + dt) { ti = t+i; currentVal = OffsetBottom + whalf + scaleOY * spline1dcalc(c,startData+ti); tt = dk*(t+i) + OffsetLeft; glVertex2d(tt,currentVal); } } glEnd(); // Рисуем оси координат glLineWidth(2.0f); glColor3d(0,0,0); glBegin(GL_LINES); // Ось OY glVertex2d(OffsetLeft,OffsetBottom); glVertex2d(OffsetLeft,rect.Height() - OffsetBottom); // Ось OX glVertex2d(OffsetLeft,OffsetBottom); glVertex2d(rect.Width()-OffsetRight,OffsetBottom); glEnd(); // Рисуем сетку кординат glDisable(GL_LINE_SMOOTH); glLineWidth(1.0f); glColor4d(0,0,0,0.2f); const int gridDX = 10; const int gridDY = 15; int offsetLineGrid; int curGrid; // Чертим ось OX offsetLineGrid = (rect.Width() - (OffsetLeft + OffsetRight)) / gridDX; curGrid = OffsetLeft + offsetLineGrid; glBegin(GL_LINES); for(int i = 0; i < gridDX; i++) { glVertex2d(curGrid,OffsetBottom); glVertex2d(curGrid,rect.Height()-OffsetBottom); curGrid = curGrid + offsetLineGrid; } glEnd(); // Риски на оси OX glLineWidth(1.0f); glColor4d(0,0,0,1.0f); const int HeightMarkX = 3; curGrid = OffsetLeft + offsetLineGrid; glBegin(GL_LINES); for(int i = 0; i < gridDX; i++) { glVertex2d(curGrid,OffsetBottom+HeightMarkX); glVertex2d(curGrid,OffsetBottom-HeightMarkX); curGrid = curGrid + offsetLineGrid; } glEnd(); // Чертим ось OY offsetLineGrid = (rect.Height() - (OffsetBottom + OffsetTop)) / gridDY; curGrid = OffsetBottom + offsetLineGrid; glBegin(GL_LINES); glColor4d(0,0,0,0.2f); for(int i = 0; i < gridDY; i++) { glVertex2d(OffsetLeft,curGrid); glVertex2d(rect.Width() - OffsetRight,curGrid); curGrid = curGrid + offsetLineGrid; } glEnd(); // Риски на оси OY glLineWidth(1.0f); glColor4d(0,0,0,1.0f); const int HeightMarkY = 3; curGrid = OffsetBottom + offsetLineGrid; glBegin(GL_LINES); for(int i = 0; i < gridDY; i++) { glVertex2d(OffsetLeft-HeightMarkY,curGrid); glVertex2d(OffsetLeft+HeightMarkY,curGrid); curGrid = curGrid + offsetLineGrid; } glEnd(); glShadeModel(GL_SMOOTH); // Enable Smooth Shading 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); glEnable(GL_LIGHT0); // Включить встроенное освещение (черновое) (новая) glEnable(GL_LIGHTING); // Разрешить освещение (новая) glEnable(GL_COLOR_MATERIAL); // Включить раскраску материалов (новая) glLoadIdentity(); // Сброс вида glTranslatef(0.0f,0.0f,-10.0f); // Смещение на 10 единиц в экран //glColor3f(1.0f,1.0f,1.0f); glRasterPos2f(100, 10); glPrint("aaabbb"); // Обмениваемся буферами (передний с задним) SwapBuffers(pDC->m_hDC); //pDC->TextOut(100,100,L"ddfdfd"); wglMakeCurrent(pDC->m_hDC, NULL); } // диагностика CGeo3View #ifdef _DEBUG void CGeo3View::AssertValid() const { CView::AssertValid(); } void CGeo3View::Dump(CDumpContext& dc) const { CView::Dump(dc); } CGeo3Doc* CGeo3View::GetDocument() const // встроена неотлаженная версия { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGeo3Doc))); return (CGeo3Doc*)m_pDocument; } #endif //_DEBUG int CGeo3View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; int nPixelFormat; // Pixel format index CClientDC dcClient(this); // Get the device context m_hDC = dcClient.m_hDC; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure 1, // Version of this PFD_DRAW_TO_WINDOW | // Draw to Window PFD_SUPPORT_OPENGL | // Support OpenGL in window PFD_DOUBLEBUFFER, // Double-buffered mode PFD_TYPE_RGBA, // RGBA color mode 24, // Want 24bit color 0,0,0,0,0,0, // Not used to select mode 0,0, // Not used to select mode 0,0,0,0,0, // Not used to select mode 32, // Size of depth buffer 0, // Not used to select mode 0, // Not used to select mode PFD_MAIN_PLANE, // Draw in main plane 0, // Not used to select mode 0,0,0 }; // Not used to select mode int iPixelFormat = ChoosePixelFormat(dcClient.m_hDC,&pfd); if ( !iPixelFormat ) { // This system cannot run OpenGL TRACE(L"Error retrieving pixel format index...\n"); ASSERT(FALSE); AfxMessageBox(L"Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if if ( !SetPixelFormat(dcClient.m_hDC,iPixelFormat,&pfd) ) { // This system cannot run OpenGL TRACE(L"Error setting new pixel format...\n"); ASSERT(FALSE); AfxMessageBox(L"Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if // Update the PIXELFORMATDESCRIPTOR structure once // the device context has been modified. DescribePixelFormat(dcClient.m_hDC,iPixelFormat, sizeof(pfd),&pfd); // The PIXELFORMATDESCRIPTOR has been updated, so we now // determine whether to create and manage a custom // palette. if ( pfd.dwFlags & PFD_NEED_PALETTE ) { // We do, so build a new palette... } // if // Create the OpenGL rendering context m_hRC = wglCreateContext(dcClient.m_hDC); if ( m_hRC == NULL ) { // This system cannot run OpenGL TRACE(L"Error creating OpenGL rendering context...\n"); ASSERT(FALSE); AfxMessageBox(L"Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if glClearColor(1.0f,1.0f, 1.0f , 1.0f); wglMakeCurrent(dcClient.m_hDC,NULL); BuildFont(); double F = 10; double Fs = 1024.0; double Am = 1.0; testsize = 1000; testData = new double[testsize]; testX = new double[testsize]; //CFile file; //file.Open(L"..//log.txt",CFile::modeCreate|CFile::modeWrite,NULL); //CString strlog; for(int i = 0; i < testsize; ++i) { testData[i] = Am*sin(2*pi()*F/Fs*i); testX[i] = (double)i; // strlog.Format(L"Val = %2.4f x = %f \n",testData[i],testX[i]); // file.Write(strlog,strlog.GetLength()*2); } //CSplitterWnd splitWnd; //splitWnd.Create(this->GetParent(),0,0,CSize(200,200),NULL,WS_HSCROLL | WS_VSCROLL|SPLS_DYNAMIC_SPLIT,NULL); return 0; } void CGeo3View::OnDestroy() { // Shut down OpenGL by deleting the rendering context wglDeleteContext(m_hRC); } void CGeo3View::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); CClientDC dcClient(this); wglMakeCurrent(dcClient.m_hDC,m_hRC); CRect rect; GetClientRect(&rect); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0,0,rect.Width(),rect.Height()); glLoadIdentity(); gluOrtho2D(0,rect.Width(),0,rect.Height()); glClear(GL_COLOR_BUFFER_BIT); wglMakeCurrent(NULL,NULL); } GLvoid CGeo3View::BuildFont() // Build Our Bitmap Font { base = glGenLists(96); // Storage For 96 Characters font = CreateFont( -12, // Height Of Font 0, // Width Of Font 0, // Angle Of Escapement 0, // Orientation Angle FW_BOLD, // Font Weight FALSE, // Italic FALSE, // Underline FALSE, // Strikeout ANSI_CHARSET, // Character Set Identifier OUT_TT_PRECIS, // Output Precision CLIP_DEFAULT_PRECIS, // Clipping Precision ANTIALIASED_QUALITY, // Output Quality FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch L"Courier New"); // Font Name oldfont = (HFONT)SelectObject(m_hDC, font); // Selects The Font We Want wglUseFontBitmaps(m_hDC, 32, 96, base); // Builds 96 Characters Starting At Character 32 SelectObject(m_hDC, oldfont); // Selects The Font We Want DeleteObject(font); // Delete The Font } GLvoid CGeo3View::KillFont(GLvoid) // Delete The Font List { glDeleteLists(base, 96); // Delete All 96 Characters } GLvoid CGeo3View::glPrint(const char *fmt, ...) // Custom GL "Print" Routine { char text[256]; // Holds Our String va_list ap; // Pointer To List Of Arguments if (fmt == NULL) // If There's No Text return; // Do Nothing va_start(ap, fmt); // Parses The String For Variables vsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbers va_end(ap); // Results Are Stored In Text glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits glListBase(base-32); // Sets The Base Character to 32 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text glPopAttrib(); // Pops The Display List Bits }