Files
brandling-safari/client/Common.cpp
Gabe 238cd9c6c3 Brandling Safari: LAN safari-zone creature catching on the HD-2D engine
- Authoritative 30 Hz server (ENet, SQLite): accounts, characters, wild AI, tall grass /
  water / wandering spawns, fishing, captures, follower chains, clock + weather, LAN beacon
- Client: title / join / character creator / play screens, prediction + reconciliation,
  interpolated players and parties, HD-2D UI (dialogue with Professor Henry, HUD, collection)
- Shared deterministic zone generator, movement, protocol, roster, appearance
- Paper-doll character art pipeline (PixelLab base walk + per-item animation edits)
- Brandling roster from the company list (logo colors, jev types), Blender safari props
- Headless test bot
2026-10-02 15:20:27 -05:00

49 lines
1.7 KiB
C++

#include "Common.h"
#include <algorithm>
#include <cmath>
#include <vector>
namespace bs {
void UiTexture::upload(const hd2d::Image& img) {
if (id_ && size_ != glm::ivec2(img.width, img.height)) reset();
if (!id_) {
glCreateTextures(GL_TEXTURE_2D, 1, &id_);
glTextureStorage2D(id_, 1, GL_RGBA8, img.width, img.height);
glTextureParameteri(id_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameteri(id_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTextureParameteri(id_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(id_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
size_ = {img.width, img.height};
}
// Upload top row first so ImGui's (0,0) = top-left.
std::vector<unsigned char> flipped(img.rgba.size());
size_t row = size_t(img.width) * 4;
for (int y = 0; y < img.height; ++y)
std::copy_n(img.rgba.data() + size_t(img.height - 1 - y) * row, row, flipped.data() + size_t(y) * row);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTextureSubImage2D(id_, 0, 0, 0, img.width, img.height, GL_RGBA, GL_UNSIGNED_BYTE, flipped.data());
}
void UiTexture::reset() {
if (id_) glDeleteTextures(1, &id_);
id_ = 0;
size_ = {0, 0};
}
void UiTexture::cellUV(glm::ivec2 cell, int col, int row, ImVec2& uv0, ImVec2& uv1) const {
float w = float(std::max(size_.x, 1)), h = float(std::max(size_.y, 1));
uv0 = ImVec2(float(col * cell.x) / w, float(row * cell.y) / h);
uv1 = ImVec2(float((col + 1) * cell.x) / w, float((row + 1) * cell.y) / h);
}
float wrapAngle(float a) {
constexpr float kTwoPi = 6.28318530718f;
a = std::fmod(a + 3.14159265f, kTwoPi);
if (a < 0.0f) a += kTwoPi;
return a - 3.14159265f;
}
} // namespace bs