Programming with Visual Studio MFC and OpenGL Outline • Creating a project • Adding OpenGL initialization code and libraries • Creating a mouse event • Drawing with OpenGL • Saving information to use later (Point data) • Relevant Questions about OpenGL/MFC Creating a Project in Visual Studio Creating a Project in Visual Studio Creating a Project in Visual Studio Creating a Project in Visual Studio • Header File – Code that need to be added for OpenGL HDC m_hDC; HGLRC m_hGLContext; BOOL SetWindowPixelFormat(HDC hDC); BOOL CreateViewGLContext(HDC hDC); int m_GLPixelIndex; afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() //already in .h file Creating a Project in Visual Studio • Need to make sure the messages are getting sent/received - .cpp file BEGIN_MESSAGE_MAP(CCssample1View, CView) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SIZE() // 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() Creating a Project in Visual Studio BOOL CCssample1View::CreateViewGLContext(HDC hDC){ m_hGLContext = wglCreateContext(m_hDC); if (m_hGLContext == NULL) return FALSE; if (wglMakeCurrent(m_hDC, m_hGLContext)==FALSE) return FALSE; return TRUE; } Creating a Project in Visual Studio int CCssample1View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; HWND hWnd = GetSafeHwnd(); m_hDC = ::GetDC(hWnd); if (SetWindowPixelFormat(m_hDC)==FALSE) return 0; if (CreateViewGLContext(m_hDC)==FALSE) return 0; return 0; } Creating a Project in Visual Studio void CCssample1View::OnDestroy() { CView::OnDestroy(); if(wglGetCurrentContext()!=NULL) { // make the rendering context not current wglMakeCurrent(NULL, NULL) ; } if (m_hGLContext!=NULL){ wglDeleteContext(m_hGLContext); m_hGLContext = NULL; } // Now the associated DC can be released. CView::OnDestroy(); } Creating a Project in Visual Studio void CCssample1View::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, width, 0.0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // for double buffering glDrawBuffer(GL_BACK); } Creating a Project in Visual Studio • BOOL CCssample1View::SetWindowPixelFormat(HDC hdc){…} • This function is pretty big, in the interest of space, here is a link to a site that shows how it is done. This site also goes over the stuff mentioned here in more detail about creating the project. • http://web.agelid.com/protect/utile/documentation/OpenGL/Example%2 01%20-%20Writing%20an%20OpenGL%20Program.htm Creating a Project in Visual Studio • The previously mentioned functions and variables will allow you to use OpenGL with your project once they are added. • This code below must also be added to your OnDraw function to get the render context. //openGL code CRect rcClient; GetClientRect(rcClient); Adding OpenGL initialization code • The following code can be added to your OnDraw function. //openGL code glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, width, 0.0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); Adding OpenGL Libraries Adding OpenGL Libraries Adding OpenGL Libraries Adding OpenGL Libraries (Paths) Adding OpenGL Libraries (Paths) Creating a mouse event • afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //added to header file • ON_WM_LBUTTONDOWN() //added to message map at top of cpp file • void CCssample1View::OnLButtonDown(UINT nFlags, CPoint point) { //code to be exectud when Lbutton is pressed down } Drawing with OpenGL glBegin(GL_LINES); glVertex3d(100, height-100, 0); //height-100 is to make sure point is actually at 100, 100. It actually starts at bottom left of screen glVertex3d(200, height-200, 0); glEnd(); The above code draws a line from coordinates (100, 100) to (200, 200). Drawing with OpenGL • Primitives you can draw with OpenGL – glBegin(GL_LINES); – glBegin(GL_POINTS); – glBegin(GL_TRIANGLES); – glBegin(GL_LINE_LOOP); • There are others, these are just a few that you will most likely use. Saving info to use later (Point data) • Suppose we have a right button press event void CCssample1View::OnRButtonDown(UINT nFlags, CPoint point) { line savedLine; savedLine.start = start; //start variable was found with a left button press, save now savedLine.end = point; //save the point where the right click occurred savedLinesVector.push_back(savedLine); //save line into vector } //in the header file, in the class itself struct savedLine{ CPoint start, end; //Cpoint is mfc defined type }; vector <savedLine> savedLinesVector; //vector of type savedLine Saving info to use later (Point data) for(unsigned i=0; i<savedLinesVector.size(); i++){ //iterate through vector printing lines glBegin(GL_LINES); //this can be outside for loop also, depending on what you are doing glVertex2d(savedLinesVector[i].start.x, savedLinesVector[i].start.y); glVertex2d(savedLinesVector[i].end.x, savedLinesVector[i].end.y); glEnd(); } //this will draw all lines to the screen, this is done in the OnDraw function Relevant Questions about OpenGL/MFC • How do I read pixels from the screen in OpenGL? – glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *data); – If you wanted to read one pixel at (100, 100): • glReadPixels(100, 100, 1, 1, GL_RGB, GL_BYTE, data); • The variable data is where the pixel information is stored • How do I change the color of pixel(s)? – glColor3f(1.0, 0.0, 0.0); //red color • How do I clear the buffer? – glClear(GL_COLOR_BUFFER_BIT); • What is the CPoint type? – It allows you to gain access to the x, y coordinates at a particular point. Ex: CPoint p1; // variable p1 of type CPoint p1.x; //x coordinate at point p1.y; //y coordinate at point