我写了一个简单的例子来说明这个问题。
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 *
from kivy.graphics.opengl import *
import random
class Root(Widget):
def __init__(self, *larg, **kw):
super(Root, self).__init__(*larg, **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:
self.cb = Callback(self.setup_gl_context)
PushMatrix()
Translate(0, 0, -5)
for i in xrange(10):
Translate(.5, 0, -.5)
self.render(self.vertices, (random.random(), random.random(), random.random()))
PopMatrix()
self.cb = Callback(self.reset_gl_context)
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
def setup_gl_context(self, *args):
glEnable(GL_DEPTH_TEST)
def reset_gl_context(self, *args):
glDisable(GL_DEPTH_TEST)
def render(self, vertices, color):
for i in xrange(len(vertices)):
ChangeState(Kd=color, Ka=color, Ks=(.3, .3, .3), Tr=1., Ns=1., intensity=1.)
Mesh(vertices=vertices[i], indices=[0, 1, 2, 3, 0, 2], fmt=[('v_pos', 3, 'float')], mode='triangles')
class TestApp(App):
def build(self):
return Root()
if __name__ == '__main__':
TestApp().run()
注意:我使用过这个 shaders.glsl
。
它渲染10个正方形,这些正方形具有相同的尺寸,但颜色随机。每个新方块都是由相对翻译的Translate(.5, 0, -.5)
,因此最后渲染的方块是最远的方块。既然有glEnable(GL_DEPTH_TEST)
,当我在Linux上运行它时,它可以正确呈现:
但我创造* .apk文件使用Buildozer后(在buildzer.spec
我只改title
,name
,version
并添加glsl
到include_exts
),并运行它在Android(4.4),它是uncorrectly呈现(例如,如果GL_DEPTH_TEST
被禁用):
The problem might be the difference between OpenGL ES and OpengGL, but I think, that GL_DEPTH_TEST
should work on both. Also there might be a problem with packaging, but it does not seem like it. Can anyone help me, please?
As Reto Koradi had suggested, I looked again even deeper into the Kivy documentation. I discovered Framebuffer (module kivy.graphics.fbo
), which is an offscreen window, that acts like a Kivy Canvas. It (probably unlike Canvas) has with_depthbuffer
parameter, which is set to False
by default.
So the solution was to set with_depthbuffer = True
in Framebuffer and then use the Framebuffer's rendered texture in Canvas in order to display it.
我不确定为什么这对于Android是必需的,但对于Linux不是必需的。还有一个更好的选择,它不包括创建(有时是无意义的)帧缓冲,但是这种方法至少在两个平台上都适用。
我修改了示例代码:
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 *
from kivy.graphics.opengl import *
import random
class Root(Widget):
def __init__(self, *larg, **kw):
super(Root, self).__init__(*larg, **kw)
self.vertices = [[-1,-1, 0, 1,-1, 0, 1, 1, 0, -1, 1, 0]]
with self.canvas:
self.fbo = Fbo(with_depthbuffer = True, size = Window.size)
Rectangle(size=Window.size, texture=self.fbo.texture)
kw['shader_file'] = 'shaders.glsl'
shader_file = kw.pop('shader_file')
self.fbo.shader.source = resource_find(shader_file)
with self.fbo:
self.cb = Callback(self.setup_gl_context)
PushMatrix()
Translate(0, 0, -5)
for i in xrange(10):
Translate(.5, 0, -.5)
self.render(self.vertices, (random.random(), random.random(), random.random()))
PopMatrix()
self.cb = Callback(self.reset_gl_context)
asp = float(Window.width) / Window.height / 2.0
proj = Matrix().view_clip(-asp, asp, -0.5, 0.5, 1, 100, 1)
self.fbo['projection_mat'] = proj
def setup_gl_context(self, *args):
glEnable(GL_DEPTH_TEST)
def reset_gl_context(self, *args):
glDisable(GL_DEPTH_TEST)
def render(self, vertices, color):
for i in xrange(len(vertices)):
ChangeState(Kd=color, Ka=color, Ks=(.3, .3, .3), Tr=1., Ns=1., intensity=1.)
Mesh(vertices=vertices[i], indices=[0, 1, 2, 3, 0, 2], fmt=[('v_pos', 3, 'float')], mode='triangles')
class TestApp(App):
def build(self):
return Root()
if __name__ == '__main__':
TestApp().run()
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句