void DVWindow::loadShader(QOpenGLShaderProgram& shader, const char* vshader, const char* fshader) { /* Load the shaders from the qrc. */ shader.addShaderFromSourceFile(QOpenGLShader::Vertex, vshader); QFile res(fshader); res.open(QIODevice::ReadOnly | QIODevice::Text); QString fshaderSrc = res.readAll(); if (!context()->isOpenGLES()) fshaderSrc.prepend("#version 130\n"); shader.addShaderFromSourceCode(QOpenGLShader::Fragment, fshaderSrc); /* Bind the attribute handles. */ shader.bindAttributeLocation("vertex", vertex); shader.bindAttributeLocation("uv", uv); shader.link(); /* Bind so we set the texture sampler uniform values. */ shader.bind(); /* Left image is TEXTURE0. */ shader.setUniformValue("textureL", 0); /* Right image is TEXTURE1. */ shader.setUniformValue("textureR", 1); }
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 Refraction::draw() { _arrayBuf.bind(); QOpenGLShaderProgram *program = GL::refraction(); program->bind(); int vertexLocation = program->attributeLocation("a_position"); program->enableAttributeArray(vertexLocation); program->setAttributeBuffer(vertexLocation, GL_FLOAT, 0, 3, sizeof(VertexData)); int fragmentLocation = program->attributeLocation("a_texcoord"); program->enableAttributeArray(fragmentLocation); program->setAttributeBuffer(fragmentLocation, GL_FLOAT, sizeof(QVector3D), 2, sizeof(VertexData)); prepareMatrix(); program->setUniformValue("mvp_matrix", GL::projection() * model); program->setUniformValue("refraction", 0); _texture->bind(0); program->setUniformValue("background", 1); GameObjects::background()->bind(1); program->setUniformValue("position", _position); program->setUniformValue("radius", _radius); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, 0); }
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 AbstractKernel::setUniforms(QOpenGLShaderProgram& program, unsigned int pass) { program.setUniformValue("size", m_size); if(pass == Pass::Second) { program.setUniformValue("factor", m_factor); } }
/****************************************************************************** * 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(); }
GraphicsLayer21::GraphicsLayer21(QOpenGLVertexArrayObject* vertex_array) : m_program(nullptr), m_vertex_array(vertex_array) { initializeOpenGLFunctions(); AppearanceDialog::setBevelsEnabled(true); glDisable(GL_BLEND); // Enable OpenGL features glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // Set OpenGL parameters glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LEQUAL); glFrontFace(GL_CCW); // Create vertex buffer object m_vertex_buffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); m_vertex_buffer->setUsagePattern(QOpenGLBuffer::DynamicDraw); m_vertex_buffer->create(); m_vertex_buffer->bind(); // Load shaders QOpenGLShaderProgram* program = loadProgram(0); program->setAttributeBuffer(Position, GL_FLOAT, offsetof(Vertex, x), 3, sizeof(Vertex)); program->enableAttributeArray(Position); program = loadProgram(1); program->setAttributeBuffer(TexCoord0, GL_FLOAT, offsetof(Vertex, s), 2, sizeof(Vertex)); program->setAttributeBuffer(Position, GL_FLOAT, offsetof(Vertex, x), 3, sizeof(Vertex)); program->enableAttributeArray(Position); program->setUniformValue("texture0", GLuint(0)); program = loadProgram(2); program->setAttributeBuffer(TexCoord1, GL_FLOAT, offsetof(Vertex, s2), 2, sizeof(Vertex)); program->setAttributeBuffer(TexCoord0, GL_FLOAT, offsetof(Vertex, s), 2, sizeof(Vertex)); program->setAttributeBuffer(Position, GL_FLOAT, offsetof(Vertex, x), 3, sizeof(Vertex)); program->enableAttributeArray(Position); program->setUniformValue("texture0", GLuint(0)); program->setUniformValue("texture1", GLuint(1)); }
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(); }
/****************************************************************************** * 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); }
void csSurface::draw(QOpenGLShaderProgram& program) { if( _initRequired ) { initialize(); } if( _meshInfo.isEmpty() ) { return; } glDisable(GL_CULL_FACE); program.setUniformValue("cs_Model", _model); program.setUniformValue("cs_zMin", _meshInfo.zMin()); program.setUniformValue("cs_zInterval", _meshInfo.zInterval()); program.setUniformValue("cs_ColorMap", TMU_COLORMAP); _surface->bind(); const int vertexLoc = program.attributeLocation("cs_Vertex"); program.enableAttributeArray(vertexLoc); program.setAttributeBuffer(vertexLoc, GL_FLOAT, 0, 3); _colorTexture->bind(TMU_COLORMAP, QOpenGLTexture::ResetTextureUnit); _strip->bind(); const int numStrips = _meshInfo.rowCount() -1; const int numVertPerStrip = 2*_meshInfo.columnCount(); for(int y = 0; y < numStrips; y++) { const GLuint offset = sizeof(GLuint)*y*numVertPerStrip; const GLvoid *indices = (GLvoid*)offset; glDrawElements(GL_TRIANGLE_STRIP, numVertPerStrip, GL_UNSIGNED_INT, indices); } _strip->release(); _colorTexture->release(); program.disableAttributeArray(vertexLoc); _surface->release(); }
void csSurface::drawMesh(QOpenGLShaderProgram& program) { if( _initRequired ) { initialize(); } if( _meshInfo.isEmpty() ) { return; } program.setUniformValue("cs_DepthOffset", csCoordinateBox::DepthOffset); program.setUniformValue("cs_Model", _model); _surface->bind(); const int vertexLoc = program.attributeLocation("cs_Vertex"); program.enableAttributeArray(vertexLoc); program.setAttributeBuffer(vertexLoc, GL_FLOAT, 0, 3); const int colorLoc = program.attributeLocation("cs_Color"); program.setAttributeValue(colorLoc, QColor(Qt::black)); // Along x-Axis for(int y = 0; y < _meshInfo.rowCount(); y++) { glDrawArrays(GL_LINE_STRIP, y*_meshInfo.columnCount(), _meshInfo.columnCount()); } // Along y-Axis _meshY->bind(); for(int x = 0; x < _meshInfo.columnCount(); x++) { const GLuint offset = sizeof(GLuint)*x*_meshInfo.rowCount(); const GLvoid *indices = (GLvoid*)offset; glDrawElements(GL_LINE_STRIP, _meshInfo.rowCount(), GL_UNSIGNED_INT, indices); } _meshY->release(); program.disableAttributeArray(vertexLoc); _surface->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(); }
//! [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; }
// 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; }
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(); }
void Material::SendUniformsToShader(QOpenGLShaderProgram &shader) { /** *Diffuse component */ shader.setUniformValue("diffuse_color", m_diffuse_color); shader.setUniformValue("diffuse_intensity", m_diffuse_intensity); shader.setUniformValue("use_diffuse_texture", m_textures.contains(diffuse)); /** *Specular component */ shader.setUniformValue("specular_color", m_specular_color); shader.setUniformValue("specular_intensity", m_specular_intensity); shader.setUniformValue("specular_hardness", m_specular_hardness); }
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(); }
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); } }
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 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(); }
void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (ctx == 0) { qWarning("QOpenGLTextureGlyphCache::resizeTextureData: Called with no context"); return; } int oldWidth = m_textureResource->m_width; int oldHeight = m_textureResource->m_height; // Make the lower glyph texture size 16 x 16. if (width < 16) width = 16; if (height < 16) height = 16; GLuint oldTexture = m_textureResource->m_texture; createTextureData(width, height); if (ctx->d_func()->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::resizeTextureData(width, height); Q_ASSERT(image().depth() == 8); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); glDeleteTextures(1, &oldTexture); return; } // ### the QTextureGlyphCache API needs to be reworked to allow // ### resizeTextureData to fail QOpenGLFunctions funcs(ctx); funcs.glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo); GLuint tmp_texture; glGenTextures(1, &tmp_texture); glBindTexture(GL_TEXTURE_2D, tmp_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_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); m_filterMode = Nearest; glBindTexture(GL_TEXTURE_2D, 0); funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_texture, 0); funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); glBindTexture(GL_TEXTURE_2D, oldTexture); if (pex != 0) pex->transferMode(BrushDrawingMode); glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glViewport(0, 0, oldWidth, oldHeight); QOpenGLShaderProgram *blitProgram = 0; if (pex == 0) { if (m_blitProgram == 0) { m_blitProgram = new QOpenGLShaderProgram(ctx); { QString source; source.append(QLatin1String(qopenglslMainWithTexCoordsVertexShader)); source.append(QLatin1String(qopenglslUntransformedPositionVertexShader)); QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_blitProgram); vertexShader->compileSourceCode(source); m_blitProgram->addShader(vertexShader); } { QString source; source.append(QLatin1String(qopenglslMainFragmentShader)); source.append(QLatin1String(qopenglslImageSrcFragmentShader)); QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_blitProgram); fragmentShader->compileSourceCode(source); m_blitProgram->addShader(fragmentShader); } m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); m_blitProgram->link(); } funcs.glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray); funcs.glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray); m_blitProgram->bind(); m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); m_blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); m_blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR)); blitProgram = m_blitProgram; } else { pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, m_vertexCoordinateArray); pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, m_textureCoordinateArray); pex->shaderManager->useBlitProgram(); blitProgram = pex->shaderManager->blitProgram(); } blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); glDeleteTextures(1, &tmp_texture); glDeleteTextures(1, &oldTexture); funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo); if (pex != 0) { glViewport(0, 0, pex->width, pex->height); pex->updateClipScissorTest(); } else { m_blitProgram->disableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); m_blitProgram->disableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); } }