194 lines
6.6 KiB
Python
194 lines
6.6 KiB
Python
# -*- coding: utf-8-*-
|
||
"""
|
||
Module : Panda3DWorld
|
||
Author : Saifeddine ALOUI
|
||
Description :
|
||
Inherit this object to create your custom world
|
||
"""
|
||
import sys
|
||
import os
|
||
|
||
from core.CustomMouseController import CustomMouseController
|
||
|
||
# 获取 RenderPipelineFile 的路径
|
||
render_pipeline_path = './RenderPipelineFile'
|
||
# 将该路径添加到 sys.path 中,确保 Python 能够找到它
|
||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||
sys.path.insert(0, project_root)
|
||
sys.path.insert(0, render_pipeline_path)
|
||
|
||
# 现在你可以导入 RenderPipelineFile 中的模块了
|
||
# 例如,如果你想导入 RenderPipelineFile 中的 RenderPipeline 模块
|
||
from RenderPipelineFile.rpcore import RenderPipeline
|
||
_global_render_pipeline = None
|
||
|
||
# PyQt imports
|
||
from PyQt5.QtCore import *
|
||
from PyQt5.QtGui import *
|
||
from PyQt5.QtWidgets import *
|
||
|
||
# Panda imports
|
||
from panda3d.core import *
|
||
# from panda3d.core import loadPrcFileData
|
||
# loadPrcFileData("", "window-type none") # Set Panda to draw its main window in an offscreen buffer
|
||
from direct.showbase.DirectObject import DirectObject
|
||
from panda3d.core import GraphicsOutput, Texture, ConfigVariableManager, WindowProperties
|
||
|
||
# Set up Panda environment
|
||
from direct.showbase.ShowBase import ShowBase
|
||
import platform
|
||
|
||
# Local imports
|
||
from QPanda3D.QMouseWatcherNode import QMouseWatcherNode
|
||
|
||
from RenderPipelineFile.rpcore.render_target import RenderTarget
|
||
__all__ = ["Panda3DWorld"]
|
||
|
||
_global_world_instance=None
|
||
import builtins
|
||
|
||
|
||
class Panda3DWorld(ShowBase):
|
||
"""
|
||
Panda3DWorld : A class to handle all panda3D world manipulation
|
||
"""
|
||
|
||
def __init__(self, width=1254, height=729, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1),
|
||
name="qpanda3D"):
|
||
|
||
global _global_world_instance
|
||
global _global_render_pipeline
|
||
|
||
_global_world_instance = self
|
||
|
||
sort = -100
|
||
self.parent = None
|
||
|
||
# 设置基本配置
|
||
loadPrcFileData("", "show-frame-rate-meter 0")
|
||
loadPrcFileData("", "window-type offscreen") # 设置为离屏渲染
|
||
loadPrcFileData("", f"win-size {width} {height}")
|
||
loadPrcFileData("", "win-fixed-size #f") # 允许窗口调整大小
|
||
|
||
if (is_fullscreen):
|
||
loadPrcFileData("", "fullscreen #t")
|
||
|
||
self.render_pipeline = RenderPipeline()
|
||
self.render_pipeline.pre_showbase_init()
|
||
|
||
ShowBase.__init__(self)
|
||
|
||
# 初始化渲染管线并设置可调整大小的标志
|
||
self.render_pipeline.create(self)
|
||
_global_render_pipeline = self.render_pipeline
|
||
|
||
# 创建 Qt 能读的 RGBA8 贴图
|
||
self.qt_output_tex = Texture("qt_output_tex")
|
||
self.qt_output_tex.set_format(Texture.F_rgba8)
|
||
self.qt_output_tex.set_component_type(Texture.T_unsigned_byte)
|
||
|
||
# # 获取图形管线对象
|
||
# gsg = self.win.getGsg()
|
||
# host = gsg.getEngine().getHost()
|
||
|
||
self.win.add_render_texture(self.qt_output_tex, GraphicsOutput.RTM_copy_ram)
|
||
|
||
#self.screenTexture = Texture()
|
||
#self.screenTexture.setMinfilter(Texture.FTLinear)
|
||
#self.screenTexture.setFormat(Texture.FRgba32)
|
||
#self.screenTexture.set_wrap_u(Texture.WM_clamp)
|
||
#self.screenTexture.set_wrap_v(Texture.WM_clamp)
|
||
|
||
# buff_size_x = int(self.win.get_x_size() * size)
|
||
# buff_size_y = int(self.win.get_y_size() * size)
|
||
# winprops = WindowProperties()
|
||
# winprops.set_size(buff_size_x, buff_size_y)
|
||
#
|
||
#
|
||
# props = FrameBufferProperties()
|
||
# props.set_rgb_color(True)
|
||
# props.set_rgba_bits(8, 8, 8, 8)
|
||
# props.set_depth_bits(8)
|
||
|
||
# self.buff = self.graphicsEngine.make_output(
|
||
# self.pipe, name, sort,
|
||
# props, winprops,
|
||
# GraphicsPipe.BF_resizeable,
|
||
# self.win.get_gsg(), self.win)
|
||
|
||
#self.screenTexture = render_pipeline._final_stage.target.color_tex
|
||
|
||
#self.buff.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
|
||
# self.buff.set_sort(sort)
|
||
|
||
|
||
|
||
#self.cam = self.makeCamera(self.buff)
|
||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||
|
||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||
|
||
#self.render_pipeline._showbase.camera.reparentTo(self.render)
|
||
#base.camera.reparentTo(self.render)
|
||
#self.cam.reparentTo(self.render) # 可选同步
|
||
|
||
#render_pipeline.set_camera(self.cam)
|
||
|
||
#添加渲染效果<E69588><E69E9C>
|
||
#self.cam = self.render_pipeline._showbase.cam
|
||
#self.camNode = self.cam.node()
|
||
#self.camLens = self.camNode.get_lens()
|
||
self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
|
||
#self.render_pipeline.daytime_mgr.update()
|
||
|
||
|
||
# if clear_color is None:
|
||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, False)
|
||
# else:
|
||
# self.buff.set_clear_color(clear_color)
|
||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, True)
|
||
|
||
# self.disableMouse()
|
||
self.mouse_controller = CustomMouseController(self)
|
||
self.mouse_controller.setUp()
|
||
|
||
def render_pipeline(self):
|
||
"""获取 RenderPipeline 实例"""
|
||
return self._render_pipeline
|
||
|
||
|
||
def set_parent(self, parent: QWidget):
|
||
self.parent = parent
|
||
self.mouseWatcherNode = QMouseWatcherNode(parent)
|
||
|
||
def getAspectRatio(self, win = None):
|
||
if win is None and self.parent is not None:
|
||
return float(self.parent.width()) / float(self.parent.height())
|
||
else:
|
||
return super().getAspectRatio(win)
|
||
|
||
def get_render_pipeline():
|
||
"""获取全局 RenderPipeline 单例"""
|
||
if _global_render_pipeline is None:
|
||
raise RuntimeError(
|
||
"RenderPipeline has not been initialized yet. Please create a Panda3DWorld instance first.")
|
||
return _global_render_pipeline
|
||
|
||
def resize_buffer(self, width: int, height: int):
|
||
"""根据新窗口尺寸调整 Panda3D 渲染输出尺寸"""
|
||
# 设置 Panda3D 的窗口尺寸(offscreen 模式下对应输出区域)
|
||
props = WindowProperties()
|
||
props.set_size(width, height)
|
||
self.win.request_properties(props)
|
||
|
||
# 重新分配输出贴图的大小
|
||
self.qt_output_tex.set_x_size(width)
|
||
self.qt_output_tex.set_y_size(height)
|
||
|
||
# 更新 lens 的 aspect ratio
|
||
if self.camLens:
|
||
self.camLens.set_film_size(width, height) # 或 set_aspect_ratio(width / height)
|
||
|
||
# 强制更新窗口(有时在 Qt 内嵌时需要)
|
||
self.graphicsEngine.open_windows()
|