@@ -9,83 +9,56 @@ using namespace scratchcpprender;
99
1010Skin::Skin ()
1111{
12+ QOpenGLContext *context = QOpenGLContext::currentContext ();
13+ Q_ASSERT (context);
14+
15+ if (context) {
16+ QObject::connect (context, &QOpenGLContext::aboutToBeDestroyed, &m_signalHandler, [this ]() {
17+ // Destroy textures
18+ m_textures.clear ();
19+ });
20+ }
1221}
1322
14- Texture Skin::createAndPaintTexture (int width, int height, bool multisampled )
23+ Texture Skin::createAndPaintTexture (int width, int height)
1524{
1625 QOpenGLContext *context = QOpenGLContext::currentContext ();
1726
1827 if (!context || !context->isValid () || (width <= 0 || height <= 0 ))
1928 return Texture ();
2029
21- QOpenGLFunctions glF (context);
30+ QOpenGLExtraFunctions glF (context);
2231 glF.initializeOpenGLFunctions ();
2332
24- // Create offscreen surface
25- QOffscreenSurface surface;
26- surface.setFormat (context->format ());
27- surface.create ();
28- Q_ASSERT (surface.isValid ());
29-
30- // Save old surface
31- QSurface *oldSurface = context->surface ();
32-
33- // Make context active on the surface
34- context->makeCurrent (&surface);
35-
36- const QRectF drawRect (0 , 0 , width, height);
37- const QSize drawRectSize = drawRect.size ().toSize ();
38-
39- // Create multisampled FBO (if the multisampled parameter is set)
40- QOpenGLFramebufferObjectFormat format;
41- format.setAttachment (QOpenGLFramebufferObject::CombinedDepthStencil);
42-
43- if (multisampled)
44- format.setSamples (16 );
33+ // Render to QImage
34+ QImage image (width, height, QImage::Format_RGBA8888);
4535
46- QOpenGLFramebufferObject fbo (drawRectSize, format);
47- fbo. bind ( );
36+ // Clear the image to be fully transparent
37+ image. fill (Qt::transparent );
4838
49- // Create paint device
50- QOpenGLPaintDevice device (drawRectSize);
51- QPainter painter (&device);
52- painter.beginNativePainting ();
53- painter.setRenderHint (QPainter::Antialiasing, false );
54- glF.glClearColor (0 .0f , 0 .0f , 0 .0f , 0 .0f );
55- glF.glClear (GL_COLOR_BUFFER_BIT);
56-
57- // Call the skin-specific paint method
58- paint (&painter);
59-
60- // Done with the painting
61- painter.endNativePainting ();
39+ QPainter painter (&image);
40+ paint (&painter); // Custom paint function
6241 painter.end ();
63- fbo.release ();
64-
65- GLuint textureHandle;
66-
67- if (multisampled) {
68- // Create non-multisampled FBO (we can't take the texture from the multisampled FBO)
69- format.setSamples (0 );
70-
71- QOpenGLFramebufferObject targetFbo (drawRectSize, format);
72- targetFbo.bind ();
73-
74- // Blit the multisampled FBO to target FBO
75- QOpenGLFramebufferObject::blitFramebuffer (&targetFbo, &fbo);
76-
77- // Take the texture (will call targetFbo.release())
78- textureHandle = targetFbo.takeTexture ();
79- } else {
80- // Take the texture
81- textureHandle = fbo.takeTexture ();
42+ image.mirror ();
43+
44+ // Premultiply alpha
45+ for (int y = 0 ; y < image.height (); ++y) {
46+ QRgb *line = reinterpret_cast <QRgb *>(image.scanLine (y));
47+ for (int x = 0 ; x < image.width (); ++x) {
48+ QColor color = QColor::fromRgba (line[x]);
49+ color.setRedF (color.redF () * color.alphaF ());
50+ color.setGreenF (color.greenF () * color.alphaF ());
51+ color.setBlueF (color.blueF () * color.alphaF ());
52+ line[x] = color.rgba ();
53+ }
8254 }
8355
84- // Restore old surface
85- context-> doneCurrent ( );
86-
87- if (oldSurface)
88- context-> makeCurrent (oldSurface );
56+ // Create final texture from the image
57+ auto texture = std::make_shared<QOpenGLTexture>(image );
58+ m_textures. push_back (texture);
59+ texture-> setMinificationFilter (QOpenGLTexture::LinearMipMapLinear);
60+ texture-> setMagnificationFilter (QOpenGLTexture::Linear );
8961
90- return Texture (textureHandle, drawRectSize);
62+ // Texture(texture, width, height).toImage().save("/home/adazem009/test.png");
63+ return Texture (texture->textureId (), width, height);
9164}
0 commit comments