@@ -9,83 +9,56 @@ using namespace scratchcpprender;
9
9
10
10
Skin::Skin ()
11
11
{
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
+ }
12
21
}
13
22
14
- Texture Skin::createAndPaintTexture (int width, int height, bool multisampled )
23
+ Texture Skin::createAndPaintTexture (int width, int height)
15
24
{
16
25
QOpenGLContext *context = QOpenGLContext::currentContext ();
17
26
18
27
if (!context || !context->isValid () || (width <= 0 || height <= 0 ))
19
28
return Texture ();
20
29
21
- QOpenGLFunctions glF (context);
30
+ QOpenGLExtraFunctions glF (context);
22
31
glF.initializeOpenGLFunctions ();
23
32
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);
45
35
46
- QOpenGLFramebufferObject fbo (drawRectSize, format);
47
- fbo. bind ( );
36
+ // Clear the image to be fully transparent
37
+ image. fill (Qt::transparent );
48
38
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
62
41
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
+ }
82
54
}
83
55
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 );
89
61
90
- return Texture (textureHandle, drawRectSize);
62
+ // Texture(texture, width, height).toImage().save("/home/adazem009/test.png");
63
+ return Texture (texture->textureId (), width, height);
91
64
}
0 commit comments