Remove direct OpenGL calls from QtOpenGL
Task-number: QTBUG-36483 Change-Id: I96dea5649c0a49a11cd2ff31da659cd2067e769d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
parent
8f443ad0b9
commit
33d0a8d753
@ -89,11 +89,12 @@ void QGL2GradientCache::freeResource(QOpenGLContext *)
|
||||
|
||||
void QGL2GradientCache::cleanCache()
|
||||
{
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
QMutexLocker lock(&m_mutex);
|
||||
QGLGradientColorTableHash::const_iterator it = cache.constBegin();
|
||||
for (; it != cache.constEnd(); ++it) {
|
||||
const CacheInfo &cache_info = it.value();
|
||||
glDeleteTextures(1, &cache_info.texId);
|
||||
funcs->glDeleteTextures(1, &cache_info.texId);
|
||||
}
|
||||
cache.clear();
|
||||
}
|
||||
@ -129,6 +130,7 @@ GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity)
|
||||
|
||||
GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity)
|
||||
{
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
if (cache.size() == maxCacheSize()) {
|
||||
int elem_to_remove = qrand() % maxCacheSize();
|
||||
quint64 key = cache.keys()[elem_to_remove];
|
||||
@ -136,7 +138,7 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra
|
||||
// need to call glDeleteTextures on each removed cache entry:
|
||||
QGLGradientColorTableHash::const_iterator it = cache.constFind(key);
|
||||
do {
|
||||
glDeleteTextures(1, &it.value().texId);
|
||||
funcs->glDeleteTextures(1, &it.value().texId);
|
||||
} while (++it != cache.constEnd() && it.key() == key);
|
||||
cache.remove(key); // may remove more than 1, but OK
|
||||
}
|
||||
@ -144,10 +146,10 @@ GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gra
|
||||
CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
|
||||
uint buffer[1024];
|
||||
generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
|
||||
glGenTextures(1, &cache_entry.texId);
|
||||
glBindTexture(GL_TEXTURE_2D, cache_entry.texId);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
funcs->glGenTextures(1, &cache_entry.texId);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId);
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
return cache.insert(hash_val, cache_entry).value().texId;
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,10 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
# include <qopenglfunctions_1_1.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
@ -106,7 +110,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
|
||||
}
|
||||
|
||||
if (elementIndicesVBOId != 0) {
|
||||
funcs.glDeleteBuffers(1, &elementIndicesVBOId);
|
||||
glDeleteBuffers(1, &elementIndicesVBOId);
|
||||
elementIndicesVBOId = 0;
|
||||
}
|
||||
}
|
||||
@ -193,7 +197,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
|
||||
// Get the image data for the pattern
|
||||
QImage texImage = qt_imageForBrush(style, false);
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
|
||||
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
|
||||
}
|
||||
@ -206,7 +210,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
|
||||
// for opacity to the cache.
|
||||
GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
|
||||
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
|
||||
@ -223,7 +227,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
|
||||
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
|
||||
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA,
|
||||
QGLContext::InternalBindOption |
|
||||
QGLContext::CanFlipNativePixmapBindOption);
|
||||
@ -420,9 +424,9 @@ void QGL2PaintEngineExPrivate::updateMatrix()
|
||||
|
||||
// Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only
|
||||
// need to do this once for every matrix change and persists across all shader programs.
|
||||
funcs.glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);
|
||||
funcs.glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);
|
||||
funcs.glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);
|
||||
glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]);
|
||||
glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]);
|
||||
glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]);
|
||||
|
||||
dasher.setInvScale(inverseScale);
|
||||
stroker.setInvScale(inverseScale);
|
||||
@ -532,11 +536,11 @@ void QGL2PaintEngineEx::beginNativePainting()
|
||||
|
||||
d->nativePaintingActive = true;
|
||||
|
||||
d->funcs.glUseProgram(0);
|
||||
d->glUseProgram(0);
|
||||
|
||||
// Disable all the vertex attribute arrays:
|
||||
for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
|
||||
d->funcs.glDisableVertexAttribArray(i);
|
||||
d->glDisableVertexAttribArray(i);
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
if (!d->ctx->contextHandle()->isES()) {
|
||||
@ -561,12 +565,15 @@ void QGL2PaintEngineEx::beginNativePainting()
|
||||
|
||||
const QSize sz = d->device->size();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_1>();
|
||||
gl1funcs->initializeOpenGLFunctions();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&mv_matrix[0][0]);
|
||||
gl1funcs->glMatrixMode(GL_PROJECTION);
|
||||
gl1funcs->glLoadIdentity();
|
||||
gl1funcs->glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
|
||||
gl1funcs->glMatrixMode(GL_MODELVIEW);
|
||||
gl1funcs->glLoadMatrixf(&mv_matrix[0][0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -583,13 +590,13 @@ void QGL2PaintEngineEx::beginNativePainting()
|
||||
void QGL2PaintEngineExPrivate::resetGLState()
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
funcs.glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDepthMask(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
funcs.glClearDepthf(1);
|
||||
glClearDepthf(1);
|
||||
glStencilMask(0xff);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glStencilFunc(GL_ALWAYS, 0, 0xff);
|
||||
@ -600,7 +607,7 @@ void QGL2PaintEngineExPrivate::resetGLState()
|
||||
if (!ctx->contextHandle()->isES()) {
|
||||
// gl_Color, corresponding to vertex attribute 3, may have been changed
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
glVertexAttrib4fv(3, color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -750,7 +757,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
|
||||
qreal scaleFactor = cache->iscale / inverseScale;
|
||||
if (scaleFactor < 0.5 || scaleFactor > 2.0) {
|
||||
#ifdef QT_OPENGL_CACHE_AS_VBOS
|
||||
funcs.glDeleteBuffers(1, &cache->vbo);
|
||||
glDeleteBuffers(1, &cache->vbo);
|
||||
cache->vbo = 0;
|
||||
Q_ASSERT(cache->ibo == 0);
|
||||
#else
|
||||
@ -777,9 +784,9 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
|
||||
cache->primitiveType = GL_TRIANGLE_FAN;
|
||||
cache->iscale = inverseScale;
|
||||
#ifdef QT_OPENGL_CACHE_AS_VBOS
|
||||
funcs.glGenBuffers(1, &cache->vbo);
|
||||
funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
|
||||
funcs.glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);
|
||||
glGenBuffers(1, &cache->vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW);
|
||||
cache->ibo = 0;
|
||||
#else
|
||||
cache->vertices = (float *) malloc(floatSizeInBytes);
|
||||
@ -790,7 +797,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
|
||||
|
||||
prepareForDraw(currentBrush.isOpaque());
|
||||
#ifdef QT_OPENGL_CACHE_AS_VBOS
|
||||
funcs.glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
|
||||
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
|
||||
#else
|
||||
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
|
||||
@ -1016,9 +1023,9 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data,
|
||||
}
|
||||
|
||||
// Inc. for front-facing triangle
|
||||
funcs.glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
|
||||
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP);
|
||||
// Dec. for back-facing "holes"
|
||||
funcs.glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
|
||||
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP);
|
||||
glStencilMask(~GL_STENCIL_HIGH_BIT);
|
||||
drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN);
|
||||
|
||||
@ -1367,9 +1374,9 @@ void QGL2PaintEngineEx::renderHintsChanged()
|
||||
if (!d->ctx->contextHandle()->isES()) {
|
||||
if ((state()->renderHints & QPainter::Antialiasing)
|
||||
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
d->glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
d->glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1415,7 +1422,7 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
|
||||
bindOptions |= QGLContext::TemporarilyCachedBindOption;
|
||||
#endif
|
||||
|
||||
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
QGLTexture *texture =
|
||||
ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions);
|
||||
|
||||
@ -1457,7 +1464,7 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
|
||||
ensureActive();
|
||||
d->transferMode(ImageDrawingMode);
|
||||
|
||||
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
|
||||
QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption;
|
||||
#ifdef QGL_USE_TEXTURE_POOL
|
||||
@ -1518,8 +1525,8 @@ bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
|
||||
ensureActive();
|
||||
d->transferMode(ImageDrawingMode);
|
||||
|
||||
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
d->glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
|
||||
QGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
|
||||
|
||||
@ -1804,7 +1811,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
|
||||
funcs.glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
} else {
|
||||
// Other brush styles need two passes.
|
||||
|
||||
@ -1821,7 +1828,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, cache->texture());
|
||||
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
|
||||
|
||||
@ -1856,7 +1863,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFo
|
||||
QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest;
|
||||
if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) {
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
|
||||
if (lastMaskTextureUsed != cache->texture()) {
|
||||
glBindTexture(GL_TEXTURE_2D, cache->texture());
|
||||
lastMaskTextureUsed = cache->texture();
|
||||
@ -1957,7 +1964,7 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen
|
||||
allOpaque &= (opacity >= 0.99f);
|
||||
}
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
|
||||
QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
|
||||
QGLContext::InternalBindOption
|
||||
| QGLContext::CanFlipNativePixmapBindOption);
|
||||
@ -2031,17 +2038,17 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
|
||||
// go after beginPaint:
|
||||
d->device->beginPaint();
|
||||
|
||||
d->funcs.initializeOpenGLFunctions();
|
||||
d->initializeOpenGLFunctions();
|
||||
|
||||
d->shaderManager = new QGLEngineShaderManager(d->ctx);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
d->glDisable(GL_STENCIL_TEST);
|
||||
d->glDisable(GL_DEPTH_TEST);
|
||||
d->glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!d->ctx->contextHandle()->isES())
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
d->glDisable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
|
||||
d->glyphCacheFormat = QFontEngine::Format_A8;
|
||||
@ -2067,7 +2074,7 @@ bool QGL2PaintEngineEx::end()
|
||||
Q_D(QGL2PaintEngineEx);
|
||||
|
||||
QGLContext *ctx = d->ctx;
|
||||
d->funcs.glUseProgram(0);
|
||||
d->glUseProgram(0);
|
||||
d->transferMode(BrushDrawingMode);
|
||||
d->device->endPaint();
|
||||
|
||||
@ -2081,11 +2088,11 @@ bool QGL2PaintEngineEx::end()
|
||||
|
||||
#ifdef QT_OPENGL_CACHE_AS_VBOS
|
||||
if (!d->unusedVBOSToClean.isEmpty()) {
|
||||
glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData());
|
||||
d->glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData());
|
||||
d->unusedVBOSToClean.clear();
|
||||
}
|
||||
if (!d->unusedIBOSToClean.isEmpty()) {
|
||||
glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData());
|
||||
d->glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData());
|
||||
d->unusedIBOSToClean.clear();
|
||||
}
|
||||
#endif
|
||||
@ -2107,7 +2114,7 @@ void QGL2PaintEngineEx::ensureActive()
|
||||
|
||||
if (d->needsSync) {
|
||||
d->transferMode(BrushDrawingMode);
|
||||
glViewport(0, 0, d->width, d->height);
|
||||
d->glViewport(0, 0, d->width, d->height);
|
||||
d->needsSync = false;
|
||||
d->lastMaskTextureUsed = 0;
|
||||
d->shaderManager->setDirty();
|
||||
@ -2428,7 +2435,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state)
|
||||
if (old_state == s || old_state->clipChanged) {
|
||||
if (old_state && old_state != s && old_state->canRestoreClip) {
|
||||
d->updateClipScissorTest();
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
d->glDepthFunc(GL_LEQUAL);
|
||||
} else {
|
||||
d->regenerateClip();
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ private:
|
||||
Q_DISABLE_COPY(QGL2PaintEngineEx)
|
||||
};
|
||||
|
||||
class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate
|
||||
class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate, protected QOpenGLExtensions
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QGL2PaintEngineEx)
|
||||
public:
|
||||
@ -261,8 +261,6 @@ public:
|
||||
EngineMode mode;
|
||||
QFontEngine::GlyphFormat glyphCacheFormat;
|
||||
|
||||
QOpenGLExtensions funcs;
|
||||
|
||||
// Dirty flags
|
||||
bool matrixDirty; // Implies matrix uniforms are also dirty
|
||||
bool compositionModeDirty;
|
||||
@ -327,9 +325,9 @@ void QGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex
|
||||
|
||||
vertexAttribPointers[arrayIndex] = pointer;
|
||||
if (arrayIndex == QT_OPACITY_ATTR)
|
||||
funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
|
||||
glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer);
|
||||
else
|
||||
funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
|
||||
glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -96,6 +96,7 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
|
||||
qWarning("QGLTextureGlyphCache::createTextureData: Called with no context");
|
||||
return;
|
||||
}
|
||||
QOpenGLFunctions *funcs = ctx->contextHandle()->functions();
|
||||
|
||||
// create in QImageTextureGlyphCache baseclass is meant to be called
|
||||
// only to create the initial image and does not preserve the content,
|
||||
@ -117,8 +118,8 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
|
||||
if (!m_textureResource)
|
||||
m_textureResource = new QGLGlyphTexture(ctx);
|
||||
|
||||
glGenTextures(1, &m_textureResource->m_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
funcs->glGenTextures(1, &m_textureResource->m_texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
|
||||
m_textureResource->m_width = width;
|
||||
m_textureResource->m_height = height;
|
||||
@ -127,18 +128,18 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
|
||||
QVarLengthArray<uchar> data(width * height * 4);
|
||||
for (int i = 0; i < data.size(); ++i)
|
||||
data[i] = 0;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
} else {
|
||||
QVarLengthArray<uchar> data(width * height);
|
||||
for (int i = 0; i < data.size(); ++i)
|
||||
data[i] = 0;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
m_filterMode = Nearest;
|
||||
}
|
||||
|
||||
@ -149,6 +150,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
|
||||
qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context");
|
||||
return;
|
||||
}
|
||||
QOpenGLFunctions *funcs = ctx->contextHandle()->functions();
|
||||
|
||||
int oldWidth = m_textureResource->m_width;
|
||||
int oldHeight = m_textureResource->m_height;
|
||||
@ -165,44 +167,42 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
|
||||
if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->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);
|
||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits());
|
||||
funcs->glDeleteTextures(1, &oldTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
QOpenGLFunctions *funcs = ctx->contextHandle()->functions();
|
||||
|
||||
// ### the QTextureGlyphCache API needs to be reworked to allow
|
||||
// ### resizeTextureData to fail
|
||||
|
||||
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);
|
||||
funcs->glGenTextures(1, &tmp_texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, tmp_texture);
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
m_filterMode = Nearest;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
funcs->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);
|
||||
funcs->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);
|
||||
funcs->glDisable(GL_STENCIL_TEST);
|
||||
funcs->glDisable(GL_DEPTH_TEST);
|
||||
funcs->glDisable(GL_SCISSOR_TEST);
|
||||
funcs->glDisable(GL_BLEND);
|
||||
|
||||
glViewport(0, 0, oldWidth, oldHeight);
|
||||
funcs->glViewport(0, 0, oldWidth, oldHeight);
|
||||
|
||||
QGLShaderProgram *blitProgram = 0;
|
||||
if (pex == 0) {
|
||||
@ -257,21 +257,21 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
|
||||
|
||||
blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
|
||||
funcs->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->glDeleteTextures(1, &tmp_texture);
|
||||
funcs->glDeleteTextures(1, &oldTexture);
|
||||
|
||||
funcs->glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
|
||||
|
||||
if (pex != 0) {
|
||||
glViewport(0, 0, pex->width, pex->height);
|
||||
funcs->glViewport(0, 0, pex->width, pex->height);
|
||||
pex->updateClipScissorTest();
|
||||
}
|
||||
}
|
||||
@ -283,16 +283,17 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
|
||||
qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
|
||||
return;
|
||||
}
|
||||
QOpenGLFunctions *funcs = ctx->contextHandle()->functions();
|
||||
|
||||
if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) {
|
||||
QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
const QImage &texture = image();
|
||||
const uchar *bits = texture.constBits();
|
||||
bits += c.y * texture.bytesPerLine() + c.x;
|
||||
for (int i=0; i<c.h; ++i) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
|
||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits);
|
||||
bits += texture.bytesPerLine();
|
||||
}
|
||||
return;
|
||||
@ -329,14 +330,14 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
if (mask.format() == QImage::Format_RGB32) {
|
||||
GLenum format = GL_RGBA;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!ctx->contextHandle()->isES())
|
||||
format = GL_BGRA;
|
||||
#endif
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits());
|
||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits());
|
||||
} else {
|
||||
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
|
||||
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
|
||||
@ -349,16 +350,16 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
|
||||
|
||||
if (!ctx->d_ptr->workaround_brokenAlphaTexSubImage_init) {
|
||||
// don't know which driver versions exhibit this bug, so be conservative for now
|
||||
const QByteArray vendorString(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
|
||||
const QByteArray vendorString(reinterpret_cast<const char*>(funcs->glGetString(GL_VENDOR)));
|
||||
ctx->d_ptr->workaround_brokenAlphaTexSubImage = vendorString.indexOf("NVIDIA") >= 0;
|
||||
ctx->d_ptr->workaround_brokenAlphaTexSubImage_init = true;
|
||||
}
|
||||
|
||||
if (ctx->d_ptr->workaround_brokenAlphaTexSubImage) {
|
||||
for (int i = 0; i < maskHeight; ++i)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
|
||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i));
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ struct QGLGlyphTexture : public QOpenGLSharedResource
|
||||
if (ctx && m_fbo)
|
||||
ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &m_fbo);
|
||||
if (m_width || m_height)
|
||||
glDeleteTextures(1, &m_texture);
|
||||
ctx->contextHandle()->functions()->glDeleteTextures(1, &m_texture);
|
||||
}
|
||||
|
||||
void invalidateResource()
|
||||
|
@ -70,6 +70,10 @@
|
||||
#include "qlibrary.h"
|
||||
#include <qmutex.h>
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
#include <qopenglfunctions_1_1.h>
|
||||
#endif
|
||||
|
||||
// #define QT_GL_CONTEXT_RESOURCE_DEBUG
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -107,6 +111,7 @@ bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension)
|
||||
}
|
||||
|
||||
QOpenGLExtensions::OpenGLExtensions extensions;
|
||||
|
||||
/*
|
||||
Returns the GL extensions for the current QOpenGLContext. If there is no
|
||||
current QOpenGLContext, a default context will be created and the extensions
|
||||
@ -121,6 +126,20 @@ QOpenGLExtensions* qgl_extensions()
|
||||
return 0;
|
||||
}
|
||||
|
||||
QOpenGLFunctions *qgl_functions()
|
||||
{
|
||||
return qgl_extensions(); // QOpenGLExtensions is just a subclass of QOpenGLFunctions
|
||||
}
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions_1_1 *qgl1_functions()
|
||||
{
|
||||
QOpenGLFunctions_1_1 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_1>();
|
||||
f->initializeOpenGLFunctions();
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct QGLThreadContext {
|
||||
~QGLThreadContext() {
|
||||
if (context)
|
||||
@ -1355,7 +1374,7 @@ QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
|
||||
}
|
||||
}
|
||||
|
||||
QString versionString(QLatin1String(reinterpret_cast<const char*>(glGetString(GL_VERSION))));
|
||||
QString versionString(QLatin1String(reinterpret_cast<const char*>(qgl_functions()->glGetString(GL_VERSION))));
|
||||
OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString);
|
||||
if (currentCtx) {
|
||||
currentCtx->d_func()->version_flags_cached = true;
|
||||
@ -1687,7 +1706,7 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ
|
||||
return QImage();
|
||||
int w = size.width();
|
||||
int h = size.height();
|
||||
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
qgl_functions()->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
convertFromGLImage(img, w, h, alpha_format, include_alpha);
|
||||
return img;
|
||||
}
|
||||
@ -1701,8 +1720,8 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
|
||||
int h = size.height();
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (!QOpenGLContext::currentContext()->isES()) {
|
||||
//### glGetTexImage not in GL ES 2.0, need to do something else here!
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
|
||||
qgl1_functions()->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
}
|
||||
#endif // QT_OPENGL_ES
|
||||
convertFromGLImage(img, w, h, alpha_format, include_alpha);
|
||||
@ -2193,7 +2212,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
q->deleteTexture(texture->id);
|
||||
texture = 0;
|
||||
} else {
|
||||
glBindTexture(target, texture->id);
|
||||
qgl_functions()->glBindTexture(target, texture->id);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
@ -2245,6 +2264,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
const qint64 key, QGLContext::BindOptions options)
|
||||
{
|
||||
Q_Q(QGLContext);
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
|
||||
#ifdef QGL_BIND_TEXTURE_DEBUG
|
||||
printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n",
|
||||
@ -2255,7 +2275,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
// Reset the gl error stack...git
|
||||
while (glGetError() != GL_NO_ERROR) ;
|
||||
while (funcs->glGetError() != GL_NO_ERROR) ;
|
||||
#endif
|
||||
|
||||
// Scale the pixmap if needed. GL textures needs to have the
|
||||
@ -2280,9 +2300,9 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
GLuint filtering = options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST;
|
||||
|
||||
GLuint tx_id;
|
||||
glGenTextures(1, &tx_id);
|
||||
glBindTexture(target, tx_id);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
funcs->glGenTextures(1, &tx_id);
|
||||
funcs->glBindTexture(target, tx_id);
|
||||
funcs->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
|
||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||
bool genMipmap = !ctx->isES();
|
||||
@ -2293,23 +2313,23 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (genMipmap) {
|
||||
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
|
||||
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
funcs->glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
|
||||
funcs->glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
} else {
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
genMipmap = true;
|
||||
}
|
||||
#else
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
genMipmap = true;
|
||||
#endif
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption
|
||||
? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST);
|
||||
funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption
|
||||
? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST);
|
||||
#ifdef QGL_BIND_TEXTURE_DEBUG
|
||||
printf(" - generating mipmaps (%d ms)\n", time.elapsed());
|
||||
#endif
|
||||
} else {
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
}
|
||||
|
||||
QImage::Format target_format = img.format();
|
||||
@ -2438,12 +2458,12 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
#endif
|
||||
|
||||
const QImage &constRef = img; // to avoid detach in bits()...
|
||||
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
|
||||
pixel_type, constRef.bits());
|
||||
funcs->glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
|
||||
pixel_type, constRef.bits());
|
||||
if (genMipmap && ctx->isES())
|
||||
q->functions()->glGenerateMipmap(target);
|
||||
#ifndef QT_NO_DEBUG
|
||||
GLenum error = glGetError();
|
||||
GLenum error = funcs->glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target);
|
||||
}
|
||||
@ -2491,7 +2511,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
|
||||
q->deleteTexture(texture->id);
|
||||
texture = 0;
|
||||
} else {
|
||||
glBindTexture(target, texture->id);
|
||||
qgl_functions()->glBindTexture(target, texture->id);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
@ -2520,7 +2540,8 @@ int QGLContextPrivate::maxTextureSize()
|
||||
if (max_texture_size != -1)
|
||||
return max_texture_size;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
|
||||
#ifndef QT_OPENGL_ES
|
||||
Q_Q(QGLContext);
|
||||
@ -2529,8 +2550,9 @@ int QGLContextPrivate::maxTextureSize()
|
||||
|
||||
GLint size;
|
||||
GLint next = 64;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
if (size == 0) {
|
||||
return max_texture_size;
|
||||
}
|
||||
@ -2540,8 +2562,8 @@ int QGLContextPrivate::maxTextureSize()
|
||||
|
||||
if (next > max_texture_size)
|
||||
break;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
} while (next > size);
|
||||
|
||||
max_texture_size = size;
|
||||
@ -2658,7 +2680,7 @@ void QGLContext::deleteTexture(GLuint id)
|
||||
{
|
||||
if (QGLTextureCache::instance()->remove(this, id))
|
||||
return;
|
||||
glDeleteTextures(1, &id);
|
||||
qgl_functions()->glDeleteTextures(1, &id);
|
||||
}
|
||||
|
||||
void qt_add_rect_to_array(const QRectF &r, GLfloat *array)
|
||||
@ -2694,6 +2716,7 @@ void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *
|
||||
|
||||
static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget)
|
||||
{
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
GLfloat tx = 1.0f;
|
||||
GLfloat ty = 1.0f;
|
||||
|
||||
@ -2704,8 +2727,9 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
|
||||
#else
|
||||
if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isES()) {
|
||||
if (textureWidth == -1 || textureHeight == -1) {
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
}
|
||||
|
||||
tx = GLfloat(textureWidth);
|
||||
@ -2720,15 +2744,16 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
|
||||
GLfloat vertexArray[4*2];
|
||||
qt_add_rect_to_array(target, vertexArray);
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 0, vertexArray);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
gl1funcs->glVertexPointer(2, GL_FLOAT, 0, vertexArray);
|
||||
gl1funcs->glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
gl1funcs->glEnableClientState(GL_VERTEX_ARRAY);
|
||||
gl1funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
gl1funcs->glDisableClientState(GL_VERTEX_ARRAY);
|
||||
gl1funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
#endif // !QT_OPENGL_ES_2
|
||||
@ -2769,6 +2794,7 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
|
||||
#endif
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
if (!contextHandle()->isES()) {
|
||||
#ifdef QT_OPENGL_ES
|
||||
if (textureTarget != GL_TEXTURE_2D) {
|
||||
@ -2776,22 +2802,22 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
|
||||
return;
|
||||
}
|
||||
#else
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
const bool wasEnabled = funcs->glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
#endif
|
||||
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
funcs->glEnable(textureTarget);
|
||||
funcs->glBindTexture(textureTarget, textureId);
|
||||
|
||||
qDrawTextureRect(target, -1, -1, textureTarget);
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
glDisable(textureTarget);
|
||||
funcs->glDisable(textureTarget);
|
||||
#else
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
funcs->glDisable(textureTarget);
|
||||
funcs->glBindTexture(textureTarget, oldTexture);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -2832,18 +2858,20 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
|
||||
Q_UNUSED(textureTarget);
|
||||
#else
|
||||
if (!contextHandle()->isES()) {
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
const bool wasEnabled = funcs->glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
funcs->glEnable(textureTarget);
|
||||
funcs->glBindTexture(textureTarget, textureId);
|
||||
|
||||
GLint textureWidth;
|
||||
GLint textureHeight;
|
||||
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
|
||||
if (d_ptr->active_engine &&
|
||||
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
|
||||
@ -2860,8 +2888,8 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
|
||||
qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
|
||||
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
funcs->glDisable(textureTarget);
|
||||
funcs->glBindTexture(textureTarget, oldTexture);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -3909,7 +3937,7 @@ void QGLWidget::initializeGL()
|
||||
|
||||
void QGLWidget::paintGL()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
qgl_functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
@ -4136,7 +4164,7 @@ void QGLWidget::glDraw()
|
||||
makeCurrent();
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isES())
|
||||
glDrawBuffer(GL_FRONT);
|
||||
qgl1_functions()->glDrawBuffer(GL_FRONT);
|
||||
#endif
|
||||
QSize readback_target_size = d->glcx->d_ptr->readback_target_size;
|
||||
if (!d->glcx->initialized()) {
|
||||
@ -4158,7 +4186,7 @@ void QGLWidget::glDraw()
|
||||
if (d->autoSwap)
|
||||
swapBuffers();
|
||||
} else {
|
||||
glFlush();
|
||||
qgl_functions()->glFlush();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4176,20 +4204,20 @@ void QGLWidget::qglColor(const QColor& c) const
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
#ifdef QT_OPENGL_ES
|
||||
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
qgl_functions()->glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
#else
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx && !ctx->contextHandle()->isES()) {
|
||||
if (ctx->format().rgba())
|
||||
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
qgl1_functions()->glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glIndexi(i);
|
||||
qgl1_functions()->glIndexi(i);
|
||||
} else
|
||||
glIndexi(ctx->colorIndex(c));
|
||||
qgl1_functions()->glIndexi(ctx->colorIndex(c));
|
||||
}
|
||||
#endif //QT_OPENGL_ES
|
||||
#else
|
||||
@ -4208,23 +4236,23 @@ void QGLWidget::qglColor(const QColor& c) const
|
||||
void QGLWidget::qglClearColor(const QColor& c) const
|
||||
{
|
||||
#ifdef QT_OPENGL_ES
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
#else
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx && !ctx->contextHandle()->isES()) {
|
||||
if (ctx->format().rgba())
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glClearIndex(i);
|
||||
qgl1_functions()->glClearIndex(i);
|
||||
} else {
|
||||
glClearIndex(ctx->colorIndex(c));
|
||||
qgl1_functions()->glClearIndex(ctx->colorIndex(c));
|
||||
}
|
||||
} else {
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -4307,42 +4335,47 @@ QImage QGLWidget::convertToGLFormat(const QImage& img)
|
||||
|
||||
static void qt_save_gl_state()
|
||||
{
|
||||
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl1funcs->glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
|
||||
gl1funcs->glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
gl1funcs->glMatrixMode(GL_TEXTURE);
|
||||
gl1funcs->glPushMatrix();
|
||||
gl1funcs->glLoadIdentity();
|
||||
gl1funcs->glMatrixMode(GL_PROJECTION);
|
||||
gl1funcs->glPushMatrix();
|
||||
gl1funcs->glMatrixMode(GL_MODELVIEW);
|
||||
gl1funcs->glPushMatrix();
|
||||
|
||||
gl1funcs->glShadeModel(GL_FLAT);
|
||||
funcs->glDisable(GL_CULL_FACE);
|
||||
funcs->glDisable(GL_LIGHTING);
|
||||
funcs->glDisable(GL_STENCIL_TEST);
|
||||
funcs->glDisable(GL_DEPTH_TEST);
|
||||
funcs->glEnable(GL_BLEND);
|
||||
funcs->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void qt_restore_gl_state()
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
glPopClientAttrib();
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
|
||||
gl1funcs->glMatrixMode(GL_TEXTURE);
|
||||
gl1funcs->glPopMatrix();
|
||||
gl1funcs->glMatrixMode(GL_PROJECTION);
|
||||
gl1funcs->glPopMatrix();
|
||||
gl1funcs->glMatrixMode(GL_MODELVIEW);
|
||||
gl1funcs->glPopMatrix();
|
||||
gl1funcs->glPopAttrib();
|
||||
gl1funcs->glPopClientAttrib();
|
||||
}
|
||||
|
||||
static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
|
||||
const QFont &font)
|
||||
{
|
||||
GLfloat color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, &color[0]);
|
||||
qgl_functions()->glGetFloatv(GL_CURRENT_COLOR, &color[0]);
|
||||
|
||||
QColor col;
|
||||
col.setRgbF(color[0], color[1], color[2],color[3]);
|
||||
@ -4392,10 +4425,11 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
|
||||
if (str.isEmpty() || !isValid())
|
||||
return;
|
||||
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
GLint view[4];
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
bool use_scissor_testing = funcs->glIsEnabled(GL_SCISSOR_TEST);
|
||||
if (!use_scissor_testing)
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
funcs->glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
bool auto_swap = autoBufferSwap();
|
||||
@ -4410,8 +4444,8 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
|
||||
reuse_painter = true;
|
||||
p = engine->painter();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, width, height);
|
||||
funcs->glDisable(GL_DEPTH_TEST);
|
||||
funcs->glViewport(0, 0, width, height);
|
||||
} else {
|
||||
setAutoBufferSwap(false);
|
||||
// disable glClear() as a result of QPainter::begin()
|
||||
@ -4423,11 +4457,11 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
// if the user hasn't set a scissor box, we set one that
|
||||
// covers the current viewport
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
funcs->glScissor(view[0], view[1], view[2], view[3]);
|
||||
funcs->glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
// use the scissor box set by the user
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
funcs->glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
qt_gl_draw_text(p, x, y, str, font);
|
||||
@ -4482,15 +4516,17 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
|
||||
if (str.isEmpty() || !isValid())
|
||||
return;
|
||||
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
bool auto_swap = autoBufferSwap();
|
||||
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
GLdouble model[4 * 4], proj[4 * 4];
|
||||
GLint view[4];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions();
|
||||
gl1funcs->glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
|
||||
gl1funcs->glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
|
||||
funcs->glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
GLdouble win_x = 0, win_y = 0, win_z = 0;
|
||||
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
|
||||
&win_x, &win_y, &win_z);
|
||||
@ -4500,8 +4536,8 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
|
||||
|
||||
QPainter *p;
|
||||
bool reuse_painter = false;
|
||||
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
bool use_depth_testing = funcs->glIsEnabled(GL_DEPTH_TEST);
|
||||
bool use_scissor_testing = funcs->glIsEnabled(GL_SCISSOR_TEST);
|
||||
|
||||
qt_save_gl_state();
|
||||
|
||||
@ -4517,16 +4553,16 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
|
||||
|
||||
QRect viewport(view[0], view[1], view[2], view[3]);
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
funcs->glScissor(view[0], view[1], view[2], view[3]);
|
||||
funcs->glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
funcs->glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
glViewport(0, 0, width, height);
|
||||
glAlphaFunc(GL_GREATER, 0.0);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
funcs->glViewport(0, 0, width, height);
|
||||
gl1funcs->glAlphaFunc(GL_GREATER, 0.0);
|
||||
funcs->glEnable(GL_ALPHA_TEST);
|
||||
if (use_depth_testing)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
funcs->glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// The only option in Qt 5 is the shader-based OpenGL 2 paint engine.
|
||||
// Setting fixed pipeline transformations is futile. Instead, pass the
|
||||
@ -4964,10 +5000,11 @@ QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len)
|
||||
const GLubyte *pixels =
|
||||
reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4);
|
||||
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
funcs->glGenTextures(1, &id);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, id);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
int size;
|
||||
int offset = 0;
|
||||
@ -5060,23 +5097,24 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
|
||||
}
|
||||
|
||||
// Create the texture.
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
QOpenGLFunctions *funcs = qgl_functions();
|
||||
funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
funcs->glGenTextures(1, &id);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, id);
|
||||
if (pvrHeader->mipMapCount) {
|
||||
if ((options & QGLContext::LinearFilteringBindOption) != 0) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
}
|
||||
} else if ((options & QGLContext::LinearFilteringBindOption) != 0) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
// Load the compressed mipmap levels.
|
||||
@ -5102,7 +5140,7 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
|
||||
}
|
||||
|
||||
// Restore the default pixel alignment for later texture uploads.
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
|
||||
// Set the invert flag for the texture. The "vertical flip"
|
||||
// flag in PVR is the opposite sense to our sense of inversion.
|
||||
|
@ -346,7 +346,7 @@ public:
|
||||
|
||||
private:
|
||||
static void freeTextureFunc(QOpenGLFunctions *, GLuint id) {
|
||||
glDeleteTextures(1, &id);
|
||||
QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &id);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -226,7 +226,7 @@ void QGLContext::makeCurrent()
|
||||
if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
|
||||
if (!d->workaroundsCached) {
|
||||
d->workaroundsCached = true;
|
||||
const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
|
||||
const char *renderer = reinterpret_cast<const char *>(d->guiGlContext->functions()->glGetString(GL_RENDERER));
|
||||
if (renderer && strstr(renderer, "Mali")) {
|
||||
d->workaround_brokenFBOReadBack = true;
|
||||
}
|
||||
|
@ -347,9 +347,9 @@ bool QGLBuffer::read(int offset, void *data, int count)
|
||||
Q_D(QGLBuffer);
|
||||
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
|
||||
return false;
|
||||
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
d->funcs->glGetBufferSubData(d->type, offset, count, data);
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
return d->funcs->glGetError() == GL_NO_ERROR;
|
||||
#else
|
||||
Q_UNUSED(offset);
|
||||
Q_UNUSED(data);
|
||||
|
@ -61,11 +61,11 @@ extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool);
|
||||
#ifndef QT_NO_DEBUG
|
||||
#define QT_RESET_GLERROR() \
|
||||
{ \
|
||||
while (glGetError() != GL_NO_ERROR) {} \
|
||||
while (QOpenGLContext::currentContext()->functions()->glGetError() != GL_NO_ERROR) {} \
|
||||
}
|
||||
#define QT_CHECK_GLERROR() \
|
||||
{ \
|
||||
GLenum err = glGetError(); \
|
||||
GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \
|
||||
if (err != GL_NO_ERROR) { \
|
||||
qDebug("[%s line %d] GL Error: %d", \
|
||||
__FILE__, __LINE__, (int)err); \
|
||||
@ -460,7 +460,7 @@ namespace
|
||||
void freeTextureFunc(QGLContext *ctx, GLuint id)
|
||||
{
|
||||
Q_UNUSED(ctx);
|
||||
glDeleteTextures(1, &id);
|
||||
ctx->contextHandle()->functions()->glDeleteTextures(1, &id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,10 +493,10 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
QT_CHECK_GLERROR();
|
||||
// init texture
|
||||
if (samples == 0) {
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(target, texture);
|
||||
glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
funcs.glGenTextures(1, &texture);
|
||||
funcs.glBindTexture(target, texture);
|
||||
funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
if (mipmap) {
|
||||
int width = size.width();
|
||||
int height = size.height();
|
||||
@ -505,26 +505,26 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
width = qMax(1, width >> 1);
|
||||
height = qMax(1, height >> 1);
|
||||
++level;
|
||||
glTexImage2D(target, level, internal_format, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
funcs.glTexImage2D(target, level, internal_format, width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
}
|
||||
}
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
target, texture, 0);
|
||||
|
||||
QT_CHECK_GLERROR();
|
||||
valid = checkFramebufferStatus();
|
||||
glBindTexture(target, 0);
|
||||
funcs.glBindTexture(target, 0);
|
||||
|
||||
color_buffer = 0;
|
||||
} else {
|
||||
mipmap = false;
|
||||
GLint maxSamples;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
|
||||
samples = qBound(0, int(samples), int(maxSamples));
|
||||
|
||||
@ -694,7 +694,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
if (color_buffer)
|
||||
funcs.glDeleteRenderbuffers(1, &color_buffer);
|
||||
else
|
||||
glDeleteTextures(1, &texture);
|
||||
funcs.glDeleteTextures(1, &texture);
|
||||
if (depth_buffer)
|
||||
funcs.glDeleteRenderbuffers(1, &depth_buffer);
|
||||
if (stencil_buffer && depth_buffer != stencil_buffer)
|
||||
|
@ -164,18 +164,19 @@ void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w)
|
||||
void QGLWidgetGLPaintDevice::beginPaint()
|
||||
{
|
||||
QGLPaintDevice::beginPaint();
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
if (!glWidget->d_func()->disable_clear_on_painter_begin && glWidget->autoFillBackground()) {
|
||||
if (glWidget->testAttribute(Qt::WA_TranslucentBackground))
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
funcs->glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
else {
|
||||
const QColor &c = glWidget->palette().brush(glWidget->backgroundRole()).color();
|
||||
float alpha = c.alphaF();
|
||||
glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
|
||||
funcs->glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
|
||||
}
|
||||
if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
funcs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
else
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
funcs->glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ void QGLPBufferGLPaintDevice::beginPaint()
|
||||
|
||||
void QGLPBufferGLPaintDevice::endPaint()
|
||||
{
|
||||
glFlush();
|
||||
QOpenGLContext::currentContext()->functions()->glFlush();
|
||||
QGLPaintDevice::endPaint();
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ bool QGLPixelBuffer::makeCurrent()
|
||||
d->fbo = new QOpenGLFramebufferObject(d->req_size, format);
|
||||
d->fbo->bind();
|
||||
d->glDevice.setFbo(d->fbo->handle());
|
||||
glViewport(0, 0, d->req_size.width(), d->req_size.height());
|
||||
QOpenGLContext::currentContext()->functions()->glViewport(0, 0, d->req_size.width(), d->req_size.height());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -359,12 +359,12 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
|
||||
extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle());
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
#ifndef QT_OPENGL_ES
|
||||
GLenum format = ctx->isES() ? GL_RGBA : GL_RGBA8;
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
#else
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
ctx->functions()->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
#endif
|
||||
|
||||
if (d->blit_fbo)
|
||||
@ -629,17 +629,18 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const
|
||||
}
|
||||
|
||||
GLuint texture;
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
funcs->glGenTextures(1, &texture);
|
||||
funcs->glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
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);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
@ -3074,8 +3074,9 @@ int QGLShaderProgram::maxGeometryOutputVertices() const
|
||||
{
|
||||
GLint n = 0;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(const QGLShaderProgram);
|
||||
if (!QOpenGLContext::currentContext()->isES())
|
||||
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
|
||||
d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
@ -3229,7 +3230,7 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
|
||||
if (!resolved)
|
||||
return false;
|
||||
|
||||
if ((type & Geometry) && !QByteArray((const char *) glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4"))
|
||||
if ((type & Geometry) && !QByteArray((const char *) functions.glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -459,9 +459,9 @@ void tst_QOpenGL::fboSimpleRendering()
|
||||
|
||||
QVERIFY(fbo->bind());
|
||||
|
||||
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glFinish();
|
||||
ctx.functions()->glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
|
||||
ctx.functions()->glFinish();
|
||||
|
||||
const QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32);
|
||||
QCOMPARE(fb.size(), size);
|
||||
@ -505,9 +505,9 @@ void tst_QOpenGL::fboTextureOwnership()
|
||||
fbo->bind();
|
||||
QVERIFY(fbo->texture() != 0 && fbo->texture() != texture);
|
||||
|
||||
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glFinish();
|
||||
ctx.functions()->glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
|
||||
ctx.functions()->glFinish();
|
||||
|
||||
QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32);
|
||||
QImage reference(fb.size(), QImage::Format_RGB32);
|
||||
@ -515,7 +515,7 @@ void tst_QOpenGL::fboTextureOwnership()
|
||||
|
||||
QFUZZY_COMPARE_IMAGES(fb, reference);
|
||||
|
||||
glDeleteTextures(1, &texture);
|
||||
ctx.functions()->glDeleteTextures(1, &texture);
|
||||
delete fbo;
|
||||
}
|
||||
|
||||
|
@ -1090,9 +1090,10 @@ void tst_QGL::glFBOSimpleRendering()
|
||||
|
||||
fbo->bind();
|
||||
|
||||
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glFinish();
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
funcs->glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
funcs->glClear(GL_COLOR_BUFFER_BIT);
|
||||
funcs->glFinish();
|
||||
|
||||
QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32);
|
||||
QImage reference(fb.size(), QImage::Format_RGB32);
|
||||
@ -1390,11 +1391,11 @@ class RenderPixmapWidget : public QGLWidget
|
||||
protected:
|
||||
void initializeGL() {
|
||||
// Set some gl state:
|
||||
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
QOpenGLContext::currentContext()->functions()->glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
void paintGL() {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1683,11 +1684,12 @@ protected:
|
||||
void paintEvent(QPaintEvent*)
|
||||
{
|
||||
// clear the stencil with junk
|
||||
glStencilMask(0xFFFF);
|
||||
glClearStencil(0xFFFF);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
funcs->glStencilMask(0xFFFF);
|
||||
funcs->glClearStencil(0xFFFF);
|
||||
funcs->glDisable(GL_STENCIL_TEST);
|
||||
funcs->glDisable(GL_SCISSOR_TEST);
|
||||
funcs->glClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
QPainter painter(this);
|
||||
paint(&painter);
|
||||
@ -2029,26 +2031,27 @@ void tst_QGL::qglContextDefaultBindTexture()
|
||||
QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage));
|
||||
QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap));
|
||||
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
// Make sure the texture IDs returned are valid:
|
||||
QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
|
||||
QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE);
|
||||
|
||||
// Make sure the textures are still valid after we delete the image/pixmap:
|
||||
// Also check that although the textures are left intact, the cache entries are removed:
|
||||
delete boundImage;
|
||||
boundImage = 0;
|
||||
QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_TRUE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_TRUE);
|
||||
QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1);
|
||||
delete boundPixmap;
|
||||
boundPixmap = 0;
|
||||
QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_TRUE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_TRUE);
|
||||
QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount);
|
||||
|
||||
// Finally, make sure QGLContext::deleteTexture deletes the texture IDs:
|
||||
ctx->deleteTexture(boundImageTextureId);
|
||||
ctx->deleteTexture(boundPixmapTextureId);
|
||||
QCOMPARE((bool)glIsTexture(boundImageTextureId), GL_FALSE);
|
||||
QCOMPARE((bool)glIsTexture(boundPixmapTextureId), GL_FALSE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundImageTextureId), GL_FALSE);
|
||||
QCOMPARE((bool)funcs->glIsTexture(boundPixmapTextureId), GL_FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -62,7 +62,7 @@ bool tst_QGLFunctions::hasExtension(const char *name)
|
||||
{
|
||||
QString extensions =
|
||||
QString::fromLatin1
|
||||
(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)));
|
||||
(reinterpret_cast<const char *>(QOpenGLContext::currentContext()->functions()->glGetString(GL_EXTENSIONS)));
|
||||
return extensions.split(QLatin1Char(' ')).contains
|
||||
(QString::fromLatin1(name));
|
||||
}
|
||||
@ -194,46 +194,46 @@ void tst_QGLFunctions::features()
|
||||
// Verify that the multitexture functions appear to resolve and work.
|
||||
void tst_QGLFunctions::multitexture()
|
||||
{
|
||||
QGLFunctions funcs;
|
||||
QOpenGLFunctions funcs;
|
||||
QGLWidget glw;
|
||||
if (!glw.isValid())
|
||||
QSKIP("Could not create a GL context");
|
||||
glw.makeCurrent();
|
||||
funcs.initializeGLFunctions();
|
||||
funcs.initializeOpenGLFunctions();
|
||||
|
||||
if (!funcs.hasOpenGLFeature(QGLFunctions::Multitexture))
|
||||
if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Multitexture))
|
||||
QSKIP("Multitexture functions are not supported");
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE1);
|
||||
|
||||
GLint active = 0;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &active);
|
||||
funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active);
|
||||
QVERIFY(active == GL_TEXTURE1);
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
active = 0;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &active);
|
||||
funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active);
|
||||
QVERIFY(active == GL_TEXTURE0);
|
||||
}
|
||||
|
||||
// Verify that the glBlendColor() function appears to resolve and work.
|
||||
void tst_QGLFunctions::blendColor()
|
||||
{
|
||||
QGLFunctions funcs;
|
||||
QOpenGLFunctions funcs;
|
||||
QGLWidget glw;
|
||||
if (!glw.isValid())
|
||||
QSKIP("Could not create a GL context");
|
||||
glw.makeCurrent();
|
||||
funcs.initializeGLFunctions();
|
||||
funcs.initializeOpenGLFunctions();
|
||||
|
||||
if (!funcs.hasOpenGLFeature(QGLFunctions::BlendColor))
|
||||
if (!funcs.hasOpenGLFeature(QOpenGLFunctions::BlendColor))
|
||||
QSKIP("glBlendColor() is not supported");
|
||||
|
||||
funcs.glBlendColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
GLfloat colors[4] = {0.5f, 0.5f, 0.5f, 0.5f};
|
||||
glGetFloatv(GL_BLEND_COLOR, colors);
|
||||
funcs.glGetFloatv(GL_BLEND_COLOR, colors);
|
||||
|
||||
QCOMPARE(colors[0], 0.0f);
|
||||
QCOMPARE(colors[1], 1.0f);
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include <QtOpenGL/QtOpenGL>
|
||||
#include "tst_qglthreads.h"
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
#include <QtGui/QOpenGLFunctions_1_0>
|
||||
#endif
|
||||
|
||||
#define RUNNING_TIME 5000
|
||||
|
||||
tst_QGLThreads::tst_QGLThreads(QObject *parent)
|
||||
@ -339,8 +343,9 @@ static inline float qrandom() { return (rand() % 100) / 100.f; }
|
||||
|
||||
void renderAScene(int w, int h)
|
||||
{
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
|
||||
if (QOpenGLContext::currentContext()->isES()) {
|
||||
QGLFunctions funcs(QGLContext::currentContext());
|
||||
Q_UNUSED(w);
|
||||
Q_UNUSED(h);
|
||||
QGLShaderProgram program;
|
||||
@ -349,7 +354,7 @@ void renderAScene(int w, int h)
|
||||
program.bindAttributeLocation("pos", 0);
|
||||
program.bind();
|
||||
|
||||
funcs.glEnableVertexAttribArray(0);
|
||||
funcs->glEnableVertexAttribArray(0);
|
||||
|
||||
for (int i=0; i<1000; ++i) {
|
||||
GLfloat pos[] = {
|
||||
@ -361,30 +366,33 @@ void renderAScene(int w, int h)
|
||||
(rand() % 100) / 100.f
|
||||
};
|
||||
|
||||
funcs.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
|
||||
funcs->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
|
||||
funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
|
||||
}
|
||||
} else {
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
glViewport(0, 0, w, h);
|
||||
QOpenGLFunctions_1_0 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_0>();
|
||||
gl1funcs->initializeOpenGLFunctions();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(0, w, h, 0, 1, 100);
|
||||
glTranslated(0, 0, -1);
|
||||
gl1funcs->glViewport(0, 0, w, h);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gl1funcs->glMatrixMode(GL_PROJECTION);
|
||||
gl1funcs->glLoadIdentity();
|
||||
gl1funcs->glFrustum(0, w, h, 0, 1, 100);
|
||||
gl1funcs->glTranslated(0, 0, -1);
|
||||
|
||||
gl1funcs->glMatrixMode(GL_MODELVIEW);
|
||||
gl1funcs->glLoadIdentity();
|
||||
|
||||
for (int i=0;i<1000; ++i) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glEnd();
|
||||
gl1funcs->glBegin(GL_TRIANGLES);
|
||||
gl1funcs->glColor3f(qrandom(), qrandom(), qrandom());
|
||||
gl1funcs->glVertex2f(qrandom() * w, qrandom() * h);
|
||||
gl1funcs->glColor3f(qrandom(), qrandom(), qrandom());
|
||||
gl1funcs->glVertex2f(qrandom() * w, qrandom() * h);
|
||||
gl1funcs->glColor3f(qrandom(), qrandom(), qrandom());
|
||||
gl1funcs->glVertex2f(qrandom() * w, qrandom() * h);
|
||||
gl1funcs->glEnd();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -434,8 +442,9 @@ public:
|
||||
QSize s = m_widget->newSize;
|
||||
m_widget->mutex.unlock();
|
||||
|
||||
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
|
||||
if (s != m_size) {
|
||||
glViewport(0, 0, s.width(), s.height());
|
||||
funcs->glViewport(0, 0, s.width(), s.height());
|
||||
}
|
||||
|
||||
if (QGLContext::currentContext() != m_widget->context()) {
|
||||
@ -443,7 +452,7 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
funcs->glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
int w = m_widget->width();
|
||||
int h = m_widget->height();
|
||||
@ -451,7 +460,7 @@ public:
|
||||
renderAScene(w, h);
|
||||
|
||||
int color;
|
||||
glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
||||
funcs->glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
||||
|
||||
m_widget->swapBuffers();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user