void QEglFSCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization createShaderPrograms(); if (!m_cursorAtlas.texture) { createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); m_cursorAtlas.image = QImage(); if (m_cursor.shape != Qt::BitmapCursor) m_cursor.texture = m_cursorAtlas.texture; } } if (m_cursor.shape == Qt::BitmapCursor && !m_cursor.customCursorImage.isNull()) { // upload the custom cursor createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); m_cursor.texture = m_cursor.customCursorTexture; m_cursor.customCursorImage = QImage(); } Q_ASSERT(m_cursor.texture); glUseProgram(m_program); const GLfloat x1 = r.left(); const GLfloat x2 = r.right(); const GLfloat y1 = r.top(); const GLfloat y2 = r.bottom(); const GLfloat cursorCoordinates[] = { x1, y2, x2, y2, x1, y1, x2, y1 }; const GLfloat s1 = m_cursor.textureRect.left(); const GLfloat s2 = m_cursor.textureRect.right(); const GLfloat t1 = m_cursor.textureRect.top(); const GLfloat t2 = m_cursor.textureRect.bottom(); const GLfloat textureCoordinates[] = { s1, t2, s2, t2, s1, t1, s2, t1 }; glBindTexture(GL_TEXTURE_2D, m_cursor.texture); glEnableVertexAttribArray(m_vertexCoordEntry); glEnableVertexAttribArray(m_textureCoordEntry); glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, cursorCoordinates); glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); glUniform1f(m_textureEntry, 0); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, 0); glDisableVertexAttribArray(m_vertexCoordEntry); glDisableVertexAttribArray(m_textureCoordEntry); glUseProgram(0); }
void QEGLPlatformCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization initializeOpenGLFunctions(); createShaderPrograms(); if (!m_cursorAtlas.texture) { createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); if (m_cursor.shape != Qt::BitmapCursor) m_cursor.texture = m_cursorAtlas.texture; } } if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) { // upload the custom cursor createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); m_cursor.texture = m_cursor.customCursorTexture; m_cursor.customCursorPending = false; } Q_ASSERT(m_cursor.texture); m_program->bind(); const GLfloat x1 = r.left(); const GLfloat x2 = r.right(); const GLfloat y1 = r.top(); const GLfloat y2 = r.bottom(); const GLfloat cursorCoordinates[] = { x1, y2, x2, y2, x1, y1, x2, y1 }; const GLfloat s1 = m_cursor.textureRect.left(); const GLfloat s2 = m_cursor.textureRect.right(); const GLfloat t1 = m_cursor.textureRect.top(); const GLfloat t2 = m_cursor.textureRect.bottom(); const GLfloat textureCoordinates[] = { s1, t2, s2, t2, s1, t1, s2, t1 }; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_cursor.texture); glBindBuffer(GL_ARRAY_BUFFER, 0); m_program->enableAttributeArray(m_vertexCoordEntry); m_program->enableAttributeArray(m_textureCoordEntry); m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2); m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2); m_program->setUniformValue(m_textureEntry, 0); glDisable(GL_CULL_FACE); glFrontFace(GL_CCW); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, 0); m_program->disableAttributeArray(m_textureCoordEntry); m_program->disableAttributeArray(m_vertexCoordEntry); m_program->release(); }