diff --git a/punyverse/glgeom.py b/punyverse/glgeom.py index c6c968a..2193f15 100644 --- a/punyverse/glgeom.py +++ b/punyverse/glgeom.py @@ -11,32 +11,8 @@ from six.moves import range TWOPI = pi * 2 -__all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'belt', - 'glSection', 'glRestore', 'glContext', 'progress_bar', - 'FontEngine', 'Matrix4f', 'Disk', 'OrbitVBO', 'SimpleSphere', 'TangentSphere', 'Cube'] - - -class glContext(object): - def __init__(self, context): - self.new_context = context - - def __enter__(self): - self.old_context = get_current_context() - self.new_context.set_current() - - def __exit__(self, exc_type, exc_val, exc_tb): - self.old_context.set_current() - - -class glSection(object): - def __init__(self, type): - self.type = type - - def __enter__(self): - glBegin(self.type) - - def __exit__(self, exc_type, exc_val, exc_tb): - glEnd() +__all__ = ['compile', 'belt', 'glRestore', 'FontEngine', 'Matrix4f', 'Disk', 'OrbitVBO', + 'SimpleSphere', 'TangentSphere', 'Cube', 'Circle'] class glRestore(object): @@ -143,42 +119,20 @@ def compile(pointer, *args, **kwargs): return display -def ortho(width, height): - glDisable(GL_LIGHTING) - glDisable(GL_DEPTH_TEST) - glMatrixMode(GL_PROJECTION) - glPushMatrix() - glLoadIdentity() - glOrtho(0, width, 0, height, -1, 1) - glMatrixMode(GL_MODELVIEW) - glPushMatrix() - glLoadIdentity() +class Circle(object): + type = GL_FLOAT + stride = 2 * 4 + position_offset = 0 + position_size = 2 - -def frustrum(): - glMatrixMode(GL_PROJECTION) - glPopMatrix() - glMatrixMode(GL_MODELVIEW) - glPopMatrix() - glEnable(GL_LIGHTING) - glEnable(GL_DEPTH_TEST) - - -def crosshair(size, coords): - cx, cy = coords - with glSection(GL_LINES): - glVertex2f(cx - size, cy) - glVertex2f(cx + size, cy) - glVertex2f(cx, cy - size) - glVertex2f(cx, cy + size) - - -def circle(r, seg, coords): - cx, cy = coords - with glSection(GL_LINE_LOOP): - for i in range(seg): - theta = TWOPI * i / seg - glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r) + def __init__(self, r, segs): + self.vertex_count = segs + buffer = segs * 2 * [0] + delta = 2 * pi / segs + 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) class Disk(object): @@ -384,39 +338,3 @@ def belt(radius, cross, object, count): glScalef(scale, scale, scale) choice(object).draw() glPopMatrix() - - -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 - - 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 - - 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) diff --git a/punyverse/loader.py b/punyverse/loader.py index fd31b55..4c6d7fd 100644 --- a/punyverse/loader.py +++ b/punyverse/loader.py @@ -8,10 +8,69 @@ import pyglet from pyglet.gl import * from six.moves import zip_longest -from punyverse.glgeom import glContext, progress_bar +from punyverse.glgeom import glRestore from punyverse.world import World +class glContext(object): + def __init__(self, context): + self.new_context = context + + def __enter__(self): + self.old_context = get_current_context() + self.new_context.set_current() + + def __exit__(self, exc_type, exc_val, exc_tb): + self.old_context.set_current() + + +class glSection(object): + def __init__(self, type): + self.type = type + + def __enter__(self): + glBegin(self.type) + + def __exit__(self, exc_type, exc_val, exc_tb): + glEnd() + + +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 + + 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 + + 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) + + def get_context_info(context): info = [' %-22s %s' % (key + ':', value) for key, value in context.config.get_gl_attributes()] diff --git a/punyverse/shader.py b/punyverse/shader.py index 835571f..5f10d41 100644 --- a/punyverse/shader.py +++ b/punyverse/shader.py @@ -109,6 +109,9 @@ class Program(object): def uniform_vec3(self, name, a, b, c): glUniform3f(self.uniforms[name], a, b, c) + def uniform_vec4(self, name, a, b, c, d): + glUniform4f(self.uniforms[name], a, b, c, d) + def _variable_locations(self, count_type, get_func, loc_func): variables = {} count = GLint() diff --git a/punyverse/shaders/line.fragment.glsl b/punyverse/shaders/line.fragment.glsl new file mode 100644 index 0000000..4a54b1c --- /dev/null +++ b/punyverse/shaders/line.fragment.glsl @@ -0,0 +1,8 @@ +#version 130 + +out vec4 o_fragColor; +uniform vec4 u_color; + +void main() { + o_fragColor = u_color; +} diff --git a/punyverse/shaders/line.vertex.glsl b/punyverse/shaders/line.vertex.glsl new file mode 100644 index 0000000..2a01d02 --- /dev/null +++ b/punyverse/shaders/line.vertex.glsl @@ -0,0 +1,8 @@ +#version 130 + +in vec2 a_position; +uniform mat4 u_mvpMatrix; + +void main() { + gl_Position = u_mvpMatrix * vec4(a_position, 0, 1); +} diff --git a/punyverse/ui.py b/punyverse/ui.py index 4247ae8..6368e0b 100644 --- a/punyverse/ui.py +++ b/punyverse/ui.py @@ -143,6 +143,7 @@ class Punyverse(pyglet.window.Window): glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1)) self.info_engine = FontEngine() + self.circle = Circle(10, 20) pyglet.clock.schedule(self.update) self.on_resize(self.width, self.height) # On resize handler does nothing unless it's loaded @@ -296,13 +297,19 @@ class Punyverse(pyglet.window.Window): glDrawArrays(GL_TRIANGLES, 0, self.info_engine.vertex_count) self.info_engine.end() - self.world.activate_shader(None) glDisable(GL_BLEND) - ortho(width, height) - with glRestore(GL_CURRENT_BIT | GL_LINE_BIT): - glLineWidth(2) - cx, cy = width / 2, height / 2 - glColor4f(0, 1, 0, 1) - circle(10, 20, (cx, cy)) - frustrum() + glLineWidth(2) + mvp = projection * Matrix4f.from_angles((width / 2, height /2, 0)) + shader = self.world.activate_shader('line') + shader.uniform_vec4('u_color', 0, 1, 0, 1) + shader.uniform_mat4('u_mvpMatrix', mvp) + glBindBuffer(GL_ARRAY_BUFFER, self.circle.vbo) + + shader.vertex_attribute('a_position', self.circle.position_size, self.circle.type, GL_FALSE, + self.circle.stride, self.circle.position_offset) + glDrawArrays(GL_LINE_LOOP, 0, self.circle.vertex_count) + + glBindBuffer(GL_ARRAY_BUFFER, 0) + glLineWidth(1) + self.world.activate_shader(None) diff --git a/punyverse/world.py b/punyverse/world.py index f48549e..fc600eb 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -25,6 +25,7 @@ class World(object): 'ring': ('ring.vertex.glsl', 'ring.fragment.glsl'), 'atmosphere': ('atmosphere.vertex.glsl', 'atmosphere.fragment.glsl'), 'text': ('text.vertex.glsl', 'text.fragment.glsl'), + 'line': ('line.vertex.glsl', 'line.fragment.glsl'), } def __init__(self, file, callback):