Nuevo Render flow para los Drawables y mejoras.

Nuevo flujo de render para los drawables, que ahora tiene más sentido.
Investigado e implementado finalmente un sistema para no renderizar objetos no visibles.
Optimizaciones varias.
Constructor por defecto para Sprite, utilizando los assets por defecto.
This commit is contained in:
2022-12-18 23:20:13 +01:00
parent 08f566fda6
commit 659b113318
15 changed files with 193 additions and 108 deletions
+2
View File
@@ -13,6 +13,8 @@ namespace UE
void AssetManager::InitAssetManager() void AssetManager::InitAssetManager()
{ {
UE_LOG_INFO("AssetManager Iniciado con éxito."); UE_LOG_INFO("AssetManager Iniciado con éxito.");
//Crear una textura por defecto.
} }
+20 -48
View File
@@ -11,35 +11,15 @@ namespace UE
/* /*
* Clase base para renderizar objetos en el mundo. * Clase base para renderizar objetos en el mundo.
* El renderer extrae los datos necesarios de esta clase para renderizar el objeto.
*/ */
class Drawable : public Transformable class Drawable
{ {
public: protected:
Drawable() {} Drawable() {}
~Drawable() {} ~Drawable() {}
////////////////////////////////////////////////////////
//Get-Set del renderLayer.
inline void SetLayer(int newLayer) { _renderLayer = newLayer; }
inline int GetLayer() { return _renderLayer; }
////////////////////////////////////////////////////////
inline bool IsActive() { return isActive; }
inline void SetActive(bool active) { isActive = active; }
//¿Añadir funciones para cambiar las variables? ¿Al menos, para actualizar el actualRect de alguna forma?
protected: protected:
//Esto permite acceder a este método desde el Renderer, pero no será accesible desde fuera. //Esto permite acceder a este método desde el Renderer, pero no será accesible desde fuera.
@@ -47,40 +27,32 @@ namespace UE
friend class Renderer; friend class Renderer;
/* /*
* Esta función ha de ser sobrecargada por los Drawables. * Esta función ha de ser sobrecargada por los Sprites especificos.
* Sirve para actualizar la información que hay en el drawable para hacer el rendering. * Se deberá realizar el render en esta etapa.
* Constituye la primera parte del draw. En la que se actualizan los datos del Drawable.
* La segunda parte, ocurre en el renderer, que extraerá los datos del Drawable.
*/ */
virtual void Draw(Renderer* renderer) = 0; virtual void Draw(Renderer* renderer) = 0;
////////////////////////////////////////////////////////
public:
//Get-Set del renderLayer.
inline void SetLayer(int newLayer) { _renderLayer = newLayer; }
inline int GetLayer() { return _renderLayer; }
inline void SetVisible(bool visible) { _visible = visible; }
inline bool IsVisible() { return _visible; }
protected: protected:
//Ptr a la textura y los datos que está utilizando. //Indica en qué layer está el objeto (z order).
UE::Texture* _tx = nullptr;
//Sección de la textura que se utilizará.
SDL_Rect _txRect{0, 0, 0, 0};
//UE::Texture contiene una lista de rects, con esto, podemos seleccionar el rect que queramos.
//Pero es redundante con _txRect y para que sea seguro habría que encapsular todo.
//¿Es necesario que esté aquí? ¿Puedo simplemente tenerlo en aquellos Drawables en que lo necesite (animated ones)?
int _txRectID = 0;
////////////////////////////////////////////////////////
//Indica en qué layer del renderer está el objeto (z order).
int _renderLayer = 0; int _renderLayer = 0;
bool _visible = true;
////////////////////////////////////////////////////////
//Permite activar o desactivar el Drawable. Si está desactivado, no se debería de renderizar/ejecutar.
bool isActive = true;
}; };
} }
+38 -22
View File
@@ -2,33 +2,49 @@
#include "Render/Renderer.h" #include "Render/Renderer.h"
#include "Assets/AssetManager.h" #include "Assets/AssetManager.h"
#include "Engine.h"
#include "Logging/Logger.h" #include "Logging/Logger.h"
#include <iostream> #include <iostream>
void UE::Sprite::SetTextureRect(int textureID)
namespace UE
{ {
_txRectID = textureID; Sprite::Sprite()
{
AssetManager* as = Engine::GetAssetManager();
_tx = as->getDefaultTexture();
SetTextureRect(0);
SetLayer(1);
SetPosition(0, 0);
SDL_Rect txSize = _tx->GetTextureRect(_txRectID);
SetSize(txSize.w, txSize.h);
}
void Sprite::SetTextureRect(int textureID)
{
_txRectID = textureID;
//Sabemos que en caso de no estar disponible, no devolverá el Rect 0 (Textura completa).
_txRect = _tx->GetTextureRect(textureID);
}
void Sprite::Draw(Renderer* renderer)
{
//Comprobar si es visible.
if (!renderer->IsObjectVisible(&GetTransformRect()))
{
return;
}
renderer->DrawTextureOnWorld(_tx, _txRectID, GetTransformRect());
}
//Sabemos que en caso de no estar disponible, no devolverá el Rect 0 (Textura completa).
_txRect = _tx->GetTextureRect(textureID);
} }
void UE::Sprite::Draw(Renderer* renderer)
{
//Convertimos a ScreenCoords.
//destination.x = _pos.x;
//destination.y = _pos.y;
//
//destination.w = _size.x;
//destination.h = _size.y;
//std::cout << "Sprite Rendered to: " << destination.x << "-" << destination.y << std::endl;
//renderer->QueueDrawCall(_renderLayer, position, _tx->GetTexture(), _txRect);
}
+26 -1
View File
@@ -23,7 +23,7 @@ namespace UE
{ {
class Renderer; class Renderer;
class Sprite : public Drawable class Sprite : public Drawable, public Transformable
{ {
@@ -66,6 +66,9 @@ namespace UE
SetSize(size); SetSize(size);
} }
Sprite();
~Sprite() {} ~Sprite() {}
@@ -80,9 +83,12 @@ namespace UE
void SetTextureRect(int textureID); void SetTextureRect(int textureID);
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
inline bool IsActive() { return isActive; }
inline void SetActive(bool active) { isActive = active; }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@@ -95,6 +101,25 @@ namespace UE
private: private:
//Ptr a la textura y los datos que está utilizando.
UE::Texture* _tx = nullptr;
//Sección de la textura que se utilizará.
SDL_Rect _txRect{ 0, 0, 0, 0 };
//UE::Texture contiene una lista de rects, con esto, podemos seleccionar el rect que queramos.
//FIX: Pero es redundante con _txRect y para que sea seguro habría que encapsular todo.
//¿Es necesario que esté aquí? ¿Puedo simplemente tenerlo en aquellos Drawables en que lo necesite (animated ones)?
int _txRectID = 0;
////////////////////////////////////////////////////////
//Permite activar o desactivar el Drawable. Si está desactivado, no se debería de renderizar/ejecutar.
//NOTA: Se puede mover al Sprite para detener también el Update.
bool isActive = true;
}; };
+2 -1
View File
@@ -40,7 +40,7 @@ void UE::TextBox::Draw(Renderer* renderer)
if (_tx->GetTexture() == nullptr) if (_tx->GetTexture() == nullptr)
{ {
UE_LOG_WARN("El texto: {0} ; No se est� renderizando. La textura no existe.", _text); UE_LOG_WARN("El texto: {0} ; No se está renderizando. La textura no existe.", _text);
return; return;
} }
@@ -49,6 +49,7 @@ void UE::TextBox::Draw(Renderer* renderer)
//SDL_Texture* tx = _textTexture.GetTexture(); //SDL_Texture* tx = _textTexture.GetTexture();
//renderer->QueueDrawCall(_renderLayer, dest, _textTexture); //renderer->QueueDrawCall(_renderLayer, dest, _textTexture);
renderer->DrawTextureOnScreen(_tx, 0, GetTransformRect());
//Actualizamos en cada frame el ptr a la textura que tiene que usar el drawable. //Actualizamos en cada frame el ptr a la textura que tiene que usar el drawable.
//no vaya a ser que se invalide por algo. //no vaya a ser que se invalide por algo.
+5 -1
View File
@@ -18,7 +18,7 @@ namespace UE
typedef glm::tvec4<int> UE_Color; typedef glm::tvec4<int> UE_Color;
class TextBox : public Drawable class TextBox : public Drawable, public Transformable
{ {
public: public:
@@ -124,6 +124,10 @@ namespace UE
UE_Color _textColor = {255, 255, 255, 255}; UE_Color _textColor = {255, 255, 255, 255};
UE::Texture* _tx;
SDL_Rect _txRect;
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
+14 -2
View File
@@ -23,12 +23,24 @@ namespace UE
SDL_Rect Camera::WorldToScreenRect(SDL_Rect worldRect) SDL_Rect Camera::WorldToScreenRect(SDL_Rect worldRect)
{ {
return SDL_Rect(); glm::ivec2 worldCoords = glm::ivec2(worldRect.x, worldRect.y);
glm::ivec2 screenCoords = WorldToSreenCoords(worldCoords);
SDL_Rect screenRect = worldRect;
screenRect.x = screenCoords.x;
screenRect.y = screenCoords.y;
return screenRect;
} }
SDL_Rect Camera::ScreenToWorldRect(SDL_Rect screenRect) SDL_Rect Camera::ScreenToWorldRect(SDL_Rect screenRect)
{ {
return SDL_Rect(); glm::ivec2 screenCoords = glm::ivec2(screenRect.x, screenRect.y);
glm::ivec2 worldCoords = ScreenToWorldCoords(screenCoords);
SDL_Rect worldRect = screenRect;
worldRect.x = worldCoords.x;
worldRect.y = worldCoords.y;
return worldRect;
} }
} }
+1
View File
@@ -23,6 +23,7 @@ namespace UE
Camera(int posX, int posY) Camera(int posX, int posY)
{ {
_pos = { posX, posY }; _pos = { posX, posY };
_size = { 100, 100 };
} }
Camera(int posX, int posY, int sizeX, int sizeY) Camera(int posX, int posY, int sizeX, int sizeY)
+41 -19
View File
@@ -97,11 +97,9 @@ namespace UE
ResetCamera(); ResetCamera();
} }
//Actualizamos el rect que representa la pantalla. //Actualizamos el rect de la cámara.
glm::vec2 camPos = activeCam->GetPosition(); activeCamRect = activeCam->GetTransformRect();
int x = camPos.x;
int y = camPos.y;
_screenRect = {x, y, screenSize.x, screenSize.y};
} }
void Renderer::RenderData() void Renderer::RenderData()
@@ -119,8 +117,9 @@ namespace UE
{ {
//Extract Drawable k //Extract Drawable k
Drawable* item = layer.at(k); Drawable* item = layer.at(k);
item->Draw(this);
// FIX: Cuando la tx sea nullptr o salte except. -> Log y usar default tx. /*// FIX: Cuando la tx sea nullptr o salte except. -> Log y usar default tx.
// En definitiva, añadir seguridad aquí, se puede usar la tx default. // En definitiva, añadir seguridad aquí, se puede usar la tx default.
SDL_Texture* tx = item->_tx->GetTexture(); SDL_Texture* tx = item->_tx->GetTexture();
@@ -130,13 +129,16 @@ namespace UE
SDL_Rect screenRect = { screenCoords.x, screenCoords.y, item->_size.x, item->_size.y }; SDL_Rect screenRect = { screenCoords.x, screenCoords.y, item->_size.x, item->_size.y };
//Le pasamos todo al SDL_Renderer. //Le pasamos todo al SDL_Renderer.
SDL_RenderCopy(main_Renderer, item->_tx->GetTexture(), &(item->_txRect), &screenRect); SDL_RenderCopy(main_Renderer, item->_tx->GetTexture(), &(item->_txRect), &screenRect);*/
} }
layer.clear(); layer.clear();
} }
//Renderizado de ImGui. //Renderizado de ImGui.
//TODO: Mover a otro método para cambiar el nombre a RenderDrawables.
ImGui::Render(); ImGui::Render();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
@@ -156,8 +158,6 @@ namespace UE
void Renderer::Render(Drawable& drawable) void Renderer::Render(Drawable& drawable)
{ {
drawable.Draw(this);
int layer = drawable.GetLayer(); int layer = drawable.GetLayer();
//Check Layer. //Check Layer.
@@ -166,6 +166,11 @@ namespace UE
UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", layer); UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", layer);
return; return;
} }
if (!drawable.IsVisible())
{
return;
}
// FIX Comprobamos si el objeto es visible. // FIX Comprobamos si el objeto es visible.
// if(!IsObjectVisible(&drawCall.pos_rect)) // if(!IsObjectVisible(&drawCall.pos_rect))
// { // {
@@ -174,13 +179,36 @@ namespace UE
// } // }
//SDL_Texture* tx = drawable._tx->GetTexture(); //SDL_Texture* tx = drawable._tx->GetTexture();
//Add Item to Layer for being rendered. //Add Item to Layer for being rendered.
worldLayers.at(layer).push_back(&drawable); worldLayers.at(layer).push_back(&drawable);
} }
void Renderer::DrawTextureOnWorld(UE::Texture* tx, int txRectID, SDL_Rect worldRect)
{
//TODO: Añadir seguridad.
//Si el objeto no es visible, no lo renderizamos.
if (!IsObjectVisible(&worldRect))
{
return;
}
//Convertir WorldPos to ScreenPos.
// FIX: Usar Floats en vez de ints.
SDL_Rect screenRect = activeCam->WorldToScreenRect(worldRect);
SDL_RenderCopy(main_Renderer, tx->GetTexture(), &tx->GetTextureRect(txRectID), &screenRect);
}
void Renderer::DrawTextureOnScreen(UE::Texture* tx, int txRectID, SDL_Rect screenRect)
{
SDL_RenderCopy(main_Renderer, tx->GetTexture(), &tx->GetTextureRect(txRectID), &screenRect);
}
void Renderer::SetScreenSize(int newWidth, int newHeight) void Renderer::SetScreenSize(int newWidth, int newHeight)
{ {
@@ -189,6 +217,8 @@ namespace UE
SDL_SetWindowSize(_window, newWidth, newHeight); SDL_SetWindowSize(_window, newWidth, newHeight);
glViewport(0, 0, newWidth, newHeight); glViewport(0, 0, newWidth, newHeight);
defaultCam.SetSize(newWidth, newHeight);
UE_LOG_TRACE("Screen size chaged to: {0}x{1}", newWidth, newHeight); UE_LOG_TRACE("Screen size chaged to: {0}x{1}", newWidth, newHeight);
} }
@@ -198,17 +228,9 @@ namespace UE
} }
//CREO QUE ESTE MÉTODO NO FUNCIONA.
//LAS COORDS QUE USAMOS EN LA COMPROBACI�N NO SON LAS ADECUADAS.
bool Renderer::IsObjectVisible(SDL_Rect* objectRect) bool Renderer::IsObjectVisible(SDL_Rect* objectRect)
{ {
//Comprobamos si hay intersecci�n entre ambos. return SDL_HasIntersection(objectRect, &activeCamRect);
if (!SDL_HasIntersection(&_screenRect, objectRect))
{
//UE_LOG_TRACE("Se omite el renderizado de un objeto al estar fuera de la c�mara.");
return false;
}
return true;
} }
+18 -12
View File
@@ -80,6 +80,9 @@ namespace UE
void EndFrame(); void EndFrame();
////////////////////////////////////////////////////////
/* /*
* Rendiriza el Objeto indicado. * Rendiriza el Objeto indicado.
* El proceso consta de dos partes: * El proceso consta de dos partes:
@@ -89,6 +92,16 @@ namespace UE
void Render(Drawable& drawable); void Render(Drawable& drawable);
/*
* Renderizar una textura dado su rect en WorldCoords.
* Se ha de utilizar en las implementaciones del método Draw de la clase Drawable.
*/
void DrawTextureOnWorld(UE::Texture* tx, int txRectID, SDL_Rect worldRect);
void DrawTextureOnScreen(UE::Texture* tx, int txRectID, SDL_Rect screenRect);
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
@@ -96,8 +109,6 @@ namespace UE
inline SDL_Renderer* GetSDLRenderer() { return main_Renderer; } inline SDL_Renderer* GetSDLRenderer() { return main_Renderer; }
////////////////////////////////////////////////////////
/* /*
* Get windows/screen size. * Get windows/screen size.
@@ -112,8 +123,6 @@ namespace UE
void SetScreenSize(int newWidth, int newHeight); void SetScreenSize(int newWidth, int newHeight);
////////////////////////////////////////////////////////
/* /*
* Cambiar el color del fondo. * Cambiar el color del fondo.
@@ -121,8 +130,6 @@ namespace UE
void SetDrawingColor(SDL_Color& newColor); void SetDrawingColor(SDL_Color& newColor);
////////////////////////////////////////////////////////
/* /*
* Set the active cámera. * Set the active cámera.
@@ -145,8 +152,9 @@ namespace UE
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
//Comprueba si un objeto est� dentro del rect�ngulo de la c�mara. /*
//Usada para saber si un objeto se deber�a de renderizar o no. * Check if an object is currently visible on Screen.
*/
bool IsObjectVisible(SDL_Rect* objectRect); bool IsObjectVisible(SDL_Rect* objectRect);
@@ -187,16 +195,14 @@ namespace UE
glm::ivec2 screenSize{ 640,480 }; glm::ivec2 screenSize{ 640,480 };
SDL_Rect _screenRect{ 0, 0, screenSize.x, screenSize.y };
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
//glm::ivec2 camPosition{ 0,0 }; //glm::ivec2 camPosition{ 0,0 };
Camera* activeCam; Camera* activeCam;
Camera defaultCam = Camera(0, 0); Camera defaultCam = Camera(0, 0, screenSize.x, screenSize.y);
SDL_Rect activeCamRect{ 0, 0, screenSize.x, screenSize.y };
//DEBUG //DEBUG
+3
View File
@@ -52,11 +52,14 @@ public:
UE::Sprite mapSP(as->getTexture("PruebaMap"), 1, 2, glm::vec2(50, 45), glm::vec2(145, 145)); UE::Sprite mapSP(as->getTexture("PruebaMap"), 1, 2, glm::vec2(50, 45), glm::vec2(145, 145));
UE::Sprite default1;
sprites.push_back(sp1); sprites.push_back(sp1);
sprites.push_back(sp2); sprites.push_back(sp2);
sprites.push_back(bg); sprites.push_back(bg);
sprites.push_back(mapSP); sprites.push_back(mapSP);
sprites.push_back(default1);
UE::Font* OP_Regular = as->GetFont("OpenSans_Regular"); UE::Font* OP_Regular = as->GetFont("OpenSans_Regular");
//TTF_Font* OP_Bold = as->GetFont("OpenSans_Bold"); //TTF_Font* OP_Bold = as->GetFont("OpenSans_Bold");
+9 -3
View File
@@ -8,6 +8,7 @@
#include "Assets/Texture.h" #include "Assets/Texture.h"
#include "Drawables/Sprite.h" #include "Drawables/Sprite.h"
#include "Render/Camera.h"
#include <iostream> #include <iostream>
@@ -18,6 +19,8 @@ class TestScene2 : public UE::Scene
{ {
public: public:
UE::Camera sceneCam;
TestScene2() : Scene("TestScene") TestScene2() : Scene("TestScene")
{ {
//_sceneName = "TestScene"; //_sceneName = "TestScene";
@@ -29,8 +32,11 @@ public:
srand(255); srand(255);
UE::AssetManager* as = UE::Engine::GetAssetManager(); glm::ivec2 screenSize = UE::Engine::GetRenderer()->GetScreenSize();
sceneCam = UE::Camera(0, 0, screenSize.x, screenSize.y);
UE::Engine::GetRenderer()->SetCamera(&sceneCam);
UE::AssetManager* as = UE::Engine::GetAssetManager();
UE::Texture* tx = as->getTexture("PruebaMap"); UE::Texture* tx = as->getTexture("PruebaMap");
for (int y = 0; y < vAmount; y++) for (int y = 0; y < vAmount; y++)
@@ -195,8 +201,8 @@ private:
} }
private: private:
const int vAmount = 256; const int vAmount = 128;
const int hAmount = 256; const int hAmount = 128;
std::vector<UE::Sprite> sprites = {}; std::vector<UE::Sprite> sprites = {};
+10
View File
@@ -1,5 +1,10 @@
{ {
"Textures": [ "Textures": [
{
"name": "default",
"Path": "resources/Sprites/Data/TX_default.json",
"Type": 0
},
{ {
"name": "bg1", "name": "bg1",
"Path": "resources/Sprites/Data/TX_bg1.json", "Path": "resources/Sprites/Data/TX_bg1.json",
@@ -37,6 +42,11 @@
} }
], ],
"Fonts": [ "Fonts": [
{
"name": "default",
"Path": "resources/AssetsData/FontsData/OpenSansRegular.json",
"Type": 1
},
{ {
"name": "OpenSans_Regular", "name": "OpenSans_Regular",
"Path": "resources/AssetsData/FontsData/OpenSansRegular.json", "Path": "resources/AssetsData/FontsData/OpenSansRegular.json",
+5
View File
@@ -0,0 +1,5 @@
{
"TexturePath": "resources/Sprites/Textures/noTexture.png",
"TextureRects": [
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B