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 pyglet.gl import gl
from pyglet.gl import gl_compat, gl
from pyglet.math import Mat4, Vec3
from pyglet.graphics import Group
@ -139,8 +139,6 @@ class GroupCamera(Group):
self._view_x = view_x
self._view_y = view_y
self._zoom = zoom
self._zoom_x = self._zoom
self._zoom_y = self._zoom
self.min_zoom = min_zoom
self.max_zoom = max_zoom
@ -162,13 +160,11 @@ class GroupCamera(Group):
@property
def zoom(self) -> float:
return self._zoom
return min(max(self._zoom, self.min_zoom), self.max_zoom)
@zoom.setter
def zoom(self, value: float):
self._zoom = value
self._zoom_x = self._zoom
self._zoom_y = self._zoom
def reset(self):
self._view_x = 0
@ -197,17 +193,71 @@ class CenterGroupCamera(GroupCamera):
def set_state(self):
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)
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))
view = Mat4.from_translation(Vec3(x * self._zoom, y * self._zoom, 0))
# 不懂就问 为啥这里 * 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
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
def unset_state(self):
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`
- 删除了之前的 Camera 相关代码
- 将用于渲染到材质的代码部分改为使用 `glScissor``glViewport`
- 优化了一点性能 ( 毕竟是OpenGL )
## 20230809 DR game 0.3.2.1

View File

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

View File

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

View File

@ -12,12 +12,12 @@ import traceback
from pathlib import Path
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.sprite import Sprite
from pyglet.graphics import Batch, Group
from pyglet.shapes import Line, Rectangle
from pyglet.image import Framebuffer, Texture
from . import DR_mod_runtime
from .types import SR1Textures, SR1Rotation
@ -75,12 +75,9 @@ class SR1ShipRender(BaseScreen):
self.dy = 0
self.width = main_window.width
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.group_camera = CenterGroupCamera(window=self,
self.group_camera = CenterGroupCamera(window=main_window,
order=10,
parent=main_window.main_group,
min_zoom=(1 / 2) ** 10,
@ -129,8 +126,6 @@ class SR1ShipRender(BaseScreen):
def size(self, value: Tuple[int, int]):
if not self.width == value[0] or not self.height == value[1]:
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:
"""
@ -281,11 +276,14 @@ class SR1ShipRender(BaseScreen):
self.window_pointer.height / 2) + 10, 0 # 0 for z
self.render_d_line.x2 = self.group_camera.view_x
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.buffer.unbind()
self.render_texture.blit(x=self.dx, y=self.dy, z=0, width=self.width, height=self.height)
gl.glViewport(0, 0, self.window_pointer.width, self.window_pointer.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, window: "ClientWindow"):
@ -352,7 +350,6 @@ class SR1ShipRender(BaseScreen):
if command.find('render'):
if command.find('reset'):
self.group_camera.reset()
self.window_pointer.view = Vec4()
else:
self.status.draw_call = True
print('应该渲染飞船的')

View File

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