Migración del Renderer al nuevo sistema de Drawables.

El Renderer extrae los datos de los drawables, eliminando la clase DrawCall.
Los Drawables utilizan los nuevos Drawables. Aunque falta pulir la forma en que lo hacen.
This commit is contained in:
2022-09-19 20:10:02 +02:00
parent 6b87711424
commit f2bf82e370
16 changed files with 372 additions and 224 deletions
+8 -4
View File
@@ -19,15 +19,16 @@ using json = nlohmann::ordered_json;
///
/// TODO:
/// TODO AssetManager:
/// - Modificar las funciones de Carga para quitar la queue o implementar una que tenga sentido.
/// Por ejemplo, se puede crear una cola (std::deque) y cargar un asset cada gameLoop en vez de
/// procesar toda la cola de golpe. Optimizar�a la carga de assets.
/// - Terminar la implementaci�n del tipo de carga (queue/now).
/// - Terminar la implementación del tipo de carga (queue/now). (O quizás no...)
/// - Modificar los for en la carga de archivo, as� como la estructura del archivo JSON. El tipo de Asset est� repetido.
/// - Logging.
/// - ERROR HANDLING
/// - More asset types.
/// - ¡¡Texturas y assets por defecto. Texturas completas en el txRect 0 y demás seguridad!!
namespace UE
{
@@ -109,8 +110,11 @@ namespace UE
//Elimina una textura del mapa a partir de su nombre.
void RemoveTexture(std::string name);
//Obtiene una textura del mapa a partir de su nombre.
//inline SDL_Texture* getTexture(std::string textureName) { return _textures.at(textureName); }
/*
Obtiene una textura del mapa a partir de su nombre.
NOTA REWORK getTexture() -> La tx que se retorna habrá de ser const para evitar que modifiquen datos comunes.
Así el TextureLoader o quien la cree podrá modificar lo que desee, pero no una vez metida aquí (hecha común).
*/
inline Texture* getTexture(std::string textureName) { return _textures.at(textureName); }
//inline std::vector<SDL_Rect>* getTexureRects(std::string textureName) { return &_textureRects.at(textureName); }
+16
View File
@@ -23,6 +23,22 @@ SDL_Rect* UE::Texture::GetTextureRect(int i)
}
void UE::Texture::SetTexture(SDL_Texture* newTexture)
{
//Destruimos la tx antigua. Esperomos no se haya hecho antes...
//Algo me dice que este if tiene más bien poco sentido...
if (_texture != nullptr)
{
SDL_DestroyTexture(_texture);
}
//Cambiamos la tx por la nueva.
_texture = newTexture;
}
void UE::Texture::InitTexture()
{
std::fstream file(_dataPath);
+24 -6
View File
@@ -8,7 +8,7 @@
namespace UE
{
//REWORK Texture -> Separar los datos (sdl_tx, rects, ...) del loader. No me gusta que una textura se tenga que cargar a si misma.
class Texture
{
public:
@@ -19,9 +19,19 @@ namespace UE
Texture(std::string dataPath, SDL_Renderer* renderer)
: _dataPath(dataPath), _SDL_Renderer(renderer)
{
//REWORK -> En el Loader, estaría bien poder saber si se ha cargado o no.
// Para no añadirla al mapa de texturas y hacer fallback en la por defecto.
InitTexture();
}
//HACK Texture() -> Lo utilizaremos únicamente para poder crear Texture vacias, hasta que separemos el loader.
Texture()
{
//Creo que no es necesario nada...
_dataPath = "";
_txPath = "";
}
~Texture()
{
CleanTexture();
@@ -51,6 +61,19 @@ namespace UE
SDL_Rect* GetTextureRect(int i); // -> Devolver un SDL_Rect, el Ptr ocupa incluso más.
//HACK Tiene que ser posible hacer un SetTexture. Será necesario cuando no cree su propia textura.
// Pero habrá que pasarlo como const desde el AssetManager, para evitar modificar datos "comunes".
void SetTexture(SDL_Texture* newTexture);
/*
M�todo que a�ade un SDL_Rect al vector correspondiente.
@param newRect : Nuevo Rect que a�adir al vector de Rects.
NOTA para REWORK -> Estaba en privado. Lo he movido aquí porque será público, pero no modificable si es const.
*/
void AddRect(SDL_Rect newRect);
private:
/**
* Carga los datos desde el archivo de datos y crea la textura y sus rects.
@@ -67,11 +90,6 @@ namespace UE
*/
void CreateTexture();
/**
* M�todo que a�ade un SDL_Rect al vector correspondiente.
* @param newRect : Nuevo Rect que a�adir al vector de Rects.
*/
void AddRect(SDL_Rect newRect);
//-----------------------
//------ Variables ------
+23
View File
@@ -21,10 +21,22 @@ namespace UE
~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?
@@ -56,8 +68,19 @@ namespace UE
//¿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;
////////////////////////////////////////////////////////
//Permite activar o desactivar el Drawable. Si está desactivado, no se debería de renderizar/ejecutar.
bool isActive = true;
};
}
+4 -20
View File
@@ -9,31 +9,21 @@
void UE::Sprite::SetTextureRect(int textureID)
{
SDL_Rect* newRect = _texture->GetTextureRect(textureID);
_txRectID = textureID;
SDL_Rect* newRect = _tx->GetTextureRect(textureID);
if (newRect != nullptr)
{
_actualTxRect = newRect;
_txRect = *newRect;
}
}
void UE::Sprite::SetActive(bool active)
{
isActive = active;
}
bool UE::Sprite::IsActive()
{
return isActive;
}
void UE::Sprite::Draw(Renderer* renderer)
{
//Convertimos a ScreenCoords.
glm::ivec2 screenCoords = renderer->WorldToSreenCoords(_pos);
SDL_Rect position = { screenCoords.x, screenCoords.y, _size.x, _size.y };
//destination.x = _pos.x;
//destination.y = _pos.y;
@@ -42,12 +32,6 @@ void UE::Sprite::Draw(Renderer* renderer)
//destination.h = _size.y;
//std::cout << "Sprite Rendered to: " << destination.x << "-" << destination.y << std::endl;
renderer->QueueDrawCall(_renderLayer, position, _texture->GetTexture(), *_actualTxRect);
}
SDL_Rect UE::Sprite::getPositionRect()
{
SDL_Rect position = { _pos.x, _pos.y, _size.x, _size.y };
return position;
//renderer->QueueDrawCall(_renderLayer, position, _tx->GetTexture(), _txRect);
}
+26 -24
View File
@@ -13,7 +13,7 @@
#include "Assets/Texture.h"
//
// TODO:
// TODO Sprite:
// - Implementar soporte para SpriteSheets en los constructores.
//
//
@@ -35,26 +35,29 @@ namespace UE
// --------------
*/
//NOTA: Hay que implementar una textura por defecto, que será la que se usará cuando no se indique nada.
// De esta forma, podemos tener constructores por defecto.
/*
Se establecen todos los par�metos.
Se establecen todos los parámetos.
La textura es obligatoria, y puede ha de darse:
- En SDL_Texture* -> Sin m�s, se entiende.
En ambos casos se llama al m�todo SetTexturePtr.
Los dem�s par�metros tienen un valor por defecto.
- En SDL_Texture* -> Sin más, se entiende.
Los demás parámetros tienen un valor por defecto.
\param texturePtr: El pointer a la textura de SDL.
\param textureRects: El pointer al conjunto de SDL_Rects de la textura.
\param textureRectID: El n�mero de Rect del conjunto de rects.
\param renderLayer: La Layer en que se renderizar�.
\param textureRectID: El número de Rect del conjunto de rects. Por defecto será 0 (La textura completa).
\param renderLayer: La Layer en que se renderizará.
\param position: Posición del Sprite.
\param size: Tamaño del Sprite.
*/
Sprite(UE::Texture* texture,
int textureRectID = 0,
int renderLayer = 1,
glm::vec2 position = glm::vec2(0, 0),
glm::vec2 size = glm::vec2(100, 100))
: _texture(texture)
{
_tx = texture;
SetTextureRect(textureRectID);
SetLayer(renderLayer);
@@ -63,36 +66,35 @@ namespace UE
SetSize(size);
}
~Sprite() {}
////////////////////////////////////////////////////////
//-----------
//- Setters -
//- Methods -
//-----------
void SetTextureRect(int textureID);
void SetActive(bool active);
bool IsActive();
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//Implementa el Draw de Drawable.
void Draw(Renderer* renderer) override;
SDL_Rect getPositionRect();
private:
//Datos de la textura. Sirven para pedirla al AssetManager.
UE::Texture* _texture = nullptr;
//El que se va a renderizar.
SDL_Rect* _actualTxRect = nullptr;
bool isActive = true;
};
+34 -14
View File
@@ -1,8 +1,11 @@
#include "TextBox.h"
#include "Engine.h"
#include "Logging/Logger.h"
#include "Render/Renderer.h"
#include <SDL_render.h>
void UE::TextBox::SetText(std::string newText)
{
_text = newText;
@@ -34,31 +37,30 @@ void UE::TextBox::SetColor(int r, int g, int b, int a)
void UE::TextBox::Draw(Renderer* renderer)
{
//Si a�n no tenemos renderer, lo guardamos y procesamos.
if (_sdlRenderer == nullptr)
{
_sdlRenderer = renderer->GetSDLRenderer();
RenderTextTexture();
}
if (_textTexture == nullptr)
if (_tx->GetTexture() == nullptr)
{
UE_LOG_WARN("El texto: {0} ; No se est� renderizando. La textura no existe.", _text);
return;
}
//Generamos el SDL_Rect destino.
SDL_Rect dest = { _pos.x, _pos.y, _size.x, _size.y };
// Ya no es necesario....
//SDL_Texture* tx = _textTexture.GetTexture();
renderer->QueueDrawCall(_renderLayer, dest, _textTexture);
//renderer->QueueDrawCall(_renderLayer, dest, _textTexture);
//Actualizamos en cada frame el ptr a la textura que tiene que usar el drawable.
//no vaya a ser que se invalide por algo.
}
void UE::TextBox::RenderTextTexture()
{
//No podemos continuar hasta que no tengamos un renderer.
if (_sdlRenderer == nullptr) { return; }
// No podemos continuar sin un SDL_Renderer.
// Si no hay SDL_Renderer, lo buscamos en el Engine.
if (_sdlRenderer == nullptr) { GetSDL_Renderer(); }
SDL_DestroyTexture(_textTexture);
//Creamos el SDL_Color a partir del vec4 que contiene el color.
SDL_Color color = { _textColor.x,_textColor.y, _textColor.z, _textColor.w };
@@ -74,8 +76,8 @@ void UE::TextBox::RenderTextTexture()
return;
}
_textTexture = SDL_CreateTextureFromSurface(_sdlRenderer, loader);
if (_textTexture == NULL)
SDL_Texture* newTextTexture = SDL_CreateTextureFromSurface(_sdlRenderer, loader);
if (newTextTexture == NULL)
{
UE_LOG_ERROR("No se ha podido crear la textura del texto: {0} ; Error: {1}",
_text, SDL_GetError());
@@ -86,4 +88,22 @@ void UE::TextBox::RenderTextTexture()
SDL_FreeSurface(loader);
//Actualizamos la SDL_Texture en la Texture.
_tx->SetTexture(newTextTexture);
//Limpiamos los Rects antiguos.
_tx->GetRectsVector()->clear();
//Añadimos el Rect correspondiente.
SDL_Rect newRect = { 0, 0, _size.x, _size.y };
_tx->AddRect(newRect);
//Actualizamos el Rect en el Drawable.
_txRect = newRect;
}
void UE::TextBox::GetSDL_Renderer()
{
_sdlRenderer = Engine::GetRenderer()->GetSDLRenderer();
}
+76 -3
View File
@@ -9,13 +9,15 @@
#include "Interfaces/Transformable.h"
#include "Assets/Font.h"
#include "Assets/Texture.h"
namespace UE
{
//NOTA: hay que mover esto a la lista de definiciones (defs.h). Algún día, lo crearemos.
typedef glm::tvec4<int> UE_Color;
class TextBox : public Drawable
{
@@ -30,6 +32,15 @@ namespace UE
glm::vec2 position = glm::vec2(0, 0))
: _font(font), _text(text), _textSize(textSize)
{
//Obtenemos el SDL_Renderer que necesitamos.
GetSDL_Renderer();
//Creamos la texture.
//_textTexture = new Texture();
//Le decimos al Drawable cual es la textura que tiene que usar.
_tx = new Texture();
SetColor(textColor);
SetLayer(renderLayer);
@@ -38,28 +49,90 @@ namespace UE
RenderTextTexture();
}
~TextBox()
{
//Hay que limpiar lo que ocupamos.
//delete _textTexture;
delete _tx;
}
// Si se realiza una copia, necesitamos que esta utilice su propia textura.
// Así, si queremos copiar una para luego modificarla, no se modifican las dos.
// (Y si una se borra no se lleva consigo los ptrs de las 2).
TextBox(const TextBox& c)
: _font(c._font), _text(c._text), _textSize(c._textSize), _textColor(c._textColor)
{
//Le decimos al Drawable cual es la textura que tiene que usar.
_tx = new Texture();
SetLayer(c._renderLayer);
SetPosition(c._pos);
this->RenderTextTexture();
}
//TODO: Eliminar constructores de Copy y demás. No se debería permitir el copiar... Rompen la _textTexture.
//NOTA: Quizás, la solución esté en los Smart Pointers...
// Se me ocurre lo siguiente:
// Añadimos un almacén "estático" para texturas en algún sitio. Le puedes pedir que te de una textura,
// y te la almacena ahí. Tú recibes un ptr y lo conservas. Tendrás acceso a la tx mientras tengas el ptr a la misma.
// El sistema eliminará los ptrs que no se usen (smart pointers) porque no tengan referencias.
//
////////////////////////////////////////////////////////
//Se generar� una textura y todo eso...
void SetText(std::string newText);
void SetSize(int newSize);
////////////////////////////////////////////////////////
void SetColor(UE_Color newColor);
void SetColor(int r, int g, int b, int a);
////////////////////////////////////////////////////////
//Implementa el Draw de Drawable.
void Draw(Renderer* renderer) override;
private:
void RenderTextTexture();
////////////////////////////////////////////////////////
/*
Obtiene el SDL_Renderer desde el Engine. (Magia estática).
*/
void GetSDL_Renderer();
private:
UE::Font* _font = nullptr;
std::string _text = "Texto por defecto";
int _textSize = 18;
UE_Color _textColor;
UE_Color _textColor = {255, 255, 255, 255};
////////////////////////////////////////////////////////
//Creamos su propia textura, que le pasamos al Drawable.
//El Drawable no almacena una textura, sino un ptr (normalmente sacado del AssetManager).
//En este caso, esta es la textura a la que debe apuntar.
// Pero podemos, simplemente, crear la textura en el heap y apuntar ahí el ptr.
//Texture* _textTexture;
SDL_Texture* _textTexture = nullptr;
//Esto est� muy mal hecho, no deber�a de ser as�.
//Necesito un renderer para crear la textura del texto, pero no puedo conseguirlo con la arquitectura actual.
+1 -1
View File
@@ -42,7 +42,7 @@ namespace UE
_size.y += y;
}
SDL_Rect Transformable::GetRect()
SDL_Rect Transformable::GetTransformRect()
{
SDL_Rect rect = { _pos.x, _pos.y, _size.x, _size.y };
return rect;
+1 -1
View File
@@ -73,7 +73,7 @@ namespace UE
/*
* Devuelve el rect que representa/ocupa el objeto.
*/
SDL_Rect GetRect();
SDL_Rect GetTransformRect();
protected:
+57 -80
View File
@@ -9,6 +9,7 @@
#include "Renderer.h"
#include "Assets/Texture.h"
#include "Logging/Logger.h"
namespace UE
@@ -36,43 +37,42 @@ namespace UE
SDL_SetRenderDrawColor(main_Renderer, 0xFF, 0xFF, 0xFF, 0xFF);
#pragma region ImGui.
//Inicializamos Dear ImGui con el SDL_Renderer.
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io; //Evita que de un Warning por variable no usada.
(void)io; //Evita que de un Warning por variable no usada. Este C++ es demasiado avanzado.
ImGui::StyleColorsDark();
ImGui_ImplSDL2_InitForSDLRenderer(_window, main_Renderer);
ImGui_ImplSDLRenderer_Init(main_Renderer);
#pragma endregion
//Init layers.
//Init layers for World Rendering.
for (int i = 0; i <= LAYER_AMOUNT; i++)
{
renderLayers.push_back(std::vector<DrawCall>());
worldLayers.push_back(std::vector<Drawable*>());
}
}
void Renderer::CleanRenderer()
{
renderQueue.clear();
//Limpiamos ImGui
ImGui_ImplSDLRenderer_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
//Limpiamos SDL.
SDL_DestroyRenderer(main_Renderer);
SDL_DestroyWindow(_window);
}
//NOTA No sé para qué sirve el método RenderFrame(), es privado. ¿Eliminar método?
void Renderer::RenderFrame()
{
NewFrame();
@@ -89,13 +89,11 @@ namespace UE
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
//Quiz�s deber�amos limpiar la cola y las Layers aqu� para eliminar residuos...
//callCounter = 0;
//rendererCounter = 0;
//Comprobamos que la cámara sigue existiendo.
if (activeCam == nullptr)
{
//Si no existe la cámara activa, utilizamos la por defecto.
ResetCamera();
}
@@ -106,40 +104,38 @@ namespace UE
void Renderer::RenderData()
{
//Add items to their layer.
for (int i = 0; i < renderQueue.size(); i++)
{
DrawCall item = renderQueue.at(i);
//Add item i to layer number i.layer.
if (item.layer > LAYER_AMOUNT)
//REWORK Probablemente sea más bonito separar en métodos el World Render del UI Render.
//Iterate world layers.
for (int j = 0; j < worldLayers.size(); j++)
{
UE_LOG_ERROR("Error rendering data: Can't render item to Layer {0} -> out of range\n", item.layer);
return;
}
renderLayers.at(item.layer).push_back(item);
//Extract layer j.
std::vector<Drawable*>& layer = worldLayers.at(j);
}
renderQueue.clear();
//Iterate layers.
for (int j = 0; j < renderLayers.size(); j++)
{
std::vector<DrawCall>& layer = renderLayers.at(j);
//Render items from layer j.
for (int k = 0; k < layer.size(); k++)
{
DrawCall item = layer.at(k);
if (item.fullTexture)
{
SDL_RenderCopy(main_Renderer, item.tx, NULL, &item.pos_rect);
continue;
}
SDL_RenderCopy(main_Renderer, item.tx, &item.tx_rect, &item.pos_rect);
//Extract Drawable k
Drawable* item = layer.at(k);
SDL_Texture* tx = item->_tx->GetTexture();
//Los están en WorldCoords. Convertimos la posición a ScreenCoords.
// NOTA: Se deberá transformar todo el Rect en función de la cam, no sólo la pos.
glm::ivec2 screenCoords = WorldToSreenCoords(item->_pos);
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);
}
layer.clear();
}
//Renderizado de ImGui.
ImGui::Render();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
}
void Renderer::EndFrame()
@@ -147,9 +143,6 @@ namespace UE
//SDL_UpdateWindowSurface(window);
//SDL_RenderPresent(main_Renderer);
//SDL_RenderClear(main_Renderer);
ImGui::Render();
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
SDL_RenderPresent(main_Renderer);
@@ -157,6 +150,31 @@ namespace UE
}
void Renderer::Render(Drawable& drawable)
{
drawable.Draw(this);
int layer = drawable.GetLayer();
//Check Layer.
if (layer > LAYER_AMOUNT)
{
UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", layer);
return;
}
// FIX Comprobamos si el objeto es visible.
// if(!IsObjectVisible(&drawCall.pos_rect))
// {
// //Si no es visible, no lo renderizaríamos.
// return;
// }
//SDL_Texture* tx = drawable._tx->GetTexture();
//Add Item to Layer for being rendered.
worldLayers.at(layer).push_back(&drawable);
}
@@ -193,7 +211,7 @@ namespace UE
return fPos;
}
//CREO QUE ESTE M�TODO NO FUNCIONA.
//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)
{
@@ -215,45 +233,4 @@ namespace UE
}
void Renderer::QueueDrawCall(DrawCall drawCall)
{
//callCounter++;
//Add item i to layer number i.layer.
if (drawCall.layer > LAYER_AMOUNT)
{
UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", drawCall.layer);
return;
}
// //Comprobamos si el objeto es visible.
// if(!IsObjectVisible(&drawCall.pos_rect))
// {
// //Si no es visible, no lo renderizaríamos.
// return;
// }
renderLayers.at(drawCall.layer).push_back(drawCall);
//rendererCounter++;
//renderQueue.push_back(drawCall);
}
void Renderer::QueueDrawCall(int layer, SDL_Rect& position, SDL_Texture* texture, SDL_Rect& texture_position)
{
DrawCall dc = DrawCall(layer, position, texture, texture_position);
QueueDrawCall(dc);
}
void Renderer::QueueDrawCall(int layer, SDL_Rect & position, SDL_Texture* texture)
{
//std::cout << "Drawable added to queue";
DrawCall dc = DrawCall(layer, position, texture);
QueueDrawCall(dc);
}
void Renderer::Render(Drawable& drawable)
{
drawable.Draw(this);
}
}
+90 -62
View File
@@ -11,8 +11,7 @@
#include "Camera.h"
//
// TODO:
// - Optimizar RenderDraw moviendo la ordenaci�n por capas a Queue, quitando renderQueue.
// TODO Renderer:
// - Limpiar las funciones moviendo c�digo a otras funciones.
// - �Podr�a moverse todo a static? De esta forma, ya no har�an falta instancias.
//
@@ -20,9 +19,6 @@
namespace UE
{
struct DrawCall;
class Renderer
{
@@ -41,6 +37,9 @@ namespace UE
}
////////////////////////////////////////////////////////
/* Inicializa los componentes necesarios:
- Crea la ventana.
- Crea el renderer.
@@ -49,46 +48,93 @@ namespace UE
*/
int InitRenderer();
/* Limpia todo antes de salir. */
/* Limpia todo antes de salir.
* - Apaga ImGui.
* - Destruye el renderer.
* - Destruye la ventana.
*/
void CleanRenderer();
////////////////////////////////////////////////////////
//Hace el SDL_RenderClear() para limpiar el buffer al principio de un nuevo frame.
/*
* Hace el SDL_RenderClear() para limpiar el buffer al principio de un nuevo frame.
*/
void NewFrame();
//Ordena por layer todos los objetos de la renderQueue y los dibuja en orden.
//Se puede mover el proceso de ordenado a otra funci�n, con el objeto de ir vaciando la Queue.
/*
* Realiza el renderizado de los objetos.
* - Renderiza las layers.
* - Renderiza la UI.
* - Renderiza ImGui.
*/
void RenderData();
//Hace el swap del render buffer (tras dibujar todos los objetos). Termina el renderizado.
/*
* Hace el swap del render buffer (tras dibujar todos los objetos).
* Termina el renderizado.
*/
void EndFrame();
//A�ade un DrawCall al renderQueue.
void QueueDrawCall(DrawCall drawCall);
void QueueDrawCall(int layer, SDL_Rect& position, SDL_Texture* texture, SDL_Rect& texture_position);
void QueueDrawCall(int layer, SDL_Rect & position, SDL_Texture* texture);
//Le pasamos este renderer al Drawable para que haga lo que quiera.
//Como si quiere usar el SDL_Renderer, es libre.
/*
* Rendiriza el Objeto indicado.
* El proceso consta de dos partes:
* - 1º: El objeto hará las modificaciones necesarias a sus datos.
* - 2º: El Renderer extraerá los datos de Drawable y lo renderizará.
*/
void Render(Drawable& drawable);
/* Get SDL Renderer. */
SDL_Renderer* GetSDLRenderer() { return main_Renderer; }
///////////////////////////////////////////////////////
/* Get SDL Renderer. */
inline SDL_Renderer* GetSDLRenderer() { return main_Renderer; }
////////////////////////////////////////////////////////
/*
* Get windows/screen size.
*/
inline glm::ivec2 GetScreenSize() { return screenSize; }
/*
* Permite cambiar el tamaño de la ventana.
* REWORK: Hay que mirar los métodos de SDL y aprender cómo funcionan las ventanas.
* Quizás, incluso, abstraer la ventana a su propia clase para facilitar Fullscreen y esas cosas.
*/
void SetScreenSize(int newWidth, int newHeight);
//Permite cambiar el color de fondo.
////////////////////////////////////////////////////////
/*
* Cambiar el color del fondo.
*/
void SetDrawingColor(SDL_Color& newColor);
//Cambia la cámara que se utiliza en el renderizado.
////////////////////////////////////////////////////////
/*
* Set the active cámera.
*/
inline void SetCamera(Camera* newCam) { activeCam = newCam; }
/*
* Get a ptr to the active camera.
*/
inline Camera* GetCamera() { return activeCam; }
/*
* Cambia la cámara activa a la cámara por defecto.
* Utilizado el eliminar una cámara o cuando la activeCam ya no existe.
@@ -96,6 +142,9 @@ namespace UE
inline void ResetCamera() { activeCam = &defaultCam; }
////////////////////////////////////////////////////////
/* M�todos para transformar las coordenadas entre Screen y Wolrd. */
//WorldCoords = ScreenPos + CamPos -> ScreenPos = WorldCoords - CamPos;
@@ -104,11 +153,18 @@ namespace UE
//Convierte coordenadas de la pantalla al mundo.
glm::ivec2 ScreenToWorldCoords(glm::ivec2 screenCoord);
////////////////////////////////////////////////////////
//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.
bool IsObjectVisible(SDL_Rect* objectRect);
////////////////////////////////////////////////////////
//DEBUG
//Funci�n para renderizar un objeto un objeto en concreto directamente en el SDL_Renderer.
void DrawObject(SDL_Rect* position, SDL_Rect* texture_pos, SDL_Texture* texture);
@@ -117,37 +173,42 @@ namespace UE
private:
//Realizar RenderClear(), RenderDraw() y RenderUpdate();
//Es decir, todo lo necesario para renderizar un frame.
//NOTA RenderFrame() es privado, por lo que no puede ser usado. En el renderer, tampoco se usa.
void RenderFrame();
private:
/* Objetos de SDL para el rendering. */
SDL_Window* _window = nullptr;
SDL_Surface* screenSurface = nullptr;
SDL_Renderer* main_Renderer = nullptr;
//SDL_GLContext _glContext = nullptr;
//Almacena todas las "draw calls" para luego ordenar los objetos por layers y dibujarlos.
//Se podr�a sustituir por un std::queue o std::deque si fuera necesario.
std::vector<DrawCall> renderQueue;
////////////////////////////////////////////////////////
//Las capas en las que se organizan los diferentes objetos.
//Permite dibujar unos sprites sobre otros.
const int LAYER_AMOUNT = 10;
std::vector<std::vector<DrawCall>> renderLayers;
std::vector<std::vector<Drawable*>> worldLayers;
//int screenWidth = 640;
//int screenHeight = 480;
////////////////////////////////////////////////////////
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);
SDL_Rect _screenRect{ 0, 0, screenSize.x, screenSize.y};
//DEBUG
@@ -156,37 +217,4 @@ namespace UE
};
/*
Contiene los valores necesarios para realizar el renderizado con SDL_RenderCopy();
Se almacena en la renderQueue y luego son ordenados por las renderLayers.
*/
struct DrawCall
{
DrawCall(int layer,
SDL_Rect position,
SDL_Texture* texture,
SDL_Rect texture_position)
: layer(layer), tx(texture), tx_rect(texture_position), pos_rect(position)
{}
DrawCall(int layer,
SDL_Rect position,
SDL_Texture* texture)
: layer(layer), tx(texture), pos_rect(position)
{
tx_rect = SDL_Rect();
fullTexture = true;
}
int layer;
bool fullTexture = false;
SDL_Texture* tx;
SDL_Rect tx_rect;
SDL_Rect pos_rect;
};
}
+1 -4
View File
@@ -3,10 +3,7 @@
#include <string>
#include <iostream>
///
/// TODO:
///
///
union SDL_Event;
namespace UE
+4
View File
@@ -12,6 +12,10 @@
// - Añadir un método para recargar la escena actual. La descarga entera y la vuelve a cargar.
// - La variable "loaded" de las escenas no tiene mucha utilidad en este momento.
// ERROR SceneLoader: No se hace bien la carga y descarga de escenas. No parece estar limpiándose la memoria.
// Parece que no funciona lo de no recargar la escena en la que estás.
namespace UE
{
+3 -1
View File
@@ -63,8 +63,10 @@ public:
UE::TextBox text1(OP_Regular);
//UE::TextBox text2(OP_Bold, "Otro texto");
//UE::TextBox(OP_Regular)
texts.push_back(text1);
texts.push_back(text1); //Copiamos el text1.
//texts.emplace_back(OP_Regular); //Construimos el text1.
//texts.push_back(text2);
}
+3 -3
View File
@@ -112,7 +112,7 @@ private:
for (int i = 0; i < sprites.size(); i++)
{
UE::Sprite& sp = sprites.at(i);
SDL_Rect sp_Pos = sp.getPositionRect();
SDL_Rect sp_Pos = sp.GetTransformRect();
if (SDL_HasIntersection(&mouseRect, &sp_Pos))
{
int i = rand() % 5;
@@ -195,8 +195,8 @@ private:
}
private:
const int vAmount = 10;
const int hAmount = 10;
const int vAmount = 256;
const int hAmount = 256;
std::vector<UE::Sprite> sprites = {};