在本次的系列文章中,我們將闡述如何使用PowerVR框架創(chuàng)建跨平臺跨API的圖形應用程序——所有均來自一組源代碼文件!
本系列文章將分為以下幾個部分:
? PowerVR框架: PVRApi Vulkan和OpenGL ES抽象層
? PowerVR框架:使用PVRApi編寫可移植的Vulkan和OpenGL ES 3.0/3.1
? PowerVR框架:使用PVRAssets加載場景、紋理和著色器
? PowerVR框架:了解圖像渲染紋理效果的障礙
讓我們先從第一部分開始。
第一部分的重點是已清除的屏幕,如下所示:
雖然不是最高級的示例,但其引入了編寫框架程序所需的第一個概念。
首先,讓我們談談PowerVR框架的主旨及使用此框架的原因。
新框架設計的主旨是:
? 支持新的顯式API,如Vulkan——展示其強大功率的同時又隱藏了其冗長性
? 繼續(xù)支持OpenGL ES 3.x ——允許使用快速路徑來盡可能地模擬顯式API
? 一個源基地支持所有主要的平臺——Android、iOS、Windows、Linux和OS X
最重要的是,這個框架使我們得以盡可能多地使用樣本化代碼來進行高層次的消除設計。
請關(guān)注“新PowerVR架構(gòu)綜述”一文獲取更多信息,若不熟悉Vulkan請關(guān)注“Vulkan API的詳細解讀”一文。
現(xiàn)在,我們將創(chuàng)建第一個示例——Intro1ClearApi。
創(chuàng)建Intro1ClearApi將需要git、CMake 3.1 +和可以支持的IDE /平臺。
以下平臺已使用CMake 3.3.1進行測試,并使用了比較合適的SDK 16.1發(fā)行版PVRVFrame庫:
? Visual Studio 14
? XCode – iOS 和OS X
? Android Ninja 和Visual Studio 14
? Ubuntu 14.04 Make
所有示例和CMake文件都托管在以下資源庫的GitHub上:
PVRApiIntro
請參見GitHub頁面,了解如何在支持平臺上構(gòu)建及運行Intro1ClearApi。GitHub頁面還詳細描述了CMake的構(gòu)建過程。CMake文件是基于您自身項目框架的數(shù)據(jù)庫。若您在創(chuàng)建示例中有任何疑問請在 PowerVR Support或PowerVR Forum上與我們聯(lián)系。
讓我們回顧下第一個概念,即通過Intro1ClearApi編寫框架應用程序。所有的源代碼均涵括在ClearAPI.cpp中。
編寫框架應用程序,我們可以擴展pvr::Shell并實現(xiàn)以下切入點:
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,我們可以在這兩個函數(shù)時返回至pvr::Result::Success。這里沒有非圖像設置。
initView()——形成了Intro1ClearAPI的核心。在現(xiàn)代API如Vulkan中,我們想在主要渲染線程(renderFrame()函數(shù))之外創(chuàng)建命令緩沖區(qū)。這時我們便可以使用第二個線程或者根據(jù)命令緩沖區(qū)的靜態(tài)要求在initView()上完成。對于Intro1ClearAPI,我們在initView() 時準備所有命令緩沖區(qū),即在交換鏈中為每一幀緩沖創(chuàng)建一個命令緩沖區(qū)。在renderFrame()中提交所有命令緩沖區(qū)。
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()為每個幀緩沖創(chuàng)建了一個命令緩沖區(qū)。renderFrame()以initView()命名,以VSync…率渲染框架。通過調(diào)用getSwapChainIndex(),可以確定交換鏈中接下來是哪些幀緩沖。然后再為幀緩沖提交相應的命令緩沖區(qū)——將我們的框架渲染至屏幕中。
pvr::Result::Enum OGLESIntroducingPVRApi::renderFrame(){
onscreenCBArray[getSwapChainIndex()]->submit();
return pvr::Result::Success;
}
評論
查看更多