mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Shader for models. Instanced asteroid belt.
Removed all instances of legacy pipeline, hopefully. (Except for using VAOs, I guess)
This commit is contained in:
parent
510dcb46a6
commit
a46d5a9ff7
|
@ -63,8 +63,12 @@ class Asteroid(Entity):
|
|||
self.rotation = rx + 1, ry + 1, rz + 1
|
||||
|
||||
def draw(self, options):
|
||||
glLoadMatrixf(self.mv_matrix)
|
||||
self.model.draw()
|
||||
shader = self.world.activate_shader('model')
|
||||
shader.uniform_mat4('u_mvpMatrix', self.mvp_matrix)
|
||||
shader.uniform_mat4('u_mvMatrix', self.mv_matrix)
|
||||
shader.uniform_mat4('u_modelMatrix', self.model_matrix)
|
||||
self.model.draw(shader)
|
||||
self.world.activate_shader(None)
|
||||
|
||||
|
||||
class AsteroidManager(object):
|
||||
|
@ -100,10 +104,9 @@ class Belt(Entity):
|
|||
if not isinstance(models, list):
|
||||
models = [models]
|
||||
|
||||
objects = [WavefrontVBO(load_model(model), info.get('sx', scale), info.get('sy', scale),
|
||||
info.get('sz', scale)) for model in models]
|
||||
|
||||
self.belt_id = compile(belt, radius, cross, objects, count)
|
||||
self.objects = [WavefrontVBO(load_model(model), info.get('sx', scale), info.get('sy', scale),
|
||||
info.get('sz', scale)) for model in models]
|
||||
self.belt = BeltVBO(radius, cross, len(self.objects), count)
|
||||
self.rotation_angle = 360.0 / rotation if rotation else 0
|
||||
|
||||
super(Belt, self).__init__(world, name, (x, y, z), (inclination, longitude, argument))
|
||||
|
@ -114,8 +117,21 @@ class Belt(Entity):
|
|||
self.rotation = pitch, self.world.tick * self.rotation_angle % 360, roll
|
||||
|
||||
def draw(self, options):
|
||||
glLoadMatrixf(self.mv_matrix)
|
||||
glCallList(self.belt_id)
|
||||
shader = self.world.activate_shader('belt')
|
||||
shader.uniform_mat4('u_mvpMatrix', self.mvp_matrix)
|
||||
shader.uniform_mat4('u_mvMatrix', self.mv_matrix)
|
||||
shader.uniform_mat4('u_modelMatrix', self.model_matrix)
|
||||
|
||||
for object, vbo, count in zip(self.objects, self.belt.vbo, self.belt.sizes):
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo)
|
||||
shader.vertex_attribute('a_translate', self.belt.location_size, self.belt.type, GL_FALSE,
|
||||
self.belt.stride, self.belt.location_offset, divisor=1)
|
||||
shader.vertex_attribute('a_scale', self.belt.scale_size, self.belt.type, GL_FALSE,
|
||||
self.belt.stride, self.belt.scale_offset, divisor=1)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
object.draw(shader, instances=count)
|
||||
shader.deactivate_all_attributes()
|
||||
self.world.activate_shader(None)
|
||||
|
||||
|
||||
class Sky(Entity):
|
||||
|
@ -155,7 +171,7 @@ class Sky(Entity):
|
|||
|
||||
glDrawArrays(GL_TRIANGLES, 0, self.cube.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
|
||||
|
@ -261,7 +277,7 @@ class Body(Entity):
|
|||
shader.vertex_attribute('a_position', orbit.position_size, orbit.type, GL_FALSE,
|
||||
orbit.stride, orbit.position_offset)
|
||||
glDrawArrays(GL_LINE_LOOP, 0, orbit.vertex_count)
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
|
||||
if not solid:
|
||||
|
@ -407,7 +423,7 @@ class SphericalBody(Body):
|
|||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.sphere.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
|
@ -429,7 +445,7 @@ class SphericalBody(Body):
|
|||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.sphere.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
|
||||
|
@ -462,7 +478,7 @@ class SphericalBody(Body):
|
|||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.atmosphere.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
glDisable(GL_BLEND)
|
||||
|
@ -489,7 +505,7 @@ class SphericalBody(Body):
|
|||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.clouds.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
glDisable(GL_BLEND)
|
||||
|
@ -517,7 +533,7 @@ class SphericalBody(Body):
|
|||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, self.ring.vertex_count)
|
||||
|
||||
shader.deactivate_attributes()
|
||||
shader.deactivate_all_attributes()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
self.world.activate_shader(None)
|
||||
glDisable(GL_BLEND)
|
||||
|
@ -551,5 +567,9 @@ class ModelBody(Body):
|
|||
info.get('sz', scale))
|
||||
|
||||
def _draw(self, options):
|
||||
glLoadMatrixf(self.mv_matrix)
|
||||
self.vbo.draw()
|
||||
shader = self.world.activate_shader('model')
|
||||
shader.uniform_mat4('u_mvpMatrix', self.mvp_matrix)
|
||||
shader.uniform_mat4('u_mvMatrix', self.mv_matrix)
|
||||
shader.uniform_mat4('u_modelMatrix', self.model_matrix)
|
||||
self.vbo.draw(shader)
|
||||
self.world.activate_shader(None)
|
||||
|
|
|
@ -11,30 +11,7 @@ from six.moves import range
|
|||
|
||||
TWOPI = pi * 2
|
||||
|
||||
__all__ = ['compile', 'belt', 'glRestore', 'FontEngine', 'Matrix4f', 'Disk', 'OrbitVBO',
|
||||
'SimpleSphere', 'TangentSphere', 'Cube', 'Circle']
|
||||
|
||||
|
||||
class glRestore(object):
|
||||
def __init__(self, flags):
|
||||
self.flags = flags
|
||||
|
||||
def __enter__(self):
|
||||
glPushAttrib(self.flags)
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
glPopAttrib()
|
||||
|
||||
|
||||
class glRestoreClient(object):
|
||||
def __init__(self, flags):
|
||||
self.flags = flags
|
||||
|
||||
def __enter__(self):
|
||||
glPushClientAttrib(self.flags)
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
glPopClientAttrib()
|
||||
__all__ = ['FontEngine', 'Matrix4f', 'Disk', 'OrbitVBO', 'SimpleSphere', 'TangentSphere', 'Cube', 'Circle', 'BeltVBO']
|
||||
|
||||
|
||||
def array_to_ctypes(arr):
|
||||
|
@ -47,16 +24,19 @@ def array_to_ctypes(arr):
|
|||
}[arr.typecode]))
|
||||
|
||||
|
||||
def array_to_gl_buffer(buffer, array_type='f'):
|
||||
def array_to_gl_buffer(buffer):
|
||||
vbo = c_uint()
|
||||
glGenBuffers(1, byref(vbo))
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.value)
|
||||
buffer = array(array_type, buffer)
|
||||
glBufferData(GL_ARRAY_BUFFER, buffer.itemsize * len(buffer), array_to_ctypes(buffer), GL_STATIC_DRAW)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
return vbo.value
|
||||
|
||||
|
||||
def list_to_gl_buffer(buffer, array_type='f'):
|
||||
return array_to_gl_buffer(array(array_type, buffer))
|
||||
|
||||
|
||||
class Matrix4f(object):
|
||||
def __init__(self, matrix):
|
||||
self.matrix = array('f', matrix)
|
||||
|
@ -111,14 +91,6 @@ class Matrix4f(object):
|
|||
return type(self)(sum(a[i] * b[j] for i, j in zip(r, c)) for c in cols for r in rows)
|
||||
|
||||
|
||||
def compile(pointer, *args, **kwargs):
|
||||
display = glGenLists(1)
|
||||
glNewList(display, GL_COMPILE)
|
||||
pointer(*args, **kwargs)
|
||||
glEndList()
|
||||
return display
|
||||
|
||||
|
||||
class Circle(object):
|
||||
type = GL_FLOAT
|
||||
stride = 2 * 4
|
||||
|
@ -132,7 +104,7 @@ class Circle(object):
|
|||
for i in range(segs):
|
||||
theta = delta * i
|
||||
buffer[2*i:2*i+2] = [cos(theta) * r, sin(theta) * r]
|
||||
self.vbo = array_to_gl_buffer(buffer)
|
||||
self.vbo = list_to_gl_buffer(buffer)
|
||||
|
||||
|
||||
class Disk(object):
|
||||
|
@ -154,7 +126,7 @@ class Disk(object):
|
|||
x, y = cos(theta), sin(theta)
|
||||
buffer[6*i:6*i+6] = [rinner * x, rinner * y, 0, router * x, router * y, 1]
|
||||
buffer[6*res:6*res+6] = buffer[:6]
|
||||
self.vbo = array_to_gl_buffer(buffer)
|
||||
self.vbo = list_to_gl_buffer(buffer)
|
||||
|
||||
|
||||
class SimpleSphere(object):
|
||||
|
@ -190,7 +162,7 @@ class SimpleSphere(object):
|
|||
index += 10
|
||||
reverse ^= True
|
||||
|
||||
self.vbo = array_to_gl_buffer(buffer)
|
||||
self.vbo = list_to_gl_buffer(buffer)
|
||||
|
||||
|
||||
class TangentSphere(object):
|
||||
|
@ -231,7 +203,7 @@ class TangentSphere(object):
|
|||
]
|
||||
index += 14
|
||||
reverse ^= True
|
||||
self.vbo = array_to_gl_buffer(buffer)
|
||||
self.vbo = list_to_gl_buffer(buffer)
|
||||
|
||||
|
||||
class Cube(object):
|
||||
|
@ -242,7 +214,7 @@ class Cube(object):
|
|||
vertex_count = 36
|
||||
|
||||
def __init__(self):
|
||||
self.vbo = array_to_gl_buffer([
|
||||
self.vbo = list_to_gl_buffer([
|
||||
-1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1,
|
||||
-1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1,
|
||||
|
@ -263,7 +235,7 @@ class OrbitVBO(object):
|
|||
x, z, y = orbit.orbit(theta)
|
||||
buffer[3*theta:3*theta+3] = [x, y, z]
|
||||
|
||||
self.vbo = array_to_gl_buffer(buffer)
|
||||
self.vbo = list_to_gl_buffer(buffer)
|
||||
|
||||
def close(self):
|
||||
if self.vbo is not None:
|
||||
|
@ -322,17 +294,28 @@ class FontEngine(object):
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
|
||||
|
||||
def belt(radius, cross, object, count):
|
||||
for i in range(count):
|
||||
theta = TWOPI * random()
|
||||
r = gauss(radius, cross)
|
||||
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
|
||||
class BeltVBO(object):
|
||||
type = GL_FLOAT
|
||||
stride = 4 * 4
|
||||
location_offset = 0
|
||||
location_size = 3
|
||||
scale_offset = location_size * 4
|
||||
scale_size = 1
|
||||
|
||||
glPushMatrix()
|
||||
glTranslatef(x, y, z)
|
||||
scale = gauss(1, 0.5)
|
||||
if scale < 0:
|
||||
scale = 1
|
||||
glScalef(scale, scale, scale)
|
||||
choice(object).draw()
|
||||
glPopMatrix()
|
||||
def __init__(self, radius, cross, objects, count):
|
||||
arrays = [array('f') for i in range(objects)]
|
||||
|
||||
for i in range(count):
|
||||
theta = TWOPI * random()
|
||||
r = gauss(radius, cross)
|
||||
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
|
||||
scale = gauss(1, 0.5)
|
||||
if scale < 0:
|
||||
scale = 1
|
||||
choice(arrays).extend((x, y, z, scale))
|
||||
|
||||
self.vbo = []
|
||||
self.sizes = []
|
||||
for a in arrays:
|
||||
self.vbo.append(array_to_gl_buffer(a))
|
||||
self.sizes.append(len(a) // 4)
|
||||
|
|
|
@ -8,7 +8,6 @@ import pyglet
|
|||
from pyglet.gl import *
|
||||
from six.moves import zip_longest
|
||||
|
||||
from punyverse.glgeom import glRestore
|
||||
from punyverse.world import World
|
||||
|
||||
|
||||
|
@ -36,39 +35,40 @@ class glSection(object):
|
|||
|
||||
|
||||
def progress_bar(x, y, width, height, filled):
|
||||
with glRestore(GL_ENABLE_BIT):
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
glDisable(GL_BLEND)
|
||||
x1 = x
|
||||
x2 = x + width
|
||||
y1 = y
|
||||
y2 = y - height
|
||||
y3 = 0.65 * y1 + 0.35 * y2
|
||||
y4 = 0.25 * y1 + 0.75 * y2
|
||||
glPushAttrib(GL_ENABLE_BIT)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
glDisable(GL_BLEND)
|
||||
x1 = x
|
||||
x2 = x + width
|
||||
y1 = y
|
||||
y2 = y - height
|
||||
y3 = 0.65 * y1 + 0.35 * y2
|
||||
y4 = 0.25 * y1 + 0.75 * y2
|
||||
|
||||
glColor3f(0.6, 0.6, 0.6)
|
||||
with glSection(GL_LINE_LOOP):
|
||||
glVertex2f(x1, y1)
|
||||
glVertex2f(x1, y2)
|
||||
glVertex2f(x2, y2)
|
||||
glVertex2f(x2, y1)
|
||||
glColor3f(0.6, 0.6, 0.6)
|
||||
with glSection(GL_LINE_LOOP):
|
||||
glVertex2f(x1, y1)
|
||||
glVertex2f(x1, y2)
|
||||
glVertex2f(x2, y2)
|
||||
glVertex2f(x2, y1)
|
||||
|
||||
x1 += 1
|
||||
y1 -= 1
|
||||
x2 = x + width * filled - 1
|
||||
x1 += 1
|
||||
y1 -= 1
|
||||
x2 = x + width * filled - 1
|
||||
|
||||
with glSection(GL_TRIANGLE_STRIP):
|
||||
glColor3f(0.81, 1, 0.82)
|
||||
glVertex2f(x1, y1)
|
||||
glVertex2f(x2, y1)
|
||||
glColor3f(0, 0.83, 0.16)
|
||||
glVertex2f(x1, y3)
|
||||
glVertex2f(x2, y3)
|
||||
glVertex2f(x1, y4)
|
||||
glVertex2f(x2, y4)
|
||||
glColor3f(0.37, 0.92, 0.43)
|
||||
glVertex2f(x1, y2)
|
||||
glVertex2f(x2, y2)
|
||||
with glSection(GL_TRIANGLE_STRIP):
|
||||
glColor3f(0.81, 1, 0.82)
|
||||
glVertex2f(x1, y1)
|
||||
glVertex2f(x2, y1)
|
||||
glColor3f(0, 0.83, 0.16)
|
||||
glVertex2f(x1, y3)
|
||||
glVertex2f(x2, y3)
|
||||
glVertex2f(x1, y4)
|
||||
glVertex2f(x2, y4)
|
||||
glColor3f(0.37, 0.92, 0.43)
|
||||
glVertex2f(x1, y2)
|
||||
glVertex2f(x2, y2)
|
||||
glPopAttrib()
|
||||
|
||||
|
||||
def get_context_info(context):
|
||||
|
|
|
@ -9,7 +9,7 @@ from pyglet.gl import *
|
|||
# noinspection PyUnresolvedReferences
|
||||
from six.moves import range, zip
|
||||
|
||||
from punyverse.glgeom import array_to_gl_buffer, glRestoreClient, glRestore
|
||||
from punyverse.glgeom import list_to_gl_buffer
|
||||
from punyverse.texture import load_texture
|
||||
|
||||
|
||||
|
@ -199,25 +199,30 @@ def load_model(path):
|
|||
class ModelVBO(object):
|
||||
__slots__ = ('has_normal', 'has_texture', 'data_buf', 'index_buf', 'offset_type', 'vertex_count')
|
||||
|
||||
def draw(self):
|
||||
with glRestoreClient(GL_CLIENT_VERTEX_ARRAY_BIT):
|
||||
stride = (3 + self.has_normal * 3 + self.has_texture * 2) * 4
|
||||
def draw(self, shader, instances=None):
|
||||
stride = (3 + self.has_normal * 3 + self.has_texture * 2) * 4
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, self.data_buf)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.index_buf)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, self.data_buf)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.index_buf)
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY)
|
||||
glVertexPointer(3, GL_FLOAT, stride, 0)
|
||||
if self.has_normal:
|
||||
glEnableClientState(GL_NORMAL_ARRAY)
|
||||
glNormalPointer(GL_FLOAT, stride, 3 * 4)
|
||||
if self.has_texture:
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
|
||||
glTexCoordPointer(3, GL_FLOAT, stride, (6 if self.has_normal else 3) * 4)
|
||||
shader.vertex_attribute('a_position', 3, GL_FLOAT, GL_FALSE, stride, 0)
|
||||
if self.has_normal:
|
||||
shader.vertex_attribute('a_normal', 3, GL_FLOAT, GL_FALSE, stride, 3 * 4)
|
||||
else:
|
||||
shader.vertex_attribute_vec3('a_normal', 0, 0, 0)
|
||||
if self.has_texture:
|
||||
shader.vertex_attribute('a_uv', 2, GL_FLOAT, GL_FALSE, stride, (6 if self.has_normal else 3) * 4)
|
||||
else:
|
||||
shader.vertex_attribute_vec2('a_uv', 0, 0)
|
||||
|
||||
if instances:
|
||||
glDrawElementsInstanced(GL_TRIANGLES, self.vertex_count, self.offset_type, 0, instances)
|
||||
else:
|
||||
glDrawElements(GL_TRIANGLES, self.vertex_count, self.offset_type, 0)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
|
||||
|
||||
shader.deactivate_attributes('a_position', 'a_normal', 'a_uv')
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
|
||||
|
||||
|
||||
class WavefrontVBO(object):
|
||||
|
@ -237,31 +242,39 @@ class WavefrontVBO(object):
|
|||
for group in self.merge_groups(model):
|
||||
self.vbos.append((group.material, self.process_group(group, vertices, normals, textures)))
|
||||
|
||||
def draw(self, fv4=GLfloat * 4):
|
||||
with glRestore(GL_TEXTURE_BIT | GL_ENABLE_BIT):
|
||||
for mat, vbo in self.vbos:
|
||||
tex_id = self._tex_cache[mat.texture] if mat and mat.texture else 0
|
||||
def draw(self, shader, instances=None):
|
||||
for mat, vbo in self.vbos:
|
||||
tex_id = self._tex_cache[mat.texture] if mat and mat.texture else 0
|
||||
|
||||
if tex_id:
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
glBindTexture(GL_TEXTURE_2D, tex_id)
|
||||
else:
|
||||
glBindTexture(GL_TEXTURE_2D, 0)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
if tex_id:
|
||||
glActiveTexture(GL_TEXTURE0)
|
||||
glBindTexture(GL_TEXTURE_2D, tex_id)
|
||||
shader.uniform_bool('u_material.hasDiffuse', True)
|
||||
shader.uniform_texture('u_material.diffuseMap', 0)
|
||||
else:
|
||||
shader.uniform_bool('u_material.hasDiffuse', False)
|
||||
|
||||
if mat:
|
||||
if mat.Ka:
|
||||
kx, ky, kz = mat.Ka
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, fv4(kx, ky, kz, 1))
|
||||
if mat.Kd:
|
||||
kx, ky, kz = mat.Kd
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fv4(kx, ky, kz, 1))
|
||||
if mat.Ks:
|
||||
kx, ky, kz = mat.Ks
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(kx, ky, kz, 1))
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mat.shininess)
|
||||
if mat and mat.Ka:
|
||||
shader.uniform_vec3('u_material.ambient', *mat.Ka)
|
||||
else:
|
||||
shader.uniform_vec3('u_material.ambient', 0.2, 0.2, 0.2)
|
||||
|
||||
vbo.draw()
|
||||
if mat and mat.Kd:
|
||||
shader.uniform_vec3('u_material.diffuse', *mat.Kd)
|
||||
else:
|
||||
shader.uniform_vec3('u_material.diffuse', 0.8, 0.8, 0.8)
|
||||
|
||||
if mat and mat.Ks:
|
||||
shader.uniform_vec3('u_material.specular', *mat.Ks)
|
||||
else:
|
||||
shader.uniform_vec3('u_material.specular', 0, 0, 0)
|
||||
|
||||
if mat:
|
||||
shader.uniform_float('u_material.shininess', mat.shininess)
|
||||
else:
|
||||
shader.uniform_float('u_material.shininess', 0)
|
||||
|
||||
vbo.draw(shader, instances=instances)
|
||||
|
||||
def merge_groups(self, model):
|
||||
by_mat = defaultdict(list)
|
||||
|
@ -313,8 +326,8 @@ class WavefrontVBO(object):
|
|||
result.has_normal = has_normal
|
||||
result.has_texture = has_texture
|
||||
result.offset_type = GL_UNSIGNED_SHORT if len(offsets) < 65536 else GL_UNSIGNED_INT
|
||||
result.data_buf = array_to_gl_buffer(buffer, 'f')
|
||||
result.index_buf = array_to_gl_buffer(indices, {
|
||||
result.data_buf = list_to_gl_buffer(buffer, 'f')
|
||||
result.index_buf = list_to_gl_buffer(indices, {
|
||||
GL_UNSIGNED_SHORT: 'H',
|
||||
GL_UNSIGNED_INT: 'I',
|
||||
}[result.offset_type])
|
||||
|
|
|
@ -79,17 +79,40 @@ class Program(object):
|
|||
self.attributes = self._variable_locations(GL_ACTIVE_ATTRIBUTES, glGetActiveAttrib, glGetAttribLocation)
|
||||
self.uniforms = self._variable_locations(GL_ACTIVE_UNIFORMS, glGetActiveUniform, glGetUniformLocation)
|
||||
self.active_attributes = set()
|
||||
self.divisor_attributes = set()
|
||||
|
||||
def vertex_attribute(self, name, size, type, normalized, stride, offset):
|
||||
def vertex_attribute(self, name, size, type, normalized, stride, offset, divisor=None):
|
||||
location = self.attributes[name]
|
||||
glVertexAttribPointer(location, size, type, normalized, stride, offset)
|
||||
glEnableVertexAttribArray(location)
|
||||
if divisor:
|
||||
glVertexAttribDivisor(location, divisor)
|
||||
self.divisor_attributes.add(location)
|
||||
self.active_attributes.add(location)
|
||||
|
||||
def deactivate_attributes(self):
|
||||
def deactivate_all_attributes(self):
|
||||
for location in self.active_attributes:
|
||||
glDisableVertexAttribArray(location)
|
||||
for location in self.divisor_attributes:
|
||||
glVertexAttribDivisor(location, 0)
|
||||
self.active_attributes.clear()
|
||||
self.divisor_attributes.clear()
|
||||
|
||||
def deactivate_attributes(self, *attributes):
|
||||
for attr in attributes:
|
||||
location = self.attributes[attr]
|
||||
if location in self.active_attributes:
|
||||
glDisableVertexAttribArray(location)
|
||||
if location in self.divisor_attributes:
|
||||
glVertexAttribDivisor(location, 0)
|
||||
self.active_attributes.discard(location)
|
||||
self.divisor_attributes.discard(location)
|
||||
|
||||
def vertex_attribute_vec2(self, name, a, b):
|
||||
glVertexAttrib2f(self.attributes[name], a, b)
|
||||
|
||||
def vertex_attribute_vec3(self, name, a, b, c):
|
||||
glVertexAttrib3f(self.attributes[name], a, b, c)
|
||||
|
||||
def uniform_mat4(self, name, matrix):
|
||||
glUniformMatrix4fv(self.uniforms[name], 1, GL_FALSE, matrix)
|
||||
|
|
28
punyverse/shaders/belt.vertex.glsl
Normal file
28
punyverse/shaders/belt.vertex.glsl
Normal file
|
@ -0,0 +1,28 @@
|
|||
#version 130
|
||||
|
||||
in vec3 a_position;
|
||||
in vec3 a_normal;
|
||||
in vec2 a_uv;
|
||||
in vec3 a_translate;
|
||||
in float a_scale;
|
||||
|
||||
out vec2 v_uv;
|
||||
out vec3 v_normal;
|
||||
out vec3 v_position;
|
||||
out vec3 v_camDirection;
|
||||
|
||||
uniform mat4 u_mvpMatrix;
|
||||
uniform mat4 u_mvMatrix;
|
||||
uniform mat4 u_modelMatrix;
|
||||
|
||||
void main() {
|
||||
mat4 matrix = mat4(mat3(a_scale));
|
||||
matrix[3].xyz = a_translate;
|
||||
mat4 modelMatrix = u_modelMatrix * matrix;
|
||||
|
||||
gl_Position = u_mvpMatrix * matrix * vec4(a_position, 1);
|
||||
v_normal = normalize(vec3(modelMatrix * vec4(a_normal, 0)));
|
||||
v_uv = a_uv;
|
||||
v_position = (modelMatrix * vec4(a_position, 1)).xyz;
|
||||
v_camDirection = (u_mvMatrix * matrix * vec4(a_position, 1)).xyz;
|
||||
}
|
43
punyverse/shaders/model.fragment.glsl
Normal file
43
punyverse/shaders/model.fragment.glsl
Normal file
|
@ -0,0 +1,43 @@
|
|||
#version 130
|
||||
|
||||
in vec2 v_uv;
|
||||
in vec3 v_normal;
|
||||
in vec3 v_position;
|
||||
in vec3 v_camDirection;
|
||||
|
||||
out vec4 o_fragColor;
|
||||
|
||||
struct Material {
|
||||
bool hasDiffuse;
|
||||
sampler2D diffuseMap;
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct Sun {
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
vec3 position;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
uniform Sun u_sun;
|
||||
uniform Material u_material;
|
||||
|
||||
void main() {
|
||||
vec3 incident = normalize(u_sun.position - v_position);
|
||||
vec3 reflected = normalize(reflect(-incident, v_normal));
|
||||
|
||||
float diffuseIntensity = max(dot(v_normal, incident), 0.0);
|
||||
float shininess = pow(max(dot(normalize(v_camDirection), reflected), 0), u_material.shininess);
|
||||
|
||||
vec3 diffuse = u_material.hasDiffuse ? texture2D(u_material.diffuseMap, v_uv).rgb : vec3(1);
|
||||
vec3 ambient = u_material.ambient * u_sun.ambient * diffuse;
|
||||
vec3 specular = u_material.specular * u_sun.specular * max(shininess, 0) * diffuseIntensity;
|
||||
diffuse *= u_material.diffuse * u_sun.diffuse * diffuseIntensity;
|
||||
|
||||
o_fragColor = vec4((ambient + diffuse + specular) * u_sun.intensity, 1);
|
||||
}
|
22
punyverse/shaders/model.vertex.glsl
Normal file
22
punyverse/shaders/model.vertex.glsl
Normal file
|
@ -0,0 +1,22 @@
|
|||
#version 130
|
||||
|
||||
in vec3 a_position;
|
||||
in vec3 a_normal;
|
||||
in vec2 a_uv;
|
||||
|
||||
out vec2 v_uv;
|
||||
out vec3 v_normal;
|
||||
out vec3 v_position;
|
||||
out vec3 v_camDirection;
|
||||
|
||||
uniform mat4 u_mvpMatrix;
|
||||
uniform mat4 u_mvMatrix;
|
||||
uniform mat4 u_modelMatrix;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_mvpMatrix * vec4(a_position, 1);
|
||||
v_normal = normalize(vec3(u_modelMatrix * vec4(a_normal, 0)));
|
||||
v_uv = a_uv;
|
||||
v_position = (u_modelMatrix * vec4(a_position, 1)).xyz;
|
||||
v_camDirection = (u_mvMatrix * vec4(a_position, 1)).xyz;
|
||||
}
|
|
@ -127,21 +127,6 @@ class Punyverse(pyglet.window.Window):
|
|||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_LIGHT1)
|
||||
|
||||
fv4 = GLfloat * 4
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, fv4(.5, .5, 1, 0))
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, fv4(.5, .5, 1, 1))
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, fv4(1, 1, 1, 1))
|
||||
glLightfv(GL_LIGHT1, GL_POSITION, fv4(1, 0, .5, 0))
|
||||
glLightfv(GL_LIGHT1, GL_DIFFUSE, fv4(.5, .5, .5, 1))
|
||||
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
||||
|
||||
self.info_engine = FontEngine()
|
||||
self.circle = Circle(10, 20)
|
||||
|
||||
|
@ -214,12 +199,8 @@ class Punyverse(pyglet.window.Window):
|
|||
if not width or not height:
|
||||
# Sometimes this happen for no reason?
|
||||
return
|
||||
|
||||
glViewport(0, 0, width, height)
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
self.world.resize(width, height)
|
||||
glLoadMatrixf(self.world.projection_matrix())
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
|
||||
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
|
||||
self.world.cam.speed += scroll_y * 50 + scroll_x * 500
|
||||
|
@ -240,12 +221,9 @@ class Punyverse(pyglet.window.Window):
|
|||
|
||||
def on_draw(self):
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||
glLoadMatrixf(self.world.view_matrix())
|
||||
|
||||
c = self.world.cam
|
||||
x, y, z = c.x, c.y, c.z
|
||||
|
||||
glEnable(GL_LIGHTING)
|
||||
world = self.world
|
||||
get_distance = entity_distance(x, y, z)
|
||||
if x != world.x or y != world.y or z != world.z:
|
||||
|
@ -256,12 +234,8 @@ class Punyverse(pyglet.window.Window):
|
|||
for entity in world.tracker:
|
||||
entity.draw(self)
|
||||
|
||||
glColor4f(1, 1, 1, 1)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
|
||||
width, height = self.get_size()
|
||||
|
||||
if self.info:
|
||||
width, height = self.get_size()
|
||||
projection = Matrix4f([
|
||||
2 / width, 0, 0, 0,
|
||||
0, -2 / height, 0, 0,
|
||||
|
|
|
@ -294,7 +294,7 @@
|
|||
"radius": "2.362 * AU",
|
||||
"cross": 1000,
|
||||
"scale": 30,
|
||||
"count": 256,
|
||||
"count": 4096,
|
||||
"rotation": 114536500
|
||||
}
|
||||
},
|
||||
|
|
|
@ -26,6 +26,8 @@ class World(object):
|
|||
'atmosphere': ('atmosphere.vertex.glsl', 'atmosphere.fragment.glsl'),
|
||||
'text': ('text.vertex.glsl', 'text.fragment.glsl'),
|
||||
'line': ('line.vertex.glsl', 'line.fragment.glsl'),
|
||||
'model': ('model.vertex.glsl', 'model.fragment.glsl'),
|
||||
'belt': ('belt.vertex.glsl', 'model.fragment.glsl'),
|
||||
}
|
||||
|
||||
def __init__(self, file, callback):
|
||||
|
@ -51,12 +53,13 @@ class World(object):
|
|||
for entity in self.tracker:
|
||||
entity.update()
|
||||
|
||||
shader = self.activate_shader('planet')
|
||||
shader.uniform_vec3('u_sun.ambient', 0.1, 0.1, 0.1)
|
||||
shader.uniform_vec3('u_sun.diffuse', 1, 1, 1)
|
||||
shader.uniform_vec3('u_sun.specular', 0.5, 0.5, 0.5)
|
||||
shader.uniform_vec3('u_sun.position', 0, 0, 0)
|
||||
shader.uniform_float('u_sun.intensity', 1)
|
||||
for name in ('planet', 'model', 'belt'):
|
||||
shader = self.activate_shader(name)
|
||||
shader.uniform_vec3('u_sun.ambient', 0.1, 0.1, 0.1)
|
||||
shader.uniform_vec3('u_sun.diffuse', 1, 1, 1)
|
||||
shader.uniform_vec3('u_sun.specular', 0.5, 0.5, 0.5)
|
||||
shader.uniform_vec3('u_sun.position', 0, 0, 0)
|
||||
shader.uniform_float('u_sun.intensity', 1)
|
||||
|
||||
shader = self.activate_shader('clouds')
|
||||
shader.uniform_vec3('u_sun', 0, 0, 0)
|
||||
|
|
Loading…
Reference in a new issue