commit about v 0.5.3
release comming(no DEMO)
This commit is contained in:
parent
c882d7901c
commit
26506b6214
@ -15,26 +15,18 @@ gitee: @shenjackyuanjie
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import random
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
|
||||||
import configparser
|
import configparser
|
||||||
import multiprocessing
|
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from multiprocessing import Pipe
|
|
||||||
from multiprocessing.connection import Connection
|
|
||||||
|
|
||||||
if __name__ == '__main__': # been start will not run this
|
if __name__ == '__main__': # been start will not run this
|
||||||
sys.path.append('/bin/libs')
|
sys.path.append('/bin/libs')
|
||||||
sys.path.append('/bin')
|
sys.path.append('/bin')
|
||||||
|
|
||||||
# Difficult_Rocket function
|
# Difficult_Rocket function
|
||||||
from Difficult_Rocket import crash
|
|
||||||
from Difficult_Rocket.api.Exp import *
|
|
||||||
from Difficult_Rocket.api.translate import tr
|
from Difficult_Rocket.api.translate import tr
|
||||||
from Difficult_Rocket.graphics import widgets
|
from Difficult_Rocket.api import tools, new_thread, translate
|
||||||
from Difficult_Rocket.api import tools, load_file, new_thread, thread
|
|
||||||
|
|
||||||
# libs function
|
# libs function
|
||||||
local_lib = True
|
local_lib = True
|
||||||
@ -97,6 +89,7 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
pyglet.resource.path = ['textures']
|
pyglet.resource.path = ['textures']
|
||||||
pyglet.resource.reindex()
|
pyglet.resource.reindex()
|
||||||
self.config_file = tools.load_file('configs/main.config')
|
self.config_file = tools.load_file('configs/main.config')
|
||||||
|
self.game_config = tools.load_file('configs/game.config')
|
||||||
self.FPS = Decimal(int(self.config_file['runtime']['fps']))
|
self.FPS = Decimal(int(self.config_file['runtime']['fps']))
|
||||||
self.SPF = Decimal('1') / self.FPS
|
self.SPF = Decimal('1') / self.FPS
|
||||||
# dic
|
# dic
|
||||||
@ -115,21 +108,32 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
|
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
|
||||||
# setup
|
# setup
|
||||||
self.setup()
|
self.setup()
|
||||||
self.info_label = pyglet.text.Label(x=10, y=self.height - 10,
|
# 命令显示
|
||||||
anchor_x='left', anchor_y='top',
|
self.command_label = [pyglet.text.Label(x=10, y=10 + 20 * line,
|
||||||
batch=self.label_batch)
|
anchor_x='left', anchor_y='center',
|
||||||
|
font_name=translate.鸿蒙简体, font_size=12,
|
||||||
|
batch=self.label_batch)
|
||||||
|
for line in range(int(self.game_config['command']['show']) + 1)]
|
||||||
|
# fps显示
|
||||||
|
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
|
||||||
|
anchor_x='left', anchor_y='top',
|
||||||
|
font_name=translate.鸿蒙简体, font_size=20,
|
||||||
|
batch=self.label_batch)
|
||||||
|
# 设置刷新率
|
||||||
pyglet.clock.schedule_interval(self.update, float(self.SPF))
|
pyglet.clock.schedule_interval(self.update, float(self.SPF))
|
||||||
|
# 完成设置后的信息输出
|
||||||
self.logger.info(tr.lang('window', 'setup.done'))
|
self.logger.info(tr.lang('window', 'setup.done'))
|
||||||
|
self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid()))
|
||||||
end_time = time.time_ns()
|
end_time = time.time_ns()
|
||||||
self.use_time = end_time - start_time
|
self.use_time = end_time - start_time
|
||||||
self.logger.info(tr.lang('window', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
|
self.logger.info(tr.lang('window', 'setup.use_time').format(Decimal(self.use_time) / 1000000000))
|
||||||
self.logger.debug(tr.lang('window', 'setup.use_time_ns').format(self.use_time))
|
self.logger.debug(tr.lang('window', 'setup.use_time_ns').format(self.use_time))
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid()))
|
|
||||||
self.load_fonts()
|
self.load_fonts()
|
||||||
|
# print(pyglet.font.have_font('HarmonyOS_Sans_Black'))
|
||||||
|
|
||||||
@new_thread('client load_fonts')
|
# @new_thread('client load_fonts')
|
||||||
def load_fonts(self):
|
def load_fonts(self):
|
||||||
file_path = './libs/fonts/HarmonyOS Sans/'
|
file_path = './libs/fonts/HarmonyOS Sans/'
|
||||||
ttf_files = os.listdir(file_path)
|
ttf_files = os.listdir(file_path)
|
||||||
@ -176,7 +180,7 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
self.max_fps = [self.FPS, time.time()]
|
self.max_fps = [self.FPS, time.time()]
|
||||||
elif (time.time() - self.min_fps[1]) > self.fps_wait:
|
elif (time.time() - self.min_fps[1]) > self.fps_wait:
|
||||||
self.min_fps = [self.FPS, time.time()]
|
self.min_fps = [self.FPS, time.time()]
|
||||||
self.info_label.text = 'FPS: {:.1f} {:.1f} ({:.1f}/{:.1f}) | MSPF: {:.5f} '.format(now_FPS, 1 / tick, self.max_fps[0], self.min_fps[0], tick)
|
self.fps_label.text = 'FPS: {:.1f} {:.1f} ({:.1f}/{:.1f}) | MSPF: {:.5f} '.format(now_FPS, 1 / tick, self.max_fps[0], self.min_fps[0], tick)
|
||||||
|
|
||||||
def on_draw(self):
|
def on_draw(self):
|
||||||
self.clear()
|
self.clear()
|
||||||
@ -184,7 +188,7 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
|
|
||||||
def on_resize(self, width: int, height: int):
|
def on_resize(self, width: int, height: int):
|
||||||
super().on_resize(width, height)
|
super().on_resize(width, height)
|
||||||
self.info_label.y = height - 10
|
self.fps_label.y = height - 10
|
||||||
|
|
||||||
def draw_batch(self):
|
def draw_batch(self):
|
||||||
self.part_batch.draw()
|
self.part_batch.draw()
|
||||||
@ -213,9 +217,16 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
key.MOD_CAPSLOCK |
|
key.MOD_CAPSLOCK |
|
||||||
key.MOD_SCROLLLOCK)):
|
key.MOD_SCROLLLOCK)):
|
||||||
self.dispatch_event('on_close')
|
self.dispatch_event('on_close')
|
||||||
|
self.logger.debug(tr.lang('window', 'key.press').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
|
||||||
|
|
||||||
def on_key_release(self, symbol, modifiers) -> None:
|
def on_key_release(self, symbol, modifiers) -> None:
|
||||||
pass
|
self.logger.debug(tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
|
||||||
|
|
||||||
|
def on_text(self, text):
|
||||||
|
if text == '':
|
||||||
|
self.logger.debug(tr.lang('window', 'text.new_line'))
|
||||||
|
else:
|
||||||
|
self.logger.debug(tr.lang('window', 'text.input').format(text))
|
||||||
|
|
||||||
def on_close(self) -> None:
|
def on_close(self) -> None:
|
||||||
self.run_input = False
|
self.run_input = False
|
||||||
@ -225,4 +236,4 @@ class ClientWindow(pyglet.window.Window):
|
|||||||
config_file['window']['width'] = str(self.width)
|
config_file['window']['width'] = str(self.width)
|
||||||
config_file['window']['height'] = str(self.height)
|
config_file['window']['height'] = str(self.height)
|
||||||
config_file.write(open('configs/main.config', 'w', encoding='utf-8'))
|
config_file.write(open('configs/main.config', 'w', encoding='utf-8'))
|
||||||
super(ClientWindow, self).on_close()
|
super().on_close()
|
||||||
|
4
configs/game.config
Normal file
4
configs/game.config
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[command]
|
||||||
|
log = 1000
|
||||||
|
show = 20
|
||||||
|
size = 12
|
@ -6,6 +6,7 @@
|
|||||||
'lang.language': 'English (EN-US)',
|
'lang.language': 'English (EN-US)',
|
||||||
'logger.language': 'Logging language is: ',
|
'logger.language': 'Logging language is: ',
|
||||||
'logger.created': 'Log handler created',
|
'logger.created': 'Log handler created',
|
||||||
|
'logger.mkdir': 'logs/ folder not found, now created',
|
||||||
'logger.main_done': 'Main log handler created ',
|
'logger.main_done': 'Main log handler created ',
|
||||||
'logger.logfile_name': 'Log file name :',
|
'logger.logfile_name': 'Log file name :',
|
||||||
'logger.logfile_level': 'Log file record level :',
|
'logger.logfile_level': 'Log file record level :',
|
||||||
@ -14,17 +15,29 @@
|
|||||||
'game_start.at': 'The main thread of the game starts with:'
|
'game_start.at': 'The main thread of the game starts with:'
|
||||||
},
|
},
|
||||||
'client': {
|
'client': {
|
||||||
'setup.done': 'Client load complete ',
|
'setup.done': 'Client load complete',
|
||||||
'os.pid_is': 'Client is using PID',
|
'setup.use_time': 'Client load use: {} second',
|
||||||
|
'setup.use_time_ns': 'Client load use: {} nano second'
|
||||||
|
},
|
||||||
|
'window': {
|
||||||
|
'setup.done': 'Window load complete ',
|
||||||
|
'setup.use_time': 'Window load use: {} second',
|
||||||
|
'setup.use_time_ns': 'Window load use: {} nano second',
|
||||||
|
'os.pid_is': 'Window\'s PID: {} PPID: {}',
|
||||||
'button.been_press': 'The button is pressed, the current state of the button is:',
|
'button.been_press': 'The button is pressed, the current state of the button is:',
|
||||||
'mouse.press_at': 'mouse was click at {} button is: {}',
|
'mouse.press_at': 'mouse was click at {} button is: {}',
|
||||||
'mouse.release': 'mouse release at {} button is: {}',
|
'mouse.release': 'mouse release at {} button is: {}',
|
||||||
'mouse.right': 'right button',
|
'mouse.RIGHT': 'right button',
|
||||||
'mouse.left': 'left button'
|
'mouse.LEFT': 'left button',
|
||||||
|
'mouse.MIDDLE': 'middle button',
|
||||||
|
'key.press': 'key {} {} been press',
|
||||||
|
'key.release': 'key {} {} been release',
|
||||||
|
'text.input': 'input text {}',
|
||||||
|
'text.new_line': '换行'
|
||||||
},
|
},
|
||||||
'server': {
|
'server': {
|
||||||
'setup.done': 'server load complete ',
|
'setup.done': 'Server load complete ',
|
||||||
'os.pid_is': 'Client is using PID: {} PPID: {}'
|
'os.pid_is': 'Server is using PID: {} PPID: {}'
|
||||||
},
|
},
|
||||||
'language': 'English'
|
'language': 'English'
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,11 @@
|
|||||||
'mouse.release': '鼠标在 {} 释放,按键为:{}',
|
'mouse.release': '鼠标在 {} 释放,按键为:{}',
|
||||||
'mouse.RIGHT': '右键',
|
'mouse.RIGHT': '右键',
|
||||||
'mouse.LEFT': '左键',
|
'mouse.LEFT': '左键',
|
||||||
|
'mouse.MIDDLE': '中键',
|
||||||
|
'key.press': '按键 {} {} 被按下',
|
||||||
|
'key.release': '按键 {} {} 被释放',
|
||||||
|
'text.input': '输入字符 {}',
|
||||||
|
'text.new_line': '换行',
|
||||||
'libs.local': '正在使用本地 pyglet 库 版本为: {}',
|
'libs.local': '正在使用本地 pyglet 库 版本为: {}',
|
||||||
'libs.outer': '正在使用全局 pyglet 库 版本为: {}\n(可能会造成bug,因为本地库版本为2.0dev9)',
|
'libs.outer': '正在使用全局 pyglet 库 版本为: {}\n(可能会造成bug,因为本地库版本为2.0dev9)',
|
||||||
'fonts.found': '在字体列表中找到以下字体库: {}'
|
'fonts.found': '在字体列表中找到以下字体库: {}'
|
||||||
|
@ -35,15 +35,15 @@
|
|||||||
},
|
},
|
||||||
'loggers': {
|
'loggers': {
|
||||||
'client': {
|
'client': {
|
||||||
'level': 'DEBUG',
|
// 'level': 'DEBUG',
|
||||||
'handlers': []
|
'handlers': []
|
||||||
},
|
},
|
||||||
'server': {
|
'server': {
|
||||||
'level': 'DEBUG',
|
// 'level': 'DEBUG',
|
||||||
'handlers': []
|
'handlers': []
|
||||||
},
|
},
|
||||||
'main': {
|
'main': {
|
||||||
'level': 'DEBUG',
|
// 'level': 'DEBUG',
|
||||||
'handlers': []
|
'handlers': []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
- `Difficult_Rocket.graphics.widgets.Parts`
|
- `Difficult_Rocket.graphics.widgets.Parts`
|
||||||
- have many costume value
|
- have many costume value
|
||||||
- `libs/fonts` now have `HarmonyOS_Sans`
|
- `libs/fonts` now have `HarmonyOS_Sans`
|
||||||
|
- handler of `on_key_press` and `on_key_release` and `on_text`
|
||||||
|
- `game.config` config file
|
||||||
|
- `lang/en-us.json5` now up to date with `lang/zh-CN.json5`
|
||||||
|
|
||||||
## 20210928 V 0.5.2
|
## 20210928 V 0.5.2
|
||||||
|
|
||||||
|
@ -514,31 +514,34 @@ class UniformBufferObject:
|
|||||||
|
|
||||||
# Query the number of active Uniforms:
|
# Query the number of active Uniforms:
|
||||||
num_active = GLint()
|
num_active = GLint()
|
||||||
indices = (GLuint * num_active.value)()
|
|
||||||
indices_ptr = cast(addressof(indices), POINTER(GLint))
|
|
||||||
glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, num_active)
|
glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, num_active)
|
||||||
glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices_ptr)
|
|
||||||
|
|
||||||
# Create objects and pointers for query values, to be used in the next step:
|
# Query the uniform index order and each uniform's offset:
|
||||||
|
indices = (GLuint * num_active.value)()
|
||||||
offsets = (GLint * num_active.value)()
|
offsets = (GLint * num_active.value)()
|
||||||
gl_types = (GLuint * num_active.value)()
|
indices_ptr = cast(addressof(indices), POINTER(GLint))
|
||||||
mat_stride = (GLuint * num_active.value)()
|
|
||||||
offsets_ptr = cast(addressof(offsets), POINTER(GLint))
|
offsets_ptr = cast(addressof(offsets), POINTER(GLint))
|
||||||
|
glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices_ptr)
|
||||||
|
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_OFFSET, offsets_ptr)
|
||||||
|
|
||||||
|
# Offsets may be returned in non-ascending order, sort them with the corresponding index:
|
||||||
|
_oi = sorted(zip(offsets, indices), key=lambda x: x[0])
|
||||||
|
offsets = [x[0] for x in _oi] + [self.block.size]
|
||||||
|
indices = (GLuint * num_active.value)(*(x[1] for x in _oi))
|
||||||
|
|
||||||
|
# Query other uniform information:
|
||||||
|
gl_types = (GLint * num_active.value)()
|
||||||
|
mat_stride = (GLint * num_active.value)()
|
||||||
gl_types_ptr = cast(addressof(gl_types), POINTER(GLint))
|
gl_types_ptr = cast(addressof(gl_types), POINTER(GLint))
|
||||||
stride_ptr = cast(addressof(mat_stride), POINTER(GLint))
|
stride_ptr = cast(addressof(mat_stride), POINTER(GLint))
|
||||||
|
|
||||||
# Query the indices, offsets, and types uniforms:
|
|
||||||
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_OFFSET, offsets_ptr)
|
|
||||||
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_TYPE, gl_types_ptr)
|
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_TYPE, gl_types_ptr)
|
||||||
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_MATRIX_STRIDE, stride_ptr)
|
glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_MATRIX_STRIDE, stride_ptr)
|
||||||
|
|
||||||
offsets = offsets[:] + [self.block.size]
|
|
||||||
args = []
|
args = []
|
||||||
|
|
||||||
for i in range(num_active.value):
|
for i in range(num_active.value):
|
||||||
u_name, gl_type, length = self.block.uniforms[i]
|
u_name, gl_type, length = self.block.uniforms[indices[i]]
|
||||||
start = offsets[i]
|
size = offsets[i+1] - offsets[i]
|
||||||
size = offsets[i+1] - start
|
|
||||||
c_type_size = sizeof(gl_type)
|
c_type_size = sizeof(gl_type)
|
||||||
actual_size = c_type_size * length
|
actual_size = c_type_size * length
|
||||||
padding = size - actual_size
|
padding = size - actual_size
|
||||||
|
@ -472,6 +472,17 @@ class Mat4(tuple):
|
|||||||
0.0, 0.0, 1.0, 0.0,
|
0.0, 0.0, 1.0, 0.0,
|
||||||
vector[0], vector[1], vector[2], 1.0))
|
vector[0], vector[1], vector[2], 1.0))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_rotation(cls, angle: float, vector: Vec3) -> 'Mat4':
|
||||||
|
"""Create a rotation matrix from an angle and Vec3.
|
||||||
|
|
||||||
|
:Parameters:
|
||||||
|
`angle` : A `float`
|
||||||
|
`vector` : A `Vec3`, or 3 component tuple of float or int
|
||||||
|
Vec3 or tuple with x, y and z translaton values
|
||||||
|
"""
|
||||||
|
return cls().rotate(angle, vector)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def look_at_direction(cls, direction: Vec3, up: Vec3) -> 'Mat4':
|
def look_at_direction(cls, direction: Vec3, up: Vec3) -> 'Mat4':
|
||||||
vec_z = direction.normalize()
|
vec_z = direction.normalize()
|
||||||
@ -498,21 +509,22 @@ class Mat4(tuple):
|
|||||||
"""Get a specific column as a tuple."""
|
"""Get a specific column as a tuple."""
|
||||||
return self[index::4]
|
return self[index::4]
|
||||||
|
|
||||||
def scale(self, x=1, y=1, z=1) -> 'Mat4':
|
def scale(self, vector: Vec3) -> 'Mat4':
|
||||||
"""Get a scale Matrix on x, y, or z axis."""
|
"""Get a scale Matrix on x, y, or z axis."""
|
||||||
temp = list(self)
|
temp = list(self)
|
||||||
temp[0] *= x
|
temp[0] *= vector[0]
|
||||||
temp[5] *= y
|
temp[5] *= vector[1]
|
||||||
temp[10] *= z
|
temp[10] *= vector[2]
|
||||||
return Mat4(temp)
|
return Mat4(temp)
|
||||||
|
|
||||||
def translate(self, x=0, y=0, z=0) -> 'Mat4':
|
def translate(self, vector: Vec3) -> 'Mat4':
|
||||||
"""Get a translate Matrix along x, y, and z axis."""
|
"""Get a translate Matrix along x, y, and z axis."""
|
||||||
return Mat4(self) @ Mat4((1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1))
|
return Mat4(self) @ Mat4((1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, *vector, 1))
|
||||||
|
|
||||||
def rotate(self, angle=0, x=0, y=0, z=0) -> 'Mat4':
|
def rotate(self, angle: float, vector: Vec3) -> 'Mat4':
|
||||||
"""Get a rotation Matrix on x, y, or z axis."""
|
"""Get a rotation Matrix on x, y, or z axis."""
|
||||||
assert all(abs(n) <= 1 for n in (x, y, z)), "x,y,z must be normalized (<=1)"
|
assert all(abs(n) <= 1 for n in vector), "vector must be normalized (<=1)"
|
||||||
|
x, y, z = vector
|
||||||
c = _math.cos(angle)
|
c = _math.cos(angle)
|
||||||
s = _math.sin(angle)
|
s = _math.sin(angle)
|
||||||
t = 1 - c
|
t = 1 - c
|
||||||
|
@ -89,7 +89,7 @@ import pyglet
|
|||||||
from pyglet import gl
|
from pyglet import gl
|
||||||
from pyglet import graphics
|
from pyglet import graphics
|
||||||
from pyglet.gl import current_context
|
from pyglet.gl import current_context
|
||||||
from pyglet.math import Mat4
|
from pyglet.math import Mat4, Vec3
|
||||||
from pyglet.graphics import shader
|
from pyglet.graphics import shader
|
||||||
|
|
||||||
from .codecs import ModelDecodeException
|
from .codecs import ModelDecodeException
|
||||||
@ -190,8 +190,8 @@ class Model:
|
|||||||
self.vertex_lists = vertex_lists
|
self.vertex_lists = vertex_lists
|
||||||
self.groups = groups
|
self.groups = groups
|
||||||
self._batch = batch
|
self._batch = batch
|
||||||
self._rotation = 0, 0, 0
|
self._rotation = Vec3()
|
||||||
self._translation = 0, 0, 0
|
self._translation = Vec3()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def batch(self):
|
def batch(self):
|
||||||
@ -279,16 +279,16 @@ class BaseMaterialGroup(graphics.ShaderGroup):
|
|||||||
super().__init__(program, order, parent)
|
super().__init__(program, order, parent)
|
||||||
|
|
||||||
self.material = material
|
self.material = material
|
||||||
self.rotation = 0, 0, 0
|
self.rotation = Vec3()
|
||||||
self.translation = 0, 0, 0
|
self.translation = Vec3()
|
||||||
|
|
||||||
def set_modelview_matrix(self):
|
def set_modelview_matrix(self):
|
||||||
# NOTE: Matrix operations can be optimized later with transform feedback
|
# NOTE: Matrix operations can be optimized later with transform feedback
|
||||||
view = Mat4()
|
view = Mat4()
|
||||||
view = view.rotate(radians(self.rotation[2]), z=1)
|
view = view.rotate(radians(self.rotation[2]), Vec3(0, 0, 1))
|
||||||
view = view.rotate(radians(self.rotation[1]), y=1)
|
view = view.rotate(radians(self.rotation[1]), Vec3(0, 1, 0))
|
||||||
view = view.rotate(radians(self.rotation[0]), x=1)
|
view = view.rotate(radians(self.rotation[0]), Vec3(1, 0, 0))
|
||||||
view = view.translate(*self.translation)
|
view = view.translate(self.translation)
|
||||||
|
|
||||||
# TODO: separate the projection block, and remove this hack
|
# TODO: separate the projection block, and remove this hack
|
||||||
block = self.program.uniform_blocks['WindowBlock']
|
block = self.program.uniform_blocks['WindowBlock']
|
||||||
|
@ -178,141 +178,6 @@ fragment_array_source = """#version 150 core
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
|
|
||||||
vertex_src = """#version 150
|
|
||||||
in vec2 position;
|
|
||||||
in vec4 size;
|
|
||||||
in vec4 color;
|
|
||||||
in vec4 tex_coords;
|
|
||||||
in float rotation;
|
|
||||||
|
|
||||||
out vec4 geo_size;
|
|
||||||
out vec4 geo_color;
|
|
||||||
out vec4 geo_tex_coords;
|
|
||||||
out float geo_rotation;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(position, 0, 1);
|
|
||||||
geo_size = size;
|
|
||||||
geo_color = color;
|
|
||||||
geo_tex_coords = tex_coords;
|
|
||||||
geo_rotation = rotation;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
geometry_src = """#version 150
|
|
||||||
// We are taking single points form the vertex shader
|
|
||||||
// and emitting 4 new vertices creating a quad/sprites
|
|
||||||
layout (points) in;
|
|
||||||
layout (triangle_strip, max_vertices = 4) out;
|
|
||||||
|
|
||||||
uniform WindowBlock
|
|
||||||
{
|
|
||||||
mat4 projection;
|
|
||||||
mat4 view;
|
|
||||||
} window;
|
|
||||||
|
|
||||||
|
|
||||||
// Since geometry shader can take multiple values from a vertex
|
|
||||||
// shader we need to define the inputs from it as arrays.
|
|
||||||
// In our instance we just take single values (points)
|
|
||||||
in vec4 geo_size[];
|
|
||||||
in vec4 geo_color[];
|
|
||||||
in vec4 geo_tex_coords[];
|
|
||||||
in float geo_rotation[];
|
|
||||||
|
|
||||||
out vec2 uv;
|
|
||||||
out vec4 frag_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
// We grab the position value from the vertex shader
|
|
||||||
vec2 center = gl_in[0].gl_Position.xy;
|
|
||||||
|
|
||||||
// Calculate the half size of the sprites for easier calculations
|
|
||||||
vec2 hsize = geo_size[0].xy / 2.0;
|
|
||||||
|
|
||||||
// Convert the rotation to radians
|
|
||||||
float angle = radians(-geo_rotation[0]);
|
|
||||||
|
|
||||||
// Create a scale vector
|
|
||||||
vec2 scale = vec2(geo_size[0][2], geo_size[0][3]);
|
|
||||||
|
|
||||||
// Create a 2d rotation matrix
|
|
||||||
mat2 rot = mat2(cos(angle), sin(angle),
|
|
||||||
-sin(angle), cos(angle));
|
|
||||||
|
|
||||||
// Calculate the left, bottom, right, top:
|
|
||||||
float tl = geo_tex_coords[0].s;
|
|
||||||
float tb = geo_tex_coords[0].t;
|
|
||||||
float tr = geo_tex_coords[0].s + geo_tex_coords[0].p;
|
|
||||||
float tt = geo_tex_coords[0].t + geo_tex_coords[0].q;
|
|
||||||
|
|
||||||
// Emit a triangle strip creating a quad (4 vertices).
|
|
||||||
// Here we need to make sure the rotation is applied before we position the sprite.
|
|
||||||
// We just use hardcoded texture coordinates here. If an atlas is used we
|
|
||||||
// can pass an additional vec4 for specific texture coordinates.
|
|
||||||
// Each EmitVertex() emits values down the shader pipeline just like a single
|
|
||||||
// run of a vertex shader, but in geomtry shaders we can do it multiple times!
|
|
||||||
|
|
||||||
// Upper left
|
|
||||||
gl_Position = window.projection * window.view * vec4(rot * vec2(-hsize.x, hsize.y) * scale + center, 0.0, 1.0);
|
|
||||||
uv = vec2(tl, tt);
|
|
||||||
frag_color = geo_color[0];
|
|
||||||
EmitVertex();
|
|
||||||
|
|
||||||
// lower left
|
|
||||||
gl_Position = window.projection * window.view * vec4(rot * vec2(-hsize.x, -hsize.y) * scale + center, 0.0, 1.0);
|
|
||||||
uv = vec2(tl, tb);
|
|
||||||
frag_color = geo_color[0];
|
|
||||||
EmitVertex();
|
|
||||||
|
|
||||||
// upper right
|
|
||||||
gl_Position = window.projection * window.view * vec4(rot * vec2(hsize.x, hsize.y) * scale + center, 0.0, 1.0);
|
|
||||||
uv = vec2(tr, tt);
|
|
||||||
frag_color = geo_color[0];
|
|
||||||
EmitVertex();
|
|
||||||
|
|
||||||
// lower right
|
|
||||||
gl_Position = window.projection * window.view * vec4(rot * vec2(hsize.x, -hsize.y) * scale + center, 0.0, 1.0);
|
|
||||||
uv = vec2(tr, tb);
|
|
||||||
frag_color = geo_color[0];
|
|
||||||
EmitVertex();
|
|
||||||
|
|
||||||
// We are done with this triangle strip now
|
|
||||||
EndPrimitive();
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
fragment_src = """#version 150
|
|
||||||
in vec2 uv;
|
|
||||||
in vec4 frag_color;
|
|
||||||
|
|
||||||
out vec4 final_color;
|
|
||||||
|
|
||||||
uniform sampler2D sprite_texture;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final_color = texture(sprite_texture, uv) * frag_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def get_geo_shader():
|
|
||||||
try:
|
|
||||||
return pyglet.gl.current_context.pyglet_sprite_geo_shader
|
|
||||||
except AttributeError:
|
|
||||||
new_vert_shader = graphics.shader.Shader(vertex_src, 'vertex')
|
|
||||||
new_geom_shader = graphics.shader.Shader(geometry_src, 'geometry')
|
|
||||||
new_frag_shader = graphics.shader.Shader(fragment_src, 'fragment')
|
|
||||||
new_program = graphics.shader.ShaderProgram(new_vert_shader, new_geom_shader, new_frag_shader)
|
|
||||||
pyglet.gl.current_context.pyglet_sprite_geo_shader = new_program
|
|
||||||
return pyglet.gl.current_context.pyglet_sprite_geo_shader
|
|
||||||
|
|
||||||
|
|
||||||
def get_default_shader():
|
def get_default_shader():
|
||||||
try:
|
try:
|
||||||
return pyglet.gl.current_context.pyglet_sprite_default_shader
|
return pyglet.gl.current_context.pyglet_sprite_default_shader
|
||||||
@ -935,229 +800,3 @@ class Sprite(event.EventDispatcher):
|
|||||||
|
|
||||||
|
|
||||||
Sprite.register_event_type('on_animation_end')
|
Sprite.register_event_type('on_animation_end')
|
||||||
|
|
||||||
|
|
||||||
class GeoSprite(Sprite):
|
|
||||||
"""Instance of an on-screen image.
|
|
||||||
|
|
||||||
See the module documentation for usage.
|
|
||||||
"""
|
|
||||||
|
|
||||||
_batch = None
|
|
||||||
_animation = None
|
|
||||||
_frame_index = 0
|
|
||||||
_paused = False
|
|
||||||
_rotation = 0
|
|
||||||
_rgba = [255, 255, 255, 255]
|
|
||||||
_scale = 1.0
|
|
||||||
_scale_x = 1.0
|
|
||||||
_scale_y = 1.0
|
|
||||||
_visible = True
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
img, x=0, y=0,
|
|
||||||
blend_src=GL_SRC_ALPHA,
|
|
||||||
blend_dest=GL_ONE_MINUS_SRC_ALPHA,
|
|
||||||
batch=None,
|
|
||||||
group=None,
|
|
||||||
subpixel=False):
|
|
||||||
"""Create a sprite.
|
|
||||||
|
|
||||||
:Parameters:
|
|
||||||
`img` : `~pyglet.image.AbstractImage` or `~pyglet.image.Animation`
|
|
||||||
Image or animation to display.
|
|
||||||
`x` : int
|
|
||||||
X coordinate of the sprite.
|
|
||||||
`y` : int
|
|
||||||
Y coordinate of the sprite.
|
|
||||||
`blend_src` : int
|
|
||||||
OpenGL blend source mode. The default is suitable for
|
|
||||||
compositing sprites drawn from back-to-front.
|
|
||||||
`blend_dest` : int
|
|
||||||
OpenGL blend destination mode. The default is suitable for
|
|
||||||
compositing sprites drawn from back-to-front.
|
|
||||||
`batch` : `~pyglet.graphics.Batch`
|
|
||||||
Optional batch to add the sprite to.
|
|
||||||
`group` : `~pyglet.graphics.Group`
|
|
||||||
Optional parent group of the sprite.
|
|
||||||
`subpixel` : bool
|
|
||||||
Allow floating-point coordinates for the sprite. By default,
|
|
||||||
coordinates are restricted to integer values.
|
|
||||||
"""
|
|
||||||
self._x = x
|
|
||||||
self._y = y
|
|
||||||
|
|
||||||
if isinstance(img, image.Animation):
|
|
||||||
self._animation = img
|
|
||||||
self._texture = img.frames[0].image.get_texture()
|
|
||||||
self._next_dt = img.frames[0].duration
|
|
||||||
if self._next_dt:
|
|
||||||
clock.schedule_once(self._animate, self._next_dt)
|
|
||||||
else:
|
|
||||||
self._texture = img.get_texture()
|
|
||||||
|
|
||||||
program = get_geo_shader()
|
|
||||||
|
|
||||||
self._batch = batch or graphics.get_default_batch()
|
|
||||||
self._group = SpriteGroup(self._texture, blend_src, blend_dest, program, 0, group)
|
|
||||||
self._subpixel = subpixel
|
|
||||||
|
|
||||||
# TODO: add a property to the Texture class:
|
|
||||||
tex_coords = (self._texture.tex_coords[0], self._texture.tex_coords[1],
|
|
||||||
self._texture.tex_coords[3], self._texture.tex_coords[7])
|
|
||||||
|
|
||||||
self._vertex_list = self._batch.add(
|
|
||||||
1, GL_POINTS, self._group,
|
|
||||||
('position2f', (int(x) if subpixel else x, int(y) if subpixel else y)),
|
|
||||||
('size4f', (self._texture.width, self._texture.height, 1, 1)),
|
|
||||||
('rotation1f', (self._rotation,)),
|
|
||||||
('color4Bn', self._rgba),
|
|
||||||
('tex_coords4f', tex_coords)
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def position(self):
|
|
||||||
"""The (x, y) coordinates of the sprite, as a tuple.
|
|
||||||
|
|
||||||
:Parameters:
|
|
||||||
`x` : int
|
|
||||||
X coordinate of the sprite.
|
|
||||||
`y` : int
|
|
||||||
Y coordinate of the sprite.
|
|
||||||
"""
|
|
||||||
return self._x, self._y
|
|
||||||
|
|
||||||
@position.setter
|
|
||||||
def position(self, position):
|
|
||||||
self._x, self._y = position
|
|
||||||
self._vertex_list.position[:] = position
|
|
||||||
|
|
||||||
@property
|
|
||||||
def x(self):
|
|
||||||
"""X coordinate of the sprite.
|
|
||||||
|
|
||||||
:type: int
|
|
||||||
"""
|
|
||||||
return self._x
|
|
||||||
|
|
||||||
@x.setter
|
|
||||||
def x(self, x):
|
|
||||||
self._x = x
|
|
||||||
self._vertex_list.position[:] = x, self._y
|
|
||||||
|
|
||||||
@property
|
|
||||||
def y(self):
|
|
||||||
"""Y coordinate of the sprite.
|
|
||||||
|
|
||||||
:type: int
|
|
||||||
"""
|
|
||||||
return self._y
|
|
||||||
|
|
||||||
@y.setter
|
|
||||||
def y(self, y):
|
|
||||||
self._y = y
|
|
||||||
self._vertex_list.position[:] = self._x, y
|
|
||||||
|
|
||||||
@property
|
|
||||||
def rotation(self):
|
|
||||||
"""Clockwise rotation of the sprite, in degrees.
|
|
||||||
|
|
||||||
The sprite image will be rotated about its image's (anchor_x, anchor_y)
|
|
||||||
position.
|
|
||||||
|
|
||||||
:type: float
|
|
||||||
"""
|
|
||||||
return self._rotation
|
|
||||||
|
|
||||||
@rotation.setter
|
|
||||||
def rotation(self, rotation):
|
|
||||||
self._rotation = rotation
|
|
||||||
self._vertex_list.rotation[0] = rotation
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scale(self):
|
|
||||||
"""Base Scaling factor.
|
|
||||||
|
|
||||||
A scaling factor of 1 (the default) has no effect. A scale of 2 will
|
|
||||||
draw the sprite at twice the native size of its image.
|
|
||||||
|
|
||||||
:type: float
|
|
||||||
"""
|
|
||||||
return self._scale
|
|
||||||
|
|
||||||
@scale.setter
|
|
||||||
def scale(self, scale):
|
|
||||||
self._scale = scale
|
|
||||||
self._vertex_list.size[2:4] = (scale * self._scale_x, scale * self._scale_y)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scale_x(self):
|
|
||||||
"""Horizontal scaling factor.
|
|
||||||
|
|
||||||
A scaling factor of 1 (the default) has no effect. A scale of 2 will
|
|
||||||
draw the sprite at twice the native width of its image.
|
|
||||||
|
|
||||||
:type: float
|
|
||||||
"""
|
|
||||||
return self._scale_x
|
|
||||||
|
|
||||||
@scale_x.setter
|
|
||||||
def scale_x(self, scale_x):
|
|
||||||
self._scale_x = scale_x
|
|
||||||
self._vertex_list.size[2:4] = (self._scale * scale_x, self._scale * self._scale_y)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def scale_y(self):
|
|
||||||
"""Vertical scaling factor.
|
|
||||||
|
|
||||||
A scaling factor of 1 (the default) has no effect. A scale of 2 will
|
|
||||||
draw the sprite at twice the native height of its image.
|
|
||||||
|
|
||||||
:type: float
|
|
||||||
"""
|
|
||||||
return self._scale_y
|
|
||||||
|
|
||||||
@scale_y.setter
|
|
||||||
def scale_y(self, scale_y):
|
|
||||||
self._scale_y = scale_y
|
|
||||||
self._vertex_list.size[2:4] = (self._scale * self._scale_x, self._scale * scale_y)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def opacity(self):
|
|
||||||
"""Blend opacity.
|
|
||||||
|
|
||||||
This property sets the alpha component of the colour of the sprite's
|
|
||||||
vertices. With the default blend mode (see the constructor), this
|
|
||||||
allows the sprite to be drawn with fractional opacity, blending with the
|
|
||||||
background.
|
|
||||||
|
|
||||||
An opacity of 255 (the default) has no effect. An opacity of 128 will
|
|
||||||
make the sprite appear translucent.
|
|
||||||
|
|
||||||
:type: int
|
|
||||||
"""
|
|
||||||
return self._rgba[3]
|
|
||||||
|
|
||||||
@opacity.setter
|
|
||||||
def opacity(self, opacity):
|
|
||||||
self._rgba[3] = opacity
|
|
||||||
self._vertex_list.color[:] = self._rgba
|
|
||||||
|
|
||||||
@property
|
|
||||||
def color(self):
|
|
||||||
"""Blend color.
|
|
||||||
|
|
||||||
This property sets the color of the sprite's vertices. This allows the
|
|
||||||
sprite to be drawn with a color tint.
|
|
||||||
|
|
||||||
The color is specified as an RGB tuple of integers '(red, green, blue)'.
|
|
||||||
Each color component must be in the range 0 (dark) to 255 (saturated).
|
|
||||||
|
|
||||||
:type: (int, int, int)
|
|
||||||
"""
|
|
||||||
return self._rgba[:3]
|
|
||||||
|
|
||||||
@color.setter
|
|
||||||
def color(self, rgb):
|
|
||||||
self._rgba[:3] = list(map(int, rgb))
|
|
||||||
self._vertex_list.color[:] = self._rgba
|
|
||||||
|
@ -1011,18 +1011,8 @@ class TextLayout:
|
|||||||
return self._x, self._y
|
return self._x, self._y
|
||||||
|
|
||||||
@position.setter
|
@position.setter
|
||||||
def position(self, position):
|
def position(self, values):
|
||||||
self.update(*position)
|
x, y = values
|
||||||
|
|
||||||
def update(self, x, y):
|
|
||||||
"""Change both X and Y positions of the layout at once for faster performance.
|
|
||||||
|
|
||||||
:Parameters:
|
|
||||||
`x` : int
|
|
||||||
X coordinate of the layout.
|
|
||||||
`y` : int
|
|
||||||
Y coordinate of the layout.
|
|
||||||
"""
|
|
||||||
if self._boxes:
|
if self._boxes:
|
||||||
self._x = x
|
self._x = x
|
||||||
self._y = y
|
self._y = y
|
||||||
@ -1790,6 +1780,10 @@ class ScrollableTextLayout(TextLayout):
|
|||||||
for group in self.groups.values():
|
for group in self.groups.values():
|
||||||
group.scissor_area = area
|
group.scissor_area = area
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
|
super()._update()
|
||||||
|
self._update_scissor_area()
|
||||||
|
|
||||||
# Properties
|
# Properties
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Loading…
Reference in New Issue
Block a user