diff --git a/punyverse/entity.py b/punyverse/entity.py index dd93d82..b16f262 100644 --- a/punyverse/entity.py +++ b/punyverse/entity.py @@ -330,7 +330,7 @@ class SphericalBody(Body): self.clouds = self._get_sphere(division, tangent=False) if atm_texture is not None: - self.atm_texture = get_best_texture(atm_texture, clamp=True) + self.atm_texture = load_texture_1d(atm_texture, clamp=True) self.atmosphere = Disk(self.radius, self.radius + atm_size, 30) if 'ring' in info: @@ -432,18 +432,31 @@ class SphericalBody(Body): raise ValueError('Invalid type: %s' % self.type) def _draw_atmosphere(self): - with glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT): - mv = self.mv_matrix.matrix - matrix = Matrix4f([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, mv[12], mv[13], mv[14], 1]) - glLoadMatrixf(matrix) + glEnable(GL_BLEND) + glDisable(GL_CULL_FACE) + shader = self.world.activate_shader('atmosphere') - glDisable(GL_LIGHTING) - glEnable(GL_TEXTURE_2D) - glEnable(GL_BLEND) - glDisable(GL_CULL_FACE) + mv = self.mv_matrix.matrix + matrix = Matrix4f([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, mv[12], mv[13], mv[14], 1]) + shader.uniform_mat4('u_mvpMatrix', self.world.projection_matrix() * matrix) - glBindTexture(GL_TEXTURE_2D, self.atm_texture) - self.atmosphere.draw() + glActiveTexture(GL_TEXTURE0) + glBindTexture(GL_TEXTURE_1D, self.atm_texture) + shader.uniform_texture('u_texture', 0) + + glBindBuffer(GL_ARRAY_BUFFER, self.atmosphere.vbo) + shader.vertex_attribute('a_position', self.atmosphere.position_size, self.atmosphere.type, GL_FALSE, + self.atmosphere.stride, self.atmosphere.position_offset) + shader.vertex_attribute('a_u', self.atmosphere.u_size, self.atmosphere.type, GL_FALSE, + self.atmosphere.stride, self.atmosphere.u_offset) + + glDrawArrays(GL_TRIANGLE_STRIP, 0, self.atmosphere.vertex_count) + + shader.deactivate_attributes() + glBindBuffer(GL_ARRAY_BUFFER, 0) + self.world.activate_shader(None) + glDisable(GL_BLEND) + glEnable(GL_CULL_FACE) def _draw_clouds(self): glEnable(GL_BLEND) diff --git a/punyverse/glgeom.py b/punyverse/glgeom.py index ab1003e..37964c7 100644 --- a/punyverse/glgeom.py +++ b/punyverse/glgeom.py @@ -199,16 +199,6 @@ class Disk(object): buffer[6*res:6*res+6] = buffer[:6] 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_TEXTURE_COORD_ARRAY) - glVertexPointer(3, GL_FLOAT, 12, 0) - glTexCoordPointer(1, GL_FLOAT, 12, 8) - glDrawArrays(GL_TRIANGLE_STRIP, 0, self.vertex_count) - glBindBuffer(GL_ARRAY_BUFFER, 0) - class SimpleSphere(object): type = GL_FLOAT @@ -229,6 +219,8 @@ class SimpleSphere(object): reverse = False for i in range(longs + 1): phi1, phi2 = i * phi_div, (i + 1) * phi_div + if reverse: + phi1, phi2 = phi2, phi1 for j in range(lats + 1): theta = j * theta_div if reverse: @@ -265,6 +257,8 @@ class TangentSphere(object): reverse = False for i in range(longs + 1): phi1, phi2 = i * phi_div, (i + 1) * phi_div + if reverse: + phi1, phi2 = phi2, phi1 for j in range(lats + 1): theta = j * theta_div if reverse: diff --git a/punyverse/shaders/atmosphere.fragment.glsl b/punyverse/shaders/atmosphere.fragment.glsl new file mode 100644 index 0000000..f8cbbb9 --- /dev/null +++ b/punyverse/shaders/atmosphere.fragment.glsl @@ -0,0 +1,10 @@ +#version 130 + +in float v_u; + +out vec4 o_fragColor; +uniform sampler1D u_texture; + +void main() { + o_fragColor = texture(u_texture, v_u); +} diff --git a/punyverse/shaders/atmosphere.vertex.glsl b/punyverse/shaders/atmosphere.vertex.glsl new file mode 100644 index 0000000..15853cc --- /dev/null +++ b/punyverse/shaders/atmosphere.vertex.glsl @@ -0,0 +1,13 @@ +#version 130 + +in vec2 a_position; +in float a_u; + +out float v_u; + +uniform mat4 u_mvpMatrix; + +void main() { + gl_Position = u_mvpMatrix * vec4(a_position, 0, 1); + v_u = a_u; +} diff --git a/punyverse/world.py b/punyverse/world.py index 6ec665c..0297f86 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -23,6 +23,7 @@ class World(object): 'clouds': ('clouds.vertex.glsl', 'clouds.fragment.glsl'), 'star': ('star.vertex.glsl', 'star.fragment.glsl'), 'ring': ('ring.vertex.glsl', 'ring.fragment.glsl'), + 'atmosphere': ('atmosphere.vertex.glsl', 'atmosphere.fragment.glsl'), } def __init__(self, file, callback):