| 2933 | } |
| 2934 | |
| 2935 | void View3DInventorViewer::imageFromFramebuffer( |
| 2936 | int width, |
| 2937 | int height, |
| 2938 | int samples, |
| 2939 | const QColor& bgcolor, |
| 2940 | QImage& img, |
| 2941 | RenderIntent intent |
| 2942 | ) |
| 2943 | { |
| 2944 | auto self = const_cast<View3DInventorViewer*>(this); // NOLINT |
| 2945 | ScopedRenderIntent scopedIntent(*self, intent); |
| 2946 | |
| 2947 | auto gl = static_cast<QOpenGLWidget*>(this->viewport()); // NOLINT |
| 2948 | gl->makeCurrent(); |
| 2949 | |
| 2950 | const QOpenGLContext* context = QOpenGLContext::currentContext(); |
| 2951 | if (!context) { |
| 2952 | Base::Console().warning("imageFromFramebuffer failed because no context is active\n"); |
| 2953 | return; |
| 2954 | } |
| 2955 | |
| 2956 | QOpenGLFramebufferObjectFormat fboFormat; |
| 2957 | fboFormat.setSamples(samples); |
| 2958 | fboFormat.setAttachment(QOpenGLFramebufferObject::Depth); |
| 2959 | // With enabled alpha a transparent background is supported but |
| 2960 | // at the same time breaks semi-transparent models. A workaround |
| 2961 | // is to use a certain background color using GL_RGB as texture |
| 2962 | // format and in the output image search for the above color and |
| 2963 | // replaces it with the color requested by the user. |
| 2964 | fboFormat.setInternalTextureFormat(getInternalTextureFormat()); |
| 2965 | |
| 2966 | QOpenGLFramebufferObject fbo(width, height, fboFormat); |
| 2967 | |
| 2968 | const QColor col = backgroundColor(); |
| 2969 | auto grad = getGradientBackground(); |
| 2970 | |
| 2971 | constexpr const int maxAlpha = 255; |
| 2972 | int alpha = maxAlpha; |
| 2973 | QColor bgopaque = bgcolor; |
| 2974 | if (bgopaque.isValid()) { |
| 2975 | // force an opaque background color |
| 2976 | alpha = bgopaque.alpha(); |
| 2977 | if (alpha < maxAlpha) { |
| 2978 | bgopaque.setRgb(maxAlpha, maxAlpha, maxAlpha); |
| 2979 | } |
| 2980 | setBackgroundColor(bgopaque); |
| 2981 | setGradientBackground(Background::NoGradient); |
| 2982 | } |
| 2983 | |
| 2984 | renderToFramebuffer(&fbo); |
| 2985 | setBackgroundColor(col); |
| 2986 | setGradientBackground(grad); |
| 2987 | img = fbo.toImage(); |
| 2988 | |
| 2989 | // if background color isn't opaque manipulate the image |
| 2990 | if (alpha < maxAlpha) { |
| 2991 | QImage image(img.constBits(), img.width(), img.height(), QImage::Format_ARGB32); |
| 2992 | img = image.copy(); |