Author SHA1 Message Date
UberElectron 659b113318 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.
2022-12-18 23:20:13 +01:00
15 changed files with 193 additions and 108 deletions
+2
View File
@@ -13,6 +13,8 @@ namespace UE
void AssetManager::InitAssetManager()
{
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.
* El renderer extrae los datos necesarios de esta clase para renderizar el objeto.
*/
class Drawable : public Transformable
class Drawable
{
public:
protected:
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:
//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;
/*
* Esta función ha de ser sobrecargada por los Drawables.
* Sirve para actualizar la información que hay en el drawable para hacer el rendering.
* 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.
* Esta función ha de ser sobrecargada por los Sprites especificos.
* Se deberá realizar el render en esta etapa.
*/
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:
//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.
//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).
//Indica en qué layer está el objeto (z order).
int _renderLayer = 0;
////////////////////////////////////////////////////////
//Permite activar o desactivar el Drawable. Si está desactivado, no se debería de renderizar/ejecutar.
bool isActive = true;
bool _visible = true;
};
}
+38 -22
View File
@@ -2,33 +2,49 @@
#include "Render/Renderer.h"
#include "Assets/AssetManager.h"
#include "Engine.h"
#include "Logging/Logger.h"
#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 Sprite : public Drawable
class Sprite : public Drawable, public Transformable
{
@@ -66,6 +66,9 @@ namespace UE
SetSize(size);
}
Sprite();
~Sprite() {}
@@ -80,9 +83,12 @@ namespace UE
void SetTextureRect(int textureID);
////////////////////////////////////////////////////////
inline bool IsActive() { return isActive; }
inline void SetActive(bool active) { isActive = active; }
////////////////////////////////////////////////////////
@@ -95,6 +101,25 @@ namespace UE
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)
{
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;
}
@@ -49,6 +49,7 @@ void UE::TextBox::Draw(Renderer* renderer)
//SDL_Texture* tx = _textTexture.GetTexture();
//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.
//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;
class TextBox : public Drawable
class TextBox : public Drawable, public Transformable
{
public:
@@ -124,6 +124,10 @@ namespace UE
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)
{
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)
{
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)
{
_pos = { posX, posY };
_size = { 100, 100 };
}
Camera(int posX, int posY, int sizeX, int sizeY)
+41 -19
View File
@@ -97,11 +97,9 @@ namespace UE
ResetCamera();
}
//Actualizamos el rect que representa la pantalla.
glm::vec2 camPos = activeCam->GetPosition();
int x = camPos.x;
int y = camPos.y;
_screenRect = {x, y, screenSize.x, screenSize.y};
//Actualizamos el rect de la cámara.
activeCamRect = activeCam->GetTransformRect();
}
void Renderer::RenderData()
@@ -119,8 +117,9 @@ namespace UE
{
//Extract Drawable 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.
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 };
//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();
}
//Renderizado de ImGui.
//TODO: Mover a otro método para cambiar el nombre a RenderDrawables.
ImGui::Render();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
@@ -156,8 +158,6 @@ namespace UE
void Renderer::Render(Drawable& drawable)
{
drawable.Draw(this);
int layer = drawable.GetLayer();
//Check Layer.
@@ -166,6 +166,11 @@ namespace UE
UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", layer);
return;
}
if (!drawable.IsVisible())
{
return;
}
// FIX Comprobamos si el objeto es visible.
// if(!IsObjectVisible(&drawCall.pos_rect))
// {
@@ -174,13 +179,36 @@ namespace UE
// }
//SDL_Texture* tx = drawable._tx->GetTexture();
//Add Item to Layer for being rendered.
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)
{
@@ -189,6 +217,8 @@ namespace UE
SDL_SetWindowSize(_window, newWidth, newHeight);
glViewport(0, 0, newWidth, newHeight);
defaultCam.SetSize(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)
{
//Comprobamos si hay intersecci�n entre ambos.
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;
return SDL_HasIntersection(objectRect, &activeCamRect);
}
+18 -12
View File
@@ -80,6 +80,9 @@ namespace UE
void EndFrame();
////////////////////////////////////////////////////////
/*
* Rendiriza el Objeto indicado.
* El proceso consta de dos partes:
@@ -89,6 +92,16 @@ namespace UE
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; }
////////////////////////////////////////////////////////
/*
* Get windows/screen size.
@@ -112,8 +123,6 @@ namespace UE
void SetScreenSize(int newWidth, int newHeight);
////////////////////////////////////////////////////////
/*
* Cambiar el color del fondo.
@@ -121,8 +130,6 @@ namespace UE
void SetDrawingColor(SDL_Color& newColor);
////////////////////////////////////////////////////////
/*
* 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);
@@ -187,16 +195,14 @@ namespace UE
glm::ivec2 screenSize{ 640,480 };
SDL_Rect _screenRect{ 0, 0, screenSize.x, screenSize.y };
////////////////////////////////////////////////////////
//glm::ivec2 camPosition{ 0,0 };
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
+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 default1;
sprites.push_back(sp1);
sprites.push_back(sp2);
sprites.push_back(bg);
sprites.push_back(mapSP);
sprites.push_back(default1);
UE::Font* OP_Regular = as->GetFont("OpenSans_Regular");
//TTF_Font* OP_Bold = as->GetFont("OpenSans_Bold");
+9 -3
View File
@@ -8,6 +8,7 @@
#include "Assets/Texture.h"
#include "Drawables/Sprite.h"
#include "Render/Camera.h"
#include <iostream>
@@ -18,6 +19,8 @@ class TestScene2 : public UE::Scene
{
public:
UE::Camera sceneCam;
TestScene2() : Scene("TestScene")
{
//_sceneName = "TestScene";
@@ -29,8 +32,11 @@ public:
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");
for (int y = 0; y < vAmount; y++)
@@ -195,8 +201,8 @@ private:
}
private:
const int vAmount = 256;
const int hAmount = 256;
const int vAmount = 128;
const int hAmount = 128;
std::vector<UE::Sprite> sprites = {};
+10
View File
@@ -1,5 +1,10 @@
{
"Textures": [
{
"name": "default",
"Path": "resources/Sprites/Data/TX_default.json",
"Type": 0
},
{
"name": "bg1",
"Path": "resources/Sprites/Data/TX_bg1.json",
@@ -37,6 +42,11 @@
}
],
"Fonts": [
{
"name": "default",
"Path": "resources/AssetsData/FontsData/OpenSansRegular.json",
"Type": 1
},
{
"name": "OpenSans_Regular",
"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