First, I'm under the assumption that it's possible to have multiple shader programs and that only the currently bound one is active.

I have a QGLWidget (Qt 5.2.1).

The GLWidget instantiates two other classes that each contain their own QOpenGLShaderPrograms, load their own shaders, and handle their own drawing. This makes for a nice encapsulation.

HOWEVER -- the issue is that the data from the axis mesh (first one being initialized) is appearing in the second class's shader. So, it never draws it's own object with it's own shader. If I reverse the order of init() calls, the same thing happens in reverse.

The two drawing classes are structured identically, so I'm including only the Mesh class for brevity.

Here's the result. The AxisMesh, which draws lines, is drawing them over the Scatter class, with the same color, instead of in their own color and where they're supposed to be drawn.

opengl_issue.jpg

Is it allowed to have two QOpenGLShaderPrograms in a QGLWidget?
Is there something wrong with the approach below?

Qt Code:
  1. void GLWidget::initializeGL()
  2. {
  3. // Instantiate our drawing objects
  4. m_axisMesh = new PlotItemAxisMesh(m_plotManager, m_plotSelection, &m_axisScale);
  5. m_surfaceScatter = new PlotItemSurfaceScatter(m_plotManager, m_plotSelection, &m_axisScale);
  6.  
  7. ...
  8.  
  9. // Initialize the axis mesh class
  10. m_axisMesh->init();
  11.  
  12. // Initialize the scatter points class
  13. m_surfaceScatter->init();
  14. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. void GLWidget::paintGL()
  2. {
  3. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  4.  
  5. ...
  6.  
  7. // Draw the mesh
  8. m_axisMesh->draw(m_camera.data(), modelMatrix);
  9.  
  10. // Draw the points
  11. m_surfaceScatter->draw(m_camera.data(), modelMatrix);
  12. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. void PlotItemAxisMesh::init()
  2. {
  3. initializeOpenGLFunctions();
  4.  
  5. // Initialize the shaders
  6. initShaders();
  7.  
  8. m_program->link();
  9. m_program->bind();
  10.  
  11. // Load the data into the local VBO
  12. build();
  13.  
  14. // Release (unbind) all
  15. m_program->release();
  16. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. void PlotItemAxisMesh::build()
  2. {
  3. ShmooPlotMatrix *matrix = m_plotManager->getPlotPointMatrix();
  4.  
  5. // Calculate the y-axis height in OpenGL terms
  6. uint32_t yHeight = (m_xMax + m_yMax)/2;
  7. float yScale = yHeight / fabs(m_axisScale->getMax() - m_axisScale->getMin());
  8. float yOffset = 0 ? m_axisScale->getMin() > 0 : -m_axisScale->getMin();
  9.  
  10. // Since we swept X/Y but are plotting the points as X/Z, then Y becomes the value
  11. m_xMax = matrix->getXMax();
  12. m_yMax = yHeight;
  13. m_zMax = matrix->getYMax();
  14.  
  15. m_vertexArray.clear();
  16. m_vertexArray.reserve(4*(m_xMax + m_yMax));
  17.  
  18. ... (load vertexAray with data)
  19.  
  20. m_vertexBuffer.create();
  21. m_vertexBuffer.bind();
  22. m_vertexBuffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
  23. m_vertexBuffer.allocate(&(m_vertexArray.front()), vertexSize);
  24.  
  25. // Tell VBO how to read the data
  26. m_positionAttrIndex = m_program->attributeLocation(m_positionAttr);
  27. m_colorAttrIndex = m_program->attributeLocation(m_colorAttr);
  28.  
  29. int offset = 0;
  30. m_program->enableAttributeArray(m_positionAttrIndex);
  31. m_program->setAttributeBuffer(m_positionAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData));
  32.  
  33. offset = sizeof(QVector3D);
  34. m_program->enableAttributeArray(m_colorAttrIndex);
  35. m_program->setAttributeBuffer(m_colorAttrIndex, GL_FLOAT, offset, 3, sizeof(VertexData));
  36.  
  37. // Release (unbind) all
  38. m_vertexBuffer.release();
  39. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. void PlotItemAxisMesh::draw(PlotCamera *camera, const QMatrix4x4 &modelMatrix)
  2. {
  3.  
  4. m_program->bind();
  5. {
  6. // Set modelview-projection matrix
  7. m_program->setUniformValue("mvpMatrix", camera->getProjection() * camera->getView() * modelMatrix);
  8. m_vertexBuffer.bind();
  9. glDrawArrays(GL_LINES, 0, m_vertexArray.size());
  10. m_vertexBuffer.release();
  11. }
  12. m_program->release();
  13. }
To copy to clipboard, switch view to plain text mode