opengl实现曲柄连杆

一、程序要求

       偶然翻到自己两年前写的一个opengl实现的曲柄连杆机构程序,内容分为设计要求、主要代码及函数说明、设计方法三大块。编程环境是vs2010,窗口是MFC设计,注释都已详细解释。

•图形显示要求:
1、利用opengl实现附件的零件动画显示
2、具体尺寸自定
3、可以使用学过的各种显示方法
•菜单要求,利用鼠标右键选择菜单项
1、利用鼠标右键弹出两个菜单
2、运动速度选择:高中低三档
3、填充图选择:线框图、填充图
•窗口无要求,可以是DOS窗口,也可以是MFC Window风格窗口

二、设计方法

1.新建MFC应用程序,项目名称是opengl_homework
2.在opengl_homeworkView.h声明函数和全局变量,在opengl_homeworkView.cpp中定义函数
4. 把机构各个零件尺寸设置为全局变量,方便修改尺寸
5.设置DC像素格式、光源、创建RC、设置计时器等。
6.在OnDraw函数中渲染屏幕,绘制具体图形
7. 在已知各个零件的尺寸及曲柄的旋转角度条件下,利用正弦定理和余弦定理计算摇杆和连杆的旋转角度,确定了机构的运动方式
8.在世界坐标系中将当前绘图坐标系保存
9.将当前绘图坐标系沿Z轴负方向平移适当距离以便观察物体
10.完成拖动鼠标左键改变观察物体方向的操作
11.绘制长方体基座,坐标原点在基座后面中心
12. 沿Z轴正方向移动长方体基座的宽
13.沿X轴负方向移动基座有效长度的一半,到基座左边圆柱中心
14.绘制基座左边圆柱,给半径,高参数
15.沿X轴正方向移动基有效长度座在基座右边圆柱中心
16.画基座右边圆柱,给半径,高参数
17.沿X轴负方向移动基有效长度回到基座左边圆柱中心
18.把在基座左边圆柱中心的坐标系存起来
19.绕Z轴旋转alpha,画曲柄
20.把坐标轴移动到曲柄的中点
21.绘制红色的曲柄
22.把在基座左边圆柱中心的坐标系放出来
23.把在基座左边圆柱中心的坐标系存起来
24.沿x轴正方向移动基座有效长度回到右边圆柱中心
25.旋转摇杆角度
26.把坐标轴移动到的摇杆中点
27.绘制绿色的摇杆
28.绘制完绿色的摇杆后,画连杆
29.因为连杆螺钉高度比摇杆厚度大,所以沿Z轴负方向移动(螺钉高度/2-曲柄厚度)距离
30.绘制链接连杆和摇杆、曲柄的螺钉
31.把基座左边圆柱的坐标系放出来
32.把在基座左边圆柱中心的坐标系存起来
33.旋转曲柄角度大小
34.将坐标系沿X正方向移动曲柄有效长度
35.再将坐标系转正
36.坐标系旋转连杆的角度大小
37.将坐标系移动到连杆的后面中心
38.画连杆
39.将坐标系移动到连杆左端螺钉的底部
40.画连杆左端的圆柱,即螺钉
41.把基座左边圆柱的坐标系放出来
42.回到原始坐标系观察物体

三、主要代码

#include "stdafx.h"
#ifndef SHARED_HANDLERS
#include "opengl_homework.h"
#endif

#include "opengl_homeworkDoc.h"
#include "opengl_homeworkView.h"
#include "gl\GL.h"
#include "gl\GLU.h"
#include "gl\glut.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define C 57.2958
IMPLEMENT_DYNCREATE(Copengl_homeworkView, CView)

BEGIN_MESSAGE_MAP(Copengl_homeworkView, CView)
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &Copengl_homeworkView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_KEYDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONDOWN()
	ON_WM_TIMER()
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_WM_SIZE()
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_32773, &Copengl_homeworkView::On32773)
	ON_COMMAND(ID_32774, &Copengl_homeworkView::On32774)
	ON_COMMAND(ID_32775, &Copengl_homeworkView::On32775)
	ON_COMMAND(ID_32776, &Copengl_homeworkView::On32776)
	ON_COMMAND(ID_32777, &Copengl_homeworkView::On32777)
	ON_WM_LBUTTONUP()
END_MESSAGE_MAP()

Copengl_homeworkView::Copengl_homeworkView()
{
   
	m_hDC = NULL;
	m_hRC = NULL;
	xRot  = 0;          //鼠标左键旋转角度
	yRot  = 0;
	alpha = 45;         //曲柄初始化角度

	L1       = 10;      //曲柄有效长度
	L2       = 26;      //连杆有效长度
	L3       = 12;      //摇杆有效长度
	L4       = 24;      //基座有效长度
	r        = 1;       //所有螺钉的半径
	h0       = 2;       //基座上螺钉高度
	h1       = 4;       //连杆螺钉高度
	h_qubing = 1;       //曲柄的厚度
	w_qubing = 3;       //曲柄的宽
	W4       = 10;      //基座的宽
	H4       = 8;       //基座的高
	angle    = 10;      //每一帧变化的角度

	enter_flag      = false;
	light           = true;  //开启灯光
	full            = true; //初始化面填充
	leftbutton_flag = false;
}

