void ShaderEffectItem::bindGeometry() { if (!m_program) return; char const *const *attrNames = m_attributeNames.constData(); int offset = 0; for (int j = 0; j < m_attributeNames.size(); ++j) { if (!*attrNames[j]) continue; Q_ASSERT_X(j < m_geometry.attributeCount(), "ShaderEffectItem::bindGeometry()", "Geometry lacks attribute required by material"); const QSGGeometry::Attribute &a = m_geometry.attributes()[j]; Q_ASSERT_X(j == a.position, "ShaderEffectItem::bindGeometry()", "Geometry does not have continuous attribute positions"); #if defined(QT_OPENGL_ES_2) GLboolean normalize = a.type != GL_FLOAT; #else GLboolean normalize = a.type != GL_FLOAT && a.type != GL_DOUBLE; #endif if (normalize) qWarning() << "ShaderEffectItem::bindGeometry() - non supported attribute type!"; m_program->setAttributeArray(a.position, (GLfloat*) (((char*) m_geometry.vertexData()) + offset), a.tupleSize, m_geometry.stride()); //glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, m_geometry.stride(), (char *) m_geometry.vertexData() + offset); offset += a.tupleSize * size_of_type(a.type); } }
/** * Check that the buffer pointed to by \c readback contains the * expected transform feedback output data. */ static bool check_outputs(const void *readback) { const float *readback_f = readback; const int *readback_i = readback; unsigned num_good_varyings = count_strings(test->good_varyings); unsigned i; unsigned output_component = 0; unsigned float_index = 0; unsigned int_index = 0; bool pass = true; for (i = 0; i < num_good_varyings; i++) { const char *varying_name = test->good_varyings[i]; unsigned varying_size = test->expected_sizes[i] * size_of_type(test->expected_types[i]); if (is_floating_type(test->expected_types[i])) { unsigned j; for (j = 0; j < varying_size; j++) { float actual = readback_f[output_component]; float expected = test->expected_floats[float_index]; if (actual != expected) { printf("Output %s element %u: " "expected %f, got %f\n", varying_name, j, expected, actual); pass = false; } output_component++; float_index++; } } else { unsigned j; for (j = 0; j < varying_size; j++) { int actual = readback_i[output_component]; int expected = test->expected_ints[int_index]; if (actual != expected) { printf("Output %s element %u: " "expected %i, got %i\n", varying_name, j, expected, actual); pass = false; } output_component++; int_index++; } } } return pass; }
/** * Compute the expected number of transform feedback outputs for the * current test. This is used to size the transform feedback buffer. */ static unsigned count_outputs() { unsigned num_good_varyings = count_strings(test->good_varyings); unsigned i; unsigned num_outputs = 0; for (i = 0; i < num_good_varyings; i++) { num_outputs += size_of_type(test->expected_types[i]) * test->expected_sizes[i]; } return num_outputs; }
void QSGRenderer::bindGeometry(QSGMaterialShader *material, const QSGGeometry *g) { char const *const *attrNames = material->attributeNames(); int offset = 0; for (int j = 0; attrNames[j]; ++j) { if (!*attrNames[j]) continue; Q_ASSERT_X(j < g->attributeCount(), "QSGRenderer::bindGeometry()", "Geometry lacks attribute required by material"); const QSGGeometry::Attribute &a = g->attributes()[j]; Q_ASSERT_X(j == a.position, "QSGRenderer::bindGeometry()", "Geometry does not have continuous attribute positions"); #if defined(QT_OPENGL_ES_2) GLboolean normalize = a.type != GL_FLOAT; #else GLboolean normalize = a.type != GL_FLOAT && a.type != GL_DOUBLE; #endif glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, g->stride(), (char *) g->vertexData() + offset); offset += a.tupleSize * size_of_type(a.type); } }
void QSGRenderer::draw(const QSGMaterialShader *shader, const QSGGeometry *g) { const void *vertexData; int vertexByteSize = g->vertexCount() * g->sizeOfVertex(); if (g->vertexDataPattern() != QSGGeometry::AlwaysUploadPattern && vertexByteSize > 1024) { // The base pointer for a VBO is 0 vertexData = 0; bool updateData = QSGGeometryData::hasDirtyVertexData(g); QSGRendererVBOGeometryData *gd = QSGRendererVBOGeometryData::get(g); if (!gd->vertexBuffer) { glGenBuffers(1, &gd->vertexBuffer); updateData = true; } glBindBuffer(GL_ARRAY_BUFFER, gd->vertexBuffer); m_vertex_buffer_bound = true; if (updateData) { glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), qt_drawTypeForPattern(g->vertexDataPattern())); QSGGeometryData::clearDirtyVertexData(g); } } else { if (m_vertex_buffer_bound) { glBindBuffer(GL_ARRAY_BUFFER, 0); m_vertex_buffer_bound = false; } vertexData = g->vertexData(); } // Bind the vertices to attributes... char const *const *attrNames = shader->attributeNames(); int offset = 0; for (int j = 0; attrNames[j]; ++j) { if (!*attrNames[j]) continue; Q_ASSERT_X(j < g->attributeCount(), "QSGRenderer::bindGeometry()", "Geometry lacks attribute required by material"); const QSGGeometry::Attribute &a = g->attributes()[j]; Q_ASSERT_X(j == a.position, "QSGRenderer::bindGeometry()", "Geometry does not have continuous attribute positions"); #if defined(QT_OPENGL_ES_2) GLboolean normalize = a.type != GL_FLOAT; #else GLboolean normalize = a.type != GL_FLOAT && a.type != GL_DOUBLE; #endif glVertexAttribPointer(a.position, a.tupleSize, a.type, normalize, g->sizeOfVertex(), (char *) vertexData + offset); offset += a.tupleSize * size_of_type(a.type); } // Set up the indices... const void *indexData; if (g->indexDataPattern() != QSGGeometry::AlwaysUploadPattern && g->indexCount() > 512) { // Base pointer for a VBO is 0 indexData = 0; bool updateData = QSGGeometryData::hasDirtyIndexData(g); QSGRendererVBOGeometryData *gd = QSGRendererVBOGeometryData::get(g); if (!gd->indexBuffer) { glGenBuffers(1, &gd->indexBuffer); updateData = true; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gd->indexBuffer); m_index_buffer_bound = true; if (updateData) { glBufferData(GL_ELEMENT_ARRAY_BUFFER, g->indexCount() * g->sizeOfIndex(), g->indexData(), qt_drawTypeForPattern(g->indexDataPattern())); QSGGeometryData::clearDirtyIndexData(g); } } else { if (m_index_buffer_bound) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); m_index_buffer_bound = false; } indexData = g->indexData(); } // Set the line width if applicable if (g->drawingMode() == GL_LINES || g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP) { glLineWidth(g->lineWidth()); } // draw the stuff... if (g->indexCount()) { glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), indexData); } else { glDrawArrays(g->drawingMode(), 0, g->vertexCount()); } // We leave buffers bound for now... They will be reset by bind on next draw() or // set back to 0 if next draw is not using VBOs }