template <typename R> void call(R *r) { const auto &view = r->getViewMatrix(); const auto &projection = r->getProjectionMatrix(); for (auto &con : r->getScenario().getWorld().cellCellConnections) { auto &cc = *(con.second.get()); if (cc.adhCoef > 0) { shader.bind(); cube.vao.bind(); QColor color = QColor::fromHsvF(cc.adhCoef * 0.45, 0.7, 0.7); shader.setUniformValue(shader.uniformLocation("color"), color); shader.setUniformValue(shader.uniformLocation("projection"), projection); shader.setUniformValue(shader.uniformLocation("view"), view); QMatrix4x4 model; auto ab = toQV3D(cc.cells.second->getPosition() - cc.cells.first->getPosition()); model.translate(toQV3D(cc.cells.second->getPosition()) - ab * 0.5); auto dp = ab.normalized().x(); if (dp != 1 && dp != -1) { model.rotate(acos(dp) * 180.0 / M_PI, QVector3D::crossProduct(QVector3D(1, 0, 0), ab)); model.scale(ab.length() * 0.5, 1.0, 1.0); QMatrix4x4 nmatrix = (model).inverted().transposed(); shader.setUniformValue(shader.uniformLocation("model"), model); shader.setUniformValue(shader.uniformLocation("normalMatrix"), nmatrix); GL->glDrawElements(GL_TRIANGLES, cube.indices.size(), GL_UNSIGNED_INT, 0); } cube.vao.release(); shader.release(); } } }
template <typename R> void call(R *r) { const auto &view = r->getViewMatrix(); const auto &projection = r->getProjectionMatrix(); shader.bind(); sphere.vao.bind(); texture->bind(0); shader.setUniformValue(shader.uniformLocation("projection"), projection); shader.setUniformValue(shader.uniformLocation("view"), view); for (auto &n : r->getScenario().nutrientSources) { QMatrix4x4 model; model.translate(n.pos.x(), n.pos.y(), n.pos.z()); double c = n.content / n.initialcontent; double l = 15.0 + sqrt(n.sqradius * c) * 0.05; model.scale(l, l, l); QMatrix4x4 nmatrix = (model).inverted().transposed(); shader.setUniformValue(shader.uniformLocation("model"), model); shader.setUniformValue(shader.uniformLocation("normalMatrix"), nmatrix); auto hsv = QColor::fromHsvF(c * 0.35, 0.9, 0.9); QVector4D col(hsv.redF(), hsv.greenF(), hsv.blueF(), 0.5); std::cerr << "c = " << c << ", r = " << col.x() << std::endl; shader.setUniformValue(shader.uniformLocation("color"), col); GL->glDrawElements(GL_TRIANGLES, sphere.indices.size(), GL_UNSIGNED_INT, 0); } sphere.vao.release(); shader.release(); }
void Scene_polylines_item::initializeBuffers(CGAL::Three::Viewer_interface *viewer = 0) const { QOpenGLShaderProgram *program; //vao for the lines { program = getShaderProgram(PROGRAM_NO_SELECTION, viewer); program->bind(); vaos[Edges]->bind(); buffers[Edges_Vertices].bind(); buffers[Edges_Vertices].allocate(positions_lines.data(), static_cast<int>(positions_lines.size()*sizeof(float))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_FLOAT,0,4); buffers[Edges_Vertices].release(); vaos[Edges]->release(); program->release(); nb_lines = positions_lines.size(); positions_lines.clear(); positions_lines.swap(positions_lines); } are_buffers_filled = true; }
void Painter::paint_3_2_label( const QMatrix4x4 & viewProjection , float timef) { QOpenGLShaderProgram * program; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); program = m_programs[LabelDistanceMapProgram]; program->bind(); glBindTexture(GL_TEXTURE_2D, m_hpicgsLabelDM); program->setUniformValue("mvp", viewProjection * m_transforms[0]); m_hpicgsLabel->draw(*this); glBindTexture(GL_TEXTURE_2D, m_portccLabelDM); program->setUniformValue("mvp", viewProjection * m_transforms[1]); m_portccLabel->draw(*this); program->release(); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_BLEND); }
void Scene_polylines_item_private::initializeBuffers(CGAL::Three::Viewer_interface *viewer = 0) const { float lineWidth[2]; viewer->glGetFloatv(GL_LINE_WIDTH_RANGE, lineWidth); line_Slider->setMaximum(lineWidth[1]); QOpenGLShaderProgram *program; //vao for the lines { program = item->getShaderProgram(Scene_polylines_item::PROGRAM_NO_SELECTION, viewer); program->bind(); item->vaos[Edges]->bind(); item->buffers[Edges_Vertices].bind(); item->buffers[Edges_Vertices].allocate(positions_lines.data(), static_cast<int>(positions_lines.size()*sizeof(float))); program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_FLOAT,0,4); item->buffers[Edges_Vertices].release(); item->vaos[Edges]->release(); program->release(); nb_lines = positions_lines.size(); positions_lines.clear(); positions_lines.swap(positions_lines); } item->are_buffers_filled = true; }
template <typename R> void call(R *r) { using V = decltype(declval<typename R::Cell>().getPosition()); const auto &view = r->getViewMatrix(); const auto &projection = r->getProjectionMatrix(); shader.bind(); disk.vao.bind(); QVector4D color(0.9f, 0.9f, 0.05f, 1.0f); shader.setUniformValue(shader.uniformLocation("color"), color); shader.setUniformValue(shader.uniformLocation("projection"), projection); shader.setUniformValue(shader.uniformLocation("view"), view); for (auto &con : r->getScenario().getWorld().cellCellConnections) { auto &cc = con.second; QMatrix4x4 model; model.translate( toQV3D(cc.cells.first->getPosition() + cc.normal * cc.midpoint.first)); auto rot = V::getRotation(V(0, 0, 1), cc.normal); model.rotate(rot.teta * 180.0 / M_PI, toQV3D(rot.n)); float rad = static_cast<float>(sqrt(cc.sqradius)); model.scale(rad, rad, rad); QMatrix4x4 nmatrix = (model).inverted().transposed(); shader.setUniformValue(shader.uniformLocation("model"), model); shader.setUniformValue(shader.uniformLocation("normalMatrix"), nmatrix); GL->glDrawElements(GL_TRIANGLES, disk.indices.size(), GL_UNSIGNED_INT, 0); } color = QVector4D(0.1f, 0.7f, 0.f, 1.0f); shader.setUniformValue(shader.uniformLocation("color"), color); for (auto &con : r->getScenario().getWorld().cellCellConnections) { auto &cc = con.second; QMatrix4x4 model; model.translate(toQV3D(cc.cells.first->getPosition() + cc.icb.first.currentBasis.X * cc.midpoint.first)); auto rot = V::getRotation(V(0, 0, 1), cc.icb.first.currentBasis.X); model.rotate(rot.teta * 180.0 / M_PI, toQV3D(rot.n)); float rad = static_cast<float>(sqrt(cc.sqradius)); model.scale(rad, rad, rad); QMatrix4x4 nmatrix = (model).inverted().transposed(); shader.setUniformValue(shader.uniformLocation("model"), model); shader.setUniformValue(shader.uniformLocation("normalMatrix"), nmatrix); GL->glDrawElements(GL_TRIANGLES, disk.indices.size(), GL_UNSIGNED_INT, 0); } color = QVector4D(0.f, 0.1f, 0.7f, 1.0f); shader.setUniformValue(shader.uniformLocation("color"), color); for (auto &con : r->getScenario().getWorld().cellCellConnections) { auto &cc = con.second; QMatrix4x4 model; model.translate(toQV3D(cc.cells.second->getPosition() + cc.icb.second.currentBasis.X * cc.midpoint.second)); auto rot = V::getRotation(V(0, 0, 1), cc.icb.second.currentBasis.X); model.rotate(rot.teta * 180.0 / M_PI, toQV3D(rot.n)); float rad = static_cast<float>(sqrt(cc.sqradius)); model.scale(rad, rad, rad); QMatrix4x4 nmatrix = (model).inverted().transposed(); shader.setUniformValue(shader.uniformLocation("model"), model); shader.setUniformValue(shader.uniformLocation("normalMatrix"), nmatrix); GL->glDrawElements(GL_TRIANGLES, disk.indices.size(), GL_UNSIGNED_INT, 0); } disk.vao.release(); shader.release(); }
/****************************************************************************** * Renders a 2d polyline in the viewport. ******************************************************************************/ void ViewportSceneRenderer::render2DPolyline(const Point2* points, int count, const ColorA& color, bool closed) { OVITO_STATIC_ASSERT(sizeof(points[0]) == 2*sizeof(GLfloat)); // Load OpenGL shader. QOpenGLShaderProgram* shader = loadShaderProgram("line", ":/core/glsl/lines/line.vs", ":/core/glsl/lines/line.fs"); if(!shader->bind()) throw Exception(tr("Failed to bind OpenGL shader.")); bool wasDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST); GLint vc[4]; glGetIntegerv(GL_VIEWPORT, vc); QMatrix4x4 tm; tm.ortho(vc[0], vc[0] + vc[2], vc[1] + vc[3], vc[1], -1, 1); OVITO_CHECK_OPENGL(shader->setUniformValue("modelview_projection_matrix", tm)); QOpenGLBuffer vertexBuffer; if(glformat().majorVersion() >= 3) { if(!vertexBuffer.create()) throw Exception(tr("Failed to create OpenGL vertex buffer.")); if(!vertexBuffer.bind()) throw Exception(tr("Failed to bind OpenGL vertex buffer.")); vertexBuffer.allocate(points, 2 * sizeof(GLfloat) * count); OVITO_CHECK_OPENGL(shader->enableAttributeArray("position")); OVITO_CHECK_OPENGL(shader->setAttributeBuffer("position", GL_FLOAT, 0, 2)); vertexBuffer.release(); } else { OVITO_CHECK_OPENGL(glEnableClientState(GL_VERTEX_ARRAY)); OVITO_CHECK_OPENGL(glVertexPointer(2, GL_FLOAT, 0, points)); } if(glformat().majorVersion() >= 3) { OVITO_CHECK_OPENGL(shader->disableAttributeArray("color")); OVITO_CHECK_OPENGL(shader->setAttributeValue("color", color.r(), color.g(), color.b(), color.a())); } else { OVITO_CHECK_OPENGL(glColor4(color)); } OVITO_CHECK_OPENGL(glDrawArrays(closed ? GL_LINE_LOOP : GL_LINE_STRIP, 0, count)); if(glformat().majorVersion() >= 3) { shader->disableAttributeArray("position"); } else { OVITO_CHECK_OPENGL(glDisableClientState(GL_VERTEX_ARRAY)); } shader->release(); if(wasDepthTestEnabled) glEnable(GL_DEPTH_TEST); }
/****************************************************************************** * Renders the geometry as triangle mesh with normals. ******************************************************************************/ void OpenGLArrowPrimitive::renderWithNormals(ViewportSceneRenderer* renderer) { QOpenGLShaderProgram* shader = renderer->isPicking() ? _pickingShader : _shader; if(!shader->bind()) throw Exception(QStringLiteral("Failed to bind OpenGL shader.")); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); shader->setUniformValue("modelview_projection_matrix", (QMatrix4x4)(renderer->projParams().projectionMatrix * renderer->modelViewTM())); if(!renderer->isPicking()) shader->setUniformValue("normal_matrix", (QMatrix3x3)(renderer->modelViewTM().linear().inverse().transposed())); GLint pickingBaseID; if(renderer->isPicking()) { pickingBaseID = renderer->registerSubObjectIDs(elementCount()); renderer->activateVertexIDs(shader, _chunkSize * _verticesPerElement, true); } for(int chunkIndex = 0; chunkIndex < _verticesWithNormals.size(); chunkIndex++, pickingBaseID += _chunkSize) { int chunkStart = chunkIndex * _chunkSize; int chunkSize = std::min(_elementCount - chunkStart, _chunkSize); if(renderer->isPicking()) shader->setUniformValue("pickingBaseID", pickingBaseID); _verticesWithNormals[chunkIndex].bindPositions(renderer, shader, offsetof(VertexWithNormal, pos)); if(!renderer->isPicking()) { _verticesWithNormals[chunkIndex].bindNormals(renderer, shader, offsetof(VertexWithNormal, normal)); _verticesWithNormals[chunkIndex].bindColors(renderer, shader, 4, offsetof(VertexWithNormal, color)); } int stripPrimitivesPerElement = _stripPrimitiveVertexCounts.size() / _chunkSize; int stripVerticesPerElement = std::accumulate(_stripPrimitiveVertexCounts.begin(), _stripPrimitiveVertexCounts.begin() + stripPrimitivesPerElement, 0); OVITO_CHECK_OPENGL(shader->setUniformValue("verticesPerElement", (GLint)stripVerticesPerElement)); OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_STRIP, _stripPrimitiveVertexStarts.data(), _stripPrimitiveVertexCounts.data(), stripPrimitivesPerElement * chunkSize)); int fanPrimitivesPerElement = _fanPrimitiveVertexCounts.size() / _chunkSize; int fanVerticesPerElement = std::accumulate(_fanPrimitiveVertexCounts.begin(), _fanPrimitiveVertexCounts.begin() + fanPrimitivesPerElement, 0); OVITO_CHECK_OPENGL(shader->setUniformValue("verticesPerElement", (GLint)fanVerticesPerElement)); OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_FAN, _fanPrimitiveVertexStarts.data(), _fanPrimitiveVertexCounts.data(), fanPrimitivesPerElement * chunkSize)); _verticesWithNormals[chunkIndex].detachPositions(renderer, shader); if(!renderer->isPicking()) { _verticesWithNormals[chunkIndex].detachNormals(renderer, shader); _verticesWithNormals[chunkIndex].detachColors(renderer, shader); } } if(renderer->isPicking()) renderer->deactivateVertexIDs(shader, true); shader->release(); }
void useShader(QOpenGLShaderProgram& _s, std::function<void(UniformHandler&)>f) { withCurrentContext([&](QOpenGLFunctions& _gl) { _s.bind(); { UniformHandler _handler(_gl, _s); f(_handler); // Destructor of handler is called here implicitly // by RAII to unbind all textures } _s.release(); }); }
void OpenGLWidgetPrivate::render() { const qreal retinaScale = q->devicePixelRatio(); glViewport(0, 0, width() * retinaScale, height() * retinaScale); glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f); glClear(GL_COLOR_BUFFER_BIT); m_program->bind(); QMatrix4x4 matrix; matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f); matrix.translate(0, 0, -2); const qreal angle = 100.0f * m_frame / 30; matrix.rotate(angle, m_rotAxis); m_program->setUniformValue(m_matrixUniform, matrix); GLfloat vertices[] = { 0.0f, 0.707f, -0.5f, -0.5f, 0.5f, -0.5f }; GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(1); glDisableVertexAttribArray(0); m_program->release(); ++m_frame; if (m_interval <= 0) q->update(); }
void AssimpScene::draw( OpenGLFunctions & gl , QOpenGLShaderProgram & program , const GLenum mode) { if (!m_valid) return; if (!program.isLinked()) return; std::vector<AssimpMesh *>::const_iterator i = m_meshes.begin(); const std::vector<AssimpMesh *>::const_iterator iEnd = m_meshes.end(); program.bind(); program.setUniformValue("model", m_transform * m_normalize); for (; i != iEnd; ++i) { AssimpMesh * mesh(*i); program.setUniformValue("diffuse", mesh->material.diffuse); program.setUniformValue("ambient", mesh->material.ambient); program.setUniformValue("specular", mesh->material.specular); program.setUniformValue("emissive", mesh->material.emissive); program.setUniformValue("shininess", mesh->material.shininess); program.setUniformValue("texCount", mesh->material.texCount); if (mesh->material.texCount > 0) { program.setUniformValue("difftex", 0); gl.glActiveTexture(GL_TEXTURE0); gl.glBindTexture(GL_TEXTURE_2D, mesh->material.texture); } mesh->vao.bind(); gl.glDrawElements(mode, mesh->faces * 3, GL_UNSIGNED_INT, nullptr); mesh->vao.release(); if (mesh->material.texCount > 0) gl.glBindTexture(GL_TEXTURE_2D, 0); } program.release(); }
//! [5] void TriangleWindow::render() { const qreal retinaScale = devicePixelRatio(); glViewport(0, 0, width() * retinaScale, height() * retinaScale); glClear(GL_COLOR_BUFFER_BIT); m_program->bind(); QMatrix4x4 matrix; matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f); matrix.translate(0, 0, -2); matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0); m_program->setUniformValue(m_matrixUniform, matrix); GLfloat vertices[] = { 0.0f, 0.707f, -0.5f, -0.5f, 0.5f, -0.5f }; GLfloat colors[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(1); glDisableVertexAttribArray(0); m_program->release(); ++m_frame; }
void Painter::renderScene(const Camera &camera) { m_envMap->paint(camera); /* Paint gems */ QOpenGLShaderProgram *gemProgram = (*m_shaderPrograms)[ShaderPrograms::GemProgram]; gemProgram->bind(); gemProgram->enableAttributeArray(0); gemProgram->enableAttributeArray(1); gemProgram->setUniformValue("envmap", 0); gemProgram->setUniformValue("gemStructureMap", 1); gemProgram->setUniformValue("rainbowMap", 2); gemProgram->setUniformValue("eye", camera.eye()); gemProgram->setUniformValue("viewProjection", camera.viewProjection()); m_gl->glActiveTexture(GL_TEXTURE0); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, m_envMap->cubeMapTexture()); m_gl->glActiveTexture(GL_TEXTURE1); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, m_gemStructureMap->cubeMapTexture()); m_gl->glActiveTexture(GL_TEXTURE2); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, m_rainbowMap->cubeMapTexture()); QHash<ShaderPrograms, QOpenGLShaderProgram*> shaderPrograms; shaderPrograms.insert(ShaderPrograms::GemProgram, m_shaderPrograms->value(ShaderPrograms::GemProgram)); shaderPrograms.insert(ShaderPrograms::LighRayProgram, m_shaderPrograms->value(ShaderPrograms::LighRayProgram)); m_sceneRenderer->paint(*m_gl, camera.viewProjection(), shaderPrograms); m_gl->glActiveTexture(GL_TEXTURE0); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, 0); m_gl->glActiveTexture(GL_TEXTURE1); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, 0); m_gl->glActiveTexture(GL_TEXTURE2); m_gl->glBindTexture(GL_TEXTURE_CUBE_MAP, 0); m_gl->glBindTexture(GL_TEXTURE_2D, 0); gemProgram->disableAttributeArray(0); gemProgram->disableAttributeArray(1); gemProgram->release(); }
// Wireframe OpenGL drawing void Scene_polylines_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { if(!are_buffers_filled) { computeElements(); initializeBuffers(viewer); } vaos[Edges]->bind(); attribBuffers(viewer, PROGRAM_NO_SELECTION); QOpenGLShaderProgram *program = getShaderProgram(PROGRAM_NO_SELECTION); program->bind(); program->setAttributeValue("colors", this->color()); viewer->glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(nb_lines/4)); program->release(); vaos[Edges]->release(); if(d->draw_extremities) { Scene_group_item::drawEdges(viewer); } }
// Build a passthrough glsl program QOpenGLShaderProgram* GLImageProcessor::buildPassthorughProgram() const { QOpenGLShaderProgram* prog = new QOpenGLShaderProgram(); QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, prog); const char *vsrc = "attribute highp vec4 in_Vertex;\n" "attribute mediump vec4 in_TexCoord;\n" "varying mediump vec4 texCoord;\n" "void main(void)\n" "{\n" " gl_Position = in_Vertex;\n" " texCoord = in_TexCoord;\n" "}\n"; vshader->compileSourceCode(vsrc); QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, prog); const char *fsrc = "uniform sampler2D in_Texture;\n" "varying mediump vec4 texCoord;\n" "void main(void)\n" "{\n" " gl_FragColor = texture2D(in_Texture, texCoord.st);\n" "}\n"; fshader->compileSourceCode(fsrc); prog->addShader(vshader); prog->addShader(fshader); prog->bindAttributeLocation("in_Vertex", 0); prog->bindAttributeLocation("in_TexCoord", 1); prog->link(); prog->bind(); prog->setUniformValue("in_Texture", 0); prog->release(); return prog; }
template <typename R> void call(R *r) { const auto &view = r->getViewMatrix(); const auto &projection = r->getProjectionMatrix(); const float l = 100000.0f; shader.bind(); quad.vao.bind(); texture->bind(0); GL->glActiveTexture(GL_TEXTURE0); GL->glBindTexture(GL_TEXTURE_2D, texture->textureId()); shader.setUniformValue(shader.uniformLocation("tex"), 0); shader.setUniformValue(shader.uniformLocation("projection"), projection); shader.setUniformValue(shader.uniformLocation("view"), view); shader.setUniformValue(shader.uniformLocation("texrepeat"), 300.0f); shader.setUniformValue(shader.uniformLocation("alpha"), 0.8f); QMatrix4x4 model; model.rotate(90.0f, QVector3D(1, 0, 0)); model.translate(QVector3D(0, 0, 0)); model.scale(l, l, l); shader.setUniformValue(shader.uniformLocation("model"), model); GL->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); quad.vao.release(); shader.release(); }
void Viewer::drawVisualHints() { CGAL::QGLViewer::drawVisualHints(); if(d->distance_is_displayed) { glDisable(GL_DEPTH_TEST); QMatrix4x4 mvpMatrix; double mat[16]; camera()->getModelViewProjectionMatrix(mat); for(int i=0; i < 16; i++) { mvpMatrix.data()[i] = (float)mat[i]; } if(!isOpenGL_4_3()) { //draws the distance //nullifies the translation d->rendering_program_dist.bind(); d->rendering_program_dist.setUniformValue("mvp_matrix", mvpMatrix); d->rendering_program_dist.setUniformValue("point_size", GLfloat(6.0f)); d->vao.bind(); glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(2)); glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(2)); d->vao.release(); d->rendering_program_dist.release(); glEnable(GL_DEPTH_TEST); } else { QOpenGLShaderProgram* program = getShaderProgram(PROGRAM_SOLID_WIREFRAME); program->bind(); QVector2D vp(width(), height()); program->setUniformValue("viewport", vp); program->setUniformValue("near",(GLfloat)camera()->zNear()); program->setUniformValue("far",(GLfloat)camera()->zFar()); program->setUniformValue("width", GLfloat(3.0f)); program->setAttributeValue("colors", QColor(Qt::black)); program->setUniformValue("mvp_matrix", mvpMatrix); QMatrix4x4 f_mat; f_mat.setToIdentity(); program->setUniformValue("f_matrix", f_mat); d->vao.bind(); glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(2)); d->vao.release(); program->release(); program = getShaderProgram(PROGRAM_NO_SELECTION); program->bind(); program->setAttributeValue("colors", QColor(Qt::black)); program->setAttributeValue("point_size", 6.0f); program->setUniformValue("mvp_matrix", mvpMatrix); program->setUniformValue("f_matrix", f_mat); d->vao.bind(); glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(2)); d->vao.release(); program->release(); } } if (!d->painter->isActive()) d->painter->begin(this); //So that the text is drawn in front of everything d->painter->beginNativePainting(); glDisable(GL_DEPTH_TEST); d->painter->endNativePainting(); //Prints the displayMessage QFont font = QFont(); QFontMetrics fm(font); TextItem *message_text = new TextItem(float(10 + fm.width(d->message)/2), float(height()-20), 0, d->message, false, QFont(), Qt::gray ); if (d->_displayMessage) { d->textRenderer->addText(message_text); } d->textRenderer->draw(this); if (d->_displayMessage) d->textRenderer->removeText(message_text); }
void Viewer::attribBuffers(int program_name) const { //ModelViewMatrix used for the transformation of the camera. QMatrix4x4 mvp_mat; // ModelView Matrix used for the lighting system QMatrix4x4 mv_mat; // transformation of the manipulated frame QMatrix4x4 f_mat; f_mat.setToIdentity(); //fills the MVP and MV matrices. GLdouble d_mat[16]; this->camera()->getModelViewMatrix(d_mat); for (int i=0; i<16; ++i) mv_mat.data()[i] = GLfloat(d_mat[i]); this->camera()->getModelViewProjectionMatrix(d_mat); for (int i=0; i<16; ++i) mvp_mat.data()[i] = GLfloat(d_mat[i]); QVector4D position(0.0f,0.0f,1.0f, 1.0f ); QVector4D ambient(0.4f, 0.4f, 0.4f, 0.4f); // Diffuse QVector4D diffuse(1.0f, 1.0f, 1.0f, 1.0f); // Specular QVector4D specular(0.0f, 0.0f, 0.0f, 1.0f); QOpenGLShaderProgram* program = getShaderProgram(program_name); program->bind(); program->setUniformValue("point_size", getGlPointSize()); program->setUniformValue("mvp_matrix", mvp_mat); program->setUniformValue("is_clipbox_on", d->clipping); if(d->clipping) { QMatrix4x4 clipbox1; QMatrix4x4 clipbox2; for(int i=0;i<12;++i) { clipbox1.data()[i]=d->clipbox[i/4][i%4]; clipbox2.data()[i]=d->clipbox[(i+12)/4][(i+12)%4]; } program->setUniformValue("clipbox1", clipbox1); program->setUniformValue("clipbox2", clipbox2); } switch(program_name) { case PROGRAM_WITH_LIGHT: case PROGRAM_SPHERES: case PROGRAM_CUTPLANE_SPHERES: program->setUniformValue("alpha", 1.0f); //overriden in item draw() if necessary } switch(program_name) { case PROGRAM_WITH_LIGHT: case PROGRAM_C3T3: case PROGRAM_PLANE_TWO_FACES: case PROGRAM_INSTANCED: case PROGRAM_WITH_TEXTURE: case PROGRAM_CUTPLANE_SPHERES: case PROGRAM_SPHERES: case PROGRAM_OLD_FLAT: case PROGRAM_FLAT: program->setUniformValue("light_pos", position); program->setUniformValue("light_diff",diffuse); program->setUniformValue("light_spec", specular); program->setUniformValue("light_amb", ambient); program->setUniformValue("spec_power", 51.8f); program->setUniformValue("is_two_side", d->twosides); break; } switch(program_name) { case PROGRAM_WITH_LIGHT: case PROGRAM_C3T3: case PROGRAM_PLANE_TWO_FACES: case PROGRAM_INSTANCED: case PROGRAM_CUTPLANE_SPHERES: case PROGRAM_SPHERES: case PROGRAM_OLD_FLAT: case PROGRAM_FLAT: program->setUniformValue("mv_matrix", mv_mat); break; case PROGRAM_WITHOUT_LIGHT: case PROGRAM_SOLID_WIREFRAME: program->setUniformValue("f_matrix",f_mat); break; case PROGRAM_WITH_TEXTURE: program->setUniformValue("mv_matrix", mv_mat); program->setUniformValue("s_texture",0); program->setUniformValue("f_matrix",f_mat); break; case PROGRAM_WITH_TEXTURED_EDGES: program->setUniformValue("s_texture",0); break; case PROGRAM_NO_SELECTION: program->setUniformValue("f_matrix",f_mat); break; } program->release(); }
/****************************************************************************** * Renders the geometry as with extra information passed to the vertex shader. ******************************************************************************/ void OpenGLArrowPrimitive::renderWithElementInfo(ViewportSceneRenderer* renderer) { QOpenGLShaderProgram* shader = renderer->isPicking() ? _pickingShader : _shader; if(!shader) return; if(!shader->bind()) throw Exception(QStringLiteral("Failed to bind OpenGL shader.")); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); shader->setUniformValue("modelview_matrix", (QMatrix4x4)renderer->modelViewTM()); shader->setUniformValue("modelview_uniform_scale", (float)pow(std::abs(renderer->modelViewTM().determinant()), (FloatType(1.0/3.0)))); shader->setUniformValue("modelview_projection_matrix", (QMatrix4x4)(renderer->projParams().projectionMatrix * renderer->modelViewTM())); shader->setUniformValue("projection_matrix", (QMatrix4x4)renderer->projParams().projectionMatrix); shader->setUniformValue("inverse_projection_matrix", (QMatrix4x4)renderer->projParams().inverseProjectionMatrix); shader->setUniformValue("is_perspective", renderer->projParams().isPerspective); AffineTransformation viewModelTM = renderer->modelViewTM().inverse(); Vector3 eye_pos = viewModelTM.translation(); shader->setUniformValue("eye_pos", eye_pos.x(), eye_pos.y(), eye_pos.z()); Vector3 viewDir = viewModelTM * Vector3(0,0,1); shader->setUniformValue("parallel_view_dir", viewDir.x(), viewDir.y(), viewDir.z()); GLint viewportCoords[4]; glGetIntegerv(GL_VIEWPORT, viewportCoords); shader->setUniformValue("viewport_origin", (float)viewportCoords[0], (float)viewportCoords[1]); shader->setUniformValue("inverse_viewport_size", 2.0f / (float)viewportCoords[2], 2.0f / (float)viewportCoords[3]); GLint pickingBaseID; if(renderer->isPicking()) { pickingBaseID = renderer->registerSubObjectIDs(elementCount()); renderer->activateVertexIDs(shader, _chunkSize * _verticesPerElement, true); OVITO_CHECK_OPENGL(shader->setUniformValue("verticesPerElement", (GLint)_verticesPerElement)); } for(int chunkIndex = 0; chunkIndex < _verticesWithElementInfo.size(); chunkIndex++, pickingBaseID += _chunkSize) { int chunkStart = chunkIndex * _chunkSize; int chunkSize = std::min(_elementCount - chunkStart, _chunkSize); if(renderer->isPicking()) shader->setUniformValue("pickingBaseID", pickingBaseID); _verticesWithElementInfo[chunkIndex].bindPositions(renderer, shader, offsetof(VertexWithElementInfo, pos)); _verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_base", GL_FLOAT, offsetof(VertexWithElementInfo, base), 3, sizeof(VertexWithElementInfo)); _verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_axis", GL_FLOAT, offsetof(VertexWithElementInfo, dir), 3, sizeof(VertexWithElementInfo)); _verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_radius", GL_FLOAT, offsetof(VertexWithElementInfo, radius), 1, sizeof(VertexWithElementInfo)); if(!renderer->isPicking()) _verticesWithElementInfo[chunkIndex].bindColors(renderer, shader, 4, offsetof(VertexWithElementInfo, color)); if(_usingGeometryShader && (shadingMode() == FlatShading || renderingQuality() == HighQuality)) { OVITO_CHECK_OPENGL(glDrawArrays(GL_POINTS, 0, chunkSize)); } else { int stripPrimitivesPerElement = _stripPrimitiveVertexCounts.size() / _chunkSize; OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_STRIP, _stripPrimitiveVertexStarts.data(), _stripPrimitiveVertexCounts.data(), stripPrimitivesPerElement * chunkSize)); int fanPrimitivesPerElement = _fanPrimitiveVertexCounts.size() / _chunkSize; OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_FAN, _fanPrimitiveVertexStarts.data(), _fanPrimitiveVertexCounts.data(), fanPrimitivesPerElement * chunkSize)); } _verticesWithElementInfo[chunkIndex].detachPositions(renderer, shader); _verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_base"); _verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_axis"); _verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_radius"); if(!renderer->isPicking()) _verticesWithElementInfo[chunkIndex].detachColors(renderer, shader); } shader->enableAttributeArray("cylinder_base"); shader->enableAttributeArray("cylinder_axis"); shader->enableAttributeArray("cylinder_radius"); if(renderer->isPicking()) renderer->deactivateVertexIDs(shader, true); shader->release(); }
bool Painter::initialize() { initializeOpenGLFunctions(); // Note: As always, feel free to change/modify parameters .. as long as its possible to // see the terrain and navigation basically works, everything is ok. glClearColor(1.f, 1.f, 1.f, 0.f); m_quad = new ScreenAlignedQuad(*this); m_light = QVector3D(2.f, 3.f, 2.f); QOpenGLShaderProgram * program; // setup default assimp scene shader (rendering the meshes...) // ToDo: If you render your own scene (e.g., a terrain, keep in mind // to extend your shaders for supporting shadowmaps as well as in assimp shaders... program = createBasicShaderProgram("data/assimp.vert", "data/assimp.frag"); m_programs[PaintMode1] = program; program->bindAttributeLocation("a_vertex", 0); program->bindAttributeLocation("a_normal", 1); program->bindAttributeLocation("a_texc", 2); program->link(); // load labeling shaders and resources m_programs[LabelAlphaMappingProgram] = createBasicShaderProgram("data/label.vert", "data/labelAM.frag"); m_programs[LabelDistanceMapProgram] = createBasicShaderProgram("data/label.vert", "data/labelDM.frag"); m_hpicgsLabelAM = FileAssociatedTexture::getOrCreate2D("data/hpicgs_label.png", *this); m_portccLabelAM = FileAssociatedTexture::getOrCreate2D("data/companion_cube_label.png", *this); // load and position 3d models in the scene // Note: feel free to modify / add / remove here... there should be at least // a few scene objects visible ;) m_hpicgs = new AssimpScene(*this, "data/hpicgs.obj", true); m_hpicgs->transform().scale(0.7f, 0.7f, 0.7f); m_hpicgs->transform().translate(-0.9f, 0.8f, -0.3f); m_hpicgs->transform().rotate( 56.0f, 0.f, 1.0f, 0.f); m_hpicgs->transform().rotate(0.0f, 1.f, 0.0f, 0.f); m_plane = new AssimpScene(*this, "data/plane.obj", false); m_plane->transform().translate(0.f, -0.1f, 0.f); m_portcc = new AssimpScene(*this, "data/companion_cube.obj", true); m_portcc->transform().scale(0.5f, 0.5f, 0.5f); m_portcc->transform().translate(1.1f, 0.73f, 1.2f); m_portcc->transform().rotate(8.0f, 0.f, 1.0f, 0.f); // initialize label positions // Task_3_1 - ToDo Begin // Modify the transformation matrix T to position, scale, and orient // the labels to appropriate places, based on the initial view! No // interaction should be required to be able to see both labels. m_hpicgsLabel = new ScreenAlignedQuad(*this, 0); QMatrix4x4 T; T.translate(0.5, 0.5, -1.0); T.scale(1.0, 0.3); // ToDo: use T.translate/scale/rotate ... m_transforms << T; m_portccLabel = new ScreenAlignedQuad(*this, 0); T.translate(-1.5, 0.0, 2.0); // ToDo: use T.translate/scale/rotate ... m_transforms << T; // Task_3_1 - ToDo End // initialize shader program attribute input program = m_programs[LabelAlphaMappingProgram]; program->bind(); program->bindAttributeLocation("a_vertex", 0); program->release(); program = m_programs[LabelDistanceMapProgram]; program->bind(); program->bindAttributeLocation("a_vertex", 0); program->release(); // create distance transforms of label images glGenTextures(1, &m_hpicgsLabelDM); glBindTexture(GL_TEXTURE_2D, m_hpicgsLabelDM); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); { QImage image("data/hpicgs_label_bitmask.png"); // ToDo: pre resize? DistanceTransform DT(image, 512, 128, 0.0625f); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 128, 0, GL_RED, GL_FLOAT, DT.data()); } glGenerateMipmap(GL_TEXTURE_2D); glGenTextures(1, &m_portccLabelDM); glBindTexture(GL_TEXTURE_2D, m_portccLabelDM); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); { QImage image("data/companion_cube_label_bitmask.png"); // ToDo: pre resize? // image = image.scaled(? , ? , Qt::FastTransformation); DistanceTransform DT(image, 512, 128, 0.125f); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 128, 0, GL_RED, GL_FLOAT, DT.data()); } glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // create fbo m_programs[ShadowMapProgram] = createBasicShaderProgram("data/shadowmap.vert", "data/shadowmap.frag"); m_programs[ShadowMapDumpProgram] = createBasicShaderProgram("data/dump.vert", "data/dump.frag"); glGenTextures(1, &m_depthTex); glBindTexture(GL_TEXTURE_2D, m_depthTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, ShadowMapSize, ShadowMapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color); glBindTexture(GL_TEXTURE_2D, 0); glGenFramebuffers(1, &m_depthFbo); glBindFramebuffer(GL_FRAMEBUFFER, m_depthFbo); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_depthTex, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) qDebug() << "depth fbo invalid"; glBindFramebuffer(GL_FRAMEBUFFER, 0); return true; }
void Painter::paint() { if (m_active && m_sceneRenderer) { if (!m_initialized) { initialize(); m_time->start(); } m_counter++; if (m_counter % 60 == 0) { auto timeForPaint = (m_time->elapsed() - m_oldElapsed) / 1000; qDebug() << "time for 60 frames " << QString::number(timeForPaint); m_oldElapsed = m_time->elapsed(); } float clearColor[4] = {0.9f, 1.f, 1.f, 1.f}; m_gl->glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_gl->glEnable(GL_CULL_FACE); m_gl->glEnable(GL_DEPTH_TEST); m_gl->glDepthFunc(GL_LEQUAL); m_gl->glDepthMask(GL_TRUE); // Render to texture int viewportHeight = m_camera->viewport().height(); int viewportWidth = m_camera->viewport().width(); int previewViewportHeight = m_previewCamera->viewport().height(); int previewViewportWidth = m_previewCamera->viewport().width(); float previewSize = 1.f / (static_cast<float>(viewportWidth) / previewViewportWidth); int glowSceneViewportHeight = viewportHeight / m_blurViewportRatioScene; int glowSceneViewportWidth = viewportWidth / m_blurViewportRatioScene; bool viewportChanged = false; if (m_usedViewport->height() != viewportHeight || m_usedViewport->width() != viewportWidth) { *m_usedViewport = m_camera->viewport(); viewportChanged = true; } // Render lightrays to glowSceneTexture for glow m_gl->glBindFramebuffer(GL_FRAMEBUFFER, m_glowSceneFBO); m_gl->glBindTexture(GL_TEXTURE_2D, m_glowSceneTexture); if (viewportChanged) { m_gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glowSceneViewportWidth, glowSceneViewportHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } m_gl->glBindRenderbuffer(GL_RENDERBUFFER, m_glowSceneDepthRB); if (viewportChanged) { m_gl->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, glowSceneViewportWidth, glowSceneViewportHeight); } m_gl->glViewport(0, 0, glowSceneViewportWidth, glowSceneViewportHeight); m_gl->glClearColor(1.0, 0.0, 0.0, 0.0); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderLightRays(*m_camera); if (m_blurEffectScene) { m_blurEffectScene->blur(QSize(glowSceneViewportWidth, glowSceneViewportHeight)); } // Render preview lightrays to glowPreviewSceneTexture for glow m_gl->glBindFramebuffer(GL_FRAMEBUFFER, m_glowPreviewSceneFBO); m_gl->glBindTexture(GL_TEXTURE_2D, m_glowPreviewSceneTexture); if (viewportChanged) { m_gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, previewViewportWidth, previewViewportHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } m_gl->glBindRenderbuffer(GL_RENDERBUFFER, m_glowPreviewSceneDepthRB); if (viewportChanged) { m_gl->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, previewViewportWidth, previewViewportHeight); } m_gl->glViewport(0, 0, previewViewportWidth, previewViewportHeight); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderLightRays(*m_previewCamera); if (m_blurEffectPreviewScene) { m_blurEffectPreviewScene->blur(m_previewCamera->viewport()); } // scene m_gl->glBindFramebuffer(GL_FRAMEBUFFER, m_sceneFBO); m_gl->glBindTexture(GL_TEXTURE_2D, m_sceneTexture); if (viewportChanged) { m_gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewportWidth, viewportHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } m_gl->glBindRenderbuffer(GL_RENDERBUFFER, m_sceneDepthRB); if (viewportChanged) { m_gl->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, viewportWidth, viewportHeight); } m_gl->glViewport(0, 0, viewportWidth, viewportHeight); m_gl->glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderScene(*m_camera); // preview scene m_gl->glBindFramebuffer(GL_FRAMEBUFFER, m_previewSceneFBO); m_gl->glBindTexture(GL_TEXTURE_2D, m_previewSceneTexture); if (viewportChanged) { m_gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, previewViewportWidth, previewViewportHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } m_gl->glBindRenderbuffer(GL_RENDERBUFFER, m_previewSceneDepthRB); if (viewportChanged) { m_gl->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, previewViewportWidth, previewViewportHeight); } m_gl->glViewport(0, 0, previewViewportWidth, previewViewportHeight); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderScene(*m_previewCamera); // Render to the screen m_gl->glBindFramebuffer(GL_FRAMEBUFFER, 0); m_gl->glViewport(0, 0, viewportWidth, viewportHeight); m_gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_gl->glActiveTexture(GL_TEXTURE0); m_gl->glBindTexture(GL_TEXTURE_2D, m_sceneTexture); m_gl->glActiveTexture(GL_TEXTURE1); m_gl->glBindTexture(GL_TEXTURE_2D, m_previewSceneTexture); m_gl->glActiveTexture(GL_TEXTURE2); m_gl->glBindTexture(GL_TEXTURE_2D, m_glowSceneTexture); m_gl->glActiveTexture(GL_TEXTURE3); m_gl->glBindTexture(GL_TEXTURE_2D, m_glowPreviewSceneTexture); QOpenGLShaderProgram *sceneProgram = (*m_shaderPrograms)[ShaderPrograms::SceneProgram]; sceneProgram->bind(); sceneProgram->setUniformValue("u_sceneTexture", 0); sceneProgram->setUniformValue("u_previewSceneTexture", 1); sceneProgram->setUniformValue("u_glowSceneTexture", 2); sceneProgram->setUniformValue("u_glowPreviewSceneTexture", 3); sceneProgram->setUniformValue("u_previewSize", previewSize); m_quad->draw(*m_gl); sceneProgram->release(); // Reset OpenGL state for qml // According to https://qt.gitorious.org/qt/qtdeclarative/source/fa0eea53f73c9b03b259f075e4cd5b83bfefccd3:src/quick/items/qquickwindow.cpp m_gl->glEnable(GL_TEXTURE_2D); m_gl->glActiveTexture(GL_TEXTURE3); m_gl->glBindTexture(GL_TEXTURE_2D, 0); m_gl->glActiveTexture(GL_TEXTURE2); m_gl->glBindTexture(GL_TEXTURE_2D, 0); m_gl->glActiveTexture(GL_TEXTURE1); m_gl->glBindTexture(GL_TEXTURE_2D, 0); m_gl->glActiveTexture(GL_TEXTURE0); m_gl->glBindTexture(GL_TEXTURE_2D, 0); m_gl->glDisable(GL_TEXTURE_2D); m_gl->glDisable(GL_DEPTH_TEST); m_gl->glClearColor(0, 0, 0, 0); m_gl->glDepthMask(GL_TRUE); m_gl->glDepthFunc(GL_LESS); QCoreApplication::postEvent(m_painterQML, new QEvent(m_painterQML->paintingDoneEventType()), Qt::HighEventPriority); } }
void VideoSurface::paintGL() { mutex.lock(); VideoFrame currFrame = frame; frame.invalidate(); mutex.unlock(); if (currFrame.isValid() && res != currFrame.resolution) { res = currFrame.resolution; // delete old texture if (textureId != 0) glDeleteTextures(1, &textureId); // a texture used to render the pbo (has the match the pixelformat of the source) glGenTextures(1,&textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, res.width(), res.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } if (currFrame.isValid()) { pboIndex = (pboIndex + 1) % 2; int nextPboIndex = (pboIndex + 1) % 2; if (pboAllocSize != currFrame.frameData.size()) { qDebug() << "VideoSurface: Resize pbo " << currFrame.frameData.size() << "(" << currFrame.resolution << ")" << "bytes (before" << pboAllocSize << ")"; pbo[0]->bind(); pbo[0]->allocate(currFrame.frameData.size()); pbo[0]->release(); pbo[1]->bind(); pbo[1]->allocate(currFrame.frameData.size()); pbo[1]->release(); pboAllocSize = currFrame.frameData.size(); } pbo[pboIndex]->bind(); glBindTexture(GL_TEXTURE_2D, textureId); glTexSubImage2D(GL_TEXTURE_2D,0,0,0, res.width(), res.height(), GL_RGB, GL_UNSIGNED_BYTE, 0); pbo[pboIndex]->unmap(); pbo[pboIndex]->release(); // transfer data pbo[nextPboIndex]->bind(); void* ptr = pbo[nextPboIndex]->map(QOpenGLBuffer::WriteOnly); if (ptr) memcpy(ptr, currFrame.frameData.data(), currFrame.frameData.size()); pbo[nextPboIndex]->unmap(); pbo[nextPboIndex]->release(); } // background glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); // keep aspect ratio float aspectRatio = float(res.width()) / float(res.height()); if (width() < float(height()) * aspectRatio) { float h = float(width()) / aspectRatio; glViewport(0, (height() - h)*0.5f, width(), h); } else { float w = float(height()) * float(aspectRatio); glViewport((width() - w)*0.5f, 0, w, height()); } QOpenGLShaderProgram* programm = nullptr; switch (frame.format) { case VideoFrame::YUV: programm = yuvProgramm; break; case VideoFrame::BGR: programm = bgrProgramm; break; default: break; } if (programm) { // render pbo static float values[] = { -1, -1, 1, -1, -1, 1, 1, 1 }; programm->bind(); programm->setAttributeArray(0, GL_FLOAT, values, 2); programm->enableAttributeArray(0); } glBindTexture(GL_TEXTURE_2D, textureId); //draw fullscreen quad glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindTexture(GL_TEXTURE_2D, 0); if (programm) { programm->disableAttributeArray(0); programm->release(); } }