Compare commits

...

9 Commits

Author SHA1 Message Date
804dbfc992
use lto=yes on github? 2023-08-17 20:31:49 +08:00
8e494faa63
improve camera 2023-08-16 16:25:47 +08:00
42eef6743d
weirdddd 2023-08-15 23:30:34 +08:00
6fefb4460b
weird 2023-08-15 23:30:25 +08:00
8dfa5b230a
sync pyglet 2023-08-15 23:29:49 +08:00
726ba4ac17
add some magic from OpenGL 2023-08-13 01:01:15 +08:00
ede6f9ff6e
add back Mat4 2023-08-13 00:21:22 +08:00
d6f0caf2ae
remove zoomx and zoomy 2023-08-12 23:34:17 +08:00
d398ed1af9
opengl based render! 2023-08-12 23:32:43 +08:00
6 changed files with 88 additions and 37 deletions

View File

@ -7,7 +7,7 @@
from typing import Tuple, Optional from typing import Tuple, Optional
from pyglet.gl import gl from pyglet.gl import gl_compat, gl
from pyglet.math import Mat4, Vec3 from pyglet.math import Mat4, Vec3
from pyglet.graphics import Group from pyglet.graphics import Group
@ -139,8 +139,6 @@ class GroupCamera(Group):
self._view_x = view_x self._view_x = view_x
self._view_y = view_y self._view_y = view_y
self._zoom = zoom self._zoom = zoom
self._zoom_x = self._zoom
self._zoom_y = self._zoom
self.min_zoom = min_zoom self.min_zoom = min_zoom
self.max_zoom = max_zoom self.max_zoom = max_zoom
@ -162,13 +160,11 @@ class GroupCamera(Group):
@property @property
def zoom(self) -> float: def zoom(self) -> float:
return self._zoom return min(max(self._zoom, self.min_zoom), self.max_zoom)
@zoom.setter @zoom.setter
def zoom(self, value: float): def zoom(self, value: float):
self._zoom = value self._zoom = value
self._zoom_x = self._zoom
self._zoom_y = self._zoom
def reset(self): def reset(self):
self._view_x = 0 self._view_x = 0
@ -197,17 +193,71 @@ class CenterGroupCamera(GroupCamera):
def set_state(self): def set_state(self):
self._previous_view = self._window.view self._previous_view = self._window.view
x = (self._window.width / 2) / self._zoom + (self._view_x / self._zoom)
y = (self._window.height / 2) / self._zoom + (self._view_y / self._zoom)
x = (self._window.width / 2) / self._zoom_x + (self._view_x / self._zoom_x) view = Mat4.from_translation(Vec3(x * self._zoom, y * self._zoom, 0))
y = (self._window.height / 2) / self._zoom_y + (self._view_y / self._zoom_y)
view = Mat4.from_translation(Vec3(x * self._zoom_x, y * self._zoom_y, 0))
# 不懂就问 为啥这里 * zoom 下面还 * zoom # 不懂就问 为啥这里 * zoom 下面还 * zoom
if self._zoom == 1.0 and self._zoom_x == 1.0 and self._zoom_y == 1.0: if self._zoom == 1.0:
self._window.view = view self._window.view = view
else: else:
view = view.scale(Vec3(self._zoom_x, self._zoom_y, 1)) view = view.scale(Vec3(self._zoom, self._zoom, 1))
self._window.view = view self._window.view = view
def unset_state(self): def unset_state(self):
self._window.view = self._previous_view self._window.view = self._previous_view
class CenterGroupFrame(Group):
"""
A camera by group
can be used by just added to your widget
"""
def __init__(self,
window,
order: int = 0,
parent: Optional[Group] = None,
dx: Optional[int] = 0,
dy: Optional[int] = 0,
width: Optional[int] = 0,
height: Optional[int] = 0,
zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0):
super().__init__(order=order, parent=parent)
self.window = window
self.dx = dx
self.dy = dy
self._width = width
self._height = height
self._zoom = zoom
self.min_zoom = min_zoom
self.max_zoom = max_zoom
@property
def zoom(self) -> float:
return self._zoom
@zoom.setter
def zoom(self, value: float):
self._zoom = min(max(value, self.min_zoom), self.max_zoom)
def set_state(self):
self._previous_view = self.window.view
gl.glScissor(int(self.dx), int(self.dy), int(self._width), int(self._height))
gl.glViewport(int(self.dx), int(self.dy), int(self.window.width), int(self.window.height))
gl.glEnable(gl.GL_SCISSOR_TEST)
x = (self.window.width / 2) / self._zoom + (self.dx / self._zoom)
y = (self.window.height / 2) / self._zoom + (self.dy / self._zoom)
view = Mat4.from_translation(Vec3(x * self._zoom, y * self._zoom, 0))
view.scale(Vec3(self._zoom, self._zoom, 1))
self.window.view = view
def unset_state(self):
self.window.view = self._previous_view
gl.glDisable(gl.GL_SCISSOR_TEST)
gl.glViewport(0, 0, int(self.window.width), int(self.window.height))

