Fix xray composite shader for opengl 2.1

A commit from @fieldOfView
This commit is contained in:
Tim Kuipers 2020-03-28 10:20:03 +01:00 committed by GitHub
commit 687f598d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 12 deletions

View File

@ -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. # Cura is released under the terms of the LGPLv3 or higher.
import os.path import os.path
@ -7,6 +7,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.Resources import Resources from UM.Resources import Resources
from PyQt5.QtGui import QOpenGLContext, QImage from PyQt5.QtGui import QOpenGLContext, QImage
from PyQt5.QtCore import QSize
import numpy as np import numpy as np
import time import time
@ -54,6 +55,7 @@ class SolidView(View):
self._xray_composite_shader = None self._xray_composite_shader = None
self._composite_pass = None self._composite_pass = None
self._xray_error_image = None self._xray_error_image = None
self._xray_error_image_size = QSize(1,1)
self._extruders_model = None self._extruders_model = None
self._theme = None self._theme = None
@ -148,7 +150,9 @@ class SolidView(View):
self._xray_error_image = OpenGL.getInstance().createTexture() self._xray_error_image = OpenGL.getInstance().createTexture()
texture_file = "xray_error.png" texture_file = "xray_error.png"
try: 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: except FileNotFoundError:
Logger.log("w", "Unable to find xray error texture image [%s]", texture_file) 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.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
self._xray_composite_shader.setTexture(3, self._xray_error_image) 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(): if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings():
# Currently the RenderPass constructor requires a size > 0 # Currently the RenderPass constructor requires a size > 0
# This should be fixed in RenderPass's constructor. # This should be fixed in RenderPass's constructor.
self._xray_pass = XRayPass.XRayPass(1, 1) self._xray_pass = XRayPass.XRayPass(1, 1)
self.getRenderer().addRenderPass(self._xray_pass) renderer.addRenderPass(self._xray_pass)
if not self._composite_pass: if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite") self._composite_pass = self.getRenderer().getRenderPass("composite")
@ -177,6 +182,9 @@ class SolidView(View):
self._old_composite_shader = self._composite_pass.getCompositeShader() self._old_composite_shader = self._composite_pass.getCompositeShader()
self._composite_pass.setCompositeShader(self._xray_composite_shader) 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): def beginRendering(self):
scene = self.getController().getScene() scene = self.getController().getScene()
renderer = self.getRenderer() renderer = self.getRenderer()
@ -266,7 +274,7 @@ class SolidView(View):
self._next_xray_checking_time = time.time() + self._xray_checking_update_time self._next_xray_checking_time = time.time() + self._xray_checking_update_time
xray_img = self._xray_pass.getOutput() 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. # 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 # xray_img.byteCount() != xray_img.width() * xray_img.height() * 3

View File

@ -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. # Cura is released under the terms of the LGPLv3 or higher.
import os.path import os.path
@ -91,16 +91,17 @@ class XRayView(CuraView):
if not self._xray_error_image: if not self._xray_error_image:
self._xray_error_image = OpenGL.getInstance().createTexture() 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() theme = Application.getInstance().getTheme()
img.setPixelColor(0, 0, theme.getColor("xray_error")) dummy_image.setPixelColor(0, 0, theme.getColor("xray_error"))
self._xray_error_image.setImage(img) self._xray_error_image.setImage(dummy_image)
if not self._xray_composite_shader: if not self._xray_composite_shader:
self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "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_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_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_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) self._xray_composite_shader.setTexture(3, self._xray_error_image)
if not self._composite_pass: if not self._composite_pass:

View File

@ -25,6 +25,7 @@ fragment =
uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_layer2; //X-ray pass.
uniform sampler2D u_xray_error; //X-ray error image. uniform sampler2D u_xray_error; //X-ray error image.
uniform vec2 u_xray_error_scale;
uniform vec2 u_offset[9]; uniform vec2 u_offset[9];
uniform float u_outline_strength; uniform float u_outline_strength;
@ -55,8 +56,7 @@ fragment =
float rest = mod(intersection_count + .01, 2.0); float rest = mod(intersection_count + .01, 2.0);
if (rest > 1.0 && rest < 1.5 && intersection_count < 49) 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 * u_xray_error_scale);
result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling);
} }
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);
@ -100,6 +100,7 @@ fragment41core =
uniform sampler2D u_layer2; //X-ray pass. uniform sampler2D u_layer2; //X-ray pass.
uniform sampler2D u_xray_error; //X-ray error image. uniform sampler2D u_xray_error; //X-ray error image.
uniform vec2 u_xray_error_scale;
uniform vec2 u_offset[9]; uniform vec2 u_offset[9];
uniform float u_outline_strength; uniform float u_outline_strength;
@ -131,8 +132,7 @@ fragment41core =
float rest = mod(intersection_count + .01, 2.0); float rest = mod(intersection_count + .01, 2.0);
if (rest > 1.0 && rest < 1.5 && intersection_count < 49) 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 * u_xray_error_scale);
result = result * (1.0 - u_xray_error_strength) + u_xray_error_strength * texture(u_xray_error, v_uvs * scaling);
} }
vec4 sum = vec4(0.0); vec4 sum = vec4(0.0);