diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 9c4a040..43397cf 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -20,12 +20,12 @@ #define SRV_ADDR "127.0.0.1" #define COUNTDOWN 300 -#define BASE_WIDTH 1920 -#define BASE_HEIGHT 1080 +#define BASE_WIDTH 1600 +#define BASE_HEIGHT 900 -#define TEXTURE_PATH "./media/textures/" -#define SHADER_PATH "./media/shaders/" -#define AUDIO_PATH "./media/audio/" -#define CHUNK_PATH "./media/chunks/" +#define TEXTURE_PATH "./media/textures/" +#define SHADER_PATH "./media/shaders/" +#define AUDIO_PATH "./media/audio/" +#define CHUNK_PATH "./media/chunks/" #endif // DEFINE_H__ diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index f44eb96..64c9a06 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -96,6 +96,7 @@ void Engine::LoadResource() { LoadTexture(m_textureCrosshair, TEXTURE_PATH "cross.bmp", true); LoadTexture(m_textureFont, TEXTURE_PATH "font.bmp", true); LoadTexture(m_textureGun, TEXTURE_PATH "gun01.png", false); + LoadTexture(m_texturePovGun, TEXTURE_PATH "GUN.png", false); TextureAtlas::TextureIndex texDirtIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal3.png"); TextureAtlas::TextureIndex texIceIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal2.png"); @@ -163,16 +164,17 @@ void Engine::DisplayNotification(std::string message) { // Add a method to process the notification queue void Engine::ProcessNotificationQueue() { m_textureFont.Bind(); - float scale = GetScale(); - unsigned int xOffset = Width() - Width() * 0.26; - unsigned int yOffset = Height() - (Height() / 2.2); - // Iterate through the notifications and display them + auto [scaleX, scaleY] = GetScale(); + + unsigned int xOffset = static_cast((BASE_WIDTH - BASE_WIDTH * 0.26f) * scaleX); + unsigned int yOffset = static_cast((BASE_HEIGHT - (BASE_HEIGHT / 2.2f)) * scaleY); + for (auto it = notifications.begin(); it != notifications.end(); ) { float timeSinceDisplay = m_time - it->displayStartTime; - // Display the notification message with vertical offset - unsigned int y = yOffset - (static_cast(scale * 20) * (it - notifications.begin())); + unsigned int y = yOffset - static_cast(20.0f * scaleX * (it - notifications.begin())); + glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); @@ -187,10 +189,8 @@ void Engine::ProcessNotificationQueue() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); - - - - PrintText(xOffset, y, scale, it->message); + + PrintText(xOffset, y, it->message); glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); glBlendEquation(GL_FUNC_SUBTRACT); @@ -200,22 +200,19 @@ void Engine::ProcessNotificationQueue() { glMatrixMode(GL_PROJECTION); glPopMatrix(); - glMatrixMode(GL_MODELVIEW); glPopMatrix(); - // Check if it's time to remove the notification (display for 2 seconds) + if (timeSinceDisplay >= 4.0f) { - it = notifications.erase(it); // Remove the notification + it = notifications.erase(it); } else { ++it; } } - } - void Engine::DisplayCrosshair() { m_textureCrosshair.Bind(); static const int crossSize = 32; @@ -233,6 +230,60 @@ void Engine::DisplayCrosshair() { glEnd(); } +void Engine::DisplayPovGun() { + // Setter le blend function, tout ce qui sera noir sera transparent + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + glOrtho(0, Width(), 0, Height(), -1, 1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + float scaleX = static_cast(Width()) / BASE_WIDTH; + float scaleY = static_cast(Height()) / BASE_HEIGHT; + float baseXOffset = 0.4958 * BASE_WIDTH; + float baseWidth = 0.4688 * BASE_WIDTH; + float baseHeight = 0.5787 * BASE_HEIGHT; + float xTranslation = baseXOffset * scaleX; + float quadWidth = baseWidth * scaleX; + float quadHeight = baseHeight * scaleY; + + m_texturePovGun.Bind(); + glLoadIdentity(); + glTranslated(xTranslation, 0, 0); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2i(0, 0); + glTexCoord2f(1, 0); + glVertex2i(quadWidth, 0); + glTexCoord2f(1, 1); + glVertex2i(quadWidth, quadHeight); + glTexCoord2f(0, 1); + glVertex2i(0, quadHeight); + glEnd(); + + // Reset du blend function + glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); + glBlendEquation(GL_FUNC_SUBTRACT); + + glEnable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + void Engine::DisplayCurrentItem() { } @@ -240,54 +291,69 @@ void Engine::DisplayHud(int timer) { glBindTexture(GL_TEXTURE_2D, 0); glLoadIdentity(); glDisable(GL_BLEND); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + auto [scaleX, scaleY] = GetScale(); + + // Create a low opacity white background with border radius + float fBackPosX = (Width() / 25.0f) * scaleX; + float fBackPosY = (Height() - (Height() * 0.815) * scaleY); + float fBackWidth = (Width() / 4.0f) * scaleX; + float fBackHeight = (Height() / 5.5f) * scaleY; + + glColor4f(1.0f, 1.0f, 1.0f, 0.2f); + glBegin(GL_QUADS); + glVertex2f(fBackPosX, fBackPosY); + glVertex2f(fBackPosX + fBackWidth, fBackPosY); + glVertex2f(fBackPosX + fBackWidth, fBackPosY + fBackHeight); + glVertex2f(fBackPosX, fBackPosY + fBackHeight); + glEnd(); + + + // HP Bar + float fBarWidth = (Width() / 4.0f) * scaleX; + float fBarHeight = (Height() / 25.0f) * scaleY; + float fPosX = (Width() / 25.0f) * scaleX; + float fBarPosY = (Height() - (Height() * 0.775) * scaleY); - // Barre HP - float fBarWidth = Width() / 4; - float fBarHeight = Height() / 25; - float fPosX = Width() / 20; - float fPosY = Height() - (Height() - (fBarHeight * 4)); float playerHp = m_player.GetHP(); float facteurOmbrage = m_displayInfo ? 0.5f : 1.0f; - // Arrière-plan (Barre HP) + // HP Bar Background glColor3f(1.0f * facteurOmbrage, 1.0f * facteurOmbrage, 1.0f * facteurOmbrage); glBegin(GL_QUADS); - glVertex2f(fPosX, fPosY - fBarHeight); // Bas-Gauche - glVertex2f(fPosX + fBarWidth, fPosY - fBarHeight); // Bas-Droite - glVertex2f(fPosX + fBarWidth, fPosY); // Haut-Droite - glVertex2f(fPosX, fPosY); // Haut-Gauche + glVertex2f(fPosX, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth, fBarPosY); + glVertex2f(fPosX, fBarPosY); glEnd(); - //TODO: Associer avec méchanique de vie du joueur - - // Barre HP + // Current HP glColor3f(0.0f * facteurOmbrage, 1.0f * facteurOmbrage, 0.0f * facteurOmbrage); glBegin(GL_QUADS); - glVertex2f(fPosX, fPosY - fBarHeight); // Bas-Gauche - glVertex2f(fPosX + fBarWidth * playerHp, fPosY - fBarHeight); // Bas-Droite - glVertex2f(fPosX + fBarWidth * playerHp, fPosY); // Haut-Droite - glVertex2f(fPosX, fPosY); // Haut-Gauche + glVertex2f(fPosX, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth * playerHp, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth * playerHp, fBarPosY); + glVertex2f(fPosX, fBarPosY); glEnd(); - // Barre équip + // Equip Bar glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor3f(1.0f * facteurOmbrage, 1.0f * facteurOmbrage, 1.0f * facteurOmbrage); + + float fEquipWidth = (Width() * 0.175f) * scaleX; + float fEquipHeight = (fEquipWidth / 2.5) * scaleY; + float fEquipPosY = (Height() - (Height() * 0.765) * scaleY); + + glTranslatef(fPosX, fEquipPosY, 0); + m_textureGun.Bind(); - - float margin = Width() * 0.05; - float itemWidth = Width() * 0.33; - float itemHeight = itemWidth / 2.208; - float startX = Width() - itemWidth - margin; - float startY = margin; - - glTranslated(startX, startY, 0); - glBegin(GL_QUADS); - glTexCoord2f(1, 0); glVertex2i(0, 0); - glTexCoord2f(0, 0); glVertex2i(itemWidth, 0); - glTexCoord2f(0, 1); glVertex2i(itemWidth, itemHeight); - glTexCoord2f(1, 1); glVertex2i(0, itemHeight); + glTexCoord2f(0, 0); glVertex2i(0, 0); + glTexCoord2f(1, 0); glVertex2i(fEquipWidth, 0); + glTexCoord2f(1, 1); glVertex2i(fEquipWidth, fEquipHeight); + glTexCoord2f(0, 1); glVertex2i(0, fEquipHeight); glEnd(); glDisable(GL_BLEND); @@ -295,54 +361,74 @@ void Engine::DisplayHud(int timer) { // Username glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor3f(1.0f, 1.0f, 1.0f); - float scale = GetScale(); + m_textureFont.Bind(); std::ostringstream ss; + float fUsernamePosY = fBarPosY - (fBarHeight * 2); ss << m_player.GetUsername(); - PrintText(fPosX, fPosY, scale, ss.str()); + PrintText(fPosX, fUsernamePosY, ss.str(), 1.5f); + ss.str(""); - //Countdown + ss << m_player.GetHP() * 100 << "%"; + PrintText(fPosX * 6.25, fUsernamePosY, ss.str(), 1.5f); + + // Countdown ss.str(""); ss << "Time: " << (int)(timer / 60) << ":" << std::setw(2) << std::setfill('0') << timer % 60; - PrintText(Width() - Width() * 0.15, Height() - (Height() / 19.2), scale, ss.str()); - + PrintText(Width() - (Width() * 0.2f) * scaleX, Height() - (Height() * 0.1) * scaleY, ss.str(), 2.0f); } void Engine::DisplayInfo(float elapsedTime, BlockType bloc) { - // Bind de la texture pour le font m_textureFont.Bind(); std::ostringstream ss; - float scale = GetScale(); - unsigned int x = Width() / 25; + auto [scaleX, scaleY] = GetScale(); + float fPosX = (Width() / 100.0f) * scaleX; + float fPosY = Height() - (Height() * 0.05) * scaleY; + float charSize = 20 + (24 - 20) * (Width() - 1600) / (1920 - 1600); + ss << " Fps : " << GetFps(elapsedTime); - PrintText(x, Height() - (Height() / 19.2), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Rendered Chunks : " << m_renderCount; - PrintText(x, Height() - (Height() / 13.7), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " To-Be-Deleted Chunks : " << m_world.GettbDeleted(); - PrintText(x, Height() - (Height() / 10.7), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); - ss << " Velocity : " << m_player.GetVelocity(); // IMPORTANT : on utilise l ’ operateur << pour afficher la position - PrintText(x, Height() / 48, scale, ss.str()); + fPosY -= charSize; + + float fPosYJump = static_cast((Height() - (Height() * 0.9f)) * scaleY); + fPosY = fPosYJump; + fPosY -= charSize; + + ss << " Velocity : " << m_player.GetVelocity(); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Direction : " << m_player.GetDirection(); - PrintText(x, Height() / 24, scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Position : " << m_player.GetPosition(); - PrintText(x, Height() / 16, scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Block : "; - if (bloc == BTYPE_LAST) - ss << "Weapon."; - else ss << (int)bloc; - - PrintText(x, Height() / 12, scale, ss.str()); + ss << "Weapon"; + else + ss << (int)bloc; + PrintText(fPosX, fPosYJump, ss.str()); } void Engine::DrawHud(float elapsedTime, BlockType bloc) { @@ -364,7 +450,6 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { int timer = GetCountdown(elapsedTime); - // Appel de la fonction pour l'affichage de notifications if (m_keyK) { SystemNotification(m_messageNotification); m_keyK = false; @@ -387,7 +472,6 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { DisplayCrosshair(); } - // Reset du blend function glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); glBlendEquation(GL_FUNC_SUBTRACT); @@ -401,31 +485,36 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { glPopMatrix(); } -void Engine::PrintText(float x, float y, float scale, const std::string& t) { +void Engine::PrintText(float x, float y, const std::string& t, float charSizeMultiplier) { + auto [scaleX, scaleY] = GetScale(); + float scale = std::min(scaleX, scaleY); + + float baseCharSize = 20 + (24 - 20) * (Width() - 1600) / (1920 - 1600); + float charSize = baseCharSize * charSizeMultiplier; + glLoadIdentity(); glTranslated(x, y, 0); for (unsigned int i = 0; i < t.length(); ++i) { float left = (float)((t[i] - 32) % 16) / 16.f; float top = (float)((t[i] - 32) / 16) / 16.f; - top += .5f; + top += 0.5f; glBegin(GL_QUADS); - glTexCoord2f(left, 1.f - top - .0625f); glVertex2f(0, 0); - glTexCoord2f(left + .0625f, 1.f - top - .0625f); glVertex2f(12 * scale, 0); - glTexCoord2f(left + .0625f, 1.f - top); glVertex2f(12 * scale, 12 * scale); - glTexCoord2f(left, 1.f - top); glVertex2f(0, 12 * scale); + glTexCoord2f(left, 1.f - top - .0625f); glVertex2f(0, 0); + glTexCoord2f(left + .0625f, 1.f - top - .0625f); glVertex2f(charSize * scale, 0); + glTexCoord2f(left + .0625f, 1.f - top); glVertex2f(charSize * scale, charSize * scale); + glTexCoord2f(left, 1.f - top); glVertex2f(0, charSize * scale); glEnd(); - glTranslated(8 * scale, 0, 0); + glTranslated(0.5555f * charSize * scale, 0, 0); } } -float Engine::GetScale() const { - float widthRatio = Width() / BASE_WIDTH; - float heightRatio = Height() / BASE_HEIGHT; - - return (widthRatio + heightRatio) / 2.0f; +std::pair Engine::GetScale() const { + float widthRatio = static_cast(Width()) / BASE_WIDTH; + float heightRatio = static_cast(Height()) / BASE_HEIGHT; + return { widthRatio, heightRatio }; } int Engine::GetFps(float elapsedTime) const { return 1 / elapsedTime; } @@ -539,6 +628,7 @@ void Engine::Render(float elapsedTime) { ProcessNotificationQueue(); DrawHud(elapsedTime, bloc); + DisplayPovGun(); static bool fell = false; if (m_player.GetPosition().y < 1.7f && !fell) { diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index fa3a088..53ed25e 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -36,7 +36,7 @@ public: virtual void MouseReleaseEvent(const MOUSE_BUTTON &button, int x, int y); private: - float GetScale() const; + std::pair GetScale() const; int GetFps(float elapsedTime) const; int GetCountdown(float elapsedTime); @@ -48,11 +48,12 @@ private: void DisplayNotification(std::string message); void ProcessNotificationQueue(); void DisplayCrosshair(); + void DisplayPovGun(); void DisplayCurrentItem(); void DisplayHud(int timer); void DisplayInfo(float elapsedTime, BlockType bloc); void DrawHud(float elapsedTime, BlockType bloc); - void PrintText(float x, float y, float scale, const std::string& t); + void PrintText(float x, float y, const std::string& t, float charSizeMultiplier = 1.0f); Connector m_conn; Shader m_shader01; @@ -66,6 +67,7 @@ private: Texture m_textureFont; Texture m_textureCrosshair; Texture m_textureGun; + Texture m_texturePovGun; Skybox m_skybox; Audio m_audio = Audio(AUDIO_PATH "start.wav");