Last active
March 1, 2020 19:50
-
-
Save tito/8770e36845fd14f4df3c30b2031318cf to your computer and use it in GitHub Desktop.
Panda3D with Kivy WRAPPER (Windows and Linux)
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 pandawrapper import PandaApp | |
from kivy.base import runTouchApp | |
try: | |
from kaki.app import App | |
with_kaki = True | |
except ImportError: | |
from kivy.app import App | |
with_kaki = False | |
from kivy.factory import Factory as F | |
class OmanApp(App): | |
IDLE_DETECTION = True | |
AUTORELOADER_IGNORE_PATTERNS = [ | |
"*__pycache__*", | |
"*.cache*", | |
"*.log" | |
] | |
AUTORELOADER_PATHS = [ | |
(".", {"recursive": True}) | |
] | |
def build_app(self): | |
# build your app here as usual | |
return F.Button(size_hint=(.5, .5), text="Hello") | |
if not with_kaki: | |
def build(self): | |
return self.build_app() | |
# pandawrapper support | |
def build_panda_app(self): | |
self.panda_app = base = PandaApp() | |
def run(self): | |
self.build_panda_app() | |
self.load_config() | |
self.load_kv(filename=self.kv_file) | |
root = self.build() | |
if root is not None: | |
self.root = root | |
runTouchApp(self.root, slave=True) | |
self.panda_app.run() | |
self.stop() | |
if __name__ == "__main__": | |
OmanApp().run()(oman) |
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
import os | |
import sys | |
os.environ["KIVY_WINDOW"] = "" | |
if sys.platform == "linux": | |
os.environ["KIVY_GL_BACKEND"] = "gl" | |
import kivy.core | |
orig_core_select_lib = kivy.core.core_select_lib | |
def core_select_lib_hide_window(category, *largs, **kwargs): | |
if category == "window": | |
return | |
return orig_core_select_lib(category, *largs, **kwargs) | |
kivy.core.core_select_lib = core_select_lib_hide_window | |
import kivy.core.window | |
from kivy.app import App | |
from kivy.config import Config | |
from kivy.base import EventLoop, runTouchApp, stopTouchApp | |
from kivy.core.window import WindowBase | |
from kivy.graphics import opengl as gl | |
from kivy.lang import Builder | |
from kivy.properties import ObjectProperty | |
from kivy.clock import Clock | |
from direct.showbase.ShowBase import ShowBase | |
from panda3d.core import ( | |
CallbackNode, Camera, NodePath, MouseWatcher, loadPrcFileData) | |
from direct.showbase import DirectObject | |
base = None | |
class MouseWrapper(DirectObject.DirectObject): | |
def __init__(self, window): | |
super().__init__() | |
self.window = window | |
self.accept('mouse1', self.on_mouse_1) | |
self.accept('mouse1-up', self.on_mouse_up_1) | |
self.accept('mouse3', self.on_mouse_2) | |
self.accept('mouse3-up', self.on_mouse_up_2) | |
def on_mouse_1(self): | |
self.window.have_touch_down += 1 | |
self.window.dispatch_mouse('on_mouse_down', 'left') | |
def on_mouse_up_1(self): | |
self.window.have_touch_down -= 1 | |
self.window.dispatch_mouse('on_mouse_up', 'left') | |
def on_mouse_2(self): | |
self.window.have_touch_down += 1 | |
self.window.dispatch_mouse('on_mouse_down', 'right') | |
def on_mouse_up_2(self): | |
self.window.have_touch_down -= 1 | |
self.window.dispatch_mouse('on_mouse_up', 'right') | |
class KivyWindow(WindowBase): | |
_clearcolor = ObjectProperty() | |
def __init__(self, panda_app, display_region, **kwargs): | |
self.panda_app = panda_app | |
display_region.set_draw_callback(self.on_panda_draw) | |
self.mouse_wrapper = MouseWrapper(self) | |
self.have_touch_down = 0 | |
super().__init__(**kwargs) | |
Clock.schedule_interval(lambda _: self.canvas.ask_update(), 0) | |
kivy.core.window.Window = self | |
def _prepare_gl_context(self, *largs): | |
self.reset_gl_context() | |
gl.glEnableVertexAttribArray(0) | |
gl.glEnableVertexAttribArray(1) | |
def _leave_gl_context(self, *largs): | |
gl.glDisableVertexAttribArray(0) | |
gl.glDisableVertexAttribArray(1) | |
def reset_gl_context(self): | |
gl.glEnable(gl.GL_BLEND) | |
gl.glDisable(gl.GL_DEPTH_TEST) | |
gl.glEnable(gl.GL_STENCIL_TEST) | |
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) | |
gl.glBlendFuncSeparate(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA, gl.GL_ONE, gl.GL_ONE) | |
gl.glActiveTexture(gl.GL_TEXTURE0) | |
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) | |
def on_panda_draw(self, data=None): | |
self.update_mouse() | |
if data: | |
self.size = list(self.panda_app.win.get_size()) | |
self._prepare_gl_context() | |
EventLoop.idle() | |
self._leave_gl_context() | |
def update_mouse(self): | |
if self.have_touch_down: | |
x, y = self.get_mouse_position() | |
self.dispatch('on_mouse_move', x, y, []) | |
def dispatch_mouse(self, event_name, btn=None): | |
x, y = self.get_mouse_position() | |
self.dispatch(event_name, x, y, btn, []) | |
def get_mouse_position(self): | |
mw = base.mouseWatcherNode | |
if not mw.hasMouse(): | |
return 0, 0 | |
w, h = self.system_size | |
x, y = mw.getMouseX(), mw.getMouseY() | |
lx = (x + 1) / 2 | |
ly = 1 - (y + 1) / 2 | |
return lx * w, ly * h | |
class PandaApp(ShowBase): | |
def __init__(self): | |
global base | |
base = self | |
width = Config.getint("graphics", "width") | |
height = Config.getint("graphics", "height") | |
loadPrcFileData("", "load-file-type p3assimp") | |
loadPrcFileData("", "framebuffer-multisample 1") | |
loadPrcFileData("", "framebuffer-srgb true") | |
loadPrcFileData("", "multisamples 2") | |
loadPrcFileData("", f"win-size {width} {height}") | |
ShowBase.__init__(self) | |
self.display_region = self.win.make_display_region() | |
self.display_region.set_sort(30) | |
self.disable_mouse() | |
self.accept("escape", self.on_escape) | |
self.kivy_window = KivyWindow( | |
panda_app=self, | |
display_region=self.display_region, | |
) | |
def on_escape(self): | |
stopTouchApp() | |
self.userExit() | |
class PandaWrapperApp(App): | |
def build_panda_app(self): | |
self.panda_app = base = PandaApp() | |
def run(self): | |
self.build_panda_app() | |
self.load_config() | |
self.load_kv(filename=self.kv_file) | |
root = self.build() | |
if root is not None: | |
self.root = root | |
runTouchApp(self.root, slave=True) | |
self.panda_app.run() | |
self.stop() | |
if __name__ == "__main__": | |
from kivy.factory import Factory as F | |
class PandaTestApp(PandaWrapperApp): | |
def build(self): | |
btn = F.Button( | |
size_hint_y=None, | |
text="Hello world") | |
# build panda scene | |
scene = self.panda_app.loader.loadModel('models/environment') | |
scene.reparentTo(self.panda_app.render) | |
scene.setScale(0.25, 0.25, 0.25) | |
return btn | |
PandaTestApp().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment