当鼠标移动时,我正在尝试用正方形绘制光标位置。
我正在使用 SharpGL 和 OpenGLControl,但光标箭头和绘制的正方形之间存在延迟。
在 MouseMove 事件中,我存储了一个以鼠标位置为中心的正方形(映射在 _pointCursor 中,它是一个顶点列表),然后在控件的 Draw 事件中,我实际绘制它:
private void DrawPointers(OpenGL gl)
{
if (_pointCursor == null)
return;
SetColor(gl, Color.LightGray);
gl.Begin(OpenGL.GL_LINE_LOOP);
foreach (var item in _pointCursor)
{
gl.Vertex(item.X, item.Y, item.Z);
}
gl.End();
}
为了避免这种延迟,是否有任何技巧、配置或策略?
我认为问题在于如何绘制所有内容。如果我删除DrawAxis()
并且DrawGrid()
没有更多的延迟。在这种情况下,它可能取决于我的绘图策略,我使用了很多gl.Begin()
and gl.End()
。
另一件事是,DrawGrid()
并DrawAxis()
继续绘制一个固定的背景。我不使用着色器。
这是代码:
private void MouseDrawCursors(XglVertex v)
{
if ((_view == ViewType._2D) && ((_status == EditStatus.Idle) || (_status == EditStatus.DrawLine)))
{
_pointCursor = v.DrawSquare(0.1f); //Return a list of vertex
_pointCross = v.DrawCross(20); //Return a list of vertex
}
}
private void openGLControl1_MouseMove(object sender, MouseEventArgs e)
{
if (_gl == null)
return;
double worldX = 0;
double worldY = 0;
double worldZ = 0;
_gl.GetWorldCoords(e.X, e.Y, ref worldX, ref worldY, ref worldZ);
XglVertex v = new XglVertex((float)worldX, (float)worldY, (float)worldZ);
MouseDrawCursors(v);
}
private void Draw()
{
if (_gl == null)
return;
//Enable 3D
if (_view == ViewType._2D)
_gl.Disable(OpenGL.GL_DEPTH_TEST);
else
_gl.Enable(OpenGL.GL_DEPTH_TEST);
_gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
//Enable Aplpha
_gl.Enable(OpenGL.GL_BLEND);
_gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
#region Projection
_gl.MatrixMode(OpenGL.GL_MODELVIEW);
_gl.LoadIdentity();
_gl.Scale(Params.ScaleFactor, Params.ScaleFactor, Params.ScaleFactor);
_gl.Translate(Params.X, Params.Y, Params.Z);
if (_status == EditStatus.Rotate)
_arc_ball_effect.ArcBall.TransformMatrix(_gl);
else
_gl.Rotate(Params.XAngle, Params.YAngle, Params.ZAngle);
_gl.MatrixMode(OpenGL.GL_PROJECTION); //matrice di proiezione
_gl.LoadIdentity(); //ripristina matrice identità
float worldWidth = Params.Width;
float worldHeight = Params.Height;
float near = Params.Near;
float far = Params.Far;
_gl.Viewport(0, 0, openGLControl1.Width, openGLControl1.Height);
if (_aspect_ratio >= 1.0)
_gl.Ortho(0, (worldWidth * _aspect_ratio), 0, worldHeight, near, far);
else
_gl.Ortho(0, worldWidth, 0, (worldHeight / _aspect_ratio), near, far);
#endregion
if (Params.ShowPointers)
DrawPointers(_gl);
if (Params.ShowAxis)
DrawAxis(_gl);
if (Params.ShowGrid)
DrawGrid(_gl);
_gl.Flush();
}
private void DrawPointers(OpenGL gl)
{
if (_pointCursor == null)
return;
if (_pointCursor.Count == 0)
return;
SetColor(gl, Color.LightGray);
gl.Begin(OpenGL.GL_LINE_LOOP);
foreach (var item in _pointCursor)
{
gl.Vertex(item.X, item.Y, item.Z);
}
gl.End();
if (_pointCross == null)
return;
SetColor(gl, Color.LightGreen);
gl.Begin(OpenGL.GL_LINES);
foreach (var item in _pointCross)
{
gl.Vertex(item.X, item.Y, item.Z);
}
gl.End();
}
private void DrawGrid(OpenGL gl)
{
if (_gl == null)
return;
if (_grid == null)
return;
if (!Params.ShowGrid)
return;
SetColor(gl, _grid.GridColor);
if (_grid.EnableXY)
{
gl.Begin(OpenGL.GL_POINTS);
foreach (var p in _grid.XY)
{
gl.Vertex(p.X, p.Y, p.Z);
}
gl.End();
}
if (_grid.EnableYZ)
{
gl.Begin(OpenGL.GL_POINTS);
foreach (var p in _grid.YZ)
{
gl.Vertex(p.X, p.Y, p.Z);
}
gl.End();
}
if (_grid.EnableZX)
{
gl.Begin(OpenGL.GL_POINTS);
foreach (var p in _grid.ZX)
{
gl.Vertex(p.X, p.Y, p.Z);
}
gl.End();
}
}