我正在尝试在640x360
窗口内渲染一个1280x720
红色方块。问题在于OpenGL的视口不会自动进入Qt窗口系统中由正方形占据的区域内。也就是说,如果我的视频对象具有640x360
尺寸,则OpenGl视口仍具有1280x720
尺寸(为什么?)。
无论如何,我可以使用glViewport(this->x, this->y, this->width, this->height);
来解决此问题。问题在于,在OpenGL中,坐标系的原点位于左下角,而this->x, this->y, this->width, this->height
是来自QML语法中对象坐标的,原点位于左上角。结果是这样的:
main.qml :
import QtQuick 2.0
import OpenGlVideoQtQuick2 1.0
Grid {
columns: 2
spacing: 2
width: 1280
height: 720
OpenGlVideoQtQuick2 {
width: 640
height: 360
}
}
,但是红色正方形占据了第三个网格,而不是第一个:
我可以通过进行glViewport(this->x, WINDOW_HEIGHT-this->y, this->width, this->height);
(其中WINDOW_HEIGHT
的值为720
来{strong>轻松来解决此问题,但是我不认为我应该信任OpenGL视口始终具有窗口的大小,因此我应该获取OpenGl视口的尺寸,但我认为这是不可能的。
我尝试过
GLint dims[2] = {9999, 9999};
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, dims);
std::cout << "dimenson x:" << dims[0] << " dimenson y:" << dims[1] << std::endl;
这给了我dimenson x:8192 dimenson y:8192
,这对我来说毫无意义。
您可以在此处查看整个可构建项目:https://github.com/lucaszanella/QQuickPaintedItemBug/tree/0a8ef6b5229afa7113ec1e4e3838981042792329
答案 0 :(得分:2)
这是伪代码中的解决方案:
int w = item->width() * window->devicePixelRatio();
int h = item->height() * window->devicePixelRatio();
int x = item->x();
int y = window->height()* window->devicePixelRatio() - h - item->y()
glViewport(x, y, w, h);
我已经使用Qt 场景图-QML下的OpenGL 示例进行了测试。 这是我所做的更改:
main.qml
Squircle {
x: 80
y: 120
width: 160
height: 240
[...]
}
squircle.cpp
void Squircle::sync()
{
if (!m_renderer) {
m_renderer = new SquircleRenderer();
connect(window(), &QQuickWindow::beforeRendering, m_renderer, &SquircleRenderer::paint, Qt::DirectConnection);
}
m_renderer->setViewportSize(this->size().toSize() * window()->devicePixelRatio());
m_renderer->setPosition(this->position().toPoint());
m_renderer->setT(m_t);
m_renderer->setWindow(window());
}
void SquircleRenderer::paint()
{
[...]
int y = (m_window->size()* m_window->devicePixelRatio()).height() - m_viewportSize.height() - m_position.y();
glViewport(m_position.x(), y, m_viewportSize.width(), m_viewportSize.height());
[...]
}
squircle.h
class SquircleRenderer : public QObject, protected QOpenGLFunctions
{
Q_OBJECT
public:
void setPosition(const QPoint &position) { m_position = position; }
[...]
private:
[...]
QPoint m_position;
};
结果如下: