mirror of https://github.com/kivy/kivy.git
78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
'''
|
|
3D Rotating Monkey Head
|
|
========================
|
|
|
|
This example demonstrates using OpenGL to display a rotating monkey head. This
|
|
includes loading a Blender OBJ file, shaders written in OpenGL's Shading
|
|
Language (GLSL), and using scheduled callbacks.
|
|
|
|
The monkey.obj file is an OBJ file output from the Blender free 3D creation
|
|
software. The file is text, listing vertices and faces and is loaded
|
|
using a class in the file objloader.py. The file simple.glsl is
|
|
a simple vertex and fragment shader written in GLSL.
|
|
'''
|
|
|
|
from kivy.app import App
|
|
from kivy.clock import Clock
|
|
from kivy.core.window import Window
|
|
from kivy.uix.widget import Widget
|
|
from kivy.resources import resource_find
|
|
from kivy.graphics.transformation import Matrix
|
|
from kivy.graphics.opengl import glEnable, glDisable, GL_DEPTH_TEST
|
|
from kivy.graphics import RenderContext, Callback, PushMatrix, PopMatrix, \
|
|
Color, Translate, Rotate, Mesh, UpdateNormalMatrix
|
|
from objloader import ObjFile
|
|
|
|
|
|
class Renderer(Widget):
|
|
def __init__(self, **kwargs):
|
|
self.canvas = RenderContext(compute_normal_mat=True)
|
|
self.canvas.shader.source = resource_find('simple.glsl')
|
|
self.scene = ObjFile(resource_find("monkey.obj"))
|
|
super(Renderer, self).__init__(**kwargs)
|
|
with self.canvas:
|
|
self.cb = Callback(self.setup_gl_context)
|
|
PushMatrix()
|
|
self.setup_scene()
|
|
PopMatrix()
|
|
self.cb = Callback(self.reset_gl_context)
|
|
Clock.schedule_interval(self.update_glsl, 1 / 60.)
|
|
|
|
def setup_gl_context(self, *args):
|
|
glEnable(GL_DEPTH_TEST)
|
|
|
|
def reset_gl_context(self, *args):
|
|
glDisable(GL_DEPTH_TEST)
|
|
|
|
def update_glsl(self, delta):
|
|
asp = self.width / float(self.height)
|
|
proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
|
|
self.canvas['projection_mat'] = proj
|
|
self.canvas['diffuse_light'] = (1.0, 1.0, 0.8)
|
|
self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
|
|
self.rot.angle += delta * 100
|
|
|
|
def setup_scene(self):
|
|
Color(1, 1, 1, 1)
|
|
PushMatrix()
|
|
Translate(0, 0, -3)
|
|
self.rot = Rotate(1, 0, 1, 0)
|
|
m = list(self.scene.objects.values())[0]
|
|
UpdateNormalMatrix()
|
|
self.mesh = Mesh(
|
|
vertices=m.vertices,
|
|
indices=m.indices,
|
|
fmt=m.vertex_format,
|
|
mode='triangles',
|
|
)
|
|
PopMatrix()
|
|
|
|
|
|
class RendererApp(App):
|
|
def build(self):
|
|
return Renderer()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
RendererApp().run()
|