317 lines
8.4 KiB
C++
317 lines
8.4 KiB
C++
// 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 ;
|
|
}
|
|
}
|