View File

@ -11,6 +11,8 @@
- 将 `sr1_ship` 渲染器使用的 Camera 改成 `CenterGroupCamera` - 将 `sr1_ship` 渲染器使用的 Camera 改成 `CenterGroupCamera`
- 删除了之前的 Camera 相关代码 - 删除了之前的 Camera 相关代码
- 将用于渲染到材质的代码部分改为使用 `glScissor``glViewport`
- 优化了一点性能 ( 毕竟是OpenGL )
## 20230809 DR game 0.3.2.1 ## 20230809 DR game 0.3.2.1

View File

@ -208,7 +208,6 @@ class ObjectSpace:
# the next time this object space is active. # the next time this object space is active.
self.doomed_textures = [] self.doomed_textures = []
self.doomed_buffers = [] self.doomed_buffers = []
self.doomed_vaos = []
self.doomed_shader_programs = [] self.doomed_shader_programs = []
@ -231,6 +230,8 @@ class Context:
self.context_share = context_share self.context_share = context_share
self.canvas = None self.canvas = None
self.doomed_vaos = []
if context_share: if context_share:
self.object_space = context_share.object_space self.object_space = context_share.object_space
else: else:
@ -276,15 +277,15 @@ class Context:
buffers = (gl.GLuint * len(buffers))(*buffers) buffers = (gl.GLuint * len(buffers))(*buffers)
gl.glDeleteBuffers(len(buffers), buffers) gl.glDeleteBuffers(len(buffers), buffers)
self.object_space.doomed_buffers.clear() self.object_space.doomed_buffers.clear()
if self.object_space.doomed_vaos:
vaos = self.object_space.doomed_vaos[:]
vaos = (gl.GLuint * len(vaos))(*vaos)
gl.glDeleteVertexArrays(len(vaos), vaos)
self.object_space.doomed_vaos.clear()
if self.object_space.doomed_shader_programs: if self.object_space.doomed_shader_programs:
for program_id in self.object_space.doomed_shader_programs: for program_id in self.object_space.doomed_shader_programs:
gl.glDeleteProgram(program_id) gl.glDeleteProgram(program_id)
self.object_space.doomed_shader_programs.clear() self.object_space.doomed_shader_programs.clear()
if self.doomed_vaos:
vaos = self.doomed_vaos[:]
vaos = (gl.GLuint * len(vaos))(*vaos)
gl.glDeleteVertexArrays(len(vaos), vaos)
self.doomed_vaos.clear()
def destroy(self): def destroy(self):
"""Release the context. """Release the context.
@ -351,10 +352,10 @@ class Context:
.. versionadded:: 2.0 .. versionadded:: 2.0
""" """
if gl.current_context and self.object_space is gl.current_context.object_space and False: if gl.current_context is self:
gl.glDeleteVertexArrays(1, gl.GLuint(vao_id)) gl.glDeleteVertexArrays(1, gl.GLuint(vao_id))
else: else:
self.object_space.doomed_vaos.append(vao_id) self.doomed_vaos.append(vao_id)
def delete_shader_program(self, program_id): def delete_shader_program(self, program_id):
"""Safely delete a Shader Program belonging to this context. """Safely delete a Shader Program belonging to this context.

View File

