- Kivy 教程
- Kivy - 首頁
- Kivy 基礎
- Kivy - 開始
- Kivy - 安裝
- Kivy - 架構
- Kivy - 檔案語法
- Kivy - 應用
- Kivy - Hello World
- Kivy - 應用生命週期
- Kivy - 事件
- Kivy - 屬性
- Kivy - 輸入
- Kivy - 行為
- Kivy 按鈕
- Kivy - 按鈕
- Kivy - 按鈕事件
- Kivy - 按鈕顏色
- Kivy - 按鈕大小
- Kivy - 按鈕位置
- Kivy - 圓形按鈕
- Kivy - 停用按鈕
- Kivy - 圖片按鈕
- Kivy 小部件
- Kivy - 小部件
- Kivy - 標籤
- Kivy - 文字輸入
- Kivy - 畫布
- Kivy - 直線
- Kivy - 複選框
- Kivy - 下拉列表
- Kivy - 視窗
- Kivy - 滾動檢視
- Kivy - 輪播
- Kivy - 滑塊
- Kivy - 圖片
- Kivy - 彈出視窗
- Kivy - 開關
- Kivy - 微調器
- Kivy - 分隔器
- Kivy - 進度條
- Kivy - 氣泡
- Kivy - 標籤面板
- Kivy - 散點圖
- Kivy - 手風琴
- Kivy - 檔案選擇器
- Kivy - 顏色選擇器
- Kivy - 程式碼輸入
- Kivy - 模態檢視
- Kivy - 切換按鈕
- Kivy - 相機
- Kivy - 樹檢視
- Kivy - reStructuredText
- Kivy - 動作欄
- Kivy - 播放器
- Kivy - 模板檢視
- Kivy - 虛擬鍵盤
- Kivy - 觸控漣漪
- Kivy - 音訊
- Kivy - 影片
- Kivy - 拼寫檢查
- Kivy - 效果
- Kivy - 輸入記錄器
- Kivy - OpenGL
- Kivy - 文字
- Kivy - 文字標記
- Kivy - 設定
- Kivy 佈局
- Kivy - 佈局
- Kivy - 浮動佈局
- Kivy - 網格佈局
- Kivy - 箱式佈局
- Kivy - 堆疊佈局
- Kivy - 錨點佈局
- Kivy - 相對佈局
- Kivy - 分頁佈局
- Kivy - 迴圈佈局
- Kivy - 佈局巢狀
- Kivy 高階概念
- Kivy - 配置物件
- Kivy - 圖集
- Kivy - 資料載入器
- Kivy - 快取管理器
- Kivy - 控制檯
- Kivy - 動畫
- Kivy - 多筆畫
- Kivy - 時鐘
- Kivy - SVG
- Kivy - UrlRequest
- Kivy - 剪貼簿
- Kivy - 工廠
- Kivy - 手勢
- Kivy - 語言
- Kivy - 圖形
- Kivy - 繪圖
- Kivy - 打包
- Kivy - Garden
- Kivy - 儲存
- Kivy - 向量
- Kivy - 工具函式
- Kivy - 檢查器
- Kivy - 工具
- Kivy - 日誌記錄器
- Kivy - 幀緩衝區
- Kivy 應用和專案
- Kivy - 繪圖應用
- Kivy - 計算器應用
- Kivy - 秒錶應用
- Kivy - 相機處理
- Kivy - 圖片檢視器
- Kivy - 貝塞爾曲線
- Kivy - 畫布壓力測試
- Kivy - 繪製圓形
- Kivy - 小部件動畫
- Kivy - 其他
- Kivy 有用資源
- Kivy - 快速指南
- Kivy - 有用資源
- Kivy - 討論
Kivy - OpenGL
Kivy 框架擁有強大的圖形功能,其構建在 OpenGL 和 SDL 指令之上。Kivy 使用 OpenGL ES 2 圖形庫,並基於頂點緩衝物件和著色器。“kivy.graphics.opengl” 模組是圍繞 OpenGL 命令的 Python 包裝器。
著色器是使用者定義的程式,旨在在圖形處理器的某些階段執行。著色器是用 OpenGL 著色語言 (GLSL) 編寫的,這是一種高階著色語言,其語法基於 C 程式語言。
在 Web 上建立圖形的兩種常用著色器是頂點著色器和片段(畫素)著色器。
頂點著色器 - 它們接收來自先前流水線階段的輸入(例如頂點位置、顏色和光柵化畫素),並自定義輸出到下一個階段。
片段著色器 - 它們接收所有畫素的二維位置作為輸入,並自定義每個畫素的輸出顏色。
本教程不詳細討論 GLSL 的功能和語法。我們將在本章中使用一個開源著色器檔案 (kaleidoscope.glsl)。
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;
uniform sampler2D tex1;
void main(void){
vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
vec2 uv;
float a = atan(p.y,p.x);
float r = sqrt(dot(p,p));
uv.x = 7.0*a/3.1416;
uv.y = -time+ sin(7.0*r+time) + .7*cos(time+7.0*a);
float w = .5+.5*(sin(time+7.0*r)+ .7*cos(time+7.0*a));
vec3 col = texture2D(tex0,uv*.5).xyz;
gl_FragColor = vec4(col*w,1.0);
}
在我們的 Kivy 應用程式碼中,我們使用一個 .kv 檔案,它只在 FloatLayout 小部件的畫布上繪製一個矩形。
<ShaderWidget>:
canvas:
Color:
rgb: 1, 0, 0
Rectangle:
pos: self.pos
size: self.size
此 "kv" 檔案的 ShaderWidget 規則對應於 ShaderWidget 類。它安排一個時鐘間隔,在每秒後觸發以更新著色器定義中的 glsl 變數。
class ShaderWidget(FloatLayout):
fs = StringProperty(None)
def __init__(self, **kwargs):
self.canvas = RenderContext()
super(ShaderWidget, self).__init__(**kwargs)
Clock.schedule_interval(self.update_glsl, 1 / 60.)
"fs" 類變數儲存來自 glsl 檔案的程式碼。來自 kivy.graphics 模組的 RenderContext() 方法儲存所有必要的繪圖資訊,即頂點著色器和片段著色器等。
"fs" StringProperty 繫結到 "on_fs()" 方法,該方法將設定著色器。
def on_fs(self, instance, value):
shader = self.canvas.shader
old_value = shader.fs
shader.fs = value
if not shader.success:
shader.fs = old_value
raise Exception('failed')
每次預定的時鐘事件發生時,都會呼叫 update_glsl() 方法。它基本上更新應用視窗上每個畫素的片段顏色。
def update_glsl(self, *largs): self.canvas['time'] = Clock.get_boottime() self.canvas['resolution'] = list(map(float, self.size)) win_rc = Window.render_context self.canvas['projection_mat'] = win_rc['projection_mat'] self.canvas['modelview_mat'] = win_rc['modelview_mat'] self.canvas['frag_modelview_mat'] = win_rc['frag_modelview_mat']
App 類簡單地從 kv 檔案和類定義載入 ShaderWidget。
示例
完整的程式碼如下:
from kivy.clock import Clock
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.core.window import Window
Window.size=(720,400)
file=open('kaleidoscope.glsl')
shader=file.read()
class ShaderWidget(FloatLayout):
fs = StringProperty(None)
def __init__(self, **kwargs):
self.canvas = RenderContext()
super(ShaderWidget, self).__init__(**kwargs)
Clock.schedule_interval(self.update_glsl, 1 / 60.)
def on_fs(self, instance, value):
shader = self.canvas.shader
old_value = shader.fs
shader.fs = value
if not shader.success:
shader.fs = old_value
raise Exception('failed')
def update_glsl(self, *largs):
self.canvas['time'] = Clock.get_boottime()
self.canvas['resolution'] = list(map(float, self.size)).
win_rc = Window.render_context
self.canvas['projection_mat'] = win_rc['projection_mat']
self.canvas['modelview_mat'] = win_rc['modelview_mat']
self.canvas['frag_modelview_mat'] = win_rc['frag_modelview_mat']
class 'kaleidoscopeApp(App):
title='kaleidoscope'
def build(self):
return ShaderWidget(fs=shader)
'kaleidoscopeApp().run()
輸出
執行此程式碼並檢查輸出: