summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qmlrewrite.cpp4
-rw-r--r--src/opengl/qgl.cpp188
-rw-r--r--src/opengl/qglframebufferobject.cpp71
-rw-r--r--src/opengl/qglframebufferobject.h4
4 files changed, 199 insertions, 68 deletions
diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp
index 3f35160..5166c96 100644
--- a/src/declarative/qml/qmlrewrite.cpp
+++ b/src/declarative/qml/qmlrewrite.cpp
@@ -73,8 +73,8 @@ QString RewriteBinding::rewrite(QString code, unsigned position,
unsigned startOfStatement = node->firstSourceLocation().begin() - _position;
unsigned endOfStatement = node->lastSourceLocation().end() - _position;
- _writer->replace(startOfStatement, 0, QLatin1String("(function() {\n"));
- _writer->replace(endOfStatement, 0, QLatin1String("\n})"));
+ _writer->replace(startOfStatement, 0, QLatin1String("(function() { "));
+ _writer->replace(endOfStatement, 0, QLatin1String(" })"));
w.write(&code);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 9e0c5f8..087902b 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -63,6 +63,7 @@
#include "qpixmap.h"
#include "qimage.h"
+#include "qmatrix4x4.h"
#include "qgl_p.h"
#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
@@ -251,46 +252,24 @@ QGLSignalProxy *QGLSignalProxy::instance()
\sa QGLContext, QGLWidget
*/
-static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
+static inline void qgluProject
+ (qreal objx, qreal objy, qreal objz,
+ const QMatrix4x4& model, const QMatrix4x4& proj, const GLint viewport[4],
+ GLfloat *winx, GLfloat *winy, GLfloat* winz)
{
-#define M(row,col) m[col*4+row]
- out[0] =
- M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
- out[1] =
- M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
- out[2] =
- M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
- out[3] =
- M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
-#undef M
-}
-
-static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz,
- const GLdouble model[16], const GLdouble proj[16],
- const GLint viewport[4],
- GLdouble * winx, GLdouble * winy, GLdouble * winz)
-{
- GLdouble in[4], out[4];
-
- in[0] = objx;
- in[1] = objy;
- in[2] = objz;
- in[3] = 1.0;
- transform_point(out, model, in);
- transform_point(in, proj, out);
+ QVector4D transformed = proj.map(model.map(QVector4D(objx, objy, objz, 1)));
- if (in[3] == 0.0)
- return GL_FALSE;
+ qreal w = transformed.w();
+ if (w == 0.0f)
+ w = 1.0f; // Just in case!
- in[0] /= in[3];
- in[1] /= in[3];
- in[2] /= in[3];
+ qreal x = transformed.x() / w;
+ qreal y = transformed.y() / w;
- *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
- *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
+ *winx = viewport[0] + (1 + x) * viewport[2] / 2;
+ *winy = viewport[1] + (1 + y) * viewport[3] / 2;
- *winz = (1 + in[2]) / 2;
- return GL_TRUE;
+ *winz = (1 + transformed.z() / w) / 2;
}
/*!
@@ -2073,6 +2052,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
case QImage::Format_RGB16:
pixel_type = GL_UNSIGNED_SHORT_5_6_5;
texture_format = GL_RGB;
+ format = GL_RGB;
break;
case QImage::Format_RGB32:
if (format == GL_RGBA)
@@ -4113,6 +4093,30 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
p->setFont(old_font);
}
+#if defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1)
+
+// OpenGL/ES 1.0 cannot fetch viewports from the GL server.
+// We therefore create a default viewport to simulate the fetch.
+
+static void qt_gl_get_viewport(GLint *view, int deviceWidth, int deviceHeight)
+{
+ view[0] = 0;
+ view[1] = 0;
+ view[2] = deviceWidth;
+ view[3] = deviceHeight;
+}
+
+#else
+
+static void qt_gl_get_viewport(GLint *view, int deviceWidth, int deviceHeight)
+{
+ Q_UNUSED(deviceWidth);
+ Q_UNUSED(deviceHeight);
+ glGetIntegerv(GL_VIEWPORT, view);
+}
+
+#endif
+
/*!
Renders the string \a str into the GL context of this widget.
@@ -4138,13 +4142,19 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
GLint view[4];
#ifndef QT_OPENGL_ES
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
- if (!use_scissor_testing)
- glGetIntegerv(GL_VIEWPORT, &view[0]);
#else
bool use_scissor_testing = false;
#endif
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
+ if (!use_scissor_testing) {
+ qt_gl_get_viewport(&view[0], width, height);
+ } else {
+ view[0] = 0;
+ view[1] = 0;
+ view[2] = width;
+ view[3] = height;
+ }
bool auto_swap = autoBufferSwap();
QPaintEngine *engine = paintEngine();
@@ -4216,12 +4226,95 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
#endif
}
+#if defined(QT_OPENGL_ES_2) || \
+ (defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1))
+
+// OpenGL/ES 1.0 cannot fetch matrices from the GL server.
+// OpenGL/ES 2.0 does not use fixed-function matrices at all.
+// We therefore create some default matrices to simulate the fetch.
+
+static QMatrix4x4 qt_gl_projection_matrix(int deviceWidth, int deviceHeight)
+{
+ QMatrix4x4 m;
+ m.ortho(0, deviceWidth, deviceHeight, 0, -1, 1);
+ return m;
+}
+
+static QMatrix4x4 qt_gl_modelview_matrix(void)
+{
+ return QMatrix4x4();
+}
+
+#else // !QT_OPENGL_ES_2
+
+static QMatrix4x4 qt_gl_fetch_matrix(GLenum type)
+{
+ QMatrix4x4 matrix;
+#if defined(QT_OPENGL_ES_1_CL)
+ GLfixed mat[16];
+ glGetFixedv(type, mat);
+ qreal *m = matrix.data();
+ for (int index = 0; index < 16; ++index)
+ m[index] = vt2f(mat[index]);
+#else
+ if (sizeof(qreal) == sizeof(GLfloat)) {
+ glGetFloatv(type, reinterpret_cast<GLfloat *>(matrix.data()));
+#if !defined(QT_OPENGL_ES)
+ } else if (sizeof(qreal) == sizeof(GLdouble)) {
+ glGetDoublev(type, reinterpret_cast<GLdouble *>(matrix.data()));
+#endif
+ } else {
+ GLfloat mat[16];
+ glGetFloatv(type, mat);
+ qreal *m = matrix.data();
+ for (int index = 0; index < 16; ++index)
+ m[index] = mat[index];
+ }
+#endif
+ matrix.inferSpecialType();
+ return matrix;
+}
+
+static QMatrix4x4 qt_gl_projection_matrix(int deviceWidth, int deviceHeight)
+{
+ Q_UNUSED(deviceWidth);
+ Q_UNUSED(deviceHeight);
+ return qt_gl_fetch_matrix(GL_PROJECTION_MATRIX);
+}
+
+static QMatrix4x4 qt_gl_modelview_matrix(void)
+{
+ return qt_gl_fetch_matrix(GL_MODELVIEW_MATRIX);
+}
+
+#endif // !QT_OPENGL_ES_2
+
/*! \overload
\a x, \a y and \a z are specified in scene or object coordinates
relative to the currently set projection and model matrices. This
can be useful if you want to annotate models with text labels and
have the labels move with the model as it is rotated etc.
+
+ This function fetches the modelview matrix, projection matrix, and
+ current viewport from the GL server to map (\a x, \a y, \a z)
+ into window co-ordinates. This entails several round-trips to the GL
+ server which will probably impact performance.
+
+ Fetching the modelview and projection matrices is not supported
+ under OpenGL/ES 1.0 and OpenGL/ES 2.0 so a default orthographic
+ projection will be used to map the co-ordinates on those platforms.
+ This probably will not give results that are consistent with desktop
+ and OpenGL/ES 1.1 systems. Fetching the viewport is not supported
+ under OpenGL/ES 1.0, so the full device will be used as the viewport.
+
+ This function is deprecated because it is non-portable. It is
+ recommended that the application map the co-ordinates itself using
+ application-provided matrix data that reflects the desired
+ transformation. Then use QPainter::drawText() to draw \a str at
+ the mapped position.
+
+ \sa QMatrix4x4
*/
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int)
{
@@ -4233,16 +4326,15 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
- GLdouble model[4][4], proj[4][4];
+
+ QMatrix4x4 model = qt_gl_modelview_matrix();
+ QMatrix4x4 proj = qt_gl_projection_matrix(width, height);
GLint view[4];
-#ifndef QT_OPENGL_ES
- glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]);
- glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
- glGetIntegerv(GL_VIEWPORT, &view[0]);
-#endif
- GLdouble win_x = 0, win_y = 0, win_z = 0;
- qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
- &win_x, &win_y, &win_z);
+ qt_gl_get_viewport(view, width, height);
+
+ GLfloat win_x = 0, win_y = 0, win_z = 0;
+ qgluProject(qreal(x), qreal(y), qreal(z),
+ model, proj, &view[0], &win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
QPaintEngine *engine = paintEngine();
@@ -4295,11 +4387,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
glEnable(GL_ALPHA_TEST);
if (use_depth_testing)
glEnable(GL_DEPTH_TEST);
-#ifndef QT_OPENGL_ES
- glTranslated(0, 0, -win_z);
-#else
glTranslatef(0, 0, -win_z);
-#endif
#endif // !defined(QT_OPENGL_ES_2)
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index c53ed3a..452f155 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -74,9 +74,34 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
} \
}
+#ifndef QT_OPENGL_ES
+#define DEFAULT_FORMAT GL_RGBA8
+#else
+#define DEFAULT_FORMAT GL_RGBA
+#endif
+
class QGLFramebufferObjectFormatPrivate
{
public:
+ QGLFramebufferObjectFormatPrivate()
+ : ref(1),
+ samples(0),
+ attachment(QGLFramebufferObject::NoAttachment),
+ target(GL_TEXTURE_2D),
+ internal_format(DEFAULT_FORMAT)
+ {
+ }
+ QGLFramebufferObjectFormatPrivate
+ (const QGLFramebufferObjectFormatPrivate *other)
+ : ref(1),
+ samples(other->samples),
+ attachment(other->attachment),
+ target(other->target),
+ internal_format(other->internal_format)
+ {
+ }
+
+ QAtomicInt ref;
int samples;
QGLFramebufferObject::Attachment attachment;
GLenum target;
@@ -109,6 +134,20 @@ public:
*/
/*!
+ \internal
+*/
+void QGLFramebufferObjectFormat::detach()
+{
+ if (d->ref != 1) {
+ QGLFramebufferObjectFormatPrivate *newd
+ = new QGLFramebufferObjectFormatPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
Creates a QGLFramebufferObjectFormat object for specifying
the format of an OpenGL framebuffer object.
@@ -118,19 +157,9 @@ public:
\sa samples(), attachment(), target(), internalTextureFormat()
*/
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
QGLFramebufferObjectFormat::QGLFramebufferObjectFormat()
{
d = new QGLFramebufferObjectFormatPrivate;
- d->samples = 0;
- d->attachment = QGLFramebufferObject::NoAttachment;
- d->target = GL_TEXTURE_2D;
- d->internal_format = DEFAULT_FORMAT;
}
/*!
@@ -139,8 +168,8 @@ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat()
QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other)
{
- d = new QGLFramebufferObjectFormatPrivate;
- *d = *other.d;
+ d = other.d;
+ d->ref.ref();
}
/*!
@@ -149,7 +178,12 @@ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjec
QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other)
{
- *d = *other.d;
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
return *this;
}
@@ -158,7 +192,8 @@ QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFrame
*/
QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
{
- delete d;
+ if (!d->ref.deref())
+ delete d;
}
/*!
@@ -176,6 +211,7 @@ QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
*/
void QGLFramebufferObjectFormat::setSamples(int samples)
{
+ detach();
d->samples = samples;
}
@@ -197,6 +233,7 @@ int QGLFramebufferObjectFormat::samples() const
*/
void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment)
{
+ detach();
d->attachment = attachment;
}
@@ -219,6 +256,7 @@ QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const
*/
void QGLFramebufferObjectFormat::setTextureTarget(GLenum target)
{
+ detach();
d->target = target;
}
@@ -242,6 +280,7 @@ GLenum QGLFramebufferObjectFormat::textureTarget() const
*/
void QGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat)
{
+ detach();
d->internal_format = internalTextureFormat;
}
@@ -260,12 +299,14 @@ GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
/*! \internal */
void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
{
+ detach();
d->target = target;
}
/*! \internal */
void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum internalTextureFormat)
{
+ detach();
d->internal_format = internalTextureFormat;
}
#endif
@@ -871,7 +912,7 @@ QSize QGLFramebufferObject::size() const
/*!
Returns the format of this framebuffer object.
*/
-const QGLFramebufferObjectFormat &QGLFramebufferObject::format() const
+QGLFramebufferObjectFormat QGLFramebufferObject::format() const
{
Q_D(const QGLFramebufferObject);
return d->format;
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index ec1ae7d..6c1c0be 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -93,7 +93,7 @@ public:
virtual ~QGLFramebufferObject();
- const QGLFramebufferObjectFormat &format() const;
+ QGLFramebufferObjectFormat format() const;
bool isValid() const;
bool isBound() const;
@@ -161,6 +161,8 @@ public:
private:
QGLFramebufferObjectFormatPrivate *d;
+
+ void detach();
};
QT_END_NAMESPACE