如何在Kivy中更改3D网格的颜色?

时间:2014-08-02 14:44:33

标签: python 3d kivy

我想用Kivy渲染3D网格,我可以翻译,旋转和改变颜色。我设法简化/编辑Niko Skrypnik's Rubik's cube,现在我有了这个代码,它只是呈现一个可旋转的红色方块:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.resources import resource_find
from kivy.graphics.transformation import Matrix
from kivy.graphics import *

class Renderer(Widget):
    def __init__(self, **kw):
        self.vertices = [[ -1,-1, 0,
                            1,-1, 0,
                            1, 1,-0,
                           -1, 1, 0]]

        kw['shader_file'] = 'shaders.glsl'
        self.canvas = RenderContext(compute_normal_mat=True)
        shader_file = kw.pop('shader_file')
        self.canvas.shader.source = resource_find(shader_file)

        with self.canvas:
            Translate(0, 0, -4.5)
            self.rot = Rotate(0, 1, 1, 1)
            ChangeState(Kd=(1.0, 0.0, 0.0),
                        Ka=(1.0, 0.0, 0.0),
                        Ks=(.3, .3, .3),
                        Tr=1.,
                        Ns=1.,
                        intensity=1.)
            for i in xrange(len(self.vertices)):
                Mesh(   vertices=self.vertices[i],
                        indices=[0, 1, 2, 3, 0, 2],
                        fmt=[('v_pos', 3, 'float')],
                        mode='triangles')

        asp = float(Window.width) / Window.height / 2.0
        proj = Matrix().view_clip(-asp, asp, -0.5, 0.5, 1, 100, 1)
        self.canvas['projection_mat'] = proj

        Window.request_keyboard(None, self).bind(on_key_down = self.on_keyboard_down)

    def on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == "left": self.rot.angle -= 10
        elif keycode[1] == "right": self.rot.angle += 10

class MyApp(App):
     def build(self):
         return Renderer()

if __name__ == '__main__':
     MyApp().run()

注意:我在Github的Rubik立方体项目中使用了shaders.glsl

使用相同的原理我可以翻译或缩放它,但我还没弄明白如何改变它的颜色。唯一有效的方法是基本上清理画布并再次渲染它,但我相信有更好的方法 有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:0)

您可以通过RenderContext __setitem__将统一变量传递给着色器。在这种情况下,颜色(固有和光照)都是通过Kd和Ka变量,所以你可以这样做:

self.canvas['Kd'] = [0., 1., 0.]
self.canvas['Ka'] = [0., 1., 0.]

这应该使一切都变绿。

你可以(当然)为着色器中的任何其他统一变量做类似的事情。