mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-10 16:28:21 +03:00
Merge pull request #204 from kichikuou/3d
3d: Various improvements for Rance Quest
This commit is contained in:
+1
-1
@@ -191,7 +191,7 @@ struct RE_instance {
|
||||
bool local_transform_needs_update;
|
||||
mat4 local_transform;
|
||||
mat3 normal_transform;
|
||||
mat4 *bone_transforms; // model->nr_bones elements
|
||||
mat3x4 *bone_transforms; // row-major, model->nr_bones elements
|
||||
GLuint bone_transforms_ubo;
|
||||
vec4 bounding_sphere;
|
||||
struct RE_instance *shadow_volume_instance;
|
||||
|
||||
@@ -91,7 +91,7 @@ uniform int alpha_mode;
|
||||
|
||||
in vec2 tex_coord;
|
||||
in vec2 light_tex_coord;
|
||||
in vec3 color_mod;
|
||||
in vec4 color_mod;
|
||||
in vec3 frag_pos;
|
||||
in vec4 shadow_frag_pos;
|
||||
in float dist;
|
||||
@@ -125,7 +125,7 @@ void main() {
|
||||
if (diffuse_type == DIFFUSE_LIGHT_MAP) {
|
||||
diffuse *= texture(light_texture, light_tex_coord).rgb;
|
||||
}
|
||||
frag_rgb += texel.rgb * diffuse * color_mod;
|
||||
frag_rgb += texel.rgb * diffuse * color_mod.rgb;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ void main() {
|
||||
}
|
||||
|
||||
// Alpha mapping
|
||||
float alpha = texel.a * alpha_mod;
|
||||
float alpha = texel.a * color_mod.a * alpha_mod;
|
||||
if (alpha_mode == ALPHA_TEST) {
|
||||
if (alpha < 0.8)
|
||||
discard;
|
||||
|
||||
+18
-8
@@ -39,6 +39,12 @@ out vec3 specular_dir;
|
||||
out vec3 ls_ex;
|
||||
out vec3 ls_in;
|
||||
|
||||
const vec2 uv_scroll = vec2(0.0);
|
||||
|
||||
#else // ENGINE == REIGN_ENGINE
|
||||
|
||||
uniform vec2 uv_scroll;
|
||||
|
||||
#endif // ENGINE == REIGN_ENGINE
|
||||
|
||||
uniform mat4 local_transform;
|
||||
@@ -49,8 +55,8 @@ uniform mat3 normal_transform;
|
||||
const int MAX_BONES = 308; // see 3d_internal.h
|
||||
const int NR_WEIGHTS = 4;
|
||||
uniform bool has_bones;
|
||||
layout(std140) uniform BoneTransforms {
|
||||
mat4 bone_matrices[MAX_BONES];
|
||||
layout(std140, row_major) uniform BoneTransforms {
|
||||
mat4x3 bone_matrices[MAX_BONES];
|
||||
};
|
||||
|
||||
uniform bool use_normal_map;
|
||||
@@ -62,14 +68,14 @@ in vec3 vertex_pos;
|
||||
in vec3 vertex_normal;
|
||||
in vec2 vertex_uv;
|
||||
in vec2 vertex_light_uv;
|
||||
in vec3 vertex_color;
|
||||
in vec4 vertex_color;
|
||||
in vec4 vertex_tangent;
|
||||
in ivec4 vertex_bone_index;
|
||||
in vec4 vertex_bone_weight;
|
||||
|
||||
out vec2 tex_coord;
|
||||
out vec2 light_tex_coord;
|
||||
out vec3 color_mod;
|
||||
out vec4 color_mod;
|
||||
out vec3 frag_pos;
|
||||
out vec4 shadow_frag_pos;
|
||||
out float dist;
|
||||
@@ -80,13 +86,17 @@ void main() {
|
||||
mat4 local_bone_transform = local_transform;
|
||||
mat3 normal_bone_transform = normal_transform;
|
||||
if (has_bones) {
|
||||
mat4 bone_transform = mat4(0.f);
|
||||
mat4x3 bone_transform = mat4x3(0.0);
|
||||
for (int i = 0; i < NR_WEIGHTS; i++) {
|
||||
if (vertex_bone_index[i] >= 0) {
|
||||
bone_transform += bone_matrices[vertex_bone_index[i]] * vertex_bone_weight[i];
|
||||
}
|
||||
}
|
||||
local_bone_transform *= bone_transform;
|
||||
local_bone_transform *= mat4(
|
||||
vec4(bone_transform[0], 0.0),
|
||||
vec4(bone_transform[1], 0.0),
|
||||
vec4(bone_transform[2], 0.0),
|
||||
vec4(bone_transform[3], 1.0));
|
||||
normal_bone_transform *= mat3(bone_transform);
|
||||
}
|
||||
|
||||
@@ -104,8 +114,8 @@ void main() {
|
||||
vec4 view_pos = view_transform * world_pos;
|
||||
gl_Position = proj_transform * view_pos;
|
||||
|
||||
tex_coord = vertex_uv;
|
||||
light_tex_coord = vertex_light_uv;
|
||||
tex_coord = vertex_uv + uv_scroll;
|
||||
light_tex_coord = vertex_light_uv + uv_scroll;
|
||||
color_mod = vertex_color;
|
||||
dist = -view_pos.z;
|
||||
shadow_frag_pos = shadow_transform * world_pos;
|
||||
|
||||
@@ -22,8 +22,8 @@ uniform mat3 normal_transform;
|
||||
const int MAX_BONES = 308; // see 3d_internal.h
|
||||
const int NR_WEIGHTS = 4;
|
||||
uniform bool has_bones;
|
||||
layout(std140) uniform BoneTransforms {
|
||||
mat4 bone_matrices[MAX_BONES];
|
||||
layout(std140, row_major) uniform BoneTransforms {
|
||||
mat4x3 bone_matrices[MAX_BONES];
|
||||
};
|
||||
uniform float outline_thickness;
|
||||
|
||||
@@ -36,13 +36,17 @@ void main() {
|
||||
mat4 local_bone_transform = local_transform;
|
||||
mat3 normal_bone_transform = normal_transform;
|
||||
if (has_bones) {
|
||||
mat4 bone_transform = mat4(0.f);
|
||||
mat4x3 bone_transform = mat4x3(0.0);
|
||||
for (int i = 0; i < NR_WEIGHTS; i++) {
|
||||
if (vertex_bone_index[i] >= 0) {
|
||||
bone_transform += bone_matrices[vertex_bone_index[i]] * vertex_bone_weight[i];
|
||||
}
|
||||
}
|
||||
local_bone_transform *= bone_transform;
|
||||
local_bone_transform *= mat4(
|
||||
vec4(bone_transform[0], 0.0),
|
||||
vec4(bone_transform[1], 0.0),
|
||||
vec4(bone_transform[2], 0.0),
|
||||
vec4(bone_transform[3], 1.0));
|
||||
normal_bone_transform *= mat3(bone_transform);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ uniform mat4 view_transform;
|
||||
const int MAX_BONES = 308; // see 3d_internal.h
|
||||
const int NR_WEIGHTS = 4;
|
||||
uniform bool has_bones;
|
||||
layout(std140) uniform BoneTransforms {
|
||||
mat4 bone_matrices[MAX_BONES];
|
||||
layout(std140, row_major) uniform BoneTransforms {
|
||||
mat4x3 bone_matrices[MAX_BONES];
|
||||
};
|
||||
|
||||
in vec3 vertex_pos;
|
||||
@@ -31,13 +31,17 @@ in vec4 vertex_bone_weight;
|
||||
void main() {
|
||||
mat4 local_bone_transform = local_transform;
|
||||
if (has_bones) {
|
||||
mat4 bone_transform = mat4(0.f);
|
||||
mat4x3 bone_transform = mat4x3(0.0);
|
||||
for (int i = 0; i < NR_WEIGHTS; i++) {
|
||||
if (vertex_bone_index[i] >= 0) {
|
||||
bone_transform += bone_matrices[vertex_bone_index[i]] * vertex_bone_weight[i];
|
||||
}
|
||||
}
|
||||
local_bone_transform *= bone_transform;
|
||||
local_bone_transform *= mat4(
|
||||
vec4(bone_transform[0], 0.0),
|
||||
vec4(bone_transform[1], 0.0),
|
||||
vec4(bone_transform[2], 0.0),
|
||||
vec4(bone_transform[3], 1.0));
|
||||
}
|
||||
|
||||
gl_Position = view_transform * local_bone_transform * vec4(vertex_pos, 1.0);
|
||||
|
||||
@@ -177,6 +177,7 @@ struct RE_renderer {
|
||||
GLint ls_sun_color;
|
||||
GLint alpha_mode;
|
||||
GLint alpha_texture;
|
||||
GLint uv_scroll;
|
||||
|
||||
GLuint billboard_vao;
|
||||
GLuint billboard_attr_buffer;
|
||||
@@ -446,6 +447,8 @@ struct pol_mesh {
|
||||
vec2 *light_uvs;
|
||||
uint32_t nr_colors;
|
||||
vec3 *colors;
|
||||
uint32_t nr_alphas;
|
||||
float *alphas;
|
||||
uint32_t nr_triangles;
|
||||
struct pol_triangle *triangles;
|
||||
// Parameters in .opr file.
|
||||
@@ -470,6 +473,7 @@ struct pol_triangle {
|
||||
uint32_t uv_index[3];
|
||||
uint32_t light_uv_index[3];
|
||||
uint32_t color_index[3];
|
||||
uint32_t alpha_index[3];
|
||||
vec3 normals[3];
|
||||
uint32_t material_group_index;
|
||||
};
|
||||
|
||||
+9
-5
@@ -42,7 +42,7 @@ struct vertex_light_uv {
|
||||
};
|
||||
|
||||
struct vertex_color {
|
||||
GLfloat color[3];
|
||||
GLfloat color[4];
|
||||
};
|
||||
|
||||
struct vertex_tangent {
|
||||
@@ -227,7 +227,7 @@ static void *buf_alloc(uint8_t **ptr, int size)
|
||||
static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_group_index, int material)
|
||||
{
|
||||
bool has_light_map = m->light_uvs && model->materials[material].light_map;
|
||||
bool has_vertex_colors = m->nr_colors > 0;
|
||||
bool has_vertex_colors = m->nr_colors > 0 || m->nr_alphas > 0;
|
||||
bool has_normal_map = model->materials[material].normal_map != 0;
|
||||
bool has_bones = !!model->bone_map;
|
||||
|
||||
@@ -264,7 +264,11 @@ static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_
|
||||
}
|
||||
if (has_vertex_colors) {
|
||||
struct vertex_color *v_color = buf_alloc(&ptr, sizeof(struct vertex_color));
|
||||
glm_vec3_copy(m->colors[t->color_index[j]], v_color->color);
|
||||
if (m->nr_colors > 0)
|
||||
glm_vec3_copy(m->colors[t->color_index[j]], v_color->color);
|
||||
else
|
||||
glm_vec3_one(v_color->color);
|
||||
v_color->color[3] = m->nr_alphas > 0 ? m->alphas[t->alpha_index[j]] : 1.f;
|
||||
}
|
||||
if (has_normal_map) {
|
||||
struct vertex_tangent *v_tangent = buf_alloc(&ptr, sizeof(struct vertex_tangent));
|
||||
@@ -329,11 +333,11 @@ static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_
|
||||
}
|
||||
if (has_vertex_colors) {
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glVertexAttribPointer(VATTR_COLOR, 3, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_color, color));
|
||||
glVertexAttribPointer(VATTR_COLOR, 4, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_color, color));
|
||||
base += sizeof(struct vertex_color);
|
||||
} else {
|
||||
glDisableVertexAttribArray(VATTR_COLOR);
|
||||
glVertexAttrib3f(VATTR_COLOR, 1.0, 1.0, 1.0);
|
||||
glVertexAttrib4f(VATTR_COLOR, 1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
if (has_normal_map) {
|
||||
glEnableVertexAttribArray(VATTR_TANGENT);
|
||||
|
||||
+15
-9
@@ -134,7 +134,7 @@ static void destroy_vertex(struct pol_vertex *v)
|
||||
free(v->weights);
|
||||
}
|
||||
|
||||
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, int unknowns_length, const struct pol_material_group *mg)
|
||||
static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle_index, const struct pol_material_group *mg)
|
||||
{
|
||||
struct pol_triangle *t = &mesh->triangles[triangle_index];
|
||||
t->vert_index[0] = buffer_read_int32(r);
|
||||
@@ -148,11 +148,15 @@ static void parse_triangle(struct buffer *r, struct pol_mesh *mesh, int triangle
|
||||
t->light_uv_index[1] = buffer_read_int32(r) - mesh->nr_uvs;
|
||||
t->light_uv_index[2] = buffer_read_int32(r) - mesh->nr_uvs;
|
||||
}
|
||||
|
||||
t->color_index[0] = buffer_read_int32(r);
|
||||
t->color_index[1] = buffer_read_int32(r);
|
||||
t->color_index[2] = buffer_read_int32(r);
|
||||
|
||||
buffer_skip(r, unknowns_length);
|
||||
if (mesh->alphas) {
|
||||
t->alpha_index[0] = buffer_read_int32(r);
|
||||
t->alpha_index[1] = buffer_read_int32(r);
|
||||
t->alpha_index[2] = buffer_read_int32(r);
|
||||
}
|
||||
|
||||
read_direction(r, t->normals[0]);
|
||||
read_direction(r, t->normals[1]);
|
||||
@@ -234,19 +238,20 @@ static struct pol_mesh *parse_mesh(struct buffer *r, const struct pol *pol)
|
||||
}
|
||||
}
|
||||
|
||||
int triangle_unknowns_length = 0;
|
||||
if (pol->version >= 2) {
|
||||
int nr_unknown_bytes = buffer_read_int32(r);
|
||||
if (nr_unknown_bytes) {
|
||||
buffer_skip(r, nr_unknown_bytes);
|
||||
triangle_unknowns_length += 12;
|
||||
mesh->nr_alphas = buffer_read_int32(r);
|
||||
if (mesh->nr_alphas > 0) {
|
||||
mesh->alphas = xcalloc(mesh->nr_alphas, sizeof(float));
|
||||
for (uint32_t i = 0; i < mesh->nr_alphas; i++) {
|
||||
mesh->alphas[i] = buffer_read_u8(r) / 255.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mesh->nr_triangles = buffer_read_int32(r);
|
||||
mesh->triangles = xcalloc(mesh->nr_triangles, sizeof(struct pol_triangle));
|
||||
for (uint32_t i = 0; i < mesh->nr_triangles; i++) {
|
||||
parse_triangle(r, mesh, i, triangle_unknowns_length, &pol->materials[mesh->material]);
|
||||
parse_triangle(r, mesh, i, &pol->materials[mesh->material]);
|
||||
}
|
||||
|
||||
if (pol->version == 1) {
|
||||
@@ -270,6 +275,7 @@ static void free_mesh(struct pol_mesh *mesh)
|
||||
free(mesh->uvs);
|
||||
free(mesh->light_uvs);
|
||||
free(mesh->colors);
|
||||
free(mesh->alphas);
|
||||
free(mesh->triangles);
|
||||
free(mesh);
|
||||
}
|
||||
|
||||
+11
-6
@@ -178,13 +178,15 @@ static void update_bones(struct RE_instance *inst)
|
||||
}
|
||||
glm_mat4_copy(bone_transform, parent_transforms[i]);
|
||||
|
||||
glm_mat4_mul(bone_transform, inst->model->bones[i].inverse_bind_matrix, inst->bone_transforms[i]);
|
||||
|
||||
glm_vec3_minv(aabb[0], bone_transform[3], aabb[0]);
|
||||
glm_vec3_maxv(aabb[1], bone_transform[3], aabb[1]);
|
||||
|
||||
glm_mat4_mul(bone_transform, inst->model->bones[i].inverse_bind_matrix, bone_transform);
|
||||
glm_mat4_transpose(bone_transform); // column major -> row major
|
||||
glm_mat3x4_copy(bone_transform, inst->bone_transforms[i]);
|
||||
}
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, inst->bone_transforms_ubo);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, inst->model->nr_bones * sizeof(mat4), inst->bone_transforms);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, inst->model->nr_bones * sizeof(mat3x4), inst->bone_transforms);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
// Update inst->bounding_sphere.
|
||||
@@ -440,10 +442,10 @@ bool RE_instance_load(struct RE_instance *instance, const char *name)
|
||||
ht_put(instance->plugin->model_cache, name, instance->model);
|
||||
}
|
||||
if (instance->model && instance->model->nr_bones > 0) {
|
||||
instance->bone_transforms = xcalloc(instance->model->nr_bones, sizeof(mat4));
|
||||
instance->bone_transforms = xcalloc(instance->model->nr_bones, sizeof(mat3x4));
|
||||
glGenBuffers(1, &instance->bone_transforms_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, instance->bone_transforms_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_BONES * sizeof(mat4), NULL, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_BONES * sizeof(mat3x4), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
return !!instance->model;
|
||||
@@ -531,7 +533,10 @@ bool RE_instance_trans_local_pos_to_world_pos_by_bone(struct RE_instance *instan
|
||||
if (instance->local_transform_needs_update)
|
||||
RE_instance_update_local_transform(instance);
|
||||
|
||||
glm_mat4_mulv3(instance->bone_transforms[bone], offset, 1.0, out);
|
||||
mat4 bone_transform = GLM_MAT4_IDENTITY_INIT;
|
||||
glm_mat3x4_copy(instance->bone_transforms[bone], bone_transform);
|
||||
glm_mat4_transpose(bone_transform); // row major -> column major
|
||||
glm_mat4_mulv3(bone_transform, offset, 1.0, out);
|
||||
glm_mat4_mulv3(instance->local_transform, out, 1.0, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
+12
-2
@@ -181,7 +181,7 @@ static void init_billboard_mesh(struct RE_renderer *r)
|
||||
glDisableVertexAttribArray(VATTR_LIGHT_UV);
|
||||
glVertexAttrib2f(VATTR_LIGHT_UV, 0.0, 0.0);
|
||||
glDisableVertexAttribArray(VATTR_COLOR);
|
||||
glVertexAttrib3f(VATTR_COLOR, 1.0, 1.0, 1.0);
|
||||
glVertexAttrib4f(VATTR_COLOR, 1.0, 1.0, 1.0, 1.0);
|
||||
glDisableVertexAttribArray(VATTR_NORMAL);
|
||||
glVertexAttrib3f(VATTR_NORMAL, 0.0, 0.0, 1.0);
|
||||
glDisableVertexAttribArray(VATTR_TANGENT);
|
||||
@@ -254,6 +254,7 @@ struct RE_renderer *RE_renderer_new(enum RE_plugin_version version)
|
||||
r->ls_sun_color = glGetUniformLocation(r->program, "ls_sun_color");
|
||||
r->alpha_mode = glGetUniformLocation(r->program, "alpha_mode");
|
||||
r->alpha_texture = glGetUniformLocation(r->program, "alpha_texture");
|
||||
r->uv_scroll = glGetUniformLocation(r->program, "uv_scroll");
|
||||
|
||||
glGenRenderbuffers(1, &r->depth_buffer);
|
||||
|
||||
@@ -429,13 +430,22 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r, enum d
|
||||
glUniform1i(r->alpha_mode, ALPHA_BLEND);
|
||||
}
|
||||
|
||||
vec2 uv_scroll;
|
||||
glm_vec2_scale(mesh->uv_scroll, r->last_frame_timestamp / 1000.f, uv_scroll);
|
||||
glUniform2fv(r->uv_scroll, 1, uv_scroll);
|
||||
|
||||
glBindVertexArray(mesh->vao);
|
||||
|
||||
if (mesh->flags & MESH_BOTH)
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (mesh->nr_indices)
|
||||
glDrawElements(GL_TRIANGLES, mesh->nr_indices, GL_UNSIGNED_SHORT, NULL);
|
||||
else
|
||||
glDrawArrays(GL_TRIANGLES, 0, mesh->nr_vertices);
|
||||
|
||||
if (mesh->flags & MESH_BOTH)
|
||||
glEnable(GL_CULL_FACE);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
@@ -1059,7 +1069,7 @@ struct height_detector *RE_renderer_create_height_detector(struct RE_renderer *r
|
||||
GLuint bone_transforms_ubo;
|
||||
glGenBuffers(1, &bone_transforms_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, bone_transforms_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_BONES * sizeof(mat4), NULL, GL_STATIC_DRAW);
|
||||
glBufferData(GL_UNIFORM_BUFFER, MAX_BONES * sizeof(mat3x4), NULL, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, BONE_TRANSFORMS_BINDING, bone_transforms_ubo);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user