mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller Scene] Wire up camera (flutter/engine#38053)
* [Impeller Scene] Wire up camera * Resolve view transform once
This commit is contained in:
parent
ab78871b66
commit
cfccb9ed0b
@ -7,7 +7,7 @@
|
||||
namespace impeller {
|
||||
namespace scene {
|
||||
|
||||
Camera Camera::MakePerspective(Scalar fov_y, Vector3 position) {
|
||||
Camera Camera::MakePerspective(Radians fov_y, Vector3 position) {
|
||||
Camera camera;
|
||||
camera.fov_y_ = fov_y;
|
||||
camera.position_ = position;
|
||||
@ -26,9 +26,8 @@ Matrix Camera::GetTransform(ISize target_size) const {
|
||||
return transform_.value();
|
||||
}
|
||||
|
||||
transform_ =
|
||||
Matrix::MakePerspective(Radians(fov_y_), target_size, z_near_, z_far_) *
|
||||
Matrix::MakeLookAt(position_, target_, up_).Invert();
|
||||
transform_ = Matrix::MakePerspective(fov_y_, target_size, z_near_, z_far_) *
|
||||
Matrix::MakeLookAt(position_, target_, up_);
|
||||
|
||||
return transform_.value();
|
||||
}
|
||||
|
||||
@ -13,14 +13,14 @@ namespace scene {
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
static Camera MakePerspective(Scalar fov_y, Vector3 position);
|
||||
static Camera MakePerspective(Radians fov_y, Vector3 position);
|
||||
|
||||
Camera LookAt(Vector3 target, Vector3 up = Vector3(0, -1, 0)) const;
|
||||
|
||||
Matrix GetTransform(ISize target_size) const;
|
||||
|
||||
private:
|
||||
Scalar fov_y_ = 60;
|
||||
Radians fov_y_ = Degrees(60);
|
||||
Vector3 position_ = Vector3();
|
||||
Vector3 target_ = Vector3(0, 0, -1);
|
||||
Vector3 up_ = Vector3(0, -1, 0);
|
||||
|
||||
@ -26,7 +26,7 @@ bool Scene::Render(const RenderTarget& render_target,
|
||||
const Camera& camera) const {
|
||||
// Collect the render commands from the scene.
|
||||
SceneEncoder encoder;
|
||||
if (!root_.Render(encoder, camera)) {
|
||||
if (!root_.Render(encoder)) {
|
||||
FML_LOG(ERROR) << "Failed to render frame.";
|
||||
return false;
|
||||
}
|
||||
@ -34,7 +34,7 @@ bool Scene::Render(const RenderTarget& render_target,
|
||||
// Encode the commands.
|
||||
|
||||
std::shared_ptr<CommandBuffer> command_buffer =
|
||||
encoder.BuildSceneCommandBuffer(*scene_context_, render_target);
|
||||
encoder.BuildSceneCommandBuffer(*scene_context_, camera, render_target);
|
||||
|
||||
// TODO(bdero): Do post processing.
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ void SceneEncoder::Add(const SceneCommand& command) {
|
||||
}
|
||||
|
||||
static void EncodeCommand(const SceneContext& scene_context,
|
||||
const Matrix& view_transform,
|
||||
RenderPass& render_pass,
|
||||
const SceneCommand& scene_command) {
|
||||
auto& host_buffer = render_pass.GetTransientsBuffer();
|
||||
@ -39,7 +40,7 @@ static void EncodeCommand(const SceneContext& scene_context,
|
||||
scene_command.material->BindToCommand(scene_context, host_buffer, cmd);
|
||||
|
||||
GeometryVertexShader::VertInfo info;
|
||||
info.mvp = scene_command.transform;
|
||||
info.mvp = view_transform * scene_command.transform;
|
||||
GeometryVertexShader::BindVertInfo(cmd, host_buffer.EmplaceUniform(info));
|
||||
|
||||
render_pass.AddCommand(std::move(cmd));
|
||||
@ -47,6 +48,7 @@ static void EncodeCommand(const SceneContext& scene_context,
|
||||
|
||||
std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
|
||||
const SceneContext& scene_context,
|
||||
const Camera& camera,
|
||||
const RenderTarget& render_target) const {
|
||||
auto command_buffer = scene_context.GetContext()->CreateCommandBuffer();
|
||||
if (!command_buffer) {
|
||||
@ -61,7 +63,9 @@ std::shared_ptr<CommandBuffer> SceneEncoder::BuildSceneCommandBuffer(
|
||||
}
|
||||
|
||||
for (auto& command : commands_) {
|
||||
EncodeCommand(scene_context, *render_pass, command);
|
||||
Matrix view_transform =
|
||||
camera.GetTransform(render_pass->GetRenderTargetSize());
|
||||
EncodeCommand(scene_context, view_transform, *render_pass, command);
|
||||
}
|
||||
|
||||
if (!render_pass->EncodeCommands()) {
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/renderer/command_buffer.h"
|
||||
#include "impeller/scene/camera.h"
|
||||
#include "impeller/scene/geometry.h"
|
||||
#include "impeller/scene/material.h"
|
||||
|
||||
@ -34,6 +35,7 @@ class SceneEncoder {
|
||||
|
||||
std::shared_ptr<CommandBuffer> BuildSceneCommandBuffer(
|
||||
const SceneContext& scene_context,
|
||||
const Camera& camera,
|
||||
const RenderTarget& render_target) const;
|
||||
|
||||
std::vector<SceneCommand> commands_;
|
||||
|
||||
@ -56,17 +56,17 @@ bool SceneEntity::Add(const std::shared_ptr<SceneEntity>& child) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneEntity::Render(SceneEncoder& encoder, const Camera& camera) const {
|
||||
OnRender(encoder, camera);
|
||||
bool SceneEntity::Render(SceneEncoder& encoder) const {
|
||||
OnRender(encoder);
|
||||
for (auto& child : children_) {
|
||||
if (!child->Render(encoder, camera)) {
|
||||
if (!child->Render(encoder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneEntity::OnRender(SceneEncoder& encoder, const Camera& camera) const {
|
||||
bool SceneEntity::OnRender(SceneEncoder& encoder) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -34,13 +34,13 @@ class SceneEntity {
|
||||
|
||||
bool Add(const std::shared_ptr<SceneEntity>& child);
|
||||
|
||||
bool Render(SceneEncoder& encoder, const Camera& camera) const;
|
||||
bool Render(SceneEncoder& encoder) const;
|
||||
|
||||
protected:
|
||||
Matrix local_transform_;
|
||||
|
||||
private:
|
||||
virtual bool OnRender(SceneEncoder& encoder, const Camera& camera) const;
|
||||
virtual bool OnRender(SceneEncoder& encoder) const;
|
||||
|
||||
SceneEntity* parent_ = nullptr;
|
||||
std::vector<std::shared_ptr<SceneEntity>> children_;
|
||||
|
||||
@ -37,20 +37,21 @@ TEST_P(SceneTest, CuboidUnlit) {
|
||||
material->SetColor(Color::Red());
|
||||
mesh->SetMaterial(std::move(material));
|
||||
|
||||
Vector3 size(1, 2, 3);
|
||||
Vector3 size(1, 1, 0);
|
||||
mesh->SetGeometry(Geometry::MakeCuboid(size));
|
||||
|
||||
mesh->SetLocalTransform(Matrix::MakeTranslation(size / 2));
|
||||
mesh->SetLocalTransform(Matrix::MakeTranslation(-size / 2));
|
||||
|
||||
scene.Add(mesh);
|
||||
}
|
||||
|
||||
// Face towards the +Z direction (+X right, +Y up).
|
||||
auto camera = Camera::MakePerspective(
|
||||
/* fov */ kPiOver4,
|
||||
/* position */ {50, -30, 50})
|
||||
/* fov */ Radians(kPiOver4),
|
||||
/* position */ {2, 2, -5})
|
||||
.LookAt(
|
||||
/* target */ Vector3(),
|
||||
/* up */ {0, -1, 0});
|
||||
/* up */ {0, 1, 0});
|
||||
|
||||
scene.Render(render_target, camera);
|
||||
return true;
|
||||
|
||||
@ -24,8 +24,7 @@ void StaticMeshEntity::SetMaterial(std::shared_ptr<Material> material) {
|
||||
}
|
||||
|
||||
// |SceneEntity|
|
||||
bool StaticMeshEntity::OnRender(SceneEncoder& encoder,
|
||||
const Camera& camera) const {
|
||||
bool StaticMeshEntity::OnRender(SceneEncoder& encoder) const {
|
||||
SceneCommand command = {
|
||||
.label = "Static Mesh",
|
||||
.transform = GetGlobalTransform(),
|
||||
|
||||
@ -25,7 +25,7 @@ class StaticMeshEntity final : public SceneEntity {
|
||||
|
||||
private:
|
||||
// |SceneEntity|
|
||||
bool OnRender(SceneEncoder& encoder, const Camera& camera) const override;
|
||||
bool OnRender(SceneEncoder& encoder) const override;
|
||||
|
||||
std::shared_ptr<Material> material_;
|
||||
std::shared_ptr<Geometry> geometry_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user