opengl如何用键盘实现放大缩小平移的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opengl如何用键盘实现放大缩小平移的问题相关的知识,希望对你有一定的参考价值。
在程序中如何用QW实现X轴旋转,AS轴实现Y轴旋转,ZX实现Z轴旋转,OP实现平移,上下箭头分别实现放大和缩小,求一般代码
// 工具界面View.cpp : C工具界面View 类的实现//
#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "工具界面.h"
#endif
#include "工具界面Doc.h"
#include "工具界面View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// C工具界面View
IMPLEMENT_DYNCREATE(C工具界面View, CView)
BEGIN_MESSAGE_MAP(C工具界面View, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_COMMAND(ID_ceshi1, &C工具界面View::OnCeshi1)
ON_COMMAND(ID_ceshi2, &C工具界面View::OnCeshi2)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// C工具界面View 构造/析构
C工具界面View::C工具界面View()
// TODO: 在此处添加构造代码
m_pDC=new CClientDC(this);
gg=10.0;
jj=1.0;
kk=0.0;
C工具界面View::~C工具界面View()
BOOL C工具界面View::PreCreateWindow(CREATESTRUCT& cs)
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
// C工具界面View 绘制
void C工具界面View::OnDraw(CDC* /*pDC*/)
C工具界面Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
// C工具界面View 打印
BOOL C工具界面View::OnPreparePrinting(CPrintInfo* pInfo)
// 默认准备
return DoPreparePrinting(pInfo);
void C工具界面View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
// TODO: 添加额外的打印前进行的初始化过程
void C工具界面View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
// TODO: 添加打印后进行的清理过程
// C工具界面View 诊断
#ifdef _DEBUG
void C工具界面View::AssertValid() const
CView::AssertValid();
void C工具界面View::Dump(CDumpContext& dc) const
CView::Dump(dc);
C工具界面Doc* C工具界面View::GetDocument() const // 非调试版本是内联的
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(C工具界面Doc)));
return (C工具界面Doc*)m_pDocument;
#endif //_DEBUG
// C工具界面View 消息处理程序
BOOL C工具界面View::SetupPixelFormat(HDC hDC)
static PIXELFORMATDESCRIPTOR pfd =
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER,
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)
return FALSE;
//设置像素索引
if(SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
return FALSE;
return TRUE;
//创建环境RC
BOOL C工具界面View::CreateViewGLContext(HDC hDC)
//生成绘制描述表
this->m_hGLContext = ::wglCreateContext(hDC);
if(this->m_hGLContext==NULL)
//创建失败
return FALSE;
//设置当前绘制描述表
if(::wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
//选为当前RC失败
return FALSE;
return TRUE;
//gl初始化
BOOL C工具界面View::InitOpengl(CDC *pDC)
m_pDC=new CClientDC(this);
//设置像素格式
if (SetupPixelFormat(hDC) == FALSE)
return 0;
//创建并设置RC
if (CreateViewGLContext(m_pDC->GetSafeHdc()) == FALSE)
return FALSE;
return TRUE;
int C工具界面View::OnCreate(LPCREATESTRUCT lpCreateStruct)
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
m_pDC=new CClientDC(this);
//使用窗口DC来设置RC
InitOpengl(m_pDC);
return 0;
void C工具界面View::OnDestroy()
CView::OnDestroy();
// TODO: 在此处添加消息处理程序代码
if(wglGetCurrentContext()!=NULL)
wglMakeCurrent(NULL,NULL);
if(this->m_hGLContext!=NULL)
wglDeleteContext(this->m_hGLContext);
this->m_hGLContext = NULL;
if (m_pDC->GetSafeHdc())
DeleteObject(m_pDC);
void C工具界面View::OnSize(UINT nType, int cx, int cy)
CView::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
GLsizei width, height;
GLdouble aspect;
width = cx;
height = cy;
if (cy==0)
aspect = (GLdouble)width;
else
aspect = (GLdouble)width/(GLdouble)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,aspect,0.0,200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
void C工具界面View::OnCeshi1()
// TODO: 在此添加命令处理程序代码
CPaintDC dc(this);
ceshifun1(0.0,0.0,0.0);
bool C工具界面View::ceshifun1(float mm=0.0, float nn=0.0,float oo=0.0)
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(100.0,100.0,100.0,0.0,0.0,0.0,0.0,1.0,0.0);
glTranslatef(mm,nn,oo);
glColor3f(0.0,1.0,0.0);
auxWireTeapot(40.00);
glFlush();
::SwapBuffers(m_pDC->GetSafeHdc()); //交换缓冲区
return TRUE;
void C工具界面View::OnCeshi2()
// TODO: 在此添加命令处理程序代码
ceshifun2(60.0,0.0,0.0,0.0,1.0,1.0,1.0);
bool C工具界面View::ceshifun2(float ss=60.0,float aa=0.0,float bb=0.0,float cc=0.0,float dd=1.0,float ee=1.0,float ff=1.0)
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(100.0,100.0,100.0,0.0,0.0,0.0,0.0,1.0,0.0);
glRotatef(ss,aa,bb,cc);
glScalef(dd,ee,ff);
glColor3f(0.0,1.0,0.0);
auxWireTeapot(40.00);
glFlush();
::SwapBuffers(m_pDC->GetSafeHdc()); //交换缓冲区
return true;
void C工具界面View::OnPaint()
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CView::OnPaint()
void C工具界面View::OnLButtonDown(UINT nFlags, CPoint point)
gg++;
hh=gg/10;
// TODO: 在此添加消息处理程序代码和/或调用默认值
C工具界面View::ceshifun2(60.0,0.0,0.0,0.0,hh,hh,hh);
CView::OnLButtonDown(nFlags, point);
void C工具界面View::OnRButtonDown(UINT nFlags, CPoint point)
jj++;
ii=10*jj;
// TODO: 在此添加消息处理程序代码和/或调用默认值
C工具界面View::ceshifun2(ii,7.0,7.0,0.0,1.0,1.0,1.0);
CView::OnRButtonDown(nFlags, point);
void C工具界面View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
// TODO: 在此添加消息处理程序代码和/或调用默认值
kk++;
ll=10*kk;
switch(nChar)
case'w':
case'W':
C工具界面View::ceshifun1(ll,0.0,0.0);
break;
case's':
case'S':
C工具界面View::ceshifun1((-ll),0.0,0.0);
break;
case'a':
case'A':
C工具界面View::ceshifun1(0.0,ll,0.0);
break;
case'd':
case'D':
C工具界面View::ceshifun1(0.0,(-ll),0.0);
break;
CView::OnKeyDown(nChar, nRepCnt, nFlags);
参考技术A void speckeys( int key, int x, int y )
if ( key == GLUT_KEY_LEFT )mm = glm::translate( mm, glm::vec3( -0.1f, 0.0f, 0.0f ) );
else if( key == GLUT_KEY_RIGHT )mm = glm::translate( mm, glm::vec3( 0.1f, 0.0f, 0.0f ) );
else if( key == GLUT_KEY_UP )mm = glm::translate( mm, glm::vec3( 0.0f, 0.0f, -0.1f ) );
else if( key == GLUT_KEY_DOWN )mm = glm::translate( mm, glm::vec3( 0.0f, 0.0f, 0.1f ) );
glutPostRedisplay();
自定义控件实现图像的显示和放大缩小,平移,右击菜单选择“自适应窗口”“保存图像”
前面介绍了2个控件组合在一起实现,对PictureBox控件的操作,今天我们自己新建一个控件来自己用。
新建一个Windows窗体解决方案,添加“用户控件”,把PictureBox控件拖到指定的区域,给我们要自己定义的控件改下名字UserControl_Display
界面就完成了,现在我们要自定义的控件添加事件和右击菜单(contextMenuStrip1)控件
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Drawing; 5 using System.Data; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 11 namespace _自定义控件显示图片 12 { 13 public partial class UserControl_Display : UserControl 14 { 15 16 public System.Drawing.Point mouseDownPoint;//存储鼠标焦点的全局变量 17 public bool isSelected = false; 18 public int width; 19 public int height; 20 21 22 public UserControl_Display() 23 { 24 InitializeComponent(); 25 } 26 27 //这个是显示图片用的 28 public void Display(Image image) 29 { 30 pictureBox1.Image = image; 31 32 width = pictureBox1.Width;//控件的原始大小保存一下,恢复的时候用 33 height = pictureBox1.Height; 36 } 37 38 // 在MouseUp处获知鼠标是否松开,终止拖动操作; 39 private void pictureBox1_MouseUp(object sender, MouseEventArgs e) 40 { 41 isSelected = false; 42 } 43 44 private void pictureBox1_MouseEnter(object sender, EventArgs e) 45 { 46 pictureBox1.Focus(); 47 pictureBox1.Cursor = Cursors.SizeAll; 48 } 49 50 //在MouseDown处获知鼠标是否按下,并记录下此时的鼠标坐标值; 51 private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 52 { 53 if (e.Button == MouseButtons.Left) 54 { 55 mouseDownPoint.X = Cursor.Position.X; //注:全局变量mouseDownPoint前面已定义为Point类型 56 mouseDownPoint.Y = Cursor.Position.Y; 57 isSelected = true; 58 } 61 } 62 63 //图片平移,在MouseMove处添加拖动函数操作 64 private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 65 { 66 if (isSelected && IsMouseInPanel())//确定已经激发MouseDown事件,和鼠标在picturebox的范围内 67 { 68 this.pictureBox1.Left = this.pictureBox1.Left + (Cursor.Position.X - mouseDownPoint.X); 69 this.pictureBox1.Top = this.pictureBox1.Top + (Cursor.Position.Y - mouseDownPoint.Y); 70 mouseDownPoint.X = Cursor.Position.X; 71 mouseDownPoint.Y = Cursor.Position.Y; 72 } 73 } 74 75 private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) 76 { 77 double scale = 1; 78 if (pictureBox1.Height > 0) 79 { 80 scale = (double)pictureBox1.Width / (double)pictureBox1.Height; 81 } 82 pictureBox1.Width += (int)(e.Delta * scale); 83 pictureBox1.Height += e.Delta; 84 } 85 86 87 private bool IsMouseInPanel() 88 { 89 if (this.pictureBox1.Left < PointToClient(Cursor.Position).X 90 && PointToClient(Cursor.Position).X < this.pictureBox1.Left 91 + this.pictureBox1.Width && this.pictureBox1.Top 92 < PointToClient(Cursor.Position).Y && PointToClient(Cursor.Position).Y 93 < this.pictureBox1.Top + this.pictureBox1.Height) 94 { 95 return true; 96 } 97 else 98 { 99 return false; 100 } 101 102 } 103 104 105 /// <summary> 106 /// 右击菜单的保存图像 107 /// </summary> 108 /// <param name="sender"></param> 109 /// <param name="e"></param> 110 private void SaveImage_Click(object sender, EventArgs e) 111 { 112 Image image = this.pictureBox1.Image; 113 string imageName = DateTime.Now.ToString("HH时MM分SS秒") + ".bmp"; 114 image.Save(@imageName); 115 } 116 117 //右击菜单的图像适应控件的大小 118 private void ImageFitPictureBox_Click(object sender, EventArgs e) 119 { 120 pictureBox1.Width = width;//控件的大小恢复 121 pictureBox1.Height = height; 122 123 //PictureBox控件的位置 124 pictureBox1.Left = 1; 125 pictureBox1.Top = 1; 126 } 127 } 128 }
以上是关于opengl如何用键盘实现放大缩小平移的问题的主要内容,如果未能解决你的问题,请参考以下文章
Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能