NativeScript, NativeScriptComponent

- Added NativeScript
- Added NativeScriptComponent
- Minor changes to clearing back buffer's color
This commit is contained in:
Light 2021-07-31 09:37:09 +04:30
parent aab0c7b958
commit c846e48c71
14 changed files with 170 additions and 56 deletions

View file

@ -0,0 +1,5 @@
#pragma once
// #todo: add project config stuff
// #define LIGHT_IGNORE_UNDEFINED_DEBUG_BREAK

View file

@ -12,8 +12,6 @@ namespace Light {
{
unsigned int width, height;
unsigned int samples = 1;
glm::uvec4 defaultColor = glm::uvec4(0u);
};
class Framebuffer
@ -21,7 +19,7 @@ namespace Light {
public:
static Ref<Framebuffer> Create(const FramebufferSpecification& specification, Ref<SharedContext> sharedContext);
virtual void BindAsTarget() = 0;
virtual void BindAsTarget(const glm::vec4& clearColor) = 0;
virtual void BindAsResource() = 0;
virtual void Resize(const glm::uvec2& size) = 0;

View file

@ -25,8 +25,9 @@ namespace Light {
m_ViewProjectionBuffer(nullptr),
m_RenderCommand(nullptr),
m_Blender(nullptr),
m_Camera(nullptr),
m_TargetFramebuffer(nullptr)
m_DefaultFramebufferCamera(nullptr),
m_TargetFramebuffer(nullptr),
m_ShouldClearBackbuffer(false)
{
LT_ENGINE_ASSERT(!s_Context, "Renderer::Renderer: an instance of 'Renderer' already exists, do not construct this class!");
s_Context = this;
@ -136,7 +137,9 @@ namespace Light {
void Renderer::EndFrame()
{
m_RenderCommand->SwapBuffers();
m_RenderCommand->ClearBackBuffer(m_Camera->GetBackgroundColor());
m_RenderCommand->ClearBackBuffer(m_DefaultFramebufferCamera ? m_DefaultFramebufferCamera->GetBackgroundColor() : glm::vec4(0.0f));
m_DefaultFramebufferCamera = nullptr;
}
void Renderer::BeginSceneImpl(Camera* camera, const glm::mat4& cameraTransform, const Ref<Framebuffer>& targetFrameBuffer /* = nullptr */)
@ -145,14 +148,16 @@ namespace Light {
m_TargetFramebuffer = targetFrameBuffer;
if (targetFrameBuffer)
targetFrameBuffer->BindAsTarget();
targetFrameBuffer->BindAsTarget(camera->GetBackgroundColor());
else
{
m_DefaultFramebufferCamera = camera;
m_RenderCommand->DefaultTargetFramebuffer();
}
// update view projection buffer
m_Camera = camera;
glm::mat4* map = (glm::mat4*)m_ViewProjectionBuffer->Map();
map[0] = m_Camera->GetProjection() * glm::inverse(cameraTransform);
map[0] = camera->GetProjection() * glm::inverse(cameraTransform);
m_ViewProjectionBuffer->UnMap();
// map renderers
@ -190,7 +195,7 @@ namespace Light {
}
// reset frame buffer
if(m_TargetFramebuffer)
if (m_TargetFramebuffer)
{
m_TargetFramebuffer = nullptr;
m_RenderCommand->DefaultTargetFramebuffer();

View file

@ -39,9 +39,11 @@ namespace Light {
Scope<RenderCommand> m_RenderCommand;
Scope<Blender> m_Blender;
Camera* m_Camera;
Camera* m_DefaultFramebufferCamera;
Ref<Framebuffer> m_TargetFramebuffer;
bool m_ShouldClearBackbuffer;
public:
static Scope<Renderer> Create(GLFWwindow* windowHandle, Ref<SharedContext> sharedContext);

View file

@ -2,6 +2,7 @@
#include "Base/Base.h"
#include "Components/TransformComponent.h"
#include "Components/CameraComponent.h"
#include "Components/NativeScriptComponent.h"
#include "Components/SpriteRendererComponent.h"
#include "Components/CameraComponent.h"
#include "Components/TransformComponent.h"

View file

@ -0,0 +1,24 @@
#pragma once
#include "Base/Base.h"
#include "ScriptableEntity.h"
namespace Light {
struct NativeScriptComponent
{
NativeScript* instance;
NativeScript* (*CreateInstance)();
void (*DestroyInstance)(NativeScriptComponent*);
template<typename T>
void Bind()
{
CreateInstance = []() { return static_cast<NativeScript*>(new T()); };
DestroyInstance = [](NativeScriptComponent* nsc) { delete (T*)(nsc->instance); nsc->instance = nullptr; };
}
};
}

View file

@ -0,0 +1,34 @@
#pragma once
#include "Entity.h"
#include "Base/Base.h"
namespace Light {
class NativeScript
{
friend class Scene;
private:
Entity m_Entity;
unsigned int m_UniqueIdentifier = 0; // :#todo
public:
NativeScript() = default;
virtual ~NativeScript() = default;
inline unsigned int GetUID() const { return m_UniqueIdentifier; }
template<typename T>
T& GetComponent()
{
return m_Entity.GetComponent<T>();
}
protected:
virtual void OnCreate () {}
virtual void OnDestroy() {}
virtual void OnUpdate(float ts) {}
};
}

View file

@ -19,6 +19,34 @@ namespace Light {
{
}
void Scene::OnCreate()
{
/* native scripts */
{
m_Registry.view<NativeScriptComponent>().
each([](NativeScriptComponent& nsc)
{
if (nsc.instance == nullptr)
{
nsc.instance = nsc.CreateInstance();
nsc.instance->OnCreate();
}
});
}
}
void Scene::OnUpdate(float deltaTime)
{
/* native scripts */
{
m_Registry.view<NativeScriptComponent>().
each([=](NativeScriptComponent& nsc)
{
nsc.instance->OnUpdate(deltaTime);
});
}
}
void Scene::OnRender(const Ref<Framebuffer>& targetFrameBuffer /* = nullptr */)
{
Camera* sceneCamera = nullptr;
@ -26,38 +54,32 @@ namespace Light {
/* scene camera */
{
auto group = m_Registry.group(entt::get<TransformComponent, CameraComponent>);
for (auto& entity : group)
m_Registry.group(entt::get<TransformComponent, CameraComponent>).
each([&](TransformComponent& transformComp, CameraComponent& cameraComp)
{
auto& [transformComp, cameraComp] = group.get<TransformComponent, CameraComponent>(entity);
if (cameraComp.isPrimary)
{
sceneCamera = &cameraComp.camera;
sceneCameraTransform = &transformComp.transform;
}
}
});
}
/* draw quads */
{
if (sceneCamera)
{
Renderer::BeginScene(sceneCamera, *sceneCameraTransform, targetFrameBuffer);
auto group = m_Registry.group(entt::get<TransformComponent, SpriteRendererComponent>);
for (auto& entity : group)
m_Registry.group(entt::get<TransformComponent, SpriteRendererComponent>).
each([](TransformComponent& transformComp, SpriteRendererComponent& spriteRendererComp)
{
auto& [transformComp, spriteRendererComp] = group.get<TransformComponent, SpriteRendererComponent>(entity);
Renderer::DrawQuad(transformComp.transform, spriteRendererComp.texture);
}
});
Renderer::EndScene();
}
}
}

View file

@ -14,14 +14,17 @@ namespace Light {
class Scene
{
private:
friend class Entity;
private:
entt::registry m_Registry;
public:
Scene();
~Scene();
void OnCreate();
void OnUpdate(float deltaTime);
void OnRender(const Ref<Framebuffer>& targetFrameBuffer = nullptr);
Entity CreateEntity(const std::string& name, const glm::mat4& transform);

View file

@ -43,13 +43,13 @@ namespace Light {
DXC(m_Context->GetDevice()->CreateRenderTargetView(m_ColorAttachment.Get(), &rtvDesc, &m_RenderTargetView));
}
void dxFramebuffer::BindAsTarget()
void dxFramebuffer::BindAsTarget(const glm::vec4& clearColor)
{
FLOAT color[] = {
m_Specification.defaultColor.r,
m_Specification.defaultColor.g,
m_Specification.defaultColor.b,
m_Specification.defaultColor.a,
clearColor.r,
clearColor.g,
clearColor.b,
clearColor.a,
};
m_Context->GetDeviceContext()->OMSetRenderTargets(1u, m_RenderTargetView.GetAddressOf(), nullptr);

View file

@ -29,7 +29,7 @@ namespace Light {
inline void* GetColorAttachment() override { return (void*)m_ShaderResourceView.Get(); }
void BindAsTarget() override;
void BindAsTarget(const glm::vec4& clearColor) override;
void BindAsResource() override;
void Resize(const glm::uvec2& size) override;

View file

@ -23,13 +23,13 @@ namespace Light {
// glDeleteTextures(1, &m_DepthStencilAttachmentID);
}
void glFramebuffer::BindAsTarget()
void glFramebuffer::BindAsTarget(const glm::vec4& clearColor)
{
// #todo: use viewport instead of default x=0, y=0
glBindFramebuffer(GL_FRAMEBUFFER, m_BufferID);
glViewport(0, 0, m_Specification.width, m_Specification.height);
glClearColor(m_Specification.defaultColor.r, m_Specification.defaultColor.g, m_Specification.defaultColor.b, m_Specification.defaultColor.a);
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
glClear(GL_COLOR_BUFFER_BIT);
}

View file

@ -18,7 +18,7 @@ namespace Light {
glFramebuffer(const FramebufferSpecification& specification);
~glFramebuffer();
void BindAsTarget() override;
void BindAsTarget(const glm::vec4& clearColor) override;
void BindAsResource() override;
void Resize(const glm::uvec2& size) override;

View file

@ -16,6 +16,7 @@ namespace Light {
Scene m_Scene;
Entity m_CameraEntity;
Entity m_NativeScriptEntity;
public:
MirrorLayer(const std::string& name)
@ -24,7 +25,7 @@ namespace Light {
ResourceManager::LoadTexture("awesomeface", "res/Textures/awesomeface.png");
m_AwesomefaceTexture = ResourceManager::GetTexture("awesomeface");
m_Framebuffer = std::shared_ptr<Framebuffer>(Framebuffer::Create({ 800u, 600u, 1, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f) }, GraphicsContext::GetSharedContext()));
m_Framebuffer = std::shared_ptr<Framebuffer>(Framebuffer::Create({ 800u, 600u, 1u }, GraphicsContext::GetSharedContext()));
m_CameraEntity = m_Scene.CreateEntity("camera", glm::mat4(1.0f));
m_CameraEntity.AddComponent<CameraComponent>(SceneCamera(), true);
@ -37,6 +38,45 @@ namespace Light {
m_Scene.CreateEntity("quad", glm::translate(glm::mat4(1.0f), { position.x, position.y, 0.0f }) *
glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f})).AddComponent<SpriteRendererComponent>(m_AwesomefaceTexture);
}
m_NativeScriptEntity = m_Scene.CreateEntity("nsc", glm::translate(glm::mat4(1.0f), glm::vec3(0.0f)) * glm::scale(glm::mat4(1.0f), glm::vec3(250.0f, 250.0f, 1.0f)));
m_NativeScriptEntity.AddComponent<SpriteRendererComponent>(m_AwesomefaceTexture);
class SampleNativeScript : public Light::NativeScript
{
private:
void OnUpdate(float deltaTime)
{
LT_CLIENT_TRACE("NativeScript on update {}", deltaTime);
}
};
m_NativeScriptEntity.AddComponent<NativeScriptComponent>().Bind<SampleNativeScript>();
// create native scripts
m_Scene.OnCreate();
}
void OnUpdate(float deltaTime) override
{
if (Input::GetKeyboardKey(Key::A))
m_Direction.x = -1.0f;
else if (Input::GetKeyboardKey(Key::D))
m_Direction.x = 1.0f;
else
m_Direction.x = 0.0f;
if (Input::GetKeyboardKey(Key::W))
m_Direction.y = 1.0f;
else if (Input::GetKeyboardKey(Key::S))
m_Direction.y = -1.0f;
else
m_Direction.y = 0.0f;
auto& transform = m_CameraEntity.GetComponent<TransformComponent>();
transform = glm::translate(transform.transform, glm::vec3(m_Direction * m_Speed * deltaTime, 0.0));
m_Scene.OnUpdate(deltaTime);
}
void OnRender() override
@ -73,26 +113,6 @@ namespace Light {
ImGui::End();
}
void OnUpdate(float deltaTime) override
{
if (Input::GetKeyboardKey(Key::A))
m_Direction.x = -1.0f;
else if (Input::GetKeyboardKey(Key::D))
m_Direction.x = 1.0f;
else
m_Direction.x = 0.0f;
if (Input::GetKeyboardKey(Key::W))
m_Direction.y = 1.0f;
else if (Input::GetKeyboardKey(Key::S))
m_Direction.y = -1.0f;
else
m_Direction.y = 0.0f;
auto& transform = m_CameraEntity.GetComponent<TransformComponent>();
transform = glm::translate(transform.transform, glm::vec3(m_Direction * m_Speed * deltaTime, 0.0));
}
};
}