void QWaylandBufferMaterial::bind() { QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); const GLenum target = bufferTypes[m_format].textureTarget; ensureTextures(bufferTypes[m_format].planeCount); switch (m_textures.size()) { case 3: gl->glActiveTexture(GL_TEXTURE2); gl->glBindTexture(target, m_textures[2]); case 2: gl->glActiveTexture(GL_TEXTURE1); gl->glBindTexture(target, m_textures[1]); case 1: gl->glActiveTexture(GL_TEXTURE0); gl->glBindTexture(target, m_textures[0]); } }
void GLImageProcessor::plot(int w, int h) { vao.bind(); plotProgram->bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glActiveTexture(GL_TEXTURE0); f->glBindTexture(GL_TEXTURE_2D, renderFbo->texture()); f->glViewport(0, 0, w, h); f->glDrawArrays(GL_QUADS, 0, 4); plotProgram->release(); vao.release(); }
void VideoMaterial::bind() { QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); GstBuffer *frame = NULL; m_frameMutex.lock(); if (m_frame) frame = gst_buffer_ref(m_frame); m_frameMutex.unlock(); if (frame) { GstMapInfo info; gst_buffer_map(frame, &info, GST_MAP_READ); functions->glActiveTexture(GL_TEXTURE1); bindTexture(1, info.data); functions->glActiveTexture(GL_TEXTURE2); bindTexture(2, info.data); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(0, info.data); gst_buffer_unmap(frame, &info); gst_buffer_unref(frame); } else { functions->glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); functions->glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); } }
void TFInteg2DGL::integrate(const float *colormap, int resolution, float basesize, float stepsize) { if (!texFull || resolution != texFull->width()) newResources(resolution); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); tex1d->setData(QOpenGLTexture::RGBA, QOpenGLTexture::Float32, colormap); // framebuffer object GLint oFbo, viewport[4], activeTex, oTex; newFbo(); f->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oFbo); f->glBindFramebuffer(GL_FRAMEBUFFER, *fbo); f->glClear(GL_COLOR_BUFFER_BIT); // viewport f->glGetIntegerv(GL_VIEWPORT, viewport); f->glViewport(0, 0, resolution, resolution); // 1d texture f->glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); f->glActiveTexture(GL_TEXTURE0); f->glGetIntegerv(GL_TEXTURE_1D, &oTex); f->glBindTexture(GL_TEXTURE_1D, tex1d->textureId()); // paint painter.recreateVAO(); painter.paint("tf1d", 0, "resolution", resolution, "basesize", basesize, "segLen", stepsize); // clean f->glActiveTexture(GL_TEXTURE0); f->glBindTexture(GL_TEXTURE_1D, oTex); f->glActiveTexture(activeTex); // std::unique_ptr<GLubyte[]> pixels(new GLubyte [resolution * resolution * 4]); // f->glReadPixels(0, 0, resolution, resolution, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); // QImage image(pixels.get(), resolution, resolution, QImage::Format_RGBA8888); // static QLabel label; // label.resize(resolution, resolution); // label.setPixmap(QPixmap::fromImage(image.mirrored())); // label.show(); f->glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); f->glBindFramebuffer(GL_FRAMEBUFFER, oFbo); }
void QSGVlcVideoFrameMaterial::bindPlane( GLenum texUnit, GLuint texId, const void* plane, quint16 width, quint16 height ) { QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glActiveTexture( texUnit ); glBindTexture( GL_TEXTURE_2D, texId ); if( plane ) { glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, plane ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); } }
void bind() { QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); QMutexLocker lock(&m_frameMutex); if (m_frame.isValid()) { if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { QSize textureSize = m_frame.size(); int stride = m_frame.bytesPerLine(); switch (m_frame.pixelFormat()) { case QVideoFrame::Format_RGB565: stride /= 2; break; default: stride /= 4; } m_width = qreal(m_frame.width()) / stride; textureSize.setWidth(stride); if (m_textureSize != textureSize) { if (!m_textureSize.isEmpty()) functions->glDeleteTextures(1, &m_textureId); functions->glGenTextures(1, &m_textureId); m_textureSize = textureSize; } GLint dataType = GL_UNSIGNED_BYTE; GLint dataFormat = GL_RGBA; if (m_frame.pixelFormat() == QVideoFrame::Format_RGB565) { dataType = GL_UNSIGNED_SHORT_5_6_5; dataFormat = GL_RGB; } GLint previousAlignment; functions->glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment); functions->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); functions->glActiveTexture(GL_TEXTURE0); functions->glBindTexture(GL_TEXTURE_2D, m_textureId); functions->glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, m_textureSize.width(), m_textureSize.height(), 0, dataFormat, dataType, m_frame.bits()); functions->glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment); functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); m_frame.unmap(); } m_frame = QVideoFrame(); } else { functions->glActiveTexture(GL_TEXTURE0); functions->glBindTexture(GL_TEXTURE_2D, m_textureId); } }
void QtViewRenderer::render() { QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); OpenGLStateSaver state(f); f->glEnable(GL_BLEND); f->glBlendEquation(GL_FUNC_ADD); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glDisable(GL_CULL_FACE); f->glDisable(GL_DEPTH_TEST); f->glActiveTexture(GL_TEXTURE0); glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, m_width, m_height); QMatrix4x4 ortho; ortho.ortho(m_viewBounds[0], m_viewBounds[2], m_viewBounds[3], m_viewBounds[1], -1, 1); m_shader->bind(); m_shader->setUniformValue(m_locationTex, 0); m_shader->setUniformValue(m_locationProjMtx, ortho); m_VAO->bind(); int vboSize = 0, eboSize = 0; for (const auto cmd_list : m_drawLists) { if (cmd_list->vtxBuffer().empty() || cmd_list->idxBuffer().empty()) continue; const DrawList::DrawIdx* idx_buffer_offset = nullptr; m_VBO->bind(); int vtxSize = cmd_list->vtxBuffer().size() * sizeof(DrawList::DrawVert); if (vtxSize > vboSize) { m_VBO->allocate(vtxSize); vboSize = vtxSize; } m_VBO->write(0, &cmd_list->vtxBuffer().front(), vtxSize); m_EBO->bind(); int idxSize = cmd_list->idxBuffer().size() * sizeof(DrawList::DrawIdx); if (idxSize > eboSize) { m_EBO->allocate(idxSize); eboSize = idxSize; } m_EBO->write(0, &cmd_list->idxBuffer().front(), idxSize); for (const auto& pcmd : cmd_list->cmdBuffer()) { glBindTexture(GL_TEXTURE_2D, pcmd.textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(pcmd.elemCount), GL_UNSIGNED_INT, idx_buffer_offset); idx_buffer_offset += pcmd.elemCount; } } m_shader->release(); m_VAO->release(); }
void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const { QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); GLuint fboId; functions->glGenFramebuffers(1, &fboId); GLuint tmpTexture = 0; functions->glGenTextures(1, &tmpTexture); functions->glBindTexture(GL_TEXTURE_2D, tmpTexture); functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); functions->glBindTexture(GL_TEXTURE_2D, 0); functions->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); functions->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tmpTexture, 0); functions->glActiveTexture(GL_TEXTURE0); functions->glBindTexture(GL_TEXTURE_2D, textureId); functions->glDisable(GL_STENCIL_TEST); functions->glDisable(GL_DEPTH_TEST); functions->glDisable(GL_SCISSOR_TEST); functions->glDisable(GL_BLEND); GLfloat textureCoordinateArray[8]; textureCoordinateArray[0] = 0.0f; textureCoordinateArray[1] = 0.0f; textureCoordinateArray[2] = 1.0f; textureCoordinateArray[3] = 0.0f; textureCoordinateArray[4] = 1.0f; textureCoordinateArray[5] = 1.0f; textureCoordinateArray[6] = 0.0f; textureCoordinateArray[7] = 1.0f; GLfloat vertexCoordinateArray[8]; vertexCoordinateArray[0] = -1.0f; vertexCoordinateArray[1] = -1.0f; vertexCoordinateArray[2] = 1.0f; vertexCoordinateArray[3] = -1.0f; vertexCoordinateArray[4] = 1.0f; vertexCoordinateArray[5] = 1.0f; vertexCoordinateArray[6] = -1.0f; vertexCoordinateArray[7] = 1.0f; functions->glViewport(0, 0, width, height); functions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); functions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); { static const char *vertexShaderSource = "attribute vec4 vertexCoordsArray; \n" "attribute vec2 textureCoordArray; \n" "varying vec2 textureCoords; \n" "void main(void) \n" "{ \n" " gl_Position = vertexCoordsArray; \n" " textureCoords = textureCoordArray; \n" "} \n"; static const char *fragmentShaderSource = "varying vec2 textureCoords; \n" "uniform sampler2D texture; \n" "void main() \n" "{ \n" " gl_FragColor = texture2D(texture, textureCoords); \n" "} \n"; GLuint vertexShader = functions->glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = functions->glCreateShader(GL_FRAGMENT_SHADER); if (vertexShader == 0 || fragmentShader == 0) { GLenum error = functions->glGetError(); qWarning("QSGDistanceFieldGlyphCache::saveTexture: Failed to create shaders. (GL error: %x)", error); return; } functions->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); functions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); functions->glCompileShader(vertexShader); GLint len = 1; functions->glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len); char infoLog[2048]; functions->glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog); if (qstrlen(infoLog) > 0) qWarning("Problems compiling vertex shader:\n %s", infoLog); functions->glCompileShader(fragmentShader); functions->glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog); if (qstrlen(infoLog) > 0) qWarning("Problems compiling fragment shader:\n %s", infoLog); GLuint shaderProgram = functions->glCreateProgram(); functions->glAttachShader(shaderProgram, vertexShader); functions->glAttachShader(shaderProgram, fragmentShader); functions->glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray"); functions->glBindAttribLocation(shaderProgram, 1, "textureCoordArray"); functions->glLinkProgram(shaderProgram); functions->glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog); if (qstrlen(infoLog) > 0) qWarning("Problems linking shaders:\n %s", infoLog); functions->glUseProgram(shaderProgram); functions->glEnableVertexAttribArray(0); functions->glEnableVertexAttribArray(1); int textureUniformLocation = functions->glGetUniformLocation(shaderProgram, "texture"); functions->glUniform1i(textureUniformLocation, 0); } functions->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); { GLenum error = functions->glGetError(); if (error != GL_NO_ERROR) qWarning("glDrawArrays reported error 0x%x", error); } uchar *data = new uchar[width * height * 4]; functions->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); QImage image(data, width, height, QImage::Format_ARGB32); QByteArray fileName = m_referenceFont.familyName().toLatin1() + '_' + QByteArray::number(textureId); fileName = fileName.replace('/', '_').replace(' ', '_') + ".png"; image.save(QString::fromLocal8Bit(fileName)); { GLenum error = functions->glGetError(); if (error != GL_NO_ERROR) qWarning("glReadPixels reported error 0x%x", error); } functions->glDisableVertexAttribArray(0); functions->glDisableVertexAttribArray(1); functions->glDeleteFramebuffers(1, &fboId); functions->glDeleteTextures(1, &tmpTexture); delete[] data; }
void QSGVideoMaterial_YUV::bind() { QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); QMutexLocker lock(&m_frameMutex); if (m_frame.isValid()) { if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { int fw = m_frame.width(); int fh = m_frame.height(); // Frame has changed size, recreate textures... if (m_textureSize != m_frame.size()) { if (!m_textureSize.isEmpty()) functions->glDeleteTextures(m_planeCount, m_textureIds); functions->glGenTextures(m_planeCount, m_textureIds); m_textureSize = m_frame.size(); } GLint previousAlignment; functions->glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment); functions->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (m_format.pixelFormat() == QVideoFrame::Format_NV12 || m_format.pixelFormat() == QVideoFrame::Format_NV21) { const int y = 0; const int uv = 1; m_planeWidth[0] = m_planeWidth[1] = qreal(fw) / m_frame.bytesPerLine(y); functions->glActiveTexture(GL_TEXTURE1); bindTexture(m_textureIds[1], m_frame.bytesPerLine(uv) / 2, fh / 2, m_frame.bits(uv), GL_LUMINANCE_ALPHA); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), GL_LUMINANCE); } else { // YUV420P || YV12 const int y = 0; const int u = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 1 : 2; const int v = m_frame.pixelFormat() == QVideoFrame::Format_YUV420P ? 2 : 1; m_planeWidth[0] = qreal(fw) / m_frame.bytesPerLine(y); m_planeWidth[1] = m_planeWidth[2] = qreal(fw) / (2 * m_frame.bytesPerLine(u)); functions->glActiveTexture(GL_TEXTURE1); bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), fh / 2, m_frame.bits(u), GL_LUMINANCE); functions->glActiveTexture(GL_TEXTURE2); bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), fh / 2, m_frame.bits(v), GL_LUMINANCE); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), GL_LUMINANCE); } functions->glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment); m_frame.unmap(); } m_frame = QVideoFrame(); } else { // Go backwards to finish with GL_TEXTURE0 for (int i = m_planeCount - 1; i >= 0; --i) { functions->glActiveTexture(GL_TEXTURE0 + i); functions->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); } } }