#c# #opengl #window
#c# #opengl #окно
Вопрос:
я пытаюсь добавить возможность изменять размер окна приложения, не заставляя содержимое окна одновременно растягиваться. я пытался изменить операторы if и пробовал разные вычисления соотношения, чтобы не повлиять
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (mShader != null)
{
int uProjectionLocation = GL.GetUniformLocation(mShader.ShaderProgramID, "uProjection");
int windowHeight = ClientRectangle.Height;
int windowWidth = ClientRectangle.Width;
if (windowHeight > windowWidth)
{
if (windowWidth < 1)
{
windowWidth = 1;
}
float ratio = windowWidth / windowHeight;
Matrix4 projection = Matrix4.CreateOrthographic(ratio * 10, ratio * 10, -1, 1);
GL.UniformMatrix4(uProjectionLocation, true, ref projection);
}
else if(windowHeight < windowWidth)
{
if (windowHeight < 1)
{
windowHeight = 1;
}
float ratio = windowWidth / windowHeight;
Matrix4 projection = Matrix4.CreateOrthographic(ratio * 10, ratio * 10, -1, 1);
GL.UniformMatrix4(uProjectionLocation, true, ref projection);
}
}
GL.Viewport(this.ClientRectangle);
}
Ответ №1:
Прежде всего,
float ratio = windowWidth / windowHeight;
скорее всего, это не то, что вы на самом деле имели в виду при написании этого кода. windowWidth
и windowHeight
оба имеют тип int
, поэтому /
перед преобразованием результата в float
будет выполнено целочисленное деление. В результате ratio
большую часть времени будет составлять ровно 1. И иногда может быть 0 (если высота > ширина). И иногда, возможно, 2 (в некоторых широкоэкранных настройках). Скорее всего, вы хотите что-то более похожее на это:
float ratio = (float)windowWidth / (float)windowHeight;
Однако даже тогда, когда вы вычисляете свою матрицу
Matrix4 projection = Matrix4.CreateOrthographic(ratio * 10, ratio * 10, -1, 1);
вы масштабируете ширину и высоту с помощью ratio
, что означает, что независимо от того, какое соотношение в итоге будет, вы снова получите матрицу для квадратного окна просмотра (поскольку ширина и высота одинаковы). Скорее всего, вы хотите, например, масштабировать только ширину с учетом соотношения сторон
Matrix4 projection = Matrix4.CreateOrthographic(ratio * 10, 10, -1, 1);
Помимо всего этого, обратите внимание, что большая часть фактической функциональности дублируется в обеих ветвях вашего if
оператора. Также обратите внимание, что вы просто пропускаете случай, когда ширина и высота равны. Вы могли бы переписать всю эту кучу «если», например, вот так
float ratio = (float)ClientRectangle.Width / (float)Math.Max(ClientRectangle.Height, 1);
Matrix4 projection = Matrix4.CreateOrthographic(ratio * 10, 10, -1, 1);
GL.UniformMatrix4(uProjectionLocation, true, ref projection);