mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Convert rings to shaders.
Also add planet shadows onto rings.
This commit is contained in:
parent
1319514cdc
commit
d41fcb7d7f
|
@ -468,15 +468,31 @@ class SphericalBody(Body):
|
||||||
glDisable(GL_BLEND)
|
glDisable(GL_BLEND)
|
||||||
|
|
||||||
def _draw_rings(self):
|
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)
|
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)
|
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):
|
def _draw(self, options):
|
||||||
self._draw_sphere()
|
self._draw_sphere()
|
||||||
|
|
|
@ -9,7 +9,7 @@ from six.moves import range
|
||||||
|
|
||||||
TWOPI = pi * 2
|
TWOPI = pi * 2
|
||||||
|
|
||||||
__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'Sphere', 'belt',
|
__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'belt',
|
||||||
'glSection', 'glRestore', 'progress_bar']
|
'glSection', 'glRestore', 'progress_bar']
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,6 +179,13 @@ def circle(r, seg, coords):
|
||||||
|
|
||||||
|
|
||||||
class Disk(object):
|
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):
|
def __init__(self, rinner, router, segs):
|
||||||
res = segs * 5
|
res = segs * 5
|
||||||
delta = 2 * pi / res
|
delta = 2 * pi / res
|
||||||
|
@ -276,45 +283,6 @@ class TangentSphere(object):
|
||||||
self.vbo = array_to_gl_buffer(buffer)
|
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):
|
class OrbitVBO(object):
|
||||||
def __init__(self, orbit):
|
def __init__(self, orbit):
|
||||||
buffer = 360 * 3 * [0]
|
buffer = 360 * 3 * [0]
|
||||||
|
|
22
punyverse/shaders/ring.fragment.glsl
Normal file
22
punyverse/shaders/ring.fragment.glsl
Normal 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;
|
||||||
|
}
|
16
punyverse/shaders/ring.vertex.glsl
Normal file
16
punyverse/shaders/ring.vertex.glsl
Normal 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;
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ class World(object):
|
||||||
'planet': ('planet.vertex.glsl', 'planet.fragment.glsl'),
|
'planet': ('planet.vertex.glsl', 'planet.fragment.glsl'),
|
||||||
'clouds': ('clouds.vertex.glsl', 'clouds.fragment.glsl'),
|
'clouds': ('clouds.vertex.glsl', 'clouds.fragment.glsl'),
|
||||||
'star': ('star.vertex.glsl', 'star.fragment.glsl'),
|
'star': ('star.vertex.glsl', 'star.fragment.glsl'),
|
||||||
|
'ring': ('ring.vertex.glsl', 'ring.fragment.glsl'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, file, callback):
|
def __init__(self, file, callback):
|
||||||
|
|
Loading…
Reference in a new issue