问题
I paint some figures using GLControl (OpenTK) in Windows forms. However, the problem is that I cannot figure out, how to use GL.Ortho() method.
Here is the code I have written:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void GlControlPaint(object sender, PaintEventArgs e)
{
GlControl.MakeCurrent();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Viewport(150, 150, 300, 300);
//GL.Ortho(0, 1, 0, 1, -1, 1);
GL.ClearColor(Color.White);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.2, 0.2, 0.45, 0.2, 0.45, -0.2, 0.2, -0.2);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.1, -0.1, 0.1, 0.1, 0.2, 0.2, 0.2, -0.2);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.2, -0.2, -0.45, -0.2, -0.45, 0.2, -0.2, 0.2);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.1, 0.1, -0.1, -0.1, -0.2, -0.2, -0.2, 0.2);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.1, 0.1, -0.2, 0.2, 0.2, 0.2, 0.1, 0.1);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.1, -0.1, 0.2, -0.2, -0.2, -0.2, -0.1, -0.1);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.2, 0.2, -0.2, 0.45, 0.2, 0.45, 0.2, 0.2);
PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.2, -0.2, 0.2, -0.45, -0.2, -0.45, -0.2, -0.2);
PaintSquareOrBorder(BeginMode.LineLoop, Color.Black, -0.1, -0.1, 0.1, -0.1, 0.1, 0.1, -0.1, 0.1);
PaintBordersForMainFigure();
GlControl.SwapBuffers();
GlControl.Refresh();
}
private void PaintBordersForMainFigure()
{
PaintLine(Color.Black, 0.2, 0.2, 0.45, 0.2);
PaintLine(Color.Black, 0.45, 0.2, 0.45, -0.2);
PaintLine(Color.Black, 0.45, -0.2, 0.2, -0.2);
PaintLine(Color.Black, 0.2, -0.2, 0.2, -0.45);
PaintLine(Color.Black, 0.2, -0.45, -0.2, -0.45);
PaintLine(Color.Black, -0.2, -0.45, -0.2, -0.2);
PaintLine(Color.Black, -0.2, -0.2, -0.45, -0.2);
PaintLine(Color.Black, -0.45, -0.2, -0.45, 0.2);
PaintLine(Color.Black, -0.45, 0.2, -0.2, 0.2);
PaintLine(Color.Black, -0.2, 0.2, -0.2, 0.45);
PaintLine(Color.Black, -0.2, 0.45, 0.2, 0.45);
PaintLine(Color.Black, 0.2, 0.45, 0.2, 0.2);
}
private static void PaintLine(Color color, double x1, double y1, double x2, double y2)
{
GL.Color3(color);
GL.Begin(BeginMode.Lines);
GL.Vertex2(x1, y1);
GL.Vertex2(x2, y2);
GL.End();
}
private static void PaintSquareOrBorder(BeginMode beginMode, Color color, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
GL.Color3(color);
GL.Begin(beginMode);
GL.Vertex2(x1, y1);
GL.Vertex2(x2, y2);
GL.Vertex2(x3, y3);
GL.Vertex2(x4, y4);
GL.End();
}
}
This is the result I get without GL.Ortho:
This is the result I would like to get with GL.Ortho
But if I uncomment the GL.Ortho code, I get this:
At first I thought, that as I use 2d objects only, I should use Ortho2D for that. However, I found out that Gl.Ortho2d does not exist in OpenTK. Using official documentation I found out, that there isn't that much of a difference between these 2, except for the fact that when Ortho2d is used near and far parameters are implicitly set to -1 and 1 respectively.
Having set those parameters, I get a white screen. I would like to know, what am I doing wrong?
DISCLAIMER: I don't need the exact coordinates to achieve the result in the screenshot. I just use it in order for you to see what I am trying to do. What I would like to get the idea why my window is completely blank when I use Gl.Ortho2d.
回答1:
The problem is that GL.Ortho() multiplies the current matrix with an orthographic matrix. So with each rendered frame you keep multiplying your matrix with a new orthographic matrix, and your view drifts away somewhere where you cant see anything.
Change it to something like that, and you see a nice animation:
GL.Ortho(-0.99, 1, -0.99, 1, -1, 1);
Add those two lines in front of your GL.Ortho() call, this way the matrix is an identity matrix before you multiply it with your orthographic matrix.
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
回答2:
This is how i do at my project. Hope that helps. But i dont remember why i did in this way.
GL.MatrixMode(MatrixMode.Projection);
Matrix4 ortho = Matrix4.CreateOrthographic(glControl1.Width, glControl1.Height, 10, 3000);
GL.LoadMatrix(ref ortho);
v = Matrix4.LookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref v);
my viewport is GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
来源:https://stackoverflow.com/questions/15477367/how-to-use-gl-ortho-in-opentk-correctly