Reputation: 1848
I am going through the examples in the book "C# Game Programming For Serious Game Creation" and am seeing some strange behavior. I set a viewport and the ortho projection and then try to draw a triangle 50px wide. I am only seeing a tiny portion of the triangle at first, but when I resize the window (e.g., maximize and then restore), the triangle suddenly shows as the correct size.
Here is a simple example that reproduces the issue:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tao.OpenGl;
namespace SimpleExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
_openGLControl.InitializeContexts();
}
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
int width = ClientSize.Width;
int height = ClientSize.Height;
double halfWidth = (double)width / 2;
double halfHeight = (double)height / 2;
Gl.glViewport(0, 0, width, height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(-halfWidth, halfWidth, -halfHeight, halfHeight, -100, 100);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
}
private void _openGLControl_Paint(object sender, PaintEventArgs e)
{
Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
{
Gl.glColor4d(1.0, 0.0, 0.0, 0.5);
Gl.glVertex3d(-50, 0, 0);
Gl.glColor3d(0.0, 1.0, 0.0);
Gl.glVertex3d(50, 0, 0);
Gl.glColor3d(0.0, 0.0, 1.0);
Gl.glVertex3d(0, 50, 0);
}
Gl.glEnd();
Gl.glFinish();
}
}
}
The OnClientSizeChanged event does get triggered when the program starts before the triangle is drawn, but the viewport/ortho don't seem to change anything until I resize the window.
I am using the OpenTk library and including Tao.OpenGL (as you can see). I am using a SimpleOpenGlControl on my form which has Dock set to Fill. Running in VS2012 on Windows 7. I would like to stick as close as possible to the book examples, and not use glut or any extra libraries. Can anyone point out what I'm doing wrong?
Upvotes: 1
Views: 2240
Reputation: 2769
My guess is that the initial OnClientSizeChanged
is called during InitializeComponent();
which would mean that _openGLControl.InitializeContexts();
is not called yet and the changes to the viewport are not applied to your control. So, to fix it, I would set the viewport after you initialised the contexts of the control.
Upvotes: 2
Reputation: 162164
Changing any aspect of an OpenGL view requires a complete redraw of the scene. Since a typical OpenGL rendering will include overlays (HUD, annotation, etc.) it makes no sense to set viewport and projection matrices separately from drawing. Hence glViewport and projection matrix setup should be performed in the drawing routine.
Any changes of window size or other viewing aspect must trigger a full redraw anyway and having the viewport and projection setup in the drawing routine takes care of that without putting further thought into it then.
Upvotes: 2