Following is my open gl window class. when I try and create multiples of the class, to share the textures loaded, only one of the windows displays the textures correctly. Sometimes my textures get moved around. Could someone point out my error, perhaps in the init or the create functions?
Thanks in advanced.
My code:
class OpenGLDisplayClass : public CWnd
{
public:
OpenGLDisplayClass();
virtual BOOL Create(CWnd*, const RECT&, int TypeOfWindow = 0);
virtual void Update();
virtual void Display(){};
void ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection = 0);
void MakeContextCurrent(BOOL onOff);
~OpenGLDisplayClass();
protected:
// declare event functions
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize (UINT, int, int);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
DECLARE_MESSAGE_MAP ()
void CreateViewPort(double angle, int x1, int y1, int width, int height);
static HGLRC m_first_hRC ; //OpenGL Rendering Context
static CDC* m_first_pDC; //Device Context
HGLRC m_hRC ; //OpenGL Rendering Context
CDC* m_pDC; //Device Context
HDC m_hdc;
CRect m_window_area;
ViewType m_view;
BOOL SetupPixelFormat();
BOOL InitOpenGL();
static int m_objects;
static bool m_initialized;
private:
};
int OpenGLDisplayClass::m_objects = 0;
bool OpenGLDisplayClass::m_initialized = false;
HGLRC OpenGLDisplayClass::m_first_hRC = NULL; //OpenGL Rendering Context
CDC* OpenGLDisplayClass::m_first_pDC = NULL;
//CDC* OpenGLDisplayClass::m_pDC; //Device Context
BEGIN_MESSAGE_MAP (OpenGLDisplayClass, CWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP ()
//-----------------------------------------------------------------------------
OpenGLDisplayClass::OpenGLDisplayClass()
{
m_view = view_chase;
m_objects++;
};
//-----------------------------------------------------------------------------
OpenGLDisplayClass::~OpenGLDisplayClass()
{
wglMakeCurrent(0,0);
wglDeleteContext(m_hRC);
if(m_pDC)
{
delete m_pDC;
}
m_pDC = NULL;
m_objects–;
if (m_objects<= 0)
{
m_initialized = false;
m_objects = 0;
}
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor.
1, // Version number
PFD_DRAW_TO_WINDOW | // Format must support windows
PFD_SUPPORT_OPENGL | // Use OpenGL
PFD_DOUBLEBUFFER | // Use double buffer
PFD_GENERIC_ACCELERATED |
PFD_GENERIC_FORMAT, // Pixel format is for a window.
PFD_TYPE_RGBA, // Request A RGBA Format
24, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
32, // 32bit Z-buffer (depth buffer)
1, // 1 Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
//int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
int m_nPixelFormat = ::ChoosePixelFormat(m_hdc, &pfd);
if (m_nPixelFormat == 0)
return FALSE;
// return ::SetPixelFormat(dc.m_hDC, nPixelFormat, &pfd);
// return ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd);
return ::SetPixelFormat(m_hdc, m_nPixelFormat, &pfd);
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::InitOpenGL()
{
//Get a DC for the Client Area
m_pDC = new CClientDC(this);
//Failure to Get DC
if(m_pDC == NULL)
return FALSE;
// Get device context only once.
m_hdc = GetDC()->m_hDC;
// m_hdc = m_pDC->GetSafeHdc();
if(!SetupPixelFormat())
return FALSE;
//Create Rendering Context
m_hRC = wglCreateContext(m_hdc);//m_pDC->GetSafeHdc());
//Failure to Create Rendering Context
if(m_hRC == 0)
return FALSE;
//Make the RC Current
//if(::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
// return FALSE;
if(wglMakeCurrent(m_hdc, m_hRC) == FALSE)
return FALSE;
// set material values.
GLfloat mat_specular[] = {0.5f, 0.5f, 0.5f, 1.0};
GLfloat mat_shininess[] = {30.0f};
// set the light values.
GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat ambient[] = {0.3f, 0.3f, 0.3f, 1.0f };
GLfloat lightPos[] = {10000.0, 0.0, 1000.0, 0.0};
// setup lights and material
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
// glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); // Really Nice Perspective Calculations
glHint(GL_POLYGON_SMOOTH_HINT , GL_FASTEST);
glHint(GL_POINT_SMOOTH_HINT , GL_FASTEST);
glHint(GL_LINE_SMOOTH_HINT , GL_FASTEST);
return true;
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::Create(CWnd *pParentWnd, const RECT &rect, int TypeOfWindow)
{
if (CWnd::Create(NULL, “”, WS_CHILD | WS_VISIBLE, rect, pParentWnd, 0, NULL) == -1)
return false;
GetClientRect(&m_window_area);
if (!InitOpenGL())
{
MessageBox(“Error setting up OpenGL!”,
“Init Error!”,
MB_OK | MB_ICONERROR );
return -1;
}
if (m_initialized == false)
{
BuildFont(m_hdc);//m_pDC->GetSafeHdc());
LoadCommonTextures();
DrawCommonShapes(TypeOfWindow);
m_first_hRC = m_hRC;
m_initialized = true;
}
else
{
wglShareLists(m_first_hRC, m_hRC);
};
return true;
};
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
return CWnd::PreCreateWindow(cs);
}
//-----------------------------------------------------------------------------
BOOL OpenGLDisplayClass::OnEraseBkgnd(CDC* pDC)
{
//return CView::OnEraseBkgnd(pDC);
return TRUE ;
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::CreateViewPort(double angle, int x1, int y1, int width, int height)
{
glScissor(x1, y1, width,height);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glViewport(x1, y1, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);
glMatrixMode(GL_MODELVIEW);
// glLoadIdentity();
}
void OpenGLDisplayClass::ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
int left = x1,
right = width,
bottom = y1,
top = height;
glViewport(x1, y1, width, height);
if (projection == 0)
{
// glTranslated(x1, y1, 0);
gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);
}
else
{
glOrtho(left, right, bottom, top, -1000, 3000);
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
};
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::OnSize(UINT nType, int cx, int cy)
{
CClientDC dc(this);
wglMakeCurrent(dc.m_hDC, m_hRC);
m_window_area = CRect(0, 0, cx, cy);
CreateViewPort(30.0, 0, 0, cx, cy);
wglMakeCurrent(NULL, NULL);
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::MakeContextCurrent(BOOL onOff)
{
if (onOff)
{
// ::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
::wglMakeCurrent(m_hdc, m_hRC);
}
else
{
::wglMakeCurrent(NULL, NULL);
};
}
//-----------------------------------------------------------------------------
void OpenGLDisplayClass::Update()
{
Invalidate(FALSE);
UpdateWindow();
};