最近在學習C#版本的OpenGL(SharpGL),遇到了一個應用上的問題,請各路神仙幫忙指點一下



功能需求:通過滑鼠滾輪的方式實作圖形放大縮小的功能,要求:放大縮小都已滑鼠所在位置為中心。
先簡單說一下我的實作思路(由于對OpenGL不熟悉,所以很多運算都是自己寫的,各位大神若有更便捷的方法,幫忙指點一下):
1、確定螢屏像素點坐標和視野矩陣坐標之間的對應關系:
1.1、已知控制元件OpenGLControl的width和height,用Ortho設定視野大小,可以得到螢屏像素與視野長寬對應比。
如: gl.Ortho(-10, 10, -10 , 10 , 0.01, 100);
xx = 20.0 / openGLControl1.Width;
yy = 20.0 / openGLControl1.Height;
1.2、螢屏像素坐標是左上角為(0,0),右下角為(width,height),視野中心坐標為(0,0,0),可以得到滑鼠所在位置對應視野坐標:
Mouse_Pos_x = xx * (e.X - openGLControl1.Width / 2);
Mouse_Pos_y = yy * (-e.Y + openGLControl1.Height / 2);
2、滑鼠滾動事件(程式在下面)
3、縮放操作:
在OpenGLlDraw函式中加
gl.Scale(Scale, Scale, Scale);
此時,不加任何平移指令的話,所有的放大縮小都是依據視野中心(0,0,0)進行縮放。
在縮放操作前,加入平移指令gl.Translate(Mouse_Pos_x*(1-Scale), Mouse_Pos_y*(1-Scale), 0),可以實作在指定滑鼠點進行縮放效果。
問題來了,由于OpenGLDraw每次繪制的時候都是依據單位矩陣進行幾何變換,若滑鼠縮放時,滑鼠位置和上次縮放操作位置不同,Mouse_Pos_x和Mouse_Pos_y就不一樣,導致OpenGLDraw繪制的時候會重新以當前滑鼠位置進行縮放平移運算,沒辦法在之前縮放平移的操作基礎上疊加此次平移效果。
想實作一種:此次的縮放平移gl.Translate操作是在上次的縮放平移gl.Translate基礎上的操作。
附上主要程式:
private void openGLControl1_Resized(object sender, EventArgs e)
{
SharpGL.OpenGL gl = this.openGLControl1.OpenGL;
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Ortho(-10, 10, -10 / ratio, 10 / ratio, 0.01, 100);
xx = 20.0 / openGLControl1.Width;
yy = 20.0 / openGLControl1.Height ;
gl.LookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
gl.MatrixMode(OpenGL.GL_MODELVIEW);
}
private void Mouse_Wheel(object sender, MouseEventArgs e)
{
//當e.Delta > 0時滑鼠滾輪是向上滾動,e.Delta < 0時滑鼠滾輪向下滾動
if (Mouse_In_Flag)
{
if (e.Delta < 0)
Scale += 0.1f;
else
Scale -= 0.1f;
if (Scale >= 5)
Scale = 5;
if (Scale <= 0.05)
Scale = 0.05;
Mouse_Pos_x = (double)xx * (e.X - openGLControl1.Width / 2);
Mouse_Pos_y = (double)yy * (-e.Y + openGLControl1.Height / 2);
}
}
private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
{
OpenGL gl=this.openGLControl1.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT|OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
DrawGrid(gl);
gl.PushMatrix();
gl.Translate(Mouse_Pos_x*(1-Scale), Mouse_Pos_y*(1-Scale), 0)
gl.Scale(Scale, Scale, Scale);
gl.Color(1f,1f,0f);
gl.LineWidth(2f);
gl.Begin(OpenGL.GL_LINE_LOOP);
gl.Vertex(0, 0, 0);
gl.Vertex(5, 0, 0);
gl.Vertex(5, 5, 0);
gl.Vertex(0, 5, 0);
gl.End();
gl.PopMatrix();
gl.Flush();
}
uj5u.com熱心網友回復:
已經過去好幾天了,自己頂一下吧最近在研究project和unproject,看看能不能找到好的方法實作
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/26257.html
標籤:C#
