QWindowCompositor::QWindowCompositor(QOpenGLWindow *window) : QWaylandCompositor(window) , m_window(window) , m_textureBlitter(0) , m_renderScheduler(this) , m_draggingWindow(0) , m_dragKeyIsPressed(false) , m_cursorSurface(0) , m_cursorHotspotX(0) , m_cursorHotspotY(0) , m_modifiers(Qt::NoModifier) { enableSubSurfaceExtension(); m_window->makeCurrent(); m_textureCache = new QOpenGLTextureCache(m_window->context()); m_textureBlitter = new TextureBlitter(); m_backgroundImage = makeBackgroundImage(QLatin1String(":/background.jpg")); m_renderScheduler.setSingleShot(true); connect(&m_renderScheduler,SIGNAL(timeout()),this,SLOT(render())); QOpenGLFunctions *functions = m_window->context()->functions(); functions->glGenFramebuffers(1, &m_surface_fbo); window->installEventFilter(this); setRetainedSelectionEnabled(true); setOutputGeometry(QRect(QPoint(0, 0), window->size())); setOutputRefreshRate(qRound(qGuiApp->primaryScreen()->refreshRate() * 1000.0)); }
OpenGLData::OpenGLData(QOpenGLWindow *window) : m_window(window) , m_textureBlitter(0) , m_ppcm(64) { m_window->makeCurrent(); m_textureCache = new QOpenGLTextureCache(m_window->context()); m_textureBlitter = new TextureBlitter(); QOpenGLFunctions *functions = m_window->context()->functions(); functions->glGenFramebuffers(1, &m_surface_fbo); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_BLEND); glBlendFunc (GL_ONE,GL_ONE_MINUS_SRC_ALPHA); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); }
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; }