Я пишу приложение на Python, использующее Kivy для рендеринга графики.Я хотел бы узнать, как получить доступ к текущей матрице представления модели в kivy, той же самой матрице, что и в вершинном шейдере.
Вот мой пример кода (Python 2.7, Kivy 1.9):
#!/usr/bin/env python
from kivy.app import App
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.graphics import *
from kivy.graphics.transformation import Matrix
from kivy.resources import resource_find
from kivy.uix.widget import Widget
vertices = [0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
2.0, 0.0, 0.0, 0.0, 0.0, 1.0,
0.0, 2.0, 0.0, 0.0, 0.0, 1.0,
2.0, 2.0, 0.0, 0.0, 0.0, 1.0]
indices = [0, 1, 2, 1, 2, 3]
vformat = [(b'v_pos', 3, 'float'), (b'v_normal', 3, 'float')]
class Renderer(Widget):
def __init__(self, **kwargs):
super(Renderer, self).__init__(**kwargs)
self.canvas = RenderContext(compute_normal_mat=True)
self.canvas.shader.source = resource_find('simple.glsl')
with self.canvas:
PushMatrix()
Translate(0, -1, -3)
self.rot = Rotate(1, 0, 1, 0)
UpdateNormalMatrix()
self.mesh = Mesh(vertices=vertices, indices=indices,
fmt=vformat, mode='triangles')
PopMatrix()
Clock.schedule_interval(self.update_glsl, 1 / 60.)
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.rot.angle += delta * 100
print self.canvas['modelview_mat']
class RendererApp(App):
def build(self):
return Renderer()
if __name__ == "__main__":
RendererApp().run()
и файл шейдера simple.glsl :
---VERTEX SHADER-----------------------------------
attribute vec3 v_pos;
attribute vec3 v_normal;
uniform mat4 modelview_mat;
uniform mat4 projection_mat;
varying vec4 normal_vec;
void main (void) {
normal_vec = vec4(v_normal, 0.0);
gl_Position = projection_mat * modelview_mat * vec4(v_pos, 1.0);
}
---FRAGMENT SHADER---------------------------------
uniform mat4 normal_mat;
varying vec4 normal_vec;
void main (void){
vec4 v_normal = normalize( normal_mat * normal_vec ) ;
float theta = clamp(abs(dot(v_normal, vec4(0.0, 0.0, 1.0, 1.0))), 0.0, 1.0);
gl_FragColor = vec4(theta, theta, theta, 1.0);
}
В функции update_glsl
мне нужна текущая матрица представления модели для некоторых вычислений.Я пытался self.canvas['modelview_mat']
, но это всегда дает мне матрицу идентичности.