[Python, Работа с 3D-графикой, Разработка мобильных приложений] Кроссплатформенные OpenGL + Python при помощи Kivy
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Предыстория: будучи наивным чукотским программистом, я думал: "питон такой кроссплатформенный, напишу игрушку для сына, запущу на планшетике, пусть играется". В результате две недели ушло на попытки натыкать решение по переезду с PyOpenGL+pygame на kivy, так как внятного примера использования OpenGL с kivy не нашел. Возможно, кому-то мой опыт поможет сэкономить время.
Примерная схема процессаДисклеймер:
- Никого не призываю разрабатывать на python приложения с 3д-графикой под андроид. Это не самый шустрый вариант. Но если очень хочется, то можно читать дальше.
- В kivy есть встроенное-своё-родное решение Mesh, которое умеет в 3д-графику. С примерами тоже не всё так просто. Я предпочел голый OpenGL.
- Возможно, я открыл Америку в попытках найти Индию. Надеюсь, более опытные товарищи поправят и дополнят.
Перед тем, как начать работать с 3D графикой в kivy, стоит почитать про библиотеку вообще и про её установку (например, мануалы рекомендуют использовать виртуальную среду).В чем проблема? Описание функций OpenGL разработчики kivy коварно прячут на своём официальном сайте. Вопрос только в том, как заставить это работать.За исключением нескольких нюансов, переезд с PyOpenGL+pygame на kivy касательно использования функций собственно OpenGL заключается в замене строчек:
from OpenGL.GL import *
from OpenGL.GL.shaders import *
на:
from kivy.graphics.opengl import *
Нюансы: PyOpenGL работает с массивами numpy напрямую, в kivy приходится преобразовывать их функцией tobytes(). Для загрузки текстур в kivy используется glPixelStorei и glTexImage2D вместо glTexStorage2D и glTexSubImage2D. Шейдеры под андроид должны быть под версию 2 (без in, out и прочих излишеств) и иметь в начале код:
#ifdef GL_ES
precision highp float;
#endif
Далее самое интересное - это всё надо как-то подключить к выводу на экран. В связке PyOpenGL+pygame код имеет такую структуру:
#Было:
import pygame
from pygame.locals import *
def init():
pygame.init()
pygame.display.set_mode((Width, Height), HWSURFACE | OPENGL | DOUBLEBUF)
''' дальше идут функции, инициализирующие работу с PyOpenGL '''
def main():
init()
while True:
''' меняем вершины и запускаем отрисовку '''
pygame.display.flip()
В kivy надо создать класс приложения на основе класса App, в котором необходимо сослаться на виджет, унаследованный от класса Widget. Кроме того, нам понадобится объект Window, который автоматически создается при работе с kivy с учетом используемой операционной системы. Базовый класс у Window - WindowBase.Таким образом структура приложения будет примерно такой:
#Стало:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.base import EventLoop
from kivy.clock import Clock
def init():
''' почти те же функции, инициализирующие работу с OpenGL '''
init()
class CustomWidget(Widget):
def __init__(self, **kwargs):
super(CustomWidget, self).__init__(**kwargs)
def update_glsl(self, nap):
''' здесь меняем вершины и запускаем отрисовку '''
Window.flip()
class MainApp(App):
def build(self):
root = CustomWidget()
EventLoop.ensure_window()
return root
def on_start(self):
Clock.schedule_interval(self.root.update_glsl, 40 ** -1) #это наш желательный FPS
if __name__ == '__main__':
MainApp().run()
Этот код уже покажет картинку (если добавить соответствующий функционал OpenGL), но картинка будет мерзко мигать. Это происходит потому, что у объекта Window есть свой вызов функции flip(), который вставляет чёрный экран в наш вывод. Этот вызов описан в упомянутом классе WindowBase. Добавим следующий код, отключающий лишний флип, в описание класса MainApp:
def passFunc(W):
pass
class MainApp(App):
def build(self):
root = CustomWidget()
EventLoop.ensure_window()
#вот тут отключаем лишний флип:
Window.on_flip = lambda W = Window: passFunc(W)
return root
Что дальше? После заполнения пробелов в этом коде, между программистом и apk-файлом остаётся только билдозер. Вот мануал, которого достаточно даже для непродвинутого юзера вроде меня (см. также подпись к видео, там есть скрипт, сильно упрощающий работу):Извините, данный ресурс не поддреживается. :( Кроме того в spec-файле рекомендую включить полноэкранный режим для пущего фпс.Example вот. Код рисует инопланетянина с логотипа андроида (как на КДПВ), позволяет его вращать с помощью мышки/сенсора.А что там всё-таки с производительностью? Ну такое. Написал небольшую игрушку - змейку в трехмерном пространстве. FPS на самсунг А51 болтается между 15 и 25. Видео записано с телефона:Извините, данный ресурс не поддреживается. :( Сын, между тем, отказался играться в моё поделие, ну хотя бы смотрит с интересом. Плоские рисованные игры двухлетке, оказывается, лучше заходят. Вот ради чего всё начиналось:Извините, данный ресурс не поддреживается. :( Стиль рубленой змеи - пара скриншотов с этапа отладки как дань уважения Джеки Чану:
Авангард 1
Авангард 2
При отладке текстур возникает желание использовать настроечную таблицу от старого телевещания
===========
Источник:
habr.com
===========
Похожие новости:
- [Python, Разработка под MacOS, Разработка под Linux, Разработка под Windows] Трепещущий Kivy. Обзор возможностей фреймворка Kivy и библиотеки KivyMD
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android] Робопрактика в режиме онлайн для мобильных разработчиков в red_mad_robot
- [Python, JavaScript, C#, Логические игры] 10 лучших игр по программированию, которые улучшат ваши навыки (перевод)
- [Анализ и проектирование систем, Работа с 3D-графикой, Алгоритмы, Графический дизайн] Студенческая Лунная площадка может помочь NASA совершить посадку на Луну (перевод)
- [Разработка мобильных приложений, Разработка под Android, Локализация продуктов] CompositionLocal в Jetpack Compose. Что это и как с его помощью реализовать реактивную локализацию приложения
- [Разработка под iOS, Разработка мобильных приложений, Разработка игр, Unity] Запуск игры на Unity из приложения SwiftUI для iOS (перевод)
- [Совершенный код, Разработка мобильных приложений, Разработка под Android, Kotlin] Kotlin Best Practices
- [Информационная безопасность, Python, Тестирование веб-сервисов] Пишем расширение для Burp Suite с помощью Python
- [Python, PostgreSQL] Обрезаем большую таблицу PostgreSQL в production
- [Python, Программирование, Машинное обучение] Взлом reCAPTCHA v2
Теги для поиска: #_python, #_rabota_s_3dgrafikoj (Работа с 3D-графикой), #_razrabotka_mobilnyh_prilozhenij (Разработка мобильных приложений), #_opengl, #_python, #_android, #_3dgrafika (3d-графика), #_python, #_rabota_s_3dgrafikoj (
Работа с 3D-графикой
), #_razrabotka_mobilnyh_prilozhenij (
Разработка мобильных приложений
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:50
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Предыстория: будучи наивным чукотским программистом, я думал: "питон такой кроссплатформенный, напишу игрушку для сына, запущу на планшетике, пусть играется". В результате две недели ушло на попытки натыкать решение по переезду с PyOpenGL+pygame на kivy, так как внятного примера использования OpenGL с kivy не нашел. Возможно, кому-то мой опыт поможет сэкономить время. Примерная схема процессаДисклеймер:
from OpenGL.GL import *
from OpenGL.GL.shaders import * from kivy.graphics.opengl import *
#ifdef GL_ES
precision highp float; #endif #Было:
import pygame from pygame.locals import * def init(): pygame.init() pygame.display.set_mode((Width, Height), HWSURFACE | OPENGL | DOUBLEBUF) ''' дальше идут функции, инициализирующие работу с PyOpenGL ''' def main(): init() while True: ''' меняем вершины и запускаем отрисовку ''' pygame.display.flip() #Стало:
from kivy.app import App from kivy.uix.widget import Widget from kivy.core.window import Window from kivy.base import EventLoop from kivy.clock import Clock def init(): ''' почти те же функции, инициализирующие работу с OpenGL ''' init() class CustomWidget(Widget): def __init__(self, **kwargs): super(CustomWidget, self).__init__(**kwargs) def update_glsl(self, nap): ''' здесь меняем вершины и запускаем отрисовку ''' Window.flip() class MainApp(App): def build(self): root = CustomWidget() EventLoop.ensure_window() return root def on_start(self): Clock.schedule_interval(self.root.update_glsl, 40 ** -1) #это наш желательный FPS if __name__ == '__main__': MainApp().run() def passFunc(W):
pass class MainApp(App): def build(self): root = CustomWidget() EventLoop.ensure_window() #вот тут отключаем лишний флип: Window.on_flip = lambda W = Window: passFunc(W) return root Авангард 1 Авангард 2 При отладке текстур возникает желание использовать настроечную таблицу от старого телевещания =========== Источник: habr.com =========== Похожие новости:
Работа с 3D-графикой ), #_razrabotka_mobilnyh_prilozhenij ( Разработка мобильных приложений ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:50
Часовой пояс: UTC + 5