Compare commits

...

3 Commits

Author SHA1 Message Date
bee3545196 change to permanent visibility of ship labels 2026-02-02 13:48:28 +06:00
e050d7d0ec Improve ship nickname rendering 2026-02-02 04:44:18 +06:00
e18484ea62 add player ID labels for ships 2026-02-01 23:34:21 +06:00
8 changed files with 91 additions and 19 deletions

View File

@ -1,11 +1,14 @@
#version 330 core
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D uText;
uniform vec3 uColor;
uniform vec4 uColor;
uniform vec4 uOutlineColor;
uniform float uOutlineWidth = 0.7;
void main() {
float a = texture(uText, TexCoord).r; // glyph alpha in RED channel
FragColor = vec4(uColor, a);
float dist = texture(uText, TexCoord).r;
float outline = smoothstep(0.5 - uOutlineWidth, 0.5 + uOutlineWidth, dist);
float text = smoothstep(0.5, 0.5 + 0.1, dist);
float glow = exp(-pow(dist - 0.5, 2.0) / 0.02);
FragColor = vec4(uColor.rgb * (text + glow * 0.6), uColor.a * outline);
}

View File

@ -155,7 +155,7 @@ int main() {
try {
net::io_context ioc;
tcp::acceptor acceptor{ ioc, {tcp::v4(), 8080} };
int next_id = 1000;
int next_id = 0;
std::cout << "Server started on port 8080...\n";

View File

@ -656,6 +656,7 @@ namespace ZL
}
drawShip();
drawRemoteShips();
drawRemoteShipsLabels();
drawBoxes();
drawBoxesLabels();
@ -729,6 +730,62 @@ namespace ZL
CheckGlError();
}
void Game::drawRemoteShipsLabels()
{
if (!textRenderer) return;
#ifdef NETWORK
// 2D поверх 3D
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Берем удаленных игроков
latestRemotePlayers = networkClient->getRemotePlayers();
auto now = std::chrono::system_clock::now();
now -= std::chrono::milliseconds(CLIENT_DELAY);
for (auto const& [id, remotePlayer] : latestRemotePlayers)
{
if (!remotePlayer.canFetchClientStateAtTime(now))
continue;
ClientState st = remotePlayer.fetchClientStateAtTime(now);
// Позиция корабля в мире
Vector3f shipWorld = st.position;
float distSq = (Environment::shipState.position - shipWorld).squaredNorm();
/*if (distSq > MAX_DIST_SQ) // дальность прорисовки никнейма
continue;*/
float dist = sqrt(distSq);
float alpha = 1.0f; // постоянная видимость
/*float alpha = std::clamp(1.f - (dist - FADE_START) / FADE_RANGE, 0.f, 1.f); // дальность прорисовки никнейма
if (alpha < 0.01f)
continue; */
Vector3f labelWorld = shipWorld + Vector3f{ 0.f, -4.f, 0.f }; // регулировка высоты
float sx, sy, depth;
if (!worldToScreen(labelWorld, sx, sy, depth))
continue;
float uiX = sx, uiY = sy;
float scale = std::clamp(BASE_SCALE / (dist * PERSPECTIVE_K + 1.f), MIN_SCALE, MAX_SCALE);
// Дефолтный лейбл
std::string label = "Player (" + std::to_string(st.id) + ") " + std::to_string((int)dist) + "m";
// TODO: nickname sync
textRenderer->drawText(label, uiX + 1.f, uiY + 1.f, scale, true, {0.f, 0.f, 0.f, alpha}); // color param
textRenderer->drawText(label, uiX, uiY, scale, true, { 1.f, 1.f, 1.f, alpha });
}
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
#endif
}
void Game::processTickCount() {
if (lastTickCount == 0) {
@ -749,7 +806,7 @@ namespace ZL
size_t delta = newTickCount - lastTickCount;
if (delta > CONST_MAX_TIME_INTERVAL)
{
throw std::runtime_error("Synchronization is lost");
//throw std::runtime_error("Synchronization is lost");
}
auto now_ms = newTickCount;

View File

@ -50,6 +50,7 @@ namespace ZL {
void drawBoxesLabels();
void drawUI();
void drawRemoteShips();
void drawRemoteShipsLabels();
void fireProjectiles();
bool worldToScreen(const Vector3f& world, float& outX, float& outY, float& outDepth) const;
@ -114,6 +115,13 @@ namespace ZL {
uint64_t lastExplosionTime = 0;
const uint64_t explosionDurationMs = 500;
static constexpr float MAX_DIST_SQ = 10000.f * 10000.f;
static constexpr float FADE_START = 6000.f;
static constexpr float FADE_RANGE = 4000.f;
static constexpr float BASE_SCALE = 140.f;
static constexpr float PERSPECTIVE_K = 0.05f; // Tune
static constexpr float MIN_SCALE = 0.4f;
static constexpr float MAX_SCALE = 1.5f;
};

View File

@ -835,6 +835,15 @@ namespace ZL {
}
}
void Renderer::RenderUniform4fv(const std::string& uniformName, const float* value)
{
auto shader = shaderManager.GetCurrentShader();
auto uniform = shader->uniformList.find(uniformName);
if (uniform != shader->uniformList.end()) {
glUniform4fv(uniform->second, 1, value);
}
}
void Renderer::RenderUniform1i(const std::string& uniformName, const int value)
{
auto shader = shaderManager.GetCurrentShader();

View File

@ -138,6 +138,7 @@ namespace ZL {
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
void RenderUniform1i(const std::string& uniformName, const int value);
void RenderUniform3fv(const std::string& uniformName, const float* value);
void RenderUniform4fv(const std::string& uniformName, const float* value);
void RenderUniform1f(const std::string& uniformName, float value);
void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer);

View File

@ -3,8 +3,9 @@
#include FT_FREETYPE_H
#include "Environment.h"
#include "render/OpenGlExtensions.h" // если у тебя там gl* указатели
#include "render/OpenGlExtensions.h"
#include <iostream>
#include <array>
namespace ZL {
@ -25,8 +26,6 @@ bool TextRenderer::init(Renderer& renderer, const std::string& ttfPath, int pixe
{
r = &renderer;
// Добавим шейдер (если у тебя shaderManager работает так же, как с default)
// Подстрой под твой AddShaderFromFiles: тут без zip.
r->shaderManager.AddShaderFromFiles(shaderName,
"resources/shaders/text2d.vertex",
"resources/shaders/text2d.fragment",
@ -109,7 +108,7 @@ bool TextRenderer::loadGlyphs(const std::string& ttfPath, int pixelSize)
return true;
}
void TextRenderer::drawText(const std::string& text, float x, float y, float scale, bool centered)
void TextRenderer::drawText(const std::string& text, float x, float y, float scale, bool centered, std::array<float, 4> color)
{
if (!r) return;
@ -127,8 +126,6 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
r->shaderManager.PushShader(shaderName);
// Орто-проекция в пикселях: (0..W, 0..H)
// ВАЖНО: мы рисуем в координатах Game::drawBoxesLabels() как uiX/uiY
// Здесь предположим, что (0,0) внизу слева.
float W = (float)Environment::width;
float H = (float)Environment::height;
@ -142,9 +139,7 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
r->RenderUniformMatrix4fv("uProjection", false, proj.data());
r->RenderUniform1i("uText", 0);
// белый цвет
float color[3] = {1.0f, 1.0f, 1.0f};
r->RenderUniform3fv("uColor", color);
r->RenderUniform4fv("uColor", color.data());
glActiveTexture(GL_TEXTURE0);
// glBindVertexArray(vao);
@ -184,9 +179,7 @@ void TextRenderer::drawText(const std::string& text, float x, float y, float sca
};
glBindTexture(GL_TEXTURE_2D, g.texID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
glDrawArrays(GL_TRIANGLES, 0, 6);
penX += (g.advance >> 6) * scale;

View File

@ -5,6 +5,7 @@
#include <unordered_map>
#include <Eigen/Dense>
#include "render/Renderer.h"
#include <array>
namespace ZL {
@ -22,7 +23,7 @@ public:
~TextRenderer();
bool init(Renderer& renderer, const std::string& ttfPath, int pixelSize);
void drawText(const std::string& text, float x, float y, float scale, bool centered);
void drawText(const std::string& text, float x, float y, float scale, bool centered, std::array<float, 4> color = { 1.f,1.f,1.f,1.f });
private:
bool loadGlyphs(const std::string& ttfPath, int pixelSize);