计算机图形学(三)——opengl实现动态钻石图的绘制

钻石图的实验原理:

双缓冲技术:

双缓冲是一种基本的动画技术,主要用于解决单缓冲擦除图像时带来的屏幕闪烁问题。
所谓双缓冲,是指一个屏幕设备上下文(屏幕缓冲区)和一个内存设备上下文(内存缓冲区)。内存缓冲区用于准备图形,屏幕缓冲区用于显示图形。图形绘制到内存缓冲区,而非直接绘制到屏幕缓冲区。每帧动画只执行图形从内存缓冲区到屏幕缓冲区的拷贝操作,屏幕缓冲区只是内存缓冲区的一个映像。双缓冲机制中根本不需要擦除屏幕缓冲区,因此有效地避免了屏幕闪烁现象,可生成平滑的逐帧动画。

在这里插入图片描述

实验效果图:

在这里插入图片描述

在绘制旋转的钻石图时,首先定义金刚石图案类,绘制出静态的钻石图,然后定义定时器消息响应函数,让旋转角每次增加,重新绘制钻石图,利用双缓冲技术即可将旋转的钻石图绘制出来。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心代码如下

// CppDiamondView.cpp : implementation of the CCppDiamondView class
//

#include "stdafx.h"
#include "CppDiamond.h"

#include "CppDiamondDoc.h"
#include "CppDiamondView.h"

#include "Diamond.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CCppDiamondView

IMPLEMENT_DYNCREATE(CCppDiamondView, CView)

BEGIN_MESSAGE_MAP(CCppDiamondView, CView)
	//{{AFX_MSG_MAP(CCppDiamondView)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/
// CCppDiamondView construction/destruction

CCppDiamondView::CCppDiamondView()
{
	// TODO: add construction code here

	Alpha = 0;				//初始旋转角
	ptr = new CDiamond;		//动态建立金刚石图案对象

}

CCppDiamondView::~CCppDiamondView()
{
	delete ptr;				//释放动态创建的金刚石图案的内存空间
	ptr = NULL;				//置指针为空
}

BOOL CCppDiamondView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/
// CCppDiamondView drawing

void CCppDiamondView::OnDraw(CDC* pDC)
{
	CCppDiamondDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	SetTimer(1,100,NULL);		//设置定时器
	DoubleBuffer(pDC);			//调用双缓冲函数绘制金刚石图案
}

/
// CCppDiamondView printing

BOOL CCppDiamondView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CCppDiamondView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CCppDiamondView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/
// CCppDiamondView diagnostics

#ifdef _DEBUG
void CCppDiamondView::AssertValid() const
{
	CView::AssertValid();
}

void CCppDiamondView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCppDiamondDoc* CCppDiamondView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCppDiamondDoc)));
	return (CCppDiamondDoc*)m_pDocument;
}
#endif //_DEBUG

/
// CCppDiamondView message handlers

void CCppDiamondView::DoubleBuffer(CDC* pDC)
{
	CRect rect;
	GetClientRect(&rect);

	pDC->SetMapMode(MM_ANISOTROPIC);
	pDC->SetWindowExt(rect.Width(),rect.Height());
	pDC->SetViewportExt(rect.Width(),-rect.Height());
	pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);

	CDC memDC;						//声明内存缓冲区
	memDC.CreateCompatibleDC(pDC);	//创建与pDC兼容的memDC
	CBitmap NewBitmap, *pOldBitmap; //声明位图对象和指针
	NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());	//创建兼容的位图
	pOldBitmap = memDC.SelectObject(&NewBitmap);	//将位图选入内存
	memDC.FillSolidRect(rect,pDC->GetBkColor());	//用背景色填充客户区
	rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);

	memDC.SetMapMode(MM_ANISOTROPIC);	//定义内存的坐标系
	memDC.SetWindowExt(rect.Width(),rect.Height());
	memDC.SetViewportExt(rect.Width(),-rect.Height());
	memDC.OffsetViewportOrg(rect.Width()/2,rect.Height()/2);
	DrawGraph(&memDC);		//向内存绘制图形

	pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);		//将memDC中的位图拷贝到pDC
	memDC.SelectObject(pOldBitmap);
	NewBitmap.DeleteObject();
	memDC.DeleteDC();
}

void CCppDiamondView::DrawGraph(CDC* pDC)
{
	ptr->SetAngle(Alpha);	//设置金刚石图案的旋转角
	ptr->Draw(pDC);			//根据旋转角绘制金刚石图案板
}

void CCppDiamondView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default

	Alpha += 1;				//角度增量
	
	if (Alpha == 360)		//循环播放
	{
		Alpha = 0;
	}
	
	Invalidate(false);		//使客户区无效,强制执行OnDraw函数进行重绘
	

	CView::OnTimer(nIDEvent);
}

完整代码可添加QQ获取

1173953942 备注钻石图即可

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值