OpenGL Resize Window -> 对象被“移动/翻译”
Posted
技术标签:
【中文标题】OpenGL Resize Window -> 对象被“移动/翻译”【英文标题】:OpenGL Resize Window -> objects are “moved / translated” 【发布时间】:2019-02-12 13:15:20 【问题描述】:当窗口的resize事件被调用时,对象被移出视口/屏幕。
下面的链接是一个视频,展示了正在发生的事情: https://drive.google.com/file/d/1dBnOqBDUBNCQrwr7ChFlpS8vbBQ6wfKh/view?usp=sharing
我刚刚发现它只是在使用 QT Windowing 时发生。 GLFW 并没有发生这种情况... wooow
我使用以下代码:
void Renderer::resize(int width, int height)
RendererSettings* settings = RendererSettings::getInstance();
settings->setSize(width, height);
glViewport(0, 0, width, height);
if (camera != nullptr)
float aspectRatio = float(width) / float(height);
camera->updateProjectionPerspectiveAspect(aspectRatio);
我不再更换相机了。
updateProjectionPerspectiveAspect
与 glFrustum(FoV, aspect, near, far)
相同。但其他参数的数据保持不变。
void Camera::setProjectionPerspective(float fieldOfView, float aspectRatio, float near, float far)
this->fieldOfView = fieldOfView;
this->aspectRatio = aspectRatio;
this->nearFrustum = near;
this->farFrustum = far;
float xmin, xmax, ymin, ymax; // Dimensions of near clipping plane
float xFmin, xFmax, yFmin, yFmax; // Dimensions of far clipping plane
// Do the Math for the near clipping plane
ymax = near * tanf(float(fieldOfView * PI_DIV_360));
ymin = -ymax;
xmin = ymin * aspectRatio;
xmax = -xmin;
// Construct the projection matrix
projectionMatrix = Mat4f::identity();
projectionMatrix[0] = (2.0f * near) / (xmax - xmin);
projectionMatrix[5] = (2.0f * near) / (ymax - ymin);
projectionMatrix[8] = (xmax + xmin) / (xmax - xmin);
projectionMatrix[9] = (ymax + ymin) / (ymax - ymin);
projectionMatrix[10] = -((far + near) / (far - near));
projectionMatrix[11] = -1.0f;
projectionMatrix[14] = -((2.0f * far * near) / (far - near));
projectionMatrix[15] = 0.0f;
Camera 参数不为空,并且在调整大小期间会调用此事件“resize”。参数宽度和高度是正确的。
【问题讨论】:
您好,您使用的不是普通的 OpenGL,您有某种额外的 API 覆盖它。请指定您的工具,或者如果您不知道,请向我们展示您的工具 嗨,您记录了width
和height
的值吗?他们是正确的吗?此外是camera
null
还是if
branch 被执行?
@tomerzeitune updateProjectionPerspectiveAspect 与 glFrustum 相同。在OpenGL ES中没有用到,所以上面的代码是OpenGL。
@bitflip-at 参数正确,摄像头不为空。我只更新投影矩阵相机。
@Bruno 这是 openGL ES 吗?我不明白这个相机类是什么。
【参考方案1】:
我认为你的投影矩阵是错误的,主要是因为你根本没有使用变量aspectRatio
,但是你这样做的方式看起来是正确的..? (所以这只是我的猜测:P)
这是我使用纵横比参数在 C 中制作投影矩阵的方法,也许这会有所帮助
mat4 set_perspective_matrix(GLfloat fov, GLfloat aspect, GLfloat nearPlane, GLfloat farPlane)
mat4 p;
GLfloat f = 1.0/ tan(fov * 3.1415926/360.0);
GLfloat c1 = -(farPlane + nearPlane) / (farPlane - nearPlane);
GLfloat c2 = -(2.0 * farPlane * nearPlane) / (farPlane - nearPlane);
p._[0] = f/aspect;
p._[1] = 0.0;
p._[2] = 0.0;
p._[3] = 0.0;
p._[4] = 0.0;
p._[5] = f;
p._[6] = 0.0;
p._[7] = 0.0;
p._[8] = 0.0;
p._[9] = 0.0;
p._[10] = c1;
p._[11] = c2;
p._[12] = 0.0;
p._[13] = 0.0;
p._[14] =-1.0;
p._[15] = 0.0;
return p;
这是一篇描述投影矩阵设置的好文章:The Perspective Matrix
【讨论】:
他确实使用投影矩阵的纵横比 哦,我明白了。 (没有代码着色,我迷路了)好吧,也许这仍然有帮助 @bitflip-at 我用这个透视矩阵做了一些工作,比如 BSP Tree 3D,但我想我从来没有调整过调整后的大小。今晚我会试试你的建议。你可能是对的。 @bitflip-at 为了与 OpenGL 一起使用,这个投影矩阵必须被转置。 @bitflip-at 不幸的是,我尝试了代码并且发生了同样的事情。当我调整大小时,对象被翻译到窗口的右边框。但非常感谢您的提示。【参考方案2】:问题出在 QT Windowing 上。使用以下代码调整大小已解决:
void QtOpenGLRenderer::resizeEvent(QResizeEvent* event)
QSize size = event->size();
if (event->oldSize().isEmpty())
initialScreenSize = size;
return;
size = parentWidget->size();
float deltaX = size.width() - initialScreenSize.width();
float deltaY = size.height() - initialScreenSize.height();
renderer->resize(size.width() - deltaX, size.height() - deltaY);
【讨论】:
以上是关于OpenGL Resize Window -> 对象被“移动/翻译”的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript/JQuery: $(window).resize 调整大小完成后如何触发?
在 Angular 2 中测试由“(window:resize)”事件触发的函数
jquery $(window).resize 事件在移动向上或向下滚动时触发
将div height设置为与window相同(在window resize时调整大小)