-
-
Save methanoliver/f265cd68bf13ac1008d7140d07b2e023 to your computer and use it in GitHub Desktop.
Gradient() equivalent of Solid()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## This file *MUST* be named `game/python-packages/gradient.py` to work properly. | |
from renpy.gl2.gl2mesh3 import Mesh3 # type: ignore | |
from renpy.gl2.gl2model import GL2Model # type: ignore | |
def solid_gradient(w, h, color_start, color_end, vertical): | |
""" | |
Returns a texture with a gradient in it. | |
""" | |
def __color_to_tuple(color): | |
# Actually, why does it premultiply alpha here? | |
a = color[3] / 255.0 | |
r = a * color[0] / 255.0 | |
g = a * color[1] / 255.0 | |
b = a * color[2] / 255.0 | |
return (r, g, b, a) | |
mesh = Mesh3.rectangle(0, 0, w, h) | |
start_color = __color_to_tuple(color_start) | |
end_color = __color_to_tuple(color_end) | |
return GL2Model((w, h), mesh, ("oliver.gradient", ), | |
({ "u_gradient_start" : start_color, "u_gradient_end": end_color, | |
"u_vertical": vertical })) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## This file can be placed anywhere, | |
## but I recommend you put it in `game/python-packages/gradient.rpy`. | |
init python: | |
from gradient import solid_gradient | |
class Gradient(renpy.Displayable): | |
""" | |
A displayable that fills the area it's assigned with a linear gradient. | |
Mostly duplicated from RenPy's original Solid code. | |
Limitations: Will only work if `config.gl2` is True, | |
i.e. if model-based rendering is enabled. What happens if it isn't | |
has never been tested. | |
Arguments: | |
`color` - the color of the start of the gradient. | |
`end_color` - the color of the end of the gradient. | |
`vertical` - True if the gradient is to be vertical. Defaults to false. | |
Horizontal gradients start at the left, while vertical gradients | |
start at the top. | |
""" | |
def __init__(self, color, end_color, vertical=False, **properties): | |
super(Gradient, self).__init__(**properties) | |
if color is not None and end_color is not None: | |
self.color = renpy.easy.color(color) | |
self.end_color = renpy.easy.color(end_color) | |
else: | |
self.color = None | |
self.end_color = None | |
self.vertical = vertical | |
def __hash__(self): | |
return hash((self.color, self.end_color, self.vertical)) | |
def __eq__(self, o): | |
if not self._equals(o): | |
return False | |
return (all([self.color == o.color, | |
self.end_color == o.end_color, | |
self.vertical == o.vertical])) | |
def visit(self): | |
return [ ] | |
def render(self, width, height, st, at): | |
xminimum, yminimum = renpy.display.layout.xyminimums(self.style, width, height) | |
width = max(xminimum, width) | |
height = max(yminimum, height) | |
color = self.color or self.style.color | |
# Misusing a property here. | |
end_color = self.end_color or self.style.black_color | |
# We can't pass a boolean to the shader. | |
vertical = 0.0 | |
if self.vertical: | |
vertical = 1.0 | |
rv = renpy.display.render.Render(width, height) | |
if color is None or width <= 0 or height <= 0: | |
return rv | |
SIZE = 10 | |
if width < SIZE or height < SIZE: | |
tex = solid_gradient(width, height, color, end_color, vertical) | |
else: | |
tex = solid_gradient(SIZE, SIZE, color, end_color, vertical) | |
rv.forward = renpy.display.render.Matrix2D(1.0 * SIZE / width, 0, 0, 1.0 * SIZE / height) | |
rv.reverse = renpy.display.render.Matrix2D(1.0 * width / SIZE, 0, 0, 1.0 * height / SIZE) | |
rv.blit(tex, (0, 0)) | |
return rv | |
init python hide: | |
renpy.register_shader("oliver.gradient", | |
variables=""" | |
uniform vec2 u_model_size; | |
uniform vec4 u_gradient_start; | |
uniform vec4 u_gradient_end; | |
uniform float u_vertical; | |
varying vec2 v_uv; | |
""", | |
vertex_200=""" | |
v_uv = a_position.xy / u_model_size; | |
""", | |
fragment_200=""" | |
float coord = u_vertical > 0.5 ? v_uv.y : v_uv.x; | |
gl_FragColor = vec4( | |
smoothstep(u_gradient_start.r, u_gradient_end.r, coord), | |
smoothstep(u_gradient_start.g, u_gradient_end.g, coord), | |
smoothstep(u_gradient_start.b, u_gradient_end.b, coord), | |
smoothstep(u_gradient_start.a, u_gradient_end.a, coord) | |
); | |
""") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment