From 0794766644e169b2c1d1614cc2712b0d9db286b6 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 Mar 2020 23:24:20 +0100 Subject: [PATCH] Fix xray composite shader for opengl 2.1 textureSize() is not available in opengl 2.1, so we calculate the xray error image scale outside the shader (which is also a theoretical performance improvement because now the scale does not get computed over and over for each pixel) --- plugins/SolidView/SolidView.py | 16 ++++++++++++---- plugins/XRayView/XRayView.py | 9 +++++---- resources/shaders/xray_composite.shader | 8 ++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index 4db938017d..0604315f3b 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 Ultimaker B.V. +# Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os.path @@ -7,6 +7,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Selection import Selection from UM.Resources import Resources from PyQt5.QtGui import QOpenGLContext, QImage +from PyQt5.QtCore import QSize import numpy as np import time @@ -54,6 +55,7 @@ class SolidView(View): self._xray_composite_shader = None self._composite_pass = None self._xray_error_image = None + self._xray_error_image_size = QSize(1,1) self._extruders_model = None self._theme = None @@ -148,7 +150,9 @@ class SolidView(View): self._xray_error_image = OpenGL.getInstance().createTexture() texture_file = "xray_error.png" try: - self._xray_error_image.load(Resources.getPath(Resources.Images, texture_file)) + texture_image = QImage(Resources.getPath(Resources.Images, texture_file)).mirrored() + self._xray_error_image.setImage(texture_image) + self._xray_error_image_size = texture_image.size() except FileNotFoundError: Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) @@ -162,12 +166,13 @@ class SolidView(View): self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) self._xray_composite_shader.setTexture(3, self._xray_error_image) + renderer = self.getRenderer() if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings(): # Currently the RenderPass constructor requires a size > 0 # This should be fixed in RenderPass's constructor. self._xray_pass = XRayPass.XRayPass(1, 1) - self.getRenderer().addRenderPass(self._xray_pass) + renderer.addRenderPass(self._xray_pass) if not self._composite_pass: self._composite_pass = self.getRenderer().getRenderPass("composite") @@ -177,6 +182,9 @@ class SolidView(View): self._old_composite_shader = self._composite_pass.getCompositeShader() self._composite_pass.setCompositeShader(self._xray_composite_shader) + error_image_scale = [renderer.getViewportWidth() / self._xray_error_image_size.width(), renderer.getViewportHeight() / self._xray_error_image_size.height()] + self._xray_composite_shader.setUniformValue("u_xray_error_scale", error_image_scale) + def beginRendering(self): scene = self.getController().getScene() renderer = self.getRenderer() @@ -266,7 +274,7 @@ class SolidView(View): self._next_xray_checking_time = time.time() + self._xray_checking_update_time xray_img = self._xray_pass.getOutput() - xray_img = xray_img.convertToFormat(QImage.Format.Format_RGB888) + xray_img = xray_img.convertToFormat(QImage.Format_RGB888) # We can't just read the image since the pixels are aligned to internal memory positions. # xray_img.byteCount() != xray_img.width() * xray_img.height() * 3 diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py index 29fcfbca53..1b6fcca4c6 100644 --- a/plugins/XRayView/XRayView.py +++ b/plugins/XRayView/XRayView.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2020 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os.path @@ -91,16 +91,17 @@ class XRayView(CuraView): if not self._xray_error_image: self._xray_error_image = OpenGL.getInstance().createTexture() - img = QImage(1, 1, QImage.Format_RGB888) + dummy_image = QImage(1, 1, QImage.Format_RGB888) theme = Application.getInstance().getTheme() - img.setPixelColor(0, 0, theme.getColor("xray_error")) - self._xray_error_image.setImage(img) + dummy_image.setPixelColor(0, 0, theme.getColor("xray_error")) + self._xray_error_image.setImage(dummy_image) if not self._xray_composite_shader: self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "xray_composite.shader")) self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb())) self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb())) self._xray_composite_shader.setUniformValue("u_xray_error_strength", 0.8) + self._xray_composite_shader.setUniformValue("u_xray_error_scale", [1, 1]) # irrelevant, because we don't use an actual texture self._xray_composite_shader.setTexture(3, self._xray_error_image) if not self._composite_pass: diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader index 6eccc2d4e5..f71cdbf901 100644 --- a/resources/shaders/xray_composite.shader +++ b/resources/shaders/xray_composite.shader @@ -25,6 +25,7 @@ fragment = uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_xray_error; //X-ray error image. + uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -55,8 +56,7 @@ fragment = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); } vec4 sum = vec4(0.0); @@ -100,6 +100,7 @@ fragment41core = uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_xray_error; //X-ray error image. + uniform vec2 u_xray_error_scale; uniform vec2 u_offset[9]; uniform float u_outline_strength; @@ -131,8 +132,7 @@ fragment41core = float rest = mod(intersection_count + .01, 2.0); if (rest > 1.0 && rest < 1.5 && intersection_count < 49) { - vec2 scaling = textureSize(u_layer0, 0) / textureSize(u_xray_error, 0); - result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling); + result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * u_xray_error_scale); } vec4 sum = vec4(0.0);