diff --git a/shaders/reign.f.glsl b/shaders/reign.f.glsl index fd29a6b..1bb576a 100644 --- a/shaders/reign.f.glsl +++ b/shaders/reign.f.glsl @@ -62,6 +62,7 @@ uniform int alpha_mode; in vec2 tex_coord; in vec2 light_tex_coord; +in vec3 color_mod; in vec3 frag_pos; in vec4 shadow_frag_pos; in float dist; @@ -103,7 +104,7 @@ void main() { if (diffuse_type == DIFFUSE_LIGHT_MAP) { diffuse *= texture(light_texture, light_tex_coord).rgb; } - frag_rgb += texel.rgb * diffuse; + frag_rgb += texel.rgb * diffuse * color_mod; } } diff --git a/shaders/reign.v.glsl b/shaders/reign.v.glsl index 15a771b..135805f 100644 --- a/shaders/reign.v.glsl +++ b/shaders/reign.v.glsl @@ -51,12 +51,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_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 vec3 frag_pos; out vec4 shadow_frag_pos; out float dist; @@ -97,6 +99,7 @@ void main() { tex_coord = vertex_uv; light_tex_coord = vertex_light_uv; + color_mod = vertex_color; dist = -view_pos.z; shadow_frag_pos = shadow_transform * world_pos; diff --git a/src/3d/3d_internal.h b/src/3d/3d_internal.h index f0d8192..b79e3c9 100644 --- a/src/3d/3d_internal.h +++ b/src/3d/3d_internal.h @@ -98,6 +98,7 @@ enum RE_attribute_location { VATTR_BONE_INDEX, VATTR_BONE_WEIGHT, VATTR_LIGHT_UV, + VATTR_COLOR, VATTR_TANGENT, }; @@ -425,6 +426,8 @@ struct pol_mesh { vec2 *uvs; uint32_t nr_light_uvs; vec2 *light_uvs; + uint32_t nr_colors; + vec3 *colors; uint32_t nr_triangles; struct pol_triangle *triangles; }; @@ -444,6 +447,7 @@ struct pol_triangle { uint32_t vert_index[3]; uint32_t uv_index[3]; uint32_t light_uv_index[3]; + uint32_t color_index[3]; vec3 normals[3]; uint32_t material_group_index; }; diff --git a/src/3d/model.c b/src/3d/model.c index 48d90ef..a437f43 100644 --- a/src/3d/model.c +++ b/src/3d/model.c @@ -40,6 +40,10 @@ struct vertex_light_uv { GLfloat uv[2]; }; +struct vertex_color { + GLfloat color[3]; +}; + struct vertex_tangent { GLfloat tangent[4]; }; @@ -217,12 +221,15 @@ 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_normal_map = model->materials[material].normal_map != 0; bool has_bones = !!model->bone_map; GLsizei stride = sizeof(struct vertex_common); if (has_light_map) stride += sizeof(struct vertex_light_uv); + if (has_vertex_colors) + stride += sizeof(struct vertex_color); if (has_normal_map) stride += sizeof(struct vertex_tangent); if (has_bones) @@ -249,6 +256,10 @@ static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_ struct vertex_light_uv *v_light_uv = buf_alloc(&ptr, sizeof(struct vertex_light_uv)); glm_vec2_copy(m->light_uvs[t->light_uv_index[j]], v_light_uv->uv); } + 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 (has_normal_map) { struct vertex_tangent *v_tangent = buf_alloc(&ptr, sizeof(struct vertex_tangent)); glm_vec4_ucopy(tangent[j], v_tangent->tangent); @@ -305,6 +316,14 @@ static void add_mesh(struct model *model, struct pol_mesh *m, uint32_t material_ glDisableVertexAttribArray(VATTR_LIGHT_UV); glVertexAttrib2f(VATTR_LIGHT_UV, 0.0, 0.0); } + if (has_vertex_colors) { + glEnableVertexAttribArray(VATTR_COLOR); + glVertexAttribPointer(VATTR_COLOR, 3, 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); + } if (has_normal_map) { glEnableVertexAttribArray(VATTR_TANGENT); glVertexAttribPointer(VATTR_TANGENT, 4, GL_FLOAT, GL_FALSE, stride, base + offsetof(struct vertex_tangent, tangent)); diff --git a/src/3d/parser.c b/src/3d/parser.c index 87383c2..c37271c 100644 --- a/src/3d/parser.c +++ b/src/3d/parser.c @@ -148,6 +148,9 @@ 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); @@ -214,13 +217,25 @@ static struct pol_mesh *parse_mesh(struct buffer *r, const struct pol *pol) } } - int triangle_unknowns_length = 12; - if (pol->version == 1) { - int nr_unknown_vecs = buffer_read_int32(r); - buffer_skip(r, nr_unknown_vecs * 12); - } else { - int nr_unknown_ints = buffer_read_int32(r); - buffer_skip(r, nr_unknown_ints * 4); + mesh->nr_colors = buffer_read_int32(r); + if (mesh->nr_colors > 0) { + mesh->colors = xcalloc(mesh->nr_colors, sizeof(vec3)); + for (uint32_t i = 0; i < mesh->nr_colors; i++) { + if (pol->version == 1) { + mesh->colors[i][0] = buffer_read_float(r); + mesh->colors[i][1] = buffer_read_float(r); + mesh->colors[i][2] = buffer_read_float(r); + } else { + mesh->colors[i][0] = buffer_read_u8(r) / 255.f; + mesh->colors[i][1] = buffer_read_u8(r) / 255.f; + mesh->colors[i][2] = buffer_read_u8(r) / 255.f; + buffer_skip(r, 1); + } + } + } + + 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); @@ -254,6 +269,7 @@ static void free_mesh(struct pol_mesh *mesh) free(mesh->vertices); free(mesh->uvs); free(mesh->light_uvs); + free(mesh->colors); free(mesh->triangles); free(mesh); } diff --git a/src/3d/renderer.c b/src/3d/renderer.c index 39cf4ac..d1c1dd3 100644 --- a/src/3d/renderer.c +++ b/src/3d/renderer.c @@ -74,6 +74,7 @@ static GLuint load_shader(const char *vertex_shader_path, const char *fragment_s glBindAttribLocation(program, VATTR_BONE_INDEX, "vertex_bone_index"); glBindAttribLocation(program, VATTR_BONE_WEIGHT, "vertex_bone_weight"); glBindAttribLocation(program, VATTR_LIGHT_UV, "vertex_light_uv"); + glBindAttribLocation(program, VATTR_COLOR, "vertex_color"); glBindAttribLocation(program, VATTR_TANGENT, "vertex_tangent"); glLinkProgram(program); @@ -144,6 +145,8 @@ static void init_billboard_mesh(struct RE_renderer *r) glVertexAttribPointer(VATTR_UV, 2, GL_FLOAT, GL_FALSE, 20, (const void *)12); glDisableVertexAttribArray(VATTR_LIGHT_UV); glVertexAttrib2f(VATTR_LIGHT_UV, 0.0, 0.0); + glDisableVertexAttribArray(VATTR_COLOR); + glVertexAttrib3f(VATTR_COLOR, 1.0, 1.0, 1.0); glDisableVertexAttribArray(VATTR_NORMAL); glVertexAttrib3f(VATTR_NORMAL, 0.0, 0.0, 1.0); glDisableVertexAttribArray(VATTR_TANGENT);