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();


本回答被提问者和网友采纳
参考技术B 楼上的回答真不是一般的详细啊。。。仔细一看对问题没啥帮助啊。。。不过有可以借鉴的地方啊。。。楼主应该重载消息OnKeyDown啊。。。如果用的只是glut那么响应的应该是那个什么keyboard的函数啊。。。我忘了叫什么了啊。。。而且没有什么所谓的一般代码啊。。。

自定义控件实现图像的显示和放大缩小,平移,右击菜单选择“自适应窗口”“保存图像”

前面介绍了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如何用键盘实现放大缩小平移的问题的主要内容,如果未能解决你的问题,请参考以下文章

openGL按鼠标中键实现放大缩小

纯js实现用键盘控制DIV上下左右+放大缩小与变色

JAVA:放大/缩小时,圆圈被绑定到图像视图中的一个位置

Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能

每次我在前端放大/缩小时,如何以编程方式检查 Altair 图表的放大/缩小功能

OpenGL基础仿射变换原理解析