diff --git a/punyverse/entity.py b/punyverse/entity.py index 69d9279..7611487 100644 --- a/punyverse/entity.py +++ b/punyverse/entity.py @@ -274,10 +274,11 @@ class SphericalBody(Body): _sphere_cache = {} @classmethod - def _get_sphere(cls, division): - if division in cls._sphere_cache: - return cls._sphere_cache[division] - cls._sphere_cache[division] = sphere = TangentSphere(division, division) + def _get_sphere(cls, division, tangent=True): + if (division, tangent) in cls._sphere_cache: + return cls._sphere_cache[division, tangent] + cls._sphere_cache[division, tangent] = sphere = \ + (TangentSphere if tangent else SimpleSphere)(division, division) return sphere def __init__(self, name, world, info, parent=None): @@ -290,8 +291,8 @@ class SphericalBody(Body): self.shininess = info.get('shininess', 0) self.type = info.get('type', 'planet') - self.diffuse_texture = get_best_texture(info['texture']) - self.sphere = self._get_sphere(division) + self.texture = get_best_texture(info['texture']) + self.sphere = self._get_sphere(division, tangent=self.type == 'planet') self.atmosphere = None self.clouds = None @@ -331,7 +332,7 @@ class SphericalBody(Body): shader.uniform_mat4('u_mvpMatrix', self.world.vp_matrix * self.model_matrix) glActiveTexture(GL_TEXTURE0) - glBindTexture(GL_TEXTURE_2D, self.diffuse_texture) + glBindTexture(GL_TEXTURE_2D, self.texture) shader.uniform_bool('u_planet.hasDiffuse', True) shader.uniform_texture('u_planet.diffuseMap', 0) @@ -361,9 +362,34 @@ class SphericalBody(Body): self.world.activate_shader(None) glActiveTexture(GL_TEXTURE0) + def _draw_star(self): + shader = self.world.activate_shader('star') + shader.uniform_float('u_radius', self.radius) + shader.uniform_mat4('u_mvpMatrix', self.world.vp_matrix * self.model_matrix) + + glActiveTexture(GL_TEXTURE0) + glBindTexture(GL_TEXTURE_2D, self.texture) + shader.uniform_texture('u_emission', 0) + + glBindBuffer(GL_ARRAY_BUFFER, self.sphere.vbo) + shader.vertex_attribute('a_normal', self.sphere.direction_size, self.sphere.type, GL_FALSE, + self.sphere.stride, self.sphere.direction_offset) + shader.vertex_attribute('a_uv', self.sphere.uv_size, self.sphere.type, GL_FALSE, + self.sphere.stride, self.sphere.uv_offset) + + glDrawArrays(GL_TRIANGLE_STRIP, 0, self.sphere.vertex_count) + + shader.deactivate_attributes() + glBindBuffer(GL_ARRAY_BUFFER, 0) + self.world.activate_shader(None) + def _draw_sphere(self): if self.type == 'planet': self._draw_planet() + elif self.type == 'star': + self._draw_star() + else: + raise ValueError('Invalid type: %s' % self.type) def _draw_atmosphere(self): with glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT): diff --git a/punyverse/shaders/sphere.planet.fragment.glsl b/punyverse/shaders/planet.fragment.glsl similarity index 100% rename from punyverse/shaders/sphere.planet.fragment.glsl rename to punyverse/shaders/planet.fragment.glsl diff --git a/punyverse/shaders/sphere.vertex.glsl b/punyverse/shaders/planet.vertex.glsl similarity index 100% rename from punyverse/shaders/sphere.vertex.glsl rename to punyverse/shaders/planet.vertex.glsl diff --git a/punyverse/shaders/star.fragment.glsl b/punyverse/shaders/star.fragment.glsl new file mode 100644 index 0000000..899f94d --- /dev/null +++ b/punyverse/shaders/star.fragment.glsl @@ -0,0 +1,8 @@ +#version 130 + +in vec2 v_uv; +uniform sampler2D u_emission; + +void main() { + gl_FragColor = vec4(texture(u_emission, v_uv).rgb, 1); +} diff --git a/punyverse/shaders/star.vertex.glsl b/punyverse/shaders/star.vertex.glsl new file mode 100644 index 0000000..9107f97 --- /dev/null +++ b/punyverse/shaders/star.vertex.glsl @@ -0,0 +1,14 @@ +#version 130 + +in vec3 a_normal; +in vec2 a_uv; + +out vec2 v_uv; + +uniform float u_radius; +uniform mat4 u_mvpMatrix; + +void main() { + gl_Position = u_mvpMatrix * vec4(u_radius * a_normal, 1); + v_uv = a_uv; +} diff --git a/punyverse/world.py b/punyverse/world.py index e96167b..927e913 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -19,7 +19,8 @@ def load_world(file, callback=lambda message, completion: None): class World(object): PROGRAMS = { 'sky': ('sky.vertex.glsl', 'sky.fragment.glsl'), - 'planet': ('sphere.vertex.glsl', 'sphere.planet.fragment.glsl'), + 'planet': ('planet.vertex.glsl', 'planet.fragment.glsl'), + 'star': ('star.vertex.glsl', 'star.fragment.glsl'), } def __init__(self, file, callback):