Files
korenkonder_ReDIVA/src/CRE/Glitter/glitter.cpp
T

343 lines
8.9 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "glitter.hpp"
#include "../gl_state.hpp"
namespace Glitter {
const float_t min_emission = 0.01f;
const CurveTypeFlags effect_curve_flags = (CurveTypeFlags)(0
| CURVE_TYPE_TRANSLATION_XYZ
| CURVE_TYPE_ROTATION_XYZ
| CURVE_TYPE_SCALE_XYZ
| CURVE_TYPE_SCALE_ALL
| CURVE_TYPE_COLOR_RGBA);
const CurveTypeFlags emitter_curve_flags = (CurveTypeFlags)(0
| CURVE_TYPE_TRANSLATION_XYZ
| CURVE_TYPE_ROTATION_XYZ
| CURVE_TYPE_SCALE_XYZ
| CURVE_TYPE_SCALE_ALL
| CURVE_TYPE_EMISSION_INTERVAL
| CURVE_TYPE_PARTICLES_PER_EMISSION);
const CurveTypeFlags particle_curve_flags = (CurveTypeFlags)(0
| CURVE_TYPE_TRANSLATION_XYZ
| CURVE_TYPE_ROTATION_XYZ
| CURVE_TYPE_SCALE_XYZ
| CURVE_TYPE_SCALE_ALL
| CURVE_TYPE_COLOR_RGBA
| CURVE_TYPE_UV_SCROLL);
const CurveTypeFlags particle_x_curve_flags = (CurveTypeFlags)(0
| CURVE_TYPE_TRANSLATION_XYZ
| CURVE_TYPE_ROTATION_XYZ
| CURVE_TYPE_SCALE_XYZ
| CURVE_TYPE_SCALE_ALL
| CURVE_TYPE_COLOR_RGBA
| CURVE_TYPE_COLOR_RGB_SCALE
| CURVE_TYPE_UV_SCROLL
| CURVE_TYPE_UV_SCROLL_2ND);
const Direction emitter_direction_types[] = {
DIRECTION_BILLBOARD,
DIRECTION_BILLBOARD_Y_AXIS,
DIRECTION_X_AXIS,
DIRECTION_Y_AXIS,
DIRECTION_Z_AXIS,
DIRECTION_EFFECT_ROTATION,
};
const size_t emitter_direction_types_count =
sizeof(emitter_direction_types) / sizeof(Direction);
const Direction emitter_direction_default_direction =
DIRECTION_EFFECT_ROTATION;
const EmitterDirection emitter_direction_default =
EMITTER_DIRECTION_EFFECT_ROTATION;
const Direction particle_draw_types[] = {
DIRECTION_BILLBOARD,
DIRECTION_BILLBOARD_Y_AXIS,
DIRECTION_X_AXIS,
DIRECTION_Y_AXIS,
DIRECTION_Z_AXIS,
DIRECTION_EMITTER_DIRECTION,
DIRECTION_EMITTER_ROTATION,
DIRECTION_PARTICLE_ROTATION,
DIRECTION_PREV_POSITION,
DIRECTION_PREV_POSITION_DUP,
DIRECTION_EMIT_POSITION,
};
const size_t particle_draw_types_count =
sizeof(particle_draw_types) / sizeof(Direction);
const Direction particle_draw_type_default_direction =
DIRECTION_BILLBOARD;
const ParticleDrawType particle_draw_type_default =
PARTICLE_DRAW_TYPE_BILLBOARD;
const ParticleBlend particle_blend_draw_types[] = {
PARTICLE_BLEND_TYPICAL,
PARTICLE_BLEND_ADD,
PARTICLE_BLEND_MULTIPLY,
};
const size_t particle_blend_draw_types_count =
sizeof(particle_blend_draw_types) / sizeof(ParticleBlend);
const ParticleBlend particle_blend_draw_default_blend =
PARTICLE_BLEND_TYPICAL;
const ParticleBlendDraw particle_blend_draw_default =
PARTICLE_BLEND_DRAW_TYPICAL;
const ParticleBlend particle_blend_mask_types[] = {
PARTICLE_BLEND_TYPICAL,
PARTICLE_BLEND_ADD,
PARTICLE_BLEND_MULTIPLY,
};
const size_t particle_blend_mask_types_count =
sizeof(particle_blend_mask_types) / sizeof(ParticleBlend);
const ParticleBlend particle_blend_mask_default_blend =
PARTICLE_BLEND_TYPICAL;
const ParticleBlendMask particle_blend_mask_default =
PARTICLE_BLEND_MASK_TYPICAL;
const Pivot pivot_reverse[] = {
PIVOT_BOTTOM_RIGHT,
PIVOT_BOTTOM_CENTER,
PIVOT_BOTTOM_LEFT,
PIVOT_MIDDLE_RIGHT,
PIVOT_MIDDLE_CENTER,
PIVOT_MIDDLE_LEFT,
PIVOT_TOP_RIGHT,
PIVOT_TOP_CENTER,
PIVOT_TOP_LEFT,
};
const char* effect_ext_anim_index_name[] = {
"P1",
"P2",
"P3",
"P4",
"P5",
"P6",
};
const char* effect_ext_anim_node_index_name[] = {
"None",
"Head",
"Mouth",
"Belly",
"Chest",
"Left Shoulder",
"Left Elbow",
"Left Elbow Dup",
"Left Hand",
"Right Shoulder",
"Right Elbow",
"Right Elbow Dup",
"Right Hand",
"Left Thigh",
"Left Knee",
"Left Toe",
"Right Thigh",
"Right Knee",
"Right Toe",
};
const char* effect_type_name[] = {
"Normal",
"Local",
"Chara Parent",
"Object Parent",
};
const char* emitter_name[] = {
"Box",
"Cylinder",
"Sphere",
"Mesh",
"Polygon",
};
const char* emitter_direction_name[] = {
"Billboard",
"Billboard (Y Axis)",
"X Axis",
"Y Axis",
"Z Axis",
"Effect Rotation",
};
const char* emitter_emission_name[] = {
"On Timer",
"On Start",
"On End",
};
const char* emitter_emission_direction_name[] = {
"None",
"Outward",
"Inward",
};
const char* emitter_timer_name[] = {
"By Time",
"By Distance",
};
const char* key_name[] = {
"Constant",
"Linear",
"Hermite",
};
const char* particle_blend_name[] = {
"Zero",
"Typical",
"Add",
"Subtract",
"Multiply",
"Punch Through",
};
const char* particle_blend_draw_name[] = {
"Typical",
"Add",
"Multiply",
};
const char* particle_blend_mask_name[] = {
"Typical",
"Add",
"Multiply",
};
const char* particle_draw_type_name[] = {
"Billboard",
"Billboard (Y Axis)",
"X Axis",
"Y Axis",
"Z Axis",
"Emitter Direction",
"Emitter Rotation",
"Particle Rotation",
"Prev Position",
"Prev Position Dup",
"Emit Position",
};
const char* particle_name[] = {
"Quad",
"Line",
"Locus",
"Mesh",
};
const char* pivot_name[] = {
"Top Left",
"Top Center",
"Top Right",
"Middle Left",
"Middle Center",
"Middle Right",
"Bottom Left",
"Bottom Center",
"Bottom Right",
};
const char* uv_index_type_name[] = {
"Fixed",
"Initial Random / Fixed",
"Random",
"Forward",
"Reverse",
"Initial Random / Forward",
"Initial Random / Reverse",
"User",
};
void axis_angle_from_vectors(vec3& axis, float_t& angle, const vec3& vec1, const vec3& vec2) {
axis = vec3::cross(vec1, vec2);
angle = vec3::length(axis);
if (angle >= 0.000001f)
angle = asinf(clamp_def(angle, -1.0f, 1.0f));
else {
angle = 0.0f;
axis = vec3::cross(vec3(0.0f, 1.0f, 0.0f), vec1);
if (vec3::length(axis) < 0.000001f)
axis = vec3::cross(vec3(0.0f, 0.0f, 1.0f), vec1);
}
if (vec3::dot(vec1, vec2) < 0.0f)
angle = (float_t)M_PI - angle;
}
#if !SHARED_GLITTER_BUFFER
void CreateBuffer(size_t max_count, bool is_quad,
Buffer*& buffer, GLuint& vao, GL::ArrayBuffer& vbo, GL::ElementArrayBuffer& ebo) {
free_def(buffer);
buffer = force_malloc<Buffer>(max_count);
glGenVertexArrays(1, &vao);
gl_state_bind_vertex_array(vao, true);
static const GLsizei buffer_size = sizeof(Buffer);
vbo.Create(buffer_size * max_count);
vbo.Bind(true);
if (is_quad) {
size_t count = max_count / 4 * 5;
uint32_t* ebo_data = force_malloc<uint32_t>(count);
for (size_t i = 0, j = 0, k = count; k; i += 5, j += 4, k -= 5) {
ebo_data[i + 0] = (uint32_t)(j + 0);
ebo_data[i + 1] = (uint32_t)(j + 1);
ebo_data[i + 2] = (uint32_t)(j + 3);
ebo_data[i + 3] = (uint32_t)(j + 2);
ebo_data[i + 4] = 0xFFFFFFFF;
}
ebo.Create(sizeof(uint32_t) * count, ebo_data);
ebo.Bind(true);
free_def(ebo_data);
}
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size,
(void*)offsetof(Buffer, position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, buffer_size,
(void*)offsetof(Buffer, uv));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, buffer_size,
(void*)offsetof(Buffer, color));
gl_state_bind_array_buffer(0);
gl_state_bind_vertex_array(0);
if (is_quad)
gl_state_bind_element_array_buffer(0);
}
void DeleteBuffer(Buffer*& buffer, GLuint& vao, GL::ArrayBuffer& vbo, GL::ElementArrayBuffer& ebo) {
ebo.Destroy();
vbo.Destroy();
if (vao) {
glDeleteVertexArrays(1, &vao);
vao = 0;
}
free_def(buffer);
}
#endif
}