在本次的系列文章中,我们将阐述如何使用PowerVR框架创建跨平台跨API的图形应用程序——所有均来自一组源代码文件!
本系列文章将分为以下几个部分:
? PowerVR框架: PVRApi Vulkan和OpenGL ES抽象层
? PowerVR框架:使用PVRApi编写可移植的Vulkan和OpenGL ES 3.0/3.1
? PowerVR框架:使用PVRAssets加载场景、纹理和着色器
? PowerVR框架:了解图像渲染纹理效果的障碍
让我们先从第一部分开始。
第一部分的重点是已清除的屏幕,如下所示:
虽然不是最高级的示例,但其引入了编写框架程序所需的第一个概念。
首先,让我们谈谈PowerVR框架的主旨及使用此框架的原因。
新框架设计的主旨是:
? 支持新的显式API,如Vulkan——展示其强大功率的同时又隐藏了其冗长性
? 继续支持OpenGL ES 3.x ——允许使用快速路径来尽可能地模拟显式API
? 一个源基地支持所有主要的平台——Android、iOS、Windows、Linux和OS X
最重要的是,这个框架使我们得以尽可能多地使用样本化代码来进行高层次的消除设计。
请关注“新PowerVR架构综述”一文获取更多信息,若不熟悉Vulkan请关注“Vulkan API的详细解读”一文。
现在,我们将创建第一个示例——Intro1ClearApi。
创建Intro1ClearApi将需要git、CMake 3.1 +和可以支持的IDE /平台。
以下平台已使用CMake 3.3.1进行测试,并使用了比较合适的SDK 16.1发行版PVRVFrame库:
? Visual Studio 14
? XCode – iOS 和OS X
? Android Ninja 和Visual Studio 14
? Ubuntu 14.04 Make
所有示例和CMake文件都托管在以下资源库的GitHub上:
PVRApiIntro
请参见GitHub页面,了解如何在支持平台上构建及运行Intro1ClearApi。GitHub页面还详细描述了CMake的构建过程。CMake文件是基于您自身项目框架的数据库。若您在创建示例中有任何疑问请在 PowerVR Support或PowerVR Forum上与我们联系。
让我们回顾下第一个概念,即通过Intro1ClearApi编写框架应用程序。所有的源代码均涵括在ClearAPI.cpp中。
编写框架应用程序,我们可以扩展pvr::Shell并实现以下切入点:
class MyApp : public pvr
{
public:
virtual pvr::Result::Enum initApplication(); // Perform non-graphics set-up - audio initialization etc
virtual pvr::Result::Enum initView(); // Graphics set-up - load textures, create command buffers etc
virtual pvr::Result::Enum renderFrame(); // Render frame called at VSync rate - submit command buffers etc
virtual pvr::Result::Enum releaseView(); // Graphics tear down - delete textures, command buffers etc
virtual pvr::Result::Enum quitApplication(); // Non-graphics tear down - close audio devices etc
};
initApplication()和quitApplication()——对于Intro1ClearAPI,我们可以在这两个函数时返回至pvr::Result::Success。这里没有非图像设置。
initView()——形成了Intro1ClearAPI的核心。在现代API如Vulkan中,我们想在主要渲染线程(renderFrame()函数)之外创建命令缓冲区。这时我们便可以使用第二个线程或者根据命令缓冲区的静态要求在initView()上完成。对于Intro1ClearAPI,我们在initView() 时准备所有命令缓冲区,即在交换链中为每一帧缓冲创建一个命令缓冲区。在renderFrame()中提交所有命令缓冲区。
pvr::Result::Enum OGLESIntroducingPVRApi::initView() {
onscreenFB = getGraphicsContext()->createOnScreenFboSet(); // This returns an array of our on-screen frame buffers. In OpenGL ES we just receive one.
// We then create a command buffer for each frame buffer
for (int i = 0 ; i < getSwapChainLength(); i++){
onscreenCBArray.add(getGraphicsContext()->createCommandBufferOnDefaultPool());
auto & cb = onscreenCBArray[i];
auto & frameBuffer = onscreenFB[i];
// We record a command buffer with a render pass that clears the screen for each frame buffer
cb->beginRecording();
cb->beginRenderPass(frameBuffer, pvr::Rectanglei(0, 0, getWidth(), getHeight()),false,
glm::vec4(123.0 / 255.0, 172.0 / 255.0, 189.0 / 255.0, 1.0));
cb->endRenderPass();
cb->endRecording();
}
return pvr::Result::Success;
};
renderFrame()——在这里,我们通过initView()为每个帧缓冲创建了一个命令缓冲区。renderFrame()以initView()命名,以VSync…率渲染框架。通过调用getSwapChainIndex(),可以确定交换链中接下来是哪些帧缓冲。然后再为帧缓冲提交相应的命令缓冲区——将我们的框架渲染至屏幕中。
pvr::Result::Enum OGLESIntroducingPVRApi::renderFrame(){
onscreenCBArray[getSwapChainIndex()]->submit();
return pvr::Result::Success;
}
在Vulkan中提交命令缓冲区的成本很低——仅在渲染线程中提交命令缓冲区可以确保帧速率的稳定。如果需要一个新的命令缓冲区,则可以在后台线程中创建——充分利用现代多核处理器的优势。
releaseView()——这是最后一个覆盖的函数,随后我们又返回到pvr::Result::Success。
这篇介绍中,我们回顾了使用PowerVR框架渲染屏幕所需的最简单的原则。
相比原始的Vulkan调用,这里已经大量减少了冗余。相比较而言,这里生成的是API流——包括结构参数——通过PowerVR框架渲染基本场景Intro1ClearApi Vulkan API调用而生成。
该框架还通过将EGL/windowset-upIntro1ClearApi OpenGL ES调用抽象化而简化了OpenGL ES渲染。
更重要的是,这个相同的代码覆盖了所有平台——OpenGL ES和Vulkan,实现了适用于这两种API的抽象。
在接下来的文章中,我将阐述绘制三角形的过程,展示使用PVRApi 时Vulkan和OpenGL ES之间的第一个差异之处。
评论
查看更多