I want to create an application where application View will be divided with OpenGL 3d models in two different views attached to the Childframe using splitter. For this purpose i made a parent class extended from a view class , and inside this class i have initialize all the opengl required code.
for e.g.
#pragma once
#include <gl/gl.h>
#include <gl/glu.h>
#define IL //when you dont want to use image library and you want to load everything by your self then remove this
// COpenGlView view
class COpenGlView : public CView
{
DECLARE_DYNCREATE(COpenGlView)
protected:
void oglBeginRendering();
COpenGlView(); // protected constructor used by dynamic creation
virtual ~COpenGlView();
/*******************/
/* Private Members */
/*******************/
// Window information
CWnd *hWnd;
HDC hdc;
HGLRC hrc;
int m_nPixelFormat;
CRect m_rect;
CRect m_oldWindow;
CRect m_originalRect;
public:
/******************/
/* Public Members */
/******************/
UINT_PTR m_unpTimer;
// View information variables
float m_fLastX;
float m_fLastY;
float m_fPosX;
float m_fPosY;
float m_fZoom;
float m_fRotX;
float m_fRotY;
bool m_bIsMaximized;
float m_fZoomSpeed;
float m_fRotateSpeed;
GLuint texture[1];
void oglCreate(CRect rect, CWnd *parent,CString strWindowName=L"OpenGl");
virtual void oglInitialize(void);
virtual void oglDrawScene(void);
float randFloat(const float& min, const float& max);
int randInt(const int& min, const int& max);
void Reset();
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTimer(UINT_PTR nIDEvent);
virtual void OnInitialUpdate();
};
here is the cpp
// OpenGlView.cpp : implementation file
//
#include "stdafx.h"
#include "OpenGlView.h"
// COpenGlView
IMPLEMENT_DYNCREATE(COpenGlView, CView)
COpenGlView::COpenGlView()
{
m_fPosX = 0.0f; // X position of model in camera view
m_fPosY = 0.0f; // Y position of model in camera view
m_fZoom = 5.0f; // Zoom on model in camera view
m_fRotX = 0.0f; // Rotation on model in camera view
m_fRotY = 0.0f; // Rotation on model in camera view
m_fZoomSpeed=0.05f;
m_fRotateSpeed = 0.05f;
m_bIsMaximized = false;
}
COpenGlView::~COpenGlView()
{
}
void COpenGlView::Reset()
{
m_fPosX = 0.0f; // X position of model in camera view
m_fPosY = 0.0f; // Y position of model in camera view
m_fZoom = 5.0f; // Zoom on model in camera view
m_fRotX = 0.0f; // Rotation on model in camera view
m_fRotY = 0.0f; // Rotation on model in camera view
m_fZoomSpeed=0.05f;
m_fRotateSpeed = 0.05f;
m_bIsMaximized = false;
}
BEGIN_MESSAGE_MAP(COpenGlView, CView)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_TIMER()
END_MESSAGE_MAP()
// COpenGlView drawing
void COpenGlView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
// COpenGlView diagnostics
#ifdef _DEBUG
void COpenGlView::AssertValid() const
{
CView::AssertValid();
}
#ifndef _WIN32_WCE
void COpenGlView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif
#endif //_DEBUG
// COpenGlView message handlers
int COpenGlView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void COpenGlView::OnPaint()
{
//CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CView::OnPaint() for painting messages
ValidateRect(NULL);
}
void COpenGlView::OnMouseMove(UINT nFlags, CPoint point)
{
int diffX = (int)(point.x - m_fLastX);
int diffY = (int)(point.y - m_fLastY);
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
// Left mouse button
if (nFlags & MK_LBUTTON)
{
m_fRotX += (float)m_fRotateSpeed * diffY;
if ((m_fRotX > 360.0f) || (m_fRotX < -360.0f))
{
m_fRotX = 0.0f;
}
m_fRotY += (float)0.5f * diffX;
if ((m_fRotY > 360.0f) || (m_fRotY < -360.0f))
{
m_fRotY = 0.0f;
}
}
// Right mouse button
else if (nFlags & MK_RBUTTON)
{
m_fZoom -= (float)m_fZoomSpeed * diffY;
}
// Middle mouse button
else if (nFlags & MK_MBUTTON)
{
m_fPosX += (float)0.05f * diffX;
m_fPosY -= (float)0.05f * diffY;
}
OnDraw(NULL);
CView::OnMouseMove(nFlags, point);
}
void COpenGlView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;
// Map the OpenGL coordinates.
glViewport(0, 0, cx, cy);
// Projection view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our current view perspective
gluPerspective(35.0f, (float)cx / (float)cy, 0.01f, 2000.0f);
// Model view
glMatrixMode(GL_MODELVIEW);
switch (nType)
{
// If window resize token is "maximize"
case SIZE_MAXIMIZED:
{
// Get the current window rect
GetWindowRect(m_rect);
// Move the window accordingly
MoveWindow(6, 6, cx - 14, cy - 14);
// Get the new window rect
GetWindowRect(m_rect);
// Store our old window as the new rect
m_oldWindow = m_rect;
break;
}
// If window resize token is "restore"
case SIZE_RESTORED:
{
// If the window is currently maximized
if (m_bIsMaximized)
{
// Get the current window rect
GetWindowRect(m_rect);
// Move the window accordingly (to our stored old window)
MoveWindow(m_oldWindow.left, m_oldWindow.top - 18, m_originalRect.Width() - 4, m_originalRect.Height() - 4);
// Get the new window rect
GetWindowRect(m_rect);
// Store our old window as the new rect
m_oldWindow = m_rect;
}
break;
}
}
}
void COpenGlView::oglBeginRendering()
{
SetTimer(1, 1, 0);
}
void COpenGlView::OnTimer(UINT_PTR nIDEvent)
{
switch (nIDEvent)
{
case 1:
{
// Clear color and depth buffer bits
wglMakeCurrent(hdc, hrc);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
oglDrawScene();
// Swap buffers
SwapBuffers(hdc);
glFlush();
wglMakeCurrent(NULL, NULL);
break;
}
default:
break;
}
CView::OnTimer(nIDEvent);
}
void COpenGlView::OnInitialUpdate()
{
CView::OnInitialUpdate();
COpenGlView::oglInitialize();
// TODO: Add your specialized code here and/or call the base class
}
void COpenGlView::oglCreate(CRect rect, CWnd *parent,CString strWindowName)
{
CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_OWNDC, NULL, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL);
CreateEx(0, className,strWindowName, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0);
// Set initial variables' values
m_oldWindow = rect;
m_originalRect = rect;
hWnd = parent;
GLenum s = glGetError();
}
void COpenGlView::oglInitialize(void)
{
// Initial Setup:
//
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16, // z-buffer depth
0, 0, 0, 0, 0, 0, 0,
};
// Get device context only once.
//hdc = GetDC()->m_hDC;
// Pixel format.
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
// Basic Setup:
//
// Set color to use when clearing the background.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
// Turn on backface culling
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
GLenum a = glGetError();
OnDraw(NULL);
//wglMakeCurrent(NULL, NULL);
}
void COpenGlView::oglDrawScene(void)
{
// Wireframe Mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
// Front Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
// Bottom Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right Side
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left Side
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -m_fZoom);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
GLenum a = glGetError();
}
//--------------------------------------------------------
// Get an random integer within a specified range
//--------------------------------------------------------
int COpenGlView::randInt(const int& min, const int& max) {
return ((rand()%(int)(((max) + 1)-(min)))+ (min));
}
//--------------------------------------------------------
// Get a random float within a specified range
//--------------------------------------------------------
float COpenGlView::randFloat(const float& min, const float& max) {
float range = max - min;
float num = range * rand() / RAND_MAX;
return (num + min);
}
then i extended two more view classes from the same class class
C3dRightView : public COpenGlView
and
C3dRightView : public COpenGlView
then in childframe class i added splitter code and called these two classes in the splitter window. The problem is both opengl view code works fine but if i stop one of the initialization of opengl then the other one display. I tried everything and i cant display two different graphical opengl animation in both of these two different views. I have checked the HDC memory map and it seems like both classes are using parent with respect to their dynamic hdc object but if i stop ones code then other view display properly.
detail classes are below
class C3dRightView : public COpenGlView
{
DECLARE_DYNCREATE(C3dRightView)
protected:
GLuint m_left_texture[53];
C3dRightView(); // protected constructor used by dynamic creation
virtual ~C3dRightView();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
virtual void OnInitialUpdate();
void oglDrawScene(void);
void oglInitialize(void);
afx_msg void OnTimer(UINT_PTR nIDEvent);
};
void C3dRightView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CView::OnPaint() for painting messages
}
void C3dRightView::OnInitialUpdate()
{
hdc = C3dRightView::GetDC()->m_hDC;
/** If i open below code then left view stop displaying model **/
COpenGlView::OnInitialUpdate();
oglInitialize();
//-=-=-=-=-=-=-==--=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
oglBeginRendering();
// TODO: Add your specialized code here and/or call the base class
}
void C3dRightView::oglInitialize(void)
{
COpenGlView::oglInitialize();
}
void C3dRightView::oglDrawScene(void)
{
// Wireframe Mode
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 1.0f, 1.0f, 0.0f);
glLoadIdentity();
//glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
glRotated(90,0.0f, 0.0f, -1.0f);
glRotatef(180,1.0f,0,0.0f);
GLenum a = glGetError();
glBegin(GL_TRIANGLES); // Start Drawing A Triangle
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd();
}
the second view file is like this
class C3dLeftView : public COpenGlView
{
DECLARE_DYNCREATE(C3dLeftView)
protected:
GLuint m_left_texture[53];
C3dLeftView(); // protected constructor used by dynamic creation
virtual ~C3dLeftView();
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
virtual void OnInitialUpdate();
void oglDrawScene(void);
void oglInitialize(void);
afx_msg void OnTimer(UINT_PTR nIDEvent);
};
void C3dLeftView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CView::OnPaint() for painting messages
}
void C3dLeftView::OnInitialUpdate()
{
hdc = C3dLeftView::GetDC()->m_hDC;
COpenGlView::OnInitialUpdate();
oglInitialize();
oglBeginRendering();
// TODO: Add your specialized code here and/or call the base class
}
void C3dLeftView::oglInitialize(void)
{
COpenGlView::oglInitialize();
}
void C3dLeftView::oglDrawScene(void)
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glLoadIdentity();
//glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
glRotated(90,0.0f, 0.0f, -1.0f);
glRotatef(180,1.0f,0,0.0f);
GLenum a = glGetError();
glBegin(GL_TRIANGLES); // Start Drawing A Triangle
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
glColor3f(1.0f,0.0f,0.0f); // Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
glColor3f(0.0f,0.0f,1.0f); // Blue
glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
glColor3f(0.0f,1.0f,0.0f); // Green
glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
glEnd();
/*************************************************************************************/
}
if comment below code inside initialupdate function of the view then other view codes works fine.
COpenGlView::OnInitialUpdate();
oglInitialize();
some how the initialupdate code of the parent code works for its one child rather than two of them.