166 lines
4.5 KiB
C++
166 lines
4.5 KiB
C++
#pragma once
|
|
|
|
uint16_t constexpr const_hash(const char* input)
|
|
{
|
|
return *input ?
|
|
static_cast<uint16_t>(*input) + 33 * const_hash(input + 1) :
|
|
5381;
|
|
}
|
|
|
|
bool point_in_rect(const glm::vec2& point, const glm::vec4& rect);
|
|
glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b);
|
|
glm::vec4 rect_union(glm::vec4 a, glm::vec4 b);
|
|
bool segments_intersect(const glm::vec2& p0a, const glm::vec2& p0b,
|
|
const glm::vec2& p1a, const glm::vec2& p1b, glm::vec2& out_pt);
|
|
glm::vec4 rand_color();
|
|
glm::vec3 convert_hsv2rgb(const glm::vec3 c);
|
|
glm::vec3 convert_rgb2hsv(const glm::vec3 c);
|
|
|
|
void check_OpenGLError(const char* stmt, const char* fname, int line);
|
|
|
|
template<typename T, int N> struct cbuffer
|
|
{
|
|
T m_vec[N];
|
|
int m_capacity;
|
|
int m_count;
|
|
int m_index;
|
|
cbuffer()
|
|
{
|
|
m_capacity = N;
|
|
m_index = 0;
|
|
m_count = 0;
|
|
}
|
|
void clear()
|
|
{
|
|
m_index = 0;
|
|
m_count = 0;
|
|
}
|
|
T& head()
|
|
{
|
|
return m_index == 0 ? m_vec[m_count - 1] : m_vec[m_index - 1];
|
|
}
|
|
void add(const T& v)
|
|
{
|
|
m_vec[m_index] = v;
|
|
m_index = (m_index + 1) % m_capacity;
|
|
m_count = m_count < m_capacity ? m_count + 1 : m_count;
|
|
}
|
|
int count() const
|
|
{
|
|
return m_count;
|
|
}
|
|
template<typename T2 = T> T2 average() const
|
|
{
|
|
T2 tot{};
|
|
if (m_count == 0)
|
|
return tot;
|
|
for (int i = 0; i < m_count; i++)
|
|
tot += m_vec[i];
|
|
return tot / (float)m_count;
|
|
}
|
|
};
|
|
|
|
NS_START
|
|
template<typename T, int Max = 0>
|
|
class BlockingQueue
|
|
{
|
|
std::deque<T> q;
|
|
std::condition_variable post_cv;
|
|
std::condition_variable get_cv;
|
|
mutable std::mutex mutex;
|
|
public:
|
|
volatile bool unlocked = false;
|
|
BlockingQueue() = default;
|
|
BlockingQueue(const BlockingQueue& other) = delete;
|
|
BlockingQueue& operator=(const BlockingQueue& other) = delete;
|
|
BlockingQueue(BlockingQueue&& other) : q(std::move(q)) { }
|
|
BlockingQueue& operator=(BlockingQueue&& other) { q = std::move(q); return *this; }
|
|
void Post(T&& pkt)
|
|
{
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
if (Max > 0)
|
|
{
|
|
post_cv.wait(lock, [&]() { return unlocked | (q.size() < Max); });
|
|
if (q.size() >= Max) return;
|
|
}
|
|
q.push_back(std::forward<T>(pkt));
|
|
get_cv.notify_one();
|
|
}
|
|
T Get()
|
|
{
|
|
static T emptyT{};
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
get_cv.wait(lock, [&]() { return unlocked | (q.size() > 0); });
|
|
if (q.empty())
|
|
return std::move(emptyT);
|
|
T tmp = std::move(q.front());
|
|
q.pop_front();
|
|
if (Max > 0) post_cv.notify_all();
|
|
return std::move(tmp);
|
|
}
|
|
void UnlockGetters()
|
|
{
|
|
unlocked = true;
|
|
get_cv.notify_all();
|
|
if (Max > 0) post_cv.notify_all();
|
|
}
|
|
int Size() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
return (int)q.size();
|
|
}
|
|
};
|
|
|
|
struct gl_state
|
|
{
|
|
GLboolean blend;
|
|
GLboolean depth_test;
|
|
GLboolean scissor_test;
|
|
GLint vp[4];
|
|
GLfloat cc[4];
|
|
GLint tex[10];
|
|
GLint cube;
|
|
GLint sampler[10];
|
|
GLint program;
|
|
GLint fb;
|
|
GLint active_tex;
|
|
void save()
|
|
{
|
|
blend = glIsEnabled(GL_BLEND);
|
|
depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
glGetIntegerv(GL_VIEWPORT, vp);
|
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
|
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
|
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb);
|
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
|
|
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &cube);
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + i);
|
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, tex + i);
|
|
glGetIntegerv(GL_SAMPLER_BINDING, sampler + i);
|
|
}
|
|
}
|
|
void restore()
|
|
{
|
|
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
|
depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
|
scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
|
glUseProgram(program);
|
|
for (int i = 0; i < 10; ++i)
|
|
{
|
|
glActiveTexture(GL_TEXTURE0 + i);
|
|
glBindTexture(GL_TEXTURE_2D, tex[i]);
|
|
glBindSampler(i, sampler[i]);
|
|
}
|
|
glActiveTexture(active_tex);
|
|
glBindTexture(GL_TEXTURE_BINDING_CUBE_MAP, cube);
|
|
}
|
|
};
|
|
|
|
NS_END
|