2015-01-21 8 views
10

मैं कच्चे ओपनजीएल कॉल का उपयोग कर QtQuick दृश्य में एक आइटम खींचना चाहता हूं। मैंने this question में सुझाए गए दृष्टिकोण को लेने का निर्णय लिया है।कच्चे ओपनजीएल कॉल के साथ एक क्यूएमएल आइटम ड्राइंग के साथ समस्या

मैं QQuickFramebufferObject से पाने के लिए एक क्यूटी त्वरित आइटम बनाया और QML करने के लिए इसे Renderer के रूप में सामने आ रहा है:

class FboInSGRenderer : public QQuickFramebufferObject { 
    Q_OBJECT 
public: 
    Renderer *createRenderer() const; 
}; 

स्रोत फ़ाइल:

class LogoInFboRenderer : public QQuickFramebufferObject::Renderer { 
    public: 
     LogoInFboRenderer() { } 

     void render() { 
      int width = 1, height = 1; 
      glEnable(GL_BLEND); 
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
      glColor4f(0.0, 1.0, 0.0, 0.8); 
      glBegin(GL_QUADS); 
      glVertex2f(0, 0); 
      glVertex2f(width, 0); 
      glVertex2f(width, height); 
      glVertex2f(0, height); 
      glEnd(); 

      glLineWidth(2.5); 
      glColor4f(0.0, 0.0, 0.0, 1.0); 
      glBegin(GL_LINES); 
      glVertex2f(0, 0); 
      glVertex2f(width, height); 
      glVertex2f(width, 0); 
      glVertex2f(0, height); 
      glEnd(); 

      update(); 
     } 

     QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { 
      QOpenGLFramebufferObjectFormat format; 
      format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); 
      format.setSamples(4); 
      return new QOpenGLFramebufferObject(size, format); 
     } 
}; 

QQuickFramebufferObject::Renderer *FboInSGRenderer::createRenderer() const { 
    return new LogoInFboRenderer(); 
} 

में: (Scene Graph - Rendering FBOs कोड क्यूटी उदाहरण पर आधारित है) क्यूएमएल मैं इसे निम्नानुसार उपयोग करता हूं:

import QtQuick 2.4 
import SceneGraphRendering 1.0 

Rectangle { 
    width: 400 
    height: 400 
    color: "purple" 
    Renderer { 
     id: renderer 
     anchors.fill: parent 
    } 
} 

मैं वा देखने के लिए कि गाया "एक्स" पूरे दृश्य को भरने जाएगा उम्मीद है, लेकिन इसके बजाय मैं परिणाम नीचे प्रस्तुत हो:

enter image description here

अन्य प्रयोगों पुष्टि करते हैं कि आकर्षित किया आकार हमेशा यह आकार (चौड़ाई/ऊंचाई) विभाजित है लगते हैं 2.

मैंने यह भी देखा कि createFramebufferObject में size पैरामीटर सही मान है।

दस्तावेज़ों में देखकर मुझे textureFollowsItemSizeQQuickFramebufferObject कक्षा में संपत्ति का नेतृत्व किया, लेकिन यह डिफ़ॉल्ट रूप से true पर सेट किया गया है।

क्या मैं कुछ गलत कर रहा हूं या क्या मुझे इस व्यवहार को क्यूटी बग के रूप में माना जाना चाहिए?

+0

मैं QQuick पता नहीं है, लेकिन ओपन और मैं नहीं दिख रहा है या तो आप एक कैमरा स्थापित किया है कि (प्रक्षेपण या मॉडलव्यू) या एक व्यूपोर्ट। यदि आप डिफ़ॉल्ट opengl कैमरा का उपयोग करते हैं तो यह नकारात्मक z-axis को देखता है। इस प्रकार, जब सकारात्मक एक्स- और वाई-क्वाड्रंट में चित्रण करते हैं तो मैं आपके द्वारा दिखाए जाने वाले परिणाम की अपेक्षा करता हूं (याद रखें, ओपनजी वाई में उल्टा है)। फ्रेमबफर में कुछ 2 डी आइटम प्रस्तुत करने के लिए मैं ज़ेड-दिशा में ऑर्थो कैमरा सेट करता हूं और उदाहरण के लिए सीमाओं [0,0] से [pixels_width, pixels_height] के साथ एक glViewport सेट करेगा। – Thomas

+0

मैंने आपके कोड का उपयोग किया है - मेरे मामले में हरी चीज़ केवल एक बार प्रस्तुत की जाती है। ऐसा क्यों है? – Pietrko

उत्तर

2