@ -51,6 +51,10 @@ pub mod data {
pub data: SR1PartType, pub data: SR1PartType,
} }
impl PySR1PartType {
pub fn new(data: SR1PartType) -> Self { Self { data } }
}
#[pymethods] #[pymethods]
impl PySR1PartType { impl PySR1PartType {
#[getter] #[getter]
@ -81,10 +85,6 @@ pub mod data {
fn get_type(&self) -> String { self.data.p_type.into() } fn get_type(&self) -> String { self.data.p_type.into() }
} }
impl PySR1PartType {
pub fn new(data: SR1PartType) -> Self { Self { data } }
}
#[pyclass] #[pyclass]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[pyo3(name = "SR1PartList_rs")] #[pyo3(name = "SR1PartList_rs")]

View File

@ -12,12 +12,12 @@ import traceback
from pathlib import Path from pathlib import Path
from typing import List, TYPE_CHECKING, Dict, Optional, Generator, Tuple from typing import List, TYPE_CHECKING, Dict, Optional, Generator, Tuple
from pyglet.math import Vec4, Mat4 from pyglet.gl import gl
from pyglet.math import Mat4
from pyglet.text import Label from pyglet.text import Label
from pyglet.sprite import Sprite from pyglet.sprite import Sprite
from pyglet.graphics import Batch, Group from pyglet.graphics import Batch, Group
from pyglet.shapes import Line, Rectangle from pyglet.shapes import Line, Rectangle
from pyglet.image import Framebuffer, Texture
from . import DR_mod_runtime from . import DR_mod_runtime
from .types import SR1Textures, SR1Rotation from .types import SR1Textures, SR1Rotation
@ -75,12 +75,9 @@ class SR1ShipRender(BaseScreen):
self.dy = 0 self.dy = 0
self.width = main_window.width self.width = main_window.width
self.height = main_window.height self.height = main_window.height
self.buffer = Framebuffer()
self.render_texture = Texture.create(self.width, self.height)
self.buffer.attach_texture(self.render_texture)
self.main_batch = Batch() self.main_batch = Batch()
self.group_camera = CenterGroupCamera(window=self, self.group_camera = CenterGroupCamera(window=main_window,
order=10, order=10,
parent=main_window.main_group, parent=main_window.main_group,
min_zoom=(1 / 2) ** 10, min_zoom=(1 / 2) ** 10,
@ -129,8 +126,6 @@ class SR1ShipRender(BaseScreen):
def size(self, value: Tuple[int, int]): def size(self, value: Tuple[int, int]):
if not self.width == value[0] or not self.height == value[1]: if not self.width == value[0] or not self.height == value[1]:
self.width, self.height = value self.width, self.height = value
self.render_texture = Texture.create(self.width, self.height)
self.buffer.attach_texture(self.render_texture)
def load_xml(self, file_path: str) -> bool: def load_xml(self, file_path: str) -> bool:
""" """
@ -281,11 +276,14 @@ class SR1ShipRender(BaseScreen):
self.window_pointer.height / 2) + 10, 0 # 0 for z self.window_pointer.height / 2) + 10, 0 # 0 for z
self.render_d_line.x2 = self.group_camera.view_x self.render_d_line.x2 = self.group_camera.view_x
self.render_d_line.y2 = self.group_camera.view_y self.render_d_line.y2 = self.group_camera.view_y
self.buffer.bind()
window.clear() gl.glEnable(gl.GL_SCISSOR_TEST)
gl.glScissor(int(self.dx), int(self.dy), int(self.width), int(self.height))
gl.glViewport(int(self.dx), int(self.dy), self.window_pointer.width, self.window_pointer.height)
self.main_batch.draw() # use group camera, no need to with self.main_batch.draw() # use group camera, no need to with
self.buffer.unbind() gl.glViewport(0, 0, self.window_pointer.width, self.window_pointer.height)
self.render_texture.blit(x=self.dx, y=self.dy, z=0, width=self.width, height=self.height) gl.glScissor(0, 0, self.window_pointer.width, self.window_pointer.height)
gl.glDisable(gl.GL_SCISSOR_TEST)
# def on_draw(self, dt: float, window): # TODO: wait for pyglet 2.1 # def on_draw(self, dt: float, window): # TODO: wait for pyglet 2.1
def on_draw(self, window: "ClientWindow"): def on_draw(self, window: "ClientWindow"):
@ -352,7 +350,6 @@ class SR1ShipRender(BaseScreen):
if command.find('render'): if command.find('render'):
if command.find('reset'): if command.find('reset'):
self.group_camera.reset() self.group_camera.reset()
self.window_pointer.view = Vec4()
else: else:
self.status.draw_call = True self.status.draw_call = True
print('应该渲染飞船的') print('应该渲染飞船的')

View File

@ -37,6 +37,7 @@ if __name__ == '__main__':
compiler.output_path = Path('./build/github') compiler.output_path = Path('./build/github')
compiler.python_cmd = 'python' compiler.python_cmd = 'python'
compiler.save_xml = False compiler.save_xml = False
compiler.use_lto = True
# 检测 --xml 参数 # 检测 --xml 参数
if '--xml' in sys.argv: if '--xml' in sys.argv: