no message
This commit is contained in:
420
cocos/renderer/pipeline/xr/ar/ARBackground.cpp
Normal file
420
cocos/renderer/pipeline/xr/ar/ARBackground.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "pipeline/xr/ar/ARBackground.h"
|
||||
#include "ar/ARModule.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "gfx-base/GFXCommandBuffer.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "gfx-base/GFXDevice.h"
|
||||
#include "gfx-base/GFXTexture.h"
|
||||
#include "pipeline/Define.h"
|
||||
#include "pipeline/PipelineStateManager.h"
|
||||
#include "pipeline/forward/ForwardPipeline.h"
|
||||
#include "platform/interfaces/modules/Device.h"
|
||||
#include "scene/Camera.h"
|
||||
|
||||
namespace cc {
|
||||
namespace pipeline {
|
||||
|
||||
ARBackground::~ARBackground() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ARBackground::activate(RenderPipeline *pipeline, gfx::Device *dev) {
|
||||
_device = dev;
|
||||
|
||||
#pragma region _shader
|
||||
|
||||
ShaderSources<StandardShaderSource> sources;
|
||||
|
||||
sources.glsl4 = {
|
||||
R"(
|
||||
precision highp float;
|
||||
layout(location = 0) in vec2 a_position;
|
||||
layout(location = 1) in vec2 a_texCoord;
|
||||
|
||||
layout(location = 0) out vec2 v_texCoord;
|
||||
void main() {
|
||||
gl_Position = vec4(a_position, 0, 1);
|
||||
v_texCoord = a_texCoord;
|
||||
}
|
||||
)",
|
||||
R"(
|
||||
precision highp float;
|
||||
layout(location = 0) in vec2 v_texCoord;
|
||||
layout(set = 1, binding = 0) uniform sampler2D u_YTex;
|
||||
layout(set = 1, binding = 1) uniform sampler2D u_CbCrTex;
|
||||
layout(set = 1, binding = 2) uniform Transfer_Mat {
|
||||
mat4 u_YCbCrToRGB;
|
||||
};
|
||||
|
||||
layout(location = 0) out vec4 o_color;
|
||||
void main() {
|
||||
vec4 ycbcr = vec4(texture(u_YTex, v_texCoord).r, texture(u_CbCrTex, v_texCoord).rg, 1);
|
||||
o_color = u_YCbCrToRGB * ycbcr;
|
||||
}
|
||||
)",
|
||||
};
|
||||
|
||||
sources.glsl3 = {
|
||||
R"(
|
||||
in vec2 a_position;
|
||||
in vec2 a_texCoord;
|
||||
layout(std140) uniform Mats {
|
||||
mat4 u_MVP;
|
||||
mat4 u_CoordMatrix;
|
||||
};
|
||||
|
||||
out vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = (u_CoordMatrix * vec4(a_texCoord, 0, 1)).xy;
|
||||
gl_Position = u_MVP * vec4(a_position, 0, 1);
|
||||
}
|
||||
)",
|
||||
R"(
|
||||
#extension GL_OES_EGL_image_external_essl3 : require
|
||||
precision mediump float;
|
||||
|
||||
in vec2 v_texCoord;
|
||||
uniform samplerExternalOES u_texture;
|
||||
|
||||
out vec4 o_color;
|
||||
void main() {
|
||||
o_color = texture(u_texture, v_texCoord);
|
||||
}
|
||||
)",
|
||||
};
|
||||
|
||||
sources.glsl1 = {
|
||||
R"(
|
||||
attribute vec2 a_position;
|
||||
attribute vec2 a_texCoord;
|
||||
uniform mat4 u_MVP;
|
||||
uniform mat4 u_CoordMatrix;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
void main() {
|
||||
v_texCoord = (u_CoordMatrix * vec4(a_texCoord, 0, 1)).xy;
|
||||
gl_Position = u_MVP * vec4(a_position, 0, 1);
|
||||
}
|
||||
)",
|
||||
R"(
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
uniform samplerExternalOES u_texture;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D(u_texture, v_texCoord);
|
||||
}
|
||||
)",
|
||||
};
|
||||
|
||||
StandardShaderSource &source = getAppropriateShaderSource(sources);
|
||||
|
||||
gfx::ShaderStageList shaderStageList;
|
||||
|
||||
gfx::ShaderStage vertexShaderStage;
|
||||
vertexShaderStage.stage = gfx::ShaderStageFlagBit::VERTEX;
|
||||
vertexShaderStage.source = source.vert;
|
||||
shaderStageList.emplace_back(std::move(vertexShaderStage));
|
||||
|
||||
gfx::ShaderStage fragmentShaderStage;
|
||||
fragmentShaderStage.stage = gfx::ShaderStageFlagBit::FRAGMENT;
|
||||
fragmentShaderStage.source = source.frag;
|
||||
shaderStageList.emplace_back(std::move(fragmentShaderStage));
|
||||
|
||||
gfx::AttributeList attributeList = {
|
||||
{"a_position", gfx::Format::RG32F, false, 0, false, 0},
|
||||
{"a_texCoord", gfx::Format::RG32F, false, 0, false, 1},
|
||||
};
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
gfx::UniformBlockList blockList = {{materialSet, 0, "Mats", {{"u_MVP", gfx::Type::MAT4, 1}, {"u_CoordMatrix", gfx::Type::MAT4, 1}}, 2}};
|
||||
gfx::UniformSamplerTextureList samplerTextures = {{materialSet, 1, "u_texture", gfx::Type::SAMPLER2D, 1}};
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
gfx::UniformBlockList blockList = {{materialSet, 2, "Transfer_Mat", {{"u_YCbCrToRGB", gfx::Type::MAT4, 1}}, 1}};
|
||||
gfx::UniformSamplerTextureList samplerTextures = {{materialSet, 0, "u_YTex", gfx::Type::SAMPLER2D, 1}, {materialSet, 1, "u_CbCrTex", gfx::Type::SAMPLER2D, 1}};
|
||||
#endif
|
||||
gfx::ShaderInfo shaderInfo;
|
||||
shaderInfo.name = "ARBackGround";
|
||||
shaderInfo.stages = std::move(shaderStageList);
|
||||
shaderInfo.attributes = attributeList;
|
||||
shaderInfo.blocks = std::move(blockList);
|
||||
shaderInfo.samplerTextures = std::move(samplerTextures);
|
||||
_shader = _device->createShader(shaderInfo);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region _inputAssembler
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
float vertices[] = {-1, -1, 0, 0,
|
||||
-1, 1, 0, 1,
|
||||
1, -1, 1, 0,
|
||||
1, 1, 1, 1};
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
float vertices[] = {-1, -1, 0, 1,
|
||||
-1, 1, 0, 0,
|
||||
1, -1, 1, 1,
|
||||
1, 1, 1, 0};
|
||||
#endif
|
||||
_vertexBuffer = _device->createBuffer({
|
||||
gfx::BufferUsage::VERTEX,
|
||||
gfx::MemoryUsage::DEVICE,
|
||||
sizeof(vertices),
|
||||
4 * sizeof(float),
|
||||
});
|
||||
_vertexBuffer->update(vertices, sizeof(vertices));
|
||||
|
||||
uint16_t indices[] = {0, 2, 1, 1, 2, 3};
|
||||
gfx::BufferInfo indexBufferInfo = {
|
||||
gfx::BufferUsageBit::INDEX,
|
||||
gfx::MemoryUsage::DEVICE,
|
||||
sizeof(indices),
|
||||
sizeof(uint16_t),
|
||||
};
|
||||
auto *indexBuffer = _device->createBuffer(indexBufferInfo);
|
||||
indexBuffer->update(indices, sizeof(indices));
|
||||
|
||||
gfx::DrawInfo drawInfo;
|
||||
drawInfo.indexCount = 6;
|
||||
gfx::BufferInfo indirectBufferInfo = {
|
||||
gfx::BufferUsageBit::INDIRECT,
|
||||
gfx::MemoryUsage::DEVICE,
|
||||
sizeof(gfx::DrawInfo),
|
||||
sizeof(gfx::DrawInfo),
|
||||
};
|
||||
auto *indirectBuffer = _device->createBuffer(indirectBufferInfo);
|
||||
indirectBuffer->update(&drawInfo, sizeof(gfx::DrawInfo));
|
||||
|
||||
gfx::InputAssemblerInfo inputAssemblerInfo;
|
||||
inputAssemblerInfo.attributes = std::move(attributeList);
|
||||
inputAssemblerInfo.vertexBuffers.emplace_back(_vertexBuffer);
|
||||
inputAssemblerInfo.indexBuffer = indexBuffer;
|
||||
inputAssemblerInfo.indirectBuffer = indirectBuffer;
|
||||
_inputAssembler = _device->createInputAssembler(inputAssemblerInfo);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
gfx::DescriptorSetLayoutInfo dslInfo;
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
dslInfo.bindings.push_back({0, gfx::DescriptorType::UNIFORM_BUFFER, 1, gfx::ShaderStageFlagBit::VERTEX});
|
||||
dslInfo.bindings.push_back({1, gfx::DescriptorType::SAMPLER_TEXTURE, 1, gfx::ShaderStageFlagBit::FRAGMENT});
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
dslInfo.bindings.push_back({0, gfx::DescriptorType::SAMPLER_TEXTURE, 1, gfx::ShaderStageFlagBit::FRAGMENT});
|
||||
dslInfo.bindings.push_back({1, gfx::DescriptorType::SAMPLER_TEXTURE, 1, gfx::ShaderStageFlagBit::FRAGMENT});
|
||||
dslInfo.bindings.push_back({2, gfx::DescriptorType::UNIFORM_BUFFER, 1, gfx::ShaderStageFlagBit::FRAGMENT});
|
||||
#endif
|
||||
_descriptorSetLayout = _device->createDescriptorSetLayout(dslInfo);
|
||||
|
||||
_descriptorSet = _device->createDescriptorSet({_descriptorSetLayout});
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
gfx::BufferInfo uniformBufferInfo = {
|
||||
gfx::BufferUsage::UNIFORM,
|
||||
gfx::MemoryUsage::DEVICE,
|
||||
2 * sizeof(Mat4),
|
||||
};
|
||||
_uniformBuffer = _device->createBuffer(uniformBufferInfo);
|
||||
float mats[] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, -1, 0,
|
||||
0, 0, -1, 1,
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1};
|
||||
_uniformBuffer->update(mats, 2 * sizeof(Mat4));
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
gfx::BufferInfo transferUniformBufferInfo = {
|
||||
gfx::BufferUsage::UNIFORM,
|
||||
gfx::MemoryUsage::DEVICE,
|
||||
sizeof(Mat4),
|
||||
};
|
||||
float transferMats[] = {
|
||||
1.0000f, 1.0000f, 1.0000f, 0.0000f,
|
||||
0.0000f, -.3441f, 1.7720f, 0.0000f,
|
||||
1.4020f, -.7141f, 0.0000f, 0.0000f,
|
||||
-.7010f, 0.5291f, -.8860f, 1.0000f};
|
||||
_ycbcrTransferBuffer = _device->createBuffer(transferUniformBufferInfo);
|
||||
_ycbcrTransferBuffer->update(transferMats, sizeof(Mat4));
|
||||
#endif
|
||||
|
||||
_pipelineLayout = _device->createPipelineLayout({{pipeline->getDescriptorSetLayout(), _descriptorSetLayout}});
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
// background id
|
||||
glGenTextures(1, &_glTex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ARBackground::render(cc::scene::Camera *camera, gfx::RenderPass *renderPass, gfx::CommandBuffer *cmdBuffer) {
|
||||
auto *const armodule = cc::ar::ARModule::get();
|
||||
if (!armodule) return;
|
||||
int apiState = armodule->getAPIState();
|
||||
if (apiState < 0) return;
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
if (armodule->getTexInitFlag()) {
|
||||
gfx::SamplerInfo samplerInfo = {
|
||||
gfx::Filter::LINEAR,
|
||||
gfx::Filter::LINEAR,
|
||||
gfx::Filter::NONE,
|
||||
gfx::Address::CLAMP,
|
||||
gfx::Address::CLAMP,
|
||||
gfx::Address::CLAMP,
|
||||
};
|
||||
|
||||
auto *sampler = _device->getSampler(samplerInfo);
|
||||
armodule->setCameraTextureName(static_cast<int>(_glTex));
|
||||
|
||||
gfx::TextureInfo textureInfo;
|
||||
textureInfo.usage = gfx::TextureUsage::SAMPLED | gfx::TextureUsage::TRANSFER_SRC;
|
||||
textureInfo.format = gfx::Format::RGBA8;
|
||||
textureInfo.width = camera->getWidth();
|
||||
textureInfo.height = camera->getHeight();
|
||||
textureInfo.externalRes = reinterpret_cast<void *>(_glTex);
|
||||
gfx::Texture *backgroundTex = _device->createTexture(textureInfo);
|
||||
|
||||
_descriptorSet->bindBuffer(0, _uniformBuffer);
|
||||
_descriptorSet->bindSampler(1, sampler);
|
||||
_descriptorSet->bindTexture(1, backgroundTex);
|
||||
_descriptorSet->update();
|
||||
|
||||
armodule->resetTexInitFlag();
|
||||
}
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
if (armodule->getTexInitFlag()) {
|
||||
auto *pixelBuffer = armodule->getCameraTextureRef();
|
||||
if (pixelBuffer != nullptr) {
|
||||
gfx::SamplerInfo samplerInfo;
|
||||
auto *sampler = _device->getSampler(samplerInfo);
|
||||
|
||||
gfx::TextureInfo yTexInfo;
|
||||
yTexInfo.usage = gfx::TextureUsage::SAMPLED | gfx::TextureUsage::TRANSFER_SRC;
|
||||
yTexInfo.format = gfx::Format::R8;
|
||||
// TODO: need improvement
|
||||
// here do not effect exactly, just for CC_ASSERT in TextureValidator::doInit
|
||||
yTexInfo.width = 1;
|
||||
yTexInfo.height = 1;
|
||||
yTexInfo.externalRes = pixelBuffer;
|
||||
yTexInfo.layerCount = 0;
|
||||
gfx::TextureInfo cbcrTexInfo;
|
||||
cbcrTexInfo.usage = gfx::TextureUsage::SAMPLED | gfx::TextureUsage::TRANSFER_SRC;
|
||||
cbcrTexInfo.format = gfx::Format::RG8;
|
||||
// TODO: need improvement
|
||||
// here do not effect exactly, just for CC_ASSERT in TextureValidator::doInit
|
||||
cbcrTexInfo.width = 1;
|
||||
cbcrTexInfo.height = 1;
|
||||
cbcrTexInfo.externalRes = pixelBuffer;
|
||||
cbcrTexInfo.layerCount = 1;
|
||||
gfx::Texture *yTex = _device->createTexture(yTexInfo);
|
||||
gfx::Texture *cbcrTex = _device->createTexture(cbcrTexInfo);
|
||||
|
||||
_descriptorSet->bindSampler(0, sampler);
|
||||
_descriptorSet->bindTexture(0, yTex);
|
||||
_descriptorSet->bindSampler(1, sampler);
|
||||
_descriptorSet->bindTexture(1, cbcrTex);
|
||||
_descriptorSet->bindBuffer(2, _ycbcrTransferBuffer);
|
||||
_descriptorSet->update();
|
||||
|
||||
armodule->resetTexInitFlag();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
auto data = armodule->getCameraTexCoords();
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
if (apiState > 1) {
|
||||
float vertices[] = {-1, -1, data[2], data[3],
|
||||
-1, 1, data[0], data[1],
|
||||
1, -1, data[6], data[7],
|
||||
1, 1, data[4], data[5]};
|
||||
_vertexBuffer->update(vertices, sizeof(vertices));
|
||||
} else {
|
||||
float vertices[] = {-1, -1, data[0], data[1],
|
||||
-1, 1, data[2], data[3],
|
||||
1, -1, data[4], data[5],
|
||||
1, 1, data[6], data[7]};
|
||||
_vertexBuffer->update(vertices, sizeof(vertices));
|
||||
}
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
float vertices[] = {-1, -1, data[2], data[3],
|
||||
-1, 1, data[0], data[1],
|
||||
1, -1, data[6], data[7],
|
||||
1, 1, data[4], data[5]};
|
||||
_vertexBuffer->update(vertices, sizeof(vertices));
|
||||
#endif
|
||||
|
||||
gfx::PipelineStateInfo pipelineInfo;
|
||||
pipelineInfo.shader = _shader;
|
||||
pipelineInfo.pipelineLayout = _pipelineLayout;
|
||||
pipelineInfo.renderPass = renderPass;
|
||||
pipelineInfo.inputState = {_inputAssembler->getAttributes()};
|
||||
|
||||
_pipelineState = _device->createPipelineState(pipelineInfo);
|
||||
|
||||
cmdBuffer->bindInputAssembler(_inputAssembler);
|
||||
cmdBuffer->bindPipelineState(_pipelineState);
|
||||
cmdBuffer->bindDescriptorSet(materialSet, _descriptorSet);
|
||||
cmdBuffer->draw(_inputAssembler);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T &ARBackground::getAppropriateShaderSource(ShaderSources<T> &sources) {
|
||||
switch (_device->getGfxAPI()) {
|
||||
case gfx::API::GLES2:
|
||||
return sources.glsl1;
|
||||
case gfx::API::GLES3:
|
||||
return sources.glsl3;
|
||||
case gfx::API::METAL:
|
||||
case gfx::API::VULKAN:
|
||||
return sources.glsl4;
|
||||
default: break;
|
||||
}
|
||||
return sources.glsl4;
|
||||
}
|
||||
|
||||
void ARBackground::destroy() {
|
||||
CC_SAFE_DESTROY_AND_DELETE(_shader);
|
||||
CC_SAFE_DESTROY_AND_DELETE(_vertexBuffer);
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
CC_SAFE_DESTROY_AND_DELETE(_uniformBuffer);
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
CC_SAFE_DESTROY_AND_DELETE(_ycbcrTransferBuffer);
|
||||
#endif
|
||||
CC_SAFE_DESTROY_AND_DELETE(_inputAssembler);
|
||||
CC_SAFE_DESTROY_AND_DELETE(_descriptorSetLayout);
|
||||
CC_SAFE_DESTROY_AND_DELETE(_descriptorSet);
|
||||
CC_SAFE_DESTROY_AND_DELETE(_pipelineLayout);
|
||||
CC_SAFE_DESTROY_AND_DELETE(_pipelineState);
|
||||
}
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace cc
|
||||
85
cocos/renderer/pipeline/xr/ar/ARBackground.h
Normal file
85
cocos/renderer/pipeline/xr/ar/ARBackground.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gfx-agent/DeviceAgent.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "gfx-base/GFXDevice.h"
|
||||
#include "gfx-base/GFXPipelineLayout.h"
|
||||
#include "gfx-base/GFXPipelineState.h"
|
||||
#include "pipeline/RenderStage.h"
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
#include "gfx-gles3/GLES3Wrangler.h"
|
||||
#endif
|
||||
|
||||
namespace cc {
|
||||
namespace pipeline {
|
||||
|
||||
struct StandardShaderSource {
|
||||
ccstd::string vert;
|
||||
ccstd::string frag;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ShaderSources {
|
||||
T glsl4;
|
||||
T glsl3;
|
||||
T glsl1;
|
||||
};
|
||||
|
||||
class CC_DLL ARBackground {
|
||||
public:
|
||||
ARBackground() = default;
|
||||
~ARBackground();
|
||||
|
||||
void activate(RenderPipeline* pipeline, gfx::Device* dev);
|
||||
void render(scene::Camera* camera, gfx::RenderPass* renderPass, gfx::CommandBuffer* cmdBuffer);
|
||||
void destroy();
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
T& getAppropriateShaderSource(ShaderSources<T>& sources);
|
||||
|
||||
gfx::Device* _device{nullptr};
|
||||
|
||||
gfx::Shader* _shader{nullptr};
|
||||
gfx::Buffer* _vertexBuffer{nullptr};
|
||||
|
||||
gfx::InputAssembler* _inputAssembler{nullptr};
|
||||
gfx::DescriptorSetLayout* _descriptorSetLayout{nullptr};
|
||||
gfx::DescriptorSet* _descriptorSet{nullptr};
|
||||
gfx::PipelineLayout* _pipelineLayout{nullptr};
|
||||
gfx::PipelineState* _pipelineState{nullptr};
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
gfx::Buffer* _uniformBuffer{nullptr};
|
||||
GLuint _glTex{0U};
|
||||
#elif CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||
gfx::Buffer* _ycbcrTransferBuffer{nullptr};
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace cc
|
||||
144
cocos/renderer/pipeline/xr/ar/ARStage.cpp
Normal file
144
cocos/renderer/pipeline/xr/ar/ARStage.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "pipeline/xr/ar/ARStage.h"
|
||||
#include "ar/ARModule.h"
|
||||
#include "core/scene-graph/Node.h"
|
||||
#include "gfx-base/GFXCommandBuffer.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
#include "gfx-base/GFXFramebuffer.h"
|
||||
#include "gfx-base/GFXTexture.h"
|
||||
#include "pipeline/Enum.h"
|
||||
#include "pipeline/PipelineSceneData.h"
|
||||
#include "pipeline/PipelineUBO.h"
|
||||
#include "pipeline/RenderPipeline.h"
|
||||
#include "pipeline/forward/ForwardPipeline.h"
|
||||
#include "pipeline/xr/ar/ARBackground.h"
|
||||
#include "scene/Camera.h"
|
||||
#include "scene/RenderWindow.h"
|
||||
|
||||
namespace cc {
|
||||
namespace pipeline {
|
||||
|
||||
RenderStageInfo ARStage::initInfo = {
|
||||
"ARStage",
|
||||
static_cast<uint>(ForwardStagePriority::AR),
|
||||
static_cast<uint>(RenderFlowTag::SCENE)};
|
||||
const RenderStageInfo &ARStage::getInitializeInfo() { return ARStage::initInfo; }
|
||||
|
||||
ARStage::ARStage() {
|
||||
_arBackground = ccnew ARBackground;
|
||||
}
|
||||
|
||||
ARStage::~ARStage() = default;
|
||||
|
||||
bool ARStage::initialize(const RenderStageInfo &info) {
|
||||
RenderStage::initialize(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ARStage::activate(RenderPipeline *pipeline, RenderFlow *flow) {
|
||||
RenderStage::activate(pipeline, flow);
|
||||
|
||||
_arBackground->activate(pipeline, _device);
|
||||
}
|
||||
|
||||
void ARStage::destroy() {
|
||||
CC_SAFE_DESTROY_AND_DELETE(_arBackground);
|
||||
CC_SAFE_DELETE(_pipeline);
|
||||
CC_SAFE_DELETE(_device);
|
||||
RenderStage::destroy();
|
||||
}
|
||||
|
||||
void ARStage::render(scene::Camera *camera) {
|
||||
auto *const armodule = cc::ar::ARModule::get();
|
||||
if (!armodule) return;
|
||||
int apiState = armodule->getAPIState();
|
||||
if (apiState < 0) return;
|
||||
const Node *camNode = camera->getNode();
|
||||
if (armodule->getCameraId() != camNode->_id) return;
|
||||
|
||||
struct RenderData {
|
||||
framegraph::TextureHandle outputTex;
|
||||
framegraph::TextureHandle depth;
|
||||
};
|
||||
auto *const sceneData = _pipeline->getPipelineSceneData();
|
||||
|
||||
float shadingScale{sceneData->getShadingScale()};
|
||||
|
||||
auto arSetup = [&](framegraph::PassNodeBuilder &builder, RenderData &data) {
|
||||
gfx::TextureInfo colorTexInfo = {
|
||||
gfx::TextureType::TEX2D,
|
||||
gfx::TextureUsageBit::COLOR_ATTACHMENT | gfx::TextureUsageBit::SAMPLED,
|
||||
gfx::Format::RGBA16F,
|
||||
static_cast<uint>(camera->getWindow()->getWidth() * shadingScale),
|
||||
static_cast<uint>(camera->getWindow()->getHeight() * shadingScale),
|
||||
};
|
||||
data.outputTex = builder.create(RenderPipeline::fgStrHandleOutColorTexture, colorTexInfo);
|
||||
|
||||
framegraph::RenderTargetAttachment::Descriptor colorAttachmentInfo;
|
||||
colorAttachmentInfo.usage = framegraph::RenderTargetAttachment::Usage::COLOR;
|
||||
colorAttachmentInfo.loadOp = gfx::LoadOp::CLEAR;
|
||||
|
||||
colorAttachmentInfo.endAccesses = {gfx::AccessFlagBit::COLOR_ATTACHMENT_WRITE};
|
||||
|
||||
data.outputTex = builder.write(data.outputTex, colorAttachmentInfo);
|
||||
|
||||
// depth
|
||||
gfx::TextureInfo depthTexInfo{
|
||||
gfx::TextureType::TEX2D,
|
||||
gfx::TextureUsageBit::DEPTH_STENCIL_ATTACHMENT,
|
||||
gfx::Format::DEPTH_STENCIL,
|
||||
static_cast<uint>(_pipeline->getWidth() * shadingScale),
|
||||
static_cast<uint>(_pipeline->getHeight() * shadingScale),
|
||||
};
|
||||
framegraph::RenderTargetAttachment::Descriptor depthAttachmentInfo;
|
||||
depthAttachmentInfo.usage = framegraph::RenderTargetAttachment::Usage::DEPTH_STENCIL;
|
||||
depthAttachmentInfo.loadOp = gfx::LoadOp::CLEAR;
|
||||
depthAttachmentInfo.clearDepth = camera->getClearDepth();
|
||||
depthAttachmentInfo.clearStencil = camera->getClearStencil();
|
||||
depthAttachmentInfo.endAccesses = {gfx::AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE};
|
||||
|
||||
data.depth = builder.create(RenderPipeline::fgStrHandleOutDepthTexture, depthTexInfo);
|
||||
data.depth = builder.write(data.depth, depthAttachmentInfo);
|
||||
|
||||
builder.writeToBlackboard(RenderPipeline::fgStrHandleOutColorTexture, data.outputTex);
|
||||
builder.writeToBlackboard(RenderPipeline::fgStrHandleOutDepthTexture, data.depth);
|
||||
builder.setViewport(_pipeline->getViewport(camera), _pipeline->getScissor(camera));
|
||||
};
|
||||
|
||||
auto offset = _pipeline->getPipelineUBO()->getCurrentCameraUBOOffset();
|
||||
auto arExec = [this, camera, offset](const RenderData & /*data*/, const framegraph::DevicePassResourceTable &table) {
|
||||
auto *cmdBuff = _pipeline->getCommandBuffers()[0];
|
||||
|
||||
auto *renderPass = table.getRenderPass();
|
||||
_arBackground->render(camera, renderPass, cmdBuff);
|
||||
};
|
||||
|
||||
// add pass
|
||||
_pipeline->getFrameGraph().addPass<RenderData>(static_cast<uint>(CommonInsertPoint::DIP_AR_BACKGROUND), ForwardPipeline::fgStrHandleForwardPass, arSetup, arExec);
|
||||
}
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace cc
|
||||
54
cocos/renderer/pipeline/xr/ar/ARStage.h
Normal file
54
cocos/renderer/pipeline/xr/ar/ARStage.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pipeline/RenderStage.h"
|
||||
|
||||
namespace cc {
|
||||
namespace pipeline {
|
||||
|
||||
// ARModule ADD, need remove after modify
|
||||
class ARBackground;
|
||||
|
||||
class CC_DLL ARStage : public RenderStage {
|
||||
public:
|
||||
static const RenderStageInfo &getInitializeInfo();
|
||||
|
||||
ARStage();
|
||||
~ARStage() override;
|
||||
|
||||
bool initialize(const RenderStageInfo &info) override;
|
||||
void activate(RenderPipeline *pipeline, RenderFlow *flow) override;
|
||||
void destroy() override;
|
||||
void render(scene::Camera *camera) override;
|
||||
|
||||
private:
|
||||
static RenderStageInfo initInfo;
|
||||
|
||||
ARBackground *_arBackground = nullptr;
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user