Compare commits
3 Commits
b5dbb694f3
...
e7359a1467
| Author | SHA1 | Date | |
|---|---|---|---|
| e7359a1467 | |||
| 96680dae0f | |||
| dc7b3bf7e0 |
@@ -9,14 +9,14 @@
|
|||||||
#include <stdexcept> // Para runtime_error
|
#include <stdexcept> // Para runtime_error
|
||||||
#include <string> // Para basic_string, string
|
#include <string> // Para basic_string, string
|
||||||
#include <vector> // Para vector
|
#include <vector> // Para vector
|
||||||
#include <array> // Para vector
|
#include <array> // Para vector
|
||||||
#include "balloon_manager.h" // Para BalloonManager
|
#include "balloon_manager.h" // Para BalloonManager
|
||||||
#include "fade.h" // Para Fade, FadeType, FadeMode
|
#include "fade.h" // Para Fade, FadeType, FadeMode
|
||||||
#include "global_inputs.h" // Para check, update
|
#include "global_inputs.h" // Para check, update
|
||||||
#include "input.h" // Para Input
|
#include "input.h" // Para Input
|
||||||
#include "jail_audio.h" // Para JA_GetMusicState, JA_SetMusicVolume
|
#include "jail_audio.h" // Para JA_GetMusicState, JA_SetMusicVolume
|
||||||
#include "lang.h" // Para getText
|
#include "lang.h" // Para getText
|
||||||
#include "global_events.h" // Para handleEvent
|
#include "global_events.h" // Para handleEvent
|
||||||
#include "param.h" // Para Param, ParamGame, param
|
#include "param.h" // Para Param, ParamGame, param
|
||||||
#include "player.h" // Para Player, PlayerState
|
#include "player.h" // Para Player, PlayerState
|
||||||
#include "resource.h" // Para Resource
|
#include "resource.h" // Para Resource
|
||||||
@@ -57,6 +57,9 @@ Credits::Credits()
|
|||||||
fade_out_->setType(FadeType::FULLSCREEN);
|
fade_out_->setType(FadeType::FULLSCREEN);
|
||||||
fade_out_->setPostDuration(400);
|
fade_out_->setPostDuration(400);
|
||||||
|
|
||||||
|
updateRedRect();
|
||||||
|
tiled_bg_->setColor(Color(255, 96, 96));
|
||||||
|
|
||||||
initPlayers();
|
initPlayers();
|
||||||
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
|
||||||
fillTextTexture();
|
fillTextTexture();
|
||||||
@@ -94,6 +97,7 @@ void Credits::update()
|
|||||||
for (int i = 0; i < REPEAT; ++i)
|
for (int i = 0; i < REPEAT; ++i)
|
||||||
{
|
{
|
||||||
tiled_bg_->update();
|
tiled_bg_->update();
|
||||||
|
cycleColors();
|
||||||
balloon_manager_->update();
|
balloon_manager_->update();
|
||||||
updateTextureDstRects();
|
updateTextureDstRects();
|
||||||
throwBalloons();
|
throwBalloons();
|
||||||
@@ -104,7 +108,7 @@ void Credits::update()
|
|||||||
updateAllFades();
|
updateAllFades();
|
||||||
++counter_;
|
++counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen::get()->update();
|
Screen::get()->update();
|
||||||
globalInputs::update();
|
globalInputs::update();
|
||||||
|
|
||||||
@@ -128,23 +132,25 @@ void Credits::render()
|
|||||||
// Comprueba el manejador de eventos
|
// Comprueba el manejador de eventos
|
||||||
void Credits::checkEvents()
|
void Credits::checkEvents()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
globalEvents::check(event);
|
globalEvents::check(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comprueba las entradas
|
// Comprueba las entradas
|
||||||
void Credits::checkInput()
|
void Credits::checkInput()
|
||||||
{
|
{
|
||||||
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
||||||
if (Input::get()->checkAnyButtonPressed())
|
if (Input::get()->checkAnyButtonPressed(INPUT_ALLOW_REPEAT))
|
||||||
|
|
||||||
{
|
{
|
||||||
if (mini_logo_on_position_)
|
if (mini_logo_on_position_)
|
||||||
{
|
{
|
||||||
// Si el mini_logo ha llegado a su posición final, al pulsar cualquier tecla se activa el fundido
|
// Si el mini_logo ha llegado a su posición final, al pulsar cualquier tecla se activa el fundido
|
||||||
fading_ = true;
|
fading_ = true;
|
||||||
|
want_to_pass_ = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -152,6 +158,10 @@ void Credits::checkInput()
|
|||||||
want_to_pass_ = true;
|
want_to_pass_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
want_to_pass_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||||
globalInputs::check();
|
globalInputs::check();
|
||||||
@@ -268,12 +278,16 @@ void Credits::fillCanvas()
|
|||||||
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_);
|
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, &mini_logo_rect_src_, &mini_logo_rect_dst_);
|
||||||
|
|
||||||
// Dibuja los rectangulos negros
|
// Dibuja los rectangulos negros
|
||||||
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0xFF);
|
||||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &top_black_rect_);
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &top_black_rect_);
|
||||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &bottom_black_rect_);
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &bottom_black_rect_);
|
||||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &left_black_rect_);
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &left_black_rect_);
|
||||||
SDL_RenderFillRect(Screen::get()->getRenderer(), &right_black_rect_);
|
SDL_RenderFillRect(Screen::get()->getRenderer(), &right_black_rect_);
|
||||||
|
|
||||||
|
// Dibuja el rectangulo rojo
|
||||||
|
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0xFF, 0, 0, 0xFF);
|
||||||
|
SDL_RenderDrawRect(Screen::get()->getRenderer(), &red_rect);
|
||||||
|
|
||||||
// Si el mini_logo está en su destino, lo dibuja encima de lo anterior
|
// Si el mini_logo está en su destino, lo dibuja encima de lo anterior
|
||||||
if (mini_logo_on_position_)
|
if (mini_logo_on_position_)
|
||||||
{
|
{
|
||||||
@@ -419,13 +433,14 @@ void Credits::updateBlackRects()
|
|||||||
// Si los rectangulos superior e inferior han llegado al centro
|
// Si los rectangulos superior e inferior han llegado al centro
|
||||||
if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x)
|
if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x)
|
||||||
{
|
{
|
||||||
|
constexpr int SPEED = 2;
|
||||||
// Si los rectangulos izquierdo y derecho no han llegado al centro
|
// Si los rectangulos izquierdo y derecho no han llegado al centro
|
||||||
// Incrementa la anchura del rectangulo situado a la izquierda
|
// Incrementa la anchura del rectangulo situado a la izquierda
|
||||||
left_black_rect_.w = std::min(left_black_rect_.w + 4, param.game.game_area.center_x);
|
left_black_rect_.w = std::min(left_black_rect_.w + SPEED, param.game.game_area.center_x);
|
||||||
|
|
||||||
// Incrementa la anchura y modifica la posición del rectangulo situado a la derecha
|
// Incrementa la anchura y modifica la posición del rectangulo situado a la derecha
|
||||||
right_black_rect_.w += 4;
|
right_black_rect_.w += SPEED;
|
||||||
right_black_rect_.x = std::max(right_black_rect_.x - 4, param.game.game_area.center_x);
|
right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x);
|
||||||
|
|
||||||
--current_step;
|
--current_step;
|
||||||
setVolume(static_cast<int>(initial_volume_ * current_step / steps_));
|
setVolume(static_cast<int>(initial_volume_ * current_step / steps_));
|
||||||
@@ -447,12 +462,22 @@ void Credits::updateBlackRects()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza el rectangulo rojo
|
||||||
|
void Credits::updateRedRect()
|
||||||
|
{
|
||||||
|
red_rect.x = left_black_rect_.x + left_black_rect_.w;
|
||||||
|
red_rect.y = top_black_rect_.y + top_black_rect_.h - 1;
|
||||||
|
red_rect.w = right_black_rect_.x - red_rect.x;
|
||||||
|
red_rect.h = bottom_black_rect_.y - red_rect.y + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Actualiza el estado de fade
|
// Actualiza el estado de fade
|
||||||
void Credits::updateAllFades()
|
void Credits::updateAllFades()
|
||||||
{
|
{
|
||||||
if (fading_)
|
if (fading_)
|
||||||
{
|
{
|
||||||
updateBlackRects();
|
updateBlackRects();
|
||||||
|
updateRedRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
fade_in_->update();
|
fade_in_->update();
|
||||||
@@ -483,4 +508,42 @@ void Credits::resetVolume()
|
|||||||
{
|
{
|
||||||
options.audio.music.volume = initial_volume_;
|
options.audio.music.volume = initial_volume_;
|
||||||
JA_SetMusicVolume(to_JA_volume(options.audio.music.volume));
|
JA_SetMusicVolume(to_JA_volume(options.audio.music.volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cambia el color del fondo
|
||||||
|
void Credits::cycleColors()
|
||||||
|
{
|
||||||
|
constexpr int UPPER_LIMIT = 255; // Límite superior
|
||||||
|
constexpr int LOWER_LIMIT = 80; // Límite inferior
|
||||||
|
|
||||||
|
static float r = static_cast<float>(UPPER_LIMIT);
|
||||||
|
static float g = static_cast<float>(LOWER_LIMIT);
|
||||||
|
static float b = static_cast<float>(LOWER_LIMIT);
|
||||||
|
static float stepR = -0.5f; // Paso flotante para transiciones suaves
|
||||||
|
static float stepG = 0.3f;
|
||||||
|
static float stepB = 0.7f;
|
||||||
|
|
||||||
|
// Ajustar valores de R
|
||||||
|
r += stepR;
|
||||||
|
if (r >= UPPER_LIMIT || r <= LOWER_LIMIT)
|
||||||
|
{
|
||||||
|
stepR = -stepR; // Cambia de dirección al alcanzar los límites
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajustar valores de G
|
||||||
|
g += stepG;
|
||||||
|
if (g >= UPPER_LIMIT || g <= LOWER_LIMIT)
|
||||||
|
{
|
||||||
|
stepG = -stepG; // Cambia de dirección al alcanzar los límites
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajustar valores de B
|
||||||
|
b += stepB;
|
||||||
|
if (b >= UPPER_LIMIT || b <= LOWER_LIMIT)
|
||||||
|
{
|
||||||
|
stepB = -stepB; // Cambia de dirección al alcanzar los límites
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar el color, redondeando a enteros antes de usar
|
||||||
|
tiled_bg_->setColor(Color(static_cast<int>(r), static_cast<int>(g), static_cast<int>(b)));
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ private:
|
|||||||
SDL_Rect bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; // Rectangulo negro inferior
|
SDL_Rect bottom_black_rect_ = {play_area_.x, param.game.game_area.rect.h - black_bars_size_, play_area_.w, black_bars_size_}; // Rectangulo negro inferior
|
||||||
SDL_Rect left_black_rect_ = {play_area_.x, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la izquierda
|
SDL_Rect left_black_rect_ = {play_area_.x, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la izquierda
|
||||||
SDL_Rect right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha
|
SDL_Rect right_black_rect_ = {play_area_.x + play_area_.w, param.game.game_area.center_y - 1, 0, 2}; // Rectangulo negro situado a la derecha
|
||||||
|
SDL_Rect red_rect = play_area_; // Rectangulo rojo para delimitar la ventana
|
||||||
|
|
||||||
// Actualiza las variables
|
// Actualiza las variables
|
||||||
void update();
|
void update();
|
||||||
@@ -85,6 +86,9 @@ private:
|
|||||||
// Actualiza los rectangulos negros
|
// Actualiza los rectangulos negros
|
||||||
void updateBlackRects();
|
void updateBlackRects();
|
||||||
|
|
||||||
|
// Actualiza el rectangulo rojo
|
||||||
|
void updateRedRect();
|
||||||
|
|
||||||
// Actualiza el estado de fade
|
// Actualiza el estado de fade
|
||||||
void updateAllFades();
|
void updateAllFades();
|
||||||
|
|
||||||
@@ -94,6 +98,9 @@ private:
|
|||||||
// Reestablece el nivel de volumen
|
// Reestablece el nivel de volumen
|
||||||
void resetVolume();
|
void resetVolume();
|
||||||
|
|
||||||
|
// Cambia el color del fondo
|
||||||
|
void cycleColors();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
Credits();
|
Credits();
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ Director::Director(int argc, const char *argv[])
|
|||||||
section::name = section::Name::GAME;
|
section::name = section::Name::GAME;
|
||||||
section::options = section::Options::GAME_PLAY_1P;
|
section::options = section::Options::GAME_PLAY_1P;
|
||||||
#elif DEBUG
|
#elif DEBUG
|
||||||
section::name = section::Name::LOGO;
|
section::name = section::Name::CREDITS;
|
||||||
#else // NORMAL GAME
|
#else // NORMAL GAME
|
||||||
section::name = section::Name::LOGO;
|
section::name = section::Name::LOGO;
|
||||||
section::options = section::Options::NONE;
|
section::options = section::Options::NONE;
|
||||||
|
|||||||
@@ -346,8 +346,8 @@ void Game::updateGameStateGameOver()
|
|||||||
{
|
{
|
||||||
// La partida ha terminado con la derrota de los jugadores
|
// La partida ha terminado con la derrota de los jugadores
|
||||||
section::name = section::Name::HI_SCORE_TABLE;
|
section::name = section::Name::HI_SCORE_TABLE;
|
||||||
section::options = section::Options::HI_SCORE_AFTER_GAME_OVER;
|
|
||||||
}
|
}
|
||||||
|
section::options = section::Options::HI_SCORE_AFTER_PLAYING;
|
||||||
if (options.audio.enabled)
|
if (options.audio.enabled)
|
||||||
{
|
{
|
||||||
JA_StopChannel(-1);
|
JA_StopChannel(-1);
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ void HiScoreTable::updateFade()
|
|||||||
|
|
||||||
if (fade_->hasEnded() && fade_mode_ == FadeMode::OUT)
|
if (fade_->hasEnded() && fade_mode_ == FadeMode::OUT)
|
||||||
{
|
{
|
||||||
section::name = (section::options == section::Options::HI_SCORE_AFTER_GAME_OVER)
|
section::name = (section::options == section::Options::HI_SCORE_AFTER_PLAYING)
|
||||||
? section::Name::TITLE
|
? section::Name::TITLE
|
||||||
: section::Name::INSTRUCTIONS;
|
: section::Name::INSTRUCTIONS;
|
||||||
section::options = section::Options::NONE;
|
section::options = section::Options::NONE;
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ void Intro::initSprites()
|
|||||||
const int X_DEST = param.game.game_area.center_x - SPRITE_WIDTH / 2;
|
const int X_DEST = param.game.game_area.center_x - SPRITE_WIDTH / 2;
|
||||||
const int Y_DEST = param.game.game_area.first_quarter_y - (SPRITE_HEIGHT / 4);
|
const int Y_DEST = param.game.game_area.first_quarter_y - (SPRITE_HEIGHT / 4);
|
||||||
|
|
||||||
// Inicializa los sprites de la intro
|
// Inicializa los sprites con las imagenes
|
||||||
constexpr int TOTAL_SPRITES = 6;
|
constexpr int TOTAL_SPRITES = 6;
|
||||||
for (int i = 0; i < TOTAL_SPRITES; ++i)
|
for (int i = 0; i < TOTAL_SPRITES; ++i)
|
||||||
{
|
{
|
||||||
@@ -339,7 +339,7 @@ void Intro::initSprites()
|
|||||||
const int S_X_DEST = X_DEST - BORDER / 2;
|
const int S_X_DEST = X_DEST - BORDER / 2;
|
||||||
const int S_Y_DEST = Y_DEST - BORDER / 2;
|
const int S_Y_DEST = Y_DEST - BORDER / 2;
|
||||||
|
|
||||||
// Crea las texturas para las sombras
|
// Crea las texturas para las imágenes traseras
|
||||||
std::vector<std::shared_ptr<Texture>> shadow_textures;
|
std::vector<std::shared_ptr<Texture>> shadow_textures;
|
||||||
|
|
||||||
for (int i = 0; i < TOTAL_SPRITES; ++i)
|
for (int i = 0; i < TOTAL_SPRITES; ++i)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include "jail_shader.h"
|
#include "jail_shader.h"
|
||||||
#include <SDL2/SDL_rect.h> // para SDL_Point
|
#include <SDL2/SDL.h> // para SDL_Point
|
||||||
#include <stdlib.h> // para NULL, free, malloc, exit
|
#include <cstdlib> // para NULL, free, malloc, exit
|
||||||
#include <string.h> // para strncmp
|
#include <cstring> // para strncmp
|
||||||
#include <iostream> // para basic_ostream, char_traits, operator<<
|
#include <iostream> // para std::cout, std::endl
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
@@ -10,12 +10,13 @@
|
|||||||
|
|
||||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#include <OpenGL/gl3.h>
|
#include <OpenGL/gl3.h>
|
||||||
#else
|
#else // NO ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#endif //! ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
#endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#else
|
|
||||||
|
#else // SI NO ES __APPLE__
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
#endif
|
#endif // __APPLE__
|
||||||
|
|
||||||
namespace shader
|
namespace shader
|
||||||
{
|
{
|
||||||
@@ -25,12 +26,10 @@ namespace shader
|
|||||||
SDL_Texture *backBuffer = nullptr;
|
SDL_Texture *backBuffer = nullptr;
|
||||||
SDL_Point win_size = {320 * 4, 256 * 4};
|
SDL_Point win_size = {320 * 4, 256 * 4};
|
||||||
SDL_Point tex_size = {320, 256};
|
SDL_Point tex_size = {320, 256};
|
||||||
bool usingOpenGL;
|
bool usingOpenGL = false;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
|
// Declaración de funciones de extensión de OpenGL (evitando GLEW)
|
||||||
// I'm avoiding the use of GLEW or some extensions handler, but that
|
|
||||||
// doesn't mean you should...
|
|
||||||
PFNGLCREATESHADERPROC glCreateShader;
|
PFNGLCREATESHADERPROC glCreateShader;
|
||||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||||
@@ -66,120 +65,125 @@ namespace shader
|
|||||||
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
|
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
|
||||||
glUseProgram;
|
glUseProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GLuint compileShader(const char *source, GLuint shaderType)
|
// Función para compilar un shader a partir de un std::string
|
||||||
|
GLuint compileShader(const std::string &source, GLuint shaderType)
|
||||||
{
|
{
|
||||||
// Create ID for shader
|
if (source.empty())
|
||||||
GLuint result = glCreateShader(shaderType);
|
|
||||||
// Add define depending on shader type
|
|
||||||
const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source};
|
|
||||||
// Define shader text
|
|
||||||
glShaderSource(result, 2, sources, NULL);
|
|
||||||
// Compile shader
|
|
||||||
glCompileShader(result);
|
|
||||||
|
|
||||||
// Check vertex shader for errors
|
|
||||||
GLint shaderCompiled = GL_FALSE;
|
|
||||||
glGetShaderiv(result, GL_COMPILE_STATUS, &shaderCompiled);
|
|
||||||
if (shaderCompiled != GL_TRUE)
|
|
||||||
{
|
{
|
||||||
std::cout << "Error en la compilación: " << result << "!" << std::endl;
|
throw std::runtime_error("ERROR FATAL: El código fuente del shader está vacío.");
|
||||||
GLint logLength;
|
|
||||||
glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength);
|
|
||||||
if (logLength > 0)
|
|
||||||
{
|
|
||||||
GLchar *log = (GLchar *)malloc(logLength);
|
|
||||||
glGetShaderInfoLog(result, logLength, &logLength, log);
|
|
||||||
std::cout << "Shader compile log:" << log << std::endl;
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
glDeleteShader(result);
|
|
||||||
result = 0;
|
|
||||||
// } else {
|
|
||||||
// std::cout << "Shader compilado correctamente. Id = " << result << std::endl;
|
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
// Crear identificador del shader
|
||||||
|
GLuint resultado = glCreateShader(shaderType);
|
||||||
|
|
||||||
|
// Agregar una directiva según el tipo de shader
|
||||||
|
std::string directiva = (shaderType == GL_VERTEX_SHADER)
|
||||||
|
? "#define VERTEX\n"
|
||||||
|
: "#define FRAGMENT\n";
|
||||||
|
|
||||||
|
const char *sources[2] = {directiva.c_str(), source.c_str()};
|
||||||
|
|
||||||
|
// Especificar el código fuente del shader
|
||||||
|
glShaderSource(resultado, 2, sources, nullptr);
|
||||||
|
|
||||||
|
// Compilar el shader
|
||||||
|
glCompileShader(resultado);
|
||||||
|
|
||||||
|
// Verificar si la compilación fue exitosa
|
||||||
|
GLint compiladoCorrectamente = GL_FALSE;
|
||||||
|
glGetShaderiv(resultado, GL_COMPILE_STATUS, &compiladoCorrectamente);
|
||||||
|
if (compiladoCorrectamente != GL_TRUE)
|
||||||
|
{
|
||||||
|
std::cout << "Error en la compilación del shader (" << resultado << ")!" << std::endl;
|
||||||
|
GLint longitudLog;
|
||||||
|
glGetShaderiv(resultado, GL_INFO_LOG_LENGTH, &longitudLog);
|
||||||
|
if (longitudLog > 0)
|
||||||
|
{
|
||||||
|
std::vector<GLchar> log(longitudLog);
|
||||||
|
glGetShaderInfoLog(resultado, longitudLog, &longitudLog, log.data());
|
||||||
|
std::cout << "Registro de compilación del shader: " << log.data() << std::endl;
|
||||||
|
}
|
||||||
|
glDeleteShader(resultado);
|
||||||
|
resultado = 0;
|
||||||
|
}
|
||||||
|
return resultado;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource)
|
// Función para compilar un programa de shaders (vertex y fragment) a partir de std::string
|
||||||
|
GLuint compileProgram(const std::string &vertexShaderSource, const std::string &fragmentShaderSource)
|
||||||
{
|
{
|
||||||
GLuint programId = 0;
|
GLuint idPrograma = glCreateProgram();
|
||||||
GLuint vtxShaderId, fragShaderId;
|
|
||||||
|
|
||||||
programId = glCreateProgram();
|
// Si el fragment shader está vacío, reutilizamos el código del vertex shader
|
||||||
|
GLuint idShaderVertice = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||||
|
GLuint idShaderFragmento = compileShader(fragmentShaderSource.empty() ? vertexShaderSource : fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
if (idShaderVertice && idShaderFragmento)
|
||||||
fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
if (vtxShaderId && fragShaderId)
|
|
||||||
{
|
{
|
||||||
// Associate shader with program
|
// Asociar los shaders al programa
|
||||||
glAttachShader(programId, vtxShaderId);
|
glAttachShader(idPrograma, idShaderVertice);
|
||||||
glAttachShader(programId, fragShaderId);
|
glAttachShader(idPrograma, idShaderFragmento);
|
||||||
glLinkProgram(programId);
|
glLinkProgram(idPrograma);
|
||||||
glValidateProgram(programId);
|
glValidateProgram(idPrograma);
|
||||||
|
|
||||||
// Check the status of the compile/link
|
// Verificar el estado del enlace
|
||||||
GLint logLen;
|
GLint longitudLog;
|
||||||
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
|
glGetProgramiv(idPrograma, GL_INFO_LOG_LENGTH, &longitudLog);
|
||||||
if (logLen > 0)
|
if (longitudLog > 0)
|
||||||
{
|
{
|
||||||
char *log = (char *)malloc(logLen * sizeof(char));
|
std::vector<char> log(longitudLog);
|
||||||
// Show any errors as appropriate
|
glGetProgramInfoLog(idPrograma, longitudLog, &longitudLog, log.data());
|
||||||
glGetProgramInfoLog(programId, logLen, &logLen, log);
|
std::cout << "Registro de información del programa:" << std::endl
|
||||||
std::cout << "Prog Info Log: " << std::endl
|
<< log.data() << std::endl;
|
||||||
<< log << std::endl;
|
|
||||||
free(log);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (vtxShaderId)
|
if (idShaderVertice)
|
||||||
{
|
{
|
||||||
glDeleteShader(vtxShaderId);
|
glDeleteShader(idShaderVertice);
|
||||||
}
|
}
|
||||||
if (fragShaderId)
|
if (idShaderFragmento)
|
||||||
{
|
{
|
||||||
glDeleteShader(fragShaderId);
|
glDeleteShader(idShaderFragmento);
|
||||||
}
|
}
|
||||||
return programId;
|
return idPrograma;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool init(SDL_Window *win, SDL_Texture *backBuffer, const char *vertexShader, const char *fragmentShader)
|
bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader)
|
||||||
{
|
{
|
||||||
shader::win = win;
|
shader::win = ventana;
|
||||||
shader::renderer = SDL_GetRenderer(win);
|
shader::renderer = SDL_GetRenderer(ventana);
|
||||||
shader::backBuffer = backBuffer;
|
shader::backBuffer = texturaBackBuffer;
|
||||||
SDL_GetWindowSize(win, &win_size.x, &win_size.y);
|
SDL_GetWindowSize(ventana, &win_size.x, &win_size.y);
|
||||||
int access;
|
|
||||||
SDL_QueryTexture(backBuffer, NULL, &access, &tex_size.x, &tex_size.y);
|
int acceso;
|
||||||
if (access != SDL_TEXTUREACCESS_TARGET)
|
SDL_QueryTexture(texturaBackBuffer, nullptr, &acceso, &tex_size.x, &tex_size.y);
|
||||||
|
if (acceso != SDL_TEXTUREACCESS_TARGET)
|
||||||
{
|
{
|
||||||
std::cout << "ERROR FATAL: La textura per al render ha de tindre SDL_TEXTUREACCESS_TARGET definit." << std::endl;
|
throw std::runtime_error("ERROR FATAL: La textura debe tener definido SDL_TEXTUREACCESS_TARGET.");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RendererInfo rendererInfo;
|
SDL_RendererInfo infoRenderer;
|
||||||
SDL_GetRendererInfo(renderer, &rendererInfo);
|
SDL_GetRendererInfo(renderer, &infoRenderer);
|
||||||
|
|
||||||
if (!strncmp(rendererInfo.name, "opengl", 6))
|
// Verificar que el renderer sea OpenGL
|
||||||
|
if (!strncmp(infoRenderer.name, "opengl", 6))
|
||||||
{
|
{
|
||||||
// std::cout << "Es OpenGL!" << std::endl;
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
if (!initGLExtensions())
|
if (!initGLExtensions())
|
||||||
{
|
{
|
||||||
std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl;
|
std::cout << "ADVERTENCIA: No se han podido inicializar las extensiones de OpenGL." << std::endl;
|
||||||
usingOpenGL = false;
|
usingOpenGL = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Compilar el shader y dejarlo listo para usar.
|
// Compilar el programa de shaders utilizando std::string
|
||||||
programId = compileProgram(vertexShader, fragmentShader);
|
programId = compileProgram(vertexShader, fragmentShader);
|
||||||
// std::cout << "programId = " << programId << std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl;
|
std::cout << "ADVERTENCIA: El driver del renderer no es OpenGL." << std::endl;
|
||||||
usingOpenGL = false;
|
usingOpenGL = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -190,48 +194,90 @@ namespace shader
|
|||||||
void render()
|
void render()
|
||||||
{
|
{
|
||||||
GLint oldProgramId;
|
GLint oldProgramId;
|
||||||
// Guarrada para obtener el textureid (en driverdata->texture)
|
// Establece el color de fondo
|
||||||
// Detach the texture
|
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
SDL_SetRenderTarget(renderer, nullptr);
|
||||||
SDL_SetRenderTarget(renderer, NULL);
|
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
|
|
||||||
if (usingOpenGL)
|
if (usingOpenGL)
|
||||||
{
|
{
|
||||||
SDL_GL_BindTexture(backBuffer, NULL, NULL);
|
SDL_GL_BindTexture(backBuffer, nullptr, nullptr);
|
||||||
if (programId != 0)
|
if (programId != 0)
|
||||||
{
|
{
|
||||||
glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgramId);
|
glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgramId);
|
||||||
glUseProgram(programId);
|
glUseProgram(programId);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLfloat minx, miny, maxx, maxy;
|
// Recupera el tamaño lógico configurado con SDL_RenderSetLogicalSize
|
||||||
GLfloat minu, maxu, minv, maxv;
|
int logicalW, logicalH;
|
||||||
|
SDL_RenderGetLogicalSize(renderer, &logicalW, &logicalH);
|
||||||
|
if (logicalW == 0 || logicalH == 0)
|
||||||
|
{
|
||||||
|
logicalW = win_size.x;
|
||||||
|
logicalH = win_size.y;
|
||||||
|
}
|
||||||
|
|
||||||
// Coordenadas de la ventana donde pintar.
|
// Cálculo del viewport
|
||||||
minx = 0.0f;
|
int viewportX = 0, viewportY = 0, viewportW = win_size.x, viewportH = win_size.y;
|
||||||
miny = 0.0f;
|
SDL_bool useIntegerScale = SDL_RenderGetIntegerScale(renderer);
|
||||||
maxx = tex_size.x;
|
if (useIntegerScale)
|
||||||
maxy = tex_size.y;
|
{
|
||||||
|
// Calcula el factor de escalado entero máximo que se puede aplicar
|
||||||
|
int scaleX = win_size.x / logicalW;
|
||||||
|
int scaleY = win_size.y / logicalH;
|
||||||
|
int scale = (scaleX < scaleY ? scaleX : scaleY);
|
||||||
|
if (scale < 1)
|
||||||
|
scale = 1;
|
||||||
|
viewportW = logicalW * scale;
|
||||||
|
viewportH = logicalH * scale;
|
||||||
|
viewportX = (win_size.x - viewportW) / 2;
|
||||||
|
viewportY = (win_size.y - viewportH) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Letterboxing: preserva la relación de aspecto usando una escala flotante
|
||||||
|
float windowAspect = static_cast<float>(win_size.x) / win_size.y;
|
||||||
|
float logicalAspect = static_cast<float>(logicalW) / logicalH;
|
||||||
|
if (windowAspect > logicalAspect)
|
||||||
|
{
|
||||||
|
viewportW = static_cast<int>(logicalAspect * win_size.y);
|
||||||
|
viewportX = (win_size.x - viewportW) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
viewportH = static_cast<int>(win_size.x / logicalAspect);
|
||||||
|
viewportY = (win_size.y - viewportH) / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glViewport(viewportX, viewportY, viewportW, viewportH);
|
||||||
|
|
||||||
minu = 0.0f;
|
// Configurar la proyección ortográfica usando el espacio lógico
|
||||||
maxu = 1.0f;
|
glMatrixMode(GL_PROJECTION);
|
||||||
minv = 0.0f;
|
glLoadIdentity();
|
||||||
maxv = 1.0f;
|
|
||||||
|
|
||||||
glViewport(0, 0, win_size.x, win_size.y);
|
// Queremos que el origen esté en la esquina superior izquierda del espacio lógico.
|
||||||
|
glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
// Dibuja el quad con las coordenadas ajustadas.
|
||||||
|
// Se asignan las coordenadas de textura "normales" para que no quede espejado horizontalmente,
|
||||||
|
// y se mantiene el flip vertical para que la imagen no aparezca volteada.
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
glTexCoord2f(minu, minv);
|
// Vértice superior izquierdo
|
||||||
glVertex2f(minx, miny);
|
glTexCoord2f(0.0f, 1.0f);
|
||||||
glTexCoord2f(maxu, minv);
|
glVertex2f(0.0f, 0.0f);
|
||||||
glVertex2f(maxx, miny);
|
// Vértice superior derecho
|
||||||
glTexCoord2f(minu, maxv);
|
glTexCoord2f(1.0f, 1.0f);
|
||||||
glVertex2f(minx, maxy);
|
glVertex2f(static_cast<GLfloat>(logicalW), 0.0f);
|
||||||
glTexCoord2f(maxu, maxv);
|
// Vértice inferior izquierdo
|
||||||
glVertex2f(maxx, maxy);
|
glTexCoord2f(0.0f, 0.0f);
|
||||||
|
glVertex2f(0.0f, static_cast<GLfloat>(logicalH));
|
||||||
|
// Vértice inferior derecho
|
||||||
|
glTexCoord2f(1.0f, 0.0f);
|
||||||
|
glVertex2f(static_cast<GLfloat>(logicalW), static_cast<GLfloat>(logicalH));
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
SDL_GL_SwapWindow(win);
|
SDL_GL_SwapWindow(win);
|
||||||
|
|
||||||
if (programId != 0)
|
if (programId != 0)
|
||||||
@@ -241,7 +287,7 @@ namespace shader
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SDL_RenderCopy(renderer, backBuffer, NULL, NULL);
|
SDL_RenderCopy(renderer, backBuffer, nullptr, nullptr);
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL_render.h> // para SDL_Texture
|
#include <SDL2/SDL_render.h> // para SDL_Texture
|
||||||
#include <SDL2/SDL_video.h> // para SDL_Window
|
#include <SDL2/SDL_video.h> // para SDL_Window
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// TIPS:
|
// TIPS:
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -38,8 +39,7 @@
|
|||||||
|
|
||||||
namespace shader
|
namespace shader
|
||||||
{
|
{
|
||||||
const bool init(SDL_Window *win, SDL_Texture *backBuffer,
|
//const bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const char *vertexShader, const char *fragmentShader = nullptr);
|
||||||
const char *vertexShader, const char *fragmentShader = nullptr);
|
bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader = "");
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
}
|
}
|
||||||
@@ -327,7 +327,7 @@ void Screen::initShaders()
|
|||||||
{
|
{
|
||||||
loadShaders();
|
loadShaders();
|
||||||
}
|
}
|
||||||
shader::init(window_, game_canvas_, shaderSource.c_str());
|
shader::init(window_, game_canvas_, shaderSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el tamaño de la ventana
|
// Calcula el tamaño de la ventana
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace section
|
|||||||
QUIT_WITH_CONTROLLER,
|
QUIT_WITH_CONTROLLER,
|
||||||
QUIT_FROM_EVENT,
|
QUIT_FROM_EVENT,
|
||||||
RELOAD,
|
RELOAD,
|
||||||
HI_SCORE_AFTER_GAME_OVER,
|
HI_SCORE_AFTER_PLAYING,
|
||||||
NONE,
|
NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user