Source code for ipymd.visualise.opengl.renderers.triangles

'''TriangleRenderer is the basics for other shapes, we pass just
triangle vertices and we got the result.

'''
import numpy as np

from .base import DefaultRenderer
from ..buffers import VertexBuffer
from ..shaders import set_uniform

from OpenGL.GL import (GL_DYNAMIC_DRAW, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
                       GL_COLOR_ARRAY, GL_UNSIGNED_BYTE, GL_FLOAT, GL_TRIANGLES,
                       glEnableClientState, glDrawArrays)

[docs]class TriangleRenderer(DefaultRenderer): '''Renders an array of triangles. A lot of renderers are built on this, for example :py:class:`~chemlab.graphics.renderers.SphereRenderer`. The implementation is relatively fast since it's based on VertexBuffers. .. image:: /_static/triangle_renderer.png **Parameters** widget: The parent QChemlabWidget vertices: np.ndarray((NTRIANGLES*3, 3), dtype=float) The triangle vertices, keeping in mind the unwinding order. If the face of the triangle is pointing outwards, the vertices should be provided in clokckwise order. normals: np.ndarray((NTRIANGLES*3, 3), dtype=float) The normals to each of the triangle vertices, used for lighting calculations. colors: np.ndarray((NTRIANGLES*3, 4), dtype=np.uint8) Color for each of the vertices in (r,g,b,a) values in the interval [0, 255] ''' def __init__(self, widget, vertices, normals, colors, shading='phong'): super(TriangleRenderer, self).__init__(widget) n_triangles = len(vertices) # Convert arrays to numpy arrays, float32 precision, # compatible with opengl, and cast to ctypes vertices = np.array(vertices, dtype=np.float32) normals = np.array(normals, dtype=np.float32) colors = np.array(colors, dtype=np.uint8) self.shading = shading # Store vertices, colors and normals in 3 different vertex # buffer objects self._vbo_v = VertexBuffer(vertices, GL_DYNAMIC_DRAW) self._vbo_n = VertexBuffer(normals, GL_DYNAMIC_DRAW) self._vbo_c = VertexBuffer(colors, GL_DYNAMIC_DRAW) self._n_triangles = n_triangles
[docs] def setup_shader(self): super(TriangleRenderer, self).setup_shader() shd = {'phong' : 0, 'toon': 1}[self.shading] set_uniform(self.shader, 'shading_type', '1i', shd)
[docs] def draw_vertices(self): # Draw all the vbo defined in set_atoms glEnableClientState(GL_VERTEX_ARRAY) self._vbo_v.bind_vertexes(3, GL_FLOAT) glEnableClientState(GL_NORMAL_ARRAY) self._vbo_n.bind_normals(GL_FLOAT) glEnableClientState(GL_COLOR_ARRAY) self._vbo_c.bind_colors(4, GL_UNSIGNED_BYTE) glDrawArrays(GL_TRIANGLES, 0, self._n_triangles) self._vbo_v.unbind() self._vbo_n.unbind() self._vbo_c.unbind()
[docs] def update_vertices(self, vertices): """ Update the triangle vertices. """ vertices = np.array(vertices, dtype=np.float32) self._vbo_v.set_data(vertices)
[docs] def update_normals(self, normals): """ Update the triangle normals. """ normals = np.array(normals, dtype=np.float32) self._vbo_n.set_data(normals)
[docs] def update_colors(self, colors): ''' Update the triangle colors. ''' colors = np.array(colors, dtype=np.float32) self._vbo_c.set_data(colors)