73 void getSetCheck(); |
73 void getSetCheck(); |
74 void openGLVersionCheck(); |
74 void openGLVersionCheck(); |
75 void graphicsViewClipping(); |
75 void graphicsViewClipping(); |
76 void partialGLWidgetUpdates_data(); |
76 void partialGLWidgetUpdates_data(); |
77 void partialGLWidgetUpdates(); |
77 void partialGLWidgetUpdates(); |
|
78 void glWidgetWithAlpha(); |
78 void glWidgetRendering(); |
79 void glWidgetRendering(); |
|
80 void glFBOSimpleRendering(); |
79 void glFBORendering(); |
81 void glFBORendering(); |
80 void multipleFBOInterleavedRendering(); |
82 void multipleFBOInterleavedRendering(); |
81 void glFBOUseInGLWidget(); |
83 void glFBOUseInGLWidget(); |
82 void glPBufferRendering(); |
84 void glPBufferRendering(); |
83 void glWidgetReparent(); |
85 void glWidgetReparent(); |
84 void glWidgetRenderPixmap(); |
86 void glWidgetRenderPixmap(); |
85 void stackedFBOs(); |
|
86 void colormap(); |
87 void colormap(); |
87 void fboFormat(); |
88 void fboFormat(); |
88 void testDontCrashOnDanglingResources(); |
89 void testDontCrashOnDanglingResources(); |
89 void replaceClipping(); |
90 void replaceClipping(); |
90 void clipTest(); |
91 void clipTest(); |
239 obj1.setStencilBufferSize(TEST_INT_MAX); |
250 obj1.setStencilBufferSize(TEST_INT_MAX); |
240 QCOMPARE(TEST_INT_MAX, obj1.stencilBufferSize()); |
251 QCOMPARE(TEST_INT_MAX, obj1.stencilBufferSize()); |
241 |
252 |
242 // bool QGLFormat::sampleBuffers() |
253 // bool QGLFormat::sampleBuffers() |
243 // void QGLFormat::setSampleBuffers(bool) |
254 // void QGLFormat::setSampleBuffers(bool) |
244 #if !defined(QT_OPENGL_ES_2) |
|
245 QCOMPARE(false, obj1.sampleBuffers()); |
255 QCOMPARE(false, obj1.sampleBuffers()); |
246 QVERIFY(!obj1.testOption(QGL::SampleBuffers)); |
256 QVERIFY(!obj1.testOption(QGL::SampleBuffers)); |
247 QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); |
257 QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); |
248 #else |
258 |
249 QCOMPARE(true, obj1.sampleBuffers()); |
|
250 QVERIFY(obj1.testOption(QGL::SampleBuffers)); |
|
251 QVERIFY(!obj1.testOption(QGL::NoSampleBuffers)); |
|
252 #endif |
|
253 obj1.setSampleBuffers(false); |
259 obj1.setSampleBuffers(false); |
254 QCOMPARE(false, obj1.sampleBuffers()); |
260 QCOMPARE(false, obj1.sampleBuffers()); |
255 QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); |
261 QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); |
256 obj1.setSampleBuffers(true); |
262 obj1.setSampleBuffers(true); |
257 QCOMPARE(true, obj1.sampleBuffers()); |
263 QCOMPARE(true, obj1.sampleBuffers()); |
700 QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); |
706 QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); |
701 #endif //defined(QT_OPENGL_ES_1) |
707 #endif //defined(QT_OPENGL_ES_1) |
702 #endif //QT_BUILD_INTERNAL |
708 #endif //QT_BUILD_INTERNAL |
703 } |
709 } |
704 |
710 |
|
711 static bool fuzzyComparePixels(const QRgb testPixel, const QRgb refPixel, const char* file, int line, int x = -1, int y = -1) |
|
712 { |
|
713 static int maxFuzz = 1; |
|
714 static bool maxFuzzSet = false; |
|
715 |
|
716 // On 16 bpp systems, we need to allow for more fuzz: |
|
717 if (!maxFuzzSet) { |
|
718 maxFuzzSet = true; |
|
719 if (appDefaultDepth() < 24) |
|
720 maxFuzz = 32; |
|
721 } |
|
722 |
|
723 int redFuzz = qAbs(qRed(testPixel) - qRed(refPixel)); |
|
724 int greenFuzz = qAbs(qGreen(testPixel) - qGreen(refPixel)); |
|
725 int blueFuzz = qAbs(qBlue(testPixel) - qBlue(refPixel)); |
|
726 int alphaFuzz = qAbs(qAlpha(testPixel) - qAlpha(refPixel)); |
|
727 |
|
728 if (refPixel != 0 && testPixel == 0) { |
|
729 QString msg; |
|
730 if (x >= 0) { |
|
731 msg = QString("Test pixel [%1, %2] is null (black) when it should be (%3,%4,%5,%6)") |
|
732 .arg(x).arg(y) |
|
733 .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); |
|
734 } else { |
|
735 msg = QString("Test pixel is null (black) when it should be (%2,%3,%4,%5)") |
|
736 .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); |
|
737 } |
|
738 |
|
739 QTest::qFail(msg.toLatin1(), file, line); |
|
740 return false; |
|
741 } |
|
742 |
|
743 if (redFuzz > maxFuzz || greenFuzz > maxFuzz || blueFuzz > maxFuzz || alphaFuzz > maxFuzz) { |
|
744 QString msg; |
|
745 |
|
746 if (x >= 0) |
|
747 msg = QString("Pixel [%1,%2]: ").arg(x).arg(y); |
|
748 else |
|
749 msg = QString("Pixel "); |
|
750 |
|
751 msg += QString("Max fuzz (%1) exceeded: (%2,%3,%4,%5) vs (%6,%7,%8,%9)") |
|
752 .arg(maxFuzz) |
|
753 .arg(qRed(testPixel)).arg(qGreen(testPixel)).arg(qBlue(testPixel)).arg(qAlpha(testPixel)) |
|
754 .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); |
|
755 QTest::qFail(msg.toLatin1(), file, line); |
|
756 return false; |
|
757 } |
|
758 return true; |
|
759 } |
|
760 |
|
761 static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceImage, const char* file, int line) |
|
762 { |
|
763 QCOMPARE(testImage.width(), referenceImage.width()); |
|
764 QCOMPARE(testImage.height(), referenceImage.height()); |
|
765 |
|
766 for (int y = 0; y < testImage.height(); y++) { |
|
767 for (int x = 0; x < testImage.width(); x++) { |
|
768 if (!fuzzyComparePixels(testImage.pixel(x, y), referenceImage.pixel(x, y), file, line, x, y)) { |
|
769 // Might as well save the images for easier debugging: |
|
770 referenceImage.save("referenceImage.png"); |
|
771 testImage.save("testImage.png"); |
|
772 return; |
|
773 } |
|
774 } |
|
775 } |
|
776 } |
|
777 |
|
778 #define QFUZZY_COMPARE_IMAGES(A,B) \ |
|
779 fuzzyCompareImages(A, B, __FILE__, __LINE__) |
|
780 |
|
781 #define QFUZZY_COMPARE_PIXELS(A,B) \ |
|
782 fuzzyComparePixels(A, B, __FILE__, __LINE__) |
|
783 |
705 class UnclippedWidget : public QWidget |
784 class UnclippedWidget : public QWidget |
706 { |
785 { |
707 public: |
786 public: |
708 void paintEvent(QPaintEvent *) |
787 void paintEvent(QPaintEvent *) |
709 { |
788 { |
855 QPaintEngine* pe = p.paintEngine(); |
948 QPaintEngine* pe = p.paintEngine(); |
856 engineType = pe->type(); |
949 engineType = pe->type(); |
857 |
950 |
858 // This test only ensures it's possible to paint onto a QGLWidget. Full |
951 // This test only ensures it's possible to paint onto a QGLWidget. Full |
859 // paint engine feature testing is way out of scope! |
952 // paint engine feature testing is way out of scope! |
860 |
953 p.fillRect(-1, -1, width()+2, height()+2, Qt::red); |
861 p.fillRect(0, 0, width(), height(), Qt::red); |
954 |
862 // No p.end() or swap buffers, should be done automatically |
955 // No p.end() or swap buffers, should be done automatically |
863 } |
956 } |
864 |
957 |
865 }; |
958 }; |
866 |
959 |
867 void tst_QGL::glWidgetRendering() |
960 void tst_QGL::glWidgetRendering() |
868 { |
961 { |
869 GLWidget w; |
962 GLWidget w; |
|
963 #ifdef Q_WS_QWS |
|
964 w.setWindowFlags(Qt::FramelessWindowHint); |
|
965 #endif |
|
966 w.setGeometry(100, 100, 200, 200); |
870 w.show(); |
967 w.show(); |
871 |
968 |
872 #ifdef Q_WS_X11 |
969 #ifdef Q_WS_X11 |
873 qt_x11_wait_for_window_manager(&w); |
970 qt_x11_wait_for_window_manager(&w); |
874 #endif |
971 #endif |
879 |
976 |
880 QImage fb = w.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); |
977 QImage fb = w.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); |
881 QImage reference(fb.size(), QImage::Format_RGB32); |
978 QImage reference(fb.size(), QImage::Format_RGB32); |
882 reference.fill(0xffff0000); |
979 reference.fill(0xffff0000); |
883 |
980 |
884 QCOMPARE(fb, reference); |
981 QFUZZY_COMPARE_IMAGES(fb, reference); |
|
982 } |
|
983 |
|
984 void tst_QGL::glFBOSimpleRendering() |
|
985 { |
|
986 if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) |
|
987 QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle); |
|
988 |
|
989 QGLWidget glw; |
|
990 glw.makeCurrent(); |
|
991 |
|
992 // No multisample with combined depth/stencil attachment: |
|
993 QGLFramebufferObjectFormat fboFormat; |
|
994 fboFormat.setAttachment(QGLFramebufferObject::NoAttachment); |
|
995 |
|
996 // Don't complicate things by using NPOT: |
|
997 QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat); |
|
998 |
|
999 fbo->bind(); |
|
1000 |
|
1001 glClearColor(1.0, 0.0, 0.0, 1.0); |
|
1002 glClear(GL_COLOR_BUFFER_BIT); |
|
1003 glFinish(); |
|
1004 |
|
1005 QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); |
|
1006 QImage reference(fb.size(), QImage::Format_RGB32); |
|
1007 reference.fill(0xffff0000); |
|
1008 |
|
1009 QFUZZY_COMPARE_IMAGES(fb, reference); |
|
1010 |
|
1011 delete fbo; |
885 } |
1012 } |
886 |
1013 |
887 // NOTE: This tests that CombinedDepthStencil attachment works by assuming the |
1014 // NOTE: This tests that CombinedDepthStencil attachment works by assuming the |
888 // GL2 engine is being used and is implemented the same way as it was when |
1015 // GL2 engine is being used and is implemented the same way as it was when |
889 // this autotest was written. If this is not the case, there may be some |
1016 // this autotest was written. If this is not the case, there may be some |
934 delete fbo; |
1061 delete fbo; |
935 |
1062 |
936 // As we're doing more than trivial painting, we can't just compare to |
1063 // As we're doing more than trivial painting, we can't just compare to |
937 // an image rendered with raster. Instead, we sample at well-defined |
1064 // an image rendered with raster. Instead, we sample at well-defined |
938 // test-points: |
1065 // test-points: |
939 QCOMPARE(fb.pixel(39, 64), QColor(Qt::red).rgb()); |
1066 QFUZZY_COMPARE_PIXELS(fb.pixel(39, 64), QColor(Qt::red).rgb()); |
940 QCOMPARE(fb.pixel(89, 64), QColor(Qt::red).rgb()); |
1067 QFUZZY_COMPARE_PIXELS(fb.pixel(89, 64), QColor(Qt::red).rgb()); |
941 QCOMPARE(fb.pixel(64, 39), QColor(Qt::blue).rgb()); |
1068 QFUZZY_COMPARE_PIXELS(fb.pixel(64, 39), QColor(Qt::blue).rgb()); |
942 QCOMPARE(fb.pixel(64, 89), QColor(Qt::blue).rgb()); |
1069 QFUZZY_COMPARE_PIXELS(fb.pixel(64, 89), QColor(Qt::blue).rgb()); |
943 |
1070 |
944 QCOMPARE(fb.pixel(167, 39), QColor(Qt::red).rgb()); |
1071 QFUZZY_COMPARE_PIXELS(fb.pixel(167, 39), QColor(Qt::red).rgb()); |
945 QCOMPARE(fb.pixel(217, 39), QColor(Qt::red).rgb()); |
1072 QFUZZY_COMPARE_PIXELS(fb.pixel(217, 39), QColor(Qt::red).rgb()); |
946 QCOMPARE(fb.pixel(192, 64), QColor(Qt::green).rgb()); |
1073 QFUZZY_COMPARE_PIXELS(fb.pixel(192, 64), QColor(Qt::green).rgb()); |
947 } |
1074 } |
948 |
1075 |
949 |
1076 |
950 // Tests multiple QPainters active on different FBOs at the same time, with |
1077 // Tests multiple QPainters active on different FBOs at the same time, with |
951 // interleaving painting. Performance-wise, this is sub-optimal, but it still |
1078 // interleaving painting. Performance-wise, this is sub-optimal, but it still |
1032 delete fbo3; |
1159 delete fbo3; |
1033 |
1160 |
1034 // As we're doing more than trivial painting, we can't just compare to |
1161 // As we're doing more than trivial painting, we can't just compare to |
1035 // an image rendered with raster. Instead, we sample at well-defined |
1162 // an image rendered with raster. Instead, we sample at well-defined |
1036 // test-points: |
1163 // test-points: |
1037 QCOMPARE(fb1.pixel(39, 64), QColor(Qt::red).rgb()); |
1164 QFUZZY_COMPARE_PIXELS(fb1.pixel(39, 64), QColor(Qt::red).rgb()); |
1038 QCOMPARE(fb1.pixel(89, 64), QColor(Qt::red).rgb()); |
1165 QFUZZY_COMPARE_PIXELS(fb1.pixel(89, 64), QColor(Qt::red).rgb()); |
1039 QCOMPARE(fb1.pixel(64, 39), QColor(Qt::blue).rgb()); |
1166 QFUZZY_COMPARE_PIXELS(fb1.pixel(64, 39), QColor(Qt::blue).rgb()); |
1040 QCOMPARE(fb1.pixel(64, 89), QColor(Qt::blue).rgb()); |
1167 QFUZZY_COMPARE_PIXELS(fb1.pixel(64, 89), QColor(Qt::blue).rgb()); |
1041 QCOMPARE(fb1.pixel(167, 39), QColor(Qt::red).rgb()); |
1168 QFUZZY_COMPARE_PIXELS(fb1.pixel(167, 39), QColor(Qt::red).rgb()); |
1042 QCOMPARE(fb1.pixel(217, 39), QColor(Qt::red).rgb()); |
1169 QFUZZY_COMPARE_PIXELS(fb1.pixel(217, 39), QColor(Qt::red).rgb()); |
1043 QCOMPARE(fb1.pixel(192, 64), QColor(Qt::green).rgb()); |
1170 QFUZZY_COMPARE_PIXELS(fb1.pixel(192, 64), QColor(Qt::green).rgb()); |
1044 |
1171 |
1045 QCOMPARE(fb2.pixel(39, 64), QColor(Qt::green).rgb()); |
1172 QFUZZY_COMPARE_PIXELS(fb2.pixel(39, 64), QColor(Qt::green).rgb()); |
1046 QCOMPARE(fb2.pixel(89, 64), QColor(Qt::green).rgb()); |
1173 QFUZZY_COMPARE_PIXELS(fb2.pixel(89, 64), QColor(Qt::green).rgb()); |
1047 QCOMPARE(fb2.pixel(64, 39), QColor(Qt::red).rgb()); |
1174 QFUZZY_COMPARE_PIXELS(fb2.pixel(64, 39), QColor(Qt::red).rgb()); |
1048 QCOMPARE(fb2.pixel(64, 89), QColor(Qt::red).rgb()); |
1175 QFUZZY_COMPARE_PIXELS(fb2.pixel(64, 89), QColor(Qt::red).rgb()); |
1049 QCOMPARE(fb2.pixel(167, 39), QColor(Qt::green).rgb()); |
1176 QFUZZY_COMPARE_PIXELS(fb2.pixel(167, 39), QColor(Qt::green).rgb()); |
1050 QCOMPARE(fb2.pixel(217, 39), QColor(Qt::green).rgb()); |
1177 QFUZZY_COMPARE_PIXELS(fb2.pixel(217, 39), QColor(Qt::green).rgb()); |
1051 QCOMPARE(fb2.pixel(192, 64), QColor(Qt::blue).rgb()); |
1178 QFUZZY_COMPARE_PIXELS(fb2.pixel(192, 64), QColor(Qt::blue).rgb()); |
1052 |
1179 |
1053 QCOMPARE(fb3.pixel(39, 64), QColor(Qt::blue).rgb()); |
1180 QFUZZY_COMPARE_PIXELS(fb3.pixel(39, 64), QColor(Qt::blue).rgb()); |
1054 QCOMPARE(fb3.pixel(89, 64), QColor(Qt::blue).rgb()); |
1181 QFUZZY_COMPARE_PIXELS(fb3.pixel(89, 64), QColor(Qt::blue).rgb()); |
1055 QCOMPARE(fb3.pixel(64, 39), QColor(Qt::green).rgb()); |
1182 QFUZZY_COMPARE_PIXELS(fb3.pixel(64, 39), QColor(Qt::green).rgb()); |
1056 QCOMPARE(fb3.pixel(64, 89), QColor(Qt::green).rgb()); |
1183 QFUZZY_COMPARE_PIXELS(fb3.pixel(64, 89), QColor(Qt::green).rgb()); |
1057 QCOMPARE(fb3.pixel(167, 39), QColor(Qt::blue).rgb()); |
1184 QFUZZY_COMPARE_PIXELS(fb3.pixel(167, 39), QColor(Qt::blue).rgb()); |
1058 QCOMPARE(fb3.pixel(217, 39), QColor(Qt::blue).rgb()); |
1185 QFUZZY_COMPARE_PIXELS(fb3.pixel(217, 39), QColor(Qt::blue).rgb()); |
1059 QCOMPARE(fb3.pixel(192, 64), QColor(Qt::red).rgb()); |
1186 QFUZZY_COMPARE_PIXELS(fb3.pixel(192, 64), QColor(Qt::red).rgb()); |
1060 } |
1187 } |
1061 |
1188 |
1062 class FBOUseInGLWidget : public QGLWidget |
1189 class FBOUseInGLWidget : public QGLWidget |
1063 { |
1190 { |
1064 public: |
1191 public: |
1105 QVERIFY(w.fboPainterBeginOk); |
1235 QVERIFY(w.fboPainterBeginOk); |
1106 |
1236 |
1107 QImage widgetFB = w.grabFrameBuffer(false); |
1237 QImage widgetFB = w.grabFrameBuffer(false); |
1108 QImage widgetReference(widgetFB.size(), widgetFB.format()); |
1238 QImage widgetReference(widgetFB.size(), widgetFB.format()); |
1109 widgetReference.fill(0xff0000ff); |
1239 widgetReference.fill(0xff0000ff); |
1110 QCOMPARE(widgetFB, widgetReference); |
1240 QFUZZY_COMPARE_IMAGES(widgetFB, widgetReference); |
1111 |
1241 |
1112 QImage fboReference(w.fboImage.size(), w.fboImage.format()); |
1242 QImage fboReference(w.fboImage.size(), w.fboImage.format()); |
1113 fboReference.fill(0xffff0000); |
1243 fboReference.fill(0xffff0000); |
1114 QCOMPARE(w.fboImage, fboReference); |
1244 QFUZZY_COMPARE_IMAGES(w.fboImage, fboReference); |
1115 } |
1245 } |
1116 |
1246 |
1117 void tst_QGL::glWidgetReparent() |
1247 void tst_QGL::glWidgetReparent() |
1118 { |
1248 { |
1119 // Try it as a top-level first: |
1249 // Try it as a top-level first: |
1203 |
1333 |
1204 QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32); |
1334 QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32); |
1205 QImage reference(fb.size(), QImage::Format_RGB32); |
1335 QImage reference(fb.size(), QImage::Format_RGB32); |
1206 reference.fill(0xffff0000); |
1336 reference.fill(0xffff0000); |
1207 |
1337 |
1208 QCOMPARE(fb, reference); |
1338 QFUZZY_COMPARE_IMAGES(fb, reference); |
1209 } |
1339 } |
1210 |
|
1211 |
|
1212 // When using multiple FBOs at the same time, unbinding one FBO should re-bind the |
|
1213 // previous. I.e. It should be possible to have a stack of FBOs where pop'ing there |
|
1214 // top re-binds the one underneeth. |
|
1215 void tst_QGL::stackedFBOs() |
|
1216 { |
|
1217 if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) |
|
1218 QSKIP("QGLFramebufferObject not supported on this platform", SkipSingle); |
|
1219 |
|
1220 QGLWidget glw; |
|
1221 glw.show(); |
|
1222 |
|
1223 #ifdef Q_WS_X11 |
|
1224 qt_x11_wait_for_window_manager(&glw); |
|
1225 #endif |
|
1226 QTest::qWait(200); |
|
1227 |
|
1228 glw.makeCurrent(); |
|
1229 |
|
1230 // No multisample with combined depth/stencil attachment: |
|
1231 QGLFramebufferObjectFormat fboFormat; |
|
1232 fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); |
|
1233 |
|
1234 // Don't complicate things by using NPOT: |
|
1235 QGLFramebufferObject *fbo1 = new QGLFramebufferObject(128, 128, fboFormat); |
|
1236 QGLFramebufferObject *fbo2 = new QGLFramebufferObject(128, 128, fboFormat); |
|
1237 QGLFramebufferObject *fbo3 = new QGLFramebufferObject(128, 128, fboFormat); |
|
1238 |
|
1239 glClearColor(1.0, 0.0, 1.0, 1.0); |
|
1240 glClear(GL_COLOR_BUFFER_BIT); |
|
1241 |
|
1242 fbo1->bind(); |
|
1243 glClearColor(1.0, 0.0, 0.0, 1.0); |
|
1244 glClear(GL_COLOR_BUFFER_BIT); |
|
1245 |
|
1246 fbo2->bind(); |
|
1247 glClearColor(0.0, 1.0, 0.0, 1.0); |
|
1248 glClear(GL_COLOR_BUFFER_BIT); |
|
1249 |
|
1250 fbo3->bind(); |
|
1251 glClearColor(0.0, 0.0, 1.0, 1.0); |
|
1252 glClear(GL_COLOR_BUFFER_BIT); |
|
1253 glScissor(32, 32, 64, 64); |
|
1254 glEnable(GL_SCISSOR_TEST); |
|
1255 glClearColor(0.0, 1.0, 1.0, 1.0); |
|
1256 glClear(GL_COLOR_BUFFER_BIT); |
|
1257 fbo3->release(); |
|
1258 |
|
1259 // Scissor rect & test should be left untouched by the fbo release... |
|
1260 glClearColor(0.0, 0.0, 0.0, 1.0); |
|
1261 glClear(GL_COLOR_BUFFER_BIT); |
|
1262 fbo2->release(); |
|
1263 |
|
1264 glClearColor(1.0, 1.0, 1.0, 1.0); |
|
1265 glClear(GL_COLOR_BUFFER_BIT); |
|
1266 fbo1->release(); |
|
1267 |
|
1268 glClearColor(1.0, 1.0, 0.0, 1.0); |
|
1269 glClear(GL_COLOR_BUFFER_BIT); |
|
1270 |
|
1271 glw.swapBuffers(); |
|
1272 |
|
1273 QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); |
|
1274 QImage fb1 = fbo1->toImage().convertToFormat(QImage::Format_RGB32); |
|
1275 QImage fb2 = fbo2->toImage().convertToFormat(QImage::Format_RGB32); |
|
1276 QImage fb3 = fbo3->toImage().convertToFormat(QImage::Format_RGB32); |
|
1277 |
|
1278 delete fbo1; |
|
1279 delete fbo2; |
|
1280 delete fbo3; |
|
1281 |
|
1282 QImage widgetReference(widgetFB.size(), widgetFB.format()); |
|
1283 QImage fb1Reference(fb1.size(), fb1.format()); |
|
1284 QImage fb2Reference(fb2.size(), fb2.format()); |
|
1285 QImage fb3Reference(fb3.size(), fb3.format()); |
|
1286 |
|
1287 QPainter widgetReferencePainter(&widgetReference); |
|
1288 QPainter fb1ReferencePainter(&fb1Reference); |
|
1289 QPainter fb2ReferencePainter(&fb2Reference); |
|
1290 QPainter fb3ReferencePainter(&fb3Reference); |
|
1291 |
|
1292 widgetReferencePainter.fillRect(0, 0, widgetReference.width(), widgetReference.height(), Qt::magenta); |
|
1293 fb1ReferencePainter.fillRect(0, 0, fb1Reference.width(), fb1Reference.height(), Qt::red); |
|
1294 fb2ReferencePainter.fillRect(0, 0, fb2Reference.width(), fb2Reference.height(), Qt::green); |
|
1295 fb3ReferencePainter.fillRect(0, 0, fb3Reference.width(), fb3Reference.height(), Qt::blue); |
|
1296 |
|
1297 // Flip y-coords to match GL for the widget (which can be any size) |
|
1298 widgetReferencePainter.fillRect(32, glw.height() - 96, 64, 64, Qt::yellow); |
|
1299 fb1ReferencePainter.fillRect(32, 32, 64, 64, Qt::white); |
|
1300 fb2ReferencePainter.fillRect(32, 32, 64, 64, Qt::black); |
|
1301 fb3ReferencePainter.fillRect(32, 32, 64, 64, Qt::cyan); |
|
1302 |
|
1303 widgetReferencePainter.end(); |
|
1304 fb1ReferencePainter.end(); |
|
1305 fb2ReferencePainter.end(); |
|
1306 fb3ReferencePainter.end(); |
|
1307 |
|
1308 QCOMPARE(widgetFB, widgetReference); |
|
1309 QCOMPARE(fb1, fb1Reference); |
|
1310 QCOMPARE(fb2, fb2Reference); |
|
1311 QCOMPARE(fb3, fb3Reference); |
|
1312 } |
|
1313 |
|
1314 |
1340 |
1315 class ColormapExtended : public QGLColormap |
1341 class ColormapExtended : public QGLColormap |
1316 { |
1342 { |
1317 public: |
1343 public: |
1318 ColormapExtended() {} |
1344 ColormapExtended() {} |
1596 glw.paint(&referencePainter); |
1625 glw.paint(&referencePainter); |
1597 referencePainter.end(); |
1626 referencePainter.end(); |
1598 |
1627 |
1599 const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); |
1628 const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); |
1600 |
1629 |
1601 QCOMPARE(widgetFB, reference); |
1630 // Sample pixels in a grid pattern which avoids false failures due to |
|
1631 // off-by-one pixel errors on some buggy GL implementations |
|
1632 for (int x = 25; x < reference.width(); x += 50) { |
|
1633 for (int y = 25; y < reference.width(); y += 50) { |
|
1634 QFUZZY_COMPARE_PIXELS(widgetFB.pixel(x, y), reference.pixel(x, y)); |
|
1635 } |
|
1636 } |
1602 } |
1637 } |
1603 |
1638 |
1604 class ClipTestGLWidget : public QGLWidget |
1639 class ClipTestGLWidget : public QGLWidget |
1605 { |
1640 { |
1606 public: |
1641 public: |
1607 void paint(QPainter *painter) |
1642 void paint(QPainter *painter) |
1608 { |
1643 { |
1609 painter->fillRect(rect(), Qt::white); |
1644 painter->fillRect(-1, -1, width()+2, height()+2, Qt::white); |
1610 painter->setClipRect(10, 10, width()-20, height()-20); |
1645 painter->setClipRect(10, 10, width()-20, height()-20); |
1611 painter->fillRect(rect(), Qt::cyan); |
1646 painter->fillRect(rect(), Qt::cyan); |
1612 |
1647 |
1613 painter->save(); |
1648 painter->save(); |
1614 painter->setClipRect(10, 10, 100, 100, Qt::IntersectClip); |
1649 painter->setClipRect(10, 10, 100, 100, Qt::IntersectClip); |
1803 QVERIFY(!qt_shared_test()->value(glw1->context())); |
1847 QVERIFY(!qt_shared_test()->value(glw1->context())); |
1804 qt_shared_test()->insert(glw1->context(), res1); |
1848 qt_shared_test()->insert(glw1->context(), res1); |
1805 QVERIFY(qt_shared_test()->value(glw1->context()) == res1); |
1849 QVERIFY(qt_shared_test()->value(glw1->context()) == res1); |
1806 |
1850 |
1807 // Create another context that shares with the first. |
1851 // Create another context that shares with the first. |
|
1852 QVERIFY(!glw1->isSharing()); |
1808 QGLWidget *glw2 = new QGLWidget(0, glw1); |
1853 QGLWidget *glw2 = new QGLWidget(0, glw1); |
1809 if (!glw2->isSharing()) { |
1854 if (!glw2->isSharing()) { |
1810 delete glw2; |
1855 delete glw2; |
1811 delete glw1; |
1856 delete glw1; |
1812 QSKIP("Context sharing is not supported", SkipSingle); |
1857 QSKIP("Context sharing is not supported", SkipSingle); |
1813 } |
1858 } |
|
1859 QVERIFY(glw1->isSharing()); |
1814 QVERIFY(glw1->context() != glw2->context()); |
1860 QVERIFY(glw1->context() != glw2->context()); |
1815 |
1861 |
1816 // Check that the first context's resource is also on the second. |
1862 // Check that the first context's resource is also on the second. |
1817 QVERIFY(qt_shared_test()->value(glw1->context()) == res1); |
1863 QVERIFY(qt_shared_test()->value(glw1->context()) == res1); |
1818 QVERIFY(qt_shared_test()->value(glw2->context()) == res1); |
1864 QVERIFY(qt_shared_test()->value(glw2->context()) == res1); |