Cambios en el renderer para facilitar el uso de ImGui por ahí, fuera del propio renderer.
Implimentado un sistema de cámara y la consiguiente conversión entre WorldCoords y ScreenCoords.
This commit is contained in:
@@ -28,10 +28,10 @@ namespace UE
|
||||
}
|
||||
|
||||
//Configuramos los parámetros de la ventana de SDL.
|
||||
SDL_WindowFlags windowFlags = (SDL_WindowFlags)(SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE);
|
||||
Uint32 windowFlags = (SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
//Creamos la ventana de SDL.
|
||||
_window = SDL_CreateWindow("UberGame1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, windowFlags);
|
||||
_window = SDL_CreateWindow("UberGame1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenSize.x, screenSize.y, windowFlags);
|
||||
if (_window == NULL)
|
||||
{
|
||||
UE_LOG_CRITICAL("No se ha podido crear la ventana de SDL con OpenGL y esas mierdas: {0}", SDL_GetError());
|
||||
@@ -85,14 +85,13 @@ namespace UE
|
||||
|
||||
void Renderer::RenderFrame()
|
||||
{
|
||||
StartRender();
|
||||
RenderQueue();
|
||||
RenderIMGUI();
|
||||
FinishRender();
|
||||
NewFrame();
|
||||
RenderData();
|
||||
EndFrame();
|
||||
}
|
||||
|
||||
|
||||
void Renderer::StartRender()
|
||||
void Renderer::NewFrame()
|
||||
{
|
||||
SDL_RenderClear(main_Renderer);
|
||||
|
||||
@@ -100,9 +99,11 @@ namespace UE
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
//Quizás deberíamos limpiar la cola y las Layers aquí para eliminar residuos...
|
||||
|
||||
}
|
||||
|
||||
void Renderer::RenderQueue()
|
||||
void Renderer::RenderData()
|
||||
{
|
||||
//Add items to their layer.
|
||||
for (int i = 0; i < renderQueue.size(); i++)
|
||||
@@ -112,7 +113,7 @@ namespace UE
|
||||
//Add item i to layer number i.layer.
|
||||
if (item.layer > LAYER_AMOUNT)
|
||||
{
|
||||
std::cout << "Layer out of range\n";
|
||||
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);
|
||||
@@ -135,15 +136,8 @@ namespace UE
|
||||
|
||||
}
|
||||
|
||||
void Renderer::RenderIMGUI()
|
||||
{
|
||||
bool show = true;
|
||||
ImGui::ShowDemoWindow(&show);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Renderer::FinishRender()
|
||||
void Renderer::EndFrame()
|
||||
{
|
||||
//SDL_UpdateWindowSurface(window);
|
||||
//SDL_RenderPresent(main_Renderer);
|
||||
@@ -161,14 +155,24 @@ namespace UE
|
||||
|
||||
|
||||
|
||||
void Renderer::SetScreenSize(Sint32 newWidth, Sint32 newHeight)
|
||||
void Renderer::SetScreenSize(int newWidth, int newHeight)
|
||||
{
|
||||
SCREEN_WIDTH = newWidth;
|
||||
SCREEN_HEIGHT = newHeight;
|
||||
screenSize.x = newWidth;
|
||||
screenSize.y = newHeight;
|
||||
SDL_SetWindowSize(_window, newWidth, newHeight);
|
||||
glViewport(0, 0, newWidth, newHeight);
|
||||
|
||||
UE_LOG_TRACE("Screen size chaged to: {0}x{1}", newWidth, newHeight);
|
||||
}
|
||||
|
||||
void Renderer::SetCamPosition(int posX, int posY)
|
||||
{
|
||||
camPosition.x = posX;
|
||||
camPosition.y = posY;
|
||||
UE_LOG_TRACE("Cam position chaged to: {0}x{1}", posX, posY);
|
||||
}
|
||||
|
||||
//¿Deberíamos operar la posición para que tenga en cuenta la cámara?
|
||||
void Renderer::DrawObject(SDL_Rect* position, SDL_Rect* texture_pos, SDL_Texture* texture)
|
||||
{
|
||||
SDL_RenderCopy(main_Renderer, texture, texture_pos, position);
|
||||
@@ -181,9 +185,19 @@ namespace UE
|
||||
//Add item i to layer number i.layer.
|
||||
if (drawCall.layer > LAYER_AMOUNT)
|
||||
{
|
||||
std::cout << "Layer out of range\n";
|
||||
UE_LOG_ERROR("Can't add DrawCall to Layer {0} -> out of range\n", drawCall.layer);
|
||||
return;
|
||||
}
|
||||
|
||||
//Convertimos la posición del objeto de WorldCoords y ScreenCoords relativas a la camPosition.
|
||||
//Únicamente cambiamos las coords. Se podría añadir un modificador para el tamaño en relación al tamaño de la cam o algo así.
|
||||
//WorldCoords = ScreenPos + CamPos -> ScreenPos = WorldCoords - CamPos;
|
||||
glm::ivec2 oPos{ drawCall.pos_rect.x, drawCall.pos_rect.y };
|
||||
glm::ivec2 fPos = oPos - camPosition;
|
||||
|
||||
drawCall.pos_rect.x = fPos.x;
|
||||
drawCall.pos_rect.y = fPos.y;
|
||||
|
||||
renderLayers.at(drawCall.layer).push_back(drawCall);
|
||||
|
||||
//renderQueue.push_back(drawCall);
|
||||
@@ -192,31 +206,14 @@ namespace UE
|
||||
void Renderer::QueueDrawCall(int layer, SDL_Rect& position, SDL_Texture* texture, SDL_Rect& texture_position)
|
||||
{
|
||||
DrawCall dc = DrawCall(layer, position, texture, texture_position);
|
||||
|
||||
//Add item i to layer number i.layer.
|
||||
if (layer > LAYER_AMOUNT)
|
||||
{
|
||||
std::cout << "Layer out of range\n";
|
||||
return;
|
||||
}
|
||||
renderLayers.at(layer).push_back(dc);
|
||||
|
||||
//renderQueue.push_back(dc);
|
||||
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);
|
||||
|
||||
if (layer >= LAYER_AMOUNT)
|
||||
{
|
||||
std::cout << "Layer out of range\n";
|
||||
return;
|
||||
}
|
||||
renderLayers.at(layer).push_back(dc);
|
||||
|
||||
//renderQueue.push_back(dc);
|
||||
QueueDrawCall(dc);
|
||||
}
|
||||
|
||||
void Renderer::Render(Drawable& drawable)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// TODO:
|
||||
// - Optimizar RenderDraw moviendo la ordenación por capas a Queue, quitando renderQueue.
|
||||
// - Limpiar las funciones moviendo código a otras funciones.
|
||||
//
|
||||
// - ¿Podría moverse todo a static? De esta forma, ya no harían falta instancias.
|
||||
//
|
||||
|
||||
|
||||
@@ -31,8 +31,10 @@ namespace UE
|
||||
int windowHeight,
|
||||
int renderingLayers = 10)
|
||||
|
||||
: SCREEN_WIDTH(windowWidth), SCREEN_HEIGHT(windowHeight), LAYER_AMOUNT(renderingLayers)
|
||||
: LAYER_AMOUNT(renderingLayers)
|
||||
{
|
||||
screenSize.x = windowWidth;
|
||||
screenSize.y = windowHeight;
|
||||
//UE_LOG_INFO("Game Renderer Created.");
|
||||
}
|
||||
|
||||
@@ -49,9 +51,18 @@ namespace UE
|
||||
void CleanRenderer();
|
||||
|
||||
|
||||
//Realizar RenderClear(), RenderDraw() y RenderUpdate();
|
||||
//Es decir, todo lo necesario para renderizar un frame.
|
||||
void RenderFrame();
|
||||
|
||||
|
||||
//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.
|
||||
void RenderData();
|
||||
|
||||
|
||||
//Hace el swap del render buffer (tras dibujar todos los objetos). Termina el renderizado.
|
||||
void EndFrame();
|
||||
|
||||
|
||||
//Añade un DrawCall al renderQueue.
|
||||
@@ -59,35 +70,29 @@ namespace UE
|
||||
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 el este renderer al Drawable para que haga lo que quiera.
|
||||
//Le pasamos este renderer al Drawable para que haga lo que quiera.
|
||||
//Como si quiere usar el SDL_Renderer, es libre.
|
||||
void Render(Drawable& drawable);
|
||||
|
||||
/* Get SDL Renderer. */
|
||||
SDL_Renderer* GetSDLRenderer() { return main_Renderer; }
|
||||
|
||||
inline glm::ivec2 GetScreenSize() { return glm::ivec2(SCREEN_WIDTH, SCREEN_HEIGHT); }
|
||||
void SetScreenSize(Sint32 newWidth, Sint32 newHeight);
|
||||
inline glm::ivec2 GetScreenSize() { return screenSize; }
|
||||
void SetScreenSize(int newWidth, int newHeight);
|
||||
|
||||
inline glm::ivec2 GetCamPosition() { return camPosition; }
|
||||
void SetCamPosition(int posX, int posY);
|
||||
|
||||
|
||||
//DEBUG
|
||||
//Función para renderizar un objeto un objeto en concreto.
|
||||
//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);
|
||||
|
||||
|
||||
private:
|
||||
//Hace el SDL_RenderClear() para limpiar el buffer al principio de un nuevo frame.
|
||||
void StartRender();
|
||||
|
||||
//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.
|
||||
void RenderQueue();
|
||||
|
||||
void RenderIMGUI();
|
||||
|
||||
//Hace el swap del render buffer (tras dibujar todos los objetos). Termina el renderizado.
|
||||
void FinishRender();
|
||||
|
||||
//Realizar RenderClear(), RenderDraw() y RenderUpdate();
|
||||
//Es decir, todo lo necesario para renderizar un frame.
|
||||
void RenderFrame();
|
||||
|
||||
|
||||
private:
|
||||
@@ -108,8 +113,11 @@ namespace UE
|
||||
std::vector<std::vector<DrawCall>> renderLayers;
|
||||
|
||||
|
||||
int SCREEN_WIDTH = 640;
|
||||
int SCREEN_HEIGHT = 480;
|
||||
//int screenWidth = 640;
|
||||
//int screenHeight = 480;
|
||||
|
||||
glm::ivec2 screenSize{ 640,480 };
|
||||
glm::ivec2 camPosition{ 0,0 };
|
||||
|
||||
};
|
||||
|
||||
@@ -124,7 +132,7 @@ namespace UE
|
||||
SDL_Texture* texture,
|
||||
SDL_Rect texture_position = SDL_Rect())
|
||||
|
||||
: layer(layer), tx(texture), tx_rect(texture_position), pos_rect(position)
|
||||
: layer(layer), tx(texture), tx_rect(texture_position), pos_rect(position)
|
||||
{}
|
||||
|
||||
int layer;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
///
|
||||
/// TODO:
|
||||
/// - Scene debería ser serializable y cargable desde archivos, al menos para las clases derivadas.
|
||||
/// - Scene debería ser serializable y cargable desde archivos, al menos para las clases derivadas. ( o quizás no....)
|
||||
///
|
||||
///
|
||||
|
||||
@@ -33,6 +33,7 @@ namespace UE
|
||||
|
||||
/* Funciones que habrán de sobrecargar las escenas del usuario. */
|
||||
virtual void SceneLoad() { std::cout << "EMPTY SCENE CREATED" << std::endl; }
|
||||
virtual void SceneRender() { std::cout << "EMPTY SCENE IS BEING RENDERED" << std::endl; }
|
||||
virtual void SceneUpdate() {}
|
||||
virtual void SceneUnload() { std::cout << "EMPTY SCENE DESCARGADA" << std::endl; }
|
||||
|
||||
|
||||
+40
-5
@@ -96,8 +96,9 @@ void Loop()
|
||||
{
|
||||
_quit = true;
|
||||
}
|
||||
if (eventHandler.type == SDL_WINDOWEVENT_RESIZED)
|
||||
if (eventHandler.type == SDL_WINDOWEVENT && eventHandler.window.event == SDL_WINDOWEVENT_RESIZED)
|
||||
{
|
||||
//GAME_LOG_CRITICAL("Window Size chaged {0}x{1}", eventHandler.window.data1, eventHandler.window.data2);
|
||||
Game::GetRenderer()->SetScreenSize(eventHandler.window.data1, eventHandler.window.data2);
|
||||
}
|
||||
if (eventHandler.type == SDL_KEYDOWN)
|
||||
@@ -125,12 +126,33 @@ void Loop()
|
||||
{
|
||||
GAME_LOG_TRACE("FPS: {0} / dT: {1}", 60, UE::Time::deltaTime);
|
||||
}
|
||||
if (keyStates[SDL_SCANCODE_1])
|
||||
|
||||
if (keyStates[SDL_SCANCODE_W])
|
||||
{
|
||||
glm::ivec2 camPos = Game::GetRenderer()->GetCamPosition();
|
||||
camPos.y -= 5;
|
||||
Game::GetRenderer()->SetCamPosition(camPos.x, camPos.y);
|
||||
}
|
||||
if (keyStates[SDL_SCANCODE_2])
|
||||
if (keyStates[SDL_SCANCODE_S])
|
||||
{
|
||||
glm::ivec2 camPos = Game::GetRenderer()->GetCamPosition();
|
||||
camPos.y += 5;
|
||||
Game::GetRenderer()->SetCamPosition(camPos.x, camPos.y);
|
||||
}
|
||||
if (keyStates[SDL_SCANCODE_D])
|
||||
{
|
||||
glm::ivec2 camPos = Game::GetRenderer()->GetCamPosition();
|
||||
camPos.x += 5;
|
||||
Game::GetRenderer()->SetCamPosition(camPos.x, camPos.y);
|
||||
}
|
||||
if (keyStates[SDL_SCANCODE_A])
|
||||
{
|
||||
glm::ivec2 camPos = Game::GetRenderer()->GetCamPosition();
|
||||
camPos.x -= 5;
|
||||
Game::GetRenderer()->SetCamPosition(camPos.x, camPos.y);
|
||||
}
|
||||
|
||||
Game::GetSceneManager()->GetActiveScenePtr()->SceneUpdate();
|
||||
|
||||
//Game::GetRenderer()->QueueDrawCall(4, DestR2, test1);
|
||||
//Game::GetRenderer()->QueueDrawCall(1, DestR, background);
|
||||
@@ -139,9 +161,22 @@ void Loop()
|
||||
//sp2.Draw(renderer);
|
||||
//sp3.Draw(Game::GetRenderer());
|
||||
//
|
||||
Game::GetSceneManager()->GetActiveScenePtr()->SceneUpdate();
|
||||
|
||||
Game::GetRenderer()->RenderFrame();
|
||||
//Iniciamos un nuevo Frame.
|
||||
Game::GetRenderer()->NewFrame();
|
||||
|
||||
//Renderiza la escena.
|
||||
Game::GetSceneManager()->GetActiveScenePtr()->SceneRender();
|
||||
|
||||
//Así podemos renderizar cosas de ImGui cuando estemos entre NewFrame y EndFrame.
|
||||
bool show = true;
|
||||
ImGui::ShowDemoWindow(&show);
|
||||
|
||||
//Dibuja las cosas del Renderer.
|
||||
Game::GetRenderer()->RenderData();
|
||||
|
||||
//Terminamos el Frame.
|
||||
Game::GetRenderer()->EndFrame();
|
||||
|
||||
UE::Time::EndFrame();
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
void SceneUpdate() override
|
||||
{
|
||||
UE_LOG_INFO("Escena {0} UPDATE", _sceneName);
|
||||
//UE_LOG_INFO("Escena {0} UPDATE", _sceneName);
|
||||
|
||||
UE::Renderer* renderer;
|
||||
renderer = Game::GetRenderer();
|
||||
@@ -51,18 +51,22 @@ public:
|
||||
|
||||
UE::Sprite& sp1 = sprites.at(0);
|
||||
glm::vec2 pos = sp1.GetPosition();
|
||||
if (pos.x > screenSize.x) { pos.x -= 1000; }
|
||||
if (pos.x > screenSize.x) { pos.x = 0; }
|
||||
else { pos.x += 200 * UE::Time::deltaTime; }
|
||||
|
||||
sp1.SetPosition(pos);
|
||||
|
||||
}
|
||||
|
||||
void SceneRender() override
|
||||
{
|
||||
UE::Renderer* renderer;
|
||||
renderer = Game::GetRenderer();
|
||||
|
||||
for (UE::Sprite sp : sprites)
|
||||
{
|
||||
renderer->Render(sp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SceneUnload() override
|
||||
|
||||
Reference in New Issue
Block a user