// OpenGLRenderer.cpp : implementation file // #include "stdafx.h" #include "OpenGLRenderer.h" // OpenGLRenderer //---------------------------------------------------------------------------- OpenGLRenderer::OpenGLRenderer( void) { m_hdc = nullptr ; m_hrc = nullptr ; memset( &m_wglewc, 0, sizeof( WGLEWContext)) ; memset( &m_glewc, 0, sizeof( GLEWContext)) ; } //---------------------------------------------------------------------------- OpenGLRenderer::~OpenGLRenderer( void) { } //---------------------------------------------------------------------------- BEGIN_MESSAGE_MAP( OpenGLRenderer, CWnd) END_MESSAGE_MAP() // OpenGLRenderer message handlers bool OpenGLRenderer::CreateGLContext( CRect rect, CWnd *parent) { CString className = AfxRegisterWndClass( CS_HREDRAW | CS_VREDRAW | CS_OWNDC, NULL, (HBRUSH)GetStockObject(WHITE_BRUSH), NULL) ; //default background colour CreateEx( 0, className, _T("OpenGL with MFC/CDialog"), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0) ; m_rectWin = rect ; if ( ! InitContext()) { MessageBox( _T("ERROR Creating InitContext")) ; return false ; } // Setup the OpenGL Window's timer to render //m_unpTimer = SetTimer( 1, 20, 0) ; return true ; } //---------------------------------------------------------------------------- bool OpenGLRenderer::InitContext( void) { PIXELFORMATDESCRIPTOR pfd ; memset( &pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)) ; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR) ; pfd.nVersion = 1 ; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW ; pfd.iPixelType = PFD_TYPE_RGBA ; pfd.cColorBits = 32 ; pfd.cDepthBits = 32 ; pfd.iLayerType = PFD_MAIN_PLANE ; m_hdc = GetDC()->m_hDC ; int nPixelFormat = ChoosePixelFormat( m_hdc, &pfd) ; if ( nPixelFormat == 0) return false ; BOOL bResult = SetPixelFormat (m_hdc, nPixelFormat, &pfd) ; if ( ! bResult) return false ; HGLRC tempContext = wglCreateContext( m_hdc) ; wglMakeCurrent( m_hdc, tempContext) ; GLenum WglewInitResult ; WglewInitResult = wglewInit() ; if ( WglewInitResult != GLEW_OK) { AfxMessageBox( _T("WGLEW is not initialized!")) ; } int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //WGL_CONTEXT_FLAGS_ARB, 0, 0 }; if ( wglewIsSupported( "WGL_ARB_create_context") == 1) { m_hrc = wglCreateContextAttribsARB( m_hdc, 0, attribs) ; wglMakeCurrent( m_hdc, NULL) ; wglDeleteContext( tempContext) ; wglMakeCurrent( m_hdc, m_hrc) ; } else { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before) m_hrc = tempContext; } if ( ! m_hrc) return false; GLenum GlewInitResult; glewExperimental = GL_TRUE ; GlewInitResult = glewInit() ; if ( GlewInitResult != GLEW_OK) { AfxMessageBox( _T("GLEW is not initialized!")) ; } CString str; str.Format(_T("OpenGL version: %s\n"),(CString)glGetString(GL_VERSION)); TRACE(str); return true; } //---------------------------------------------------------------------------- void OpenGLRenderer::PrepareScene( void) { wglMakeCurrent( m_hdc, m_hrc) ; glClearColor(0.0, 0.0, 1.0, 0.0); //background to clear with. GLenum qq = glGetError() ; //do other preparations here glMatrixMode( GL_PROJECTION) ; qq = glGetError() ; glLoadIdentity() ; qq = glGetError() ; glOrtho( -10, 10, -10, 10, 1, 1000) ; qq = glGetError() ; glMatrixMode( GL_MODELVIEW) ; qq = glGetError() ; glLoadIdentity() ; qq = glGetError() ; gluLookAt( 0, 0, 10, 0, 0, -100, 0, 1, 0) ; qq = glGetError() ; wglMakeCurrent( m_hdc, NULL) ; } //---------------------------------------------------------------------------- void OpenGLRenderer::Reshape( int nW, int nH) { if ( m_hdc == NULL) return ; m_rectWin.SetRect( m_rectWin.left, m_rectWin.top, m_rectWin.left + nW, m_rectWin.top + nH) ; MoveWindow( m_rectWin, FALSE) ; if ( wglMakeCurrent( m_hdc, m_hrc)) glViewport( 0, 0, (GLsizei)nW, (GLsizei)nH) ; wglMakeCurrent( m_hdc, NULL) ; DrawScene() ; } //---------------------------------------------------------------------------- void OpenGLRenderer::DrawScene( void) { wglMakeCurrent( m_hdc, m_hrc) ; //-------------------------------- //-------------------------------- glClear( GL_COLOR_BUFFER_BIT) ; for ( int i=0; i<2; i++) { if ( m_vaoID[i] != 0) { glBindVertexArray( m_vaoID[i]) ; glDrawArrays( GL_LINE_STRIP, 0, m_GLSizeCount) ; } } //-------------------------------- glFlush() ; SwapBuffers( m_hdc) ; wglMakeCurrent( m_hdc, NULL) ; } //---------------------------------------------------------------------------- void OpenGLRenderer::SetData( int iType) { const int SQUARE = 1 ; //const int CUBE = 2 ; const int TRIANGLE = 3 ; m_iShapeType = iType ; switch ( iType) { case SQUARE : SetSquare() ; break; case TRIANGLE: SetTriangle() ; break; default: SetTriangle() ; } } //---------------------------------------------------------------------------- void OpenGLRenderer::SetSquare( void) { wglMakeCurrent( m_hdc, m_hrc) ; // First simple object m_GLSizeCount = 5 ; m_GLIntSize = 4 ; GLfloat Square[] = { -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.0f, 1.0f } ; // inizializzo VAOs a non allocati m_vaoID[0] = 0 ; m_vaoID[1] = 0 ; // VAO allocation glGenVertexArrays( 1, &m_vaoID[0]) ; if ( m_vaoID[0] == 0) return ; // First VAO setup glBindVertexArray( m_vaoID[0]) ; glGenBuffers( 1, &m_vboID[0]) ; glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0]) ; glBufferData( GL_ARRAY_BUFFER, sizeof( Square), Square, GL_STATIC_DRAW) ; glVertexAttribPointer( (GLuint)0, m_GLIntSize, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; wglMakeCurrent( m_hdc, NULL) ; } //---------------------------------------------------------------------------- void OpenGLRenderer::SetTriangle( void) { wglMakeCurrent( m_hdc, m_hrc) ; m_GLIntSize = 4; //number of floats per item. i.e. number of floats per point in space. m_GLSizeCount = 4; //number of items. ie sizeof(TriangleA)/m_GLIntSize GLfloat TriangleA[] = { -0.3f, 0.5f, -1.0f, 1.0f, -0.8f, -0.5f, -1.0f, 1.0f, 0.2f, -0.5f, -1.0f, 1.0f, -0.3f, 0.5f, -1.0f, 1.0f } ; GLfloat TriangleB[] = { -0.2f, 0.5f, -1.0f, 1.0f, 0.3f, -0.5f, -1.0f, 1.0f, 0.8f, 0.5f, -1.0f, 1.0f, -0.2f, 0.5f, -1.0f, 1.0f } ; // inizializzo VAOs a non allocati m_vaoID[0] = 0 ; m_vaoID[1] = 0 ; // VAOs allocation glGenVertexArrays( 2, &m_vaoID[0]) ; // First VAO setup glBindVertexArray( m_vaoID[0]) ; glGenBuffers( 1, &m_vboID[0]) ; //VBO allocation glBindBuffer( GL_ARRAY_BUFFER, m_vboID[0]) ; glBufferData( GL_ARRAY_BUFFER, sizeof(TriangleA), TriangleA, GL_STATIC_DRAW) ; glVertexAttribPointer( (GLuint)0, m_GLIntSize, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; // Second VAO setup glBindVertexArray( m_vaoID[1]) ; glGenBuffers( 1, &m_vboID[1]) ; //VBO allocation glBindBuffer( GL_ARRAY_BUFFER, m_vboID[1]) ; glBufferData( GL_ARRAY_BUFFER, sizeof(TriangleB), TriangleB, GL_STATIC_DRAW) ; glVertexAttribPointer( (GLuint)0, m_GLIntSize, GL_FLOAT, GL_FALSE, 0, 0) ; glEnableVertexAttribArray( 0) ; glBindVertexArray( 0) ; wglMakeCurrent( m_hdc, NULL) ; } //---------------------------------------------------------------------------- void OpenGLRenderer::DestroyScene( void) { wglMakeCurrent( m_hdc, m_hrc) ; glBindBuffer( GL_ARRAY_BUFFER, 0) ; glDeleteBuffers( 2, m_vboID) ; glBindVertexArray( 0) ; glDeleteVertexArrays( 2, m_vaoID) ; wglMakeCurrent( nullptr, nullptr) ; if ( m_hrc != nullptr) { wglDeleteContext( m_hrc) ; m_hrc = nullptr ; } }