三维显示软件制作--显示部分(1)

显示部分主要由opengl实现

首先需要解决的问题是如何在MFC的对话框程序中应用opengl

参考网上内容,先做了一个小实验。


MFC对话框程序中应用opengl主要涉及到几个部分:opengl的初始化,opengl窗口的渲染,opengl窗口的创建

为了便于外部调用,新建类COpengl,继承类public CWnd,添加:

public:
	virtual void RenderScene();
	void Create(CRect rect,CWnd *parent);
	virtual ~COpengl();

protected:
	CRect m_rect;
	CWnd* m_parent;
	int InitGL();
	void KillGLWindow();
	HDC m_hDC;
	HGLRC m_hRC;
	DEVMODE m_DMsaved;

并在opengl.cpp中添加如下代码:

#include <gl/freeglut.h>//我用的是freeglut  省略了在连接依赖库中添加东西
COpengl::~COpengl()
{
	KillGLWindow(); 
}

void COpengl::Create(CRect rect,CWnd *parent) //通过窗体父句柄创建opengl类,传递给m_rect,在这个矩形内画图
{
	ASSERT(rect);
	ASSERT(parent);
	m_rect=rect;
	m_parent=parent;
	CString className = AfxRegisterWndClass(
		CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
		NULL,
		(HBRUSH)GetStockObject(BLACK_BRUSH),
		NULL); //注册类
	CreateEx(
		0,
		className,
		"OpenGL",
		WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
		rect,
		parent,
		0);//创建这个opengl类
}


int COpengl::OnCreate(LPCREATESTRUCT lpCreateStruct) //这个基本上是固定的格式---直接从网上copy来
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &m_DMsaved); //枚举显示设置,这句是为了获得m_DMsaved,以便下用(颜色深度)
	GLuint	PixelFormat;								// Holds The Results After Searching For A Match
	static	PIXELFORMATDESCRIPTOR pfd=					// pfd Tells Windows How We Want Things To Be
	{																		
		sizeof(PIXELFORMATDESCRIPTOR),					// Size Of This Pixel Format Descriptor
			1,											// Version Number
			PFD_DRAW_TO_WINDOW |						// Format Must Support Window
			PFD_SUPPORT_OPENGL|							// Format Must Support OpenGL
			PFD_DOUBLEBUFFER,							// Must Support Double Buffering
			PFD_TYPE_RGBA,								// Request An RGBA Format
			m_DMsaved.dmBitsPerPel,						// 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
			16,											// 16Bit Z-Buffer (Depth Buffer)  
			0,											// No Stencil Buffer
			0,											// No Auxiliary Buffer
			PFD_MAIN_PLANE,								// Main Drawing Layer
			0,											// Reserved
			0, 0, 0										// Layer Masks Ignored
	};	//颜色描述符设置																	
	if ( !( m_hDC = ::GetDC ( m_hWnd ) ) )
	{							// Did We Get A Device Context?																	
		KillGLWindow ();						// Reset The Display
		TRACE ( "Can't Create A GL Device Context." );
		return FALSE;												
	}	
	if ( !( PixelFormat = ChoosePixelFormat ( m_hDC, &pfd ) ) )	
	{		// Did Windows Find A Matching Pixel Format?																		
		KillGLWindow ();						// Reset The Display
		TRACE ( "Can't Find A Suitable PixelFormat." );
		return FALSE;												
	}	
	if ( !SetPixelFormat ( m_hDC, PixelFormat, &pfd ) )
	{				// Are We Able To Set The Pixel Format?																		
		KillGLWindow ();						// Reset The Display
		TRACE ( "Can't Set The PixelFormat." );
		return FALSE;												
	}	
	if ( !( m_hRC = wglCreateContext ( m_hDC ) ) ) 
	{					// Are We Able To Get A Rendering Context?																	
		KillGLWindow ();						// Reset The Display
		TRACE( " Can't Create A GL Rendering Context." );
		return FALSE;													
	}	
	if ( !wglMakeCurrent ( m_hDC, m_hRC ) )	
	{							// Try To Activate The Rendering Context																		
		KillGLWindow ();						// Reset The Display
		TRACE ( "Can't Activate The GL Rendering Context." );
		return FALSE;													
	}
	if ( !InitGL () )
	{							// Initialize Our Newly Created GL Window																		
		KillGLWindow ();						// Reset The Display
		TRACE ( "Initialization Failed." );
		return FALSE;													
	}
	return 0;
}

void COpengl::KillGLWindow() //销毁opengl的显示
{
	if (m_hRC)
	{
		wglMakeCurrent ( NULL, NULL );
		wglDeleteContext ( m_hRC );
		m_hRC=NULL;
	}
	if (m_hDC && !::ReleaseDC(m_hWnd,m_hDC))
	{
		m_hDC=NULL;
	}
	if (m_hWnd && !::DestroyWindow(m_hWnd))
	{
		m_hWnd=NULL;
	}

}

int COpengl::InitGL() //opengl初始化
{
	glShadeModel(GL_SMOOTH);									// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);								// Black Background
	glClearDepth(1.0f);										// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);									// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);										// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);						// Really Nice Perspective Calculations
	glEnable(GL_TEXTURE_2D);									// Enable Texture Mapping
	return TRUE;
}

void COpengl::RenderScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen And Depth Buffer
	glLoadIdentity();
	static GLfloat	zrot;				// Z Rotation 
	glPushMatrix();						// Push Matrix Onto Stack (Copy The Current Matrix)
	glLoadIdentity();
	glTranslatef(0.0f,0.0f,-1.0f);
	glRotatef(zrot,0.0f,0.0f,1.0f);
	glBegin(GL_QUADS);  //我创建了一个2d的正方形,并让它不停转动
	glColor3f(1.0f,0.0f,0.0f);glVertex3f(-0.5f, -0.5f,  0.0f);
	glColor3f(0.0f,1.0f,0.0f);glVertex3f( 0.5f, -0.5f,  0.0f);
	glColor3f(0.0f,1.0f,0.0f);glVertex3f( 0.5f,  0.5f,  0.0f);
	glColor3f(0.0f,0.0f,1.0f);glVertex3f(-0.5f,  0.5f,  0.0f);
	glEnd();
	glPopMatrix();
	zrot+=1;
	SwapBuffers(m_hDC);//双缓冲需要swapbuffer
	Invalidate(FALSE); //使双缓冲模式生效
}

另外,如果RenderScene中没有Invalidate(False)的话,双缓冲模式就不会生效了------

到此,opengl部分的配置就ok了,现在需要的就是在程序中引用opengl  

首先在new3dDlg.h中加入

#include"Opengl.h"

在类定义中加入:

public:
       CRect drawrect;
protected:
       COpengl m_opengl;

转到new3dDlg.cpp中:

首先要在窗口初始化的时候对opengl进行初始化

在OnInitDialog()中加入

drawrect.top=40;
drawrect.bottom=680;
drawrect.left=280;
drawrect.right=1080;
ScreenToClient(drawrect);//规定opengl的显示区域
m_opengl.Create(drawrect,this);//根据主窗口和矩形区域调用创建opengl类的程序
SetTimer(121,50,NULL);//设置时钟对opengl显示进行刷新,相当于opengl程序中的glutMainLoop

为窗口添加WM_TIMER消息响应事件,并加入

if (nIDEvent==121)
{
	m_opengl.RenderScene();
}

这样,编译连接后,一个旋转的正方形就产生了------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值