तैयार आयत आधे आकार है क्योंकि डिफ़ॉल्ट समन्वय सीमा है [-1, 1], नहीं [0, 1] के रूप में अपने कोड मान लिया गया है कि आप उम्मीद । आप उपयोग करना चाहते हैं [0, 1] पैमाने पर है, तो आप उचित रूप से स्थापित करना चाहिए प्रक्षेपण मैट्रिक्स:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); 
+0

धन्यवाद! यह मेरी समस्या हल करता है, हालांकि मैं दूसरे में चला जाता हूं: जब मैं उस आइटम को बदलता हूं जिसमें उस आइटम को शामिल किया गया है, तो फ्रेम-बफर ऑब्जेक्ट कलाकृतियों से भरा जा रहा है - आइटम सही ढंग से प्रस्तुतकर्ता नहीं है। मैं इसे और जांचने की कोशिश करूंगा और अगर मुझे जवाब नहीं मिलेगा तो शायद मैं नया प्रश्न पोस्ट करूंगा। – pawel

+0

क्या आपको विंडो आकार बदलने के बारे में नई समस्या का समाधान मिला? – Mauri

0

क्यूटी प्रलेखन कहते हैं: "Warning: It is crucial that OpenGL operations and interaction with the scene graph happens exclusively on the rendering thread, primarily during the updatePaintNode() call. The best rule of thumb is to only use classes with the "QSG" prefix inside the QQuickItem::updatePaintNode() function." मैं इसे इस तरह से कार्य करें:

* ज

class MyQuickItem : public QQuickItem 
{ 
    Q_OBJECT 
public: 
    MyQuickItem(); 
    ~MyQuickItem(); 

protected: 
    QSGNode *updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData); 
    QSGNode *addNode(QSGGeometry *geometry, const QColor &color); 
}; 

* सीपीपी

MyQuickItem::MyQuickItem() 
{ 
    setFlag(QQuickItem::ItemHasContents,true); 
} 

MyQuickItem::~MyQuickItem() 
{ 

} 

QSGNode *MyQuickItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) 
{ 
    Q_UNUSED(updatePaintNodeData) 

    QSGTransformNode *root = static_cast<QSGTransformNode *>(oldNode); 
    if(!root) root = new QSGTransformNode; 
    QSGNode *node; 
    QSGGeometry *geometry; 

    QSGSimpleRectNode *rect = new QSGSimpleRectNode(); 
    rect->setColor(Qt::green); 
    rect->setRect(boundingRect()); 
    root->appendChildNode(rect); 

    geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2); 
    geometry->setDrawingMode(GL_LINES); 
    geometry->setLineWidth(5.0); 
    geometry->vertexDataAsPoint2D()[0].set(x(), y()); 
    geometry->vertexDataAsPoint2D()[1].set(width(), height()); 
    node = addNode(geometry,Qt::blue); 
    root->appendChildNode(node); 

    geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2); 
    geometry->setDrawingMode(GL_LINES); 
    geometry->setLineWidth(5.0); 
    geometry->vertexDataAsPoint2D()[0].set(width(), y()); 
    geometry->vertexDataAsPoint2D()[1].set(x(), height()); 
    node = addNode(geometry,Qt::blue); 
    root->appendChildNode(node); 

    return root; 
} 

QSGNode *MyQuickItem::addNode(QSGGeometry *geometry, const QColor &color) 
{ 
    QSGFlatColorMaterial *material = new QSGFlatColorMaterial; 
    material->setColor(color); 
    QSGGeometryNode *node = new QSGGeometryNode; 
    node->setGeometry(geometry); 
    node->setFlag(QSGNode::OwnsGeometry); 
    node->setMaterial(material); 
    node->setFlag(QSGNode::OwnsMaterial); 
    return node; 
} 

मुख्य हैं। सीपीपी

qmlRegisterType<MyQuickItem>("MyObjects", 1, 0, "MyObject"); 

और उपयोग:

import QtQuick 2.3 
import QtQuick.Window 2.2 
import MyObjects 1.0  

Window { 
    visible: true 
    width: 360 
    height: 360 

    MyObject { 
     anchors.fill: parent 
    } 
} 
+0

धन्यवाद, दुर्भाग्य से यह वही नहीं है जो मैं चाहता था। मुझे यह दृष्टिकोण पता है लेकिन मेरे मामले में मुझे कच्चे ओपनजीएल को कॉल करने की ज़रूरत है (मैं बाहरी पुस्तकालय के साथ एकीकृत हूं जो उस आइटम पर चित्रित होना चाहिए)। जिन चीजों को मैं करने की कोशिश कर रहा हूं, वह संभव होना चाहिए - उदाहरण के लिए मैंने अपने प्रश्न में उल्लेख किया है, यह भी है (दृश्य ग्राफ - प्रस्तुत करने वाले एफबीओ)। – pawel

संबंधित मुद्दे