在本次的系列文章中,我們將闡述如何使用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之間的第一個差異之處。
評論
查看更多