Last active
November 23, 2017 14:36
-
-
Save onslauth/a79759324bb692b8f4a0f5ff4b131bd8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://imgur.com/a/1hBQr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from kivy.uix.widget import Widget | |
from kivy.resources import resource_find | |
from kivy.uix.image import Image | |
from kivy.graphics.fbo import Fbo | |
from kivy.graphics import ( | |
Callback, PushMatrix, PopMatrix, Rotate, Translate, Scale, | |
Rectangle, Color, Mesh, UpdateNormalMatrix, Canvas) | |
from kivy.graphics.transformation import Matrix | |
from kivy.graphics.opengl import ( | |
glEnable, glDisable, GL_DEPTH_TEST) | |
from kivy.properties import ( | |
StringProperty, ListProperty, ObjectProperty, NumericProperty, | |
BooleanProperty, DictProperty) | |
from os.path import join, dirname | |
import numpy as np | |
class ObjectRenderer(Widget): | |
obj_translation = ListProperty([0, 0, 0]) | |
obj_rotation = ListProperty([0, 0, 0]) | |
obj_scale = NumericProperty(1) | |
obj_texture = StringProperty('') | |
texture = ObjectProperty(None, allownone=True) | |
cam_translation = ListProperty([0, 0, 0]) | |
cam_rotation = ListProperty([0, 0, 0]) | |
display_all = BooleanProperty(True) | |
light_sources = DictProperty() | |
ambiant = NumericProperty(.5) | |
diffuse = NumericProperty(.5) | |
specular = NumericProperty(.5) | |
mode = StringProperty('triangles') | |
def __init__(self, **kwargs): | |
self.canvas = Canvas() | |
with self.canvas: | |
self.fbo = Fbo(size=self.size, | |
with_depthbuffer=True, | |
compute_normal_mat=True, | |
clear_color=(0., 0., 0., 0.)) | |
self.viewport = Rectangle(size=self.size, pos=self.pos) | |
self.fbo.shader.source = resource_find( | |
join(dirname(__file__), 'shaders.glsl')) | |
self.vertex_format = [ ( b'v_pos', 3, 'float' ), | |
( b'v_color', 4, 'float' ), | |
( b'v_tc0', 2, 'float' ) ] | |
super(ObjectRenderer, self).__init__(**kwargs) | |
def on_obj_rotation(self, *args): | |
self.obj_rot_x.angle = self.obj_rotation[0] | |
self.obj_rot_y.angle = self.obj_rotation[1] | |
self.obj_rot_z.angle = self.obj_rotation[2] | |
def on_cam_rotation(self, *args): | |
self.cam_rot_x.angle = self.cam_rotation[0] | |
self.cam_rot_y.angle = self.cam_rotation[1] | |
self.cam_rot_z.angle = self.cam_rotation[2] | |
def on_obj_translation(self, *args): | |
self.obj_translate.xyz = self.cam_translation | |
def on_cam_translation(self, *args): | |
self.cam_translate.xyz = self.cam_translation | |
def on_obj_scale(self, *args): | |
self.scale.xyz = [self.obj_scale, ] * 3 | |
def on_display_all(self, *args): | |
self.setup_canvas() | |
def on_light_sources(self, *args): | |
self.fbo['light_sources'] = [ | |
ls[:] for ls in self.light_sources.values()] | |
self.fbo['nb_lights'] = len(self.light_sources) | |
def on_ambiant(self, *args): | |
self.fbo['ambiant'] = self.ambiant | |
def on_diffuse(self, *args): | |
self.fbo['diffuse'] = self.diffuse | |
def on_specular(self, *args): | |
self.fbo['specular'] = self.specular | |
def on_mode(self, *args): | |
self.setup_canvas() | |
def setup_canvas(self, *args): | |
with self.fbo: | |
self.fbo['ambiant'] = self.ambiant | |
self.fbo['diffuse'] = self.diffuse | |
self.fbo['specular'] = self.specular | |
self.cb = Callback(self.setup_gl_context) | |
PushMatrix() | |
self.setup_scene() | |
PopMatrix() | |
self.cb = Callback(self.reset_gl_context) | |
def on_size(self, instance, value): | |
self.fbo.size = value | |
self.viewport.texture = self.fbo.texture | |
self.viewport.size = value | |
self.update_glsl() | |
def on_pos(self, instance, value): | |
self.viewport.pos = value | |
def on_texture(self, instance, value): | |
self.viewport.texture = value | |
def setup_gl_context(self, *args): | |
glEnable(GL_DEPTH_TEST) | |
self.fbo.clear_buffer() | |
def reset_gl_context(self, *args): | |
glDisable(GL_DEPTH_TEST) | |
def update_glsl(self, *args): | |
asp = self.width / float(self.height) | |
proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1) | |
self.fbo['projection_mat'] = proj | |
def setup_scene(self): | |
Color(1, 1, 1, 0) | |
PushMatrix() | |
self.cam_translate = Translate(self.cam_translation) | |
# Rotate(0, 1, 0, 0) | |
self.cam_rot_x = Rotate(self.cam_rotation[0], 1, 0, 0) | |
self.cam_rot_y = Rotate(self.cam_rotation[1], 0, 1, 0) | |
self.cam_rot_z = Rotate(self.cam_rotation[2], 0, 0, 1) | |
self.scale = Scale(self.obj_scale) | |
UpdateNormalMatrix() | |
self.draw_object() | |
PopMatrix() | |
def draw_object(self): | |
self.obj_rot_x = Rotate(self.obj_rotation[0], 1, 0, 0) | |
self.obj_rot_y = Rotate(self.obj_rotation[1], 0, 1, 0) | |
self.obj_rot_z = Rotate(self.obj_rotation[2], 0, 0, 1) | |
self.obj_translate = Translate(xyz=self.obj_translation) | |
texture = None | |
vertices = np.zeros( ( 3, 9 ), 'f' ) | |
vertices[ 0 ] = [ -0.5, -0.5, -1, 0, 0, 1, 1, 0, 0 ] | |
vertices[ 1 ] = [ -0.5, 0.5, -1, 0, 0, 1, 1, 0, 0 ] | |
vertices[ 2 ] = [ 0.5, 0.5, -1, 0, 0, 1, 1, 0, 0 ] | |
indices = [ 0, 1, 2 ] | |
Mesh( | |
vertices=vertices.ravel( ), | |
indices=indices, | |
fmt=self.vertex_format, | |
mode=self.mode) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* simple.glsl | |
simple diffuse lighting based on laberts cosine law; see e.g.: | |
http://en.wikipedia.org/wiki/Lambertian_reflectance | |
http://en.wikipedia.org/wiki/Lambert%27s_cosine_law | |
*/ | |
---VERTEX SHADER------------------------------------------------------- | |
#ifdef GL_ES | |
precision highp float; | |
#endif | |
attribute vec3 v_pos; | |
attribute vec3 v_normal; | |
attribute vec4 v_color; | |
attribute vec2 v_tc0; | |
uniform mat4 modelview_mat; | |
uniform mat4 projection_mat; | |
uniform float Tr; | |
varying vec4 normal_vec; | |
varying vec4 vertex_pos; | |
varying vec4 color_vec; | |
varying vec2 tc0_vec; | |
void main (void) { | |
//compute vertex position in eye_sapce and normalize normal vector | |
vec4 pos = modelview_mat * vec4(v_pos,1.0); | |
vertex_pos = pos; | |
normal_vec = vec4(v_normal,0.0); | |
color_vec = v_color; | |
tc0_vec = v_tc0; | |
gl_Position = projection_mat * pos; | |
} | |
---FRAGMENT SHADER----------------------------------------------------- | |
#ifdef GL_ES | |
precision highp float; | |
#endif | |
varying vec4 normal_vec; | |
varying vec4 vertex_pos; | |
varying vec4 color_vec; | |
varying vec2 tc0_vec; | |
uniform sampler2D texture0; | |
uniform mat4 normal_mat; | |
uniform vec3 Kd; | |
uniform vec3 Ka; | |
uniform vec3 Ks; | |
uniform float Tr; | |
uniform float Ns; | |
uniform float intensity; | |
void main (void){ | |
//correct normal, and compute light vector (assume light at the eye) | |
vec4 v_normal = normalize( normal_mat * normal_vec ); | |
vec4 v_light = normalize( vec4(0,0,0,1) - vertex_pos ); | |
//reflectance based on lamberts law of cosine | |
vec3 Ia = intensity*Kd; | |
vec3 Id = intensity*Ka * max(dot(v_light, v_normal), 0.0); | |
vec3 Is = intensity*Ks * pow(max(dot(v_light, v_normal), 0.0), Ns); | |
//gl_FragColor = vec4(Ia + Id + Is, Tr); | |
vec4 t = texture2D( texture0, tc0_vec ); | |
gl_FragColor = t * color_vec; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment