2015-04-26 39 views
0

我有一個QGLWidget(Qt 5.2.1)。QOpenGLShaderProgram - 多個實例產生損壞的結果

GLWidget實例化兩個其他類,每個類都包含它們自己的QOpenGLShaderPrograms,加載它們自己的着色器,並處理它們自己的圖形。這使得一個很好的封裝。

然而,問題是來自軸網格的數據(第一個被初始化)出現在第二類的着色器中。因此,它從不用自己的着色器繪製自己的對象。如果我逆轉init()調用的順序,則相反的情況會發生。

這兩個繪圖類的結構相同,所以爲了簡潔起見,我只包含Mesh類。

結果如下。繪製線條的AxisMesh將它們繪製在Scatter類上,使用相同的顏色,而不是用它們自己的顏色以及它們應該繪製的位置。

在這幅畫的線條應該是一個不同的顏色和不同的位置: The lines in this picture should be a different color and a different location

問題:

是否允許有兩個QOpenGLShaderPrograms在QGLWidget來繪圖?

下面的方法有什麼問題嗎?

GLWidget initialzeGL方法:

void GLWidget::initializeGL() 
{ 
    // Instantiate our drawing objects 
    m_axisMesh  = new PlotItemAxisMesh(m_plotManager, m_plotSelection, &m_axisScale); 
    m_surfaceScatter = new PlotItemSurfaceScatter(m_plotManager, m_plotSelection, &m_axisScale); 

... 

    // Initialize the axis mesh class 
    m_axisMesh->init(); 

    // Initialize the scatter points class 
    m_surfaceScatter->init(); 
} 

GLWidget paintGL方法:

void GLWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

... 

    // Draw the mesh 
    m_axisMesh->draw(m_camera.data(), modelMatrix); 

    // Draw the points 
    m_surfaceScatter->draw(m_camera.data(), modelMatrix); 
} 

軸網格init方法:

void PlotItemAxisMesh::init() 
{ 
    initializeOpenGLFunctions(); 

    // Initialize the shaders 
    initShaders(); 

    m_program->link(); 
    m_program->bind(); 

    // Load the data into the local VBO 
    build(); 

    // Release (unbind) all 
    m_program->release(); 
} 

軸網格生成方法:

void PlotItemAxisMesh::build() 
{ 
    ShmooPlotMatrix *matrix = m_plotManager->getPlotPointMatrix(); 

    // Calculate the y-axis height in OpenGL terms 
    uint32_t yHeight = (m_xMax + m_yMax)/2; 
    float yScale  = yHeight/fabs(m_axisScale->getMax() - m_axisScale->getMin()); 
    float yOffset = 0 ? m_axisScale->getMin() > 0 : -m_axisScale->getMin(); 

    // Since we swept X/Y but are plotting the points as X/Z, then Y becomes the value 
    m_xMax = matrix->getXMax(); 
    m_yMax = yHeight; 
    m_zMax = matrix->getYMax(); 

    m_vertexArray.clear(); 
    m_vertexArray.reserve(4*(m_xMax + m_yMax)); 

... (load vertexAray with data) 

    m_vertexBuffer.create(); 
    m_vertexBuffer.bind(); 
    m_vertexBuffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); 
    m_vertexBuffer.allocate(&(m_vertexArray.front()), vertexSize); 

    // Tell VBO how to read the data 
    m_positionAttrIndex = m_program->attributeLocation(m_positionAttr); 
    m_colorAttrIndex = m_program->attributeLocation(m_colorAttr); 

    int offset = 0; 
    m_program->enableAttributeArray(m_positionAttrIndex); 
    m_program->setAttributeBuffer(m_positionAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData)); 

    offset = sizeof(QVector3D); 
    m_program->enableAttributeArray(m_colorAttrIndex); 
    m_program->setAttributeBuffer(m_colorAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData)); 

    // Release (unbind) all 
    m_vertexBuffer.release(); 
} 

軸網繪製方法:

void PlotItemAxisMesh::draw(PlotCamera *camera, const QMatrix4x4 &modelMatrix) 
{ 

    m_program->bind(); 
    { 
     // Set modelview-projection matrix 
     m_program->setUniformValue("mvpMatrix", camera->getProjection() * camera->getView() * modelMatrix); 
     m_vertexBuffer.bind(); 
     glDrawArrays(GL_LINES, 0, m_vertexArray.size()); 
     m_vertexBuffer.release(); 
    } 
    m_program->release(); 
} 
+1

我不知道Qt的東西,但我懷疑,這個問題是有關您在設置頂點屬性的方式。頂點設置狀態不是程序的一部分。由於您似乎有在程序類中設置頂點狀態的方法,因此它看起來就像是這樣,這可能會讓您失望。程序和頂點狀態是不相關的,並且將它們設置在同一個類中的方法看起來像一個不幸的設計。 –

+0

謝謝Reto。在設計方面,如果我有兩個需要不同着色器的對象,你會如何設置它們?如果不是將着色器程序封裝爲對象的一部分,您會如何推薦? – Alchete

+1

如果我的理論是正確的,你可以通過在'draw()'方法中調用'enableAttributeArray()'和'setAttributeBuffer()'來調用它。 –

回答

0

謝謝@Reto Koradi爲解決

的修復是改變抽籤的方法來啓用/定在平局時的屬性緩衝區。

void PlotItemAxisMesh::draw(PlotCamera *camera, const QMatrix4x4 &modelMatrix) 
{ 
    m_program->bind(); 
    { 
     m_vertexBuffer.bind(); 

     int offset = 0; 
     m_program->enableAttributeArray(m_positionAttrIndex); 
     m_program->setAttributeBuffer(m_positionAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData)); 

     offset = sizeof(QVector3D); 
     m_program->enableAttributeArray(m_colorAttrIndex); 
     m_program->setAttributeBuffer(m_colorAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData)); 

     // Set modelview-projection matrix 
     m_program->setUniformValue("mvpMatrix", camera->getProjection() * camera->getView() * modelMatrix); 

     glDrawArrays(GL_LINES, 0, m_vertexArray.size()); 
     m_vertexBuffer.release(); 
    } 
    m_program->release(); 
} 

正確繪製

enter image description here