aa12's picture

Graphic shifts when maximizing or minimizing window

Now I am creating a simple 3D plot program. I setup lines to draw a plot and everything looks fine when starting debugging. However, when I minimize the window and go back to the original window size by clicking the icon at the task bar (or simply maximize the window), layout (view point) of the plot does not stay the same. In addition, I put glcontrol on tab 1 of tabcontrol and when I swich between tab 1 and 2, it also changes the layout of the plot. I need the plot stays the same view. I am not sure if c# changes their coordinate system everytime when widnow is changed (minimize, maximize etc.).

Could somebody give me how to fix this issue? Partial codes related to drawing are below. It seems that if I don't use GL.Rotate, problem does not happen. (But then I could not view 3d plot).

namespace _3DPlot
{
public partial class Form1 : Form
{

bool loaded = false;

public Form1()
{
InitializeComponent();

}

private void glControl1_Load(object sender, EventArgs e)
{

loaded = true;
glControl1.MakeCurrent();
GL.ClearColor(Color.White);
SetupViewport();

}

private void glControl1_Paint(object sender, EventArgs e)
{

if (!loaded)
return;

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
glControl1.MakeCurrent();
GL.Rotate(-75, 1, 0, 0);
GL.Rotate(0, 0, 1, 0);
GL.Rotate(40, 0, 0, 1);

GL.Color3(1, 0, 0);

GL.Begin(BeginMode.Lines);
GL.Vertex3(0, 0, 0);
GL.Vertex3(0, 0, 100);
GL.End();

GL.Begin(BeginMode.Lines);
GL.Vertex3(0, 0, 0);
GL.Vertex3(0, 100, 0);
GL.End();

GL.Begin(BeginMode.Lines);
GL.Vertex3(0, 0, 0);
GL.Vertex3(100, 0, 0);
GL.End();

glControl1.SwapBuffers();

}

private void SetupViewport()
{
int w = glControl1.Width;
int h = glControl1.Height;
GL.Viewport(0, 0, w, h);

GL.MatrixMode(MatrixMode.Projection);
//GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();

GL.Ortho(-250, 300, -100, 500, 600, -300);

}

}
}


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
account_deleted's picture

Viewport and projection matrix setup should be done in the paint event because they depend on the size of the window. The load event is called when the control is first added to the window, while the paint event is called every time it is shown or resized.

 private void glControl1_Paint(object sender, PaintEventArgs e)
{
    glControl1.MakeCurrent();
 
    SetupViewport();
 
    // etc etc.
 
    glControl1.SwapBuffers();
}

There's no need for if(!loaded) because paint events are not raised before loading anyway.
Using GL.Ortho(...) to set your projection works fine. However, it's generally a good idea to keep the projection's origin in the center of the screen and to base its dimensions on the dimensions of the viewport.
Zooming can be handled by resizing the projection matrix. Looking at different parts of the plot would be done by moving the Modelview matrix with GL.PushMatrix(), GL.Rotate(x,y,z,w), GL.Translate(x,y,z), and GL.PopMatrix().
Also be careful that you're always in the correct matrix mode and are not adding transformations each time the plot is redrawn.

aa12's picture

Thank you for your reply. Now it works. If you can answer my question regarding your comment, I will appreciate it.

1) You said that it is good idea to keep the origin in the ceter of the screen. Why? Defining the origin at the center makes a code clean and easier to reference later? In that case, should I set like GL.Ortho(0, screenwidth, 0, screen height, 1,-1)?

2) What do you mean by the last sentence ( I am always in the correct matrix mode)?

jrwatts's picture

Setting up your viewport in the paint event is very inefficient. It should be sufficient to only set the viewport when the window is resized.