⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splinedlg.cpp

📁 生成样条的程序
💻 CPP
字号:
// SplineDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "Spline.h"
#include "SplineDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#ifndef CALLBACK
#define CALLBACK
#endif

GLfloat ctlpoints[4][4][3];

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

void CALLBACK nurbsError(GLenum errorCode)
{
	const GLubyte *estring;

	estring = gluErrorString(errorCode);
	fprintf (stderr, "Nurbs Error: %s\n", estring);
	exit (0);
}


class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CSplineDlg 对话框




CSplineDlg::CSplineDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSplineDlg::IDD, pParent)
	, m_pDC(NULL)
	, m_pNurb(NULL)
	,m_hGLContext(NULL)
	, m_bShowPoints(FALSE)
	, m_pWnd(NULL)
	, m_trans(0)
	, m_width(0)
	, m_height(0)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSplineDlg::DoDataExchange(CDataExchange* pDX)
{
	DDX_Control(IDC_STATICTRANS,m_sliTrans);
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CSplineDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_WM_DESTROY()
END_MESSAGE_MAP()


// CSplineDlg 消息处理程序

BOOL CSplineDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	myFirst();
	CSliderCtrl m_sliTrans;
	m_sliTrans.SetPos(0);
	m_sliTrans.SetRange(-10,10);
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CSplineDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CSplineDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}

	///////////////////自己加的语句////////////////////
	static BOOL     bBusy = FALSE;    //紧接着的三句是为了 应用  双缓存

	if(bBusy) 	return;
	bBusy = TRUE;
	//  没有下面的语句时 背景为 黑色
	//	glClearColor(0.2f,0.2f,0.5f,1.0f);
	//   为了增加本章的趣味性  先屏蔽该句
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除缓存,将背景置空

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	InitSurface();
	reshape();
	myDraw();                                              // 自己绘制图形
	//m_pWnd->Invalidate();
	UpdateWindow();
	
	glFinish();

	SwapBuffers(wglGetCurrentDC());                        //  双缓存 应用
	bBusy = FALSE;
	////////////////////////////////////////
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CSplineDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


BOOL CSplineDlg::myPixelFomat(void)
{
	static PIXELFORMATDESCRIPTOR pfd = 
	{
		sizeof(PIXELFORMATDESCRIPTOR), 
		1,                             
		PFD_DRAW_TO_WINDOW |           
		PFD_SUPPORT_OPENGL|			// support OpenGL
		PFD_DOUBLEBUFFER,             // double buffered
		PFD_TYPE_RGBA,              
		24,                         
		0, 0, 0, 0, 0, 0,           
		0,                          
		0,                          
		0,                          
		0, 0, 0, 0,                 
		32,                         
		0,                          
		0,                          
		PFD_MAIN_PLANE,             
		0,                          
		0, 0, 0                     
	};
	int pixelformat;

	if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
	{
		MessageBox("ChoosePixelFormat failed");
		return FALSE;
	}

	if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
	{
		MessageBox("SetPixelFormat failed");
		return FALSE;
	}

	return TRUE;
}

// 渲染描述表
void CSplineDlg::myFirst(void)
{
	PIXELFORMATDESCRIPTOR pfd;
	int         n;
	HGLRC		hrc;                        //渲染描述表rc的句柄

	CWnd* m_pWnd=GetDlgItem(IDC_STATICDISPLAY);
	m_pDC = new CClientDC(m_pWnd);
	CRect rect;
	m_pWnd->GetClientRect(&rect);
	m_width=rect.Width();
	m_height=rect.Height();

	ASSERT(m_pDC != NULL);

	if (!myPixelFomat())
		return;
	n =::GetPixelFormat(m_pDC->GetSafeHdc());		 // 成功了就返回这种像素形式的索引值,否则返回0
	::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);


	hrc = wglCreateContext(m_pDC->GetSafeHdc());    //创建并初始化 渲染描述表
	wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);

	GetClientRect(&m_oldRect);						// 获得客户区的大小
	glClearDepth(1.0f);								//  清除深度缓存 使它变为 1.0 为现在的深度缓存值
	glEnable(GL_DEPTH_TEST);							
	glMatrixMode(GL_MODELVIEW);						//启动 模型-视图 矩阵
	glLoadIdentity();
}

void CSplineDlg::OnDestroy()
{
	CDialog::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
	//  删除渲染描述表及绑定的设备描述表
	HGLRC	hrc;

	hrc = ::wglGetCurrentContext();

	::wglMakeCurrent(NULL,  NULL);				// 使得当前的hdc 和 hglrc 都为空 其定义见下方


	/*
	BOOL wglMakeCurrent(
	HDC  hdc,      // device context of device that OpenGL calls are 
	// to be drawn on
	HGLRC  hglrc   // OpenGL rendering context to be made the calling 
	// thread's current rendering context
	);
	*/


	if (hrc)
		::wglDeleteContext(hrc);

	if (m_pDC)
		delete m_pDC;
}

void CSplineDlg::myDraw(void)
{
	GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
	int i, j;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();
	glRotatef(330.0, 1.,0.,0.);
	glScalef (0.5, 0.5, 0.5);
	gluBeginSurface(m_pNurb);
	gluNurbsSurface(m_pNurb, 
		8, knots, 8, knots,
		4 * 3, 3, &ctlpoints[0][0][0], 
		4, 4, GL_MAP2_VERTEX_3);
	gluEndSurface(m_pNurb);

//	if (m_bShowPoints) {
		glPointSize(5.0);
		glDisable(GL_LIGHTING);
		glColor3f(1.0, 1.0, 0.0);
		glBegin(GL_POINTS);
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				glVertex3f(ctlpoints[i][j][0], 
					ctlpoints[i][j][1], ctlpoints[i][j][2]);
			}
		//}
		glEnd();
		glEnable(GL_LIGHTING);
	}
	glPopMatrix();
	glFlush();
	
}

void CSplineDlg::InitSurface(void)
{
	GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat mat_shininess[] = { 100.0 };

	glClearColor (0.0, 0.0, 0.0, 0.0);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_AUTO_NORMAL);
	glEnable(GL_NORMALIZE);

	// 初始化 表面
	int u, v;
	for (u = 0; u < 4; u++) {
		for (v = 0; v < 4; v++) {
			ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
			ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);

			if ( (u == 1 || u == 2) && (v == 1 || v == 2))
				ctlpoints[u][v][2] = 3.0;
			else
				ctlpoints[u][v][2] = -3.0;
		}
	}			

	m_pNurb = gluNewNurbsRenderer();
	gluNurbsProperty(m_pNurb, GLU_SAMPLING_TOLERANCE, 25.0);
	gluNurbsProperty(m_pNurb, GLU_DISPLAY_MODE, GLU_FILL);
	//gluNurbsCallback(m_pNurb, GLU_ERROR, nurbsError);
}


BOOL CSplineDlg::CreateViewGLContext(HDC hDC)  // 没有用到
{
	m_hGLContext = wglCreateContext(hDC);

	if(m_hGLContext==NULL)
		return FALSE;

	if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)
		return FALSE;

	return TRUE;
}

// 调整显示比例
void CSplineDlg::reshape(void)
{
	glViewport(0, 0, (GLsizei) m_width, (GLsizei) m_height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective (45.0, (GLdouble)m_width/(GLdouble)m_height, 3.0, 8.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef (0.0, 0.0, -5.0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -