mirror of
https://github.com/lxsang/Diya-API.git
synced 2024-12-27 03:48:21 +01:00
149 lines
3.3 KiB
Smalltalk
149 lines
3.3 KiB
Smalltalk
Class {
|
|
#name : #DiyaEllipseShader,
|
|
#superclass : #Diya2DShader,
|
|
#category : #'Diya-Shaders'
|
|
}
|
|
|
|
{ #category : #accessing }
|
|
DiyaEllipseShader class >> fragmentShader [
|
|
^'
|
|
#ifdef GL_ES
|
|
precision highp float;
|
|
#endif
|
|
|
|
uniform vec2 u_resolution;
|
|
uniform vec2 u_mouse;
|
|
uniform float u_time;
|
|
// 2D uniforms
|
|
uniform int u_texture_type;
|
|
uniform vec4 u_color;
|
|
uniform vec4 u_border_color;
|
|
uniform sampler2D u_texture;
|
|
uniform float u_border;
|
|
uniform float u_rx;
|
|
uniform float u_ry;
|
|
varying float rotation;
|
|
varying vec2 middle;
|
|
varying vec2 texcoord;
|
|
struct Ellipse
|
|
{
|
|
vec2 c;
|
|
float minor;
|
|
float major;
|
|
float f;
|
|
};
|
|
float get_foci(float major, float minor)
|
|
{
|
|
return sqrt((major*major)-(minor*minor));
|
|
}
|
|
Ellipse create_ellipse(vec2 c, float mi, float ma)
|
|
{
|
|
Ellipse e;
|
|
e.c = c;
|
|
e.major = max(mi,ma);
|
|
e.minor = min(mi,ma);
|
|
e.f = get_foci(e.major, e.minor);
|
|
return e;
|
|
}
|
|
bool is_inside_ellipse(vec2 p, Ellipse e)
|
|
{
|
|
float first = ((p.x-e.c.x)*(p.x-e.c.x)) / (e.major*e.major);
|
|
float second = ((p.y-e.c.y)*(p.y-e.c.y)) / (e.minor*e.minor);
|
|
return first+second <= 1.0;
|
|
}
|
|
|
|
bool is_inside_border(vec2 p, Ellipse e, float w)
|
|
{
|
|
float first = ((p.x-e.c.x)*(p.x-e.c.x)) / ((e.major-w)*(e.major-w));
|
|
float second = ((p.y-e.c.y)*(p.y-e.c.y)) / ((e.minor-w)*(e.minor-w));
|
|
float sum = first + second;
|
|
return sum<= 1.0;
|
|
}
|
|
|
|
void draw_ellipse(inout vec4 c, vec2 p, Ellipse e, float border)
|
|
{
|
|
c = vec4(0);
|
|
if (is_inside_border(p,e, border))
|
|
{
|
|
vec4 texcolor = vec4(1);
|
|
// vec2 uv = (p - (e.c - vec2(e.major , e.minor))) / vec2(e.major*2.0, e.minor*2.0);
|
|
// alpha
|
|
if(u_texture_type == 0x1906) {
|
|
texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a);
|
|
}
|
|
// rgba
|
|
else if (u_texture_type == 0x1908){
|
|
texcolor = texture2D(u_texture, texcoord);
|
|
}
|
|
c = texcolor * u_color;
|
|
}
|
|
else
|
|
{
|
|
if (is_inside_ellipse(p, e))
|
|
{
|
|
c = u_border_color;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
vec2 rotate_point(vec2 center, vec2 p,float angle)
|
|
{
|
|
float s = sin(-angle);
|
|
float c = cos(-angle);
|
|
|
|
// translate point back to origin:
|
|
p.x -= center.x;
|
|
p.y -= center.y;
|
|
|
|
// rotate point
|
|
float xnew = p.x * c - p.y * s;
|
|
float ynew = p.x * s + p.y * c;
|
|
|
|
// translate point back:
|
|
p.x = xnew + center.x;
|
|
p.y = ynew + center.y;
|
|
return p;
|
|
}
|
|
|
|
void main() {
|
|
vec4 color = vec4(0);
|
|
//defining ellipse
|
|
Ellipse e = create_ellipse(middle, u_ry, u_rx);
|
|
draw_ellipse(color,rotate_point(middle, gl_FragCoord.xy, rotation), e, u_border);
|
|
// Output to screen
|
|
gl_FragColor = color;
|
|
}
|
|
'
|
|
]
|
|
|
|
{ #category : #accessing }
|
|
DiyaEllipseShader class >> vertexShader [
|
|
^'
|
|
#ifdef GL_ES
|
|
precision mediump float;
|
|
#endif
|
|
uniform mat4 u_projection;
|
|
uniform mat3 u_transform;
|
|
uniform vec2 u_resolution;
|
|
varying float rotation;
|
|
varying vec2 middle;
|
|
varying vec2 texcoord;
|
|
void main()
|
|
{
|
|
vec3 coord_global = u_transform * vec3(gl_Vertex.xy, 1.0);
|
|
gl_Position = u_projection * vec4(coord_global.xy, 0, 1.0);
|
|
rotation = atan(u_transform[1][0], u_transform[0][0]);
|
|
vec2 org = (u_transform * vec3(0.0,0.0,1.0)).xy;
|
|
middle = vec2(org.x, u_resolution.y - org.y);
|
|
texcoord = gl_Vertex.zw;
|
|
}'
|
|
]
|
|
|
|
{ #category : #initialization }
|
|
DiyaEllipseShader >> setUpUniforms [
|
|
super setUpUniforms.
|
|
self addUniform: #u_rx of: Uniform1F.
|
|
self addUniform: #u_ry of: Uniform1F.
|
|
]
|