一种让程序支持多渲染器的方法
在实际开发中,我们往往倾向于使用新的渲染器API进行图形的绘制,但是担心当部署到目标机器上时,由于硬件和显卡配置的限制而无法使用新的渲染器API。这可真让开发者们头疼。由于不同模型的格式不一样,渲染的方法也不尽相同,再加上渲染器的千变万化,让我们的工作量加大了很多!
一种解决方案是使用游戏引擎来解决问题。本文并不是介绍究竟如何使用这些引擎,而是提出了一种自己的方案,通过为每一个渲染器写一个渲染处理器(render handler)来化解这性能和兼容性的矛盾。
实例:我在开发的时候层考虑如果使用了在OpenGL1.5中提出来的VBO,那么移植到目标机器上时可能会抛弃那些并不支持OpenGL1.5规范的机器(因为可能显卡驱动没有安装等原因而无法支持OpenGL1.5规范)。不过使用glBegin()、glEnd()这样一个顶点一个顶点地添加的确会降低性能,想用VBO来提高性能。怎么办呢?
使用C++的多态机制可以解决问题。根据多次游戏程序编写的经验,我发现一般资源都会经过初始化、使用和回收三个过程,所以我将这三个过程作为纯虚函数提炼出来。成为了IRenderHandler接口。
class IRenderHandler
{
public:
virtual void Init( void ) = 0;
virtual void Render( void ) = 0;
virtual void Release( void ) = 0;
};
IRenderHandler是一个接口类,它抽象了一段渲染过程,子类或实现可以重写这三个纯虚函数,做出不同的渲染效果。
一个很简单的继承例子是,如果应用程序需要DirectX和OpenGL的支持,那么简单地继承这个接口成为两个顶级接口即可。
class IGLRenderHandler: publicIRenderHandler
{
};
class IDXRenderHandler: publicIRenderHandler
{
};
更具体的情况,想要渲染各个模型,由于各个模型的渲染方式不一样,这样的情况必须再从中继承一个类以适应不同模型的渲染情况。
class MMDRenderHandler: publicIGLRenderHandler
{
public:
virtual ~MMDRenderHandler( void ) { }
……
void Init( void )
{
……
}
protected:
QVector<quint16> m_Indices;
QVector<Material> m_Materials;
QVector<Texture2D> m_Textures;
QVector<Bone> m_Bones;
QString m_Dir;
……
};
对于OpenGL1.1规范和OpenGL1.5规范,再从中继承两个类以实现不同OpenGL规范的渲染。
class MMDRenderHandler_1_1:
public MMDRenderHandler,
protected QOpenGLFunctions_1_1
{
voidInit( void )
{
……
}
void Render(void )
{
……
}
void Release(void )
{
……
}
}
class MMDRenderHandler_1_5:
public MMDRenderHandler,
protected QOpenGLFunctions_1_5
{
void Init( void)
{
……
}
void Render(void )
{
……
}
void Release(void )
{
……
}
};
我使用的是Qt,对于各种OpenGL规范,Qt为我们提供了各种程序集,我和大家一样,无法具体知道每一个函数是从OpenGL什么版本开始提供的,又有哪些函数从OpenGL什么版本开始消失的,还好Qt提供了QOpenGLFunctions_X_X这样的类,通过其保护继承可以让开发者知道在某个版本中OpenGL的函数是否可用,如果不可用,它会报编译错误(OpenGL1.1以及以前的函数除外)。
在Qt中有一个非常方便的函数,可以判断当前系统支持的最高的OpenGL版本,它就是QGLFormat::openGLVersionFlags( )静态函数。我们使用一个指针(或智能指针)保存渲染处理器的地址,像这样:
QScopedPointer<MMDRenderHandler>m_pRenderHandler;
根据系统环境来渲染的代码是:
// 看看OpenGL标准来决定渲染器
if ( QGLFormat::openGLVersionFlags( ) &QGLFormat::OpenGL_Version_1_5 )
{
m_pRenderHandler.reset( new MMDRenderHandler_1_5 );
}
else if ( QGLFormat::openGLVersionFlags( )& QGLFormat::OpenGL_Version_1_1 )
{
m_pRenderHandler.reset( new MMDRenderHandler_1_1 );
}
在开发中,我接触过一游戏引擎,我看到它们对渲染器的封装很深,不过不外乎在渲染时有BeginRender()和EndRender()这样的函数。BeginRender()这样的函数我想意义在于将顶点缓存暴露出来供用户填充数据进来,而EndRender()函数则是结束用户的顶点输入,提交顶点。这里BeginRender()和EndRender()看起来和glBegin()、glEnd()的作用差不多,但由于一些特殊而高效的数据结构使得游戏引擎的执行效率很高。BeginRender()和EndRender()这对函数还包含了对渲染器代码的封装,使得使用跨渲染器的游戏引擎成为可能。
分享到:
相关推荐
这个程序有13种渲染模式,在每种模式中都有特定的场景,在不同的情况下,我们可以使用其中一种模式作为最佳的渲染模式。 安装说明:https://blog.csdn.net/hongfu951/article/details/11 解压密码:123
一个 3d 场景渲染器,支持 OpenGL 中的交互式查看和使用光线追踪的逼真渲染。 在克莱姆森大学期间,我学到了很多有关计算机图形学的知识。 这是我们部门关注的一件大事。 这样做的结果是,我最终喜欢制作光线追踪器...
最初,此工具支持PlayStation 3,但现在已经扩展到支持一系列其他媒体渲染器,包括Xbox 360和各种三星和索尼电视机。通用媒体服务器可以从许多平台以最小配置流式传输或转码许多不同的媒体格式。它由MPlayer和FFmpeg...
它还包括智能墙、门和窗、SketchUp翻译器、动态快照指示器、3D布尔操作、MText、SHX字体支持、实体属性编辑器、渲染增强和新的符号工具。 DataCAD 2021是一个一体化的CAD应用程序,它为建筑师和工程师提供了所有...
*基于模板,实现了一种简单的反射机制,以完全解耦主程序框架,控制器和视图。 *支持cookie和内置会话; *支持后端渲染,控制器将数据生成到视图以生成Html页面。视图由CSP模板文件描述,C ++代码通过CSP标记嵌入到...
材质X MaterialX是用于在应用程序和渲染器之间传递丰富材质和外观开发内容的开放标准。 MaterialX起源于2012年的Lucasfilm,已被Industrial Light&Magic(ILM)用于诸如《星球大战:原力觉醒》等故事片和诸如...
V-Ray渲染器提供了一种特殊的材质——VrayMtl。在场景中使用该材质能够获得更加准确的物理照明(光能分布),更快的渲染,反射和折射参数调节更方便。使用VrayMtl,你可以应用不同的纹理贴图,控制其反射和折射,...
泰格 TIGL Demo这个项目概述了TIGL与Titanium移动应用程序一起提供的...一个JavaScript模块,它提供了一种优化且更方便的方式来控制java模块 入门 先决条件: 和必须正确安装并在您的计算机上运行。 要安装Tianium,可
Markdown 文档自动即时渲染为微信图文,让你不再为微信文章排版而发愁!只要你会基本的 Markdown 语法,就能做出一篇样式简洁而又美观大方的微信图文。 功能特性 支持自定义 CSS 样式 支持 Markdown 所有基础语法...
开放式着色语言(OSL)是一种小而丰富的语言,用于高级渲染器和其他应用程序中的可编程着色,非常适合描述材质,灯光,位移和图案生成。 OSL最初是由Sony Pictures Imageworks开发的,用于其内部渲染器(用于故事片...
画布具有一种将其内容作为data:image URL获取的方法,该方法用于获取原始浏览器请求的重定向URL。 所以: 阻止原始请求 使用XHR从请求的URL加载图像数据 将接收到的图像数据渲染到画布中 从画布获取data:image ...
React Liberty 可以自由选择 WebGL / Canvas / DOM / Native 或任何其他 UI 渲染器 这是一个 React 库,旨在通过呈现三种实体来抽象渲染器。 它们是图像、文本和容器。 React Liberty 使用 CSS Layout 来布置组件,...
SVG 是可缩放矢量图形(Scalable Vector Graphics),基于可扩展标记语言,用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。SVG 的优势有很多: SVG 使用 XML 格式定义图形,可通过文本编辑...
CaTeX是一个开源项目,旨在提供一种在Flutter中快速渲染TeX的方法。 对于(因此是关联)而言,这是必需的。 它也由维护(请参阅文件),最初由单独创建。笔记CaTeX是v0.1之前的版本,并且不支持某些主要的TeX功能。...
UGUI 节点图框架,具有节点、端口和连接功能,支持拖放、自定义 UI 线条渲染器,并提供有用功能,用于创建节点图、流程图、电路板、连接拼图等各种创造性的交互方式,供用户与您的游戏或应用程序交互。 通过使用 API...
由于安装在连接到本地网络的其他Mac或PC计算机上的应用程序,渲染管理器可以在所有网络计算机之间分散渲染,从而大大缩短计算时间。 5、白平衡 白平衡允许您将场景的主色调整为环境照明。只需将此新参数设置为自动...
该项目的目的是提供一种可在所有设备上运行的快速轻量级2D库。 PixiJS渲染器使每个人都可以享受硬件加速的强大功能,而无需WebGL的先验知识。 而且,它很快。 真快。 如果您想随时了解PixiJS的最新消息,请随时在...
该项目的目的是提供一种适用于所有设备的快速轻量级2D库。 PixiJS渲染器使每个人都可以享受硬件加速的强大功能,而无需WebGL的先验知识。 而且,它很快。 真快。 如果你想要跟上最新的最新消息PixiJS然后随意跟随...
说明了一种在运行时利用已解析的XAML的方法。 小文件应该很好,但大文件可能不是最好的方法。 产品特点 支持Markdig的所有标准功能(即完全兼容CommonMark)。 此外,支持以下扩展: 自动连结 任务列表(仅WPF...
Java SSM项目是一种使用Java语言和SSM框架(Spring + Spring MVC + MyBatis)开发的Web应用程序。SSM是一种常用的Java开发框架组合,它结合了Spring框架、Spring MVC框架和MyBatis框架的优点,能够快速构建可靠、...