我在main qml中创建了两个Squircle项目实例
第一个实例在屏幕中心的大小为500,500对齐
第二个实例的屏幕尺寸对齐大小以完成屏幕
一次只能播放一件事但是在第一次播放器播放期间我无法看到视频因为二次播放器glviewport覆盖整个屏幕及其清除因为画面总是连接到beforeRendering信号
代码:
.h
#ifndef SQUIRCLE_H
#define SQUIRCLE_H
#include <QtQuick/QQuickItem>
#include <QtGui/QOpenGLShaderProgram>
//! [1]
class SquircleRenderer : public QObject {
Q_OBJECT
public:
SquircleRenderer() : m_t(0), m_program(0) {}
~SquircleRenderer();
void setT(qreal t) { m_t = t; }
void setViewportSize(const QRectF &size) { m_viewportSize = size; }
public slots:
void paint();
private:
QRectF m_viewportSize;
qreal m_t;
QOpenGLShaderProgram *m_program;
};
//! [1]
//! [2]
class Squircle : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
public:
Squircle();
qreal t() const { return m_t; }
void setT(qreal t);
signals:
void tChanged();
public slots:
void sync();
void cleanup();
private slots:
void handleWindowChanged(QQuickWindow *win);
private:
qreal m_t;
SquircleRenderer *m_renderer;
};
//! [2]
#endif // SQUIRCLE_H
的.cpp
#include "squircle.h"
#include <QtQuick/qquickwindow.h>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
//! [7]
//!
Squircle::Squircle()
: m_t(0)
, m_renderer(0)
{
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
}
//! [7]
//! [8]
void Squircle::setT(qreal t)
{
if (t == m_t)
return;
m_t = t;
emit tChanged();
if (window())
window()->update();
}
//! [8]
//! [1]
void Squircle::handleWindowChanged(QQuickWindow *win)
{
if (win) {
connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), Qt::DirectConnection);
connect(win, SIGNAL(sceneGraphInvalidated()), this, SLOT(cleanup()), Qt::DirectConnection);
//! [1]
// If we allow QML to do the clearing, they would clear what we paint
// and nothing would show.
//! [3]
win->setClearBeforeRendering(false);
}
}
//! [3]
//! [6]
void Squircle::cleanup()
{
if (m_renderer) {
delete m_renderer;
m_renderer = 0;
}
}
SquircleRenderer::~SquircleRenderer()
{
delete m_program;
}
//! [6]
//! [9]
void Squircle::sync()
{
if (!m_renderer) {
m_renderer = new SquircleRenderer();
connect(window(), SIGNAL(beforeRendering()), m_renderer, SLOT(paint()), Qt::DirectConnection);
}
QRectF re(mapToScene(parentItem()->boundingRect().topLeft()),parentItem()->boundingRect().size());
m_renderer->setViewportSize(re);
m_renderer->setT(m_t);
}
//! [9]
//! [4]
void SquircleRenderer::paint()
{
if (!m_program) {
m_program = new QOpenGLShaderProgram();
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform lowp float t;"
"varying highp vec2 coords;"
"void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}");
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
}
//! [4] //! [5]
m_program->bind();
m_program->enableAttributeArray(0);
float values[] = {
-1, -1,
1, -1,
-1, 1,
1, 1
};
m_program->setAttributeArray(0, GL_FLOAT, values, 2);
m_program->setUniformValue("t", (float) m_t);
glViewport(m_viewportSize.x(), m_viewportSize.y(), m_viewportSize.width(), m_viewportSize.height());
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glScissor(m_viewportSize.x(), m_viewportSize.y(), m_viewportSize.width(), m_viewportSize.height());
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_program->disableAttributeArray(0);
m_program->release();
}
//! [5]
loader 有人可以帮助我解决这个问题。
答案 0 :(得分:1)
我创建了两个opengl项目实例
没有名为“OpenGL Item ”的东西。 OpenGL只需绘制点,线和三角形就可以了。在OpenGL中清除意味着创建一个空白的平板以进行绘制。 OpenGL中没有“对象”或“项目”。
如果你用OpenGL绘制了几个“东西”,并且想要改变其中一个“东西”的外观,你必须清除帧缓冲区,并用你想要的东西重新绘制每个“东西”在新状态下出现改变。