Copengl_homeworkView::~Copengl_homeworkView()
{
   
}

BOOL Copengl_homeworkView::PreCreateWindow(CREATESTRUCT& cs)
{
   
	//  CREATESTRUCT cs 来修改窗口类或样式
	cs.style |= WS_CLIPSIBLINGS|WS_CLIPCHILDREN|CS_OWNDC;//增加属性
	return CView::PreCreateWindow(cs);
}


int Copengl_homeworkView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	Init();       //像素格式的设置和RC的创建
	return 0;
}


void Copengl_homeworkView::Init()
{
   
	m_hDC = ::GetDC(m_hWnd);//获取DC
	ASSERT(m_hDC);
	//指定DC像素格式,填充数据结构
	static	PIXELFORMATDESCRIPTOR pfdWnd =
	{
   
		sizeof(PIXELFORMATDESCRIPTOR), // Structure size.
		1,                             // Structure version number.结构版本,一般设置1
		PFD_DRAW_TO_WINDOW |           // Property flags.  使之能在窗口或者其他设备上画图
		PFD_SUPPORT_OPENGL |           //使之能使用opengl函数
		PFD_DOUBLEBUFFER,              //指明使用了双缓冲
		PFD_TYPE_RGBA,                 //定义显示颜色的方法
		24,                            // 24-bit color.制定了一个颜色的位数
		0, 0, 0, 0, 0, 0,              // Not concerned with these.
		0, 0, 0, 0, 0, 0, 0,           // No alpha or accum buffer.
		32,                            // 32-bit depth buffer.
		0, 0,                          // No stencil or aux buffer.
		PFD_MAIN_PLANE,                // Main layer type.
		0,                             // Reserved.
		0, 0, 0                        // Unsupported.
	};
	int pixelformat;
	pixelformat = ChoosePixelFormat(m_hDC, &pfdWnd);     //选择像素格式,选择成功就返回格式索引,否则返回0
	ASSERT(SetPixelFormat(m_hDC, pixelformat, &pfdWnd)); //为DC设置像素格式
	m_hRC = wglCreateContext(m_hDC);                     //创建RC
	VERIFY(wglMakeCurrent(m_hDC,m_hRC));                 //激活RC
	SetupRC();                                           //渲染绘图
	VERIFY(wglMakeCurrent(NULL,NULL));                   //关闭RC
	SetTimer(1,50,NULL);	                             //计时器ID是1,每100毫秒变化
}

void Copengl_homeworkView::Release()
{
   
	wglDeleteContext(m_hRC);    //删除创建的RC
	KillTimer(1);               //删除计时器
	::ReleaseDC(m_hWnd,m_hDC);  //释放窗口和DC,释放DC,使其他应用程序可以使用
}

void Copengl_homeworkView::Resize(int width,int height)
{
   
	GLfloat w_h;
	glViewport(0,0,width,height);        //为了选择一个更小的绘图区域,将图像映射到像素矩形中,根据窗口的变化实时重绘窗口
	w_h = (GLfloat)width/(GLfloat)height;
	glMatrixMode(GL_PROJECTION);         //对接下来要做什么进行声明   这里是投影,投影下面有系列函数
	glLoadIdentity();                    //把矩阵设置为单位矩阵
	gluPerspective(45,w_h,5,155);        //指定视野角度,y轴的上下方向     物体的宽高比   近平面距离     远平面距离
	glMatrixMode(GL_MODELVIEW);          //模型视图
	glLoadIdentity();
}


void Copengl_homeworkView::OnDraw(CDC* pDC)
{
   
	wglMakeCurrent(m_hDC,m_hRC); //设定当前线程的渲染环境,设置当前RC
	RenderScene();               //具体绘制图形
	SwapBuffers(m_hDC);          //交换缓存
	wglMakeCurrent(m_hDC,NULL);  //非当前化RC
}


void Copengl_homeworkView::SetupRC()                 //打底初始化,在初始化函数里面
{
   
	glShadeModel(GL_SMOOTH);                         //启用阴影平滑
	glEnable(GL_DEPTH_TEST);                         //启用深度测试
	glFrontFace(GL_CCW);                             //逆时针方面为正面
	glEnable(GL_CULL_FACE);                          //不计算面的反面内部
	glClearColor(1,1,1,1);                           //最后一个参数是透明度
	glEnable(GL_COLOR_MATERIAL);                     //开启灯光后显示材料颜色
	glLightModeli(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值