Convert rings to shaders.

Also add planet shadows onto rings.
This commit is contained in:
Quantum 2018-08-27 19:28:17 -04:00
parent f7cd7671ae
commit 896d9d88b7
5 changed files with 71 additions and 48 deletions

View file

@ -468,15 +468,31 @@ class SphericalBody(Body):
glDisable(GL_BLEND)
def _draw_rings(self):
with glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
glLoadMatrixf(self.mv_matrix)
glDisable(GL_LIGHTING)
glEnable(GL_TEXTURE_2D)
glEnable(GL_BLEND)
glDisable(GL_CULL_FACE)
shader = self.world.activate_shader('ring')
shader.uniform_mat4('u_modelMatrix', self.model_matrix)
shader.uniform_mat4('u_mvpMatrix', self.mvp_matrix)
shader.uniform_vec3('u_planet', *self.location)
shader.uniform_vec3('u_sun', 0, 0, 0)
shader.uniform_float('u_planetRadius', self.radius)
shader.uniform_float('u_ambient', 0.1)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.ring_texture)
self.ring.draw()
shader.uniform_texture('u_texture', 0)
glBindBuffer(GL_ARRAY_BUFFER, self.ring.vbo)
shader.vertex_attribute('a_position', self.ring.position_size, self.ring.type, GL_FALSE,
self.ring.stride, self.ring.position_offset)
shader.vertex_attribute('a_u', self.ring.u_size, self.ring.type, GL_FALSE,
self.ring.stride, self.ring.u_offset)
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.ring.vertex_count)
shader.deactivate_attributes()
glBindBuffer(GL_ARRAY_BUFFER, 0)
self.world.activate_shader(None)
glDisable(GL_BLEND)
def _draw(self, options):
self._draw_sphere()

View file

@ -9,7 +9,7 @@ from six.moves import range
TWOPI = pi * 2
__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'Sphere', 'belt',
__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'belt',
'glSection', 'glRestore', 'progress_bar']
@ -179,6 +179,13 @@ def circle(r, seg, coords):
class Disk(object):
type = GL_FLOAT
stride = 3 * 4
position_offset = 0
position_size = 2
u_offset = position_size * 4
u_size = 1
def __init__(self, rinner, router, segs):
res = segs * 5
delta = 2 * pi / res
@ -276,45 +283,6 @@ class TangentSphere(object):
self.vbo = array_to_gl_buffer(buffer)
class Sphere(object):
def __init__(self, r, lats, longs):
tau = pi * 2
phi_div = tau / longs
theta_div = pi / lats
self.vertex_count = (lats + 1) * (longs + 1) * 2
buffer = self.vertex_count * 8 * [0]
index = 0
for i in range(longs + 1):
phi1, phi2 = i * phi_div, (i + 1) * phi_div
for j in range(lats + 1):
theta = j * theta_div
sine = sin(theta)
dz = cos(theta)
t = 1 - theta / pi
dx1 = sine * cos(phi2)
dy1 = sine * sin(phi2)
dx2 = sine * cos(phi1)
dy2 = sine * sin(phi1)
buffer[index:index + 16] = [r * dx1, r * dy1, r * dz, dx1, dy1, dz, phi2 / tau, t,
r * dx2, r * dy2, r * dz, dx2, dy2, dz, phi1 / tau, t]
index += 16
self.vbo = array_to_gl_buffer(buffer)
def draw(self):
with glRestoreClient(GL_CLIENT_VERTEX_ARRAY_BIT):
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glVertexPointer(3, GL_FLOAT, 32, 0)
glNormalPointer(GL_FLOAT, 32, 3 * 4)
glTexCoordPointer(3, GL_FLOAT, 32, 6 * 4)
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.vertex_count)
glBindBuffer(GL_ARRAY_BUFFER, 0)
class OrbitVBO(object):
def __init__(self, orbit):
buffer = 360 * 3 * [0]

View file

@ -0,0 +1,22 @@
#version 130
in vec3 v_position;
in float v_u;
out vec4 o_fragColor;
uniform vec3 u_sun;
uniform vec3 u_planet;
uniform float u_planetRadius;
uniform float u_ambient;
uniform sampler2D u_texture;
void main() {
vec3 incident = v_position - u_sun;
vec3 plane_normal = u_planet - u_sun;
vec3 plane_intersect = dot(plane_normal, plane_normal) / dot(incident, plane_normal) * incident;
o_fragColor = texture(u_texture, vec2(v_u, 0));
if (length(plane_intersect) < length(incident) &&
distance(plane_intersect, plane_normal) <= u_planetRadius)
o_fragColor.rgb *= u_ambient;
}

View file

@ -0,0 +1,16 @@
#version 130
in vec2 a_position;
in float a_u;
out vec3 v_position;
out float v_u;
uniform mat4 u_mvpMatrix;
uniform mat4 u_modelMatrix;
void main() {
gl_Position = u_mvpMatrix * vec4(a_position, 0, 1);
v_position = (u_modelMatrix * vec4(a_position, 0, 1)).xyz;
v_u = a_u;
}

View file

@ -22,6 +22,7 @@ class World(object):
'planet': ('planet.vertex.glsl', 'planet.fragment.glsl'),
'clouds': ('clouds.vertex.glsl', 'clouds.fragment.glsl'),
'star': ('star.vertex.glsl', 'star.fragment.glsl'),
'ring': ('ring.vertex.glsl', 'ring.fragment.glsl'),
}
def __init__(self, file, callback):